namespace
SushiDSP
- Declared in
include/SushiDSP/audio_format/AsioSampleConverter.hpp
Contains
SushiDSP::AntiderivativeAntialiaserSushiDSP::AsioAudioDeviceSushiDSP::AsyncLogSinkSushiDSP::BiquadSushiDSP::BufferPoolSushiDSP::CapturedLogLineSushiDSP::CapturingLogSinkSushiDSP::DenormalGuardSushiDSP::DeviceFormatSushiDSP::FftSushiDSP::FmvComponentsSushiDSP::FmvSourceLoadSushiDSP::FmvToneStackSushiDSP::GraphicEqualizerSushiDSP::GridConductionLawSushiDSP::HalfbandDesignSushiDSP::HalfbandDownsampler2xSushiDSP::HalfbandUpsampler2xSushiDSP::IAudioDeviceSushiDSP::IAudioNodeSushiDSP::ICabinetHostSushiDSP::ILogSinkSushiDSP::IrSushiDSP::IrLoaderSushiDSP::IrLoadOptionsSushiDSP::LogArgumentSushiDSP::LogCategorySushiDSP::LoggerSushiDSP::LogLineQueueSushiDSP::LogRecordSushiDSP::LongTailedPairSushiDSP::LongTailedPairHalfSushiDSP::LongTailedPairTubeSushiDSP::MillerInputCapacitanceSushiDSP::NewtonRaphsonSolverSushiDSP::NodeDescriptorSushiDSP::OutputTransformerStageSushiDSP::Oversampler4xSushiDSP::Oversampler8xSushiDSP::ParameterBindingSushiDSP::ParameterChangeSushiDSP::ParameterDescriptorSushiDSP::ParameterTableSushiDSP::PartitionedConvolutionSushiDSP::PentodeEL34SushiDSP::PentodeStageSushiDSP::PlateSwingSushiDSP::PortLayoutSushiDSP::PowerAmpFeedbackSushiDSP::PowerAmpFeedbackComponentsSushiDSP::PowerAmpFeedbackTerminationSushiDSP::PowerSupplySagStageSushiDSP::PowerTubePresetSushiDSP::PrepareInfoSushiDSP::ProcessContextSushiDSP::QueuedLogLineSushiDSP::ResamplerSushiDSP::ResonanceControlSushiDSP::RigGraphSushiDSP::RtGraphSlotSushiDSP::RtSwapSlotSushiDSP::ScopedLogSinkSushiDSP::Sdl2AudioDeviceSushiDSP::SiliconDiodeSushiDSP::SincResamplerSushiDSP::SingleTriodeInverterSushiDSP::SmoothedParameterSushiDSP::SpscRingSushiDSP::StderrLogSinkSushiDSP::StreamingConvolutionSushiDSP::Triode12AX7SushiDSP::TriodeStageSushiDSP::WavFileSushiDSP::WavWriterSushiDSP::WdfCapacitorSushiDSP::WdfPortSushiDSP::WdfResistorSushiDSP::dkSushiDSP::models
Enumerations
enum class AsioSampleFormatThe sample container formats this converter supports, independent of any ASIO SDK type - AsioAudioDevice maps the real ASIOSampleType to this enum once at device- open time, keeping the ASIO SDK's headers out of every other translation unit that needs sample conversion (this file compiles and is tested on every platform).
Int16LSBInt32LSBFloat32LSB
enum class ChannelSelectionWhich physical device channel(s) a host app reads from / writes to.
A rig node itself is always mono; this only picks which of a (stereo-capable) device's channels feeds it or receives its output.
LeftRightStereo
enum class ParamKindHow a ParameterDescriptor's value maps to a host automation control.
LinearLogarithmicDecibelBooleanChoice
enum class LogLevelOrders the severities of a log line, least severe first.
TraceStep-by-step flow for a developer chasing one defect.
DebugInternal state at a decision point.
InfoA lifecycle event an operator cares about.
WarnThe program recovered or fell back.
ErrorAn operation failed and its caller sees a failure.
FatalThe process cannot continue.
Typedefs
using SushiDSP::DeviceCallback = std::function<void(const float* const* inputs, float* const* outputs, std::uint32_t frames)>Invoked by an IAudioDevice on its real-time thread once per block.
Must fill exactly frames samples of each of outputs[0..output_channels). inputs may be nullptr, or point to input_channels channels of captured audio, or be non-null with fewer meaningful channels than input_channels reports (a device with zero input capability reports input_channels == 0 and always passes nullptr). The callback itself must be allocation-free, lock-free, syscall-free, and throw-free.
using SushiDSP::NodeHandle = std::uint32_tIdentifies one node inside a RigGraph, as returned by RigGraph::add_node().
Variables
constexpr FmvComponents kJcm2203ToneStack { 470e-12f, 22e-9f, 22e-9f, 33e3f, 1e6f, 25e3f, 220e3f }The JCM800 2203's values: 470 pF, 22 nF, 22 nF, 33 kOhm, 1 MOhm, 25 kOhm, 220 kOhm.
constexpr PowerAmpFeedbackComponents kMark2cFeedback { 250e3f, 1.5e3f, 56e3f, 4.7e-9f, 22e3f, 1.5e3f, 3.3e3f, 47e-9f, 0.1e-6f, 150e3f }The Mark IIC+'s values, read off jrb32's traced schematic (docs/agent/2026_09_20_V0_1_0_RELEASE/REPORT.md).
constexpr MillerInputCapacitance kTriode12AX7MillerCapacitance { 1.6f, 1.7f, 10.0f }The 12AX7's grid capacitances, the two from docs/reference/spice/models/12ax7_koren.sub and the 10 pF a point-to-point turret board strays at the grid node.
constexpr SingleTriodeInverter kTriode12AX7Inverter82kPlate { -1.346012f, 61.927402f, 1.888775f, PlateSwing{ 117.418041f, 89.548144f } }A 12AX7 pair on an 82 kOhm plate over a 10.47 kOhm tail at 360 V, both grid leaks returned to the 470 Ohm and 10 kOhm junction: gm 2.193524 mA/V, ra 43055.615 Ohm, mu 94.443529, the cathodes at 29.984558 V, the plate at 242.581959 V idle and 123.049256 V of plate-to-cathode voltage at Vgk = 0 (docs/reference/spice/jcm_ltp).
constexpr GridConductionLaw kPentodeEL34GridConduction { static_cast<float>(PentodeEL34::kGridCurrentScale), static_cast<float>(PentodeEL34::kGridThresholdVolts), static_cast<float>(PentodeEL34::kGridTransitionVolts) }The power tube's grid law, read from PentodeEL34 so the stage and the DK model agree.
constexpr GridConductionLaw kTriode12AX7GridConduction { static_cast<float>(Triode12AX7::kGridCurrentScale), static_cast<float>(Triode12AX7::kGridThresholdVolts), static_cast<float>(Triode12AX7::kGridTransitionVolts) }The 12AX7's grid law, read from Triode12AX7 so the stage and the DK model agree.
constexpr float kFullScaleVolts = 2.0fThe peak voltage a full-scale (+/-1.0) sample represents at the amp's input, so a module's circuit model can be driven in volts rather than in normalized units.
constexpr std::size_t kDefaultLogQueueCapacity = 256Holds the queue length an application gets when it has no reason to choose one.
constexpr std::size_t kMaxLogMessageLength = 1024Bounds a formatted message in characters; a longer one is cut at this length.
constexpr float kHalfbandStage1Taps[115]Holds the 115 taps of the base <-> 2x stage, which runs at 2*f_base.
constexpr HalfbandDesign kHalfbandStage1 { kHalfbandStage1Taps, 115u, 0.225f, -90.123f }constexpr float kHalfbandStage2Taps[27] = { 1.717119303e-04f, 0.000000000e+00f, -1.208480913e-03f, 0.000000000e+00f, 4.838680383e-03f, 0.000000000e+00f, -1.437510550e-02f, 0.000000000e+00f, 3.597847000e-02f, 0.000000000e+00f, -8.671597391e-02f, 0.000000000e+00f, 3.113107085e-01f, 5.000000000e-01f, 3.113107085e-01f, 0.000000000e+00f, -8.671597391e-02f, 0.000000000e+00f, 3.597847000e-02f, 0.000000000e+00f, -1.437510550e-02f, 0.000000000e+00f, 4.838680383e-03f, 0.000000000e+00f, -1.208480913e-03f, 0.000000000e+00f, 1.717119303e-04f, }Holds the 27 taps of the 2x <-> 4x stage, which runs at 4*f_base.
constexpr HalfbandDesign kHalfbandStage2 { kHalfbandStage2Taps, 27u, 0.1375f, -101.599f }constexpr float kHalfbandStage3Taps[15] = { -1.697079046e-03f, 0.000000000e+00f, 1.412014756e-02f, 0.000000000e+00f, -6.346059591e-02f, 0.000000000e+00f, 3.010375202e-01f, 5.000000000e-01f, 3.010375202e-01f, 0.000000000e+00f, -6.346059591e-02f, 0.000000000e+00f, 1.412014756e-02f, 0.000000000e+00f, -1.697079046e-03f, }Holds the 15 taps of the 4x <-> 8x stage, which runs at 8*f_base.
constexpr HalfbandDesign kHalfbandStage3 { kHalfbandStage3Taps, 15u, 0.06875f, -110.691f }constexpr std::uint32_t kResamplerHalfWidthZeroCrossings = 34uInput samples stored on each side of the resampler prototype's peak (not the count of true zero crossings, which is lower since fc < 0.5).
constexpr std::uint32_t kResamplerPhasesPerZeroCrossing = 512uTable entries stored per zero crossing (the polyphase interpolation density).
constexpr std::uint32_t kResamplerKernelLength = 17410uLength of the kernel table in src/math/ResamplerKernel.hpp: peak, right wing and one guard entry.
constexpr float kResamplerCutoff = 0.45fCutoff of the prototype's ideal lowpass, in cycles per input sample.
constexpr float kResamplerPassbandEdge = 0.4fEdge of the band over which the passband ripple is measured.
constexpr float kResamplerStopbandDecibels = -100.477fWorst stopband level measured on the oversampled kernel, in dB.
Functions
float asio_sample_to_float(AsioSampleFormat format, const void *sample_bytes)Decodes one sample from a hardware buffer into a float in [-1, 1].
Parameters
formatThe sample's container format.
sample_bytesPointer to the sample's raw bytes (2 or 4, per format).
Returns
The decoded value.
void float_to_asio_sample(AsioSampleFormat format, float value, void *out_sample_bytes)Encodes a float in [-1, 1] into a hardware buffer's native format, clamping values outside that range to the format's full-scale value rather than overflowing.
Parameters
formatThe destination container format.
valueThe value to encode.
out_sample_bytesDestination for the sample's raw bytes (2 or 4, per format).
ChannelSelection parse_channel_selection(const std::string &value, const char *flag_name)Parses "L"/"l"/"R"/"r"/"stereo" into a ChannelSelection.
Parameters
valueThe flag's value, e.g. from "--input=L".
flag_nameThe flag's name, used only in the exception message (e.g. "--input").
Returns
The parsed selection.
Exceptions
std::runtime_errorif value matches none of the accepted spellings.
const char * channel_selection_label(ChannelSelection selection)A short human-readable label for a selection: "L", "R", or "stereo".
Parameters
selectionThe selection to label.
Returns
A statically-allocated label string.
std::size_t channel_selection_input_index(ChannelSelection selection)Maps a single-channel selection to a device input-array index: Left -> 0, Right -> 1.
Not meaningful for Stereo (callers only pass Left/Right here, since capturing one mono signal always reads exactly one physical channel).
Parameters
selectionLeft or Right.
Returns
0 for Left, 1 for Right.
bool rig_output_adapts_to_device(std::uint32_t rig_channels, std::uint32_t device_channels)Reports whether a rig output width can be written to a device output width.
The table is the one RigGraph::channels_adapt carries, clamped to the two widths write_rig_output_to_device implements: 1 into 1, 2 into 2, 1 into 2 (copied) and 2 into 1 (summed and halved). See docs/archive/superpowers/specs/2026-09-07-stereo-tracks-design.md.
Parameters
rig_channelsThe rig's output channel count.
device_channelsThe device's output channel count.
Returns
False when the pair has no rule, which the caller turns into a setup-time refusal.
void write_rig_output_to_device(const float *const *rig_outputs, std::uint32_t rig_channels, float *const *device_outputs, std::uint32_t device_channels, std::uint32_t frames, ChannelSelection output_selection)Writes a rig's output block into a device's output channels, adapting the width by the rig_output_adapts_to_device table.
Real-time safe: no allocation, lock, syscall or throw.
Parameters
rig_outputsOne pointer per rig output channel, each
framessamples.device_outputsOne pointer per device output channel; every one is written in full.
output_selectionGates a two-channel device: Left writes only device_outputs[0], Right only device_outputs[1], Stereo both. A one-channel device ignores it.
Precondition
rig_output_adapts_to_device(rig_channels, device_channels) is true.
float audio_taper_pot(float normalized)Returns the voltage division an audio-taper volume pot makes at one position, position to the three halves.
Parameters
normalizedPot position in [0, 1].
Returns
The fraction of its input the wiper passes, 0 at the bottom and 1 wide open.
void apply_output_safety_clamp(float *samples, std::uint32_t frames, float gain)Scales a block by its node's output gain and holds the result inside the converter's range, in place.
Parameters
samplesThe block to scale and clamp.
framesHow many samples the block holds.
gainThe output gain applied before the clamp.
Precondition
samples addresses frames writable floats.
float feedback_tail_resistance_ohms(const PowerAmpFeedbackComponents &components)Returns the resistance the inverter's tail sees to ground through the leg.
The leg carries the tail's own return, so this is what a long-tailed pair built beside it takes as its tail resistance; passing anything else makes the two disagree.
Parameters
componentsThe leg's component values.
float feedback_grid_source_resistance_ohms(const PowerAmpFeedbackComponents &components)Returns the resistance the driven grid is fed from, looking back into the leg.
This is the Thevenin resistance at the divider, which the grid reaches through a coupling capacitor low against it across the band. It moves by about a hundred ohms over the presence pot's whole travel, so it is taken at the pot's midpoint and treated as fixed.
Parameters
componentsThe leg's component values.
float decibels_to_gain(float db)Converts a level in decibels to a linear amplitude multiplier.
Parameters
dbThe level in decibels; 0 dB is unity.
Returns
The linear gain.
float gain_to_decibels(float gain)Converts a linear amplitude multiplier to decibels.
Parameters
gainThe linear gain; values below 1e-9 are floored to keep the log finite.
Returns
The level in decibels.
Logger & default_logger() noexceptReturns the logger of the process.
It starts with a StderrLogSink and LogLevel::Info, so a line logged before an application installs its own sink still reaches stderr.
constexpr LogCategory make_log_category(std::string_view name) noexceptMakes the category a module declares once, in its <module>_log_category.hpp.
Parameters
nameMust outlive every line logged under the category; a string literal does.
std::size_t format_log_arguments(char *buffer, std::size_t capacity, std::string_view format, const LogArgument *arguments, std::size_t argument_count) noexceptReplaces each {} of a format with the next argument, in order.
A marker with no argument left prints as {}; an argument with no marker is not printed.
Parameters
bufferReceives the text, cut at capacity, with no terminator.
argumentsMay be null when argument_count is zero.
Returns
The number of characters written, at most capacity.
std::size_t format_log_message(char *buffer, std::size_t capacity, std::string_view format) noexceptCopies a format that takes no values, so each {} in it prints as {}.
Parameters
bufferReceives the text, cut at capacity, with no terminator.
Returns
The number of characters written, at most capacity.
template <typename First, typename... Rest>
std::size_t format_log_message(char *buffer, std::size_t capacity, std::string_view format, const First &first, const Rest &... rest) noexceptFormats a message from values of the kinds LogArgument captures.
Parameters
bufferReceives the text, cut at capacity, with no terminator.
Returns
The number of characters written, at most capacity.
constexpr const char * log_level_name(LogLevel level) noexceptReturns the upper-case name a sink prints for a level.
Returns
A string with static storage, never null.

