Skip to content

Waldorf Quantum/Iridium: apply the modulation and envelope laws of the firmware 4.0.6, convert the filter LFO, the glide and the polyphony - #428

Open
douglas-carmichael wants to merge 2 commits into
git-moss:mainfrom
douglas-carmichael:qpat-model-features
Open

douglas-carmichael wants to merge 2 commits into
git-moss:mainfrom
douglas-carmichael:qpat-model-features

Conversation

@douglas-carmichael

Copy link
Copy Markdown
Contributor

Stacked on #427, which is stacked on #426 and #425; the diff shows all four until those land. All four are rebased on main.

Read out of the Iridium MK2 firmware 4.0.6 and measured on an Iridium MK2 with OS 4.0.6.

Pitch modulation amounts are squared. ModMatrix::calc squares the amount of a slot on the destinations Pitch and Osc1-3 Pitch, keeping its sign - these destinations are registered with the squaring flag and the amount goes through fabs - and the voice multiplies the sum with 24 semitones. Pitch envelopes and vibratos were written and read with the linear semitones / 24: an amount of 50 % plays 6 semitones, not 12, and the amount written for a vibrato of 50 cents plays about 1 cent. Both directions use the law of the device now.

Envelope times. The sound engine plays an attack, a decay or a release as 60 x 10^(3 (x - 1)) - 0.06 seconds; the display shows - 0.001, the law which was used. Every stage played 60 ms short and every stage below 60 ms was written as instant. The creator writes x = log (1 + t / 0.06) / log (1000) and the detector reads with the same law. The minimum of the de-click rule becomes 0.01 s, which writes exactly the value of the former 0.07 s - the length the device played in the test which established that rule.

Matrix destinations by name. The list of destinations grew with the firmware: the VCA is 107 up to the format version 13, 108 in 14 and 117 in 15, Filter1 Cutoff 99, 100 and 109. The loader resolves every enumeration by the name in its hint (PatchLib::migrateIOAreaToStagingArea calls Param::DiscreteNameToIndex) and uses the stored index only without one. The detector matches destinations by the hint and falls back to the index of the file's version, which finds the tremolo of patches written by older firmware and no longer takes a version 8 slot on LFO1 Speed - index 117 there - for a tremolo. The creator writes the index of the version it writes.

New

  • An LFO on Filter1 Cutoff is read and written (slot 6, LFO 3). This destination is not squared; the full amount moves the cutoff by 135 semitones, the range of Filter1CutOff.
  • The portamento of a source is written as the glide: GlideOnOff, GlideRate (2 x^2 seconds, the same time for every interval), GlideType Legato for a legato source.
  • A polyphony of 1 is written with the mono mode; a mono patch is read with a polyphony of 1.
  • A key tracking which all key-tracked zones of a group share is written as Osc{i}Keytrack.

Fixed

  • A pitch envelope whose start level is not set (-1) was written as one which starts at a level - no attack, and the attack time of the source as its decay - so e.g. the decay of an SFZ pitch drop was lost. The test is getStartLevel () > 0 now; AbstractNKIMetadataFileHandler writes Kontakt pitch envelopes with the same != 0 test.
  • The hint of a negative pitch bend range was written as --2.

Measured on an Iridium MK2 (OS 4.0.6), recordings analysed by pitch tracking:

test expected measured
free envelope at full level into Osc2 Pitch at +50 % 6 semitones (squared), 12 (linear) 6.00 semitones at A4 and at C5
converted vibrato of 50 cents at 5 Hz +/-50 cents +/-49.97 cents at 4.999 Hz; the previous conversion: +/-1.04 cents
converted SFZ pitch drop of 12 semitones over 0.5 s starts an octave high +12.02 semitones, linear slide; the previous conversion: no slide
GlideRate 0.7071 1 s for every interval 1.000 s over 200 and over 400 cents
unipolar square LFO at +8.89 % on Filter1 Cutoff an octave 11.75 +/- 0.5 semitones, every 1.000 s
stages written for 0.07, 0.1, 0.25, 0.5, 1 and 2 s with the display law, EnvelopeVariation 0 t - 0.06 0.011, 0.041, 0.190, 0.441, 0.940 and 1.940 s for attack, decay and release

Checked

  • QPAT corpus: 19 of 19.
  • All 1,787 factory patches analyse without an exception.
  • An SFZ with a polyphony of 1, 50 % key tracking, a vibrato, a pitch envelope, a cutoff LFO and a tremolo round-trips through QPAT to SFZ and to QPAT; envelope times round-trip exactly.
  • Reading the factory and the Flux Vol. 1 patches changes only the pitch amounts, finds 3 and 4 cutoff LFOs and moves one tremolo to the real VCA slot.
  • Writing Espen Kraft's PX Vol. 2 (43 presets) and an E4B bank (474 presets) changes only envelope times; the sample maps are identical.

…K2 generation

The 'Use a second layer' check box becomes a 'Maximum number of layers' drop-down with 1,
2, 3 or 4 layers. With 3 or 4, a source with more than 6 groups is written with
up to 9 or 12 multi-samples in the layout the Iridium MK2 stores its own patches in: the
layer count 2, the format version 15 and always four stored layers, of which
the unused ones are switched off (LayerActive 0, no oscillators, no maps). The
loader of the device clears the file offsets of the layers 3 and 4 in files up
to the version 14, which is why the layout needs the version 15. Only as many
layers as the groups need are used, so a source with up to 6 groups is still
written as the 2-layer patch of the version 14 which every instrument of the
family plays. The samples of all later layers are named in the first layer for
the importer of the device.

A setting of the old option is taken over, and the old command line parameter
is still accepted. Verified on an Iridium MK2 with OS 4.0.6: a written 4-layer
patch with one sample pitch per layer plays all four pitches, a 3-layer patch
with its switched-off fourth layer plays its three.

Claude-Session: https://claude.ai/code/session_01P2bmFi6STyJoKHvjkuLiVy
…e firmware 4.0.6, convert the filter LFO, the glide and the polyphony

The Iridium MK2 firmware 4.0.6 squares the amount of a matrix slot on the
destinations Pitch and Osc1-3 Pitch, keeping its sign, and multiplies the sum
with 24 semitones (the destinations are registered with the squaring flag,
ModMatrix::calc squares the amount with fabs). Pitch envelopes and vibratos were
written with the linear semitones / 24: an amount of 50 % plays 6 semitones and
the amount written for a 50 cent vibrato plays about 1 cent. Both directions now
use the law of the device; the modulation-wheel vibratos of the factory patches
(11-20 %) are 29-96 cents with it.

The index of a matrix destination depends on the format version (VCA 107 up to
version 13, 108 in 14, 117 in 15) and the device resolves every enumeration by
the name in its hint (PatchLib::migrateIOAreaToStagingArea calls
Param::DiscreteNameToIndex). The reader matches destinations by the hint and
falls back to the index of the version, which finds the tremolo of patches
written by older firmware and no longer takes e.g. 'LFO1 Speed' at 117 of a
version 8 file for one. The writer uses the index of the written version.

New: an LFO on Filter1 Cutoff is read and written (slot 6, LFO 3; linear,
135 semitones at the full amount). A portamento is written as the glide and read
back (2 x GlideRate^2 seconds for every interval, Legato type for a legato
source). A polyphony of 1 is written with the mono mode and a mono patch is read
with a polyphony of 1. A key tracking which all key-tracked zones of a group
share goes into the key tracking of the oscillator.

Fixed: every attack, decay and release was 60 ms too short on the device. The
sound engine plays a stage as 60 x 10^(3 (x - 1)) - 0.06 s; the display shows
- 0.001 s, the law which was used, which also wrote every stage below 0.06 s as
instant. Both directions now use the law of the engine. The de-click minimum
becomes 0.01 s, which writes exactly the value of the former 0.07 s - the
length the device played in the hardware test which established it.

Fixed: a pitch envelope without a start level (-1, unset) was written like one
which starts at a level - attack 0 and the source's attack time as its decay -
so the decay of e.g. an SFZ pitch drop was lost. The hint of a negative pitch
bend range was written as '--2'.

Checked: the QPAT corpus harness 19 of 19; all 1,787 factory patches analyse
without an exception; an SFZ with polyphony 1, 50 % key tracking, a vibrato, a
pitch envelope, a cutoff LFO and a tremolo round-trips through QPAT to SFZ and
QPAT unchanged; reading the factory and Flux Vol. 1 patches changes only the
pitch amounts, adds 3 and 4 cutoff LFOs and moves one tremolo to the real VCA
slot; before the envelope law change 1,146 presets of four other libraries (two
SF2, a Renoise and an E4B set) were written byte-identically, since none of them
uses these modulations; with it, PX Vol. 2 (43) and an E4B bank (474) differ
only in envelope times (AmpEnvRelease in all, AmpEnvDecay in 85, filter envelope
times in 18), their sample maps are identical.

Hardware (Iridium MK2, OS 4.0.6, recordings 2026-09-14): a free envelope at
full level into Osc2 Pitch at +50 % plays 6.00 semitones above the unmodulated
oscillator at two keys (squared law); a GlideRate of 0.7071 glides for 1.000 s
over 200 and 400 cents in a straight line of pitch; a unipolar square LFO at
+8.89 % on Filter1 Cutoff moves a resonant 24 dB low-pass by 11.75 +/- 0.5
semitones, every 1.000 s; a converted 50 cent vibrato at 5 Hz swings +/-49.97
cents at 4.999 Hz, the daily driver's conversion of the same source +/-1.04
cents, as the squared law predicts for its linear amount; a converted SFZ pitch
drop of 12 semitones over 0.5 s starts four notes 12.02 semitones high and
slides down on a straight line (within 0.8 cents) in 0.408-0.437 s, while the
daily driver's conversion plays no slide at all. Envelope times with EnvelopeVariation at 0
(three patches, three linear pitch envelopes each, three notes each): stages
written for 0.07, 0.1, 0.25, 0.5, 1 and 2 s with the display law took
0.011/0.041/0.190/0.441/0.940/1.940 s for attack, decay and release, within 2
ms across notes - the engine law above.

Claude-Session: https://claude.ai/code/session_01VCnGn5JX5qjoiFb6874GV4
douglas-carmichael added a commit to douglas-carmichael/ConvertWithMoss that referenced this pull request Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant