Pithesiser Goes Public!

Well… in a small way!

I volunteered to do a five minute “Lightning Talk” at my place of work, which took place over lunchtime today. Myself and three other presenters had just five minutes each to present some cool tech they’d uncovered; so I decided to do a swift run through and demo of the Pithesiser! Not strictly work related, but that wasn’t necessarily the remit.

It was a bit nerve-wracking but fun (other than my voice fading). I came in at about 4 minutes 15 seconds for the whole talk (including a swift demo) and the synth sounded a bit better than I was hoping. Demo is overegging it a bit; I had time to bash out a few chords and tweak a few settings to demonstrate variation from cheap gentle electric piano sound-alike to full on monster LFO early ’70s Radiophonic Workshop.

Everyone seemed to enjoy the proceedings, and it was a novel and great way to spend one’s lunch hour.

(c) 2013 Nicholas Tuckett.

 

Grab-bag of Progress

The Pithesiser grows in capability…

Over the last couple of weekends I’ve been adding some more features:

  • Completed ADSR envelope support with controls and rendering: linked to note volume. Attack and decay levels and times are controllable, along with sustain and release. A simple graph of the envelope shape is rendered on screen, updated when any envelope controls are changed.
  • Single low-frequency oscillator that can modulate volume or pitch: this can be tuned from 0.1Hz to 20Hz, supports a wide range of waveforms (saw up/down, triangle, square, sine) and also sports an adjustable intensity (which maps to +/- a whole octave for pitch).
  • Simple image rendering: for a funky logo – still to be drawn properly!

I’m thinking of next extending the LFO stuff further – e.g. add another oscillator so pitch and volume can modulate independently, add envelopes for intensity & frequency.

After that, it’ll probably be back to core synthesis functionality – try and make the oscillators sound better (they’re very basic so not surprisingly exhibit subtle strange harmonics), maybe go for two oscillators per voice (probably leading to detailed performance investigation and optimisation), try adding filtering into the signal chain…

I’m starting to find the number of controls required is getting unwieldy, so it might be pragmatic to put some work into making that more configurable. The Korg nanoKontrol has a nice “scene” button that effectively offsets the controller numbers in a paging fashion, so that might be a way of organising lots of controls – a page for each oscillator, plus an LFO page and a “master” page for global controls?

Text rendering is going to become a necessity, to make the increasingly growing set of states visible. After a while, telling apart a wavetable band limited sawtooth with linear interpolation from its procedural cousin gets a bit tricky…

(c) 2013 Nicholas Tuckett

Brief Technical Overview

I thought I’d share some of the juicy technical details of Pithesiser as it stands right now.

The Pithesiser program is written in C on Linux, and is constructed as a number of discrete modules (corresponding to paired source and header files). Modules include low level audio interfacing with hardware, waveform generation modules, graphics rendering modules and the “main” module of the program.

When executing, Pithesiser runs as a small number of processing threads, each with different responsibilities.

Main thread – the Core Audio Loop

This is the beating heart of the Pithesiser – effectively the main loop of the program. It does the actual synthesis for any notes that are playing,  mixes them together and passes them in small chunks to the  audio output thread.

The same thread also currently processes received MIDI input and uses that to trigger notes and update the synthesiser state such as master volume, selected waveform and envelope parameters. It also sends events to the rendering system to update the display when state changes and when audio chunks are completed.

I might consider splitting the core audio processing from the other work done in this thread; however right now it’s small, simple and can be quickly and directly updated from said thread.

Audio Output Thread

This manages the audio output buffers – provides access for the core audio loop to write mixed audio data, and sends completed buffers on to the audio hardware for playback via ALSA.

MIDI Processing Thread

This thread wakes up on the arrival of data via any MIDI device, packages that data up into discrete events and posts them onto the MIDI event queue for the main thread to read. It also maintains a map of the current controller values and whether they have changed sinced last polled.

Rendering Thread

This thread accepts graphics events from the main thread that are used to update the display (currently just the oscilloscope  and a simple graph representing the volume envelope). This thread receives copies of the mixed audio output and uses that to render the oscilloscope display and also to drive the timing of when to physically update the screen (execute OpenVG operations and swap the display buffers).

As the audio output operates on a much higher frequency than the display (345Hz vs 60Hz), the oscilloscope holds on to the waveform data it receives until it has enough to match the equivalent of 1/60th of a second of audio output, then renders it all out. That means that the core audio loop completes roughly 5.75 times for each frame rendered to the screen.

Event Communication

Where threads communicate via events, this is implemented as simple ring-buffers of predefined C structures using simple arrays as storage for the events. Semaphores and mutexes are used to manage synchronisation and notification between such communicating threads.

Some Choice Metrics

  • Sample rate used for synthesis, mixing and playback: 44.1 kHz.
  • Size of audio data chunks: 128 samples (equivalent to nearly 3 milliseconds).
  • Target render frame rate: 60Hz.

(c) 2013 Nick Tuckett.

A New Case

The Pithesiser has a new enclosure:

image

It’s one of the Mr Raspberry cases – easy to put together and feels fairly robust. Got it from PC Supplies Ltd via Amazon in the UK, where it is advertised as an Adafruit case. However it isn’t one of the official Adafruit Pi enclosures, so calling it such is a bit rich really. Perfectly fine case though, and matches the pictures on Amazon.

(c) 2013 Nick Tuckett.

Introducing the Pithesiser

Having acquired a Raspberry Pi around the middle of last year, I started looking around for a project to get my teeth into – one which would motivate me to sustain my efforts yet be flexible enough to tackle piecemeal, whenever I had some spare time available. Given the popularity of this new affordable hardware platform, there were a lot of Pi projects starting up across the web; so how to choose?

Late in the autumn, I came across the Piana project (http://raspberrypisynthesizer.blogspot.co.uk/) – and that really inspired me to start creating my own software synthesiser. Such a project would bring together a whole heap of interests from my life and career, and would open up new areas of learning for me too. And if that doesn’t motivate me to keep going…

One final cherry on the cake was a tenuous personal connection from a long time ago – the gentleman behind Piana and I both worked at the same firm back in 1988, where he was a star of the R&D department and I was a lowly placement student between school and university. We never really met – I was stagestruck by his awesome demonstrations of hacker skills back then. He’s obviously still got his mojo working 25 years later…

Progress so far

I started working on the Pithesiser at the end of October 2012, progressing the software through increasing levels of capability to where it is today:

  • Basic audio mixing and output via ALSA.
  • Simple wavetable driven signal generation supporting interpolation and band limited waveforms.
  • Basic procedural waveform generation to compare with wavetables
  • 8 note polyphony with one oscillator per voice.
  • MIDI controller and note input.
  • ADSR amplitude envelopes.
  • OpenVG user interface rendering framework.
  • Basic oscilloscope display.

There’s still lots to do before being ready for public exposure, and before coming anywhere near what Piana can do.

Hardware
image

  • Model B Raspberry Pi.
  • Pluscom 7-port USB hub powered from the Pi.
  • Akai LPK25 laptop MIDI keyboard plugged into the Pi via the hub.
  • Korg nanoKontrol  plugged into the Pi via the hub.
  • Afunta USB sound card plugged direct into the Pi.

The Pi is a 512Mb model, though the memory footprint is nowhere near that.

The USB sound card gives better quality output than the onboard audio, and also works much more smoothly with ALSA. Not to mention it might be saving my bacon over latency (http://raspberrypisynthesizer.blogspot.co.uk/2012/09/usb-audio-saves-day.html).

I’ve not experienced problems with USB MIDI as reported by Piana (http://raspberrypisynthesizer.blogspot.co.uk/2012/08/usb-midi-problems.html) but from profiling Pithesiser’s feature set, I’m not yet driving the Pi anything like as hard.

Note that the Xbox 360 in the background of the picture is not part of the Pithesiser!

Software

I’m using Eclipse with the Linaro Pi GCC toolchain provided by the Pi Foundation on my 64-bit Ubuntu 12.04 desktop PC. The Pi is running Raspbian, currently on kernel 3.2.27+.

Where next?

I’ve got a “to-do” list for Pithesiser list that’s big and ever growing. Here’s some likely highlights:

  • Finish off ADSR envelopes: still need to implement the release stage, and add a UI and controller input for editing.
  • Enrich waveform generation: add more waveform types, add a second oscillator per voice, improve overall audio quality.
  • Filtering.
  • LFO.
  • Noise generation.
  • Optimisation.

My plan is to blog irregularly about what I find interesting about this project, both on details of what’s already been done and what comes next. Plus answering any sensible and interesting questions that I may be lucky enough to receive.

(c) 2013 Nicholas Tuckett.