From f729563b683c3ac7adcf07d2f4dffcdfa49fd605 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Tue, 8 May 2018 20:32:41 +0200 Subject: fix pitchbend --- src/adlmidi_midiplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 7c40fa0..39d7bff 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1393,7 +1393,7 @@ void MIDIplay::realTime_PatchChange(uint8_t channel, uint8_t patch) void MIDIplay::realTime_PitchBend(uint8_t channel, uint16_t pitch) { channel = channel % 16; - Ch[channel].bend = (uint32_t(pitch) - 8192) * Ch[channel].bendsense; + Ch[channel].bend = (int(pitch) - 8192) * Ch[channel].bendsense; NoteUpdate_All(channel, Upd_Pitch); } -- cgit v1.2.3 From 6545b648cded507215be777864194f4cc961f877 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Thu, 10 May 2018 15:03:47 +0200 Subject: meaningful handling of pitch bend sensitivity --- src/adlmidi_midiplay.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 39d7bff..e7489b1 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -2358,8 +2358,14 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB) switch(addr + nrpn * 0x10000 + MSB * 0x20000) { case 0x0000 + 0*0x10000 + 1*0x20000: // Pitch-bender sensitivity - Ch[MidCh].bendsense = value / 8192.0; + { + if (MSB) + Ch[MidCh].bendsense_msb = value; + else + Ch[MidCh].bendsense_lsb = value; + Ch[MidCh].updateBendSensitivity(); break; + } case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed if(value == 64) Ch[MidCh].vibspeed = 1.0; else if(value < 100) Ch[MidCh].vibspeed = 1.0 / (1.6e-2 * (value ? value : 1)); -- cgit v1.2.3 From 82b0b69707fe69108fd1721b97f14b55d5c50642 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Thu, 10 May 2018 16:19:27 +0200 Subject: pitch bend sensitivity attempt #2 --- src/adlmidi_midiplay.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index e7489b1..6bc2366 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -2358,14 +2358,13 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB) switch(addr + nrpn * 0x10000 + MSB * 0x20000) { case 0x0000 + 0*0x10000 + 1*0x20000: // Pitch-bender sensitivity - { - if (MSB) - Ch[MidCh].bendsense_msb = value; - else - Ch[MidCh].bendsense_lsb = value; + Ch[MidCh].bendsense_msb = value; + Ch[MidCh].updateBendSensitivity(); + break; + case 0x0000 + 0*0x10000 + 0*0x20000: // Pitch-bender sensitivity LSB + Ch[MidCh].bendsense_lsb = value; Ch[MidCh].updateBendSensitivity(); break; - } case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed if(value == 64) Ch[MidCh].vibspeed = 1.0; else if(value < 100) Ch[MidCh].vibspeed = 1.0 / (1.6e-2 * (value ? value : 1)); -- cgit v1.2.3 From 07bf460041bcc518483078afb34e83b9a3aeabb6 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Mon, 14 May 2018 03:56:48 +0300 Subject: Fixed DosBox emulator build with the same issue when macros not defined --- src/adlmidi_midiplay.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 6bc2366..69c1808 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -2797,6 +2797,7 @@ void MIDIplay::AdlChannel::users_clear() void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count) { + ADL_UNUSED(count);//Avoid warning for release builds assert(count <= users_max); if(users == users_first && users) { // self assignment -- cgit v1.2.3 From e0576650d4b235c291ca68bf8d5aa6b7f6d3b6cf Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 15:16:15 +0200 Subject: make the AdlInstrumentTester a P-Impl --- src/adlmidi_midiplay.cpp | 57 ++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 21 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 69c1808..9ccd3f8 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -2517,35 +2517,47 @@ retry_arpeggio: #ifndef ADLMIDI_DISABLE_CPP_EXTRAS +struct AdlInstrumentTester::Impl +{ + uint32_t cur_gm; + uint32_t ins_idx; + std::vector adl_ins_list; + OPL3 *opl; + MIDIplay *play; +}; + ADLMIDI_EXPORT AdlInstrumentTester::AdlInstrumentTester(ADL_MIDIPlayer *device) + : P(new Impl) { - cur_gm = 0; - ins_idx = 0; - play = reinterpret_cast(device->adl_midiPlayer); - if(!play) - return; - opl = &play->opl; + MIDIplay *play = reinterpret_cast(device->adl_midiPlayer); + P->cur_gm = 0; + P->ins_idx = 0; + P->play = play; + P->opl = play ? &play->opl : NULL; } ADLMIDI_EXPORT AdlInstrumentTester::~AdlInstrumentTester() -{} +{ + delete P; +} ADLMIDI_EXPORT void AdlInstrumentTester::FindAdlList() { const unsigned NumBanks = (unsigned)adl_getBanksCount(); std::set adl_ins_set; for(unsigned bankno = 0; bankno < NumBanks; ++bankno) - adl_ins_set.insert(banks[bankno][cur_gm]); - adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end()); - ins_idx = 0; + adl_ins_set.insert(banks[bankno][P->cur_gm]); + P->adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end()); + P->ins_idx = 0; NextAdl(0); - opl->Silence(); + P->opl->Silence(); } ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127 { + OPL3 *opl = P->opl; if(opl->LogarithmicVolumes) opl->Touch_Real(c, volume * 127 / (127 * 127 * 127) / 2); else @@ -2559,11 +2571,13 @@ ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // V ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) { - if(adl_ins_list.empty()) FindAdlList(); - const unsigned meta = adl_ins_list[ins_idx]; + MIDIplay *play = P->play; + OPL3 *opl = P->opl; + if(P->adl_ins_list.empty()) FindAdlList(); + const unsigned meta = P->adl_ins_list[P->ins_idx]; const adlinsdata &ains = opl->GetAdlMetaIns(meta); - int tone = (cur_gm & 128) ? (cur_gm & 127) : (note + 50); + int tone = (P->cur_gm & 128) ? (P->cur_gm & 127) : (note + 50); if(ains.tone) { /*if(ains.tone < 20) @@ -2611,15 +2625,16 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) ADLMIDI_EXPORT void AdlInstrumentTester::NextGM(int offset) { - cur_gm = (cur_gm + 256 + (uint32_t)offset) & 0xFF; + P->cur_gm = (P->cur_gm + 256 + (uint32_t)offset) & 0xFF; FindAdlList(); } ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) { - if(adl_ins_list.empty()) FindAdlList(); + OPL3 *opl = P->opl; + if(P->adl_ins_list.empty()) FindAdlList(); const unsigned NumBanks = (unsigned)adl_getBanksCount(); - ins_idx = (uint32_t)((int32_t)ins_idx + (int32_t)adl_ins_list.size() + offset) % adl_ins_list.size(); + P->ins_idx = (uint32_t)((int32_t)P->ins_idx + (int32_t)P->adl_ins_list.size() + offset) % P->adl_ins_list.size(); #if 0 UI.Color(15); @@ -2632,9 +2647,9 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) std::fflush(stderr); #endif - for(unsigned a = 0; a < adl_ins_list.size(); ++a) + for(unsigned a = 0, n = P->adl_ins_list.size(); a < n; ++a) { - const unsigned i = adl_ins_list[a]; + const unsigned i = P->adl_ins_list[a]; const adlinsdata &ains = opl->GetAdlMetaIns(i); char ToneIndication[8] = " "; @@ -2651,12 +2666,12 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) std::printf("%s%s%s%u\t", ToneIndication, ains.adlno1 != ains.adlno2 ? "[2]" : " ", - (ins_idx == a) ? "->" : "\t", + (P->ins_idx == a) ? "->" : "\t", i ); for(unsigned bankno = 0; bankno < NumBanks; ++bankno) - if(banks[bankno][cur_gm] == i) + if(banks[bankno][P->cur_gm] == i) std::printf(" %u", bankno); std::printf("\n"); -- cgit v1.2.3 From 9b478615e7f0cd73c360fd289b05db52b5f730f1 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 01:31:18 +0200 Subject: storing adldata and adlinsdata in unified structures --- src/adlmidi_midiplay.cpp | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 9ccd3f8..5f3ce57 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1058,12 +1058,12 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //int meta = banks[opl.AdlBank][midiins]; size_t meta = opl.GetAdlMetaNumber(midiins); - const adlinsdata *ains = &opl.GetAdlMetaIns(meta); + adlinsdata2 ains = opl.GetAdlMetaIns(meta); int16_t tone = note; if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks { - if(ains->flags & adlinsdata::Flag_NoSound) + if(ains.flags & adlinsdata::Flag_NoSound) { if(hooks.onDebugMessage) { @@ -1076,27 +1076,27 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) bank = 0; midiins = Ch[channel].patch; meta = opl.GetAdlMetaNumber(midiins); - ains = &opl.GetAdlMetaIns(meta); + ains = opl.GetAdlMetaIns(meta); } } - if(ains->tone) + if(ains.tone) { /*if(ains.tone < 20) tone += ains.tone; else*/ - if(ains->tone < 128) - tone = ains->tone; + if(ains.tone < 128) + tone = ains.tone; else - tone -= ains->tone - 128; + tone -= ains.tone - 128; } //uint16_t i[2] = { ains.adlno1, ains.adlno2 }; - bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op; + bool pseudo_4op = ains.flags & adlinsdata::Flag_Pseudo4op; MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] = { - {0, ains->adlno1, false}, - {0, ains->adlno2, pseudo_4op} + {0, ains.adl[0], false}, + {0, ains.adl[1], pseudo_4op} }; if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF]) @@ -1104,7 +1104,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(hooks.onDebugMessage) { - if(!caugh_missing_instruments.count(static_cast(midiins)) && (ains->flags & adlinsdata::Flag_NoSound)) + if(!caugh_missing_instruments.count(static_cast(midiins)) && (ains.flags & adlinsdata::Flag_NoSound)) { hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins); caugh_missing_instruments.insert(static_cast(midiins)); @@ -1132,7 +1132,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(ccount == 1 && static_cast(a) == adlchannel[0]) continue; // ^ Don't use the same channel for primary&secondary - if(voices[0].insId == voices[1].insId || pseudo_4op/*i[0] == i[1] || pseudo_4op*/) + if(voices[0].ains == voices[1].ains || pseudo_4op/*i[0] == i[1] || pseudo_4op*/) { // Only use regular channels uint8_t expected_mode = 0; @@ -1440,7 +1440,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, const uint8_t vol = info.vol; const int midiins = info.midiins; const size_t insmeta = info.insmeta; - const adlinsdata &ains = opl.GetAdlMetaIns(insmeta); + const adlinsdata2 ains = opl.GetAdlMetaIns(insmeta); AdlChannel::Location my_loc; my_loc.MidCh = MidCh; my_loc.note = info.note; @@ -1454,7 +1454,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, if(props_mask & Upd_Patch) { - opl.Patch(c, ins.insId); + opl.Patch(c, ins.ains); AdlChannel::LocationData *d = ch[c].users_find_or_create(my_loc); if(d) { // inserts if necessary d->sustained = false; @@ -1610,7 +1610,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, // Don't bend a sustained note if(!d || !d->sustained) { - double bend = Ch[MidCh].bend + opl.GetAdlIns(ins.insId).finetune; + double bend = Ch[MidCh].bend + ins.ains.finetune; double phase = 0.0; if((ains.flags & adlinsdata::Flag_Pseudo4op) && ins.pseudo4op) @@ -2575,7 +2575,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) OPL3 *opl = P->opl; if(P->adl_ins_list.empty()) FindAdlList(); const unsigned meta = P->adl_ins_list[P->ins_idx]; - const adlinsdata &ains = opl->GetAdlMetaIns(meta); + const adlinsdata2 ains = opl->GetAdlMetaIns(meta); int tone = (P->cur_gm & 128) ? (P->cur_gm & 127) : (note + 50); if(ains.tone) @@ -2589,16 +2589,15 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) tone -= ains.tone - 128; } double hertz = 172.00093 * std::exp(0.057762265 * (tone + 0.0)); - int i[2] = { ains.adlno1, ains.adlno2 }; int32_t adlchannel[2] = { 0, 3 }; - if(i[0] == i[1]) + if(ains.adl[0] == ains.adl[1]) { adlchannel[1] = -1; adlchannel[0] = 6; // single-op if(play->hooks.onDebugMessage) { play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData, - "noteon at %d(%d) for %g Hz\n", adlchannel[0], i[0], hertz); + "noteon at %d for %g Hz\n", adlchannel[0], hertz); } } else @@ -2606,7 +2605,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) if(play->hooks.onDebugMessage) { play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData, - "noteon at %d(%d) and %d(%d) for %g Hz\n", adlchannel[0], i[0], adlchannel[1], i[1], hertz); + "noteon at %d and %d for %g Hz\n", adlchannel[0], adlchannel[1], hertz); } } @@ -2616,7 +2615,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) for(unsigned c = 0; c < 2; ++c) { if(adlchannel[c] < 0) continue; - opl->Patch((uint16_t)adlchannel[c], (uint16_t)i[c]); + opl->Patch((uint16_t)adlchannel[c], ains.adl[c]); opl->Touch_Real((uint16_t)adlchannel[c], 127 * 127 * 100); opl->Pan((uint16_t)adlchannel[c], 0x30); opl->NoteOn((uint16_t)adlchannel[c], hertz); @@ -2650,7 +2649,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) for(unsigned a = 0, n = P->adl_ins_list.size(); a < n; ++a) { const unsigned i = P->adl_ins_list[a]; - const adlinsdata &ains = opl->GetAdlMetaIns(i); + const adlinsdata2 ains = opl->GetAdlMetaIns(i); char ToneIndication[8] = " "; if(ains.tone) @@ -2665,7 +2664,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) } std::printf("%s%s%s%u\t", ToneIndication, - ains.adlno1 != ains.adlno2 ? "[2]" : " ", + ains.adl[0] != ains.adl[1] ? "[2]" : " ", (P->ins_idx == a) ? "->" : "\t", i ); -- cgit v1.2.3 From bed6bcb220346c622a307bf405b9a1e87fd99db5 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 19 May 2018 19:55:47 +0300 Subject: OpenWatcom compilation fix --- src/adlmidi_midiplay.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 5f3ce57..1ee7cfb 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1093,11 +1093,21 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //uint16_t i[2] = { ains.adlno1, ains.adlno2 }; bool pseudo_4op = ains.flags & adlinsdata::Flag_Pseudo4op; +#ifndef __WATCOMC__ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] = { {0, ains.adl[0], false}, {0, ains.adl[1], 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].pseudo4op = false; + voices[1].chip_chan = 0; + voices[1].ains = ains.adl[1]; + voices[1].pseudo4op = pseudo_4op; +#endif if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF]) voices[1] = voices[0];//i[1] = i[0]; -- cgit v1.2.3 From bb4797ee68c0f12018196d3ee8caddcdcad9fe38 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 19 May 2018 22:33:37 +0300 Subject: Works and fixes - Fixed an incorrect calculation of 4-op channels and choosing 4-op channels for 2-op only banks - Resolved trouble with automatically chosen flags because of internal confusion --- src/adlmidi_midiplay.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 1ee7cfb..8aab901 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -740,16 +740,28 @@ MIDIplay::MIDIplay(unsigned long sampleRate): void MIDIplay::applySetup() { m_setup.tick_skip_samples_delay = 0; - opl.HighTremoloMode = m_setup.HighTremoloMode == -1 ? adlbanksetup[m_setup.AdlBank].deepTremolo : (bool)m_setup.HighTremoloMode; - opl.HighVibratoMode = m_setup.HighVibratoMode == -1 ? adlbanksetup[m_setup.AdlBank].deepVibrato : (bool)m_setup.HighVibratoMode; - opl.AdlPercussionMode = m_setup.AdlPercussionMode == -1 ? adlbanksetup[m_setup.AdlBank].adLibPercussions : (bool)m_setup.AdlPercussionMode; - opl.ScaleModulators = m_setup.ScaleModulators == -1 ? adlbanksetup[m_setup.AdlBank].scaleModulators : (bool)m_setup.ScaleModulators; + + if(opl.AdlBank != ~0u) + opl.dynamic_bank_setup = adlbanksetup[m_setup.AdlBank]; + + opl.HighTremoloMode = m_setup.HighTremoloMode < 0 ? + opl.dynamic_bank_setup.deepTremolo : + (bool)m_setup.HighTremoloMode; + opl.HighVibratoMode = m_setup.HighVibratoMode < 0 ? + opl.dynamic_bank_setup.deepVibrato : + (bool)m_setup.HighVibratoMode; + opl.AdlPercussionMode = m_setup.AdlPercussionMode < 0 ? + opl.dynamic_bank_setup.adLibPercussions : + (bool)m_setup.AdlPercussionMode; + opl.ScaleModulators = m_setup.ScaleModulators < 0 ? + opl.dynamic_bank_setup.scaleModulators : + (bool)m_setup.ScaleModulators; opl.LogarithmicVolumes = m_setup.LogarithmicVolumes; //opl.CartoonersVolumes = false; opl.m_musicMode = OPL3::MODE_MIDI; opl.ChangeVolumeRangesModel(static_cast(m_setup.VolumeModel)); if(m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model - opl.m_volumeScale = (OPL3::VolumesScale)adlbanksetup[m_setup.AdlBank].volumeModel; + opl.m_volumeScale = (OPL3::VolumesScale)opl.dynamic_bank_setup.volumeModel; opl.NumCards = m_setup.NumCards; opl.NumFourOps = m_setup.NumFourOps; -- cgit v1.2.3 From f545d69e3384e235828580e3f3e64aa959435478 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 20 May 2018 02:07:05 +0300 Subject: Polishing default tempo for MIDI files are lacks the tempo event #91 --- src/adlmidi_midiplay.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 8aab901..7919e91 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1822,6 +1822,14 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat evt.subtype = evtype; evt.data.insert(evt.data.begin(), data.begin(), data.end()); +#if 0 /* Print all tempo events */ + if(evt.subtype == MidiEvent::ST_TEMPOCHANGE) + { + if(hooks.onDebugMessage) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "Temp Change: %02X%02X%02X", evt.data[0], evt.data[1], evt.data[2]); + } +#endif + /* TODO: Store those meta-strings separately and give ability to read them * by external functions (to display song title and copyright in the player) */ if(evt.subtype == MidiEvent::ST_COPYRIGHT) -- cgit v1.2.3 From 56c0cd7f2439898080df2e0a8129b72d2d85ca70 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Thu, 31 May 2018 02:05:58 +0300 Subject: Small polishing of volume model and CMF/RSXX tempo - Removed "Logarithmic volumes" flag as volume models concept successfuly serves this task. "Logarithmic volumes" flag is useless when we have volume models. - Fixed "too fast" tempo while playing CMF and EA-MUS (aka RSXX) files --- src/adlmidi_midiplay.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 7919e91..52d8409 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -756,8 +756,8 @@ void MIDIplay::applySetup() opl.ScaleModulators = m_setup.ScaleModulators < 0 ? opl.dynamic_bank_setup.scaleModulators : (bool)m_setup.ScaleModulators; - opl.LogarithmicVolumes = m_setup.LogarithmicVolumes; - //opl.CartoonersVolumes = false; + if(m_setup.LogarithmicVolumes) + opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3); opl.m_musicMode = OPL3::MODE_MIDI; opl.ChangeVolumeRangesModel(static_cast(m_setup.VolumeModel)); if(m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model @@ -1555,8 +1555,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, switch(opl.m_volumeScale) { + case OPL3::VOLUME_Generic: - case OPL3::VOLUME_CMF: { volume = vol * Ch[MidCh].volume * Ch[MidCh].expression; @@ -1569,20 +1569,24 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, */ //volume = (int)(volume * std::sqrt( (double) ch[c].users.size() )); - if(opl.LogarithmicVolumes) - volume = volume * 127 / (127 * 127 * 127) / 2; - else - { - // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A) - volume = volume > 8725 ? static_cast(std::log(static_cast(volume)) * 11.541561 + (0.5 - 104.22845)) : 0; - // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A) - //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0); - } + // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A) + volume = volume > 8725 ? static_cast(std::log(static_cast(volume)) * 11.541561 + (0.5 - 104.22845)) : 0; + // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A) + //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0); + opl.Touch_Real(c, volume, brightness); //opl.Touch(c, volume); } break; + case OPL3::VOLUME_NATIVE: + { + volume = vol * Ch[MidCh].volume * Ch[MidCh].expression; + volume = volume * 127 / (127 * 127 * 127) / 2; + opl.Touch_Real(c, volume, brightness); + } + break; + case OPL3::VOLUME_DMX: { volume = 2 * ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129) + 1; @@ -2588,7 +2592,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::FindAdlList() ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127 { OPL3 *opl = P->opl; - if(opl->LogarithmicVolumes) + if(opl->m_volumeScale == OPL3::VOLUME_NATIVE) opl->Touch_Real(c, volume * 127 / (127 * 127 * 127) / 2); else { -- cgit v1.2.3 From 91d6cdb84996710e993ccdf85203ac65c3238457 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Thu, 31 May 2018 02:37:09 +0300 Subject: Failed attempt to move RSXX note-on to aftertouch conversion into preprocessor --- src/adlmidi_midiplay.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 52d8409..0ecb023 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1246,28 +1246,23 @@ void MIDIplay::realTime_NoteOff(uint8_t channel, uint8_t note) void MIDIplay::realTime_NoteAfterTouch(uint8_t channel, uint8_t note, uint8_t atVal) { channel = channel % 16; - MIDIchannel::activenoteiterator - i = Ch[channel].activenotes_find(note); - if(!i) + MIDIchannel::activenoteiterator i = Ch[channel].activenotes_find(note); + if(i) { - // Ignore touch if note is not active - return; + i->vol = 127 - atVal; + NoteUpdate(channel, i, Upd_Volume); } - i->vol = 127 - atVal; - NoteUpdate(channel, i, Upd_Volume); } void MIDIplay::realTime_ChannelAfterTouch(uint8_t channel, uint8_t atVal) { // TODO: Verify, is this correct action? channel = channel % 16; - for(MIDIchannel::activenoteiterator - i = Ch[channel].activenotes_begin(); i; ++i) + for(MIDIchannel::activenoteiterator i = Ch[channel].activenotes_begin(); i; ++i) { // Set this pressure to all active notes on the channel i->vol = 127 - atVal; } - NoteUpdate_All(channel, Upd_Volume); } @@ -1964,9 +1959,16 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat evt.data.push_back(*(ptr++)); evt.data.push_back(*(ptr++)); - if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0)) + /* TODO: Implement conversion of RSXX's note volumes out of synthesizer */ + /*if((opl.m_musicMode == OPL3::MODE_RSXX) && (evType == MidiEvent::T_NOTEON) && (evt.data[1] != 0)) + { + //NOT WORKING YET + evt.type = MidiEvent::T_NOTETOUCH; + } + else */if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0)) + { evt.type = MidiEvent::T_NOTEOFF; // Note ON with zero velocity is Note OFF! - //111'th loopStart controller (RPG Maker and others) + } //111'th loopStart controller (RPG Maker and others) else if((evType == MidiEvent::T_CTRLCHANGE) && (evt.data[0] == 111)) { //Change event type to custom Loop Start event and clear data -- cgit v1.2.3 From 17127e55c549ea59bb43bb6da7d06f11fd84db53 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Thu, 31 May 2018 03:36:40 +0300 Subject: Implement correct support for after-touch feature --- src/adlmidi_midiplay.cpp | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 0ecb023..c6bc198 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -976,6 +976,9 @@ void MIDIplay::realTime_ResetState() bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) { + if(note >= 128) + note = 128; + if((opl.m_musicMode == OPL3::MODE_RSXX) && (velocity != 0)) { // Check if this is just a note after-touch @@ -998,14 +1001,16 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(velocity == 0) return false; - size_t midiins = Ch[channel].patch; + MIDIchannel &midiChan = Ch[channel]; + + size_t midiins = midiChan.patch; bool isPercussion = (channel % 16 == 9); bool isXgPercussion = false; uint16_t bank = 0; - if(Ch[channel].bank_msb || Ch[channel].bank_lsb) + if(midiChan.bank_msb || midiChan.bank_lsb) { - bank = (uint16_t(Ch[channel].bank_msb) * 256) + uint16_t(Ch[channel].bank_lsb); + bank = (uint16_t(midiChan.bank_msb) * 256) + uint16_t(midiChan.bank_lsb); //0x7E00 - XG SFX1/SFX2 channel (16128 signed decimal) //0x7F00 - XG Percussion channel (16256 signed decimal) if(bank == 0x7E00 || bank == 0x7F00) @@ -1086,7 +1091,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) } } bank = 0; - midiins = Ch[channel].patch; + midiins = midiChan.patch; meta = opl.GetAdlMetaNumber(midiins); ains = opl.GetAdlMetaIns(meta); } @@ -1199,7 +1204,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(hooks.onDebugMessage) hooks.onDebugMessage(hooks.onDebugMessage_userData, "ignored unplaceable note [bank %i, inst %i, note %i, MIDI channel %i]", - bank, Ch[channel].patch, note, channel); + bank, midiChan.patch, note, channel); continue; // Could not play this note. Ignore it. } @@ -1218,8 +1223,9 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) // Allocate active note for MIDI channel std::pair - ir = Ch[channel].activenotes_insert(note); + ir = midiChan.activenotes_insert(note); ir.first->vol = velocity; + ir.first->vibrato = midiChan.noteAftertouch[note]; ir.first->tone = tone; ir.first->midiins = midiins; ir.first->insmeta = meta; @@ -1246,24 +1252,20 @@ void MIDIplay::realTime_NoteOff(uint8_t channel, uint8_t note) void MIDIplay::realTime_NoteAfterTouch(uint8_t channel, uint8_t note, uint8_t atVal) { channel = channel % 16; + MIDIchannel &chan = Ch[channel]; MIDIchannel::activenoteiterator i = Ch[channel].activenotes_find(note); if(i) { - i->vol = 127 - atVal; - NoteUpdate(channel, i, Upd_Volume); + i->vibrato = atVal; } + chan.noteAftertouch[note % 128] = atVal; + chan.noteAfterTouchInUse = (std::memcmp(chan.noteAftertouch, chan.noteAftertouch_Zero, 128) != 0); } void MIDIplay::realTime_ChannelAfterTouch(uint8_t channel, uint8_t atVal) { - // TODO: Verify, is this correct action? channel = channel % 16; - for(MIDIchannel::activenoteiterator i = Ch[channel].activenotes_begin(); i; ++i) - { - // Set this pressure to all active notes on the channel - i->vol = 127 - atVal; - } - NoteUpdate_All(channel, Upd_Volume); + Ch[channel].aftertouch = atVal; } void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value) @@ -1633,14 +1635,16 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, { double bend = Ch[MidCh].bend + ins.ains.finetune; double phase = 0.0; + uint8_t vibrato = std::max(Ch[MidCh].vibrato, Ch[MidCh].aftertouch); + vibrato = std::max(vibrato, i->vibrato); if((ains.flags & adlinsdata::Flag_Pseudo4op) && ins.pseudo4op) { phase = ains.voice2_fine_tune;//0.125; // Detune the note slightly (this is what Doom does) } - if(Ch[MidCh].vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay)) - bend += Ch[MidCh].vibrato * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos); + if(vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay)) + bend += static_cast(vibrato) * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos); #ifdef ADLMIDI_USE_DOSBOX_OPL #define BEND_COEFFICIENT 172.00093 @@ -2453,7 +2457,7 @@ void MIDIplay::UpdateVibrato(double amount) { for(size_t a = 0, b = Ch.size(); a < b; ++a) { - if(Ch[a].vibrato && !Ch[a].activenotes_empty()) + if(Ch[a].hasVibrato() && !Ch[a].activenotes_empty()) { NoteUpdate_All(static_cast(a), Upd_Pitch); Ch[a].vibpos += amount * Ch[a].vibspeed; -- cgit v1.2.3 From ae5298bc3638b1883cb2925ec07b60a7e158e26f Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Thu, 31 May 2018 03:11:28 +0200 Subject: a small mistake fixed about maximum note number --- src/adlmidi_midiplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index c6bc198..e453a05 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -977,7 +977,7 @@ void MIDIplay::realTime_ResetState() bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) { if(note >= 128) - note = 128; + note = 127; if((opl.m_musicMode == OPL3::MODE_RSXX) && (velocity != 0)) { -- cgit v1.2.3 From 9007918bce92c5af1305426ead055591e29dd6b9 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Thu, 31 May 2018 07:36:51 +0200 Subject: rewrite the check of whether aftertouch is used --- src/adlmidi_midiplay.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index e453a05..b8ef555 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1258,8 +1258,16 @@ void MIDIplay::realTime_NoteAfterTouch(uint8_t channel, uint8_t note, uint8_t at { i->vibrato = atVal; } - chan.noteAftertouch[note % 128] = atVal; - chan.noteAfterTouchInUse = (std::memcmp(chan.noteAftertouch, chan.noteAftertouch_Zero, 128) != 0); + + uint8_t oldAtVal = chan.noteAftertouch[note % 128]; + if(atVal != oldAtVal) + { + chan.noteAftertouch[note % 128] = atVal; + bool inUse = atVal != 0; + for(unsigned n = 0; !inUse && n < 128; ++n) + inUse = chan.noteAftertouch[n] != 0; + chan.noteAfterTouchInUse = inUse; + } } void MIDIplay::realTime_ChannelAfterTouch(uint8_t channel, uint8_t atVal) -- cgit v1.2.3 From 77c563275fe8ad287b6d43e2ba041a2918db369c Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Thu, 31 May 2018 07:40:39 +0200 Subject: rewrite DMX table to occupy 8x less space --- src/adlmidi_midiplay.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index b8ef555..8da4a43 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -25,7 +25,7 @@ // Mapping from MIDI volume level to OPL level value. -static const uint32_t DMX_volume_mapping_table[] = +static const uint8_t DMX_volume_mapping_table[128] = { 0, 1, 3, 5, 6, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, @@ -43,23 +43,6 @@ static const uint32_t DMX_volume_mapping_table[] = 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127, - //Protection entries to avoid crash if value more than 127 - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, }; static const uint8_t W9X_volume_mapping_table[32] = @@ -1596,7 +1579,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, { volume = 2 * ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129) + 1; //volume = 2 * (Ch[MidCh].volume) + 1; - volume = (DMX_volume_mapping_table[vol] * volume) >> 9; + volume = (DMX_volume_mapping_table[(vol < 128) ? vol : 127] * volume) >> 9; opl.Touch_Real(c, volume, brightness); } break; -- cgit v1.2.3 From c4ed5cf15e64a84129865a58b5063ef0e73f0bcf Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 14:27:04 +0200 Subject: bank storage inside dynamic map --- src/adlmidi_midiplay.cpp | 80 +++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 48 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 8da4a43..75b5f58 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1001,7 +1001,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //Let XG SFX1/SFX2 bank will have LSB==1 (128...255 range in WOPN file) //Let XG Percussion bank will use (0...127 range in WOPN file) bank = (uint16_t)midiins + ((bank == 0x7E00) ? 128 : 0); // MIDI instrument defines the patch - midiins = opl.dynamic_percussion_offset + note; // Percussion instrument + midiins = note; // Percussion instrument isXgPercussion = true; isPercussion = false; } @@ -1010,43 +1010,36 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(isPercussion) { bank = (uint16_t)midiins; // MIDI instrument defines the patch - midiins = opl.dynamic_percussion_offset + note; // Percussion instrument + midiins = note; // Percussion instrument } + if(isPercussion || isXgPercussion) + bank += OPL3::PercussionTag; //Set bank bank - if(bank > 0) + const OPL3::Bank *bnk = NULL; + if((bank & ~(uint16_t)OPL3::PercussionTag) > 0) { - if(isPercussion || isXgPercussion) - { - 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) - { - if(!caugh_missing_banks_melodic.count(bank)) - { - hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion MIDI bank %i (patch %i)", channel, bank, midiins); - caugh_missing_banks_melodic.insert(bank); - } - } - } - else + OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank); + if(b != opl.dynamic_banks.end()) + bnk = &b->second; + + if(!bnk && hooks.onDebugMessage) { - 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) - { - if(!caugh_missing_banks_percussion.count(bank)) - { - hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic MIDI bank %i (patch %i)", channel, bank, midiins); - caugh_missing_banks_percussion.insert(bank); - } - } + std::set &missing = (isPercussion || isXgPercussion) ? + caugh_missing_banks_percussion : caugh_missing_banks_melodic; + const char *text = (isPercussion || isXgPercussion) ? + "percussion" : "melodic"; + if(missing.insert(bank).second) + hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing %s MIDI bank %i (patch %i)", channel, text, bank, midiins); } } + //Or fall back to first bank + if(!bnk) + { + OPL3::BankMap::iterator b = opl.dynamic_banks.find((bank & OPL3::PercussionTag)); + if(b != opl.dynamic_banks.end()) + bnk = &b->second; + } /* if(MidCh%16 == 9 || (midiins != 32 && midiins != 46 && midiins != 48 && midiins != 50)) @@ -1057,8 +1050,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //if(midiins == 56) vol = vol*6/10; // HACK //int meta = banks[opl.AdlBank][midiins]; - size_t meta = opl.GetAdlMetaNumber(midiins); - adlinsdata2 ains = opl.GetAdlMetaIns(meta); + const adlinsdata2 &ains = bnk ? bnk->ins[midiins] : OPL3::emptyInstrument; int16_t tone = note; if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks @@ -1067,16 +1059,11 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) { if(hooks.onDebugMessage) { - if(!caugh_missing_instruments.count(static_cast(midiins))) - { + if(caugh_missing_instruments.insert(static_cast(midiins)).second) hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caugh a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank); - caugh_missing_instruments.insert(static_cast(midiins)); - } } bank = 0; midiins = midiChan.patch; - meta = opl.GetAdlMetaNumber(midiins); - ains = opl.GetAdlMetaIns(meta); } } @@ -1114,11 +1101,9 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(hooks.onDebugMessage) { - if(!caugh_missing_instruments.count(static_cast(midiins)) && (ains.flags & adlinsdata::Flag_NoSound)) - { + if((ains.flags & adlinsdata::Flag_NoSound) && + caugh_missing_instruments.insert(static_cast(midiins)).second) hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins); - caugh_missing_instruments.insert(static_cast(midiins)); - } } // Allocate AdLib channel (the physical sound channel for the note) @@ -1211,7 +1196,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) ir.first->vibrato = midiChan.noteAftertouch[note]; ir.first->tone = tone; ir.first->midiins = midiins; - ir.first->insmeta = meta; + ir.first->ains = &ains; ir.first->chip_channels_count = 0; for(unsigned ccount = 0; ccount < MIDIchannel::NoteInfo::MaxNumPhysChans; ++ccount) @@ -1449,8 +1434,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, const int16_t tone = info.tone; const uint8_t vol = info.vol; const int midiins = info.midiins; - const size_t insmeta = info.insmeta; - const adlinsdata2 ains = opl.GetAdlMetaIns(insmeta); + const adlinsdata2 &ains = *info.ains; AdlChannel::Location my_loc; my_loc.MidCh = MidCh; my_loc.note = info.note; @@ -2606,7 +2590,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note) OPL3 *opl = P->opl; if(P->adl_ins_list.empty()) FindAdlList(); const unsigned meta = P->adl_ins_list[P->ins_idx]; - const adlinsdata2 ains = opl->GetAdlMetaIns(meta); + const adlinsdata2 ains(adlins[meta]); int tone = (P->cur_gm & 128) ? (P->cur_gm & 127) : (note + 50); if(ains.tone) @@ -2680,7 +2664,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) for(unsigned a = 0, n = P->adl_ins_list.size(); a < n; ++a) { const unsigned i = P->adl_ins_list[a]; - const adlinsdata2 ains = opl->GetAdlMetaIns(i); + const adlinsdata2 ains(adlins[i]); char ToneIndication[8] = " "; if(ains.tone) -- cgit v1.2.3 From 9b7e9b6880cd2e3d2d11582bccb06c834c242010 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Fri, 1 Jun 2018 11:57:34 +0200 Subject: bank fallback on blank instrument --- src/adlmidi_midiplay.cpp | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 75b5f58..3d3f52e 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1015,6 +1015,8 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(isPercussion || isXgPercussion) bank += OPL3::PercussionTag; + const adlinsdata2 *ains = &OPL3::emptyInstrument; + //Set bank bank const OPL3::Bank *bnk = NULL; if((bank & ~(uint16_t)OPL3::PercussionTag) > 0) @@ -1023,7 +1025,9 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(b != opl.dynamic_banks.end()) bnk = &b->second; - if(!bnk && hooks.onDebugMessage) + if(bnk) + ains = &bnk->ins[midiins]; + else if(hooks.onDebugMessage) { std::set &missing = (isPercussion || isXgPercussion) ? caugh_missing_banks_percussion : caugh_missing_banks_melodic; @@ -1034,11 +1038,14 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) } } //Or fall back to first bank - if(!bnk) + if(ains->flags & adlinsdata::Flag_NoSound) { - OPL3::BankMap::iterator b = opl.dynamic_banks.find((bank & OPL3::PercussionTag)); + OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank & OPL3::PercussionTag); if(b != opl.dynamic_banks.end()) bnk = &b->second; + + if(bnk) + ains = &bnk->ins[midiins]; } /* @@ -1050,12 +1057,11 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //if(midiins == 56) vol = vol*6/10; // HACK //int meta = banks[opl.AdlBank][midiins]; - const adlinsdata2 &ains = bnk ? bnk->ins[midiins] : OPL3::emptyInstrument; int16_t tone = note; if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks { - if(ains.flags & adlinsdata::Flag_NoSound) + if(ains->flags & adlinsdata::Flag_NoSound) { if(hooks.onDebugMessage) { @@ -1067,32 +1073,32 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) } } - if(ains.tone) + if(ains->tone) { - /*if(ains.tone < 20) - tone += ains.tone; + /*if(ains->tone < 20) + tone += ains->tone; else*/ - if(ains.tone < 128) - tone = ains.tone; + if(ains->tone < 128) + tone = ains->tone; else - tone -= ains.tone - 128; + tone -= ains->tone - 128; } - //uint16_t i[2] = { ains.adlno1, ains.adlno2 }; - bool pseudo_4op = ains.flags & adlinsdata::Flag_Pseudo4op; + //uint16_t i[2] = { ains->adlno1, ains->adlno2 }; + bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op; #ifndef __WATCOMC__ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] = { - {0, ains.adl[0], false}, - {0, ains.adl[1], pseudo_4op} + {0, ains->adl[0], false}, + {0, ains->adl[1], 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].ains = ains->adl[0]; voices[0].pseudo4op = false; voices[1].chip_chan = 0; - voices[1].ains = ains.adl[1]; + voices[1].ains = ains->adl[1]; voices[1].pseudo4op = pseudo_4op; #endif @@ -1101,7 +1107,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(hooks.onDebugMessage) { - if((ains.flags & adlinsdata::Flag_NoSound) && + if((ains->flags & adlinsdata::Flag_NoSound) && caugh_missing_instruments.insert(static_cast(midiins)).second) hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins); } @@ -1196,7 +1202,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) ir.first->vibrato = midiChan.noteAftertouch[note]; ir.first->tone = tone; ir.first->midiins = midiins; - ir.first->ains = &ains; + ir.first->ains = ains; ir.first->chip_channels_count = 0; for(unsigned ccount = 0; ccount < MIDIchannel::NoteInfo::MaxNumPhysChans; ++ccount) -- cgit v1.2.3 From 82e57cf34fe4b5cd01ed6499eb0db6edc67b5da3 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 2 Jun 2018 00:46:50 +0300 Subject: Warning fixes --- src/adlmidi_midiplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 3d3f52e..610c64e 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -2651,7 +2651,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextGM(int offset) ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) { - OPL3 *opl = P->opl; + //OPL3 *opl = P->opl; if(P->adl_ins_list.empty()) FindAdlList(); const unsigned NumBanks = (unsigned)adl_getBanksCount(); P->ins_idx = (uint32_t)((int32_t)P->ins_idx + (int32_t)P->adl_ins_list.size() + offset) % P->adl_ins_list.size(); -- cgit v1.2.3 From 461bc4c3c4a89852bcd70c793f55cda3eba2ff4c Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 2 Jun 2018 01:25:49 +0300 Subject: Remove duplicated "Poke" function call It's no sense to have uint32-argument poke function as all emulators are using uint16 and uint8 data only --- src/adlmidi_midiplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 610c64e..16d125e 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -2066,7 +2066,7 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu v |= 0x30; //std::printf("OPL poke %02X, %02X\n", i, v); //std::fflush(stdout); - opl.PokeN(0, i, v); + opl.Poke(0, i, v); return; } -- cgit v1.2.3 From bfd80e89d91a1f014ee8c7bf8996aecfbc257975 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 2 Jun 2018 01:41:10 +0300 Subject: Beautify the "adlmidi_midiplay.cpp" --- src/adlmidi_midiplay.cpp | 148 +++++++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 69 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 16d125e..07bcc6a 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -205,7 +205,9 @@ void MIDIplay::MidiTrackRow::sortEvents(bool *noteStates) j = noteOffs.erase(j); markAsOn.erase(note_i); continue; - } else { + } + else + { //When same row has many note-offs on same row //that means a zero-length note follows previous note //it must be shuted down @@ -434,17 +436,17 @@ bool MIDIplay::buildTrackData() if(track.empty()) continue;//Empty track is useless! - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION std::fprintf(stdout, "\n============Track %" PRIuPTR "=============\n", tk); std::fflush(stdout); - #endif +#endif MidiTrackRow *posPrev = &(*(track.begin()));//First element for(MidiTrackQueue::iterator it = track.begin(); it != track.end(); it++) { - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION bool tempoChanged = false; - #endif +#endif MidiTrackRow &pos = *it; if((posPrev != &pos) && //Skip first event (!tempos.empty()) && //Only when in-track tempo events are available @@ -490,9 +492,9 @@ bool MIDIplay::buildTrackData() //Apply next tempo currentTempo = points[j].tempo; - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION tempoChanged = true; - #endif +#endif } //Then calculate time between last tempo change point and end point TempoChangePoint tailTempo = points.back(); @@ -535,10 +537,10 @@ bool MIDIplay::buildTrackData() loopEndTime = pos.time; } - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION std::fprintf(stdout, "= %10" PRId64 " = %10f%s\n", pos.absPos, pos.time, tempoChanged ? " <----TEMPO CHANGED" : ""); std::fflush(stdout); - #endif +#endif abs_position += pos.delay; posPrev = &pos; @@ -558,7 +560,7 @@ bool MIDIplay::buildTrackData() //Resolve "hell of all times" of too short drum notes: //move too short percussion note-offs far far away as possible /********************************************************************************/ - #if 1 //Use this to record WAVEs for comparison before/after implementing of this +#if 1 //Use this to record WAVEs for comparison before/after implementing of this if(opl.m_musicMode == OPL3::MODE_MIDI)//Percussion fix is needed for MIDI only, not for IMF/RSXX or CMF { //! Minimal real time in seconds @@ -608,8 +610,8 @@ bool MIDIplay::buildTrackData() } bool percussion = (et->channel == 9) || - banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal) - banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal) + banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal) + banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal) if(!percussion) continue; @@ -670,7 +672,7 @@ bool MIDIplay::buildTrackData() #undef DRUM_NOTE_MIN_TIME #undef DRUM_NOTE_MIN_TICKS } - #endif +#endif return true; } @@ -728,17 +730,17 @@ void MIDIplay::applySetup() opl.dynamic_bank_setup = adlbanksetup[m_setup.AdlBank]; opl.HighTremoloMode = m_setup.HighTremoloMode < 0 ? - opl.dynamic_bank_setup.deepTremolo : - (bool)m_setup.HighTremoloMode; + opl.dynamic_bank_setup.deepTremolo : + (bool)m_setup.HighTremoloMode; opl.HighVibratoMode = m_setup.HighVibratoMode < 0 ? - opl.dynamic_bank_setup.deepVibrato : - (bool)m_setup.HighVibratoMode; + opl.dynamic_bank_setup.deepVibrato : + (bool)m_setup.HighVibratoMode; opl.AdlPercussionMode = m_setup.AdlPercussionMode < 0 ? - opl.dynamic_bank_setup.adLibPercussions : - (bool)m_setup.AdlPercussionMode; + opl.dynamic_bank_setup.adLibPercussions : + (bool)m_setup.AdlPercussionMode; opl.ScaleModulators = m_setup.ScaleModulators < 0 ? - opl.dynamic_bank_setup.scaleModulators : - (bool)m_setup.ScaleModulators; + opl.dynamic_bank_setup.scaleModulators : + (bool)m_setup.ScaleModulators; if(m_setup.LogarithmicVolumes) opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3); opl.m_musicMode = OPL3::MODE_MIDI; @@ -791,9 +793,9 @@ uint64_t MIDIplay::ReadVarLenEx(uint8_t **ptr, uint8_t *end, bool &ok) double MIDIplay::Tick(double s, double granularity) { s *= tempoMultiplier; - #ifdef ENABLE_BEGIN_SILENCE_SKIPPING +#ifdef ENABLE_BEGIN_SILENCE_SKIPPING if(CurrentPositionNew.began) - #endif +#endif CurrentPositionNew.wait -= s; CurrentPositionNew.absTimePosition += s; @@ -822,7 +824,7 @@ double MIDIplay::Tick(double s, double granularity) return CurrentPositionNew.wait; } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ void MIDIplay::TickIteratos(double s) { @@ -939,7 +941,7 @@ void MIDIplay::setTempo(double tempo) { tempoMultiplier = tempo; } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ void MIDIplay::realTime_ResetState() { @@ -987,7 +989,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) MIDIchannel &midiChan = Ch[channel]; size_t midiins = midiChan.patch; - bool isPercussion = (channel % 16 == 9); + bool isPercussion = (channel % 16 == 9); bool isXgPercussion = false; uint16_t bank = 0; @@ -1030,9 +1032,9 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) else if(hooks.onDebugMessage) { std::set &missing = (isPercussion || isXgPercussion) ? - caugh_missing_banks_percussion : caugh_missing_banks_melodic; + caugh_missing_banks_percussion : caugh_missing_banks_melodic; const char *text = (isPercussion || isXgPercussion) ? - "percussion" : "melodic"; + "percussion" : "melodic"; if(missing.insert(bank).second) hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing %s MIDI bank %i (patch %i)", channel, text, bank, midiins); } @@ -1100,7 +1102,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) voices[1].chip_chan = 0; voices[1].ains = ains->adl[1]; voices[1].pseudo4op = pseudo_4op; -#endif +#endif /* __WATCOMC__ */ if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF]) voices[1] = voices[0];//i[1] = i[0]; @@ -1456,7 +1458,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, { opl.Patch(c, ins.ains); AdlChannel::LocationData *d = ch[c].users_find_or_create(my_loc); - if(d) { // inserts if necessary + if(d) // inserts if necessary + { d->sustained = false; d->vibdelay = 0; d->kon_time_until_neglible = ains.ms_sound_kon; @@ -1492,7 +1495,9 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, { opl.Touch_Real(c, 0); ch[c].koff_time_until_neglible = 0; - } else { + } + else + { ch[c].koff_time_until_neglible = ains.ms_sound_koff; } } @@ -1627,11 +1632,11 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, if(vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay)) bend += static_cast(vibrato) * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos); - #ifdef ADLMIDI_USE_DOSBOX_OPL -#define BEND_COEFFICIENT 172.00093 - #else -#define BEND_COEFFICIENT 172.4387 - #endif +#ifdef ADLMIDI_USE_DOSBOX_OPL +# define BEND_COEFFICIENT 172.00093 +#else +# define BEND_COEFFICIENT 172.4387 +#endif opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (tone + bend + phase))); #undef BEND_COEFFICIENT if(hooks.onNote) @@ -1656,9 +1661,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) const size_t TrackCount = CurrentPositionNew.track.size(); const PositionNew RowBeginPosition(CurrentPositionNew); - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION double maxTime = 0.0; - #endif +#endif for(size_t tk = 0; tk < TrackCount; ++tk) { @@ -1676,10 +1681,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) for(size_t i = 0; i < track.pos->events.size(); i++) { const MidiEvent &evt = track.pos->events[i]; - #ifdef ENABLE_BEGIN_SILENCE_SKIPPING +#ifdef ENABLE_BEGIN_SILENCE_SKIPPING if(!CurrentPositionNew.began && (evt.type == MidiEvent::T_NOTEON)) CurrentPositionNew.began = true; - #endif +#endif if(isSeek && (evt.type == MidiEvent::T_NOTEON)) continue; HandleEvent(tk, evt, track.status); @@ -1687,10 +1692,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) break;//Stop event handling on catching loopEnd event! } - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION if(maxTime < track.pos->time) maxTime = track.pos->time; - #endif +#endif // Read next event time (unless the track just ended) if(track.status >= 0) { @@ -1700,11 +1705,11 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) } } - #ifdef DEBUG_TIME_CALCULATION +#ifdef DEBUG_TIME_CALCULATION std::fprintf(stdout, " \r"); std::fprintf(stdout, "Time: %10f; Audio: %10f\r", maxTime, CurrentPositionNew.absTimePosition); std::fflush(stdout); - #endif +#endif // Find shortest delay from all track uint64_t shortest = 0; @@ -1728,9 +1733,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) fraction t = shortest * Tempo; - #ifdef ENABLE_BEGIN_SILENCE_SKIPPING +#ifdef ENABLE_BEGIN_SILENCE_SKIPPING if(CurrentPositionNew.began) - #endif +#endif CurrentPositionNew.wait += t.value(); //if(shortest > 0) UI.PrintLn("Delay %ld (%g)", shortest, (double)t.valuel()); @@ -1756,9 +1761,7 @@ bool MIDIplay::ProcessEventsNew(bool isSeek) return true;//Has events in queue } -#endif -#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &status) { uint8_t *&ptr = *pptr; @@ -1977,7 +1980,7 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat return evt; } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ const std::string &MIDIplay::getErrorString() { @@ -2146,7 +2149,7 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu } } } -#endif +#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const { @@ -2154,7 +2157,7 @@ int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::Not // Same midi-instrument = some stability //if(c == MidCh) s += 4; - for (AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next) + for(AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next) { s -= 4000; @@ -2468,9 +2471,9 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed { // If there is an adlib channel that has multiple notes // simulated on the same channel, arpeggio them. - #if 0 +#if 0 const unsigned desired_arpeggio_rate = 40; // Hz (upper limit) - #if 1 +# if 1 static unsigned cache = 0; amount = amount; // Ignore amount. Assume we get a constant rate. cache += MaxSamplesAtTime * desired_arpeggio_rate; @@ -2478,15 +2481,15 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed if(cache < PCM_RATE) return; cache %= PCM_RATE; - #else +# else static double arpeggio_cache = 0; arpeggio_cache += amount * desired_arpeggio_rate; if(arpeggio_cache < 1.0) return; arpeggio_cache = 0.0; - #endif - #endif +# endif +#endif static unsigned arpeggio_counter = 0; ++arpeggio_counter; @@ -2510,7 +2513,7 @@ retry_arpeggio: rate_reduction = 1; for(unsigned count = (arpeggio_counter / rate_reduction) % n_users, - n = 0; n < count; ++n) + n = 0; n < count; ++n) i = i->next; if(i->sustained == false) @@ -2656,7 +2659,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) const unsigned NumBanks = (unsigned)adl_getBanksCount(); P->ins_idx = (uint32_t)((int32_t)P->ins_idx + (int32_t)P->adl_ins_list.size() + offset) % P->adl_ins_list.size(); - #if 0 +#if 0 UI.Color(15); std::fflush(stderr); std::printf("SELECTED G%c%d\t%s\n", @@ -2665,7 +2668,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset) std::fflush(stdout); UI.Color(7); std::fflush(stderr); - #endif +#endif for(unsigned a = 0, n = P->adl_ins_list.size(); a < n; ++a) { @@ -2725,9 +2728,9 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch) NextGM(+1); break; case 3: - #if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)) +#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)) case 27: - #endif +#endif return false; default: const char *p = std::strchr(notes, ch); @@ -2737,7 +2740,7 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch) return true; } -#endif//ADLMIDI_DISABLE_CPP_EXTRAS +#endif /* ADLMIDI_DISABLE_CPP_EXTRAS */ // Implement the user map data structure. @@ -2777,13 +2780,15 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_allocate() MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_find_or_create(Location loc) { LocationData *user = users_find(loc); - if(!user) { + if(!user) + { user = users_allocate(); if(!user) return NULL; LocationData *prev = user->prev, *next = user->next; *user = LocationData(); - user->prev = prev; user->next = next; + user->prev = prev; + user->next = next; user->loc = loc; } return user; @@ -2799,7 +2804,8 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_insert(const Loc return NULL; LocationData *prev = user->prev, *next = user->next; *user = x; - user->prev = prev; user->next = next; + user->prev = prev; + user->next = next; } return user; } @@ -2834,7 +2840,8 @@ void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count) { ADL_UNUSED(count);//Avoid warning for release builds assert(count <= users_max); - if(users == users_first && users) { + if(users == users_first && users) + { // self assignment assert(users_size == count); return; @@ -2842,17 +2849,20 @@ void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count) users_clear(); const LocationData *src_cell = users; // move to the last - if(src_cell) { + if(src_cell) + { while(src_cell->next) src_cell = src_cell->next; } // push cell copies in reverse order - while(src_cell) { + while(src_cell) + { LocationData *dst_cell = users_allocate(); assert(dst_cell); LocationData *prev = dst_cell->prev, *next = dst_cell->next; *dst_cell = *src_cell; - dst_cell->prev = prev; dst_cell->next = next; + dst_cell->prev = prev; + dst_cell->next = next; src_cell = src_cell->prev; } assert(users_size == count); -- cgit v1.2.3 From adcf702a7e18846ad4f8753ec5a32cf56585ca23 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Sun, 3 Jun 2018 15:46:50 +0300 Subject: Bugfixes - Fixed all MSVC 2015/2017 warnings in both 32 and 64 bit builds - Fixed weird behavior when using adl_setHVibrato, adl_setHTremolo, adl_setScaleModulators, and adl_setVolumeRangeModel when passing the -1 "Auto" state - Move arpeggio counter into the MIDIPlay class as originally it was a global static variable which is ugly and danger when running multiple instances of the same library --- src/adlmidi_midiplay.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 07bcc6a..3c94d76 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -680,7 +680,8 @@ bool MIDIplay::buildTrackData() MIDIplay::MIDIplay(unsigned long sampleRate): - cmf_percussion_mode(false) + cmf_percussion_mode(false), + m_arpeggioCounter(0) #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER , fullSongTimeLength(0.0), postSongWaitDelay(1.0), @@ -731,16 +732,16 @@ void MIDIplay::applySetup() opl.HighTremoloMode = m_setup.HighTremoloMode < 0 ? opl.dynamic_bank_setup.deepTremolo : - (bool)m_setup.HighTremoloMode; + (m_setup.HighTremoloMode != 0); opl.HighVibratoMode = m_setup.HighVibratoMode < 0 ? opl.dynamic_bank_setup.deepVibrato : - (bool)m_setup.HighVibratoMode; + (m_setup.HighVibratoMode != 0); opl.AdlPercussionMode = m_setup.AdlPercussionMode < 0 ? opl.dynamic_bank_setup.adLibPercussions : - (bool)m_setup.AdlPercussionMode; + (m_setup.AdlPercussionMode != 0); opl.ScaleModulators = m_setup.ScaleModulators < 0 ? opl.dynamic_bank_setup.scaleModulators : - (bool)m_setup.ScaleModulators; + (m_setup.ScaleModulators != 0); if(m_setup.LogarithmicVolumes) opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3); opl.m_musicMode = OPL3::MODE_MIDI; @@ -755,6 +756,9 @@ void MIDIplay::applySetup() opl.Reset(m_setup.emulator, m_setup.PCM_RATE); ch.clear(); ch.resize(opl.NumChannels); + + // Reset the arpeggio counter + m_arpeggioCounter = 0; } #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER @@ -1441,7 +1445,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, MIDIchannel::NoteInfo &info = *i; const int16_t tone = info.tone; const uint8_t vol = info.vol; - const int midiins = info.midiins; + const int midiins = static_cast(info.midiins); const adlinsdata2 &ains = *info.ains; AdlChannel::Location my_loc; my_loc.MidCh = MidCh; @@ -2151,7 +2155,7 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu } #endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ -int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const +int64_t MIDIplay::CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const { int64_t s = -ch[c].koff_time_until_neglible; @@ -2198,7 +2202,7 @@ int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::Not // increase the score slightly. unsigned n_evacuation_stations = 0; - for(unsigned c2 = 0; c2 < opl.NumChannels; ++c2) + for(size_t c2 = 0; c2 < static_cast(opl.NumChannels); ++c2) { if(c2 == c) continue; @@ -2299,11 +2303,11 @@ void MIDIplay::KillOrEvacuate(size_t from_channel, hooks.onNote(hooks.onNote_userData, (int)from_channel, i->tone, - i->midiins, 0, 0.0); + static_cast(i->midiins), 0, 0.0); hooks.onNote(hooks.onNote_userData, (int)c, i->tone, - i->midiins, + static_cast(i->midiins), i->vol, 0.0); } @@ -2490,8 +2494,8 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed arpeggio_cache = 0.0; # endif #endif - static unsigned arpeggio_counter = 0; - ++arpeggio_counter; + + ++m_arpeggioCounter; for(uint32_t c = 0; c < opl.NumChannels; ++c) { @@ -2512,7 +2516,7 @@ retry_arpeggio: if(n_users >= 4) rate_reduction = 1; - for(unsigned count = (arpeggio_counter / rate_reduction) % n_users, + for(size_t count = (m_arpeggioCounter / rate_reduction) % n_users, n = 0; n < count; ++n) i = i->next; -- cgit v1.2.3 From 51a7cb19a8656c91baf616df5986d8e4c4cce97d Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Mon, 4 Jun 2018 03:30:28 +0300 Subject: Fixed bend sensitivity processing --- src/adlmidi_midiplay.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 3c94d76..2413f39 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1400,14 +1400,16 @@ void MIDIplay::realTime_PatchChange(uint8_t channel, uint8_t patch) void MIDIplay::realTime_PitchBend(uint8_t channel, uint16_t pitch) { channel = channel % 16; - Ch[channel].bend = (int(pitch) - 8192) * Ch[channel].bendsense; + Ch[channel].bendSrc = (int(pitch) - 8192); + Ch[channel].bend = Ch[channel].bendSrc * Ch[channel].bendsense; NoteUpdate_All(channel, Upd_Pitch); } void MIDIplay::realTime_PitchBend(uint8_t channel, uint8_t msb, uint8_t lsb) { channel = channel % 16; - Ch[channel].bend = (int(lsb) + int(msb) * 128 - 8192) * Ch[channel].bendsense; + Ch[channel].bendSrc = (int(lsb) + int(msb) * 128 - 8192); + Ch[channel].bend = Ch[channel].bendSrc * Ch[channel].bendsense; NoteUpdate_All(channel, Upd_Pitch); } @@ -1641,7 +1643,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, #else # define BEND_COEFFICIENT 172.4387 #endif - opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (tone + bend + phase))); + opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (static_cast(tone) + bend + phase))); #undef BEND_COEFFICIENT if(hooks.onNote) hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, Ch[MidCh].bend); @@ -2388,10 +2390,12 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB) case 0x0000 + 0*0x10000 + 1*0x20000: // Pitch-bender sensitivity Ch[MidCh].bendsense_msb = value; Ch[MidCh].updateBendSensitivity(); + NoteUpdate_All(MidCh, Upd_Pitch); break; case 0x0000 + 0*0x10000 + 0*0x20000: // Pitch-bender sensitivity LSB Ch[MidCh].bendsense_lsb = value; Ch[MidCh].updateBendSensitivity(); + NoteUpdate_All(MidCh, Upd_Pitch); break; case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed if(value == 64) Ch[MidCh].vibspeed = 1.0; -- cgit v1.2.3 From d8142ef298fa4ce54a8dbf8977709b9209c148e6 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Mon, 4 Jun 2018 09:36:27 +0200 Subject: new pitchbend strategy --- src/adlmidi_midiplay.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 2413f39..d7155f4 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1400,16 +1400,14 @@ void MIDIplay::realTime_PatchChange(uint8_t channel, uint8_t patch) void MIDIplay::realTime_PitchBend(uint8_t channel, uint16_t pitch) { channel = channel % 16; - Ch[channel].bendSrc = (int(pitch) - 8192); - Ch[channel].bend = Ch[channel].bendSrc * Ch[channel].bendsense; + Ch[channel].bend = int(pitch) - 8192; NoteUpdate_All(channel, Upd_Pitch); } void MIDIplay::realTime_PitchBend(uint8_t channel, uint8_t msb, uint8_t lsb) { channel = channel % 16; - Ch[channel].bendSrc = (int(lsb) + int(msb) * 128 - 8192); - Ch[channel].bend = Ch[channel].bendSrc * Ch[channel].bendsense; + Ch[channel].bend = int(lsb) + int(msb) * 128 - 8192; NoteUpdate_All(channel, Upd_Pitch); } @@ -1625,7 +1623,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, // Don't bend a sustained note if(!d || !d->sustained) { - double bend = Ch[MidCh].bend + ins.ains.finetune; + double midibend = Ch[MidCh].bend * Ch[MidCh].bendsense; + double bend = midibend + ins.ains.finetune; double phase = 0.0; uint8_t vibrato = std::max(Ch[MidCh].vibrato, Ch[MidCh].aftertouch); vibrato = std::max(vibrato, i->vibrato); @@ -1646,7 +1645,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (static_cast(tone) + bend + phase))); #undef BEND_COEFFICIENT if(hooks.onNote) - hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, Ch[MidCh].bend); + hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, midibend); } } } @@ -2390,12 +2389,10 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB) case 0x0000 + 0*0x10000 + 1*0x20000: // Pitch-bender sensitivity Ch[MidCh].bendsense_msb = value; Ch[MidCh].updateBendSensitivity(); - NoteUpdate_All(MidCh, Upd_Pitch); break; case 0x0000 + 0*0x10000 + 0*0x20000: // Pitch-bender sensitivity LSB Ch[MidCh].bendsense_lsb = value; Ch[MidCh].updateBendSensitivity(); - NoteUpdate_All(MidCh, Upd_Pitch); break; case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed if(value == 64) Ch[MidCh].vibspeed = 1.0; -- cgit v1.2.3 From 70c83caace9911dc5d8b80c1653c96b073f88e4a Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 15 Jun 2018 01:37:43 +0300 Subject: Give more live to very long sustaining notes --- src/adlmidi_midiplay.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index d7155f4..0623ce7 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -100,17 +100,16 @@ inline bool isXgPercChannel(uint8_t msb, uint8_t lsb) void MIDIplay::AdlChannel::AddAge(int64_t ms) { + const int64_t neg = static_cast(-0x1FFFFFFFl); if(users_empty()) - koff_time_until_neglible = - std::max(int64_t(koff_time_until_neglible - ms), static_cast(-0x1FFFFFFFl)); + koff_time_until_neglible = std::max(int64_t(koff_time_until_neglible - ms), neg); else { koff_time_until_neglible = 0; - for(LocationData *i = users_first; i; i = i->next) { - i->kon_time_until_neglible = - std::max(i->kon_time_until_neglible - ms, static_cast(-0x1FFFFFFFl)); + if(!i->fixed_sustain) + i->kon_time_until_neglible = std::max(i->kon_time_until_neglible - ms, neg); i->vibdelay += ms; } } @@ -1466,6 +1465,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, { d->sustained = false; d->vibdelay = 0; + d->fixed_sustain = (ains.ms_sound_kon == static_cast(adlNoteOnMaxTime)); d->kon_time_until_neglible = ains.ms_sound_kon; d->ins = ins; } -- cgit v1.2.3