Mercurial > mplayer.hg
annotate libaf/af_extrastereo.c @ 16962:bdc218b5a49a
Do not hang forever when the card delivers no new data.
author | reimar |
---|---|
date | Thu, 10 Nov 2005 20:32:47 +0000 |
parents | 7b7c94b5e78a |
children | fd6f824ef894 |
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 | 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); | |
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 | 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 | 43 if (((af_data_t*)arg)->format == AF_FORMAT_FLOAT_NE) |
44 { | |
45 af->data->format = AF_FORMAT_FLOAT_NE; | |
46 af->data->bps = 4; | |
47 af->play = play_float; | |
48 }// else | |
49 { | |
50 af->data->format = AF_FORMAT_S16_NE; | |
51 af->data->bps = 2; | |
52 af->play = play_s16; | |
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 | 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 | 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 | 105 static af_data_t* play_float(struct af_instance_s* af, af_data_t* data) |
106 { | |
107 af_extrastereo_t *s = af->setup; | |
108 register int i = 0; | |
109 float *a = (float*)data->audio; // Audio data | |
110 int len = data->len/4; // Number of samples | |
111 float avg, l, r; | |
112 | |
113 for (i = 0; i < len; i+=2) | |
114 { | |
115 avg = (a[i] + a[i + 1]) / 2; | |
116 | |
117 l = avg + (s->mul * (a[i] - avg)); | |
118 r = avg + (s->mul * (a[i + 1] - avg)); | |
119 | |
120 a[i] = af_softclip(l); | |
121 a[i + 1] = af_softclip(r); | |
122 } | |
123 | |
124 return data; | |
125 } | |
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 | 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 }; |