summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/machine/rescap.h18
-rw-r--r--src/mame/linn/linndrum.cpp5
-rw-r--r--src/mame/oberheim/dmx.cpp5
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);