amr_nb_codec.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:7k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "./amr_nb_codec.h"
  36. #include "amr_frame_hdr.h"
  37. extern "C" {
  38. #include "interf_dec.h"
  39. };
  40. static const UINT32 MaxSamples = 160;
  41. inline
  42. static UINT8 FlipNibble(UINT8 ch)
  43. {
  44.     static const UINT8 z_flipTbl[16] = {
  45. 0x0, 0x8, 0x4, 0xc, 
  46. 0x2, 0xa, 0x6, 0xe,
  47. 0x1, 0x9, 0x5, 0xd, 
  48. 0x3, 0xb, 0x7, 0xf
  49.     };
  50.     return z_flipTbl[ch];
  51. }
  52. static void Convert2IF2(const UINT8* pSrc, UINT8* pDst)
  53. {
  54.     // RFC 3267 Section 5.3 Speech Frame
  55.     //   7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
  56.     // +---+---------------+---+---+---+-------------------------------+----
  57.     // | P |       FT      | Q | P | P |        d(0) - d(7)            | ...
  58.     // +---+---------------+---+---+---+-------------------------------+----
  59.     //
  60.     // P  = padding
  61.     // FT = frame type
  62.     // Q  = quality indicator
  63.     // 3GPP TS 26.101 Annex A IF2 format
  64.     //   7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
  65.     // +---------------+---------------+-------------------------------+----
  66.     // | d(3) - d(0)   |       FT      |       d(11) - d(4)            | ...
  67.     // +---------------+---------------+-------------------------------+----
  68.     //
  69.     // Note : The conversion needs to change the endian-ness of the payload
  70.     //        bits and shift the data by 4 bits
  71.     int frameType = (*pSrc++ >> 3) & 0xf;
  72.     int frameBytes = (CAMRFrameInfo::FrameBits(NarrowBand,frameType) + 7) >> 3;
  73.     UINT8 outCh = (UINT8)frameType;
  74.     if (frameBytes)
  75.     {
  76. for (int i = 0; i < frameBytes; i++)
  77. {
  78.     UINT8 inCh = *pSrc++;
  79.     *pDst++ = outCh | (FlipNibble(inCh >> 4) << 4);
  80.     outCh = FlipNibble(inCh & 0xf);
  81. }
  82.     }
  83.     else
  84. *pDst = outCh;
  85. }
  86. CAMRCodec::CAMRCodec() :
  87.     m_lRefCount(0),
  88.     m_pState(0),
  89.     m_nConcealSamples(0),
  90.     m_pFrameBuf(new UINT8[1 + ((CAMRFrameInfo::MaxFrameBits(NarrowBand) + 7) >> 3)])
  91. {}
  92. CAMRCodec::~CAMRCodec()
  93. {
  94.     if (m_pState)
  95.     {
  96. Decoder_Interface_exit(m_pState);
  97. m_pState = 0;
  98.     }
  99.     
  100.     delete [] m_pFrameBuf;
  101. }
  102. /*
  103.  * IUnknown methods
  104.  */
  105. STDMETHODIMP CAMRCodec::QueryInterface(REFIID riid, void** ppvObj)
  106. {
  107.     HX_RESULT res = HXR_NOINTERFACE;
  108.     *ppvObj = NULL;
  109.     if (IsEqualIID(riid, IID_IUnknown))
  110.     {
  111. AddRef();
  112. *ppvObj = this;
  113. res = HXR_OK;
  114.     }
  115.     else if (IsEqualIID(riid, IID_IHXAudioDecoder))
  116.     {
  117. AddRef();
  118. *ppvObj = (IHXAudioDecoder*)this;
  119. res = HXR_OK;
  120.     }
  121.     return res;
  122. }
  123. STDMETHODIMP_(ULONG32) CAMRCodec::AddRef()
  124. {
  125.     return InterlockedIncrement(&m_lRefCount);
  126. }
  127. STDMETHODIMP_(ULONG32) CAMRCodec::Release()
  128. {
  129.     if (InterlockedDecrement(&m_lRefCount) > 0)
  130.     {
  131.         return m_lRefCount;
  132.     }
  133.     delete this;
  134.     return 0;
  135. }
  136. /*
  137.  * IHXAudioDecoder methods
  138.  */
  139. STDMETHODIMP CAMRCodec::OpenDecoder(UINT32 cfgType, const void* config,
  140.     UINT32 nBytes)
  141. {
  142.     HX_RESULT res = HXR_FAILED;
  143.     if (m_pState)
  144.     {
  145. Decoder_Interface_exit(m_pState);
  146.     }
  147.     
  148.     m_pState = Decoder_Interface_init();
  149.     if (m_pState)
  150. res = HXR_OK;
  151.     return res;
  152. }
  153. STDMETHODIMP CAMRCodec::Reset()
  154. {
  155.     HX_RESULT res = HXR_OK;
  156.     if (m_pState)
  157.     {
  158. Decoder_Interface_exit(m_pState);
  159. m_pState = Decoder_Interface_init();
  160. if (!m_pState)
  161.     res = HXR_FAILED;
  162.     }
  163.     
  164.     m_nConcealSamples = 0;
  165.     return res;
  166. }
  167. STDMETHODIMP CAMRCodec::GetMaxSamplesOut(UINT32& nSamples) CONSTMETHOD
  168. {
  169.     nSamples = MaxSamples;
  170.     return HXR_OK;
  171. }
  172. STDMETHODIMP CAMRCodec::GetNChannels(UINT32& nChannels) CONSTMETHOD
  173. {
  174.     nChannels = 1;
  175.     return HXR_OK;
  176. }
  177. STDMETHODIMP CAMRCodec::GetSampleRate(UINT32& sampleRate) CONSTMETHOD
  178. {
  179.     sampleRate = 8000;
  180.     return HXR_OK;
  181. }
  182. STDMETHODIMP CAMRCodec::GetDelay(UINT32& nSamples) CONSTMETHOD
  183. {
  184.     nSamples = 0;
  185.     return HXR_OK;
  186. }
  187. STDMETHODIMP CAMRCodec::Decode(const UCHAR* data, UINT32 nBytes, 
  188.        UINT32 &nBytesConsumed, INT16 *samplesOut, 
  189.        UINT32& nSamplesOut, BOOL eof)
  190. {
  191.     HX_RESULT res = HXR_UNEXPECTED;
  192.     nSamplesOut = 0;
  193.     nBytesConsumed = 0;
  194.     if (m_pState)
  195.     {
  196. if (m_nConcealSamples)
  197. {     
  198.     // Currently we do not do anything special for concealment
  199.     // so we will just output silence for the concealment
  200.     // samples.
  201.     if (m_nConcealSamples > MaxSamples)
  202. nSamplesOut = MaxSamples;
  203.     else
  204. nSamplesOut = m_nConcealSamples;
  205.     
  206.     res = HXR_OK;
  207.     for (UINT32 i = 0; i < nSamplesOut; i++)
  208. *samplesOut++ = 0;
  209.     m_nConcealSamples -= nSamplesOut;
  210. }
  211. else if (nBytes)
  212. {
  213.     VerifyInput((UCHAR*)data, nBytes, nBytes);
  214.         // Convert the RFC3267 Section 5.3 speech frame
  215.     // format into 3GPP TS 26.101 Annex A IF2 format
  216.     Convert2IF2(data, m_pFrameBuf);
  217.     // Get frame type.
  218.     int frameType = *m_pFrameBuf & 0xf;
  219.     int frameBytes = 
  220. 1 + ((CAMRFrameInfo::FrameBits(NarrowBand, frameType) + 7) >> 3);
  221.     if ((int)nBytes >= frameBytes)
  222.     {
  223. Decoder_Interface_Decode(m_pState, 
  224.  m_pFrameBuf, 
  225.  samplesOut, 0);
  226. nBytesConsumed = frameBytes;
  227. nSamplesOut = MaxSamples;
  228. res = HXR_OK;
  229.     }
  230. }
  231.     }
  232.     
  233.     return res;
  234. }
  235. STDMETHODIMP CAMRCodec::Conceal(UINT32 nSamples)
  236. {
  237.     // We want to conceal only in MaxSamples size blocks.
  238.     UINT32 nFrameCount = (nSamples + MaxSamples - 1) / MaxSamples;
  239.     UINT32 nConcealSamples = nFrameCount * MaxSamples;
  240.     m_nConcealSamples += nConcealSamples;
  241.     return HXR_OK;
  242. }