aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fm_banks/wopl_files/lostvik.woplbin31899 -> 31899 bytes
-rw-r--r--include/adlmidi.h19
-rw-r--r--src/adlmidi.cpp35
-rw-r--r--src/adlmidi_load.cpp4
-rw-r--r--src/adlmidi_midiplay.cpp19
-rw-r--r--src/adlmidi_private.cpp19
-rw-r--r--src/adlmidi_xmi2mid.c7
-rw-r--r--utils/adlmidi-2/midiplay.cc2
-rw-r--r--utils/midiplay/adlmidiplay.cpp8
9 files changed, 86 insertions, 27 deletions
diff --git a/fm_banks/wopl_files/lostvik.wopl b/fm_banks/wopl_files/lostvik.wopl
index fe19ef9..ce2c07e 100644
--- a/fm_banks/wopl_files/lostvik.wopl
+++ b/fm_banks/wopl_files/lostvik.wopl
Binary files differ
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)