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

📄 macaudio.cp

📁 linux下的一款播放器
💻 CP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: macaudio.cp,v 1.5.32.1 2004/07/09 02:01:22 hubbe Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** */////	macaudio.cp// #include <stdio.h>#include "macaudio.h"#include "USound.h"		#ifndef _MAC_MACHO#include <AIFF.h>#include <fixmath.h>#endif#include "hxtypes.h"		#include "hxerrors.h"		#include "hxcom.h"#include "hxausvc.h"#include "auderrs.h"#include "hxaudev.h"#include "hxslist.h"#include "hxtick.h"		#include "chxpckts.h"#ifdef THREADS_SUPPORTED#include "hxthread.h"#endif#include "hxmm.h"//#define LOG_MULTIPLE_DEFERRED_TASKS 1BOOL 				gSoundCallbackTime = FALSE;#if defined( _CARBON ) || defined( _MAC_UNIX )DeferredTaskUPP		CAudioOutMac::gDeferredTask = NewDeferredTaskUPP(CAudioOutMac::DeferredTaskCallback);#elseDeferredTaskUPP		CAudioOutMac::gDeferredTask = NewDeferredTaskProc(CAudioOutMac::DeferredTaskCallback);#endif#ifdef THREADS_SUPPORTEDHXMutex*		CAudioOutMac::zm_pMutex = NULL;#endifCAudioOutMac*       gActiveAudioDevice = NULL;			    #if defined( _CARBON ) || defined( _MAC_UNIX )typedef pascal Handle (*MacAudioNewHandleSysProcPtr)(Size);CFragConnectionID gAudioInterfaceLibConnID = kInvalidID;MacAudioNewHandleSysProcPtr gMacAudioNewHandleSysProc = nil;bool gMacAudioTriedToInitialize = false;void MacAudioInitInterfaceLibProcPtrs(){	if (gMacAudioTriedToInitialize) return;	gMacAudioTriedToInitialize = true;	if (gAudioInterfaceLibConnID == kInvalidID)	{		GetSharedLibrary("\pInterfaceLib", kCompiledCFragArch, kReferenceCFrag,			&gAudioInterfaceLibConnID, nil, nil);	}		if (gAudioInterfaceLibConnID != kInvalidID)	{		OSErr err = noErr;				err = FindSymbol(gAudioInterfaceLibConnID, "\pNewHandleSys", (Ptr*)&gMacAudioNewHandleSysProc, nil);	}}#endif/*--------------------------------------------------------------------------|	CMacWaveFormat||		Default ctor.--------------------------------------------------------------------------*/CMacWaveFormat::CMacWaveFormat (void)	{ /* begin CMacWaveFormat */			SetFormatDflt ();		} /* end CMacWaveFormat *//*--------------------------------------------------------------------------|	~CMacWaveFormat||		dtor.--------------------------------------------------------------------------*/CMacWaveFormat::~CMacWaveFormat (void)	{ /* begin ~CMacWaveFormat */		} /* end ~CMacWaveFormat *//*--------------------------------------------------------------------------|	SetUpSound||		Formats a sound handle.--------------------------------------------------------------------------*/OSErr CMacWaveFormat::SetUpSound (	SndListHandle	sndHandle,	long			numBytes,	short			*headerLen,	long			*headerOffset)		{ /* begin SetUpSound */				OSErr	e = noErr;		long	response;				if (sampleSize > 8) {			if (USound::CheckSMVersion () < 3) {			    if ((::Gestalt(gestaltSoundAttr, &response) == noErr)			    	&& ((response & (1L << gestalt16BitSoundIO)) == 0))					return (noHardwareErr);				} /* if */							else {			    if ((::Gestalt(gestaltSoundAttr, &response) == noErr)			    	&& ((response & (1L << gestalt16BitAudioSupport)) == 0))					return (noHardwareErr);				} /* else */			} /* if */					if (noErr != (e = ::SetupSndHeader (sndHandle,										   numChannels,										   sampleRate,										   sampleSize,										   compressionType,										   baseFrequency,										   numBytes,										   headerLen)))			goto CleanUp;							   		if (noErr != (e = USound::GetSoundHeaderOffset (sndHandle, headerOffset)))			goto CleanUp;		CleanUp:			return (e);			} /* end SetUpSound *//*--------------------------------------------------------------------------|	SetHeaderLength [static]||		Formats a sound header for a given byte count.--------------------------------------------------------------------------*/OSErr CMacWaveFormat::SetHeaderLength (	SoundHeaderPtr	pSoundHeader,	long			numBytes)		{ /* begin SetHeaderLength */			switch (pSoundHeader->encode) {			case stdSH: 										/*standard sound header*/				pSoundHeader->length = numBytes;				break;							case extSH: 										/*extended sound header*/				{                                ExtSoundHeaderPtr	eh = (ExtSoundHeaderPtr) pSoundHeader;				eh->numFrames = numBytes / (eh->numChannels * (eh->sampleSize / 8));                                }				break;							case cmpSH:											/*compressed sound header*/				{                                CmpSoundHeaderPtr	ch = (CmpSoundHeaderPtr) pSoundHeader;				ch->numFrames = numBytes / (ch->numChannels * (ch->sampleSize / 8));                                }				break;							default:				return badFormat;			} /* switch */						return noErr;			} /* SetHeaderLength *//*--------------------------------------------------------------------------|	SetFormatDflt||		Sets up the default Sound header information.--------------------------------------------------------------------------*/void CMacWaveFormat::SetFormatDflt (void)	{ /* begin SetFormatDflt */				//mwf.wf.nAvgBytesPerSec = 22050;		//mwf.wf.nBlockAlign = 2;				numChannels = 1;					//mwf.wf.nChannels = 1;		sampleRate = Long2Fix (8000);		//mwf.wf.nSamplesPerSec = 8000;		//sampleRate = rate11025hz;			//mwf.wf.nSamplesPerSec = 11025;		sampleSize = 16;					//mwf.wBitsPerSample = 16;		compressionType = NoneType;			//mwf.wf.wFormatTag = WAVE_FORMAT_PCM;		baseFrequency = kMiddleC;			} /* end SetFormatDflt *//*--------------------------------------------------------------------------|	SetFormatDflt||		Sets up the default Sound header information.--------------------------------------------------------------------------*/void CMacWaveFormat::SetFormat (		ULONG32	inSampleRate,	UINT16 	channels,	UINT16  bitsPerSample)	{ 				numChannels = channels;							sampleRate = inSampleRate << 16L;				sampleSize = bitsPerSample;							compressionType = NoneType;					baseFrequency = kMiddleC;			}/*--------------------------------------------------------------------------|	CWaveHeader--------------------------------------------------------------------------*/CWaveHeader::CWaveHeader (void)	: soundA5 (0)	, state (kFreeState)	, waveOut (NULL)	, mMaxPlay (0)	, sndHandle (nil)	, mHeaderLen (0)	, mSoundHeader (nil)	{ /* begin CWaveHeader */				soundA5 = SetCurrentA5 ();			} /* end CWaveHeader */	/*--------------------------------------------------------------------------|	~CWaveHeader--------------------------------------------------------------------------*/CWaveHeader::~CWaveHeader (void)	{ /* begin ~CWaveHeader */				if (sndHandle) ::DisposeHandle ((Handle) sndHandle);		sndHandle = nil;			} /* end ~CWaveHeader */	/*--------------------------------------------------------------------------|	CWaveHeader--------------------------------------------------------------------------*/const	Size	CWaveHeader::kSndHeaderSize = 512;		UINT16	CWaveHeader::WAVE_BLOCKSIZE = 4096;OSErr CWaveHeader::Allocate (		UINT16	inMaxPlay,	float   sampleRate,	UINT16  channels,	UINT16  bitsPerSample)		{ /* begin Allocate */				OSErr	e = badFormat;				long	offset;				if (!waveOut)			goto CleanUp;				OSErr theError;		sndHandle = (SndListHandle) ::TempNewHandle (kSndHeaderSize + inMaxPlay, &theError);		if (!sndHandle)			goto CleanUp;        check_noerr (theError);		waveOut->wf.SetFormat ((long)sampleRate,channels,bitsPerSample);				if (noErr != (e = waveOut->wf.SetUpSound (sndHandle, inMaxPlay, &mHeaderLen, &offset)))			goto CleanUp;				::SetHandleSize ((Handle) sndHandle, mHeaderLen + inMaxPlay);		if (noErr != (e = MemError ()))			goto CleanUp;					mMaxPlay = inMaxPlay;		::MoveHHi ((Handle) sndHandle);		::HLock ((Handle) sndHandle);		mSoundHeader = (SoundHeaderPtr) ((*(Handle) sndHandle) + offset);			CleanUp:				return (e);			} /* end Allocate *//*--------------------------------------------------------------------------|	Release--------------------------------------------------------------------------*/void CWaveHeader::Release (short	releaseCode, BOOL bSendTimeSync /*= TRUE*/){ /* begin Release */	    if (kFreeState != state)     {	state = kFreeState;	if ((CWaveHeader::kResetRelease != releaseCode) &&		(CWaveHeader::kAbortRelease != releaseCode)) //cz 5/7/96	if (waveOut) waveOut->DonePlaying (cbPlaying, timeEnd,releaseCode == kCallBackRelease, bSendTimeSync);    } /* if */			    if (kAbortRelease == releaseCode)     {        	if (sndHandle) 	{	    ::DisposeHandle ((Handle) sndHandle);	    sndHandle=NULL;	}		sndHandle = nil;	mMaxPlay = 0;	mSoundHeader = nil;    } /* if */		} /* end Release *//*--------------------------------------------------------------------------|	PlayBuffer--------------------------------------------------------------------------*/OSErr CWaveHeader::PlayBuffer (		char		*pData,	UINT16		cbPlayingArg,	ULONG32		timeEndArg)		{ /* begin PlayBuffer */				OSErr		e = noErr;				SndCommand	cmd;						if (!waveOut)			return (badFormat);					if (kFreeState != state)			return (badFormat);					if (!sndHandle) 			return (nilHandleErr);				if (cbPlayingArg > mMaxPlay)			return (memFullErr);				if (noErr != (e = waveOut->wf.SetHeaderLength (mSoundHeader, cbPlayingArg)))			goto CleanUp;				if(pData != NULL)				::BlockMove (pData, (*(Handle) sndHandle) + mHeaderLen, cbPlayingArg);				cmd.cmd = bufferCmd;		cmd.param1 = 0;		cmd.param2 = (long) mSoundHeader;		if (noErr != (e = ::SndDoCommand (waveOut->chan, &cmd, TRUE))) goto CleanUp;					state = kQueuedState;		cbPlaying = cbPlayingArg;		timeEnd = timeEndArg;		waveOut->StartedPlaying (cbPlaying);				cmd.cmd = callBackCmd;		cmd.param1 = kCallBackRelease;		cmd.param2 = (long) this;		if (noErr != (e = ::SndDoCommand (waveOut->chan, &cmd, TRUE))) goto CleanUp;				waveOut->m_bAudioCallbacksAreAlive = TRUE;			CleanUp:			return (e);			} /* end PlayBuffer */	/*--------------------------------------------------------------------------|	NewChannel--------------------------------------------------------------------------*/SndChannelPtr CWaveHeader::NewChannel (void)	{ /* begin NewChannel */				SndChannelPtr		chan = nil;#if defined( _CARBON ) || defined( _MAC_UNIX )		SndCallBackUPP		userProc = NewSndCallBackUPP (Callback);#else		SndCallBackUPP		userProc = NewSndCallBackProc (Callback);#endif		//		if (noErr != ::SndNewChannel (&chan, sampledSynth, initStereo + initNoDrop + initNoInterp, userProc))		if (noErr != ::SndNewChannel (&chan, sampledSynth, initStereo, userProc))			chan = nil;				return chan;			} /* end NewChannel *//*--------------------------------------------------------------------------|	DisposeChannel--------------------------------------------------------------------------*/OSErr CWaveHeader::DisposeChannel (		SndChannelPtr	chan)		{ /* begin DisposeChannel */	OSErr e;			if(chan)		{			SndCallBackUPP		userProc = chan->callBack;#if defined( _CARBON ) || defined( _MAC_UNIX )			if (userProc) DisposeSndCallBackUPP (userProc);#else			if (userProc) DisposeRoutineDescriptor (userProc);#endif					e = ::SndDisposeChannel (chan, TRUE);				}		return e;			} /* end DisposeChannel *//*--------------------------------------------------------------------------|	Callback--------------------------------------------------------------------------*/pascal void CWaveHeader::Callback (	SndChannelPtr	chan,	SndCommand		*cmd)		{ /* begin Callback */		#ifndef _MAC_UNIX		HXMM_INTERRUPTON();#endif	//    if (HXMM_RAHUL_CHECK())//    {//        DebugStr("\pCWaveHeader Deferred Task ENTER;g");//    }    		DeferredTask*	dtrec = NULL;		CWaveHeader*    wh    = NULL;                SndCommand*	  newCommand;                		if (cmd)		{			wh = (CWaveHeader *) cmd->param2;						if ( wh )			{			    CAudioOutMac* theWaveOut = wh->waveOut;			    			    if ( theWaveOut )			    {				CMacWaveFormat wf = theWaveOut->wf;								UINT32 ulBytesPerSecond = 					wf.numChannels *					( (ULONG32)wf.sampleRate >> 16 ) *					( wf.sampleSize / 8 );								theWaveOut->m_millisecondsIntoClip +=					(double)wh->cbPlaying * 1000.0 / (double)ulBytesPerSecond;			    }			}						dtrec=wh->waveOut->mDeferredTaskRec;		}				if (!dtrec)		{			goto CleanUp;		}				newCommand=new SndCommand;		HX_ASSERT(newCommand);				if (!newCommand)		{			delete dtrec;			goto CleanUp;		}				if (cmd)		{			*newCommand=*cmd;		}		else		{			delete newCommand;			delete dtrec;			goto CleanUp;		}				wh->waveOut->AddToThePendingList(newCommand);			if (!wh->waveOut->m_bDeferredTaskPending)		{		    wh->waveOut->m_bDeferredTaskPending = TRUE;		    		    short err = 0;		    		    if ( wh->waveOut->m_bIsQuitting )		    {			err = -1; // just so it's nonzero		    }		    else		    {			err = DTInstall(dtrec);		    }		    if ( err != noErr )		    {			wh->waveOut->m_bDeferredTaskPending = FALSE;			wh->waveOut->m_bAudioCallbacksAreAlive = FALSE;			delete dtrec;			delete newCommand;			goto CleanUp;		    }		}			/*			if (wh) {			long	saveA5 = SetA5 (wh->soundA5);			wh->Release (cmd->param1);			SetA5 (saveA5);			} 	*/			CleanUp:		#ifndef _MAC_UNIX		HXMM_INTERRUPTOFF();#endif		//    if (HXMM_RAHUL_CHECK())//    {//        DebugStr("\pCWaveHeader Deferred Task LEAVE;g");//    }		return;			} /* end Callback */	pascal void CAudioOutMac::DeferredTaskCallback(long param){    if (!param)    {        return;    }    #ifndef _MAC_UNIX	HXMM_INTERRUPTON();#endif		CAudioOutMac* pAudioOut = (CAudioOutMac*) param;		pAudioOut->m_bAudioCallbacksAreAlive = FALSE;	#ifdef THREADS_SUPPORTED

⌨️ 快捷键说明

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