RasPi Magazine - Issue No. 21
RasPi Magazine - Issue No. 21
BUILD
21
CODE
TOP 10
ANDROID
APPS
Plus
Run science
experiments on your Pi
Welcome
Did you know that your
Raspberry Pi is powerful
Get inspired
enough to handle some pretty Discover the RasPi
high-level audio processing? community’s best projects
This month we’re going to show you how to
code a simple polyphonic synthesiser using Expert advice
Python, from scratch. It’s such a worthwhile Got a question? Get in touch
project because the lessons you’ll learn while and we’ll give you a hand
working with buffers, manipulating the flow
of data into each of them, and running the
maths on the outputs, will really help you
Easy-to-follow
out with your audio, video and electronics guides
projects. As well as this, we’re also playing Learn to make and code
around with a great little device for doing gadgets with Raspberry Pi
science experiments, and following up last
issue’s guide to profiling your Python code
with a tutorial on optimisation. Enjoy!
Editor
RasPiViv
Discover how a Pi can keep poison dart frogs cool
What is PaPiRus?
Check out this nifty display module
Talking Pi
Your questions answered and your opinions shared
Code a simple synthesiser
Learn how to write a simple polyphonic synthesiser (and
the theory behind it) using Python and Cython
We are going to take you through the basics
of wavetable synthesis theory and use that THE PROJECT
ESSENTIALS
knowledge to create a real-time synthesiser
Raspberry Pi 2 or 3
in Python. At the moment, it is controlled by the computer
USB sound card
keyboard, but it could easily be adapted to accept a MIDI
keyboard as input.
The Python implementation of such a synthesiser
turns out to be too slow for polyphonic sound (ie playing
multiple notes at the same time) so we’ll use Cython,
which compiles Python to C so that you can then compile
it to native machine code to improve the performance.
The end result is polyphony of three notes, so this is not
intended for use as a serious synthesiser. Instead, this
tutorial will enable you to become familiar with synthesis
concepts in a comfortable language: Python.
Once you’re finished, try taking this project further by
customising the key mapping to better fit your keyboard
layout, or tweaking the code in order to read input from
a MIDI keyboard.
“We’ll use
Cython, which
01 Install packages compiles
Using the latest Raspbian image, install the required
packages with the following commands:
Python to C so
sudo apt-get update that you can
sudo apt-get upgrade then compile
sudo apt-get install python-pip python2.7-dev it to native
portaudio19-dev machine code
sudo pip install cython pyaudio to improve the
The final step compiles Cython and PyAudio from
source, so you might want to go and do something
performance”
else while it works its magic.
02 Disable built-in sound card Cython
We had issues getting the Raspberry Pi’s built-in sound Cython compiles
card to work reliably while developing the synthesiser Python down to the
code. For that reason, we are using a USB sound card C code that would
and will disable the built-in card so that the default card be used by the
is the USB one: interpreter to run
sudo rm /etc/modprobe.d/alsa* the code. This can
sudo editor /etc/modules
optimise some parts
Comment out the relevant line by changing ‘snd-
of your Python code
bcm2835’ to ‘#snd-bcm2835’ and save, then:
sudo reboot into pure C code,
which is significantly
faster, by giving C
types such as int, float
and char to Python
variables. Once you
have C code, it can
be compiled with a
C compiler (usually
GCC) that optimises
the code even further.
For more details, go
to www.cython.org.
06 Start to code
Our code file is going to be called synth.pyx. This
extension tells Cython that it is not plain Python
code – and as such, can’t be run in a normal Python
interpreter. Create the file with your favourite editor and
add the imports.
07 MIDI Table
To synthesise the standard note of a piano, we need a
table of MIDI values. MIDI notes range from 0-127. MIDI “To synthesise
note 60 is middle C on a piano. The MIDI Table class has
the standard
a ‘get note’ function that returns the frequency of a note
when you give it a MIDI note number.
note of a piano,
we need a table
of MIDI values.
MIDI notes
range from
0-127. MIDI note
60 is middle C
on a piano”
08 Attack, Decay, Sustain, Release
The ADSR class applies a volume curve over time to
the raw output of an oscillator. It does this by returning
a multiplier to the note that is a multiple between 0.0
and 1.0. The version we provide has an attack time of
100 ms, a decay time of 300 ms and a release time of
50 ms. You can try changing these values to see how it
affects the sound.
The ADSR class does a lot of maths (44,100 times
per second, per note). As such, we want to give types to
all of the variables so that the maths can be optimised
into a raw C loop where possible, because Python has
a massive amount of overhead when compared to
C. This is what the cdef keyword does. If cdef public
is used, then the variable can also be accessed from
inside Python as well.
09 Generate notes
The note class is the core of our synthesiser. It uses the
wavetable to generate waves of a specific frequency.
The synthesiser asks the note class for a sample. After
generating a sample, the ADSR multiplier is applied “The synth
and then returned to the synthesiser. If you’re interested
asks the note
in the maths behind this, it’s worth having a read of the
Wikipedia page: http://bit.ly/1KgI9dp.
class for a
The note class does as much maths as the ADSR sample. After
class, so it is optimised as much as possible using generating a
cdef keywords. The cpdef keyword used for the sample, the
next_sample function means that the function can be ADSR multiplier
called from a non-cdef class. However, the main synth is applied
class is much too complicated to give static types to
and then
absolutely everything.
returned to the
10 The audio flow synthesiser”
This synth class is the main class of the application.
It has two sample buffers that are the length of the
buffer size. While one buffer is being played by the
sound card, the other buffer is being filled in a different
thread. Once the sound card has played a buffer, the
callback function is called. References to the buffers
are swapped and the buffer that has just been filled is
returned to the audio library.
The smaller the buffer size, the lower the latency.
The Raspbian image isn’t optimised for real time audio
by default so you may have trouble getting small buffer
sizes. It also depends on the USB sound card used.
11 Synth loop
The start method of the synth class initialises the audio
hardware and then starts the synth_loop method in
its own thread. While the exit event is set to false, the
do_sample function is called.
The do_sample function loops through the notes
that are currently turned on and asks for a sample from
each one. These samples are shifted right by three (ie “There is a
divided by 2^3) and added to out_sample. The division
mapping of
ensures that the output sample can’t overflow (this is a
very primitive method of adding notes together, but it
letters on
works nonetheless). a keyboard
The resulting sample is then put in the sample to MIDI note
buffer. Once the buffer is full, the more_samples numbers for an
condition is cleared and the synth_loop thread waits to entire keyboard
be notified that the buffer it has just built has been sent octave. We
to the audio card. At this point, the synthesiser can fill
have tried to
up the buffer that has just finished playing and then the
cycle continues. match the
letter spacing
12 Turn on notes to how a piano
There are both note_on/off and freq_on/off functions is laid out to
that enable either MIDI notes or arbitrary frequencies to make things
be turned on easily. Added to this, there is also a toggle
easier”
note function which keeps track of MIDI notes that are
on and turns them off if they are already on. The toggle
note method is used specifically for keyboard input.
Above The simple user interface. Notice how the step size in
the wavetable varies with frequency
The Code SIMPLE SYNTH
#!/usr/bin/python2
import pyaudio
import time
from array import *
from cpython cimport array as c_array
import wave
import threading
import tty, termios, sys
07 class MIDITable:
# Generation code from
# http://www.adambuckley.net/software/beep.c
def __init__(self):
self.notes = []
self.fill_notes()
def fill_notes(self):
# Frequency of MIDI note 0 in Hz
frequency = 8.175799
def next_val(self):
self.samples_gone += 1
if self.samples_gone > self.samples_per_ms:
self.samples_gone = 0
else:
return self.multiplier
if self.state == ‘A’:
self.multiplier += self.attack
if self.multiplier >= 1:
self.state = ‘D’
elif self.state == ‘D’:
self.multiplier -= self.decay
if self.multiplier <= self.sustain_amplitude:
self.state = ‘S’
elif self.state == ‘R’:
self.multiplier -= self.release
return self.multiplier
The Code SIMPLE SYNTH
09 cdef class Note:
cdef int wavetable_len
cdef float position, step_size
cdef c_array.array wavetable
cdef public float freq
cdef public object adsr
cdef public int off
def __repr__(self):
return (“Note: Frequency = {0}Hz, ”
“Step Size = {1}”).format(self.freq,
self.step_size)
adsr = self.adsr.next_val()
# Need to turn the note off
# synth will remove on next sample
if adsr < 0:
self.off = 1
return out_sample
pos_int = int(self.position)
pos_dec = self.position - pos_int
# Do linear interpolation
p1 = self.wavetable[pos_int]
p2 = 0
return out_sample
class Synth:
BUFSIZE = 1024
SAMPLERATE = 44100
def __init__(self):
self.audio = pyaudio.PyAudio()
self.load_wavetable()
self.notes = []
self.notes_on = []
def stream_init(self):
self.stream = self.audio.open(
format = pyaudio.paInt16,
channels = 1,
rate = Synth.SAMPLERATE,
output = True,
frames_per_buffer = Synth.BUFSIZE,
stream_callback = self.callback)
def load_wavetable(self):
# Load wavetable and assert it is the
# correct format
fh = wave.open(‘square.wav’, ‘r’)
assert fh.getnchannels() == 1
assert fh.getframerate() == Synth.SAMPLERATE
assert fh.getsampwidth() == 2 # aka 16 bit
def swap_buffers(self):
tmp = self.playbuf
self.playbuf = self.newbuf
The Code SIMPLE SYNTH
self.newbuf = tmp
# Setting the condition makes the synth loop
# generate more samples
self.more_samples.set()
self.newbuf[i] = out_sample
def synth_loop(self):
cdef int i
def start(self):
self.stream_init()
# Start synth loop thread
t = threading.Thread(target=self.synth_loop)
t.start()
13 class KBInput:
def __init__(self, synth):
self.synth = synth
@staticmethod
def getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN,
old_settings)
return ch
def loop(self):
while True:
c = self.getch()
The Code SIMPLE SYNTH
13 if c == ‘q’:
self.synth.stop()
return
if c in self.keymap:
n = self.keymap[c]
self.synth.toggle_note(n)
if __name__ == “__main__”:
s = Synth()
s.start()
kb = KBInput(s)
kb.loop()
RasPiViv
Nate Bensing tells us how he built an environmental
control system to keep seven poison dart frogs cosy
So, what do you keep in the vivarium?
Right now I have seven poison dart frogs –
they’re frogs from South America that, in the
wild, excrete poison alkaloids, but in captivity, because their
diet is just fruit flies, they can’t produce any poison. They’re
something I’ve been interested in for quite a long time. I
think I saw them first when I was in grade school at a trip
to the Denver zoo, and I just thought they were the coolest Nate Bensing
animals I’d ever seen in my life. I’ve wanted to keep them is a marketing
since then but the opportunity never came up – they’re consultant,
kinda rare – until I found a breeder on Craigslist who has photographer and
an incredible collection and he breeds them to support his graphic designer for
hobby. So right now I have a total of seven: two blue poison Wheaton Design in
dart frogs, which I think could be a breeding pair, and I Northern Colorado.
recently obtained five yellow-banded poison dart frogs. He enjoys learning
about electronics,
What kind of requirements do you have for the creating automation
vivarium, then? projects, and
The temperature is really important, which a lot of people contributing as
have trouble with because your house temperature is much as he can
going to be about the same as an enclosed box, give to the Pi and Linux
or take, as lighting can heat things up. But you have to communities that
maintain specific temperatures between about 75 and 85 made this possible.
degrees, and the humidity is even more important because
the frogs use the humidity to thermoregulate, kinda like
how we sweat.
So basically, what I needed was a way to monitor and
regulate the humidity. I looked around online for a couple
of days trying to come up with a solution – a lot of people
use little timers, and there are a couple of systems that are
made for this but they don’t do very much.
Below RasPiCam is
great for remote
Mostly, our tutorials are about completing a video viewing
specific project and reaching a particular
goal. However, this time we’re doing
something a bit different. We are showing
you some Android apps that you can use
along with your Ras Pi. These apps aren’t
tied to particular projects – you can use
them whenever and as often as you like
– but we think they can add something to
your whole experience with the Pi.
Some of the apps in our list are Pi-
specific, while others are more general
but have a Pi relevance. Chances are
you might already know or use one or
two, but we hope that you can discover
something new from the selection on
offer. If you have an Android phone or
tablet and have not explored the range
of apps available for your Raspberry Pi,
you might be missing out on some cool
and very useful options.
RaspiCam Remote RasPi
If you are into apps that use the Pi camera then Check
here’s a neat free app that lets you access it When you want
remotely. You can save images to your Android to check info like
device so you can access them later and it will run a the free memory
video mode based on single-frame capture. of your Pi or its
network status,
AndFTP (your FTP client) processes and
Sometimes you might need to transfer files onto such, set up SSH
your Pi, and for this you may appreciate AndFTP. login and use the
It can serve more devices than the Pi and could free RasPi Check on
be useful if your Pi is a web server. The free version your Android tablet
is competent, while the Pro version at £3.89 adds in or phone. The app
features like folder sync. can also restart
and stop the Pi,
Raspi-R and send custom
This is a well-featured remote control app that commands, too.
can accommodate more than one Pi. As well
as monitor the status of your Pi, you can execute
Linux commands, remotely control and reboot the Pi,
and handle Python3 scripts. A free app with in-app
purchases available.
VNC Viewer
For even more direct remote control of your Ras Pi,
we recommend checking out VNC Viewer. This is
an excellent VNC client that enables you to view
and control your Pi’s desktop GUI if you’ve got a VNC
server running on it. RealVNC, makers of the VNC Viewer
app, have an open source version of their VNC software
available to download on their website, and you can
also get hold of a free license for the main VNC software,
which is only for personal use and does not include
encryption. We like using the tightvnc server.
Run science experiments
on the ExpEYES kit
ExpEYES is an affordable digital oscilloscope with a signal
generator, and other features – perfect for electronics
ExpEYES is a relatively unheard of but very
THE PROJECT
impressive hardware and software platform ESSENTIALS
for science and electronics experimentation,
Raspberry Pi
as well as a useful electronic probing tool for makers
ExpEYES kit
and professionals alike. It is also open source on both http://bit.ly/1AR15dz
the hardware and software sides, which makes it
affordable and versatile.
ExpEYES is billed as a science and experimentation
kit but really it is much more than that – it is a fully-
functioning four-channel digital oscilloscope with an
impressive array of features. ExpEYES ships with a
wealth of online documentation in a variety of formats
(graphics, user guides, web content), including upwards
of 50 suggested experiments, and the kit itself contains
all of the hardware required to play around with the
interesting science of electronics contained within the
guide material.
The aim is to enable the learning of what can
be complex concepts of electronics in an easy and
affordable way, without getting bogged down in the
arcane details. Paired with our favourite little single-
board computer, the Raspberry Pi, you have an
extremely powerful and affordable device. “The aim is
to enable
the learning
01 Get the parts of what can
ExpEYES is available to purchase from a variety of online be complex
vendors, including CPC (http://cpc.farnell.com), for concepts of
around £50. It is possible to get the kits slightly cheaper electronics in
from India (see http://expeyes.in/hardware.html for an easy and
other vendors worldwide), however it’s likely to end up
affordable
costing more due to higher shipping rates as well as
potential import fees and duties. way”
02 Open it up Supported
The ExpEYES kit contains everything you need to get platforms
underway, with over 50 documented experiments The ExpEYES
from the ExpEYES website. The only other item that may software is mainly
come in handy is a breadboard. You will also need a written in Python.
Raspberry Pi, or another computer with a USB port, This means that
in order to run the digital oscilloscope software and the core software
connect to ExpEYES. to run your ExpEYES
device is quite
03 What’s inside? platform-agnostic –
As you may have guessed, the ExpEYES kit includes if the device can run
the main ExpEYES USB digital oscilloscope, but it also a Python interpreter
contains a wide range of other hardware including and has a Python
a DC motor, magnets, LEDs, coils, piezoelectric discs, module enabling it
wiring, a small screwdriver for opening the screw to access the serial
terminals and more. You also get a live CD which port, then it will
contains all the ExpEYES software and documentation work with ExpEYES.
ready to go on a bootable disc. If you visit the
ExpEYES website,
04 What can it do? there is a page that
The chip at the heart of ExpEYES is an AVR ATmega16 explains how to
MCU (microcontroller unit), running at 8 MHz coupled install the software
to a USB interface IC (FT232RL). These are low-cost on Linux and
but provide good value for money. As we have Windows – http://
already mentioned, ExpEYES is therefore capable www.expeyes.in/
of acting as a four-channel oscilloscope but also software.html.
has a built-in signal generator, 12-bit analogue
resolution, microsecond timing resolution and a 250
kHz sampling frequency. At this price point, that’s
an impressive set of features and certainly accurate
enough for anything that is not mission critical (like
learning, hobby projects, quick readings and so on).
05 Using the live CD
Perhaps the easiest way to get up and running with
ExpEYES (if you have a computer with a CD drive) is to
use the live CD which is included in the ExpEYES kit.
Making sure that you are booting into the live CD from
your BIOS boot menu, you should then be greeted with
a Linux-based desktop. Plug in your ExpEYES by USB and
you can open the software from the menu by going to
Applications>Science>ExpEYES-Junior. Alternatively, you
can run it from a terminal window using:
sudo python /usr/share/expeyes/eyes-junior/
croplus.py
08 Install dependencies
ExpEYES has a number of dependencies that are
required for it to run under Linux, as well as a number
of other recommended libraries. During the installation
undertaken in Step 7, the dependencies should be
Above The ExpEYES
installed by default. However, to avoid any problems hardware has a
later, you can run the following command in order to female header,
making it simple to
make sure that they are all installed: plug in jumper wires
sudo apt-get install python python-expeyes
python-imaging-tk python-tk grace tix python-
numpy python-scipy python-pygrace
import expeyes.eyesj
p=expeyes.eyesj.open()
14 The Python library (continued)
Now we will plot a sine wave using the ExpEYES and
PyLab libraries. On the device, connect OD1 to IN1 and
SINE to A1 with some wire. Run the following code and
you should see that a sine wave has been plotted. “The custom
Python library
import expeyes.eyesj is slightly
from pylab import * harder to use
than the GUI
p=expeyes.eyesj.open()
and not as
p.set_state(10,1)
print p.set_voltage(2.5) pretty, but
ion() # set pylab interactive mode it enables
t,v = p.capture (1,300,100) a lot more
(plot t,v) versatility”
15 Further experiments
This tutorial has shown you just a single example of
the documented ExpEYES experiments available at
http://expeyes.in. There is a wide variety of different
techniques and phenomena explored in those
experiments, so it is highly recommended to get your
hands on an ExpEYES kit and work through them.
Running through those examples as a beginner will
give you a much deeper understanding of electronics.
16 The verdict
A digital storage oscilloscope (plus extras) is a
useful tool in any engineer or hacker’s toolbox, as
it enables you to get insights into your projects that
aren’t possible with just visual checks or using a
multimeter. Whilst no £50 oscilloscope will compare to
expensive professional units, this is a great entry-level
Below The project
product as well as a versatile, portable USB device documentation can all
with multiplatform support for when you just can’t be be found on GitHub:
https://github.com/
lugging around a 10 kg, £1000+ scope. expeyes/expeyes-doc
FAQ What is PaPiRus?
Need a low-cost, low-power display for your Pi project?
Check out the amazing PaPiRus HAT!
I’m guessing this is not about vintage papercraft, then? “Well, the
Not this time, although the PaPiRus is quite paper-like in PaPiRus is a
many ways. HAT module for
Well, now I’m confused. So what exactly is the PaPiRus?
the Raspberry
Well, the PaPiRus is a HAT module for the Raspberry Pi that Pi that adds an
adds an ePaper display to it for you to use in your projects. ePaper display
to it for you
Remind me again – what exactly is a HAT module? to use in your
The Raspberry Pi Foundation released something called projects”
the HAT specification, which is a set of guidelines for
producing Raspberry Pi add-ons that sit nice and neatly on
top of the Pi itself – Hardware Attached on Top – and which
also makes things much easier for their end users. So the
PaPiRus is an add-on board that fits in with the Foundation’s
particular specifications.
append = newlist.append
for word in oldlist:
append(word)
c = a * b
LinuxUserMagZJVYLK9MVY
*PUUHTVU+LZR[VW
How do I get a
Great question! If you have a Pi
Wi-Fi signal into
LinuxUserMagZJVYLK8MVY
Awesome
Upgrades