From 07c13dfd11cbd45e96a5c21cd88ccd44601678ea Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 30 Jul 2012 21:29:29 +0300 Subject: allow multiple sound drivers to be compiled --- plugins/dfsound/alsa.c | 50 ++++++++++++++++++++++------------------ plugins/dfsound/dsoundoss.h | 21 ----------------- plugins/dfsound/nullsnd.c | 24 +++++++++++++------- plugins/dfsound/oss.c | 54 ++++++++++++++++++++++++++++---------------- plugins/dfsound/out.c | 51 +++++++++++++++++++++++++++++++++++++++++ plugins/dfsound/out.h | 12 ++++++++++ plugins/dfsound/pulseaudio.c | 38 ++++++++++++++++++------------- plugins/dfsound/sdl.c | 29 ++++++++++++++++-------- plugins/dfsound/spu.c | 8 +++---- plugins/dfsound/stdafx.h | 3 --- 10 files changed, 186 insertions(+), 104 deletions(-) delete mode 100644 plugins/dfsound/dsoundoss.h create mode 100644 plugins/dfsound/out.c create mode 100644 plugins/dfsound/out.h (limited to 'plugins/dfsound') diff --git a/plugins/dfsound/alsa.c b/plugins/dfsound/alsa.c index c67943a..58900cc 100644 --- a/plugins/dfsound/alsa.c +++ b/plugins/dfsound/alsa.c @@ -15,21 +15,17 @@ * * ***************************************************************************/ -#include "stdafx.h" - -#define _IN_OSS - -#include "externals.h" - +#include #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #include +#include "out.h" static snd_pcm_t *handle = NULL; static snd_pcm_uframes_t buffer_size; // SETUP SOUND -void SetupSound(void) +static int alsa_init(void) { snd_pcm_hw_params_t *hwparams; snd_pcm_status_t *status; @@ -49,13 +45,13 @@ void SetupSound(void) SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { printf("Audio open error: %s\n", snd_strerror(err)); - return; + return -1; } if((err = snd_pcm_nonblock(handle, 0))<0) { printf("Can't set blocking moded: %s\n", snd_strerror(err)); - return; + return -1; } snd_pcm_hw_params_alloca(&hwparams); @@ -63,63 +59,64 @@ void SetupSound(void) if((err=snd_pcm_hw_params_any(handle, hwparams))<0) { printf("Broken configuration for this PCM: %s\n", snd_strerror(err)); - return; + return -1; } if((err=snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED))<0) { printf("Access type not available: %s\n", snd_strerror(err)); - return; + return -1; } if((err=snd_pcm_hw_params_set_format(handle, hwparams, format))<0) { printf("Sample format not available: %s\n", snd_strerror(err)); - return; + return -1; } if((err=snd_pcm_hw_params_set_channels(handle, hwparams, pchannels))<0) { printf("Channels count not available: %s\n", snd_strerror(err)); - return; + return -1; } if((err=snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0))<0) { printf("Rate not available: %s\n", snd_strerror(err)); - return; + return -1; } if((err=snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0))<0) { printf("Buffer time error: %s\n", snd_strerror(err)); - return; + return -1; } if((err=snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0))<0) { printf("Period time error: %s\n", snd_strerror(err)); - return; + return -1; } if((err=snd_pcm_hw_params(handle, hwparams))<0) { printf("Unable to install hw params: %s\n", snd_strerror(err)); - return; + return -1; } snd_pcm_status_alloca(&status); if((err=snd_pcm_status(handle, status))<0) { printf("Unable to get status: %s\n", snd_strerror(err)); - return; + return -1; } buffer_size = snd_pcm_status_get_avail(status); + return 0; } // REMOVE SOUND -void RemoveSound(void) +static void alsa_finish(void) { if(handle != NULL) { @@ -130,9 +127,9 @@ void RemoveSound(void) } // GET BYTES BUFFERED -unsigned long SoundGetBytesBuffered(void) +static int alsa_busy(void) { - unsigned long l; + int l; if (handle == NULL) // failed to open? return 1; @@ -146,7 +143,7 @@ unsigned long SoundGetBytesBuffered(void) } // FEED SOUND DATA -void SoundFeedStreamData(unsigned char* pSound,long lBytes) +static void alsa_feed(void *pSound, int lBytes) { if (handle == NULL) return; @@ -154,3 +151,12 @@ void SoundFeedStreamData(unsigned char* pSound,long lBytes) snd_pcm_prepare(handle); snd_pcm_writei(handle,pSound, lBytes / 4); } + +void out_register_alsa(struct out_driver *drv) +{ + drv->name = "alsa"; + drv->init = alsa_init; + drv->finish = alsa_finish; + drv->busy = alsa_busy; + drv->feed = alsa_feed; +} diff --git a/plugins/dfsound/dsoundoss.h b/plugins/dfsound/dsoundoss.h deleted file mode 100644 index 543b297..0000000 --- a/plugins/dfsound/dsoundoss.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************** - dsoundoss.h - description - ------------------- - begin : Wed May 15 2002 - copyright : (C) 2002 by Pete Bernert - email : BlackDove@addcom.de - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -void SetupSound(void); -void RemoveSound(void); -unsigned long SoundGetBytesBuffered(void); -void SoundFeedStreamData(unsigned char* pSound,long lBytes); diff --git a/plugins/dfsound/nullsnd.c b/plugins/dfsound/nullsnd.c index bf07909..d8714df 100644 --- a/plugins/dfsound/nullsnd.c +++ b/plugins/dfsound/nullsnd.c @@ -1,24 +1,32 @@ -#include "stdafx.h" -#define _IN_OSS -#include "externals.h" +#include "out.h" // SETUP SOUND -void SetupSound(void) +static int none_init(void) { + return 0; } // REMOVE SOUND -void RemoveSound(void) +static void none_finish(void) { } // GET BYTES BUFFERED -unsigned long SoundGetBytesBuffered(void) +static int none_busy(void) { - return 0; + return 1; } // FEED SOUND DATA -void SoundFeedStreamData(unsigned char* pSound,long lBytes) +static void none_feed(void *buf, int bytes) +{ +} + +void out_register_none(struct out_driver *drv) { + drv->name = "none"; + drv->init = none_init; + drv->finish = none_finish; + drv->busy = none_busy; + drv->feed = none_feed; } diff --git a/plugins/dfsound/oss.c b/plugins/dfsound/oss.c index 04d7446..709cb37 100644 --- a/plugins/dfsound/oss.c +++ b/plugins/dfsound/oss.c @@ -15,11 +15,14 @@ * * ***************************************************************************/ -#include "stdafx.h" - -#define _IN_OSS - -#include "externals.h" +#include +#include +#include +#include +#include +#include +#include +#include "out.h" //////////////////////////////////////////////////////////////////////// // oss globals @@ -37,7 +40,7 @@ extern int errno; // SETUP SOUND //////////////////////////////////////////////////////////////////////// -void SetupSound(void) +static int oss_init(void) { int pspeed=44100; int pstereo; @@ -52,14 +55,14 @@ void SetupSound(void) if((oss_audio_fd=open("/dev/dsp",O_WRONLY,0))==-1) { - printf("Sound device not available!\n"); - return; + printf("OSS device not available\n"); + return -1; } if(ioctl(oss_audio_fd,SNDCTL_DSP_RESET,0)==-1) { printf("Sound reset failed\n"); - return; + return -1; } // we use 64 fragments with 1024 bytes each @@ -71,7 +74,7 @@ void SetupSound(void) if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1) { printf("Sound set fragment failed!\n"); - return; + return -1; } format = AFMT_S16_NE; @@ -79,39 +82,41 @@ void SetupSound(void) if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1) { printf("Sound format not supported!\n"); - return; + return -1; } if(format!=AFMT_S16_NE) { printf("Sound format not supported!\n"); - return; + return -1; } if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1 || !oss_stereo) { printf("Stereo mode not supported!\n"); - return; + return -1; } if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1) { printf("Sound frequency not supported\n"); - return; + return -1; } if(oss_speed!=pspeed) { printf("Sound frequency not supported\n"); - return; + return -1; } + + return 0; } //////////////////////////////////////////////////////////////////////// // REMOVE SOUND //////////////////////////////////////////////////////////////////////// -void RemoveSound(void) +static void oss_finish(void) { if(oss_audio_fd != -1 ) { @@ -121,10 +126,10 @@ void RemoveSound(void) } //////////////////////////////////////////////////////////////////////// -// GET BYTES BUFFERED +// GET BUFFERED STATUS //////////////////////////////////////////////////////////////////////// -unsigned long SoundGetBytesBuffered(void) +static int oss_busy(void) { audio_buf_info info; unsigned long l; @@ -146,8 +151,17 @@ unsigned long SoundGetBytesBuffered(void) // FEED SOUND DATA //////////////////////////////////////////////////////////////////////// -void SoundFeedStreamData(unsigned char* pSound,long lBytes) +static void oss_feed(void *buf, int bytes) { if(oss_audio_fd == -1) return; - write(oss_audio_fd,pSound,lBytes); + write(oss_audio_fd, buf, bytes); +} + +void out_register_oss(struct out_driver *drv) +{ + drv->name = "oss"; + drv->init = oss_init; + drv->finish = oss_finish; + drv->busy = oss_busy; + drv->feed = oss_feed; } diff --git a/plugins/dfsound/out.c b/plugins/dfsound/out.c new file mode 100644 index 0000000..150d718 --- /dev/null +++ b/plugins/dfsound/out.c @@ -0,0 +1,51 @@ +#include +#include +#include "out.h" + +#define MAX_OUT_DRIVERS 5 + +static struct out_driver out_drivers[MAX_OUT_DRIVERS]; +struct out_driver *out_current; +static int driver_count; + +#define REGISTER_DRIVER(d) { \ + extern void out_register_##d(struct out_driver *drv); \ + out_register_##d(&out_drivers[driver_count++]); \ +} + +void SetupSound(void) +{ + int i; + + if (driver_count == 0) { +#ifdef HAVE_OSS + REGISTER_DRIVER(oss); +#endif +#ifdef HAVE_ALSA + REGISTER_DRIVER(alsa); +#endif +#ifdef HAVE_SDL + REGISTER_DRIVER(sdl); +#endif +#ifdef HAVE_PULSE + REGISTER_DRIVER(pulse); +#endif +#ifdef HAVE_LIBRETRO + REGISTER_DRIVER(libretro); +#endif + REGISTER_DRIVER(none); + } + + for (i = 0; i < driver_count; i++) + if (out_drivers[i].init() == 0) + break; + + if (i < 0 || i >= driver_count) { + printf("the impossible happened\n"); + abort(); + } + + out_current = &out_drivers[i]; + printf("selected sound output driver: %s\n", out_current->name); +} + diff --git a/plugins/dfsound/out.h b/plugins/dfsound/out.h new file mode 100644 index 0000000..4607099 --- /dev/null +++ b/plugins/dfsound/out.h @@ -0,0 +1,12 @@ + +struct out_driver { + const char *name; + int (*init)(void); + void (*finish)(void); + int (*busy)(void); + void (*feed)(void *data, int bytes); +}; + +extern struct out_driver *out_current; + +void SetupSound(void); diff --git a/plugins/dfsound/pulseaudio.c b/plugins/dfsound/pulseaudio.c index 1dadd88..057c2c4 100644 --- a/plugins/dfsound/pulseaudio.c +++ b/plugins/dfsound/pulseaudio.c @@ -19,8 +19,6 @@ comment : Much of this was taken from simple.c, in the pulseaudio #include "stdafx.h" -#ifdef USEPULSEAUDIO - #define _IN_OSS #include "externals.h" @@ -136,7 +134,7 @@ static void stream_request_cb (pa_stream *stream, size_t length, void *userdata) // SETUP SOUND //////////////////////////////////////////////////////////////////////// -void SetupSound (void) +static void pulse_init(void) { int error_number; @@ -145,7 +143,7 @@ void SetupSound (void) if (device.mainloop == NULL) { fprintf (stderr, "Could not acquire PulseAudio main loop\n"); - return; + return -1; } // Acquire context //////////////////////////////////////////////////////// @@ -156,7 +154,7 @@ void SetupSound (void) if (device.context == NULL) { fprintf (stderr, "Could not acquire PulseAudio device context\n"); - return; + return -1; } // Connect to PulseAudio server /////////////////////////////////////////// @@ -164,7 +162,7 @@ void SetupSound (void) { error_number = pa_context_errno (device.context); fprintf (stderr, "Could not connect to PulseAudio server: %s\n", pa_strerror(error_number)); - return; + return -1; } // Run mainloop until sever context is ready ////////////////////////////// @@ -172,7 +170,7 @@ void SetupSound (void) if (pa_threaded_mainloop_start (device.mainloop) < 0) { fprintf (stderr, "Could not start mainloop\n"); - return; + return -1; } pa_context_state_t context_state; @@ -184,7 +182,7 @@ void SetupSound (void) { error_number = pa_context_errno (device.context); fprintf (stderr, "Context state is not good: %s\n", pa_strerror (error_number)); - return; + return -1; } else if (context_state == PA_CONTEXT_READY) break; @@ -216,7 +214,7 @@ void SetupSound (void) { error_number = pa_context_errno (device.context); fprintf (stderr, "Could not acquire new PulseAudio stream: %s\n", pa_strerror (error_number)); - return; + return -1; } // Set callbacks for server events //////////////////////////////////////// @@ -231,7 +229,7 @@ void SetupSound (void) { pa_context_errno (device.context); fprintf (stderr, "Could not connect for playback: %s\n", pa_strerror (error_number)); - return; + return -1; } // Run mainloop until stream is ready ///////////////////////////////////// @@ -248,7 +246,7 @@ void SetupSound (void) { error_number = pa_context_errno (device.context); fprintf (stderr, "Stream state is not good: %s\n", pa_strerror (error_number)); - return; + return -1; } else fprintf (stderr, "PulseAudio stream state is %d\n", stream_state); @@ -258,13 +256,13 @@ void SetupSound (void) pa_threaded_mainloop_unlock (device.mainloop); fprintf (stderr, "PulseAudio should be connected\n"); - return; + return 0; } //////////////////////////////////////////////////////////////////////// // REMOVE SOUND //////////////////////////////////////////////////////////////////////// -void RemoveSound (void) +static void pulse_finish(void) { if (device.mainloop != NULL) pa_threaded_mainloop_stop (device.mainloop); @@ -295,7 +293,7 @@ void RemoveSound (void) // GET BYTES BUFFERED //////////////////////////////////////////////////////////////////////// -unsigned long SoundGetBytesBuffered (void) +static int pulse_busy(void) { int free_space; int error_code; @@ -329,7 +327,7 @@ unsigned long SoundGetBytesBuffered (void) // FEED SOUND DATA //////////////////////////////////////////////////////////////////////// -void SoundFeedStreamData (unsigned char *pSound, long lBytes) +static void pulse_feed(void *pSound, int lBytes) { int error_code; int size; @@ -348,4 +346,12 @@ void SoundFeedStreamData (unsigned char *pSound, long lBytes) } } } -#endif + +void out_register_pulse(struct out_driver *drv) +{ + drv->name = "pulseaudio"; + drv->init = pulse_init; + drv->finish = pulse_finish; + drv->busy = pulse_busy; + drv->feed = pulse_feed; +} diff --git a/plugins/dfsound/sdl.c b/plugins/dfsound/sdl.c index f7dc298..ce92b6e 100644 --- a/plugins/dfsound/sdl.c +++ b/plugins/dfsound/sdl.c @@ -16,10 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA */ -#include "stdafx.h" - -#include "externals.h" +#include #include +#include "out.h" #define BUFFER_SIZE 22050 @@ -61,10 +60,10 @@ static void DestroySDL() { } } -void SetupSound(void) { +static int sdl_init(void) { SDL_AudioSpec spec; - if (pSndBuffer != NULL) return; + if (pSndBuffer != NULL) return -1; InitSDL(); @@ -76,7 +75,7 @@ void SetupSound(void) { if (SDL_OpenAudio(&spec, NULL) < 0) { DestroySDL(); - return; + return -1; } iBufSize = BUFFER_SIZE; @@ -84,16 +83,17 @@ void SetupSound(void) { pSndBuffer = (short *)malloc(iBufSize * sizeof(short)); if (pSndBuffer == NULL) { SDL_CloseAudio(); - return; + return -1; } iReadPos = 0; iWritePos = 0; SDL_PauseAudio(0); + return 0; } -void RemoveSound(void) { +static void sdl_finish(void) { if (pSndBuffer == NULL) return; SDL_CloseAudio(); @@ -103,7 +103,7 @@ void RemoveSound(void) { pSndBuffer = NULL; } -unsigned long SoundGetBytesBuffered(void) { +static int sdl_busy(void) { int size; if (pSndBuffer == NULL) return 1; @@ -116,7 +116,7 @@ unsigned long SoundGetBytesBuffered(void) { return 0; } -void SoundFeedStreamData(unsigned char *pSound, long lBytes) { +static void sdl_feed(void *pSound, int lBytes) { short *p = (short *)pSound; if (pSndBuffer == NULL) return; @@ -132,3 +132,12 @@ void SoundFeedStreamData(unsigned char *pSound, long lBytes) { lBytes -= sizeof(short); } } + +void out_register_sdl(struct out_driver *drv) +{ + drv->name = "sdl"; + drv->init = sdl_init; + drv->finish = sdl_finish; + drv->busy = sdl_busy; + drv->feed = sdl_feed; +} diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index bbbe1e3..45a7886 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -24,7 +24,7 @@ #include "externals.h" #include "registers.h" -#include "dsoundoss.h" +#include "out.h" #ifdef ENABLE_NLS #include @@ -697,7 +697,7 @@ static int do_samples(int forced_updates) // until enuff free place is available/a new channel gets // started - if(!forced_updates && SoundGetBytesBuffered()) // still enuff data in sound buffer? + if(!forced_updates && out_current->busy()) // still enuff data in sound buffer? { return 0; } @@ -872,7 +872,7 @@ static int do_samples(int forced_updates) // wanna have around 1/60 sec (16.666 ms) updates if (iCycle++ > 16/FRAG_MSECS) { - SoundFeedStreamData((unsigned char *)pSpuBuffer, + out_current->feed(pSpuBuffer, ((unsigned char *)pS) - ((unsigned char *)pSpuBuffer)); pS = (short *)pSpuBuffer; iCycle = 0; @@ -1056,7 +1056,7 @@ long CALLBACK SPUclose(void) bSPUIsOpen = 0; // no more open - RemoveSound(); // no more sound handling + out_current->finish(); // no more sound handling return 0; } diff --git a/plugins/dfsound/stdafx.h b/plugins/dfsound/stdafx.h index 45b366b..d40344f 100644 --- a/plugins/dfsound/stdafx.h +++ b/plugins/dfsound/stdafx.h @@ -23,9 +23,6 @@ #include #include #include -#ifdef USEOSS -#include -#endif #include #include #define RRand(range) (random()%range) -- cgit v1.2.3