libmad.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:10k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: libmad.c 543 2006-01-07 22:06:24Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common/common.h"
  24. #include "libmad.h"
  25. #include "libmad/frame.h"
  26. #include "libmad/synth.h"
  27. typedef struct libmad
  28. {
  29. codec Codec;
  30. buffer Buffer;
  31. struct mad_stream Stream;
  32. struct mad_frame Frame;
  33. struct mad_synth Synth;
  34. int BufferAlign;
  35. int AdjustBytes; // adjust (rewind) RefTime
  36. bool_t Skip; // skip next frame
  37. int AdjustTime;
  38. int FormatSet;
  39. } libmad;
  40. static INLINE void UpdateAdjustTime( libmad* p )
  41. {
  42. if (p->Codec.In.Format.ByteRate)
  43. p->AdjustTime = (TICKSPERSEC * 4096) / p->Codec.In.Format.ByteRate;
  44. else
  45. p->AdjustTime = 0;
  46. }
  47. static int UpdateInput( libmad* p )
  48. {
  49. BufferClear(&p->Buffer);
  50. mad_frame_finish(&p->Frame);
  51. mad_stream_finish(&p->Stream);
  52. mad_synth_finish(&p->Synth);
  53. if (p->Codec.In.Format.Type == PACKET_AUDIO)
  54. {
  55. PacketFormatPCM(&p->Codec.Out.Format,&p->Codec.In.Format,MAD_F_FRACBITS+1);
  56. p->Codec.Out.Format.Format.Audio.Flags = PCM_PLANES;
  57. p->FormatSet = 0;
  58. p->AdjustBytes = 0;
  59. UpdateAdjustTime(p);
  60. mad_stream_init(&p->Stream);
  61. mad_frame_init(&p->Frame);
  62. mad_synth_init(&p->Synth);
  63. }
  64. return ERR_NONE;
  65. }
  66. static int Process( libmad* p, const packet* Packet, const flowstate* State )
  67. {
  68. if (Packet)
  69. {
  70. // remove processed bytes from buffer
  71. BufferPack(&p->Buffer,p->Stream.next_frame - p->Stream.buffer);
  72. // set new reftime
  73. if (Packet->RefTime >= 0)
  74. {
  75. p->Codec.Packet.RefTime = Packet->RefTime;
  76. p->AdjustBytes = p->Buffer.WritePos - p->Buffer.ReadPos;
  77. }
  78. // add new packet to buffer
  79. BufferWrite(&p->Buffer,Packet->Data[0],Packet->Length,p->BufferAlign);
  80. mad_stream_buffer(&p->Stream, p->Buffer.Data+p->Buffer.ReadPos, p->Buffer.WritePos-p->Buffer.ReadPos);
  81. }
  82. else
  83. p->Codec.Packet.RefTime = TIME_UNKNOWN;
  84. for (;;)
  85. {
  86. while (mad_frame_decode(&p->Frame, &p->Stream) == -1)
  87. {
  88. if (p->Stream.error == MAD_ERROR_BUFLEN || p->Stream.error == MAD_ERROR_BUFPTR)
  89. return ERR_NEED_MORE_DATA;
  90. if (p->Stream.error == MAD_ERROR_NOMEM)
  91. {
  92. BufferDrop(&p->Buffer);
  93. return ERR_OUT_OF_MEMORY;
  94. }
  95. }
  96. if (p->Skip)
  97. {
  98. // the first frame, it may be corrupt
  99. p->Skip--;
  100. continue;
  101. }
  102. mad_synth_frame(&p->Synth,&p->Frame);
  103. // handle stereo streams with random mono frames (is this really a good mp3?)
  104. if (p->Codec.Out.Format.Format.Audio.Channels==2 && p->Synth.pcm.channels==1)
  105. {
  106. p->Synth.pcm.channels = 2;
  107. memcpy(p->Synth.pcm.samples[1],p->Synth.pcm.samples[0],
  108. p->Synth.pcm.length * sizeof(mad_fixed_t));
  109. }
  110. if (p->Codec.In.Format.ByteRate != (int)(p->Frame.header.bitrate >> 3))
  111. {
  112. p->Codec.In.Format.ByteRate = (p->Frame.header.bitrate >> 3);
  113. UpdateAdjustTime(p);
  114. }
  115. // adjust RefTime with AdjustBytes (now that we know the bitrate)
  116. if (p->Codec.Packet.RefTime >= 0)
  117. p->Codec.Packet.RefTime -= (p->AdjustBytes * p->AdjustTime) >> 12;
  118. // output format setup needed?
  119. if (p->Codec.Out.Format.Format.Audio.SampleRate != (int)p->Synth.pcm.samplerate ||
  120. p->Codec.Out.Format.Format.Audio.Channels != p->Synth.pcm.channels)
  121. {
  122. if (p->FormatSet)
  123. {
  124. p->FormatSet--;
  125. continue; // probably a bad frame, drop it
  126. }
  127. // set new output format
  128. p->Codec.In.Format.Format.Audio.SampleRate = p->Codec.Out.Format.Format.Audio.SampleRate = p->Synth.pcm.samplerate;
  129. p->Codec.In.Format.Format.Audio.Channels = p->Codec.Out.Format.Format.Audio.Channels = p->Synth.pcm.channels;
  130. ConnectionUpdate(&p->Codec.Node,CODEC_OUTPUT,p->Codec.Out.Pin.Node,p->Codec.Out.Pin.No);
  131. }
  132. p->FormatSet = 16; // reset countdown
  133. break;
  134. }
  135. // build output packet
  136. p->Codec.Packet.Length = p->Synth.pcm.length * sizeof(mad_fixed_t);
  137. p->Codec.Packet.Data[0] = p->Synth.pcm.samples[0];
  138. p->Codec.Packet.Data[1] = p->Synth.pcm.samples[1];
  139. return ERR_NONE;
  140. }
  141. static int Flush( libmad* p )
  142. {
  143. BufferDrop(&p->Buffer);
  144. p->Skip = 1;
  145. mad_frame_finish(&p->Frame);
  146. mad_synth_finish(&p->Synth);
  147. mad_stream_finish(&p->Stream);
  148. mad_frame_init(&p->Frame);
  149. mad_synth_init(&p->Synth);
  150. mad_stream_init(&p->Stream);
  151. return ERR_NONE;
  152. }
  153. #ifdef BUILDFIXED
  154. #include <math.h>
  155. extern struct fixedfloat {
  156.   unsigned long mantissa : 27;
  157.   unsigned long exponent :  5;
  158. } rq_table[8207];
  159. #endif
  160. static int Create( libmad* p )
  161. {
  162. p->Codec.Process = (packetprocess)Process;
  163. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  164. p->Codec.Flush = (nodefunc)Flush;
  165. p->BufferAlign = Context()->LowMemory?4096:16384;
  166. return ERR_NONE;
  167. }
  168. #define XING_FRAMES     0x01
  169. #define XING_BYTES 0x02
  170. #define XING_TOC 0x04
  171. #define XING_SCALE 0x08
  172. typedef struct mp3
  173. {
  174. rawaudio RawAudio;
  175. int Frames;
  176. int Bytes;
  177. bool_t TOC;
  178. uint8_t TOCTable[100];
  179. int VBRITableSize;
  180. int VBRIEntryFrames;
  181. int* VBRITable;
  182. } mp3;
  183. static int Read(format_reader* Reader,int n)
  184. {
  185. int v=0;
  186. while (n--)
  187. {
  188. v = v << 8;
  189. v += Reader->Read8(Reader);
  190. }
  191. return v;
  192. }
  193. static int InitMP3(mp3* p)
  194. {
  195. static const int RateTable[4] = { 44100, 48000, 32000, 99999 };
  196. format_reader* Reader;
  197. int i,SampleRate,Id,Mode,Layer,SamplePerFrame;
  198. int Result = RawAudioInit(&p->RawAudio);
  199. p->TOC = 0;
  200. p->Bytes = p->RawAudio.Format.FileSize - p->RawAudio.Head;
  201. p->Frames = 0;
  202. p->RawAudio.VBR = 0;
  203. Reader = p->RawAudio.Format.Reader;
  204. for (i=0;i<2048;++i)
  205. if (Reader->Read8(Reader) == 0xFF)
  206. {
  207. filepos_t Frame;
  208. i = Reader->Read8(Reader);
  209. if ((i & 0xE0) != 0xE0)
  210. continue;
  211. Id = (i >> 3) & 3;
  212. Layer = (i >> 1) & 3;
  213. SampleRate = RateTable[(Reader->Read8(Reader) >> 2) & 3];
  214. if (Id==2)
  215. SampleRate >>= 1; // MPEG2
  216. if (Id==0)
  217. SampleRate >>= 2; // MPEG2.5
  218. Mode = (Reader->Read8(Reader) >> 6) & 3;
  219. SamplePerFrame = (Layer == 3)?384:1152;
  220. Frame = Reader->FilePos;
  221. //Xing offset
  222. if (Id==3)
  223. {
  224. // MPEG1
  225. Reader->Skip(Reader,Mode==3 ? 17:32);
  226. }
  227. else
  228. {
  229. // MPEG2/2.5
  230. Reader->Skip(Reader,Mode==3 ? 9:17);
  231. if (Layer == 1) // layer-3
  232. SamplePerFrame = 576;
  233. }
  234. if (Reader->ReadLE32(Reader) == FOURCCLE('X','i','n','g'))
  235. {
  236. int Flags = Reader->ReadBE32(Reader);
  237. if (Flags & XING_FRAMES) 
  238. p->Frames = Reader->ReadBE32(Reader);
  239. if (Flags & XING_BYTES)
  240. p->Bytes = Reader->ReadBE32(Reader);
  241. if (Flags & XING_TOC)
  242. {
  243. p->TOC = 1;
  244. Reader->Read(Reader,p->TOCTable,100);
  245. }
  246. }
  247. else
  248. {
  249. Reader->Seek(Reader,Frame+32,SEEK_SET);
  250. if (Reader->ReadLE32(Reader) == FOURCCLE('V','B','R','I'))
  251. {
  252. int Scale,EntryBytes;
  253. Reader->Skip(Reader,2+2+2); //Version,Delay,Quality
  254. p->Bytes= Reader->ReadBE32(Reader);
  255. p->Frames = Reader->ReadBE32(Reader);
  256. p->VBRITableSize = Reader->ReadBE16(Reader)+1;
  257. Scale = Reader->ReadBE16(Reader);
  258. EntryBytes = Reader->ReadBE16(Reader);
  259. p->VBRIEntryFrames = Reader->ReadBE16(Reader);
  260. p->VBRITable = malloc(sizeof(int)*p->VBRITableSize);
  261. if (p->VBRITable)
  262. for (i=0;i<p->VBRITableSize;++i)
  263. p->VBRITable[i] = Read(Reader,EntryBytes)*Scale;
  264. }
  265. }
  266. if (p->Frames>0)
  267. {
  268. p->RawAudio.VBR = 1;
  269. p->RawAudio.Format.Duration = Scale(p->Frames,TICKSPERSEC*SamplePerFrame,SampleRate);
  270. if (p->Bytes>0)
  271. p->RawAudio.Format.Streams[0]->Format.ByteRate = Scale(p->Bytes,TICKSPERSEC,p->RawAudio.Format.Duration);
  272. }
  273. break;
  274. }
  275. Reader->Seek(Reader,p->RawAudio.Head,SEEK_SET);
  276. return Result;
  277. }
  278. static void DoneMP3(mp3* p)
  279. {
  280. if (p->VBRITable)
  281. {
  282. free(p->VBRITable);
  283. p->VBRITable = NULL;
  284. }
  285. }
  286. static int SeekMP3(mp3* p, tick_t Time, filepos_t FilePos,bool_t PrevKey)
  287. {
  288. if (FilePos < 0 && Time > 0 && p->RawAudio.Format.Duration > 0)
  289. {
  290. int i,a,b;
  291. if (Time > p->RawAudio.Format.Duration)
  292. Time = p->RawAudio.Format.Duration;
  293. if (p->VBRITable)
  294. {
  295. int i;
  296. tick_t Left;
  297. tick_t EntryTime = p->RawAudio.Format.Duration / p->VBRITableSize;
  298. FilePos = p->RawAudio.Head;
  299. Left = Time;
  300. for (i=0;Left>0 && i<p->VBRITableSize;++i)
  301. {
  302. FilePos += p->VBRITable[i];
  303. Left -= EntryTime;
  304. }
  305. if (i>0)
  306. FilePos += Scale(Left,p->VBRITable[i-1],EntryTime);
  307. }
  308. else
  309. if (p->TOC && p->Bytes>0)
  310. {
  311. i = Scale(Time,100,p->RawAudio.Format.Duration);
  312. if (i>99) i=99;
  313. a = p->TOCTable[i];
  314. if (i==99)
  315. b = 256;
  316. else
  317. b = p->TOCTable[i+1];
  318. a <<= 10;
  319. b <<= 10;
  320. a += Scale(Time - Scale(i,p->RawAudio.Format.Duration,100),b-a,p->RawAudio.Format.Duration);
  321. FilePos = p->RawAudio.Head + Scale(a,p->Bytes,256*1024);
  322. }
  323. }
  324. return RawAudioSeek(&p->RawAudio,Time,FilePos,PrevKey);
  325. }
  326. static int CreateMP3( mp3* p )
  327. {
  328. p->RawAudio.Format.Init = (fmtfunc)InitMP3;
  329. p->RawAudio.Format.Done = (fmtvoid)DoneMP3;
  330. p->RawAudio.Format.Seek = (fmtseek)SeekMP3;
  331. return ERR_NONE;
  332. }
  333. static const nodedef MP3 = 
  334. {
  335. sizeof(mp3),
  336. MP3_ID,
  337. RAWAUDIO_CLASS,
  338. PRI_DEFAULT-5,
  339. (nodecreate)CreateMP3,
  340. };
  341. static const nodedef LibMad = 
  342. {
  343. sizeof(libmad),
  344. LIBMAD_ID,
  345. CODEC_CLASS,
  346. PRI_DEFAULT-5,
  347. (nodecreate)Create,
  348. };
  349. void LibMad_Init()
  350. {
  351. #ifdef BUILDFIXED
  352. int x;
  353. struct fixedfloat* p=rq_table;
  354. for (x=0;x<8207;++x,++p)
  355. {
  356. int exp;
  357. double v = frexp(pow(x,4./3.),&exp);
  358. if (exp) ++exp;
  359. p->exponent = (unsigned short)exp;
  360. p->mantissa = (int)(0x10000000 * (v*0.5));
  361. }
  362. #endif
  363. NodeRegisterClass(&LibMad);
  364. NodeRegisterClass(&MP3);
  365. }
  366. void LibMad_Done()
  367. {
  368. NodeUnRegisterClass(LIBMAD_ID);
  369. NodeUnRegisterClass(MP3_ID);
  370. }