⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audaix.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
       pAudioOutHdr = NULL; // don't add the same buffer again...
    } while (bWroteSomething);
    
    return m_wLastError;
}


// Seek() is never called.
HX_RESULT CAudioOutAIX::_Imp_Seek(ULONG32 ulSeekTime)
{
    return HXR_OK;
}


HX_RESULT CAudioOutAIX::_Imp_Pause()
{
    m_paused = TRUE;
    
    return RA_AOE_NOERR;
}

HX_RESULT CAudioOutAIX::_Imp_Resume()
{
    m_paused = FALSE;
    return RA_AOE_NOERR;
}

/////////////////////////////////////////////////////////////////////////
// Imp_Reset()
//    Reset the device.  It is important to note that this call results 
//    from a seek, so we must act accordingly.
//
HX_RESULT CAudioOutAIX::_Imp_Reset()
{
    _Imp_Close();
    _Imp_Open(NULL);
    while(!m_pWriteList->IsEmpty())
      {
	IHXBuffer* pBuffer = (IHXBuffer*)m_pWriteList->RemoveHead();
	HX_RELEASE(pBuffer);
      }
    HX_ASSERT( m_pWriteList->IsEmpty() );
    // these are vital! If they are not set this way, playback after a seek 
    // will just stop after a few frames.
    m_bPaused       = FALSE;
    m_bFirstWrite   = TRUE;
    // and these are fairly obvious, but necessary after a seek. It should be
    // noted here that the audio timeline after a seek is relative to the 
    // internal timeline of the core scheduler; all our playback is based from 
    // our start.
    m_ulTotalWritten =0;
    m_ulCurrentTime = 0;
    
    return RA_AOE_NOERR;
}


// this will force the player to play all remaining data.  The call
// will block until finished playing - if this is not what is desired,
// change the second parameter of the call to FALSE. 
HX_RESULT CAudioOutAIX::_Imp_Drain()
{
    // -pjg need to drain the WriteList also.
    // this will force the player to play all remaining data.  If passed TRUE, 
    // the call will block until finished playing. 

    while(!m_pWriteList->IsEmpty())
      {
	IHXBuffer* pBuffer = (IHXBuffer*)m_pWriteList->RemoveHead();
	HX_RELEASE(pBuffer);
      }

    m_pAudioDevice->play_remaining_data( gpSomEnvironment, TRUE );
    
    return RA_AOE_NOERR;
}




AUDIOERROR CAudioOutAIX::SetDeviceConfig( const HXAudioFormat* pFormat )
{
    m_pAudioDevice->set_sample_rate        ( gpSomEnvironment, 
					     pFormat->ulSamplesPerSec, 
					     &m_oSamples );
    m_pAudioDevice->set_number_of_channels ( gpSomEnvironment, 
					     pFormat->uChannels );
    m_pAudioDevice->set_bits_per_sample    ( gpSomEnvironment, 
					     pFormat->uBitsPerSample );
    m_pAudioDevice->set_audio_format_type  ( gpSomEnvironment, "PCM" );
    m_pAudioDevice->set_number_format      ( gpSomEnvironment, 
					     "TWOS_COMPLEMENT" );
    m_pAudioDevice->set_byte_order         ( gpSomEnvironment, "MSB" ); 
    m_pAudioDevice->set_time_format        ( gpSomEnvironment, 
					     UMSAudioTypes_Msecs ); 
    
    m_pAudioDevice->set_balance   ( gpSomEnvironment, lDefaultBalance );  
    m_pAudioDevice->set_volume    ( gpSomEnvironment, zlCurrentVolume );
    m_pAudioDevice->enable_output ( gpSomEnvironment, "LINE_OUT", 
				    &m_lLeftGain, &m_lRightGain  );
    
    m_pAudioDevice->initialize    ( gpSomEnvironment );
    
    m_pAudioDevice->start         ( gpSomEnvironment );
    
    m_num_channels = pFormat->uChannels;
    m_sample_rate  = pFormat->ulSamplesPerSec; 
    m_bits_per_sample = pFormat->uBitsPerSample;
    
    return RA_AOE_NOERR;
}


HX_RESULT CAudioOutAIX::_Imp_CheckFormat( const HXAudioFormat* pFormat )
{
    // Check for valid format inputs.
    if ( pFormat->uChannels != 1 && pFormat->uChannels != 2 ) 
      {
	return HXR_FAIL;
      }
    if ( pFormat->uBitsPerSample != 8 && pFormat->uBitsPerSample != 16 ) 
      {
	return HXR_FAIL;
      }
    
    return HXR_OK;
}



/************************************************************************
 *  Method:
 *              CAudioOutAIX::_Imp_GetCurrentTime
 *      Purpose:
 *              Get the current time from the audio device.
 *		We added this to support the clock available in the
 *		Window's audio driver.
 *  
 *              Current time is simply a function of the total number of 
 *              bytes written to the device minus the number still in
 *              the device queue.  This is expressed as playbackbytes.
 *
 *              Ported to Aix 4.3.1 by fhutchinson, Jan 1999.
 *
 *   The minitimer below is a simple timer employed to avoid excessive 
 *   calls to the UMS audio driver to get the current time, the rationale 
 *   being that a gettimeofday call and a little arithmetic is less expensive 
 *   than a call to the driver. The threshold value is the number of 
 *   microseconds (1/1,000,000 sec) that must pass before the time goes off.
 */    

#include <string.h>  // for strerror()

HX_RESULT CAudioOutAIX::_Imp_GetCurrentTime( ULONG32& ulCurrentTime )
{
    long lBytesPerSample = m_bits_per_sample/8;
    long lBytesStillInDeviceBuffer;
    ulCurrentTime = m_ulCurrentTime;

    UMSAudioDevice_ReturnCode retCode;
    
    // set the device to return the amount of data still in the device buffer as a
    // number of bytes
    retCode = m_pAudioDevice->set_time_format( gpSomEnvironment, UMSAudioTypes_Bytes );
    if( retCode != UMSAudioDevice_Success ) 
    {
	m_wLastError = UMSErrorCodeToRACode( retCode );
	return (m_wLastError = UMSErrorCodeToRACode( retCode ) );
    }
    
    retCode = m_pAudioDevice->write_buff_used( gpSomEnvironment, &lBytesStillInDeviceBuffer );
    if( retCode != UMSAudioDevice_Success ) 
    {
	// almost certainly because the device is not opened.
	return (m_wLastError = UMSErrorCodeToRACode( retCode ) );
    }
    
    long lBytesPlayed =  m_ulTotalWritten - lBytesStillInDeviceBuffer;
    
    m_ulCurrentTime = ulCurrentTime = 
      ( (lBytesPlayed /lBytesPerSample) / 
	(float)m_sample_rate * 1000 / m_num_channels );
   
    return HXR_OK;
}




/************************************************************************
 *  Method:
 *              CAudioOutAIX::_Imp_GetAudioFd
 *      Purpose: Intended to return the file descriptor of the device. 
 *               However, UMS is not file descriptor-based, so we 
 *               return a -1, generally accepted as a closed device fd.
 */
INT16 CAudioOutAIX::_Imp_GetAudioFd()
{
    return -1;
}


/************************************************************************
 *  Method:
 *              CAudioOutAIX::DoTimeSyncs
 *      Purpose:
 *		Manual time syncs! Fork!
 */
void CAudioOutAIX::DoTimeSyncs()
{
    ReschedPlaybackCheck();
    OnTimeSync(); // XXXDMB      // hxaudev.cpp::CHXAudioDevice::OnTimeSync()
    
    return;
}

/************************************************************************
 *  Method:
 *              CAudioOutAIX::ReschedPlaybackCheck()
 *      Purpose:
 *		Reschedule playback callback.
 */
HX_RESULT CAudioOutAIX::ReschedPlaybackCheck()
{
    HX_RESULT theErr = HXR_OK;
    
    if (m_bCallbackPending)
      return theErr;

    *m_pPlaybackCountCBTime += (int) (m_ulGranularity*1000) / 2;
    // Put this back in the scheduler.
    HXPlaybackCountCb* pCallback = 0;
    pCallback = new HXPlaybackCountCb(TRUE);
    if (pCallback)
      {
	pCallback->m_pAudioDeviceObject = this;
	m_bCallbackPending = TRUE;
	m_PendingCallbackID = 
	  m_pScheduler->AbsoluteEnter(pCallback,*((HXTimeval*)m_pPlaybackCountCBTime)) ;
      }
    else
      theErr = HXR_OUTOFMEMORY;  // but ignored, why?
    
    return theErr;
}



UINT16	CAudioOutAIX::_NumberOfBlocksRemainingToPlay(void)
{
    ULONG32 ulCurTime = 0;
    GetCurrentAudioTime(ulCurTime);
    
    UINT32 bytesBuffered = 0;
    LISTPOSITION i = m_pWriteList->GetHeadPosition();
    
    while (i)
    {
	bytesBuffered += ((IHXBuffer *)m_pWriteList->GetAt(i)) -> GetSize();
	m_pWriteList->GetNext(i);
    }


    m_pAudioDevice->set_time_format( gpSomEnvironment, UMSAudioTypes_Bytes );

    long lBytesStillInDeviceBuffer;
    UINT32 tries = 100;
    UMSAudioDevice_ReturnCode retCode;

    while (--tries &&
           (m_pAudioDevice->write_buff_used( gpSomEnvironment, &lBytesStillInDeviceBuffer )) != UMSAudioDevice_Success);

    if (!tries)
    {
	HX_ASSERT(FALSE);
	// don't know what to do!
    }

    UINT16 blocks = 
	(bytesBuffered + lBytesStillInDeviceBuffer) / m_wBlockSize + 1;
    //UINT16 blocks = (int) (((double)bytesBuffered + lBytesStillInDeviceBuffer) /
//			     m_ulBytesPerGran) + 1;

    return blocks;
}


// CAudioOutAIX::HXPlaybackCountCb
CAudioOutAIX::HXPlaybackCountCb::HXPlaybackCountCb(BOOL timed) 
  : m_lRefCount (0),
    m_pAudioDeviceObject (0),
    m_timed(timed)
{
}

CAudioOutAIX::HXPlaybackCountCb::~HXPlaybackCountCb()
{
}

/*
 * IUnknown methods
 */
/////////////////////////////////////////////////////////////////////////
//      Method:
//              IUnknown::QueryInterface
//      Purpose:
//              Implement this to export the interfaces supported by your 
//              object.
//
STDMETHODIMP CAudioOutAIX::HXPlaybackCountCb::QueryInterface(REFIID riid, void** ppvObj)
{
    if (IsEqualIID(riid, IID_IHXCallback))
    {
        AddRef();
        *ppvObj = (IHXCallback*)this;
        return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IUnknown))
    {
        AddRef();
        *ppvObj = this;
        return HXR_OK;
    }
    
    *ppvObj = NULL;
    return HXR_NOINTERFACE;
}



/////////////////////////////////////////////////////////////////////////
//      Method:
//              IUnknown::AddRef
//      Purpose:
//              Everyone usually implements this the same... feel free to use
//              this implementation.
//
STDMETHODIMP_(ULONG32) CAudioOutAIX::HXPlaybackCountCb::AddRef()
{
  return InterlockedIncrement(&m_lRefCount);
}

/////////////////////////////////////////////////////////////////////////
//      Method:
//              IUnknown::Release
//      Purpose:
//              Everyone usually implements this the same... feel free to use
//              this implementation.
//
STDMETHODIMP_(ULONG32) CAudioOutAIX::HXPlaybackCountCb::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
        return m_lRefCount;
    }

    delete this;
    return 0;
}

/*
 *      IHXPlaybackCountCb methods
 */
STDMETHODIMP CAudioOutAIX::HXPlaybackCountCb::Func(void)
{
    if (m_pAudioDeviceObject)
    {
	if(!m_timed)
	{
	    m_pAudioDeviceObject->_Imp_Write(NULL);
	}
	else
	{
	    m_pAudioDeviceObject->_Imp_Write(NULL);
	    m_pAudioDeviceObject->m_bCallbackPending  = FALSE;
	    m_pAudioDeviceObject->DoTimeSyncs();
	}
    }

    return HXR_OK;
}

//
//   getUMSAudioDeviceError()
//  
//  returns the string description of the given UMS error code
//

static const char * getUMSAudioDeviceError( UMSAudioDevice_ReturnCode code ) 
{
  switch( code )
    {
    case UMSAudioDevice_Success        : return "Success";
    case UMSAudioDevice_InvalidParam   : return "Invalid parameter";
    case UMSAudioDevice_MemoryError    : return "Success";
    case UMSAudioDevice_DeviceNotAvail : return "Device is not available";
    case UMSAudioDevice_Preempted      : return "Preempted";
    case UMSAudioDevice_Interrupted    : return "Inerrupted";
    case UMSAudioDevice_DeviceError    : return "Device error";
      
      // make sure this is last before default case.
    case UMSAudioDevice_Failure : return "undescribed error";
    default : break;
      
    }
  return "Unknown error";
}


//
//  UMSErrorCodeToRACode()
// 
//  Converts the UMS return code to a best-guess RMA return code equivalent.
//
audio_error UMSErrorCodeToRACode( UMSAudioDevice_ReturnCode retCode ) 
{
  switch( retCode )
    {
    case UMSAudioDevice_Success               : return RA_AOE_NOERR;
    case UMSAudioDevice_InvalidParam          : return RA_AOE_INVALPARAM;
    case UMSAudioDevice_DeviceNotAvail        : return RA_AOE_BADDEVICEID;
    case UMSAudioDevice_NoDevice              : return RA_AOE_BADDEVICEID; 
    case UMSAudioDevice_IncompatibleSettings  : return RA_AOE_BADFORMAT  ; 
    case UMSAudioDevice_NotOpen               : return RA_AOE_DEVNOTOPEN  ; 
    case UMSAudioDevice_NotReady              : return RA_AOE_DEVBUSY  ; 
    case UMSAudioDevice_SettingsChanged       : return RA_AOE_BADFORMAT  ; 
      // this is a stretch...
    case UMSAudioDevice_DeviceError           : return RA_AOE_BADWRITE  ; 
    case UMSAudioDevice_NotSupported          : return RA_AOE_NOTSUPPORTED  ; 

      // and these we will classify under general for now.
    case UMSAudioDevice_Interrupted           : ;
    case UMSAudioDevice_Preempted             : ;
    case UMSAudioDevice_MemoryError           : ;
    case UMSAudioDevice_Failure               : ;
    case UMSAudioDevice_UnderRun              : ;
    case UMSAudioDevice_OverRun               : ;
    default : break;
    }
  return RA_AOE_GENERAL;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -