I did something similar on a Raspberry Pi using the GPIO pins one afternoon when bored. I made a 4-bit R2R DAC [1] using typical 5% tolerance resistors and fed it directly into a small speaker. I shrunk a 16 bit audio file down to 4 bits and then toggled the GPIO pins in a loop in Python from Linux userspace around 40 kHz. The result was easily intelligible speech, and easily recognizable, if not exactly pleasant, music. I was surprised how good the results were considering it was made of literally nothing but wire. It was quite noisy, which I assume was from the clock jitter running with an inexactly timed update loop, and the zero filtering.
[1] https://en.wikipedia.org/wiki/Resistor_ladder#R%E2%80%932R_r...