Skip to content

Matt Wood piano sampler — slice raw takes, generate SFZ + Kontakt .nki #1

Description

Context

Matt Wood (composer/musician, cmyk-music.com, Syracuse Architecture classmate of Grant's) recorded all 88 keys of a piano he used to own, one note at a time, but never sampled it into a playable instrument. He's done it manually before in Kontakt and it's too time-consuming. Goal: automate slice → label → SFZ → .nki pipeline so he gets a playable plugin without the hand-mapping tedium.

Intro happened in this channel on 2026-05-26.

Deliverable

Two Kontakt 6 instruments (separate .nki + sample folders), shipped together:

  • Piano_Sustain.nki — pedal-down long notes
  • Piano_Staccato.nki — short notes

Each backed by an SFZ so it also runs free in sfizz for non-Kontakt users.

V1 ships as two separate instruments (Matt's call). Keyswitch consolidation can come later.

Source material

Matt is sending a zip (Drive invite to [email protected]) of 6 continuous WAV files, each ~25 minutes, 24-bit / 48 kHz stereo. Each file is one pass, chromatic A0 → C8:

File Articulation Dynamic Round-robins
1 Long (pedal-down) Quiet RR1
2 Long (pedal-down) Quiet RR2
3 Long (pedal-down) Loud (single)
4 Short (staccato) Quiet RR1
5 Short (staccato) Quiet RR2
6 Short (staccato) Loud (single)

Total samples after slicing: ~528 (88 × 6), modulo retakes.

Recording notes from Matt

  • Gaps between notes are nearly silent. Some room noise from hot mic preamps and audible piano mechanics — wanted, do not remove.
  • Within any pass, a note may have been retaken 2× or 3× if the first attempt was bad. Rule: always keep the LAST take of a given pitch (also has the most tail).
  • No release tails captured separately.
  • Matt's aesthetic: transparent, close, wide. No processing of any kind — no EQ, no compression, no normalization, no denoise, no de-hum, no de-click in the body of the note.

Pipeline stages

0. Slice + label

  • Silence-split each of the 6 files (sox / pydub.silence.split_on_silence or equivalent).
  • Sample-accurate cuts on zero-crossings to avoid boundary clicks.
  • Light pitch detection (FFT peak on first ~200ms, or CREPE for safety) on each slice → identify fundamental → group by detected MIDI note → keep the last slice per note (handles retakes).
  • Output per file: 88 labeled WAVs named Piano_<Note>_<sus|stacc>_v<1|2>_rr<1|2>.wav (e.g. Piano_C4_sus_v1_rr1.wav).

1. Edge treatment (ONLY processing allowed)

  • Head: ~2-3 ms fade-in to kill boundary pops.
  • Tail: ~50-100 ms gentle fade-out, erring long so natural decay is preserved.
  • Both configurable; iterate with Matt after first pass.
  • Output stays 24-bit / 48 kHz stereo WAV. No resampling, no dither, no re-encode.

2. SFZ generation

Two SFZ files (piano_sustain.sfz, piano_staccato.sfz). Per-instrument structure:

<group> // quiet layer
lokey=A0 hikey=C8
lovel=0 hivel=110
amp_veltrack=100        // 0-40 naturally quietest via velocity curve
seq_length=2            // 2 RR alternate

<group> // loud layer
lovel=111 hivel=127
amp_veltrack=100
seq_length=1            // single RR, no alternation

Per-sample <region> entries with pitch_keycenter, lokey/hikey (interpolated for any holes), sample=..., seq_position=N for RRs.

Release envelope per group; tunable.

3. Kontakt import

Drag SFZ into Kontakt 6 → File → Import → SFZ. Save as .nki. Kontakt builds the instrument and we tweak envelopes / EQ-off / output routing in Kontakt's UI before saving the final .nki.

Licensing / ownership

  • Repo is private under BimRoss. Code MIT.
  • Samples remain Matt's IP.
  • If Matt ever wants to commercially distribute, packaging options range from a free zip (.nki + samples) to NI's Kontakt Player NKS program (expensive, application-based). Out of scope for v1.

Open questions / risks

  • Pedal-sustain bleed: if long-quiet notes ring into each other, silence-split may merge them. Fallback: longer silence threshold or pitch-change-based segmentation.
  • Retake count uncertainty: Matt doesn't know exactly how many notes were retaken. The "group by detected pitch, keep last" rule handles arbitrary counts.
  • Asymmetric RR on loud layers: single RR on loud. Acceptable for v1 per Matt ("ship honest first"). Could fake a second RR later with 5¢ detune + 1 ms offset if needed.

Timeline

First playable .nki to Matt within a week of receiving the audio. Faster if files are clean.

Status

  • Repo created
  • Audio zip received from Matt
  • Repo scaffolded with piano-sampler/ subdir + Python pipeline
  • Slice + label working on one file
  • All 6 files processed, 528 labeled samples
  • SFZ files generated
  • First .nki delivered to Matt for review
  • Iteration on fades / envelopes / RR feel
  • V1 ship

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions