From e1881084c46f3769e77d6213457bdb8b52dd327a Mon Sep 17 00:00:00 2001 From: Michael Mogenson Date: Fri, 27 Mar 2026 10:57:38 -0400 Subject: [PATCH] Update script for stand-alone ppak generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continue to reverse engineer the ppak format on a 128 mb EP-133 K.O. II with OS 2.0.5. The goal is to generate a stand-alone ppak file without relying on copying settings from a backup. EP-133 Format Findings Error Clock 43 — BPM Must Be Non-Zero The settings file (222 bytes) stores BPM as a float32 LE at bytes 4–7. A zero BPM causes "Error Clock 43" on load. Always write a valid BPM there, and also at bytes 12–15 of every pad file. Pads Silent After Loading Four separate root causes, discovered in order: 1. Per-pad volume (byte 16) defaults to 0 Pad file byte 16 is volume (0–100). An uninitialized bytearray(27) leaves it at 0 = silent. Fix: set data[16] = 100. 2. Group project volume defaults to 0 The settings file has four group volume floats at offsets 24, 72, 120, 168. An uninitialized settings buffer leaves them at 0.0 = silent. Fix: write float32(1.0) at those offsets. 3. Settings sentinel value is -1.0, not 0.0 All other float slots in the settings group blocks (48 bytes × 4 groups) must be filled with -1.0 (0x000080bf), which the device treats as "use default." Writing 0.0 is interpreted as zero and silences those parameters. 4. Sample ROM ID (bytes 8–9) — the critical one Bytes 8–9 of each pad file are a uint16 LE that the device uses to locate the sample's audio data in ROM. Without the correct value, the pad shows the right sample name in the UI but produces no sound. Zero is not a valid stand-in. These are not derivable from the sample number — they are firmware ROM addresses discovered empirically: ┌────────┬───────────────┬────────┐ │ Sample │ Name │ ROM ID │ ├────────┼───────────────┼────────┤ │ 1 │ MICRO KICK │ 22412 │ ├────────┼───────────────┼────────┤ │ 31 │ BOOMER KICK │ 30133 │ ├────────┼───────────────┼────────┤ │ 126 │ SNARE OPEN │ 18697 │ ├────────┼───────────────┼────────┤ │ 203 │ CLOSED HAT LO │ 7558 │ ├────────┼───────────────┼────────┤ │ 221 │ OPEN HAT REAL │ 14798 │ └────────┴───────────────┴────────┘ Discovery method: assign the sample on-device (or reassign away and back), take a project backup, extract bytes 8–9 from the pad file in the backup tar. ROM ID Structure Internal storage order is hats → snares → kicks — opposite of the user-facing 200s/100s/1s numbering. Within each category, higher sample number = higher ROM offset. The slope differs by category (~402 ROM units/sample for hats, ~257 for kicks), reflecting different average sample lengths. Labeled Pad Numbers ≠ File Numbers The numbers printed on the device do not match the p01–p12 file numbers in the tar. The bottom two rows are swapped: Row 3 (labeled 1-3) → files p07-p09 Row 1 (labeled 7-9) → files p01-p03 Rows 2, 4 (labeled 4-6, 10-12) → files p04-p06, p10-p12 (direct) Pattern events reference pad file numbers via row_byte = (file_num - 1) * 8. Using labeled numbers directly sends events to the wrong pads. Two Separate Volume Controls - Byte 16 of the pad file: per-pad volume (0–100). Fixed at write time; the sound-edit volume knob on the device does not update this. - Group project volume float in the settings file: what the volume knob actually controls (0.0–1.0). Both must be non-zero for sound to play. --- SKILL.md | 29 +- references/default-samples.csv | 309 ++ references/format-details.md | 235 +- references/user-manual.md | 4877 ++++++++++++++++++++++++++++++++ scripts/create_ppak.py | 111 +- scripts/fetch_manual.py | 70 + 6 files changed, 5488 insertions(+), 143 deletions(-) create mode 100644 references/default-samples.csv create mode 100644 references/user-manual.md create mode 100644 scripts/fetch_manual.py diff --git a/SKILL.md b/SKILL.md index daa85ed..e86ea83 100644 --- a/SKILL.md +++ b/SKILL.md @@ -143,13 +143,38 @@ for i in range(16): ## Device SKU -The meta.json requires matching `device_sku` and `base_sku`. Get from user's backup file or use common value `TE032AS001`. +The meta.json requires a `device_sku` and `base_sku` that may be different. Get from user's backup file or use common value `TE032AS001`. + +## User Manual + +Reference `references/user-manual.md` for questions from the user about how to perform an action on the EP-133. + +Run `scripts/fetch_manual.py` to update `references/user-manual.md` to the latest content from the Teenage Engineering website. + +## Sample Assignment + +See `references/default-samples.csv` for a list of the default sample names and numbers. Reference this list to choose which sample number to assign to a pad. + +**The samples are organized into the following categories:** +- Kick drums start at 1 +- Snare drums start at 100 +- Cymbals start at 200 +- Percussion sounds start at 300 +- Bass sounds start at 400 +- Melodic sounds start at 500 +- Loops start at 600 +- User 1 starts at 700 +- User 2 starts at 800 +- SFX star at 900 + +If the user asks to generate and load new samples, assign them to the appropriate category and do not overwrite an existing default sample. ## Troubleshooting | Error | Cause | Fix | |-------|-------|-----| -| "SKUS DOES NOT MATCH" | Wrong device_sku in meta.json | Use SKU from user's backup | +| "SKUS DOES NOT MATCH" | Wrong device_sku or base_sku in meta.json | Use SKU from user's backup | | "PAK FILE IS EMPTY" | Missing leading slashes in ZIP paths | Use `/projects/P01.tar` not `projects/P01.tar` | | Device crash | Invalid byte values in patterns | Use only documented encoding values | | No sound on playback | Wrong pattern file for group | Put Group B events in `patterns/b01`, not `patterns/a01` | +| Error Clock 43 | The BPM cannot be 0 | Set a BPM value in ppak | diff --git a/references/default-samples.csv b/references/default-samples.csv new file mode 100644 index 0000000..a340711 --- /dev/null +++ b/references/default-samples.csv @@ -0,0 +1,309 @@ +1;MICRO KICK +2;NT KICK +3;NT KICK B +4;NT KICK C +5;NT KICK D +6;LOCK KIK +7;KICK GRIT +8;KICK VERB +9;KICK MID +10;KICK BUMP +11;KICK 9X9 DIRT +12;KICK 9X9 DIRT B +13;KICK 9X9 DIRT C +14;KICK 9X9 DIRT D +15;KICK 9X9 DIRT E +16;KICK HARD +17;KICK AIR +18;KICK THUD +19;AFTERPARTY KICK +20;CARDIO KICK I +21;NT ALT KICK +22;NT ALT KICK B +23;NT ALT KICK C +24;KICK DIRT +25;KICK SUB +26;KICK SP +27;KICK FLUX +28;KICK FLUX B +29;KICK SUB B +30;KICK OPEN +31;BOOMER KICK +100;NT SNARE +101;NT SNARE B +102;NT SNARE C +103;SNARE LO +104;SNARE MID +105;SNARE HI +106;SNARE 6X6 l +107;SNARE 6X6 2 +108;SNARE 6X6 3 +109;SNARE CLASSIC +110;SNARE FAT +111;SNARE SMACK +112;SNARE BURST +113;BRUSHY SNARE I +114;NT SNARE ALT +115;NT SNARE ALT B +116;NT SNARE ALT C +117;SNARE RIM +118;SNARE PUNCH +119;SNARE POP +120;SNARE SNAP +121;SNARE VINYL +122;SNARE MP3K +123;SNARE MINI BM +124;SNARE VINYL B +125;SNARE RES +126;SNARE OPEN +127;SNARE WOOD +128;QUIK ROLL 3 +129;LONDON SNARE 2 +130;NT RIMSHOT +131;NT RIMSHOT B +132;NT RIMSHOT C +133;RIM LO +134;RIM MID +135;RIM HI +136;RIMSHOT DDDI +137;RIMSHOT VINYL +138;RIMSHOT 7X7 SP +139;RIMSHOT DMX +140;RIM DARK +141;RIM SMACK +142;RIM SNAP +143;SIDEQUEST SNARE +144;KNOW RIMSHOT I +145;AKKOUNTANT RIM 2 +200;NT HH CLOSED +201;NT HH CLOSED B +202;NT HH CLOSED C +203;CLOSED HAT LO +204;CLOSED HAT MID +205;CLOSED HAT HI +206;CLOSED HAT PEDAL +207;CLOSED HAT FOOT +208;HAT CLOSED 9X9 +209;HAT CLOSED 5X5 +210;HAT CLOSED 6X6 +211;HAT CLOSED 8X8 +212;CLOSED HAT LO B +213;CLOSED HAT HI B +214;CLOSED HAT AIR +215;GOLDEN HAT I +216;SHINE HAT 4 +217;CRUNCH HAT 2 +218;NT HH OPEN +219;NT HH OPEN B +220;NT HH OPEN C +221;OPEN HAT REAL +222;OPEN HAT DRIVE +223;OPEN HAT METAL +224;HAT OPEN 9X9 +225;HAT OPEN 5X5 +226;HAT OPEN 6X6 +227;HAT OPEN 8X8 +228;OPEN HAT LO +229;OPEN HAT HI +230;OPEN HAT AIR +231;GOLDEN HAT I B +232;BRUSH HAT 4 +233;LUCKY DBL HAT 2 +234;GIRTH OPEN HAT 3 +235;NT RIDE +236;NT RIDE B +237;RIDE DARK +238;RIDE BRITE +239;RIDE SAKATA +240;CYMBAL MPI +241;RIDE 7X7 +242;RIDE DARK B +243;RIDE LITE +244;RIDE BELL +245;RIDE HI +246;TOASTER BELL +247;NT RIDE C +248;CRASH +249;CRASH 9X9 +250;CHINA 626 +251;SPLASH +252;CRASH CYM +253;80 GREAT CRASH +300;NT CLAP +301;NT CLAP B +302;NT CLAP C +303;CLAP REAL +304;CLAP HARD +305;CLAP SNAP +306;CLAP VINYL +307;CLAP TRUMULATOR +308;CLAP SP DISCO +309;CLAP SP DISCO B +310;CLAP DARK +311;CLAP LITE +312;CLAP AIR +313;CLAP NOISE +314;GOSPEL CLAP 3 +315;HOMECOMING CLAP +316;DETROIT CLAP 2 +317;NT TAMBO +318;NT TAMBO B +319;NT TAMBO C +320;HAND DRUM LO +321;AGOGO +322;BONGO MID 4 +323;HAND DRUM HI +324;CONGA MID II +325;TAMB +326;MARACA +327;BONGO HI +328;GUIRO +329;BONGO LO +330;CLAVE +331;CONGA LO +332;CONGA HI +333;CABASE LMI +334;CABASA MP3K +335;CABASA LNNDRUM +336;SHAKER DMX +337;TAMB B +338;CLAVE B +339;COWBELL +340;SHAKER +341;HERMES HIHAT 2 +342;LOWW CLAVE I +343;NT PERC +344;NT PERC B +345;NT PERC C +346;TOM FAT +347;TOM SKIN +348;TOM ROUND LO +349;TOM ROUND HI +350;TOM SP +351;TOM LNNDRUM +352;TOM LO FLAM +353;TOM MID +354;TOM HI +355;SWEET SHAKE I +356;FUNCTION TOM 3 +357;HUNDOBELL PERC 2 +400;NT BASS +401;S95X ROUND +402;TUBRO BASS +403;E BASS ROUND +404;BASIC +405;MP3K SUB +406;SYN A RE +407;UPRIGHT SUB +408;E BASS PICK +409;THMP +410;CAT ENVELOPE +411;TB3X3 PUNCH +412;UGGBASS +413;E BASS PICK B +414;PERFECT BASS +415;PRODIGY SUB +416;S95X SUB +417;BASS THUB +418;ROCKELBASS MID +419;E BASS DIST +420;OB SUB +421;CX TONE +422;BUZZ BASS +423;ROCKELBASS SHORT +424;MNO EVO FILTER +425;SYNTH 4TH HIT +426;THIRTY SEVEN SUB +427;ORGA +428;MUD +429;REESE +430;P.SIX SIMPLE +431;S612 ELECTRIC +432;AKUBASS MIDLONG +433;MUD B +434;WET BASS +435;CS5 SQUARE +436;S612 WARM +437;ELEC BASS +438;BOING +439;ORGAN DX HOUSE +440;REVY +441;SDSV TOM +442;DR SMPL WARM +443;GROWLY +444;ORGANISH +445;TWO SIX OO SMOOT +446;PRODIGY PUNCH +447;FLATE +448;KAA WA BELL AIR +449;SO ROUND +450;DE-EX SOLID +451;CHICAGO +452;SUBD +453;PHONEC GRR +454;OVERDRIVE +455;PRODIGY SQUARE +456;TOCK +457;LOBB WOBB +458;PUFF +459;RUDE TWANG +500;BLUE +501;PIANO S95X +502;WURLI CLEAN +503;MUTE STRATO +504;CUTE EMU FLUTE +505;ULTRA +506;SQUICK +507;CLAV 360 PHASER +508;BABY CHORD +509;BG VOCAL +510;SKYLINE STRING +511;OCTAVE STAB +512;TRUMPET BREEZY +513;SCARY VIBES +514;SLY SYNTH CHORD +515;EPIANO 360 +516;ORGAN DX VERB +517;PLUCK HI BASS +518;PLUCK HYBRID +519;PROPHET PIANO +520;EPIANO 360 BASS +521;HOUSEORGAN DE-EX +522;SOOTHE STRING +523;CELLO PLUCKZ +524;HIGH PAN +525;SYNTH MICRO FUNK +526;DR ORGAN CHORD +527;LEADAFT +528;SOOTHE STRONG +529;SIMPLE TROMBONE +530;CELLO 360 +531;FLUTE 360 FILTER +532;ORGAN DX200 STAB +533;WATERCHORD AM7 +534;SAD GUITAR +535;HORN 360 ENGLISH +536;STRINGS 360 +537;HOUSE CHORD EM7 +538;UPRIGHT CHORD +539;EXOTIC PLUCK +540;SKY LEAD +541;STRINGS DR +542;LIQUID CHORD EM7 +543;CHORDY F9SUS4 +544;BROKEN BELL PERC +545;PLING CHORD +546;S612 VERB HIT +547;DR +548;VOX S612 DARK +549;SITAR ONE SHOT +550;LOOK ORGAN +551;THIRTY 7 STAB +552;BUZZ DELAY +553;VOX S612 EH +554;GUZHENG +555;NT CHORDY +556;FX BIRDS TAPE +557;VOX S612 GATED +558;O3D +559;SEARCH CHORD \ No newline at end of file diff --git a/references/format-details.md b/references/format-details.md index c19aae2..69d72a6 100644 --- a/references/format-details.md +++ b/references/format-details.md @@ -51,29 +51,31 @@ Byte 3: 0x00 (constant) Offset Size Type Description ------ ---- -------- ----------- 0 2 uint16LE Time position (0-383 ticks per bar) -2 1 uint8 Row byte (pad identifier) +2 1 uint8 Row byte (pad file number identifier) 3 1 uint8 Column byte (0x3c = 60 for normal playback) 4 1 uint8 Velocity (0-127) 5 3 bytes Flags (typically 0x10 0x00 0x00) ``` -### Row Byte to Pad Mapping +### Row Byte to Pad File Mapping ``` -Pad 1 = 0x00 (0) -Pad 2 = 0x08 (8) -Pad 3 = 0x10 (16) -Pad 4 = 0x18 (24) -Pad 5 = 0x20 (32) -Pad 6 = 0x28 (40) -Pad 7 = 0x30 (48) -Pad 8 = 0x38 (56) -Pad 9 = 0x40 (64) -Pad 10 = 0x48 (72) -Pad 11 = 0x50 (80) -Pad 12 = 0x58 (88) +Pad file 1 = 0x00 (0) +Pad file 2 = 0x08 (8) +Pad file 3 = 0x10 (16) +Pad file 4 = 0x18 (24) +Pad file 5 = 0x20 (32) +Pad file 6 = 0x28 (40) +Pad file 7 = 0x30 (48) +Pad file 8 = 0x38 (56) +Pad file 9 = 0x40 (64) +Pad file 10 = 0x48 (72) +Pad file 11 = 0x50 (80) +Pad file 12 = 0x58 (88) ``` -Formula: `row_byte = (pad_number - 1) * 8` +Formula: `row_byte = (pad_file_number - 1) * 8` + +**Note**: Pattern events use pad *file* numbers, not labeled pad numbers. See Pad Layout section. ### Column Byte @@ -81,33 +83,117 @@ For standard drum playback, always use `0x3c` (60). Other values may represent chromatic pitch offsets but can cause issues. Stick to 0x3c unless experimenting. +## Pad Layout — Labeled vs File Numbers + +The pad numbers printed on the device (labeled) do **not** match the pad file numbers (p01–p12) used in the tar archive. The bottom two rows of the 4×3 grid are swapped. + +Physical grid (4 rows × 3 columns): +``` +Row 1 (top): file p01 p02 p03 ←→ labeled 7 8 9 +Row 2: file p04 p05 p06 ←→ labeled 4 5 6 +Row 3: file p07 p08 p09 ←→ labeled 1 2 3 +Row 4 (bottom): file p10 p11 p12 ←→ labeled 10 11 12 +``` + +Full mapping: + +| Labeled | File | Labeled | File | +|---------|------|---------|------| +| 1 | p07 | 7 | p01 | +| 2 | p08 | 8 | p02 | +| 3 | p09 | 9 | p03 | +| 4 | p04 | 10 | p10 | +| 5 | p05 | 11 | p11 | +| 6 | p06 | 12 | p12 | + +Formula for labeled pads 1–9: `file = labeled + 6` if labeled ≤ 3, else `labeled - 6` if labeled ≥ 7, else `labeled`. +Labeled pads 10–12 map directly to files p10–p12. + +`create_ppak.py` exports `LABEL_TO_PAD_FILE` and `PAD_FILE_TO_LABEL` dicts for this conversion. + ## Pad File Binary Format (27 bytes) ``` Offset Size Description ------ ---- ----------- -0 1 Unknown (preserve from template) +0 1 Unknown (observed as 0x00) 1 2 Sample number (uint16LE, 0 = no sample) -3 24 Pad parameters (preserve from template) +3 5 Unknown (observed as 0x00) +8 2 Sample ROM ID (uint16LE) — see below +10 2 Unknown (observed as 0x00) +12 4 Project BPM (float32LE) — device writes this on sample assignment +16 1 Volume (0–100; default 100 = full volume) +17 3 Unknown (observed as 0x00) +20 1 Unknown (0xff in all observed pads) +21 3 Unknown (observed as 0x00) +24 1 Pan (0–127; default 60 = center) +25 2 Unknown (observed as 0x00) ``` -### Assigning a Sample -```python -import struct +### Sample ROM ID (bytes 8–9) -with open(pad_file, 'rb') as f: - data = bytearray(f.read()) +A uint16 little-endian value the device uses to locate the sample's audio data in ROM. +**A pad with a valid sample number but a zero ROM ID will show the correct sample name but produce no sound.** -# Set sample number at bytes 1-2 -data[1:3] = struct.pack(' out + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e4e_opt.svg) + +use (minus) and (plus) to navigate to ‘OUT’, then hit (enter). + +((6)) navigate to sync > out > 8 + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e4c_opt.svg) + +use (minus) and (plus) to navigate to ‘8’, then hit (enter). + +((7)) sync 8 + +![](https://assets.teenage.engineering/_img/655e04470ef9e99c4401a3b7_opt.svg) + +K.O.II will now send a 1/8 clock pulse on it’s sync-out jack, meaning that it can sync with any device that receives 1/8 clock. + +((8)) press play + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e4a_opt.svg) + +press play on your pocket operator then (play) on your K.O.II and the two will sync to the same BPM! + +12.6 + +sync K.O.II to a pocket operator + +return to index + +((1)) connect your pocket operator to K.O.II + +![](https://assets.teenage.engineering/_img/6558b0f93b3fb091108d3fba_opt.svg) + +for this setup you will need a 3.5 mm stereo (trs) to 2 x 3.5 mm mono (ts) cable. + +connect the stereo end to the output of the pocket operator then plug the right channel (ring - red on our cables) into the input jack on your K.O.II and the left channel (tip - brown or white on our cables) into the sync input jack on your K.O.II. + +((2)) set your pocket operator to sync 1 + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e3e_opt.svg) + +press the function button under the rightmost knob and the bpm button until the screen shows SY1. + +this will send a sync pulse on the left channel (tip) of the output jack. + +((3)) enter system settings + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e40_opt.svg) + +enter system settings by pressing (shift) and (erase). + +((4)) navigate to sync + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e48_opt.svg) + +use (minus) and (plus) to navigate to the sync settings, then press (enter) on the pads. + +((5)) navigate to sync > in + +![](https://assets.teenage.engineering/_img/6558ad273b3fb091108d3ebd_opt.svg) + +use (minus) and (plus) to navigate to ‘in’, then hit (enter). + +((6)) navigate to sync > in > 8 + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e4c_opt.svg) + +use (minus) and (plus) to navigate to ‘8’, then hit (enter). + +((7)) sync 8 + +![](https://assets.teenage.engineering/_img/655e04470ef9e99c4401a3b9_opt.svg) + +K.O.II will now listen for a 1/8 clock pulse on it’s sync-in jack, meaning that it can sync with any device that sends 1/8 clock. + +((8)) press play + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e4a_opt.svg) + +press play on your pocket operator then (play) on your K.O.II and the two will sync to the same BPM! + +pro-tip! with this setup you can add the K.O.II’s internal effects to the audio coming from the pocket operator! + +12.7 + +connect your K.O.II to the drum machine + +return to index + +((1)) connect your K.O.II to the drum machine + +![](https://assets.teenage.engineering/_img/6558b13d3b3fb091108d3fca_opt.svg) + +first plug one end of a 3.5 mm cable into the sync out on your vintage drum machine, then the other end into the sync input on your K.O.II. + +some vintage drum machines use a standard called DIN-sync that requires an adaptor or special cable. + +((2)) enter system settings + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e40_opt.svg) + +enter system settings by pressing (shift) and (erase). + +((3)) navigate to sync + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e48_opt.svg) + +use (minus) and (plus) to navigate to the sync settings, then press (enter) on the pads. + +((4)) navigate to sync > in + +![](https://assets.teenage.engineering/_img/6558ad273b3fb091108d3ebd_opt.svg) + +use (minus) and (plus) to navigate to ‘in’, then hit (enter). + +((5)) navigate to sync > in > 24 + +![](https://assets.teenage.engineering/_img/6558ae263b3fb091108d3ee7_opt.svg) + +use (minus) and (plus) to navigate to ‘24’, then hit (enter) + +((6)) sync 24 + +![](https://assets.teenage.engineering/_img/655e04380ef9e99c4401a263_opt.svg) + +K.O.II will now listen for a sync24 clock pulse on it’s sync-in jack, meaning that it can sync with any device that sends sync24 clock. + +((7)) press play! + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e4a_opt.svg) + +press play on your drum machine and K.O.II (play) at the same time and sync to the same BPM! + +((8)) sync out to the drum machine + +![](https://assets.teenage.engineering/_img/6558ab2f3b3fb091108d3e62_opt.svg) + +follow the same steps as before but instead connect the K.O.II’s sync out to the sync-in of your drum machine then navigate to sync > out > 24. + +12.8 + +control K.O.II with a midi keyboard + +return to index + +((1)) get started! + +![](https://assets.teenage.engineering/_img/655e045a0ef9e99c4401a557_opt.svg) + +for this setup, depending on your midi keyboard you may need a 3.5 mm stereo (trs) to midi din cable. some midi keyboards have trs midi and thus a 3.5 mm trs cable can be used between the keyboard and the K.O.II. + +for usb midi keyboards you will need a midi host (this is typically a computer connected over usb-c or a dedicated midi host box) between the K.O. II and the MIDI keyboard. + +((2)) connect your midi keyboard + +![](https://assets.teenage.engineering/_img/6558aefa3b3fb091108d3f12_opt.svg) + +once you have your midi keyboard connected, K.O.II will detect any notes and light up the MIDI or usb icon (depending on what input is used) on the screen. + +((3)) play the pads with the keyboard! + +![](https://assets.teenage.engineering/_img/655e04eb0ef9e99c4401b356_opt.svg) + +now, any notes you play on the keyboard will trigger the pads on K.O.II! + +((4)) play one pad across the keyboard! + +![](https://assets.teenage.engineering/_img/6558aefa3b3fb091108d3f14_opt.svg) + +if you want to play one pad transposed across the keyboard then just press (keys)! + +12.9 + +sequence external midi with K.O.II + +return to index + +((1)) get started! + +![](https://assets.teenage.engineering/_img/655e045a0ef9e99c4401a557_opt.svg) + +for this setup, depending on your midi device you may need a 3.5 mm stereo (trs) to midi din cable. + +some midi devices have trs midi and thus a 3.5 mm trs cable can be used. alternatively for usb midi devices a usb-c cable can be used. + +((2)) connect your midi device + +![](https://assets.teenage.engineering/_img/6558b0783b3fb091108d3f77_opt.svg) + +once you have your midi device connected, K.O.II will be able to send midi notes to it. + +((3)) set a pad as a midi channel + +![](https://assets.teenage.engineering/_img/6558b0773b3fb091108d3f57_opt.svg) + +press (shift) and (sound) to enter sound edit mode. + +((4)) set a pad as a midi channel + +![](https://assets.teenage.engineering/_img/6558b0773b3fb091108d3f59_opt.svg) + +select a pad, then navigate to the pad’s midi settings using (minus) and (plus). + +pro-tip! setting the value of a pad when holding (sound) to “000” will create an empty pad that can hold midi without stealing any voices. + +((5)) change midi channel + +![](https://assets.teenage.engineering/_img/6558b0773b3fb091108d3f5b_opt.svg) + +use the (knobx) knob to change the midi channel that the pad will send to. + +((6)) change midi root note + +![](https://assets.teenage.engineering/_img/6558b0773b3fb091108d3f5d_opt.svg) + +use the (knoby) knob to change the root note of the midi notes, this allows you to sync your midi to the root note of your sample. + +((7)) done! + +![](https://assets.teenage.engineering/_img/655e04eb0ef9e99c4401b356_opt.svg) + +now, any notes you play or sequence on that pad will send midi to the chosen channel! + +((8)) bonus: send or receive midi clock + +![](https://assets.teenage.engineering/_img/6558b0773b3fb091108d3f5f_opt.svg) + +to send or receive clock to or from the connected devices go to system settings by pressing (shift) and (erase) then navigate to MIDI > Clock and choose from off, on or out. + +12.10 + +resample a chord + +return to index + +((1)) select a sound to sample + +![](https://assets.teenage.engineering/_img/67e2721cc78bea47501baf04_opt.svg) + +press (sound) then press a pad and select a sound from the sound library. + +((2)) enable KEYS mode + +![](https://assets.teenage.engineering/_img/67e2721c2194e647024835cf_opt.svg) + +press (main) to return to the main screen. select the pad and then press (keys) to activate keys mode. + +((3)) press SAMPLE + +![](https://assets.teenage.engineering/_img/67e2721c579f7347525184c7_opt.svg) + +press (sample) to enter the sampler. + +((4)) select resampling + +![](https://assets.teenage.engineering/_img/67e2721c6f11e447026947de_opt.svg) + +press (plus) to select resampling as the sound source for sampling. + +((5)) select a group + +![](https://assets.teenage.engineering/_img/67e2721c380c85474f758200_opt.svg) + +press a group pad to choose which group to sample to. + +((6)) start hands free sampling + +![](https://assets.teenage.engineering/_img/67e2721cff5a93474f632aa4_opt.svg) + +press (shift) and a pad to start hands free sampling on that pad. + +((7)) reopen the group with the sample + +![](https://assets.teenage.engineering/_img/67e2721c58bd4a4751e9b869_opt.svg) + +go back to the group with the sample you wish to resample. + +((8)) play the chord + +![](https://assets.teenage.engineering/_img/67e2721c5477ff4702aced1b_opt.svg) + +play the chord you wish to record on the pads. + +((9)) stop recording + +![](https://assets.teenage.engineering/_img/67e2721cecb3f84702697d3e_opt.svg) + +press (sample) to stop the recording. + +((10)) done! + +![](https://assets.teenage.engineering/_img/67e2721bf27fc947026a426b_opt.svg) + +you will now have a chord that has been resampled to another group’s pad! + +![](https://assets.teenage.engineering/_img/655a6b040bfd382a42dda03f_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda050_opt.svg) + +--- + +# system + +((14)) + +system + +return to index + +SYSTEM lets you configure stuff like pad-velocity or how your midi and sync ports behave. for quick access, you can learn the numbers, like typing 301 and ENTER to turn velocity on. now you’re in expert mode! + +SYSTEM SETTINGS + +![](https://assets.teenage.engineering/_img/6558b9803b3fb091108d408b_opt.svg) + +to customize the behavior of your K.O.II press (SHIFT) and (ERASE) to access system settings. + +navigate + +![](https://assets.teenage.engineering/_img/6558b9803b3fb091108d408d_opt.svg) + +press (minus) or (plus) to navigate through the settings, and then ENTER to select. + +enter + +![](https://assets.teenage.engineering/_img/6558b9803b3fb091108d408f_opt.svg) + +to navigate back to the previous page you can press (SHIFT) and ENTER. + +alternatively you can also use the following codes to directly access the setting once in system settings. + +code + +path + +setting + +100 + +mid + +clk + +off + +MIDI Clock Off (default) + +101 + +mid + +clk + +in + +MIDI Clock in (receive only) + +102 + +mid + +clk + +out + +MIDI Clock Out (send only) + +110 + +mid + +chn + +all + +Receive all channels, send on MIDI channel 1. + +111 + +mid + +chn + +ch.1 + +Receive and send on MIDI Channel 1 + +112 + +mid + +chn + +ch.2 + +Receive and send on MIDI Channel 2 + +113 + +mid + +chn + +ch.3 + +Receive and send on MIDI Channel 3 + +114 + +mid + +chn + +ch.4 + +Receive and send on MIDI Channel 4 + +115 + +mid + +chn + +ch.5 + +Receive and send on MIDI Channel 5 + +116 + +mid + +chn + +ch.6 + +Receive and send on MIDI Channel 6 + +117 + +mid + +chn + +ch.7 + +Receive and send on MIDI Channel 7 + +118 + +mid + +chn + +ch.8 + +Receive and send on MIDI Channel 8 + +119 + +mid + +chn + +ch.9 + +Receive and send on MIDI Channel 9 + +120 + +mid + +chn + +ch10 + +Receive and send on MIDI Channel 10 + +121 + +mid + +chn + +ch.11 + +Receive and send on MIDI Channel 11 + +122 + +mid + +chn + +ch.12 + +Receive and send on MIDI Channel 12 + +123 + +mid + +chn + +ch.13 + +Receive and send on MIDI Channel 13 + +124 + +mid + +chn + +ch.14 + +Receive and send on MIDI Channel 14 + +125 + +mid + +chn + +ch.15 + +Receive and send on MIDI Channel 15 + +126 + +mid + +chn + +ch.16 + +Receive and send on MIDI Channel 16 + +127 + +mid + +chn + +off + +only send midi if midi channel assigned in sound edit + +130 + +mid + +thr + +off + +disable MIDI thru + +131 + +mid + +thr + +on + +enable midi thru (Forwards MIDI signals, in→ out) + +140 + +mid + +rst + +off + +do not reset midi controllers at stop (default) + +141 + +mid + +rst + +on + +reset midi controllers at stop + +200 + +syn + +in + +8 + +Sync In Rate 1/8th Note + +201 + +syn + +in + +16 + +Sync In Rate 1/16th Note (default) + +202 + +syn + +in + +24 + +SYNC IN RATE 24 PULSES PER QUARTER NOTE + +210 + +syn + +out + +8 + +SYNC OUT RATE 1/8TH NOTE + +211 + +syn + +out + +16 + +Sync Out Rate 1/16th Note (default) + +212 + +syn + +out + +24 + +Sync Out Rate 24 Pulses per Quarter Note + +300 + +pad + +vel + +off + +PAD VELOCITY OFF (DEFAULT) + +301 + +pad + +vel + +hi + +PAD VELOCITY HIGH. PLAY WITH A SOFT TOUCH + +302 + +pad + +vel + +lo + +PAD VELOCITY LOW. FOR VIGOROUS PLAY STYLES + +310 + +pad + +sca + +12t + +12 TONE EQUAL TEMPERAMENT (DEFAULT) + +311 + +pad + +sca + +maj + +MAJOR (IONIAN MODE) + +312 + +pad + +sca + +min + +MINOR (AEOLIAN MODE) + +313 + +pad + +sca + +dor + +DORIAN MODE + +314 + +pad + +sca + +phr + +PHR PHRYGIAN MODE + +315 + +pad + +sca + +lyd + +LYD LYDIAN MODE + +316 + +pad + +sca + +mix + +MIX MIXOLYDIAN MODE + +317 + +pad + +sca + +loc + +LOCRIAN MODE + +318 + +pad + +sca + +ma.p + +MAJOR PENTATONIC + +319 + +pad + +sca + +mi.p + +MINOR PENTATONIC + +320 + +pad + +key + +c + +SCALE KEY C (DEFAULT) + +321 + +pad + +key + +c# + +SCALE KEY c# + +322 + +pad + +key + +d + +SCALE KEY D + +323 + +pad + +key + +d# + +SCALE KEY d# + +324 + +pad + +key + +e + +SCALE KEY e + +325 + +pad + +key + +f + +SCALE KEY f + +326 + +pad + +key + +f# + +SCALE KEY f# + +327 + +pad + +key + +g + +SCALE KEY g + +328 + +pad + +key + +g# + +SCALE KEY g# + +329 + +pad + +key + +a + +SCALE KEY a + +330 + +pad + +key + +A# + +SCALE KEY a# + +331 + +pad + +key + +b + +SCALE KEY b + +340 + +pad + +aud + +on + +enable sample auditioning when tweaking values + +341 + +pad + +aud + +off + +disable sample auditioning when tweaking values + +400 + +seq + +met + +on + +Enable metronome at record+play + +401 + +seq + +met + +rec + +Enable metronome at record only (default) + +402 + +seq + +met + +cnt + +enable metronome at count-in only + +410 + +seq + +scn + +tic + +Change scene immediately (default) + +411 + +seq + +scn + +bar + +Sync scene changes with bar end + +412 + +seq + +scn + +ptn + +Sync scene changes with pattern end + +14.1 + +midi implementation chart + +return to index + +function + +transmitted + +recognised + +notes + +basic channel + +mode + +mode + +velocity + +aftertouch + +pitch bend + +controlchange + +program change + +system exclusive + +systemcommon + +systemrealtime + +aux messages + +default + +changed + +default + +messages + +altered + +true voice + +note on + +note off + +keys + +channels + +CC#0,32 + +CC#1 + +song position + +song select + +tune request + +clock + +commands + +all sound off + +reset all controllers + +local on/off + +all notes off + +active sensing + +system reset + +1 + +1–16 + +mode 1 + +x + +- + +36-47 (group a) + +48-59 (group b) + +60-71 (group c) + +72-83 (group d) + +keys mode: 0-127 + +- + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + +x + +x + +x + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + + (0-127) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + +x + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + +x + +x + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + +1 + +1–16 + +mode 1 + +x + +- + +36-47 (group a) + +48-59 (group b) + +60-71 (group c) + +72-83 (group d) + +keys mode: 0-127 + +- + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + +x + +x + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + + (0-127) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + +x + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +![](https://assets.teenage.engineering/_img/655925ce3b3fb091108d4850_opt.svg) + +x + +x + +x + +x + +x + +x + +memorized + +bank select + +mod wheel + +use bank select to reach all sounds 1-999 + +identity request+reply, proprietary messages + +Mode 1: OMNI ON, POLYMode 2: OMNI ON, MONOMode 3: OMNI OFF, POLYMode 4: OMNI OFF, MONO + +14.2 + +midi note map + +return to index + +when using an external midi device such as a keyboard or drum pad, you can use the table below as a midi note reference for triggering specific pads on each group. if you are in keys mode, this will change to a chromatic keyboard. + +make sure that you are addressing the correct midi channel, this can be set in sound edit’s midi page as well as the system settings. + +MIDI note number + +note name + +group + +pad + +36 + +c2 + +a + +. + +37 + +c#2 + +a + +0 + +38 + +d2 + +a + +enter + +39 + +d#2 + +a + +1 + +40 + +e2 + +a + +2 + +41 + +f2 + +a + +3 + +42 + +f#2 + +a + +4 + +43 + +g2 + +a + +5 + +44 + +g#2 + +a + +6 + +45 + +a2 + +a + +7 + +46 + +a#2 + +a + +8 + +47 + +b2 + +a + +9 + +48 + +c3 + +b + +. + +49 + +c#3 + +b + +0 + +50 + +d3 + +b + +enter + +51 + +d#3 + +b + +1 + +52 + +e3 + +b + +2 + +53 + +f3 + +b + +3 + +54 + +f#3 + +b + +4 + +55 + +g3 + +b + +5 + +56 + +g#3 + +b + +6 + +57 + +a3 + +b + +7 + +58 + +a#3 + +b + +8 + +59 + +b3 + +b + +9 + +60 + +c4 + +c + +. + +61 + +c#4 + +c + +0 + +62 + +d4 + +c + +enter + +63 + +d#4 + +c + +1 + +64 + +e4 + +c + +2 + +65 + +f4 + +c + +3 + +66 + +f#4 + +c + +4 + +67 + +g4 + +c + +5 + +68 + +g#4 + +c + +6 + +69 + +a4 + +c + +7 + +70 + +a#4 + +c + +8 + +71 + +b4 + +c + +9 + +72 + +c5 + +d + +. + +73 + +c#5 + +d + +0 + +74 + +d5 + +d + +enter + +75 + +d#5 + +d + +1 + +76 + +e5 + +d + +2 + +77 + +f5 + +d + +3 + +78 + +f#5 + +d + +4 + +79 + +g5 + +d + +5 + +80 + +g#5 + +d + +6 + +81 + +a5 + +d + +7 + +82 + +a#5 + +d + +8 + +83 + +b5 + +d + +9 + +14.3 + +lock mode + +return to index + +lock mode + +![](https://assets.teenage.engineering/_img/6565e430dbc59af3332d528d_opt.svg) + +to prevent any changes to projects, patterns, scenes, pads and settings you can use lock mode. + +hold (main) on start up to lock the device. + +lock mode + +![](https://assets.teenage.engineering/_img/6565e430dbc59af3332d5292_opt.svg) + +lok will display on the screen for about 1 second. + +any changes made on the device will reset when the device is restarted. + +14.4 + +error codes + +return to index + +error code + +meaning + +solution + +E.01 + +sram error + +your unit needs to be repaired + +E.02 + +flash error + +your unit needs to be repaired + +E.03 + +codec error + +your unit needs to be repaired + +E.10 + +LFS INVALID + +file-system error, flash needs to be formatted + +E.11 + +LFS CORRUPT + +file-system error, flash needs to be formatted + +E.12 + +OTHER LFS ERROR + +file-system error, flash needs to be formatted + +E.05 + +sample\_fs error + +file-system error, flash needs to be formatted + +if your segment display shows a file-system error code it means the file-system needs to be formatted. +to do this, power the device off, then hold (shift) + (erase) and turn it on. + +this will format the drive erasing all sounds and help your device to boot up again by removing any files that were causing issues.  +make sure to update the OS to our latest release as we are constantly fixing bugs that may cause such issues. + +![](https://assets.teenage.engineering/_img/655a6b040bfd382a42dda03f_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda050_opt.svg) + +--- + +# erase-drive + +((15)) + +erase drive + +return to index + +![](https://assets.teenage.engineering/_img/6559274d3b3fb091108d48a8_opt.svg) + +warning! this will remove all your work as well as all factory sounds. once removed factory sounds can not be recovered! + +erase drive + +![](https://assets.teenage.engineering/_img/655928363b3fb091108d48f2_opt.svg) + +if you want to start fresh and remove all samples and patterns from your device + +hold (SHIFT) + (ERASE) on start up to format the device. + +erase drive + +![](https://assets.teenage.engineering/_img/655928353b3fb091108d48ed_opt.svg) + +FMT will display on the screen for about 10 seconds + +then it will start up as usual with all content removed. + +![](https://assets.teenage.engineering/_img/655a6b040bfd382a42dda03f_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda050_opt.svg) + +--- + +# tech-specs + +((16)) + +technical specifications + +return to index + +Stereo Line input24 bitSNR: 96 dBAimpedance: 6.5 kOhmanalog gain: 0 - 12 dBmax level: 8 dBu, 2.0 Vrms +Stereo Headphone/Line Output:24 bitSNR: 98 dBAmax level: 5 dBu, 1.4 Vrms +MIDI inputMMA compliant pinout (type A)opto-coupled +MIDI outputMMA compliant pinout (type A)voltage: 3.3 V + +Sync outputTIP: Sync 8th, 16th, 24 ppqnRING: Start/Stopvoltage: 3.3 V +Sync inputTIP: Sync 8th, 16th, 24 ppqnRING: Start/Stopvoltage: 3.3 Vmax level: 10 V +internal clock/sequencer resolution/step resolution96 ticks (ppqn) + +![](https://assets.teenage.engineering/_img/655a6b040bfd382a42dda03f_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda050_opt.svg) + +--- + +# credits + +((17)) + +credits + +return to index + +![](https://assets.teenage.engineering/_img/655a79990bfd382a42dda793_opt.svg) + +beta tester +256kalvaro villalobosbweebcuckooDEFENSE MECHANISMdimi3djcuvcuvdom adverbEmerging Patternsflahjavslkngrrrlanematt donaldmatthew williamsmichael hellqvistnick hooknoiserocksamplik prostsean hellfritschtt beatsWeSyellow eyes + +content +teddy stuartjerker eklundvalter kinbomisak hedtjarntenganben mintobil bryantnosaj thingthe kountbyron the aquariusakebono unlimitedmanmade mastering + +![](https://assets.teenage.engineering/_img/655a6b040bfd382a42dda03f_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda050_opt.svg) + +--- + +# warnings-warranty-fcc + +18. + +warnings and warranty + +return to index + +warnings. warranty and fcc. + +teenage engineering ep-133model no: TE032AS001 +fcc regulatory compliance +this device complies with part 15 of the fcc rules. operation is subject to the following two conditions: +(1) this device may not cause harmful interference, and (2) this device must accept any interference received, including interference that may cause undesired operation. +warning: changes or modifications not expressly approved by the party responsible for compliance could void the user's authority to operate the equipment. + +note: this equipment has been tested and found to comply with the limits for a class b digital device, pursuant to part 15 of the fcc rules. these limits are designed to provide reasonable protection against harmful interference in a residential installation. this equipment generates, uses and can radiate radio frequency energy and, if not installed and used in accordance with the instructions, may cause harmful interference to radio communications. however, there is no guarantee that interference will not occur in a particular installation. if this equipment does cause harmful interference to radio or television reception, which can be determined by turning the equipment off and on, the user is encouraged to try to correct the interference by one or more of the following measures: + +* reorient or relocate the receiving antenna. +* increase the separation between the equipment and receiver. +* connect the equipment into an outlet on a circuit different from that to which the receiver is connected. +* consult the dealer or an experienced radio/TV technician for help. + +ices statement +ices-3 (B) / nmb-3 (b) + +warranty and return policy +warranty, returns policy and terms and conditions can be found here + +recycling +electrical and electronic equipment, parts and batteries marked with this crossed-out wheelie bin symbol must not be disposed of with normal household wastage, it must be collected and disposed of separately to protect the environment. + +![](https://assets.teenage.engineering/_img/655a6b040bfd382a42dda03f_opt.svg) + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) + +--- + +# whats-new + +what's new + +return to index + +![](https://assets.teenage.engineering/_img/69314ebb3b4aa756565cac45_opt.svg) + +release notes + +* improved audio stability to reduce glitches. +* restored SYNC OUT continuous clock output. + +* fixed: bug fixes and performance improvements for EP SAMPLE TOOL. +* fixed: various UI quirks related to faders, sampling, and chopping + +* fixed: turned-off LEDs could sometimes glow dimly. +* fixed: various MIDI bugs. + +![](https://assets.teenage.engineering/_img/68d267ea5492f019d27d2b8f_opt.svg) + +new features! + + +* added: Show "disk low" warning message when pressing SAMPLE and there is not enough disk space to record 20 seconds. +* added: midi reset all controllers on sequencer stop. this is now system setting 140 (on) and 141 (off). + +project management + +* fix: project erase did not reset scenes +* fix: Project erase did not reset some pad settings (e.g. MIDI channel). + +* fix: Swing was not updated when loading a new project. +* fix: After loading a project, erasing notes would not enable the undo umbrella. + +sound editing + +* fix: With a perfectly timed stop, the sequencer could stop past pattern end. (E.g. 5.1.1 for a 4-bar pattern.) +* fix: Only record note repeats for the currently selected group. + +* fix: For some notes, LEDs were not lit for the full duration. This caused misleading blinks at note-off. +* fix: Stuck notes when using punch in fx pad 0. + +sampling + +* added: Show "disk low" warning message when pressing SAMPLE and there is not enough disk space to record 20 seconds. +* fix: When hands-free sampling 20 seconds of stereo, the device would incorrectly display "FUL" and discard the recording. + +* fix: Newly recorded samples would inherit settings (like pan or pitch) from the pad's previous state. +* fix: faster storage cleanup after deleting samples. + +* fix: When fixed-length resampling a pattern, start recording instantly, also 
capturing any initial silence. This preserves the timing relative to pattern start. + +sound editing + +* fix: Trim in would not always move to sample start. +* fix: Small trims would not enable the scissors icon. + +* fix: The UI did not refresh after pasting a pad. +* fix: Keep pad settings when browsing sounds with +/- and returning to original sound. Numpad selection acts as a fresh load. + +* fix: Pads would leave mute groups when changing sound. +* fix: Improved initial
BPM and bar length
detection for samples imported via EP SAMPLE TOOL, especially those with custom sample rates. + +midi and sync
 + +* removed: midi program change support. program change can still be recorded and relayed but is no longer mapped on the device. +* added: midi reset all controllers on sequencer stop. this is now system setting 140 (on) and 141 (off). + +* fix: Recording fast external MIDI aftertouch/pitch bend messages no longer causes audio stutter on playback. +* fix: Stuck notes when changing pads while playing on MIDI controller. + +* fix: Sync icon blinked with wrong rate. +* fix: Do not record MIDI Channel Mode messages +* fix: TRS midi out could sometimes fail. (running status wasn't reset) + +misc
 + +* fix: System settings did not show navigation after punching in a number. + +* fix: A rare issue where some machines would display a garbled error message on startup. + +* fix: Allow switching scenes by MAIN+single digit. + +![](https://assets.teenage.engineering/_img/683ea89bc94ac612a63e45c4_opt.svg) + +scenes + +* Erase Scene ((ERASE)+(mAIN)) Update: + + Hold for 2s: + + If the current scene is empty and not part of the song, it is deleted (displays “DEL”). + + Otherwise, its contents are cleared (displays “CLR”). + +SONG MODE + +* changed: stop the song when it reaches end. +* changed: when stopping a song, go back to the position where the song was started. + 
 +* fix: undo while recording could restore the wrong pattern. + +* fix: pause song progression when LOOP mode is active. +* fix: when recording, notes sometimes got quantised to the wrong pattern. + +* fix: stay in active scene when leaving song mode. + 
 +* fix: Improved song mode cut/paste visual feedback. + +sampling + +* new: allow chopping a sample from one group to another. + + (Example: Press (groupa), select a sound by pressing pad, press (groupB), CHOP!) +* fix: hands-free sampling was allowed on already recorded pads, causing a weird state + +* fix: hands-free sampling did not stop automatically after 20 seconds. +* fix: lag when retaking a sample. + 
 +* fix: the sequencer sometimes did not stop after fixed-length pattern recording. + +* fix: in hands-free sampling, prevent changing the fixed recording length using (plus) / (minus) after recording has started. + +connectivity + +* new: added system setting MID -> CHN -> OFF (127). When selected, pads only send and receive MIDI voice messages if a MIDI channel is assigned in SOUND EDIT. +* new: reduced latency by enabling running status on TRS MIDI OUT. +* fix: weird behaviours when recording with external clock. +* sync in start did not exit record arm mode. + +* in some cases, stop did not stop recording and metronome. +* fix: Program Change and Channel Pressure messages on TRS MIDI OUT. +* fix: OMNI/basic channel MIDI notes were forwarded even if MIDI THRU was OFF. + +* fix: SYNC24 OUT did not work well with some devices
(e.g. MC-202). +* fix: Improved USB reliability when connecting to Windows PCs. +* fix: handle unsupported characters when uploading sounds with EP SAMPLE TOOL. + +sound edit + +* fix: SOUND EDIT trim out audition was broken if trim in was greater
than 0. +* fix: sound pitch could get stuck at 0.00 when finetuning. + +* fix: AMP could be displayed instead of PTC when changing sound pitch with Y knob. +* fix: timestretch did not work with external clock. + +* fix: Sound timestretch BAR setting did not save and load correctly. +* fix: Holding SHIFT+SOUND to save a sound now works during playback. + +projects + +* fix: sidechain settings were not loaded correctly. + +* fix: project erase did not reset pattern length. + +* fix: Project load did not reset pattern position. + +punch-in FX
 + +* fix: Weird behaviour of punch-in FX when sequencer is stopped. + +* fix: punch-in FX ENTER could sometimes cut out very long notes. + +* fix: out of sync time-stretched samples when using tape-stop-punch in FX. + +misc + +* fix: punch-in FX ENTER could sometimes cut out very long notes. +* fix: display BAT when powering down due to critically low battery + +* fix: Improved handling of disk full when saving settings and pattern data. + +* fix: loop mode sample start position was off when using external clock or tape-stop punch in fx. + +crashes + +* fix: crash when playing song with external clock. +* fix: crash when switching project with a queued scene change. + +* fix: crash when pressing (shift) + (groupA) in song mode while the song is playing. + +* fix: error 'pattern 30' when loading a pattern. + +os 2.o + +![](https://assets.teenage.engineering/_img/67ee36c0abb22c5ef8f3eaac_opt.svg) + +stack effects, make a beat from a beat or combine samples, all using the new resampler. +just hit (sample) then press (plus) until RSP shows on screen. you can then hold (shift), press a pad then press (play) to sample the length of the currently selected pattern. you can even switch groups after you’ve engaged hands free sampling to sample sounds from another group.  +learn more about resampling here + +![](https://assets.teenage.engineering/_img/67ee3607ce418c5f8e33d9fa_opt.svg) + +![](https://assets.teenage.engineering/_img/67ee39b7b7521c5ef8237cea_opt.svg) + +use song mode to chain scenes together. +hold main then press (enter) to open the song list editor, you can then view and edit the current song position as well as add up to 99 different song positions. combining that with a maximum pattern length of 99 bars that means you can create songs as long as 9,801 bars! this fight might just need some wraps... +learn more about song mode here + +![](https://assets.teenage.engineering/_img/67f6576fa83b625d845c6643_opt.svg) + +![](https://assets.teenage.engineering/_img/67e3bd6cf3c7e25f86734e76_opt.svg) + +sometimes you need both hands to play an instrument, and you want to sample it. use hands free sampling and let ko2 hold the buttons for you. +when sampling hold (shift) and press a pad to engage hands free sampling. you can then sing, play, shout and strum, ko2 will take care of the rest. once you are done just press sample and ko2 will stop sampling. remember to adjust your threshold and gain and combine hands free sampling with the new resampling feature send your beat back into the ring. +learn more about hands free sampling here + +![](https://assets.teenage.engineering/_img/67ee3a5b5ce8d35f8e6c3802_opt.svg) + +kick and bass not getting along? sidechain will duck the volume of the bass when the kick comes in. +press (shift) and (fx) to open output, then (plus) to switch to sidechain. select the sidechain source by holding a group pad and selecting a sound on the pads, then select the destination groups by holding (shift) and pressing the group pads. dial in how hard they punch by adjusting the length and shape with (knobx) and (knoby) respectively. +learn more about midi sidechain here + +![](https://assets.teenage.engineering/_img/67f66379551aa16e057da5d3_opt.svg) + +![](https://assets.teenage.engineering/_img/67e3bf8ad7e9055f8682e6b5_opt.svg) + +with increased polyphony, ko2 goes from 12 mono/6 stereo sounds to up to 16 mono and 12 stereo sounds. +no need to pull your punches anymore but watch out for time stretched, stereo and high pitched samples as they may reduce the polyphony. + +![](https://assets.teenage.engineering/_img/67ee3bede983696a76a1123f_opt.svg) + +struggling to land your kicks on time? what about adding one bar loops? try out the new larger note intervals, now you can hit your target every time and record perfect four on the floors. +ko2 now supports 1/1, 1/2 and 1/4 timing intervals! +bonus! hold (shift) while in timing to latch the note repeat so ko2 can hit the hats for you while you focus on the kick and snare. +learn more about larger note intervals here + +![](https://assets.teenage.engineering/_img/67ee3c7a87afb96a765c6f04_opt.svg) + +![](https://assets.teenage.engineering/_img/67e3c1e56ba2e65f85e494de_opt.svg) + +ko2 now supports midi thru so it can pass notes along to other machines. +hold (shift) and press (erase) to open the system settings then press (plus) to go to mid, then (enter), press (plus) twice to go to thr, then (enter) again and then set it to on with (plus) and (enter) once more. boom! now any incoming midi messages will be passed along to midi out and usb. +ko2 also features a bunch of midi improvements such as:a system setting for midi in and out channelssending and receiving program change messagesa new midi note map so you can play any sound on any pad with an external controllerincoming pitch bend and mod wheel messages now affect sample playbackPads now by default send midi notes to the system midi channelthe sound edit midi channel now changes the midi in channel for that pad too +learn about all the midi changes here + +![](https://assets.teenage.engineering/_img/67e3c261f4eedf5f85907d59_opt.svg) + +as well as all the huge features we have added there are also smaller ones,here is a comprehensive list of the rest. + +* (main) + numpad can now always switch to any scene 1-99. +* hold (SHIFT) + (SOUND) two seconds to save sound edits. +* changes are now saved to disk also during sample playback. this means we no longer need the brain icon to show unsaved changes. +* in MAIN mode, (minus) and (plus) now moves by steps even after bar 10. Since a position like 10.1.2 will not fit on the display, steps are shown with the TIC display. +* sound pitch setting is now step-less. +* snap to zero crossing when changing TRIM IN on mono sounds. +* sync live project switch to bar end. +* made swing a project setting instead of a global setting. +* system setting 412: SEQ/SCN/PTN. Sync scene changes with pattern end. + +update your device here + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) + +--- + +# software-licenses + +software licenses + +return to index + +littlefs +Copyright (c) 2022, The littlefs authors.Copyright (c) 2017, Arm Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 +* Neither the name of ARM nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF zTHE POSSIBILITY OF SUCH DAMAGE. + +tinycrypt +==================================== +           TinyCrypt Cryptographic Library                        +==================================== +Copyright (c) 2017, Intel Corporation.All rights reserved.          +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, zthis list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 Neither the name of the Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=================================== + +Copyright (c) 2014, Kenneth MacKayAll rights reserved. +https://github.com/kmackay/micro-ecc +Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +==================================== + +MCUboot

 +https://github.com/mcu-tools/mcuboot +

Copyright (c) {YYYY} [NAME OF COPYRIGHT OWNER]

 +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

 +http://www.apache.org/licenses/LICENSE-2.0

 +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +![](https://assets.teenage.engineering/_img/655a6b490bfd382a42dda052_opt.svg) diff --git a/scripts/create_ppak.py b/scripts/create_ppak.py index 2e40354..6f17b21 100644 --- a/scripts/create_ppak.py +++ b/scripts/create_ppak.py @@ -16,18 +16,50 @@ from typing import Dict, List, Tuple, Optional +# Mapping between labeled pad numbers (printed on device) and pad file numbers (p01-p12). +# The bottom two rows of pads are swapped: labeled 1-3 live in files 7-9 and vice versa. +# Row of 4-6 and row of 10-12 are unchanged. +LABEL_TO_PAD_FILE: Dict[int, int] = { + 1: 7, 2: 8, 3: 9, + 4: 4, 5: 5, 6: 6, + 7: 1, 8: 2, 9: 3, + 10: 10, 11: 11, 12: 12, +} +PAD_FILE_TO_LABEL: Dict[int, int] = {v: k for k, v in LABEL_TO_PAD_FILE.items()} + + +# Per-sample identifier bytes (8, 9) required for the device to locate sample audio. +# Without these a pad shows the correct sample name but produces no sound. +# Values are reverse-engineered by reassigning samples on device and diffing backups. +# Add new entries as they are discovered. +PAD_SAMPLE_IDS: Dict[int, Tuple[int, int]] = { + 1: (140, 87), # MICRO KICK + 31: (181, 117), # BOOMER KICK + 126: ( 9, 73), # SNARE OPEN + 203: (134, 29), # CLOSED HAT LO + 221: (206, 57), # OPEN HAT REAL +} + + class EP133Project: """Create EP-133 project files (.ppak)""" - def __init__(self, device_sku: str = "TE032AS001", project_num: int = 1): + def __init__(self, bpm: float, device_sku: str = "TE032AS001", project_num: int = 1, + base_sku: Optional[str] = None): """ Initialize a new EP-133 project. Args: - device_sku: Device serial number (get from user's backup meta.json) + bpm: Project tempo in BPM (required — zero BPM causes "Error Clock" on device) + device_sku: Device SKU (get from user's backup meta.json, e.g. "TE032AS002") project_num: Project slot 1-9 + base_sku: Hardware base SKU (get from user's backup meta.json, e.g. "TE032AS001"). + Distinct from device_sku — get both from the backup's meta.json. + Defaults to device_sku if not provided. """ + self.bpm = float(bpm) self.device_sku = device_sku + self.base_sku = base_sku if base_sku is not None else device_sku self.project_num = project_num self.pad_assignments: Dict[str, Dict[int, int]] = { 'a': {}, 'b': {}, 'c': {}, 'd': {} @@ -101,14 +133,18 @@ def add_event(self, pattern: str, time: int, pad: int, velocity: int = 100): Args: pattern: Pattern name ('a01', 'b01', 'c01', 'd01') - time: Time position in ticks (0-383 for one bar) + time: Time position in ticks (96 PPQN; one bar = 384 ticks). + Multi-bar patterns are valid — ticks beyond 383 are allowed. pad: Pad number 1-12 velocity: Velocity 0-127 (default 100) + + Note: duplicate (time, pad) pairs are silently deduplicated on save, + keeping the highest velocity event. """ if pattern not in self.patterns: raise ValueError(f"Invalid pattern: {pattern}. Must be a01, b01, c01, or d01") - if not 0 <= time <= 383: - raise ValueError(f"Invalid time: {time}. Must be 0-383") + if time < 0: + raise ValueError(f"Invalid time: {time}. Must be >= 0") if not 1 <= pad <= 12: raise ValueError(f"Invalid pad: {pad}. Must be 1-12") if not 0 <= velocity <= 127: @@ -133,7 +169,13 @@ def _create_pattern_data(self, events: List[Tuple[int, int, int]]) -> bytes: if not events: return bytes([0x00, 0x01, 0x00, 0x00]) - events = sorted(events, key=lambda x: x[0]) + # Deduplicate: for same (time, pad), keep highest velocity + deduped: dict = {} + for evt in events: + key = (evt[0], evt[1]) + if key not in deduped or evt[2] > deduped[key][2]: + deduped[key] = evt + events = sorted(deduped.values(), key=lambda x: x[0]) if len(events) > 255: raise ValueError(f"Too many events: {len(events)}. Maximum is 255") @@ -155,8 +197,20 @@ def _create_pad_data(self, group: str, pad: int) -> bytes: if self._template_pads and group in self._template_pads and pad in self._template_pads[group]: data = bytearray(self._template_pads[group][pad]) else: - # Minimal 27-byte pad file + # 27-byte pad file with correct defaults (reverse-engineered from device backup) data = bytearray(27) + # Bytes 8-9: sample-specific identifier — device needs this to locate audio data. + # Without it the pad is silent even if the sample number is correct. + # Values reverse-engineered by reassigning samples on device and diffing backups. + sample_num = self.pad_assignments[group].get(pad, 0) + sample_id = PAD_SAMPLE_IDS.get(sample_num, (0, 0)) + data[8] = sample_id[0] + data[9] = sample_id[1] + # Bytes 12-15: project BPM as float32 LE — device writes this on sample assignment. + struct.pack_into(' or
; fall back to + content = soup.find("article") or soup.find("main") or soup.find("body") + + # Remove nav, footer, header noise + for tag in content.find_all(["nav", "footer", "header", "script", "style"]): + tag.decompose() + + md = markdownify.markdownify(str(content), heading_style="ATX", strip=["a"]) + md = md.strip() + + slug = path.rstrip("/").split("/")[-1] + sections.append(f"# {slug}\n\n{md}\n") + +OUTPUT.write_text("\n---\n\n".join(sections), encoding="utf-8") +print(f"\nWrote {OUTPUT} ({OUTPUT.stat().st_size // 1024} KB)")