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

📄 sdl_esdaudio.c

📁 完整的RTP RTSP代码库
💻 C
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2004 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: SDL_esdaudio.c,v 1.4 2005/01/17 20:46:17 wmaycisco Exp $";#endif/* Allow access to an ESD network stream mixing buffer */#ifdef ESD_SUPPORT#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <signal.h>#include <unistd.h>#include <esd.h>#include "Our_SDL_audio.h"#include "SDL_audiomem.h"#include "SDL_audio_c.h"#include "SDL_audiodev_c.h"#include "SDL_esdaudio.h"#ifdef ESD_DYNAMIC#include <SDL_name.h>#include <SDL_loadso.h>#else#define SDL_NAME(X)	X#endif/* The tag name used by ESD audio */#define ESD_DRIVER_NAME		"esd"/* Audio driver functions */static int ESD_OpenAudio(_THIS, SDL_AudioSpec *spec);static void ESD_WaitAudio(_THIS);static void ESD_PlayAudio(_THIS);static Uint8 *ESD_GetAudioBuf(_THIS);static void ESD_CloseAudio(_THIS);#ifdef ESD_DYNAMICstatic const char *esd_library = ESD_DYNAMIC;static void *esd_handle = NULL;static int esd_loaded = 0;static int (*SDL_NAME(esd_open_sound))( const char *host );static int (*SDL_NAME(esd_close))( int esd );static int (*SDL_NAME(esd_play_stream))( esd_format_t format, int rate,                                         const char *host, const char *name );static struct {	const char *name;	void **func;} esd_functions[] = {	{ "esd_open_sound",	(void **)&SDL_NAME(esd_open_sound)	},	{ "esd_close",		(void **)&SDL_NAME(esd_close)		},	{ "esd_play_stream",	(void **)&SDL_NAME(esd_play_stream)	},};static void UnloadESDLibrary(){	if ( esd_loaded ) {		SDL_UnloadObject(esd_handle);		esd_handle = NULL;		esd_loaded = 0;	}}static int LoadESDLibrary(void){	int i, retval = -1;	esd_handle = SDL_LoadObject(esd_library);	if ( esd_handle ) {		esd_loaded = 1;		retval = 0;		for ( i=0; i<SDL_TABLESIZE(esd_functions); ++i ) {			*esd_functions[i].func = SDL_LoadFunction(esd_handle, esd_functions[i].name);			if ( !*esd_functions[i].func ) {				retval = -1;				UnloadESDLibrary();				break;			}		}	}	return retval;}#elsestatic void UnloadESDLibrary(){	return;}static int LoadESDLibrary(void){	return 0;}#endif /* ESD_DYNAMIC *//* Audio driver bootstrap functions */static int Audio_Available(void){	int connection;	int available;	available = 0;	if ( LoadESDLibrary() < 0 ) {		return available;	}	connection = SDL_NAME(esd_open_sound)(NULL);	if ( connection >= 0 ) {		available = 1;		SDL_NAME(esd_close)(connection);	}	UnloadESDLibrary();	return(available);}static void Audio_DeleteDevice(SDL_AudioDevice *device){	free(device->hidden);	free(device);	UnloadESDLibrary();}static SDL_AudioDevice *Audio_CreateDevice(int devindex){	SDL_AudioDevice *this;	/* Initialize all variables that we clean on shutdown */	LoadESDLibrary();	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));	audio_fd = -1;	/* Set the function pointers */	this->OpenAudio = ESD_OpenAudio;	this->WaitAudio = ESD_WaitAudio;	this->PlayAudio = ESD_PlayAudio;	this->GetAudioBuf = ESD_GetAudioBuf;	this->CloseAudio = ESD_CloseAudio;	this->free = Audio_DeleteDevice;	return this;}AudioBootStrap ESD_bootstrap_ours = {	ESD_DRIVER_NAME, "Enlightened Sound Daemon",	Audio_Available, Audio_CreateDevice};/* This function waits until it is possible to write a full sound buffer */static void ESD_WaitAudio(_THIS){	Sint32 ticks;	/* Check to see if the thread-parent process is still alive */	{ static int cnt = 0;		/* Note that this only works with thread implementations 		   that use a different process id for each thread.		*/		if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */			if ( kill(parent, 0) < 0 ) {				this->enabled = 0;			}		}	}	/* Use timer for general audio synchronization */	ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS;	if ( ticks > 0 ) {		SDL_Delay(ticks);	}}static void ESD_PlayAudio(_THIS){	int written;	/* Write the audio data, checking for EAGAIN on broken audio drivers */	do {		written = write(audio_fd, mixbuf, mixlen);		if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) {			SDL_Delay(1);	/* Let a little CPU time go by */		}	} while ( (written < 0) && 	          ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) );	/* Set the next write frame */	next_frame += frame_ticks;	/* If we couldn't write, assume fatal error for now */	if ( written < 0 ) {		this->enabled = 0;	}}static Uint8 *ESD_GetAudioBuf(_THIS){	return(mixbuf);}static void ESD_CloseAudio(_THIS){	if ( mixbuf != NULL ) {		SDL_FreeAudioMem(mixbuf);		mixbuf = NULL;	}	if ( audio_fd >= 0 ) {		SDL_NAME(esd_close)(audio_fd);		audio_fd = -1;	}}/* Try to get the name of the program */static char *get_progname(void){	char *progname = NULL;#ifdef linux	FILE *fp;	static char temp[BUFSIZ];	sprintf(temp, "/proc/%d/cmdline", getpid());	fp = fopen(temp, "r");	if ( fp != NULL ) {		if ( fgets(temp, sizeof(temp)-1, fp) ) {			progname = strrchr(temp, '/');			if ( progname == NULL ) {				progname = temp;			} else {				progname = progname+1;			}		}		fclose(fp);	}#endif	return(progname);}static int ESD_OpenAudio(_THIS, SDL_AudioSpec *spec){	esd_format_t format;	/* Convert audio spec to the ESD audio format */	format = (ESD_STREAM | ESD_PLAY);	switch ( spec->format & 0xFF ) {		case 8:			format |= ESD_BITS8;			break;		case 16:			format |= ESD_BITS16;			break;		default:			SDL_SetError("Unsupported ESD audio format");			return(-1);	}	if ( spec->channels == 1 ) {		format |= ESD_MONO;	} else {		format |= ESD_STEREO;	}#if 0	spec->samples = ESD_BUF_SIZE;	/* Darn, no way to change this yet */#endif	/* Open a connection to the ESD audio server */	audio_fd = SDL_NAME(esd_play_stream)(format, spec->freq, NULL, get_progname());	if ( audio_fd < 0 ) {		SDL_SetError("Couldn't open ESD connection");		return(-1);	}	/* Calculate the final parameters for this audio specification */	SDL_CalculateAudioSpec(spec);	frame_ticks = (float)(spec->samples*1000)/spec->freq;	next_frame = SDL_GetTicks()+frame_ticks;	/* Allocate mixing buffer */	mixlen = spec->size;	mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);	if ( mixbuf == NULL ) {		return(-1);	}	memset(mixbuf, spec->silence, spec->size);	/* Get the parent process id (we're the parent of the audio thread) */	parent = getpid();	/* We're ready to rock and roll. :-) */	return(0);}#endif /* ESD_SUPPORT */

⌨️ 快捷键说明

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