Monday

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

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)

AutoAnalogAudio Library - nRF52 Now supports Successive Approximation Analog-to-Digital Converter for Audio Input

 AutoAnalogAudio Library - nRF52 Now supports SAADC Support for Successive Approximation Analog-to-Digital Converter for Audio Input I'v...