Add support for the Kurzweil K2000/K2500/K2600 format (KRZ, K25, K26) - NOT yet tested on hardware#189
Open
douglas-carmichael wants to merge 3 commits into
Conversation
Add a detector and creator for Kurzweil K2x00 object files. A file is a bank of numbered objects: programs, keymaps and samples (which may hold several recordings for multiple root keys and stereo pairs). The layout was derived from the source code of the GPL tool KurzFiler by Marc Halbruegge (see documentation/design/KURZWEIL_FORMAT.md). Reading converts each program into one multi-sample: the layers reference keymaps from which the key ranges, the 8 dynamic velocity levels, root keys, per-entry tunings, loops and the 16-bit sample data are read. Compacted keymaps (a shared sample ID for all entries) and all entry layouts (the method bits) are supported. Keymaps and samples which are not referenced by any program become multi-samples of their own. Zones which map samples from the device ROM cannot be converted and are skipped with a note. A zone which appears identically on several adjacent velocity levels is merged back into one zone. Writing creates a .krz file which uses only K2000 features and therefore loads on all three device families. Each multi-sample becomes a program with one layer and a keymap: one sample object is written per zone (16-bit, the sample rate is kept), the velocity layers are distributed onto the 8 dynamic levels (levels with the same zones share one entry table), tuning, partial or disabled key tracking and the root key are encoded into the per-entry tunings and the data after the loop end is cut off since the device plays a loop until the sample end. If any zone is stereo, all samples of the program are written as stereo left/right header pairs (mono zones are duplicated). Several multi-samples can be written into one file as a library; when the object IDs (200-999 per type) do not suffice, multiple files are created. Verified against the KurzFiler test corpus (including real-world .k26 banks): all files read; round-tripped files re-load byte-identical sample data, mappings and loops in the reference implementation.
A drop-down selects the device family for which the file is named: K2000 (krz), K2500 (k25) or K2600 (k26). Since the written objects use only K2000 features and load on all three families, the selection only sets the file extension. On the command line the device is set with -p KurzweilTargetDevice=K2000|K2500|K2600 (the extensions are accepted as well), the default is K2000.
The K2600 manual documents the Volume Adjust parameter of a sample with a range of -64.0 to +63.5 dB, which confirms that the volume adjust byte of the sample header holds 0.5 dB steps. The zone gain is now written into it and read back from it. The manual also documents the maximum sample playback rate of the devices as 96 kHz (and the current Kurzweil range - K2700, PC4, Forte, which loads K2x00 files as well - caps its own audio imports at 96 kHz). Samples with higher rates are now down-sampled to 96 kHz with the sample positions re-calculated accordingly.
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.
This adds a detector and creator for Kurzweil K2x00 object files (.krz, .k25, .k26). A file is a bank of numbered objects: programs, keymaps and samples, where a sample object may hold several recordings (multiple root keys, stereo left/right pairs). The layout was derived from the source code of the GPL tool KurzFiler by Marc Halbruegge (https://sourceforge.net/projects/kurzfiler/); the implementation here is new code written against a format description extracted from it, documented in
documentation/design/KURZWEIL_FORMAT.md. The current Kurzweil range (K2700, PC4, Forte) imports K2x00 files as well, so the created files are not only for the vintage units.Reading: each program becomes one multi-sample. Its layers reference keymaps, from which the key ranges, the 8 dynamic velocity levels, root keys, per-entry tunings (cents), per-sample volume adjusts, loops and the 16-bit sample data (per-header sample rates, stored as nanosecond periods) are read. All keymap entry layouts (the method bits) are supported, including compacted keymaps with a shared sample ID. Keymaps and samples not referenced by any program are converted as multi-samples of their own. Zones which map samples from the device ROM cannot be converted and are skipped with a note (once per sample) - many factory/commercial K-series banks are affected. A zone appearing identically on several adjacent velocity levels is merged back into one zone.
Writing: the created files use only K2000 features (mode 2 programs) and therefore load on all three device families; a Target Device option selects the file extension - krz (default), k25 or k26 (CLI:
-p KurzweilTargetDevice=K2000|K2500|K2600). Each multi-sample becomes a program with one layer and a keymap: one sample object per zone (16-bit; the sample rate is kept up to 96 kHz, the maximum sample playback rate documented in the K2600 manual, higher rates are down-sampled), the zone gain is written into the sample volume adjust (0.5 dB steps, the unit is confirmed by the -64.0..+63.5 dB range of the Volume Adjust parameter in the K2600 manual), velocity layers are distributed onto the 8 dynamic levels (levels with the same zones share one entry table), and tuning, partial/disabled key tracking and the root key are encoded into the per-entry tunings. Since the device plays a loop until the sample end, data after the loop end is cut off. If any zone is stereo, all samples of the program are written as stereo pairs (mono zones are duplicated). Libraries are supported: several multi-samples in one file, split over multiple files when the object IDs (200-999 per type) run out.Verification: KurzFiler itself was compiled and used as a reference reader. The KurzFiler test corpus (including real-world .k26 banks) converts without errors, and round-tripped files re-load in the reference implementation with byte-identical sample data (CRC-checked), identical keymap entry runs, loops, roots, volume adjusts and maxPitch values. A synthetic stereo + velocity-layer test confirmed channel order, loop truncation, per-sample rates and the 96 kHz down-sampling (including the re-calculated loop positions) in both directions. Not yet tested on the actual hardware - the generated objects mirror KurzFiler's hardware-proven output values, but I do not have a K2x00 at hand. (Since the K2700/PC4/Forte load these files too, a test on one of those would also be meaningful.)
Known limitations (also noted in the docs): the keymap-entry volume adjust unit is unconfirmed and therefore ignored (the per-sample volume adjust is converted), the natural envelopes and program filter/envelope segments are not decoded, loops are forward-only (the per-sample Reverse/Bidirectional playback modes exist on the device but their bit positions in the header are unknown), and keys below C0 (MIDI 12) cannot be mapped.
README-FORMATS.md, the CHANGELOG and the feature support matrix are updated.