I could use some guidance implementing the Audio library. Currently, I've got several tasks that are time critical. I am using the RTOS "Chibi" with success. There are two primary tasks that need to happen at 500 uS and 500 mS intervals. The 500 mS task updates an LCD screen, which does use up some resources. However, my back-of-the-envelope calculations suggest that I should still have plenty of processing power to play a sound file.
I created another thread to play the audio file. I set a time interval for this thread as well - it should be called every 2 uS. However, even changing around the thread priorities, the sound is very choppy. Is there a software solution to this problem or do I need a separate audio chip?
//ChibiOS Tests
#include <SD.h>
#include <SPI.h>
#include <Audio.h>
#include <ChibiOS_ARM.h>
#include <LiquidCrystal.h>
//declare variables
File myFile;
const int S= 1024;
short buffer[S];
Thread* tp1;
Thread* tp2;
Thread* tp3;
LiquidCrystal lcd(47,48,49,50,51,52);
static WORKING_AREA(waTask1, 1024);
static msg_t Task1(void *arg){
systime_t displayCheckTime = chTimeNow();
while (!chThdShouldTerminate()){
task1CheckTime += MS2ST(500);
doTask1();
chThdSleepUntil(task1CheckTime);
}
return 0;
}
static WORKING_AREA(waTask2, 14336);
static msg_t Task2(void *arg){
systime_t task2CheckTime = chTimeNow();
while(!chThdShouldTerminate()){
task2CheckTime += US2ST(500);
doTask2();
chThdSleepUntil(task2CheckTime);
}
}
static WORKING_AREA(waMusic, 10240);
static msg_t Music(void *arg){
systime_t musicCheckTime = chTimeNow();
while(!chThdShouldTerminate()){
musicCheckTime += US2ST(2);
playMusic();
chThdSleepUntil(musicCheckTime);
}
}
void setup() {
Serial.begin(9600);
// wait for USB Serial
while (!Serial) {}
lcd.begin(20,4);
//do some stuff
Serial.println("Initializing SD card...");
lcd.print("Initializing SD");
pinMode(4, OUTPUT);
if (!SD.begin(4)) {
Serial.println(" failed!");
lcd.print("OOPS!");
return;
}
Serial.println(" done.");
// hi-speed SPI transfers
SPI.setClockDivider(4);
// 44100Khz stereo => 88200 sample rate
// 100 mSec of prebuffering.
Audio.begin(88200, 100);
chBegin(mainThread);
// chBegin never returns, main thread continues with mainThread()
while(1) {}
}
//------------------------------------------------------------------------------
// main thread runs at NORMALPRIO
void mainThread() {
myFile = SD.open("test.wav");
if (!myFile) {
// if the file didn't open, print an error and stop
Serial.println("error opening test.wav");
while (true);
}
if (myFile) Serial.print("Loaded file!");
// start thread
tp1 = chThdCreateStatic(waTask1, sizeof(waTask1),
NORMALPRIO, Task1, NULL);
// start thread
tp2 = chThdCreateStatic(waTask2, sizeof(waTask2),
NORMALPRIO + 1, Firing, NULL);
// start music thread
tp3 = chThdCreateStatic(waMusic, sizeof(waMusic),
NORMALPRIO, Music, NULL);
while(1){
if (finished){
// print memory use
chThdTerminate(tp1);
chThdTerminate(tp2);
}
}
}
//------------------------------------------------------------------------------
void loop() {
// not used
}
void doTask1() {
//do stuff
}
void doTask2(){
//print a couple lines to LCD screen
}
void playMusic(){
//Serial.println("Playing");
// until the file is not finished
while(1){
//int count=0;
if (myFile.available()) {
// read from the file into buffer
myFile.read(buffer, sizeof(buffer));
//Serial.println("reading file");
// Prepare samples
int volume = 1023;
Audio.prepare(buffer, S, volume);
// Feed samples to audio
//Serial.println("prepared samples");
Audio.write(buffer, S);
// Every 100 block print a '.'
//count++;
//if (count == 100) {
//Serial.print(".");
//count = 0;
//}
}
if (!myFile.available()) myFile.close();
//Serial.println("End of file. Thank you for listening!");
}
}