base.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include "config.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <limits.h>
  5. #include "midi/base.h"
  6. #include "alMidi.h"
  7. #include "alMain.h"
  8. #include "alError.h"
  9. #include "alThunk.h"
  10. #include "evtqueue.h"
  11. #include "rwlock.h"
  12. #include "alu.h"
  13. /* Microsecond resolution */
  14. #define TICKS_PER_SECOND (1000000)
  15. /* MIDI events */
  16. #define SYSEX_EVENT (0xF0)
  17. void InitEvtQueue(EvtQueue *queue)
  18. {
  19. queue->events = NULL;
  20. queue->maxsize = 0;
  21. queue->size = 0;
  22. queue->pos = 0;
  23. }
  24. void ResetEvtQueue(EvtQueue *queue)
  25. {
  26. ALsizei i;
  27. for(i = 0;i < queue->size;i++)
  28. {
  29. if(queue->events[i].event == SYSEX_EVENT)
  30. {
  31. free(queue->events[i].param.sysex.data);
  32. queue->events[i].param.sysex.data = NULL;
  33. }
  34. }
  35. free(queue->events);
  36. queue->events = NULL;
  37. queue->maxsize = 0;
  38. queue->size = 0;
  39. queue->pos = 0;
  40. }
  41. ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt)
  42. {
  43. ALsizei pos;
  44. if(queue->maxsize == queue->size)
  45. {
  46. if(queue->pos > 0)
  47. {
  48. /* Queue has some stale entries, remove them to make space for more
  49. * events. */
  50. for(pos = 0;pos < queue->pos;pos++)
  51. {
  52. if(queue->events[pos].event == SYSEX_EVENT)
  53. {
  54. free(queue->events[pos].param.sysex.data);
  55. queue->events[pos].param.sysex.data = NULL;
  56. }
  57. }
  58. memmove(&queue->events[0], &queue->events[queue->pos],
  59. (queue->size-queue->pos)*sizeof(queue->events[0]));
  60. queue->size -= queue->pos;
  61. queue->pos = 0;
  62. }
  63. else
  64. {
  65. /* Queue is full, double the allocated space. */
  66. void *temp = NULL;
  67. ALsizei newsize;
  68. newsize = (queue->maxsize ? (queue->maxsize<<1) : 16);
  69. if(newsize > queue->maxsize)
  70. temp = realloc(queue->events, newsize * sizeof(queue->events[0]));
  71. if(!temp)
  72. return AL_OUT_OF_MEMORY;
  73. queue->events = temp;
  74. queue->maxsize = newsize;
  75. }
  76. }
  77. pos = queue->pos;
  78. if(queue->size > 0)
  79. {
  80. ALsizei high = queue->size - 1;
  81. while(pos < high)
  82. {
  83. ALsizei mid = pos + (high-pos)/2;
  84. if(queue->events[mid].time < evt->time)
  85. pos = mid + 1;
  86. else
  87. high = mid;
  88. }
  89. while(pos < queue->size && queue->events[pos].time <= evt->time)
  90. pos++;
  91. if(pos < queue->size)
  92. memmove(&queue->events[pos+1], &queue->events[pos],
  93. (queue->size-pos)*sizeof(queue->events[0]));
  94. }
  95. queue->events[pos] = *evt;
  96. queue->size++;
  97. return AL_NO_ERROR;
  98. }
  99. void MidiSynth_Construct(MidiSynth *self, ALCdevice *device)
  100. {
  101. InitEvtQueue(&self->EventQueue);
  102. RWLockInit(&self->Lock);
  103. self->Soundfonts = NULL;
  104. self->NumSoundfonts = 0;
  105. self->Gain = 1.0f;
  106. self->State = AL_INITIAL;
  107. self->LastEvtTime = 0;
  108. self->NextEvtTime = UINT64_MAX;
  109. self->SamplesSinceLast = 0.0;
  110. self->SamplesToNext = 0.0;
  111. self->SamplesPerTick = (ALdouble)device->Frequency / TICKS_PER_SECOND;
  112. }
  113. void MidiSynth_Destruct(MidiSynth *self)
  114. {
  115. ALsizei i;
  116. for(i = 0;i < self->NumSoundfonts;i++)
  117. DecrementRef(&self->Soundfonts[i]->ref);
  118. free(self->Soundfonts);
  119. self->Soundfonts = NULL;
  120. self->NumSoundfonts = 0;
  121. ResetEvtQueue(&self->EventQueue);
  122. }
  123. ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids)
  124. {
  125. ALCdevice *device = context->Device;
  126. ALsoundfont **sfonts;
  127. ALsizei i;
  128. if(self->State != AL_INITIAL && self->State != AL_STOPPED)
  129. return AL_INVALID_OPERATION;
  130. sfonts = calloc(1, count * sizeof(sfonts[0]));
  131. if(!sfonts) return AL_OUT_OF_MEMORY;
  132. for(i = 0;i < count;i++)
  133. {
  134. if(ids[i] == 0)
  135. sfonts[i] = ALsoundfont_getDefSoundfont(context);
  136. else if(!(sfonts[i]=LookupSfont(device, ids[i])))
  137. {
  138. free(sfonts);
  139. return AL_INVALID_VALUE;
  140. }
  141. }
  142. for(i = 0;i < count;i++)
  143. IncrementRef(&sfonts[i]->ref);
  144. sfonts = ExchangePtr((XchgPtr*)&self->Soundfonts, sfonts);
  145. count = ExchangeInt(&self->NumSoundfonts, count);
  146. for(i = 0;i < count;i++)
  147. DecrementRef(&sfonts[i]->ref);
  148. free(sfonts);
  149. return AL_NO_ERROR;
  150. }
  151. extern inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain);
  152. extern inline ALfloat MidiSynth_getGain(const MidiSynth *self);
  153. extern inline void MidiSynth_setState(MidiSynth *self, ALenum state);
  154. extern inline ALenum MidiSynth_getState(const MidiSynth *self);
  155. void MidiSynth_stop(MidiSynth *self)
  156. {
  157. ResetEvtQueue(&self->EventQueue);
  158. self->LastEvtTime = 0;
  159. self->NextEvtTime = UINT64_MAX;
  160. self->SamplesSinceLast = 0.0;
  161. self->SamplesToNext = 0.0;
  162. }
  163. extern inline void MidiSynth_reset(MidiSynth *self);
  164. ALuint64 MidiSynth_getTime(const MidiSynth *self)
  165. {
  166. ALuint64 time = self->LastEvtTime + (self->SamplesSinceLast/self->SamplesPerTick);
  167. return clampu64(time, self->LastEvtTime, self->NextEvtTime);
  168. }
  169. extern inline ALuint64 MidiSynth_getNextEvtTime(const MidiSynth *self);
  170. void MidiSynth_setSampleRate(MidiSynth *self, ALdouble srate)
  171. {
  172. ALdouble sampletickrate = srate / TICKS_PER_SECOND;
  173. self->SamplesSinceLast = self->SamplesSinceLast * sampletickrate / self->SamplesPerTick;
  174. self->SamplesToNext = self->SamplesToNext * sampletickrate / self->SamplesPerTick;
  175. self->SamplesPerTick = sampletickrate;
  176. }
  177. extern inline void MidiSynth_update(MidiSynth *self, ALCdevice *device);
  178. ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2)
  179. {
  180. MidiEvent entry;
  181. ALenum err;
  182. entry.time = time;
  183. entry.event = event;
  184. entry.param.val[0] = param1;
  185. entry.param.val[1] = param2;
  186. err = InsertEvtQueue(&self->EventQueue, &entry);
  187. if(err != AL_NO_ERROR) return err;
  188. if(entry.time < self->NextEvtTime)
  189. {
  190. self->NextEvtTime = entry.time;
  191. self->SamplesToNext = (self->NextEvtTime - self->LastEvtTime) * self->SamplesPerTick;
  192. self->SamplesToNext -= self->SamplesSinceLast;
  193. }
  194. return AL_NO_ERROR;
  195. }
  196. ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *data, ALsizei size)
  197. {
  198. MidiEvent entry;
  199. ALenum err;
  200. entry.time = time;
  201. entry.event = SYSEX_EVENT;
  202. entry.param.sysex.size = size;
  203. entry.param.sysex.data = malloc(size);
  204. if(!entry.param.sysex.data)
  205. return AL_OUT_OF_MEMORY;
  206. memcpy(entry.param.sysex.data, data, size);
  207. err = InsertEvtQueue(&self->EventQueue, &entry);
  208. if(err != AL_NO_ERROR)
  209. {
  210. free(entry.param.sysex.data);
  211. return err;
  212. }
  213. if(entry.time < self->NextEvtTime)
  214. {
  215. self->NextEvtTime = entry.time;
  216. self->SamplesToNext = (self->NextEvtTime - self->LastEvtTime) * self->SamplesPerTick;
  217. self->SamplesToNext -= self->SamplesSinceLast;
  218. }
  219. return AL_NO_ERROR;
  220. }