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

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: amrnb.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 "amrnb.h"
  25. #include "26104/interf_dec.h"
  26. #include "26104/sp_dec.h"
  27. #include "26104/typedef.h"
  28. typedef struct amrnb
  29. {
  30. codec Codec;
  31. buffer Buffer;
  32. void* Decoder;
  33. int16_t Synth[160];
  34. } amrnb;
  35. static int UpdateInput(amrnb* p)
  36. {
  37. if (p->Decoder)
  38. {
  39. Decoder_Interface_exit(p->Decoder);
  40. p->Decoder = NULL;
  41. }
  42. BufferClear(&p->Buffer);
  43. if (p->Codec.In.Format.Type == PACKET_AUDIO)
  44. {
  45.     p->Decoder = Decoder_Interface_init();
  46. if (!p->Decoder)
  47. return ERR_OUT_OF_MEMORY;
  48. p->Codec.In.Format.Format.Audio.SampleRate = 8000;
  49. p->Codec.In.Format.Format.Audio.Channels = 1;
  50. PacketFormatPCM(&p->Codec.Out.Format,&p->Codec.In.Format,16);
  51. }
  52. return ERR_NONE;
  53. }
  54. static int Process(amrnb* p, const packet* Packet, const flowstate* State)
  55. {
  56. static const uint8_t PackedSize[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
  57. int Size;
  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,256);
  65. }
  66. else
  67. p->Codec.Packet.RefTime = TIME_UNKNOWN;
  68. if (p->Buffer.WritePos - p->Buffer.ReadPos < 1)
  69. return ERR_NEED_MORE_DATA;
  70. if (p->Buffer.Data[p->Buffer.ReadPos] == '#' &&
  71. p->Buffer.WritePos - p->Buffer.ReadPos > 6 &&
  72. memcmp(p->Buffer.Data+p->Buffer.ReadPos,"#!AMRn",6)==0)
  73. p->Buffer.ReadPos += 6;
  74. Size = PackedSize[(p->Buffer.Data[p->Buffer.ReadPos] >> 3) & 0xF]+1;
  75. if (p->Buffer.WritePos - p->Buffer.ReadPos < Size)
  76. return ERR_NEED_MORE_DATA;
  77.     Decoder_Interface_Decode(p->Decoder, p->Buffer.Data+p->Buffer.ReadPos, p->Synth, 0);
  78. p->Buffer.ReadPos += Size;
  79. p->Codec.Packet.Length = sizeof(p->Synth);
  80. p->Codec.Packet.Data[0] = p->Synth;
  81. return ERR_NONE;
  82. }
  83. extern void Decoder_Interface_reset(void*);
  84. static int Flush(amrnb* p)
  85. {
  86. if (p->Decoder)
  87. Decoder_Interface_reset(p->Decoder);
  88. return ERR_NONE;
  89. }
  90. static int Create(amrnb* p)
  91. {
  92. p->Codec.Process = (packetprocess)Process;
  93. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  94. p->Codec.Flush = (nodefunc)Flush;
  95. return ERR_NONE;
  96. }
  97. static const nodedef AMRNB =
  98. {
  99. sizeof(amrnb),
  100. AMRNB_ID,
  101. CODEC_CLASS,
  102. PRI_DEFAULT,
  103. (nodecreate)Create,
  104. NULL,
  105. };
  106. static const nodedef AMRNBFile = 
  107. {
  108. 0, //parent size
  109. AMRNB_FILE_ID,
  110. RAWAUDIO_CLASS,
  111. PRI_DEFAULT-5,
  112. };
  113. void AMRNB_Init()
  114. {
  115. NodeRegisterClass(&AMRNB);
  116. NodeRegisterClass(&AMRNBFile);
  117. }
  118. void AMRNB_Done()
  119. {
  120. NodeUnRegisterClass(AMRNB_ID);
  121. NodeUnRegisterClass(AMRNB_FILE_ID);
  122. }