/*****************************************************************************
* mixer.c : audio output mixing operations
*****************************************************************************
- * Copyright (C) 2002 VideoLAN
- * $Id: mixer.c,v 1.22 2002/12/18 14:17:11 sam Exp $
+ * Copyright (C) 2002-2004 VideoLAN
+ * $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*****************************************************************************/
int aout_MixerNew( aout_instance_t * p_aout )
{
- p_aout->mixer.p_module = module_Need( p_aout, "audio mixer", NULL );
+ p_aout->mixer.p_module = module_Need( p_aout, "audio mixer", NULL, 0 );
if ( p_aout->mixer.p_module == NULL )
{
msg_Err( p_aout, "no suitable aout mixer" );
*****************************************************************************
* Please note that you must hold the mixer lock.
*****************************************************************************/
-int aout_MixerDelete( aout_instance_t * p_aout )
+void aout_MixerDelete( aout_instance_t * p_aout )
{
- if ( p_aout->mixer.b_error ) return 0;
+ if ( p_aout->mixer.b_error ) return;
module_Unneed( p_aout, p_aout->mixer.p_module );
p_aout->mixer.b_error = 1;
-
- return 0;
}
/*****************************************************************************
p_buffer = aout_FifoPop( p_aout, p_fifo );
aout_BufferFree( p_buffer );
p_buffer = p_fifo->p_first;
+ p_input->p_first_byte_to_mix = NULL;
}
if ( p_buffer == NULL )
}
/* Check for the continuity of start_date */
- while ( p_buffer != NULL && p_buffer->end_date < start_date )
+ while ( p_buffer != NULL && p_buffer->end_date < start_date - 1 )
{
+ /* We authorize a +-1 because rounding errors get compensated
+ * regularly. */
aout_buffer_t * p_next = p_buffer->p_next;
- msg_Err( p_aout, "the mixer got a packet in the past ("I64Fd")",
- start_date - p_buffer->end_date );
+ msg_Warn( p_aout, "the mixer got a packet in the past ("I64Fd")",
+ start_date - p_buffer->end_date );
aout_BufferFree( p_buffer );
p_fifo->p_first = p_buffer = p_next;
p_input->p_first_byte_to_mix = NULL;
break;
}
- if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer.mixer ) )
- {
- /* Additionally check that p_first_byte_to_mix is well
- * located. */
- mtime_t i_nb_bytes = (start_date - p_buffer->start_date)
- * p_aout->mixer.mixer.i_bytes_per_frame
- * p_aout->mixer.mixer.i_rate
- / p_aout->mixer.mixer.i_frame_length
- / 1000000;
- ptrdiff_t mixer_nb_bytes;
-
- if ( p_input->p_first_byte_to_mix == NULL )
- {
- p_input->p_first_byte_to_mix = p_buffer->p_buffer;
- }
- mixer_nb_bytes = p_input->p_first_byte_to_mix
- - p_buffer->p_buffer;
-
- if ( !((i_nb_bytes + p_aout->mixer.mixer.i_bytes_per_frame
- > mixer_nb_bytes) &&
- (i_nb_bytes < p_aout->mixer.mixer.i_bytes_per_frame
- + mixer_nb_bytes)) )
- {
- msg_Warn( p_aout,
- "mixer start isn't output start ("I64Fd,
- i_nb_bytes - mixer_nb_bytes );
-
- /* Round to the nearest multiple */
- i_nb_bytes /= p_aout->mixer.mixer.i_bytes_per_frame;
- i_nb_bytes *= p_aout->mixer.mixer.i_bytes_per_frame;
- p_input->p_first_byte_to_mix = p_buffer->p_buffer
- + i_nb_bytes;
- }
- }
-
/* Check that we have enough samples. */
for ( ; ; )
{
else break;
}
if ( p_buffer == NULL ) break;
+
+ p_buffer = p_fifo->p_first;
+ if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer.mixer ) )
+ {
+ /* Additionally check that p_first_byte_to_mix is well
+ * located. */
+ mtime_t i_nb_bytes = (start_date - p_buffer->start_date)
+ * p_aout->mixer.mixer.i_bytes_per_frame
+ * p_aout->mixer.mixer.i_rate
+ / p_aout->mixer.mixer.i_frame_length
+ / 1000000;
+ ptrdiff_t mixer_nb_bytes;
+
+ if ( p_input->p_first_byte_to_mix == NULL )
+ {
+ p_input->p_first_byte_to_mix = p_buffer->p_buffer;
+ }
+ mixer_nb_bytes = p_input->p_first_byte_to_mix - p_buffer->p_buffer;
+
+ if ( !((i_nb_bytes + p_aout->mixer.mixer.i_bytes_per_frame
+ > mixer_nb_bytes) &&
+ (i_nb_bytes < p_aout->mixer.mixer.i_bytes_per_frame
+ + mixer_nb_bytes)) )
+ {
+ msg_Warn( p_aout, "mixer start isn't output start ("I64Fd")",
+ i_nb_bytes - mixer_nb_bytes );
+
+ /* Round to the nearest multiple */
+ i_nb_bytes /= p_aout->mixer.mixer.i_bytes_per_frame;
+ i_nb_bytes *= p_aout->mixer.mixer.i_bytes_per_frame;
+
+ if( i_nb_bytes < 0 ) break; /* FIXME: reset state properly */
+
+ p_input->p_first_byte_to_mix = p_buffer->p_buffer + i_nb_bytes;
+ }
+ }
}
if ( i < p_aout->i_nb_inputs || i_first_input == p_aout->i_nb_inputs )