diff options
-rw-r--r-- | fm_banks/wopl_files/lostvik.wopl | bin | 31899 -> 31899 bytes | |||
-rw-r--r-- | include/adlmidi.h | 19 | ||||
-rw-r--r-- | src/adlmidi.cpp | 35 | ||||
-rw-r--r-- | src/adlmidi_load.cpp | 4 | ||||
-rw-r--r-- | src/adlmidi_midiplay.cpp | 19 | ||||
-rw-r--r-- | src/adlmidi_private.cpp | 19 | ||||
-rw-r--r-- | src/adlmidi_xmi2mid.c | 7 | ||||
-rw-r--r-- | utils/adlmidi-2/midiplay.cc | 2 | ||||
-rw-r--r-- | utils/midiplay/adlmidiplay.cpp | 8 |
9 files changed, 86 insertions, 27 deletions
diff --git a/fm_banks/wopl_files/lostvik.wopl b/fm_banks/wopl_files/lostvik.wopl Binary files differindex fe19ef9..ce2c07e 100644 --- a/fm_banks/wopl_files/lostvik.wopl +++ b/fm_banks/wopl_files/lostvik.wopl diff --git a/include/adlmidi.h b/include/adlmidi.h index 1073721..1a613cf 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -58,8 +58,14 @@ struct ADL_MIDIPlayer void *adl_midiPlayer; }; -/* Sets number of emulated sound cards (from 1 to 100). Emulation of multiple sound cards exchanges polyphony limits*/ -extern int adl_setNumCards(struct ADL_MIDIPlayer *device, int numCards); +//DEPRECATED +#define adl_setNumCards adl_setNumChips + +/* Sets number of emulated chips (from 1 to 100). Emulation of multiple chips exchanges polyphony limits*/ +extern int adl_setNumChips(struct ADL_MIDIPlayer *device, int numCards); + +/* Get current number of emulated chips */ +extern int adl_getNumChips(struct ADL_MIDIPlayer *device); /* Sets a number of the patches bank from 0 to N banks */ extern int adl_setBank(struct ADL_MIDIPlayer *device, int bank); @@ -70,9 +76,16 @@ extern int adl_getBanksCount(); /* Returns pointer to array of names of every bank */ extern const char *const *adl_getBankNames(); -/*Sets number of 4-chan operators*/ +/*Sets number of 4-operator channels between all chips. + By default, it is automatically re-calculating every bank change. + If you want to specify custom number of four operator channels, + please call this function after bank change (adl_setBank() or adl_openBank()), + otherwise, value will be overwritten by auto-calculated.*/ extern int adl_setNumFourOpsChn(struct ADL_MIDIPlayer *device, int ops4); +/*Get current total count of 4-operator channels between all chips*/ +extern int adl_getNumFourOpsChn(struct ADL_MIDIPlayer *device); + /*Override Enable(1) or Disable(0) AdLib percussion mode. -1 - use bank default AdLib percussion mode*/ extern void adl_setPercMode(struct ADL_MIDIPlayer *device, int percmod); diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index b0de729..d6471e9 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -58,7 +58,7 @@ ADLMIDI_EXPORT struct ADL_MIDIPlayer *adl_init(long sample_rate) return midi_device; } -ADLMIDI_EXPORT int adl_setNumCards(ADL_MIDIPlayer *device, int numCards) +ADLMIDI_EXPORT int adl_setNumChips(ADL_MIDIPlayer *device, int numCards) { if(device == NULL) return -2; @@ -78,6 +78,16 @@ ADLMIDI_EXPORT int adl_setNumCards(ADL_MIDIPlayer *device, int numCards) return adlRefreshNumCards(device); } +ADLMIDI_EXPORT int adl_getNumChips(struct ADL_MIDIPlayer *device) +{ + if(device == NULL) + return -2; + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + if(play) + return (int)play->m_setup.NumCards; + return -2; +} + ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank) { #ifdef DISABLE_EMBEDDED_BANKS @@ -123,10 +133,7 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) if(!device) return -1; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); - play->m_setup.NumFourOps = static_cast<unsigned int>(ops4); - play->opl.NumFourOps = play->m_setup.NumFourOps; - - if(play->m_setup.NumFourOps > 6 * play->m_setup.NumCards) + if(ops4 > 6 * play->m_setup.NumCards) { std::stringstream s; s << "number of four-op channels may only be 0.." << (6 * (play->m_setup.NumCards)) << " when " << play->m_setup.NumCards << " OPL3 cards are used.\n"; @@ -134,9 +141,21 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) return -1; } - return adlRefreshNumCards(device); + play->m_setup.NumFourOps = static_cast<unsigned int>(ops4); + play->opl.NumFourOps = play->m_setup.NumFourOps; + + return 0; //adlRefreshNumCards(device); } +ADLMIDI_EXPORT int adl_getNumFourOpsChn(struct ADL_MIDIPlayer *device) +{ + if(!device) + return -1; + MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); + if(play) + return (int)play->m_setup.NumFourOps; + return -1; +} ADLMIDI_EXPORT void adl_setPercMode(ADL_MIDIPlayer *device, int percmod) { @@ -207,7 +226,7 @@ ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, char *filePat play->setErrorString("ADL MIDI: Can't load file"); return -1; } - else return 0; + else return adlRefreshNumCards(device); } ADLMIDI_ErrorString = "Can't load file: ADLMIDI is not initialized"; @@ -228,7 +247,7 @@ ADLMIDI_EXPORT int adl_openBankData(struct ADL_MIDIPlayer *device, void *mem, lo play->setErrorString("ADL MIDI: Can't load data from memory"); return -1; } - else return 0; + else return adlRefreshNumCards(device); } ADLMIDI_ErrorString = "Can't load file: ADL MIDI is not initialized"; diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp index 3eea1b7..359536a 100644 --- a/src/adlmidi_load.cpp +++ b/src/adlmidi_load.cpp @@ -244,6 +244,8 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr) opl.dynamic_melodic_banks.clear(); opl.dynamic_percussion_banks.clear(); + opl.setEmbeddedBank(m_setup.AdlBank); + if(version >= 2)//Read bank meta-entries { for(uint16_t i = 0; i < count_melodic_banks; i++) @@ -279,8 +281,6 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr) } } - opl.setEmbeddedBank(m_setup.AdlBank); - uint16_t total = 128 * count_melodic_banks; bool readPercussion = false; diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 3d8f88c..220b18c 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -897,21 +897,34 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(isPercussion) midiins = opl.dynamic_percussion_offset + note; // Percussion instrument + uint16_t bank = 0; //Set bank bank if(Ch[channel].bank_msb || Ch[channel].bank_lsb) { - uint16_t bank = (uint16_t(Ch[channel].bank_msb) * 256) + uint16_t(Ch[channel].bank_lsb); + bank = (uint16_t(Ch[channel].bank_msb) * 256) + uint16_t(Ch[channel].bank_lsb); if(isPercussion) { OPL3::BankMap::iterator b = opl.dynamic_percussion_banks.find(bank); if(b != opl.dynamic_percussion_banks.end()) midiins += b->second * 128; + else + { + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, + "[%i] Playing missing percussion bank %i (patch %i)", channel, bank, midiins); + } } else { OPL3::BankMap::iterator b = opl.dynamic_melodic_banks.find(bank); if(b != opl.dynamic_melodic_banks.end()) midiins += b->second * 128; + else + { + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, + "[%i] Playing missing melodic bank %i (patch %i)", channel, bank, midiins); + } } } @@ -1063,7 +1076,9 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(c < 0) { if(hooks.onDebugMessage) - hooks.onDebugMessage(hooks.onDebugMessage_userData, "ignored unplaceable note"); + hooks.onDebugMessage(hooks.onDebugMessage_userData, + "ignored unplaceable note [bank %i, inst %i, note %i, MIDI channel %i]", + bank, Ch[channel].patch, note, channel); continue; // Could not play this note. Ignore it. } diff --git a/src/adlmidi_private.cpp b/src/adlmidi_private.cpp index f13aa8c..f06e30e 100644 --- a/src/adlmidi_private.cpp +++ b/src/adlmidi_private.cpp @@ -36,11 +36,17 @@ int adlRefreshNumCards(ADL_MIDIPlayer *device) //For custom bank for(size_t a = 0; a < play->opl.dynamic_metainstruments.size(); ++a) { - ++n_total[a / 128]; + size_t div = (a >= play->opl.dynamic_percussion_offset) ? 1 : 0; + ++n_total[div]; adlinsdata &ins = play->opl.dynamic_metainstruments[a]; if((ins.adlno1 != ins.adlno2) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0)) - ++n_fourop[a / 128]; + ++n_fourop[div]; } + + play->m_setup.NumFourOps = + (n_fourop[0] >= 128 * 7 / 8) ? play->m_setup.NumCards * 6 + : (n_fourop[0] < 128 * 1 / 8) ? 0 + : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); } else { @@ -55,12 +61,13 @@ int adlRefreshNumCards(ADL_MIDIPlayer *device) if((ins.adlno1 != ins.adlno2) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0)) ++n_fourop[a / 128]; } + + play->m_setup.NumFourOps = + (n_fourop[0] >= (n_total[0] % 128) * 7 / 8) ? play->m_setup.NumCards * 6 + : (n_fourop[0] < (n_total[0] % 128) * 1 / 8) ? 0 + : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); } - play->m_setup.NumFourOps = - (n_fourop[0] >= n_total[0] * 7 / 8) ? play->m_setup.NumCards * 6 - : (n_fourop[0] < n_total[0] * 1 / 8) ? 0 - : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); play->opl.NumFourOps = play->m_setup.NumFourOps; if(n_fourop[0] >= n_total[0] * 15 / 16 && play->m_setup.NumFourOps == 0) diff --git a/src/adlmidi_xmi2mid.c b/src/adlmidi_xmi2mid.c index 083b5ed..4fae2a2 100644 --- a/src/adlmidi_xmi2mid.c +++ b/src/adlmidi_xmi2mid.c @@ -643,6 +643,11 @@ static int ConvertEvent(struct xmi_ctx *ctx, const int32_t time, data = read1(ctx); + //HACK! + if (((status >> 4) == 0xB) && (status & 0xF) != 9 && (data == 114)) { + data = 32; //Change XMI 114 controller into XG bank + } + /* Bank changes are handled here */ if ((status >> 4) == 0xB && data == 0) { data = read1(ctx); @@ -659,7 +664,7 @@ static int ConvertEvent(struct xmi_ctx *ctx, const int32_t time, CreateNewEvent(ctx, time); ctx->current->status = status; ctx->current->data[0] = 0; - ctx->current->data[1] = data; + ctx->current->data[1] = data == 127 ? 0 : data;//HACK: if (ctx->convert_type == XMIDI_CONVERT_GS127_TO_GS && data == 127) ctx->bank127[status & 0xF] = 1; diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc index 56721eb..52945dd 100644 --- a/utils/adlmidi-2/midiplay.cc +++ b/utils/adlmidi-2/midiplay.cc @@ -1825,7 +1825,7 @@ int main(int argc, char **argv) UI.ShowCursor(); return 0; } - adl_setNumCards(myDevice, (int)NumCards); + adl_setNumChips(myDevice, (int)NumCards); } if(argc >= 5) diff --git a/utils/midiplay/adlmidiplay.cpp b/utils/midiplay/adlmidiplay.cpp index 1174e3f..5ab9d68 100644 --- a/utils/midiplay/adlmidiplay.cpp +++ b/utils/midiplay/adlmidiplay.cpp @@ -117,7 +117,7 @@ int main(int argc, char **argv) if(argc < 2 || std::string(argv[1]) == "--help" || std::string(argv[1]) == "-h") { std::printf( - "Usage: adlmidi <midifilename> [ <options> ] [ <bank> [ <numcards> [ <numfourops>] ] ]\n" + "Usage: adlmidi <midifilename> [ <options> ] [ <bank> [ <numchips> [ <numfourops>] ] ]\n" " -p Enables adlib percussion instrument mode\n" " -t Enables tremolo amplification mode\n" " -v Enables vibrato amplification mode\n" @@ -289,12 +289,12 @@ int main(int argc, char **argv) numOfChips = std::atoi(argv[3]); //Set count of concurrent emulated chips count to excite channels limit of one chip - if(adl_setNumCards(myDevice, numOfChips) != 0) + if(adl_setNumChips(myDevice, numOfChips) != 0) { printError(adl_errorInfo(myDevice)); return 1; } - std::fprintf(stdout, " - Number of chips %d\n", numOfChips); + std::fprintf(stdout, " - Number of chips %d\n", adl_getNumChips(myDevice)); if(argc >= 5) { @@ -304,8 +304,8 @@ int main(int argc, char **argv) printError(adl_errorInfo(myDevice)); return 1; } - std::fprintf(stdout, " - Number of four-ops %s\n", argv[4]); } + std::fprintf(stdout, " - Number of four-ops %d\n", adl_getNumFourOpsChn(myDevice)); //Open MIDI file to play if(adl_openFile(myDevice, argv[1]) != 0) |