base.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #ifndef AL_MIDI_BASE_H
  2. #define AL_MIDI_BASE_H
  3. #include "alMain.h"
  4. #include "atomic.h"
  5. #include "evtqueue.h"
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. struct ALsoundfont;
  10. typedef size_t (*ReaderCb)(void *ptr, size_t size, void *stream);
  11. typedef struct Reader {
  12. ReaderCb cb;
  13. void *ptr;
  14. int error;
  15. } Reader;
  16. #define READ(x_, buf_, len_) ((x_)->cb((buf_), (len_), (x_)->ptr))
  17. #define READERR(x_) ((x_)->error)
  18. ALboolean loadSf2(Reader *stream, struct ALsoundfont *sfont, ALCcontext *context);
  19. struct MidiSynthVtable;
  20. typedef struct MidiSynth {
  21. EvtQueue EventQueue;
  22. ALuint64 LastEvtTime;
  23. ALuint64 NextEvtTime;
  24. ALdouble SamplesSinceLast;
  25. ALdouble SamplesToNext;
  26. ALdouble SamplesPerTick;
  27. /* NOTE: This rwlock is for the state and soundfont. The EventQueue and
  28. * related must instead use the device lock as they're used in the mixer
  29. * thread.
  30. */
  31. RWLock Lock;
  32. struct ALsoundfont **Soundfonts;
  33. ALsizei NumSoundfonts;
  34. volatile ALfloat Gain;
  35. volatile ALenum State;
  36. const struct MidiSynthVtable *vtbl;
  37. } MidiSynth;
  38. void MidiSynth_Construct(MidiSynth *self, ALCdevice *device);
  39. void MidiSynth_Destruct(MidiSynth *self);
  40. ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids);
  41. inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain) { self->Gain = gain; }
  42. inline ALfloat MidiSynth_getGain(const MidiSynth *self) { return self->Gain; }
  43. inline void MidiSynth_setState(MidiSynth *self, ALenum state) { ExchangeInt(&self->State, state); }
  44. inline ALenum MidiSynth_getState(const MidiSynth *self) { return self->State; }
  45. void MidiSynth_stop(MidiSynth *self);
  46. inline void MidiSynth_reset(MidiSynth *self) { MidiSynth_stop(self); }
  47. ALuint64 MidiSynth_getTime(const MidiSynth *self);
  48. inline ALuint64 MidiSynth_getNextEvtTime(const MidiSynth *self)
  49. {
  50. if(self->EventQueue.pos == self->EventQueue.size)
  51. return UINT64_MAX;
  52. return self->EventQueue.events[self->EventQueue.pos].time;
  53. }
  54. void MidiSynth_setSampleRate(MidiSynth *self, ALdouble srate);
  55. inline void MidiSynth_update(MidiSynth *self, ALCdevice *device)
  56. { MidiSynth_setSampleRate(self, device->Frequency); }
  57. ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2);
  58. ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *data, ALsizei size);
  59. struct MidiSynthVtable {
  60. void (*const Destruct)(MidiSynth *self);
  61. ALenum (*const selectSoundfonts)(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids);
  62. void (*const setGain)(MidiSynth *self, ALfloat gain);
  63. void (*const setState)(MidiSynth *self, ALenum state);
  64. void (*const stop)(MidiSynth *self);
  65. void (*const reset)(MidiSynth *self);
  66. void (*const update)(MidiSynth *self, ALCdevice *device);
  67. void (*const process)(MidiSynth *self, ALuint samples, ALfloat (*restrict DryBuffer)[BUFFERSIZE]);
  68. void (*const Delete)(MidiSynth *self);
  69. };
  70. #define DEFINE_MIDISYNTH_VTABLE(T) \
  71. DECLARE_THUNK(T, MidiSynth, void, Destruct) \
  72. DECLARE_THUNK3(T, MidiSynth, ALenum, selectSoundfonts, ALCcontext*, ALsizei, const ALuint*) \
  73. DECLARE_THUNK1(T, MidiSynth, void, setGain, ALfloat) \
  74. DECLARE_THUNK1(T, MidiSynth, void, setState, ALenum) \
  75. DECLARE_THUNK(T, MidiSynth, void, stop) \
  76. DECLARE_THUNK(T, MidiSynth, void, reset) \
  77. DECLARE_THUNK1(T, MidiSynth, void, update, ALCdevice*) \
  78. DECLARE_THUNK2(T, MidiSynth, void, process, ALuint, ALfloatBUFFERSIZE*restrict) \
  79. DECLARE_THUNK(T, MidiSynth, void, Delete) \
  80. \
  81. static const struct MidiSynthVtable T##_MidiSynth_vtable = { \
  82. T##_MidiSynth_Destruct, \
  83. \
  84. T##_MidiSynth_selectSoundfonts, \
  85. T##_MidiSynth_setGain, \
  86. T##_MidiSynth_setState, \
  87. T##_MidiSynth_stop, \
  88. T##_MidiSynth_reset, \
  89. T##_MidiSynth_update, \
  90. T##_MidiSynth_process, \
  91. \
  92. T##_MidiSynth_Delete, \
  93. }
  94. MidiSynth *FSynth_create(ALCdevice *device);
  95. MidiSynth *DSynth_create(ALCdevice *device);
  96. MidiSynth *SynthCreate(ALCdevice *device);
  97. #ifdef __cplusplus
  98. }
  99. #endif
  100. #endif /* AL_MIDI_BASE_H */