aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi.cpp8
-rw-r--r--src/adlmidi_load.cpp43
-rw-r--r--src/adlmidi_midiplay.cpp27
-rw-r--r--src/adlmidi_opl3.cpp17
-rw-r--r--src/adlmidi_private.hpp22
5 files changed, 78 insertions, 39 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index dc9c980..8ee5996 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -93,10 +93,7 @@ ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank)
bankno = 0;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- play->m_setup.AdlBank = static_cast<uint32_t>(bankno);
- play->opl.AdlBank = play->m_setup.AdlBank;
-
- if(play->m_setup.AdlBank >= NumBanks)
+ if(static_cast<uint32_t>(bankno) >= NumBanks)
{
std::stringstream s;
s << "bank number may only be 0.." << (NumBanks - 1) << ".\n";
@@ -104,6 +101,9 @@ ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank)
return -1;
}
+ play->m_setup.AdlBank = static_cast<uint32_t>(bankno);
+ play->opl.setEmbeddedBank(play->m_setup.AdlBank);
+
return adlRefreshNumCards(device);
#endif
}
diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp
index 76765dc..9b28810 100644
--- a/src/adlmidi_load.cpp
+++ b/src/adlmidi_load.cpp
@@ -241,6 +241,9 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr)
//6'th byte reserved for ADLMIDI's default volume model
m_setup.VolumeModel = (int)head[5];
+ opl.dynamic_melodic_banks.clear();
+ opl.dynamic_percussion_banks.clear();
+
if(version >= 2)//Read bank meta-entries
{
for(uint16_t i = 0; i < count_melodic_banks; i++)
@@ -251,6 +254,9 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr)
errorStringOut = "Custom bank: Fail to read melodic bank meta-data!";
return false;
}
+ uint16_t bank = uint16_t(bank_meta[33]) * 256 + uint16_t(bank_meta[32]);
+ size_t offset = opl.dynamic_melodic_banks.size();
+ opl.dynamic_melodic_banks[bank] = offset;
//strncpy(bankMeta.name, char_p(bank_meta), 32);
//bankMeta.lsb = bank_meta[32];
//bankMeta.msb = bank_meta[33];
@@ -264,15 +270,16 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr)
errorStringOut = "Custom bank: Fail to read melodic bank meta-data!";
return false;
}
+ uint16_t bank = uint16_t(bank_meta[33]) * 256 + uint16_t(bank_meta[32]);
+ size_t offset = opl.dynamic_percussion_banks.size();
+ opl.dynamic_percussion_banks[bank] = offset;
//strncpy(bankMeta.name, char_p(bank_meta), 32);
//bankMeta.lsb = bank_meta[32];
//bankMeta.msb = bank_meta[33];
}
}
- opl.AdlBank = m_setup.AdlBank;
- opl.dynamic_metainstruments.clear();
- opl.dynamic_instruments.clear();
+ opl.setEmbeddedBank(m_setup.AdlBank);
uint16_t total = 128 * count_melodic_banks;
bool readPercussion = false;
@@ -284,28 +291,24 @@ tryAgain:
memset(&ins, 0, sizeof(WOPL_Inst));
if(!readInstrument(fr, ins, readPercussion))
{
- opl.dynamic_metainstruments.clear();
- opl.dynamic_instruments.clear();
+ opl.setEmbeddedBank(m_setup.AdlBank);
errorStringOut = "Custom bank: Fail to read instrument!";
return false;
}
- if(i < 128) //Only first bank!
+ /*
+ * 0..127 - melodic, 128...255 - percussion.
+ * TODO: Make separated melodic and drum arrays and make MIDI bank ID support
+ */
+ ins.adlins.adlno1 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag);
+ opl.dynamic_instruments.push_back(ins.op[0]);
+ ins.adlins.adlno2 = ins.adlins.adlno1;
+ if(ins.fourOps)
{
- /*
- * 0..127 - melodic, 128...255 - percussion.
- * TODO: Make separated melodic and drum arrays and make MIDI bank ID support
- */
- ins.adlins.adlno1 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag);
- opl.dynamic_instruments.push_back(ins.op[0]);
- ins.adlins.adlno2 = ins.adlins.adlno1;
- if(ins.fourOps)
- {
- ins.adlins.adlno2 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag);
- opl.dynamic_instruments.push_back(ins.op[1]);
- }
- opl.dynamic_metainstruments.push_back(ins.adlins);
+ ins.adlins.adlno2 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag);
+ opl.dynamic_instruments.push_back(ins.op[1]);
}
+ opl.dynamic_metainstruments.push_back(ins.adlins);
}
if(!readPercussion)
@@ -316,6 +319,8 @@ tryAgain:
}
opl.AdlBank = ~0u; // Use dynamic banks!
+ //Percussion offset is count of instruments multipled to count of melodic banks
+ opl.dynamic_percussion_offset = 128 * count_melodic_banks;
return true;
}
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 7d1ba75..8794d9f 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -866,10 +866,29 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(velocity == 0)
return false;
- uint8_t midiins = Ch[channel].patch;
+ size_t midiins = Ch[channel].patch;
+ bool isPercussion = (channel % 16 == 9);
- if(channel % 16 == 9)
- midiins = 128 + note; // Percussion instrument
+ if(isPercussion)
+ midiins = opl.dynamic_percussion_offset + note; // Percussion instrument
+
+ //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);
+ if(isPercussion)
+ {
+ OPL3::BankMap::iterator b = opl.dynamic_percussion_banks.find(bank);
+ if(b != opl.dynamic_percussion_banks.end())
+ midiins += b->second * 128;
+ }
+ else
+ {
+ OPL3::BankMap::iterator b = opl.dynamic_melodic_banks.find(bank);
+ if(b != opl.dynamic_melodic_banks.end())
+ midiins += b->second * 128;
+ }
+ }
/*
if(MidCh%16 == 9 || (midiins != 32 && midiins != 46 && midiins != 48 && midiins != 50))
@@ -921,7 +940,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
*/
//int meta = banks[opl.AdlBank][midiins];
- const uint32_t meta = opl.GetAdlMetaNumber(midiins);
+ const size_t meta = opl.GetAdlMetaNumber(midiins);
const adlinsdata &ains = opl.GetAdlMetaIns(meta);
int16_t tone = note;
diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp
index ce26ba6..9db3803 100644
--- a/src/adlmidi_opl3.cpp
+++ b/src/adlmidi_opl3.cpp
@@ -115,30 +115,39 @@ static const unsigned short Channels[23] =
*/
-const adlinsdata &OPL3::GetAdlMetaIns(unsigned n)
+const adlinsdata &OPL3::GetAdlMetaIns(size_t n)
{
return (n & DynamicMetaInstrumentTag) ?
dynamic_metainstruments[n & ~DynamicMetaInstrumentTag]
: adlins[n];
}
-unsigned OPL3::GetAdlMetaNumber(unsigned midiins)
+size_t OPL3::GetAdlMetaNumber(size_t midiins)
{
return (AdlBank == ~0u) ?
(midiins | DynamicMetaInstrumentTag)
: banks[AdlBank][midiins];
}
-
const adldata &OPL3::GetAdlIns(size_t insno)
{
return (insno & DynamicInstrumentTag)
? dynamic_instruments[insno & ~DynamicInstrumentTag]
- : adl[insno];
+ : adl[insno];
+}
+
+void OPL3::setEmbeddedBank(unsigned int bank)
+{
+ AdlBank = bank;
+ //Embedded banks are supports 128:128 GM set only
+ dynamic_percussion_offset = 128;
+ dynamic_melodic_banks.clear();
+ dynamic_percussion_banks.clear();
}
OPL3::OPL3() :
+ dynamic_percussion_offset(128),
DynamicInstrumentTag(0x8000u),
DynamicMetaInstrumentTag(0x4000000u),
NumCards(1),
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 698dad5..dbea5e6 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -141,8 +141,9 @@ public:
};
class MIDIplay;
-struct OPL3
+class OPL3
{
+public:
friend class MIDIplay;
uint32_t NumChannels;
char ____padding[4];
@@ -162,13 +163,19 @@ private:
friend int adlRefreshNumCards(ADL_MIDIPlayer *device);
std::vector<adlinsdata> dynamic_metainstruments; // Replaces adlins[] when CMF file
std::vector<adldata> dynamic_instruments; // Replaces adl[] when CMF file
+ size_t dynamic_percussion_offset;
+ typedef std::map<uint16_t, size_t> BankMap;
+ BankMap dynamic_melodic_banks;
+ BankMap dynamic_percussion_banks;
const unsigned DynamicInstrumentTag /* = 0x8000u*/,
DynamicMetaInstrumentTag /* = 0x4000000u*/;
public:
- const adlinsdata &GetAdlMetaIns(unsigned n);
- unsigned GetAdlMetaNumber(unsigned midiins);
+ const adlinsdata &GetAdlMetaIns(size_t n);
+ size_t GetAdlMetaNumber(size_t midiins);
const adldata &GetAdlIns(size_t insno);
+ void setEmbeddedBank(unsigned int bank);
+
//! Total number of running concurrent emulated chips
unsigned int NumCards;
//! Currently running embedded bank number. "~0" means usign of the custom bank.
@@ -446,14 +453,14 @@ public:
{
// Current pressure
uint8_t vol;
- // Tone selected on noteon:
char ____padding[1];
+ // Tone selected on noteon:
int16_t tone;
+ char ____padding2[4];
// Patch selected on noteon; index to banks[AdlBank][]
- uint8_t midiins;
+ size_t midiins;
// Index to physical adlib data structure, adlins[]
- char ____padding2[3];
- uint32_t insmeta;
+ size_t insmeta;
struct Phys
{
//! ins, inde to adl[]
@@ -471,7 +478,6 @@ public:
}
};
typedef std::map<uint16_t, Phys> PhysMap;
- char ____padding3[4];
// List of OPL3 channels it is currently occupying.
std::map<uint16_t /*adlchn*/, Phys> phys;
};