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

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 <windows.h>
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include "mhead.h"     /* mpeg header structure, decode protos */
  38. #include "mpadecobjfltpt.h"
  39. #ifdef _WIN32
  40. #include <conio.h>
  41. #endif
  42. #define BS_BUFBYTES 60000U
  43. #define PCM_BUFBYTES 60000U
  44. typedef struct _FileInfo {
  45. char *infileName;
  46. char *outfileName;
  47. } FileInfo;
  48. typedef struct _BitStream {
  49. unsigned char *buffer;
  50. unsigned char *bufptr;
  51. int trigger;      
  52. int bufbytes;
  53. } BitStream;
  54. typedef struct _PCM {
  55. unsigned char *buffer;
  56. unsigned int bufbytes;
  57. unsigned int trigger;
  58. } PCM;
  59. static int print_mpeg_info( MPEG_HEAD *h, int bitrate_arg)   /* info only */
  60. {
  61. int bitrate;
  62. int samprate;
  63. static char *Layer_msg[] = { "INVALID", "III", "II", "I" };
  64. static char *mode_msg[] = { "STEREO", "JOINT", "DUAL", "MONO" };
  65. static int sr_table[8] =
  66.     { 22050L, 24000L, 16000L, 1L,
  67. 44100L, 48000L, 32000L, 1L };
  68. bitrate = bitrate_arg/1000;
  69. printf("n Layer %s ", Layer_msg[h->option]);
  70. printf("  %s ", mode_msg[h->mode]);
  71. samprate = sr_table[4*h->id + h->sr_index];
  72. if( (h->sync & 1) == 0 ) 
  73. samprate = samprate/2;  // mpeg25
  74. printf(" %d ", samprate);
  75. printf("  %dKb ", bitrate);
  76. if( (h->mode == 1) && (h->option != 1) )
  77. printf("  %d stereo bands ", 4 + 4*h->mode_ext  );
  78. if( h->prot == 0 ) 
  79. printf(" (CRC)");
  80. return 0;
  81. }
  82. static int bs_fill(FILE *infile, BitStream *bs)
  83. {
  84. int nread;
  85. if( bs->bufbytes < 0 ) 
  86. bs->bufbytes = 0;  // signed var could be negative
  87. if( bs->bufbytes < bs->trigger ) {
  88. memmove(bs->buffer, bs->bufptr, bs->bufbytes);
  89. nread = fread(bs->buffer + bs->bufbytes, 1, BS_BUFBYTES - bs->bufbytes, infile);
  90. if(nread == -1) {      /*-- test for -1 = error --*/
  91. bs->trigger = 0;
  92. printf("n FILE_READ_ERRORn");
  93. return 0; 
  94. }
  95. bs->bufbytes += nread;
  96. bs->bufptr = bs->buffer;
  97. }
  98. return 1;
  99. }
  100. int WINAPI DecodeMP3File(LPVOID lpParam)
  101. {
  102. int bitrate, framebytes, nFrames, sampleCount;
  103. int in_bytes, out_bytes, writeFlag;
  104. FileInfo *fileInfo;
  105. FILE *infile, *outfile;
  106. unsigned int nwrite;
  107. unsigned long temp, inBytes, pcmBytes;
  108. MPEG_HEAD head;
  109. IN_OUT x;
  110. DEC_INFO decinfo;
  111. CMpaDecObj decobj;
  112. BitStream bs;
  113. PCM pcm;
  114. in_bytes = 0;
  115. out_bytes = 0;
  116. pcm.bufbytes = 0;
  117. pcm.trigger = (PCM_BUFBYTES - 2500*sizeof(short));
  118. /* open files */
  119. fileInfo = (FileInfo *)lpParam;
  120. infile = fopen(fileInfo->infileName, "rb");
  121. if (!infile)
  122. return -1;
  123. writeFlag = 0;
  124. if (strcmp(fileInfo->outfileName, "nul")) {
  125. writeFlag = 1;
  126. outfile = fopen(fileInfo->outfileName, "wb");
  127. if (!outfile)
  128. return -1;
  129. }
  130. /* allocate buffers */
  131. bs.buffer = new unsigned char [BS_BUFBYTES];
  132. pcm.buffer = new unsigned char [PCM_BUFBYTES];
  133. if (!bs.buffer || !pcm.buffer) {
  134. if (bs.buffer)
  135. delete [] bs.buffer;
  136. if (pcm.buffer)
  137. delete [] pcm.buffer;
  138. return -1;
  139. }
  140. /* fill bs buffer */
  141. bs.bufbytes = 0;
  142. bs.bufptr   = bs.buffer;
  143. bs.trigger  =  2500;
  144. bs_fill(infile, &bs);
  145. /* parse mpeg header */
  146. framebytes = head_info2(bs.buffer, bs.bufbytes, &head, &bitrate, 0);
  147. if (framebytes == 0) {
  148. printf("header parsing errorn");
  149. delete [] bs.buffer;
  150. delete [] pcm.buffer;
  151.     }
  152. print_mpeg_info(&head, bitrate);
  153. decobj.Init_n(bs.buffer, bs.bufbytes);
  154. /*---- get info -------*/
  155. decobj.GetPCMInfo_v(temp, decinfo.channels, decinfo.bits);
  156. decinfo.samprate = temp;
  157. decinfo.type = 0;
  158. //printf(" output: samprate = %d, channels = %d, bits = %d, type = %dn", 
  159. // decinfo.samprate, decinfo.channels, decinfo.bits, decinfo.type);
  160. /*----- DECODE -----*/
  161. nFrames = 0;
  162. sampleCount = 0;
  163. while (1) {
  164. /* check for EOF */
  165. if(!bs_fill(infile, &bs) || bs.bufbytes < framebytes) 
  166. break;
  167. inBytes = bs.bufbytes;
  168. pcmBytes = PCM_BUFBYTES - pcm.bufbytes;
  169. /* you can uncomment this to see which file is being decoded, and watch the threads take turns */
  170. /* printf("decoding %sn", fileInfo->infileName); */
  171. decobj.DecodeFrame_v(bs.bufptr, &inBytes, pcm.buffer + pcm.bufbytes, &pcmBytes);
  172. x.in_bytes = inBytes;
  173. x.out_bytes = pcmBytes;
  174. if( x.in_bytes <= 0 ) {
  175. printf("n BAD SYNC IN MPEG FILEn");
  176. break;
  177. }
  178. bs.bufptr += x.in_bytes;
  179. bs.bufbytes -= x.in_bytes;
  180. pcm.bufbytes += x.out_bytes;
  181. sampleCount += (x.out_bytes / sizeof(short));
  182. if( pcm.bufbytes > pcm.trigger ) {
  183. if (writeFlag) {
  184. nwrite = fwrite(pcm.buffer, 1, pcm.bufbytes, outfile);
  185. if( nwrite != pcm.bufbytes  ) {
  186. printf("n FILE WRITE ERRORn");
  187. break;
  188. }
  189. }
  190. out_bytes += pcm.bufbytes;
  191. pcm.bufbytes = 0;
  192. }
  193. #ifdef _WIN32
  194. if( kbhit() ) 
  195. break;
  196. #endif
  197. nFrames++;
  198. in_bytes += x.in_bytes;
  199. }
  200. if( writeFlag && pcm.bufbytes > 0 ) {
  201. if (writeFlag) {
  202. nwrite = fwrite(pcm.buffer, 1, pcm.bufbytes, outfile);
  203. if( nwrite != pcm.bufbytes  ) {
  204. printf("n FILE WRITE ERRORn");
  205. }
  206. }
  207. out_bytes += pcm.bufbytes;
  208. pcm.bufbytes = 0;
  209. }
  210. /* cleanup */
  211. fclose(infile);
  212. if (writeFlag)
  213. fclose(outfile);
  214. delete [] bs.buffer;
  215. delete [] pcm.buffer;
  216. #ifdef _WIN32
  217. while(kbhit()) 
  218. getch();  /* purge key board */
  219. #endif
  220. printf("n");
  221. return 0;
  222. }
  223. void Usage(void)
  224. {
  225. printf("Usage: towave infile1.mp3 outfile1.pcm [infile2.mp3 outfile2.pcm]n");
  226. exit(-1);
  227. }
  228. int main(int argc,char *argv[])
  229. {
  230. HANDLE hDecThread1, hDecThread2;
  231. DWORD  decThreadID1, decThreadID2;
  232. DWORD exitCode1, exitCode2;
  233. FileInfo fileInfo1, fileInfo2;
  234. if (argc != 3 && argc != 5)
  235. Usage();
  236. if (argc == 3 || argc == 5) {
  237. fileInfo1.infileName = argv[1];
  238. fileInfo1.outfileName = argv[2];
  239. hDecThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DecodeMP3File, (LPVOID)&fileInfo1, 0, &decThreadID1 );
  240. if (hDecThread1)
  241. printf("Started decoder thread 1: infile = %16s    outfile = %16sn", fileInfo1.infileName, fileInfo1.outfileName);
  242. else 
  243. printf("error creating decoder thread 1n");
  244. if (argc == 5) {
  245. fileInfo2.infileName = argv[3];
  246. fileInfo2.outfileName = argv[4];
  247. hDecThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DecodeMP3File, (LPVOID)&fileInfo2, 0, &decThreadID2 );
  248. if (hDecThread2)
  249. printf("Started decoder thread 2: infile = %16s    outfile = %16sn", fileInfo2.infileName, fileInfo2.outfileName);
  250. else 
  251. printf("error creating decoder thread 2n");
  252. }
  253. exitCode1 = exitCode2 = 0;
  254. do {
  255. if (hDecThread1)
  256. GetExitCodeThread(hDecThread1, &exitCode1);
  257. if (hDecThread2)
  258. GetExitCodeThread(hDecThread2, &exitCode2);
  259. } while (exitCode1 == STILL_ACTIVE || exitCode2 == STILL_ACTIVE);
  260. if (hDecThread1)
  261. CloseHandle(hDecThread1);
  262. if (hDecThread2)
  263. CloseHandle(hDecThread2);
  264. return 0;
  265. }