Skip to content

Commit

Permalink
Added basic support for stream audion from a Process (from Yun Bridge…
Browse files Browse the repository at this point in the history
… library). Plays audio, but currently too choppy to be useful.

Removed SD support to avoid conflict with bridge library
  • Loading branch information
nfriedly committed May 6, 2015
1 parent 14c5931 commit 951ed43
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 98 deletions.
254 changes: 166 additions & 88 deletions Adafruit_VS1053.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@
BSD license, all text above must be included in any redistribution
****************************************************/

#include <Bridge.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

static Adafruit_VS1053_FilePlayer *myself;

#ifndef _BV
#define _BV(x) (1<<(x))
#endif
/*
On Arduino Yun, the Bridge library provides a conflicting
implementation of File. This avoids the conflict by disabling
the file player when the bridge's FileIO library is present.
See also:
* https://github.com/adafruit/Adafruit_VS1053_Library/issues/14
* https://github.com/arduino/Arduino/issues/1942
*/
//#include <SD.h>


static Adafruit_VS1053_FilePlayer *myself;

#if defined(__AVR__)
SIGNAL(TIMER0_COMPA_vect) {
Expand Down Expand Up @@ -77,15 +86,6 @@ static const uint8_t dreqinttable[] = {
#elif defined(__AVR_ATmega256RFR2__)
4, 0,
5, 1,
#elif defined(__SAM3X8E__)
0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
20, 20, 21, 21, 22, 22, 23, 23, 24, 24,
25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
30, 30, 31, 31, 32, 32, 33, 33,

#endif
};

Expand Down Expand Up @@ -183,7 +183,7 @@ void Adafruit_VS1053_FilePlayer::stopPlaying(void) {

// wrap it up!
playingMusic = false;
currentTrack.close();
//currentTrack.close();
}

void Adafruit_VS1053_FilePlayer::pausePlaying(boolean pause) {
Expand All @@ -196,11 +196,11 @@ void Adafruit_VS1053_FilePlayer::pausePlaying(boolean pause) {
}

boolean Adafruit_VS1053_FilePlayer::paused(void) {
return (!playingMusic && currentTrack);
return (!playingMusic); // && currentTrack);
}

boolean Adafruit_VS1053_FilePlayer::stopped(void) {
return (!playingMusic && !currentTrack);
return (!playingMusic); // && !currentTrack);
}


Expand All @@ -211,10 +211,11 @@ boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) {
sciWrite(VS1053_REG_WRAMADDR, 0x1e29);
sciWrite(VS1053_REG_WRAM, 0);

currentTrack = SD.open(trackname);
if (!currentTrack) {
return false;
}
// currentTrack = SD.open(trackname);
//
// if (!currentTrack) {
// return false;
// }

// As explained in datasheet, set twice 0 in REG_DECODETIME to set time back to 0
sciWrite(VS1053_REG_DECODETIME, 0x00);
Expand All @@ -236,11 +237,37 @@ boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) {
return true;
}

boolean Adafruit_VS1053_FilePlayer::playStream(Process p) {
// reset playback
sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW);
// resync
sciWrite(VS1053_REG_WRAMADDR, 0x1e29);
sciWrite(VS1053_REG_WRAM, 0);

// As explained in datasheet, set twice 0 in REG_DECODETIME to set time back to 0
sciWrite(VS1053_REG_DECODETIME, 0x00);
sciWrite(VS1053_REG_DECODETIME, 0x00);


playingMusic = true;

// wait till its ready for data
while (! readyForData() );


// fill it up!
while (playingMusic && readyForData())
feedBufferFromStream(p);

// Serial.println("Ready");

return true;
}

void Adafruit_VS1053_FilePlayer::feedBuffer(void) {
static uint8_t running = 0;
uint8_t sregsave;

#ifndef __SAM3X8E__
// Do not allow 2 copies of this code to run concurrently.
// If an interrupt causes feedBuffer() to run while another
// copy of feedBuffer() is already running in the main
Expand All @@ -255,13 +282,65 @@ void Adafruit_VS1053_FilePlayer::feedBuffer(void) {
running = 1;
SREG = sregsave;
}
#endif


if (! playingMusic) {
running = 0;
return; // paused or stopped
}
// if (! currentTrack) {
// running = 0;
// return;
// }
// if (! readyForData()) {
// running = 0;
// return;
// }
//
// // Feed the hungry buffer! :)
// while (readyForData()) {
// //UDR0 = '.';
//
// // Read some audio data from the SD card file
// int bytesread = currentTrack.read(mp3buffer, VS1053_DATABUFFERLEN);
//
// if (bytesread == 0) {
// // must be at the end of the file, wrap it up!
// playingMusic = false;
// currentTrack.close();
// running = 0;
// return;
// }
// playData(mp3buffer, bytesread);
// }
running = 0;
return;
}

void Adafruit_VS1053_FilePlayer::feedBufferFromStream(Process p) {
static uint8_t running = 0;
uint8_t sregsave;

// Do not allow 2 copies of this code to run concurrently.
// If an interrupt causes feedBuffer() to run while another
// copy of feedBuffer() is already running in the main
// program, havoc can occur. "running" detects this state
// and safely returns.
sregsave = SREG;
cli();
if (running) {
SREG = sregsave;
return; // return safely, before touching hardware! :-)
} else {
running = 1;
SREG = sregsave;
}

if (! playingMusic) {
running = 0;
return; // paused or stopped
}
if (! currentTrack) {
if (p.available() <= 0 && !p.running()) {
playingMusic = false;
running = 0;
return;
}
Expand All @@ -274,13 +353,12 @@ void Adafruit_VS1053_FilePlayer::feedBuffer(void) {
while (readyForData()) {
//UDR0 = '.';

// Read some audio data from the SD card file
int bytesread = currentTrack.read(mp3buffer, VS1053_DATABUFFERLEN);

// Read some audio data from the stream to the buffer
int bytesread = p.readBytes(mp3buffer, VS1053_DATABUFFERLEN);
if (bytesread == 0) {
// must be at the end of the file, wrap it up!
// must be at the end of the stream
playingMusic = false;
currentTrack.close();
running = 0;
return;
}
Expand All @@ -290,12 +368,11 @@ void Adafruit_VS1053_FilePlayer::feedBuffer(void) {
return;
}


/***************************************************************/

/* VS1053 'low level' interface */
static volatile PortReg *clkportreg, *misoportreg, *mosiportreg;
static PortMask clkpin, misopin, mosipin;
static volatile uint8_t *clkportreg, *misoportreg, *mosiportreg;
static uint8_t clkpin, misopin, mosipin;

Adafruit_VS1053::Adafruit_VS1053(int8_t mosi, int8_t miso, int8_t clk,
int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) {
Expand Down Expand Up @@ -362,57 +439,58 @@ void Adafruit_VS1053::applyPatch(const uint16_t *patch, uint16_t patchsize) {

uint16_t Adafruit_VS1053::loadPlugin(char *plugname) {

File plugin = SD.open(plugname);
if (!plugin) {
Serial.println("Couldn't open the plugin file");
Serial.println(plugin);
return 0xFFFF;
}

if ((plugin.read() != 'P') ||
(plugin.read() != '&') ||
(plugin.read() != 'H'))
return 0xFFFF;

uint16_t type;

// Serial.print("Patch size: "); Serial.println(patchsize);
while ((type = plugin.read()) >= 0) {
uint16_t offsets[] = {0x8000UL, 0x0, 0x4000UL};
uint16_t addr, len;

//Serial.print("type: "); Serial.println(type, HEX);

if (type >= 4) {
plugin.close();
return 0xFFFF;
}

len = plugin.read(); len <<= 8;
len |= plugin.read() & ~1;
addr = plugin.read(); addr <<= 8;
addr |= plugin.read();
//Serial.print("len: "); Serial.print(len);
//Serial.print(" addr: $"); Serial.println(addr, HEX);

if (type == 3) {
// execute rec!
plugin.close();
return addr;
}

// set address
sciWrite(VS1053_REG_WRAMADDR, addr + offsets[type]);
// write data
do {
uint16_t data;
data = plugin.read(); data <<= 8;
data |= plugin.read();
sciWrite(VS1053_REG_WRAM, data);
} while ((len -=2));
}

plugin.close();
// File plugin = SD.open(plugname);
//
// if (!plugin) {
// Serial.println("Couldn't open the plugin file");
// Serial.println(plugin);
// return 0xFFFF;
// }
//
// if ((plugin.read() != 'P') ||
// (plugin.read() != '&') ||
// (plugin.read() != 'H'))
// return 0xFFFF;
//
// uint16_t type;
//
// // Serial.print("Patch size: "); Serial.println(patchsize);
// while ((type = plugin.read()) >= 0) {
// uint16_t offsets[] = {0x8000UL, 0x0, 0x4000UL};
// uint16_t addr, len;
//
// //Serial.print("type: "); Serial.println(type, HEX);
//
// if (type >= 4) {
// plugin.close();
// return 0xFFFF;
// }
//
// len = plugin.read(); len <<= 8;
// len |= plugin.read() & ~1;
// addr = plugin.read(); addr <<= 8;
// addr |= plugin.read();
// //Serial.print("len: "); Serial.print(len);
// //Serial.print(" addr: $"); Serial.println(addr, HEX);
//
// if (type == 3) {
// // execute rec!
// plugin.close();
// return addr;
// }
//
// // set address
// sciWrite(VS1053_REG_WRAMADDR, addr + offsets[type]);
// // write data
// do {
// uint16_t data;
// data = plugin.read(); data <<= 8;
// data |= plugin.read();
// sciWrite(VS1053_REG_WRAM, data);
// } while ((len -=2));
// }
//
// plugin.close();
return 0xFFFF;
}

Expand Down Expand Up @@ -443,15 +521,15 @@ void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) {
v <<= 8;
v |= right;

noInterrupts(); //cli();
cli();
sciWrite(VS1053_REG_VOLUME, v);
interrupts(); //sei();
sei();
}

uint16_t Adafruit_VS1053::decodeTime() {
noInterrupts(); //cli();
cli();
uint16_t t = sciRead(VS1053_REG_DECODETIME);
interrupts(); //sei();
sei();
return t;
}

Expand Down
Loading

0 comments on commit 951ed43

Please sign in to comment.