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

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: ac3.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 "ac3.h"
  25. #include "liba52/a52.h"
  26. typedef struct a52
  27. {
  28. codec Codec;
  29. buffer Buffer;
  30. a52_state_t* State;
  31. sample_t* Samples;
  32. int FrameSize;
  33. int SubFrame;
  34. } a52;
  35. static int UpdateInput(a52* p)
  36. {
  37. if (p->State)
  38. {
  39.     a52_free(p->State);
  40. p->State = NULL;
  41. }
  42. BufferClear(&p->Buffer);
  43. if (p->Codec.In.Format.Type == PACKET_AUDIO)
  44. {
  45. PacketFormatPCM(&p->Codec.Out.Format,&p->Codec.In.Format,30);
  46. p->Codec.Out.Format.Format.Audio.Flags = PCM_PLANES;
  47. if (p->Codec.Out.Format.Format.Audio.Channels>0)
  48. p->Codec.Out.Format.Format.Audio.Channels = 2;
  49. p->SubFrame = 6;
  50. p->FrameSize = 0;
  51. p->State = a52_init(0);
  52. p->Samples = a52_samples(p->State);
  53. }
  54. return ERR_NONE;
  55. }
  56. static int Process(a52* p, const packet* Packet, const flowstate* State)
  57. {
  58. if (Packet)
  59. {
  60. if (Packet->RefTime >= 0)
  61. p->Codec.Packet.RefTime = Packet->RefTime;
  62. // add new packet to buffer
  63. BufferPack(&p->Buffer,0);
  64. BufferWrite(&p->Buffer,Packet->Data[0],Packet->Length,2048);
  65. }
  66. else
  67. p->Codec.Packet.RefTime = TIME_UNKNOWN;
  68. for (;;)
  69. {
  70. if (p->SubFrame >= 6)
  71. {
  72. static const int Channels[16] = { 2, 1, 2, 3, 3, 4, 4, 5, 1, 1, 2 };
  73. int Flags;
  74. int SampleRate;
  75. int BitRate;
  76. level_t Level;
  77. // find valid frame header
  78. while (!p->FrameSize)
  79. {
  80. if (p->Buffer.WritePos-p->Buffer.ReadPos < 8)
  81. return ERR_NEED_MORE_DATA;
  82.                 p->FrameSize = a52_syncinfo(p->Buffer.Data+p->Buffer.ReadPos,&Flags,&SampleRate,&BitRate);
  83. if (p->FrameSize)
  84. {
  85. p->Codec.In.Format.ByteRate = BitRate/8;
  86. p->Codec.In.Format.Format.Audio.SampleRate = SampleRate;
  87.                     p->Codec.In.Format.Format.Audio.Channels = Channels[Flags & A52_CHANNEL_MASK];
  88.                     if (Flags & A52_LFE)
  89. p->Codec.In.Format.Format.Audio.Channels++;
  90. if (p->Codec.Out.Format.Format.Audio.SampleRate != SampleRate ||
  91. p->Codec.Out.Format.Format.Audio.Channels != 2)
  92. {
  93. p->Codec.Out.Format.Format.Audio.Channels = 2;
  94. p->Codec.Out.Format.Format.Audio.SampleRate = SampleRate;
  95. ConnectionUpdate(&p->Codec.Node,CODEC_OUTPUT,p->Codec.Out.Pin.Node,p->Codec.Out.Pin.No);
  96. }
  97. break;
  98. }
  99. p->Buffer.ReadPos++;
  100. }
  101. if (p->Buffer.WritePos-p->Buffer.ReadPos < p->FrameSize)
  102. return ERR_NEED_MORE_DATA;
  103.             Flags = A52_STEREO;
  104.             Level = 1<<26;
  105.             if (!a52_frame(p->State, p->Buffer.Data+p->Buffer.ReadPos, &Flags, &Level, 384)) 
  106. {
  107. // valid frame
  108. p->SubFrame = 0;
  109. p->Buffer.ReadPos += p->FrameSize;
  110. }
  111. p->FrameSize = 0;
  112. }
  113. else
  114. {
  115. if (!a52_block(p->State))
  116. break;
  117. p->SubFrame = 6; // skip to next frame
  118. }
  119. }
  120. p->Codec.Packet.Length = 256 * sizeof(sample_t);
  121. p->Codec.Packet.Data[0] = p->Samples;
  122. p->Codec.Packet.Data[1] = p->Samples+256;
  123. p->SubFrame++;
  124. return ERR_NONE;
  125. }
  126. static int Flush(a52* p)
  127. {
  128. p->FrameSize = 0;
  129. p->SubFrame = 6;
  130. return ERR_NONE;
  131. }
  132. static int Create(a52* p)
  133. {
  134. p->Codec.Process = (packetprocess)Process;
  135. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  136. p->Codec.Flush = (nodefunc)Flush;
  137. return ERR_NONE;
  138. }
  139. static const nodedef A52 =
  140. {
  141. sizeof(a52),
  142. A52_ID,
  143. CODEC_CLASS,
  144. PRI_DEFAULT,
  145. (nodecreate)Create,
  146. NULL,
  147. };
  148. static const nodedef AC3 = 
  149. {
  150. 0, //parent size
  151. AC3_ID,
  152. RAWAUDIO_CLASS,
  153. PRI_DEFAULT-5,
  154. };
  155. void AC3_Init()
  156. {
  157. NodeRegisterClass(&A52);
  158. NodeRegisterClass(&AC3);
  159. }
  160. void AC3_Done()
  161. {
  162. NodeUnRegisterClass(AC3_ID);
  163. NodeUnRegisterClass(A52_ID);
  164. }