1 /*
2  * libOPNMIDI is a free Software MIDI synthesizer library with OPN2 (YM2612) emulation
3  *
4  * MIDI parser and player (Original code from ADLMIDI): Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
5  * OPNMIDI Library and YM2612 support:   Copyright (c) 2017-2020 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 "opnmidi_opn2.hpp"
25 #include "opnmidi_private.hpp"
26 
27 #if defined(OPNMIDI_DISABLE_NUKED_EMULATOR) && defined(OPNMIDI_DISABLE_MAME_EMULATOR) && \
28     defined(OPNMIDI_DISABLE_GENS_EMULATOR) && defined(OPNMIDI_DISABLE_GX_EMULATOR) && \
29     defined(OPNMIDI_DISABLE_NP2_EMULATOR) && defined(OPNMIDI_DISABLE_MAME_2608_EMULATOR) && \
30     defined(OPNMIDI_DISABLE_PMDWIN_EMULATOR)
31 #error "No emulators enabled. You must enable at least one emulator to use this library!"
32 #endif
33 
34 // Nuked OPN2 emulator, Most accurate, but requires the powerful CPU
35 #ifndef OPNMIDI_DISABLE_NUKED_EMULATOR
36 #include "chips/nuked_opn2.h"
37 #endif
38 
39 // MAME YM2612 emulator, Well-accurate and fast
40 #ifndef OPNMIDI_DISABLE_MAME_EMULATOR
41 #include "chips/mame_opn2.h"
42 #endif
43 
44 // GENS 2.10 emulator, very outdated and inaccurate, but gives the best performance
45 #ifndef OPNMIDI_DISABLE_GENS_EMULATOR
46 #include "chips/gens_opn2.h"
47 #endif
48 
49 // Genesis Plus GX emulator, Variant of MAME with enhancements
50 #ifndef OPNMIDI_DISABLE_GX_EMULATOR
51 #include "chips/gx_opn2.h"
52 #endif
53 
54 // Neko Project II OPNA emulator
55 #ifndef OPNMIDI_DISABLE_NP2_EMULATOR
56 #include "chips/np2_opna.h"
57 #endif
58 
59 // MAME YM2608 emulator
60 #ifndef OPNMIDI_DISABLE_MAME_2608_EMULATOR
61 #include "chips/mame_opna.h"
62 #endif
63 
64 // PMDWin OPNA emulator
65 #ifndef OPNMIDI_DISABLE_PMDWIN_EMULATOR
66 #include "chips/pmdwin_opna.h"
67 #endif
68 
69 // VGM File dumper
70 #ifdef OPNMIDI_MIDI2VGM
71 #include "chips/vgm_file_dumper.h"
72 #endif
73 
74 static const unsigned opn2_emulatorSupport = 0
75 #ifndef OPNMIDI_DISABLE_NUKED_EMULATOR
76     | (1u << OPNMIDI_EMU_NUKED)
77 #endif
78 #ifndef OPNMIDI_DISABLE_MAME_EMULATOR
79     | (1u << OPNMIDI_EMU_MAME)
80 #endif
81 #ifndef OPNMIDI_DISABLE_GENS_EMULATOR
82     | (1u << OPNMIDI_EMU_GENS)
83 #endif
84 #ifndef OPNMIDI_DISABLE_GX_EMULATOR
85     | (1u << OPNMIDI_EMU_GX)
86 #endif
87 #ifndef OPNMIDI_DISABLE_NP2_EMULATOR
88     | (1u << OPNMIDI_EMU_NP2)
89 #endif
90 #ifndef OPNMIDI_DISABLE_MAME_2608_EMULATOR
91     | (1u << OPNMIDI_EMU_MAME_2608)
92 #endif
93 #ifndef OPNMIDI_DISABLE_PMDWIN_EMULATOR
94     | (1u << OPNMIDI_EMU_PMDWIN)
95 #endif
96 #ifdef OPNMIDI_MIDI2VGM
97     | (1u << OPNMIDI_VGM_DUMPER)
98 #endif
99 ;
100 
101 //! Check emulator availability
opn2_isEmulatorAvailable(int emulator)102 bool opn2_isEmulatorAvailable(int emulator)
103 {
104     return (opn2_emulatorSupport & (1u << (unsigned)emulator)) != 0;
105 }
106 
107 //! Find highest emulator
opn2_getHighestEmulator()108 int opn2_getHighestEmulator()
109 {
110     int emu = -1;
111     for(unsigned m = opn2_emulatorSupport; m > 0; m >>= 1)
112         ++emu;
113     return emu;
114 }
115 
116 //! Find lowest emulator
opn2_getLowestEmulator()117 int opn2_getLowestEmulator()
118 {
119     int emu = -1;
120     unsigned m = opn2_emulatorSupport;
121     if(m > 0)
122     {
123         for(emu = 0; (m & 1) == 0; m >>= 1)
124             ++emu;
125     }
126     return emu;
127 }
128 
129 
130 
131 /***************************************************************
132  *                    Volume model tables                      *
133  ***************************************************************/
134 
135 // Mapping from MIDI volume level to OPL level value.
136 
137 static const uint_fast32_t s_dmx_volume_model[128] =
138 {
139     0,  1,  3,  5,  6,  8,  10, 11,
140     13, 14, 16, 17, 19, 20, 22, 23,
141     25, 26, 27, 29, 30, 32, 33, 34,
142     36, 37, 39, 41, 43, 45, 47, 49,
143     50, 52, 54, 55, 57, 59, 60, 61,
144     63, 64, 66, 67, 68, 69, 71, 72,
145     73, 74, 75, 76, 77, 79, 80, 81,
146     82, 83, 84, 84, 85, 86, 87, 88,
147     89, 90, 91, 92, 92, 93, 94, 95,
148     96, 96, 97, 98, 99, 99, 100, 101,
149     101, 102, 103, 103, 104, 105, 105, 106,
150     107, 107, 108, 109, 109, 110, 110, 111,
151     112, 112, 113, 113, 114, 114, 115, 115,
152     116, 117, 117, 118, 118, 119, 119, 120,
153     120, 121, 121, 122, 122, 123, 123, 123,
154     124, 124, 125, 125, 126, 126, 127, 127,
155 };
156 
157 static const uint_fast32_t W9X_volume_mapping_table[32] =
158 {
159     63, 63, 40, 36, 32, 28, 23, 21,
160     19, 17, 15, 14, 13, 12, 11, 10,
161     9,  8,  7,  6,  5,  5,  4,  4,
162     3,  3,  2,  2,  1,  1,  0,  0
163 };
164 
165 static const uint32_t g_noteChannelsMap[6] = { 0, 1, 2, 4, 5, 6 };
166 
getOpnChannel(size_t in_channel,size_t & out_chip,uint8_t & out_port,uint32_t & out_ch)167 static inline void getOpnChannel(size_t     in_channel,
168                                  size_t     &out_chip,
169                                  uint8_t    &out_port,
170                                  uint32_t   &out_ch)
171 {
172     out_chip    = in_channel / 6;
173     size_t ch4 = in_channel % 6;
174     out_port = ((ch4 < 3) ? 0 : 1);
175     out_ch = static_cast<uint32_t>(ch4 % 3);
176 }
177 
178 
179 /***************************************************************
180  *               Standard frequency formula                    *
181  * *************************************************************/
182 
s_commonFreq(double tone)183 static inline double s_commonFreq(double tone)
184 {
185     return std::exp(0.057762265 * tone);
186 }
187 
188 
189 
190 enum
191 {
192     MasterVolumeDefault = 127
193 };
194 
195 enum
196 {
197     OPN_PANNING_LEFT  = 0x80,
198     OPN_PANNING_RIGHT = 0x40,
199     OPN_PANNING_BOTH  = 0xC0
200 };
201 
makeEmptyInstrument()202 static OpnInstMeta makeEmptyInstrument()
203 {
204     OpnInstMeta ins;
205     memset(&ins, 0, sizeof(OpnInstMeta));
206     ins.flags = OpnInstMeta::Flag_NoSound;
207     return ins;
208 }
209 
210 const OpnInstMeta OPN2::m_emptyInstrument = makeEmptyInstrument();
211 
OPN2()212 OPN2::OPN2() :
213     m_regLFOSetup(0),
214     m_numChips(1),
215     m_scaleModulators(false),
216     m_runAtPcmRate(false),
217     m_softPanning(false),
218     m_masterVolume(MasterVolumeDefault),
219     m_musicMode(MODE_MIDI),
220     m_volumeScale(VOLUME_Generic),
221     m_lfoEnable(false),
222     m_lfoFrequency(0),
223     m_chipFamily(OPNChip_OPN2)
224 {
225     m_insBankSetup.volumeModel = OPN2::VOLUME_Generic;
226     m_insBankSetup.lfoEnable = false;
227     m_insBankSetup.lfoFrequency = 0;
228     m_insBankSetup.chipType = OPNChip_OPN2;
229 
230     // Initialize blank instruments banks
231     m_insBanks.clear();
232 }
233 
~OPN2()234 OPN2::~OPN2()
235 {
236     clearChips();
237 }
238 
setupLocked()239 bool OPN2::setupLocked()
240 {
241     return (m_musicMode == MODE_CMF ||
242             m_musicMode == MODE_IMF ||
243             m_musicMode == MODE_RSXX);
244 }
245 
writeReg(size_t chip,uint8_t port,uint8_t index,uint8_t value)246 void OPN2::writeReg(size_t chip, uint8_t port, uint8_t index, uint8_t value)
247 {
248     m_chips[chip]->writeReg(port, index, value);
249 }
250 
writeRegI(size_t chip,uint8_t port,uint32_t index,uint32_t value)251 void OPN2::writeRegI(size_t chip, uint8_t port, uint32_t index, uint32_t value)
252 {
253     m_chips[chip]->writeReg(port, static_cast<uint8_t>(index), static_cast<uint8_t>(value));
254 }
255 
writePan(size_t chip,uint32_t index,uint32_t value)256 void OPN2::writePan(size_t chip, uint32_t index, uint32_t value)
257 {
258     m_chips[chip]->writePan(static_cast<uint16_t>(index), static_cast<uint8_t>(value));
259 }
260 
noteOff(size_t c)261 void OPN2::noteOff(size_t c)
262 {
263     size_t      chip;
264     uint8_t     port;
265     uint32_t    cc;
266     size_t      ch4 = c % 6;
267     getOpnChannel(c, chip, port, cc);
268     writeRegI(chip, 0, 0x28, g_noteChannelsMap[ch4]);
269 }
270 
noteOn(size_t c,double tone)271 void OPN2::noteOn(size_t c, double tone)
272 {
273     // Hertz range: 0..131071
274     double hertz = s_commonFreq(tone);
275 
276     if(hertz < 0) // Avoid infinite loop
277         return;
278 
279     double coef;
280     switch(m_chipFamily)
281     {
282     case OPNChip_OPN2: default:
283         coef = 321.88557; break;
284     case OPNChip_OPNA:
285         coef = 309.12412; break;
286     }
287     hertz *= coef;
288 
289     size_t      chip;
290     uint8_t     port;
291     uint32_t    cc;
292     size_t      ch4 = c % 6;
293     getOpnChannel(c, chip, port, cc);
294 
295     uint32_t octave = 0, ftone = 0, mul_offset = 0;
296     const OpnTimbre &adli = m_insCache[c];
297 
298     //Basic range until max of octaves reaching
299     while((hertz >= 1023.75) && (octave < 0x3800))
300     {
301         hertz /= 2.0;    // Calculate octave
302         octave += 0x800;
303     }
304     //Extended range, rely on frequency multiplication increment
305     while(hertz >= 2036.75)
306     {
307         hertz /= 2.0;    // Calculate octave
308         mul_offset++;
309     }
310     ftone = octave + static_cast<uint32_t>(hertz + 0.5);
311 
312     for(size_t op = 0; op < 4; op++)
313     {
314         uint32_t reg = adli.OPS[op].data[0];
315         uint16_t address = static_cast<uint16_t>(0x30 + (op * 4) + cc);
316         if(mul_offset > 0) // Increase frequency multiplication value
317         {
318             uint32_t dt  = reg & 0xF0;
319             uint32_t mul = reg & 0x0F;
320             if((mul + mul_offset) > 0x0F)
321             {
322                 mul_offset = 0;
323                 mul = 0x0F;
324             }
325             writeRegI(chip, port, address, uint8_t(dt | (mul + mul_offset)));
326         }
327         else
328         {
329             writeRegI(chip, port, address, uint8_t(reg));
330         }
331     }
332 
333     writeRegI(chip, port, 0xA4 + cc, (ftone>>8) & 0xFF);//Set frequency and octave
334     writeRegI(chip, port, 0xA0 + cc, ftone & 0xFF);
335     writeRegI(chip, 0, 0x28, 0xF0 + g_noteChannelsMap[ch4]);
336 }
337 
touchNote(size_t c,uint_fast32_t velocity,uint_fast32_t channelVolume,uint_fast32_t channelExpression,uint8_t brightness)338 void OPN2::touchNote(size_t c,
339                      uint_fast32_t velocity,
340                      uint_fast32_t channelVolume,
341                      uint_fast32_t channelExpression,
342                      uint8_t brightness)
343 {
344     size_t      chip;
345     uint8_t     port;
346     uint32_t    cc;
347     getOpnChannel(c, chip, port, cc);
348 
349     const OpnTimbre &adli = m_insCache[c];
350 
351     uint_fast32_t volume = 0;
352 
353     uint8_t op_vol[4] =
354     {
355         adli.OPS[OPERATOR1].data[1],
356         adli.OPS[OPERATOR2].data[1],
357         adli.OPS[OPERATOR3].data[1],
358         adli.OPS[OPERATOR4].data[1],
359     };
360 
361     bool alg_do[8][4] =
362     {
363         /*
364          * Yeah, Operator 2 and 3 are seems swapped
365          * which we can see in the algorithm 4
366          */
367         //OP1   OP3   OP2    OP4
368         //30    34    38     3C
369         {false,false,false,true},//Algorithm #0:  W = 1 * 2 * 3 * 4
370         {false,false,false,true},//Algorithm #1:  W = (1 + 2) * 3 * 4
371         {false,false,false,true},//Algorithm #2:  W = (1 + (2 * 3)) * 4
372         {false,false,false,true},//Algorithm #3:  W = ((1 * 2) + 3) * 4
373         {false,false,true, true},//Algorithm #4:  W = (1 * 2) + (3 * 4)
374         {false,true ,true ,true},//Algorithm #5:  W = (1 * (2 + 3 + 4)
375         {false,true ,true ,true},//Algorithm #6:  W = (1 * 2) + 3 + 4
376         {true ,true ,true ,true},//Algorithm #7:  W = 1 + 2 + 3 + 4
377     };
378 
379     switch(m_volumeScale)
380     {
381     default:
382     case Synth::VOLUME_Generic:
383     {
384         volume = velocity * m_masterVolume *
385                  channelVolume * channelExpression;
386 
387         /* If the channel has arpeggio, the effective volume of
388              * *this* instrument is actually lower due to timesharing.
389              * To compensate, add extra volume that corresponds to the
390              * time this note is *not* heard.
391              * Empirical tests however show that a full equal-proportion
392              * increment sounds wrong. Therefore, using the square root.
393              */
394         //volume = (int)(volume * std::sqrt( (double) ch[c].users.size() ));
395         const double c1 = 11.541560327111707;
396         const double c2 = 1.601379199767093e+02;
397         const uint_fast32_t minVolume = 1108075; // 8725 * 127
398 
399         // The formula below: SOLVE(V=127^4 * 2^( (A-63.49999) / 8), A)
400         if(volume > minVolume)
401         {
402             double lv = std::log(static_cast<double>(volume));
403             volume = static_cast<uint_fast32_t>(lv * c1 - c2) * 2;
404         }
405         else
406             volume = 0;
407     }
408     break;
409 
410     case Synth::VOLUME_NATIVE:
411     {
412         volume = velocity * channelVolume * channelExpression;
413         //volume = volume * m_masterVolume / (127 * 127 * 127) / 2;
414         volume = (volume * m_masterVolume) / 4096766;
415     }
416     break;
417 
418     case Synth::VOLUME_DMX:
419     {
420         volume = (channelVolume * channelExpression * m_masterVolume) / 16129;
421         volume = (s_dmx_volume_model[volume] + 1) << 1;
422         volume = (s_dmx_volume_model[(velocity < 128) ? velocity : 127] * volume) >> 9;
423 
424         if(volume > 0)
425             volume += 64;//OPN has 0~127 range. As 0...63 is almost full silence, but at 64 to 127 is very closed to OPL3, just add 64.
426     }
427     break;
428 
429     case Synth::VOLUME_APOGEE:
430     {
431         volume = (channelVolume * channelExpression * m_masterVolume / 16129);
432         volume = ((64 * (velocity + 0x80)) * volume) >> 15;
433         //volume = ((63 * (vol + 0x80)) * Ch[MidCh].volume) >> 15;
434         if(volume > 0)
435             volume += 64;//OPN has 0~127 range. As 0...63 is almost full silence, but at 64 to 127 is very closed to OPL3, just add 64.
436     }
437     break;
438 
439     case Synth::VOLUME_9X:
440     {
441         //volume = 63 - W9X_volume_mapping_table[(((vol * Ch[MidCh].volume /** Ch[MidCh].expression*/) * 127 / 16129 /*2048383*/) >> 2)];
442         volume = 63 - W9X_volume_mapping_table[((velocity * channelVolume * channelExpression * m_masterVolume / 2048383) >> 2)];
443         //volume = W9X_volume_mapping_table[vol >> 2] + volume;
444         if(volume > 0)
445             volume += 64;//OPN has 0~127 range. As 0...63 is almost full silence, but at 64 to 127 is very closed to OPL3, just add 64.
446     }
447     break;
448     }
449 
450 
451     if(volume > 127)
452         volume = 127;
453 
454     uint8_t alg = adli.fbalg & 0x07;
455     for(uint8_t op = 0; op < 4; op++)
456     {
457         bool do_op = alg_do[alg][op] || m_scaleModulators;
458         uint32_t x = op_vol[op];
459         uint32_t vol_res = do_op ? (127 - (static_cast<uint32_t>(volume) * (127 - (x & 127))) / 127) : x;
460         if(brightness != 127)
461         {
462             brightness = static_cast<uint32_t>(::round(127.0 * ::sqrt((static_cast<double>(brightness)) * (1.0 / 127.0))));
463             if(!do_op)
464                 vol_res = (127 - (brightness * (127 - (static_cast<uint32_t>(vol_res) & 127))) / 127);
465         }
466         writeRegI(chip, port, 0x40 + cc + (4 * op), vol_res);
467     }
468     // Correct formula (ST3, AdPlug):
469     //   63-((63-(instrvol))/63)*chanvol
470     // Reduces to (tested identical):
471     //   63 - chanvol + chanvol*instrvol/63
472     // Also (slower, floats):
473     //   63 + chanvol * (instrvol / 63.0 - 1)
474 }
475 
setPatch(size_t c,const OpnTimbre & instrument)476 void OPN2::setPatch(size_t c, const OpnTimbre &instrument)
477 {
478     size_t      chip;
479     uint8_t     port;
480     uint32_t    cc;
481     getOpnChannel(c, chip, port, cc);
482     m_insCache[c] = instrument;
483     for(uint8_t d = 0; d < 7; d++)
484     {
485         for(uint8_t op = 0; op < 4; op++)
486             writeRegI(chip, port, 0x30 + (0x10 * d) + (op * 4) + cc, instrument.OPS[op].data[d]);
487     }
488 
489     writeRegI(chip, port, 0xB0 + cc, instrument.fbalg);//Feedback/Algorithm
490     m_regLFOSens[c] = (m_regLFOSens[c] & 0xC0) | (instrument.lfosens & 0x3F);
491     writeRegI(chip, port, 0xB4 + cc, m_regLFOSens[c]);//Panorame and LFO bits
492 }
493 
setPan(size_t c,uint8_t value)494 void OPN2::setPan(size_t c, uint8_t value)
495 {
496     size_t      chip;
497     uint8_t     port;
498     uint32_t    cc;
499     getOpnChannel(c, chip, port, cc);
500     const OpnTimbre &adli = m_insCache[c];
501     uint8_t val = 0;
502     if(m_softPanning)
503     {
504         val = (OPN_PANNING_BOTH & 0xC0) | (adli.lfosens & 0x3F);
505         writePan(chip, c % 6, value);
506         writeRegI(chip, port, 0xB4 + cc, val);
507     }
508     else
509     {
510         int panning = 0;
511         if(value  < 64 + 32) panning |= OPN_PANNING_LEFT;
512         if(value >= 64 - 32) panning |= OPN_PANNING_RIGHT;
513         val = (panning & 0xC0) | (adli.lfosens & 0x3F);
514         writePan(chip, c % 6, 64);
515         writeRegI(chip, port, 0xB4 + cc, val);
516     }
517     m_regLFOSens[c] = val;
518 }
519 
silenceAll()520 void OPN2::silenceAll() // Silence all OPL channels.
521 {
522     for(size_t c = 0; c < m_numChannels; ++c)
523     {
524         noteOff(c);
525         touchNote(c, 0);
526     }
527 }
528 
commitLFOSetup()529 void OPN2::commitLFOSetup()
530 {
531     uint8_t regLFOSetup = (m_lfoEnable ? 8 : 0) | (m_lfoFrequency & 7);
532     m_regLFOSetup = regLFOSetup;
533     for(size_t chip = 0; chip < m_numChips; ++chip)
534         writeReg(chip, 0, 0x22, regLFOSetup);
535 }
536 
setVolumeScaleModel(OPNMIDI_VolumeModels volumeModel)537 void OPN2::setVolumeScaleModel(OPNMIDI_VolumeModels volumeModel)
538 {
539     switch(volumeModel)
540     {
541     case OPNMIDI_VolumeModel_AUTO://Do nothing until restart playing
542         break;
543 
544     case OPNMIDI_VolumeModel_Generic:
545         m_volumeScale = OPN2::VOLUME_Generic;
546         break;
547 
548     case OPNMIDI_VolumeModel_NativeOPN2:
549         m_volumeScale = OPN2::VOLUME_NATIVE;
550         break;
551 
552     case OPNMIDI_VolumeModel_DMX:
553         m_volumeScale = OPN2::VOLUME_DMX;
554         break;
555 
556     case OPNMIDI_VolumeModel_APOGEE:
557         m_volumeScale = OPN2::VOLUME_APOGEE;
558         break;
559 
560     case OPNMIDI_VolumeModel_9X:
561         m_volumeScale = OPN2::VOLUME_9X;
562         break;
563     }
564 }
565 
getVolumeScaleModel()566 OPNMIDI_VolumeModels OPN2::getVolumeScaleModel()
567 {
568     switch(m_volumeScale)
569     {
570     default:
571     case OPN2::VOLUME_Generic:
572         return OPNMIDI_VolumeModel_Generic;
573     case OPN2::VOLUME_NATIVE:
574         return OPNMIDI_VolumeModel_NativeOPN2;
575     case OPN2::VOLUME_DMX:
576         return OPNMIDI_VolumeModel_DMX;
577     case OPN2::VOLUME_APOGEE:
578         return OPNMIDI_VolumeModel_APOGEE;
579     case OPN2::VOLUME_9X:
580         return OPNMIDI_VolumeModel_9X;
581     }
582 }
583 
clearChips()584 void OPN2::clearChips()
585 {
586     for(size_t i = 0; i < m_chips.size(); i++)
587         m_chips[i].reset(NULL);
588     m_chips.clear();
589 }
590 
reset(int emulator,unsigned long PCM_RATE,OPNFamily family,void * audioTickHandler)591 void OPN2::reset(int emulator, unsigned long PCM_RATE, OPNFamily family, void *audioTickHandler)
592 {
593 #if !defined(ADLMIDI_AUDIO_TICK_HANDLER)
594     ADL_UNUSED(audioTickHandler);
595 #endif
596     clearChips();
597     m_insCache.clear();
598     m_regLFOSens.clear();
599 #ifdef OPNMIDI_MIDI2VGM
600     if(emulator == OPNMIDI_VGM_DUMPER && (m_numChips > 2))
601         m_numChips = 2;// VGM Dumper can't work in multichip mode
602 #endif
603     m_chips.resize(m_numChips, AdlMIDI_SPtr<OPNChipBase>());
604 
605 #ifdef OPNMIDI_MIDI2VGM
606     m_loopStartHook = NULL;
607     m_loopStartHookData = NULL;
608     m_loopEndHook = NULL;
609     m_loopEndHookData = NULL;
610 #endif
611 
612     for(size_t i = 0; i < m_chips.size(); i++)
613     {
614         OPNChipBase *chip;
615 
616         switch(emulator)
617         {
618         default:
619             assert(false);
620             abort();
621 #ifndef OPNMIDI_DISABLE_MAME_EMULATOR
622         case OPNMIDI_EMU_MAME:
623             chip = new MameOPN2(family);
624             break;
625 #endif
626 #ifndef OPNMIDI_DISABLE_NUKED_EMULATOR
627         case OPNMIDI_EMU_NUKED:
628             chip = new NukedOPN2(family);
629             break;
630 #endif
631 #ifndef OPNMIDI_DISABLE_GENS_EMULATOR
632         case OPNMIDI_EMU_GENS:
633             chip = new GensOPN2(family);
634             break;
635 #endif
636 #ifndef OPNMIDI_DISABLE_GX_EMULATOR
637         case OPNMIDI_EMU_GX:
638             chip = new GXOPN2(family);
639             break;
640 #endif
641 #ifndef OPNMIDI_DISABLE_NP2_EMULATOR
642         case OPNMIDI_EMU_NP2:
643             chip = new NP2OPNA<>(family);
644             break;
645 #endif
646 #ifndef OPNMIDI_DISABLE_MAME_2608_EMULATOR
647         case OPNMIDI_EMU_MAME_2608:
648             chip = new MameOPNA(family);
649             break;
650 #endif
651 #ifndef OPNMIDI_DISABLE_PMDWIN_EMULATOR
652         case OPNMIDI_EMU_PMDWIN:
653             chip = new PMDWinOPNA(family);
654             break;
655 #endif
656 #ifdef OPNMIDI_MIDI2VGM
657         case OPNMIDI_VGM_DUMPER:
658             chip = new VGMFileDumper(family);
659             if(i == 0)//Set hooks for first chip only
660             {
661                 m_loopStartHook = &VGMFileDumper::loopStartHook;
662                 m_loopStartHookData = chip;
663                 m_loopEndHook  = &VGMFileDumper::loopEndHook;
664                 m_loopEndHookData = chip;
665             }
666             break;
667 #endif
668         }
669         m_chips[i].reset(chip);
670         chip->setChipId(static_cast<uint32_t>(i));
671         chip->setRate(static_cast<uint32_t>(PCM_RATE), chip->nativeClockRate());
672         if(m_runAtPcmRate)
673             chip->setRunningAtPcmRate(true);
674 #if defined(ADLMIDI_AUDIO_TICK_HANDLER)
675         chip->setAudioTickHandlerInstance(audioTickHandler);
676 #endif
677         family = chip->family();
678     }
679 
680     m_chipFamily = family;
681     m_numChannels = m_numChips * 6;
682     m_insCache.resize(m_numChannels,   m_emptyInstrument.op[0]);
683     m_regLFOSens.resize(m_numChannels,    0);
684 
685     uint8_t regLFOSetup = (m_lfoEnable ? 8 : 0) | (m_lfoFrequency & 7);
686     m_regLFOSetup = regLFOSetup;
687 
688     for(size_t card = 0; card < m_numChips; ++card)
689     {
690         writeReg(card, 0, 0x22, regLFOSetup);//push current LFO state
691         writeReg(card, 0, 0x27, 0x00);  //set Channel 3 normal mode
692         writeReg(card, 0, 0x2B, 0x00);  //Disable DAC
693         //Shut up all channels
694         writeReg(card, 0, 0x28, 0x00 ); //Note Off 0 channel
695         writeReg(card, 0, 0x28, 0x01 ); //Note Off 1 channel
696         writeReg(card, 0, 0x28, 0x02 ); //Note Off 2 channel
697         writeReg(card, 0, 0x28, 0x04 ); //Note Off 3 channel
698         writeReg(card, 0, 0x28, 0x05 ); //Note Off 4 channel
699         writeReg(card, 0, 0x28, 0x06 ); //Note Off 5 channel
700     }
701 
702     silenceAll();
703 #ifdef OPNMIDI_MIDI2VGM
704     if(m_loopStartHook) // Post-initialization Loop Start hook (fix for loop edge passing clicks)
705         m_loopStartHook(m_loopStartHookData);
706 #endif
707 }
708 
chipFamily() const709 OPNFamily OPN2::chipFamily() const
710 {
711     return m_chipFamily;
712 }
713