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

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 "hxcom.h"
  36. #include "hxtypes.h"
  37. #include "hxresult.h"
  38. #ifdef _WINDOWS
  39. #include <windows.h>
  40. #endif
  41. #include "hlxclib/string.h"
  42. #include "timeval.h"
  43. #include "ihxpckts.h"
  44. #include "hxfiles.h"
  45. #include "hxengin.h"
  46. #include "hxcore.h"
  47. #include "hxprefs.h"
  48. #include "hxtick.h"
  49. #ifdef _MACINTOSH
  50. #include "hxmm.h"
  51. #endif
  52. #include "hxthread.h"
  53. //#include "resampl2.h"
  54. #include "hxausvc.h"
  55. #include "hxrsmp2.h"
  56. #include "hxheap.h"
  57. #ifdef _DEBUG
  58. #undef HX_THIS_FILE
  59. static const char HX_THIS_FILE[] = __FILE__;
  60. #endif
  61. // HXScheduler...
  62. HXCDQualityResampler::HXCDQualityResampler() 
  63.     :   m_lRefCount (0)
  64.     , m_pResampler(NULL)
  65.     , m_audioChannelConversion(AUDIO_CHANNEL_NONE)
  66.     , m_audioSampleConversion(AUDIO_SAMPLE_NONE)
  67.     , m_ulSamplesSaved(0)
  68.     , m_ulSamplesFixed(0)
  69.     , m_ulBytesFixed(0)
  70.     ,   m_pBPS8To16Out(NULL)
  71. {
  72. }
  73. HXCDQualityResampler::~HXCDQualityResampler()
  74. {
  75.     Close();
  76. }
  77. /*
  78.  * IUnknown methods
  79.  */
  80. /////////////////////////////////////////////////////////////////////////
  81. // Method:
  82. // IUnknown::QueryInterface
  83. // Purpose:
  84. // Implement this to export the interfaces supported by your 
  85. // object.
  86. //
  87. STDMETHODIMP HXCDQualityResampler::QueryInterface(REFIID riid, void** ppvObj)
  88. {
  89.     QInterfaceList qiList[] =
  90.         {
  91.             { GET_IIDHANDLE(IID_IHXAudioResampler), (IHXAudioResampler*)this },
  92.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXAudioResampler*)this },
  93.         };
  94.     
  95.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  96. }
  97. /////////////////////////////////////////////////////////////////////////
  98. // Method:
  99. // IUnknown::AddRef
  100. // Purpose:
  101. // Everyone usually implements this the same... feel free to use
  102. // this implementation.
  103. //
  104. STDMETHODIMP_(ULONG32) HXCDQualityResampler::AddRef()
  105. {
  106.     return InterlockedIncrement(&m_lRefCount);
  107. }
  108. /////////////////////////////////////////////////////////////////////////
  109. // Method:
  110. // IUnknown::Release
  111. // Purpose:
  112. // Everyone usually implements this the same... feel free to use
  113. // this implementation.
  114. //
  115. STDMETHODIMP_(ULONG32) HXCDQualityResampler::Release()
  116. {
  117.     if (InterlockedDecrement(&m_lRefCount) > 0)
  118.     {
  119. return m_lRefCount;
  120.     }
  121.     delete this;
  122.     return 0;
  123. }
  124. /*
  125.  * IHXResampler methods
  126.  */
  127. STDMETHODIMP_(UINT32) 
  128. HXCDQualityResampler::Resample(UINT16* pInput, 
  129. UINT32 ulInputBytes, 
  130.                                 UINT16* pOutput) 
  131. {
  132.     UINT32  ulOutputBytes = 0;
  133.     UINT32  ulSamplesIn = 0;
  134.     UINT32  ulFramesIn = 0;
  135.     UINT32  ulSamplesOut = 0;
  136.     UINT32  ulBytesSaved = 0;   
  137.     UINT32  ulOut = 0;
  138.     ulSamplesIn = (ulInputBytes * 8) / m_inAudioFormat.uBitsPerSample;
  139.     
  140.     ulSamplesOut = ulSamplesIn;
  141.     ulOutputBytes = ulInputBytes;
  142.     // channel conversion first(STEREO -> MONO)
  143.     // MONO -> STEREO is handled by the caller(AudioStream)
  144.     if (AUDIO_CHANNEL_DOWN == m_audioChannelConversion)
  145.     {
  146. Downmix16((short*)pInput, ulSamplesIn);
  147. // half the output samples after channel conversion
  148. ulSamplesIn /= 2;
  149. ulSamplesOut = ulSamplesIn;
  150.     }
  151.     // resampler's output always be 16bits
  152.     if (m_inAudioFormat.uBitsPerSample == 8 && m_outAudioFormat.uBitsPerSample == 16)
  153.     {
  154. ulFramesIn = ulSamplesIn / m_inAudioFormat.uChannels;
  155. ulOut = m_inAudioFormat.uChannels * 2 * ulFramesIn;
  156. if (!m_pBPS8To16Out)
  157. {
  158.     m_pBPS8To16Out = (short*)new char[ulOut];
  159. }
  160. BPS8To16((short*)pInput, ulInputBytes, (short*)m_pBPS8To16Out, ulOut);
  161. pInput = (UINT16*)m_pBPS8To16Out;
  162.     }
  163.     if (m_pResampler)
  164.     {
  165. if (m_ulSamplesSaved)
  166. {
  167.     ulBytesSaved = m_ulSamplesSaved * m_outAudioFormat.uBitsPerSample / 8;
  168.     HX_ASSERT(ulBytesSaved < m_ulBytesFixed);
  169.             if (ulBytesSaved >= m_ulBytesFixed) ulBytesSaved = m_ulBytesFixed;
  170.     ::memcpy(pOutput, (UCHAR*)pOutput+m_ulBytesFixed, ulBytesSaved); /* Flawfinder: ignore */
  171. }
  172. ulSamplesOut = m_pResampler->Resample((short*)pInput,
  173.      ulSamplesIn,
  174.      (short*)((UCHAR*)pOutput + ulBytesSaved));
  175. m_ulSamplesSaved += ulSamplesOut - m_ulSamplesFixed;
  176. ulOutputBytes = m_ulBytesFixed;
  177.     }
  178.     else
  179.     {
  180. ulOutputBytes = (ulSamplesOut * m_outAudioFormat.uBitsPerSample) / 8;
  181.         HX_ASSERT(ulOutputBytes < m_ulBytesFixed);
  182.         if (ulOutputBytes >= m_ulBytesFixed) ulOutputBytes = m_ulBytesFixed;
  183. ::memcpy(pOutput, pInput, ulOutputBytes); /* Flawfinder: ignore */
  184.     }
  185.     return ulOutputBytes;
  186. }
  187. STDMETHODIMP_(UINT32) 
  188. HXCDQualityResampler::Requires(UINT32 outputFrames)
  189. {
  190.     UINT32 inputFrames = 0;
  191.     UINT32 ulSamplesRequired = 0;
  192.     // we only need to resample half of the output frames
  193.     // since the caller will do the MONO -> STEREO channel conversion
  194.     if (AUDIO_CHANNEL_UP == m_audioChannelConversion)
  195.     {
  196. outputFrames /= 2;
  197.     }
  198.     // take into account of the extra samples from the last Resample()
  199.     ulSamplesRequired = outputFrames * m_outAudioFormat.uChannels - m_ulSamplesSaved;
  200.     m_ulSamplesFixed = outputFrames * m_outAudioFormat.uChannels;
  201.     m_ulBytesFixed = (outputFrames * m_outAudioFormat.uChannels * m_outAudioFormat.uBitsPerSample) / 8;;
  202.     if (m_pResampler)
  203.     {
  204. inputFrames = m_pResampler->GetMinInput(ulSamplesRequired) / m_inAudioFormat.uChannels;
  205.     }
  206.     else
  207.     {
  208. inputFrames = ulSamplesRequired / m_inAudioFormat.uChannels;
  209.     }
  210.     // we need to double the input frames for STEREO -> MONO channel
  211.     // conversion
  212.     if (AUDIO_CHANNEL_DOWN == m_audioChannelConversion)
  213.     {
  214. inputFrames *= 2;
  215.     }
  216.     return inputFrames;
  217. }
  218. HX_RESULT
  219. HXCDQualityResampler::Init(HXAudioFormat inAudioFormat,
  220.     REF(HXAudioFormat) outAudioFormat)
  221. {
  222.     HX_RESULT rc = HXR_OK;
  223.     CopyAudioFormat(inAudioFormat, m_inAudioFormat);
  224.     CopyAudioFormat(outAudioFormat, m_outAudioFormat);
  225.     INT32   actualMaxSamplesIn = (m_inAudioFormat.uMaxBlockSize * 8) / m_inAudioFormat.uBitsPerSample;
  226.     INT32   actualMaxSamplesOut = 0;
  227.     INT32   actualMaxInputBytes = m_inAudioFormat.uMaxBlockSize;
  228.     INT32   actualResamplerChannel = m_inAudioFormat.uChannels;
  229.     // cleanup the mess
  230.     Close();
  231.     // this wrapper class will do the STEREO -> MONO channel conversion
  232.     // MONO -> STEREO channel conversion will be done by the caller
  233.     if (m_outAudioFormat.uChannels > m_inAudioFormat.uChannels)
  234.     {
  235. m_audioChannelConversion = AUDIO_CHANNEL_UP;
  236.     }
  237.     else if (m_outAudioFormat.uChannels < m_inAudioFormat.uChannels)
  238.     {
  239. m_audioChannelConversion = AUDIO_CHANNEL_DOWN;
  240. actualMaxInputBytes /= 2;
  241. actualResamplerChannel = m_outAudioFormat.uChannels;
  242.     }
  243.     else
  244.     {
  245. m_audioChannelConversion = AUDIO_CHANNEL_NONE;
  246.     }
  247.     if (m_outAudioFormat.ulSamplesPerSec == m_inAudioFormat.ulSamplesPerSec)
  248.     {
  249. m_audioSampleConversion = AUDIO_SAMPLE_NONE;
  250.     }
  251.     else
  252.     {
  253. m_audioSampleConversion = AUDIO_SAMPLE_NEEDED;
  254.     }
  255.     if (AUDIO_SAMPLE_NONE != m_audioSampleConversion)
  256.     {
  257. if (HXR_OK == RAExactResampler::Create(&m_pResampler,
  258.        m_inAudioFormat.ulSamplesPerSec,
  259.        m_outAudioFormat.ulSamplesPerSec,
  260.        actualResamplerChannel,
  261.            RAExactResampler::_INT16)) // 16bit per sample output
  262. {
  263.     actualMaxSamplesOut = m_pResampler->GetMaxOutput(actualMaxSamplesIn);
  264. }
  265. else
  266. {
  267.     HX_DELETE(m_pResampler);
  268.     rc = HXR_FAILED;
  269. }
  270.     }
  271.     else
  272.     {
  273. actualMaxSamplesOut = actualMaxSamplesIn;
  274.     }
  275.     outAudioFormat.uMaxBlockSize = m_outAudioFormat.uMaxBlockSize = (actualMaxSamplesOut * m_outAudioFormat.uBitsPerSample) / 8;
  276.     
  277.     return rc;
  278. }
  279. void
  280. HXCDQualityResampler::Downmix16(INT16* pIn, UINT32 nSamplesIn)
  281. {
  282.     UINT32 i ;
  283.     for (i = 0 ; i < nSamplesIn / 2 ; i++)
  284.     {
  285. INT32 t = (INT32)pIn[2*i] + (INT32)pIn[2*i+1] ;
  286. pIn[i] = (INT16)(t>>1);
  287.     }
  288. }
  289. void
  290. HXCDQualityResampler::BPS8To16(INT16* pInput, UINT32 ulBytesIn, INT16* pOutput, UINT32& ulBytesOut)
  291. {
  292.     long inputFrames = ulBytesIn / (m_inAudioFormat.uBitsPerSample/8) / m_inAudioFormat.uChannels;
  293.     long n = 0;
  294.     if (1 == m_outAudioFormat.uChannels) 
  295.     {
  296. unsigned char* pIn = (unsigned char*) pInput;
  297. for (n = 0; n < inputFrames; n++) 
  298. {
  299.     pOutput[n] = (short) (((short)*pIn++ - 128) << 8);
  300. }
  301.     }
  302.     else if (2 == m_outAudioFormat.uChannels) 
  303.     { 
  304.         unsigned char* pIn = (unsigned char*) pInput;
  305. long m = 0;
  306. for (n = 0; n < inputFrames; n++ ) 
  307. {
  308.     pOutput[m] = (short) (((short)*pIn++ - 128) << 8);
  309.     m++;
  310.     pOutput[m] = (short) (((short)*pIn++ - 128) << 8);
  311.     m++;
  312. }
  313.     } 
  314.     ulBytesOut = m_inAudioFormat.uChannels * 2 * inputFrames;
  315.     return;
  316. }
  317. void
  318. HXCDQualityResampler::CopyAudioFormat(HXAudioFormat from, REF(HXAudioFormat) to)
  319. {
  320.     to.uChannels = from.uChannels;
  321.     to.uBitsPerSample = from.uBitsPerSample;
  322.     to.ulSamplesPerSec = from.ulSamplesPerSec;
  323.     to.uMaxBlockSize = from.uMaxBlockSize;
  324. }
  325. void
  326. HXCDQualityResampler::Close()
  327. {
  328.     HX_VECTOR_DELETE(m_pBPS8To16Out);
  329.     HX_DELETE(m_pResampler);
  330. }