Neale Pickett
·
2016-09-27
MusicPlayer.cpp
1#include <Arduino.h>
2#include <SPI.h>
3#include <Adafruit_VS1053.h>
4#include <SD.h>
5#include "MusicPlayer.h"
6
7
8
9MusicPlayer::MusicPlayer(int8_t cs, int8_t dcs, int8_t dreq, int8_t cardcs)
10{
11 musicPlayer = new Adafruit_VS1053_FilePlayer(cs, dcs, dreq, cardcs);
12 musicPlayer->begin();
13 musicPlayer->setVolume(1, 1); // lower = louder
14 musicPlayer->sineTest(0x44, 500);
15 SD.begin(cardcs);
16}
17
18void
19MusicPlayer::setVolume(uint8_t left, uint8_t right)
20{
21 musicPlayer->setVolume(left, right);
22}
23
24
25boolean
26MusicPlayer::startPlayingFile(const char *trackname)
27{
28 return musicPlayer->startPlayingFile(trackname);
29}
30
31boolean
32MusicPlayer::isPlaying()
33{
34 return musicPlayer->playingMusic;
35}
36
37void
38MusicPlayer::stopPlaying()
39{
40 musicPlayer->stopPlaying();
41}
42
43void
44MusicPlayer::poll(unsigned long jiffies)
45{
46 /* Cleverness ensues
47 *
48 * The Adafruit library is written to let you go off and do whatever you need,
49 * hooking into an interrupt to sort of act like a multitasking operating system,
50 * interrupting your program periodically.
51 *
52 * That's smart, since it makes it easy to use,
53 * but we want this to be responsive, and can't handle something barging in and taking up lots of time:
54 * it makes things look really uneven as our display code pauses to fill the buffer.
55 * Fortunately, we don't have to fill the entire buffer at once, we can trickle data in.
56 * That's what this does.
57 *
58 * Since the entire program is polling, without ever calling delay,
59 * and hopefully doing what needs to be done quickly,
60 * we check to see if the music chip wants more data.
61 * If it does, we give it one chunk, and only one chunk,
62 * rather than filling its buffer back up completely.
63 *
64 * There is still some weirdness with this loop,
65 * possibly because the SPI routines are masking interrupts used to increment millis.
66 * But it's remarkably more fluid than the other way.
67 */
68
69 if (musicPlayer->playingMusic && musicPlayer->readyForData()) {
70 int bytesread = musicPlayer->currentTrack.read(musicPlayer->mp3buffer, VS1053_DATABUFFERLEN);
71 if (bytesread == 0) {
72 musicPlayer->playingMusic = false;
73 musicPlayer->currentTrack.close();
74 } else {
75 musicPlayer->playData(musicPlayer->mp3buffer, bytesread);
76 }
77 }
78}