From e8882d58c9c4db8992b0620565e671979cd6a696 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Wed, 22 Aug 2018 00:51:52 +0300 Subject: Rotate octave on high out of range tone frequencies --- src/adlmidi_opl3.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/adlmidi_opl3.cpp') diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 94602ba..5ea2053 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -266,33 +266,37 @@ void OPL3::noteOff(size_t c) void OPL3::noteOn(size_t c, double hertz) // Hertz range: 0..131071 { size_t chip = c / 23, cc = c % 23; - uint32_t x = 0x2000; + uint32_t octave = 0; - if(hertz < 0 || hertz > 131071) // Avoid infinite loop + if(hertz < 0) return; while(hertz >= 1023.5) { - hertz /= 2.0; // Calculate octave - x += 0x400; + hertz /= 2.0; // Calculate octave + if(octave < 0x1C00) + octave += 0x400; } - x += static_cast(hertz + 0.5); + octave += static_cast(hertz + 0.5); uint32_t chn = g_channelsMap[cc]; if(cc >= 18) { m_regBD[chip ] |= (0x10 >> (cc - 18)); writeRegI(chip , 0x0BD, m_regBD[chip ]); - x &= ~0x2000u; //x |= 0x800; // for test } + else + { + octave += 0x2000u; /* Key-ON [KON] */ + } if(chn != 0xFFF) { - writeRegI(chip , 0xA0 + chn, (x & 0xFF)); - writeRegI(chip , 0xB0 + chn, (x >> 8)); - m_keyBlockFNumCache[c] = (x >> 8); + writeRegI(chip , 0xA0 + chn, (octave & 0xFF)); + writeRegI(chip , 0xB0 + chn, (octave >> 8)); + m_keyBlockFNumCache[c] = (octave >> 8); } } -- cgit v1.2.3 From 55bee6c3f34ab15eab6bd843d9aab78a175486cf Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Mon, 27 Aug 2018 22:56:52 +0200 Subject: reassign the channel categories after num4ops was decreased --- src/adlmidi_opl3.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'src/adlmidi_opl3.cpp') diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 5ea2053..19cd952 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -452,31 +452,39 @@ void OPL3::silenceAll() // Silence all OPL channels. void OPL3::updateChannelCategories() { - uint32_t fours = m_numFourOps; + const uint32_t fours = m_numFourOps; - for(size_t chip = 0; chip < m_numChips; ++chip) + for(uint32_t chip = 0, fours_left = fours; chip < m_numChips; ++chip) { m_regBD[chip] = (m_deepTremoloMode * 0x80 + m_deepVibratoMode * 0x40 + m_rhythmMode * 0x20); writeRegI(chip, 0x0BD, m_regBD[chip]); - uint32_t fours_this_chip = std::min(fours, static_cast(6u)); + uint32_t fours_this_chip = std::min(fours_left, static_cast(6u)); writeRegI(chip, 0x104, (1 << fours_this_chip) - 1); - fours -= fours_this_chip; + fours_left -= fours_this_chip; } - // Mark all channels that are reserved for four-operator function - if(m_rhythmMode == 1) + if(!m_rhythmMode) + { + for(size_t a = 0, n = m_numChips; a < n; ++a) + { + for(size_t b = 0; b < 23; ++b) + m_channelCategory[a * 23 + b] = + (b >= 18) ? ChanCat_Rhythm_Slave : ChanCat_Regular; + } + } + else { - for(size_t a = 0; a < m_numChips; ++a) + for(size_t a = 0, n = m_numChips; a < n; ++a) { - for(size_t b = 0; b < 5; ++b) - m_channelCategory[a * 23 + 18 + b] = static_cast(b + 3); - for(size_t b = 0; b < 3; ++b) - m_channelCategory[a * 23 + 6 + b] = ChanCat_Rhythm_Slave; + for(size_t b = 0; b < 23; ++b) + m_channelCategory[a * 23 + b] = + (b >= 18) ? static_cast(ChanCat_Rhythm_Bass + (b - 18)) : + (b >= 6 && b < 9) ? ChanCat_Rhythm_Slave : ChanCat_Regular; } } - size_t nextfour = 0; - for(size_t a = 0; a < m_numFourOps; ++a) + uint32_t nextfour = 0; + for(uint32_t a = 0; a < fours; ++a) { m_channelCategory[nextfour] = ChanCat_4op_Master; m_channelCategory[nextfour + 3] = ChanCat_4op_Slave; -- cgit v1.2.3 From 399992184883f76a0cd8909a92c15dea85dc657c Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Tue, 28 Aug 2018 01:31:08 +0300 Subject: Little beautifying --- src/adlmidi_opl3.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/adlmidi_opl3.cpp') diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 19cd952..e127568 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -468,8 +468,10 @@ void OPL3::updateChannelCategories() for(size_t a = 0, n = m_numChips; a < n; ++a) { for(size_t b = 0; b < 23; ++b) + { m_channelCategory[a * 23 + b] = (b >= 18) ? ChanCat_Rhythm_Slave : ChanCat_Regular; + } } } else @@ -477,9 +479,11 @@ void OPL3::updateChannelCategories() for(size_t a = 0, n = m_numChips; a < n; ++a) { for(size_t b = 0; b < 23; ++b) + { m_channelCategory[a * 23 + b] = (b >= 18) ? static_cast(ChanCat_Rhythm_Bass + (b - 18)) : (b >= 6 && b < 9) ? ChanCat_Rhythm_Slave : ChanCat_Regular; + } } } -- cgit v1.2.3 From 57ef547b460843c0864e14ae4ce0fcf1f901a9d7 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Tue, 28 Aug 2018 13:20:16 +0300 Subject: Small warning fix --- src/adlmidi_opl3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/adlmidi_opl3.cpp') diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index e127568..c98469f 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -481,7 +481,7 @@ void OPL3::updateChannelCategories() for(size_t b = 0; b < 23; ++b) { m_channelCategory[a * 23 + b] = - (b >= 18) ? static_cast(ChanCat_Rhythm_Bass + (b - 18)) : + (b >= 18) ? static_cast(ChanCat_Rhythm_Bass + (b - 18)) : (b >= 6 && b < 9) ? ChanCat_Rhythm_Slave : ChanCat_Regular; } } -- cgit v1.2.3 From c7b3199669a7b7e0ba11eb0d94d4e143a5fdd633 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 31 Aug 2018 03:54:16 +0300 Subject: Added high tone frequency extension from OPL3-BE --- src/adlmidi_opl3.cpp | 93 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 23 deletions(-) (limited to 'src/adlmidi_opl3.cpp') diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index e127568..7ec1fd6 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -263,40 +263,85 @@ void OPL3::noteOff(size_t c) writeRegI(chip, 0xB0 + g_channelsMap[cc], m_keyBlockFNumCache[c] & 0xDF); } -void OPL3::noteOn(size_t c, double hertz) // Hertz range: 0..131071 +void OPL3::noteOn(size_t c1, size_t c2, double hertz) // Hertz range: 0..131071 { - size_t chip = c / 23, cc = c % 23; - uint32_t octave = 0; + size_t chip = c1 / 23, cc1 = c1 % 23, cc2 = c2 % 23; + uint32_t octave = 0, ftone = 0, mul_offset = 0; if(hertz < 0) return; - while(hertz >= 1023.5) + //Basic range until max of octaves reaching + while((hertz >= 1023.5) && (octave < 0x1C00)) + { + hertz /= 2.0; // Calculate octave + octave += 0x400; + } + //Extended range, rely on frequency multiplication increment + while(hertz >= 1022.75) { - hertz /= 2.0; // Calculate octave - if(octave < 0x1C00) - octave += 0x400; + hertz /= 2.0; // Calculate octave + mul_offset++; } - octave += static_cast(hertz + 0.5); - uint32_t chn = g_channelsMap[cc]; + ftone = octave + static_cast(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]; - if(cc >= 18) + if(cc1 < 18) { - m_regBD[chip ] |= (0x10 >> (cc - 18)); - writeRegI(chip , 0x0BD, m_regBD[chip ]); - //x |= 0x800; // for test + ftone += 0x2000u; /* Key-ON [KON] */ + + const bool natural_4op = (m_channelCategory[c1] == ChanCat_4op_Master); + const size_t opsCount = natural_4op ? 4 : 2; + const uint16_t op_addr[4] = + { + g_operatorsMap[cc1 * 2 + 0], g_operatorsMap[cc1 * 2 + 1], + g_operatorsMap[cc2 * 2 + 0], g_operatorsMap[cc2 * 2 + 1] + }; + const uint32_t ops[4] = + { + patch1.modulator_E862 & 0xFF, + patch1.carrier_E862 & 0xFF, + patch2.modulator_E862 & 0xFF, + patch2.carrier_E862 & 0xFF + }; + + for(size_t op = 0; op < opsCount; op++) + { + if((op > 0) && (op_addr[op] == 0xFFF)) + break; + if(mul_offset > 0) + { + uint32_t dt = ops[op] & 0xF0; + uint32_t mul = ops[op] & 0x0F; + if((mul + mul_offset) > 0x0F) + { + mul_offset = 0; + mul = 0x0F; + } + writeRegI(chip, 0x20 + op_addr[op], (dt | (mul + mul_offset)) & 0xFF); + } + else + { + writeRegI(chip, 0x20 + op_addr[op], ops[op] & 0xFF); + } + } } - else + + if(chn != 0xFFF) { - octave += 0x2000u; /* Key-ON [KON] */ + writeRegI(chip , 0xA0 + chn, (ftone & 0xFF)); + writeRegI(chip , 0xB0 + chn, (ftone >> 8)); + m_keyBlockFNumCache[c1] = (ftone >> 8); } - if(chn != 0xFFF) + if(cc1 >= 18) { - writeRegI(chip , 0xA0 + chn, (octave & 0xFF)); - writeRegI(chip , 0xB0 + chn, (octave >> 8)); - m_keyBlockFNumCache[c] = (octave >> 8); + m_regBD[chip ] |= (0x10 >> (cc1 - 18)); + writeRegI(chip , 0x0BD, m_regBD[chip ]); + //x |= 0x800; // for test } } @@ -312,15 +357,17 @@ void OPL3::touchNote(size_t c, uint8_t volume, uint8_t brightness) uint8_t x = adli.modulator_40, y = adli.carrier_40; uint32_t mode = 1; // 2-op AM - if(m_channelCategory[c] == 0 || m_channelCategory[c] == 3) + if(m_channelCategory[c] == ChanCat_Regular || + m_channelCategory[c] == ChanCat_Rhythm_Bass) { mode = adli.feedconn & 1; // 2-op FM or 2-op AM } - else if(m_channelCategory[c] == 1 || m_channelCategory[c] == 2) + else if(m_channelCategory[c] == ChanCat_4op_Master || + m_channelCategory[c] == ChanCat_4op_Slave) { const adldata *i0, *i1; - if(m_channelCategory[c] == 1) + if(m_channelCategory[c] == ChanCat_4op_Master) { i0 = &adli; i1 = &m_insCache[c + 3]; @@ -481,7 +528,7 @@ void OPL3::updateChannelCategories() for(size_t b = 0; b < 23; ++b) { m_channelCategory[a * 23 + b] = - (b >= 18) ? static_cast(ChanCat_Rhythm_Bass + (b - 18)) : + (b >= 18) ? static_cast(ChanCat_Rhythm_Bass + (b - 18)) : (b >= 6 && b < 9) ? ChanCat_Rhythm_Slave : ChanCat_Regular; } } -- cgit v1.2.3 From bec09ea33dbf582b81c1d75d39e5df2b7a6a143d Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Sat, 1 Sep 2018 13:39:16 +0200 Subject: provide default initialization for bank setup --- src/adlmidi_opl3.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/adlmidi_opl3.cpp') diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 60c173e..aff879a 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -168,6 +168,12 @@ OPL3::OPL3() : m_musicMode(MODE_MIDI), m_volumeScale(VOLUME_Generic) { + m_insBankSetup.volumeModel = OPL3::VOLUME_Generic; + m_insBankSetup.deepTremolo = false; + m_insBankSetup.deepVibrato = false; + m_insBankSetup.adLibPercussions = false; + m_insBankSetup.scaleModulators = false; + #ifdef DISABLE_EMBEDDED_BANKS m_embeddedBank = CustomBankTag; #else -- cgit v1.2.3 From 34ac11d4e79cef67596ad30dfa9df4f9586641aa Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Thu, 6 Sep 2018 05:31:39 +0200 Subject: access into global chip settings --- src/adlmidi_opl3.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/adlmidi_opl3.cpp') diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index aff879a..e486dd6 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -631,6 +631,24 @@ void OPL3::setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel) } } +ADLMIDI_VolumeModels OPL3::getVolumeScaleModel() +{ + switch(m_volumeScale) + { + default: + case OPL3::VOLUME_Generic: + return ADLMIDI_VolumeModel_Generic; + case OPL3::VOLUME_NATIVE: + return ADLMIDI_VolumeModel_NativeOPL3; + case OPL3::VOLUME_DMX: + return ADLMIDI_VolumeModel_DMX; + case OPL3::VOLUME_APOGEE: + return ADLMIDI_VolumeModel_APOGEE; + case OPL3::VOLUME_9X: + return ADLMIDI_VolumeModel_9X; + } +} + #ifndef ADLMIDI_HW_OPL void OPL3::clearChips() { -- cgit v1.2.3