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

📄 winaudio.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	default:		    theErr = HXR_OUTOFMEMORY;	break;    }#if defined(_WIN32) && !defined(_WINCE)	if ( !theErr )	{	    if (!zm_bMixerVolSupportChecked)	    {		CheckForVolumeSupport();	    }	}#endif    return theErr;}HX_RESULT CAudioOutWindows::_Imp_Close(){#ifdef _TESTING	if ( m_audfile > 0 ) 		close(m_audfile);	m_audfile = -1;#endif zm_bClosed = TRUE;    if (m_hWave)     {	// NOTE: Before we can close, we need to reset!	Reset();	m_pMutex->Lock();	if (m_pWaveHdrs)	{	    UINT16 unWHIndex;	    // Unprepare the individual headers	    for (unWHIndex = 0; unWHIndex < m_unAllocedBufferCnt; ++unWHIndex)	    {    		CWaveHeader* pWaveHeader = &m_pWaveHdrs[unWHIndex];		if (pWaveHeader->m_pPrepared)		{		    LPWAVEHDR lpwHeader = LPWAVEHDR(&pWaveHeader->m_WAVEHDR);		    		    // By now all headers should be marked as done because they		    // are back from the audio device or prepared because we		    // prepared them but never used them		    HX_ASSERT(lpwHeader->dwFlags & WHDR_DONE ||			lpwHeader->dwFlags & WHDR_PREPARED);		    //OutputDebugString("BEFORE CALL TO:waveOutUnprepareHeader\r\n");		    HX_VERIFY(MMSYSERR_NOERROR == waveOutUnprepareHeader(m_hWave, 					LPWAVEHDR(&pWaveHeader->m_WAVEHDR), sizeof(WAVEHDR)));		    //OutputDebugString("AFTER CALL TO:waveOutUnprepareHeader\r\n");		    pWaveHeader->m_pPrepared = FALSE;		}	    }	}		if (m_ppAllocedBuffers)	{	    UINT16 unIndex;	    for (unIndex = 0; unIndex < m_unAllocedBufferCnt; unIndex++)	    {		delete[] m_ppAllocedBuffers[unIndex];	    }	    delete[] m_ppAllocedBuffers;	    m_ppAllocedBuffers = NULL;	}	m_rAvailBuffers.FlushQueue();	m_UsedBuffersList.RemoveAll();	m_unAllocedBufferCnt = 0;		m_pMutex->Unlock();	for (int i = 0; 		i < 5 && (WAVERR_STILLPLAYING == waveOutClose( m_hWave )); ++i)	{	    waveOutReset( m_hWave );	}	m_hWave = NULL;	if (m_pWaveHdrs)	{	    delete[] m_pWaveHdrs;	    m_pWaveHdrs = NULL;	}    }    UnRegister();    m_bIsFirstPacket	= TRUE;    m_bInitialized	= FALSE;    return HXR_OK;}HX_RESULT CAudioOutWindows::_Imp_Write(     const HXAudioData* pAudioOutHdr ){    BOOL	    bTemp;    CWaveHeader*    pWaveHeader;    MMRESULT	    res;    ULONG32	    ulBufLen = 0;    UCHAR*	    pBuffer = 0;    if (pAudioOutHdr->pData)    {	pBuffer	 = pAudioOutHdr->pData->GetBuffer();	ulBufLen = pAudioOutHdr->pData->GetSize();    }    if (!m_bInitialized)    {	m_bInitialized = AllocateBuffers(MAX_REASONABLE_BUFFS,(UINT16)ulBufLen);    }    if (!m_bInitialized) return HXR_FAILED;    m_pMutex->Lock();    pWaveHeader = (CWaveHeader*)m_rAvailBuffers.DeQueuePtr(bTemp);    m_pMutex->Unlock();    if (!bTemp)     {	return HXR_WOULD_BLOCK;    }#ifdef _TESTING    if ( m_audfile > 0 )        write(m_audfile, pBuffer,ulBufLen); #endif    UINT32 ulBytesToCopy = ulBufLen;    HX_ASSERT(ulBytesToCopy <= pWaveHeader->m_WAVEHDR.dwBufferLength);    if (ulBytesToCopy > pWaveHeader->m_WAVEHDR.dwBufferLength)        ulBytesToCopy = pWaveHeader->m_WAVEHDR.dwBufferLength;    pWaveHeader->m_bAvail = FALSE;        memcpy(pWaveHeader->m_WAVEHDR.lpData, pBuffer, HX_SAFESIZE_T(ulBytesToCopy)); /* Flawfinder: ignore */    pWaveHeader->m_ulTimeEnd = pAudioOutHdr->ulAudioTime;    /* This is needed for LIVE where audio packets may not start     * from timestamp 0     */    if (m_bIsFirstPacket)    {	m_bIsFirstPacket = FALSE;    }    //OutputDebugString("BEFORE CALL TO:waveOutWrite\r\n");    res = waveOutWrite(m_hWave, LPWAVEHDR(&pWaveHeader->m_WAVEHDR), sizeof(WAVEHDR));    m_pMutex->Lock();    m_UsedBuffersList.AddTail(pWaveHeader);    m_pMutex->Unlock();    //OutputDebugString("AFTER CALL TO:waveOutWrite\r\n");    return HXR_OK;}HX_RESULT CAudioOutWindows::_Imp_Seek(ULONG32 ulSeekTime){    return HXR_OK;}HX_RESULT CAudioOutWindows::_Imp_Pause(){    MMRESULT res;    if (m_hWave)     {//	OutputDebugString("BEFORE CALL TO:waveOutPause\r\n");        res = waveOutPause(m_hWave);	//OutputDebugString("AFTER CALL TO:waveOutPause\r\n");    }    return HXR_OK;}HX_RESULT CAudioOutWindows::_Imp_Resume(){    MMRESULT res;    if (m_hWave)     {//	OutputDebugString("BEFORE CALL TO:waveOutRestart\r\n");        res = waveOutRestart(m_hWave);	//OutputDebugString("AFTER CALL TO:waveOutRestart\r\n");    }    OnTimeSync();    return HXR_OK;}HX_RESULT CAudioOutWindows::_Imp_Reset(){//{FILE* f1 = ::fopen("c:\\audio.txt", "a+"); ::fprintf(f1, "Reset: \n");::fclose(f1);}    MMRESULT res;    m_bResetting = TRUE;    if (m_hWave)     {//	OutputDebugString("BEFORE CALL TO:waveOutReset\r\n");	res = waveOutReset(m_hWave);	// Need to be turned on after RC2000 XXXRA	// commenting it out for safety reasons.	//_Imp_Pause();	//OutputDebugString("AFTER CALL TO:waveOutReset\r\n");	m_bIsFirstPacket	= TRUE;	m_llDeviceBytesPlayed = 0;	m_llDeviceSamplesPlayed = 0;	m_ulLastDeviceBytesPlayed = 0;	m_ulLastDeviceSamplesPlayed = 0;	m_ulDevPosRollOver = 0;    }    // First return the unused buffers to the available queue    // Then pump out the wom_dones.    //    _NumberOfBlocksRemainingToPlay();    // Make sure we handle all the wave-done messages,    // but establish a time limit to cope with the     // unpredictable nature of Windows. Wait for up    // to 1 second.    DWORD start = HX_GET_TICKCOUNT();    if (m_hWnd)    {	do	{	    MSG msg;	    // Yield, and try to pump WOM_DONE's to the Async Window!	    while (PeekMessage(&msg, m_hWnd, MM_WOM_DONE, MM_WOM_DONE, PM_REMOVE))	    {		if(msg.message == WM_QUIT) 		{   		    // When peeking WM_QUIT message in the main thread of an application 		    // we have to put it back into message queue to allow the application 		    // to exit correctly. SB		    PostQuitMessage(0);		    break;		}		else		{		    DispatchMessage(&msg);		}	    }	    if (CALCULATE_ELAPSED_TICKS(start, HX_GET_TICKCOUNT()) >= 1000)	    {		// Brute force, mark them as free... We probably 		// could do something better here, like close and		// reopen the wave device... but this is what the		// old code did, so lets try it as well!		ULONG32 lTmp;		m_pMutex->Lock();		for (lTmp = 0; m_pWaveHdrs && (lTmp < m_unAllocedBufferCnt); ++lTmp)		{		    CWaveHeader *pwhDone = &m_pWaveHdrs[lTmp];		    if (pwhDone && pwhDone->m_bAvail == FALSE)		    {			pwhDone->m_bAvail = TRUE;			m_rAvailBuffers.EnQueuePtr(pwhDone);		    }		}		m_pMutex->Unlock();		//OutputDebugString("Bail WOM_DONE vacuum, passed timeout!\r\n");		break;	    }	}	while (_NumberOfBlocksRemainingToPlay());    }    //OutputDebugString("END: WOM_DONE vacuum!\r\n");    m_bResetting = FALSE;    return HXR_OK;}HX_RESULT CAudioOutWindows::_Imp_Drain(){    return HXR_OK;}HX_RESULT CAudioOutWindows::_Imp_CheckFormat(     const HXAudioFormat* pFormat ){#if defined(_WIN32)    LPWAVEFORMATEX	wavePtr;#elif defined( _WINDOWS )    LPWAVEFORMAT	wavePtr;#endif    m_WaveFormat.SetFormat(pFormat->ulSamplesPerSec, pFormat->uChannels, pFormat->uBitsPerSample);   	// Get the Windows style wave format!    wavePtr = m_WaveFormat.GetWaveFormat();    MMRESULT wRet = waveOutOpen(&m_hWave,WAVE_MAPPER,wavePtr,		        0, (DWORD)this,WAVE_FORMAT_QUERY);    switch (wRet)    {	case MMSYSERR_NOERROR:	    return( HXR_OK );	case MMSYSERR_ALLOCATED:    return( HXR_AUDIO_DRIVER );	case MMSYSERR_NOMEM:	    return( HXR_OUTOFMEMORY );	case MMSYSERR_BADDEVICEID:  return( HXR_AUDIO_DRIVER );	case WAVERR_BADFORMAT:	    return( HXR_AUDIO_DRIVER );	case WAVERR_SYNC:	    return( HXR_AUDIO_DRIVER );	case MMSYSERR_NODRIVER:	    return( HXR_AUDIO_DRIVER );	default:		    return( HXR_AUDIO_DRIVER );    }}BOOL CAudioOutWindows::AllocateBuffers(UINT16 unNumBuffers, UINT16 unBufSize){    UCHAR**	    ppWaveBuffers;    CWaveHeader*    pWaveHdrs;    MMRESULT	    tRes;    UINT16	    unWHIndex;    ppWaveBuffers = NULL;    pWaveHdrs = NULL;    // Allocate memory for wave block headers and for wave data.    if (!(pWaveHdrs = new CWaveHeader [unNumBuffers]))    {        goto OnError;    }    //	This array holds the buffer pointers so we can free them later    //	There NO other purpose for this array.	    if (!(ppWaveBuffers = new UCHAR*[unNumBuffers]))    {	goto OnError;    }    memset( ppWaveBuffers, 0, unNumBuffers * sizeof( UCHAR* ) );				        // Mark all wave block headers as available, and point them    // at their respective wave data blocks.    // AND enqueue them in the AvailableBuffers Queue.    // AND allocate their buffers!!!    for (unWHIndex = 0; unWHIndex < unNumBuffers; unWHIndex++)     {        UCHAR*	pBuff;	// Try to allocate the individual audio buffers    	pBuff = new UCHAR [unBufSize];	if (!pBuff)	{	    goto OnError;    	}	ppWaveBuffers[unWHIndex] = pBuff;	CWaveHeader* pWaveHeader = &pWaveHdrs[unWHIndex];	// Init some header data before Preparing the header	pWaveHeader->m_WAVEHDR.lpData = (char *)pBuff;	pWaveHeader->m_WAVEHDR.dwUser = DWORD(pWaveHeader);	pWaveHeader->m_WAVEHDR.dwFlags = 0L;	pWaveHeader->m_WAVEHDR.dwBufferLength = unBufSize;	pWaveHeader->m_WAVEHDR.dwLoops = 0L;	pWaveHeader->m_bAvail = TRUE;	pWaveHeader->m_pUser = this;	m_pMutex->Lock();	m_rAvailBuffers.EnQueuePtr(pWaveHeader);	m_pMutex->Unlock();	//OutputDebugString("BEFORE CALL TO:waveOutPrepareHeader\r\n");        tRes = waveOutPrepareHeader(m_hWave, LPWAVEHDR(&pWaveHeader->m_WAVEHDR), sizeof(WAVEHDR));	//OutputDebugString("AFTER CALL TO:waveOutPrepareHeader\r\n");	if (tRes != MMSYSERR_NOERROR)	{	    goto OnError;	}	else	{	    pWaveHeader->m_pPrepared = TRUE;    	}    }    m_unAllocedBufferCnt = unNumBuffers;    m_unAllocedBuffSize = unBufSize;    m_pWaveHdrs = pWaveHdrs;    m_ppAllocedBuffers = ppWaveBuffers;    return TRUE;OnError:    if (pWaveHdrs)    {	// Unprepare the individual headers	for (unWHIndex = 0; unWHIndex < unNumBuffers; ++unWHIndex)	{    	    CWaveHeader* pWaveHeader = &pWaveHdrs[unWHIndex];	    if (pWaveHeader->m_pPrepared)	    {		//OutputDebugString("BEFORE CALL TO:waveOutUnprepareHeader\r\n");		tRes = waveOutUnprepareHeader(m_hWave, 				    LPWAVEHDR(&pWaveHeader->m_WAVEHDR), sizeof(WAVEHDR));		//OutputDebugString("AFTER CALL TO:waveOutUnprepareHeader\r\n");		pWaveHeader->m_pPrepared = FALSE;	    }	}	delete[] pWaveHdrs;	pWaveHdrs = NULL;    }    //	ppWaveBuffers actually points at an array of pointers that need to be free'd    if (ppWaveBuffers)    {	//	Free the individual buffers	for (unWHIndex = 0; unWHIndex < unNumBuffers; ++unWHIndex)	{	    UCHAR* pBuff;	    pBuff = ppWaveBuffers[unWHIndex];	    if (pBuff)	    {    		delete[] pBuff;	    }	}	//	Now free ppWaveBuffers itself	delete[] ppWaveBuffers;	ppWaveBuffers = NULL;    }    return FALSE;}/************************************************************************ *  Method: *              CAudioOutWindows::_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 CAudioOutWindows::_Imp_GetCurrentTime(         ULONG32& ulCurrentTime){	ULONG32 ulDeviceTime = 0;	ULONG32 ulDeviceBytesPlayed = 0;	UINT32	ulDeviceSamplesPlayed = 0;	WAVEFMTPTR pWFmt = m_WaveFormat.GetWaveFormat();	// Set the time to the playback time of the	// wave device since it's the most accurate.	MMTIME mmTime;

⌨️ 快捷键说明

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