Raspberry Pi AY-3-8910

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.

Some Videos

Initial test:

Now in stereo. It's hard to get the lighting right to show the LEDs.

Has an audio plug now, but still recording video the old fashioned way with a cheap camera (in the dark).


Build directions:

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: Schematic 1, Schematic 2.

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 AY-3-8910 datasheet. 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).

See the README for a bit more info.

Future Work


All the code can be found on github: https://github.com/deater/vmw-meter.git

git clone https://github.com/deater/vmw-meter.git

Look in the ay-3-8910 directory.

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.

Build Log

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 be working.

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 help.

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 weren't working.

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 office window 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 this manually.

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 this.

22 September 2016

Worked on improving the 8x16 display. Some new features, and the buttons now work.

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.

14 September 2016

This project was posted on the official Raspberry Pi foundation blog, cool.

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 growing up 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 Hackaday. 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).

shift register leds

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.

23 August 2016

Printed out manuals, reading them.
Other projects at the VMW Hardware/Software Productions Page