- added Gez's VOC loader.

SVN r2901 (trunk)
This commit is contained in:
Christoph Oelckers 2010-10-05 22:31:22 +00:00
parent 00f6f459e5
commit 5ff3b3f329
5 changed files with 169 additions and 6 deletions

View file

@ -1307,10 +1307,15 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
wlump.Read(sfxdata, size);
SDWORD len = LittleLong(((SDWORD *)sfxdata)[1]);
// If the sound is voc, use the custom loader.
if (strncmp ((const char *)sfxstart, "Creative Voice File", 19) == 0)
{
sfx->data = GSnd->LoadSoundVoc(sfxstart, len);
}
// If the sound is raw, just load it as such.
// Otherwise, try the sound as DMX format.
// If that fails, let FMOD try and figure it out.
if (sfx->bLoadRAW ||
else if (sfx->bLoadRAW ||
(((BYTE *)sfxdata)[0] == 3 && ((BYTE *)sfxdata)[1] == 0 && len <= size - 8))
{
int frequency;

View file

@ -2316,7 +2316,7 @@ void FMODSoundRenderer::UpdateSounds()
//
//==========================================================================
SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart)
SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend)
{
FMOD_CREATESOUNDEXINFO exinfo;
SoundHandle retval = { NULL };
@ -2372,7 +2372,9 @@ SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequ
if (loopstart >= 0)
{
sample->setLoopPoints(loopstart, FMOD_TIMEUNIT_PCM, numsamples - 1, FMOD_TIMEUNIT_PCM);
if (loopend == -1)
loopend = numsamples - 1;
sample->setLoopPoints(loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM);
}
retval.data = sample;

View file

@ -14,7 +14,7 @@ public:
void SetSfxVolume (float volume);
void SetMusicVolume (float volume);
SoundHandle LoadSound(BYTE *sfxdata, int length);
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart);
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1);
void UnloadSound (SoundHandle sfx);
unsigned int GetMSLength(SoundHandle sfx);
unsigned int GetSampleLength(SoundHandle sfx);

View file

@ -124,7 +124,7 @@ public:
SoundHandle retval = { NULL };
return retval;
}
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart)
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend)
{
SoundHandle retval = { NULL };
return retval;
@ -344,3 +344,158 @@ FString SoundStream::GetStats()
{
return "No stream stats available.";
}
//==========================================================================
//
// SoundRenderer :: LoadSoundVoc
//
//==========================================================================
SoundHandle SoundRenderer::LoadSoundVoc(BYTE *sfxdata, int length)
{
BYTE * data = NULL;
int len, frequency, channels, bits, loopstart, loopend;
len = frequency = channels = bits = 0;
loopstart = loopend = -1;
do if (length > 26)
{
// First pass to parse data and validate the file
if (strncmp ((const char *)sfxdata, "Creative Voice File", 19))
break;
int i = 26, blocktype = 0, blocksize = 0, codec = -1;
bool noextra = true, okay = true;
while (i < length)
{
// Read block header
blocktype = sfxdata[i];
if (blocktype == 0)
break;
blocksize = sfxdata[i+1] + (sfxdata[i+2]<<8) + (sfxdata[i+3]<<16);
i += 4;
if (i + blocksize > length)
{
okay = false;
break;
}
// Read block data
switch (blocktype)
{
case 1: // Sound data
if (noextra && (codec == -1 || codec == sfxdata[i+1]))
{
frequency = 1000000/(256 - sfxdata[i]);
channels = 1;
codec = sfxdata[i+1];
if (codec == 0)
bits = 8;
else if (codec == 4)
bits = -16;
else okay = false;
len += blocksize - 2;
}
break;
case 2: // Sound data continuation
if (codec == -1)
okay = false;
len += blocksize;
break;
case 3: // Silence
if (frequency == 1000000/(256 - sfxdata[i+2]))
{
int silength = 1 + sfxdata[i] + (sfxdata[i+1]<<8);
if (codec == 0) // 8-bit unsigned PCM
len += silength;
else if (codec == 4) // 16-bit signed PCM
len += silength<<1;
else okay = false;
} else okay = false;
break;
case 4: // Mark (ignored)
case 5: // Text (ignored)
break;
case 6: // Repeat start
loopstart = len;
break;
case 7: // Repeat end
loopend = len;
if (loopend < loopstart)
okay = false;
break;
case 8: // Extra info
noextra = false;
if (codec == -1)
{
codec = sfxdata[i+2];
channels = 1+sfxdata[i+3];
frequency = 256000000/(channels * (65536 - (sfxdata[i]+(sfxdata[i+1]<<8))));
} else okay = false;
break;
case 9: // Sound data in new format
if (codec == -1)
{
frequency = sfxdata[i] + (sfxdata[i+1]<<8) + (sfxdata[i+2]<<16) + (sfxdata[i+3]<<24);
bits = sfxdata[i+4];
channels = sfxdata[i+5];
codec = sfxdata[i+6] + (sfxdata[i+7]<<8);
if (codec == 0)
bits = 8;
else if (codec == 4)
bits = -16;
else okay = false;
len += blocksize - 12;
} else okay = false;
break;
default: // Unknown block type
okay = false;
DPrintf ("Unknown VOC block type %i\n", blocktype);
break;
}
// Move to next block
i += blocksize;
}
// Second pass to write the data
if (okay)
{
data = new BYTE[len];
i = 26;
int j = 0;
while (i < length)
{
// Read block header again
blocktype = sfxdata[i];
if (blocktype == 0) break;
blocksize = sfxdata[i+1] + (sfxdata[i+2]<<8) + (sfxdata[i+3]<<16);
i += 4;
switch (blocktype)
{
case 1: memcpy(data+j, sfxdata+i+2, blocksize-2 ); j += blocksize-2; break;
case 2: memcpy(data+j, sfxdata+i, blocksize ); j += blocksize; break;
case 9: memcpy(data+j, sfxdata+i+12, blocksize-12); j += blocksize-12; break;
case 3:
{
int silength = 1 + sfxdata[i] + (sfxdata[i+1]<<8);
if (bits == 8)
{
memset(data+j, 128, silength);
j += silength;
}
else if (bits == -16)
{
memset(data+j, 0, silength<<1);
j += silength<<1;
}
}
break;
default: break;
}
}
}
} while (false);
SoundHandle retval = LoadSoundRaw(data, len, frequency, channels, bits, loopstart, loopend);
if (data) delete[] data;
return retval;
}

View file

@ -92,7 +92,8 @@ public:
virtual void SetSfxVolume (float volume) = 0;
virtual void SetMusicVolume (float volume) = 0;
virtual SoundHandle LoadSound(BYTE *sfxdata, int length) = 0;
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart) = 0;
SoundHandle LoadSoundVoc(BYTE *sfxdata, int length);
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1) = 0;
virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory
virtual unsigned int GetMSLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
virtual unsigned int GetSampleLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency