24
24
/*****************************************************************************
26
26
*****************************************************************************/
27
#include <stdlib.h> /* malloc(), free() */
31
#include "audio_output.h"
32
#include "aout_internal.h"
31
#include <vlc_common.h>
32
#include <vlc_plugin.h>
34
#include <vlc_filter.h>
35
#include <vlc_block.h>
34
37
/*****************************************************************************
36
39
*****************************************************************************/
37
40
static int Create ( vlc_object_t * );
39
static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
42
/*****************************************************************************
44
*****************************************************************************/
41
static int OpenFilter( vlc_object_t * );
45
43
vlc_module_begin();
46
set_description( _("Audio filter for simple channel mixing") );
44
set_description( N_("Audio filter for simple channel mixing") );
47
45
set_capability( "audio filter", 10 );
48
46
set_category( CAT_AUDIO );
49
47
set_subcategory( SUBCAT_AUDIO_MISC );
50
48
set_callbacks( Create, NULL );
51
set_description( N_("audio filter for simple channel mixing") );
52
set_capability( "audio filter2", 10 );
53
set_callbacks( OpenFilter, NULL );
53
56
/*****************************************************************************
58
*****************************************************************************/
59
#define AOUT_CHANS_STEREO_FRONT ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT )
60
#define AOUT_CHANS_STEREO_REAR ( AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT )
61
#define AOUT_CHANS_STEREO_MIDDLE (AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT )
63
#define AOUT_CHANS_2_0 AOUT_CHANS_STEREO_FRONT
64
#define AOUT_CHANS_4_0 (AOUT_CHANS_STEREO_FRONT | AOUT_CHANS_STEREO_REAR )
65
#define AOUT_CHANS_5_0 ( AOUT_CHANS_4_0 | AOUT_CHAN_CENTER )
66
#define AOUT_CHANS_6_0 (AOUT_CHANS_STEREO_FRONT | AOUT_CHANS_STEREO_REAR | AOUT_CHANS_STEREO_MIDDLE )
67
#define AOUT_CHANS_7_0 ( AOUT_CHANS_6_0 | AOUT_CHAN_CENTER )
69
static bool IsSupported( const audio_format_t *p_input, const audio_format_t *p_output );
71
static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
74
static block_t *Filter( filter_t *, block_t * );
76
/*****************************************************************************
54
77
* Create: allocate trivial channel mixer
55
78
*****************************************************************************/
56
79
static int Create( vlc_object_t *p_this )
58
81
aout_filter_t * p_filter = (aout_filter_t *)p_this;
60
if ( (p_filter->input.i_physical_channels
61
== p_filter->output.i_physical_channels
62
&& p_filter->input.i_original_channels
63
== p_filter->output.i_original_channels)
64
|| p_filter->input.i_format != p_filter->output.i_format
65
|| p_filter->input.i_rate != p_filter->output.i_rate
66
|| p_filter->input.i_format != VLC_FOURCC('f','l','3','2') )
71
/* Only conversion to Stereo and 4.0 right now */
72
if( p_filter->output.i_physical_channels !=
73
(AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)
74
&& p_filter->output.i_physical_channels !=
75
( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
76
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) )
81
/* Only from 7/7.1/5/5.1 */
82
if( (p_filter->input.i_physical_channels & ~AOUT_CHAN_LFE) !=
83
(AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
84
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) &&
85
(p_filter->input.i_physical_channels & ~AOUT_CHAN_LFE) !=
86
(AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
87
AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
88
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT) )
83
if( !IsSupported( &p_filter->input, &p_filter->output ) )
93
86
p_filter->pf_do_work = DoWork;
94
87
p_filter->b_in_place = 0;
102
95
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
103
96
aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
105
99
int i_input_nb = aout_FormatNbChannels( &p_filter->input );
106
100
int i_output_nb = aout_FormatNbChannels( &p_filter->output );
107
101
float *p_dest = (float *)p_out_buf->p_buffer;
108
float *p_src = (float *)p_in_buf->p_buffer;
102
const float *p_src = (const float *)p_in_buf->p_buffer;
111
105
p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
112
106
p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * i_output_nb / i_input_nb;
114
if( p_filter->output.i_physical_channels ==
115
(AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) )
108
if( p_filter->output.i_physical_channels == AOUT_CHANS_2_0 )
117
110
if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT )
118
111
for( i = p_in_buf->i_nb_samples; i--; )
139
132
if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
135
else if( p_filter->output.i_physical_channels == AOUT_CHAN_CENTER )
137
if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT )
138
for( i = p_in_buf->i_nb_samples; i--; )
140
*p_dest = p_src[6] + p_src[0] / 4 + p_src[1] / 4 + p_src[2] / 8 + p_src[3] / 8 + p_src[4] / 8 + p_src[5] / 8;
145
if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
147
else if( p_filter->input.i_physical_channels & AOUT_CHAN_REARLEFT )
148
for( i = p_in_buf->i_nb_samples; i--; )
150
*p_dest = p_src[4] + p_src[0] / 4 + p_src[1] / 4 + p_src[2] / 6 + p_src[3] / 6;
155
if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
158
for( i = p_in_buf->i_nb_samples; i--; )
160
*p_dest = p_src[0] / 2 + p_src[1] / 2;
144
168
if( p_filter->input.i_physical_channels & AOUT_CHAN_MIDDLELEFT )
174
198
if( p_filter->input.i_physical_channels & AOUT_CHAN_LFE ) p_src++;
203
/*****************************************************************************
205
*****************************************************************************/
206
static int OpenFilter( vlc_object_t *p_this )
208
filter_t *p_filter = (filter_t *)p_this;
210
audio_format_t fmt_in = p_filter->fmt_in.audio;
211
audio_format_t fmt_out = p_filter->fmt_out.audio;
213
fmt_in.i_format = p_filter->fmt_in.i_codec;
214
fmt_out.i_format = p_filter->fmt_out.i_codec;
216
if( !IsSupported( &fmt_in, &fmt_out ) )
219
p_filter->pf_audio_filter = Filter;
224
/*****************************************************************************
226
*****************************************************************************/
227
static block_t *Filter( filter_t *p_filter, block_t *p_block )
229
aout_filter_t aout_filter;
230
aout_buffer_t in_buf, out_buf;
234
if( !p_block || !p_block->i_samples )
237
block_Release( p_block );
241
i_out_size = p_block->i_samples *
242
p_filter->fmt_out.audio.i_bitspersample *
243
p_filter->fmt_out.audio.i_channels / 8;
245
p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size );
248
msg_Warn( p_filter, "can't get output buffer" );
249
block_Release( p_block );
253
p_out->i_samples = p_block->i_samples;
254
p_out->i_dts = p_block->i_dts;
255
p_out->i_pts = p_block->i_pts;
256
p_out->i_length = p_block->i_length;
258
aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys;
259
aout_filter.input = p_filter->fmt_in.audio;
260
aout_filter.input.i_format = p_filter->fmt_in.i_codec;
261
aout_filter.output = p_filter->fmt_out.audio;
262
aout_filter.output.i_format = p_filter->fmt_out.i_codec;
264
in_buf.p_buffer = p_block->p_buffer;
265
in_buf.i_nb_bytes = p_block->i_buffer;
266
in_buf.i_nb_samples = p_block->i_samples;
267
out_buf.p_buffer = p_out->p_buffer;
268
out_buf.i_nb_bytes = p_out->i_buffer;
269
out_buf.i_nb_samples = p_out->i_samples;
271
DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf );
273
block_Release( p_block );
275
p_out->i_buffer = out_buf.i_nb_bytes;
276
p_out->i_samples = out_buf.i_nb_samples;
281
/*****************************************************************************
283
*****************************************************************************/
284
static bool IsSupported( const audio_format_t *p_input, const audio_format_t *p_output )
286
if( p_input->i_format != VLC_FOURCC('f','l','3','2') ||
287
p_input->i_format != p_output->i_format ||
288
p_input->i_rate != p_output->i_rate )
291
if( p_input->i_physical_channels == p_output->i_physical_channels &&
292
p_input->i_original_channels == p_output->i_original_channels )
297
/* Only conversion to Mono, Stereo and 4.0 right now */
298
if( p_output->i_physical_channels != AOUT_CHAN_CENTER &&
299
p_output->i_physical_channels != AOUT_CHANS_2_0 &&
300
p_output->i_physical_channels != AOUT_CHANS_4_0 )
305
/* Only from 7/7.1/5/5.1/2.0 */
306
if( (p_input->i_physical_channels & ~AOUT_CHAN_LFE) != AOUT_CHANS_7_0 &&
307
(p_input->i_physical_channels & ~AOUT_CHAN_LFE) != AOUT_CHANS_5_0 &&
308
p_input->i_physical_channels != AOUT_CHANS_2_0 )
313
/* Only if we downmix */
314
if( aout_FormatNbChannels( p_input ) <= aout_FormatNbChannels( p_output ) )