diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | include/adlmidi.h | 6 | ||||
-rw-r--r-- | src/adlmidi_opl3.cpp | 52 | ||||
-rw-r--r-- | src/adlmidi_opl3.hpp | 6 | ||||
-rw-r--r-- | src/wopl/wopl_file.h | 3 | ||||
-rw-r--r-- | utils/midiplay/adlmidiplay.cpp | 2 | ||||
-rw-r--r-- | utils/vlc_codec/libadlmidi.c | 5 |
7 files changed, 59 insertions, 16 deletions
@@ -188,6 +188,7 @@ To build that example you will need to have installed SDL2 library. * Improved an accuracy of Win9X volume model * Removed C++ extras. C++-binded instruments tester is useless since a real-time MIDI API can completely replace it * Added AIL volume model + * Added Generic FM variant of Win9X volume model ## 1.4.0 2018-10-01 * Implemented a full support for Portamento! (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) diff --git a/include/adlmidi.h b/include/adlmidi.h index 3a81794..ae52c82 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -112,14 +112,16 @@ enum ADLMIDI_VolumeModels ADLMIDI_VolumeModel_DMX = 3, /*! Logarithmic volume scale, used in Apogee Sound System. */ ADLMIDI_VolumeModel_APOGEE = 4, - /*! Aproximated and shorted volume map table. Similar to general, but has less granularity. */ + /*! Aproximated and shorted volume map table (SB16 driver). Similar to general, but has less granularity. */ ADLMIDI_VolumeModel_9X = 5, /*! DMX model with a fixed bug of AM voices */ ADLMIDI_VolumeModel_DMX_Fixed = 6, /*! Apogee model with a fixed bug of AM voices*/ ADLMIDI_VolumeModel_APOGEE_Fixed = 7, /*! Audio Interfaces Library volume scaling model */ - ADLMIDI_VolumeModel_AIL = 8 + ADLMIDI_VolumeModel_AIL = 8, + /*! Aproximated and shorted volume map table (Generic FM driver). Similar to general, but has less granularity. */ + ADLMIDI_VolumeModel_9X_GENERIC_FM = 9 }; /** diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index 1e78227..d5ae1f3 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -197,7 +197,7 @@ static const uint16_t g_channelsMapPan[NUM_OF_CHANNELS] = // Mapping from MIDI volume level to OPL level value. -static const uint_fast32_t DMX_volume_mapping_table[128] = +static const uint_fast32_t s_dmx_volume_model[128] = { 0, 1, 3, 5, 6, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, @@ -217,7 +217,7 @@ static const uint_fast32_t DMX_volume_mapping_table[128] = 124, 124, 125, 125, 126, 126, 127, 127, }; -static const uint_fast32_t W9X_volume_mapping_table[32] = +static const uint_fast32_t s_w9x_sb16_volume_model[32] = { 80, 63, 40, 36, 32, 28, 23, 21, 19, 17, 15, 14, 13, 12, 11, 10, @@ -225,7 +225,15 @@ static const uint_fast32_t W9X_volume_mapping_table[32] = 3, 3, 2, 2, 1, 1, 0, 0 }; -static const uint_fast32_t AIL_vel_graph[16] = +static const uint_fast32_t s_w9x_generic_fm_volume_model[32] = +{ + 40, 36, 32, 28, 23, 21, 19, 17, + 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 5, 4, 4, 3, 3, + 2, 2, 1, 1, 1, 0, 0, 0 +}; + +static const uint_fast32_t s_ail_vel_graph[16] = { 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127 @@ -582,8 +590,8 @@ void OPL3::touchNote(size_t c, case Synth::VOLUME_DMX_FIXED: { volume = (channelVolume * channelExpression * m_masterVolume) / 16129; - volume = (DMX_volume_mapping_table[volume] + 1) << 1; - volume = (DMX_volume_mapping_table[(velocity < 128) ? velocity : 127] * volume) >> 9; + volume = (s_dmx_volume_model[volume] + 1) << 1; + volume = (s_dmx_volume_model[(velocity < 128) ? velocity : 127] * volume) >> 9; } break; @@ -597,7 +605,14 @@ void OPL3::touchNote(size_t c, case Synth::VOLUME_9X: { volume = (channelVolume * channelExpression * m_masterVolume) / 16129; - volume = W9X_volume_mapping_table[volume >> 2]; + volume = s_w9x_sb16_volume_model[volume >> 2]; + } + break; + + case Synth::VOLUME_9X_GENERIC_FM: + { + volume = (channelVolume * channelExpression * m_masterVolume) / 16129; + volume = s_w9x_generic_fm_volume_model[volume >> 2]; } break; @@ -609,7 +624,7 @@ void OPL3::touchNote(size_t c, midiVolume++; velocity = (velocity & 0x7F) >> 3; - velocity = AIL_vel_graph[velocity]; + velocity = s_ail_vel_graph[velocity]; midiVolume = (midiVolume * velocity) * 2; midiVolume >>= 8; @@ -709,9 +724,21 @@ void OPL3::touchNote(size_t c, else if(m_volumeScale == Synth::VOLUME_9X) { if(do_carrier) - tlCar += volume + W9X_volume_mapping_table[velocity >> 2]; + tlCar += volume + s_w9x_sb16_volume_model[velocity >> 2]; + if(do_modulator) + tlMod += volume + s_w9x_sb16_volume_model[velocity >> 2]; + + if(tlCar > 0x3F) + tlCar = 0x3F; + if(tlMod > 0x3F) + tlMod = 0x3F; + } + else if(m_volumeScale == Synth::VOLUME_9X_GENERIC_FM) + { + if(do_carrier) + tlCar += volume + s_w9x_generic_fm_volume_model[velocity >> 2]; if(do_modulator) - tlMod += volume + W9X_volume_mapping_table[velocity >> 2]; + tlMod += volume + s_w9x_generic_fm_volume_model[velocity >> 2]; if(tlCar > 0x3F) tlCar = 0x3F; @@ -950,9 +977,14 @@ void OPL3::setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel) case ADLMIDI_VolumeModel_APOGEE_Fixed: m_volumeScale = OPL3::VOLUME_APOGEE_FIXED; break; + case ADLMIDI_VolumeModel_AIL: m_volumeScale = OPL3::VOLUME_AIL; break; + + case ADLMIDI_VolumeModel_9X_GENERIC_FM: + m_volumeScale = OPL3::VOLUME_9X_GENERIC_FM; + break; } } @@ -977,6 +1009,8 @@ ADLMIDI_VolumeModels OPL3::getVolumeScaleModel() return ADLMIDI_VolumeModel_APOGEE_Fixed; case OPL3::VOLUME_AIL: return ADLMIDI_VolumeModel_AIL; + case OPL3::VOLUME_9X_GENERIC_FM: + return ADLMIDI_VolumeModel_9X_GENERIC_FM; } } diff --git a/src/adlmidi_opl3.hpp b/src/adlmidi_opl3.hpp index 83db8e1..d29582f 100644 --- a/src/adlmidi_opl3.hpp +++ b/src/adlmidi_opl3.hpp @@ -144,14 +144,16 @@ public: VOLUME_DMX, //! Apoge Sound System volume scaling model VOLUME_APOGEE, - //! Windows 9x driver volume scale table + //! Windows 9x SB16 driver volume scale table VOLUME_9X, //! DMX model with a fixed bug of AM voices VOLUME_DMX_FIXED, //! Apogee model with a fixed bug of AM voices VOLUME_APOGEE_FIXED, //! Audio Interfaces Library volume scaling model - VOLUME_AIL + VOLUME_AIL, + //! Windows 9x Generic FM driver volume scale table + VOLUME_9X_GENERIC_FM } m_volumeScale; //! Reserved diff --git a/src/wopl/wopl_file.h b/src/wopl/wopl_file.h index fa76ce7..752d363 100644 --- a/src/wopl/wopl_file.h +++ b/src/wopl/wopl_file.h @@ -59,7 +59,8 @@ typedef enum WOPL_VolumeModel WOPL_VM_Win9x, WOPL_VM_DMX_Fixed, WOPL_VM_Apogee_Fixed, - WOPL_VM_AIL + WOPL_VM_AIL, + WOPL_VM_Win9x_GenericFM } WOPL_VolumeModel; typedef enum WOPL_InstrumentFlags diff --git a/utils/midiplay/adlmidiplay.cpp b/utils/midiplay/adlmidiplay.cpp index 9f2abdd..c4738e1 100644 --- a/utils/midiplay/adlmidiplay.cpp +++ b/utils/midiplay/adlmidiplay.cpp @@ -222,6 +222,8 @@ const char* volume_model_to_str(int vm) return "Apogee (fixed)"; case ADLMIDI_VolumeModel_AIL: return "AIL"; + case ADLMIDI_VolumeModel_9X_GENERIC_FM: + return "9X (Generic FM)"; } } diff --git a/utils/vlc_codec/libadlmidi.c b/utils/vlc_codec/libadlmidi.c index 18e7d31..e59826c 100644 --- a/utils/vlc_codec/libadlmidi.c +++ b/utils/vlc_codec/libadlmidi.c @@ -81,7 +81,7 @@ #define FULL_RANGE_CC74_LONGTEXT N_( \ "Scale range of CC-74 \"Brightness\" with full 0~127 range. By default is only 0~64 affects the sounding.") -static const int volume_models_values[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; +static const int volume_models_values[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; static const char * const volume_models_descriptions[] = { N_("Auto (defined by bank)"), @@ -89,10 +89,11 @@ static const char * const volume_models_descriptions[] = N_("OPL3 Native"), N_("DMX"), N_("Apogee Sound System"), - N_("Win9x driver"), + N_("Win9x SB16 driver"), N_("DMX (Fixed AM)"), N_("Apogee Sound System (Fixed AM)"), N_("Audio Interfaces Library (AIL)"), + N_("Win9x Generic FM driver"), NULL }; |