/*****************************************************************************
* aout_sys_t: portaudio audio output method descriptor
*****************************************************************************/
/*****************************************************************************
* aout_sys_t: portaudio audio output method descriptor
*****************************************************************************/
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
set_description( N_("PORTAUDIO audio output") )
set_category( CAT_AUDIO )
set_subcategory( SUBCAT_AUDIO_AOUT )
set_description( N_("PORTAUDIO audio output") )
set_category( CAT_AUDIO )
set_subcategory( SUBCAT_AUDIO_AOUT )
set_capability( "audio output", 0 )
set_callbacks( Open, Close )
vlc_module_end ()
set_capability( "audio output", 0 )
set_callbacks( Open, Close )
vlc_module_end ()
const PaStreamCallbackTimeInfo *paDate,
PaStreamCallbackFlags statusFlags, void *p_cookie )
{
const PaStreamCallbackTimeInfo *paDate,
PaStreamCallbackFlags statusFlags, void *p_cookie )
{
p_sys->i_channels, p_sys->pi_chan_table,
p_sys->i_bits_per_sample );
}
vlc_memcpy( outputBuffer, p_buffer->p_buffer,
framesPerBuffer * p_sys->i_sample_size );
p_sys->i_channels, p_sys->pi_chan_table,
p_sys->i_bits_per_sample );
}
vlc_memcpy( outputBuffer, p_buffer->p_buffer,
framesPerBuffer * p_sys->i_sample_size );
- /* aout_BufferFree may be dangereous here, but then so is
- * aout_OutputNextBuffer (calls aout_BufferFree internally).
- * one solution would be to link the no longer useful buffers
- * in a second fifo (in aout_OutputNextBuffer too) and to
- * wait until we are in Play to do the actual free.
- */
*****************************************************************************/
static int Open( vlc_object_t * p_this )
{
*****************************************************************************/
static int Open( vlc_object_t * p_this )
{
- p_aout->output.p_sys = p_sys;
- p_aout->output.pf_play = Play;
+ p_aout->sys = p_sys;
+ p_aout->pf_play = aout_PacketPlay;
+ p_aout->pf_pause = aout_PacketPause;
+ p_aout->pf_flush = aout_PacketFlush;
/* Retrieve output device id from config */
p_sys->i_device_id = var_CreateGetInteger( p_aout, "portaudio-audio-device" );
/* Retrieve output device id from config */
p_sys->i_device_id = var_CreateGetInteger( p_aout, "portaudio-audio-device" );
pa_thread->p_aout = p_aout;
pa_thread->b_error = false;
vlc_mutex_init( &pa_thread->lock_wait );
pa_thread->p_aout = p_aout;
pa_thread->b_error = false;
vlc_mutex_init( &pa_thread->lock_wait );
- if( vlc_thread_create( pa_thread, "aout", PORTAUDIOThread,
+ if( vlc_clone( &pa_thread->thread, PORTAUDIOThread, pa_thread,
VLC_THREAD_PRIORITY_OUTPUT ) )
{
msg_Err( p_aout, "cannot create PORTAUDIO thread" );
VLC_THREAD_PRIORITY_OUTPUT ) )
{
msg_Err( p_aout, "cannot create PORTAUDIO thread" );
vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
vlc_mutex_unlock( &pa_thread->lock_wait );
pa_thread->b_wait = false;
vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
vlc_mutex_unlock( &pa_thread->lock_wait );
pa_thread->b_wait = false;
*****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
*****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
vlc_mutex_unlock( &pa_thread->lock_wait );
pa_thread->b_wait = false;
vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
vlc_mutex_unlock( &pa_thread->lock_wait );
pa_thread->b_wait = false;
var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE,
&val, &text );
msg_Dbg( p_aout, "device supports 5.1 channels" );
}
var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );
var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE,
&val, &text );
msg_Dbg( p_aout, "device supports 5.1 channels" );
}
var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );
const PaHostErrorInfo* paLastHostErrorInfo = Pa_GetLastHostErrorInfo();
PaStreamParameters paStreamParameters;
vlc_value_t val;
const PaHostErrorInfo* paLastHostErrorInfo = Pa_GetLastHostErrorInfo();
PaStreamParameters paStreamParameters;
vlc_value_t val;
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
| AOUT_CHAN_LFE;
}
else if( val.i_int == AOUT_VAR_3F2R )
{
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
| AOUT_CHAN_LFE;
}
else if( val.i_int == AOUT_VAR_3F2R )
{
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
}
else if( val.i_int == AOUT_VAR_2F2R )
{
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
}
else if( val.i_int == AOUT_VAR_2F2R )
{
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
}
else if( val.i_int == AOUT_VAR_MONO )
{
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
}
else if( val.i_int == AOUT_VAR_MONO )
{
- p_aout->output.i_nb_samples = FRAME_SIZE;
- aout_FormatPrepare( &p_aout->output.output );
+ aout_FormatPrepare( &p_aout->format );
+ aout_PacketInit( p_aout, &p_sys->packet, FRAME_SIZE );
- p_aout->output.p_sys->i_channel_mask = i_channel_mask;
- p_aout->output.p_sys->i_bits_per_sample = 32; /* forced to paFloat32 */
- p_aout->output.p_sys->i_channels = i_channels;
+ p_aout->sys->i_channel_mask = i_channel_mask;
+ p_aout->sys->i_bits_per_sample = 32; /* forced to paFloat32 */
+ p_aout->sys->i_channels = i_channels;
aout_CheckChannelReorder( NULL, pi_channels_out,
i_channel_mask, i_channels,
aout_CheckChannelReorder( NULL, pi_channels_out,
i_channel_mask, i_channels,
paStreamParameters.hostApiSpecificStreamInfo = NULL;
i_err = Pa_OpenStream( &p_sys->p_stream, NULL /* no input */,
paStreamParameters.hostApiSpecificStreamInfo = NULL;
i_err = Pa_OpenStream( &p_sys->p_stream, NULL /* no input */,
FRAME_SIZE, paClipOff, paCallback, p_sys );
if( i_err != paNoError )
{
FRAME_SIZE, paClipOff, paCallback, p_sys );
if( i_err != paNoError )
{
{
msg_Err( p_aout, "Pa_StartStream() failed" );
Pa_CloseStream( p_sys->p_stream );
{
msg_Err( p_aout, "Pa_StartStream() failed" );
Pa_CloseStream( p_sys->p_stream );
#ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN
/*****************************************************************************
* PORTAUDIOThread: all interactions with libportaudio.a are handled
* in this single thread. Otherwise libportaudio.a is _not_ happy :-(
*****************************************************************************/
#ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN
/*****************************************************************************
* PORTAUDIOThread: all interactions with libportaudio.a are handled
* in this single thread. Otherwise libportaudio.a is _not_ happy :-(
*****************************************************************************/
vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
vlc_mutex_unlock( &pa_thread->lock_signal );
pa_thread->b_signal = false;
p_aout = pa_thread->p_aout;
vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
vlc_mutex_unlock( &pa_thread->lock_signal );
pa_thread->b_signal = false;
p_aout = pa_thread->p_aout;
vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
vlc_mutex_unlock( &pa_thread->lock_signal );
pa_thread->b_signal = false;
vlc_cond_wait( &pa_thread->signal, &pa_thread->lock_signal );
vlc_mutex_unlock( &pa_thread->lock_signal );
pa_thread->b_signal = false;