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

📄 macaudio.cp

📁 linux下的一款播放器
💻 CP
📖 第 1 页 / 共 2 页
字号:
	if (zm_pMutex)	{	    zm_pMutex->Lock();	}#endif#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)	    if ( !pAudioOut->m_bAudioCallbacksAreAlive )	    {		DebugStr( "\pDeferredTaskCallback -- m_bAudioCallbacksAreAlive not true!;g" );	    }#endif	while (gActiveAudioDevice &&	       pAudioOut->m_pPendingCallbackList && 	      !pAudioOut->m_pPendingCallbackList->IsEmpty())	{		SndCommand*	cmd = (SndCommand*) pAudioOut->m_pPendingCallbackList->RemoveHead();		BOOL bIsEmpty = pAudioOut->m_pPendingCallbackList->IsEmpty();		#ifdef THREADS_SUPPORTED		// we used to deadlock here; we'd grab the audio mutex before the core mutex,		// which is not how the rest of this class operates		if (zm_pMutex)		{		    zm_pMutex->Unlock();		}#endif		/* Send time sync for ONLY the last pending audio callback */		pAudioOut->ProcessCmd(cmd, bIsEmpty);				     	delete cmd;#ifdef THREADS_SUPPORTED		if (zm_pMutex)		{		    zm_pMutex->Lock();		}#endif	}		/* It is possible that on a timesync, a renderer may issue a hyper navigate request.	 * This may result in leaving the currently active page (thereby unloading 	 * the embedded player and the core. We would have destructed the CMacAudio class	 * in this case.	 */ 	if (!gActiveAudioDevice)	{	    goto cleanup;	}		pAudioOut->m_bDeferredTaskPending = FALSE;	cleanup:	#ifdef THREADS_SUPPORTED	if (zm_pMutex)	{	    zm_pMutex->Unlock();	}#endif#ifndef _MAC_UNIX	HXMM_INTERRUPTOFF();#endif}voidCAudioOutMac::ProcessCmd(SndCommand* cmd, BOOL bSendTimeSync /*= TRUE*/){	CWaveHeader	*wh = (CWaveHeader *) cmd->param2;	if (wh)	{		wh->Release(cmd->param1, bSendTimeSync);	}}	/*--------------------------------------------------------------------------|	CAudioOutMac--------------------------------------------------------------------------*/UINT16 CAudioOutMac::NUM_WAVEHDRS = 12;	// was 30CAudioOutMac::CAudioOutMac ()	: chan (nil)	, mlpWaveHdrs (NULL)	, mcbPlaying (0)	, mPaused (TRUE)	, m_uNumBlocksInDevice(0)	, m_bFirstPacket(TRUE)	, m_ulTimeOfFirstPacket(0L)	, m_pPendingCallbackList(NULL)	, m_bDeferredTaskPending(FALSE)	, m_bAudioCallbacksAreAlive(FALSE)	, m_bIsQuitting(FALSE)	, m_millisecondsIntoClip(0.0)	, m_pCallback(NULL)	, m_pInterruptState(NULL){ /* begin CAudioOutMac */	mDeferredTaskRec=(DeferredTask*)NewPtrClear(sizeof(DeferredTask));		mDeferredTaskRec->qType=dtQType;	mDeferredTaskRec->dtAddr=CAudioOutMac::gDeferredTask;    mDeferredTaskRec->dtParam= (long) this;    	// Gestalt-based code that remembers potential deferred tasks for emergency removal	#ifndef _MAC_UNIX	Handle dtGestaltHandle = nil;	OSErr err = Gestalt( kLetInterruptsFinishBeforeQuittingGestalt, (long*)&dtGestaltHandle );	if ( err != noErr )	{#if defined( _CARBON )	    MacAudioInitInterfaceLibProcPtrs();	    if (gMacAudioNewHandleSysProc)	    {		dtGestaltHandle = (*gMacAudioNewHandleSysProc)( 0 );	    }	    if (!dtGestaltHandle)	    {		dtGestaltHandle = NewHandle( 0 );	    }#else	    dtGestaltHandle = NewHandleSys( 0 );#endif	    if ( dtGestaltHandle )	    {		NewGestaltValue( kLetInterruptsFinishBeforeQuittingGestalt, (long)dtGestaltHandle );	    }	}	if ( dtGestaltHandle )	{	    GestaltDeferredStruct gds;	    gds.quitting = &m_bIsQuitting;	    gds.pending = &m_bAudioCallbacksAreAlive;	    GetCurrentProcess(&(gds.psn));	    PtrAndHand( &gds, dtGestaltHandle, sizeof(gds) );	}#endif	#ifdef THREADS_SUPPORTED	if (!zm_pMutex)	{	    HXMutex::MakeMutex(zm_pMutex);	}#endif    gActiveAudioDevice = this;} /* end CAudioOutMac *//*--------------------------------------------------------------------------|	~CAudioOutMac--------------------------------------------------------------------------*/CAudioOutMac::~CAudioOutMac (){ /* begin ~CAudioOutMac */ 		Abort ();#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)	BOOL bWaitedForPending = FALSE;	if ( m_bAudioCallbacksAreAlive )	{	    DebugStr( "\pCAudioOutMac dtor -- m_bAudioCallbacksAreAlive still true!;g" );	    bWaitedForPending = TRUE;	}#endif        m_bIsQuitting = TRUE;    // sit-n-spin awaiting interrupts to finish.    for ( int i = 0; i < 10; i++ )    {	unsigned long dummyTix;	Delay( 6, &dummyTix );	if ( !m_bAudioCallbacksAreAlive )	{	    i = 10;	}    }    #if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)	if ( bWaitedForPending )	{	    if ( m_bAudioCallbacksAreAlive )	    {		DebugStr( "\ptasks STILL pending! This is gonna hurt...;g" );	    }	    else	    {		DebugStr( "\pSuccessfully purged pending callbacks;g" );	    }	}#endif	if (mDeferredTaskRec)	{	// first ensure that the Gestalt handle doesn't think it's	// here any more.	#ifndef _MAC_UNIX	Handle dtGestaltHandle = nil;	Gestalt( kLetInterruptsFinishBeforeQuittingGestalt, (long*)&dtGestaltHandle );	if ( dtGestaltHandle )	{	    // XXXNH: only look at tasks for this process	    ProcessSerialNumber psn;	    GetCurrentProcess(&psn);		    // zip through and if an entry equals this deferred task,	    // simply zero it out. We won't worry about shuffling	    // the handle size at this juncture.	    long hSize = GetHandleSize( dtGestaltHandle );	    GestaltDeferredStruct* currentPtr = (GestaltDeferredStruct*)*dtGestaltHandle;	    for ( int i = 0; i < hSize / sizeof(GestaltDeferredStruct); i++ )	    {	        unsigned char bSameProcess = FALSE;	        SameProcess(&(currentPtr[i].psn), &psn, &bSameProcess);	        		if (bSameProcess && 		    currentPtr[i].quitting == &m_bIsQuitting && 		    currentPtr[i].pending == &m_bAudioCallbacksAreAlive )		{		    currentPtr[i].quitting = NULL;		    currentPtr[i].pending = NULL;		}	    }    	}#endif		::DisposePtr	((Ptr)mDeferredTaskRec);	}    			CleanupPendingLists();		HX_DELETE(m_pPendingCallbackList);		gActiveAudioDevice = NULL;		HX_RELEASE(m_pScheduler);	HX_RELEASE(m_pInterruptState);} /* end ~CAudioOutMac */UINT16 CAudioOutMac::m_uzVolume = 50;HX_RESULT   	CAudioOutMac::_Imp_Open( const HXAudioFormat* pFormat ){    /*    **	Open the sound channel.    */    NUM_WAVEHDRS = 45; //params->numBufs;    CWaveHeader::WAVE_BLOCKSIZE = pFormat->uMaxBlockSize;	    if (chan) CWaveHeader::DisposeChannel (chan);    m_bAudioCallbacksAreAlive = FALSE;	    chan = CWaveHeader::NewChannel ();    if (!chan) 	return (HX_AUDIO_DRIVER_ERROR);		if (!m_pPendingCallbackList)	{	    m_pPendingCallbackList = new CHXSimpleList;	}	    ULONG32 nSampleRate = pFormat->ulSamplesPerSec;    ULONG32 nBlockSize = pFormat->uMaxBlockSize;#if powerc && FORCE_RATE_CONVERSION	// if we are on a PowerPC we will do our own sample rate conversion	// since the Apple version gives us a lot of pops and aliasing    ULONG32 sysSampleRate = ::USound::GetSystemSampleRate(chan);		// Note: we currently have to HACK 11227 and 22254 sample rates on	// old macs to 11025 and 22050	    switch(sysSampleRate)    {	case 11227:	    sysSampleRate = 11025;	    break;				case 22254:	    sysSampleRate = 22050;	    break;    }			// we only have a problem if the sample rate is <= 32000 Hz. (sigh!)    if(nSampleRate <= 32000)    {	if(sysSampleRate > 0 && nSampleRate != sysSampleRate)	{	    UINT16 bytesPerSample = pFormat->wBitsPerSample > 8 ? 2 : 1;	    UINT16 frameSize = bytesPerSample * pFormat->wChannels;	    ULONG32 bytesPerSecond = (ULONG32) (nSampleRate * frameSize);				    float bufDuration = (float)pFormat->uMaxBlockSize/(float)bytesPerSecond;				    // calculate the bytesPerSecond of the system sample rate				    bytesPerSecond = (ULONG32) (sysSampleRate * frameSize);				    // update the buffer size to handle the new sample rate	    nBlockSize = bytesPerSecond * bufDuration;				    // round the buffersize to a framesize	    nBlockSize = ((nBlockSize/frameSize) * frameSize) + frameSize;	    nSampleRate = sysSampleRate;	    //pFormat->ulSamplesPerSec = sysSampleRate;	}    }#ifndef MAC_RELEASE#if 0	char s[256];	::sprintf(s,"sample rate %ld",sysSampleRate);	::c2pstr(s);	DebugStr((UCHAR *)s);#endif#endif // MAC_RELEASE#endif // powerc && FORCE_RATE_CONVERSION//    SetVolume(pFormat->volume);    _Imp_SetVolume(m_uzVolume);    	/*	**	Allocate memory for wave block headers and for wave data.	*/	    if (NULL == mlpWaveHdrs)     {	if (NULL == (mlpWaveHdrs = new CWaveHeader [NUM_WAVEHDRS])) 	    return (HX_MEMORY_ERROR);			for (short iwh = 0; iwh < NUM_WAVEHDRS; iwh++) 	{	    CWaveHeader	*pwh = GetWaveHeader (iwh);	    if (pwh) 	    {		pwh->SetOutput (this);		switch (pwh->Allocate (nBlockSize, nSampleRate,			pFormat->uChannels,pFormat->uBitsPerSample)) 		{		    case noErr:			break;						    case memFullErr:			return (HX_MEMORY_ERROR);						    default:			return (HX_AUDIO_DRIVER_ERROR);		} 	    } 	}     } 		/*	**	Indicate that no audio blocks are currently playing.	*/    mcbPlaying = 0;    mPaused = FALSE;        if (!m_pScheduler && m_pContext)    {	m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler);	m_pContext->QueryInterface(IID_IHXInterruptState, (void**) &m_pInterruptState);    }        return (HX_NO_ERROR);}HX_RESULT   	CAudioOutMac::_Imp_Close( void ){    Abort();    return HXR_OK;}HX_RESULT   	CAudioOutMac::_Imp_Pause( void ){    mPaused = TRUE;        if (OkToPauseResume(FALSE))    {	// Stop playback	if (chan != NULL) 	DoImmediate (pauseCmd);    }    	    return HXR_OK;}HX_RESULT   	CAudioOutMac::_Imp_Resume( void ){    mPaused = FALSE;    if (OkToPauseResume(TRUE))    {	if (chan != NULL) 	{	DoImmediate (resumeCmd);	}		this->OnTimeSync();    }        return HXR_OK;    }HX_RESULT   	CAudioOutMac::_Imp_Write( const HXAudioData* pAudioOutHdr ){    HX_RESULT err = HX_NO_ERROR;        //    CWaveHeader	*pwh = GetWaveHeader(0);;    CWaveHeader	*pwh=NULL;	    Boolean found = FALSE;    void* pBuffer = NULL;		    for (short iwh = 0; iwh < NUM_WAVEHDRS && !found; iwh++)     {	pwh = GetWaveHeader(iwh);	found = pwh && pwh->Available ();    }	    if (found)    {	pBuffer = pwh->get_buffer();    }    else    {	return playError;    }    if(pwh == 0)    {	return (playError);    }	    char* pData = 0;    pData = (char*)pAudioOutHdr->pData->GetBuffer();    ULONG32 nLen = pAudioOutHdr->pData->GetSize();    if (pBuffer)    {    	memcpy(pBuffer, pData, nLen);    		if (noErr != pwh->PlayBuffer ((char*)pBuffer, nLen, pAudioOutHdr->ulAudioTime))	    err = (playError);    }	if (!err)	{		m_uNumBlocksInDevice++;		if(m_bFirstPacket)		{			m_bFirstPacket = FALSE;			m_ulTimeOfFirstPacket = pAudioOutHdr->ulAudioTime;		}			}    return err;}HX_RESULT   	CAudioOutMac::_Imp_Reset( void ){    // Stop playback    if (chan != NULL) {	DoImmediate (pauseCmd);	DoImmediate (flushCmd);	DoImmediate (quietCmd);    } /* if */    m_ulCurrentTime = 0;    m_bFirstPacket = TRUE;        // Mark blocks as available.    ReleaseBlocks (CWaveHeader::kResetRelease);    m_uNumBlocksInDevice = 0;        CleanupPendingLists();		    return HX_NO_ERROR;}HX_RESULT  	CAudioOutMac::_Imp_Drain( void ){    return HX_NO_ERROR;}BOOL 		CAudioOutMac::_Imp_SupportsVolume( void ){    return TRUE;}UINT16   	CAudioOutMac::_Imp_GetVolume(){#if 0    unsigned long	volume=0;    SndCommand		theCmd;    theCmd.cmd = getVolumeCmd;    theCmd.param1 = 0;    theCmd.param2 = volume;	// queue volume command in channel    ::SndDoImmediate(chan,&theCmd);    return  (UINT16) volume;#endif    return m_uzVolume;}HX_RESULT   	CAudioOutMac::_Imp_SetVolume( const UINT16 uVolume ){    SndCommand		theCmd;    unsigned long	volume;    unsigned long	leftVolume, rightVolume;	//    if(uVolume < 0) uVolume = 0;        if(chan)    {#if defined( _CARBON ) || defined( _MAC_UNIX )	leftVolume = rightVolume = (long) uVolume * 5; //uVolume is between 0 and 100	volume = (rightVolume << 16) + leftVolume;	theCmd.cmd = volumeCmd;	theCmd.param1 = 0;	theCmd.param2 = volume;	// queue volume command in channel	::SndDoImmediate(chan,&theCmd);#else#if OLDROUTINENAMES && !GENERATINGCFM	if (USound::CheckSMVersion () < 3)		::SetSoundVol (uVolume);#else	leftVolume = rightVolume = (long) uVolume * 5; //uVolume is between 0 and 100	volume = (rightVolume << 16) + leftVolume;	theCmd.cmd = volumeCmd;	theCmd.param1 = 0;	theCmd.param2 = volume;	// queue volume command in channel	::SndDoImmediate(chan,&theCmd);#endif#endif    }        m_uzVolume = uVolume;    return HXR_OK;	}HX_RESULT   	CAudioOutMac::_Imp_CheckFormat( const HXAudioFormat* pFormat){    return HX_NO_ERROR;}HX_RESULT CAudioOutMac::_Imp_Seek(ULONG32 ulSeekTime){    m_ulCurrentTime = 0;    return HX_NO_ERROR;}/*---------------------------------------------------------------------------|	ReleaseBlocks||		Frees the blocks manually--------------------------------------------------------------------------*/void CAudioOutMac::ReleaseBlocks (		short	releaseCode)		{ /* begin ReleaseBlocks */			// Mark blocks as available.		for (short iwh = 0; iwh < NUM_WAVEHDRS; iwh++) {			CWaveHeader	*pwh = GetWaveHeader (iwh);				//			if (pwh && !pwh->Available ())			if (pwh)				pwh->Release (releaseCode);			} /* for */					m_millisecondsIntoClip = 0.0;	} /* end ReleaseBlocks *//*---------------------------------------------------------------------------|	DoImmediate||		Executes a sound command--------------------------------------------------------------------------*/OSErr CAudioOutMac::DoImmediate (		short	cmd,	short	param1/*= 0*/,	long	param2/*= 0L*/)		{ /* begin DoImmediate */				SndCommand	sndCmd;				sndCmd.cmd = cmd;		sndCmd.param1 = param1;		sndCmd.param2 = param2;				return ::SndDoImmediate (chan, &sndCmd);				} /* end DoImmediate *//*---------------------------------------------------------------------------|	Abort||		Halts playback and shuts down--------------------------------------------------------------------------*/void CAudioOutMac::Abort (void)		{ /* begin Abort */			// Stop playback		if (chan != NULL) {			//	Kludge around usual SM unreliability

⌨️ 快捷键说明

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