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

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: mpc.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.  
  24. #include "../common/common.h"
  25. #include "mpc.h"
  26. #include "libmusepack/include/musepack/musepack.h"
  27. typedef struct mpc 
  28. {
  29. format_base Format;
  30. mpc_reader Reader;
  31. mpc_decoder Decoder;
  32. mpc_streaminfo Info;
  33. MPC_SAMPLE_FORMAT* Buffer;
  34. int SampleRate;
  35. int SampleSize;
  36. int64_t Samples;
  37. mpc_uint16_t* SeekTable;
  38. } mpc;
  39. static void Done(mpc* p)
  40. {
  41. free(p->SeekTable);
  42. p->SeekTable = NULL;
  43. free(p->Buffer);
  44. p->Buffer = NULL;
  45. }
  46. static int Init(mpc* p)
  47. {
  48. format_stream* s;
  49. p->Format.HeaderLoaded = 1;
  50. p->Format.TimeStamps = 0;
  51. mpc_streaminfo_init(&p->Info);
  52. p->Samples = 0;
  53. p->Buffer = (MPC_SAMPLE_FORMAT*)malloc(sizeof(MPC_SAMPLE_FORMAT)*MPC_DECODER_BUFFER_LENGTH);
  54. if (!p->Buffer)
  55. return ERR_OUT_OF_MEMORY;
  56. if (mpc_streaminfo_read(&p->Info,&p->Reader) != ERROR_CODE_OK)
  57. return ERR_INVALID_DATA;
  58. s = Format_AddStream(&p->Format,sizeof(format_stream));
  59. if (s)
  60. {
  61. PacketFormatClear(&s->Format);
  62. s->Format.Type = PACKET_AUDIO;
  63. s->Format.Format.Audio.Format = AUDIOFMT_PCM;
  64. s->Format.Format.Audio.Bits = MPC_FIXED_POINT_SCALE_SHIFT;
  65. s->Format.Format.Audio.SampleRate = p->Info.sample_freq;
  66. s->Format.Format.Audio.Channels = p->Info.channels;
  67. PacketFormatDefault(&s->Format);
  68. s->Format.ByteRate = (int)p->Info.average_bitrate >> 3;
  69. s->PacketBurst = 1;
  70. s->Fragmented = 1;
  71. s->DisableDrop = 1;
  72. p->Format.Duration = (tick_t)((p->Info.pcm_samples * TICKSPERSEC) / p->Info.sample_freq);
  73. Format_PrepairStream(&p->Format,s);
  74. if (p->Format.Comment.Node)
  75. {
  76. // id3v1
  77. format_reader* Reader = p->Format.Reader;
  78. char Buffer[ID3V1_SIZE];
  79. filepos_t Save = Reader->Input->Seek(Reader->Input,0,SEEK_CUR);
  80. if (Save>=0 && Reader->Input->Seek(Reader->Input,-(int)sizeof(Buffer),SEEK_END)>=0)
  81. {
  82. if (Reader->Input->Read(Reader->Input,Buffer,sizeof(Buffer)) == sizeof(Buffer))
  83. ID3v1_Parse(Buffer,&p->Format.Comment);
  84. Reader->Input->Seek(Reader->Input,Save,SEEK_SET);
  85. }
  86. if (p->Info.header_position>0)
  87. {
  88. // id3v2
  89. filepos_t Save = Reader->FilePos;
  90. if (Reader->Seek(Reader,0,SEEK_SET)==ERR_NONE)
  91. {
  92. void* Buffer = malloc(p->Info.header_position);
  93. if (Buffer)
  94. {
  95. int Len = Reader->Read(Reader,Buffer,p->Info.header_position);
  96. ID3v2_Parse(Buffer,Len,&p->Format.Comment,0);
  97. free(Buffer);
  98. }
  99. Reader->Seek(Reader,Save,SEEK_SET);
  100. }
  101. }
  102. }
  103. }
  104. mpc_decoder_setup(&p->Decoder,&p->Reader);
  105. p->SeekTable = (mpc_uint16_t*)malloc(sizeof(mpc_uint16_t)*(p->Info.frames+64));
  106. if (p->SeekTable)
  107. {
  108. memset(p->SeekTable,0,sizeof(mpc_uint16_t)*(p->Info.frames+64));
  109. p->Decoder.SeekTable = p->SeekTable;
  110. }
  111.     if (!mpc_decoder_initialize(&p->Decoder, &p->Info)) 
  112. return ERR_INVALID_DATA;
  113. p->SampleRate = p->Info.sample_freq;
  114. p->SampleSize = p->Info.channels * sizeof(MPC_SAMPLE_FORMAT);
  115. return ERR_NONE;
  116. }
  117. static int Seek(mpc* p, tick_t Time, int FilePos, bool_t PrevKey)
  118. {
  119. int64_t Samples;
  120. if (Time < 0)
  121. {
  122. if (FilePos<0 || p->Format.FileSize<0)
  123. return ERR_NOT_SUPPORTED;
  124. Time = Scale(FilePos,p->Format.Duration,p->Format.FileSize);
  125. }
  126. Samples = ((int64_t)Time * p->SampleRate+(TICKSPERSEC/2)) / TICKSPERSEC;
  127. if (!mpc_decoder_seek_sample(&p->Decoder,Samples))
  128. return ERR_NOT_SUPPORTED;
  129. p->Samples = Samples;
  130. return ERR_NONE;
  131. }
  132. static int Process(mpc* p,format_stream* Stream)
  133. {
  134. int Result = ERR_NONE;
  135. int Samples,No,Burst;
  136. if (Stream->Pending)
  137. {
  138. Result = Format_Send(&p->Format,Stream);
  139. if (Result == ERR_BUFFER_FULL || Result == ERR_SYNCED)
  140. return Result;
  141. }
  142. Burst = Stream->PacketBurst;
  143. for (No=0;No<Burst;++No)
  144. {
  145. if (p->Format.Reader[0].BufferAvailable < (MINBUFFER/2) && 
  146. !p->Format.Reader[0].NoMoreInput)
  147. return ERR_NEED_MORE_DATA;
  148. Samples = mpc_decoder_decode(&p->Decoder,p->Buffer,NULL,NULL);
  149. if (Samples == -1)
  150. return ERR_INVALID_DATA;
  151. if (Samples == 0)
  152. return Format_CheckEof(&p->Format,Stream);
  153. Stream->Packet.RefTime = (tick_t)((p->Samples * TICKSPERSEC) / p->SampleRate);
  154. Stream->Packet.Data[0] = p->Buffer;
  155. Stream->Packet.Length = Samples * p->SampleSize;
  156. Stream->Pending = 1;
  157. p->Samples += Samples;
  158. Result = Format_Send(&p->Format,Stream);
  159. if (Result == ERR_BUFFER_FULL || Result == ERR_SYNCED)
  160. break;
  161. }
  162. if (Result == ERR_BUFFER_FULL || Result == ERR_NEED_MORE_DATA)
  163. Result = ERR_NONE;
  164. return Result;
  165. }
  166. static mpc_int32_t IORead(void *data, void *ptr, mpc_int32_t size)
  167. {
  168. format_reader* Reader = (format_reader*)data;
  169. return Reader->Read(Reader,ptr,size);
  170. }
  171. static mpc_bool_t IOSeek(void *data, mpc_int32_t offset)
  172. {
  173. format_reader* Reader = (format_reader*)data;
  174. return (mpc_bool_t)(Format_Seek(Reader->Format,(filepos_t)offset,SEEK_SET) == ERR_NONE);
  175. }
  176. static mpc_int32_t IOTell(void *data)
  177. {
  178. format_reader* Reader = (format_reader*)data;
  179.     return Reader->FilePos;
  180. }
  181. static mpc_int32_t IOGetSize(void *data)
  182. {
  183. format_reader* Reader = (format_reader*)data;
  184. if (Reader->Format->FileSize < 0)
  185. return 0;
  186. return Reader->Format->FileSize;
  187. }
  188. static mpc_bool_t IOCanSeek(void *data)
  189. {
  190.     return 1;
  191. }
  192. static int Create(mpc* p)
  193. {
  194. p->Format.Init = (fmtfunc) Init;
  195. p->Format.Done = (fmtvoid) Done;
  196. p->Format.Seek = (fmtseek) Seek;
  197. p->Format.Process = (fmtstreamprocess) Process;
  198. p->Format.FillQueue = NULL;
  199. p->Format.ReadPacket = NULL;
  200. p->Format.Sended = NULL;
  201. p->Reader.data = p->Format.Reader;
  202.     p->Reader.read = IORead;
  203. p->Reader.seek = IOSeek;
  204. p->Reader.tell = IOTell;
  205. p->Reader.get_size = IOGetSize;
  206. p->Reader.canseek = IOCanSeek;
  207. return ERR_NONE;
  208. }
  209. static const nodedef MPC =
  210. {
  211. sizeof(mpc),
  212. MPC_ID,
  213. FORMATBASE_CLASS,
  214. PRI_DEFAULT,
  215. (nodecreate)Create,
  216. };
  217. void MPC_Init()
  218. {
  219. NodeRegisterClass(&MPC);
  220. }
  221. void MPC_Done()
  222. {
  223. NodeUnRegisterClass(MPC_ID);
  224. }