baby8 sequencer to actual drum sounds

 I've been asked for more details about this project: 




When you build something you know the details of what you've done and just assume that everyone else does too. 

In short, the baby8 is a sequencer. It's a great kit and a great introduction to sequencers. It has 'gate' and 'cv' (control voltage) outputs. I've connected these to the pico, which is reading those and sending MIDI out. There is no audio at that point. You use a computer or some other device to receive that MIDI and generate the audio.

Output from the sequencer

I'm new to the modular synthesiser world,  I didn't know what the cv output 'looks like' and what the voltage levels are. So my partner helped me to 'scope those and we discovered that the control voltage ranges from ~2v to ~7.5v.  (for each 'step' of the sequencer, this voltage is set by the pot.) You can use this voltage to control anything else that you choose. 

There's also a gate output. This is a square wave at a similar voltage, with adjustable pulse width. The idea is that this is the trigger for whatever you're using the sequencer for.

Connecting things up

The Pico has an ADC on board. (Analogue to Digital Converter). This means that it can read a voltage and turn that into a number. The voltage range that it can read is only 0-3.3V, so we need to somehow change our 2v-7.5v into 0-3.3v (or as close as possible).

If we can remove that 2v, and halve the remaining voltage we're pretty much there. 

For halving the voltage, a simple resistor divider should do the trick. For dropping the 2v - a diode has the strange property of dropping ~0.6v across itself. Three of those in series pretty much drops 2v. So here's my very rough-and-ready circuit, using components I could easily reach out and grab. This is what I ended up with:

For the 'gate' output from the sequencer, dividing that by two (same as the above circuit but without the diodes) makes a ~3.3v signal which is acceptable for the pico's regular GPIO pins.

The code on the Pico 

I like programming. Simply downloading code and running it seems unexciting to me. 

You have to draw a line though. I'm not going to go to the trouble of learning all the details of how USB works and reinventing that wheel, so I use TinyUSB to make the Pico into a USB host or device, in this case a MIDI device. More on that later

I like C, I learned it in 1993 on the Amiga and most of my day job for many years has been with Objective-C, an object-orientated C. So I prefer it to the higher-level languages like circuit python.

For this project, even in C, there's very little to the code. 

Reading the Pico's ADC isn't so straightforward in C, there's quite a bit of setting up to do, but there is plenty of example code and tutorials out there. I suspect it's easier in something like circuit python.

Reading the gate signal is a lot easier, we're just reading a GPIO input, which is entry-level 'blinky' stuff. 

I used an interrupt here - basically this line says "call my function gate_callback() whenever this GPIO goes high"


The gate_callback() function then reads the ADC (voltage level). It does a bit of maths to turn that into a suitable note number. This could easily be a musical note but in this case I want to trigger drums, so I'll be using the special midi channel 10 where certain note values represent certain drum sounds

I'm then using a buffer, because you want to return as quickly as you can from an interrupt but I won't go into that here. Basically the information we have so far is buffered and picked up in our main program loop.  I'm sure this could be done very easily with a single loop, polling the gate and cv.

For each note you want to play, you have to send a 'note on' message and later a 'note off' message. 

In short, every message consists of either 2 or (more usually) 3 bytes. The first has the highest bit set (ie it's > 128) and represents both the instruction (note on / note off or whatever) and also the channel (0-16). We're using channel 10, which is usually used for drums, so our first byte is either hex 9A (note on, channel 10) or hex 8A (note off, channel 10).

The second byte (0-127) is the note number. Think of that as the note on the piano keyboard, but in this case it represents our choice of drum sound.  The third byte (again 0-127) is the 'velocity' of the note. I have simply set this to 127 for every 'note on', but it's easy to vary that for harder or softer hits on the drum sounds.

Here's more information about the midi format

MIDI output

As mentioned, I like TinyUSB, it can be set up so that the pico's micro-USB port can be plugged into a computer and be recognised as a 'midi device'. (MIDI device vs host is a bigger subject). So in code, simply  writing those three bytes is enough - I use TinyUSB's tud_midi_stream_write();

However,  MIDI is just old-style serial at 31250 baud.  So you could set up the Pico's UART to that baud rate and send the midi bytes to that output. A serial to MIDI adaptor is very simple, consisting of little more than an opto-coupler and MIDI socket. 

MIDI is the language that all musical instruments and musical software speak.  As we've seen above, it's no more than a few bytes which are instructions to turn notes on and off (and maybe other messages too about how to vary those notes). 

Anything that can receive midi and generate audio will then turn what we've done into sound (using samples or synthesised sound).  Traditionally, 'modules' like this one were used. I'm working on MIDISID which is a similar thing using SID chips to synthesize the sound in their own distinctive way. 

For this project I simply plugged the pico (set up as a midi device, remember) into my computer and set up a drum track in Logic Pro to receive and play live the MIDI output.

Comments

Popular posts from this blog

e-ther 2 - Announcement and full rundown of features

Enclosures for MIDISID

MIDISID - second batch and giveaway