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

📄 sdl_dx5audio.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga    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 library 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    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id$";#endif/* Allow access to a raw mixing buffer */#include <stdio.h>#include "SDL_types.h"#include "SDL_error.h"#include "SDL_timer.h"#include "SDL_audio.h"#include "SDL_audio_c.h"#include "SDL_dx5audio.h"/* Define this if you want to use DirectX 6 DirectSoundNotify interface *///#define USE_POSITION_NOTIFY/* DirectX function pointers for audio */HRESULT (WINAPI *DSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);/* Audio driver functions */static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec);static void DX5_ThreadInit(_THIS);static void DX5_WaitAudio_BusyWait(_THIS);#ifdef USE_POSITION_NOTIFYstatic void DX6_WaitAudio_EventWait(_THIS);#endifstatic void DX5_PlayAudio(_THIS);static Uint8 *DX5_GetAudioBuf(_THIS);static void DX5_WaitDone(_THIS);static void DX5_CloseAudio(_THIS);static int DX5_AudioDelayMsec(_THIS);/* Audio driver bootstrap functions */static int Audio_Available(void){	HINSTANCE DSoundDLL;	int dsound_ok;	/* Version check DSOUND.DLL (Is DirectX okay?) */	dsound_ok = 0;	DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL"));	if ( DSoundDLL != NULL ) {		/* We just use basic DirectSound, we're okay */		/* Yay! */		/* Unfortunately, the sound drivers on NT have		   higher latencies than the audio buffers used		   by many SDL applications, so there are gaps		   in the audio - it sounds terrible.  Punt for now.		 */		OSVERSIONINFO ver;		ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);		GetVersionEx(&ver);		switch (ver.dwPlatformId) {			case VER_PLATFORM_WIN32_NT:				if ( ver.dwMajorVersion > 4 ) {					/* Win2K */					dsound_ok = 1;				} else {					/* WinNT */					dsound_ok = 0;				}				break;			default:				/* Win95 or Win98 */				dsound_ok = 1;				break;		}		/* Now check for DirectX 5 or better - otherwise		 * we will fail later in DX5_OpenAudio without a chance		 * to fall back to the DIB driver. */		if (dsound_ok) {			/* DirectSoundCaptureCreate was added in DX5 */			if (!GetProcAddress(DSoundDLL, TEXT("DirectSoundCaptureCreate")))				dsound_ok = 0;		}		/* Clean up.. */		FreeLibrary(DSoundDLL);	}	return(dsound_ok);}/* Functions for loading the DirectX functions dynamically */static HINSTANCE DSoundDLL = NULL;static void DX5_Unload(void){	if ( DSoundDLL != NULL ) {		FreeLibrary(DSoundDLL);		DSoundCreate = NULL;		DSoundDLL = NULL;	}}static int DX5_Load(void){	int status;	DX5_Unload();	DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL"));	if ( DSoundDLL != NULL ) {		DSoundCreate = (void *)GetProcAddress(DSoundDLL,					TEXT("DirectSoundCreate"));	}	if ( DSoundDLL && DSoundCreate ) {		status = 0;	} else {		DX5_Unload();		status = -1;	}	return status;}static void Audio_DeleteDevice(SDL_AudioDevice *device){	DX5_Unload();	free(device->hidden);	free(device);}static SDL_AudioDevice *Audio_CreateDevice(int devindex){	SDL_AudioDevice *this;	/* Load DirectX */	if ( DX5_Load() < 0 ) {		return(NULL);	}	/* Initialize all variables that we clean on shutdown */	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));	if ( this ) {		memset(this, 0, (sizeof *this));		this->hidden = (struct SDL_PrivateAudioData *)				malloc((sizeof *this->hidden));	}	if ( (this == NULL) || (this->hidden == NULL) ) {		SDL_OutOfMemory();		if ( this ) {			free(this);		}		return(0);	}	memset(this->hidden, 0, (sizeof *this->hidden));	/* Set the function pointers */	this->OpenAudio = DX5_OpenAudio;	this->ThreadInit = DX5_ThreadInit;	this->WaitAudio = DX5_WaitAudio_BusyWait;	this->PlayAudio = DX5_PlayAudio;	this->GetAudioBuf = DX5_GetAudioBuf;	this->WaitDone = DX5_WaitDone;	this->CloseAudio = DX5_CloseAudio;	this->AudioDelayMsec = DX5_AudioDelayMsec;	this->free = Audio_DeleteDevice;	return this;}AudioBootStrap DSOUND_bootstrap = {	"dsound", "Win95/98/2000 DirectSound",	Audio_Available, Audio_CreateDevice};static void SetDSerror(const char *function, int code){	static const char *error;	static char  errbuf[1024];	errbuf[0] = 0;	switch (code) {		case E_NOINTERFACE:			error = 		"Unsupported interface\n-- Is DirectX 5.0 or later installed?";			break;		case DSERR_ALLOCATED:			error = "Audio device in use";			break;		case DSERR_BADFORMAT:			error = "Unsupported audio format";			break;		case DSERR_BUFFERLOST:			error = "Mixing buffer was lost";			break;		case DSERR_CONTROLUNAVAIL:			error = "Control requested is not available";			break;		case DSERR_INVALIDCALL:			error = "Invalid call for the current state";			break;		case DSERR_INVALIDPARAM:			error = "Invalid parameter";			break;		case DSERR_NODRIVER:			error = "No audio device found";			break;		case DSERR_OUTOFMEMORY:			error = "Out of memory";			break;		case DSERR_PRIOLEVELNEEDED:			error = "Caller doesn't have priority";			break;		case DSERR_UNSUPPORTED:			error = "Function not supported";			break;		default:			sprintf(errbuf, "%s: Unknown DirectSound error: 0x%x",								function, code);			break;	}	if ( ! errbuf[0] ) {		sprintf(errbuf, "%s: %s", function, error);	}	SDL_SetError("%s", errbuf);	return;}/* DirectSound needs to be associated with a window */static HWND mainwin = NULL;/* */void DX5_SoundFocus(HWND hwnd){	mainwin = hwnd;}static void DX5_ThreadInit(_THIS){	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);}static void DX5_WaitAudio_BusyWait(_THIS){	DWORD status;	DWORD cursor, junk;	HRESULT result;	/* Semi-busy wait, since we have no way of getting play notification	   on a primary mixing buffer located in hardware (DirectX 5.0)	*/	result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk);	if ( result != DS_OK ) {		if ( result == DSERR_BUFFERLOST ) {			IDirectSoundBuffer_Restore(mixbuf);		}#ifdef DEBUG_SOUND		SetDSerror("DirectSound GetCurrentPosition", result);#endif		return;	}	cursor /= mixlen;	while ( cursor == playing ) {		/* FIXME: find out how much time is left and sleep that long */		SDL_Delay(10);		/* Try to restore a lost sound buffer */		IDirectSoundBuffer_GetStatus(mixbuf, &status);		if ( (status&DSBSTATUS_BUFFERLOST) ) {			IDirectSoundBuffer_Restore(mixbuf);			IDirectSoundBuffer_GetStatus(mixbuf, &status);			if ( (status&DSBSTATUS_BUFFERLOST) ) {				break;			}		}		if ( ! (status&DSBSTATUS_PLAYING) ) {			result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING);			if ( result == DS_OK ) {				continue;			}#ifdef DEBUG_SOUND			SetDSerror("DirectSound Play", result);#endif			return;		}		/* Find out where we are playing */		result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,								&cursor, &junk);		if ( result != DS_OK ) {			SetDSerror("DirectSound GetCurrentPosition", result);			return;		}		cursor /= mixlen;	}}#ifdef USE_POSITION_NOTIFYstatic void DX6_WaitAudio_EventWait(_THIS){	DWORD status;	HRESULT result;	/* Try to restore a lost sound buffer */	IDirectSoundBuffer_GetStatus(mixbuf, &status);	if ( (status&DSBSTATUS_BUFFERLOST) ) {		IDirectSoundBuffer_Restore(mixbuf);		IDirectSoundBuffer_GetStatus(mixbuf, &status);		if ( (status&DSBSTATUS_BUFFERLOST) ) {			return;		}	}	if ( ! (status&DSBSTATUS_PLAYING) ) {		result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING);		if ( result != DS_OK ) {#ifdef DEBUG_SOUND			SetDSerror("DirectSound Play", result);#endif			return;		}	}	WaitForSingleObject(audio_event, INFINITE);}#endif /* USE_POSITION_NOTIFY */static void DX5_PlayAudio(_THIS){	/* Unlock the buffer, allowing it to play */	if ( locked_buf ) {		IDirectSoundBuffer_Unlock(mixbuf, locked_buf, mixlen, NULL, 0);	}}static Uint8 *DX5_GetAudioBuf(_THIS){	DWORD   cursor, junk;	HRESULT result;	DWORD   rawlen;	/* Figure out which blocks to fill next */	locked_buf = NULL;	result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk);	if ( result == DSERR_BUFFERLOST ) {		IDirectSoundBuffer_Restore(mixbuf);		result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,								&cursor, &junk);	}	if ( result != DS_OK ) {		SetDSerror("DirectSound GetCurrentPosition", result);

⌨️ 快捷键说明

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