Rework HRTF decision logic
[openal-soft.git] / OpenAL32 / alMidi.c
blob015b1915b89ca6746aef4765ac9ab33bd7842ea5
2 #include "config.h"
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <limits.h>
9 #include "alMain.h"
10 #include "alMidi.h"
11 #include "alError.h"
12 #include "alThunk.h"
13 #include "evtqueue.h"
14 #include "rwlock.h"
15 #include "alu.h"
17 #include "midi/base.h"
20 MidiSynth *SynthCreate(ALCdevice *device)
22 MidiSynth *synth = NULL;
23 if(!synth) synth = SSynth_create(device);
24 if(!synth) synth = FSynth_create(device);
25 if(!synth) synth = DSynth_create(device);
26 return synth;
30 AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id)
32 alMidiSoundfontvSOFT(1, &id);
35 AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids)
37 ALCdevice *device;
38 ALCcontext *context;
39 MidiSynth *synth;
40 ALenum err;
42 context = GetContextRef();
43 if(!context) return;
45 if(count < 0)
46 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
48 device = context->Device;
49 synth = device->Synth;
51 WriteLock(&synth->Lock);
52 if(synth->State == AL_PLAYING || synth->State == AL_PAUSED)
53 alSetError(context, AL_INVALID_OPERATION);
54 else
56 err = V(synth,selectSoundfonts)(context, count, ids);
57 if(err != AL_NO_ERROR)
58 alSetError(context, err);
60 WriteUnlock(&synth->Lock);
62 done:
63 ALCcontext_DecRef(context);
67 AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2)
69 ALCdevice *device;
70 ALCcontext *context;
71 ALenum err;
73 context = GetContextRef();
74 if(!context) return;
76 if(!(event == AL_NOTEOFF_SOFT || event == AL_NOTEON_SOFT ||
77 event == AL_KEYPRESSURE_SOFT || event == AL_CONTROLLERCHANGE_SOFT ||
78 event == AL_PROGRAMCHANGE_SOFT || event == AL_CHANNELPRESSURE_SOFT ||
79 event == AL_PITCHBEND_SOFT))
80 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
81 if(!(channel >= 0 && channel <= 15))
82 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
83 if(!(param1 >= 0 && param1 <= 127))
84 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
85 if(!(param2 >= 0 && param2 <= 127))
86 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
88 device = context->Device;
89 ALCdevice_Lock(device);
90 err = MidiSynth_insertEvent(device->Synth, time, event|channel, param1, param2);
91 ALCdevice_Unlock(device);
92 if(err != AL_NO_ERROR)
93 alSetError(context, err);
95 done:
96 ALCcontext_DecRef(context);
99 AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size)
101 ALCdevice *device;
102 ALCcontext *context;
103 ALenum err;
105 context = GetContextRef();
106 if(!context) return;
108 if(!data || size < 0)
109 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
111 device = context->Device;
112 ALCdevice_Lock(device);
113 err = MidiSynth_insertSysExEvent(device->Synth, time, data, size);
114 ALCdevice_Unlock(device);
115 if(err != AL_NO_ERROR)
116 alSetError(context, err);
118 done:
119 ALCcontext_DecRef(context);
122 AL_API void AL_APIENTRY alMidiPlaySOFT(void)
124 ALCcontext *context;
125 MidiSynth *synth;
127 context = GetContextRef();
128 if(!context) return;
130 synth = context->Device->Synth;
131 WriteLock(&synth->Lock);
132 MidiSynth_setState(synth, AL_PLAYING);
133 WriteUnlock(&synth->Lock);
135 ALCcontext_DecRef(context);
138 AL_API void AL_APIENTRY alMidiPauseSOFT(void)
140 ALCcontext *context;
141 MidiSynth *synth;
143 context = GetContextRef();
144 if(!context) return;
146 synth = context->Device->Synth;
147 WriteLock(&synth->Lock);
148 MidiSynth_setState(synth, AL_PAUSED);
149 WriteUnlock(&synth->Lock);
151 ALCcontext_DecRef(context);
154 AL_API void AL_APIENTRY alMidiStopSOFT(void)
156 ALCdevice *device;
157 ALCcontext *context;
158 MidiSynth *synth;
160 context = GetContextRef();
161 if(!context) return;
163 device = context->Device;
164 synth = device->Synth;
166 WriteLock(&synth->Lock);
167 MidiSynth_setState(synth, AL_STOPPED);
169 ALCdevice_Lock(device);
170 V0(synth,stop)();
171 ALCdevice_Unlock(device);
172 WriteUnlock(&synth->Lock);
174 ALCcontext_DecRef(context);
177 AL_API void AL_APIENTRY alMidiResetSOFT(void)
179 ALCdevice *device;
180 ALCcontext *context;
181 MidiSynth *synth;
183 context = GetContextRef();
184 if(!context) return;
186 device = context->Device;
187 synth = device->Synth;
189 WriteLock(&synth->Lock);
190 MidiSynth_setState(synth, AL_INITIAL);
192 ALCdevice_Lock(device);
193 V0(synth,reset)();
194 ALCdevice_Unlock(device);
195 WriteUnlock(&synth->Lock);
197 ALCcontext_DecRef(context);
201 AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value)
203 ALCdevice *device;
204 ALCcontext *context;
206 context = GetContextRef();
207 if(!context) return;
209 if(!(value >= 0.0f && isfinite(value)))
210 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
212 device = context->Device;
213 V(device->Synth,setGain)(value);
215 done:
216 ALCcontext_DecRef(context);