1 /*
2 * FAAC - Freeware Advanced Audio Coder
3 * Copyright (C) 2002 Krzysztof Nikiel
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id: input.c,v 1.21 2017/07/02 14:35:23 knik Exp $
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #ifdef _WIN32
31 #include <io.h>
32 #include <fcntl.h>
33 #endif
34
35 #include "input.h"
36
37 #define SWAP32(x) (((x & 0xff) << 24) | ((x & 0xff00) << 8) \
38 | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24))
39 #define SWAP16(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
40
41 #ifdef WORDS_BIGENDIAN
42 # define UINT32(x) SWAP32(x)
43 # define UINT16(x) SWAP16(x)
44 #else
45 # define UINT32(x) (x)
46 # define UINT16(x) (x)
47 #endif
48
49 typedef struct
50 {
51 uint32_t label; /* 'RIFF' */
52 uint32_t length; /* Length of rest of file */
53 uint32_t chunk_type; /* 'WAVE' */
54 }
55 riff_t;
56
57 typedef struct
58 {
59 uint32_t label;
60 uint32_t len;
61 }
62 riffsub_t;
63
64 #ifdef _MSC_VER
65 #pragma pack(push, 1)
66 #endif
67
68 #define WAVE_FORMAT_PCM 1
69 #define WAVE_FORMAT_FLOAT 3
70 #define WAVE_FORMAT_EXTENSIBLE 0xfffe
71 struct WAVEFORMATEX
72 {
73 uint16_t wFormatTag;
74 uint16_t nChannels;
75 uint32_t nSamplesPerSec;
76 uint32_t nAvgBytesPerSec;
77 uint16_t nBlockAlign;
78 uint16_t wBitsPerSample;
79 uint16_t cbSize;
80 }
81 #ifdef __GNUC__
82 __attribute__((packed))
83 #endif
84 ;
85
86 struct WAVEFORMATEXTENSIBLE
87 {
88 struct WAVEFORMATEX Format;
89 union {
90 uint16_t wValidBitsPerSample; // bits of precision
91 uint16_t wSamplesPerBlock; // valid if wBitsPerSample==0
92 uint16_t wReserved; // If neither applies, set to zero.
93 } Samples;
94 uint32_t dwChannelMask; // which channels are present in stream
95 unsigned char SubFormat[16]; // guid
96 }
97 #ifdef __GNUC__
98 __attribute__((packed))
99 #endif
100 ;
101
102 #ifdef _MSC_VER
103 #pragma pack(pop)
104 #endif
105
106 static unsigned char waveformat_pcm_guid[16] =
107 {
108 WAVE_FORMAT_PCM,0,0,0,
109 0x00, 0x00,
110 0x10, 0x00,
111 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
112 };
113
unsuperr(const char * name)114 static void unsuperr(const char *name)
115 {
116 fprintf(stderr, "%s: file format not supported\n", name);
117 }
118
seekcur(FILE * f,int ofs)119 static void seekcur(FILE *f, int ofs)
120 {
121 int cnt;
122
123 for (cnt = 0; cnt < ofs; cnt++)
124 fgetc(f);
125 }
126
seekchunk(FILE * f,riffsub_t * riffsub,char * name)127 static int seekchunk(FILE *f, riffsub_t *riffsub, char *name)
128 {
129 int skipped;
130
131 for(skipped = 0; skipped < 10; skipped++)
132 {
133 if (fread(riffsub, 1, sizeof(*riffsub), f) != sizeof(*riffsub))
134 return 0;
135
136 riffsub->len = UINT32(riffsub->len);
137 if (riffsub->len & 1)
138 riffsub->len++;
139
140 if (!memcmp(&(riffsub->label), name, 4))
141 return 1;
142
143 seekcur(f, riffsub->len);
144 }
145
146 return 0;
147 }
148
wav_open_read(const char * name,int rawinput)149 pcmfile_t *wav_open_read(const char *name, int rawinput)
150 {
151 FILE *wave_f;
152 riff_t riff;
153 riffsub_t riffsub;
154 struct WAVEFORMATEXTENSIBLE wave;
155 char *riffl = "RIFF";
156 char *wavel = "WAVE";
157 char *fmtl = "fmt ";
158 char *datal = "data";
159 int fmtsize;
160 pcmfile_t *sndf;
161 int dostdin = 0;
162
163 if (!strcmp(name, "-"))
164 {
165 #ifdef _WIN32
166 _setmode(_fileno(stdin), O_BINARY);
167 #endif
168 wave_f = stdin;
169 dostdin = 1;
170 }
171 else if (!(wave_f = fopen(name, "rb")))
172 {
173 perror(name);
174 return NULL;
175 }
176
177 if (!rawinput) // header input
178 {
179 if (fread(&riff, 1, sizeof(riff), wave_f) != sizeof(riff))
180 return NULL;
181 if (memcmp(&(riff.label), riffl, 4))
182 return NULL;
183 if (memcmp(&(riff.chunk_type), wavel, 4))
184 return NULL;
185
186 if (!seekchunk(wave_f, &riffsub, fmtl))
187 return NULL;
188
189 if (memcmp(&(riffsub.label), fmtl, 4))
190 return NULL;
191 memset(&wave, 0, sizeof(wave));
192
193 fmtsize = (riffsub.len < sizeof(wave)) ? riffsub.len : sizeof(wave);
194 // check if format is at least 16 bytes long
195 if (fmtsize < 16)
196 return NULL;
197
198 if (fread(&wave, 1, fmtsize, wave_f) != fmtsize)
199 return NULL;
200
201 seekcur(wave_f, riffsub.len - fmtsize);
202
203 if (!seekchunk(wave_f, &riffsub, datal))
204 return NULL;
205
206 if (UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_PCM && UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_FLOAT)
207 {
208 if (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_EXTENSIBLE)
209 {
210 if (UINT16(wave.Format.cbSize) < 22) // struct too small
211 return NULL;
212 if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16))
213 {
214 waveformat_pcm_guid[0] = WAVE_FORMAT_FLOAT;
215 if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16))
216 {
217 unsuperr(name);
218 return NULL;
219 }
220 }
221 }
222 else
223 {
224 unsuperr(name);
225 return NULL;
226 }
227 }
228 }
229
230 sndf = (pcmfile_t*)malloc(sizeof(*sndf));
231 memset(sndf, 0, sizeof(*sndf));
232 sndf->f = wave_f;
233
234 if (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_FLOAT) {
235 sndf->isfloat = 1;
236 } else {
237 sndf->isfloat = (wave.SubFormat[0] == WAVE_FORMAT_FLOAT);
238 }
239 if (rawinput)
240 {
241 sndf->bigendian = 1;
242 if (dostdin)
243 sndf->samples = 0;
244 else
245 {
246 fseek(sndf->f, 0 , SEEK_END);
247 sndf->samples = ftell(sndf->f);
248 rewind(sndf->f);
249 }
250 }
251 else
252 {
253 sndf->bigendian = 0;
254 sndf->channels = UINT16(wave.Format.nChannels);
255 sndf->samplebytes = UINT16(wave.Format.wBitsPerSample) / 8;
256 sndf->samplerate = UINT32(wave.Format.nSamplesPerSec);
257 if (!sndf->samplebytes || !sndf->channels)
258 return NULL;
259 sndf->samples = riffsub.len / (sndf->samplebytes * sndf->channels);
260 }
261 return sndf;
262 }
263
264
chan_remap(int32_t * buf,int channels,int blocks,int * map)265 static void chan_remap(int32_t *buf, int channels, int blocks, int *map)
266 {
267 int i;
268 int32_t *tmp = (int32_t*)malloc(channels * sizeof(int32_t));
269
270 for (i = 0; i < blocks; i++)
271 {
272 int chn;
273
274 memcpy(tmp, buf + i * channels, sizeof(int32_t) * channels);
275
276 for (chn = 0; chn < channels; chn++)
277 buf[i * channels + chn] = tmp[map[chn]];
278 }
279 free(tmp);
280 }
281
wav_read_float32(pcmfile_t * sndf,float * buf,size_t num,int * map)282 size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map)
283 {
284 size_t cnt;
285 size_t isize;
286 char *bufi;
287
288 if ((sndf->samplebytes > 4) || (sndf->samplebytes < 1))
289 return 0;
290
291 isize = num * sndf->samplebytes;
292 bufi = (char*)(buf + num);
293 bufi -= isize;
294 isize = fread(bufi, 1, isize, sndf->f);
295 isize /= sndf->samplebytes;
296
297 // perform in-place conversion
298 for (cnt = 0; cnt < num; cnt++)
299 {
300 if (cnt >= isize)
301 break;
302
303 if (sndf->isfloat)
304 {
305 switch (sndf->samplebytes) {
306 case 4:
307 buf[cnt] *= 32768.0;
308 break;
309 default:
310 return 0;
311 }
312 continue;
313 }
314
315 switch (sndf->samplebytes)
316 {
317 case 1:
318 {
319 uint8_t *in = (uint8_t*)bufi;
320 uint8_t s = in[cnt];
321
322 buf[cnt] = ((float)s - 128.0) * (float)256;
323 }
324 break;
325 case 2:
326 {
327 int16_t *in = (int16_t*)bufi;
328 int16_t s = in[cnt];
329 #ifdef WORDS_BIGENDIAN
330 if (!sndf->bigendian)
331 #else
332 if (sndf->bigendian)
333 #endif
334 buf[cnt] = (float)SWAP16(s);
335 else
336 buf[cnt] = (float)s;
337 }
338 break;
339 case 3:
340 {
341 int s;
342 uint8_t *in = (uint8_t*)bufi;
343 in += 3 * cnt;
344
345 if (!sndf->bigendian)
346 s = in[0] | (in[1] << 8) | (in[2] << 16);
347 else
348 s = (in[0] << 16) | (in[1] << 8) | in[2];
349
350 // fix sign
351 if (s & 0x800000)
352 s |= 0xff000000;
353
354 buf[cnt] = (float)s / 256;
355 }
356 break;
357 case 4:
358 {
359 int32_t *in = (int32_t*)bufi;
360 int s = in[cnt];
361 #ifdef WORDS_BIGENDIAN
362 if (!sndf->bigendian)
363 #else
364 if (sndf->bigendian)
365 #endif
366 buf[cnt] = (float)SWAP32(s) / 65536;
367 else
368 buf[cnt] = (float)s / 65536;
369 }
370 break;
371 default:
372 return 0;
373 }
374 }
375
376 if (map)
377 chan_remap((int32_t *)buf, sndf->channels, cnt / sndf->channels, map);
378
379 return cnt;
380 }
381
wav_read_int24(pcmfile_t * sndf,int32_t * buf,size_t num,int * map)382 size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map)
383 {
384 int size;
385 int i;
386 uint8_t *bufi;
387
388 if ((sndf->samplebytes > 4) || (sndf->samplebytes < 1))
389 return 0;
390
391 bufi = (uint8_t *)buf + sizeof(*buf) * num - sndf->samplebytes * (num - 1) - sizeof(*buf);
392
393 size = fread(bufi, sndf->samplebytes, num, sndf->f);
394
395 // convert to 24 bit
396 // fix endianness
397 switch (sndf->samplebytes) {
398 case 1:
399 /* this is endian clean */
400 for (i = 0; i < size; i++)
401 buf[i] = (bufi[i] - 128) * 65536;
402 break;
403
404 case 2:
405 #ifdef WORDS_BIGENDIAN
406 if (!sndf->bigendian)
407 #else
408 if (sndf->bigendian)
409 #endif
410 {
411 // swap bytes
412 for (i = 0; i < size; i++)
413 {
414 int16_t s = ((int16_t *)bufi)[i];
415
416 s = SWAP16(s);
417
418 buf[i] = ((uint32_t)s) << 8;
419 }
420 }
421 else
422 {
423 // no swap
424 for (i = 0; i < size; i++)
425 {
426 int s = ((int16_t *)bufi)[i];
427
428 buf[i] = s << 8;
429 }
430 }
431 break;
432
433 case 3:
434 if (!sndf->bigendian)
435 {
436 for (i = 0; i < size; i++)
437 {
438 int s = bufi[3 * i] | (bufi[3 * i + 1] << 8) | (bufi[3 * i + 2] << 16);
439
440 // fix sign
441 if (s & 0x800000)
442 s |= 0xff000000;
443
444 buf[i] = s;
445 }
446 }
447 else // big endian input
448 {
449 for (i = 0; i < size; i++)
450 {
451 int s = (bufi[3 * i] << 16) | (bufi[3 * i + 1] << 8) | bufi[3 * i + 2];
452
453 // fix sign
454 if (s & 0x800000)
455 s |= 0xff000000;
456
457 buf[i] = s;
458 }
459 }
460 break;
461
462 case 4:
463 #ifdef WORDS_BIGENDIAN
464 if (!sndf->bigendian)
465 #else
466 if (sndf->bigendian)
467 #endif
468 {
469 // swap bytes
470 for (i = 0; i < size; i++)
471 {
472 int s = buf[i];
473
474 buf[i] = SWAP32(s);
475 }
476 }
477 break;
478 }
479
480 if (map)
481 chan_remap(buf, sndf->channels, size / sndf->channels, map);
482
483 return size;
484 }
485
wav_close(pcmfile_t * sndf)486 int wav_close(pcmfile_t *sndf)
487 {
488 int i = fclose(sndf->f);
489 free(sndf);
490 return i;
491 }
492