7568
|
1 /* This audio output filter changes the format of a data block. Valid
|
|
2 formats are: AFMT_U8, AFMT_S8, AFMT_S16_LE, AFMT_S16_BE
|
|
3 AFMT_U16_LE, AFMT_U16_BE, AFMT_S32_LE and AFMT_S32_BE.
|
|
4 */
|
|
5
|
|
6 #include <stdio.h>
|
|
7 #include <stdlib.h>
|
|
8 #include <string.h>
|
|
9 #include <unistd.h>
|
|
10 #include <inttypes.h>
|
|
11 #include <limits.h>
|
|
12
|
|
13 #include "../config.h"
|
|
14 #include "../mp_msg.h"
|
|
15
|
|
16 #include "../libao2/afmt.h"
|
|
17
|
|
18 #include "af.h"
|
|
19
|
|
20 // Number of bits
|
|
21 #define B08 (0<<0)
|
|
22 #define B16 (1<<0)
|
|
23 #define B32 (2<<0)
|
|
24 #define NBITS_MASK (3<<0)
|
|
25
|
|
26 // Endianess
|
|
27 #define BE (0<<2) // Big Endian
|
|
28 #define LE (1<<2) // Little Endian
|
|
29 #define END_MASK (1<<2)
|
|
30
|
|
31 // Signed
|
|
32 #define US (0<<3) // Un Signed
|
|
33 #define SI (1<<3) // SIgned
|
|
34 #define SIGN_MASK (1<<3)
|
|
35
|
|
36 int decode(int format)
|
|
37 {
|
|
38 // Check input format
|
|
39 switch(format){
|
|
40 case(AFMT_U8):
|
|
41 return LE|B08|US;
|
|
42 case(AFMT_S8):
|
|
43 return LE|B08|SI; break;
|
|
44 case(AFMT_S16_LE):
|
|
45 return LE|B16|SI; break;
|
|
46 case(AFMT_S16_BE):
|
|
47 return BE|B16|SI; break;
|
|
48 case(AFMT_U16_LE):
|
|
49 return LE|B16|US; break;
|
|
50 case(AFMT_U16_BE):
|
|
51 return BE|B16|US; break;
|
|
52 case(AFMT_S32_LE):
|
|
53 return LE|B32|SI; break;
|
|
54 case(AFMT_S32_BE):
|
|
55 return BE|B32|SI; break;
|
|
56 case(AFMT_IMA_ADPCM):
|
|
57 case(AFMT_MU_LAW):
|
|
58 case(AFMT_A_LAW):
|
|
59 case(AFMT_MPEG):
|
|
60 case(AFMT_AC3):
|
|
61 mp_msg(MSGT_AFILTER,MSGL_ERR,"[af_format] Input audio format not yet supported \n");
|
|
62 return 0;
|
|
63 default:
|
|
64 //This can not happen ....
|
|
65 mp_msg(MSGT_AFILTER,MSGL_ERR,"Unrecognized input audio format\n");
|
|
66 return 0;
|
|
67 }
|
|
68
|
|
69 }
|
|
70
|
|
71 // Initialization and runtime control
|
|
72 static int control(struct af_instance_s* af, int cmd, void* arg)
|
|
73 {
|
|
74 switch(cmd){
|
|
75 case AF_CONTROL_REINIT:
|
|
76 // Make sure this filter isn't redundant
|
|
77 if(af->data->format == ((af_data_t*)arg)->format && af->data->bps == ((af_data_t*)arg)->bps)
|
|
78 return AF_DETACH;
|
|
79
|
|
80 af->data->rate = ((af_data_t*)arg)->rate;
|
|
81 af->data->nch = ((af_data_t*)arg)->nch;
|
|
82 af->mul.n = af->data->bps;
|
|
83 af->mul.d = ((af_data_t*)arg)->bps;
|
|
84 return AF_OK;
|
|
85 case AF_CONTROL_FORMAT:
|
|
86 // Reinit must be called after this function has been called
|
|
87
|
|
88 // Sanity check for sample format
|
|
89 if(0 == ((int)af->setup=decode(((af_data_t*)arg)->format)))
|
|
90 return AF_ERROR;
|
|
91 af->data->format = ((af_data_t*)arg)->format;
|
|
92
|
|
93 // Sanity check for bytes per sample
|
|
94 if(((af_data_t*)arg)->bps != 4 && ((af_data_t*)arg)->bps != 2 && ((af_data_t*)arg)->bps != 1){
|
|
95 mp_msg(MSGT_AFILTER,MSGL_ERR,"[format] The number of output bytes per sample must be 1, 2 or 4. Current value is%i \n",((af_data_t*)arg)->bps);
|
|
96 return AF_ERROR;
|
|
97 }
|
|
98 af->data->bps=((af_data_t*)arg)->bps;
|
|
99
|
|
100 mp_msg(MSGT_AFILTER,MSGL_STATUS,"[format] Changing number sample format to 0x%08X and/or bytes per sample to %i \n",af->data->format,af->data->bps);
|
|
101 return AF_OK;
|
|
102 }
|
|
103 return AF_UNKNOWN;
|
|
104 }
|
|
105
|
|
106 // Deallocate memory
|
|
107 static void uninit(struct af_instance_s* af)
|
|
108 {
|
|
109 if(af->data)
|
|
110 free(af->data);
|
|
111 (int)af->setup = 0;
|
|
112 }
|
|
113
|
|
114 // Filter data through filter
|
|
115 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
|
|
116 {
|
|
117 af_data_t* l = af->data; // Local data
|
|
118 void* la = NULL; // Local audio
|
|
119 int lf = (int)af->setup; // Local format
|
|
120 af_data_t* c = data; // Current working data
|
|
121 void* ca = c->audio; // Current audio
|
|
122 int cf = decode(c->format); // Current format
|
|
123 register int i = 0; // Counter
|
|
124 int len = c->len>>(cf&NBITS_MASK); // Loop end
|
|
125
|
|
126 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
|
|
127 return NULL;
|
|
128
|
|
129 la = l->audio;
|
|
130
|
|
131 // Change to little endian
|
|
132 if((cf&END_MASK)!=LE){
|
|
133 switch(cf&NBITS_MASK){
|
|
134 case(B16):{
|
|
135 register uint16_t s;
|
|
136 for(i=1;i<len;i++){
|
|
137 s=((uint16_t*)ca)[i];
|
|
138 ((uint16_t*)ca)[i]=(uint16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8);
|
|
139 }
|
|
140 }
|
|
141 break;
|
|
142 case(B32):{
|
|
143 register uint32_t s;
|
|
144 for(i=1;i<len;i++){
|
|
145 s=((uint32_t*)ca)[i];
|
|
146 ((uint32_t*)ca)[i]=(uint32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) |
|
|
147 ((s&0x00FF0000)>>8) | ((s&0xFF000000)>>24));
|
|
148 }
|
|
149 }
|
|
150 break;
|
|
151 }
|
|
152 }
|
|
153 // Change signed/unsigned
|
|
154 if((cf&SIGN_MASK) != (lf&SIGN_MASK)){
|
|
155 switch((cf&NBITS_MASK)){
|
|
156 case(B08):
|
|
157 switch(cf&SIGN_MASK){
|
|
158 case(US):
|
|
159 for(i=0;i<len;i++)
|
|
160 ((int8_t*)ca)[i]=(int8_t)(SCHAR_MIN+((int)((uint8_t*)ca)[i]));
|
|
161 break;
|
|
162 case(SI):
|
|
163 for(i=0;i<len;i++)
|
|
164 ((uint8_t*)ca)[i]=(uint8_t)(SCHAR_MAX+((int)((int8_t*)ca)[i]));
|
|
165 break;
|
|
166 }
|
|
167 break;
|
|
168 case(B16):
|
|
169 switch(cf&SIGN_MASK){
|
|
170 case(US):
|
|
171 for(i=0;i<len;i++)
|
|
172 ((int16_t*)ca)[i]=(int16_t)(SHRT_MIN+((int)((uint16_t*)ca)[i]));
|
|
173 break;
|
|
174 case(SI):
|
|
175 for(i=0;i<len;i++)
|
|
176 ((uint16_t*)ca)[i]=(uint16_t)(SHRT_MAX+((int)((int16_t*)ca)[i]));
|
|
177 break;
|
|
178 }
|
|
179 break;
|
|
180 case(B32):
|
|
181 switch(cf&SIGN_MASK){
|
|
182 case(US):
|
|
183 for(i=0;i<len;i++)
|
|
184 ((int32_t*)ca)[i]=(int32_t)(INT_MIN+((uint32_t*)ca)[i]);
|
|
185 break;
|
|
186 case(SI):
|
|
187 for(i=0;i<len;i++)
|
|
188 ((uint32_t*)ca)[i]=(uint32_t)(INT_MAX+((int32_t*)ca)[i]);
|
|
189 break;
|
|
190 }
|
|
191 break;
|
|
192 }
|
|
193 }
|
|
194 // Change the number of bits
|
|
195 if((cf&NBITS_MASK) == (lf&NBITS_MASK)){
|
|
196 memcpy(la,ca,c->len);
|
|
197 } else {
|
|
198 switch(cf&NBITS_MASK){
|
|
199 case(B08):
|
|
200 switch(lf&NBITS_MASK){
|
|
201 case(B16):
|
|
202 for(i=1;i<len;i++)
|
|
203 ((uint16_t*)la)[i]=((uint16_t)((uint8_t*)ca)[i])<<8;
|
|
204 break;
|
|
205 case(B32):
|
|
206 for(i=1;i<len;i++)
|
|
207 ((uint32_t*)la)[i]=((uint32_t)((uint8_t*)ca)[i])<<24;
|
|
208 break;
|
|
209 }
|
|
210 break;
|
|
211 case(B16):
|
|
212 switch(lf&NBITS_MASK){
|
|
213 case(B08):
|
|
214 for(i=0;i<len;i++)
|
|
215 ((uint8_t*)la)[i]=(uint8_t)((((uint16_t*)ca)[i])>>8);
|
|
216 break;
|
|
217 case(B32):
|
|
218 for(i=1;i<len;i++)
|
|
219 ((uint32_t*)la)[i]=((uint32_t)((uint16_t*)ca)[i])<<16;
|
|
220 break;
|
|
221 }
|
|
222 break;
|
|
223 case(B32):
|
|
224 switch(lf&NBITS_MASK){
|
|
225 case(B08):
|
|
226 for(i=0;i<len;i++)
|
|
227 ((uint8_t*)la)[i]=(uint8_t)((((uint32_t*)ca)[i])>>24);
|
|
228 break;
|
|
229 case(B16):
|
|
230 for(i=1;i<len;i++)
|
|
231 ((uint16_t*)la)[i]=(uint16_t)((((uint32_t*)ca)[i])>>16);
|
|
232 break;
|
|
233 }
|
|
234 break;
|
|
235 }
|
|
236 }
|
|
237 // Switch to the correct endainess (again the problem with sun?)
|
|
238 if((lf&END_MASK)!=LE){
|
|
239 switch(cf&NBITS_MASK){
|
|
240 case(B16):{
|
|
241 register uint16_t s;
|
|
242 for(i=1;i<len;i++){
|
|
243 s=((uint16_t*)la)[i];
|
|
244 ((uint16_t*)la)[i]=(uint16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8);
|
|
245 }
|
|
246 }
|
|
247 break;
|
|
248 case(B32):{
|
|
249 register uint32_t s;
|
|
250 for(i=1;i<len;i++){
|
|
251 s=((uint32_t*)la)[i];
|
|
252 ((uint32_t*)la)[i]=(uint32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) |
|
|
253 ((s&0x00FF0000)>>8) | ((s&0xFF000000)>>24));
|
|
254 }
|
|
255 }
|
|
256 break;
|
|
257 }
|
|
258 }
|
|
259
|
|
260 // Set output data
|
|
261
|
|
262 // Make sure no samples are lost
|
|
263 c->len = (c->len*l->bps)/c->bps;
|
|
264 c->audio = l->audio;
|
|
265 c->bps = l->bps;
|
|
266 c->format = l->format;
|
|
267 return c;
|
|
268 }
|
|
269
|
|
270 // Allocate memory and set function pointers
|
|
271 static int open(af_instance_t* af){
|
|
272 af->control=control;
|
|
273 af->uninit=uninit;
|
|
274 af->play=play;
|
|
275 af->mul.n=1;
|
|
276 af->mul.d=1;
|
|
277 af->data=calloc(1,sizeof(af_data_t));
|
|
278 if(af->data == NULL)
|
|
279 return AF_ERROR;
|
|
280 (int)af->setup = 0;
|
|
281 return AF_OK;
|
|
282 }
|
|
283
|
|
284 // Description of this filter
|
|
285 af_info_t af_info_format = {
|
|
286 "Sample format conversion",
|
|
287 "format",
|
|
288 "Anders",
|
|
289 "",
|
|
290 open
|
|
291 };
|