Zack Scholl


 / #hardware 

creating a sample player machine from scratch.

the zeptocore is a portable sample player I created from scratch, released on May 3rd, 2024, which is available to buy on my website

the zeptocore is a handmade, handheld sample player. Its main purpose is to reimagine samples with fast tactile switches, while reacting, in realtime, to randomly changing patterns and effects.

the beginnings

I’ve been interested in mangling samples for a long time. I created a number of programs for the norns sound computer using SuperCollider that allow you to mangle samples in interesting ways. here is a selection:

After a few years of making software, I decided it would be fun and rewarding to make a physical device.

the breadboard

I started working on this device a year ago using off-the-shelf components wired into a breadboard. I got the very first prototype working in July, on a long plane trip from Seattle to Berlin. (Strangely no TSA agent ever asked me about the breadboard with wires sticking out of it!)

Here is the first video of the first ever version where instead of tactile switches I’m using the keyboard:

This version is basically just some off the shelf components (a pcm5102, a SD card breakout, and a raspberry pi pico.

Most importantly, it was fun. I am a big proponent of dogfooding and at each step in the process of building, it was important that I really enjoyed the device.

I actually still support this breadboard version with off-the-shelf parts, which I call “zeptoboard”.

You can build this today and it still works great, especially with the MIDI interface on a Chrome browser:

the hardware

Once I got the basic concept working I started on the hardware. The basic hardware is not too complicated - it needed to support SD card SDIO interfaces, 20 buttons, and 20 lights, 3 knobs. I am using the Raspberry Pi Pico as the CPU which didn’t have enough GPIOs for all of this, so I added a PCA9552 as a light controller and did a keyboard matrix for the tactile switches. Instead of off-the-shelf SD card and audio DAC I also integrated them into the board.

All in all it took me about 28 tries to get the board right (yes, that’s right, I spent about $3,000 over three months to finalize the hardware). There were about 15 versions that just didn’t work and it turned out to be something really silly like a bad soldering pad for the sd card.

In the end I was able to get matching colors for the Raspberry Pi Pico and the board which I also liked. (There was a separate incident where a large box of Raspberry Pi Picos got lost on its way to me and everything was delayed weeks).

the firmware

I spent almost a year writing the firmware which I call “_core” as it is somewhat hardware agnostic. I’m still writing the firmware. There are now over 1,500 commits to the codebase, most of them pretty substantial. I never fully realized how much work went into such a small device, but now I know.

One very fun part of doing the firmware was writing my own effects. I’m especially proud of the saturation and fuzz effects. The fuzz, for example, is a very simple transfer function which has a really cool effect on sound:

the tool

The zeptocore loads samples from an SD card, but the samples need to be conditioned to a specific format (16-bit, 44.1khz, with appended and prepended audio for better streaming). To aid this, I also created a web tool called “the tool” where you can load samples in the browser and then directly download the files to load onto the sd card.

This part was fun to develop, it was a lot of frontend work - somewhat creating a file-browser/DAW in a website - but it paid off in the end to really improve the ease of use.

the challenges

There were several technical challenges that took me awhile to figure out.

The biggest challenge was the SD card latency. I made a decision early on that I would not limit sample length, so samples would be streamed directly off the SD card instead of loaded into internal memory. This comes with a severe limitation in that seeks to audio blocks can, in worst case scenarios, take up to 3-6 milliseconds. This means, if I choose an audio block of 10 ms (meaning latency of ~10-20 milliseconds which is at just the threshold of perception), it only provides enough time to do one seek per audioblock. This means that I can only do monophonic sample playback.

The problem continued though, in that different SD cards have different worst-case scenario latency. Even when using the “fast” SDIO protocol, some of the SD cards I tried had worst-case latencies of 10-30 milliseconds! So I had to spend a lot of time finding which SD cards are reasonable to use with this device, and make clear disclaimers against using the “wrong” ones.

The other technical challenge was to create the sample download tool in a way that was compatible with the onboard C-libraries. The tool was developed in Go which was nice because it came with pretty easy libraries to write my own marshal/unmarshal functions that would be compatible with my C struct. Even more complicating, is that in the zeptocore firmware I use bit-packing to reduce the memory usage a little more, but since that varies between compilers there is an intermediate unmarshaling inside the zeptocore to take the save data and unpack it into the bitpacked structs.

the release

After two dozen revisions, and months and months of firmware, I am so happy to finally “release” the zeptocore into the wild. Its certainly a fun device - I would spent hours playing with it when I was supposed to be programming it.

I hope that others can find joy in it too.

There are now a couple of vendors to purchase: