Move atomic method definitions to a separate common source
[openal-soft.git] / OpenAL32 / alMidi.c
blob6313523ef045dca5839cb21936e46cd913291846
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;
104 ALsizei i;
106 context = GetContextRef();
107 if(!context) return;
109 if(!data || size < 0)
110 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
111 for(i = 0;i < size;i++)
113 if((data[i]&0x80))
114 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
117 device = context->Device;
118 ALCdevice_Lock(device);
119 err = MidiSynth_insertSysExEvent(device->Synth, time, data, size);
120 ALCdevice_Unlock(device);
121 if(err != AL_NO_ERROR)
122 alSetError(context, err);
124 done:
125 ALCcontext_DecRef(context);
128 AL_API void AL_APIENTRY alMidiPlaySOFT(void)
130 ALCcontext *context;
131 MidiSynth *synth;
133 context = GetContextRef();
134 if(!context) return;
136 synth = context->Device->Synth;
137 WriteLock(&synth->Lock);
138 MidiSynth_setState(synth, AL_PLAYING);
139 WriteUnlock(&synth->Lock);
141 ALCcontext_DecRef(context);
144 AL_API void AL_APIENTRY alMidiPauseSOFT(void)
146 ALCcontext *context;
147 MidiSynth *synth;
149 context = GetContextRef();
150 if(!context) return;
152 synth = context->Device->Synth;
153 WriteLock(&synth->Lock);
154 MidiSynth_setState(synth, AL_PAUSED);
155 WriteUnlock(&synth->Lock);
157 ALCcontext_DecRef(context);
160 AL_API void AL_APIENTRY alMidiStopSOFT(void)
162 ALCdevice *device;
163 ALCcontext *context;
164 MidiSynth *synth;
166 context = GetContextRef();
167 if(!context) return;
169 device = context->Device;
170 synth = device->Synth;
172 WriteLock(&synth->Lock);
173 MidiSynth_setState(synth, AL_STOPPED);
175 ALCdevice_Lock(device);
176 V0(synth,stop)();
177 ALCdevice_Unlock(device);
178 WriteUnlock(&synth->Lock);
180 ALCcontext_DecRef(context);
183 AL_API void AL_APIENTRY alMidiResetSOFT(void)
185 ALCdevice *device;
186 ALCcontext *context;
187 MidiSynth *synth;
189 context = GetContextRef();
190 if(!context) return;
192 device = context->Device;
193 synth = device->Synth;
195 WriteLock(&synth->Lock);
196 MidiSynth_setState(synth, AL_INITIAL);
198 ALCdevice_Lock(device);
199 V0(synth,reset)();
200 ALCdevice_Unlock(device);
201 WriteUnlock(&synth->Lock);
203 ALCcontext_DecRef(context);
207 AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value)
209 ALCdevice *device;
210 ALCcontext *context;
212 context = GetContextRef();
213 if(!context) return;
215 if(!(value >= 0.0f && isfinite(value)))
216 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
218 device = context->Device;
219 V(device->Synth,setGain)(value);
221 done:
222 ALCcontext_DecRef(context);