diff options
author | Chris Robinson <[email protected]> | 2013-12-18 22:51:53 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-12-18 22:51:53 -0800 |
commit | 8083fb5be7943e6c5ade6c062ae78559c0826472 (patch) | |
tree | 5e39ff595fcead4d272ad8896aef43b94c8adcec /Alc/midi/base.c | |
parent | b9468dc9176861f6ab6f6e358fda71c0d6fecc90 (diff) |
Add a new ALsoundfont object type
Includes a basic hierarchy for presets, instruments, samples, zones,
generators, and modulators.
Diffstat (limited to 'Alc/midi/base.c')
-rw-r--r-- | Alc/midi/base.c | 344 |
1 files changed, 278 insertions, 66 deletions
diff --git a/Alc/midi/base.c b/Alc/midi/base.c index 46c9b3d2..20d7a27c 100644 --- a/Alc/midi/base.c +++ b/Alc/midi/base.c @@ -8,6 +8,7 @@ #include "midi/base.h" +#include "alMidi.h" #include "alMain.h" #include "alError.h" #include "evtqueue.h" @@ -22,6 +23,100 @@ #define SYSEX_EVENT (0xF0) +void InitEvtQueue(EvtQueue *queue) +{ + queue->events = NULL; + queue->maxsize = 0; + queue->size = 0; + queue->pos = 0; +} + +void ResetEvtQueue(EvtQueue *queue) +{ + ALsizei i; + for(i = 0;i < queue->size;i++) + { + if(queue->events[i].event == SYSEX_EVENT) + { + free(queue->events[i].param.sysex.data); + queue->events[i].param.sysex.data = NULL; + } + } + + free(queue->events); + queue->events = NULL; + queue->maxsize = 0; + queue->size = 0; + queue->pos = 0; +} + +ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt) +{ + ALsizei pos; + + if(queue->maxsize == queue->size) + { + if(queue->pos > 0) + { + /* Queue has some stale entries, remove them to make space for more + * events. */ + for(pos = 0;pos < queue->pos;pos++) + { + if(queue->events[pos].event == SYSEX_EVENT) + { + free(queue->events[pos].param.sysex.data); + queue->events[pos].param.sysex.data = NULL; + } + } + memmove(&queue->events[0], &queue->events[queue->pos], + (queue->size-queue->pos)*sizeof(queue->events[0])); + queue->size -= queue->pos; + queue->pos = 0; + } + else + { + /* Queue is full, double the allocated space. */ + void *temp = NULL; + ALsizei newsize; + + newsize = (queue->maxsize ? (queue->maxsize<<1) : 16); + if(newsize > queue->maxsize) + temp = realloc(queue->events, newsize * sizeof(queue->events[0])); + if(!temp) + return AL_OUT_OF_MEMORY; + + queue->events = temp; + queue->maxsize = newsize; + } + } + + pos = queue->pos; + if(queue->size > 0) + { + ALsizei high = queue->size - 1; + while(pos < high) + { + ALsizei mid = pos + (high-pos)/2; + if(queue->events[mid].time < evt->time) + pos = mid + 1; + else + high = mid; + } + while(pos < queue->size && queue->events[pos].time <= evt->time) + pos++; + + if(pos < queue->size) + memmove(&queue->events[pos+1], &queue->events[pos], + (queue->size-pos)*sizeof(queue->events[0])); + } + + queue->events[pos] = *evt; + queue->size++; + + return AL_NO_ERROR; +} + + void MidiSynth_Construct(MidiSynth *self, ALCdevice *device) { InitEvtQueue(&self->EventQueue); @@ -147,95 +242,212 @@ ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte * } -void InitEvtQueue(EvtQueue *queue) +void ALsfzone_Construct(ALsfzone *self) { - queue->events = NULL; - queue->maxsize = 0; - queue->size = 0; - queue->pos = 0; + self->Generators = NULL; + self->NumGenerators = 0; + self->GeneratorsMax = 0; + + self->Modulators = NULL; + self->NumModulators = 0; + self->ModulatorsMax = 0; + + self->Object = NULL; } -void ResetEvtQueue(EvtQueue *queue) +void ALsfzone_Destruct(ALsfzone *self) +{ + self->Object = NULL; + + free(self->Modulators); + self->Modulators = NULL; + self->NumModulators = 0; + self->ModulatorsMax = 0; + + free(self->Generators); + self->Generators = NULL; + self->NumGenerators = 0; + self->GeneratorsMax = 0; +} + +ALenum ALsfzone_addGenerator(ALsfzone *self, ALenum generator, ALint value) { ALsizei i; - for(i = 0;i < queue->size;i++) + for(i = 0;i < self->NumGenerators;i++) { - if(queue->events[i].event == SYSEX_EVENT) + if(self->Generators[i].Generator == generator) { - free(queue->events[i].param.sysex.data); - queue->events[i].param.sysex.data = NULL; + self->Generators[i].Value = value; + return AL_NO_ERROR; } } - free(queue->events); - queue->events = NULL; - queue->maxsize = 0; - queue->size = 0; - queue->pos = 0; + if(self->NumGenerators == self->GeneratorsMax) + { + ALsizei newmax = 0; + ALvoid *temp = NULL; + + newmax = (self->GeneratorsMax ? self->GeneratorsMax<<1 : 1); + if(newmax > self->GeneratorsMax) + temp = realloc(self->Generators, newmax * sizeof(ALsfgenerator)); + if(!temp) return AL_OUT_OF_MEMORY; + + self->Generators = temp; + self->GeneratorsMax = newmax; + } + + self->Generators[self->NumGenerators].Generator = generator; + self->Generators[self->NumGenerators].Value = value; + self->NumGenerators++; + + return AL_NO_ERROR; } -ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt) +ALenum ALsfzone_addModulator(ALsfzone *self, ALenum sourceop, ALenum destop, ALint amount, ALenum amtsourceop, ALenum transop) { - ALsizei pos; - - if(queue->maxsize == queue->size) + ALsizei i; + for(i = 0;i < self->NumModulators;i++) { - if(queue->pos > 0) + if(self->Modulators[i].SourceOp == sourceop && self->Modulators[i].DestOp == destop && + self->Modulators[i].AmountSourceOp == amtsourceop && + self->Modulators[i].TransformOp == transop) { - /* Queue has some stale entries, remove them to make space for more - * events. */ - for(pos = 0;pos < queue->pos;pos++) - { - if(queue->events[pos].event == SYSEX_EVENT) - { - free(queue->events[pos].param.sysex.data); - queue->events[pos].param.sysex.data = NULL; - } - } - memmove(&queue->events[0], &queue->events[queue->pos], - (queue->size-queue->pos)*sizeof(queue->events[0])); - queue->size -= queue->pos; - queue->pos = 0; + self->Modulators[i].Amount = amount; + return AL_NO_ERROR; } - else - { - /* Queue is full, double the allocated space. */ - void *temp = NULL; - ALsizei newsize; + } - newsize = (queue->maxsize ? (queue->maxsize<<1) : 16); - if(newsize > queue->maxsize) - temp = realloc(queue->events, newsize * sizeof(queue->events[0])); - if(!temp) - return AL_OUT_OF_MEMORY; + if(self->NumModulators == self->ModulatorsMax) + { + ALsizei newmax = 0; + ALvoid *temp = NULL; - queue->events = temp; - queue->maxsize = newsize; - } + 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; } - pos = queue->pos; - if(queue->size > 0) + 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; +} + +/* Stores a new object pointer in the zone. Returns the old object pointer. */ +ALvoid *ALsfzone_setRefObject(ALsfzone *self, ALvoid *object) +{ + ALvoid *oldobj = self->Object; + self->Object = object; + return oldobj; +} + + +void ALsfsample_Construct(ALsfsample *self) +{ + self->ref = 0; + + self->id = 0; +} + +void ALsfsample_Destruct(ALsfsample *self) +{ + self->id = 0; +} + + +void ALsfinstrument_Construct(ALsfinstrument *self) +{ + self->ref = 0; + + self->Zones = NULL; + self->NumZones = 0; + + self->id = 0; +} + +void ALsfinstrument_Destruct(ALsfinstrument *self) +{ + ALsizei i; + + self->id = 0; + + for(i = 0;i < self->NumZones;i++) { - ALsizei high = queue->size - 1; - while(pos < high) - { - ALsizei mid = pos + (high-pos)/2; - if(queue->events[mid].time < evt->time) - pos = mid + 1; - else - high = mid; - } - while(pos < queue->size && queue->events[pos].time <= evt->time) - pos++; + if(self->Zones[i].Object) + DecrementRef(&((ALsfsample*)self->Zones[i].Object)->ref); + ALsfzone_Destruct(&self->Zones[i]); + } + free(self->Zones); + self->Zones = NULL; + self->NumZones = 0; +} - if(pos < queue->size) - memmove(&queue->events[pos+1], &queue->events[pos], - (queue->size-pos)*sizeof(queue->events[0])); + +void ALsfpreset_Construct(ALsfpreset *self) +{ + self->ref = 0; + + self->Zones = NULL; + self->NumZones = 0; + + self->id = 0; +} + +void ALsfpreset_Destruct(ALsfpreset *self) +{ + ALsizei i; + + self->id = 0; + + for(i = 0;i < self->NumZones;i++) + { + if(self->Zones[i].Object) + DecrementRef(&((ALsfinstrument*)self->Zones[i].Object)->ref); + ALsfzone_Destruct(&self->Zones[i]); } + free(self->Zones); + self->Zones = NULL; + self->NumZones = 0; +} - queue->events[pos] = *evt; - queue->size++; - return AL_NO_ERROR; +void ALsoundfont_Construct(ALsoundfont *self) +{ + self->ref = 0; + + self->Presets = NULL; + self->NumPresets = 0; + + self->SampleData = NULL; + self->SampleDataLen = 0; + + self->id = 0; +} + +void ALsoundfont_Destruct(ALsoundfont *self) +{ + ALsizei i; + + self->id = 0; + + for(i = 0;i < self->NumPresets;i++) + { + DecrementRef(&self->Presets[i]->ref); + self->Presets[i] = NULL; + } + free(self->Presets); + self->Presets = NULL; + self->NumPresets = 0; + + free(self->SampleData); + self->SampleData = NULL; + self->SampleDataLen = 0; } |