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 #include <stdlib.h>
00028 #include <string.h>
00029
00030 #include <vlc/vlc.h>
00031 #include "audio_output.h"
00032 #include "aout_internal.h"
00033
00034
00035
00036
00037 static int Create ( vlc_object_t * );
00038
00039 static void DoWork ( aout_instance_t *, aout_buffer_t * );
00040
00041
00042
00043
00044 vlc_module_begin();
00045 set_category( CAT_AUDIO );
00046 set_subcategory( SUBCAT_AUDIO_MISC );
00047 set_description( _("Trivial audio mixer") );
00048 set_capability( "audio mixer", 1 );
00049 set_callbacks( Create, NULL );
00050 vlc_module_end();
00051
00052
00053
00054
00055 static int Create( vlc_object_t *p_this )
00056 {
00057 aout_instance_t * p_aout = (aout_instance_t *)p_this;
00058
00059 if ( p_aout->mixer.mixer.i_format != VLC_FOURCC('f','l','3','2')
00060 && p_aout->mixer.mixer.i_format != VLC_FOURCC('f','i','3','2') )
00061 {
00062 return -1;
00063 }
00064
00065 p_aout->mixer.pf_do_work = DoWork;
00066
00067 return 0;
00068 }
00069
00070
00071
00072
00073 static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
00074 {
00075 int i = 0;
00076 aout_input_t * p_input = p_aout->pp_inputs[i];
00077 int i_nb_channels = aout_FormatNbChannels( &p_aout->mixer.mixer );
00078 int i_nb_bytes = p_buffer->i_nb_samples * sizeof(int32_t)
00079 * i_nb_channels;
00080 byte_t * p_in;
00081 byte_t * p_out;
00082
00083 while ( p_input->b_error )
00084 {
00085 p_input = p_aout->pp_inputs[++i];
00086
00087
00088 }
00089 p_in = p_input->p_first_byte_to_mix;
00090 p_out = p_buffer->p_buffer;
00091
00092 for ( ; ; )
00093 {
00094 ptrdiff_t i_available_bytes = (p_input->fifo.p_first->p_buffer
00095 - p_in)
00096 + p_input->fifo.p_first->i_nb_samples
00097 * sizeof(int32_t)
00098 * i_nb_channels;
00099
00100 if ( i_available_bytes < i_nb_bytes )
00101 {
00102 aout_buffer_t * p_old_buffer;
00103
00104 if ( i_available_bytes > 0 )
00105 p_aout->p_vlc->pf_memcpy( p_out, p_in, i_available_bytes );
00106 i_nb_bytes -= i_available_bytes;
00107 p_out += i_available_bytes;
00108
00109
00110 p_old_buffer = aout_FifoPop( p_aout, &p_input->fifo );
00111 aout_BufferFree( p_old_buffer );
00112 if ( p_input->fifo.p_first == NULL )
00113 {
00114 msg_Err( p_aout, "internal amix error" );
00115 return;
00116 }
00117 p_in = p_input->fifo.p_first->p_buffer;
00118 }
00119 else
00120 {
00121 if ( i_nb_bytes > 0 )
00122 p_aout->p_vlc->pf_memcpy( p_out, p_in, i_nb_bytes );
00123 p_input->p_first_byte_to_mix = p_in + i_nb_bytes;
00124 break;
00125 }
00126 }
00127
00128
00129 for ( i++; i < p_aout->i_nb_inputs; i++ )
00130 {
00131 aout_fifo_t * p_fifo;
00132 aout_buffer_t * p_deleted;
00133
00134 p_input = p_aout->pp_inputs[i];
00135 if ( p_input->b_error ) continue;
00136 p_fifo = &p_input->fifo;
00137 p_deleted = p_fifo->p_first;
00138 while ( p_deleted != NULL )
00139 {
00140 aout_buffer_t * p_next = p_deleted->p_next;
00141 aout_BufferFree( p_deleted );
00142 p_deleted = p_next;
00143 }
00144 p_fifo->p_first = NULL;
00145 p_fifo->pp_last = &p_fifo->p_first;
00146 }
00147 }
00148