Digital Audio 101: Playing Audio from a Microcontroller
blog.tarkalabs.com
blog.tarkalabs.com
At 8/16 mhz there are plenty of cycles for multi-channel audio synthesis. Not much room for samples, but a lot can be done with envelopes, saw, square, and noise waveforms.
Obviously it's not going to be ideal for an audiophile, but the quality is not too shabby. A fun project for those curious.
Still, stick to off-the-shelf class-D amplifiers, such as the PAM8403.
Pretty sure you can do that. A Class D amplifier is to a class A/B traditional one what a switching power supply is to a linear one, so I would expect to be able to make a class D amplifier using for example a PWM driven H bridge usually employed to drive electric motors, or a chip used to make switching power supplies. If they can work at high frequencies (say 50KHz or more) then they should work; all it's needed is modulating their input or feedback pins the right way. Probably not HiFi for the sensitive ear, still good enough.
LoFi effects pedals could be fun.
As long as the PWM D/A has a good clock to keep the PWM ratio accurate, I think it should be eminently listenable, given a proper reconstruction filter and a decent power supply.
It would be fun to try this.
So, for example, a speaker will become an inductor with a series resistor to represent losses, and another resistor to represent power that is converted to audio.
The reason for asking is that I want to be able to plug it into a simulator (spice) and also simulate the mechanical part (using an electrical equivalent circuit).
EDIT: found something here: https://audiojudgement.com/speaker-equivalent-circuit/
.subckt sub_pickup_1 a b
L0 a 1 2.5 NT=1
Rs 1 b 5000
Cp a b 3.0E-11
Rp a b 10000000
V1 a 2 DC 0 AC 0.01 0 SIN(0 0.05 440 0 0 0)
R1 2 b 1
.ends sub_pickup_1
xL1 7 0 sub_pickup_1You can also use a scheme a little bit like PWM called PCM where the GPIO pin can be switched on and off at a frequency much higher than audio (typically 2Mhz or higher) and the duty cycle is varied at the sample rate. This can be implemented on an Arduino using code like https://github.com/damellis/PCM/blob/master/PCM.c
A big issue I ran into was filling up the data memory, which was what required such limiting quantization. I'm curious if anyone has tried doing this sort of audio but using a noise-shaping quantizer (i.e. Delta Sigma Modulation), as that was my next plan but I forgot about the project.
With DSM, you can generate a higher frequency 1 bit sequence, that when filtered recovers the original audio signal. The benefit here being that for the same amount of storage space, you can push the quantization noise into higher frequencies that aren't as prevalent in speech/music, then filter it off.
Any modern Cortex-based microcontroller has more than enough oomph to handle 4x as many voices plus filters, etc.
If you've got multiple cores it's no problem: Just run the note-playing code on a different core. However, if you've only got one core you'll need some method to play those notes without disrupting the main loop.
Most chips will have some sort of PWM or advanced timer peripheral that can generate waveforms on a pin without direct CPU intervention. You write to registers to change the frequency, duty cycle, etc.
Many chips also include asynchronous DACs, but they're usually too low-resolution for high-fidelity audio.
Most microcontrollers also include some form of DMA, which can shuttle data between peripherals and memory without CPU intervention. You can also user timer peripherals to trigger DMA transfers, which lets you send buffered data to a DAC on a KHz schedule while the CPU does other things.
And of course, you can usually use timer peripherals to periodically interrupt the main thread when you don't want to wait in a busy-loop.
In DuinoTune [1] the song playback had a per song 'tick' timer interrupt at 12 per beat which handles note on/off, envelope, pitch/audio glides. And a per-sample timer interrupt which does a mixdown of the voices and updates the hardware PWM duty-cycle to generate the waveform.
A Wav-playing doorbell with an ATTiny85 to play wave files from an SD-card