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 #ifndef ADLMIDI_PRIVATE_HPP
25 #define ADLMIDI_PRIVATE_HPP
26
27 // Setup compiler defines useful for exporting required public API symbols in gme.cpp
28 #ifndef ADLMIDI_EXPORT
29 # if defined (_WIN32) && defined(ADLMIDI_BUILD_DLL)
30 # define ADLMIDI_EXPORT __declspec(dllexport)
31 # elif defined (LIBADLMIDI_VISIBILITY)
32 # define ADLMIDI_EXPORT __attribute__((visibility ("default")))
33 # else
34 # define ADLMIDI_EXPORT
35 # endif
36 #endif
37
38
39 #ifdef _WIN32
40 #define NOMINMAX 1
41 #endif
42
43 #if defined(_WIN32) && !defined(__WATCOMC__)
44 # undef NO_OLDNAMES
45 # include <stdint.h>
46 # ifdef _MSC_VER
47 # ifdef _WIN64
48 typedef __int64 ssize_t;
49 # else
50 typedef __int32 ssize_t;
51 # endif
52 # define NOMINMAX 1 //Don't override std::min and std::max
53 # else
54 # ifdef _WIN64
55 typedef int64_t ssize_t;
56 # else
57 typedef int32_t ssize_t;
58 # endif
59 # endif
60 # include <windows.h>
61 #endif
62
63 #if defined(__DJGPP__) || (defined(__WATCOMC__) && (defined(__DOS__) || defined(__DOS4G__) || defined(__DOS4GNZ__)))
64 #define ADLMIDI_HW_OPL
65 #include <conio.h>
66 #ifdef __DJGPP__
67 #include <pc.h>
68 #include <dpmi.h>
69 #include <go32.h>
70 #include <sys/farptr.h>
71 #include <dos.h>
72 #endif
73
74 #endif
75
76 #include <vector>
77 #include <list>
78 #include <string>
79 //#ifdef __WATCOMC__
80 //#include <myset.h> //TODO: Implemnet a workaround for OpenWatcom to fix a crash while using those containers
81 //#include <mymap.h>
82 //#else
83 #include <map>
84 #include <set>
85 //#endif
86 #include <cstdlib>
87 #include <cstring>
88 #include <cmath>
89 #include <cstdarg>
90 #include <cstdio>
91 #include <cassert>
92 #include <vector> // vector
93 #include <deque> // deque
94 #include <cmath> // exp, log, ceil
95 #if defined(__WATCOMC__)
96 #include <math.h> // round, sqrt
97 #endif
98 #include <inttypes.h>
99 #include <stdio.h>
100 #include <stdlib.h>
101 #include <limits> // numeric_limit
102
103 #ifndef _WIN32
104 #include <errno.h>
105 #endif
106
107 #include <deque>
108 #include <algorithm>
109
110 /*
111 * Workaround for some compilers are has no those macros in their headers!
112 */
113 #ifndef INT8_MIN
114 #define INT8_MIN (-0x7f - 1)
115 #endif
116 #ifndef INT16_MIN
117 #define INT16_MIN (-0x7fff - 1)
118 #endif
119 #ifndef INT32_MIN
120 #define INT32_MIN (-0x7fffffff - 1)
121 #endif
122 #ifndef INT8_MAX
123 #define INT8_MAX 0x7f
124 #endif
125 #ifndef INT16_MAX
126 #define INT16_MAX 0x7fff
127 #endif
128 #ifndef INT32_MAX
129 #define INT32_MAX 0x7fffffff
130 #endif
131
132 #include "file_reader.hpp"
133
134 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
135 // Rename class to avoid ABI collisions
136 #define BW_MidiSequencer AdlMidiSequencer
137 #include "midi_sequencer.hpp"
138 typedef BW_MidiSequencer MidiSequencer;
139 #endif//ADLMIDI_DISABLE_MIDI_SEQUENCER
140
141 #ifndef ADLMIDI_HW_OPL
142 #include "chips/opl_chip_base.h"
143 #endif
144
145 #include "adldata.hh"
146
147 #include "adlmidi.h" //Main API
148
149 #ifndef ADLMIDI_DISABLE_CPP_EXTRAS
150 #include "adlmidi.hpp" //Extra C++ API
151 #endif
152
153 #include "adlmidi_ptr.hpp"
154 #include "adlmidi_bankmap.h"
155
156 #define ADL_UNUSED(x) (void)x
157
158 #define OPL_PANNING_LEFT 0x10
159 #define OPL_PANNING_RIGHT 0x20
160 #define OPL_PANNING_BOTH 0x30
161
162 extern std::string ADLMIDI_ErrorString;
163
164 /*
165 Sample conversions to various formats
166 */
167 template <class Real>
adl_cvtReal(int32_t x)168 inline Real adl_cvtReal(int32_t x)
169 {
170 return static_cast<Real>(x) * (static_cast<Real>(1) / static_cast<Real>(INT16_MAX));
171 }
172
adl_cvtS16(int32_t x)173 inline int32_t adl_cvtS16(int32_t x)
174 {
175 x = (x < INT16_MIN) ? (INT16_MIN) : x;
176 x = (x > INT16_MAX) ? (INT16_MAX) : x;
177 return x;
178 }
179
adl_cvtS8(int32_t x)180 inline int32_t adl_cvtS8(int32_t x)
181 {
182 return adl_cvtS16(x) / 256;
183 }
adl_cvtS24(int32_t x)184 inline int32_t adl_cvtS24(int32_t x)
185 {
186 return adl_cvtS16(x) * 256;
187 }
adl_cvtS32(int32_t x)188 inline int32_t adl_cvtS32(int32_t x)
189 {
190 return adl_cvtS16(x) * 65536;
191 }
adl_cvtU16(int32_t x)192 inline int32_t adl_cvtU16(int32_t x)
193 {
194 return adl_cvtS16(x) - INT16_MIN;
195 }
adl_cvtU8(int32_t x)196 inline int32_t adl_cvtU8(int32_t x)
197 {
198 return (adl_cvtS16(x) / 256) - INT8_MIN;
199 }
adl_cvtU24(int32_t x)200 inline int32_t adl_cvtU24(int32_t x)
201 {
202 enum { int24_min = -(1 << 23) };
203 return adl_cvtS24(x) - int24_min;
204 }
adl_cvtU32(int32_t x)205 inline int32_t adl_cvtU32(int32_t x)
206 {
207 // unsigned operation because overflow on signed integers is undefined
208 return (uint32_t)adl_cvtS32(x) - (uint32_t)INT32_MIN;
209 }
210
211 struct ADL_MIDIPlayer;
212 /**
213 * @brief OPL3 Chip management class
214 */
215 class OPL3
216 {
217 friend class MIDIplay;
218 friend class AdlInstrumentTester;
219 friend int adlRefreshNumCards(ADL_MIDIPlayer *device);
220 public:
221 enum
222 {
223 PercussionTag = 1 << 15,
224 CustomBankTag = 0xFFFFFFFF
225 };
226
227 //! Total number of chip channels between all running emulators
228 uint32_t m_numChannels;
229 //! Just a padding. Reserved.
230 char _padding[4];
231 #ifndef ADLMIDI_HW_OPL
232 //! Running chip emulators
233 std::vector<AdlMIDI_SPtr<OPLChipBase > > m_chips;
234 #endif
235
236 private:
237 //! Cached patch data, needed by Touch()
238 std::vector<adldata> m_insCache;
239 //! Value written to B0, cached, needed by NoteOff.
240 /*! Contains Key on/off state, octave block and frequency number values
241 */
242 std::vector<uint32_t> m_keyBlockFNumCache;
243 //! Cached BD registry value (flags register: DeepTremolo, DeepVibrato, and RhythmMode)
244 std::vector<uint32_t> m_regBD;
245
246 public:
247 /**
248 * @brief MIDI bank entry
249 */
250 struct Bank
251 {
252 //! MIDI Bank instruments
253 adlinsdata2 ins[128];
254 };
255 typedef BasicBankMap<Bank> BankMap;
256 //! MIDI bank instruments data
257 BankMap m_insBanks;
258 //! MIDI bank-wide setup
259 AdlBankSetup m_insBankSetup;
260
261 public:
262 //! Blank instrument template
263 static const adlinsdata2 m_emptyInstrument;
264 //! Total number of running concurrent emulated chips
265 uint32_t m_numChips;
266 //! Currently running embedded bank number. "CustomBankTag" means usign of the custom bank.
267 uint32_t m_embeddedBank;
268 //! Total number of needed four-operator channels in all running chips
269 uint32_t m_numFourOps;
270 //! Turn global Deep Tremolo mode on
271 bool m_deepTremoloMode;
272 //! Turn global Deep Vibrato mode on
273 bool m_deepVibratoMode;
274 //! Use Rhythm Mode percussions
275 bool m_rhythmMode;
276 //! Carriers-only are scaled by default by volume level. This flag will tell to scale modulators too.
277 bool m_scaleModulators;
278 //! Run emulator at PCM rate if that possible. Reduces sounding accuracy, but decreases CPU usage on lower rates.
279 bool m_runAtPcmRate;
280
281 //! Just a padding. Reserved.
282 char _padding2[3];
283
284 /**
285 * @brief Music playing mode
286 */
287 enum MusicMode
288 {
289 //! MIDI mode
290 MODE_MIDI,
291 //! Id-Software Music mode
292 MODE_IMF,
293 //! Creative Music Files mode
294 MODE_CMF,
295 //! EA-MUS (a.k.a. RSXX) mode
296 MODE_RSXX
297 } m_musicMode;
298
299 /**
300 * @brief Volume models enum
301 */
302 enum VolumesScale
303 {
304 //! Generic volume model (linearization of logarithmic scale)
305 VOLUME_Generic,
306 //! OPL3 native logarithmic scale
307 VOLUME_NATIVE,
308 //! DMX volume scale logarithmic table
309 VOLUME_DMX,
310 //! Apoge Sound System volume scaling model
311 VOLUME_APOGEE,
312 //! Windows 9x driver volume scale table
313 VOLUME_9X
314 } m_volumeScale;
315
316 //! Reserved
317 char _padding3[8];
318
319 /**
320 * @brief Channel categiry enumeration
321 */
322 enum ChanCat
323 {
324 //! Regular melodic/percussion channel
325 ChanCat_Regular = 0,
326 //! Four-op master
327 ChanCat_4op_Master = 1,
328 //! Four-op slave
329 ChanCat_4op_Slave = 2,
330 //! Rhythm-mode Bass drum
331 ChanCat_Rhythm_Bass = 3,
332 //! Rhythm-mode Snare drum
333 ChanCat_Rhythm_Snare = 4,
334 //! Rhythm-mode Tom-Tom
335 ChanCat_Rhythm_Tom = 5,
336 //! Rhythm-mode Cymbal
337 ChanCat_Rhythm_Cymbal = 6,
338 //! Rhythm-mode Hi-Hat
339 ChanCat_Rhythm_HiHat = 7,
340 //! Rhythm-mode Slave channel
341 ChanCat_Rhythm_Slave = 8
342 };
343
344 //! Category of the channel
345 /*! 1 = quad-master, 2 = quad-slave, 0 = regular
346 3 = percussion BassDrum
347 4 = percussion Snare
348 5 = percussion Tom
349 6 = percussion Crash cymbal
350 7 = percussion Hihat
351 8 = percussion slave
352 */
353 std::vector<uint32_t> m_channelCategory;
354
355
356 /**
357 * @brief C.O. Constructor
358 */
359 OPL3();
360
361 /**
362 * @brief Choose one of embedded banks
363 * @param bank ID of the bank
364 */
365 void setEmbeddedBank(uint32_t bank);
366
367 /**
368 * @brief Write data to OPL3 chip register
369 * @param chip Index of emulated chip. In hardware OPL3 builds, this parameter is ignored
370 * @param address Register address to write
371 * @param value Value to write
372 */
373 void writeReg(size_t chip, uint16_t address, uint8_t value);
374
375 /**
376 * @brief Write data to OPL3 chip register
377 * @param chip Index of emulated chip. In hardware OPL3 builds, this parameter is ignored
378 * @param address Register address to write
379 * @param value Value to write
380 */
381 void writeRegI(size_t chip, uint32_t address, uint32_t value);
382
383 /**
384 * @brief Off the note in specified chip channel
385 * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)])
386 */
387 void noteOff(size_t c);
388
389 /**
390 * @brief On the note in specified chip channel with specified frequency of the tone
391 * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)])
392 * @param hertz Frequency of the tone in hertzes
393 */
394 void noteOn(size_t c, double hertz);
395
396 /**
397 * @brief Change setup of instrument in specified chip channel
398 * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)])
399 * @param volume Volume level (from 0 to 63)
400 * @param brightness CC74 Brightness level (from 0 to 127)
401 */
402 void touchNote(size_t c, uint8_t volume, uint8_t brightness = 127);
403
404 /**
405 * @brief Set the instrument into specified chip channel
406 * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)])
407 * @param instrument Instrument data to set into the chip channel
408 */
409 void setPatch(size_t c, const adldata &instrument);
410
411 /**
412 * @brief Set panpot position
413 * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)])
414 * @param value 3-bit panpot value
415 */
416 void setPan(size_t c, uint8_t value);
417
418 /**
419 * @brief Shut up all chip channels
420 */
421 void silenceAll();
422
423 /**
424 * @brief Commit updated flag states to chip registers
425 */
426 void updateChannelCategories();
427
428 /**
429 * @brief commit deepTremolo and deepVibrato flags
430 */
431 void commitDeepFlags();
432
433 /**
434 * @brief Set the volume scaling model
435 * @param volumeModel Type of volume scale model scale
436 */
437 void setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel);
438
439 #ifndef ADLMIDI_HW_OPL
440 /**
441 * @brief Clean up all running emulated chip instances
442 */
443 void clearChips();
444 #endif
445
446 /**
447 * @brief Reset chip properties and initialize them
448 * @param emulator Type of chip emulator
449 * @param PCM_RATE Output sample rate to generate on output
450 * @param audioTickHandler PCM-accurate clock hook
451 */
452 void reset(int emulator, unsigned long PCM_RATE, void *audioTickHandler);
453 };
454
455
456 /**
457 * @brief Hooks of the internal events
458 */
459 struct MIDIEventHooks
460 {
MIDIEventHooksMIDIEventHooks461 MIDIEventHooks() :
462 onNote(NULL),
463 onNote_userData(NULL),
464 onDebugMessage(NULL),
465 onDebugMessage_userData(NULL)
466 {}
467
468 //! Note on/off hooks
469 typedef void (*NoteHook)(void *userdata, int adlchn, int note, int ins, int pressure, double bend);
470 NoteHook onNote;
471 void *onNote_userData;
472
473 //! Library internal debug messages
474 typedef void (*DebugMessageHook)(void *userdata, const char *fmt, ...);
475 DebugMessageHook onDebugMessage;
476 void *onDebugMessage_userData;
477 };
478
479
480 class MIDIplay
481 {
482 friend void adl_reset(struct ADL_MIDIPlayer*);
483 public:
484 explicit MIDIplay(unsigned long sampleRate = 22050);
485
~MIDIplay()486 ~MIDIplay()
487 {}
488
489 void applySetup();
490
491 void resetMIDI();
492
493 /**********************Internal structures and classes**********************/
494
495 /**
496 * @brief Persistent settings for each MIDI channel
497 */
498 struct MIDIchannel
499 {
500 //! LSB Bank number
501 uint8_t bank_lsb,
502 //! MSB Bank number
503 bank_msb;
504 //! Current patch number
505 uint8_t patch;
506 //! Volume level
507 uint8_t volume,
508 //! Expression level
509 expression;
510 //! Panning level
511 uint8_t panning,
512 //! Vibrato level
513 vibrato,
514 //! Channel aftertouch level
515 aftertouch;
516 //! Portamento time
517 uint16_t portamento;
518 //! Is Pedal sustain active
519 bool sustain;
520 //! Is Soft pedal active
521 bool softPedal;
522 //! Is portamento enabled
523 bool portamentoEnable;
524 //! Source note number used by portamento
525 int8_t portamentoSource; // note number or -1
526 //! Portamento rate
527 double portamentoRate;
528 //! Per note Aftertouch values
529 uint8_t noteAftertouch[128];
530 //! Is note aftertouch has any non-zero value
531 bool noteAfterTouchInUse;
532 //! Reserved
533 char _padding[6];
534 //! Pitch bend value
535 int bend;
536 //! Pitch bend sensitivity
537 double bendsense;
538 //! Pitch bend sensitivity LSB value
539 int bendsense_lsb,
540 //! Pitch bend sensitivity MSB value
541 bendsense_msb;
542 //! Vibrato position value
543 double vibpos,
544 //! Vibrato speed value
545 vibspeed,
546 //! Vibrato depth value
547 vibdepth;
548 //! Vibrato delay time
549 int64_t vibdelay;
550 //! Last LSB part of RPN value received
551 uint8_t lastlrpn,
552 //! Last MSB poart of RPN value received
553 lastmrpn;
554 //! Interpret RPN value as NRPN
555 bool nrpn;
556 //! Brightness level
557 uint8_t brightness;
558
559 //! Is melodic channel turned into percussion
560 bool is_xg_percussion;
561
562 /**
563 * @brief Per-Note information
564 */
565 struct NoteInfo
566 {
567 //! Note number
568 uint8_t note;
569 //! Is note active
570 bool active;
571 //! Current pressure
572 uint8_t vol;
573 //! Note vibrato (a part of Note Aftertouch feature)
574 uint8_t vibrato;
575 //! Tone selected on noteon:
576 int16_t noteTone;
577 //! Current tone (!= noteTone if gliding note)
578 double currentTone;
579 //! Gliding rate
580 double glideRate;
581 //! Patch selected on noteon; index to bank.ins[]
582 size_t midiins;
583 //! Is note the percussion instrument
584 bool isPercussion;
585 //! Note that plays missing instrument. Doesn't using any chip channels
586 bool isBlank;
587 //! Patch selected
588 const adlinsdata2 *ains;
589 enum
590 {
591 MaxNumPhysChans = 2,
592 MaxNumPhysItemCount = MaxNumPhysChans,
593 };
594
595 /**
596 * @brief Reference to currently using chip channel
597 */
598 struct Phys
599 {
600 //! Destination chip channel
601 uint16_t chip_chan;
602 //! ins, inde to adl[]
603 adldata ains;
604 //! Is this voice must be detunable?
605 bool pseudo4op;
606
assignMIDIplay::MIDIchannel::NoteInfo::Phys607 void assign(const Phys &oth)
608 {
609 ains = oth.ains;
610 pseudo4op = oth.pseudo4op;
611 }
operator ==MIDIplay::MIDIchannel::NoteInfo::Phys612 bool operator==(const Phys &oth) const
613 {
614 return (ains == oth.ains) && (pseudo4op == oth.pseudo4op);
615 }
operator !=MIDIplay::MIDIchannel::NoteInfo::Phys616 bool operator!=(const Phys &oth) const
617 {
618 return !operator==(oth);
619 }
620 };
621
622 //! List of OPL3 channels it is currently occupying.
623 Phys chip_channels[MaxNumPhysItemCount];
624 //! Count of used channels.
625 unsigned chip_channels_count;
626
phys_findMIDIplay::MIDIchannel::NoteInfo627 Phys *phys_find(unsigned chip_chan)
628 {
629 Phys *ph = NULL;
630 for(unsigned i = 0; i < chip_channels_count && !ph; ++i)
631 if(chip_channels[i].chip_chan == chip_chan)
632 ph = &chip_channels[i];
633 return ph;
634 }
phys_find_or_createMIDIplay::MIDIchannel::NoteInfo635 Phys *phys_find_or_create(uint16_t chip_chan)
636 {
637 Phys *ph = phys_find(chip_chan);
638 if(!ph) {
639 if(chip_channels_count < MaxNumPhysItemCount) {
640 ph = &chip_channels[chip_channels_count++];
641 ph->chip_chan = chip_chan;
642 }
643 }
644 return ph;
645 }
phys_ensure_find_or_createMIDIplay::MIDIchannel::NoteInfo646 Phys *phys_ensure_find_or_create(uint16_t chip_chan)
647 {
648 Phys *ph = phys_find_or_create(chip_chan);
649 assert(ph);
650 return ph;
651 }
phys_erase_atMIDIplay::MIDIchannel::NoteInfo652 void phys_erase_at(const Phys *ph)
653 {
654 intptr_t pos = ph - chip_channels;
655 assert(pos < static_cast<intptr_t>(chip_channels_count));
656 for(intptr_t i = pos + 1; i < static_cast<intptr_t>(chip_channels_count); ++i)
657 chip_channels[i - 1] = chip_channels[i];
658 --chip_channels_count;
659 }
phys_eraseMIDIplay::MIDIchannel::NoteInfo660 void phys_erase(unsigned chip_chan)
661 {
662 Phys *ph = phys_find(chip_chan);
663 if(ph)
664 phys_erase_at(ph);
665 }
666 };
667
668 //! Reserved
669 char _padding2[5];
670 //! Count of gliding notes in this channel
671 unsigned gliding_note_count;
672
673 //! Active notes in the channel
674 NoteInfo activenotes[128];
675
676 struct activenoteiterator
677 {
activenoteiteratorMIDIplay::MIDIchannel::activenoteiterator678 explicit activenoteiterator(NoteInfo *info = NULL)
679 : ptr(info) {}
operator ++MIDIplay::MIDIchannel::activenoteiterator680 activenoteiterator &operator++()
681 {
682 if(ptr->note == 127)
683 ptr = NULL;
684 else
685 for(++ptr; ptr && !ptr->active;)
686 ptr = (ptr->note == 127) ? NULL : (ptr + 1);
687 return *this;
688 }
operator ++MIDIplay::MIDIchannel::activenoteiterator689 activenoteiterator operator++(int)
690 {
691 activenoteiterator pos = *this;
692 ++*this;
693 return pos;
694 }
operator *MIDIplay::MIDIchannel::activenoteiterator695 NoteInfo &operator*() const
696 { return *ptr; }
operator ->MIDIplay::MIDIchannel::activenoteiterator697 NoteInfo *operator->() const
698 { return ptr; }
operator ==MIDIplay::MIDIchannel::activenoteiterator699 bool operator==(activenoteiterator other) const
700 { return ptr == other.ptr; }
operator !=MIDIplay::MIDIchannel::activenoteiterator701 bool operator!=(activenoteiterator other) const
702 { return ptr != other.ptr; }
operator NoteInfo*MIDIplay::MIDIchannel::activenoteiterator703 operator NoteInfo *() const
704 { return ptr; }
705 private:
706 NoteInfo *ptr;
707 };
708
activenotes_beginMIDIplay::MIDIchannel709 activenoteiterator activenotes_begin()
710 {
711 activenoteiterator it(activenotes);
712 return (it->active) ? it : ++it;
713 }
714
activenotes_findMIDIplay::MIDIchannel715 activenoteiterator activenotes_find(uint8_t note)
716 {
717 assert(note < 128);
718 return activenoteiterator(
719 activenotes[note].active ? &activenotes[note] : NULL);
720 }
721
activenotes_ensure_findMIDIplay::MIDIchannel722 activenoteiterator activenotes_ensure_find(uint8_t note)
723 {
724 activenoteiterator it = activenotes_find(note);
725 assert(it);
726 return it;
727 }
728
activenotes_insertMIDIplay::MIDIchannel729 std::pair<activenoteiterator, bool> activenotes_insert(uint8_t note)
730 {
731 assert(note < 128);
732 NoteInfo &info = activenotes[note];
733 bool inserted = !info.active;
734 if(inserted) info.active = true;
735 return std::pair<activenoteiterator, bool>(activenoteiterator(&info), inserted);
736 }
737
activenotes_eraseMIDIplay::MIDIchannel738 void activenotes_erase(activenoteiterator pos)
739 {
740 if(pos)
741 pos->active = false;
742 }
743
activenotes_emptyMIDIplay::MIDIchannel744 bool activenotes_empty()
745 {
746 return !activenotes_begin();
747 }
748
activenotes_clearMIDIplay::MIDIchannel749 void activenotes_clear()
750 {
751 for(uint8_t i = 0; i < 128; ++i) {
752 activenotes[i].note = i;
753 activenotes[i].active = false;
754 }
755 }
756
757 /**
758 * @brief Reset channel into initial state
759 */
resetMIDIplay::MIDIchannel760 void reset()
761 {
762 resetAllControllers();
763 patch = 0;
764 vibpos = 0;
765 bank_lsb = 0;
766 bank_msb = 0;
767 lastlrpn = 0;
768 lastmrpn = 0;
769 nrpn = false;
770 is_xg_percussion = false;
771 }
772
773 /**
774 * @brief Reset all MIDI controllers into initial state
775 */
resetAllControllersMIDIplay::MIDIchannel776 void resetAllControllers()
777 {
778 bend = 0;
779 bendsense_msb = 2;
780 bendsense_lsb = 0;
781 updateBendSensitivity();
782 volume = 100;
783 expression = 127;
784 sustain = false;
785 softPedal = false;
786 vibrato = 0;
787 aftertouch = 0;
788 std::memset(noteAftertouch, 0, 128);
789 noteAfterTouchInUse = false;
790 vibspeed = 2 * 3.141592653 * 5.0;
791 vibdepth = 0.5 / 127;
792 vibdelay = 0;
793 panning = OPL_PANNING_BOTH;
794 portamento = 0;
795 portamentoEnable = false;
796 portamentoSource = -1;
797 portamentoRate = HUGE_VAL;
798 brightness = 127;
799 }
800
801 /**
802 * @brief Has channel vibrato to process
803 * @return
804 */
hasVibratoMIDIplay::MIDIchannel805 bool hasVibrato()
806 {
807 return (vibrato > 0) || (aftertouch > 0) || noteAfterTouchInUse;
808 }
809
810 /**
811 * @brief Commit pitch bend sensitivity value from MSB and LSB
812 */
updateBendSensitivityMIDIplay::MIDIchannel813 void updateBendSensitivity()
814 {
815 int cent = bendsense_msb * 128 + bendsense_lsb;
816 bendsense = cent * (1.0 / (128 * 8192));
817 }
818
MIDIchannelMIDIplay::MIDIchannel819 MIDIchannel()
820 {
821 activenotes_clear();
822 gliding_note_count = 0;
823 reset();
824 }
825 };
826
827 /**
828 * @brief Additional information about OPL3 channels
829 */
830 struct AdlChannel
831 {
832 struct Location
833 {
834 uint16_t MidCh;
835 uint8_t note;
operator ==MIDIplay::AdlChannel::Location836 bool operator==(const Location &l) const
837 { return MidCh == l.MidCh && note == l.note; }
operator !=MIDIplay::AdlChannel::Location838 bool operator!=(const Location &l) const
839 { return !operator==(l); }
840 };
841 struct LocationData
842 {
843 LocationData *prev, *next;
844 Location loc;
845 enum {
846 Sustain_None = 0x00,
847 Sustain_Pedal = 0x01,
848 Sustain_Sostenuto = 0x02,
849 Sustain_ANY = Sustain_Pedal | Sustain_Sostenuto,
850 };
851 uint32_t sustained;
852 char _padding[6];
853 MIDIchannel::NoteInfo::Phys ins; // a copy of that in phys[]
854 //! Has fixed sustain, don't iterate "on" timeout
855 bool fixed_sustain;
856 //! Timeout until note will be allowed to be killed by channel manager while it is on
857 int64_t kon_time_until_neglible;
858 int64_t vibdelay;
859 };
860
861 //! Time left until sounding will be muted after key off
862 int64_t koff_time_until_neglible;
863
864 enum { users_max = 128 };
865 LocationData *users_first, *users_free_cells;
866 LocationData users_cells[users_max];
867 unsigned users_size;
868
869 bool users_empty() const;
870 LocationData *users_find(Location loc);
871 LocationData *users_allocate();
872 LocationData *users_find_or_create(Location loc);
873 LocationData *users_insert(const LocationData &x);
874 void users_erase(LocationData *user);
875 void users_clear();
876 void users_assign(const LocationData *users, size_t count);
877
878 // For channel allocation:
AdlChannelMIDIplay::AdlChannel879 AdlChannel(): koff_time_until_neglible(0)
880 {
881 users_clear();
882 }
883
AdlChannelMIDIplay::AdlChannel884 AdlChannel(const AdlChannel &oth): koff_time_until_neglible(oth.koff_time_until_neglible)
885 {
886 if(oth.users_first)
887 {
888 users_first = NULL;
889 users_assign(oth.users_first, oth.users_size);
890 }
891 else
892 users_clear();
893 }
894
operator =MIDIplay::AdlChannel895 AdlChannel &operator=(const AdlChannel &oth)
896 {
897 koff_time_until_neglible = oth.koff_time_until_neglible;
898 users_assign(oth.users_first, oth.users_size);
899 return *this;
900 }
901
902 /**
903 * @brief Increases age of active note in milliseconds time
904 * @param ms Amount time in milliseconds
905 */
906 void addAge(int64_t ms);
907 };
908
909 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
910 /**
911 * @brief MIDI files player sequencer
912 */
913 MidiSequencer m_sequencer;
914
915 /**
916 * @brief Interface between MIDI sequencer and this library
917 */
918 BW_MidiRtInterface m_sequencerInterface;
919
920 /**
921 * @brief Initialize MIDI sequencer interface
922 */
923 void initSequencerInterface();
924 #endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
925
926 struct Setup
927 {
928 int emulator;
929 bool runAtPcmRate;
930 unsigned int bankId;
931 unsigned int numFourOps;
932 unsigned int numChips;
933 int deepTremoloMode;
934 int deepVibratoMode;
935 int rhythmMode;
936 bool logarithmicVolumes;
937 int volumeScaleModel;
938 //unsigned int SkipForward;
939 int scaleModulators;
940 bool fullRangeBrightnessCC74;
941
942 double delay;
943 double carry;
944
945 /* The lag between visual content and audio content equals */
946 /* the sum of these two buffers. */
947 double mindelay;
948 double maxdelay;
949
950 /* For internal usage */
951 ssize_t tick_skip_samples_delay; /* Skip tick processing after samples count. */
952 /* For internal usage */
953
954 unsigned long PCM_RATE;
955 };
956
957 /**
958 * @brief MIDI Marker entry
959 */
960 struct MIDI_MarkerEntry
961 {
962 //! Label of marker
963 std::string label;
964 //! Absolute position in seconds
965 double pos_time;
966 //! Absolute position in ticks in the track
967 uint64_t pos_ticks;
968 };
969
970 //! Available MIDI Channels
971 std::vector<MIDIchannel> m_midiChannels;
972
973 //! CMF Rhythm mode
974 bool m_cmfPercussionMode;
975
976 //! Master volume, controlled via SysEx
977 uint8_t m_masterVolume;
978
979 //! SysEx device ID
980 uint8_t m_sysExDeviceId;
981
982 /**
983 * @brief MIDI Synthesizer mode
984 */
985 enum SynthMode
986 {
987 Mode_GM = 0x00,
988 Mode_GS = 0x01,
989 Mode_XG = 0x02,
990 Mode_GM2 = 0x04,
991 };
992 //! MIDI Synthesizer mode
993 uint32_t m_synthMode;
994
995 //! Installed function hooks
996 MIDIEventHooks hooks;
997
998 private:
999 //! Per-track MIDI devices map
1000 std::map<std::string, size_t> m_midiDevices;
1001 //! Current MIDI device per track
1002 std::map<size_t /*track*/, size_t /*channel begin index*/> m_currentMidiDevice;
1003
1004 //! Padding to fix CLanc code model's warning
1005 char _padding[7];
1006
1007 //! Chip channels map
1008 std::vector<AdlChannel> m_chipChannels;
1009 //! Counter of arpeggio processing
1010 size_t m_arpeggioCounter;
1011
1012 #if defined(ADLMIDI_AUDIO_TICK_HANDLER)
1013 //! Audio tick counter
1014 uint32_t m_audioTickCounter;
1015 #endif
1016
1017 //! Local error string
1018 std::string errorStringOut;
1019
1020 //! Missing instruments catches
1021 std::set<size_t> caugh_missing_instruments;
1022 //! Missing melodic banks catches
1023 std::set<size_t> caugh_missing_banks_melodic;
1024 //! Missing percussion banks catches
1025 std::set<size_t> caugh_missing_banks_percussion;
1026
1027 public:
1028
1029 const std::string &getErrorString();
1030 void setErrorString(const std::string &err);
1031
1032 //! OPL3 Chip manager
1033 OPL3 m_synth;
1034
1035 //! Generator output buffer
1036 int32_t m_outBuf[1024];
1037
1038 //! Synthesizer setup
1039 Setup m_setup;
1040
1041 /**
1042 * @brief Load custom bank from file
1043 * @param filename Path to bank file
1044 * @return true on succes
1045 */
1046 bool LoadBank(const std::string &filename);
1047
1048 /**
1049 * @brief Load custom bank from memory block
1050 * @param data Pointer to memory block where raw bank file is stored
1051 * @param size Size of given memory block
1052 * @return true on succes
1053 */
1054 bool LoadBank(const void *data, size_t size);
1055
1056 /**
1057 * @brief Load custom bank from opened FileAndMemReader class
1058 * @param fr Instance with opened file
1059 * @return true on succes
1060 */
1061 bool LoadBank(FileAndMemReader &fr);
1062
1063 #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
1064 /**
1065 * @brief MIDI file loading pre-process
1066 * @return true on success, false on failure
1067 */
1068 bool LoadMIDI_pre();
1069
1070 /**
1071 * @brief MIDI file loading post-process
1072 * @return true on success, false on failure
1073 */
1074 bool LoadMIDI_post();
1075
1076 /**
1077 * @brief Load music file from a file
1078 * @param filename Path to music file
1079 * @return true on success, false on failure
1080 */
1081
1082 bool LoadMIDI(const std::string &filename);
1083
1084 /**
1085 * @brief Load music file from the memory block
1086 * @param data pointer to the memory block
1087 * @param size size of memory block
1088 * @return true on success, false on failure
1089 */
1090 bool LoadMIDI(const void *data, size_t size);
1091
1092 /**
1093 * @brief Periodic tick handler.
1094 * @param s seconds since last call
1095 * @param granularity don't expect intervals smaller than this, in seconds
1096 * @return desired number of seconds until next call
1097 */
1098 double Tick(double s, double granularity);
1099 #endif //ADLMIDI_DISABLE_MIDI_SEQUENCER
1100
1101 /**
1102 * @brief Process extra iterators like vibrato or arpeggio
1103 * @param s seconds since last call
1104 */
1105 void TickIterators(double s);
1106
1107
1108 /* RealTime event triggers */
1109 /**
1110 * @brief Reset state of all channels
1111 */
1112 void realTime_ResetState();
1113
1114 /**
1115 * @brief Note On event
1116 * @param channel MIDI channel
1117 * @param note Note key (from 0 to 127)
1118 * @param velocity Velocity level (from 0 to 127)
1119 * @return true if Note On event was accepted
1120 */
1121 bool realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
1122
1123 /**
1124 * @brief Note Off event
1125 * @param channel MIDI channel
1126 * @param note Note key (from 0 to 127)
1127 */
1128 void realTime_NoteOff(uint8_t channel, uint8_t note);
1129
1130 /**
1131 * @brief Note aftertouch event
1132 * @param channel MIDI channel
1133 * @param note Note key (from 0 to 127)
1134 * @param atVal After-Touch level (from 0 to 127)
1135 */
1136 void realTime_NoteAfterTouch(uint8_t channel, uint8_t note, uint8_t atVal);
1137
1138 /**
1139 * @brief Channel aftertouch event
1140 * @param channel MIDI channel
1141 * @param atVal After-Touch level (from 0 to 127)
1142 */
1143 void realTime_ChannelAfterTouch(uint8_t channel, uint8_t atVal);
1144
1145 /**
1146 * @brief Controller Change event
1147 * @param channel MIDI channel
1148 * @param type Type of controller
1149 * @param value Value of the controller (from 0 to 127)
1150 */
1151 void realTime_Controller(uint8_t channel, uint8_t type, uint8_t value);
1152
1153 /**
1154 * @brief Patch change
1155 * @param channel MIDI channel
1156 * @param patch Patch Number (from 0 to 127)
1157 */
1158 void realTime_PatchChange(uint8_t channel, uint8_t patch);
1159
1160 /**
1161 * @brief Pitch bend change
1162 * @param channel MIDI channel
1163 * @param pitch Concoctated raw pitch value
1164 */
1165 void realTime_PitchBend(uint8_t channel, uint16_t pitch);
1166
1167 /**
1168 * @brief Pitch bend change
1169 * @param channel MIDI channel
1170 * @param msb MSB of pitch value
1171 * @param lsb LSB of pitch value
1172 */
1173 void realTime_PitchBend(uint8_t channel, uint8_t msb, uint8_t lsb);
1174
1175 /**
1176 * @brief LSB Bank Change CC
1177 * @param channel MIDI channel
1178 * @param lsb LSB value of bank number
1179 */
1180 void realTime_BankChangeLSB(uint8_t channel, uint8_t lsb);
1181
1182 /**
1183 * @brief MSB Bank Change CC
1184 * @param channel MIDI channel
1185 * @param msb MSB value of bank number
1186 */
1187 void realTime_BankChangeMSB(uint8_t channel, uint8_t msb);
1188
1189 /**
1190 * @brief Bank Change (united value)
1191 * @param channel MIDI channel
1192 * @param bank Bank number value
1193 */
1194 void realTime_BankChange(uint8_t channel, uint16_t bank);
1195
1196 /**
1197 * @brief Sets the Device identifier
1198 * @param id 7-bit Device identifier
1199 */
1200 void setDeviceId(uint8_t id);
1201
1202 /**
1203 * @brief System Exclusive message
1204 * @param msg Raw SysEx Message
1205 * @param size Length of SysEx message
1206 * @return true if message was passed successfully. False on any errors
1207 */
1208 bool realTime_SysEx(const uint8_t *msg, size_t size);
1209
1210 /**
1211 * @brief Turn off all notes and mute the sound of releasing notes
1212 */
1213 void realTime_panic();
1214
1215 /**
1216 * @brief Device switch (to extend 16-channels limit of MIDI standard)
1217 * @param track MIDI track index
1218 * @param data Device name
1219 * @param length Length of device name string
1220 */
1221 void realTime_deviceSwitch(size_t track, const char *data, size_t length);
1222
1223 /**
1224 * @brief Currently selected device index
1225 * @param track MIDI track index
1226 * @return Multiple 16 value
1227 */
1228 size_t realTime_currentDevice(size_t track);
1229
1230 /**
1231 * @brief Send raw OPL chip command
1232 * @param reg OPL Register
1233 * @param value Value to write
1234 */
1235 void realTime_rawOPL(uint8_t reg, uint8_t value);
1236
1237 #if defined(ADLMIDI_AUDIO_TICK_HANDLER)
1238 // Audio rate tick handler
1239 void AudioTick(uint32_t chipId, uint32_t rate);
1240 #endif
1241
1242 private:
1243 /**
1244 * @brief Hardware manufacturer (Used for SysEx)
1245 */
1246 enum
1247 {
1248 Manufacturer_Roland = 0x41,
1249 Manufacturer_Yamaha = 0x43,
1250 Manufacturer_UniversalNonRealtime = 0x7E,
1251 Manufacturer_UniversalRealtime = 0x7F
1252 };
1253
1254 /**
1255 * @brief Roland Mode (Used for SysEx)
1256 */
1257 enum
1258 {
1259 RolandMode_Request = 0x11,
1260 RolandMode_Send = 0x12
1261 };
1262
1263 /**
1264 * @brief Device model (Used for SysEx)
1265 */
1266 enum
1267 {
1268 RolandModel_GS = 0x42,
1269 RolandModel_SC55 = 0x45,
1270 YamahaModel_XG = 0x4C
1271 };
1272
1273 /**
1274 * @brief Process generic SysEx events
1275 * @param dev Device ID
1276 * @param realtime Is real-time event
1277 * @param data Raw SysEx data
1278 * @param size Size of given SysEx data
1279 * @return true when event was successfully handled
1280 */
1281 bool doUniversalSysEx(unsigned dev, bool realtime, const uint8_t *data, size_t size);
1282
1283 /**
1284 * @brief Process events specific to Roland devices
1285 * @param dev Device ID
1286 * @param data Raw SysEx data
1287 * @param size Size of given SysEx data
1288 * @return true when event was successfully handled
1289 */
1290 bool doRolandSysEx(unsigned dev, const uint8_t *data, size_t size);
1291
1292 /**
1293 * @brief Process events specific to Yamaha devices
1294 * @param dev Device ID
1295 * @param data Raw SysEx data
1296 * @param size Size of given SysEx data
1297 * @return true when event was successfully handled
1298 */
1299 bool doYamahaSysEx(unsigned dev, const uint8_t *data, size_t size);
1300
1301 private:
1302 /**
1303 * @brief Note Update properties
1304 */
1305 enum
1306 {
1307 Upd_Patch = 0x1,
1308 Upd_Pan = 0x2,
1309 Upd_Volume = 0x4,
1310 Upd_Pitch = 0x8,
1311 Upd_All = Upd_Pan + Upd_Volume + Upd_Pitch,
1312 Upd_Off = 0x20,
1313 Upd_Mute = 0x40,
1314 Upd_OffMute = Upd_Off + Upd_Mute
1315 };
1316
1317 /**
1318 * @brief Update active note
1319 * @param MidCh MIDI Channel where note is processing
1320 * @param i Iterator that points to active note in the MIDI channel
1321 * @param props_mask Properties to update
1322 * @param select_adlchn Specify chip channel, or -1 - all chip channels used by the note
1323 */
1324 void noteUpdate(size_t midCh,
1325 MIDIchannel::activenoteiterator i,
1326 unsigned props_mask,
1327 int32_t select_adlchn = -1);
1328
1329 /**
1330 * @brief Update all notes in specified MIDI channel
1331 * @param midCh MIDI channel to update all notes in it
1332 * @param props_mask Properties to update
1333 */
1334 void noteUpdateAll(size_t midCh, unsigned props_mask);
1335
1336 /**
1337 * @brief Determine how good a candidate this adlchannel would be for playing a note from this instrument.
1338 * @param c Wanted chip channel
1339 * @param ins Instrument wanted to be used in this channel
1340 * @return Calculated coodness points
1341 */
1342 int64_t calculateChipChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins) const;
1343
1344 /**
1345 * @brief A new note will be played on this channel using this instrument.
1346 * @param c Wanted chip channel
1347 * @param ins Instrument wanted to be used in this channel
1348 * Kill existing notes on this channel (or don't, if we do arpeggio)
1349 */
1350 void prepareChipChannelForNewNote(size_t c, const MIDIchannel::NoteInfo::Phys &ins);
1351
1352 /**
1353 * @brief Kills note that uses wanted channel. When arpeggio is possible, note is evaluating to another channel
1354 * @param from_channel Wanted chip channel
1355 * @param j Chip channel instance
1356 * @param i MIDI Channel active note instance
1357 */
1358 void killOrEvacuate(
1359 size_t from_channel,
1360 AdlChannel::LocationData *j,
1361 MIDIchannel::activenoteiterator i);
1362
1363 /**
1364 * @brief Off all notes and silence sound
1365 */
1366 void panic();
1367
1368 /**
1369 * @brief Kill note, sustaining by pedal or sostenuto
1370 * @param MidCh MIDI channel, -1 - all MIDI channels
1371 * @param this_adlchn Chip channel, -1 - all chip channels
1372 * @param sustain_type Type of systain to process
1373 */
1374 void killSustainingNotes(int32_t midCh = -1,
1375 int32_t this_adlchn = -1,
1376 uint32_t sustain_type = AdlChannel::LocationData::Sustain_ANY);
1377 /**
1378 * @brief Find active notes and mark them as sostenuto-sustained
1379 * @param MidCh MIDI channel, -1 - all MIDI channels
1380 */
1381 void markSostenutoNotes(int32_t midCh = -1);
1382
1383 /**
1384 * @brief Set RPN event value
1385 * @param MidCh MIDI channel
1386 * @param value 1 byte part of RPN value
1387 * @param MSB is MSB or LSB part of value
1388 */
1389 void setRPN(size_t midCh, unsigned value, bool MSB);
1390
1391 /**
1392 * @brief Update portamento setup in MIDI channel
1393 * @param midCh MIDI channel where portamento needed to be updated
1394 */
1395 void updatePortamento(size_t midCh);
1396
1397 /**
1398 * @brief Off the note
1399 * @param midCh MIDI channel
1400 * @param note Note to off
1401 */
1402 void noteOff(size_t midCh, uint8_t note);
1403
1404 /**
1405 * @brief Update processing of vibrato to amount of seconds
1406 * @param amount Amount value in seconds
1407 */
1408 void updateVibrato(double amount);
1409
1410 /**
1411 * @brief Update auto-arpeggio
1412 * @param amount Amount value in seconds [UNUSED]
1413 */
1414 void updateArpeggio(double /*amount*/);
1415
1416 /**
1417 * @brief Update Portamento gliding to amount of seconds
1418 * @param amount Amount value in seconds
1419 */
1420 void updateGlide(double amount);
1421
1422 public:
1423 /**
1424 * @brief Checks was device name used or not
1425 * @param name Name of MIDI device
1426 * @return Offset of the MIDI Channels, multiple to 16
1427 */
1428 size_t chooseDevice(const std::string &name);
1429
1430 /**
1431 * @brief Gets a textual description of the state of chip channels
1432 * @param text character pointer for text
1433 * @param attr character pointer for text attributes
1434 * @param size number of characters available to write
1435 */
1436 void describeChannels(char *text, char *attr, size_t size);
1437 };
1438
1439 // I think, this is useless inside of Library
1440 /*
1441 struct FourChars
1442 {
1443 char ret[4];
1444
1445 FourChars(const char *s)
1446 {
1447 for(unsigned c = 0; c < 4; ++c)
1448 ret[c] = s[c];
1449 }
1450 FourChars(unsigned w) // Little-endian
1451 {
1452 for(unsigned c = 0; c < 4; ++c)
1453 ret[c] = static_cast<int8_t>((w >>(c * 8)) & 0xFF);
1454 }
1455 };
1456 */
1457
1458 #if defined(ADLMIDI_AUDIO_TICK_HANDLER)
1459 extern void adl_audioTickHandler(void *instance, uint32_t chipId, uint32_t rate);
1460 #endif
1461 extern int adlRefreshNumCards(ADL_MIDIPlayer *device);
1462
1463
1464 #endif // ADLMIDI_PRIVATE_HPP
1465