1 /*
2 * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
3 *
4 * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
5 * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
6 *
7 * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
8 * http://iki.fi/bisqwit/source/adlmidi.html
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "adlmidi_private.hpp"
25
26 #ifdef ADLMIDI_HW_OPL
27 #define MaxChips 1
28 #define MaxChips_STR "1" //Why not just "#MaxCards" ? Watcom fails to pass this with "syntax error" :-P
29 #else
30 #define MaxChips 100
31 #define MaxChips_STR "100"
32 #endif
33
34 /* Unify MIDI player casting and interface between ADLMIDI and OPNMIDI */
35 #define GET_MIDI_PLAYER(device) reinterpret_cast<MIDIplay *>((device)->adl_midiPlayer)
36 typedef MIDIplay MidiPlayer;
37
38 static ADL_Version adl_version = {
39 ADLMIDI_VERSION_MAJOR,
40 ADLMIDI_VERSION_MINOR,
41 ADLMIDI_VERSION_PATCHLEVEL
42 };
43
44 static const ADLMIDI_AudioFormat adl_DefaultAudioFormat =
45 {
46 ADLMIDI_SampleType_S16,
47 sizeof(int16_t),
48 2 * sizeof(int16_t),
49 };
50
51 /*---------------------------EXPORTS---------------------------*/
52
adl_init(long sample_rate)53 ADLMIDI_EXPORT struct ADL_MIDIPlayer *adl_init(long sample_rate)
54 {
55 ADL_MIDIPlayer *midi_device;
56 midi_device = (ADL_MIDIPlayer *)malloc(sizeof(ADL_MIDIPlayer));
57 if(!midi_device)
58 {
59 ADLMIDI_ErrorString = "Can't initialize ADLMIDI: out of memory!";
60 return NULL;
61 }
62
63 MIDIplay *player = new MIDIplay(static_cast<unsigned long>(sample_rate));
64 if(!player)
65 {
66 free(midi_device);
67 ADLMIDI_ErrorString = "Can't initialize ADLMIDI: out of memory!";
68 return NULL;
69 }
70 midi_device->adl_midiPlayer = player;
71 adlRefreshNumCards(midi_device);
72 return midi_device;
73 }
74
adl_close(struct ADL_MIDIPlayer * device)75 ADLMIDI_EXPORT void adl_close(struct ADL_MIDIPlayer *device)
76 {
77 if(!device)
78 return;
79 MIDIplay * play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
80 if(play)
81 delete play;
82 device->adl_midiPlayer = NULL;
83 free(device);
84 device = NULL;
85 }
86
adl_setCallback(ADL_MIDIPlayer * device,void (* AdlMidiCallback)(void))87 ADLMIDI_EXPORT void adl_setCallback(ADL_MIDIPlayer *device, void (*AdlMidiCallback)(void)) {
88 MidiPlayer *play = GET_MIDI_PLAYER(device);
89 if(play) {
90 MidiSequencer &seq = play->m_sequencer;
91 seq.MidiCallback = AdlMidiCallback;
92 }
93 }
94
adl_setDeviceIdentifier(ADL_MIDIPlayer * device,unsigned id)95 ADLMIDI_EXPORT int adl_setDeviceIdentifier(ADL_MIDIPlayer *device, unsigned id)
96 {
97 if(!device || id > 0x0f)
98 return -1;
99 MidiPlayer *play = GET_MIDI_PLAYER(device);
100 if(!play)
101 return -1;
102 play->setDeviceId(static_cast<uint8_t>(id));
103 return 0;
104 }
105
adl_setNumChips(ADL_MIDIPlayer * device,int numChips)106 ADLMIDI_EXPORT int adl_setNumChips(ADL_MIDIPlayer *device, int numChips)
107 {
108 if(device == NULL)
109 return -2;
110
111 MidiPlayer *play = GET_MIDI_PLAYER(device);
112 #ifdef ADLMIDI_HW_OPL
113 ADL_UNUSED(numChips);
114 play->m_setup.numChips = 1;
115 #else
116 play->m_setup.numChips = static_cast<unsigned int>(numChips);
117 #endif
118 if(play->m_setup.numChips < 1 || play->m_setup.numChips > MaxChips)
119 {
120 play->setErrorString("number of chips may only be 1.." MaxChips_STR ".\n");
121 return -1;
122 }
123
124 play->m_synth.m_numChips = play->m_setup.numChips;
125 adl_reset(device);
126
127 return adlRefreshNumCards(device);
128 }
129
adl_getNumChips(struct ADL_MIDIPlayer * device)130 ADLMIDI_EXPORT int adl_getNumChips(struct ADL_MIDIPlayer *device)
131 {
132 if(device == NULL)
133 return -2;
134 MidiPlayer *play = GET_MIDI_PLAYER(device);
135 if(play)
136 return (int)play->m_setup.numChips;
137 return -2;
138 }
139
adl_setBank(ADL_MIDIPlayer * device,int bank)140 ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank)
141 {
142 #ifdef DISABLE_EMBEDDED_BANKS
143 ADL_UNUSED(bank);
144 MidiPlayer *play = GET_MIDI_PLAYER(device);
145 play->setErrorString("This build of libADLMIDI has no embedded banks. "
146 "Please load banks by using adl_openBankFile() or "
147 "adl_openBankData() functions instead of adl_setBank().");
148 return -1;
149 #else
150 const uint32_t NumBanks = static_cast<uint32_t>(maxAdlBanks());
151 int32_t bankno = bank;
152
153 if(bankno < 0)
154 bankno = 0;
155
156 MidiPlayer *play = GET_MIDI_PLAYER(device);
157 if(static_cast<uint32_t>(bankno) >= NumBanks)
158 {
159 char errBuf[150];
160 snprintf(errBuf, 150, "Embedded bank number may only be 0..%u!\n", static_cast<unsigned int>(NumBanks - 1));
161 play->setErrorString(errBuf);
162 return -1;
163 }
164
165 play->m_setup.bankId = static_cast<uint32_t>(bankno);
166 play->m_synth.setEmbeddedBank(play->m_setup.bankId);
167 play->applySetup();
168
169 return adlRefreshNumCards(device);
170 #endif
171 }
172
adl_getBanksCount()173 ADLMIDI_EXPORT int adl_getBanksCount()
174 {
175 #ifndef DISABLE_EMBEDDED_BANKS
176 return maxAdlBanks();
177 #else
178 return 0;
179 #endif
180 }
181
adl_getBankNames()182 ADLMIDI_EXPORT const char *const *adl_getBankNames()
183 {
184 #ifndef DISABLE_EMBEDDED_BANKS
185 return banknames;
186 #else
187 return NULL;
188 #endif
189 }
190
adl_reserveBanks(ADL_MIDIPlayer * device,unsigned banks)191 ADLMIDI_EXPORT int adl_reserveBanks(ADL_MIDIPlayer *device, unsigned banks)
192 {
193 if(!device)
194 return -1;
195 MidiPlayer *play = GET_MIDI_PLAYER(device);
196 OPL3::BankMap &map = play->m_synth.m_insBanks;
197 map.reserve(banks);
198 return (int)map.capacity();
199 }
200
adl_getBank(ADL_MIDIPlayer * device,const ADL_BankId * idp,int flags,ADL_Bank * bank)201 ADLMIDI_EXPORT int adl_getBank(ADL_MIDIPlayer *device, const ADL_BankId *idp, int flags, ADL_Bank *bank)
202 {
203 if(!device || !idp || !bank)
204 return -1;
205
206 ADL_BankId id = *idp;
207 if(id.lsb > 127 || id.msb > 127 || id.percussive > 1)
208 return -1;
209 size_t idnumber = ((id.msb << 8) | id.lsb | (id.percussive ? size_t(OPL3::PercussionTag) : 0));
210
211 MidiPlayer *play = GET_MIDI_PLAYER(device);
212 OPL3::BankMap &map = play->m_synth.m_insBanks;
213
214 OPL3::BankMap::iterator it;
215 if(!(flags & ADLMIDI_Bank_Create))
216 {
217 it = map.find(idnumber);
218 if(it == map.end())
219 return -1;
220 }
221 else
222 {
223 std::pair<size_t, OPL3::Bank> value;
224 value.first = idnumber;
225 memset(&value.second, 0, sizeof(value.second));
226 for (unsigned i = 0; i < 128; ++i)
227 value.second.ins[i].flags = adlinsdata::Flag_NoSound;
228
229 std::pair<OPL3::BankMap::iterator, bool> ir;
230 if(flags & ADLMIDI_Bank_CreateRt)
231 {
232 ir = map.insert(value, OPL3::BankMap::do_not_expand_t());
233 if(ir.first == map.end())
234 return -1;
235 }
236 else
237 ir = map.insert(value);
238 it = ir.first;
239 }
240
241 it.to_ptrs(bank->pointer);
242 return 0;
243 }
244
adl_getBankId(ADL_MIDIPlayer * device,const ADL_Bank * bank,ADL_BankId * id)245 ADLMIDI_EXPORT int adl_getBankId(ADL_MIDIPlayer *device, const ADL_Bank *bank, ADL_BankId *id)
246 {
247 if(!device || !bank)
248 return -1;
249
250 OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
251 OPL3::BankMap::key_type idnumber = it->first;
252 id->msb = (idnumber >> 8) & 127;
253 id->lsb = idnumber & 127;
254 id->percussive = (idnumber & OPL3::PercussionTag) ? 1 : 0;
255 return 0;
256 }
257
adl_removeBank(ADL_MIDIPlayer * device,ADL_Bank * bank)258 ADLMIDI_EXPORT int adl_removeBank(ADL_MIDIPlayer *device, ADL_Bank *bank)
259 {
260 if(!device || !bank)
261 return -1;
262
263 MidiPlayer *play = GET_MIDI_PLAYER(device);
264 OPL3::BankMap &map = play->m_synth.m_insBanks;
265 OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
266 size_t size = map.size();
267 map.erase(it);
268 return (map.size() != size) ? 0 : -1;
269 }
270
adl_getFirstBank(ADL_MIDIPlayer * device,ADL_Bank * bank)271 ADLMIDI_EXPORT int adl_getFirstBank(ADL_MIDIPlayer *device, ADL_Bank *bank)
272 {
273 if(!device)
274 return -1;
275
276 MidiPlayer *play = GET_MIDI_PLAYER(device);
277 OPL3::BankMap &map = play->m_synth.m_insBanks;
278
279 OPL3::BankMap::iterator it = map.begin();
280 if(it == map.end())
281 return -1;
282
283 it.to_ptrs(bank->pointer);
284 return 0;
285 }
286
adl_getNextBank(ADL_MIDIPlayer * device,ADL_Bank * bank)287 ADLMIDI_EXPORT int adl_getNextBank(ADL_MIDIPlayer *device, ADL_Bank *bank)
288 {
289 if(!device)
290 return -1;
291
292 MidiPlayer *play = GET_MIDI_PLAYER(device);
293 OPL3::BankMap &map = play->m_synth.m_insBanks;
294
295 OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
296 if(++it == map.end())
297 return -1;
298
299 it.to_ptrs(bank->pointer);
300 return 0;
301 }
302
adl_getInstrument(ADL_MIDIPlayer * device,const ADL_Bank * bank,unsigned index,ADL_Instrument * ins)303 ADLMIDI_EXPORT int adl_getInstrument(ADL_MIDIPlayer *device, const ADL_Bank *bank, unsigned index, ADL_Instrument *ins)
304 {
305 if(!device || !bank || index > 127 || !ins)
306 return 1;
307
308 OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
309 cvt_FMIns_to_ADLI(*ins, it->second.ins[index]);
310 ins->version = 0;
311 return 0;
312 }
313
adl_setInstrument(ADL_MIDIPlayer * device,ADL_Bank * bank,unsigned index,const ADL_Instrument * ins)314 ADLMIDI_EXPORT int adl_setInstrument(ADL_MIDIPlayer *device, ADL_Bank *bank, unsigned index, const ADL_Instrument *ins)
315 {
316 if(!device || !bank || index > 127 || !ins)
317 return 1;
318
319 if(ins->version != 0)
320 return 1;
321
322 OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
323 cvt_ADLI_to_FMIns(it->second.ins[index], *ins);
324 return 0;
325 }
326
adl_loadEmbeddedBank(struct ADL_MIDIPlayer * device,ADL_Bank * bank,int num)327 ADLMIDI_EXPORT int adl_loadEmbeddedBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank, int num)
328 {
329 if(!device)
330 return -1;
331 MidiPlayer *play = GET_MIDI_PLAYER(device);
332 if (!play)
333 return -1;
334
335 #ifdef DISABLE_EMBEDDED_BANKS
336 ADL_UNUSED(bank);
337 ADL_UNUSED(num);
338 play->setErrorString("This build of libADLMIDI has no embedded banks. "
339 "Please load banks by using adl_openBankFile() or "
340 "adl_openBankData() functions instead of adl_loadEmbeddedBank().");
341 return -1;
342 #else
343 if(num < 0 || num >= maxAdlBanks())
344 return -1;
345
346 OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
347 size_t id = it->first;
348
349 for (unsigned i = 0; i < 128; ++i) {
350 size_t insno = i + ((id & OPL3::PercussionTag) ? 128 : 0);
351 size_t adlmeta = ::banks[num][insno];
352 it->second.ins[i] = adlinsdata2(::adlins[adlmeta]);
353 }
354 return 0;
355 #endif
356 }
357
adl_setNumFourOpsChn(ADL_MIDIPlayer * device,int ops4)358 ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4)
359 {
360 if(!device)
361 return -1;
362 MidiPlayer *play = GET_MIDI_PLAYER(device);
363 if((unsigned int)ops4 > 6 * play->m_setup.numChips)
364 {
365 char errBuff[250];
366 snprintf(errBuff, 250, "number of four-op channels may only be 0..%u when %u OPL3 cards are used.\n", (6 * (play->m_setup.numChips)), play->m_setup.numChips);
367 play->setErrorString(errBuff);
368 return -1;
369 }
370
371 play->m_setup.numFourOps = static_cast<unsigned int>(ops4);
372 play->m_synth.m_numFourOps = play->m_setup.numFourOps;
373 play->m_synth.updateChannelCategories();
374
375 return 0; //adlRefreshNumCards(device);
376 }
377
adl_getNumFourOpsChn(struct ADL_MIDIPlayer * device)378 ADLMIDI_EXPORT int adl_getNumFourOpsChn(struct ADL_MIDIPlayer *device)
379 {
380 if(!device)
381 return -1;
382 MidiPlayer *play = GET_MIDI_PLAYER(device);
383 if(play)
384 return (int)play->m_setup.numFourOps;
385 return -1;
386 }
387
adl_setPercMode(ADL_MIDIPlayer * device,int percmod)388 ADLMIDI_EXPORT void adl_setPercMode(ADL_MIDIPlayer *device, int percmod)
389 {
390 if(!device) return;
391 MidiPlayer *play = GET_MIDI_PLAYER(device);
392 play->m_setup.rhythmMode = percmod;
393 play->m_synth.m_rhythmMode = play->m_setup.rhythmMode < 0 ?
394 (play->m_synth.m_insBankSetup.adLibPercussions) :
395 (play->m_setup.rhythmMode != 0);
396 play->m_synth.updateChannelCategories();
397 }
398
adl_setHVibrato(ADL_MIDIPlayer * device,int hvibro)399 ADLMIDI_EXPORT void adl_setHVibrato(ADL_MIDIPlayer *device, int hvibro)
400 {
401 if(!device) return;
402 MidiPlayer *play = GET_MIDI_PLAYER(device);
403 play->m_setup.deepVibratoMode = hvibro;
404 play->m_synth.m_deepVibratoMode = play->m_setup.deepVibratoMode < 0 ?
405 play->m_synth.m_insBankSetup.deepVibrato :
406 (play->m_setup.deepVibratoMode != 0);
407 play->m_synth.commitDeepFlags();
408 }
409
adl_setHTremolo(ADL_MIDIPlayer * device,int htremo)410 ADLMIDI_EXPORT void adl_setHTremolo(ADL_MIDIPlayer *device, int htremo)
411 {
412 if(!device) return;
413 MidiPlayer *play = GET_MIDI_PLAYER(device);
414 play->m_setup.deepTremoloMode = htremo;
415 play->m_synth.m_deepTremoloMode = play->m_setup.deepTremoloMode < 0 ?
416 play->m_synth.m_insBankSetup.deepTremolo :
417 (play->m_setup.deepTremoloMode != 0);
418 play->m_synth.commitDeepFlags();
419 }
420
adl_setScaleModulators(ADL_MIDIPlayer * device,int smod)421 ADLMIDI_EXPORT void adl_setScaleModulators(ADL_MIDIPlayer *device, int smod)
422 {
423 if(!device)
424 return;
425 MidiPlayer *play = GET_MIDI_PLAYER(device);
426 if(!play)
427 return;
428 play->m_setup.scaleModulators = smod;
429 play->m_synth.m_scaleModulators = play->m_setup.scaleModulators < 0 ?
430 play->m_synth.m_insBankSetup.scaleModulators :
431 (play->m_setup.scaleModulators != 0);
432 }
433
adl_setFullRangeBrightness(struct ADL_MIDIPlayer * device,int fr_brightness)434 ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness)
435 {
436 if(!device)
437 return;
438 MidiPlayer *play = GET_MIDI_PLAYER(device);
439 if(!play)
440 return;
441 play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0);
442 }
443
adl_setLoopEnabled(ADL_MIDIPlayer * device,int loopEn)444 ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
445 {
446 if(!device)
447 return;
448 MidiPlayer *play = GET_MIDI_PLAYER(device);
449 if(!play)
450 return;
451 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
452 play->m_sequencer.setLoopEnabled(loopEn != 0);
453 #else
454 ADL_UNUSED(loopEn);
455 #endif
456 }
457
458 /* !!!DEPRECATED!!! */
adl_setLogarithmicVolumes(struct ADL_MIDIPlayer * device,int logvol)459 ADLMIDI_EXPORT void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol)
460 {
461 if(!device)
462 return;
463 MidiPlayer *play = GET_MIDI_PLAYER(device);
464 if(!play)
465 return;
466 play->m_setup.logarithmicVolumes = (logvol != 0);
467 if(play->m_setup.logarithmicVolumes)
468 play->m_synth.setVolumeScaleModel(ADLMIDI_VolumeModel_NativeOPL3);
469 else
470 play->m_synth.setVolumeScaleModel(static_cast<ADLMIDI_VolumeModels>(play->m_synth.m_volumeScale));
471 }
472
adl_setVolumeRangeModel(struct ADL_MIDIPlayer * device,int volumeModel)473 ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int volumeModel)
474 {
475 if(!device)
476 return;
477 MidiPlayer *play = GET_MIDI_PLAYER(device);
478 if(!play)
479 return;
480 play->m_setup.volumeScaleModel = volumeModel;
481 if(play->m_setup.volumeScaleModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model
482 play->m_synth.m_volumeScale = (OPL3::VolumesScale)play->m_synth.m_insBankSetup.volumeModel;
483 else
484 play->m_synth.setVolumeScaleModel(static_cast<ADLMIDI_VolumeModels>(volumeModel));
485 }
486
adl_openBankFile(struct ADL_MIDIPlayer * device,const char * filePath)487 ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath)
488 {
489 if(device && device->adl_midiPlayer)
490 {
491 MidiPlayer *play = GET_MIDI_PLAYER(device);
492 play->m_setup.tick_skip_samples_delay = 0;
493 if(!play->LoadBank(filePath))
494 {
495 std::string err = play->getErrorString();
496 if(err.empty())
497 play->setErrorString("ADL MIDI: Can't load file");
498 return -1;
499 }
500 else return adlRefreshNumCards(device);
501 }
502
503 ADLMIDI_ErrorString = "Can't load file: ADLMIDI is not initialized";
504 return -1;
505 }
506
adl_openBankData(struct ADL_MIDIPlayer * device,const void * mem,unsigned long size)507 ADLMIDI_EXPORT int adl_openBankData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size)
508 {
509 if(device && device->adl_midiPlayer)
510 {
511 MidiPlayer *play = GET_MIDI_PLAYER(device);
512 if(!play)
513 return -1;
514 play->m_setup.tick_skip_samples_delay = 0;
515 if(!play->LoadBank(mem, static_cast<size_t>(size)))
516 {
517 std::string err = play->getErrorString();
518 if(err.empty())
519 play->setErrorString("ADL MIDI: Can't load data from memory");
520 return -1;
521 }
522 else return adlRefreshNumCards(device);
523 }
524
525 ADLMIDI_ErrorString = "Can't load file: ADL MIDI is not initialized";
526 return -1;
527 }
528
adl_openFile(ADL_MIDIPlayer * device,const char * filePath)529 ADLMIDI_EXPORT int adl_openFile(ADL_MIDIPlayer *device, const char *filePath)
530 {
531 if(device && device->adl_midiPlayer)
532 {
533 MidiPlayer *play = GET_MIDI_PLAYER(device);
534 if(!play)
535 return -1;
536 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
537 play->m_setup.tick_skip_samples_delay = 0;
538 if(!play->LoadMIDI(filePath))
539 {
540 std::string err = play->getErrorString();
541 if(err.empty())
542 play->setErrorString("ADL MIDI: Can't load file");
543 return -1;
544 }
545 else return 0;
546 #else
547 ADL_UNUSED(filePath);
548 play->setErrorString("ADLMIDI: MIDI Sequencer is not supported in this build of library!");
549 return -1;
550 #endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
551 }
552
553 ADLMIDI_ErrorString = "Can't load file: ADL MIDI is not initialized";
554 return -1;
555 }
556
adl_openData(ADL_MIDIPlayer * device,const void * mem,unsigned long size)557 ADLMIDI_EXPORT int adl_openData(ADL_MIDIPlayer *device, const void *mem, unsigned long size)
558 {
559 if(device && device->adl_midiPlayer)
560 {
561 MidiPlayer *play = GET_MIDI_PLAYER(device);
562 if(!play)
563 return -1;
564 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
565 play->m_setup.tick_skip_samples_delay = 0;
566 if(!play->LoadMIDI(mem, static_cast<size_t>(size)))
567 {
568 std::string err = play->getErrorString();
569 if(err.empty())
570 play->setErrorString("ADL MIDI: Can't load data from memory");
571 return -1;
572 }
573 else return 0;
574 #else
575 ADL_UNUSED(mem);
576 ADL_UNUSED(size);
577 play->setErrorString("ADLMIDI: MIDI Sequencer is not supported in this build of library!");
578 return -1;
579 #endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
580 }
581 ADLMIDI_ErrorString = "Can't load file: ADL MIDI is not initialized";
582 return -1;
583 }
584
585
adl_emulatorName()586 ADLMIDI_EXPORT const char *adl_emulatorName()
587 {
588 return "<adl_emulatorName() is deprecated! Use adl_chipEmulatorName() instead!>";
589 }
590
adl_chipEmulatorName(struct ADL_MIDIPlayer * device)591 ADLMIDI_EXPORT const char *adl_chipEmulatorName(struct ADL_MIDIPlayer *device)
592 {
593 if(device)
594 {
595 #ifndef ADLMIDI_HW_OPL
596 MidiPlayer *play = GET_MIDI_PLAYER(device);
597 if(play && !play->m_synth.m_chips.empty())
598 return play->m_synth.m_chips[0]->emulatorName();
599 #else
600 return "Hardware OPL3 chip on 0x330";
601 #endif
602 }
603 return "Unknown";
604 }
605
adl_switchEmulator(struct ADL_MIDIPlayer * device,int emulator)606 ADLMIDI_EXPORT int adl_switchEmulator(struct ADL_MIDIPlayer *device, int emulator)
607 {
608 if(device)
609 {
610 MidiPlayer *play = GET_MIDI_PLAYER(device);
611 assert(play);
612 if(!play)
613 return -1;
614 if((emulator >= 0) && (emulator < ADLMIDI_EMU_end))
615 {
616 play->m_setup.emulator = emulator;
617 adl_reset(device);
618 return 0;
619 }
620 play->setErrorString("OPL3 MIDI: Unknown emulation core!");
621 }
622 return -1;
623 }
624
625
adl_setRunAtPcmRate(ADL_MIDIPlayer * device,int enabled)626 ADLMIDI_EXPORT int adl_setRunAtPcmRate(ADL_MIDIPlayer *device, int enabled)
627 {
628 if(device)
629 {
630 MidiPlayer *play = GET_MIDI_PLAYER(device);
631 if(play)
632 {
633 play->m_setup.runAtPcmRate = (enabled != 0);
634 adl_reset(device);
635 return 0;
636 }
637 }
638 return -1;
639 }
640
641
adl_linkedLibraryVersion()642 ADLMIDI_EXPORT const char *adl_linkedLibraryVersion()
643 {
644 #if !defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
645 return ADLMIDI_VERSION;
646 #else
647 return ADLMIDI_VERSION " (HQ)";
648 #endif
649 }
650
adl_linkedVersion()651 ADLMIDI_EXPORT const ADL_Version *adl_linkedVersion()
652 {
653 return &adl_version;
654 }
655
adl_errorString()656 ADLMIDI_EXPORT const char *adl_errorString()
657 {
658 return ADLMIDI_ErrorString.c_str();
659 }
660
adl_errorInfo(struct ADL_MIDIPlayer * device)661 ADLMIDI_EXPORT const char *adl_errorInfo(struct ADL_MIDIPlayer *device)
662 {
663 if(!device)
664 return adl_errorString();
665 MidiPlayer *play = GET_MIDI_PLAYER(device);
666 if(!play)
667 return adl_errorString();
668 return play->getErrorString().c_str();
669 }
670
adl_getMusicTitle(struct ADL_MIDIPlayer * device)671 ADLMIDI_EXPORT const char *adl_getMusicTitle(struct ADL_MIDIPlayer *device)
672 {
673 return adl_metaMusicTitle(device);
674 }
675
adl_reset(struct ADL_MIDIPlayer * device)676 ADLMIDI_EXPORT void adl_reset(struct ADL_MIDIPlayer *device)
677 {
678 if(!device)
679 return;
680 MidiPlayer *play = GET_MIDI_PLAYER(device);
681 play->m_setup.tick_skip_samples_delay = 0;
682 play->m_synth.m_runAtPcmRate = play->m_setup.runAtPcmRate;
683 play->m_synth.reset(play->m_setup.emulator, play->m_setup.PCM_RATE, play);
684 play->m_chipChannels.clear();
685 play->m_chipChannels.resize((size_t)play->m_synth.m_numChannels);
686 play->resetMIDI();
687 }
688
adl_totalTimeLength(struct ADL_MIDIPlayer * device)689 ADLMIDI_EXPORT double adl_totalTimeLength(struct ADL_MIDIPlayer *device)
690 {
691 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
692 if(!device)
693 return -1.0;
694 MidiPlayer *play = GET_MIDI_PLAYER(device);
695 if(!play)
696 return -1.0;
697 return play->m_sequencer.timeLength();
698 #else
699 ADL_UNUSED(device);
700 return -1.0;
701 #endif
702 }
703
adl_loopStartTime(struct ADL_MIDIPlayer * device)704 ADLMIDI_EXPORT double adl_loopStartTime(struct ADL_MIDIPlayer *device)
705 {
706 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
707 if(!device)
708 return -1.0;
709 MidiPlayer *play = GET_MIDI_PLAYER(device);
710 if(!play)
711 return -1.0;
712 return play->m_sequencer.getLoopStart();
713 #else
714 ADL_UNUSED(device);
715 return -1.0;
716 #endif
717 }
718
adl_loopEndTime(struct ADL_MIDIPlayer * device)719 ADLMIDI_EXPORT double adl_loopEndTime(struct ADL_MIDIPlayer *device)
720 {
721 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
722 if(!device)
723 return -1.0;
724 MidiPlayer *play = GET_MIDI_PLAYER(device);
725 if(!play)
726 return -1.0;
727 return play->m_sequencer.getLoopEnd();
728 #else
729 ADL_UNUSED(device);
730 return -1.0;
731 #endif
732 }
733
adl_positionTell(struct ADL_MIDIPlayer * device)734 ADLMIDI_EXPORT double adl_positionTell(struct ADL_MIDIPlayer *device)
735 {
736 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
737 if(!device)
738 return -1.0;
739 MidiPlayer *play = GET_MIDI_PLAYER(device);
740 if(!play)
741 return -1.0;
742 return play->m_sequencer.tell();
743 #else
744 ADL_UNUSED(device);
745 return -1.0;
746 #endif
747 }
748
adl_positionSeek(struct ADL_MIDIPlayer * device,double seconds)749 ADLMIDI_EXPORT void adl_positionSeek(struct ADL_MIDIPlayer *device, double seconds)
750 {
751 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
752 if(seconds < 0.0)
753 return;//Seeking negative position is forbidden! :-P
754 if(!device)
755 return;
756 MidiPlayer *play = GET_MIDI_PLAYER(device);
757 if(!play)
758 return;
759 play->realTime_panic();
760 play->m_setup.delay = play->m_sequencer.seek(seconds, play->m_setup.mindelay);
761 play->m_setup.carry = 0.0;
762 #else
763 ADL_UNUSED(device);
764 ADL_UNUSED(seconds);
765 #endif
766 }
767
adl_positionRewind(struct ADL_MIDIPlayer * device)768 ADLMIDI_EXPORT void adl_positionRewind(struct ADL_MIDIPlayer *device)
769 {
770 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
771 if(!device)
772 return;
773 MidiPlayer *play = GET_MIDI_PLAYER(device);
774 if(!play)
775 return;
776 play->realTime_panic();
777 play->m_sequencer.rewind();
778 #else
779 ADL_UNUSED(device);
780 #endif
781 }
782
adl_setTempo(struct ADL_MIDIPlayer * device,double tempo)783 ADLMIDI_EXPORT void adl_setTempo(struct ADL_MIDIPlayer *device, double tempo)
784 {
785 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
786 if(!device || (tempo <= 0.0))
787 return;
788 MidiPlayer *play = GET_MIDI_PLAYER(device);
789 if(!play)
790 return;
791 play->m_sequencer.setTempo(tempo);
792 #else
793 ADL_UNUSED(device);
794 ADL_UNUSED(tempo);
795 #endif
796 }
797
798
adl_describeChannels(struct ADL_MIDIPlayer * device,char * str,char * attr,size_t size)799 ADLMIDI_EXPORT int adl_describeChannels(struct ADL_MIDIPlayer *device, char *str, char *attr, size_t size)
800 {
801 if(!device)
802 return -1;
803 MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
804 if(!play)
805 return -1;
806 play->describeChannels(str, attr, size);
807 return 0;
808 }
809
810
adl_metaMusicTitle(struct ADL_MIDIPlayer * device)811 ADLMIDI_EXPORT const char *adl_metaMusicTitle(struct ADL_MIDIPlayer *device)
812 {
813 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
814 if(!device)
815 return "";
816 MidiPlayer *play = GET_MIDI_PLAYER(device);
817 if(!play)
818 return "";
819 return play->m_sequencer.getMusicTitle().c_str();
820 #else
821 ADL_UNUSED(device);
822 return "";
823 #endif
824 }
825
826
adl_metaMusicCopyright(struct ADL_MIDIPlayer * device)827 ADLMIDI_EXPORT const char *adl_metaMusicCopyright(struct ADL_MIDIPlayer *device)
828 {
829 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
830 if(!device)
831 return "";
832 MidiPlayer *play = GET_MIDI_PLAYER(device);
833 if(!play)
834 return "";
835 return play->m_sequencer.getMusicCopyright().c_str();
836 #else
837 ADL_UNUSED(device);
838 return "";
839 #endif
840 }
841
adl_metaTrackTitleCount(struct ADL_MIDIPlayer * device)842 ADLMIDI_EXPORT size_t adl_metaTrackTitleCount(struct ADL_MIDIPlayer *device)
843 {
844 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
845 if(!device)
846 return 0;
847 MidiPlayer *play = GET_MIDI_PLAYER(device);
848 if(!play)
849 return 0;
850 return play->m_sequencer.getTrackTitles().size();
851 #else
852 ADL_UNUSED(device);
853 return 0;
854 #endif
855 }
856
adl_metaTrackTitle(struct ADL_MIDIPlayer * device,size_t index)857 ADLMIDI_EXPORT const char *adl_metaTrackTitle(struct ADL_MIDIPlayer *device, size_t index)
858 {
859 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
860 if(!device)
861 return "";
862 MidiPlayer *play = GET_MIDI_PLAYER(device);
863 const std::vector<std::string> &titles = play->m_sequencer.getTrackTitles();
864 if(index >= titles.size())
865 return "INVALID";
866 return titles[index].c_str();
867 #else
868 ADL_UNUSED(device);
869 ADL_UNUSED(index);
870 return "NOT SUPPORTED";
871 #endif
872 }
873
874
adl_metaMarkerCount(struct ADL_MIDIPlayer * device)875 ADLMIDI_EXPORT size_t adl_metaMarkerCount(struct ADL_MIDIPlayer *device)
876 {
877 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
878 if(!device)
879 return 0;
880 MidiPlayer *play = GET_MIDI_PLAYER(device);
881 if(!play)
882 return 0;
883 return play->m_sequencer.getMarkers().size();
884 #else
885 ADL_UNUSED(device);
886 return 0;
887 #endif
888 }
889
adl_metaMarker(struct ADL_MIDIPlayer * device,size_t index)890 ADLMIDI_EXPORT Adl_MarkerEntry adl_metaMarker(struct ADL_MIDIPlayer *device, size_t index)
891 {
892 struct Adl_MarkerEntry marker;
893 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
894 MidiPlayer *play = GET_MIDI_PLAYER(device);
895 const std::vector<MidiSequencer::MIDI_MarkerEntry> &markers = play->m_sequencer.getMarkers();
896 if(!device || !play || (index >= markers.size()))
897 {
898 marker.label = "INVALID";
899 marker.pos_time = 0.0;
900 marker.pos_ticks = 0;
901 return marker;
902 }
903 else
904 {
905 const MidiSequencer::MIDI_MarkerEntry &mk = markers[index];
906 marker.label = mk.label.c_str();
907 marker.pos_time = mk.pos_time;
908 marker.pos_ticks = (unsigned long)mk.pos_ticks;
909 }
910 #else
911 ADL_UNUSED(device);
912 ADL_UNUSED(index);
913 marker.label = "NOT SUPPORTED";
914 marker.pos_time = 0.0;
915 marker.pos_ticks = 0;
916 #endif
917 return marker;
918 }
919
adl_setRawEventHook(struct ADL_MIDIPlayer * device,ADL_RawEventHook rawEventHook,void * userData)920 ADLMIDI_EXPORT void adl_setRawEventHook(struct ADL_MIDIPlayer *device, ADL_RawEventHook rawEventHook, void *userData)
921 {
922 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
923 if(!device)
924 return;
925 MidiPlayer *play = GET_MIDI_PLAYER(device);
926 play->m_sequencerInterface.onEvent = rawEventHook;
927 play->m_sequencerInterface.onEvent_userData = userData;
928 #else
929 ADL_UNUSED(device);
930 ADL_UNUSED(rawEventHook);
931 ADL_UNUSED(userData);
932 #endif
933 }
934
935 /* Set note hook */
adl_setNoteHook(struct ADL_MIDIPlayer * device,ADL_NoteHook noteHook,void * userData)936 ADLMIDI_EXPORT void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_NoteHook noteHook, void *userData)
937 {
938 if(!device)
939 return;
940 MidiPlayer *play = GET_MIDI_PLAYER(device);
941 play->hooks.onNote = noteHook;
942 play->hooks.onNote_userData = userData;
943 }
944
945 /* Set debug message hook */
adl_setDebugMessageHook(struct ADL_MIDIPlayer * device,ADL_DebugMessageHook debugMessageHook,void * userData)946 ADLMIDI_EXPORT void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData)
947 {
948 if(!device)
949 return;
950 MidiPlayer *play = GET_MIDI_PLAYER(device);
951 play->hooks.onDebugMessage = debugMessageHook;
952 play->hooks.onDebugMessage_userData = userData;
953 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
954 play->m_sequencerInterface.onDebugMessage = debugMessageHook;
955 play->m_sequencerInterface.onDebugMessage_userData = userData;
956 #endif
957 }
958
959 #ifndef ADLMIDI_HW_OPL
960
961 # ifndef __WATCOMC__
962 template <class Dst>
CopySamplesRaw(ADL_UInt8 * dstLeft,ADL_UInt8 * dstRight,const int32_t * src,size_t frameCount,unsigned sampleOffset)963 static void CopySamplesRaw(ADL_UInt8 *dstLeft, ADL_UInt8 *dstRight, const int32_t *src,
964 size_t frameCount, unsigned sampleOffset)
965 {
966 for(size_t i = 0; i < frameCount; ++i) {
967 *(Dst *)(dstLeft + (i * sampleOffset)) = src[2 * i];
968 *(Dst *)(dstRight + (i * sampleOffset)) = src[(2 * i) + 1];
969 }
970 }
971
972 template <class Dst, class Ret>
CopySamplesTransformed(ADL_UInt8 * dstLeft,ADL_UInt8 * dstRight,const int32_t * src,size_t frameCount,unsigned sampleOffset,Ret (& transform)(int32_t))973 static void CopySamplesTransformed(ADL_UInt8 *dstLeft, ADL_UInt8 *dstRight, const int32_t *src,
974 size_t frameCount, unsigned sampleOffset,
975 Ret(&transform)(int32_t))
976 {
977 for(size_t i = 0; i < frameCount; ++i) {
978 *(Dst *)(dstLeft + (i * sampleOffset)) = static_cast<Dst>(transform(src[2 * i]));
979 *(Dst *)(dstRight + (i * sampleOffset)) = static_cast<Dst>(transform(src[(2 * i) + 1]));
980 }
981 }
982
SendStereoAudio(int samples_requested,ssize_t in_size,int32_t * _in,ssize_t out_pos,ADL_UInt8 * left,ADL_UInt8 * right,const ADLMIDI_AudioFormat * format)983 static int SendStereoAudio(int samples_requested,
984 ssize_t in_size,
985 int32_t *_in,
986 ssize_t out_pos,
987 ADL_UInt8 *left,
988 ADL_UInt8 *right,
989 const ADLMIDI_AudioFormat *format)
990 {
991 if(!in_size)
992 return 0;
993 size_t outputOffset = static_cast<size_t>(out_pos);
994 size_t inSamples = static_cast<size_t>(in_size * 2);
995 size_t maxSamples = static_cast<size_t>(samples_requested) - outputOffset;
996 size_t toCopy = std::min(maxSamples, inSamples);
997
998 ADLMIDI_SampleType sampleType = format->type;
999 const unsigned containerSize = format->containerSize;
1000 const unsigned sampleOffset = format->sampleOffset;
1001
1002 left += (outputOffset / 2) * sampleOffset;
1003 right += (outputOffset / 2) * sampleOffset;
1004
1005 typedef int32_t(&pfnConvert)(int32_t);
1006 typedef float(&ffnConvert)(int32_t);
1007 typedef double(&dfnConvert)(int32_t);
1008
1009 switch(sampleType) {
1010 case ADLMIDI_SampleType_S8:
1011 case ADLMIDI_SampleType_U8:
1012 {
1013 pfnConvert cvt = (sampleType == ADLMIDI_SampleType_S8) ? adl_cvtS8 : adl_cvtU8;
1014 switch(containerSize) {
1015 case sizeof(int8_t):
1016 CopySamplesTransformed<int8_t>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1017 break;
1018 case sizeof(int16_t):
1019 CopySamplesTransformed<int16_t>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1020 break;
1021 case sizeof(int32_t):
1022 CopySamplesTransformed<int32_t>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1023 break;
1024 default:
1025 return -1;
1026 }
1027 break;
1028 }
1029 case ADLMIDI_SampleType_S16:
1030 case ADLMIDI_SampleType_U16:
1031 {
1032 pfnConvert cvt = (sampleType == ADLMIDI_SampleType_S16) ? adl_cvtS16 : adl_cvtU16;
1033 switch(containerSize) {
1034 case sizeof(int16_t):
1035 CopySamplesTransformed<int16_t>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1036 break;
1037 case sizeof(int32_t):
1038 CopySamplesRaw<int32_t>(left, right, _in, toCopy / 2, sampleOffset);
1039 break;
1040 default:
1041 return -1;
1042 }
1043 break;
1044 }
1045 case ADLMIDI_SampleType_S24:
1046 case ADLMIDI_SampleType_U24:
1047 {
1048 pfnConvert cvt = (sampleType == ADLMIDI_SampleType_S24) ? adl_cvtS24 : adl_cvtU24;
1049 switch(containerSize) {
1050 case sizeof(int32_t):
1051 CopySamplesTransformed<int32_t>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1052 break;
1053 default:
1054 return -1;
1055 }
1056 break;
1057 }
1058 case ADLMIDI_SampleType_S32:
1059 case ADLMIDI_SampleType_U32:
1060 {
1061 pfnConvert cvt = (sampleType == ADLMIDI_SampleType_S32) ? adl_cvtS32 : adl_cvtU32;
1062 switch(containerSize) {
1063 case sizeof(int32_t):
1064 CopySamplesTransformed<int32_t>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1065 break;
1066 default:
1067 return -1;
1068 }
1069 break;
1070 }
1071 case ADLMIDI_SampleType_F32:
1072 {
1073 if(containerSize != sizeof(float))
1074 return -1;
1075 ffnConvert cvt = adl_cvtReal<float>;
1076 CopySamplesTransformed<float>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1077 break;
1078 }
1079 case ADLMIDI_SampleType_F64:
1080 {
1081 if(containerSize != sizeof(double))
1082 return -1;
1083 dfnConvert cvt = adl_cvtReal<double>;
1084 CopySamplesTransformed<double>(left, right, _in, toCopy / 2, sampleOffset, cvt);
1085 break;
1086 }
1087 default:
1088 return -1;
1089 }
1090
1091 return 0;
1092 }
1093 # else // __WATCOMC__
1094
1095 /*
1096 Workaround for OpenWattcom where templates are declared above are causing compiler to be crashed
1097 */
CopySamplesTransformed(ADL_UInt8 * dstLeft,ADL_UInt8 * dstRight,const int32_t * src,size_t frameCount,unsigned sampleOffset,int32_t (& transform)(int32_t))1098 static void CopySamplesTransformed(ADL_UInt8 *dstLeft, ADL_UInt8 *dstRight, const int32_t *src,
1099 size_t frameCount, unsigned sampleOffset,
1100 int32_t(&transform)(int32_t))
1101 {
1102 for(size_t i = 0; i < frameCount; ++i) {
1103 *(int16_t *)(dstLeft + (i * sampleOffset)) = (int16_t)transform(src[2 * i]);
1104 *(int16_t *)(dstRight + (i * sampleOffset)) = (int16_t)transform(src[(2 * i) + 1]);
1105 }
1106 }
1107
SendStereoAudio(int samples_requested,ssize_t in_size,int32_t * _in,ssize_t out_pos,ADL_UInt8 * left,ADL_UInt8 * right,const ADLMIDI_AudioFormat * format)1108 static int SendStereoAudio(int samples_requested,
1109 ssize_t in_size,
1110 int32_t *_in,
1111 ssize_t out_pos,
1112 ADL_UInt8 *left,
1113 ADL_UInt8 *right,
1114 const ADLMIDI_AudioFormat *format)
1115 {
1116 if(!in_size)
1117 return 0;
1118 size_t outputOffset = static_cast<size_t>(out_pos);
1119 size_t inSamples = static_cast<size_t>(in_size * 2);
1120 size_t maxSamples = static_cast<size_t>(samples_requested) - outputOffset;
1121 size_t toCopy = std::min(maxSamples, inSamples);
1122
1123 ADLMIDI_SampleType sampleType = format->type;
1124 const unsigned containerSize = format->containerSize;
1125 const unsigned sampleOffset = format->sampleOffset;
1126
1127 left += (outputOffset / 2) * sampleOffset;
1128 right += (outputOffset / 2) * sampleOffset;
1129
1130 if(sampleType == ADLMIDI_SampleType_U16)
1131 {
1132 switch(containerSize) {
1133 case sizeof(int16_t):
1134 CopySamplesTransformed(left, right, _in, toCopy / 2, sampleOffset, adl_cvtS16);
1135 break;
1136 default:
1137 return -1;
1138 }
1139 }
1140 else
1141 return -1;
1142 return 0;
1143 }
1144 # endif // __WATCOM__
1145
1146 #endif // ADLMIDI_HW_OPL
1147
1148
adl_play(struct ADL_MIDIPlayer * device,int sampleCount,short * out)1149 ADLMIDI_EXPORT int adl_play(struct ADL_MIDIPlayer *device, int sampleCount, short *out)
1150 {
1151 return adl_playFormat(device, sampleCount, (ADL_UInt8 *)out, (ADL_UInt8 *)(out + 1), &adl_DefaultAudioFormat);
1152 }
1153
adl_playFormat(ADL_MIDIPlayer * device,int sampleCount,ADL_UInt8 * out_left,ADL_UInt8 * out_right,const ADLMIDI_AudioFormat * format)1154 ADLMIDI_EXPORT int adl_playFormat(ADL_MIDIPlayer *device, int sampleCount,
1155 ADL_UInt8 *out_left, ADL_UInt8 *out_right,
1156 const ADLMIDI_AudioFormat *format)
1157 {
1158 #if defined(ADLMIDI_DISABLE_MIDI_SEQUENCER) || defined(ADLMIDI_HW_OPL)
1159 ADL_UNUSED(device);
1160 ADL_UNUSED(sampleCount);
1161 ADL_UNUSED(out_left);
1162 ADL_UNUSED(out_right);
1163 ADL_UNUSED(format);
1164 return 0;
1165 #endif
1166
1167 #if !defined(ADLMIDI_DISABLE_MIDI_SEQUENCER) && !defined(ADLMIDI_HW_OPL)
1168 sampleCount -= sampleCount % 2; //Avoid even sample requests
1169 if(sampleCount < 0)
1170 return 0;
1171 if(!device)
1172 return 0;
1173
1174 MidiPlayer *player = GET_MIDI_PLAYER(device);
1175 MidiPlayer::Setup &setup = player->m_setup;
1176
1177 ssize_t gotten_len = 0;
1178 ssize_t n_periodCountStereo = 512;
1179 //ssize_t n_periodCountPhys = n_periodCountStereo * 2;
1180 int left = sampleCount;
1181 bool hasSkipped = setup.tick_skip_samples_delay > 0;
1182
1183 while(left > 0)
1184 {
1185 {//...
1186 const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
1187 if(hasSkipped)
1188 {
1189 size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay;
1190 n_periodCountStereo = samples / 2;
1191 }
1192 else
1193 {
1194 setup.delay -= eat_delay;
1195 setup.carry += double(setup.PCM_RATE) * eat_delay;
1196 n_periodCountStereo = static_cast<ssize_t>(setup.carry);
1197 setup.carry -= double(n_periodCountStereo);
1198 }
1199
1200 //if(setup.SkipForward > 0)
1201 // setup.SkipForward -= 1;
1202 //else
1203 {
1204 if((player->m_sequencer.positionAtEnd()) && (setup.delay <= 0.0))
1205 break;//Stop to fetch samples at reaching the song end with disabled loop
1206
1207 ssize_t leftSamples = left / 2;
1208 if(n_periodCountStereo > leftSamples)
1209 {
1210 setup.tick_skip_samples_delay = (n_periodCountStereo - leftSamples) * 2;
1211 n_periodCountStereo = leftSamples;
1212 }
1213 //! Count of stereo samples
1214 ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo;
1215 //! Total count of samples
1216 ssize_t in_generatedPhys = in_generatedStereo * 2;
1217 //! Unsigned total sample count
1218 //fill buffer with zeros
1219 int32_t *out_buf = player->m_outBuf;
1220 std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
1221 unsigned int chips = player->m_synth.m_numChips;
1222 if(chips == 1)
1223 {
1224 player->m_synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
1225 }
1226 else if(n_periodCountStereo > 0)
1227 {
1228 /* Generate data from every chip and mix result */
1229 for(size_t card = 0; card < chips; ++card)
1230 player->m_synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
1231 }
1232
1233 /* Process it */
1234 if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
1235 return 0;
1236
1237 left -= (int)in_generatedPhys;
1238 gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
1239 }
1240
1241 if(hasSkipped)
1242 {
1243 setup.tick_skip_samples_delay -= n_periodCountStereo * 2;
1244 hasSkipped = setup.tick_skip_samples_delay > 0;
1245 }
1246 else
1247 setup.delay = player->Tick(eat_delay, setup.mindelay);
1248
1249 }//...
1250 }
1251
1252 return static_cast<int>(gotten_len);
1253 #endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
1254 }
1255
1256
adl_generate(struct ADL_MIDIPlayer * device,int sampleCount,short * out)1257 ADLMIDI_EXPORT int adl_generate(struct ADL_MIDIPlayer *device, int sampleCount, short *out)
1258 {
1259 return adl_generateFormat(device, sampleCount, (ADL_UInt8 *)out, (ADL_UInt8 *)(out + 1), &adl_DefaultAudioFormat);
1260 }
1261
adl_generateFormat(struct ADL_MIDIPlayer * device,int sampleCount,ADL_UInt8 * out_left,ADL_UInt8 * out_right,const ADLMIDI_AudioFormat * format)1262 ADLMIDI_EXPORT int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleCount,
1263 ADL_UInt8 *out_left, ADL_UInt8 *out_right,
1264 const ADLMIDI_AudioFormat *format)
1265 {
1266 #ifdef ADLMIDI_HW_OPL
1267 ADL_UNUSED(device);
1268 ADL_UNUSED(sampleCount);
1269 ADL_UNUSED(out_left);
1270 ADL_UNUSED(out_right);
1271 ADL_UNUSED(format);
1272 return 0;
1273 #else
1274 sampleCount -= sampleCount % 2; //Avoid even sample requests
1275 if(sampleCount < 0)
1276 return 0;
1277 if(!device)
1278 return 0;
1279
1280 MidiPlayer *player = GET_MIDI_PLAYER(device);
1281 MidiPlayer::Setup &setup = player->m_setup;
1282
1283 ssize_t gotten_len = 0;
1284 ssize_t n_periodCountStereo = 512;
1285
1286 int left = sampleCount;
1287 double delay = double(sampleCount) / double(setup.PCM_RATE);
1288
1289 while(left > 0)
1290 {
1291 {//...
1292 const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
1293 delay -= eat_delay;
1294 setup.carry += double(setup.PCM_RATE) * eat_delay;
1295 n_periodCountStereo = static_cast<ssize_t>(setup.carry);
1296 setup.carry -= double(n_periodCountStereo);
1297
1298 {
1299 ssize_t leftSamples = left / 2;
1300 if(n_periodCountStereo > leftSamples)
1301 n_periodCountStereo = leftSamples;
1302 //! Count of stereo samples
1303 ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo;
1304 //! Total count of samples
1305 ssize_t in_generatedPhys = in_generatedStereo * 2;
1306 //! Unsigned total sample count
1307 //fill buffer with zeros
1308 int32_t *out_buf = player->m_outBuf;
1309 std::memset(out_buf, 0, static_cast<size_t>(in_generatedPhys) * sizeof(out_buf[0]));
1310 unsigned int chips = player->m_synth.m_numChips;
1311 if(chips == 1)
1312 player->m_synth.m_chips[0]->generate32(out_buf, (size_t)in_generatedStereo);
1313 else if(n_periodCountStereo > 0)
1314 {
1315 /* Generate data from every chip and mix result */
1316 for(unsigned card = 0; card < chips; ++card)
1317 player->m_synth.m_chips[card]->generateAndMix32(out_buf, (size_t)in_generatedStereo);
1318 }
1319 /* Process it */
1320 if(SendStereoAudio(sampleCount, in_generatedStereo, out_buf, gotten_len, out_left, out_right, format) == -1)
1321 return 0;
1322
1323 left -= (int)in_generatedPhys;
1324 gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
1325 }
1326
1327 player->TickIterators(eat_delay);
1328 }//...
1329 }
1330
1331 return static_cast<int>(gotten_len);
1332 #endif
1333 }
1334
adl_tickEvents(struct ADL_MIDIPlayer * device,double seconds,double granulality)1335 ADLMIDI_EXPORT double adl_tickEvents(struct ADL_MIDIPlayer *device, double seconds, double granulality)
1336 {
1337 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
1338 if(!device)
1339 return -1.0;
1340 MidiPlayer *play = GET_MIDI_PLAYER(device);
1341 if(!play)
1342 return -1.0;
1343 return play->Tick(seconds, granulality);
1344 #else
1345 ADL_UNUSED(device);
1346 ADL_UNUSED(seconds);
1347 ADL_UNUSED(granulality);
1348 return -1.0;
1349 #endif
1350 }
1351
adl_atEnd(struct ADL_MIDIPlayer * device)1352 ADLMIDI_EXPORT int adl_atEnd(struct ADL_MIDIPlayer *device)
1353 {
1354 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
1355 if(!device)
1356 return 1;
1357 MidiPlayer *play = GET_MIDI_PLAYER(device);
1358 if(!play)
1359 return 1;
1360 return (int)play->m_sequencer.positionAtEnd();
1361 #else
1362 ADL_UNUSED(device);
1363 return 1;
1364 #endif
1365 }
1366
adl_trackCount(struct ADL_MIDIPlayer * device)1367 ADLMIDI_EXPORT size_t adl_trackCount(struct ADL_MIDIPlayer *device)
1368 {
1369 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
1370 if(!device)
1371 return 0;
1372 MidiPlayer *play = GET_MIDI_PLAYER(device);
1373 if(!play)
1374 return 0;
1375 return play->m_sequencer.getTrackCount();
1376 #else
1377 ADL_UNUSED(device);
1378 return 0;
1379 #endif
1380 }
1381
adl_setTrackOptions(struct ADL_MIDIPlayer * device,size_t trackNumber,unsigned trackOptions)1382 ADLMIDI_EXPORT int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions)
1383 {
1384 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
1385 if(!device)
1386 return -1;
1387 MidiPlayer *play = GET_MIDI_PLAYER(device);
1388 if(!play)
1389 return -1;
1390 MidiSequencer &seq = play->m_sequencer;
1391
1392 unsigned enableFlag = trackOptions & 3;
1393 trackOptions &= ~3u;
1394
1395 // handle on/off/solo
1396 switch(enableFlag)
1397 {
1398 default:
1399 break;
1400 case ADLMIDI_TrackOption_On:
1401 case ADLMIDI_TrackOption_Off:
1402 if(!seq.setTrackEnabled(trackNumber, enableFlag == ADLMIDI_TrackOption_On))
1403 return -1;
1404 break;
1405 case ADLMIDI_TrackOption_Solo:
1406 seq.setSoloTrack(trackNumber);
1407 break;
1408 }
1409
1410 // handle others...
1411 if(trackOptions != 0)
1412 return -1;
1413
1414 return 0;
1415
1416 #else
1417 ADL_UNUSED(device);
1418 ADL_UNUSED(trackNumber);
1419 ADL_UNUSED(trackOptions);
1420 return -1;
1421 #endif
1422 }
1423
adl_panic(struct ADL_MIDIPlayer * device)1424 ADLMIDI_EXPORT void adl_panic(struct ADL_MIDIPlayer *device)
1425 {
1426 if(!device)
1427 return;
1428 MidiPlayer *play = GET_MIDI_PLAYER(device);
1429 if(!play)
1430 return;
1431 play->realTime_panic();
1432 }
1433
adl_rt_resetState(struct ADL_MIDIPlayer * device)1434 ADLMIDI_EXPORT void adl_rt_resetState(struct ADL_MIDIPlayer *device)
1435 {
1436 if(!device)
1437 return;
1438 MidiPlayer *play = GET_MIDI_PLAYER(device);
1439 if(!play)
1440 return;
1441 play->realTime_ResetState();
1442 }
1443
adl_rt_noteOn(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 note,ADL_UInt8 velocity)1444 ADLMIDI_EXPORT int adl_rt_noteOn(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note, ADL_UInt8 velocity)
1445 {
1446 if(!device)
1447 return 0;
1448 MidiPlayer *play = GET_MIDI_PLAYER(device);
1449 if(!play)
1450 return 0;
1451 return (int)play->realTime_NoteOn(channel, note, velocity);
1452 }
1453
adl_rt_noteOff(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 note)1454 ADLMIDI_EXPORT void adl_rt_noteOff(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note)
1455 {
1456 if(!device)
1457 return;
1458 MidiPlayer *play = GET_MIDI_PLAYER(device);
1459 if(!play)
1460 return;
1461 play->realTime_NoteOff(channel, note);
1462 }
1463
adl_rt_noteAfterTouch(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 note,ADL_UInt8 atVal)1464 ADLMIDI_EXPORT void adl_rt_noteAfterTouch(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note, ADL_UInt8 atVal)
1465 {
1466 if(!device)
1467 return;
1468 MidiPlayer *play = GET_MIDI_PLAYER(device);
1469 if(!play)
1470 return;
1471 play->realTime_NoteAfterTouch(channel, note, atVal);
1472 }
1473
adl_rt_channelAfterTouch(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 atVal)1474 ADLMIDI_EXPORT void adl_rt_channelAfterTouch(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 atVal)
1475 {
1476 if(!device)
1477 return;
1478 MidiPlayer *play = GET_MIDI_PLAYER(device);
1479 if(!play)
1480 return;
1481 play->realTime_ChannelAfterTouch(channel, atVal);
1482 }
1483
adl_rt_controllerChange(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 type,ADL_UInt8 value)1484 ADLMIDI_EXPORT void adl_rt_controllerChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 type, ADL_UInt8 value)
1485 {
1486 if(!device)
1487 return;
1488 MidiPlayer *play = GET_MIDI_PLAYER(device);
1489 if(!play)
1490 return;
1491 play->realTime_Controller(channel, type, value);
1492 }
1493
adl_rt_patchChange(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 patch)1494 ADLMIDI_EXPORT void adl_rt_patchChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 patch)
1495 {
1496 if(!device)
1497 return;
1498 MidiPlayer *play = GET_MIDI_PLAYER(device);
1499 if(!play)
1500 return;
1501 play->realTime_PatchChange(channel, patch);
1502 }
1503
adl_rt_pitchBend(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt16 pitch)1504 ADLMIDI_EXPORT void adl_rt_pitchBend(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt16 pitch)
1505 {
1506 if(!device)
1507 return;
1508 MidiPlayer *play = GET_MIDI_PLAYER(device);
1509 if(!play)
1510 return;
1511 play->realTime_PitchBend(channel, pitch);
1512 }
1513
adl_rt_pitchBendML(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 msb,ADL_UInt8 lsb)1514 ADLMIDI_EXPORT void adl_rt_pitchBendML(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 msb, ADL_UInt8 lsb)
1515 {
1516 if(!device)
1517 return;
1518 MidiPlayer *play = GET_MIDI_PLAYER(device);
1519 if(!play)
1520 return;
1521 play->realTime_PitchBend(channel, msb, lsb);
1522 }
1523
adl_rt_bankChangeLSB(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 lsb)1524 ADLMIDI_EXPORT void adl_rt_bankChangeLSB(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 lsb)
1525 {
1526 if(!device)
1527 return;
1528 MidiPlayer *play = GET_MIDI_PLAYER(device);
1529 if(!play)
1530 return;
1531 play->realTime_BankChangeLSB(channel, lsb);
1532 }
1533
adl_rt_bankChangeMSB(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_UInt8 msb)1534 ADLMIDI_EXPORT void adl_rt_bankChangeMSB(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 msb)
1535 {
1536 if(!device)
1537 return;
1538 MidiPlayer *play = GET_MIDI_PLAYER(device);
1539 if(!play)
1540 return;
1541 play->realTime_BankChangeMSB(channel, msb);
1542 }
1543
adl_rt_bankChange(struct ADL_MIDIPlayer * device,ADL_UInt8 channel,ADL_SInt16 bank)1544 ADLMIDI_EXPORT void adl_rt_bankChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_SInt16 bank)
1545 {
1546 if(!device)
1547 return;
1548 MidiPlayer *play = GET_MIDI_PLAYER(device);
1549 if(!play)
1550 return;
1551 play->realTime_BankChange(channel, (uint16_t)bank);
1552 }
1553
adl_rt_systemExclusive(struct ADL_MIDIPlayer * device,const ADL_UInt8 * msg,size_t size)1554 ADLMIDI_EXPORT int adl_rt_systemExclusive(struct ADL_MIDIPlayer *device, const ADL_UInt8 *msg, size_t size)
1555 {
1556 if(!device)
1557 return -1;
1558 MidiPlayer *play = GET_MIDI_PLAYER(device);
1559 if(!play)
1560 return -1;
1561 return play->realTime_SysEx(msg, size);
1562 }
1563