mirror of https://github.com/nealey/proton
79 lines
2.2 KiB
C++
79 lines
2.2 KiB
C++
#include <Arduino.h>
|
|
#include <SPI.h>
|
|
#include <Adafruit_VS1053.h>
|
|
#include <SD.h>
|
|
#include "MusicPlayer.h"
|
|
|
|
|
|
|
|
MusicPlayer::MusicPlayer(int8_t cs, int8_t dcs, int8_t dreq, int8_t cardcs)
|
|
{
|
|
musicPlayer = new Adafruit_VS1053_FilePlayer(cs, dcs, dreq, cardcs);
|
|
musicPlayer->begin();
|
|
musicPlayer->setVolume(20, 20); // lower = louder
|
|
musicPlayer->sineTest(0x44, 500);
|
|
SD.begin(cardcs);
|
|
}
|
|
|
|
void
|
|
MusicPlayer::setVolume(uint8_t left, uint8_t right)
|
|
{
|
|
musicPlayer->setVolume(left, right);
|
|
}
|
|
|
|
|
|
boolean
|
|
MusicPlayer::startPlayingFile(const char *trackname)
|
|
{
|
|
return musicPlayer->startPlayingFile(trackname);
|
|
}
|
|
|
|
boolean
|
|
MusicPlayer::isPlaying()
|
|
{
|
|
return musicPlayer->playingMusic;
|
|
}
|
|
|
|
void
|
|
MusicPlayer::stopPlaying()
|
|
{
|
|
musicPlayer->stopPlaying();
|
|
}
|
|
|
|
void
|
|
MusicPlayer::poll(unsigned long jiffies)
|
|
{
|
|
/* Cleverness ensues
|
|
*
|
|
* The Adafruit library is written to let you go off and do whatever you need,
|
|
* hooking into an interrupt to sort of act like a multitasking operating system,
|
|
* interrupting your program periodically.
|
|
*
|
|
* That's smart, since it makes it easy to use,
|
|
* but we want this to be responsive, and can't handle something barging in and taking up lots of time:
|
|
* it makes things look really uneven as our display code pauses to fill the buffer.
|
|
* Fortunately, we don't have to fill the entire buffer at once, we can trickle data in.
|
|
* That's what this does.
|
|
*
|
|
* Since the entire program is polling, without ever calling delay,
|
|
* and hopefully doing what needs to be done quickly,
|
|
* we check to see if the music chip wants more data.
|
|
* If it does, we give it one chunk, and only one chunk,
|
|
* rather than filling its buffer back up completely.
|
|
*
|
|
* There is still some weirdness with this loop,
|
|
* possibly because the SPI routines are masking interrupts used to increment millis.
|
|
* But it's remarkably more fluid than the other way.
|
|
*/
|
|
|
|
if (musicPlayer->playingMusic && musicPlayer->readyForData()) {
|
|
int bytesread = musicPlayer->currentTrack.read(musicPlayer->mp3buffer, VS1053_DATABUFFERLEN);
|
|
if (bytesread == 0) {
|
|
musicPlayer->playingMusic = false;
|
|
musicPlayer->currentTrack.close();
|
|
} else {
|
|
musicPlayer->playData(musicPlayer->mp3buffer, bytesread);
|
|
}
|
|
}
|
|
}
|