Waldorf Quantum/Iridium: round the sample map positions to the nearest frame - #339
Open
douglas-carmichael wants to merge 1 commit into
Open
Waldorf Quantum/Iridium: round the sample map positions to the nearest frame#339douglas-carmichael wants to merge 1 commit into
douglas-carmichael wants to merge 1 commit into
Conversation
…t frame The sample map of a preset stores every position - sample start and end, loop start and end - as a fraction of the sample length with 8 decimal places. Such a fraction can land marginally below the exact frame boundary: frame 3977 of 5469 is written as 0.72718961, and 0.72718961 * 5469 = 3976.9999787. The reader truncated this product, which loses one frame for every position whose fraction rounds low - 759 of the 2270 loop positions on a converted card of 165 presets. Each read of such a preset therefore shifted its loops, and converting a preset to QPAT and back moved them one frame further down with every generation. The fraction is now rounded to the nearest frame. This also matches the device: presets which an Iridium MK2 itself exports store fractions which land marginally below the frame in exactly the same way (e.g. 0.64510852 * 116785 = 75338.9985 for loop start 75339), so the device has to round when it reads them back - a truncating reader mis-reads the device's own files too.
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.
The QPAT sample map stores every position - sample start/end, loop start/end - as a fraction of the sample length with 8 decimal places. Rounding a fraction to 8 decimals can land it marginally below the exact frame boundary:
The reader multiplies back and truncates (
(int)cast), so every such position loses one frame:On a converted card of 165 presets, 759 of 2270 loop positions read one frame low. Reading a preset - the Contents audition included - therefore plays its loops shifted, and a QPAT-to-QPAT conversion walks every affected loop one frame further down per generation.
The device's own files confirm that rounding is the correct interpretation. A preset exported by an Iridium MK2 itself stores the same round-to-nearest fractions - from a real export:
Both land marginally below their frame, so the device has to round when reading its own exports back - otherwise its own export/import cycles would drift. A truncating reader mis-reads the device's files exactly like ours.
The fix rounds the four positions to the nearest frame. The writer is untouched: it already writes round-to-nearest fractions, which is what the device writes as well.
One observation from the same export, as a question rather than a change: the device writes the sample end as (frames-1)/frames - the last frame index - where we write 1.0 for the full sample (which the device accepts on import). If its end fields are inclusive, reading a device-authored preset trims sample and loop ends by one frame even with rounding. I did not change this since one export is thin evidence for a convention - you may know from the format work whether the device's end positions are inclusive.
Verified by re-reading a full converted card with the fix: the 759 truncation victims move up exactly one frame, all other positions are unchanged, and writing-then-reading a preset now returns every position identically over repeated generations.