2 * This filter adds a center channel to the audio stream by
3 * averaging the left and right channel.
4 * There are two runtime controls one for setting which channel
5 * to insert the center-audio into called AF_CONTROL_SUB_CH.
7 * FIXME: implement a high-pass filter for better results.
9 * copyright (c) 2005 Alex Beregszaszi
11 * This file is part of MPlayer.
13 * MPlayer is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * MPlayer is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 // Data for specific instances of this filter
35 typedef struct af_center_s
37 int ch
; // Channel number which to insert the filtered data
40 // Initialization and runtime control
41 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
43 af_center_t
* s
= af
->setup
;
46 case AF_CONTROL_REINIT
:{
48 if(!arg
) return AF_ERROR
;
50 af
->data
->rate
= ((af_data_t
*)arg
)->rate
;
51 af
->data
->nch
= max(s
->ch
+1,((af_data_t
*)arg
)->nch
);
52 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
55 return af_test_output(af
,(af_data_t
*)arg
);
57 case AF_CONTROL_COMMAND_LINE
:{
59 sscanf(arg
,"%i", &ch
);
60 return control(af
,AF_CONTROL_CENTER_CH
| AF_CONTROL_SET
, &ch
);
62 case AF_CONTROL_CENTER_CH
| AF_CONTROL_SET
: // Requires reinit
64 if((*(int*)arg
>= AF_NCH
) || (*(int*)arg
< 0)){
65 af_msg(AF_MSG_ERROR
,"[sub] Center channel number must be between "
66 " 0 and %i current value is %i\n", AF_NCH
-1, *(int*)arg
);
71 case AF_CONTROL_CENTER_CH
| AF_CONTROL_GET
:
79 static void uninit(struct af_instance_s
* af
)
87 // Filter data through filter
88 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
90 af_data_t
* c
= data
; // Current working data
91 af_center_t
* s
= af
->setup
; // Setup for this instance
92 float* a
= c
->audio
; // Audio data
93 int len
= c
->len
/4; // Number of samples in current audio block
94 int nch
= c
->nch
; // Number of channels
95 int ch
= s
->ch
; // Channel in which to insert the center audio
99 for(i
=0;i
<len
;i
+=nch
){
100 // Average left and right
101 a
[i
+ch
] = (a
[i
]/2) + (a
[i
+1]/2);
107 // Allocate memory and set function pointers
108 static int af_open(af_instance_t
* af
){
114 af
->data
=calloc(1,sizeof(af_data_t
));
115 af
->setup
=s
=calloc(1,sizeof(af_center_t
));
116 if(af
->data
== NULL
|| af
->setup
== NULL
)
118 // Set default values
119 s
->ch
= 1; // Channel nr 2
123 // Description of this filter
124 af_info_t af_info_center
= {
125 "Audio filter for adding a center channel",
129 AF_FLAGS_NOT_REENTRANT
,