norns as sampler buddy


This script is a little util that allows to record a sound an play it back at various RPM ratios.

The main use is to replay the sample sped up into a hardware sampler to save memory and add some punch to samples (demonstration of the effect).

It comes with its own fork of the timber engine with some tweaks, so a sleep is necessary.




-- K1 held is SHIFT
-- Anywhere:
--  E1: switch page
-- Main screen:
--  E2: record speed
--  E3: playback speed
--  SHIFT + E1: sampler model
--  K2: record start/stop
--  K3: playback start/stop
-- HW Sampler Instructions:
--  E2: record speed
--  E3: playback speed
-- Dirtying:
--  SHIFT + E1: preset
--  E2: sample rate
--  SHIFT + E2: sample rate (x 1k)
--  E3: bit depth

Next Features

  • 3 band EQ (:white_check_mark: only via params menu, still need a UI page)
  • tuning / timestretching compensation
  • load a sample from disk
  • stereo to mono summing, phase invert toggle
  • instructions for other hardware samplers (SP1200, SP-202…)
  • support for intermediate RPM values
  • IPS units (for tape input source)
  • animations

See also


No release for now, not yet on maiden.


I know its not your priority but a simple slice and save option with clever/fast naming would be great!
Cool stuff btw !

I thought about it, even though it’s not the primary purpose of the script (where a hardware sampler would do this duty).

In the meantime, although minimalist, sam might suit your needs.


Hey there. I’ve been wanting to try this out and just got around to it. After restart getting an error: load fail.



script load: /home/we/dust/code/rpmate-main/rpmate.lua


script clear

MISSING INCLUDE: rpmate/lib/librpmate

SCRIPT ERROR: load fail

/home/we/dust/code/rpmate-main/rpmate.lua:31: MISSING INCLUDE: rpmate/lib/librpmate

stack traceback:

/home/we/norns/lua/core/norns.lua:138: in function </home/we/norns/lua/core/norns.lua:138>

[C]: in function ‘error’

/home/we/norns/lua/core/startup.lua:49: in function ‘include’

/home/we/dust/code/rpmate-main/rpmate.lua:31: in main chunk

[C]: in function ‘dofile’

/home/we/norns/lua/core/script.lua:186: in function </home/we/norns/lua/core/script.lua:186>

[C]: in function ‘xpcall’

/home/we/norns/lua/core/norns.lua:139: in field ‘try’

/home/we/norns/lua/core/script.lua:186: in function ‘core/script.load’

(…tail calls…)

script clear

Need to load this up and see if I’m experiencing the same thing. Really looking forward to trying this!

1 Like

The issue seems to be that you cloned the repo as a rpmate-main folder instead of the expected rpmate.

Renaming the folder should fix the issue.

The reason why it fails is that I include the lib with path rpmate/lib/*. I later discovered that lib/* would also work, making the code agnostic to the folder name. I will update the code accordingly.

Wow! Looking forward to using this with my SP1200 & Mirage samplers

1 Like

That worked! Thank you!

I finally got access back to my MPC 2k XL and was able to test.

It works surprisingly well, even with a youtube video recorded at regular speed and then sped up w/ RPMate.

I tried in the past by feeding sped up youtube video to the MPC and the result was pretty garbage (lots of artifacts).

Also, I managed to steal the 3 band EQ from pedalboard. Its buried deep in the params menu, I need to create an UI page for more direct control.

I bet it would do wonders w/ the SP. I’ve heard it does a similar sound enhancement to the MPC 2000 / S2000 w/ the speed up / slow down trick.

Don’t know about the Ensoniq, but it’s a beast of a machine (early Alchemist sound, IIRC).


could not recall the name of this at first but am glad to dig it up again…what crazy, wonderful idea and ui!


I love the idea of this, but it’s completely unstable for me. Every time I load up the script it only makes it a couple minutes before crashing. Is anyone else experiencing this as well? I’m new to the Norns, but this is the only script thats giving me issues like this.


i haven’t tested it on the last version of norns but i remember noting there was a breaking change in an sc function (of sort) that broke similar scripts (timber typically) unless patched.

might be the culprit. i need to investigate this.

@FlyingSoulo, as always, giving info like norns hw (og, shield, fates) and software version + ideally logs (captured from maiden and inserted w/ a [details=""] block) would sped investigations up.

I’m running a Norns Shield that I recently updated to version 220321. I’ll attempt to include the details below. I apologize if the formatting doesn’t work.

[details=" matron


metro_stop(): pthread_cancel() failed; error:

specified thread does not exist

script clear

script load: /home/we/dust/code/rpmate/rpmate.lua

including /home/we/dust/code/rpmate/lib/librpmate.lua

including /home/we/dust/code/rpmate/lib/inspect.lua

including /home/we/dust/code/rpmate/lib/lua/io.lua

including /home/we/dust/code/rpmate/lib/lua/ui.lua

including /home/we/dust/code/rpmate/lib/lua/math.lua

including /home/we/dust/code/rpmate/lib/lua/softcut.lua

including /home/we/dust/code/rpmate/lib/lua/timber.lua

including /home/we/dust/code/rpmate/lib/lua/core.lua

including /home/we/dust/code/rpmate/lib/lua/io.lua

including /home/we/dust/code/rpmate/lib/timbereq_engine.lua

including /home/we/dust/code/rpmate/lib/controlspecs.lua

including /home/we/dust/code/rpmate/lib/lua/screen_main.lua

including /home/we/dust/code/rpmate/lib/lua/math.lua

including /home/we/dust/code/rpmate/lib/lua/devices.lua

including /home/we/dust/code/rpmate/lib/lua/screen_insts.lua

including /home/we/dust/code/rpmate/lib/lua/math.lua

including /home/we/dust/code/rpmate/lib/lua/devices.lua

including /home/we/dust/code/rpmate/lib/lua/screen_input_level.lua

including /home/we/dust/code/rpmate/lib/lua/io.lua

including /home/we/dust/code/rpmate/lib/lua/ui.lua

including /home/we/dust/code/rpmate/lib/lua/screen_dirtying.lua

including /home/we/dust/code/rpmate/lib/lua/math.lua

script run

loading engine: TimberEq

reading PMAP /home/we/dust/data/rpmate/rpmate.pmap

m.read: /home/we/dust/data/rpmate/rpmate.pmap not read.

Engine.register_commands; count: 67

___ engine commands ___

amp if

ampAttack if

ampDecay if

ampModLfo1 if

ampModLfo2 if

ampRelease if

ampSustain if

bitDepth ii

clearSamples ii

copyParams iii

copySample iii

detuneCents if

downSampleTo ii

endFrame ii

filterFreq if

filterFreqModEnv if

filterFreqModLfo1 if

filterFreqModLfo2 if

filterFreqModPressure if

filterFreqModVel if

filterReso if

filterTracking if

filterType ii

freqModEnv if

freqModLfo1 if

freqModLfo2 if

freqMultiplier if

generateWaveform i

hs_amp if

hs_freq if

lfo1Fade if

lfo1Freq f

lfo1WaveShape i

lfo2Fade if

lfo2Freq f

lfo2WaveShape i

loadSample is

loopEndFrame ii

loopStartFrame ii

ls_amp if

ls_freq if

mid_amp if

mid_freq if

mid_q if

modAttack if

modDecay if

modRelease if

modSustain if

moveSample ii

noteKill i


noteOff i


noteOn iffi

pan if

panModEnv if

panModLfo1 if

panModLfo2 if

pitchBendAll f

pitchBendSample if

pitchBendVoice if

playMode ii

pressureAll f

pressureSample if

pressureVoice if

startFrame ii

transpose if

___ polls ___









script init

waiting for 0.033333333333333 seconds

record on

record off

attempt to play

recording: false

record duration: 6.4299998283386


record on

record off"]

i don’t seem to reproduce, but have just pushed the aforementioned fix.
hopefully it should behave better.

your logs don’t show anything suspicious but what matter is what gets logged at the moment of the crash.

as for the details, you almost got it.

should have been somethin like:


one easy way is to use the GUI toolbox to insert it:



Whatever you did seems to have addressed the issue. Thank you so much. It sounds incredible!