ymduino was originally a project to implement an interface between the Yamaha YM2149 (datasheet) and the Arduino Uno much like the once seen here. It has since evolved to be a mostly "standalone" Atari ST chiptune player.
The project was originally stalled for a very long time: 2 years! I had hit a
roadblock where I wasn't sending the signals to the sound chip correctly and
thought I needed an oscilloscope to correctly diagnose the problem. After
looking at the source code recently I figured out that the issue was caused by
some poorly thought out manipulation of the
register and was able to get it working without an oscilloscope.
The YM2149 was one of the most common sound chips for home computers and video game systems in the 1980s--one of them being the Atari ST. However, the reason that I chose to use it in this project is that there exists a common chiptune format for it: YM, which is fairly well documented and easy to use. The format is amenable to playback with and Arduino because in its raw, uncompressed form--it is just a dump of the 16 (actually 14) registers of the YM2149 at 50 Hz. Fancier features, such as fast, carefully timed interrupts or other routines to produce more complex sounds are not needed to produce basic Atari ST music. By the way, 50 Hz happens to be the refresh rate for the PAL video standard; this is unsurprising given that in the 80s home computer design often revolved around the timing of the video signal.
One of the issues noticed by Oryx in this
implementation of an Atari ST player was that using the standard
digitalWrite() function of an Arduino to control the YM2149 was too
slow. Specifically, the datasheet for the YM2149 states that the pins
controlling the mode of the chip (read, write, address) must be switched within
50ns of each other (this makes sense as the YM2149 is clocked at 2MHz). The chip
will work if this timing requirement isn't met, but the music will sound
increasingly distorted the further out of time the signals are sent. The fix is
to use some lower level Arduino primitives--namely the PORTD registers to
flip the bits quickly.
This was where I had messed up my implementation previously. I was setting the
PORTD bits to hardcoded values such as 00001100 instead of realizing
that I was also using some other pins controlled by the
to write data to the YM2149. The net result was the changing the operation mode
of the chip also clobbered the register address/data I was trying to send to the
YM2149. Unfortunately, this problem was difficult to debug because addressing
the YM2149 incorrectly just causes the chip to do nothing. The fix is to only
manipulate the desired pins when using the
PORTD register. For example,
to only set the two least significant bits to 1,
PORTD |= 11000000
should be written instead of
PORTD = 11000000. Likewise, to set bits
low, a bitwise AND operation should be used:
PORTD &= 00111111.
This wasn't originally part of the project plan, but I figured it would be much cooler to have the board play music without needing a laptop tethered to it. It's "standalone" in quotes in the sense that it needs a laptop to dump .YM files to a raw, uncompressed format that is easily streamable by the Arduino, but otherwise just needs an AC adapter and a capable line-in jack. The SD card libraries for the Arduino made this part very simple once the SPI pins are hooked up.
The total time needed for the Arduino to read 14 bytes of data off of a microSD card and ship it off to the YM2149 is well under 2000μs, so it's about 10X faster than the bare minimum needed to stream music.is well under 2000μs, so it's about 10X faster than the bare minimum needed to stream music.
A cool way to get a cheap music visualizer for free or without burning up too much computational on the Arduino is to dump the contents of one of the registers--say the fine pitch adjust value of one of the oscillators to a shift register that will drive a small array of LEDs. For around three pins and not much microcontroller time you get a somewhat interesting visuals.
The final parts count of the project is extremely low. Other than the Arduino and SD stuff--all that is added is the YM2149 itself, a 1K resistor for the output of the sound chip (common-collector amp??), the shift register, LEDs, and current limiting resistors for the LEDs.