richbits.net  /  signal · sound · software

Independent audio & hardware software

Tools for people who measure what they hear.

I design and build native macOS apps, DSP plugins and measurement rigs around real hardware: synthesizers, outboard gear, sensors. Every tool here was built to answer a question about sound or signal, and the results are published.

apps
Swift · SwiftUI · CoreMIDI · Core Audio
dsp
C++ · JUCE · oversampling · nonlinear models
analysis
Python · FFT · harmonic & THD measurement
infra
Raspberry Pi · nginx · Cloudflare Tunnel
01

Live on the network

served from Raspberry Pis, self-hosted

02

On the bench

real source excerpts, live demos

02.1 · AU / VST3 plugin

Vintage Master Saturator

A master-bus saturator modelled on analogue circuit behaviour instead of a single waveshaper.

  • 4× oversampling through a two-path polyphase allpass half-band filter
  • Magnetic hysteresis core, power-supply sag, tape head response
  • Device curves from 12AX7 to GaN, plus a true-peak limiter
C++JUCEDSP
transfer curve
harmonics · dBc
Source/PluginProcessor.cppharmonics computed in your browser
// tanh-family clipper: y = tanh(k*x)/tanh(k), so y(±1) = ±1 exactly regardless of k.
// Lower k -> wider/gentler knee; higher k -> tighter/more aggressive knee.
inline float tanhClipper (float x, float k) noexcept
{
    const float kk = juce::jmax (0.05f, k);
    return std::tanh (kk * x) / std::tanh (kk);
}
02.2 · macOS app

Sonic Lens

Hardware-audio measurement: sends a controlled test signal through outboard gear and analyses what comes back.

  • Safety-first sine generator: −18 dBFS default, −6 dBFS ceiling, emergency mute
  • Scope, FFT spectrum, H1–H10 harmonics, THD, frequency response
  • Compressor characterisation: static knee, release, THD vs. gain reduction
SwiftCore AudioFFT
Sources/AnalysisCore/AnalysisCore.swiftthe THD above uses this formula
// Total Harmonic Distortion: energy in H2…Hn relative to the fundamental
public var thd: Float {
    guard let h1 = amplitudes.first, h1 > 0 else { return 0 }
    return sqrt(amplitudes.dropFirst().reduce(0) { $0 + $1 * $1 }) / h1
}

// Harmonic levels relative to the fundamental (dBc)
public var levelsDBc: [Float] {
    guard let h1 = amplitudes.first, h1 > 0 else { return amplitudes.map { _ in -160 } }
    return amplitudes.map { DSP.decibels($0 / h1) }
}
02.3 · macOS app

Motif Editor

A native editor and librarian for the Yamaha Motif ES. Every control sends a real SysEx parameter change to the synth, and bulk dumps pull its state back.

  • Common, per-element voice editing, effects routing
  • Full waveform catalogue with solo / audition
  • Live two-way sync over CoreMIDI
SwiftSwiftUICoreMIDISysEx
Sources/MotifCore/MotifSysEx.swiftaddress shown is illustrative
/// Single-parameter change: F0 43 1n 7F 00 aa bb dd [data] F7 (no checksum)
public static func paramChange(
    deviceNum: UInt8 = 0,
    addrHi: UInt8, addrMid: UInt8, addrLo: UInt8,
    data: [UInt8]
) -> [UInt8] {
    [0xF0, yamaha, 0x10 | (deviceNum & 0x0F), modelID, 0x00,
     addrHi, addrMid, addrLo] + data + [0xF7]
}
02.4 · macOS app

Motif Capture

Capture automation for synth presets. It steps through a preset list over MIDI, records each patch and builds an auditionable library. This is what fed the Motif ES analysis.

  • Bank Select MSB/LSB + Program Change per preset
  • 16-voice hardware groups, gap-fill re-runs
  • Live RMS meter, peak hold, clip and no-signal detection
SwiftCoreMIDIAVFoundation
capture sequence · one presetMIDI out → audio in
// PRE1 A01 → A16, one hardware group at a time
B0 00 3F      // CC 0  bank select MSB
B0 20 00      // CC 32 bank select LSB
C0 00         // program change → A01
wait  settle
record 6.0 s  // native rate → 192 kbps AAC preview (~150 KB)
check  rms > floor, peak < 0 dBFS
next