X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=plugins%2Fsdl%2Faout_sdl.c;h=6295f45b2f294cae1ebcc30ed36bad4972c41af6;hb=583c6553f6761421260d86bbc21b5b3169c04319;hp=813d0eaa0a7370b726a95e673fecbdfd3a7b5e78;hpb=4cff691635a451c776822d9002f45e30d556d6ef;p=vlc diff --git a/plugins/sdl/aout_sdl.c b/plugins/sdl/aout_sdl.c index 813d0eaa0a..6295f45b2f 100644 --- a/plugins/sdl/aout_sdl.c +++ b/plugins/sdl/aout_sdl.c @@ -11,7 +11,7 @@ * 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. - * + * * 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 @@ -22,6 +22,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +#define MODULE_NAME sdl +#include "modules_inner.h" + /***************************************************************************** * Preamble *****************************************************************************/ @@ -35,14 +38,13 @@ #include /* "intf_msg.h" */ #include /* calloc(), malloc(), free() */ - -#include "SDL/SDL.h" /* SDL base include */ +#include /* SDL base include */ #include "config.h" #include "common.h" /* boolean_t, byte_t */ #include "threads.h" #include "mtime.h" -#include "plugins.h" +#include "tests.h" #include "audio_output.h" /* aout_thread_t */ @@ -51,7 +53,6 @@ #include "modules.h" - /***************************************************************************** * aout_sys_t: dsp audio output method descriptor ***************************************************************************** @@ -66,8 +67,10 @@ typedef struct aout_sys_s { byte_t * audio_buf; int i_audio_end; -} aout_sys_t; + boolean_t b_active; + +} aout_sys_t; /***************************************************************************** * Local prototypes. @@ -79,13 +82,14 @@ static long aout_GetBufInfo ( aout_thread_t *p_aout, long l_buffer_info ); static void aout_Play ( aout_thread_t *p_aout, byte_t *buffer, int i_size ); static void aout_Close ( aout_thread_t *p_aout ); -static void SDL_aout_callback(void *userdata, Uint8 *stream, int len); + +static void aout_SDLCallback ( void *userdata, Uint8 *stream, int len ); /***************************************************************************** * Functions exported as capabilities. They are declared as static so that * we don't pollute the namespace too much. *****************************************************************************/ -void aout_getfunctions( function_list_t * p_function_list ) +void _M( aout_getfunctions )( function_list_t * p_function_list ) { p_function_list->pf_probe = aout_Probe; p_function_list->functions.aout.pf_open = aout_Open; @@ -96,72 +100,72 @@ void aout_getfunctions( function_list_t * p_function_list ) } /***************************************************************************** - * aout_Probe: probes the audio device and return a score + * aout_Probe: probe the audio device and return a score ***************************************************************************** - * This function tries to open the dps and returns a score to the plugin - * manager so that it can select the best plugin. + * This function tries to initialize SDL audio and returns a score to the + * plugin manager so that it can select the best plugin. *****************************************************************************/ static int aout_Probe( probedata_t *p_data ) { - SDL_AudioSpec *desired, *obtained; + SDL_AudioSpec desired, obtained; + return 0; /* Start AudioSDL */ - if( SDL_Init(SDL_INIT_AUDIO) != 0) - intf_ErrMsgImm( "aout_Probe: SDL init error: %s", SDL_GetError() ); - - /* asks for a minimum audio spec so that we are sure the dsp exists */ - desired = (SDL_AudioSpec *)malloc( sizeof(SDL_AudioSpec) ); - obtained = (SDL_AudioSpec *)malloc( sizeof(SDL_AudioSpec) ); - - desired->freq = 11025; /* frequency */ - desired->format = AUDIO_U8; /* unsigned 8 bits */ - desired->channels = 2; /* mono */ - desired->callback = SDL_aout_callback; /* no callback function yet */ - desired->userdata = NULL; /* null parm for callback */ - desired->samples = 4096; - - + if( SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE) != 0 ) + { + intf_DbgMsg( "aout: SDL_Init failed (%s)", SDL_GetError() ); + return( 0 ); + } + + desired.freq = 11025; /* frequency */ + desired.format = AUDIO_U8; /* unsigned 8 bits */ + desired.channels = 2; /* mono */ + desired.callback = NULL; /* no callback function yet */ + desired.userdata = NULL; /* null parm for callback */ + desired.samples = 4096; + /* If we were unable to open the device, there is no way we can use * the plugin. Return a score of 0. */ - if(SDL_OpenAudio( desired, obtained ) < 0) + if( SDL_OpenAudio( &desired, &obtained ) < 0 ) { - SDL_CloseAudio(); - intf_ErrMsgImm( "aout_Probe: aout sdl error : %s", SDL_GetError() ); - return( 0 ); + intf_DbgMsg( "aout: SDL_OpenAudio failed (%s)", SDL_GetError() ); + return( 0 ); } /* Otherwise, there are good chances we can use this plugin, return 100. */ SDL_CloseAudio(); - return( 100 ); + + if( TestMethod( AOUT_METHOD_VAR, "sdl" ) ) + { + return( 999 ); + } + + return( 40 ); } /***************************************************************************** - * aout_Open: opens the audio device (the digital sound processor) + * aout_Open: open the audio device ***************************************************************************** * This function opens the dsp as a usual non-blocking write-only file, and * modifies the p_aout->i_fd with the file's descriptor. *****************************************************************************/ static int aout_Open( aout_thread_t *p_aout ) { - SDL_AudioSpec *desired; - int i_stereo = p_aout->b_stereo?2:1; - - /* asks for a minimum audio spec so that we are sure the dsp exists */ - desired = (SDL_AudioSpec *)malloc( sizeof(SDL_AudioSpec) ); + SDL_AudioSpec desired; + int i_channels = p_aout->b_stereo ? 2 : 1; - /* Allocate structure */ - + /* Allocate structure */ p_aout->p_sys = malloc( sizeof( aout_sys_t ) ); + if( p_aout->p_sys == NULL ) { - intf_ErrMsg("aout_Open error: %s", strerror(ENOMEM) ); + intf_ErrMsg( "aout error: %s", strerror(ENOMEM) ); return( 1 ); } - - + p_aout->p_sys->i_audio_end = 0; - p_aout->p_sys->audio_buf = NULL; - + p_aout->p_sys->audio_buf = malloc( OVERFLOWLIMIT ); + /* Initialize some variables */ p_aout->psz_device = 0; p_aout->i_format = AOUT_FORMAT_DEFAULT; @@ -169,38 +173,38 @@ static int aout_Open( aout_thread_t *p_aout ) AOUT_STEREO_DEFAULT ); p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT ); - - - desired->freq = p_aout->l_rate; - /* TODO: write conversion beetween AOUT_FORMAT_DEFAULT + desired.freq = p_aout->l_rate; + + /* TODO: write conversion beetween AOUT_FORMAT_DEFAULT * AND AUDIO* from SDL. */ - desired->format = AUDIO_S16LSB; /* stereo 16 bits */ - desired->channels = i_stereo; - desired->callback = SDL_aout_callback; - desired->userdata = p_aout->p_sys; - desired->samples = 2048; - - /* Open the sound device + desired.format = AUDIO_S16LSB; /* stereo 16 bits */ + desired.channels = i_channels; + desired.callback = aout_SDLCallback; + desired.userdata = p_aout->p_sys; + desired.samples = 1024; + + /* Open the sound device * we just ask the SDL to wrap at the good frequency if the one we * ask for is unavailable. This is done by setting the second parar * to NULL */ - if( SDL_OpenAudio(desired,NULL) < 0 ) + if( SDL_OpenAudio( &desired, NULL ) < 0 ) { - intf_ErrMsgImm( "aout_Open error: can't open audio device: %s", - SDL_GetError() ); + intf_ErrMsg( "aout error: SDL_OpenAudio failed (%s)", SDL_GetError() ); return( -1 ); } - SDL_PauseAudio(0); - return( 0 ); + p_aout->p_sys->b_active = 1; + SDL_PauseAudio( 0 ); + + return( 0 ); } /***************************************************************************** - * aout_SetFormat: resets the dsp and sets its format + * aout_SetFormat: reset the audio device and sets its format ***************************************************************************** - * This functions resets the DSP device, tries to initialize the output + * This functions resets the audio device, tries to initialize the output * format with the value contained in the dsp structure, and if this value * could not be set, the default value returned by ioctl is set. It then * does the same for the stereo mode, and for the output rate. @@ -208,98 +212,114 @@ static int aout_Open( aout_thread_t *p_aout ) static int aout_SetFormat( aout_thread_t *p_aout ) { /* TODO: finish and clean this */ - SDL_AudioSpec *desired; - int i_stereo = p_aout->b_stereo?2:1; - desired = (SDL_AudioSpec *)malloc( sizeof(SDL_AudioSpec) ); - -/* i_format = p_aout->i_format; -*/ - desired->freq = p_aout->l_rate; /* Set the output rate */ - desired->format = AUDIO_S16LSB; /* stereo 16 bits */ - desired->channels = i_stereo; - desired->callback = SDL_aout_callback; - desired->userdata = p_aout->p_sys; - desired->samples = 2048; - + SDL_AudioSpec desired; + int i_stereo = p_aout->b_stereo ? 2 : 1; + + /*i_format = p_aout->i_format;*/ + desired.freq = p_aout->l_rate; /* Set the output rate */ + desired.format = AUDIO_S16LSB; /* stereo 16 bits */ + desired.channels = i_stereo; + desired.callback = aout_SDLCallback; + desired.userdata = p_aout->p_sys; + desired.samples = 2048; + /* Open the sound device */ - SDL_PauseAudio(1); + SDL_PauseAudio( 1 ); SDL_CloseAudio(); - if( SDL_OpenAudio(desired,NULL) < 0 ) + + if( SDL_OpenAudio( &desired, NULL ) < 0 ) + { + p_aout->p_sys->b_active = 0; return( -1 ); - SDL_PauseAudio(0); - return(0); + } + + p_aout->p_sys->b_active = 1; + SDL_PauseAudio( 0 ); + + return( 0 ); } /***************************************************************************** * aout_GetBufInfo: buffer status query ***************************************************************************** - * returns the number of bytes in the audio buffer compared to the size of + * returns the number of bytes in the audio buffer compared to the size of * l_buffer_limit... *****************************************************************************/ static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit ) { - return( p_aout->p_sys->i_audio_end-l_buffer_limit); -} - - -static void SDL_aout_callback(void *userdata, byte_t *stream, int len) -{ - struct aout_sys_s * p_sys = userdata; - int end = p_sys->i_audio_end; - - if(end > OVERFLOWLIMIT) + if(l_buffer_limit > p_aout->p_sys->i_audio_end) { - intf_ErrMsgImm("aout SDL_aout_callback: Overflow."); - free(p_sys->audio_buf); - p_sys->audio_buf = NULL; - p_sys->i_audio_end = 0; - end = 0; - // we've gone to slow, increase output freq - } - - /* if we are not in underrun */ - if(end>len) - { - memcpy(stream, p_sys->audio_buf, len); - memmove(p_sys->audio_buf, &(p_sys->audio_buf[len]), end-len); - p_sys->audio_buf = realloc(p_sys->audio_buf, end-len); - p_sys->i_audio_end -= len; + /* returning 0 here juste gives awful sound in the speakers :/ */ + return( l_buffer_limit ); } + return( p_aout->p_sys->i_audio_end - l_buffer_limit); } /***************************************************************************** - * aout_Play: plays a sound samples buffer + * aout_Play: play a sound samples buffer ***************************************************************************** * This function writes a buffer of i_length bytes in the dsp *****************************************************************************/ static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size ) { byte_t * audio_buf = p_aout->p_sys->audio_buf; - + SDL_LockAudio(); /* Stop callbacking */ - audio_buf = realloc(audio_buf, p_aout->p_sys->i_audio_end + i_size); - memcpy(&(audio_buf[p_aout->p_sys->i_audio_end]), buffer, i_size); - p_aout->p_sys->i_audio_end += i_size; - p_aout->p_sys->audio_buf = audio_buf; - - + p_aout->p_sys->audio_buf = realloc( audio_buf, + p_aout->p_sys->i_audio_end + i_size); + memcpy( p_aout->p_sys->audio_buf + p_aout->p_sys->i_audio_end, + buffer, i_size); + + p_aout->p_sys->i_audio_end += i_size; + SDL_UnlockAudio(); /* go on callbacking */ } /***************************************************************************** - * aout_Close: closes the dsp audio device + * aout_Close: close the audio device *****************************************************************************/ static void aout_Close( aout_thread_t *p_aout ) { - SDL_LockAudio(); /* Stop callbacking */ - SDL_PauseAudio(1); /* pause audio */ - - if(p_aout->p_sys->audio_buf != NULL) /* do we have a buffer now ? */ + if( p_aout->p_sys->b_active ) { - free(p_aout->p_sys->audio_buf); + SDL_PauseAudio( 1 ); /* pause audio */ + + if( p_aout->p_sys->audio_buf != NULL ) /* do we have a buffer now ? */ + { + free( p_aout->p_sys->audio_buf ); + } } - free(p_aout->p_sys); /* Close the Output. */ + SDL_CloseAudio(); + + free( p_aout->p_sys ); /* Close the Output. */ +} + +/***************************************************************************** + * aout_SDLCallback: what to do once SDL has played sound samples + *****************************************************************************/ +static void aout_SDLCallback( void *userdata, byte_t *stream, int len ) +{ + struct aout_sys_s * p_sys = userdata; + + if( p_sys->i_audio_end > OVERFLOWLIMIT ) + { + intf_ErrMsg( "aout error: aout_SDLCallback overflowed" ); + + free( p_sys->audio_buf ); + p_sys->audio_buf = NULL; + + p_sys->i_audio_end = 0; + /* we've gone to slow, increase output freq */ + } + + /* if we are not in underrun */ + if( p_sys->i_audio_end > len ) + { + p_sys->i_audio_end -= len; + memcpy( stream, p_sys->audio_buf, len ); + memmove( p_sys->audio_buf, p_sys->audio_buf + len, p_sys->i_audio_end ); + } }