Friday, 19 August 2011

Understanding synth playback values

A few people have asked how do we read back the values from the key presses on the synth. It's a relatively simple bit-masking process, but at first appears complicated.

The first thing to do is refer to the map of keypress values (above).
Because our inputs are active low as well as recording the value generated when each button is pressed, we've also written down the inverse of this value.

Say, for example, we press the first button on the PCB.
This returns the value 191.
We take the inverse of the value. Strictly speaking, what this means is we convert the value to binary, which gives us 10111111.
The inverse of this is 01000000.
You can get the same result by subtracting the initial value from 255.
So in this case, 255-191=64 (which is 01000000 in binary)

Because each key on the synth activates a unique bit in the binary sequence, any number of keys can be pressed at any one time.
If we press the low C key (first key to the left) and the Eb key (fourth from the left, including "black notes") the PC returns the value 189.

Converting 189 to binary and inverting (or subtracting from 255) and we get 66, which is represented by 01000010

As you can see from the previous example, both binary sequences begin 01.... so whenever the second bit in the binary sequence is one, we know that the low C key has been pressed.

By identifying the values for all the keys, we can plot which bit in each binary sequence represents which key-press on the keyboard. In our PC app, we'll monitor the last known value of these binary sequences to the current one and this will allow us to work out which key has just been pressed (and equally, which key or keys have just been released). With this information, we can trigger and stop sounds playing, to recreate a genuine playable synth.

See - it's nearly working already ;-)

Why the need for plotting all the values? It has been suggested that we should make the first pushbutton go to PORTB.0 (bit 0), the second button go to B.1 (bit 1) and so on, to simplify reading the data back. In fact, this is exactly what we did in the prototype. The beauty of breadboard prototypes is that you can have wires leading everywhere, looping over each other, winding in and out of other wires.
When you come to create a PCB, however, layout is critical. So our push buttons are actually laid out 17,16,1,2,7,8 and so on. While this doesn't make sense to the casuall observer, it's much easier to use a rigid layout pattern, and make allowances for it in firmware/code, than it is to stick rigidly to a set firmware/pinout and try to force your PCB layout to match it!

[edit - 10pm same day]
Here's a short video showing the custom software (note how it detects when the instrument has been plugged in and changes the interface - we really like that subtle little touch!) and a working demonstration of the synth

I need to remember to close the windows when shooting demo videos like this! And maybe turn the telly down a bit too. And, of course, make sure the volume is up on the PC before starting!

You can see on the video that the synth not only supports "key down" type events - i.e. triggers a sample when a key is pressed - but also raises "key up" events too - stopping a sound when you lift your finger off a key, just like a real synth! Chords are played to demonstrate that the miniature synth is truly polyphonic: multiple keys can play at once. I dread to think what it would sound like, but in theory you can press (and the PC will respond to) all 17 keys at the same time. Better than some early casio keyboards even!