The ATtiny85 chip at the heart of Trinket has the novel ability to produce a 250 KHz 8-bit PWM signal. That’s four times what the Arduino Uno can muster. A low pass filter circuit then smooths the “square” PWM into a usable audio waveform:
A very basic low pass filter can be made from just a capacitor and resistor. First we need to know the filter’s cutoff frequency — frequencies below this pass through, while higher frequencies (like the PWM signal) are attenuated. A rule of thumb with PWM audio is that the highest usable audio frequency (our cutoff frequency) is about 1/10 the PWM rate. The latter we’ve already established is 250 KHz, so a good cutoff would be 25 KHz.

There’s a relationship between the capacitor and resistor values and the resulting cutoff frequency. Given any two values, we can compute the third. Already having a ton of 0.1 microfarad capacitors around, I just needed to know the corresponding resistor to achieve the desired 25 KHz cutoff (you could also do it the other way — some resistor you have around, determining a suitable capacitor). Rather than bore you with the math, you can just whip out the Circuit Playground app for iOS (select “Circuit Calculators,” then “RC Cutoff Filter,” or you can Google search for “low pass filter calculator” resources on the web and plug in the two known values you have.
For a 25 KHz cutoff and 0.1 microfarad cap, the calculator suggests a 63 Ohm resistor. That’s not a standard value you’ll find anywhere, so we just select the next common size up from there: 68 Ohms. I happened to have a bunch of 75 Ohm resistors around…that’s close enough, this isn’t precision work.

The filtered output is then fed into a 10K potentiometer for volume adjustment (you can leave this part out, but the volume will always be at the maximum) and then through a 10 microfarad capacitor that provides “AC coupling” — so the audio waveform is centered at 0 Volts rather than 1.65V (one half the Trinket’s operating voltage). The output is split to both the right and left channels of a 1/8" phono jack, to which headphones or an amplified speaker can be connected.

It’s very important that a 3.3V Trinket is used; this voltage is directly compatible with the flash memory chip. Adding the level shifting circuitry would defeat the smallness of the Trinket.
The power source can be anything the Trinket can handle: a small 3.7V LiPo cell, three or four AA or AAA alkaline cells, etc. You can also plug into USB, but there’s a 10 second timeout while the bootloader runs its course before the playback sketch runs.

Trinket Pin #4 (audio output) MUST BE DISCONNECTED before code can be uploaded to the board! If you solder the circuit permanently in a proto board, it's strongly recommended that the Trinket be socketed, or add a jumper between pin 4 and the RC filter so it can be disconnected when new code is uploaded to the chip.
The audio connection interferes with USB. Disconnect pin 4 or unplug Trinket from the breadboard before uploading code. Then reconnect afterward.
Load the sound playback sketch in the Arduino IDE:

File→Sketchbook→Libraries→Adafruit_TinyFlash→TrinketPlayer

Select “Adafruit Trinket 8 MHz” from the Tools→Board menu. Disconnect pin 4 (or remove Trinket from the circuit), press the reset button, then click Upload. After uploading, assuming all else is wired properly, your audio should start playing immediately. As the code is currently written, the sound will loop forever. You could change this to stop after the music plays, then use the reset button to restart.

This code only works on the Trinket. It uses special registers and will not compile on the Uno or other Arduino boards.
This guide was first published on Oct 21, 2013. It was last updated on Oct 21, 2013.
This page (Sound Playback) was last updated on Sep 30, 2020.