Go Down

Topic: playing wav's on through a r2r 8 bit DAC (Read 518 times) previous topic - next topic

Byte3

Hi all,

I have made a R2R Ladder 8-bit DAC and it operates okay. I'm looking for advice on how to play wav files through it. I have a sd-card reader hooked up. I'm looking to do it from scratch, unless there is an easy library already out there, I can't find it, I don't wanna buy a pre-built thing right now if I can code it from scratch.

Byte3

I found a search has helped: https://forum.arduino.cc/index.php?topic=344846.0

Grumpy_Mike

Quote
I have made a R2R Ladder 8-bit DAC and it operates okay.
You sure of that? You can't make one using 1% resistors you know. The problem will be the lack of monotonicity.
This means it will not be "true" 8 bit audio but worse than that.

Byte3

Thanks Mike,


Quite right I wasn't sure. I have chosen to save myself some time and buy a pre-made 16 bit stereo wav all in one thingymagic.

Lucario448

#4
Nov 01, 2019, 12:23 am Last Edit: Nov 01, 2019, 12:26 am by Lucario448 Reason: List tags that came out of nowhere after posting
If quality isn't an issue, then I would do something similar as TMRpcm does:

  • Read the header to figure out the sample rate it should be played (4 bytes at offset 0x18 or 24 as an unsigned long). I don't recommend you exceeding 48 KHz due to RAM and timing constrains.
  • Make a "double buffer" of at least 128 bytes each (254 maximum to avoid greater overhead caused by larger-than-8-bits integer arithmetic).
  • Create a timed interrupt that fires every period of the file's sample rate (obtained in the first point). This interrupt will update the output to the next sample coming from one of the two buffers and signal a buffer reload when necessary. You can use the TimerOne library for that (period is set in microseconds).
  • Handle buffer reloading in the loop() if the Arduino will be dedicated to play a single file without pausing or skipping (or literally anything else). Otherwise it would have to be done in another timed interrupt (and allowing nested interrupts in order to not disrupt the playback itself).
  • Fill up both buffers before commencing playback. In a WAV file, samples begin 4 bytes after the string "data" on the header; usually at offset 0x2C or 44 if no ID3 tags or any other metadata was added.

I know this sounds like a lot of work to do, but I couldn't just say reuse the TMRpcm library because it requires an effort on modifying it anyways.



PD: remember to arrange the ladder to the pins 0 to 7 (being the last one the MSB), a direct "port write" will set the state of all these 8 pins at once, also avoiding signal "glitches" in the way.

Also remember that the output has a quite high impedance; so to drive a speaker you need some sort of amplification.

Go Up