Store and use an ALbuffer for samples in an ALfontsound

The fontsound still maintains its own start, end, and loop offsets, so that the
same buffer may be shared between multiple/all fontsounds. Ideally a single
buffer should be used for all fontsounds to avoid memory fragmentation and help
CPU caching, although higher quality soundfonts may need more memory than a
single buffer can hold.
This commit is contained in:
Chris Robinson
2014-06-29 00:47:29 -07:00
parent d19e42a723
commit 389a2f7b4b
3 changed files with 34 additions and 3 deletions
+5 -3
View File
@@ -144,7 +144,7 @@ typedef struct FSample {
ALsizei NumMods;
} FSample;
static void FSample_Construct(FSample *self, ALfontsound *sound, ALsoundfont *sfont)
static void FSample_Construct(FSample *self, ALfontsound *sound)
{
fluid_sample_t *sample = STATIC_CAST(fluid_sample_t, self);
memset(sample->name, 0, sizeof(sample->name));
@@ -157,7 +157,7 @@ static void FSample_Construct(FSample *self, ALfontsound *sound, ALsoundfont *sf
sample->pitchadj = sound->PitchCorrection;
sample->sampletype = getSampleType(sound->SampleType);
sample->valid = 1;
sample->data = sfont->Samples;
sample->data = sound->Buffer ? sound->Buffer->data : NULL;
sample->amplitude_that_reaches_noise_floor_is_valid = 0;
sample->amplitude_that_reaches_noise_floor = 0.0;
@@ -240,7 +240,7 @@ static void FPreset_Construct(FPreset *self, ALsfpreset *preset, fluid_sfont_t *
ALsizei i;
self->NumSamples = preset->NumSounds;
for(i = 0;i < self->NumSamples;i++)
FSample_Construct(&self->Samples[i], preset->Sounds[i], sfont);
FSample_Construct(&self->Samples[i], preset->Sounds[i]);
}
}
@@ -294,6 +294,8 @@ static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int chan
fluid_voice_t *voice;
ALsizei m;
if(!STATIC_CAST(fluid_sample_t, sample)->data)
continue;
if(!(key >= sound->MinKey && key <= sound->MaxKey && vel >= sound->MinVelocity && vel <= sound->MaxVelocity))
continue;
+2
View File
@@ -34,6 +34,8 @@ typedef struct ALenvelope {
typedef struct ALfontsound {
RefCount ref;
struct ALbuffer *Buffer;
ALint MinKey, MaxKey;
ALint MinVelocity, MaxVelocity;
+27
View File
@@ -8,6 +8,7 @@
#include "alMidi.h"
#include "alError.h"
#include "alThunk.h"
#include "alBuffer.h"
#include "midi/base.h"
@@ -257,6 +258,10 @@ AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *val
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
switch(param)
{
case AL_BUFFER:
values[0] = (sound->Buffer ? sound->Buffer->id : 0);
break;
case AL_MOD_LFO_TO_PITCH_SOFT:
values[0] = sound->ModLfoToPitch;
break;
@@ -510,6 +515,8 @@ static void ALfontsound_Construct(ALfontsound *self)
{
InitRef(&self->ref, 0);
self->Buffer = NULL;
self->MinKey = 0;
self->MaxKey = 127;
self->MinVelocity = 0;
@@ -587,6 +594,9 @@ void ALfontsound_Destruct(ALfontsound *self)
FreeThunkEntry(self->id);
self->id = 0;
if(self->Buffer)
DecrementRef(&self->Buffer->ref);
self->Buffer = NULL;
if(self->Link)
DecrementRef(&self->Link->ref);
self->Link = NULL;
@@ -602,9 +612,26 @@ void ALfontsound_Destruct(ALfontsound *self)
void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value)
{
ALfontsound *link;
ALbuffer *buffer;
switch(param)
{
case AL_BUFFER:
buffer = value ? LookupBuffer(context->Device, value) : NULL;
if(value && !buffer)
SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
else if(buffer)
{
/* Buffer must have a non-0 length, and must be mono. */
if(buffer->SampleLen <= 0 || buffer->FmtChannels != FmtMono)
SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
}
if(buffer) IncrementRef(&buffer->ref);
if((buffer=ExchangePtr((XchgPtr*)&self->Buffer, buffer)) != NULL)
DecrementRef(&buffer->ref);
break;
case AL_MOD_LFO_TO_PITCH_SOFT:
self->ModLfoToPitch = value;
break;