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 2004 Alex Beregszaszi & Pierre Lombard
8 //=============================================================================
22 // Data for specific instances of this filter
23 typedef struct af_extrastereo_s
28 static af_data_t
* play_s16(struct af_instance_s
* af
, af_data_t
* data
);
29 static af_data_t
* play_float(struct af_instance_s
* af
, af_data_t
* data
);
31 // Initialization and runtime control
32 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
34 af_extrastereo_t
* s
= (af_extrastereo_t
*)af
->setup
;
37 case AF_CONTROL_REINIT
:{
39 if(!arg
) return AF_ERROR
;
41 af
->data
->rate
= ((af_data_t
*)arg
)->rate
;
43 if (((af_data_t
*)arg
)->format
== AF_FORMAT_FLOAT_NE
)
45 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
47 af
->play
= play_float
;
50 af
->data
->format
= AF_FORMAT_S16_NE
;
55 return af_test_output(af
,(af_data_t
*)arg
);
57 case AF_CONTROL_COMMAND_LINE
:{
59 sscanf((char*)arg
,"%f", &f
);
63 case AF_CONTROL_ES_MUL
| AF_CONTROL_SET
:
64 s
->mul
= *(float*)arg
;
66 case AF_CONTROL_ES_MUL
| AF_CONTROL_GET
:
67 *(float*)arg
= s
->mul
;
74 static void uninit(struct af_instance_s
* af
)
82 // Filter data through filter
83 static af_data_t
* play_s16(struct af_instance_s
* af
, af_data_t
* data
)
85 af_extrastereo_t
*s
= af
->setup
;
87 int16_t *a
= (int16_t*)data
->audio
; // Audio data
88 int len
= data
->len
/2; // Number of samples
91 for (i
= 0; i
< len
; i
+=2)
93 avg
= (a
[i
] + a
[i
+ 1]) / 2;
95 l
= avg
+ (int)(s
->mul
* (a
[i
] - avg
));
96 r
= avg
+ (int)(s
->mul
* (a
[i
+ 1] - avg
));
98 a
[i
] = clamp(l
, SHRT_MIN
, SHRT_MAX
);
99 a
[i
+ 1] = clamp(r
, SHRT_MIN
, SHRT_MAX
);
105 static af_data_t
* play_float(struct af_instance_s
* af
, af_data_t
* data
)
107 af_extrastereo_t
*s
= af
->setup
;
109 float *a
= (float*)data
->audio
; // Audio data
110 int len
= data
->len
/4; // Number of samples
113 for (i
= 0; i
< len
; i
+=2)
115 avg
= (a
[i
] + a
[i
+ 1]) / 2;
117 l
= avg
+ (s
->mul
* (a
[i
] - avg
));
118 r
= avg
+ (s
->mul
* (a
[i
+ 1] - avg
));
120 a
[i
] = af_softclip(l
);
121 a
[i
+ 1] = af_softclip(r
);
127 // Allocate memory and set function pointers
128 static int open(af_instance_t
* af
){
134 af
->data
=calloc(1,sizeof(af_data_t
));
135 af
->setup
=calloc(1,sizeof(af_extrastereo_t
));
136 if(af
->data
== NULL
|| af
->setup
== NULL
)
139 ((af_extrastereo_t
*)af
->setup
)->mul
= 2.5;
143 // Description of this filter
144 af_info_t af_info_extrastereo
= {
147 "Alex Beregszaszi & Pierre Lombard",
149 AF_FLAGS_NOT_REENTRANT
,