aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/midi/base.c130
-rw-r--r--Alc/midi/sf2load.c237
-rw-r--r--OpenAL32/Include/alMidi.h6
-rw-r--r--OpenAL32/alFontsound.c147
4 files changed, 209 insertions, 311 deletions
diff --git a/Alc/midi/base.c b/Alc/midi/base.c
index 599dc6dc..db839958 100644
--- a/Alc/midi/base.c
+++ b/Alc/midi/base.c
@@ -286,136 +286,6 @@ ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *
}
-void ALfontsound_Construct(ALfontsound *self)
-{
- self->ref = 0;
-
- self->MinKey = 0;
- self->MaxKey = 127;
- self->MinVelocity = 0;
- self->MaxVelocity = 127;
-
- self->ModLfoToPitch = 0;
- self->VibratoLfoToPitch = 0;
- self->ModEnvToPitch = 0;
-
- self->FilterCutoff = 13500;
- self->FilterQ = 0;
- self->ModLfoToFilterCutoff = 0;
- self->ModEnvToFilterCutoff = 0;
- self->ModLfoToVolume = 0;
-
- self->ChorusSend = 0;
- self->ReverbSend = 0;
-
- self->Pan = 0;
-
- self->ModLfo.Delay = 0;
- self->ModLfo.Frequency = 0;
-
- self->VibratoLfo.Delay = 0;
- self->VibratoLfo.Frequency = 0;
-
- self->ModEnv.DelayTime = -12000;
- self->ModEnv.AttackTime = -12000;
- self->ModEnv.HoldTime = -12000;
- self->ModEnv.DecayTime = -12000;
- self->ModEnv.SustainVol = 0;
- self->ModEnv.ReleaseTime = -12000;
- self->ModEnv.KeyToHoldTime = 0;
- self->ModEnv.KeyToDecayTime = 0;
-
- self->VolEnv.DelayTime = -12000;
- self->VolEnv.AttackTime = -12000;
- self->VolEnv.HoldTime = -12000;
- self->VolEnv.DecayTime = -12000;
- self->VolEnv.SustainVol = 0;
- self->VolEnv.ReleaseTime = -12000;
- self->VolEnv.KeyToHoldTime = 0;
- self->VolEnv.KeyToDecayTime = 0;
-
- self->Attenuation = 0;
-
- self->CoarseTuning = 0;
- self->FineTuning = 0;
-
- self->LoopMode = AL_NONE;
-
- self->TuningScale = 100;
-
- self->ExclusiveClass = 0;
-
- self->Start = 0;
- self->End = 0;
- self->LoopStart = 0;
- self->LoopEnd = 0;
- self->SampleRate = 0;
- self->PitchKey = 0;
- self->PitchCorrection = 0;
- self->SampleType = AL_NONE;
- self->Link = NULL;
-
- self->Modulators = NULL;
- self->NumModulators = 0;
- self->ModulatorsMax = 0;
-
- self->id = 0;
-}
-
-void ALfontsound_Destruct(ALfontsound *self)
-{
- FreeThunkEntry(self->id);
- self->id = 0;
-
- if(self->Link)
- DecrementRef(&self->Link->ref);
- self->Link = NULL;
-
- free(self->Modulators);
- self->Modulators = NULL;
- self->NumModulators = 0;
- self->ModulatorsMax = 0;
-}
-
-ALenum ALfontsound_addModulator(ALfontsound *self, ALenum sourceop, ALenum destop, ALint amount, ALenum amtsourceop, ALenum transop)
-{
- ALsizei i;
- for(i = 0;i < self->NumModulators;i++)
- {
- if(self->Modulators[i].SourceOp == sourceop && self->Modulators[i].DestOp == destop &&
- self->Modulators[i].AmountSourceOp == amtsourceop &&
- self->Modulators[i].TransformOp == transop)
- {
- self->Modulators[i].Amount = amount;
- return AL_NO_ERROR;
- }
- }
-
- if(self->NumModulators == self->ModulatorsMax)
- {
- ALsizei newmax = 0;
- ALvoid *temp = NULL;
-
- newmax = (self->ModulatorsMax ? self->ModulatorsMax<<1 : 1);
- if(newmax > self->ModulatorsMax)
- temp = realloc(self->Modulators, newmax * sizeof(ALsfmodulator));
- if(!temp) return AL_OUT_OF_MEMORY;
-
- self->Modulators = temp;
- self->ModulatorsMax = newmax;
- }
-
- self->Modulators[self->NumModulators].SourceOp = sourceop;
- self->Modulators[self->NumModulators].DestOp = destop;
- self->Modulators[self->NumModulators].Amount = amount;
- self->Modulators[self->NumModulators].AmountSourceOp = amtsourceop;
- self->Modulators[self->NumModulators].TransformOp = transop;
- self->NumModulators++;
-
- return AL_NO_ERROR;
-}
-
-
void ALsoundfont_Construct(ALsoundfont *self)
{
self->ref = 0;
diff --git a/Alc/midi/sf2load.c b/Alc/midi/sf2load.c
index 1b944ccd..263ba7cd 100644
--- a/Alc/midi/sf2load.c
+++ b/Alc/midi/sf2load.c
@@ -562,74 +562,6 @@ static void GenModList_accumMod(GenModList *self, const Modulator *mod)
self->mods_size++;
}
-static ALint getGenValue(GenModList *self, ALint gen)
-{
- const Generator *i = self->gens;
- const Generator *end = i + self->gens_size;
- for(;i != end;i++)
- {
- if(i->mGenerator == gen)
- return i->mAmount;
- }
-
- return (gen < 60) ? DefaultGenValue[gen] : 0;
-}
-
-
-typedef struct IFlist {
- ALuint *ids;
- ALsizei ids_size;
- ALsizei ids_max;
-} IDList;
-
-static void IDList_Construct(IDList *self)
-{
- self->ids = NULL;
- self->ids_size = 0;
- self->ids_max = 0;
-}
-
-static void IDList_Destruct(IDList *self)
-{
- free(self->ids);
- self->ids = NULL;
- self->ids_size = 0;
- self->ids_max = 0;
-}
-
-static void IDList_reserve(IDList *self, ALsizei reserve)
-{
- if(reserve > self->ids_max)
- {
- ALvoid *temp = NULL;
-
- reserve = NextPowerOf2(reserve);
- if(reserve > self->ids_max)
- temp = realloc(self->ids, reserve * sizeof(self->ids[0]));
- if(!temp)
- {
- ERR("Failed to reserve %d IDs\n", reserve);
- return;
- }
-
- self->ids = temp;
- self->ids_max = reserve;
- }
-}
-
-static void IDList_add(IDList *self, ALuint id)
-{
- if(self->ids_size == self->ids_max)
- IDList_reserve(self, self->ids_max+1);
-
- if(self->ids_max > self->ids_size)
- {
- self->ids[self->ids_size] = id;
- self->ids_size++;
- }
-}
-
-
#define ERROR_GOTO(lbl_, ...) do { \
ERR(__VA_ARGS__); \
@@ -793,7 +725,7 @@ static ALboolean ensureZoneSanity(const GenModList *zone, int splidx)
return AL_TRUE;
}
-static void fillZone(ALuint id, const GenModList *zone)
+static void fillZone(ALfontsound *sound, const GenModList *zone)
{
static const ALenum Gen2Param[60] = {
0, /* 0 - startAddrOffset */
@@ -868,66 +800,73 @@ static void fillZone(ALuint id, const GenModList *zone)
gen_end = gen + zone->gens_size;
for(;gen != gen_end;gen++)
{
- ALenum param = 0;
- switch(gen->mGenerator)
+ ALint value = (ALshort)gen->mAmount;
+ if(gen->mGenerator == 0)
+ sound->Start += value;
+ else if(gen->mGenerator == 1)
+ sound->End += value;
+ else if(gen->mGenerator == 2)
+ sound->LoopStart += value;
+ else if(gen->mGenerator == 3)
+ sound->LoopEnd += value;
+ else if(gen->mGenerator == 4)
+ sound->Start += value<<15;
+ else if(gen->mGenerator == 12)
+ sound->End += value<<15;
+ else if(gen->mGenerator == 45)
+ sound->LoopStart += value<<15;
+ else if(gen->mGenerator == 50)
+ sound->LoopEnd += value<<15;
+ else if(gen->mGenerator == 43)
{
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 12:
- case 45:
- case 50:
- /* Handled later with the sample header */
- break;
-
- case 43:
- case 44:
+ sound->MinKey = mini((value&0xff), 127);
+ sound->MaxKey = mini(((value>>8)&0xff), 127);
+ }
+ else if(gen->mGenerator == 44)
+ {
+ sound->MinVelocity = mini((value&0xff), 127);
+ sound->MaxVelocity = mini(((value>>8)&0xff), 127);
+ }
+ else
+ {
+ ALenum param = 0;
+ if(gen->mGenerator < 60)
param = Gen2Param[gen->mGenerator];
- if(param)
- alFontsound2iSOFT(id, param, gen->mAmount&0xff, gen->mAmount>>8);
- break;
-
- default:
- if(gen->mGenerator < 60)
- param = Gen2Param[gen->mGenerator];
- if(param)
+ if(param)
+ {
+ if(param == AL_BASE_KEY_SOFT && value == -1)
+ break;
+ if(param == AL_FILTER_RESONANCE_SOFT || param == AL_ATTENUATION_SOFT)
+ value = maxi(0, value);
+ else if(param == AL_CHORUS_SEND_SOFT || param == AL_REVERB_SEND_SOFT)
+ value = clampi(value, 0, 1000);
+ else if(param == AL_LOOP_MODE_SOFT)
{
- ALint value = (ALshort)gen->mAmount;
- if(param == AL_BASE_KEY_SOFT && value == -1)
- break;
- if(param == AL_FILTER_RESONANCE_SOFT || param == AL_ATTENUATION_SOFT)
- value = maxi(0, value);
- else if(param == AL_CHORUS_SEND_SOFT || param == AL_REVERB_SEND_SOFT)
- value = clampi(value, 0, 1000);
- else if(param == AL_LOOP_MODE_SOFT)
- {
- if(!(value == 0 || value == 1 || value == 3))
- value = 0;
- }
- alFontsoundiSOFT(id, param, value);
+ if(!(value == 0 || value == 1 || value == 3))
+ value = 0;
}
- else if(gen->mGenerator < 256)
+ alFontsoundiSOFT(sound->id, param, value);
+ }
+ else if(gen->mGenerator < 256)
+ {
+ static ALboolean warned[256];
+ if(!warned[gen->mGenerator])
{
- static ALboolean warned[256];
- if(!warned[gen->mGenerator])
- {
- warned[gen->mGenerator] = AL_TRUE;
- ERR("Unhandled generator %d\n", gen->mGenerator);
- }
+ warned[gen->mGenerator] = AL_TRUE;
+ ERR("Unhandled generator %d\n", gen->mGenerator);
}
- break;
+ }
}
}
}
-static void processInstrument(InstrumentHeader *inst, IDList *sounds, const Soundfont *sfont, const GenModList *pzone)
+static void processInstrument(ALfontsound ***sounds, ALsizei *sounds_size, ALCcontext *context, InstrumentHeader *inst, const Soundfont *sfont, const GenModList *pzone)
{
const Generator *gen, *gen_end;
const Modulator *mod, *mod_end;
const Zone *zone, *zone_end;
GenModList gzone;
+ ALvoid *temp;
if((inst+1)->mZoneIdx == inst->mZoneIdx)
ERR("Instrument with no zones!");
@@ -963,6 +902,14 @@ static void processInstrument(InstrumentHeader *inst, IDList *sounds, const Soun
}
}
+ temp = realloc(*sounds, (zone_end-zone + *sounds_size)*sizeof((*sounds)[0]));
+ if(!temp)
+ {
+ ERR("Failed reallocating fontsound storage to %ld elements (from %d)\n",
+ (zone_end-zone + *sounds_size), *sounds_size);
+ return;
+ }
+ *sounds = temp;
for(;zone != zone_end;zone++)
{
GenModList lzone = GenModList_clone(&gzone);
@@ -978,7 +925,6 @@ static void processInstrument(InstrumentHeader *inst, IDList *sounds, const Soun
if(gen->mGenerator == 53)
{
const SampleHeader *samp;
- ALuint id;
if(gen->mAmount >= sfont->shdr_size-1)
{
@@ -1001,25 +947,18 @@ static void processInstrument(InstrumentHeader *inst, IDList *sounds, const Soun
if(!ensureZoneSanity(&lzone, samp-sfont->shdr))
break;
- id = 0;
- alGenFontsoundsSOFT(1, &id);
- IDList_add(sounds, id);
-
- alFontsoundiSOFT(id, AL_SAMPLE_START_SOFT, samp->mStart +
- (getGenValue(&lzone, 0) + (getGenValue(&lzone, 4)<<15)));
- alFontsoundiSOFT(id, AL_SAMPLE_END_SOFT, samp->mEnd +
- (getGenValue(&lzone, 1) + (getGenValue(&lzone, 12)<<15)));
- alFontsoundiSOFT(id, AL_SAMPLE_LOOP_START_SOFT, samp->mStartloop +
- (getGenValue(&lzone, 2) + (getGenValue(&lzone, 45)<<15)));
- alFontsoundiSOFT(id, AL_SAMPLE_LOOP_END_SOFT, samp->mEndloop +
- (getGenValue(&lzone, 3) + (getGenValue(&lzone, 50)<<15)));
- alFontsoundiSOFT(id, AL_SAMPLE_RATE_SOFT, samp->mSampleRate);
- alFontsoundiSOFT(id, AL_BASE_KEY_SOFT, samp->mOriginalKey);
- alFontsoundiSOFT(id, AL_KEY_CORRECTION_SOFT, samp->mCorrection);
- alFontsoundiSOFT(id, AL_SAMPLE_TYPE_SOFT, samp->mSampleType&0x7ffff);
- alFontsoundiSOFT(id, AL_FONTSOUND_LINK_SOFT, 0);
-
- fillZone(id, &lzone);
+ (*sounds)[*sounds_size] = NewFontsound(context);
+ (*sounds)[*sounds_size]->Start = samp->mStart;
+ (*sounds)[*sounds_size]->End = samp->mEnd;
+ (*sounds)[*sounds_size]->LoopStart = samp->mStartloop;
+ (*sounds)[*sounds_size]->LoopEnd = samp->mEndloop;
+ (*sounds)[*sounds_size]->SampleRate = samp->mSampleRate;
+ (*sounds)[*sounds_size]->PitchKey = samp->mOriginalKey;
+ (*sounds)[*sounds_size]->PitchCorrection = samp->mCorrection;
+ (*sounds)[*sounds_size]->LoopMode = (samp->mSampleType&0x7ffff);
+ fillZone((*sounds)[*sounds_size], &lzone);
+ (*sounds_size)++;
+
break;
}
GenModList_insertGen(&lzone, gen, AL_FALSE);
@@ -1250,7 +1189,6 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
ALfontsound **sounds = NULL;
ALsizei sounds_size = 0;
GenModList gzone;
- IDList fsids;
if(sfont.phdr[i+1].mZoneIdx == sfont.phdr[i].mZoneIdx)
continue;
@@ -1290,8 +1228,6 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
}
}
- IDList_Construct(&fsids);
- IDList_reserve(&fsids, zone_end-zone);
for(;zone != zone_end;zone++)
{
GenModList lzone = GenModList_clone(&gzone);
@@ -1311,38 +1247,29 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
ERR("Generator %ld has invalid instrument ID generator (%d of %d)\n",
(long)(gen-sfont.pgen), gen->mAmount, sfont.inst_size-1);
else
- processInstrument(&sfont.inst[gen->mAmount], &fsids, &sfont, &lzone);
+ processInstrument(&sounds, &sounds_size, context,
+ &sfont.inst[gen->mAmount], &sfont, &lzone);
break;
}
GenModList_insertGen(&lzone, gen, AL_TRUE);
}
GenModList_Destruct(&lzone);
}
- if(fsids.ids_size > 0)
+
+ if(sounds_size > 0)
{
- sounds = calloc(fsids.ids_size, sizeof(sounds[0]));
- if(sounds)
- {
- ALCdevice *device = context->Device;
- ALsizei j;
+ ALsizei j;
- for(j = 0;j < fsids.ids_size;j++)
- {
- sounds[j] = LookupFontsound(device, fsids.ids[j]);
- IncrementRef(&sounds[j]->ref);
- }
- sounds_size = fsids.ids_size;
- }
+ for(j = 0;j < sounds_size;j++)
+ IncrementRef(&sounds[j]->ref);
+ sounds = ExchangePtr((XchgPtr*)&presets[presets_size]->Sounds, sounds);
+ ExchangeInt(&presets[presets_size]->NumSounds, sounds_size);
}
-
- sounds = ExchangePtr((XchgPtr*)&presets[presets_size]->Sounds, sounds);
- ExchangeInt(&presets[presets_size]->NumSounds, sounds_size);
presets_size++;
free(sounds);
GenModList_Destruct(&gzone);
- IDList_Destruct(&fsids);
}
for(i = 0;i < presets_size;i++)
diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h
index 8037cff8..e3b4ef26 100644
--- a/OpenAL32/Include/alMidi.h
+++ b/OpenAL32/Include/alMidi.h
@@ -96,11 +96,7 @@ typedef struct ALfontsound {
ALuint id;
} ALfontsound;
-void ALfontsound_Construct(ALfontsound *self);
-void ALfontsound_Destruct(ALfontsound *self);
-ALenum ALfontsound_addGenerator(ALfontsound *self, ALenum generator, ALint value);
-ALenum ALfontsound_addModulator(ALfontsound *self, ALenum sourceop, ALenum destop, ALint amount, ALenum amtsourceop, ALenum transop);
-
+ALfontsound *NewFontsound(ALCcontext *context);
inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id)
{ return (struct ALfontsound*)LookupUIntMapKey(&device->FontsoundMap, id); }
diff --git a/OpenAL32/alFontsound.c b/OpenAL32/alFontsound.c
index 908e88f7..b4ffb89b 100644
--- a/OpenAL32/alFontsound.c
+++ b/OpenAL32/alFontsound.c
@@ -15,13 +15,14 @@
extern inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id);
extern inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id);
+static void ALfontsound_Construct(ALfontsound *self);
+static void ALfontsound_Destruct(ALfontsound *self);
+
AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids)
{
- ALCdevice *device;
ALCcontext *context;
ALsizei cur = 0;
- ALenum err;
context = GetContextRef();
if(!context) return;
@@ -29,31 +30,16 @@ AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids)
if(!(n >= 0))
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- device = context->Device;
for(cur = 0;cur < n;cur++)
{
- ALfontsound *inst = calloc(1, sizeof(ALfontsound));
- if(!inst)
- {
- alDeleteFontsoundsSOFT(cur, ids);
- SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
- }
- ALfontsound_Construct(inst);
-
- err = NewThunkEntry(&inst->id);
- if(err == AL_NO_ERROR)
- err = InsertUIntMapEntry(&device->FontsoundMap, inst->id, inst);
- if(err != AL_NO_ERROR)
+ ALfontsound *sound = NewFontsound(context);
+ if(!sound)
{
- ALfontsound_Destruct(inst);
- memset(inst, 0, sizeof(*inst));
- free(inst);
-
alDeleteFontsoundsSOFT(cur, ids);
- SET_ERROR_AND_GOTO(context, err, done);
+ break;
}
- ids[cur] = inst->id;
+ ids[cur] = sound->id;
}
done:
@@ -653,6 +639,125 @@ done:
}
+ALfontsound *NewFontsound(ALCcontext *context)
+{
+ ALCdevice *device = context->Device;
+ ALfontsound *sound;
+ ALenum err;
+
+ sound = calloc(1, sizeof(*sound));
+ if(!sound)
+ SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL);
+ ALfontsound_Construct(sound);
+
+ err = NewThunkEntry(&sound->id);
+ if(err == AL_NO_ERROR)
+ err = InsertUIntMapEntry(&device->FontsoundMap, sound->id, sound);
+ if(err != AL_NO_ERROR)
+ {
+ ALfontsound_Destruct(sound);
+ memset(sound, 0, sizeof(*sound));
+ free(sound);
+
+ SET_ERROR_AND_RETURN_VALUE(context, err, NULL);
+ }
+
+ return sound;
+}
+
+
+static void ALfontsound_Construct(ALfontsound *self)
+{
+ self->ref = 0;
+
+ self->MinKey = 0;
+ self->MaxKey = 127;
+ self->MinVelocity = 0;
+ self->MaxVelocity = 127;
+
+ self->ModLfoToPitch = 0;
+ self->VibratoLfoToPitch = 0;
+ self->ModEnvToPitch = 0;
+
+ self->FilterCutoff = 13500;
+ self->FilterQ = 0;
+ self->ModLfoToFilterCutoff = 0;
+ self->ModEnvToFilterCutoff = 0;
+ self->ModLfoToVolume = 0;
+
+ self->ChorusSend = 0;
+ self->ReverbSend = 0;
+
+ self->Pan = 0;
+
+ self->ModLfo.Delay = 0;
+ self->ModLfo.Frequency = 0;
+
+ self->VibratoLfo.Delay = 0;
+ self->VibratoLfo.Frequency = 0;
+
+ self->ModEnv.DelayTime = -12000;
+ self->ModEnv.AttackTime = -12000;
+ self->ModEnv.HoldTime = -12000;
+ self->ModEnv.DecayTime = -12000;
+ self->ModEnv.SustainVol = 0;
+ self->ModEnv.ReleaseTime = -12000;
+ self->ModEnv.KeyToHoldTime = 0;
+ self->ModEnv.KeyToDecayTime = 0;
+
+ self->VolEnv.DelayTime = -12000;
+ self->VolEnv.AttackTime = -12000;
+ self->VolEnv.HoldTime = -12000;
+ self->VolEnv.DecayTime = -12000;
+ self->VolEnv.SustainVol = 0;
+ self->VolEnv.ReleaseTime = -12000;
+ self->VolEnv.KeyToHoldTime = 0;
+ self->VolEnv.KeyToDecayTime = 0;
+
+ self->Attenuation = 0;
+
+ self->CoarseTuning = 0;
+ self->FineTuning = 0;
+
+ self->LoopMode = AL_NONE;
+
+ self->TuningScale = 100;
+
+ self->ExclusiveClass = 0;
+
+ self->Start = 0;
+ self->End = 0;
+ self->LoopStart = 0;
+ self->LoopEnd = 0;
+ self->SampleRate = 0;
+ self->PitchKey = 0;
+ self->PitchCorrection = 0;
+ self->SampleType = AL_NONE;
+ self->Link = NULL;
+
+ self->Modulators = NULL;
+ self->NumModulators = 0;
+ self->ModulatorsMax = 0;
+
+ self->id = 0;
+}
+
+static void ALfontsound_Destruct(ALfontsound *self)
+{
+ FreeThunkEntry(self->id);
+ self->id = 0;
+
+ if(self->Link)
+ DecrementRef(&self->Link->ref);
+ self->Link = NULL;
+
+ free(self->Modulators);
+ self->Modulators = NULL;
+ self->NumModulators = 0;
+ self->ModulatorsMax = 0;
+}
+
+
/* ReleaseALFontsounds
*
* Called to destroy any fontsounds that still exist on the device