Repository navigation
Apply an audio taper to endpoint volume - #650
Merged
Merged
Conversation
… its dB surface Rocksmith sets the capture endpoint's IAudioEndpointVolume scalar while calibrating guitar input (0.17 at start, a 0.40..0.50 search ramp, then 1.0). A Windows endpoint scalar is a fader position mapped to dB through a taper, but RS_ASIO applied it as a linear amplitude, so the input was too hot below 1.0: +11.4 dB at 0.17 and +4.5..5.9 dB at 0.40..0.50. Measured on a real endpoint, amplitude = scalar^1.74 (within 0.3 dB of every measured point). - VolumeTaper.h: scalar <-> dB <-> amplitude, quantized to a 1.5 dB step. - The amplitude is computed in the setter, off the audio callback; the scalar, the amplitude and the master volume are atomics. Master volume stays linear. - IAudioEndpointVolume now implements GetVolumeRange (-96..0 dB, 1.5 dB), Get/SetMasterVolumeLevel (dB), GetVolumeStepInfo, VolumeStepUp/Down, QueryHardwareSupport (0) and GetChannelCount. The range tops out at 0 dB: no digital makeup gain, level is set with the interface's analog gain. - With software endpoint volume disabled these report E_NOTIMPL, so no range is advertised that the setters then refuse. - NaN is rejected by the scalar and dB setters.
Owner
|
The reason integer volume is applied in whole percents instead of precisely is performance. Being off by 1% is not going to get noticed, but if we're at the limit of what the system can push, converting the samples from integer to floating point, multiplying and then converting back to integer might be the thing that generates an xrun. The whole-percent math is preferable. And if 1% is not enough precision we could multiply and divide by 1000 to get 0.1% accuracy. |
The scalar and its precomputed amplitude are separate atomics, so two concurrent setters could interleave and leave the reported level and the applied gain permanently different (e.g. 0.17 reported, 0.50 applied). A mutex taken only by the setter keeps them a pair; the audio callback still reads the amplitude without locking.
L0FKA
force-pushed
the
fix/endpoint-volume-taper
branch
from
October 26, 2026 20:46
c7a8ce2 to
6aa0643
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Apply an audio taper to endpoint volume
Rocksmith adjusts guitar input gain through
IAudioEndpointVolume::SetMasterVolumeLevelScalar: 0.17 at start, a0.40..0.50 search during calibration, then 1.0. RS_ASIO uses that scalar directly as a linear amplitude
multiplier. A Windows endpoint scalar follows an audio taper, so the same setting gives very different
attenuation: the linear multiplier is +11.4 dB too hot at 0.17 and +4.5..5.9 dB too hot at 0.40..0.50.
What changes
Endpoint taper: the endpoint scalar maps to amplitude as
scalar^1.74, fitted to measurements of a realWindows software endpoint (MOTU M Series), within 0.3 dB of every measured point. At 0.17 the attenuation
becomes -26.78 dB instead of -15.39 dB.
Unity stays unity: the taper does not change the gain at scalar 1.0, which stays 0 dB. It does not fix
distortion while the endpoint is at full scale.
SoftwareMasterVolumePercentkeeps its linear meaning.Integer software volume: Int16, packed Int24 and Int32 retain whole-percent integer scaling in the callback.
This avoids converting each sample to floating point and back on a performance-sensitive path. The 1% step is
an intentional trade-off; integer tenths-of-a-percent scaling can be considered if testing shows it is needed.
Endpoint API: implements:
the interface's analog gain;
QueryHardwareSupport(0, software only).Invalid and NaN settings are rejected. With software endpoint volume disabled, the new queries report
E_NOTIMPL, so no range is advertised that the setters would refuse. Mute, per-channel volume andnotifications stay unimplemented.
Audio path: the taper is computed in the setter and cached. The audio callback reads the cached amplitude
without locking. Setters are serialized, so the reported level and the applied gain can't drift apart under
concurrent calls. Applies to capture and render.
Testing
Offline: standalone taper checks covered the measured curve, round trips, the floor, dB quantization and
steps. A deliberately wrong exponent fails them. Release x86 builds.
Live capture readout (temporary instrumentation in a validation-only build, not part of this PR):
September 2022 build, MOTU M Series Int32LSB, endpoint scalar 0.17.
Not established: improved calibration or scoring with a real guitar, long sessions, or equivalence to every
device's taper. This is one software-endpoint curve, measured on one interface. It does not change the
interface's analog gain.