towave.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:14k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2. * Version: RCSL 1.0/RPSL 1.0 
  3. *  
  4. * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5. *      
  6. * The contents of this file, and the files included with this file, are 
  7. * subject to the current version of the RealNetworks Public Source License 
  8. * Version 1.0 (the "RPSL") available at 
  9. * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10. * the file under the RealNetworks Community Source License Version 1.0 
  11. * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12. * in which case the RCSL will apply. You may also obtain the license terms 
  13. * directly from RealNetworks.  You may not use this file except in 
  14. * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15. * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16. * RCSL for the rights, obligations and limitations governing use of the 
  17. * contents of the file.  
  18. *  
  19. * This file is part of the Helix DNA Technology. RealNetworks is the 
  20. * developer of the Original Code and owns the copyrights in the portions 
  21. * it created. 
  22. *  
  23. * This file, and the files included with this file, is distributed and made 
  24. * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25. * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26. * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27. * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28. * Technology Compatibility Kit Test Suite(s) Location: 
  29. *    http://www.helixcommunity.org/content/tck 
  30. * Contributor(s): 
  31. *  
  32. * ***** END LICENSE BLOCK ***** */ 
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <math.h>
  36. #include <string.h>
  37. #ifdef _WIN32
  38. #include <io.h>
  39. #include <conio.h>
  40. #elif defined _LINUX
  41. #include <unistd.h>
  42. #define kbhit() 0
  43. #define getch()
  44. #define O_BINARY 0
  45. #endif
  46. #include <fcntl.h>     /* file open flags */
  47. #include <sys/types.h>   /* someone wants for port */
  48. #include <sys/stat.h>    /* forward slash for portability */
  49. #include "mhead.h"     /* mpeg header structure, decode protos */
  50. //#include "port.h"
  51. //#include "DXhead.h"     /* Xing header in MPEG stream */
  52. //#include "MpaDecL1.h"
  53. //#include "MpaDecL2.h"
  54. //#include "MpaDecL3.h"
  55. #include "mpadecobjfltpt.h"
  56. /* time test Pentium only */
  57. //#define TIME_TEST
  58. static char default_file[] = "TEST.MP3";
  59. static char default_outfile[] = "TEST.WAV";
  60. /*---- timing test ---*/
  61. #ifdef TIME_TEST
  62. static double tot_cycles;
  63. static int  tot_cycles_n;
  64. extern "C" {
  65.     unsigned int set_clock(void);
  66.     unsigned int get_clock(void);
  67. }
  68. //extern unsigned int global_cycles;
  69. #endif
  70. /*********  bitstream buffer */
  71. #define BS_BUFBYTES 60000U
  72. static unsigned char *bs_buffer = NULL;
  73. static unsigned char *bs_bufptr;
  74. static int bs_trigger;      
  75. static int bs_bufbytes;
  76. static int handle = -1;
  77. /********************** */
  78. /********  pcm buffer ********/
  79. #define PCM_BUFBYTES  60000U
  80. static unsigned char *pcm_buffer;
  81. static unsigned int pcm_bufbytes;
  82. static unsigned int pcm_trigger = (PCM_BUFBYTES - 2500*sizeof(short) ) ;
  83. static int handout = -1;
  84. /****************************/
  85. static int bs_fill();
  86. static int out_help();
  87. static int out_mpeg_info( MPEG_HEAD *h, int bitrate_arg);
  88. int ff_decode(char *filename, 
  89.               char *fileout, 
  90.               int reduction_code, 
  91.               int convert_code, 
  92.               int decode8_flag, 
  93.               int freq_limit);
  94. extern "C" {
  95. int cvt_to_wave_test();
  96. int write_pcm_header_wave( int handout,
  97.         int samprate, int channels, int bits, int type);
  98. int write_pcm_tailer_wave( int handout, unsigned int pcm_bytes);
  99. }
  100. static float calc_br_con( MPEG_HEAD *h);
  101. /*------------------------------------------*/
  102. main(int argc,char *argv[])
  103. {
  104. int i, k;
  105. char *filename;
  106. char *fileout;
  107. int convert_code;
  108. int reduction_code;
  109. int freq_limit;
  110. int decode8_flag;    /* decode to 8KHz */
  111. printf(
  112. "n  file-file MPEG Layer I/II/III audio decode v3.07C/32"
  113. "n Copyright 1995-99 RealNetworks Inc."
  114. "n useage: MpaDec mpeg_file pcm_file" 
  115. );
  116. /****** process command line args */
  117. filename = default_file;
  118. fileout  = default_outfile;
  119. convert_code = 0;
  120. reduction_code = 0;
  121. freq_limit = 24000;
  122. decode8_flag = 0;    /* decode to 8KHz */
  123. for(k=0, i=1; i<argc; i++) {
  124. if( argv[i][0] != '-' ) {
  125. if( k==0 ) filename = argv[i];
  126. if( k==1 ) fileout  = argv[i];
  127. k++;
  128. continue;
  129. }
  130. switch ( argv[i][1] ) {
  131. case 'h':  case 'H':
  132. out_help();
  133. return 0;
  134. case 'c':  case 'C':
  135. convert_code = atoi(argv[i]+2);
  136. break;
  137. case 'r':  case 'R':
  138. reduction_code = atoi(argv[i]+2);
  139. break;
  140. case 'f':  case 'F':
  141. freq_limit = atoi(argv[i]+2);
  142. break;
  143. case 'd':  case 'D':
  144. if( atoi(argv[i]+2) == 8 ) decode8_flag = 1;
  145. break;
  146. }
  147. }
  148. printf("n  <press any key to stop decoder>");
  149. /******** decode *********/
  150. ff_decode(filename, fileout, 
  151. reduction_code, convert_code, decode8_flag,
  152. freq_limit);
  153. /*************************/
  154. /*---- timing test --------*/
  155. #ifdef TIME_TEST
  156. if( tot_cycles_n ) {
  157. // ms per frame
  158. tot_cycles = (1.0/266000.0) * tot_cycles /tot_cycles_n; 
  159. if( tot_cycles > 5.0 ) 
  160. printf("n ave frame time ms = %8.1lf", tot_cycles);
  161. else 
  162. printf("n ave frame time ms = %8.2lf", tot_cycles);
  163. }
  164. #endif
  165. printf("n");
  166. return 0;
  167. }
  168. /*-------------------------------------------------------------*/
  169. static int out_help()
  170. {
  171. printf("n"
  172. "n -D8 option decode8 (8Ks output) convert_code:"
  173. "n    convert_code = 4*bit_code + chan_code"
  174. "n        bit_code:   1 = 16 bit linear pcm"
  175. "n                    2 =  8 bit (unsigned) linear pcm"
  176. "n                    3 = u-law (8 bits unsigned)"
  177. "n        chan_code:  0 = convert two chan to mono"
  178. "n                    1 = convert two chan to mono"
  179. "n                    2 = convert two chan to left chan"
  180. "n                    3 = convert two chan to right chan"
  181. "n decode (standard decoder) convert_code:"
  182. "n              0 = two chan output"
  183. "n              1 = convert two chan to mono"
  184. "n              2 = convert two chan to left chan"
  185. "n              3 = convert two chan to right chan"
  186. "n              (higher bits ignored)"
  187. "n decode (standard decoder) reduction_code:"
  188. "n              0 = full sample rate output"
  189. "n              1 = half rate"
  190. "n              2 = quarter rate"
  191. "n -I  option selects integer decoder"
  192. );
  193. return 1;
  194. }
  195. /*-------------------------------------------------------------*/
  196. int ff_decode(char *filename, char *fileout,
  197.   int reduction_code, int convert_code, int decode8_flag,
  198.   int freq_limit)
  199. {
  200. int framebytes;
  201. int u;
  202. MPEG_HEAD head;
  203. unsigned int nwrite;
  204. IN_OUT x;
  205. int in_bytes, out_bytes;
  206. DEC_INFO decinfo;
  207. int bitrate;
  208. //int seekpoint;
  209. //float percent;
  210. float br_con, br;
  211. //CMpaDecoderL3 decoder;
  212. //CMpaDecoderL3 *decoder = NULL;
  213. //CMpaDecoder *decoder = NULL;
  214. CMpaDecObj  decobj;
  215. /*------------------------------------------*/
  216. /*-----------------------*/
  217. printf("nMPEG input file: %s", filename);
  218. printf("n    output file: %s", fileout);
  219. /*-----------------------*/
  220. in_bytes = out_bytes = 0;
  221. /*-----------------------*/
  222. handout = -1;
  223. pcm_buffer = NULL;
  224. pcm_bufbytes = 0;
  225. /*-----------------------*/
  226. bs_buffer = NULL;
  227. handle = -1;
  228. bs_bufbytes = 0;
  229. bs_bufptr   = bs_buffer;
  230. bs_trigger  =  2500;
  231. /*------ open mpeg file --------*/
  232. handle = open(filename, O_RDONLY|O_BINARY);
  233. if( handle < 0 ) {
  234. printf("n CANNOT_OPEN_INPUT_FILEn");
  235. goto abort; }
  236. /*--- allocate bs buffer ----*/
  237. bs_buffer = new unsigned char [BS_BUFBYTES];
  238. if( bs_buffer == NULL ) {
  239. printf("n CANNOT_ALLOCATE_BUFFERn");
  240. goto abort; }
  241. /*--- fill bs buffer ----*/
  242. if( !bs_fill() ) goto abort;
  243. /*---- parse mpeg header  -------*/
  244. framebytes = head_info2(bs_buffer, bs_bufbytes, &head, &bitrate, 0);
  245. if( framebytes == 0 ) {
  246. printf("n BAD OR UNSUPPORTED MPEG FILEn");
  247. goto abort;
  248.     }
  249. /*--- display mpeg info --*/
  250. out_mpeg_info(&head, bitrate);
  251. /*if( head.option == 1 )          // Layer III
  252.     decoder = new CMpaDecoderL3;
  253. else if( head.option == 2 )     // Layer II
  254.     decoder = new CMpaDecoderL2;
  255. else if( head.option == 3 )     // Layer I
  256.     decoder = new CMpaDecoderL1;
  257. else {
  258.     printf("n BAD OR UNSUPPORTED MPEG OPTIONn");
  259.     goto abort;
  260. }*/
  261. decobj.Init_n(bs_buffer, bs_bufbytes);
  262. br_con = calc_br_con(&head);
  263. /*---- create pcm file ------*/
  264. handout = open(fileout, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  265. if( handout < 0 ) {
  266. printf("n CANNOT CREATE OUTPUT FILEn");
  267. goto abort;
  268.     }
  269. /*---- allocate pcm buffer --------*/
  270. pcm_buffer = new unsigned char [PCM_BUFBYTES];
  271. if( pcm_buffer == NULL ) {
  272. printf("n CANNOT ALLOCATE PCM BUFFERn");
  273. goto abort;
  274.     }
  275. /*---- init decoder -------*/
  276. //if( !decoder->audio_decode_init(&head,framebytes,
  277. //        reduction_code,0,convert_code,freq_limit) ) {
  278. //    printf("n DECODER INIT FAIL n");
  279. //    goto abort;
  280. //    }
  281. /*---- get info -------*/
  282. //decoder->audio_decode_info( &decinfo);
  283. unsigned long ulTemp;
  284. //decoder->GetPCMInfo_v(ulTemp, decinfo.channels, decinfo.bits);
  285. decobj.GetPCMInfo_v(ulTemp, decinfo.channels, decinfo.bits);
  286. decinfo.samprate = ulTemp;
  287. decinfo.type = 0;
  288. /*---- info display -------*/
  289. printf("n output samprate = %6ld", decinfo.samprate);
  290. printf("n output channels = %6d", decinfo.channels);
  291. printf("n output bits     = %6d", decinfo.bits);
  292. printf("n output type     = %6d", decinfo.type);
  293. #ifdef ENABLE_WAVE_HEADER
  294. /*---- write pcm header -------*/
  295. if( !write_pcm_header_wave(handout,
  296.         decinfo.samprate, decinfo.channels, decinfo.bits, decinfo.type ) ) {
  297. printf("n FILE WRITE ERRORn");
  298. goto abort;
  299.     }
  300. #endif
  301. unsigned long   ulBytes,
  302. ulPcmBytes;
  303. printf("n");
  304. /*----- DECODE -----*/
  305. for(u=0;;) {
  306. if( !bs_fill() ) break;
  307. if( bs_bufbytes < framebytes ) break;  /* end of file */
  308. #ifdef TIME_TEST
  309. set_clock();
  310. #endif
  311. //x = decoder->audio_decode(bs_bufptr, (pcm_buffer+pcm_bufbytes));
  312. ulBytes = bs_bufbytes;
  313. ulPcmBytes = PCM_BUFBYTES - pcm_bufbytes;
  314. decobj.DecodeFrame_v(bs_bufptr, &ulBytes, pcm_buffer+pcm_bufbytes, &ulPcmBytes);
  315. x.in_bytes = ulBytes;
  316. x.out_bytes = ulPcmBytes;
  317. #ifdef TIME_TEST
  318. tot_cycles += get_clock(); 
  319. tot_cycles_n++;
  320. //tot_cycles+=global_cycles; 
  321. #endif
  322. if( x.in_bytes <= 0 ) {
  323. printf("n BAD SYNC IN MPEG FILEn");
  324. break;
  325. }
  326. bs_bufptr += x.in_bytes;
  327. bs_bufbytes -= x.in_bytes;
  328. pcm_bufbytes += x.out_bytes;
  329. u++;
  330. if( pcm_bufbytes > pcm_trigger ) {
  331. nwrite = write(handout, pcm_buffer, pcm_bufbytes );
  332. if( nwrite != pcm_bufbytes  ) {
  333. printf("n FILE WRITE ERRORn");
  334. break;
  335. }
  336. out_bytes += pcm_bufbytes;
  337. pcm_bufbytes = 0;
  338. }
  339. if( kbhit() ) break;
  340. in_bytes  += x.in_bytes;
  341. if( (u & 127) == 1 )  {
  342. br = br_con * in_bytes / u;
  343. printf("r frames %6ld   bytes in %6ld    bytes out %6ld  %6.1f",
  344. u, in_bytes, out_bytes, br);
  345. }
  346. }
  347. /*---------------*/
  348. if( pcm_bufbytes > 0 ) {
  349. nwrite = write(handout, pcm_buffer, pcm_bufbytes );
  350. if( nwrite != pcm_bufbytes  ) {
  351. printf("n FILE WRITE ERRORn");
  352. }
  353. out_bytes += pcm_bufbytes;
  354. pcm_bufbytes = 0;
  355. }
  356. br = br_con * in_bytes / u;
  357. printf("n frames %6ld   bytes in %6ld    bytes out %6ld  %6.1f",
  358. u, in_bytes, out_bytes, br);
  359. #ifdef ENABLE_WAVE_HEADER
  360. /*---- write pcm tailer -------*/
  361. write_pcm_tailer_wave(handout, out_bytes);
  362. #endif
  363. printf("n    output file: %s", fileout);
  364. abort:
  365. //delete decoder;
  366. close(handle);
  367. close(handout);
  368. delete [] bs_buffer;
  369. delete [] pcm_buffer;
  370. while( kbhit() ) getch();  /* purge key board */
  371. return 1;
  372. }
  373. /*-------------------------------------------------------------*/
  374. static int bs_fill()
  375. {
  376. unsigned int nread;
  377. if( bs_bufbytes < 0 ) bs_bufbytes = 0;  // signed var could be negative
  378. if( bs_bufbytes < bs_trigger ) {
  379. memmove(bs_buffer, bs_bufptr, bs_bufbytes);
  380. nread = read(handle,bs_buffer+bs_bufbytes, BS_BUFBYTES-bs_bufbytes);
  381. if( (nread+1) == 0 ) {      /*-- test for -1 = error --*/
  382. bs_trigger = 0;
  383. printf("n FILE_READ_ERRORn");
  384. return 0; }
  385. bs_bufbytes += nread;
  386. bs_bufptr = bs_buffer;
  387. }
  388. return 1;
  389. }
  390. /*------------------------------------------------------------------*/
  391. static int out_mpeg_info( MPEG_HEAD *h, int bitrate_arg)   /* info only */
  392. {
  393. int bitrate;
  394. int samprate;
  395. static char *Layer_msg[] = { "INVALID", "III", "II", "I" };
  396. static char *mode_msg[] = { "STEREO", "JOINT", "DUAL", "MONO" };
  397. static int sr_table[8] =
  398.     { 22050L, 24000L, 16000L, 1L,
  399. 44100L, 48000L, 32000L, 1L };
  400. bitrate = bitrate_arg/1000;
  401. printf("n Layer %s ", Layer_msg[h->option]);
  402. printf("  %s ", mode_msg[h->mode]);
  403. samprate = sr_table[4*h->id + h->sr_index];
  404. if( (h->sync & 1) == 0 ) samprate = samprate/2;  // mpeg25
  405. printf(" %d ", samprate);
  406. printf("  %dKb ", bitrate);
  407. if( (h->mode == 1) && (h->option != 1) )
  408. printf("  %d stereo bands ", 4 + 4*h->mode_ext  );
  409. if( h->prot == 0 ) printf(" (CRC)");
  410. return 0;
  411. }
  412. /*------------------------------------------------------------------*/
  413. static float calc_br_con( MPEG_HEAD *h)   /* info only */
  414. {
  415. float br_con;
  416. int samprate;
  417. static int sr_table[8] =
  418.     { 22050, 24000, 16000L, 1,
  419. 44100, 48000, 32000L, 1 };
  420. samprate = sr_table[4*h->id + h->sr_index];
  421. if( h->option == 1 ) {      // layer III
  422. if( (h->sync & 1) == 0 ) samprate = samprate/2;  // mpeg25
  423. if( h->id == 1 ) {
  424. br_con = (float)(0.001*8.0*samprate/1152.0);
  425. }
  426. else {
  427. br_con = (float)(0.001*8.0*samprate/576.0);
  428. }
  429. }
  430. else if( h->option == 2 ) {      // layer II
  431.         br_con = (float)(0.001*8.0*samprate/1152.0);
  432. }
  433. else if( h->option == 3 ) {      // layer I
  434.         br_con = (float)(0.001*8.0*samprate/384.0);
  435. }
  436. else {
  437.         br_con = (float)(0.001*8.0*samprate/1152.0);
  438. }
  439. return br_con;
  440. }
  441. /*------------------------------------------------------------------*/
  442. int dummy()
  443. {
  444.     return 0;
  445. }
  446. /*------------------------------------------------------------------*/