diff options
-rw-r--r-- | src/adldata.hh | 83 | ||||
-rw-r--r-- | src/adlmidi.cpp | 4 | ||||
-rw-r--r-- | src/adlmidi_cvt.hpp | 60 | ||||
-rw-r--r-- | src/adlmidi_load.cpp | 24 | ||||
-rw-r--r-- | src/adlmidi_midiplay.cpp | 71 | ||||
-rw-r--r-- | src/adlmidi_midiplay.hpp | 8 | ||||
-rw-r--r-- | src/adlmidi_opl3.cpp | 26 | ||||
-rw-r--r-- | src/adlmidi_opl3.hpp | 8 | ||||
-rw-r--r-- | src/adlmidi_private.cpp | 68 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 2 | ||||
-rw-r--r-- | test/conversion/conversion.cpp | 2 |
11 files changed, 168 insertions, 188 deletions
diff --git a/src/adldata.hh b/src/adldata.hh index 44a55e6..aa96736 100644 --- a/src/adldata.hh +++ b/src/adldata.hh @@ -35,49 +35,64 @@ inline bool operator!=(const T &a, const T &b) \ { return !operator==(a, b); } -struct adldata +/** + * @brief OPL3 Operator data for single tumbre + */ +struct OplTimbre { - uint32_t modulator_E862, carrier_E862; // See below - uint8_t modulator_40, carrier_40; // KSL/attenuation settings - uint8_t feedconn; // Feedback/connection bits for the channel - - int8_t finetune; + //! WaveForm, Sustain/Release, AttackDecay, and AM/VIB/EG/KSR/F-Mult settings + uint32_t modulator_E862, carrier_E862; + //! KSL/attenuation settings + uint8_t modulator_40, carrier_40; + //! Feedback/connection bits for the channel + uint8_t feedconn; + //! Semi-tone offset + int8_t noteOffset; }; -ADLDATA_BYTE_COMPARABLE(struct adldata) - -struct adlinsdata -{ - enum { Flag_Pseudo4op = 0x01, Flag_NoSound = 0x02, Flag_Real4op = 0x04 }; +ADLDATA_BYTE_COMPARABLE(struct OplTimbre) - enum { Flag_RM_BassDrum = 0x08, Flag_RM_Snare = 0x10, Flag_RM_TomTom = 0x18, - Flag_RM_Cymbal = 0x20, Flag_RM_HiHat = 0x28, Mask_RhythmMode = 0x38 }; - uint16_t adlno1, adlno2; - uint8_t tone; - uint8_t flags; - uint16_t ms_sound_kon; // Number of milliseconds it produces sound; - uint16_t ms_sound_koff; - int8_t midi_velocity_offset; - double voice2_fine_tune; -}; -ADLDATA_BYTE_COMPARABLE(struct adlinsdata) +enum { OPLNoteOnMaxTime = 40000 }; -enum { adlNoteOnMaxTime = 40000 }; /** * @brief Instrument data with operators included */ -struct adlinsdata2 +struct OplInstMeta { - adldata adl[2]; - uint8_t tone; - uint8_t flags; - uint16_t ms_sound_kon; // Number of milliseconds it produces sound; - uint16_t ms_sound_koff; - int8_t midi_velocity_offset; - double voice2_fine_tune; + enum + { + Flag_Pseudo4op = 0x01, + Flag_NoSound = 0x02, + Flag_Real4op = 0x04 + }; + + enum + { + Flag_RM_BassDrum = 0x08, + Flag_RM_Snare = 0x10, + Flag_RM_TomTom = 0x18, + Flag_RM_Cymbal = 0x20, + Flag_RM_HiHat = 0x28, + Mask_RhythmMode = 0x38 + }; + + //! Operator data + OplTimbre op[2]; + //! Fixed note for drum instruments + uint8_t drumTone; + //! Instrument flags + uint8_t flags; + //! Number of milliseconds it produces sound while key on + uint16_t soundKeyOnMs; + //! Number of milliseconds it produces sound while releasing after key off + uint16_t soundKeyOffMs; + //! MIDI velocity offset + int8_t midiVelocityOffset; + //! Second voice detune + double voice2_fine_tune; }; -ADLDATA_BYTE_COMPARABLE(struct adlinsdata2) +ADLDATA_BYTE_COMPARABLE(struct OplInstMeta) #undef ADLDATA_BYTE_COMPARABLE #pragma pack(pop) @@ -96,11 +111,11 @@ struct AdlBankSetup /** * @brief Convert external instrument to internal instrument */ -void cvt_ADLI_to_FMIns(adlinsdata2 &dst, const struct ADL_Instrument &src); +void cvt_ADLI_to_FMIns(OplInstMeta &dst, const struct ADL_Instrument &src); /** * @brief Convert internal instrument to external instrument */ -void cvt_FMIns_to_ADLI(struct ADL_Instrument &dst, const adlinsdata2 &src); +void cvt_FMIns_to_ADLI(struct ADL_Instrument &dst, const OplInstMeta &src); #endif //ADLDATA_H diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index 0e91353..9d33e62 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -275,7 +275,7 @@ ADLMIDI_EXPORT int adl_getBank(ADL_MIDIPlayer *device, const ADL_BankId *idp, in value.first = idnumber; memset(&value.second, 0, sizeof(value.second)); for (unsigned i = 0; i < 128; ++i) - value.second.ins[i].flags = adlinsdata::Flag_NoSound; + value.second.ins[i].flags = OplInstMeta::Flag_NoSound; std::pair<Synth::BankMap::iterator, bool> ir; if((flags & ADLMIDI_Bank_CreateRt) == ADLMIDI_Bank_CreateRt) @@ -414,7 +414,7 @@ ADLMIDI_EXPORT int adl_loadEmbeddedBank(struct ADL_MIDIPlayer *device, ADL_Bank midi_bank_idx_t instIdx = bankData.insts[i]; if(instIdx < 0) { - it->second.ins[i].flags = adlinsdata::Flag_NoSound; + it->second.ins[i].flags = OplInstMeta::Flag_NoSound; continue; } BanksDump::InstrumentEntry instIn = g_embeddedBanksInstruments[instIdx]; diff --git a/src/adlmidi_cvt.hpp b/src/adlmidi_cvt.hpp index 74b9f78..de25253 100644 --- a/src/adlmidi_cvt.hpp +++ b/src/adlmidi_cvt.hpp @@ -26,7 +26,7 @@ #include <cmath> template <class WOPLI> -static void cvt_generic_to_FMIns(adlinsdata2 &ins, const WOPLI &in) +static void cvt_generic_to_FMIns(OplInstMeta &ins, const WOPLI &in) { ins.voice2_fine_tune = 0.0; int voice2_fine_tune = in.second_voice_detune; @@ -37,42 +37,42 @@ static void cvt_generic_to_FMIns(adlinsdata2 &ins, const WOPLI &in) ins.voice2_fine_tune = (double)(((voice2_fine_tune + 128) >> 1) - 64) / 32.0; } - ins.midi_velocity_offset = in.midi_velocity_offset; - ins.tone = in.percussion_key_number; - ins.flags = (in.inst_flags & WOPL_Ins_4op) && (in.inst_flags & WOPL_Ins_Pseudo4op) ? adlinsdata::Flag_Pseudo4op : 0; - ins.flags|= (in.inst_flags & WOPL_Ins_4op) && ((in.inst_flags & WOPL_Ins_Pseudo4op) == 0) ? adlinsdata::Flag_Real4op : 0; - ins.flags|= (in.inst_flags & WOPL_Ins_IsBlank) ? adlinsdata::Flag_NoSound : 0; + ins.midiVelocityOffset = in.midi_velocity_offset; + ins.drumTone = in.percussion_key_number; + ins.flags = (in.inst_flags & WOPL_Ins_4op) && (in.inst_flags & WOPL_Ins_Pseudo4op) ? OplInstMeta::Flag_Pseudo4op : 0; + ins.flags|= (in.inst_flags & WOPL_Ins_4op) && ((in.inst_flags & WOPL_Ins_Pseudo4op) == 0) ? OplInstMeta::Flag_Real4op : 0; + ins.flags|= (in.inst_flags & WOPL_Ins_IsBlank) ? OplInstMeta::Flag_NoSound : 0; ins.flags|= in.inst_flags & WOPL_RhythmModeMask; for(size_t op = 0, slt = 0; op < 4; op++, slt++) { - ins.adl[slt].carrier_E862 = + ins.op[slt].carrier_E862 = ((static_cast<uint32_t>(in.operators[op].waveform_E0) << 24) & 0xFF000000) //WaveForm | ((static_cast<uint32_t>(in.operators[op].susrel_80) << 16) & 0x00FF0000) //SusRel | ((static_cast<uint32_t>(in.operators[op].atdec_60) << 8) & 0x0000FF00) //AtDec | ((static_cast<uint32_t>(in.operators[op].avekf_20) << 0) & 0x000000FF); //AVEKM - ins.adl[slt].carrier_40 = in.operators[op].ksl_l_40;//KSLL + ins.op[slt].carrier_40 = in.operators[op].ksl_l_40;//KSLL op++; - ins.adl[slt].modulator_E862 = + ins.op[slt].modulator_E862 = ((static_cast<uint32_t>(in.operators[op].waveform_E0) << 24) & 0xFF000000) //WaveForm | ((static_cast<uint32_t>(in.operators[op].susrel_80) << 16) & 0x00FF0000) //SusRel | ((static_cast<uint32_t>(in.operators[op].atdec_60) << 8) & 0x0000FF00) //AtDec | ((static_cast<uint32_t>(in.operators[op].avekf_20) << 0) & 0x000000FF); //AVEKM - ins.adl[slt].modulator_40 = in.operators[op].ksl_l_40;//KSLL + ins.op[slt].modulator_40 = in.operators[op].ksl_l_40;//KSLL } - ins.adl[0].finetune = static_cast<int8_t>(in.note_offset1); - ins.adl[0].feedconn = in.fb_conn1_C0; - ins.adl[1].finetune = static_cast<int8_t>(in.note_offset2); - ins.adl[1].feedconn = in.fb_conn2_C0; + ins.op[0].noteOffset = static_cast<int8_t>(in.note_offset1); + ins.op[0].feedconn = in.fb_conn1_C0; + ins.op[1].noteOffset = static_cast<int8_t>(in.note_offset2); + ins.op[1].feedconn = in.fb_conn2_C0; - ins.ms_sound_kon = in.delay_on_ms; - ins.ms_sound_koff = in.delay_off_ms; + ins.soundKeyOnMs = in.delay_on_ms; + ins.soundKeyOffMs = in.delay_off_ms; } template <class WOPLI> -static void cvt_FMIns_to_generic(WOPLI &ins, const adlinsdata2 &in) +static void cvt_FMIns_to_generic(WOPLI &ins, const OplInstMeta &in) { ins.second_voice_detune = 0; double voice2_fine_tune = in.voice2_fine_tune; @@ -85,16 +85,16 @@ static void cvt_FMIns_to_generic(WOPLI &ins, const adlinsdata2 &in) ins.second_voice_detune = (uint8_t)m; } - ins.midi_velocity_offset = in.midi_velocity_offset; - ins.percussion_key_number = in.tone; - ins.inst_flags = (in.flags & (adlinsdata::Flag_Pseudo4op|adlinsdata::Flag_Real4op)) ? WOPL_Ins_4op : 0; - ins.inst_flags|= (in.flags & adlinsdata::Flag_Pseudo4op) ? WOPL_Ins_Pseudo4op : 0; - ins.inst_flags|= (in.flags & adlinsdata::Flag_NoSound) ? WOPL_Ins_IsBlank : 0; - ins.inst_flags |= in.flags & adlinsdata::Mask_RhythmMode; + ins.midi_velocity_offset = in.midiVelocityOffset; + ins.percussion_key_number = in.drumTone; + ins.inst_flags = (in.flags & (OplInstMeta::Flag_Pseudo4op|OplInstMeta::Flag_Real4op)) ? WOPL_Ins_4op : 0; + ins.inst_flags|= (in.flags & OplInstMeta::Flag_Pseudo4op) ? WOPL_Ins_Pseudo4op : 0; + ins.inst_flags|= (in.flags & OplInstMeta::Flag_NoSound) ? WOPL_Ins_IsBlank : 0; + ins.inst_flags |= in.flags & OplInstMeta::Mask_RhythmMode; for(size_t op = 0; op < 4; op++) { - const adldata &in2op = in.adl[(op < 2) ? 0 : 1]; + const OplTimbre &in2op = in.op[(op < 2) ? 0 : 1]; uint32_t regE862 = ((op & 1) == 0) ? in2op.carrier_E862 : in2op.modulator_E862; uint8_t reg40 = ((op & 1) == 0) ? in2op.carrier_40 : in2op.modulator_40; @@ -105,11 +105,11 @@ static void cvt_FMIns_to_generic(WOPLI &ins, const adlinsdata2 &in) ins.operators[op].ksl_l_40 = reg40; } - ins.note_offset1 = in.adl[0].finetune; - ins.fb_conn1_C0 = in.adl[0].feedconn; - ins.note_offset2 = in.adl[1].finetune; - ins.fb_conn2_C0 = in.adl[1].feedconn; + ins.note_offset1 = in.op[0].noteOffset; + ins.fb_conn1_C0 = in.op[0].feedconn; + ins.note_offset2 = in.op[1].noteOffset; + ins.fb_conn2_C0 = in.op[1].feedconn; - ins.delay_on_ms = in.ms_sound_kon; - ins.delay_off_ms = in.ms_sound_koff; + ins.delay_on_ms = in.soundKeyOnMs; + ins.delay_off_ms = in.soundKeyOffMs; } diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp index fbf87fa..1da8b03 100644 --- a/src/adlmidi_load.cpp +++ b/src/adlmidi_load.cpp @@ -43,12 +43,12 @@ bool MIDIplay::LoadBank(const void *data, size_t size) return LoadBank(file); } -void cvt_ADLI_to_FMIns(adlinsdata2 &ins, const ADL_Instrument &in) +void cvt_ADLI_to_FMIns(OplInstMeta &ins, const ADL_Instrument &in) { return cvt_generic_to_FMIns(ins, in); } -void cvt_FMIns_to_ADLI(ADL_Instrument &ins, const adlinsdata2 &in) +void cvt_FMIns_to_ADLI(ADL_Instrument &ins, const OplInstMeta &in) { cvt_FMIns_to_generic(ins, in); } @@ -133,8 +133,8 @@ bool MIDIplay::LoadBank(FileAndMemReader &fr) Synth::Bank &bank = synth.m_insBanks[bankno]; for(int j = 0; j < 128; j++) { - adlinsdata2 &ins = bank.ins[j]; - std::memset(&ins, 0, sizeof(adlinsdata2)); + OplInstMeta &ins = bank.ins[j]; + std::memset(&ins, 0, sizeof(OplInstMeta)); WOPLInstrument &inIns = slots_src_ins[ss][i].ins[j]; cvt_generic_to_FMIns(ins, inIns); } @@ -192,8 +192,8 @@ bool MIDIplay::LoadMIDI_post() /*std::printf("Ins %3u: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", i, InsData[0],InsData[1],InsData[2],InsData[3], InsData[4],InsData[5],InsData[6],InsData[7], InsData[8],InsData[9],InsData[10],InsData[11], InsData[12],InsData[13],InsData[14],InsData[15]);*/ - adlinsdata2 &adlins = synth.m_insBanks[bank].ins[i % 128]; - adldata adl; + OplInstMeta &adlins = synth.m_insBanks[bank].ins[i % 128]; + OplTimbre adl; adl.modulator_E862 = ((static_cast<uint32_t>(insData[8] & 0x07) << 24) & 0xFF000000) //WaveForm | ((static_cast<uint32_t>(insData[6]) << 16) & 0x00FF0000) //Sustain/Release @@ -207,12 +207,12 @@ bool MIDIplay::LoadMIDI_post() adl.modulator_40 = insData[2]; adl.carrier_40 = insData[3]; adl.feedconn = insData[10] & 0x0F; - adl.finetune = 0; - adlins.adl[0] = adl; - adlins.adl[1] = adl; - adlins.ms_sound_kon = 1000; - adlins.ms_sound_koff = 500; - adlins.tone = 0; + adl.noteOffset = 0; + adlins.op[0] = adl; + adlins.op[1] = adl; + adlins.soundKeyOnMs = 1000; + adlins.soundKeyOffMs = 500; + adlins.drumTone = 0; adlins.flags = 0; adlins.voice2_fine_tune = 0.0; } diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 8a6751d..c6fc1b6 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -288,7 +288,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(!i.is_end()) { MIDIchannel::NoteInfo &ni = i->value; - const int veloffset = ni.ains->midi_velocity_offset; + const int veloffset = ni.ains->midiVelocityOffset; velocity = (uint8_t)std::min(127, std::max(1, (int)velocity + veloffset)); ni.vol = velocity; noteUpdate(channel, i, Upd_Volume); @@ -339,7 +339,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(isPercussion) bank += Synth::PercussionTag; - const adlinsdata2 *ains = &Synth::m_emptyInstrument; + const OplInstMeta *ains = &Synth::m_emptyInstrument; //Set bank bank const Synth::Bank *bnk = NULL; @@ -356,7 +356,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) } //Or fall back to bank ignoring LSB (GS) - if((ains->flags & adlinsdata::Flag_NoSound) && ((m_synthMode & Mode_GS) != 0)) + if((ains->flags & OplInstMeta::Flag_NoSound) && ((m_synthMode & Mode_GS) != 0)) { size_t fallback = bank & ~(size_t)0x7F; if(fallback != bank) @@ -387,7 +387,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) } //Or fall back to first bank - if((ains->flags & adlinsdata::Flag_NoSound) != 0) + if((ains->flags & OplInstMeta::Flag_NoSound) != 0) { Synth::BankMap::iterator b = synth.m_insBanks.find(bank & Synth::PercussionTag); if(b != synth.m_insBanks.end()) @@ -396,13 +396,13 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) ains = &bnk->ins[midiins]; } - const int veloffset = ains->midi_velocity_offset; + const int veloffset = ains->midiVelocityOffset; velocity = (uint8_t)std::min(127, std::max(1, (int)velocity + veloffset)); int32_t tone = note; if(!isPercussion && (bank > 0)) // For non-zero banks { - if(ains->flags & adlinsdata::Flag_NoSound) + if(ains->flags & OplInstMeta::Flag_NoSound) { if(hooks.onDebugMessage && caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second) { @@ -415,37 +415,37 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) } } - if(ains->tone) + if(ains->drumTone) { - if(ains->tone >= 128) - tone = ains->tone - 128; + if(ains->drumTone >= 128) + tone = ains->drumTone - 128; else - tone = ains->tone; + tone = ains->drumTone; } //uint16_t i[2] = { ains->adlno1, ains->adlno2 }; - bool is_2op = !(ains->flags & (adlinsdata::Flag_Pseudo4op|adlinsdata::Flag_Real4op)); - bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op; + bool is_2op = !(ains->flags & (OplInstMeta::Flag_Pseudo4op|OplInstMeta::Flag_Real4op)); + bool pseudo_4op = ains->flags & OplInstMeta::Flag_Pseudo4op; #ifndef __WATCOMC__ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] = { - {0, ains->adl[0], false}, - {0, (!is_2op) ? ains->adl[1] : ains->adl[0], pseudo_4op} + {0, ains->op[0], false}, + {0, (!is_2op) ? ains->op[1] : ains->op[0], pseudo_4op} }; #else /* Unfortunately, Watcom can't brace-initialize structure that incluses structure fields */ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans]; voices[0].chip_chan = 0; - voices[0].ains = ains->adl[0]; + voices[0].op = ains->op[0]; voices[0].pseudo4op = false; voices[1].chip_chan = 0; - voices[1].ains = (!is_2op) ? ains->adl[1] : ains->adl[0]; + voices[1].op = (!is_2op) ? ains->op[1] : ains->op[0]; voices[1].pseudo4op = pseudo_4op; #endif /* __WATCOMC__ */ if( (synth.m_rhythmMode == 1) && ( - ((ains->flags & adlinsdata::Mask_RhythmMode) != 0) || + ((ains->flags & OplInstMeta::Mask_RhythmMode) != 0) || (m_cmfPercussionMode && (channel >= 11)) ) ) @@ -453,7 +453,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) voices[1] = voices[0];//i[1] = i[0]; } - bool isBlankNote = (ains->flags & adlinsdata::Flag_NoSound) != 0; + bool isBlankNote = (ains->flags & OplInstMeta::Flag_NoSound) != 0; if(hooks.onDebugMessage) { @@ -511,16 +511,16 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) else { expected_mode = OPL3::ChanCat_Regular; - uint32_t rm = (ains->flags & adlinsdata::Mask_RhythmMode); - if(rm == adlinsdata::Flag_RM_BassDrum) + uint32_t rm = (ains->flags & OplInstMeta::Mask_RhythmMode); + if(rm == OplInstMeta::Flag_RM_BassDrum) expected_mode = OPL3::ChanCat_Rhythm_Bass; - else if(rm == adlinsdata::Flag_RM_Snare) + else if(rm == OplInstMeta::Flag_RM_Snare) expected_mode = OPL3::ChanCat_Rhythm_Snare; - else if(rm == adlinsdata::Flag_RM_TomTom) + else if(rm == OplInstMeta::Flag_RM_TomTom) expected_mode = OPL3::ChanCat_Rhythm_Tom; - else if(rm == adlinsdata::Flag_RM_Cymbal) + else if(rm == OplInstMeta::Flag_RM_Cymbal) expected_mode = OPL3::ChanCat_Rhythm_Cymbal; - else if(rm == adlinsdata::Flag_RM_HiHat) + else if(rm == OplInstMeta::Flag_RM_HiHat) expected_mode = OPL3::ChanCat_Rhythm_HiHat; } } @@ -1154,7 +1154,7 @@ void MIDIplay::noteUpdate(size_t midCh, const double currentTone = info.currentTone; const uint8_t vol = info.vol; const int midiins = static_cast<int>(info.midiins); - const adlinsdata2 &ains = *info.ains; + const OplInstMeta &ains = *info.ains; AdlChannel::Location my_loc; my_loc.MidCh = static_cast<uint16_t>(midCh); my_loc.note = info.note; @@ -1175,15 +1175,15 @@ void MIDIplay::noteUpdate(size_t midCh, if(props_mask & Upd_Patch) { - synth.setPatch(c, ins.ains); + synth.setPatch(c, ins.op); AdlChannel::users_iterator i = m_chipChannels[c].find_or_create_user(my_loc); if(!i.is_end()) // inserts if necessary { AdlChannel::LocationData &d = i->value; d.sustained = AdlChannel::LocationData::Sustain_None; d.vibdelay_us = 0; - d.fixed_sustain = (ains.ms_sound_kon == static_cast<uint16_t>(adlNoteOnMaxTime)); - d.kon_time_until_neglible_us = 1000 * ains.ms_sound_kon; + d.fixed_sustain = (ains.soundKeyOnMs == static_cast<uint16_t>(OPLNoteOnMaxTime)); + d.kon_time_until_neglible_us = 1000 * ains.soundKeyOnMs; d.ins = ins; } } @@ -1220,7 +1220,7 @@ void MIDIplay::noteUpdate(size_t midCh, } else { - m_chipChannels[c].koff_time_until_neglible_us = 1000 * int64_t(ains.ms_sound_koff); + m_chipChannels[c].koff_time_until_neglible_us = 1000 * int64_t(ains.soundKeyOffMs); } } } @@ -1287,15 +1287,15 @@ void MIDIplay::noteUpdate(size_t midCh, { MIDIchannel &chan = m_midiChannels[midCh]; double midibend = chan.bend * chan.bendsense; - double bend = midibend + ins.ains.finetune; + double bend = midibend + ins.op.noteOffset; double phase = 0.0; uint8_t vibrato = std::max(chan.vibrato, chan.aftertouch); vibrato = std::max(vibrato, info.vibrato); - if((ains.flags & adlinsdata::Flag_Pseudo4op) && ins.pseudo4op) + if((ains.flags & OplInstMeta::Flag_Pseudo4op) && ins.pseudo4op) { - phase = ains.voice2_fine_tune;//0.125; // Detune the note slightly (this is what Doom does) + phase = ains.voice2_fine_tune; } if(vibrato && (d.is_end() || d->value.vibdelay_us >= chan.vibdelay_us)) @@ -1543,13 +1543,6 @@ void MIDIplay::killOrEvacuate(size_t from_channel, } } - /*UI.PrintLn( - "collision @%u: [%ld] <- ins[%3u]", - c, - //ch[c].midiins<128?'M':'P', ch[c].midiins&127, - ch[c].age, //adlins[ch[c].insmeta].ms_sound_kon, - ins - );*/ // Kill it noteUpdate(jd.loc.MidCh, i, diff --git a/src/adlmidi_midiplay.hpp b/src/adlmidi_midiplay.hpp index ff741ee..78cd89a 100644 --- a/src/adlmidi_midiplay.hpp +++ b/src/adlmidi_midiplay.hpp @@ -172,7 +172,7 @@ public: //! Time-to-live until release (short percussion note fix) double ttl; //! Patch selected - const adlinsdata2 *ains; + const OplInstMeta *ains; enum { MaxNumPhysChans = 2, @@ -196,18 +196,18 @@ public: //! Destination chip channel uint16_t chip_chan; //! ins, inde to adl[] - adldata ains; + OplTimbre op; //! Is this voice must be detunable? bool pseudo4op; void assign(const Phys &oth) { - ains = oth.ains; + op = oth.op; pseudo4op = oth.pseudo4op; } bool operator==(const Phys &oth) const { - return (ains == oth.ains) && (pseudo4op == oth.pseudo4op); + return (op == oth.op) && (pseudo4op == oth.pseudo4op); } bool operator!=(const Phys &oth) const { diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 1cf83e0..a38e364 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -847,15 +847,15 @@ enum -static adlinsdata2 makeEmptyInstrument() +static OplInstMeta makeEmptyInstrument() { - adlinsdata2 ins; - memset(&ins, 0, sizeof(adlinsdata2)); - ins.flags = adlinsdata::Flag_NoSound; + OplInstMeta ins; + memset(&ins, 0, sizeof(OplInstMeta)); + ins.flags = OplInstMeta::Flag_NoSound; return ins; } -const adlinsdata2 OPL3::m_emptyInstrument = makeEmptyInstrument(); +const OplInstMeta OPL3::m_emptyInstrument = makeEmptyInstrument(); OPL3::OPL3() : m_numChips(1), @@ -931,11 +931,11 @@ void OPL3::setEmbeddedBank(uint32_t bank) midi_bank_idx_t instIndex = bankData.insts[instId]; if(instIndex < 0) { - bankTarget.ins[instId].flags = adlinsdata::Flag_NoSound; + bankTarget.ins[instId].flags = OplInstMeta::Flag_NoSound; continue; } BanksDump::InstrumentEntry instIn = g_embeddedBanksInstruments[instIndex]; - adlinsdata2 &instOut = bankTarget.ins[instId]; + OplInstMeta &instOut = bankTarget.ins[instId]; adlFromInstrument(instIn, instOut); } @@ -1063,8 +1063,8 @@ void OPL3::noteOn(size_t c1, size_t c2, double tone) ftone = octave + static_cast<uint32_t>(hertz /*+ 0.5*/); uint32_t chn = g_channelsMap[cc1]; - const adldata &patch1 = m_insCache[c1]; - const adldata &patch2 = m_insCache[c2 < m_insCache.size() ? c2 : 0]; + const OplTimbre &patch1 = m_insCache[c1]; + const OplTimbre &patch2 = m_insCache[c2 < m_insCache.size() ? c2 : 0]; if(cc1 < OPL3_CHANNELS_RHYTHM_BASE) { @@ -1136,7 +1136,7 @@ void OPL3::touchNote(size_t c, uint8_t brightness) { size_t chip = c / NUM_OF_CHANNELS, cc = c % NUM_OF_CHANNELS; - const adldata &adli = m_insCache[c]; + const OplTimbre &adli = m_insCache[c]; size_t cmf_offset = ((m_musicMode == MODE_CMF) && cc >= OPL3_CHANNELS_RHYTHM_BASE) ? 10 : 0; uint16_t o1 = g_operatorsMap[cc * 2 + 0 + cmf_offset]; uint16_t o2 = g_operatorsMap[cc * 2 + 1 + cmf_offset]; @@ -1288,7 +1288,7 @@ void OPL3::touchNote(size_t c, else if(m_channelCategory[c] == ChanCat_4op_First || m_channelCategory[c] == ChanCat_4op_Second) { - const adldata *i0, *i1; + const OplTimbre *i0, *i1; if(m_channelCategory[c] == ChanCat_4op_First) { @@ -1445,7 +1445,7 @@ void OPL3::touchNote(size_t c, // 63 + chanvol * (instrvol / 63.0 - 1) } -void OPL3::setPatch(size_t c, const adldata &instrument) +void OPL3::setPatch(size_t c, const OplTimbre &instrument) { size_t chip = c / NUM_OF_CHANNELS, cc = c % NUM_OF_CHANNELS; static const uint8_t data[4] = {0x20, 0x60, 0x80, 0xE0}; @@ -1702,7 +1702,7 @@ void OPL3::reset(int emulator, unsigned long PCM_RATE, void *audioTickHandler) m_chips.resize(m_numChips, AdlMIDI_SPtr<OPLChipBase>()); #endif - const struct adldata defaultInsCache = { 0x1557403,0x005B381, 0x49,0x80, 0x4, +0 }; + const struct OplTimbre defaultInsCache = { 0x1557403,0x005B381, 0x49,0x80, 0x4, +0 }; m_numChannels = m_numChips * NUM_OF_CHANNELS; m_insCache.resize(m_numChannels, defaultInsCache); m_keyBlockFNumCache.resize(m_numChannels, 0); diff --git a/src/adlmidi_opl3.hpp b/src/adlmidi_opl3.hpp index b47c2ed..1172a45 100644 --- a/src/adlmidi_opl3.hpp +++ b/src/adlmidi_opl3.hpp @@ -66,7 +66,7 @@ public: private: //! Cached patch data, needed by Touch() - std::vector<adldata> m_insCache; + std::vector<OplTimbre> m_insCache; //! Value written to B0, cached, needed by NoteOff. /*! Contains Key on/off state, octave block and frequency number values */ @@ -81,7 +81,7 @@ public: struct Bank { //! MIDI Bank instruments - adlinsdata2 ins[128]; + OplInstMeta ins[128]; }; typedef BasicBankMap<Bank> BankMap; //! MIDI bank instruments data @@ -91,7 +91,7 @@ public: public: //! Blank instrument template - static const adlinsdata2 m_emptyInstrument; + static const OplInstMeta m_emptyInstrument; //! Total number of running concurrent emulated chips uint32_t m_numChips; //! Currently running embedded bank number. "CustomBankTag" means usign of the custom bank. @@ -277,7 +277,7 @@ public: * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)]) * @param instrument Instrument data to set into the chip channel */ - void setPatch(size_t c, const adldata &instrument); + void setPatch(size_t c, const OplTimbre &instrument); /** * @brief Set panpot position diff --git a/src/adlmidi_private.cpp b/src/adlmidi_private.cpp index 9478236..5a08f6e 100644 --- a/src/adlmidi_private.cpp +++ b/src/adlmidi_private.cpp @@ -43,11 +43,9 @@ int adlCalculateFourOpChannels(MIDIplay *play, bool silent) Synth &synth = *play->m_synth; size_t n_fourop[2] = {0, 0}, n_total[2] = {0, 0}; bool rhythmModeNeeded = false; + size_t numFourOps = 0; //Automatically calculate how much 4-operator channels is necessary -//#ifndef DISABLE_EMBEDDED_BANKS -// if(synth.m_embeddedBank == Synth::CustomBankTag) -//#endif { //For custom bank Synth::BankMap::iterator it = synth.m_insBanks.begin(); @@ -58,38 +56,17 @@ int adlCalculateFourOpChannels(MIDIplay *play, bool silent) size_t div = (bank & Synth::PercussionTag) ? 1 : 0; for(size_t i = 0; i < 128; ++i) { - adlinsdata2 &ins = it->second.ins[i]; - if(ins.flags & adlinsdata::Flag_NoSound) + OplInstMeta &ins = it->second.ins[i]; + if(ins.flags & OplInstMeta::Flag_NoSound) continue; - if((ins.flags & adlinsdata::Flag_Real4op) != 0) + if((ins.flags & OplInstMeta::Flag_Real4op) != 0) ++n_fourop[div]; ++n_total[div]; - if(div && ((ins.flags & adlinsdata::Mask_RhythmMode) != 0)) + if(div && ((ins.flags & OplInstMeta::Mask_RhythmMode) != 0)) rhythmModeNeeded = true; } } } -//#ifndef DISABLE_EMBEDDED_BANKS -// else -// { -// //For embedded bank -// for(size_t a = 0; a < 256; ++a) -// { -// size_t insno = banks[play->m_setup.bankId][a]; -// size_t div = a / 128; -// if(insno == 198) -// continue; -// ++n_total[div]; -// adlinsdata2 ins = adlinsdata2::from_adldata(::adlins[insno]); -// if((ins.flags & adlinsdata::Flag_Real4op) != 0) -// ++n_fourop[div]; -// if(div && ((ins.flags & adlinsdata::Mask_RhythmMode) != 0)) -// rhythmModeNeeded = true; -// } -// } -//#endif - - size_t numFourOps = 0; // All 2ops (no 4ops) if((n_fourop[0] == 0) && (n_fourop[1] == 0)) @@ -104,13 +81,8 @@ int adlCalculateFourOpChannels(MIDIplay *play, bool silent) else if(n_fourop[0] > 0) numFourOps = 4; -/* //Old formula - unsigned NumFourOps = ((n_fourop[0] == 0) && (n_fourop[1] == 0)) ? 0 - : (n_fourop[0] >= (n_total[0] * 7) / 8) ? play->m_setup.NumCards * 6 - : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); -*/ - synth.m_numFourOps = static_cast<unsigned>(numFourOps * synth.m_numChips); + // Update channel categories and set up four-operator channels if(!silent) synth.updateChannelCategories(); @@ -122,17 +94,17 @@ int adlCalculateFourOpChannels(MIDIplay *play, bool silent) } #ifndef DISABLE_EMBEDDED_BANKS -void adlFromInstrument(const BanksDump::InstrumentEntry &instIn, adlinsdata2 &instOut) +void adlFromInstrument(const BanksDump::InstrumentEntry &instIn, OplInstMeta &instOut) { instOut.voice2_fine_tune = 0.0; if(instIn.secondVoiceDetune != 0) instOut.voice2_fine_tune = (double)((((int)instIn.secondVoiceDetune + 128) >> 1) - 64) / 32.0; - instOut.midi_velocity_offset = instIn.midiVelocityOffset; - instOut.tone = instIn.percussionKeyNumber; - instOut.flags = (instIn.instFlags & WOPL_Ins_4op) && (instIn.instFlags & WOPL_Ins_Pseudo4op) ? adlinsdata::Flag_Pseudo4op : 0; - instOut.flags|= (instIn.instFlags & WOPL_Ins_4op) && ((instIn.instFlags & WOPL_Ins_Pseudo4op) == 0) ? adlinsdata::Flag_Real4op : 0; - instOut.flags|= (instIn.instFlags & WOPL_Ins_IsBlank) ? adlinsdata::Flag_NoSound : 0; + instOut.midiVelocityOffset = instIn.midiVelocityOffset; + instOut.drumTone = instIn.percussionKeyNumber; + instOut.flags = (instIn.instFlags & WOPL_Ins_4op) && (instIn.instFlags & WOPL_Ins_Pseudo4op) ? OplInstMeta::Flag_Pseudo4op : 0; + instOut.flags|= (instIn.instFlags & WOPL_Ins_4op) && ((instIn.instFlags & WOPL_Ins_Pseudo4op) == 0) ? OplInstMeta::Flag_Real4op : 0; + instOut.flags|= (instIn.instFlags & WOPL_Ins_IsBlank) ? OplInstMeta::Flag_NoSound : 0; instOut.flags|= instIn.instFlags & WOPL_RhythmModeMask; for(size_t op = 0; op < 2; op++) @@ -141,15 +113,15 @@ void adlFromInstrument(const BanksDump::InstrumentEntry &instIn, adlinsdata2 &in break; const BanksDump::Operator &op1 = g_embeddedBanksOperators[instIn.ops[(op * 2) + 0]]; const BanksDump::Operator &op2 = g_embeddedBanksOperators[instIn.ops[(op * 2) + 1]]; - instOut.adl[op].modulator_E862 = op1.d_E862; - instOut.adl[op].modulator_40 = op1.d_40; - instOut.adl[op].carrier_E862 = op2.d_E862; - instOut.adl[op].carrier_40 = op2.d_40; - instOut.adl[op].feedconn = (instIn.fbConn >> (op * 8)) & 0xFF; - instOut.adl[op].finetune = static_cast<int8_t>(op == 0 ? instIn.noteOffset1 : instIn.noteOffset2); + instOut.op[op].modulator_E862 = op1.d_E862; + instOut.op[op].modulator_40 = op1.d_40; + instOut.op[op].carrier_E862 = op2.d_E862; + instOut.op[op].carrier_40 = op2.d_40; + instOut.op[op].feedconn = (instIn.fbConn >> (op * 8)) & 0xFF; + instOut.op[op].noteOffset = static_cast<int8_t>(op == 0 ? instIn.noteOffset1 : instIn.noteOffset2); } - instOut.ms_sound_kon = instIn.delay_on_ms; - instOut.ms_sound_koff = instIn.delay_off_ms; + instOut.soundKeyOnMs = instIn.delay_on_ms; + instOut.soundKeyOffMs = instIn.delay_off_ms; } #endif diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index a5a3b8c..0481a72 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -228,7 +228,7 @@ extern void adl_audioTickHandler(void *instance, uint32_t chipId, uint32_t rate) extern int adlCalculateFourOpChannels(MIDIplay *play, bool silent = false); #ifndef DISABLE_EMBEDDED_BANKS -extern void adlFromInstrument(const BanksDump::InstrumentEntry &instIn, adlinsdata2 &instOut); +extern void adlFromInstrument(const BanksDump::InstrumentEntry &instIn, OplInstMeta &instOut); #endif #endif // ADLMIDI_PRIVATE_HPP diff --git a/test/conversion/conversion.cpp b/test/conversion/conversion.cpp index b4d64eb..8124fdd 100644 --- a/test/conversion/conversion.cpp +++ b/test/conversion/conversion.cpp @@ -70,7 +70,7 @@ TEST_CASE("[Conversion] Main") for (unsigned i = 0; i < 1000000; ++i) { ADL_Instrument adl_ins = random_instrument(); - adlinsdata2 internal_ins; + OplInstMeta internal_ins; cvt_generic_to_FMIns(internal_ins, adl_ins); ADL_Instrument adl_ins2; |