mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-17 01:31:25 +00:00
- avoid double loading sound data for monoization.
This commit is contained in:
parent
b5dc5ceb3c
commit
21af612224
9 changed files with 189 additions and 64 deletions
|
@ -126,7 +126,7 @@ extern float S_GetMusicVolume (const char *music);
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||||
|
|
||||||
static void S_LoadSound3D(sfxinfo_t *sfx);
|
static void S_LoadSound3D(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer);
|
||||||
static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range, AActor *actor, int channel);
|
static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range, AActor *actor, int channel);
|
||||||
static bool S_IsChannelUsed(AActor *actor, int channel, int *seen);
|
static bool S_IsChannelUsed(AActor *actor, int channel, int *seen);
|
||||||
static void S_ActivatePlayList(bool goBack);
|
static void S_ActivatePlayList(bool goBack);
|
||||||
|
@ -577,7 +577,10 @@ void S_CacheSound (sfxinfo_t *sfx)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S_LoadSound(sfx);
|
// Since we do not know in what format the sound will be used, we have to cache both.
|
||||||
|
FSoundLoadBuffer SoundBuffer;
|
||||||
|
S_LoadSound(sfx, &SoundBuffer);
|
||||||
|
S_LoadSound3D(sfx, &SoundBuffer);
|
||||||
sfx->bUsed = true;
|
sfx->bUsed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -906,6 +909,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
FSoundChan *chan;
|
FSoundChan *chan;
|
||||||
FVector3 pos, vel;
|
FVector3 pos, vel;
|
||||||
FRolloffInfo *rolloff;
|
FRolloffInfo *rolloff;
|
||||||
|
FSoundLoadBuffer SoundBuffer;
|
||||||
|
|
||||||
if (sound_id <= 0 || volume <= 0 || nosfx || nosound )
|
if (sound_id <= 0 || volume <= 0 || nosfx || nosound )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1050,7 +1054,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the sound is loaded.
|
// Make sure the sound is loaded.
|
||||||
sfx = S_LoadSound(sfx);
|
sfx = S_LoadSound(sfx, &SoundBuffer);
|
||||||
|
|
||||||
// The empty sound never plays.
|
// The empty sound never plays.
|
||||||
if (sfx->lumpnum == sfx_empty)
|
if (sfx->lumpnum == sfx_empty)
|
||||||
|
@ -1150,7 +1154,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
|
|
||||||
if (attenuation > 0)
|
if (attenuation > 0)
|
||||||
{
|
{
|
||||||
S_LoadSound3D(sfx);
|
S_LoadSound3D(sfx, &SoundBuffer);
|
||||||
SoundListener listener;
|
SoundListener listener;
|
||||||
S_SetListener(listener, players[consoleplayer].camera);
|
S_SetListener(listener, players[consoleplayer].camera);
|
||||||
chan = (FSoundChan*)GSnd->StartSound3D (sfx->data3d, &listener, float(volume), rolloff, float(attenuation), pitch, basepriority, pos, vel, channel, startflags, NULL);
|
chan = (FSoundChan*)GSnd->StartSound3D (sfx->data3d, &listener, float(volume), rolloff, float(attenuation), pitch, basepriority, pos, vel, channel, startflags, NULL);
|
||||||
|
@ -1213,12 +1217,13 @@ void S_RestartSound(FSoundChan *chan)
|
||||||
|
|
||||||
FSoundChan *ochan;
|
FSoundChan *ochan;
|
||||||
sfxinfo_t *sfx = &S_sfx[chan->SoundID];
|
sfxinfo_t *sfx = &S_sfx[chan->SoundID];
|
||||||
|
FSoundLoadBuffer SoundBuffer;
|
||||||
|
|
||||||
// If this is a singular sound, don't play it if it's already playing.
|
// If this is a singular sound, don't play it if it's already playing.
|
||||||
if (sfx->bSingular && S_CheckSingular(chan->SoundID))
|
if (sfx->bSingular && S_CheckSingular(chan->SoundID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sfx = S_LoadSound(sfx);
|
sfx = S_LoadSound(sfx, &SoundBuffer);
|
||||||
|
|
||||||
// The empty sound never plays.
|
// The empty sound never plays.
|
||||||
if (sfx->lumpnum == sfx_empty)
|
if (sfx->lumpnum == sfx_empty)
|
||||||
|
@ -1247,7 +1252,7 @@ void S_RestartSound(FSoundChan *chan)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
S_LoadSound3D(sfx);
|
S_LoadSound3D(sfx, &SoundBuffer);
|
||||||
SoundListener listener;
|
SoundListener listener;
|
||||||
S_SetListener(listener, players[consoleplayer].camera);
|
S_SetListener(listener, players[consoleplayer].camera);
|
||||||
|
|
||||||
|
@ -1392,7 +1397,7 @@ void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
|
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer)
|
||||||
{
|
{
|
||||||
if (GSnd->IsNull()) return sfx;
|
if (GSnd->IsNull()) return sfx;
|
||||||
|
|
||||||
|
@ -1452,7 +1457,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
|
||||||
// If that fails, let the sound system try and figure it out.
|
// If that fails, let the sound system try and figure it out.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSound(sfxdata, size);
|
snd = GSnd->LoadSound(sfxdata, size, false, pBuffer);
|
||||||
}
|
}
|
||||||
delete[] sfxdata;
|
delete[] sfxdata;
|
||||||
|
|
||||||
|
@ -1474,7 +1479,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
|
||||||
return sfx;
|
return sfx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S_LoadSound3D(sfxinfo_t *sfx)
|
static void S_LoadSound3D(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer)
|
||||||
{
|
{
|
||||||
if (GSnd->IsNull()) return;
|
if (GSnd->IsNull()) return;
|
||||||
|
|
||||||
|
@ -1483,40 +1488,47 @@ static void S_LoadSound3D(sfxinfo_t *sfx)
|
||||||
|
|
||||||
DPrintf(DMSG_NOTIFY, "Loading monoized sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
|
DPrintf(DMSG_NOTIFY, "Loading monoized sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
|
||||||
|
|
||||||
int size = Wads.LumpLength(sfx->lumpnum);
|
if (pBuffer->mBuffer.Size() > 0)
|
||||||
if(size <= 0) return;
|
{
|
||||||
|
GSnd->LoadSoundBuffered(pBuffer, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int size = Wads.LumpLength(sfx->lumpnum);
|
||||||
|
if (size <= 0) return;
|
||||||
|
|
||||||
FWadLump wlump = Wads.OpenLumpNum(sfx->lumpnum);
|
FWadLump wlump = Wads.OpenLumpNum(sfx->lumpnum);
|
||||||
uint8_t *sfxdata = new uint8_t[size];
|
uint8_t *sfxdata = new uint8_t[size];
|
||||||
wlump.Read(sfxdata, size);
|
wlump.Read(sfxdata, size);
|
||||||
int32_t dmxlen = LittleLong(((int32_t *)sfxdata)[1]);
|
int32_t dmxlen = LittleLong(((int32_t *)sfxdata)[1]);
|
||||||
std::pair<SoundHandle,bool> snd;
|
std::pair<SoundHandle, bool> snd;
|
||||||
|
|
||||||
// If the sound is voc, use the custom loader.
|
// If the sound is voc, use the custom loader.
|
||||||
if (strncmp ((const char *)sfxdata, "Creative Voice File", 19) == 0)
|
if (strncmp((const char *)sfxdata, "Creative Voice File", 19) == 0)
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSoundVoc(sfxdata, size, true);
|
snd = GSnd->LoadSoundVoc(sfxdata, size, true);
|
||||||
}
|
}
|
||||||
// If the sound is raw, just load it as such.
|
// If the sound is raw, just load it as such.
|
||||||
else if (sfx->bLoadRAW)
|
else if (sfx->bLoadRAW)
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSoundRaw(sfxdata, size, sfx->RawRate, 1, 8, sfx->LoopStart, true);
|
snd = GSnd->LoadSoundRaw(sfxdata, size, sfx->RawRate, 1, 8, sfx->LoopStart, true);
|
||||||
}
|
}
|
||||||
// Otherwise, try the sound as DMX format.
|
// Otherwise, try the sound as DMX format.
|
||||||
else if (((uint8_t *)sfxdata)[0] == 3 && ((uint8_t *)sfxdata)[1] == 0 && dmxlen <= size - 8)
|
else if (((uint8_t *)sfxdata)[0] == 3 && ((uint8_t *)sfxdata)[1] == 0 && dmxlen <= size - 8)
|
||||||
{
|
{
|
||||||
int frequency = LittleShort(((uint16_t *)sfxdata)[1]);
|
int frequency = LittleShort(((uint16_t *)sfxdata)[1]);
|
||||||
if (frequency == 0) frequency = 11025;
|
if (frequency == 0) frequency = 11025;
|
||||||
snd = GSnd->LoadSoundRaw(sfxdata+8, dmxlen, frequency, 1, 8, sfx->LoopStart, -1, true);
|
snd = GSnd->LoadSoundRaw(sfxdata + 8, dmxlen, frequency, 1, 8, sfx->LoopStart, -1, true);
|
||||||
}
|
}
|
||||||
// If that fails, let the sound system try and figure it out.
|
// If that fails, let the sound system try and figure it out.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSound(sfxdata, size, true);
|
snd = GSnd->LoadSound(sfxdata, size, true, pBuffer);
|
||||||
}
|
}
|
||||||
delete[] sfxdata;
|
delete[] sfxdata;
|
||||||
|
|
||||||
sfx->data3d = snd.first;
|
sfx->data3d = snd.first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -212,6 +212,7 @@ struct FSoundChan : public FISoundChannel
|
||||||
float Point[3]; // Sound is not attached to any source.
|
float Point[3]; // Sound is not attached to any source.
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FSoundChan *Channels;
|
extern FSoundChan *Channels;
|
||||||
|
|
||||||
void S_ReturnChannel(FSoundChan *chan);
|
void S_ReturnChannel(FSoundChan *chan);
|
||||||
|
@ -299,6 +300,7 @@ void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool
|
||||||
#define ATTN_IDLE 1.001f
|
#define ATTN_IDLE 1.001f
|
||||||
#define ATTN_STATIC 3.f // diminish very rapidly with distance
|
#define ATTN_STATIC 3.f // diminish very rapidly with distance
|
||||||
|
|
||||||
|
struct FSoundLoadBuffer;
|
||||||
int S_PickReplacement (int refid);
|
int S_PickReplacement (int refid);
|
||||||
void S_CacheRandomSound (sfxinfo_t *sfx);
|
void S_CacheRandomSound (sfxinfo_t *sfx);
|
||||||
|
|
||||||
|
@ -384,7 +386,7 @@ int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int ref
|
||||||
void S_MarkPlayerSounds (const char *playerclass);
|
void S_MarkPlayerSounds (const char *playerclass);
|
||||||
void S_ShrinkPlayerSoundLists ();
|
void S_ShrinkPlayerSoundLists ();
|
||||||
void S_UnloadSound (sfxinfo_t *sfx);
|
void S_UnloadSound (sfxinfo_t *sfx);
|
||||||
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
|
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer = nullptr);
|
||||||
unsigned int S_GetMSLength(FSoundID sound);
|
unsigned int S_GetMSLength(FSoundID sound);
|
||||||
void S_ParseMusInfo();
|
void S_ParseMusInfo();
|
||||||
bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time);
|
bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time);
|
||||||
|
|
|
@ -120,7 +120,7 @@ public:
|
||||||
void SetMusicVolume (float volume)
|
void SetMusicVolume (float volume)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
std::pair<SoundHandle,bool> LoadSound(uint8_t *sfxdata, int length, bool monoize)
|
std::pair<SoundHandle,bool> LoadSound(uint8_t *sfxdata, int length, bool monoize, FSoundLoadBuffer *pBuffer)
|
||||||
{
|
{
|
||||||
SoundHandle retval = { NULL };
|
SoundHandle retval = { NULL };
|
||||||
return std::make_pair(retval, true);
|
return std::make_pair(retval, true);
|
||||||
|
@ -576,6 +576,12 @@ std::pair<SoundHandle,bool> SoundRenderer::LoadSoundVoc(uint8_t *sfxdata, int le
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<SoundHandle, bool> SoundRenderer::LoadSoundBuffered(FSoundLoadBuffer *buffer, bool monoize)
|
||||||
|
{
|
||||||
|
SoundHandle retval = { NULL };
|
||||||
|
return std::make_pair(retval, true);
|
||||||
|
}
|
||||||
|
|
||||||
SoundDecoder *SoundRenderer::CreateDecoder(FileReader *reader)
|
SoundDecoder *SoundRenderer::CreateDecoder(FileReader *reader)
|
||||||
{
|
{
|
||||||
SoundDecoder *decoder = NULL;
|
SoundDecoder *decoder = NULL;
|
||||||
|
@ -604,14 +610,14 @@ SoundDecoder *SoundRenderer::CreateDecoder(FileReader *reader)
|
||||||
|
|
||||||
|
|
||||||
// Default readAll implementation, for decoders that can't do anything better
|
// Default readAll implementation, for decoders that can't do anything better
|
||||||
TArray<char> SoundDecoder::readAll()
|
TArray<uint8_t> SoundDecoder::readAll()
|
||||||
{
|
{
|
||||||
TArray<char> output;
|
TArray<uint8_t> output;
|
||||||
unsigned total = 0;
|
unsigned total = 0;
|
||||||
unsigned got;
|
unsigned got;
|
||||||
|
|
||||||
output.Resize(total+32768);
|
output.Resize(total+32768);
|
||||||
while((got=(unsigned)read(&output[total], output.Size()-total)) > 0)
|
while((got=(unsigned)read((char*)&output[total], output.Size()-total)) > 0)
|
||||||
{
|
{
|
||||||
total += got;
|
total += got;
|
||||||
output.Resize(total*2);
|
output.Resize(total*2);
|
||||||
|
|
|
@ -87,6 +87,16 @@ typedef bool (*SoundStreamCallback)(SoundStream *stream, void *buff, int len, vo
|
||||||
struct SoundDecoder;
|
struct SoundDecoder;
|
||||||
class MIDIDevice;
|
class MIDIDevice;
|
||||||
|
|
||||||
|
struct FSoundLoadBuffer
|
||||||
|
{
|
||||||
|
TArray<uint8_t> mBuffer;
|
||||||
|
uint32_t loop_start;
|
||||||
|
uint32_t loop_end;
|
||||||
|
ChannelConfig chans;
|
||||||
|
SampleType type;
|
||||||
|
int srate;
|
||||||
|
};
|
||||||
|
|
||||||
class SoundRenderer
|
class SoundRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -97,9 +107,10 @@ public:
|
||||||
virtual void SetSfxVolume (float volume) = 0;
|
virtual void SetSfxVolume (float volume) = 0;
|
||||||
virtual void SetMusicVolume (float volume) = 0;
|
virtual void SetMusicVolume (float volume) = 0;
|
||||||
// Returns a pair containing a sound handle and a boolean indicating the sound can be used in 3D.
|
// Returns a pair containing a sound handle and a boolean indicating the sound can be used in 3D.
|
||||||
virtual std::pair<SoundHandle,bool> LoadSound(uint8_t *sfxdata, int length, bool monoize=false) = 0;
|
virtual std::pair<SoundHandle,bool> LoadSound(uint8_t *sfxdata, int length, bool monoize=false, FSoundLoadBuffer *pBuffer = nullptr) = 0;
|
||||||
std::pair<SoundHandle,bool> LoadSoundVoc(uint8_t *sfxdata, int length, bool monoize=false);
|
std::pair<SoundHandle,bool> LoadSoundVoc(uint8_t *sfxdata, int length, bool monoize=false);
|
||||||
virtual std::pair<SoundHandle,bool> LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1, bool monoize = false) = 0;
|
virtual std::pair<SoundHandle,bool> LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1, bool monoize = false) = 0;
|
||||||
|
virtual std::pair<SoundHandle, bool> LoadSoundBuffered(FSoundLoadBuffer *buffer, bool monoize);
|
||||||
virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory
|
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 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
|
virtual unsigned int GetSampleLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
|
||||||
|
|
|
@ -131,7 +131,7 @@ struct SoundDecoder
|
||||||
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0;
|
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0;
|
||||||
|
|
||||||
virtual size_t read(char *buffer, size_t bytes) = 0;
|
virtual size_t read(char *buffer, size_t bytes) = 0;
|
||||||
virtual TArray<char> readAll();
|
virtual TArray<uint8_t> readAll();
|
||||||
virtual bool seek(size_t ms_offset, bool ms, bool mayrestart) = 0;
|
virtual bool seek(size_t ms_offset, bool ms, bool mayrestart) = 0;
|
||||||
virtual size_t getSampleOffset() = 0;
|
virtual size_t getSampleOffset() = 0;
|
||||||
virtual size_t getSampleLength() { return 0; }
|
virtual size_t getSampleLength() { return 0; }
|
||||||
|
|
|
@ -1205,7 +1205,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata,
|
||||||
|
|
||||||
void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass);
|
void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass);
|
||||||
|
|
||||||
std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, bool monoize)
|
std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, bool monoize, FSoundLoadBuffer *pBuffer)
|
||||||
{
|
{
|
||||||
SoundHandle retval = { NULL };
|
SoundHandle retval = { NULL };
|
||||||
MemoryReader reader((const char*)sfxdata, length);
|
MemoryReader reader((const char*)sfxdata, length);
|
||||||
|
@ -1223,29 +1223,30 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<SoundDecoder> decoder(CreateDecoder(&reader));
|
std::unique_ptr<SoundDecoder> decoder(CreateDecoder(&reader));
|
||||||
if(!decoder) return std::make_pair(retval, true);
|
if (!decoder) return std::make_pair(retval, true);
|
||||||
|
|
||||||
decoder->getInfo(&srate, &chans, &type);
|
decoder->getInfo(&srate, &chans, &type);
|
||||||
int samplesize = 1;
|
int samplesize = 1;
|
||||||
if(chans == ChannelConfig_Mono || monoize)
|
if (chans == ChannelConfig_Mono || monoize)
|
||||||
{
|
{
|
||||||
if(type == SampleType_UInt8) format = AL_FORMAT_MONO8, samplesize = 1;
|
if (type == SampleType_UInt8) format = AL_FORMAT_MONO8, samplesize = 1;
|
||||||
if(type == SampleType_Int16) format = AL_FORMAT_MONO16, samplesize = 2;
|
if (type == SampleType_Int16) format = AL_FORMAT_MONO16, samplesize = 2;
|
||||||
}
|
}
|
||||||
else if(chans == ChannelConfig_Stereo)
|
else if (chans == ChannelConfig_Stereo)
|
||||||
{
|
{
|
||||||
if(type == SampleType_UInt8) format = AL_FORMAT_STEREO8, samplesize = 2;
|
if (type == SampleType_UInt8) format = AL_FORMAT_STEREO8, samplesize = 2;
|
||||||
if(type == SampleType_Int16) format = AL_FORMAT_STEREO16, samplesize = 4;
|
if (type == SampleType_Int16) format = AL_FORMAT_STEREO16, samplesize = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(format == AL_NONE)
|
if (format == AL_NONE)
|
||||||
{
|
{
|
||||||
Printf("Unsupported audio format: %s, %s\n", GetChannelConfigName(chans),
|
Printf("Unsupported audio format: %s, %s\n", GetChannelConfigName(chans),
|
||||||
GetSampleTypeName(type));
|
GetSampleTypeName(type));
|
||||||
return std::make_pair(retval, true);
|
return std::make_pair(retval, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<char> data = decoder->readAll();
|
TArray<uint8_t> data = decoder->readAll();
|
||||||
|
|
||||||
if(chans != ChannelConfig_Mono && monoize)
|
if(chans != ChannelConfig_Mono && monoize)
|
||||||
{
|
{
|
||||||
size_t chancount = GetChannelCount(chans);
|
size_t chancount = GetChannelCount(chans);
|
||||||
|
@ -1289,7 +1290,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!startass) loop_start = Scale(loop_start, srate, 1000);
|
if (!startass) loop_start = Scale(loop_start, srate, 1000);
|
||||||
if (!endass) loop_end = Scale(loop_end, srate, 1000);
|
if (!endass && loop_end != ~0u) loop_end = Scale(loop_end, srate, 1000);
|
||||||
const uint32_t samples = data.Size() / samplesize;
|
const uint32_t samples = data.Size() / samplesize;
|
||||||
if (loop_start > samples) loop_start = 0;
|
if (loop_start > samples) loop_start = 0;
|
||||||
if (loop_end > samples) loop_end = samples;
|
if (loop_end > samples) loop_end = samples;
|
||||||
|
@ -1302,6 +1303,98 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int
|
||||||
// no console messages here, please!
|
// no console messages here, please!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retval.data = MAKE_PTRID(buffer);
|
||||||
|
if (pBuffer != nullptr)
|
||||||
|
{
|
||||||
|
pBuffer->mBuffer = std::move(data);
|
||||||
|
pBuffer->loop_start = loop_start;
|
||||||
|
pBuffer->loop_end = loop_end;
|
||||||
|
pBuffer->chans = chans;
|
||||||
|
pBuffer->type = type;
|
||||||
|
pBuffer->srate = srate;
|
||||||
|
}
|
||||||
|
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<SoundHandle, bool> OpenALSoundRenderer::LoadSoundBuffered(FSoundLoadBuffer *pBuffer, bool monoize)
|
||||||
|
{
|
||||||
|
SoundHandle retval = { NULL };
|
||||||
|
ALenum format = AL_NONE;
|
||||||
|
int srate = pBuffer->srate;
|
||||||
|
auto type = pBuffer->type;
|
||||||
|
auto chans = pBuffer->chans;
|
||||||
|
uint32_t loop_start = pBuffer->loop_start, loop_end = pBuffer->loop_end;
|
||||||
|
|
||||||
|
if (chans == ChannelConfig_Mono || monoize)
|
||||||
|
{
|
||||||
|
if (type == SampleType_UInt8) format = AL_FORMAT_MONO8;
|
||||||
|
if (type == SampleType_Int16) format = AL_FORMAT_MONO16;
|
||||||
|
}
|
||||||
|
else if (chans == ChannelConfig_Stereo)
|
||||||
|
{
|
||||||
|
if (type == SampleType_UInt8) format = AL_FORMAT_STEREO8;
|
||||||
|
if (type == SampleType_Int16) format = AL_FORMAT_STEREO16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == AL_NONE)
|
||||||
|
{
|
||||||
|
Printf("Unsupported audio format: %s, %s\n", GetChannelConfigName(chans),
|
||||||
|
GetSampleTypeName(type));
|
||||||
|
return std::make_pair(retval, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<uint8_t> &data = pBuffer->mBuffer;
|
||||||
|
|
||||||
|
if (pBuffer->chans == ChannelConfig_Stereo && monoize)
|
||||||
|
{
|
||||||
|
size_t chancount = GetChannelCount(chans);
|
||||||
|
size_t frames = data.Size() / chancount /
|
||||||
|
(type == SampleType_Int16 ? 2 : 1);
|
||||||
|
if (type == SampleType_Int16)
|
||||||
|
{
|
||||||
|
short *sfxdata = (short*)&data[0];
|
||||||
|
for (size_t i = 0; i < frames; i++)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
for (size_t c = 0; c < chancount; c++)
|
||||||
|
sum += sfxdata[i*chancount + c];
|
||||||
|
sfxdata[i] = short(sum / chancount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == SampleType_UInt8)
|
||||||
|
{
|
||||||
|
uint8_t *sfxdata = (uint8_t*)&data[0];
|
||||||
|
for (size_t i = 0; i < frames; i++)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
for (size_t c = 0; c < chancount; c++)
|
||||||
|
sum += sfxdata[i*chancount + c] - 128;
|
||||||
|
sfxdata[i] = uint8_t((sum / chancount) + 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.Resize(unsigned(data.Size() / chancount));
|
||||||
|
}
|
||||||
|
|
||||||
|
ALenum err;
|
||||||
|
ALuint buffer = 0;
|
||||||
|
alGenBuffers(1, &buffer);
|
||||||
|
alBufferData(buffer, format, &data[0], data.Size(), srate);
|
||||||
|
if ((err = getALError()) != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
Printf("Failed to buffer data: %s\n", alGetString(err));
|
||||||
|
alDeleteBuffers(1, &buffer);
|
||||||
|
getALError();
|
||||||
|
return std::make_pair(retval, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the loop points were already validated by the previous load.
|
||||||
|
if ((loop_start > 0 || loop_end > 0) && loop_end > loop_start && AL.SOFT_loop_points)
|
||||||
|
{
|
||||||
|
ALint loops[2] = { static_cast<ALint>(loop_start), static_cast<ALint>(loop_end) };
|
||||||
|
DPrintf(DMSG_NOTIFY, "Setting loop points %d -> %d\n", loops[0], loops[1]);
|
||||||
|
alBufferiv(buffer, AL_LOOP_POINTS_SOFT, loops);
|
||||||
|
// no console messages here, please!
|
||||||
|
}
|
||||||
|
|
||||||
retval.data = MAKE_PTRID(buffer);
|
retval.data = MAKE_PTRID(buffer);
|
||||||
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
||||||
|
|
|
@ -87,7 +87,8 @@ public:
|
||||||
|
|
||||||
virtual void SetSfxVolume(float volume);
|
virtual void SetSfxVolume(float volume);
|
||||||
virtual void SetMusicVolume(float volume);
|
virtual void SetMusicVolume(float volume);
|
||||||
virtual std::pair<SoundHandle,bool> LoadSound(uint8_t *sfxdata, int length, bool monoize);
|
virtual std::pair<SoundHandle, bool> LoadSound(uint8_t *sfxdata, int length, bool monoize, FSoundLoadBuffer *buffer);
|
||||||
|
virtual std::pair<SoundHandle,bool> LoadSoundBuffered(FSoundLoadBuffer *buffer, bool monoize);
|
||||||
virtual std::pair<SoundHandle,bool> LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1, bool monoize = false);
|
virtual std::pair<SoundHandle,bool> LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1, bool monoize = false);
|
||||||
virtual void UnloadSound(SoundHandle sfx);
|
virtual void UnloadSound(SoundHandle sfx);
|
||||||
virtual unsigned int GetMSLength(SoundHandle sfx);
|
virtual unsigned int GetMSLength(SoundHandle sfx);
|
||||||
|
|
|
@ -175,16 +175,16 @@ size_t SndFileDecoder::read(char *buffer, size_t bytes)
|
||||||
return total * SndInfo.channels * 2;
|
return total * SndInfo.channels * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<char> SndFileDecoder::readAll()
|
TArray<uint8_t> SndFileDecoder::readAll()
|
||||||
{
|
{
|
||||||
if(SndInfo.frames <= 0)
|
if(SndInfo.frames <= 0)
|
||||||
return SoundDecoder::readAll();
|
return SoundDecoder::readAll();
|
||||||
|
|
||||||
int framesize = 2 * SndInfo.channels;
|
int framesize = 2 * SndInfo.channels;
|
||||||
TArray<char> output;
|
TArray<uint8_t> output;
|
||||||
|
|
||||||
output.Resize((unsigned)(SndInfo.frames * framesize));
|
output.Resize((unsigned)(SndInfo.frames * framesize));
|
||||||
size_t got = read(&output[0], output.Size());
|
size_t got = read((char*)&output[0], output.Size());
|
||||||
output.Resize((unsigned)got);
|
output.Resize((unsigned)got);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct SndFileDecoder : public SoundDecoder
|
||||||
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
|
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
|
||||||
|
|
||||||
virtual size_t read(char *buffer, size_t bytes);
|
virtual size_t read(char *buffer, size_t bytes);
|
||||||
virtual TArray<char> readAll();
|
virtual TArray<uint8_t> readAll();
|
||||||
virtual bool seek(size_t ms_offset, bool ms, bool mayrestart);
|
virtual bool seek(size_t ms_offset, bool ms, bool mayrestart);
|
||||||
virtual size_t getSampleOffset();
|
virtual size_t getSampleOffset();
|
||||||
virtual size_t getSampleLength();
|
virtual size_t getSampleLength();
|
||||||
|
|
Loading…
Reference in a new issue