00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <errno.h>
00031 #include <fcntl.h>
00032 #include <string.h>
00033 #include <unistd.h>
00034 #include <stdlib.h>
00035
00036 #include <vlc/vlc.h>
00037 #include <vlc/aout.h>
00038 #include "aout_internal.h"
00039
00040 #include SDL_INCLUDE_FILE
00041
00042 #define FRAME_SIZE 2048
00043
00044
00045
00046
00047
00048
00049
00050 struct aout_sys_t
00051 {
00052 mtime_t next_date;
00053 mtime_t buffer_time;
00054 };
00055
00056
00057
00058
00059 static int Open ( vlc_object_t * );
00060 static void Close ( vlc_object_t * );
00061 static void Play ( aout_instance_t * );
00062 static void SDLCallback ( void *, byte_t *, int );
00063
00064
00065
00066
00067 vlc_module_begin();
00068 set_shortname( "SDL" );
00069 set_description( _("Simple DirectMedia Layer audio output") );
00070 set_capability( "audio output", 40 );
00071 set_category( CAT_AUDIO );
00072 set_subcategory( SUBCAT_AUDIO_AOUT );
00073 add_shortcut( "sdl" );
00074 set_callbacks( Open, Close );
00075 vlc_module_end();
00076
00077
00078
00079
00080 static int Open ( vlc_object_t *p_this )
00081 {
00082 aout_instance_t *p_aout = (aout_instance_t *)p_this;
00083 SDL_AudioSpec desired, obtained;
00084 int i_nb_channels;
00085 vlc_value_t val, text;
00086
00087
00088 uint32_t i_flags = SDL_INIT_AUDIO;
00089 if( SDL_WasInit( i_flags ) )
00090 {
00091 return VLC_EGENERIC;
00092 }
00093
00094 #ifndef WIN32
00095
00096 i_flags |= SDL_INIT_EVENTTHREAD;
00097 #endif
00098 #ifdef DEBUG
00099
00100
00101 i_flags |= SDL_INIT_NOPARACHUTE;
00102 #endif
00103
00104
00105 if( SDL_Init( i_flags ) < 0 )
00106 {
00107 msg_Err( p_aout, "cannot initialize SDL (%s)", SDL_GetError() );
00108 return VLC_EGENERIC;
00109 }
00110
00111 if ( var_Type( p_aout, "audio-device" ) != 0 )
00112 {
00113
00114 vlc_value_t val;
00115 var_Get( p_aout, "audio-device", &val );
00116 if ( val.i_int == AOUT_VAR_STEREO )
00117 {
00118 p_aout->output.output.i_physical_channels
00119 = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
00120 }
00121 else if ( val.i_int == AOUT_VAR_MONO )
00122 {
00123 p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
00124 }
00125 }
00126
00127 i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
00128 if ( i_nb_channels > 2 )
00129 {
00130
00131 i_nb_channels = 2;
00132 p_aout->output.output.i_physical_channels
00133 = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
00134 }
00135 desired.freq = p_aout->output.output.i_rate;
00136 desired.format = AUDIO_S16SYS;
00137 desired.channels = i_nb_channels;
00138 desired.callback = SDLCallback;
00139 desired.userdata = p_aout;
00140 desired.samples = FRAME_SIZE;
00141
00142
00143 if( SDL_OpenAudio( &desired, &obtained ) < 0 )
00144 {
00145 return VLC_EGENERIC;
00146 }
00147
00148 SDL_PauseAudio( 0 );
00149
00150
00151 switch ( obtained.format )
00152 {
00153 case AUDIO_S16LSB:
00154 p_aout->output.output.i_format = VLC_FOURCC('s','1','6','l'); break;
00155 case AUDIO_S16MSB:
00156 p_aout->output.output.i_format = VLC_FOURCC('s','1','6','b'); break;
00157 case AUDIO_U16LSB:
00158 p_aout->output.output.i_format = VLC_FOURCC('u','1','6','l'); break;
00159 case AUDIO_U16MSB:
00160 p_aout->output.output.i_format = VLC_FOURCC('u','1','6','b'); break;
00161 case AUDIO_S8:
00162 p_aout->output.output.i_format = VLC_FOURCC('s','8',' ',' '); break;
00163 case AUDIO_U8:
00164 p_aout->output.output.i_format = VLC_FOURCC('u','8',' ',' '); break;
00165 }
00166
00167 aout_VolumeSoftInit( p_aout );
00168
00169 if ( obtained.channels != i_nb_channels )
00170 {
00171 p_aout->output.output.i_physical_channels = (obtained.channels == 2 ?
00172 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
00173 AOUT_CHAN_CENTER);
00174
00175 if ( var_Type( p_aout, "audio-device" ) == 0 )
00176 {
00177 var_Create( p_aout, "audio-device",
00178 VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
00179 text.psz_string = _("Audio Device");
00180 var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL );
00181
00182 val.i_int = (obtained.channels == 2) ? AOUT_VAR_STEREO :
00183 AOUT_VAR_MONO;
00184 text.psz_string = (obtained.channels == 2) ? N_("Stereo") :
00185 N_("Mono");
00186 var_Change( p_aout, "audio-device",
00187 VLC_VAR_ADDCHOICE, &val, &text );
00188 var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart,
00189 NULL );
00190 }
00191 }
00192 else if ( var_Type( p_aout, "audio-device" ) == 0 )
00193 {
00194
00195 var_Create( p_aout, "audio-device",
00196 VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
00197 text.psz_string = _("Audio Device");
00198 var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL );
00199
00200 val.i_int = AOUT_VAR_STEREO;
00201 text.psz_string = N_("Stereo");
00202 var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
00203 val.i_int = AOUT_VAR_MONO;
00204 text.psz_string = N_("Mono");
00205 var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
00206 if ( i_nb_channels == 2 )
00207 {
00208 val.i_int = AOUT_VAR_STEREO;
00209 }
00210 else
00211 {
00212 val.i_int = AOUT_VAR_MONO;
00213 }
00214 var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL );
00215 var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );
00216 }
00217
00218 val.b_bool = VLC_TRUE;
00219 var_Set( p_aout, "intf-change", val );
00220
00221 p_aout->output.output.i_rate = obtained.freq;
00222 p_aout->output.i_nb_samples = obtained.samples;
00223 p_aout->output.pf_play = Play;
00224
00225 return VLC_SUCCESS;
00226 }
00227
00228
00229
00230
00231 static void Play( aout_instance_t * p_aout )
00232 {
00233 }
00234
00235
00236
00237
00238 static void Close ( vlc_object_t *p_this )
00239 {
00240 SDL_PauseAudio( 1 );
00241 SDL_CloseAudio();
00242 SDL_QuitSubSystem( SDL_INIT_AUDIO );
00243 }
00244
00245
00246
00247
00248 static void SDLCallback( void * _p_aout, byte_t * p_stream, int i_len )
00249 {
00250 aout_instance_t * p_aout = (aout_instance_t *)_p_aout;
00251 aout_buffer_t * p_buffer;
00252
00253
00254
00255
00256
00257 vlc_mutex_lock( &p_aout->output_fifo_lock );
00258 p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
00259 vlc_mutex_unlock( &p_aout->output_fifo_lock );
00260
00261 if ( p_buffer != NULL )
00262 {
00263 p_aout->p_vlc->pf_memcpy( p_stream, p_buffer->p_buffer, i_len );
00264 aout_BufferFree( p_buffer );
00265 }
00266 else
00267 {
00268 p_aout->p_vlc->pf_memset( p_stream, 0, i_len );
00269 }
00270 }
00271