Summary
When ConvertWithMoss runs in CLI mode on a large Kontakt library (one .nki with hundreds of samples), the only live feedback is a stream of . dots on stdout (IDS_NOTIFY_PROGRESS). That is fine for humans, but automation hosts and DAW plugins that spawn CWM as a child process cannot derive a numeric percentage or current item from dots alone.
We hit this integrating CWM into a proprietary DAW plugin (Kontakt import via SFZ). On a typical .nki import the UI stayed at 0% for minutes, then jumped to 100% when conversion finished.
We implemented a small, opt-in extension and would like to upstream it (or something equivalent) so all CLI users benefit.
Proposal
Add an opt-in machine-readable progress protocol on stderr, separate from the existing human-oriented stdout dots.
Activation (opt-in, zero cost when off)
- CLI flag:
-P / --machine-progress
- Environment (optional):
CWM_MACHINE_PROGRESS=1 or true (for wrappers that cannot pass flags easily)
When disabled, behaviour is unchanged.
Line format
One ASCII line per event, newline-terminated, stderr, flushed immediately:
CWM_PROGRESS pct=<0..100> phase=<token> detail=<text>
pct: integer 0..100
phase: sanitized token, e.g. start, convert, sample, done
detail: short ASCII-safe snippet (filename / path tail)
Example session:
CWM_PROGRESS pct=0 phase=start detail=C:/Libraries/MyBank
CWM_PROGRESS pct=12 phase=convert detail=Enigma.nki
CWM_PROGRESS pct=14 phase=sample detail=Kick_01.wav
CWM_PROGRESS pct=15 phase=sample detail=Snare_02.wav
...
CWM_PROGRESS pct=100 phase=done detail=
Hosts grep stderr for the prefix; humans can ignore unknown lines.
Where to emit (minimal hooks)
We found AbstractDetector is the right central place:
- Before
detect(): count matching instrument files recursively (machineProgressTotal), emit phase=start.
- Per instrument file: emit
phase=convert at file start (non-zero pct inside the file's slice) and after file finish.
- Per sample zone: in
createSampleZone() emit phase=sample after each WAV/NCW load.
- After
detect(): emit phase=done at 100%.
Percentage model
-
Between files: linear by completed file count (done / total * 100).
-
Inside one big file: interpolate within the current file's pct slice. Total sample count per .nki is unknown upfront, so we use a smooth asymptote toward the slice ceiling:
withinPct = fileLo + span * (1 - exp(-samplesDone / 25))
This gives steady forward motion on large libraries without lying that we know the final sample count.
Reference implementation (public)
We ship a working patch set (LGPL-compatible, tested on CWM 17.2.0 tip) in our public ConvertWithMoss fork:
Our fork uses prefix RUS_CWM_PROGRESS for host-side namespacing; for upstream we'd happily rename to CWM_PROGRESS and align env/flag naming with your preference.
The patch touches:
CLIBackend.java — add -P / --machine-progress, call MachineProgressReporter.setCliRequested()
- new
MachineProgressReporter.java — stderr emitter + sanitization
AbstractDetector.java — file/sample counting + pct helpers + hooks in detect loop and createSampleZone()
No GUI changes required; GUI can ignore the reporter entirely.
Why stderr?
CLI stdout already carries dots and completion text. Structured progress on stderr keeps parsers simple and matches common Unix tooling (2>&1 merge optional).
Offer
Happy to open a PR against main with:
- neutral
CWM_PROGRESS prefix
-P flag + optional env gate
- unit-free reporter class under
core
- short manual / CLI doc paragraph
We maintain a patched build for our users today; upstreaming would let us drop the fork-specific prefix and rely on official installers.
Thank you for ConvertWithMoss — it is the backbone of our Kontakt import path. Issue #139 (loop tune) was also very helpful on our side.
— Alex (cjslickmusic-max on GitHub)
Summary
When ConvertWithMoss runs in CLI mode on a large Kontakt library (one
.nkiwith hundreds of samples), the only live feedback is a stream of.dots on stdout (IDS_NOTIFY_PROGRESS). That is fine for humans, but automation hosts and DAW plugins that spawn CWM as a child process cannot derive a numeric percentage or current item from dots alone.We hit this integrating CWM into a proprietary DAW plugin (Kontakt import via SFZ). On a typical
.nkiimport the UI stayed at 0% for minutes, then jumped to 100% when conversion finished.We implemented a small, opt-in extension and would like to upstream it (or something equivalent) so all CLI users benefit.
Proposal
Add an opt-in machine-readable progress protocol on stderr, separate from the existing human-oriented stdout dots.
Activation (opt-in, zero cost when off)
-P/--machine-progressCWM_MACHINE_PROGRESS=1ortrue(for wrappers that cannot pass flags easily)When disabled, behaviour is unchanged.
Line format
One ASCII line per event, newline-terminated, stderr, flushed immediately:
pct: integer 0..100phase: sanitized token, e.g.start,convert,sample,donedetail: short ASCII-safe snippet (filename / path tail)Example session:
Hosts grep stderr for the prefix; humans can ignore unknown lines.
Where to emit (minimal hooks)
We found
AbstractDetectoris the right central place:detect(): count matching instrument files recursively (machineProgressTotal), emitphase=start.phase=convertat file start (non-zero pct inside the file's slice) and after file finish.createSampleZone()emitphase=sampleafter each WAV/NCW load.detect(): emitphase=doneat 100%.Percentage model
Between files: linear by completed file count (
done / total * 100).Inside one big file: interpolate within the current file's pct slice. Total sample count per
.nkiis unknown upfront, so we use a smooth asymptote toward the slice ceiling:withinPct = fileLo + span * (1 - exp(-samplesDone / 25))This gives steady forward motion on large libraries without lying that we know the final sample count.
Reference implementation (public)
We ship a working patch set (LGPL-compatible, tested on CWM 17.2.0 tip) in our public ConvertWithMoss fork:
Our fork uses prefix
RUS_CWM_PROGRESSfor host-side namespacing; for upstream we'd happily rename toCWM_PROGRESSand align env/flag naming with your preference.The patch touches:
CLIBackend.java— add-P/--machine-progress, callMachineProgressReporter.setCliRequested()MachineProgressReporter.java— stderr emitter + sanitizationAbstractDetector.java— file/sample counting + pct helpers + hooks in detect loop andcreateSampleZone()No GUI changes required; GUI can ignore the reporter entirely.
Why stderr?
CLI stdout already carries dots and completion text. Structured progress on stderr keeps parsers simple and matches common Unix tooling (
2>&1merge optional).Offer
Happy to open a PR against
mainwith:CWM_PROGRESSprefix-Pflag + optional env gatecoreWe maintain a patched build for our users today; upstreaming would let us drop the fork-specific prefix and rely on official installers.
Thank you for ConvertWithMoss — it is the backbone of our Kontakt import path. Issue #139 (loop tune) was also very helpful on our side.
— Alex (
cjslickmusic-maxon GitHub)