Newer
Older
monitord / lame-3.97 / frontend / .svn / text-base / mp3rtp.c.svn-base
  1. /* $Id: mp3rtp.c,v 1.22 2004/12/31 11:26:25 takehiro Exp $ */
  2.  
  3. /* Still under work ..., need a client for test, where can I get one? */
  4.  
  5. /*
  6. * experimental translation:
  7. *
  8. * gcc -I..\include -I..\libmp3lame -o mp3rtp mp3rtp.c ../libmp3lame/libmp3lame.a lametime.c get_audio.c portableio.c ieeefloat.c timestatus.c parse.c rtp.c -lm
  9. *
  10. * wavrec -t 14400 -s 44100 -S /proc/self/fd/1 | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3
  11. */
  12.  
  13. #ifdef HAVE_CONFIG_H
  14. # include <config.h>
  15. #endif
  16.  
  17. #ifdef STDC_HEADERS
  18. # include <stdlib.h>
  19. # include <string.h>
  20. #else
  21. # ifndef HAVE_STRCHR
  22. # define strchr index
  23. # define strrchr rindex
  24. # endif
  25. char *strchr (), *strrchr ();
  26. # ifndef HAVE_MEMCPY
  27. # define memcpy(d, s, n) bcopy ((s), (d), (n))
  28. # define memmove(d, s, n) bcopy ((s), (d), (n))
  29. # endif
  30. #endif
  31.  
  32. #include <time.h>
  33.  
  34. #ifdef HAVE_UNISTD_H
  35. # include <unistd.h>
  36. #endif
  37.  
  38. #include "lame.h"
  39. #include "main.h"
  40. #include "parse.h"
  41. #include "lametime.h"
  42. #include "timestatus.h"
  43. #include "get_audio.h"
  44. #include "rtp.h"
  45.  
  46. #ifdef WITH_DMALLOC
  47. #include <dmalloc.h>
  48. #endif
  49.  
  50. /*
  51. * Encode (via LAME) to mp3 with RTP streaming of the output.
  52. *
  53. * Author: Felix von Leitner <leitner@vim.org>
  54. *
  55. * mp3rtp ip[:port[:ttl]] [lame encoding options] infile outfile
  56. *
  57. * examples:
  58. * arecord -b 16 -s 22050 -w | ./mp3rtp 224.17.23.42:5004:2 -b 56 - /dev/null
  59. * arecord -b 16 -s 44100 -w | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3
  60. *
  61. */
  62.  
  63. struct rtpheader RTPheader;
  64. struct sockaddr_in rtpsi;
  65. int rtpsocket;
  66.  
  67. void rtp_output ( const char* mp3buffer, const int mp3size )
  68. {
  69. sendrtp (rtpsocket, &rtpsi, &RTPheader, mp3buffer, mp3size);
  70. RTPheader.timestamp += 5;
  71. RTPheader.b.sequence++;
  72. }
  73.  
  74. #if 0
  75. struct rtpheader RTPheader;
  76. SOCKET rtpsocket;
  77.  
  78. void rtp_output (char *mp3buffer, int mp3size)
  79. {
  80. rtp_send (rtpsocket, &RTPheader,mp3buffer,mp3size) ;
  81. RTPheader.timestamp+=5;
  82. RTPheader.b.sequence++;
  83. }
  84. #endif
  85.  
  86.  
  87.  
  88.  
  89. unsigned int maxvalue ( int Buffer [2] [1152] )
  90. {
  91. unsigned int max = 0;
  92. int i;
  93. for ( i = 0; i < 1152; i++ ) {
  94. if ( abs (Buffer[0][i]) > max ) max = abs (Buffer[0][i]);
  95. if ( abs (Buffer[1][i]) > max ) max = abs (Buffer[1][i]);
  96. }
  97. return max;
  98. }
  99.  
  100. void levelmessage ( unsigned int maxvalue )
  101. {
  102. char buff[] = "| . | . | . | . | . | . | . | . | . | . | \r";
  103. static int max = 0;
  104. static int tmp = 0;
  105.  
  106. buff [tmp] = '+';
  107. tmp = (maxvalue*61 + 16384) / (32767 + 16384/61);
  108. if (tmp > sizeof(buff)-2)
  109. tmp = sizeof(buff)-2;
  110. if (max < tmp)
  111. max = tmp;
  112. buff [max] = 'x';
  113. buff [tmp] = '#';
  114. fwrite ( buff, 1, sizeof(buff)-1, stderr );
  115. }
  116.  
  117.  
  118. /************************************************************************
  119. *
  120. * main
  121. *
  122. * PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO
  123. * psychoacoustic model.
  124. *
  125. ************************************************************************/
  126.  
  127. int main ( int argc, char **argv )
  128. {
  129. unsigned char mp3buffer [LAME_MAXMP3BUFFER];
  130. char inPath [PATH_MAX + 1];
  131. char outPath [PATH_MAX + 1];
  132. int Buffer [2] [1152];
  133.  
  134. lame_global_flags *gf;
  135. int ret;
  136. int wavsamples;
  137. int mp3bytes;
  138. FILE* outf;
  139.  
  140. char ip [16];
  141. unsigned port = 5004;
  142. unsigned ttl = 2;
  143. char dummy;
  144.  
  145. if ( argc <= 2 ) {
  146. fprintf ( stderr,
  147. "Encode (via LAME) to mp3 with RTP streaming of the output\n"
  148. "\n"
  149. " mp3rtp ip[:port[:ttl]] [lame encoding options] infile outfile\n"
  150. "\n"
  151. " examples:\n"
  152. " arecord -b 16 -s 22050 -w | ./mp3rtp 224.17.23.42:5004:2 -b 56 - /dev/null\n"
  153. " arecord -b 16 -s 44100 -w | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3\n"
  154. "\n" );
  155.  
  156. return 1;
  157. }
  158.  
  159. switch (sscanf ( argv[1], "%11[.0-9]:%u:%u%c", ip, &port, &ttl, &dummy )) {
  160. case 1:
  161. case 2:
  162. case 3:
  163. break;
  164. default:
  165. fprintf (stderr, "Illegal destination selector '%s', must be ip[:port[:ttl]]\n", argv[1] );
  166. return -1;
  167. }
  168.  
  169. rtpsocket = makesocket ( ip, port, ttl, &rtpsi );
  170. srand ( getpid () ^ time (NULL) );
  171. initrtp ( &RTPheader );
  172.  
  173. /* initialize encoder */
  174. gf=lame_init();
  175.  
  176. /* Remove the argumets that are rtp related, and then
  177. * parse the command line arguments, setting various flags in the
  178. * struct pointed to by 'gf'. If you want to parse your own arguments,
  179. * or call libmp3lame from a program which uses a GUI to set arguments,
  180. * skip this call and set the values of interest in the gf struct.
  181. * (see lame.h for documentation about these parameters)
  182. */
  183. argv[1] = argv[0];
  184. parse_args(gf, argc - 1, argv + 1, inPath, outPath,NULL,NULL);
  185.  
  186. /* open the output file. Filename parsed into gf.inPath */
  187. if ( 0 == strcmp ( outPath, "-" ) ) {
  188. lame_set_stream_binary_mode (outf = stdout);
  189. }
  190. else {
  191. if ((outf = fopen (outPath, "wb+")) == NULL) {
  192. fprintf (stderr, "Could not create \"%s\".\n", outPath);
  193. return 1;
  194. }
  195. }
  196.  
  197.  
  198. /* open the wav/aiff/raw pcm or mp3 input file. This call will
  199. * open the file with name gf.inFile, try to parse the headers and
  200. * set gf.samplerate, gf.num_channels, gf.num_samples.
  201. * if you want to do your own file input, skip this call and set
  202. * these values yourself.
  203. */
  204. init_infile(gf,inPath);
  205.  
  206.  
  207. /* Now that all the options are set, lame needs to analyze them and
  208. * set some more options
  209. */
  210. ret = lame_init_params(gf);
  211. if ( ret < 0 ) {
  212. if (ret == -1) display_bitrates (stderr);
  213. fprintf (stderr, "fatal error during initialization\n");
  214. return -1;
  215. }
  216.  
  217. lame_print_config(gf); /* print useful information about options being used */
  218.  
  219. if (update_interval < 0.)
  220. update_interval = 2.;
  221.  
  222. /* encode until we hit EOF */
  223. while ( (wavsamples = get_audio(gf, Buffer)) > 0 ) { /* read in 'wavsamples' samples */
  224. levelmessage ( maxvalue (Buffer) );
  225. mp3bytes = lame_encode_buffer_int(gf, /* encode the frame */
  226. Buffer[0], Buffer[1], wavsamples,
  227. mp3buffer, sizeof (mp3buffer) );
  228.  
  229. rtp_output ( mp3buffer, mp3bytes ); /* write MP3 output to RTP port */
  230. fwrite ( mp3buffer, 1, mp3bytes, outf ); /* write the MP3 output to file */
  231. }
  232.  
  233. mp3bytes = lame_encode_flush(gf, /* may return one or more mp3 frame */
  234. mp3buffer, sizeof (mp3buffer) );
  235. rtp_output ( mp3buffer, mp3bytes ); /* write MP3 output to RTP port */
  236. fwrite ( mp3buffer, 1, mp3bytes, outf ); /* write the MP3 output to file */
  237. lame_mp3_tags_fid(gf, outf ); /* add VBR tags to mp3 file */
  238. lame_close(gf);
  239. fclose(outf);
  240. close_infile(); /* close the sound input file */
  241. return 0;
  242. }
  243.  
  244. /* end of mp3rtp.c */