factor duplicate code in micLoadWav(). also add support for all sorts of WAV formats SDL can support.

This commit is contained in:
Arisotura 2021-08-08 15:32:29 +02:00
parent bba14b2bb0
commit c7325469c2
1 changed files with 52 additions and 49 deletions

View File

@ -195,64 +195,67 @@ void micLoadWav(const char* name)
const u64 dstfreq = 44100;
if (format.format == AUDIO_S16 || format.format == AUDIO_U16)
int srcinc = format.channels;
len /= ((SDL_AUDIO_BITSIZE(format.format) / 8) * srcinc);
micWavLength = (len * dstfreq) / format.freq;
if (micWavLength < 735) micWavLength = 735;
micWavBuffer = new s16[micWavLength];
float res_incr = len / (float)micWavLength;
float res_timer = 0;
int res_pos = 0;
for (int i = 0; i < micWavLength; i++)
{
int srcinc = format.channels;
len /= (2 * srcinc);
u16 val;
micWavLength = (len * dstfreq) / format.freq;
if (micWavLength < 735) micWavLength = 735;
micWavBuffer = new s16[micWavLength];
float res_incr = len / (float)micWavLength;
float res_timer = 0;
int res_pos = 0;
for (int i = 0; i < micWavLength; i++)
switch (SDL_AUDIO_BITSIZE(format.format))
{
u16 val = ((u16*)buf)[res_pos];
if (SDL_AUDIO_ISUNSIGNED(format.format)) val ^= 0x8000;
case 8:
val = buf[res_pos] << 8;
break;
micWavBuffer[i] = val;
case 16:
if (SDL_AUDIO_ISBIGENDIAN(format.format))
val = (buf[res_pos*2] << 8) | buf[res_pos*2 + 1];
else
val = (buf[res_pos*2 + 1] << 8) | buf[res_pos*2];
break;
res_timer += res_incr;
while (res_timer >= 1.0)
case 32:
if (SDL_AUDIO_ISFLOAT(format.format))
{
res_timer -= 1.0;
res_pos += srcinc;
u32 rawval;
if (SDL_AUDIO_ISBIGENDIAN(format.format))
rawval = (buf[res_pos*4] << 24) | (buf[res_pos*4 + 1] << 16) | (buf[res_pos*4 + 2] << 8) | buf[res_pos * 4 + 3];
else
rawval = (buf[res_pos*4 + 3] << 24) | (buf[res_pos*4 + 2] << 16) | (buf[res_pos*4 + 1] << 8) | buf[res_pos * 4];
float fval = *(float*)&rawval;
s32 ival = (s32)(fval * 0x8000);
ival = std::clamp(ival, -0x8000, 0x7FFF);
val = (s16)ival;
}
else if (SDL_AUDIO_ISBIGENDIAN(format.format))
val = (buf[res_pos*4] << 8) | buf[res_pos*4 + 1];
else
val = (buf[res_pos*4 + 3] << 8) | buf[res_pos*4 + 2];
break;
}
if (SDL_AUDIO_ISUNSIGNED(format.format))
val ^= 0x8000;
micWavBuffer[i] = val;
res_timer += res_incr;
while (res_timer >= 1.0)
{
res_timer -= 1.0;
res_pos += srcinc;
}
}
else if (format.format == AUDIO_S8 || format.format == AUDIO_U8)
{
int srcinc = format.channels;
len /= srcinc;
micWavLength = (len * dstfreq) / format.freq;
if (micWavLength < 735) micWavLength = 735;
micWavBuffer = new s16[micWavLength];
float res_incr = len / (float)micWavLength;
float res_timer = 0;
int res_pos = 0;
for (int i = 0; i < micWavLength; i++)
{
u16 val = buf[res_pos] << 8;
if (SDL_AUDIO_ISUNSIGNED(format.format)) val ^= 0x8000;
micWavBuffer[i] = val;
res_timer += res_incr;
while (res_timer >= 1.0)
{
res_timer -= 1.0;
res_pos += srcinc;
}
}
}
else
printf("bad WAV format %08X\n", format.format);
SDL_FreeWAV(buf);
}