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( _("Float32 audio mixer") );
00048 set_capability( "audio mixer", 10 );
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 {
00061 return -1;
00062 }
00063
00064 if ( p_aout->i_nb_inputs == 1 && p_aout->mixer.f_multiplier == 1.0 )
00065 {
00066
00067 return -1;
00068 }
00069
00070 p_aout->mixer.pf_do_work = DoWork;
00071
00072 return 0;
00073 }
00074
00075
00076
00077
00078 static void ScaleWords( float * p_out, const float * p_in, size_t i_nb_words,
00079 int i_nb_inputs, float f_multiplier )
00080 {
00081 int i;
00082 f_multiplier /= i_nb_inputs;
00083
00084 for ( i = i_nb_words; i--; )
00085 {
00086 *p_out++ = *p_in++ * f_multiplier;
00087 }
00088 }
00089
00090
00091
00092
00093 static void MeanWords( float * p_out, const float * p_in, size_t i_nb_words,
00094 int i_nb_inputs, float f_multiplier )
00095 {
00096 int i;
00097 f_multiplier /= i_nb_inputs;
00098
00099 for ( i = i_nb_words; i--; )
00100 {
00101 *p_out++ += *p_in++ * f_multiplier;
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111 static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
00112 {
00113 int i_nb_inputs = p_aout->i_nb_inputs;
00114 float f_multiplier = p_aout->mixer.f_multiplier;
00115 int i_input;
00116 int i_nb_channels = aout_FormatNbChannels( &p_aout->mixer.mixer );
00117
00118 for ( i_input = 0; i_input < i_nb_inputs; i_input++ )
00119 {
00120 int i_nb_words = p_buffer->i_nb_samples * i_nb_channels;
00121 aout_input_t * p_input = p_aout->pp_inputs[i_input];
00122 float * p_out = (float *)p_buffer->p_buffer;
00123 float * p_in = (float *)p_input->p_first_byte_to_mix;
00124
00125 if ( p_input->b_error ) continue;
00126
00127 for ( ; ; )
00128 {
00129 ptrdiff_t i_available_words = (
00130 (float *)p_input->fifo.p_first->p_buffer - p_in)
00131 + p_input->fifo.p_first->i_nb_samples
00132 * i_nb_channels;
00133
00134 if ( i_available_words < i_nb_words )
00135 {
00136 aout_buffer_t * p_old_buffer;
00137
00138 if ( i_available_words > 0 )
00139 {
00140 if ( !i_input )
00141 {
00142 ScaleWords( p_out, p_in, i_available_words,
00143 i_nb_inputs, f_multiplier );
00144 }
00145 else
00146 {
00147 MeanWords( p_out, p_in, i_available_words,
00148 i_nb_inputs, f_multiplier );
00149 }
00150 }
00151
00152 i_nb_words -= i_available_words;
00153 p_out += i_available_words;
00154
00155
00156 p_old_buffer = aout_FifoPop( p_aout, &p_input->fifo );
00157 aout_BufferFree( p_old_buffer );
00158 if ( p_input->fifo.p_first == NULL )
00159 {
00160 msg_Err( p_aout, "internal amix error" );
00161 return;
00162 }
00163 p_in = (float *)p_input->fifo.p_first->p_buffer;
00164 }
00165 else
00166 {
00167 if ( i_nb_words > 0 )
00168 {
00169 if ( !i_input )
00170 {
00171 ScaleWords( p_out, p_in, i_nb_words, i_nb_inputs,
00172 f_multiplier );
00173 }
00174 else
00175 {
00176 MeanWords( p_out, p_in, i_nb_words, i_nb_inputs,
00177 f_multiplier );
00178 }
00179 }
00180 p_input->p_first_byte_to_mix = (void *)(p_in
00181 + i_nb_words);
00182 break;
00183 }
00184 }
00185 }
00186 }
00187