15 #include "midi/base.h"
17 typedef struct DSynth
{
18 DERIVE_FROM_TYPE(MidiSynth
);
21 static void DSynth_Construct(DSynth
*self
, ALCdevice
*device
);
22 static DECLARE_FORWARD(DSynth
, MidiSynth
, void, Destruct
)
23 static DECLARE_FORWARD3(DSynth
, MidiSynth
, ALenum
, selectSoundfonts
, ALCcontext
*, ALsizei
, const ALuint
*)
24 static DECLARE_FORWARD1(DSynth
, MidiSynth
, void, setGain
, ALfloat
)
25 static DECLARE_FORWARD(DSynth
, MidiSynth
, void, stop
)
26 static DECLARE_FORWARD(DSynth
, MidiSynth
, void, reset
)
27 static DECLARE_FORWARD1(DSynth
, MidiSynth
, void, update
, ALCdevice
*)
28 static void DSynth_process(DSynth
*self
, ALuint SamplesToDo
, ALfloat (*restrict DryBuffer
)[BUFFERSIZE
]);
29 DECLARE_DEFAULT_ALLOCATORS(DSynth
)
30 DEFINE_MIDISYNTH_VTABLE(DSynth
);
33 static void DSynth_Construct(DSynth
*self
, ALCdevice
*device
)
35 MidiSynth_Construct(STATIC_CAST(MidiSynth
, self
), device
);
36 SET_VTABLE2(DSynth
, MidiSynth
, self
);
40 static void DSynth_processQueue(DSynth
*self
, ALuint64 time
)
42 EvtQueue
*queue
= &STATIC_CAST(MidiSynth
, self
)->EventQueue
;
44 while(queue
->pos
< queue
->size
&& queue
->events
[queue
->pos
].time
<= time
)
48 static void DSynth_process(DSynth
*self
, ALuint SamplesToDo
, ALfloatBUFFERSIZE
*restrict
UNUSED(DryBuffer
))
50 MidiSynth
*synth
= STATIC_CAST(MidiSynth
, self
);
53 if(synth
->State
!= AL_PLAYING
)
56 synth
->SamplesDone
+= SamplesToDo
;
57 synth
->ClockBase
+= (synth
->SamplesDone
/synth
->SampleRate
) * MIDI_CLOCK_RES
;
58 synth
->SamplesDone
%= synth
->SampleRate
;
60 curtime
= MidiSynth_getTime(synth
);
61 DSynth_processQueue(self
, maxi64(curtime
-1, 0));
65 MidiSynth
*DSynth_create(ALCdevice
*device
)
67 DSynth
*synth
= DSynth_New(sizeof(*synth
));
70 ERR("Failed to allocate DSynth\n");
73 memset(synth
, 0, sizeof(*synth
));
74 DSynth_Construct(synth
, device
);
75 return STATIC_CAST(MidiSynth
, synth
);