/*
* example sketch to play audio file(s) in a directory using the mp3
* library for playback and the arduino fatfs wrapper to read files.
* based on frank zhao's player at http://frank.circleofcurrent.com/
*
* (c) 2010 david sirkin sirkin@stanford.edu
*/
/* import the avr's power library for the clock_prescale_set macro. */
#include
/* import the full fatfs wrapper & mp3 library functions & defines. */
#include
#include
#include
#include
#include
#include
#include
#define mp3_cs 0 // 'command chip select' to cs pin
#define mmc_cs 14 // 'chip select' to microsd cs pin
#define dcs 18 // 'data chip select' to bsync pin
#define dreq 19 // 'data request line' to dreq pin
#define rst 20 // 'reset' to decoder's reset pin
#define read_buffer 512 // size of the microsd read buffer
#define mp3_vol 225 // output volume range is 0 to 254
#define MAX_VOL 254
#define MIN_VOL 150
#define MIN_ANALOG 0
#define MAX_ANALOG 1023
#define volumePin 8
#define interruptPin 0
#define digitalReadInterruptPin 5
#define BOUNCE_PAUSE 200
volatile bool pauseFlag = false;
volatile bool pressed = false;
volatile bool clicked = false;
volatile bool nextFlag = false;
volatile bool prevFlag = false;
volatile bool started = false;
volatile bool shuffleFlag = false;
int counter = 0;
unsigned long startTime;
unsigned long endTime;
#define BOUNCE_BUFFER 80
#define DOUBLE_CLICK 600
#define HOLD_LENGTH 600
#define SHUFFLE_LENGTH 4000
#define NUM_SONGS 38
int curSong = 1;
int songList[NUM_SONGS];
int curSongIndex = 0;
void playPauseNextPrev(){
//Serial.println("CLICKED");
//delay(BOUNCE_PAUSE);
// pauseFlag = !pauseFlag;
// Serial.println(pauseFlag);
pressed = !digitalRead(digitalReadInterruptPin);//!pressed;
if(pressed && (millis() - startTime) < BOUNCE_BUFFER) return;
//Serial.println(pressed);
if(pressed){
if(clicked && (millis() - endTime) < DOUBLE_CLICK){
//Serial.println("d");
prevFlag = true;
clicked = false;
return;
}
startTime = millis();
clicked = true;
//Serial.println("Pressed");
//Serial.print("Starttime: "); Serial.println(startTime);
}else{
endTime = millis();
//Serial.println("Unpressed");
//Serial.print("Endtime: " ); Serial.println(endTime);
//Serial.print("Diff: "); Serial.println(endTime-startTime);
if(endTime - startTime > SHUFFLE_LENGTH){
//Serial.println("s");
shuffleFlag = true;
pauseFlag = false;
}else if(endTime - startTime > HOLD_LENGTH){
//Serial.println("Hold! - Go to next sound\n\n");
nextFlag = true;
pauseFlag = false;
}else{
//Serial.println("Play/Pause!\n\n");
pauseFlag = !pauseFlag;
}
}
}
/*
* initialize the processor speed, setup the fatfs sd card (or, mms)
* filesystem, setup mp3 playback and register the pins used (device
* specific configuration)
*/
void setup() {
// the avr atmega32u4 processor is only rated to 8mhz (rather than
// 16mhz) when powered at 3.3v (rather than 5v).
clock_prescale_set(clock_div_2); // fosc 8mhz as teensy is at 3.3V
int ledPin = 11;
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
for(int i = 0; i < NUM_SONGS; i++){
songList[i] = i + 1;
}
Mp3.begin(mp3_cs,dcs,rst,dreq); // decoder cs, dcs, rst, dreq pin
Mp3.volume(mp3_vol); // default volume level is silent
FatFs.begin(mmc_cs); // register microsd card's cs pin
//Serial.begin(115200); // initialize the serial terminal
// while only rated to 8mhz, the processor seems to work at 16MHz,
// which is required to playback full-resolution 44.1kHz wav files
clock_prescale_set(clock_div_1); // fosc 16mhz only for full waves
srand (analogRead(volumePin)% 17 );
attachInterrupt(interruptPin, playPauseNextPrev, CHANGE); //because we want to do play,pause,next,prev
//delay(2000);
//Serial.println("STARTED");
}
void shuffle(){
//Serial.println("PRESHUFFLE");
// for(int i = 0; i < NUM_SONGS; i++){
// Serial.println(songList[i]);
//}
//Serial.println("END");
for(int i = 0; i < NUM_SONGS -1 ; i++){
int range = NUM_SONGS - 1 - i;
//Serial.print(range);
int num = rand() % (range + 1);
int swapIndex = i + num;
//Serial.print(" "); Serial.println(swapIndex);
int temp = songList[i];
songList[i] = songList[swapIndex];
songList[swapIndex] = temp;
}
//Serial.println("NEW ORDER");
//for(int i = 0; i < NUM_SONGS; i++){
// Serial.println(songList[i]);
//}
//Serial.println("END");
}
/*
* read in buffer 'bytes' of 'read_buffer' size from the file opened
* in the loop() function below. you can pass in a file name/pointer
* and open() it from within this function, if you prefer. Just make
* sure the FILINFO object is within scope.
*/
void mp3_play (void) {
unsigned char bytes[read_buffer]; // buffer to send to the decoder
unsigned int bytes_read; // number of bytes read from fat
do {
while(pauseFlag);
if(nextFlag){
nextFlag = false;
//Serial.println("NEXT SONG");
return;
}
if(prevFlag){
//Serial.println("PREVIOUS SONG");
return;
}
if(shuffleFlag){
//Serial.println("SHUFFLING SONGS");
shuffle();
return;
}
FatFs.read(bytes, read_buffer, &bytes_read);
Mp3.play(bytes, read_buffer);
int volReading = analogRead(volumePin);
Mp3.volume(map(volReading, MIN_ANALOG, MAX_ANALOG, MIN_VOL, MAX_VOL));
//Serial.println(volReading);
}
while (bytes_read == read_buffer);
}
FILINFO fnfo; // information on file size & type, updated by readdir
FILINFO prev; // info for previous file?
/*
* send (pointers to) all files in the root directory to dir_play(),
* even though they may not be mp3 or wav files (as they're screened
* for proper extensions there).
*/
void loop() {
//Mp3.volume(200);
if(prevFlag) {
curSongIndex -= 2; //because we advanced one, was curSong
prevFlag = false;
return;
}
if(shuffleFlag){
curSongIndex = 0;
shuffleFlag = false;
FatFs.open("0.mp3", FA_READ); // the beep
mp3_play();
}
if(curSongIndex < 0) curSongIndex = NUM_SONGS - 1;
if(curSongIndex >= NUM_SONGS) curSongIndex = 0;
curSong = songList[curSongIndex];
char num[10];
itoa(curSong, num, 10);
char song[30];
strcpy(song, num);
strcat(song, ".mp3");
if (FatFs.open(song, FA_READ) == FR_OK) {
//Serial.print("Playing ");
//Serial.println(song);
mp3_play();
}
curSongIndex++;
}
Comments (0)
You don't have permission to comment on this page.