mp3rtp.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * mp3rtp command line frontend program
  3. *
  4. * initially contributed by Felix von Leitner
  5. *
  6. * Copyright (c) 2000 Mark Taylor
  7. * 2010 Robert Hegemann
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Library General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2 of the License, or (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Library General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Library General Public
  20. * License along with this library; if not, write to the
  21. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  22. * Boston, MA 02111-1307, USA.
  23. */
  24. /* $Id$ */
  25. /* Still under work ..., need a client for test, where can I get one? */
  26. /* An audio player named Zinf (aka freeamp) can play rtp streams */
  27. /*
  28. * experimental translation:
  29. *
  30. * gcc -I..\include -I..\libmp3lame -o mp3rtp mp3rtp.c ../libmp3lame/libmp3lame.a lametime.c get_audio.c ieeefloat.c timestatus.c parse.c rtp.c -lm
  31. *
  32. * wavrec -t 14400 -s 44100 -S /proc/self/fd/1 | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3
  33. */
  34. #ifdef HAVE_CONFIG_H
  35. # include <config.h>
  36. #endif
  37. #ifdef HAVE_STDINT_H
  38. # include <stdint.h>
  39. #endif
  40. #ifdef STDC_HEADERS
  41. # include <stdlib.h>
  42. # include <string.h>
  43. #endif
  44. #include <time.h>
  45. #ifdef HAVE_UNISTD_H
  46. # include <unistd.h>
  47. #endif
  48. #include "lame.h"
  49. #include "main.h"
  50. #include "parse.h"
  51. #include "lametime.h"
  52. #include "timestatus.h"
  53. #include "get_audio.h"
  54. #include "rtp.h"
  55. #include "console.h"
  56. #ifdef WITH_DMALLOC
  57. #include <dmalloc.h>
  58. #endif
  59. /*
  60. * Encode (via LAME) to mp3 with RTP streaming of the output.
  61. *
  62. * Author: Felix von Leitner <leitner@vim.org>
  63. *
  64. * mp3rtp ip[:port[:ttl]] [lame encoding options] infile outfile
  65. *
  66. * examples:
  67. * arecord -b 16 -s 22050 -w | ./mp3rtp 224.17.23.42:5004:2 -b 56 - /dev/null
  68. * arecord -b 16 -s 44100 -w | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3
  69. *
  70. */
  71. static unsigned int
  72. maxvalue(int Buffer[2][1152])
  73. {
  74. int max = 0;
  75. int i;
  76. for (i = 0; i < 1152; i++) {
  77. if (abs(Buffer[0][i]) > max)
  78. max = abs(Buffer[0][i]);
  79. if (abs(Buffer[1][i]) > max)
  80. max = abs(Buffer[1][i]);
  81. }
  82. return max >> 16;
  83. }
  84. static void
  85. levelmessage(unsigned int maxv, int* maxx, int* tmpx)
  86. {
  87. char buff[] = "| . | . | . | . | . | . | . | . | . | . | \r";
  88. int tmp = *tmpx, max = *maxx;
  89. buff[tmp] = '+';
  90. tmp = (maxv * 61 + 16384) / (32767 + 16384 / 61);
  91. if (tmp > sizeof(buff) - 2)
  92. tmp = sizeof(buff) - 2;
  93. if (max < tmp)
  94. max = tmp;
  95. buff[max] = 'x';
  96. buff[tmp] = '#';
  97. console_printf(buff);
  98. console_flush();
  99. *maxx = max;
  100. *tmpx = tmp;
  101. }
  102. /************************************************************************
  103. *
  104. * main
  105. *
  106. * PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO
  107. * psychoacoustic model.
  108. *
  109. ************************************************************************/
  110. int
  111. lame_main(lame_t gf, int argc, char **argv)
  112. {
  113. unsigned char mp3buffer[LAME_MAXMP3BUFFER];
  114. char inPath[PATH_MAX + 1];
  115. char outPath[PATH_MAX + 1];
  116. int Buffer[2][1152];
  117. int maxx = 0, tmpx = 0;
  118. int ret;
  119. int wavsamples;
  120. int mp3bytes;
  121. FILE *outf;
  122. char ip[16];
  123. unsigned int port = 5004;
  124. unsigned int ttl = 2;
  125. char dummy;
  126. if (argc <= 2) {
  127. console_printf("Encode (via LAME) to mp3 with RTP streaming of the output\n"
  128. "\n"
  129. " mp3rtp ip[:port[:ttl]] [lame encoding options] infile outfile\n"
  130. "\n"
  131. " examples:\n"
  132. " arecord -b 16 -s 22050 -w | ./mp3rtp 224.17.23.42:5004:2 -b 56 - /dev/null\n"
  133. " arecord -b 16 -s 44100 -w | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3\n"
  134. "\n");
  135. return 1;
  136. }
  137. switch (sscanf(argv[1], "%11[.0-9]:%u:%u%c", ip, &port, &ttl, &dummy)) {
  138. case 1:
  139. case 2:
  140. case 3:
  141. break;
  142. default:
  143. error_printf("Illegal destination selector '%s', must be ip[:port[:ttl]]\n", argv[1]);
  144. return -1;
  145. }
  146. rtp_initialization();
  147. if (rtp_socket(ip, port, ttl)) {
  148. rtp_deinitialization();
  149. error_printf("fatal error during initialization\n");
  150. return 1;
  151. }
  152. lame_set_errorf(gf, &frontend_errorf);
  153. lame_set_debugf(gf, &frontend_debugf);
  154. lame_set_msgf(gf, &frontend_msgf);
  155. /* Remove the argumets that are rtp related, and then
  156. * parse the command line arguments, setting various flags in the
  157. * struct pointed to by 'gf'. If you want to parse your own arguments,
  158. * or call libmp3lame from a program which uses a GUI to set arguments,
  159. * skip this call and set the values of interest in the gf struct.
  160. * (see lame.h for documentation about these parameters)
  161. */
  162. {
  163. int i;
  164. int argc_mod = argc-1; /* leaving out exactly one argument */
  165. char** argv_mod = calloc(argc_mod, sizeof(char*));
  166. argv_mod[0] = argv[0];
  167. for (i = 2; i < argc; ++i) { /* leaving out argument number 1, parsed above */
  168. argv_mod[i-1] = argv[i];
  169. }
  170. parse_args(gf, argc_mod, argv_mod, inPath, outPath, NULL, NULL);
  171. free(argv_mod);
  172. }
  173. /* open the output file. Filename parsed into gf.inPath */
  174. if (0 == strcmp(outPath, "-")) {
  175. lame_set_stream_binary_mode(outf = stdout);
  176. }
  177. else {
  178. if ((outf = lame_fopen(outPath, "wb+")) == NULL) {
  179. rtp_deinitialization();
  180. error_printf("Could not create \"%s\".\n", outPath);
  181. return 1;
  182. }
  183. }
  184. /* open the wav/aiff/raw pcm or mp3 input file. This call will
  185. * open the file with name gf.inFile, try to parse the headers and
  186. * set gf.samplerate, gf.num_channels, gf.num_samples.
  187. * if you want to do your own file input, skip this call and set
  188. * these values yourself.
  189. */
  190. if (init_infile(gf, inPath) < 0) {
  191. rtp_deinitialization();
  192. fclose(outf);
  193. error_printf("Can't init infile '%s'\n", inPath);
  194. return 1;
  195. }
  196. /* Now that all the options are set, lame needs to analyze them and
  197. * set some more options
  198. */
  199. ret = lame_init_params(gf);
  200. if (ret < 0) {
  201. if (ret == -1)
  202. display_bitrates(stderr);
  203. rtp_deinitialization();
  204. fclose(outf);
  205. close_infile();
  206. error_printf("fatal error during initialization\n");
  207. return -1;
  208. }
  209. lame_print_config(gf); /* print useful information about options being used */
  210. if (global_ui_config.update_interval < 0.)
  211. global_ui_config.update_interval = 2.;
  212. /* encode until we hit EOF */
  213. while ((wavsamples = get_audio(gf, Buffer)) > 0) { /* read in 'wavsamples' samples */
  214. levelmessage(maxvalue(Buffer), &maxx, &tmpx);
  215. mp3bytes = lame_encode_buffer_int(gf, /* encode the frame */
  216. Buffer[0], Buffer[1], wavsamples,
  217. mp3buffer, sizeof(mp3buffer));
  218. rtp_output(mp3buffer, mp3bytes); /* write MP3 output to RTP port */
  219. fwrite(mp3buffer, 1, mp3bytes, outf); /* write the MP3 output to file */
  220. }
  221. mp3bytes = lame_encode_flush(gf, /* may return one or more mp3 frame */
  222. mp3buffer, sizeof(mp3buffer));
  223. rtp_output(mp3buffer, mp3bytes); /* write MP3 output to RTP port */
  224. fwrite(mp3buffer, 1, mp3bytes, outf); /* write the MP3 output to file */
  225. lame_mp3_tags_fid(gf, outf); /* add VBR tags to mp3 file */
  226. rtp_deinitialization();
  227. fclose(outf);
  228. close_infile(); /* close the sound input file */
  229. return 0;
  230. }
  231. /* end of mp3rtp.c */