diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/machine/rescap.h | 18 | ||||
-rw-r--r-- | src/mame/linn/linndrum.cpp | 5 | ||||
-rw-r--r-- | src/mame/oberheim/dmx.cpp | 5 |
3 files changed, 22 insertions, 6 deletions
diff --git a/src/devices/machine/rescap.h b/src/devices/machine/rescap.h index 71b9cd55216..b558f2d3a0c 100644 --- a/src/devices/machine/rescap.h +++ b/src/devices/machine/rescap.h @@ -26,6 +26,24 @@ constexpr double RES_VOLTAGE_DIVIDER(double r1, double r2) { return r2 / (r1 + r #define RES_2_SERIAL(r1,r2) ((r1)+(r2)) +// Audio taper (aka "logarithmic") potentiometer law. +// `x` should be in the range 0-1, and so is the return value. +inline double RES_AUDIO_POT_LAW(double x) +{ + // The implementation is that of an ideal log potentiometer, based on: + // https://electronics.stackexchange.com/questions/304692/formula-for-logarithmic-audio-taper-pot + + // Note that most audio potentiometers are not ideal, but they try to + // approximate this curve. + + // The 10% midpoint ("A2" potentiometer curve) is typical for audio + // applications. See any datasheet for a log potentiometer. + constexpr const double MIDPOINT = 0.1; + constexpr const double B = (1.0 / MIDPOINT - 1.0) * (1.0 / MIDPOINT - 1.0); // pow(1.0 / MIDPOINT - 1.0, 2); + constexpr const double A = 1.0 / (B - 1.0); + return A * pow(B, x) - A; +} + // macro for the RC time constant on a 74LS123 with C > 1000pF // R is in ohms, C is in farads constexpr double TIME_OF_74LS123(double r, double c) { return 0.45 * r * c; } diff --git a/src/mame/linn/linndrum.cpp b/src/mame/linn/linndrum.cpp index e4385a820e5..1bfd8566775 100644 --- a/src/mame/linn/linndrum.cpp +++ b/src/mame/linn/linndrum.cpp @@ -65,7 +65,6 @@ Reasons for MACHINE_IMPERFECT_SOUND: * Missing snare / sidestick volume envelope. * Missing tom / conga LPF and filter envelope. * Inaccurate filter for "click". -* Linear, instead of audio-taper volume sliders and master volume knob. * Linear, instead of tanh response for hi-hat VCA. PCBoards: @@ -856,7 +855,7 @@ void linndrum_audio_device::update_volume_and_pan(int channel) static constexpr const float C_VOICE = CAP_U(10); const s32 volume = m_volume[channel]->read(); - const float r_vol_bottom = volume * R_VOL_MAX / 100.0F; + const float r_vol_bottom = R_VOL_MAX * RES_AUDIO_POT_LAW(volume / 100.0F); const float r_vol_top = R_VOL_MAX - r_vol_bottom; const float r_pan_left = m_pan[channel]->read() * R_PAN_MAX / 100.0F; const float r_pan_right = R_PAN_MAX - r_pan_left; @@ -903,7 +902,7 @@ void linndrum_audio_device::update_master_volume() { static constexpr const float R_MASTER_VOLUME_MAX = RES_K(10); - const float r_pot_bottom = m_master_volume->read() * R_MASTER_VOLUME_MAX / 100.0F; + const float r_pot_bottom = R_MASTER_VOLUME_MAX * RES_AUDIO_POT_LAW(m_master_volume->read() / 100.0F); const float r_pot_top = R_MASTER_VOLUME_MAX - r_pot_bottom; const float v_input = RES_VOLTAGE_DIVIDER(r_pot_top, RES_2_PARALLEL(r_pot_bottom, OUTPUT_R_INPUT)); diff --git a/src/mame/oberheim/dmx.cpp b/src/mame/oberheim/dmx.cpp index 84b448a75a4..b7b95b1653f 100644 --- a/src/mame/oberheim/dmx.cpp +++ b/src/mame/oberheim/dmx.cpp @@ -46,7 +46,6 @@ PCBoards: Possible audio inaccuracies: - Some uncertainty on component values for HIHAT and PERC2 (see comments in HIHAT_CONFIG and PERC_CONFIG). -- Linear- instead of audio-taper faders. - Envelope decay ignores diodes in capacitor discharge path. Given the quick decay, and that the error is larger at low volumes, this might not be noticeable. @@ -1206,7 +1205,7 @@ void dmx_state::update_mix_level(int voice) static constexpr const float R_FEEDBACK_RIGHT = RES_K(27); // R29. const s32 pot_percent = m_faders[VOICE_TO_FADER_MAP[voice]]->read(); - const float r_pot_bottom = P_MAX * pot_percent / 100.0F; + const float r_pot_bottom = P_MAX * RES_AUDIO_POT_LAW(pot_percent / 100.0F); const float r_pot_top = P_MAX - r_pot_bottom; const float r_mix_left = std::get<0>(MIX_RESISTORS[voice]); const float r_mix_right = std::get<1>(MIX_RESISTORS[voice]); @@ -1237,7 +1236,7 @@ void dmx_state::update_master_volume() static constexpr const float VOLTAGE_TO_SOUND_SCALER = 0.04F; const s32 volume_value = m_master_volume->read(); - const float gain = VOLTAGE_TO_SOUND_SCALER * volume_value / 100.0F; + const float gain = VOLTAGE_TO_SOUND_SCALER * RES_AUDIO_POT_LAW(volume_value / 100.0F); m_left_mixer->set_output_gain(0, gain); m_right_mixer->set_output_gain(0, gain); LOGMASKED(LOG_FADERS, "Master volume changed: %d - %f\n", volume_value, gain); |