WAV/PCM Library Update:
After reading into the capabilities of the Arduino timers, it seemed possible to generate an audio signal from PCM/WAV data using a single timer. Reading through the documentation, and looking at examples like the Timer1/Timer3 libraries, I found that I could use OCRnA to control duty cycle, ICRn and prescale for frequency, and use an overflow interrupt to update the value of OCRnA according to the defined SAMPLE_RATE, all with one timer.
How it works:
16-bit timer 1 is used for compatibility with different Arduino boards, but 16-bit Timers 3, 4, or 5 could be used on a Mega also.
The timer is set to Phase and Frequency Correct Mode, and set to run at a defined sample rate. The settings for prescale (TCCR1B) and input capture (ICR1) are what determines the frequency of the PWM signal when timer 1 is used, and OCR1A controls the duty cycle.
An interrupt is attached to trigger every time the timer hits bottom. (Generally 16000 c/s) At this rate, an interrupt is generated 16000 times per second, and a new value is set for the duty cycle(OCR1A), then a new value is buffered for the next cycle.
In short, a signal is generated at 16000hz. The length of time each cycle stays turned on is determined by the value read in from the WAV/PCM file, which is updated every cycle.
No buffering: I am not sure of read speeds for SD cards, but testing indicates slightly higher sample rates can be achieved with no modifications. The SD library appears to default to SPI_HALF_SPEED, but will leave that inquiry for another day...
Whats new:
a: This version is completely controlled by interrupts, allowing other functions to run while music is playing.
b: There is no longer a requirement for a large memory buffer, bytes are loaded as required
c: Added function to raise/lower volume: tmrpcm.volume(1);
d: Due to interrupt-driven playback, ability to stop/start music at will is added
Data Format: unsigned 8-bit pcm, 16khz sample rate
iTunes Conversion:
a: Click Edit > Preferences > Import Settings
b: Change the dropdown to WAV Encoder and Setting: Custom > 16.000kHz, 8-bit, Mono
c: Right click any file in iTunes, and select "Create WAV Version"
d: Copy file to SD card using computer
iTunes Conversion:
a: Click Edit > Preferences > Import Settings
b: Change the dropdown to WAV Encoder and Setting: Custom > 16.000kHz, 8-bit, Mono
c: Right click any file in iTunes, and select "Create WAV Version"
d: Copy file to SD card using computer
Function Usage:
TMRpcm tmrpcm; //Declare new object
tmrpcm.speakerPin = 11; //set to 11 for Arduino Mega, 9 for Uno, Duemilanove, etc
tmrpcm.volume(1); // 1 to raise volume, 0 to lower volume
tmrpcm.play("filename"); // plays an unsigned 8-bit wav file from SD card
tmrpcm.stopPlayback(); //stops playback
tmrpcm.playing(); //returns true during playback, false otherwise
Updated Files / Source:
Notice: This version has audio quality issues. See newer blog post for updated version
Source:
Example: music.ino //Plays music while blinking a LED via the loop function
Library Package:
TMRpcm.zip (Current version here)