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 /OpenAL32 | |
parent | b9468dc9176861f6ab6f6e358fda71c0d6fecc90 (diff) |
Add a new ALsoundfont object type
Includes a basic hierarchy for presets, instruments, samples, zones,
generators, and modulators.
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alMain.h | 7 | ||||
-rw-r--r-- | OpenAL32/Include/alMidi.h | 105 | ||||
-rw-r--r-- | OpenAL32/alMidi.c | 93 |
3 files changed, 205 insertions, 0 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 64ab1174..37cab1c4 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -38,6 +38,8 @@ #define AL_PROGRAMCHANGE_SOFT 0x00C0 #define AL_CHANNELPRESSURE_SOFT 0x00D0 #define AL_PITCHBEND_SOFT 0x00E0 +typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids); +typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids); typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(const char *filename); typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(const char *filename); typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); @@ -50,6 +52,8 @@ typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value); typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname); typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values); #ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids); +AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids); AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(const char *filename); AL_API void AL_APIENTRY alMidiSoundfontSOFT(const char *filename); AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); @@ -424,6 +428,9 @@ struct ALCdevice_struct // Map of Filters for this device UIntMap FilterMap; + // Map of Soundfonts for this device + UIntMap SfontMap; + /* MIDI synth engine */ struct MidiSynth *Synth; diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h index e03cad13..46dcaad5 100644 --- a/OpenAL32/Include/alMidi.h +++ b/OpenAL32/Include/alMidi.h @@ -8,6 +8,111 @@ extern "C" { #endif +typedef struct ALsfgenerator { + ALenum Generator; + ALint Value; +} ALsfgenerator; + +typedef struct ALsfmodulator { + ALenum SourceOp; + ALenum DestOp; + ALint Amount; + ALenum AmountSourceOp; + ALenum TransformOp; +} ALsfmodulator; + +typedef struct ALsfzone { + ALsfgenerator *Generators; + ALsizei NumGenerators; + ALsizei GeneratorsMax; + + ALsfmodulator *Modulators; + ALsizei NumModulators; + ALsizei ModulatorsMax; + + /* NOTE: Preset zones may have a reference to an ALsfinstrument. Instrument + * zones may have a reference to an ALsfsample. */ + ALvoid *Object; +} ALsfzone; + +void ALsfzone_Construct(ALsfzone *self); +void ALsfzone_Destruct(ALsfzone *self); +ALenum ALsfzone_addGenerator(ALsfzone *self, ALenum generator, ALint value); +ALenum ALsfzone_addModulator(ALsfzone *self, ALenum sourceop, ALenum destop, ALint amount, ALenum amtsourceop, ALenum transop); +/* Stores a new object pointer in the zone. Returns the old object pointer. */ +ALvoid *ALsfzone_setRefObject(ALsfzone *self, ALvoid *object); + + +typedef struct ALsfsample { + volatile RefCount ref; + + ALuint Start; + ALuint End; + ALuint LoopStart; + ALuint LoopEnd; + ALuint SampleRate; + ALubyte PitchKey; + ALbyte PitchCorrection; + ALushort SampleLink; + ALenum SampleType; + + ALuint id; +} ALsfsample; + +void ALsfsample_Construct(ALsfsample *self); +void ALsfsample_Destruct(ALsfsample *self); + + +typedef struct ALsfinstrument { + volatile RefCount ref; + + ALsfzone *Zones; + ALsizei NumZones; + + ALuint id; +} ALsfinstrument; + +void ALsfinstrument_Construct(ALsfinstrument *self); +void ALsfinstrument_Destruct(ALsfinstrument *self); + + +typedef struct ALsfpreset { + volatile RefCount ref; + + ALint Program; + ALint Bank; + + ALsfzone *Zones; + ALsizei NumZones; + + ALuint id; +} ALsfpreset; + +void ALsfpreset_Construct(ALsfpreset *self); +void ALsfpreset_Destruct(ALsfpreset *self); + + +typedef struct ALsoundfont { + volatile RefCount ref; + + ALsfpreset **Presets; + ALsizei NumPresets; + + ALshort *SampleData; + ALint SampleDataLen; + + ALuint id; +} ALsoundfont; + +void ALsoundfont_Construct(ALsoundfont *self); +void ALsoundfont_Destruct(ALsoundfont *self); + +inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id) +{ return (struct ALsoundfont*)LookupUIntMapKey(&device->SfontMap, id); } +inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id) +{ return (struct ALsoundfont*)RemoveUIntMapKey(&device->SfontMap, id); } + + #ifdef __cplusplus } #endif diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index d1231fa7..74e37267 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -7,7 +7,9 @@ #include <limits.h> #include "alMain.h" +#include "alMidi.h" #include "alError.h" +#include "alThunk.h" #include "evtqueue.h" #include "rwlock.h" #include "alu.h" @@ -23,6 +25,97 @@ MidiSynth *SynthCreate(ALCdevice *device) } +extern inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id); +extern inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id); + + +AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(cur = 0;cur < n;cur++) + { + ALsoundfont *sfont = calloc(1, sizeof(ALsoundfont)); + if(!sfont) + { + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + ALsoundfont_Construct(sfont); + + err = NewThunkEntry(&sfont->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->SfontMap, sfont->id, sfont); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(sfont->id); + memset(sfont, 0, sizeof(ALsoundfont)); + free(sfont); + + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, err, done); + } + + ids[cur] = sfont->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + if(!ids[i]) + continue; + + /* Check for valid soundfont ID */ + if((sfont=LookupSfont(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sfont->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if((sfont=RemoveSfont(device, ids[i])) == NULL) + continue; + FreeThunkEntry(sfont->id); + + ALsoundfont_Destruct(sfont); + + memset(sfont, 0, sizeof(*sfont)); + free(sfont); + } + +done: + ALCcontext_DecRef(context); +} + + AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(const char *filename) { ALCdevice *device; |