Add Renoise instrument (XRNI) format support (read + write)#149
Add Renoise instrument (XRNI) format support (read + write)#149douglas-carmichael wants to merge 8 commits into
Conversation
Adds a detector and creator for the Renoise instrument format (.xrni), a ZIP archive containing an Instrument.xml description and FLAC samples in a SampleData folder. Created files use document version 34 (Renoise 3.5); document versions 24-34 can be read. Translated: key/velocity mapping, root note, tuning, volume, panning, loops, the amplitude envelope, a per-sample sampler filter (type, cutoff and resonance with a cutoff envelope), a pitch envelope and round-robins. The filter is written as the native sampler filter, including the required SampleMixerModulationDevice so the instruments load in Renoise. Also fixes a latent issue where FLAC or OGG samples stored inside a ZIP archive could fail to decompress with a "mark/reset not supported" error; AudioFileUtils.decompressToWav now wraps non-markable streams (this also benefits the existing discoDSP Bliss and DecentSampler library import). Verified against the Renoise 3.5 factory instruments (read, round-trip and load in Renoise) and the generated Instrument.xml validates against the official RenoiseInstrument34 schema.
Renoise has no loop cross-fade parameter, so by default loops are written exactly (faithful). When the loop cross-fade processing option is enabled, the cross-fade is now baked into the looped sample audio so that loops with a discontinuity (e.g. some SoundFonts) wrap seamlessly.
|
Added a second commit with an opt-in loop cross-fade, kept separate so it's easy to judge on its own. Default is unchanged and fully faithful — loops are written exactly as they come from the source. Renoise has no loop cross-fade parameter, so only when the existing "loop cross-fade" processing option is enabled does the Renoise creator bake the cross-fade into the looped sample audio. Motivation: some sources define loops with a built-in discontinuity (e.g. a SoundFont whose loop-offset generators land the loop on a non-matching point). That's reproduced faithfully by default, but it clicks in Renoise's sample-accurate looping; the option gives a way to get seamless loops without changing the faithful default. Left entirely optional for your call. |
The written instrument structure is valid for document version 33 (Renoise 3.3) and validates against the v33 and v34 schemas alike. Using 33 lets the created files load in newer Renoise versions as well as in the Renoise Redux plug-in, whose own instruments use document version 33.
Some samples trigger an ArrayIndexOutOfBoundsException in the bundled FLAC encoder library (seen e.g. with a 24-bit auto-sampled Logic EXS24 instrument). Instead of aborting the whole instrument, such a sample is now stored as an uncompressed WAV file - which Renoise reads as well - while the remaining samples stay FLAC encoded.
Renoise attaches a filter to virtually every instrument through its always-present mixer device. When that filter is parked at the transparent extreme - a high-pass at the bottom of its range or a low-pass at the top - it removes nothing audible, but writing it out as an active filter is at best pointless and at worst harmful: the Waldorf Quantum/Iridium muted a patch whose high-pass was parked at its lowest cutoff, so the converted instrument produced no sound at all. The detector now returns no filter for such transparent settings (high-pass cutoff <= 40 Hz, low-pass cutoff >= 18 kHz). Because this happens while reading the Renoise file, every output format benefits - verified that the transparent filter is dropped for Waldorf, Akai MPC, SFZ, tx16wx, DecentSampler and others, while an audible filter (e.g. a 632 Hz low-pass) is still written correctly.
|
A couple of notes for merging: 1. Complements #150. Reading an XRNI decompresses its (stereo FLAC) samples, which trips a pre-existing bug that halved stereo compressed samples on decompress — fixed separately in #150. This PR stands on its own, but converting XRNIs to uncompressed destinations only yields full-length samples with #150 merged as well, so the two go well together. 2. Small overlap with #150 in |
… a corrupt value A zero (or sub-0.06 second) attack, decay or release was converted to an out-of-range QPAT parameter value - exactly zero produced negative infinity - and written into the preset as a corrupt float. On the Quantum/Iridium this could cause a click at the start of every note. Such times are now clamped to the shortest representable value [0..1].
A Renoise amplitude envelope with no attack and no decay but a sustain below full level (e.g. attack 0, decay 0, sustain 51%) was written verbatim. On the Quantum/Iridium that snaps the amplifier to the 100% attack peak and then instantly drops to the sustain level at the start of every note, which is audible as a pop. Such an envelope is meant to be flat at the sustain level, so it is now written with a full sustain and the sustain level is folded into the per-zone gain instead - the steady-state loudness is identical but there is no longer an instantaneous level step.
|
Many thanks! Can you point me to test files? Also for the Polyend format? PM me on KVR. |
|
Thanks! I you can remove it again if you want. |
Summary
Adds read and write support for the Renoise instrument format (
.xrni) — a ZIP archive containing anInstrument.xmldescription plus FLAC samples underSampleData/. Created files use document version 34 (Renoise 3.5); document versions 24–34 can be read.What is translated
Cycle/Randomkeyzone overlapping mode)The filter is written as the native sampler filter inside the modulation set, including the required
SampleMixerModulationDevice(which backs the modulation "input" view) so the instruments open correctly in Renoise rather than crashing the editor.Also included
mark/reset not supportederror.AudioFileUtils.decompressToWavnow wraps non-markable streams in aBufferedInputStream. This also benefits the existing discoDSP Bliss and DecentSampler library import.Implementation
format/renoise:RenoiseDetector,RenoiseCreator,RenoiseTag,RenoiseValueConverter,RenoiseFilterType.ConverterBackend.documentation/README-FORMATS.md;CHANGELOG.mdupdated under 18.2.0.Known limitations (documented)
Verification
Instrument.xmlvalidates against the officialRenoiseInstrument34.xsd.