| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #include "config.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include "alMain.h"
- #include "alMidi.h"
- #include "alError.h"
- #include "alThunk.h"
- #include "evtqueue.h"
- #include "rwlock.h"
- #include "alu.h"
- #include "midi/base.h"
- MidiSynth *SynthCreate(ALCdevice *device)
- {
- MidiSynth *synth = FSynth_create(device);
- if(!synth) synth = DSynth_create(device);
- return synth;
- }
- AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id)
- {
- alMidiSoundfontvSOFT(1, &id);
- }
- AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids)
- {
- ALCdevice *device;
- ALCcontext *context;
- MidiSynth *synth;
- ALenum err;
- context = GetContextRef();
- if(!context) return;
- if(count < 0)
- SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- device = context->Device;
- synth = device->Synth;
- WriteLock(&synth->Lock);
- if(synth->State == AL_PLAYING || synth->State == AL_PAUSED)
- alSetError(context, AL_INVALID_OPERATION);
- else
- {
- err = V(synth,selectSoundfonts)(context, count, ids);
- if(err != AL_NO_ERROR)
- alSetError(context, err);
- }
- WriteUnlock(&synth->Lock);
- done:
- ALCcontext_DecRef(context);
- }
- AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2)
- {
- ALCdevice *device;
- ALCcontext *context;
- ALenum err;
- context = GetContextRef();
- if(!context) return;
- if(!(event == AL_NOTEOFF_SOFT || event == AL_NOTEON_SOFT ||
- event == AL_KEYPRESSURE_SOFT || event == AL_CONTROLLERCHANGE_SOFT ||
- event == AL_PROGRAMCHANGE_SOFT || event == AL_CHANNELPRESSURE_SOFT ||
- event == AL_PITCHBEND_SOFT))
- SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
- if(!(channel >= 0 && channel <= 15))
- SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- if(!(param1 >= 0 && param1 <= 127))
- SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- if(!(param2 >= 0 && param2 <= 127))
- SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- device = context->Device;
- ALCdevice_Lock(device);
- err = MidiSynth_insertEvent(device->Synth, time, event|channel, param1, param2);
- ALCdevice_Unlock(device);
- if(err != AL_NO_ERROR)
- alSetError(context, err);
- done:
- ALCcontext_DecRef(context);
- }
- AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size)
- {
- ALCdevice *device;
- ALCcontext *context;
- ALenum err;
- ALsizei i;
- context = GetContextRef();
- if(!context) return;
- if(!data || size < 0)
- SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- for(i = 0;i < size;i++)
- {
- if((data[i]&0x80))
- SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- }
- device = context->Device;
- ALCdevice_Lock(device);
- err = MidiSynth_insertSysExEvent(device->Synth, time, data, size);
- ALCdevice_Unlock(device);
- if(err != AL_NO_ERROR)
- alSetError(context, err);
- done:
- ALCcontext_DecRef(context);
- }
- AL_API void AL_APIENTRY alMidiPlaySOFT(void)
- {
- ALCcontext *context;
- MidiSynth *synth;
- context = GetContextRef();
- if(!context) return;
- synth = context->Device->Synth;
- WriteLock(&synth->Lock);
- V(synth,setState)(AL_PLAYING);
- WriteUnlock(&synth->Lock);
- ALCcontext_DecRef(context);
- }
- AL_API void AL_APIENTRY alMidiPauseSOFT(void)
- {
- ALCcontext *context;
- MidiSynth *synth;
- context = GetContextRef();
- if(!context) return;
- synth = context->Device->Synth;
- WriteLock(&synth->Lock);
- V(synth,setState)(AL_PAUSED);
- WriteUnlock(&synth->Lock);
- ALCcontext_DecRef(context);
- }
- AL_API void AL_APIENTRY alMidiStopSOFT(void)
- {
- ALCdevice *device;
- ALCcontext *context;
- MidiSynth *synth;
- context = GetContextRef();
- if(!context) return;
- device = context->Device;
- synth = device->Synth;
- WriteLock(&synth->Lock);
- V(synth,setState)(AL_STOPPED);
- ALCdevice_Lock(device);
- V0(synth,stop)();
- ALCdevice_Unlock(device);
- WriteUnlock(&synth->Lock);
- ALCcontext_DecRef(context);
- }
- AL_API void AL_APIENTRY alMidiResetSOFT(void)
- {
- ALCdevice *device;
- ALCcontext *context;
- MidiSynth *synth;
- context = GetContextRef();
- if(!context) return;
- device = context->Device;
- synth = device->Synth;
- WriteLock(&synth->Lock);
- V(synth,setState)(AL_INITIAL);
- ALCdevice_Lock(device);
- V0(synth,reset)();
- ALCdevice_Unlock(device);
- WriteUnlock(&synth->Lock);
- ALCcontext_DecRef(context);
- }
- AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value)
- {
- ALCdevice *device;
- ALCcontext *context;
- context = GetContextRef();
- if(!context) return;
- if(!(value >= 0.0f && isfinite(value)))
- SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- device = context->Device;
- V(device->Synth,setGain)(value);
- done:
- ALCcontext_DecRef(context);
- }
|