1 /*=============================================================================
3 // This software has been released under the terms of the GNU General Public
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
6 // Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
8 //=============================================================================
22 // Data for specific instances of this filter
23 typedef struct af_pan_s
25 int nch
; // Number of output channels; zero means same as input
26 float level
[AF_NCH
][AF_NCH
]; // Gain level for each channel
29 // Initialization and runtime control
30 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
32 af_pan_t
* s
= af
->setup
;
35 case AF_CONTROL_REINIT
:
37 if(!arg
) return AF_ERROR
;
39 af
->data
->rate
= ((af_data_t
*)arg
)->rate
;
40 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
42 af
->data
->nch
= s
->nch
? s
->nch
: ((af_data_t
*)arg
)->nch
;
43 af
->mul
= (double)af
->data
->nch
/ ((af_data_t
*)arg
)->nch
;
45 if((af
->data
->format
!= ((af_data_t
*)arg
)->format
) ||
46 (af
->data
->bps
!= ((af_data_t
*)arg
)->bps
)){
47 ((af_data_t
*)arg
)->format
= af
->data
->format
;
48 ((af_data_t
*)arg
)->bps
= af
->data
->bps
;
52 case AF_CONTROL_COMMAND_LINE
:{
57 // Read number of outputs
58 sscanf((char*)arg
,"%i%n", &nch
,&n
);
59 if(AF_OK
!= control(af
,AF_CONTROL_PAN_NOUT
| AF_CONTROL_SET
, &nch
))
63 cp
= &((char*)arg
)[n
];
65 while((*cp
== ':') && (k
< AF_NCH
)){
66 sscanf(cp
, ":%f%n" , &s
->level
[j
][k
], &n
);
67 af_msg(AF_MSG_VERBOSE
,"[pan] Pan level from channel %i to"
68 " channel %i = %f\n",k
,j
,s
->level
[j
][k
]);
78 case AF_CONTROL_PAN_LEVEL
| AF_CONTROL_SET
:{
80 int ch
= ((af_control_ext_t
*)arg
)->ch
;
81 float* level
= ((af_control_ext_t
*)arg
)->arg
;
85 s
->level
[ch
][i
] = level
[i
];
88 case AF_CONTROL_PAN_LEVEL
| AF_CONTROL_GET
:{
90 int ch
= ((af_control_ext_t
*)arg
)->ch
;
91 float* level
= ((af_control_ext_t
*)arg
)->arg
;
95 level
[i
] = s
->level
[ch
][i
];
98 case AF_CONTROL_PAN_NOUT
| AF_CONTROL_SET
:
99 // Reinit must be called after this function has been called
102 if(((int*)arg
)[0] <= 0 || ((int*)arg
)[0] > AF_NCH
){
103 af_msg(AF_MSG_ERROR
,"[pan] The number of output channels must be"
104 " between 1 and %i. Current value is %i\n",AF_NCH
,((int*)arg
)[0]);
107 s
->nch
=((int*)arg
)[0];
109 case AF_CONTROL_PAN_NOUT
| AF_CONTROL_GET
:
110 *(int*)arg
= af
->data
->nch
;
112 case AF_CONTROL_PAN_BALANCE
| AF_CONTROL_SET
:{
113 float val
= *(float*)arg
;
116 if (af
->data
->nch
>= 2) {
117 s
->level
[0][0] = min(1.f
, 1.f
- val
);
118 s
->level
[0][1] = max(0.f
, val
);
119 s
->level
[1][0] = max(0.f
, -val
);
120 s
->level
[1][1] = min(1.f
, 1.f
+ val
);
124 case AF_CONTROL_PAN_BALANCE
| AF_CONTROL_GET
:
127 *(float*)arg
= s
->level
[0][1] - s
->level
[1][0];
134 static void uninit(struct af_instance_s
* af
)
137 free(af
->data
->audio
);
143 // Filter data through filter
144 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
146 af_data_t
* c
= data
; // Current working data
147 af_data_t
* l
= af
->data
; // Local data
148 af_pan_t
* s
= af
->setup
; // Setup for this instance
149 float* in
= c
->audio
; // Input audio data
150 float* out
= NULL
; // Output audio data
151 float* end
= in
+c
->len
/4; // End of loop
152 int nchi
= c
->nch
; // Number of input channels
153 int ncho
= l
->nch
; // Number of output channels
156 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
164 register float x
= 0.0;
165 register float* tin
= in
;
167 x
+= tin
[k
] * s
->level
[j
][k
];
176 c
->len
= c
->len
/ c
->nch
* l
->nch
;
182 // Allocate memory and set function pointers
183 static int af_open(af_instance_t
* af
){
188 af
->data
=calloc(1,sizeof(af_data_t
));
189 af
->setup
=calloc(1,sizeof(af_pan_t
));
190 if(af
->data
== NULL
|| af
->setup
== NULL
)
195 // Description of this filter
196 af_info_t af_info_pan
= {
197 "Panning audio filter",