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

📄 drv_osx.c

📁 wince下著名的视频播放器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	MikMod sound library	(c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for	complete list.	This library is free software; you can redistribute it and/or modify	it under the terms of the GNU Library General Public License as	published by the Free Software Foundation; either version 2 of	the License, or (at your option) any later version. 	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU Library General Public License for more details. 	You should have received a copy of the GNU Library General Public	License along with this library; if not, write to the Free Software	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA	02111-1307, USA.*//*==============================================================================  $Id: drv_osx.c,v 1.5 2004/02/16 17:27:29 raph Exp $  Driver for output via CoreAudio [MacOS X and Darwin].==============================================================================*//*        	Written by Axel Wefers <awe@fruitz-of-dojo.de>                Notes:        - if HAVE_PTHREAD (config.h) is defined, an extra thread will be created to fill the buffers.        - if HAVE_PTHREAD is defined, a double buffered method will be used.        - if an unsupported frequency is selected [md_mixfreq], the native device frequency is used.        - if mono playback is selected and is not supported by the device, we will emulate mono          playback.        - if stereo/surround playback is selected and is not supported by the device, DMODE_STEREO          will be deactivated automagically.      Bug fixes by Anders F Bjoerklund <afb@algonet.se>      		Changes:   		- cleared up in the macro jungle, to see what was going on in the code   		- separated "has ability to use pthreads" from "wish to use pthreads"   		- moved pthread_cond_wait inside the mutex lock, to avoid a deadlock [!]   		- added more than one back buffer, currently left at eight or something        - gave up on whole thread idea, since it stutters if you rescale a window	    - moved a #pragma mark and added DRV_OSX/MISSING, for non-Darwin compiles	    - added support for float-point buffers, to avoid the conversion and copying	Future ideas: (TODO)			- support possibly partially filled buffers from libmikmod		- clean up the rest of the code and lose even more macros		- use hardware preferred native size for the sample buffers				- Altivec optimizations of the various vector transforms	    - provide a PPC64 version of the library, for PowerMac G5*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "mikmod_internals.h"#ifdef DRV_OSX//_______________________________________________________________________________________________INCLUDES#pragma mark INCLUDES#include <CoreAudio/AudioHardware.h>#pragma mark -//________________________________________________________________________________________________DEFINES#pragma mark DEFINES#define SOUND_BUFFER_SCALE_8BIT		(1.0f / 128.0f)	  /* CoreAudio requires float input.    */#define SOUND_BUFFER_SCALE_16BIT	(1.0f / 32768.0f) /* CoreAudio requires float input.    */#define SOUND_BUFFER_SIZE			4096	/* The buffersize libmikmod will use. */#define USE_FILL_THREAD				0		/* Use an extra thread to fill the buffers ? */#ifndef HAVE_PTHREAD#undef USE_FILL_THREAD#define USE_FILL_THREAD				0		/* must have pthread supports to use thread */#endif#define NUMBER_BACK_BUFFERS			8		/* Number of back buffers for the thread */#define DEBUG_TRACE_THREADS			0#pragma mark -//_________________________________________________________________________________________________MACROS#pragma mark MACROS#define CHECK_ERROR(ERRNO, RESULT)	if (RESULT != kAudioHardwareNoError)      		   \                                        {				         		   \                                            _mm_errno = ERRNO;			 		   \                                            return(1);				 		   \                                        }#define SET_PROPS()	if (AudioDeviceSetProperty (gSoundDeviceID, NULL, 0, 0,			   \                                                    kAudioDevicePropertyStreamFormat,		   \                                                    myPropertySize, &mySoundBasicDescription))	   \                        {									   \                            CHECK_ERROR								   \                            (									   \                                MMERR_OSX_BAD_PROPERTY,						   \                                AudioDeviceGetProperty (gSoundDeviceID, 0, 0,			   \                                                        kAudioDevicePropertyStreamFormat,	   \                                                        &myPropertySize, &mySoundBasicDescription) \                            );									   \                        }#define SET_STEREO()    switch (mySoundBasicDescription.mChannelsPerFrame) 			   \                        {									   \                            case 1: 								   \                                md_mode &= ~DMODE_STEREO;					   \                                gBufferMono2Stereo = 0;						   \                                break;								   \                            case 2:								   \                                if (md_mode & DMODE_STEREO)					   \                                    gBufferMono2Stereo = 0;					   \                                else								   \                                    gBufferMono2Stereo = 1;					   \                                break;								   \                            default:								   \                                _mm_errno = MMERR_OSX_SET_STEREO;				   \                                return(1);							   \                        }#define FILL_BUFFER(_buffer,_size)	\								if (Player_Paused())						   \                                {								   \                                    MUTEX_LOCK (vars);						   \                                    VC_SilenceBytes ((SBYTE*) (_buffer), (ULONG) (_size));		   \                                    MUTEX_UNLOCK (vars);					   \                                }								   \                                else								   \                                {								   \                                    MUTEX_LOCK (vars);						   \                                    VC_WriteBytes ((SBYTE*) (_buffer), (ULONG) ((_size)));		   \                                    MUTEX_UNLOCK (vars);					   \                                }#pragma mark -//_________________________________________________________________________________________________GLOBALS#pragma mark GLOBALS#if USE_FILL_THREADstatic pthread_t		gBufferFillThread;static pthread_mutex_t		gBufferMutex;static pthread_cond_t		gBufferCondition;static Boolean			gExitBufferFillThread = 0;static int					gCurrentPlayBuffer;static int					gCurrentFillBuffer;static unsigned char		*gSoundBackBuffer[NUMBER_BACK_BUFFERS];#elsestatic unsigned char 		*gSoundBuffer = NULL;#endif /* USE_FILL_THREAD */static AudioDeviceID 		gSoundDeviceID;static UInt32			gInBufferSize;static Boolean			gIOProcIsInstalled = 0,                                gDeviceHasStarted = 0,                                gBufferMono2Stereo = 0;static OSStatus			(*gAudioIOProc) (AudioDeviceID, const AudioTimeStamp *,                                                 const AudioBufferList *, const AudioTimeStamp *,                                                 AudioBufferList *, const AudioTimeStamp *, void *);#pragma mark -//____________________________________________________________________________________FUNCTION_pROTOTYPES#pragma mark FUNCTION PROTOTYPES#if USE_FILL_THREADstatic void * OSX_FillBuffer (void *);#endif /* USE_FILL_THREAD */static OSStatus OSX_AudioIOProc8Bit (AudioDeviceID, const AudioTimeStamp *,									const AudioBufferList *, const AudioTimeStamp *, AudioBufferList *,									const AudioTimeStamp *, void *);static OSStatus OSX_AudioIOProc16Bit (AudioDeviceID, const AudioTimeStamp *,									const AudioBufferList *, const AudioTimeStamp *, AudioBufferList *,									const AudioTimeStamp *, void *);static OSStatus OSX_AudioIOProcFloat (AudioDeviceID, const AudioTimeStamp *,									const AudioBufferList *, const AudioTimeStamp *, AudioBufferList *,									const AudioTimeStamp *, void *);static BOOL OSX_IsPresent (void);static BOOL OSX_Init (void);static void OSX_Exit (void);static BOOL OSX_PlayStart (void);static void OSX_PlayStop (void);static void OSX_Update (void);#pragma mark -//_______________________________________________________________________________________OSX_FillBuffer()#if USE_FILL_THREADstatic void * OSX_FillBuffer (void *theID){    unsigned char *buffer;    int done;        while (1)    {		done = 0;		while (!done)		{	        // shall the thread exit?	        if (gExitBufferFillThread) pthread_exit (NULL);			pthread_mutex_lock (&gBufferMutex);       	       		if ((gCurrentFillBuffer+1) % NUMBER_BACK_BUFFERS != gCurrentPlayBuffer)       		{       		  #if DEBUG_TRACE_THREADS				fprintf(stderr,"filling buffer #%d\n", gCurrentFillBuffer);			  #endif       			buffer = gSoundBackBuffer[gCurrentFillBuffer];         		if (++gCurrentFillBuffer >= NUMBER_BACK_BUFFERS)    				gCurrentFillBuffer = 0;										// fill the buffer...				FILL_BUFFER (buffer, gInBufferSize);			}       		else       		{       			// we are caught up now, give it a rest       			done = 1;       		}       		       		pthread_mutex_unlock (&gBufferMutex);       	}       			pthread_mutex_lock (&gBufferMutex);       	         // wait for the next buffer-fill request...		pthread_cond_wait (&gBufferCondition, &gBufferMutex);		pthread_mutex_unlock (&gBufferMutex);    }    return (theID);}#endif /* USE_FILL_THREAD *///__________________________________________________________________________________OSX_AudioIOProc8Bit()static OSStatus OSX_AudioIOProc8Bit (AudioDeviceID 		inDevice,                                     const AudioTimeStamp 	*inNow,                                     const AudioBufferList 	*inInputData,                                     const AudioTimeStamp 	*inInputTime,                                     AudioBufferList		*outOutputData,                                      const AudioTimeStamp	*inOutputTime,                                     void 			*inClientData){    register float	*myOutBuffer = (float *) outOutputData->mBuffers[0].mData;    register UInt8	*myInBuffer;    register UInt32	i;#if USE_FILL_THREAD    pthread_mutex_lock (&gBufferMutex);   #if DEBUG_TRACE_THREADS 	fprintf(stderr,"playing buffer #%d\n", gCurrentPlayBuffer);  #endif       myInBuffer = (UInt8 *) gSoundBackBuffer[gCurrentPlayBuffer]; 	if (++gCurrentPlayBuffer >= NUMBER_BACK_BUFFERS)    	gCurrentPlayBuffer = 0;	    // fill her up, please ...    pthread_cond_signal (&gBufferCondition);		pthread_mutex_unlock (&gBufferMutex);#else	myInBuffer = (UInt8 *) gSoundBuffer;	FILL_BUFFER(gSoundBuffer, gInBufferSize);#endif /* USE_FILL_THREAD */	if (gBufferMono2Stereo)	{		for (i = 0; i < SOUND_BUFFER_SIZE >> 1; i++)		{			myOutBuffer[1] = myOutBuffer[0] = (*myInBuffer++) * SOUND_BUFFER_SCALE_8BIT;            myOutBuffer+=2;        }    }    else    {    	for (i = 0; i < SOUND_BUFFER_SIZE; i++)        {        	*myOutBuffer++ = (*myInBuffer++) * SOUND_BUFFER_SCALE_8BIT;        }	}	return 0;}//_________________________________________________________________________________OSX_AudioIOProc16Bit()static OSStatus OSX_AudioIOProc16Bit (AudioDeviceID 		inDevice,                                      const AudioTimeStamp 	*inNow,                                      const AudioBufferList 	*inInputData,                                      const AudioTimeStamp 	*inInputTime,                                      AudioBufferList		*outOutputData,                                       const AudioTimeStamp	*inOutputTime,                                      void 			*inClientData){    register float	*myOutBuffer = (float *) outOutputData->mBuffers[0].mData;    register SInt16	*myInBuffer;    register UInt32	i;#if USE_FILL_THREAD	pthread_mutex_lock (&gBufferMutex); 	  #if DEBUG_TRACE_THREADS 	fprintf(stderr,"playing buffer #%d\n", gCurrentPlayBuffer);  #endif                                       	myInBuffer = (SInt16 *) gSoundBackBuffer[gCurrentPlayBuffer]; 	if (++gCurrentPlayBuffer >= NUMBER_BACK_BUFFERS)    	gCurrentPlayBuffer = 0;		// ... and check the oil too    pthread_cond_signal (&gBufferCondition);	pthread_mutex_unlock (&gBufferMutex);#else	myInBuffer = (SInt16 *) gSoundBuffer;	FILL_BUFFER(gSoundBuffer, gInBufferSize);#endif /* USE_FILL_THREAD */	if (gBufferMono2Stereo)	{		for (i = 0; i < SOUND_BUFFER_SIZE >> 1; i++)		{			myOutBuffer[1] = myOutBuffer[0] = (*myInBuffer++) * SOUND_BUFFER_SCALE_16BIT;            myOutBuffer+=2;        }    }    else    {    	for (i = 0; i < SOUND_BUFFER_SIZE; i++)        {        	*myOutBuffer++ = (*myInBuffer++) * SOUND_BUFFER_SCALE_16BIT;        }	}	return 0;}//_________________________________________________________________________________OSX_AudioIOProcFloat()static OSStatus OSX_AudioIOProcFloat (AudioDeviceID 		inDevice,                                      const AudioTimeStamp 	*inNow,                                      const AudioBufferList 	*inInputData,                                      const AudioTimeStamp 	*inInputTime,

⌨️ 快捷键说明

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