This is not the most original project, but working on my
Apple II KSP project got me thinking about
ancient sound cards, specifically the Mockingboard Sound available
on old Apple IIs.
These boards used the AY-3-8910/1/2 sound chips, which can generate
3 channels of square waves with other effects. They were commonly
used in some Spectrum and Atari computers, among other places.
There is/was quite a scene about generating chiptunes for these chips.
So the goal of this project is to have a Raspberry Pi play YM chiptune
files onto an actual AY-3-8910 along with some fun LED visualization.
Now in stereo. It's hard to get the lighting right to show the
Has an audio plug now, but still recording video the old fashioned way
with a cheap camera (in the dark).
I didn't plan for this to get popular so I wasn't really ready
with full build directions. I usually don't post those until I have
a circuit board and everything. The really awful hand-drawn
schematics from my notebook are here:
The AY-3-8910 is fairly straightforward.
Three channels of square waves plus various noise and envelope effects.
Provide a clock (1MHz in our case)
and there are 16 (well, 14) on-chip registers you write to.
Just put the address then the 8 bit value
on the bus, toggle the 3 bus control pins, and you are set.
You'll want to do this fairly fast.
A typical YM music file wants you to write all 14 registers every 50Hz.
Note that you can easily use an AY-3-8912 rather than AY-3-8910
(although the pinout is different, be careful). The 8910
has two 8-bit I/O ports taking up a lot of the pin count and this project
does not use those at all.
I use 3 of the Pi's GPIOs to shift an 8 bit value into a
75HC595 shift register.
Then I use 3 more to drive the AY-3-8910 control bus.
Visualization is done with some i2c LED displays.
The amplifier originally was an LM386 design from Figure 16 of the
I currently am using an Adafruit MAX98306 breakout instead but I'm
not 100% happy with the sound quality (need a voltage divider on the output
to not get clipping and I probably have that designed wrong).
Use SPI to drive the shift register instead of GPIO
Optimize the software.
Even using libbcm2835 it's hard to hit 50Hz from inside
Linux (maybe use my
custom low-level OS instead).
The overhead wouldn't be quite so bad if I were using a parallel load
of the registers, but that would have taken 11 GPIOs (with
3.3V to 5V level conversion).
I do need to make a bare metal design, because it's sad to have
the Pi shown better by an old 6502 Apple II running at 1MHz
French Touch "Pure Noise" Demo)
Note: this code is a work-in-progress so it's not polished (especially
the user interface). Feel free to use it such as it is but I am probably
making annoying changes all the time (like the switch to stereo output).
I don't include many (any?) YM files, not sure about copyrights.
Will have to start writing my own.
14 April 2017
Have the PCB for the sound board about 75% done then realized I had
put the Pi-2 flush against the corner where a mounting screw would be
in the way. Had to move everything over 300mils. Need to find time
to finish this.
22 March 2017
Got the volume control on the max98306 working using GPIOs.
The 74AHCT125N chips work wonders, though I'm wasting a lot of gates
as I don't have a nice even amount of signals.
Next up is seeing if I can sort out the headphone issues.
21 March 2017
Finally got SPI working! 8ms latency (versus 14ms when bitbanging)!
Level shifters made all the difference.
Here's a picture of me debugging the issue with LEDs before reconfiguring
the shift registers to use SPI.
20 March 2017
I was doing some timing.
To hit 50Hz you can't have more than 20ms of latency each frame.
Adding the 3 additional i2c displays (14-seg alphanum) pushes it up
to 21ms. So time to see if I can get SPI going for good, as that's much
faster than bitbanging the shift registers like I'm doing now.
The parts order finally escaped from New Jersey, which is good, because
they contain the key to getting
SPI working (at least with LEDs).
The problem seems to have been that the 3.3V inputs weren't
consistently high enough to drive the 5V serial/parallel latch.
And the level converter I was trying to use was optimized for i2c
and somehow wasn't working right. A more boring 74AHCT125 seems to
17 March 2017
More or less have the display part working. A demo of it in action:
I need to get some shades for that window, makes it hard to see the display.
Now I need to see if I can get the audio board working. Still having
problems with hum, dropouts, headphone detection, high-Z inputs. Analog
is so much harder than digital!
13 March 2017
The purple package finally arrived!
Assembling the board wasn't too bad. Most of the problem was various
holes not being aligned properly, but nothing disastrous.
And it even worked, first try! Not bad. I need to get a better setup
where I can take pictures without glare. The LEDs are so bright they
confuse the camera a bit and having a big window behind things doesn't
Now to get back to debugging the analog side of things.
10 March 2017
I spoke too soon. Never solder things unless they work in a breadboard
first. The level shifter was floating high when the Pi was trying to
do high-Z (which makes sense as it's an i2c optimized level shifter).
I tried dropping the supply to 3.3V to avoid the shifter.
I somehow thought the Pi GPIOs went high impedance when put
into "in" mode, but apparently not high impedance enough, as both the
headphone detect and gain select were leaking enough current that things
Frustrating. Also the 4 Ohm resistors don't sound as nice as the 8 Ohm
resistors. And the filter caps add both pops and hum, which is odd
because they should be a low-pass filter.
Also the headphone jack isn't working with the filter caps on.
Anyway I ordered some different level shift hardware to see if I can
at least get the gain/jack detect working. The package is currently
trapped in New Jersey by a blizzard though.
8 March 2017
The PCB for the display board was finally sent off to be made, now it's
just a matter of waiting for the purple package from OSH Park.
In the meantime I've been working on the sound board. I've even put together
this prototype board that in theory allows software headphone jack detection
as well as software volume control (all level shifted down to 3.3V for
Pi GPIO). Time to hook it up and see if any magic smoke escapes.
22 February 2017
I've been sidetracked on writing code that does the "Still Alive" demo,
with synchronized lyrics. The idea is I can have one chunk of code
that will create a Pi-chiptune Demo, as well as one that can
target my Apple II code.
Here's Chell watching as I test things out. I need some way to block
glare when taking these pictures so the LEDs show up better (my
doesn't have blinds for some reason.)
Also made some art for the 16x8 display. Getting recognizable shapes
in one color is a challenge.
Currently I need to get another Red 14 seg display (looks a bit odd
with that blue one), finish the ym5 chiptune, find some way to get SPI
to work, and then get line-out audio going so I can record without having
all the background noise interfering.
4 February 2017
Still working on things, have been sidetracked trying to write my own
ym5 files to play on the device. Learning a lot about synth envelopes,
ended up almost writing a tracker.
30 September 2016
Further trying to track down why SPI to 74hc595 isn't working for me.
Hooked up a sample driving LEDs and put it on an oscilloscope and
the waveforms from the Pi look perfect. Yet the actual LEDs that
get lit up do not match the signal sent out. Frustrating.
29 September 2016
Tried driving things with SPI rather than GPIO. In theory this should
offload a lot of the bit-twiddling and potentially improve the sound
a bit. Sadly I just could not get this to work. Mysteriously, even
trying to bitbang the SPI GPIOs directly didn't work.
28 September 2016
Improved the player, now looping works.
27 September 2016
Worked on the player. Can now also play YM2, YM3, YM3b and (in theory)
YM4 files. You can also now specify more than one file on the command
line and skip through them using the keypad.
26 September 2016
Use libhasa to decompress YM files, now you no longer have to do
23 September 2016
Added a headphone/line-out jack. It is the type with built in switches
to automatically cut off the speakers when a plug is inserted. However
the amp doesn't like floating inputs. I couldn't find the type of jack
with an independent switch that I could have run to a GPIO and cut off
things in software. I'll have to think about the best way to handle
22 September 2016
Worked on improving the 8x16 display. Some new features, and the buttons
15 September 2016
Cleaned up the ym_play code a lot. It's almost presentable now.
Now there's a hope that if you build a device like this you can
use ym_play and get it working.
It would be nice if people let me know things like this. I noticed my
youtube views had suddenly doubled overnight so I had to do a google search
to find out why.
I admit most of the popularity credit should go to Aleksy Lutsenko's
awesome music (I admit it's the whole reason I started this project).
All I did was hook up a few wires on a breadboard. I doubt this project
would be anywhere near as popular if I had put together a one-channel demo of
Twinkle Twinkle Little Star.
Also, disgruntled Atari and Spectrum users, I do realize that most of
the cool music comes from your scene. I only mention the Apple II
Mockingboard because I actually had a neighbor who had one. For me
Spectrum and Atari computers were mythical things that only appeared
next to BASIC video game listings saying "to make things work on your
ZX81 Spectrum please make these changes".
13 September 2016
Working on getting the 8x16 display able to print things other
than just the waterfall display.
Have time played indicator working.
Need to put out a new video with the new features.
9 September 2016
Have dual AY-3-8910 working. Stereo!
Of course I don't have any 6-channel music files so I'm just
duplicating the 3-channels out both speakers.
6 September 2016
Moved from LM386 amp to an Adafruit MAX98306 breakout.
The output of the AY-3-8910 is too high to hook directly, you need
to put a voltage divider across the output.
Also tweaked the shifter delays, and now we auto-delay the proper amount.
Now we're having no problems hitting 50Hz consistently.
Also worked on the waterfall display. A bit nicer. Was trying to make
it logarithmic but that didn't really work very well.
4 September 2016
Article on this project posted on
The video was possibly also trending on Youtube somehow.
2 September 2016
Have sound and LEDs going!
Here's the above, annotated:
1 September 2016
Fixed issues with sound (off by one error, loose address wires).
Working on the visualization.
Also dropped down to a 1MHz clock, as at 2MHz upsampling 1MHz and 1.7MHz
YM files was causing overflows.
30 August 2016
First sound with this setup! Still some issues though
29 August 2016
Testing to see if I can use a 74HC595 shift register.
Simple test getting output on LEDs worked great (once I figured out
upstream Linux [yes I am running 4.8-rc3 on my pi2] wants you to add 970
to the GPIO number).
26 August 2016
Final batch of parts arrived!
25 August 2016
Wrote some code to decode YM file format.
The LHA compression and the interlaced format is a bit of a pain.