Mercurial > mplayer.hg
annotate libaf/af_extrastereo.c @ 27532:1ecce17e826f
Make SWS_FULL_CHR_H_INP work.
author | michael |
---|---|
date | Wed, 10 Sep 2008 02:28:38 +0000 |
parents | b2402b4f0afa |
children | 72d0b1444141 |
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 <inttypes.h> |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
16 #include <math.h> |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
17 #include <limits.h> |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
18 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
19 #include "af.h" |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
20 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
21 // Data for specific instances of this filter |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
22 typedef struct af_extrastereo_s |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
23 { |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
24 float mul; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
25 }af_extrastereo_t; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
26 |
14624 | 27 static af_data_t* play_s16(struct af_instance_s* af, af_data_t* data); |
28 static af_data_t* play_float(struct af_instance_s* af, af_data_t* data); | |
29 | |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
30 // Initialization and runtime control |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
31 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
|
32 { |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
33 af_extrastereo_t* s = (af_extrastereo_t*)af->setup; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
34 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
35 switch(cmd){ |
14624 | 36 case AF_CONTROL_REINIT:{ |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
37 // Sanity check |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
38 if(!arg) return AF_ERROR; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
39 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
40 af->data->rate = ((af_data_t*)arg)->rate; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
41 af->data->nch = 2; |
14624 | 42 if (((af_data_t*)arg)->format == AF_FORMAT_FLOAT_NE) |
43 { | |
44 af->data->format = AF_FORMAT_FLOAT_NE; | |
45 af->data->bps = 4; | |
46 af->play = play_float; | |
47 }// else | |
48 { | |
49 af->data->format = AF_FORMAT_S16_NE; | |
50 af->data->bps = 2; | |
51 af->play = play_s16; | |
52 } | |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
53 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
54 return af_test_output(af,(af_data_t*)arg); |
14624 | 55 } |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
56 case AF_CONTROL_COMMAND_LINE:{ |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
57 float f; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
58 sscanf((char*)arg,"%f", &f); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
59 s->mul = f; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
60 return AF_OK; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
61 } |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
62 case AF_CONTROL_ES_MUL | AF_CONTROL_SET: |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
63 s->mul = *(float*)arg; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
64 return AF_OK; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
65 case AF_CONTROL_ES_MUL | AF_CONTROL_GET: |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
66 *(float*)arg = s->mul; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
67 return AF_OK; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
68 } |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
69 return AF_UNKNOWN; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
70 } |
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 // Deallocate memory |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
73 static void uninit(struct af_instance_s* af) |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
74 { |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
75 if(af->data) |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
76 free(af->data); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
77 if(af->setup) |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
78 free(af->setup); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
79 } |
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 // Filter data through filter |
14624 | 82 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
|
83 { |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
84 af_extrastereo_t *s = af->setup; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
85 register int i = 0; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
86 int16_t *a = (int16_t*)data->audio; // Audio data |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
87 int len = data->len/2; // Number of samples |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
88 int avg, l, r; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
89 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
90 for (i = 0; i < len; i+=2) |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
91 { |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
92 avg = (a[i] + a[i + 1]) / 2; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
93 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
94 l = avg + (int)(s->mul * (a[i] - avg)); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
95 r = avg + (int)(s->mul * (a[i + 1] - avg)); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
96 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
97 a[i] = clamp(l, SHRT_MIN, SHRT_MAX); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
98 a[i + 1] = clamp(r, SHRT_MIN, SHRT_MAX); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
99 } |
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 return data; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
102 } |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
103 |
14624 | 104 static af_data_t* play_float(struct af_instance_s* af, af_data_t* data) |
105 { | |
106 af_extrastereo_t *s = af->setup; | |
107 register int i = 0; | |
108 float *a = (float*)data->audio; // Audio data | |
109 int len = data->len/4; // Number of samples | |
110 float avg, l, r; | |
111 | |
112 for (i = 0; i < len; i+=2) | |
113 { | |
114 avg = (a[i] + a[i + 1]) / 2; | |
115 | |
116 l = avg + (s->mul * (a[i] - avg)); | |
117 r = avg + (s->mul * (a[i + 1] - avg)); | |
118 | |
119 a[i] = af_softclip(l); | |
120 a[i + 1] = af_softclip(r); | |
121 } | |
122 | |
123 return data; | |
124 } | |
125 | |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
126 // Allocate memory and set function pointers |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
14624
diff
changeset
|
127 static int af_open(af_instance_t* af){ |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
128 af->control=control; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
129 af->uninit=uninit; |
14624 | 130 af->play=play_s16; |
24888 | 131 af->mul=1; |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
132 af->data=calloc(1,sizeof(af_data_t)); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
133 af->setup=calloc(1,sizeof(af_extrastereo_t)); |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
134 if(af->data == NULL || af->setup == NULL) |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
135 return AF_ERROR; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
136 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
137 ((af_extrastereo_t*)af->setup)->mul = 2.5; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
138 return AF_OK; |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
139 } |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
140 |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
141 // Description of this filter |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
142 af_info_t af_info_extrastereo = { |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
143 "Extra stereo", |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
144 "extrastereo", |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
145 "Alex Beregszaszi & Pierre Lombard", |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
146 "", |
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
147 AF_FLAGS_NOT_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
14624
diff
changeset
|
148 af_open |
13550
81e62cbe57d9
reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents:
diff
changeset
|
149 }; |