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

📄 audqnx.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// Make sure we only deal with full samples. Bytes-per-sample*num-channels.	int nRem = ulNumBytesToRewind % (m_uSampFrameSize * m_num_channels);	ulNumBytesToRewind -= nRem;	pNewBuffer->Set( m_pRollbackBuffer+m_ulDeviceBufferSize-ulNumBytesToRewind, ulNumBytesToRewind );	m_pWriteList->AddHead(pNewBuffer);	pNewBuffer->AddRef();	// Update total pause bytes offset for time/video sync	m_ulPauseBytes += pause_bytes;	return RA_AOE_NOERR;}HX_RESULT CAudioOutQNX::_Imp_Resume(){	m_paused = FALSE;	_Imp_Write( NULL );	return RA_AOE_NOERR;}HX_RESULT CAudioOutQNX::_Imp_Reset(){	m_ulLastTimeChecked = (UINT32) -1;	m_ulLastTimeReturned = 0;	if ( m_wState == RA_AOS_CLOSED )		return RA_AOE_NOERR;	if ( m_wID < 0 )		return RA_AOE_DEVNOTOPEN;	// Temporary FLUSH <--> DRAIN	if ( ioctl (m_wID, SND_PCM_IOCTL_DRAIN_PLAYBACK, 0) == -1 )		return RA_AOE_GENERAL;	while (m_pWriteList && m_pWriteList->GetCount() > 0)	{	    IHXBuffer* pBuffer = (IHXBuffer *)(m_pWriteList->RemoveHead());	    pBuffer->Release();	}	m_ulTotalWritten    = 0;	m_bFirstWrite	    = TRUE;	m_ulLastNumBytes    = 0;	return RA_AOE_NOERR;}HX_RESULT CAudioOutQNX::_Imp_Drain(){	if ( m_wID < 0 )		return RA_AOE_DEVNOTOPEN;	// Temporary FLUSH <--> DRAIN	if ( ioctl (m_wID, SND_PCM_IOCTL_FLUSH_PLAYBACK, 0) == -1 )		return RA_AOE_GENERAL;	return RA_AOE_NOERR;}AUDIOERROR CAudioOutQNX::SetDeviceConfig( 	const HXAudioFormat* pFormat ){	if ( m_wID < 0 ) 		return RA_AOE_NOTENABLED;	int sampleWidth      = pFormat->uBitsPerSample;	ULONG32 sampleRate   = pFormat->ulSamplesPerSec;	int numChannels      = pFormat->uChannels;	m_wBlockSize         = m_ulBytesPerGran;  //pFormat->uMaxBlockSize;	ULONG32 bufSize = 128;	ULONG32 bytesPerBlock = m_wBlockSize; 	while ( bufSize < 4096 )	{		bufSize *= 2;	}	m_ulFragSize = bufSize;	snd_pcm_playback_params_t playback_params;	memset( &playback_params, 0, sizeof(playback_params) );	playback_params.fragment_size  = m_ulFragSize;	playback_params.fragments_max  = -1;	playback_params.fragments_room =  1;	/* it's okay to fail, card may not handle fragment size */	ioctl(m_wID, SND_PCM_IOCTL_PLAYBACK_PARAMS, &playback_params );	snd_pcm_format_t format;	memset( &format, 0, sizeof(format));	if( sampleWidth == 16 )	{	    format.format = SND_PCM_SFMT_S16_LE;	}	else 	{	    format.format = SND_PCM_SFMT_U8;	    m_uSampFrameSize /= 2;	}	format.channels		= numChannels;	format.rate			= sampleRate;	m_sample_rate		= sampleRate;	m_num_channels		= numChannels;	m_uSampFrameSize	= sampleWidth / 8;	if(ioctl(m_wID, SND_PCM_IOCTL_PLAYBACK_FORMAT, &format) == -1)	{	    return (  m_wLastError = RA_AOE_NOTENABLED );	}	numChannels = format.channels;	sampleRate  = format.rate;	//	// Verify that requested format was accepted by the audio device.	//	if ( numChannels != pFormat->uChannels )		((HXAudioFormat*)pFormat)->uChannels = numChannels;			if ( sampleRate != pFormat->ulSamplesPerSec )		((HXAudioFormat*)pFormat)->ulSamplesPerSec = sampleRate;	// Get the audio driver's buffer size for our rollback buffer    snd_pcm_playback_info_t pinfo;	memset( &pinfo, 0, sizeof( pinfo ) );	if(ioctl(m_wID, SND_PCM_IOCTL_PLAYBACK_INFO, &pinfo) != -1)		m_ulDeviceBufferSize = pinfo.buffer_size;		return RA_AOE_NOERR;}HX_RESULT CAudioOutQNX::_Imp_CheckFormat( 	const HXAudioFormat* pFormat ){	// QNX audio driver can do all formats that we our	// currently interested in. However, we should check	// for valid inputs.	if ( pFormat->uChannels != 1 && pFormat->uChannels != 2 )		return HXR_FAILED;	if ( pFormat->uBitsPerSample != 8 && pFormat->uBitsPerSample != 16 )		return HXR_FAILED;	// Ask driver later#if 0  /*No reason why the driver won't accept other sampling rates...*/	if ( pFormat->ulSamplesPerSec != 8000 && pFormat->ulSamplesPerSec != 9600  &&	     pFormat->ulSamplesPerSec != 11025 && pFormat->ulSamplesPerSec != 16000  &&	     pFormat->ulSamplesPerSec != 18900 && pFormat->ulSamplesPerSec != 22050  &&	     pFormat->ulSamplesPerSec != 32000 && pFormat->ulSamplesPerSec != 44100  &&	     pFormat->ulSamplesPerSec != 48000 )		return HXR_FAILED;#endif	return HXR_OK;}/************************************************************************ *  Method: *              CAudioOutQNX::_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. */HX_RESULT CAudioOutQNX::_Imp_GetCurrentTime ( ULONG32& ulCurrentTime ){    ULONG32 ulTime   = 0;    ULONG32 ulBytes  = GetPlaybackBytes();	ulBytes += m_ulPauseBytes;        ulTime = (UINT32)((  (double)(ulBytes/m_uSampFrameSize)/(double)m_sample_rate) * 1000 / m_num_channels);        //Not used anywhere but belongs to CHXAudioDevice so we must set it.    m_ulCurrentTime  = ulTime;    //Set the answer.    ulCurrentTime = ulTime;    return HXR_OK;}/************************************************************************ *  Method: *              CAudioOutQNX::_Imp_GetAudioFd *      Purpose: */INT16 CAudioOutQNX::_Imp_GetAudioFd(){    return m_wID;}/************************************************************************ *  Method: *              CAudioOutQNX::DoTimeSyncs *      Purpose: *		Manual time syncs! Fork! */void CAudioOutQNX::DoTimeSyncs(){    ReschedPlaybackCheck();	OnTimeSync();    return;}/************************************************************************ *  Method: *              CAudioOutQNX::GetPlaybackBytes *      Purpose: *		Get the number of bytes played since last open() was *		called. This ioctl() returns funky values sometimes?!@% */ULONG32 CAudioOutQNX::GetPlaybackBytes(){	snd_pcm_playback_status_t info;	memset( &info,0, sizeof(info));	if ( ioctl (m_wID, SND_PCM_IOCTL_PLAYBACK_STATUS, &info) != -1 )		return info.scount;	// If ioctl failed, just guess the value    int bytes = m_ulTotalWritten - m_ulGranularity / 2;    if (bytes < 0) 		bytes = 0;	return (ULONG32) bytes; }ULONG32 CAudioOutQNX::_GetPlaybackBuffer( ){	return( m_ulTotalWritten - GetPlaybackBytes( ) );}/************************************************************************ *  Method: *              CAudioOutQNX::ReschedPlaybackCheck() *      Purpose: *		Reschedule playback callback. */HX_RESULT CAudioOutQNX::ReschedPlaybackCheck(){    HX_RESULT theErr = HXR_OK;    if (m_bCallbackPending)		return theErr;    /* Put this back in the scheduler.     */    HXPlaybackCountCb* pCallback = 0;    pCallback = new HXPlaybackCountCb;    if (pCallback)    {        *m_pPlaybackCountCBTime += (int) (1000 * m_ulGranularity);        pCallback->m_pAudioDeviceObject = this;        m_bCallbackPending = TRUE;        m_PendingCallbackID = m_pScheduler->AbsoluteEnter(pCallback,                        *((HXTimeval*) m_pPlaybackCountCBTime));    }    else    {        theErr = HXR_OUTOFMEMORY;    }    return HXR_OK;}UINT16	CAudioOutQNX::_NumberOfBlocksRemainingToPlay(void){    UINT32 			bytesBuffered = 0;    LISTPOSITION	i = m_pWriteList->GetHeadPosition();    while (i)    {		bytesBuffered += ((IHXBuffer *)m_pWriteList->GetAt(i)) -> GetSize();		m_pWriteList->GetNext(i);    }        bytesBuffered += (m_ulTotalWritten - GetPlaybackBytes());    return bytesBuffered / m_wBlockSize + 1;}// CAudioOutQNX::HXPlaybackCountCbCAudioOutQNX::HXPlaybackCountCb::HXPlaybackCountCb(BOOL timed) :     m_lRefCount (0)    ,m_pAudioDeviceObject (0)    ,m_timed(timed){}CAudioOutQNX::HXPlaybackCountCb::~HXPlaybackCountCb(){}/* * IUnknown methods *////////////////////////////////////////////////////////////////////////////      Method://              IUnknown::QueryInterface//      Purpose://              Implement this to export the interfaces supported by your //              object.//STDMETHODIMP CAudioOutQNX::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) CAudioOutQNX::HXPlaybackCountCb::AddRef(){    return InterlockedIncrement(&m_lRefCount);}///////////////////////////////////////////////////////////////////////////      Method://              IUnknown::Release//      Purpose://              Everyone usually implements this the same... feel free to use//              this implementation.//STDMETHODIMP_(ULONG32) CAudioOutQNX::HXPlaybackCountCb::Release(){    if (InterlockedDecrement(&m_lRefCount) > 0)    {        return m_lRefCount;    }    delete this;    return 0;}/* *      IHXPlaybackCountCb methods */STDMETHODIMP CAudioOutQNX::HXPlaybackCountCb::Func(void){    if (m_pAudioDeviceObject)    {	if(!m_timed)	{	    m_pAudioDeviceObject->_Imp_Write(NULL);	}	else	{	    m_pAudioDeviceObject->m_bCallbackPending  = FALSE;	    m_pAudioDeviceObject->_Imp_Write(NULL);	    m_pAudioDeviceObject->DoTimeSyncs();	}    }    return HXR_OK;}/************************************************************************ *  Method: *              CAudioOutQNX::BuffersEmpty *      Purpose: */BOOL CAudioOutQNX::BuffersEmpty(){    snd_pcm_playback_status_t info;    if ( -1 == ioctl(m_wID, SND_PCM_IOCTL_PLAYBACK_STATUS, &info) )		return FALSE;    if ( info.queue )		return FALSE;    return TRUE;}void CAudioOutQNX::OpenMixer(){	int								i;	struct snd_mixer_info_t 		info;	struct snd_mixer_channel_info_t cinfo;    //    // return if the mixer is already opened    //    if (m_bMixerPresent)		return;    mixm_wID = open ( m_DevCtlName, O_RDWR );	if ( -1 == ioctl( mixm_wID, SND_MIXER_IOCTL_INFO, &info ) )	{		CloseMixer( );		return;	}        if (mixm_wID > 0)    {		/* find pcm channel */		memset( &cinfo, 0, sizeof( cinfo ) );		for ( i = 0; i < info.channels; i++ )		{			cinfo.channel = i;			if ( -1 == ioctl( mixm_wID, SND_MIXER_IOCTL_CHANNEL_INFO, &cinfo ) )			{				continue;			}			if ( 0 == strcmp( (char *)cinfo.name, SND_MIXER_ID_PCM ) ) 			{				m_wPCMChannel = i;				break;			}		}	}	if ( m_wPCMChannel > 0 )	{		m_bMixerPresent = 1;    }    else    {		CloseMixer( );		m_bMixerPresent = 0;    }}void CAudioOutQNX::CloseMixer(){    // Close the mixer device.    if ( mixm_wID >= 0 )     {		close ( mixm_wID );		mixm_wID = -1;    }}

⌨️ 快捷键说明

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