law.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: law.c 339 2005-11-15 11:22:45Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common/common.h"
  24. #include "law.h"
  25. typedef struct law
  26. {
  27. codec Codec;
  28. buffer Buffer;
  29. int16_t Table[256];
  30. } law;
  31. static int UpdateInput(law* p)
  32. {
  33. BufferClear(&p->Buffer);
  34. if (p->Codec.In.Format.Type == PACKET_AUDIO)
  35. PacketFormatPCM(&p->Codec.Out.Format,&p->Codec.In.Format,16);
  36. return ERR_NONE;
  37. }
  38. static int Process(law* p, const packet* Packet, const flowstate* State)
  39. {
  40. if (!Packet)
  41. return ERR_NEED_MORE_DATA;
  42. BufferDrop(&p->Buffer);
  43. if (!BufferWrite(&p->Buffer,NULL,Packet->Length*2,1024))
  44. return ERR_OUT_OF_MEMORY;
  45. p->Codec.Packet.RefTime = Packet->RefTime;
  46. p->Codec.Packet.Length = p->Buffer.WritePos;
  47. p->Codec.Packet.Data[0] = p->Buffer.Data;
  48. {
  49. uint8_t* s = (uint8_t*)Packet->Data[0];
  50. uint8_t* se = s + Packet->Length;
  51. int16_t* d = (int16_t*)p->Buffer.Data;
  52. for (;s!=se;++s,++d)
  53. *d = p->Table[*s];
  54. }
  55. return ERR_NONE;
  56. }
  57. /* from g711.c by SUN microsystems (unrestricted use) */
  58. #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
  59. #define QUANT_MASK (0xf) /* Quantization field mask. */
  60. #define NSEGS (8) /* Number of A-law segments. */
  61. #define SEG_SHIFT (4) /* Left shift for segment number. */
  62. #define SEG_MASK (0x70) /* Segment field mask. */
  63. #define BIAS (0x84) /* Bias for linear code. */
  64. /*
  65.  * alaw2linear() - Convert an A-law value to 16-bit linear PCM
  66.  *
  67.  */
  68. static INLINE int alaw2linear(int a_val)
  69. {
  70. int t;
  71. int seg;
  72. a_val ^= 0x55;
  73. t = (a_val & QUANT_MASK) << 4;
  74. seg = (a_val & SEG_MASK) >> SEG_SHIFT;
  75. switch (seg) {
  76. case 0:
  77. t += 8;
  78. break;
  79. case 1:
  80. t += 0x108;
  81. break;
  82. default:
  83. t += 0x108;
  84. t <<= seg - 1;
  85. }
  86. return ((a_val & SIGN_BIT) ? t : -t);
  87. }
  88. static INLINE int ulaw2linear(int u_val)
  89. {
  90. int t;
  91. /* Complement to obtain normal u-law value. */
  92. u_val ^= 0xFF;
  93. /*
  94.  * Extract and bias the quantization bits. Then
  95.  * shift up by the segment number and subtract out the bias.
  96.  */
  97. t = ((u_val & QUANT_MASK) << 3) + BIAS;
  98. t <<= (u_val & SEG_MASK) >> SEG_SHIFT;
  99. return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
  100. }
  101. static int CreateLaw(law* p)
  102. {
  103. p->Codec.Process = (packetprocess)Process;
  104. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  105. return ERR_NONE;
  106. }
  107. static int CreateALaw(law* p)
  108. {
  109. int n;
  110. for (n=0;n<256;++n)
  111. p->Table[n] = (int16_t)alaw2linear(n);
  112. return ERR_NONE;
  113. }
  114. static int CreateMuLaw(law* p)
  115. {
  116. int n;
  117. for (n=0;n<256;++n)
  118. p->Table[n] = (int16_t)ulaw2linear(n);
  119. return ERR_NONE;
  120. }
  121. static const nodedef Law =
  122. {
  123. sizeof(law)|CF_ABSTRACT,
  124. LAW_CLASS,
  125. CODEC_CLASS,
  126. PRI_DEFAULT,
  127. (nodecreate)CreateLaw,
  128. NULL,
  129. };
  130. static const nodedef ALaw =
  131. {
  132. 0, //parent size
  133. ALAW_ID,
  134. LAW_CLASS,
  135. PRI_DEFAULT,
  136. (nodecreate)CreateALaw,
  137. NULL,
  138. };
  139. static const nodedef MuLaw =
  140. {
  141. 0, //parent size
  142. MULAW_MS_ID,
  143. LAW_CLASS,
  144. PRI_DEFAULT,
  145. (nodecreate)CreateMuLaw,
  146. NULL,
  147. };
  148. void Law_Init()
  149. {
  150. NodeRegisterClass(&Law);
  151. NodeRegisterClass(&ALaw);
  152. NodeRegisterClass(&MuLaw);
  153. }
  154. void Law_Done()
  155. {
  156. NodeUnRegisterClass(LAW_CLASS);
  157. NodeUnRegisterClass(ALAW_ID);
  158. NodeUnRegisterClass(MULAW_MS_ID);
  159. }