Skip to content

Releases

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 24 Oct 02:00

Fixed

  • CI only: the docs-site and release jobs now install the D-Bus headers the ble default feature
    needs on Linux. No library changes from 0.6.0.

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 23 Oct 02:55

Added

  • Rename user slots without touching their sound: Device::rename_user_amp(slot, name) and
    Device::rename_user_ir(slot, name) (Python too) send only the import's name record (the AMP slot-info write,
    the IR 0x09 name write) and re-read the slot. The official app can't rename; confirmed on the pedal (a slot's
    sweep response before and after differs by at most 0.09 dB, rig noise; docs/05, "Renaming a slot"). Names are cut
    to 31 characters.

Changed

  • The activity event for a user AMP slot-info write is "User AMP slot" (it was "User AMP import"), since a rename
    sends the same record; like "User IR slot".
  • README and docs site: the NAM and IR graphs re-measured on hardware in one session with the official app's, 0.4's
    and 0.5's conversions (tools/pedalsim/readme_plots.py <session>, now with a dry-take reference instead of the
    Mac rig's calibration); the real-playing comparison is on the README and the site's front page.

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 23 Oct 01:46

Added

  • Documentation site (mdBook, site/, published to GitHub Pages by .github/workflows/pages.yml): install guides,
    both repositories' docs, the NAM / IR analysis with an interactive re-amp comparison, and the API reference.

Changed

  • nam::optimise: the loss now weights frequencies so each octave counts about the same
    (Options::weighting, Weighting::Octave, the new default). The old flat weighting gave the bottom octave
    ~0.5% of the fit, and imports came out 5–10 dB short at 50–160 Hz. In simulation the low-end error (40–160 Hz)
    of the Ampeg SVT-VR Classic (Normal) model drops from 4.9 to 2.1 dB rms and the frequency response error from
    2.5 to 1.2 dB; the frequency response improves on all six models tried, the low end on five (docs/05, "Low
    end"). Weighting::Flat keeps the old loss;
    example nam_optimise --flat. On hardware, a bass DI re-amped through the pedal against the
    model and IR in software: low end 5.2 → 3.8 dB rms, overall tone 3.5 → 2.8 dB (2.1 dB with the IR change below).
  • ir::convert_optimised: the tap fit now covers 30 Hz – 16 kHz instead of 25 Hz – 20 kHz. Cab IRs have next to
    nothing above 16 kHz, and matching it cost taps the rest of the range needs: on fifteen Ampeg IRs the 1/3-octave
    error of what the pedal plays drops from 2.42 to 2.18 dB rms (better on 13; the two DI recordings get slightly
    worse), and the 40–160 Hz error from 3.55 to 2.90 dB.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 08:10

Added

  • NAM import level normalisation, like NAM plugins: nam::convert::normalise_level scales G2 (after the pedal's
    saturation, so a pure volume change) so that every model plays at the same level, NORMALISED_LEVEL_DB,
    measured with pedal_level_db on pink noise and calibrated on the pedal to its built-in bass amps (two SVT-VR
    models 6 dB apart raw land within 0.2 dB of each other; un-normalised they sat 13–19 dB below the built-in amps). Models span about 17 dB raw; the conversions inherit
    the official app's level, which plays models quietly (24–34 dB below their own output). On by default for
    Device::import_nam_file; Device::import_nam_file_as(.., normalise), Python nam.convert(..., normalise=True)
    and Device.import_nam_file(..., normalise=...). nam::Model::loudness (the file's metadata). Example
    nam_level.
  • ir module: read and write WAV files (Wav: PCM 8–32-bit and float, any channel count), and convert, the
    official app's IR conversion recovered from its native code: files that aren't 48 kHz mono 24-bit are converted
    first (first channel, JUCE's resampler, resample_like_app, 24-bit), then the first 2048 samples are reversed and
    scaled so the 398 Hz – 3 kHz response is centred on 0 dB (app_gain). Identical to eleven captured imports
    (tests/ir_import.rs). Device::import_ir_file(slot, path) converts and uploads, named like the app (first 16
    characters). Also a windowed-sinc resample. Python: open_stomp.ir, Device.import_ir_file. Examples
    ir_check, ir_test_files (designed test IRs, tests/data/ir) and ir_capture_check.
  • The pedal plays only the first 384 taps of an uploaded IR (re-amped probe IRs; ir::PEDAL_IR_TAPS, docs/05).
  • ir::convert_optimised / Method::Optimised (feature nam): a 384-tap minimum-phase filter fitted to the whole
    IR's 1/6-octave response, at the level the app means to give it. On fifteen bass IRs in software, what the pedal
    plays is 2.4 dB rms from the full IR against 7.9 dB for the official conversion, which leaves IRs with a delayed
    start 35–44 dB too quiet. Confirmed on hardware (re-amped: 2.1 vs 4.8 dB rms, and 5.5 dB vs 16 dB rms plus 46 dB
    too quiet for a delayed IR). The default for Device::import_ir_file (Python too); convert_with,
    Device::import_ir_file_with(.., Method::App) for the official conversion, Python method=, example ir_compare.

Fixed

  • User IR uploads put the slot in data-header byte 0, as the official app does (it was in byte 1, NAM's slot byte,
    so only slot 0 was right). upload::Chunk::ir_slot; Reassembler reports either slot.

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 03:43
865f995

Added

  • nam feature and module (on by default): load and run Neural Amp Modeler .nam models (a
    pure-Rust port of NeuralAmpModelerCore's WaveNet, plain and SlimmableContainer; matches it to
    ≤ 3e-5 on its example models, which are now test vectors), and nam::convert, the official
    app's NAM → pedal converter: a fundamental/3rd-harmonic tone test and a small-signal linear
    response give two minimum-phase FIRs. With the app's own excitation the result matches its
    upload to ≤ 0.03 dB; with ours (the default) within ~1–1.5 dB rms, the app's own measurement
    noise. Device::import_nam_file(slot, path) converts and uploads. Examples nam_convert,
    nam_render, nam_check. Python: open_stomp.nam, Device.import_nam_file. Confirmed on
    hardware: an official and an open conversion of the same bass model sound identical.
  • nam::convert::Measure::Clean (convert_measured; Python nam.convert(..., measure="clean")),
    experimental: the same converter with a steady-state small-signal measurement instead of the
    app's transient-affected one. Re-amp tests on hardware against the real model (Ampeg SVT bass
    model): closer mid scoop, top-end roll-off and upper-note distortion than the official
    algorithm, but still short on the 63–90 Hz resonance and about 5 dB quieter. Not the default.
  • nam::convert::PEDAL_TAPS, upload_data, pedal_irs: the pedal runs only the first 512 taps
    of each uploaded filter (found by re-amping; docs/05). Measure::Clean now uploads exactly
    those taps, with the ignored halves zeroed; Measure::App keeps the app's layout.
  • nam::optimise and Measure::Optimised, the default for Device::import_nam_file (about a
    minute per model): fit G1/G2 so a simulation of the pedal (y = G2 ⊛ f(G1 ⊛ x), its saturation
    curve fitted from re-amp recordings) matches the model on sweeps, tones and pink noise, starting
    from the clean conversion. Hand-written gradients, Adam, no ML framework. On hardware (Ampeg SVT
    bass model) it scores 6.72–6.85 dB rms error against the real model, against 9.32 for the
    official conversion in the same session. Device::import_nam_file_with(.., Measure::App) keeps
    the official algorithm (a few seconds). Progress and cancel: convert::convert_optimised,
    optimise::optimise_with_progress. Also optimise::simulate, example nam_optimise.
    Python: Device.import_nam_file(..., measure="optimised") (default) and nam.convert(..., measure="optimised").
  • nam::convert::official_excitation / find_official_excitation: read the official app's test
    signal from the user's own Stomp Manager install (located by fingerprint; no vendor data in the
    source). With it the conversion equals the official one (error energy −51 to −93 dB on ten
    models). Strictly opt-in: Device::import_nam_file and everything else never read the app.
    Python: nam.official_excitation().
  • upload module: user AMP (NAM, SysEx 0x58) and user IR (0x10 + 0x09) upload framing:
    chunking, the 128-byte slot-info record (UserAmpInfo: name, factor), delete, and a
    Reassembler that turns captured chunks back into floats. Every captured import rebuilds
    byte for byte. Device::import_user_amp / delete_user_amp / import_user_ir send the
    official app's sequences (2048 finite floats, slots 0–9, else UploadError). Also in the
    Python bindings (open_stomp.upload, Device.import_user_amp …).
  • DeviceState follows user AMP imports and deletes (slot names, log events with progress).

Changed

  • docs/05: corrected chunk header (plain byte offset + total length, not 8-byte units), the
    slot-info record layout, and the app selecting the slot's model before uploading.
  • docs/05, docs/09: the NAM converter algorithm, recovered from the vendor code and verified stage
    by stage: a small-signal best linear approximation and a sine tone test (fundamental and 3rd
    harmonic) through the network give two minimum-phase FIRs (Wiener–Hammerstein G1/G2) whose first
    1024 taps, reversed, are the upload; factor is always 1.0.

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 21 Oct 21:14
98c4ff0

Added

  • Python bindings (bindings/python, pip install ./bindings/python, import open_stomp):
    the whole library through PyO3, mirroring the crate's modules: protocol, catalogue, records,
    DeviceState, RequestQueue, capture reader and the Device engine. One abi3 wheel per
    platform for Python ≥ 3.9, typed stubs checked with stubtest, GIL released while waiting,
    Ctrl-C interrupts blocking calls. DeviceState.feed(update) applies engine updates. Tests
    driven by the capture logs, monitor.py and shell.py (interactive) examples and a Python
    guide (docs/11).
  • The repository is now a Cargo workspace; the crate and the Python package share its version.