mirror of
https://github.com/holub/mame
synced 2025-06-04 03:46:29 +03:00
machine/rescap.h: Implemented audio potentiometer law. (#13588)
* machine/rescap.h: Implemented audio potentiometer law. Used it in oberheim/dmx.cpp and linn/linndrum.cpp. * machine/rescap.h: Function should not be a constexpr. Also avoiding pow in constexpr constants.
This commit is contained in:
parent
65730f43b4
commit
6794099d89
@ -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; }
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user