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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: audsymbian.cpp,v 1.23.2.3 2004/07/09 02:01:39 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include <e32base.h>
  50. #include <e32std.h>
  51. #include "hxassert.h"
  52. #include "hxresult.h"
  53. #include "hxslist.h"
  54. #include "hxcom.h"
  55. #include "hxtick.h"
  56. #include "hxausvc.h"
  57. #include "ihxpckts.h"   
  58. #include "audiosvr/audio_svr.h"
  59. #include "audiosvr/audio_svr_cntxt.h"
  60. #include "audsymbian.h"
  61. static UINT32 Scale(UINT32 v, UINT32 f0, UINT32 f1, UINT32 t0, UINT32 t1);
  62. CHXAudioDevice::CHXAudioDevice()
  63.     : CActive(EPriorityHigh),
  64.       m_lRefCount(0),
  65.       m_deviceOpen(false),
  66.       m_pDeviceResponse(NULL),
  67.       m_pAudioStream(NULL),
  68.       m_pAudioServerContext(NULL),
  69.       m_paused(false),
  70.       m_uMinPlayerVolume(0),
  71.       m_uMaxPlayerVolume(100),
  72.       m_uMinDevVolume(0),
  73.       m_uMaxDevVolume(100)
  74. {
  75.     CActiveScheduler::Add(this);
  76.     TInt err = m_iTimer.CreateLocal();
  77.     HX_ASSERT(KErrNone==err);
  78. }
  79. CHXAudioDevice::~CHXAudioDevice()
  80. {
  81.     Close(TRUE);
  82.     m_iTimer.Close();
  83. }
  84. ULONG32 CHXAudioDevice::AddRef()
  85. {
  86.     return InterlockedIncrement(&m_lRefCount);
  87. }
  88. ULONG32 CHXAudioDevice::Release()
  89. {
  90.     if (InterlockedDecrement(&m_lRefCount) > 0)
  91.     {
  92.         return m_lRefCount;
  93.     }
  94.     delete this;
  95.     return 0;
  96. }
  97. HX_RESULT CHXAudioDevice::QueryInterface(REFIID riid, void** ppvObj)
  98. {
  99.     if (IsEqualIID(riid, IID_IHXAudioDevice))
  100.     {
  101.         AddRef();
  102.         *ppvObj = (IHXAudioDevice*)this;
  103.         return HXR_OK;
  104.     }
  105.     else if (IsEqualIID(riid, IID_IUnknown))
  106.     {
  107.         AddRef();
  108.         *ppvObj = this;
  109.         return HXR_OK;
  110.     }
  111.     *ppvObj = NULL;
  112.     return HXR_NOINTERFACE;
  113. }
  114. HX_RESULT CHXAudioDevice::Open(const HXAudioFormat* pFormat,
  115.                                IHXAudioDeviceResponse* pDeviceResponse)
  116. {
  117.     HX_RESULT res = HXR_OK;
  118.     HX_ASSERT(!m_pDeviceResponse);
  119.     HX_RELEASE(m_pDeviceResponse);
  120.     if( pDeviceResponse )
  121.     {
  122.         m_pDeviceResponse = pDeviceResponse;
  123.         m_pDeviceResponse->AddRef();
  124.     }
  125.     if (HXR_OK != OpenDevice() || HXR_OK != InitDevice(pFormat))
  126.     {
  127.         res = HXR_FAIL;
  128.     }
  129.     return res;
  130. }
  131. HX_RESULT CHXAudioDevice::Close(const BOOL bFlush)
  132. {
  133.     Reset();
  134.     if (m_pAudioStream)
  135.     {
  136.         m_pAudioStream->Close();
  137.         m_pAudioServerContext->Stop();
  138.         m_deviceOpen = false;
  139.         HX_DELETE(m_pAudioStream);
  140.         HX_DELETE(m_pAudioServerContext);
  141.         HX_RELEASE(m_pDeviceResponse);
  142.     }
  143.     return HXR_OK;
  144. }
  145. HX_RESULT CHXAudioDevice::Write(const HXAudioData* pAudioData)
  146. {
  147.     HX_RESULT res = HXR_OK;
  148.     if (pAudioData)
  149.     {
  150.         // add the buffer to the pending write list
  151.         IHXBuffer* pAudioBuf = pAudioData->pData;
  152.         pAudioBuf->AddRef();
  153.         if( m_pAudioStream )
  154.             m_pAudioStream->Write(pAudioBuf);
  155.     }
  156.     return res;
  157. }
  158. HX_RESULT CHXAudioDevice::Reset()
  159. {
  160.     if (m_pAudioStream)
  161.     {
  162.         if (!m_pAudioStream->Stopped())
  163.         {
  164.             m_pAudioStream->Stop();
  165.         }
  166.     }
  167.     
  168.     if (IsActive())
  169.     {
  170.         Cancel();
  171.     }
  172.     return HXR_OK;
  173. }
  174. HX_RESULT CHXAudioDevice::Drain()
  175. {
  176.     HX_ASSERT("Not implemented"==NULL);
  177.     return HXR_FAIL;
  178. }
  179. HX_RESULT CHXAudioDevice::SetVolume( const UINT16 uVolume )
  180. {
  181.     HX_RESULT res = HXR_FAIL;
  182.     
  183.     if( m_pAudioStream )
  184.     {
  185.         m_pAudioStream->SetVolume(TInt(Scale(UINT32(uVolume), 
  186.                                              m_uMinPlayerVolume, m_uMaxPlayerVolume,
  187.                                              m_uMinDevVolume, m_uMaxDevVolume)));
  188.         res = HXR_OK;
  189.     }
  190.     return res;
  191. }
  192. HX_RESULT CHXAudioDevice::GetCurrentAudioTime( ULONG32& ulCurrentTime )
  193. {
  194.     HX_RESULT res = HXR_FAIL;
  195.     
  196.     HX_ASSERT(m_pAudioStream);
  197.     if( m_pAudioStream )
  198.     {
  199.         ulCurrentTime = m_pAudioStream->GetTime();
  200.         res = HXR_OK;
  201.     }
  202.     return res;
  203. }
  204. BOOL CHXAudioDevice::SupportsVolume()
  205. {
  206.     return TRUE;
  207. }
  208. UINT16 CHXAudioDevice::GetVolume()
  209. {
  210.     UINT16 vol = 0;
  211.     if (m_pAudioStream)
  212.     {
  213.         vol = UINT16(Scale(UINT32(m_pAudioStream->GetVolume()),
  214.                            m_uMinDevVolume, m_uMaxDevVolume,
  215.                            m_uMinPlayerVolume, m_uMaxPlayerVolume));
  216.     }
  217.     return vol;
  218. }
  219. short CHXAudioDevice::GetAudioFd( void )
  220. {
  221.     //We don't have file descriptors on symbian for the
  222.     //audio device.
  223.     return 0;
  224. }
  225. HX_RESULT CHXAudioDevice::Seek(ULONG32 ulSeekTime)
  226. {
  227.     HX_ASSERT( "Not implemented"==NULL);
  228.     return HXR_OK;
  229. }
  230. HX_RESULT CHXAudioDevice::Resume()
  231. {
  232.     m_paused = false;
  233.     
  234.     if(m_pAudioStream)
  235.     {
  236.         m_pAudioStream->Play();
  237.     }
  238.     if( !IsActive() )
  239.     {
  240.         m_iTimer.After(iStatus, 1000*100);
  241.         SetActive();
  242.     }
  243.     
  244.     
  245.     return HXR_OK;
  246. }
  247. HX_RESULT CHXAudioDevice::Pause()
  248. {
  249.     HX_RESULT res = HXR_OK;
  250.     m_paused = true;
  251.     if (m_pAudioStream)
  252.     {
  253.         m_pAudioStream->Pause();
  254.     }
  255.     m_iTimer.Cancel();
  256.     
  257.     return res;
  258. }
  259. HX_RESULT CHXAudioDevice::CheckFormat(const HXAudioFormat* pFormat)
  260. {
  261.     HX_RESULT res = HXR_FAIL;
  262.     //Symbian only supports 16-bit PCM.
  263.     if (pFormat->uBitsPerSample == 16 &&
  264.         HXR_OK == OpenDevice() &&
  265.         HXR_OK == InitDevice(pFormat))
  266.     {
  267.         res = HXR_OK;
  268.     }
  269.     return res;
  270. }
  271. UINT16 CHXAudioDevice::NumberOfBlocksRemainingToPlay(void)
  272. {
  273.     return (UINT16)(m_pAudioStream->GetBlocksBuffered());
  274. }
  275. BOOL CHXAudioDevice::InitVolume(const UINT16 uMinVolume,
  276.                                 const UINT16 uMaxVolume )
  277. {
  278.     HX_ASSERT(m_uMaxPlayerVolume > m_uMinPlayerVolume);
  279.     
  280.     if (m_uMaxPlayerVolume > m_uMinPlayerVolume)
  281.     {
  282.         m_uMinPlayerVolume = uMinVolume;
  283.         m_uMaxPlayerVolume = uMaxVolume;
  284.     }
  285.     return (m_uMaxPlayerVolume > m_uMinPlayerVolume) && SupportsVolume();
  286. }
  287. //
  288. // CActive methods
  289. //
  290. void CHXAudioDevice::RunL()
  291. {
  292.     if (iStatus != KErrCancel)
  293.     {
  294.         // call back the response object to update time
  295.         if( m_pDeviceResponse && !m_paused)
  296.         {
  297.             ULONG32 ulAudioTime = 0;
  298.             GetCurrentAudioTime(ulAudioTime);
  299.             m_pDeviceResponse->OnTimeSync(ulAudioTime);
  300.         }
  301.     }
  302.     m_iTimer.After(iStatus, 100*1000 );
  303.     SetActive();
  304. }
  305. void CHXAudioDevice::DoCancel()
  306. {
  307.     if (m_pAudioStream)
  308.     {
  309.         m_pAudioStream->CancelWrite();
  310.     }
  311.     m_iTimer.Cancel();
  312. }
  313. //////////////////////////////////////////////////////////////////////
  314. // private methods ///////////////////////////////////////////////////
  315. //////////////////////////////////////////////////////////////////////
  316. HX_RESULT CHXAudioDevice::OpenDevice()
  317. {
  318.     HX_RESULT res = HXR_FAIL;
  319.     if (m_deviceOpen)
  320.         return HXR_OK;
  321.     if(!m_pAudioStream)
  322.     {
  323.         m_pAudioStream = new HXSymbianAudioClient;
  324.     }
  325.     if (m_pAudioStream)
  326.     {
  327.         // create the thread context for the audio server to run 
  328.         if (!m_pAudioServerContext)
  329.         {
  330.             m_pAudioServerContext = new HXSymbianAudioServerContext;
  331.         }
  332.         // start the audio sevrver thread
  333.         if (m_pAudioServerContext && !m_pAudioServerContext->Running())
  334.         {
  335.             m_pAudioServerContext->Start();
  336.         }
  337.         // connect to the audio server and share the session
  338.         if (m_pAudioServerContext->Running() &&
  339.             KErrNone == m_pAudioStream->Connect() &&
  340.             KErrNone == m_pAudioStream->Share(RSessionBase::EAutoAttach))
  341.         {
  342.             m_deviceOpen = true;
  343.             res = HXR_OK;
  344.         }
  345.     }
  346.     return res;
  347. }
  348. HX_RESULT CHXAudioDevice::InitDevice(const HXAudioFormat* pFormat)
  349. {
  350.     HX_RESULT res = HXR_FAIL;
  351.     // attempt to init device with given audio format
  352.     if (m_pAudioStream &&  
  353.         (KErrNone == m_pAudioStream->Init(pFormat->ulSamplesPerSec,
  354.                                           pFormat->uChannels)))
  355.     {
  356.         // grab device volume info (first opportunity)
  357.         m_uMinDevVolume = m_pAudioStream->GetMinVolume();
  358.         m_uMaxDevVolume = m_pAudioStream->GetMaxVolume();
  359.         res = HXR_OK;
  360.     }
  361.     return res;
  362. }
  363. //////////////////////////////////////////////////////////////////////
  364. // convenience methods ///////////////////////////////////////////////
  365. //////////////////////////////////////////////////////////////////////
  366. UINT32 Scale(UINT32 v, UINT32 f0, UINT32 f1, UINT32 t0, UINT32 t1)
  367. {
  368.     HX_ASSERT(f1 > f0);
  369.     HX_ASSERT(t1 >= t0);
  370.     HX_ASSERT(v >= f0);
  371.     if (f1 > f0 && v > f0)
  372.     {
  373.         UINT64 tr = t1 - t0;
  374.         UINT64 fr = f1 - f0;
  375.         UINT64 n  = v - f0;
  376.         UINT64 q  = n / fr;
  377.         UINT64 r  = n % fr;
  378.         return t0 + INT64_TO_UINT32((q * tr + (r * tr + (fr >> 1)) / fr));
  379.     }
  380.     return 0;
  381. }