amr_wb_codec.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:7k
源码类别:

Symbian

开发平台:

C/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_wb_codec.h"
  36. #include "amr_frame_hdr.h"
  37. extern "C" {
  38. #include "dec_if.h"
  39. };
  40. static const UINT32 MaxSamples = 320;
  41. static void Convert2IF2(AMRFlavor flavor, const UINT8* pSrc, UINT8* pDst)
  42. {
  43.     // RFC 3267 Section 5.3 Speech Frame
  44.     //   7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
  45.     // +---+---------------+---+---+---+-------------------------------+----
  46.     // | P |       FT      | Q | P | P |        d(0) - d(7)            | ...
  47.     // +---+---------------+---+---+---+-------------------------------+----
  48.     //
  49.     // P  = padding
  50.     // FT = frame type
  51.     // Q  = quality indicator
  52.     // 3GPP TS 26.201 Annex A IF2 format
  53.     //   7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
  54.     // +---------------+---------------+-------------------------------+----
  55.     // |       FT      | Q | d(0)-d(2) |           d(3)-d(10)          | ...
  56.     // +---------------+---------------+-------------------------------+----
  57.     //
  58.     // Note : The conversion needs to shift
  59.     int frameType = (pSrc[0] >> 3) & 0xf;
  60.     int frameBytes = (CAMRFrameInfo::FrameBits(flavor, frameType) + 7) >> 3;
  61.     if (frameBytes)
  62.     {
  63. // Copy header info and d(0) - d(2)
  64. *pDst++ = ((pSrc[0] << 1) & 0xf8) | (pSrc[1] >> 5);
  65.     
  66. UINT32 tmpBuf = pSrc[1] & 0x1f;
  67.     
  68. pSrc += 2;
  69.     
  70. // Copy d(3) - d(N - 7)
  71. for (int i = 0; i < (frameBytes - 1); i++)
  72. {
  73.     tmpBuf <<= 8;
  74.     tmpBuf |= *pSrc++;
  75.     
  76.     *pDst++ = (UINT8)((tmpBuf >> 5) & 0xff);
  77. }
  78. // Copy d(N-6) - d(N-1)
  79. *pDst = (UINT8)((tmpBuf << 3) & 0xff);
  80.     }
  81.     else
  82.     {
  83. *pDst++ = ((pSrc[0] << 1) & 0xf8);
  84.     }
  85. }
  86. CAMRWideBandCodec::CAMRWideBandCodec() :
  87.     m_lRefCount(0),
  88.     m_pState(0),
  89.     m_nConcealSamples(0),
  90.     m_pFrameBuf(new UINT8[1 + ((CAMRFrameInfo::MaxFrameBits(WideBand) + 7) >> 3)])
  91. {}
  92. CAMRWideBandCodec::~CAMRWideBandCodec()
  93. {
  94.     if (m_pState)
  95.     {
  96. D_IF_exit(m_pState);
  97. m_pState = 0;
  98.     }
  99.     
  100.     delete [] m_pFrameBuf;
  101. }
  102. /*
  103.  * IUnknown methods
  104.  */
  105. STDMETHODIMP CAMRWideBandCodec::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) CAMRWideBandCodec::AddRef()
  124. {
  125.     return InterlockedIncrement(&m_lRefCount);
  126. }
  127. STDMETHODIMP_(ULONG32) CAMRWideBandCodec::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 CAMRWideBandCodec::OpenDecoder(UINT32 cfgType, const void* config,
  140.     UINT32 nBytes)
  141. {
  142.     HX_RESULT res = HXR_FAILED;
  143.     if (m_pState)
  144.     {
  145. D_IF_exit(m_pState);
  146.     }
  147.     m_pState = D_IF_init();
  148.     if (m_pState)
  149. res = HXR_OK;
  150.     return res;
  151. }
  152. STDMETHODIMP CAMRWideBandCodec::Reset()
  153. {
  154.     HX_RESULT res = HXR_OK;
  155.     if (m_pState)
  156.     {
  157. D_IF_exit(m_pState);
  158. m_pState = D_IF_init();
  159. if (!m_pState)
  160.     res = HXR_FAILED;
  161.     }
  162.     m_nConcealSamples = 0;
  163.     return res;
  164. }
  165. STDMETHODIMP CAMRWideBandCodec::GetMaxSamplesOut(UINT32& nSamples) CONSTMETHOD
  166. {
  167.     nSamples = MaxSamples;
  168.     return HXR_OK;
  169. }
  170. STDMETHODIMP CAMRWideBandCodec::GetNChannels(UINT32& nChannels) CONSTMETHOD
  171. {
  172.     nChannels = 1;
  173.     return HXR_OK;
  174. }
  175. STDMETHODIMP CAMRWideBandCodec::GetSampleRate(UINT32& sampleRate) CONSTMETHOD
  176. {
  177.     sampleRate = 16000;
  178.     return HXR_OK;
  179. }
  180. STDMETHODIMP CAMRWideBandCodec::GetDelay(UINT32& nSamples) CONSTMETHOD
  181. {
  182.     nSamples = 0;
  183.     return HXR_OK;
  184. }
  185. STDMETHODIMP CAMRWideBandCodec::Decode(const UCHAR* data, UINT32 nBytes, 
  186.        UINT32 &nBytesConsumed, INT16 *samplesOut, 
  187.        UINT32& nSamplesOut, BOOL eof)
  188. {
  189.     HX_RESULT res = HXR_UNEXPECTED;
  190.     nSamplesOut = 0;
  191.     nBytesConsumed = 0;
  192.     if (m_pState)
  193.     {
  194. if (m_nConcealSamples)
  195. {     
  196.     // Currently we do not do anything special for concealment
  197.     // so we will just output silence for the concealment
  198.     // samples.
  199.     if (m_nConcealSamples > MaxSamples)
  200. nSamplesOut = MaxSamples;
  201.     else
  202. nSamplesOut = m_nConcealSamples;
  203.     
  204.     res = HXR_OK;
  205.     for (UINT32 i = 0; i < nSamplesOut; i++)
  206. *samplesOut++ = 0;
  207.     m_nConcealSamples -= nSamplesOut;
  208. }
  209. else if (nBytes)
  210. {
  211.     VerifyInput((UCHAR*)data, nBytes, nBytes);
  212.     UCHAR* pData;
  213.     int frameType;
  214. #ifdef IF2
  215. // Convert the RFC3267 Section 5.3 speech frame
  216. // format into 3GPP TS 26.101 Annex A IF2 format
  217.     Convert2IF2(WideBand, data, m_pFrameBuf);
  218.     pData = m_pFrameBuf;
  219.     frameType = (*pData >> 4) & 0xf;
  220. #else
  221. // no conversion necessary
  222.     pData = (UCHAR*)data;
  223.     frameType = (*pData >> 3) & 0xf;
  224. #endif
  225.     int frameBytes = 
  226. 1 + ((CAMRFrameInfo::FrameBits(WideBand, frameType) + 7) >> 3);
  227.     if ((int)nBytes >= frameBytes)
  228.     {
  229. D_IF_decode(m_pState, pData, samplesOut, _good_frame);
  230. nBytesConsumed = frameBytes;
  231. nSamplesOut = MaxSamples;
  232. res = HXR_OK;
  233.     }
  234. }
  235.     }
  236.     
  237.     return res;
  238. }
  239. STDMETHODIMP CAMRWideBandCodec::Conceal(UINT32 nSamples)
  240. {
  241.     // We want to conceal only in MaxSamples size blocks.
  242.     UINT32 nFrameCount = (nSamples + MaxSamples - 1) / MaxSamples;
  243.     UINT32 nConcealSamples = nFrameCount * MaxSamples;
  244.     m_nConcealSamples += nConcealSamples;
  245.     return HXR_OK;
  246. }