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

📄 sdl_alsa_audio.c

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    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*/#include "SDL_config.h"/* Allow access to a raw mixing buffer */#include <sys/types.h>#include <signal.h>	/* For kill() */#include "SDL_timer.h"#include "SDL_audio.h"#include "../SDL_audiomem.h"#include "../SDL_audio_c.h"#include "SDL_alsa_audio.h"#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC#include <dlfcn.h>#include "SDL_name.h"#include "SDL_loadso.h"#else#define SDL_NAME(X)	X#endif/* The tag name used by ALSA audio */#define DRIVER_NAME         "alsa"/* The default ALSA audio driver */#define DEFAULT_DEVICE	"default"/* Audio driver functions */static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec);static void ALSA_WaitAudio(_THIS);static void ALSA_PlayAudio(_THIS);static Uint8 *ALSA_GetAudioBuf(_THIS);static void ALSA_CloseAudio(_THIS);#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMICstatic const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC;static void *alsa_handle = NULL;static int alsa_loaded = 0;static int (*SDL_snd_pcm_open)(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);static int (*SDL_NAME(snd_pcm_open))(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);static int (*SDL_NAME(snd_pcm_close))(snd_pcm_t *pcm);static snd_pcm_sframes_t (*SDL_NAME(snd_pcm_writei))(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);static int (*SDL_NAME(snd_pcm_resume))(snd_pcm_t *pcm);static int (*SDL_NAME(snd_pcm_prepare))(snd_pcm_t *pcm);static int (*SDL_NAME(snd_pcm_drain))(snd_pcm_t *pcm);static const char *(*SDL_NAME(snd_strerror))(int errnum);static size_t (*SDL_NAME(snd_pcm_hw_params_sizeof))(void);static size_t (*SDL_NAME(snd_pcm_sw_params_sizeof))(void);static int (*SDL_NAME(snd_pcm_hw_params_any))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);static int (*SDL_NAME(snd_pcm_hw_params_set_access))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access);static int (*SDL_NAME(snd_pcm_hw_params_set_format))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);static int (*SDL_NAME(snd_pcm_hw_params_set_channels))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);static int (*SDL_NAME(snd_pcm_hw_params_get_channels))(const snd_pcm_hw_params_t *params);static unsigned int (*SDL_NAME(snd_pcm_hw_params_set_rate_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);static snd_pcm_uframes_t (*SDL_NAME(snd_pcm_hw_params_set_period_size_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir);static snd_pcm_sframes_t (*SDL_NAME(snd_pcm_hw_params_get_period_size))(const snd_pcm_hw_params_t *params);static unsigned int (*SDL_NAME(snd_pcm_hw_params_set_periods_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);static int (*SDL_NAME(snd_pcm_hw_params_get_periods))(snd_pcm_hw_params_t *params);static int (*SDL_NAME(snd_pcm_hw_params))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);/**/static int (*SDL_NAME(snd_pcm_sw_params_current))(snd_pcm_t *pcm, snd_pcm_sw_params_t *swparams);static int (*SDL_NAME(snd_pcm_sw_params_set_start_threshold))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);static int (*SDL_NAME(snd_pcm_sw_params_set_avail_min))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);static int (*SDL_NAME(snd_pcm_sw_params))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);static int (*SDL_NAME(snd_pcm_nonblock))(snd_pcm_t *pcm, int nonblock);#define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof)#define snd_pcm_sw_params_sizeof SDL_NAME(snd_pcm_sw_params_sizeof)/* cast funcs to char* first, to please GCC's strict aliasing rules. */static struct {	const char *name;	void **func;} alsa_functions[] = {	{ "snd_pcm_open",	(void**)(char*)&SDL_NAME(snd_pcm_open)		},	{ "snd_pcm_close",	(void**)(char*)&SDL_NAME(snd_pcm_close)	},	{ "snd_pcm_writei",	(void**)(char*)&SDL_NAME(snd_pcm_writei)	},	{ "snd_pcm_resume",	(void**)(char*)&SDL_NAME(snd_pcm_resume)	},	{ "snd_pcm_prepare",	(void**)(char*)&SDL_NAME(snd_pcm_prepare)	},	{ "snd_pcm_drain",	(void**)(char*)&SDL_NAME(snd_pcm_drain)	},	{ "snd_strerror",	(void**)(char*)&SDL_NAME(snd_strerror)		},	{ "snd_pcm_hw_params_sizeof",		(void**)(char*)&SDL_NAME(snd_pcm_hw_params_sizeof)		},	{ "snd_pcm_sw_params_sizeof",		(void**)(char*)&SDL_NAME(snd_pcm_sw_params_sizeof)		},	{ "snd_pcm_hw_params_any",		(void**)(char*)&SDL_NAME(snd_pcm_hw_params_any)		},	{ "snd_pcm_hw_params_set_access",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_access)		},	{ "snd_pcm_hw_params_set_format",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_format)		},	{ "snd_pcm_hw_params_set_channels",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_channels)	},	{ "snd_pcm_hw_params_get_channels",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_channels)	},	{ "snd_pcm_hw_params_set_rate_near",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_rate_near)	},	{ "snd_pcm_hw_params_set_period_size_near",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_period_size_near)	},	{ "snd_pcm_hw_params_get_period_size",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_period_size)	},	{ "snd_pcm_hw_params_set_periods_near",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_periods_near)	},	{ "snd_pcm_hw_params_get_periods",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_periods)	},	{ "snd_pcm_hw_params",	(void**)(char*)&SDL_NAME(snd_pcm_hw_params)	},	{ "snd_pcm_sw_params_current",	(void**)(char*)&SDL_NAME(snd_pcm_sw_params_current)	},	{ "snd_pcm_sw_params_set_start_threshold",	(void**)(char*)&SDL_NAME(snd_pcm_sw_params_set_start_threshold)	},	{ "snd_pcm_sw_params_set_avail_min",	(void**)(char*)&SDL_NAME(snd_pcm_sw_params_set_avail_min)	},	{ "snd_pcm_sw_params",	(void**)(char*)&SDL_NAME(snd_pcm_sw_params)	},	{ "snd_pcm_nonblock",	(void**)(char*)&SDL_NAME(snd_pcm_nonblock)	},};static void UnloadALSALibrary(void) {	if (alsa_loaded) {/*		SDL_UnloadObject(alsa_handle);*/		dlclose(alsa_handle);		alsa_handle = NULL;		alsa_loaded = 0;	}}static int LoadALSALibrary(void) {	int i, retval = -1;/*	alsa_handle = SDL_LoadObject(alsa_library);*/	alsa_handle = dlopen(alsa_library,RTLD_NOW);	if (alsa_handle) {		alsa_loaded = 1;		retval = 0;		for (i = 0; i < SDL_arraysize(alsa_functions); i++) {/*			*alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/#if HAVE_DLVSYM			*alsa_functions[i].func = dlvsym(alsa_handle,alsa_functions[i].name,"ALSA_0.9");			if (!*alsa_functions[i].func)#endif				*alsa_functions[i].func = dlsym(alsa_handle,alsa_functions[i].name);			if (!*alsa_functions[i].func) {				retval = -1;				UnloadALSALibrary();				break;			}		}	}	return retval;}#elsestatic void UnloadALSALibrary(void) {	return;}static int LoadALSALibrary(void) {	return 0;}#endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */static const char *get_audio_device(int channels){	const char *device;		device = SDL_getenv("AUDIODEV");	/* Is there a standard variable name? */	if ( device == NULL ) {		if (channels == 6) device = "surround51";		else if (channels == 4) device = "surround40";		else device = DEFAULT_DEVICE;	}	return device;}/* Audio driver bootstrap functions */static int Audio_Available(void){	int available;	int status;	snd_pcm_t *handle;	available = 0;	if (LoadALSALibrary() < 0) {		return available;	}	status = SDL_NAME(snd_pcm_open)(&handle, get_audio_device(2), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);	if ( status >= 0 ) {		available = 1;        	SDL_NAME(snd_pcm_close)(handle);	}	UnloadALSALibrary();	return(available);}static void Audio_DeleteDevice(SDL_AudioDevice *device){	SDL_free(device->hidden);	SDL_free(device);	UnloadALSALibrary();}static SDL_AudioDevice *Audio_CreateDevice(int devindex){	SDL_AudioDevice *this;	/* Initialize all variables that we clean on shutdown */	LoadALSALibrary();	this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice));	if ( this ) {		SDL_memset(this, 0, (sizeof *this));		this->hidden = (struct SDL_PrivateAudioData *)				SDL_malloc((sizeof *this->hidden));	}	if ( (this == NULL) || (this->hidden == NULL) ) {		SDL_OutOfMemory();		if ( this ) {			SDL_free(this);		}		return(0);	}	SDL_memset(this->hidden, 0, (sizeof *this->hidden));	/* Set the function pointers */	this->OpenAudio = ALSA_OpenAudio;	this->WaitAudio = ALSA_WaitAudio;	this->PlayAudio = ALSA_PlayAudio;	this->GetAudioBuf = ALSA_GetAudioBuf;	this->CloseAudio = ALSA_CloseAudio;	this->free = Audio_DeleteDevice;	return this;}AudioBootStrap ALSA_bootstrap = {	DRIVER_NAME, "ALSA 0.9 PCM audio",	Audio_Available, Audio_CreateDevice};/* This function waits until it is possible to write a full sound buffer */static void ALSA_WaitAudio(_THIS){	/* 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;			}		}	}}/* * http://bugzilla.libsdl.org/show_bug.cgi?id=110 * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE

⌨️ 快捷键说明

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