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