Support a couple of other wav file variants.
This commit is contained in:
parent
75ee7daa82
commit
e002c43430
1 changed files with 78 additions and 8 deletions
|
@ -756,12 +756,28 @@ static qboolean QDECL S_LoadWavSound (sfx_t *s, qbyte *data, size_t datalen, int
|
|||
COM_CharBias(data + info.dataofs, info.samples*info.numchannels);
|
||||
format = QAF_S8;
|
||||
}
|
||||
else if (info.format == 1 && info.bitwidth == 16) //signed shorts
|
||||
else if (info.format == 1 && (info.bitwidth > 8 && info.bitwidth <= 16)) //signed shorts
|
||||
{
|
||||
COM_SwapLittleShortBlock((short *)(data + info.dataofs), info.samples*info.numchannels);
|
||||
format = QAF_S16;
|
||||
}
|
||||
else if (info.format == 1 && info.bitwidth == 32) //24 or 32bit int audio
|
||||
else if (info.format == 1 && (info.bitwidth > 16 && info.bitwidth <= 24))
|
||||
{ //packed
|
||||
short *out = (short *)(data + info.dataofs);
|
||||
qbyte *in = (qbyte *)(data + info.dataofs);
|
||||
int s;
|
||||
size_t samples = info.samples*info.numchannels;
|
||||
while(samples --> 0)
|
||||
{
|
||||
s = *in++<<0;
|
||||
s |= *in++<<8;
|
||||
s |= *in++<<16;
|
||||
s |= 0 <<24;
|
||||
*out++ = s>>8; //just drop the least significant bits.
|
||||
}
|
||||
format = QAF_S16;
|
||||
}
|
||||
else if (info.format == 1 && (info.bitwidth > 24 && info.bitwidth <= 32)) //24(padded) or 32bit int audio
|
||||
{
|
||||
short *out = (short *)(data + info.dataofs);
|
||||
int *in = (int *)(data + info.dataofs);
|
||||
|
@ -784,6 +800,25 @@ static qboolean QDECL S_LoadWavSound (sfx_t *s, qbyte *data, size_t datalen, int
|
|||
}
|
||||
format = QAF_F32;
|
||||
}
|
||||
else if (info.format == 3 && info.bitwidth == 64) //signed doubles, converted to floats cos doubles is just silly.
|
||||
{
|
||||
if (bigendian)
|
||||
{
|
||||
size_t i = info.samples*info.numchannels;
|
||||
qint64_t *in = (qint64_t*)(data + info.dataofs);
|
||||
float *out = (short *)(data + info.dataofs);
|
||||
union {
|
||||
qint64_t i;
|
||||
double d;
|
||||
} s;
|
||||
while(i --> 0)
|
||||
{
|
||||
s.i = LittleI64(in[i]);
|
||||
out[i] = s.d;
|
||||
}
|
||||
}
|
||||
format = QAF_F32;
|
||||
}
|
||||
#else
|
||||
else if (info.format == 3 && info.bitwidth == 32) //signed floats
|
||||
{
|
||||
|
@ -799,6 +834,25 @@ static qboolean QDECL S_LoadWavSound (sfx_t *s, qbyte *data, size_t datalen, int
|
|||
}
|
||||
format = QAF_S16;
|
||||
}
|
||||
else if (info.format == 3 && info.bitwidth == 64) //signed doubles
|
||||
{
|
||||
short *out = (short *)(data + info.dataofs);
|
||||
qint64_t *in = (qint64_t *)(data + info.dataofs);
|
||||
union {
|
||||
qint64_t i;
|
||||
double d;
|
||||
} s;
|
||||
size_t samples = info.samples*info.numchannels;
|
||||
int t;
|
||||
while(samples --> 0)
|
||||
{ //in place size conversion, so we need to do it forwards.
|
||||
s.i = LittleI64(*in++);
|
||||
t = s.d * 32767;
|
||||
t = bound(-32768, t, 32767);
|
||||
*out++ = t;
|
||||
}
|
||||
format = QAF_S16;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
|
@ -810,7 +864,7 @@ static qboolean QDECL S_LoadWavSound (sfx_t *s, qbyte *data, size_t datalen, int
|
|||
case 6/*WAVE_FORMAT_ALAW*/: Con_Printf ("%s uses unsupported a-law format.\n", s->name); break;
|
||||
case 7/*WAVE_FORMAT_MULAW*/: Con_Printf ("%s uses unsupported mu-law format.\n", s->name); break;
|
||||
case 0xfffe/*WAVE_FORMAT_EXTENSIBLE*/:
|
||||
default: Con_Printf ("%s has an unsupported format (%#x).\n", s->name, info.format); break;
|
||||
default: Con_Printf ("%s has an unsupported format (%#"PRIX16").\n", s->name, info.format); break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1246,12 +1300,28 @@ static wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
|
|||
return info;
|
||||
}
|
||||
ctx.data_p += 8;
|
||||
info.format = GetLittleShort(&ctx);
|
||||
info.format = (unsigned short)GetLittleShort(&ctx);
|
||||
|
||||
info.numchannels = GetLittleShort(&ctx);
|
||||
info.numchannels = (unsigned short)GetLittleShort(&ctx);
|
||||
info.rate = GetLittleLong(&ctx);
|
||||
ctx.data_p += 4+2;
|
||||
info.bitwidth = GetLittleShort(&ctx);
|
||||
ctx.data_p += 4; //nAvgBytesPerSec
|
||||
ctx.data_p += 2; //nBlockAlign
|
||||
info.bitwidth = (unsigned short)GetLittleShort(&ctx); //meant to be a multiple of 8, but when its not we will treat it as 'nValidBits' and assume the lower bits are padded to bytes.
|
||||
|
||||
if (info.format == 0xfffe)
|
||||
{
|
||||
if (GetLittleShort(&ctx) >= 22) //cbSize
|
||||
{
|
||||
ctx.data_p += 2; //wValidBitsPerSample. don't really care
|
||||
ctx.data_p += 4; //dwChannelMask. don't really care.
|
||||
if (!memcmp(ctx.data_p, "\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x00\x38\x9b\x71", 16))
|
||||
info.format = 1; //pcm(regular ints)
|
||||
else if (!memcmp(ctx.data_p, "\x03\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x00\x38\x9b\x71", 16))
|
||||
info.format = 3; //float
|
||||
//else leave it unusable.
|
||||
ctx.data_p += 16; //SubFormat. convert to the real format
|
||||
}
|
||||
}
|
||||
|
||||
// get cue chunk
|
||||
chunklen = FindChunk(&ctx, "cue ");
|
||||
|
@ -1286,7 +1356,7 @@ static wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
|
|||
}
|
||||
|
||||
ctx.data_p += 8;
|
||||
samples = (chunklen<<3) / info.bitwidth / info.numchannels;
|
||||
samples = (chunklen<<3) / ((info.bitwidth+7)&~7) / info.numchannels;
|
||||
|
||||
if (info.samples)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue