annotate libaf/af_extrastereo.c @ 15978:c8dc500e078e

memcpy and memmove both copy memory, but when using memcpy the source and destination must not overlap, but here, they did overlap. Committed with the kind blessing of Richard, patch by uau
author gpoirier
date Fri, 15 Jul 2005 22:09:30 +0000
parents 7b7c94b5e78a
children fd6f824ef894
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
1 /*=============================================================================
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
2 //
13602
14090f7300a8 The full name of the GPL is GNU General Public License.
diego
parents: 13550
diff changeset
3 // This software has been released under the terms of the GNU General Public
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
5 //
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
6 // Copyright 2004 Alex Beregszaszi & Pierre Lombard
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
7 //
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
8 //=============================================================================
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
9 */
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
10
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
11 #include <stdio.h>
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
12 #include <stdlib.h>
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
13 #include <string.h>
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
14
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
15 #include <unistd.h>
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
16 #include <inttypes.h>
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
17 #include <math.h>
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
18 #include <limits.h>
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
19
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
20 #include "af.h"
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
21
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
22 // Data for specific instances of this filter
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
23 typedef struct af_extrastereo_s
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
24 {
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
25 float mul;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
26 }af_extrastereo_t;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
27
14624
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
28 static af_data_t* play_s16(struct af_instance_s* af, af_data_t* data);
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
29 static af_data_t* play_float(struct af_instance_s* af, af_data_t* data);
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
30
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
31 // Initialization and runtime control
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
32 static int control(struct af_instance_s* af, int cmd, void* arg)
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
33 {
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
34 af_extrastereo_t* s = (af_extrastereo_t*)af->setup;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
35
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
36 switch(cmd){
14624
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
37 case AF_CONTROL_REINIT:{
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
38 // Sanity check
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
39 if(!arg) return AF_ERROR;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
40
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
41 af->data->rate = ((af_data_t*)arg)->rate;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
42 af->data->nch = 2;
14624
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
43 if (((af_data_t*)arg)->format == AF_FORMAT_FLOAT_NE)
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
44 {
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
45 af->data->format = AF_FORMAT_FLOAT_NE;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
46 af->data->bps = 4;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
47 af->play = play_float;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
48 }// else
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
49 {
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
50 af->data->format = AF_FORMAT_S16_NE;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
51 af->data->bps = 2;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
52 af->play = play_s16;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
53 }
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
54
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
55 return af_test_output(af,(af_data_t*)arg);
14624
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
56 }
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
57 case AF_CONTROL_COMMAND_LINE:{
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
58 float f;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
59 sscanf((char*)arg,"%f", &f);
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
60 s->mul = f;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
61 return AF_OK;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
62 }
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
63 case AF_CONTROL_ES_MUL | AF_CONTROL_SET:
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
64 s->mul = *(float*)arg;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
65 return AF_OK;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
66 case AF_CONTROL_ES_MUL | AF_CONTROL_GET:
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
67 *(float*)arg = s->mul;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
68 return AF_OK;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
69 }
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
70 return AF_UNKNOWN;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
71 }
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
72
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
73 // Deallocate memory
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
74 static void uninit(struct af_instance_s* af)
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
75 {
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
76 if(af->data)
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
77 free(af->data);
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
78 if(af->setup)
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
79 free(af->setup);
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
80 }
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
81
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
82 // Filter data through filter
14624
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
83 static af_data_t* play_s16(struct af_instance_s* af, af_data_t* data)
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
84 {
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
85 af_extrastereo_t *s = af->setup;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
86 register int i = 0;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
87 int16_t *a = (int16_t*)data->audio; // Audio data
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
88 int len = data->len/2; // Number of samples
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
89 int avg, l, r;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
90
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
91 for (i = 0; i < len; i+=2)
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
92 {
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
93 avg = (a[i] + a[i + 1]) / 2;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
94
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
95 l = avg + (int)(s->mul * (a[i] - avg));
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
96 r = avg + (int)(s->mul * (a[i + 1] - avg));
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
97
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
98 a[i] = clamp(l, SHRT_MIN, SHRT_MAX);
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
99 a[i + 1] = clamp(r, SHRT_MIN, SHRT_MAX);
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
100 }
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
101
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
102 return data;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
103 }
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
104
14624
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
105 static af_data_t* play_float(struct af_instance_s* af, af_data_t* data)
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
106 {
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
107 af_extrastereo_t *s = af->setup;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
108 register int i = 0;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
109 float *a = (float*)data->audio; // Audio data
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
110 int len = data->len/4; // Number of samples
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
111 float avg, l, r;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
112
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
113 for (i = 0; i < len; i+=2)
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
114 {
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
115 avg = (a[i] + a[i + 1]) / 2;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
116
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
117 l = avg + (s->mul * (a[i] - avg));
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
118 r = avg + (s->mul * (a[i + 1] - avg));
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
119
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
120 a[i] = af_softclip(l);
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
121 a[i + 1] = af_softclip(r);
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
122 }
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
123
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
124 return data;
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
125 }
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
126
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
127 // Allocate memory and set function pointers
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
128 static int open(af_instance_t* af){
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
129 af->control=control;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
130 af->uninit=uninit;
14624
7b7c94b5e78a now supports float based operation aswell
alex
parents: 14245
diff changeset
131 af->play=play_s16;
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
132 af->mul.n=1;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
133 af->mul.d=1;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
134 af->data=calloc(1,sizeof(af_data_t));
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
135 af->setup=calloc(1,sizeof(af_extrastereo_t));
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
136 if(af->data == NULL || af->setup == NULL)
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
137 return AF_ERROR;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
138
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
139 ((af_extrastereo_t*)af->setup)->mul = 2.5;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
140 return AF_OK;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
141 }
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
142
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
143 // Description of this filter
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
144 af_info_t af_info_extrastereo = {
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
145 "Extra stereo",
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
146 "extrastereo",
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
147 "Alex Beregszaszi & Pierre Lombard",
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
148 "",
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
149 AF_FLAGS_NOT_REENTRANT,
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
150 open
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff changeset
151 };