1 /*****************************************************************************
2 * float32.c : precise float32 audio mixer implementation
3 *****************************************************************************
4 * Copyright (C) 2002 the VideoLAN team
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
37 /*****************************************************************************
39 *****************************************************************************/
40 static int Create ( vlc_object_t
* );
42 static void DoWork ( aout_instance_t
*, aout_buffer_t
* );
44 /*****************************************************************************
46 *****************************************************************************/
48 set_category( CAT_AUDIO
);
49 set_subcategory( SUBCAT_AUDIO_MISC
);
50 set_description( N_("Float32 audio mixer") );
51 set_capability( "audio mixer", 10 );
52 set_callbacks( Create
, NULL
);
55 /*****************************************************************************
56 * Create: allocate mixer
57 *****************************************************************************/
58 static int Create( vlc_object_t
*p_this
)
60 aout_instance_t
* p_aout
= (aout_instance_t
*)p_this
;
62 if ( p_aout
->mixer
.mixer
.i_format
!= VLC_FOURCC('f','l','3','2') )
67 /* Use the trivial mixer when we can */
68 if ( p_aout
->i_nb_inputs
== 1 && p_aout
->mixer
.f_multiplier
== 1.0 )
71 for( i
= 0; i
< p_aout
->i_nb_inputs
; i
++ )
73 if( p_aout
->pp_inputs
[i
]->f_multiplier
!= 1.0 )
76 if( i
>= p_aout
->i_nb_inputs
)
80 p_aout
->mixer
.pf_do_work
= DoWork
;
84 /*****************************************************************************
85 * ScaleWords: prepare input words for averaging
86 *****************************************************************************/
87 static void ScaleWords( float * p_out
, const float * p_in
, size_t i_nb_words
,
88 int i_nb_inputs
, float f_multiplier
)
91 f_multiplier
/= i_nb_inputs
;
93 for ( i
= i_nb_words
; i
--; )
95 *p_out
++ = *p_in
++ * f_multiplier
;
99 /*****************************************************************************
100 * MeanWords: average input words
101 *****************************************************************************/
102 static void MeanWords( float * p_out
, const float * p_in
, size_t i_nb_words
,
103 int i_nb_inputs
, float f_multiplier
)
106 f_multiplier
/= i_nb_inputs
;
108 for ( i
= i_nb_words
; i
--; )
110 *p_out
++ += *p_in
++ * f_multiplier
;
114 /*****************************************************************************
115 * DoWork: mix a new output buffer
116 *****************************************************************************
117 * Terminology : in this function a word designates a single float32, eg.
118 * a stereo sample is consituted of two words.
119 *****************************************************************************/
120 static void DoWork( aout_instance_t
* p_aout
, aout_buffer_t
* p_buffer
)
122 const int i_nb_inputs
= p_aout
->i_nb_inputs
;
123 const float f_multiplier_global
= p_aout
->mixer
.f_multiplier
;
124 const int i_nb_channels
= aout_FormatNbChannels( &p_aout
->mixer
.mixer
);
127 for ( i_input
= 0; i_input
< i_nb_inputs
; i_input
++ )
129 int i_nb_words
= p_buffer
->i_nb_samples
* i_nb_channels
;
130 aout_input_t
* p_input
= p_aout
->pp_inputs
[i_input
];
131 float f_multiplier
= f_multiplier_global
* p_input
->f_multiplier
;
133 float * p_out
= (float *)p_buffer
->p_buffer
;
134 float * p_in
= (float *)p_input
->p_first_byte_to_mix
;
136 if ( p_input
->b_error
) continue;
140 ptrdiff_t i_available_words
= (
141 (float *)p_input
->fifo
.p_first
->p_buffer
- p_in
)
142 + p_input
->fifo
.p_first
->i_nb_samples
145 if ( i_available_words
< i_nb_words
)
147 aout_buffer_t
* p_old_buffer
;
149 if ( i_available_words
> 0 )
153 ScaleWords( p_out
, p_in
, i_available_words
,
154 i_nb_inputs
, f_multiplier
);
158 MeanWords( p_out
, p_in
, i_available_words
,
159 i_nb_inputs
, f_multiplier
);
163 i_nb_words
-= i_available_words
;
164 p_out
+= i_available_words
;
167 p_old_buffer
= aout_FifoPop( p_aout
, &p_input
->fifo
);
168 aout_BufferFree( p_old_buffer
);
169 if ( p_input
->fifo
.p_first
== NULL
)
171 msg_Err( p_aout
, "internal amix error" );
174 p_in
= (float *)p_input
->fifo
.p_first
->p_buffer
;
178 if ( i_nb_words
> 0 )
182 ScaleWords( p_out
, p_in
, i_nb_words
, i_nb_inputs
,
187 MeanWords( p_out
, p_in
, i_nb_words
, i_nb_inputs
,
191 p_input
->p_first_byte_to_mix
= (void *)(p_in