Mercurial > mplayer.hg
annotate libaf/af_format.c @ 7657:dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
author | arpi |
---|---|
date | Mon, 07 Oct 2002 19:21:35 +0000 |
parents | c67328dd459a |
children | 194bcc364c3f |
rev | line source |
---|---|
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 | |
7571
8819fdf88b5d
Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents:
7568
diff
changeset
|
100 mp_msg(MSGT_AFILTER,MSGL_V,"[format] Changing number sample format to 0x%08X and/or bytes per sample to %i \n",af->data->format,af->data->bps); |
7568 | 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 "", | |
7615 | 290 AF_FLAGS_REENTRANT, |
7568 | 291 open |
292 }; |