diff options
-rw-r--r-- | include/adlmidi.h | 4 | ||||
-rw-r--r-- | src/adlmidi_midiplay.cpp | 5 | ||||
-rw-r--r-- | src/adlmidi_opl3.cpp | 35 | ||||
-rw-r--r-- | src/adlmidi_opl3.hpp | 12 | ||||
-rw-r--r-- | utils/midiplay/adlmidiplay.cpp | 2 |
5 files changed, 50 insertions, 8 deletions
diff --git a/include/adlmidi.h b/include/adlmidi.h index c26e0ed..0aaba8a 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -123,7 +123,9 @@ enum ADLMIDI_VolumeModels /*! Aproximated and shorted volume map table (Generic FM driver). Similar to general, but has less granularity. */ ADLMIDI_VolumeModel_9X_GENERIC_FM = 9, /*! HMI Sound Operating System volume scaling model */ - ADLMIDI_VolumeModel_HMI = 10 + ADLMIDI_VolumeModel_HMI = 10, + /*! HMI Sound Operating System volume scaling model, older variant with bugs */ + ADLMIDI_VolumeModel_HMI_OLD = 11 }; /** diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index c6fc1b6..8d92933 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1247,7 +1247,7 @@ void MIDIplay::noteUpdate(size_t midCh, { const MIDIchannel &ch = m_midiChannels[midCh]; bool is_percussion = (midCh == 9) || ch.is_xg_percussion; - uint_fast32_t brightness = is_percussion ? 127 : ch.brightness; + uint_fast32_t brightness = ch.brightness; if(!m_setup.fullRangeBrightnessCC74) { @@ -1262,7 +1262,8 @@ void MIDIplay::noteUpdate(size_t midCh, vol, ch.volume, ch.expression, - static_cast<uint8_t>(brightness)); + brightness, + is_percussion); /* DEBUG ONLY!!! static uint32_t max = 0; diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index a38e364..9fbb8bb 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -1034,6 +1034,7 @@ void OPL3::noteOn(size_t c1, size_t c2, double tone) break; case VOLUME_HMI: + case VOLUME_HMI_OLD: hertz = s_hmiFreq(tone); break; @@ -1133,7 +1134,8 @@ void OPL3::touchNote(size_t c, uint_fast32_t velocity, uint_fast32_t channelVolume, uint_fast32_t channelExpression, - uint8_t brightness) + uint_fast32_t brightness, + bool isDrum) { size_t chip = c / NUM_OF_CHANNELS, cc = c % NUM_OF_CHANNELS; const OplTimbre &adli = m_insCache[c]; @@ -1265,6 +1267,7 @@ void OPL3::touchNote(size_t c, break; case VOLUME_HMI: + case VOLUME_HMI_OLD: { volume = (channelVolume * channelExpression * m_masterVolume) / 16129; volume = (((volume * 128) / 127) * velocity) >> 7; @@ -1412,6 +1415,28 @@ void OPL3::touchNote(size_t c, tlCar = (8192 - vol) >> 7; } } + else if(m_volumeScale == Synth::VOLUME_HMI_OLD) + { + uint_fast32_t vol; + + if(adli.feedconn == 0 && !isDrum) + { + vol = (channelVolume * channelExpression * 64) / 16129; + vol = (((vol * 128) / 127) * velocity) >> 7; + vol = s_hmi_volume_table[vol >> 1]; + + vol = (64 - vol) << 1; + vol *= (64 - tlCar); + tlMod = (8192 - vol) >> 7; + } + + if(isDrum) // TODO: VERIFY A CORRECTNESS OF THIS!!! + vol = s_hmi_volume_table[velocity >> 1]; + + vol = (64 - volume) << 1; + vol *= (64 - tlCar); + tlCar = (8192 - vol) >> 7; + } else { if(do_modulator) @@ -1420,7 +1445,7 @@ void OPL3::touchNote(size_t c, tlCar = 63 - volume + (volume * tlCar) / 63; } - if(brightness != 127) + if(brightness != 127 && !isDrum) { brightness = brightnessToOPL(brightness); if(!do_modulator) @@ -1643,6 +1668,10 @@ void OPL3::setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel) case ADLMIDI_VolumeModel_HMI: m_volumeScale = OPL3::VOLUME_HMI; break; + + case ADLMIDI_VolumeModel_HMI_OLD: + m_volumeScale = OPL3::VOLUME_HMI_OLD; + break; } } @@ -1671,6 +1700,8 @@ ADLMIDI_VolumeModels OPL3::getVolumeScaleModel() return ADLMIDI_VolumeModel_9X_GENERIC_FM; case OPL3::VOLUME_HMI: return ADLMIDI_VolumeModel_HMI; + case OPL3::VOLUME_HMI_OLD: + return ADLMIDI_VolumeModel_HMI_OLD; } } diff --git a/src/adlmidi_opl3.hpp b/src/adlmidi_opl3.hpp index c4a2b07..0165d02 100644 --- a/src/adlmidi_opl3.hpp +++ b/src/adlmidi_opl3.hpp @@ -157,7 +157,9 @@ public: //! Windows 9x Generic FM driver volume scale table VOLUME_9X_GENERIC_FM, //! HMI Sound Operating System volume scale table - VOLUME_HMI + VOLUME_HMI, + //! HMI Sound Operating System volume scale model, older variant + VOLUME_HMI_OLD } m_volumeScale; //! Reserved @@ -263,14 +265,18 @@ public: /** * @brief Change setup of instrument in specified chip channel * @param c Channel of chip (Emulated chip choosing by next formula: [c = ch + (chipId * 23)]) - * @param volume Volume level (from 0 to 127) + * @param velocity Note velocity (from 0 to 127) + * @param channelVolume Channel volume level (from 0 to 127) + * @param channelExpression Channel expression level (from 0 to 127) * @param brightness CC74 Brightness level (from 0 to 127) + * @param isDrum Is this a drum note? This flag is needed for some volume model algorithms */ void touchNote(size_t c, uint_fast32_t velocity, uint_fast32_t channelVolume = 127, uint_fast32_t channelExpression = 127, - uint8_t brightness = 127); + uint_fast32_t brightness = 127, + bool isDrum = false); /** * @brief Set the instrument into specified chip channel diff --git a/utils/midiplay/adlmidiplay.cpp b/utils/midiplay/adlmidiplay.cpp index b11ea82..fd071f2 100644 --- a/utils/midiplay/adlmidiplay.cpp +++ b/utils/midiplay/adlmidiplay.cpp @@ -226,6 +226,8 @@ const char* volume_model_to_str(int vm) return "9X (Generic FM)"; case ADLMIDI_VolumeModel_HMI: return "HMI Sound Operating System"; + case ADLMIDI_VolumeModel_HMI_OLD: + return "HMI Sound Operating System (Old)"; } } |