ref: 01e7ed7a09fda1c453edb6aed593ce402e88ddd6
parent: 78c76b0af96edb3a5f9f2a91d7227b8538f174de
author: Krzysztof Nikiel <knik@users.sourceforge.net>
date: Fri Oct 27 11:09:18 EDT 2017
fixed compiler warnings; made wav_read_float32() much faster
--- a/frontend/input.c
+++ b/frontend/input.c
@@ -278,113 +278,102 @@
size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map)
{
- size_t i = 0;
- unsigned char bufi[8];
+ size_t cnt;
+ size_t isize;
+ void *bufi;
- if ((sndf->samplebytes > 8) || (sndf->samplebytes < 1))
+ if ((sndf->samplebytes > 4) || (sndf->samplebytes < 1))
return 0;
- while (i<num) {
- if (fread(bufi, sndf->samplebytes, 1, sndf->f) != 1)
- break;
+ isize = num * sndf->samplebytes;
+ bufi = (buf + num);
+ bufi -= isize;
+ isize = fread(bufi, 1, isize, sndf->f);
+ isize /= sndf->samplebytes;
- if (sndf->isfloat)
- {
- switch (sndf->samplebytes) {
- case 4:
- buf[i] = (*(float *)&bufi) * (float)32768;
- break;
+ // perform in-place conversion
+ for (cnt = 0; cnt < num; cnt++)
+ {
+ if (cnt >= isize)
+ break;
- case 8:
- buf[i] = (float)((*(double *)&bufi) * (float)32768);
- break;
-
- default:
- return 0;
+ if (sndf->isfloat)
+ {
+ switch (sndf->samplebytes) {
+ case 4:
+ buf[cnt] *= 32768.0;
+ break;
+ default:
+ return 0;
+ }
+ continue;
}
- }
- else
- {
- // convert to 32 bit float
- // fix endianness
- switch (sndf->samplebytes) {
+
+ switch (sndf->samplebytes)
+ {
case 1:
- /* this is endian clean */
- buf[i] = ((float)bufi[0] - 128) * (float)256;
- break;
+ {
+ uint8_t *in = bufi;
+ uint8_t s = in[cnt];
+ buf[cnt] = ((float)s - 128.0) * (float)256;
+ }
+ break;
case 2:
+ {
+ int16_t *in = bufi;
+ int16_t s = in[cnt];
#ifdef WORDS_BIGENDIAN
- if (!sndf->bigendian)
+ if (!sndf->bigendian)
#else
- if (sndf->bigendian)
+ if (sndf->bigendian)
#endif
- {
- // swap bytes
- int16_t s = ((int16_t *)bufi)[0];
- s = SWAP16(s);
- buf[i] = (float)s;
- }
- else
- {
- // no swap
- int s = ((int16_t *)bufi)[0];
- buf[i] = (float)s;
- }
- break;
-
+ buf[cnt] = (float)SWAP16(s);
+ else
+ buf[cnt] = (float)s;
+ }
+ break;
case 3:
- if (!sndf->bigendian)
- {
- int s = bufi[0] | (bufi[1] << 8) | (bufi[2] << 16);
+ {
+ int s;
+ uint8_t *in = bufi;
+ in += 3 * cnt;
- // fix sign
- if (s & 0x800000)
- s |= 0xff000000;
+ if (!sndf->bigendian)
+ s = in[0] | (in[1] << 8) | (in[2] << 16);
+ else
+ s = (in[0] << 16) | (in[1] << 8) | in[2];
- buf[i] = (float)s / 256;
- }
- else // big endian input
- {
- int s = (bufi[0] << 16) | (bufi[1] << 8) | bufi[2];
+ // fix sign
+ if (s & 0x800000)
+ s |= 0xff000000;
- // fix sign
- if (s & 0x800000)
- s |= 0xff000000;
-
- buf[i] = (float)s / 256;
- }
+ buf[cnt] = (float)s / 256;
+ }
break;
-
case 4:
+ {
+ int32_t *in = bufi;
+ int s = in[cnt];
#ifdef WORDS_BIGENDIAN
- if (!sndf->bigendian)
+ if (!sndf->bigendian)
#else
- if (sndf->bigendian)
+ if (sndf->bigendian)
#endif
- {
- // swap bytes
- int s = *(int *)&bufi;
- buf[i] = (float)SWAP32(s) / 65536;
- }
- else
- {
- int s = *(int *)&bufi;
- buf[i] = (float)s / 65536;
- }
- break;
-
+ buf[cnt] = (float)SWAP32(s) / 65536;
+ else
+ buf[cnt] = (float)s / 65536;
+ }
+ break;
default:
- return 0;
+ return 0;
}
- }
- i++;
}
if (map)
- chan_remap((int32_t *)buf, sndf->channels, i / sndf->channels, map);
+ chan_remap((int32_t *)buf, sndf->channels, cnt / sndf->channels, map);
- return i;
+ return cnt;
}
size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map)