Created
February 11, 2023 15:08
-
-
Save raphox/4605a8756516f14e2c8ea371eda908ec to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#include <SPI.h> | |
#include <SD.h> | |
#include "AutoAnalogAudio.h" | |
/******** User Config ************************************/ | |
#define SD_CS_PIN 5 | |
#define AUDIO_DEBUG | |
//Number of ADC readings to sample in a single request. Set to MAX_BUFFER_SIZE or a number < 512 | |
uint32_t adcReadings = MAX_BUFFER_SIZE; | |
/*********************************************************/ | |
AutoAnalog aaAudio; | |
File myFile; | |
#include "myWAV.h" | |
bool doADC = false; | |
bool firstADC = false; | |
void setup() { | |
Serial.begin(57600); | |
if (!SD.begin(SD_CS_PIN)) { | |
Serial.println("SD init failed!"); | |
return; | |
} | |
Serial.println("SD ok\nAnalog Audio Begin"); | |
aaAudio.begin(1, 1); // Start AAAudio with only the DAC (ADC,DAC,External ADC) | |
aaAudio.autoAdjust = 0; // Disable automatic timer adjustment | |
aaAudio.setSampleRate(80000); | |
aaAudio.dacBitsPerSample = 8; | |
} | |
void loop() { | |
if (Serial.available()) { | |
char input = Serial.read(); | |
switch (input) { | |
case '1': playAudio("/M8b24kM.wav"); break; //Play a *.wav file by name - 16bit, 32khz, Mono | |
case '2': playAudio("/M8b24kS.wav"); break; //Play 16bit, 32khz, Stereo | |
case '3': playAudio("/M8b44kST.wav"); break; //Play 16bit, 44khz, Mono | |
case '4': playAudio("/M16b24kS.wav"); break; //Play 16bit, 44khz, Stereo | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
uint8_t channelSelection = 2; | |
uint32_t loadBuffer(); | |
void DACC_Handler(void) { | |
aaAudio.dacHandler(); //Link the DAC ISR/IRQ to the library. Called by the MCU when DAC is ready for data | |
uint32_t samples = loadBuffer(); | |
if (samples) { | |
aaAudio.feedDAC(channelSelection, samples); | |
} | |
} | |
float volumeVar = 1.00; | |
/* Function to open the audio file, seek to starting position and enable the DAC */ | |
uint32_t endPosition = 0; | |
void playAudio(const char *audioFile) { | |
uint32_t sampleRate = 16000; | |
uint16_t numChannels = 1; | |
uint16_t bitsPerSample = 8; | |
uint32_t dataSize = 0; | |
uint32_t startPosition = 44; | |
Serial.println("Play"); | |
if (myFile) { | |
Serial.println("Close Current"); | |
//Ramp in and ramp out functions prevent popping and clicking when starting/stopping playback | |
aaAudio.rampOut(0); | |
aaAudio.disableDAC(); | |
myFile.close(); | |
} | |
//Open the designated file | |
myFile = SD.open(audioFile); | |
if (myFile) { | |
myFile.seek(22); | |
myFile.read((byte*)&numChannels, 2); | |
myFile.read((byte*)&sampleRate, 4); | |
myFile.seek(34); | |
myFile.read((byte*)&bitsPerSample, 2); | |
myFile.seek(40); | |
myFile.read((byte*)&dataSize, 4); | |
endPosition = dataSize + 44; | |
if (myFile.size() > endPosition) { | |
//startPosition = myFile.size() - dataSize; | |
endPosition = dataSize + 44; | |
myFile.seek(endPosition); | |
uint8_t buf[myFile.size() - (endPosition)]; | |
myFile.read(buf, myFile.size() - (endPosition)); | |
Serial.println("Metadata:"); | |
Serial.println(myFile.size() - (endPosition)); | |
for (int i = 0; i < myFile.size() - (endPosition); i++) { | |
Serial.print((char)buf[i]); | |
} | |
Serial.println(); | |
} | |
if (bitsPerSample > 12) { | |
bitsPerSample = 16; | |
} else if (bitsPerSample > 10 ) { | |
bitsPerSample = 12; | |
} else if (bitsPerSample > 8) { | |
bitsPerSample = 10; | |
} else { | |
bitsPerSample = 8; | |
} | |
sampleRate *= numChannels; | |
Serial.print("SampleRate "); | |
Serial.println(sampleRate); | |
Serial.println("Set smp rate"); | |
bool stereo = numChannels > 1 ? true : false; | |
aaAudio.setSampleRate(sampleRate, stereo); | |
aaAudio.dacBitsPerSample = bitsPerSample; | |
//Skip past the WAV header | |
myFile.seek(startPosition); | |
//Load one buffer | |
loadBuffer(); | |
//Feed the DAC to start playback | |
if (aaAudio.dacBitsPerSample == 8) { | |
aaAudio.rampIn(aaAudio.dacBuffer[0]); | |
} else { | |
aaAudio.rampIn((uint8_t)aaAudio.dacBuffer16[0]); | |
} | |
aaAudio.feedDAC(channelSelection, MAX_BUFFER_SIZE, true); | |
} else { | |
Serial.print("Failed to open "); | |
Serial.println(audioFile); | |
} | |
} | |
/* Function called from DAC interrupt after dacHandler(). Loads data into the dacBuffer */ | |
uint32_t loadBuffer() { | |
uint32_t samplesToRead = 0; | |
uint32_t metaDataSize = myFile.size() - endPosition; | |
if (myFile) { | |
if (myFile.available() > metaDataSize + 1 ) { | |
samplesToRead = MAX_BUFFER_SIZE; | |
size_t availableBytes = 0; | |
if (aaAudio.dacBitsPerSample == 8) { | |
//Load 32 samples into the 8-bit dacBuffer | |
if ( (availableBytes = (myFile.available() - metaDataSize)) <= samplesToRead) { | |
samplesToRead = availableBytes; | |
Serial.print("File Size "); | |
Serial.print(myFile.size()); | |
Serial.print(" Bytes Read "); | |
Serial.println(myFile.position() + samplesToRead); | |
} | |
myFile.read(aaAudio.dacBuffer, samplesToRead); | |
for (int i = 0; i < samplesToRead; i++) { | |
int16_t tmpVar = (uint16_t)aaAudio.dacBuffer[i] - 0x80; | |
tmpVar = (tmpVar / volumeVar) + 0x80; | |
aaAudio.dacBuffer[i] = tmpVar; | |
} | |
} else { | |
if ( (availableBytes = (myFile.available() - metaDataSize)) <= (samplesToRead * 2) ) { | |
samplesToRead = availableBytes / 2; | |
Serial.print("File Size16 "); | |
Serial.print(myFile.size()); | |
Serial.print(" Bytes Read "); | |
Serial.println(myFile.position() + availableBytes); | |
} | |
//Load 32 samples (64 bytes) into the 16-bit dacBuffer | |
int16_t tmpBuffer[samplesToRead]; | |
myFile.read((byte*)tmpBuffer, samplesToRead * 2); | |
//Convert the 16-bit samples to 12-bit | |
for (int i = 0; i < samplesToRead; i++) { | |
tmpBuffer[i] /= volumeVar; | |
aaAudio.dacBuffer16[i] = (tmpBuffer[i] + 0x8000) >> 8; | |
} | |
} | |
} else { | |
Serial.println("File close"); | |
myFile.close(); | |
Serial.print("Dis DAC, "); | |
aaAudio.rampOut(0); | |
//If using tasks, disabling the active task and DAC will be done from within the task itself | |
//Need to let aaAudio know by setting the parameter to 'true'. Using useTasks variable | |
aaAudio.disableDAC(true); | |
} | |
} | |
return samplesToRead; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment