make it not sub

This commit is contained in:
caternuson 2017-10-24 13:46:08 -07:00
parent 9c3c4db525
commit 43638abc8b
3 changed files with 265 additions and 0 deletions

View file

@ -0,0 +1,242 @@
//
// Gordon Cole MP3 Player
//
#include <SPI.h>
#include <SD.h>
#include <Adafruit_VS1053.h>
// Guide is based on Feather M0 Express
// ARDUINO_SAMD_FEATHER_M0 defines only
// VS1053 Pins
#define VS1053_RESET -1 // VS1053 reset pin (not used!)
#define VS1053_CS 6 // VS1053 chip select pin (output)
#define VS1053_DCS 10 // VS1053 Data/command select pin (output)
#define CARDCS 5 // Card chip select pin
#define VS1053_DREQ 9 // VS1053 Data request, ideally an Interrupt pin
// Button Pins
#define BUTTON_PLAY 13 // PLAY / STOP button
#define BUTTON_PAUSE 12 // PAUSE / RESUME button
#define BUTTON_NEXT 11 // NEXT button
// Status LED
#define LED_STATUS 19 // status LED
#define BLINK_RATE 500 // blink rate in ms
// Volume Control
#define KNOB_VOLUME 0 // volume knob
#define KNOB_MIN 0 // min ADC value
#define KNOB_MAX 1023 // max ADC value
#define VOL_MIN 0 // min volume (most loud)
#define VOL_MAX 50 // max volume (most quiet)
// Maximum number of files (tracks) to load
#define TRACKS_MAX 100
// Player behavior
#define AUTO_PLAY_NEXT true // true to automatically go to next track
unsigned long currentMillis, previousMillis;
int currentKnob, previousKnob;
int volume;
int currentTrack, totalTracks;
char trackListing[TRACKS_MAX][13] = {' '};
enum mode {
PLAYING,
PAUSED,
STOPPED
} currentMode = STOPPED;
Adafruit_VS1053_FilePlayer musicPlayer =
Adafruit_VS1053_FilePlayer(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ, CARDCS);
//-----------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
// Leave commented for standalone operation, uncomment for troubleshooting
//while (!Serial) ;
// Initialize pins
pinMode(BUTTON_PLAY, INPUT_PULLUP);
pinMode(BUTTON_PAUSE, INPUT_PULLUP);
pinMode(BUTTON_NEXT, INPUT_PULLUP);
pinMode(LED_STATUS, OUTPUT);
// Initialize status LED
previousMillis = millis();
digitalWrite(LED_STATUS, LOW);
Serial.println("\n\nGordon Cole MP3 Player");
// Initialize the music player
if (! musicPlayer.begin()) {
Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
while (1);
}
Serial.println(F("VS1053 found"));
musicPlayer.softReset();
// Make a tone to indicate VS1053 is working
musicPlayer.sineTest(0x44, 500);
// Set volume for left, right channels. lower numbers == louder volume!
previousKnob = analogRead(KNOB_VOLUME);
volume = map(previousKnob, KNOB_MIN, KNOB_MAX, VOL_MIN, VOL_MAX);
Serial.print("Volume = "); Serial.println(volume);
musicPlayer.setVolume(volume, volume);
// Initialize the SD card
if (!SD.begin(CARDCS)) {
Serial.println(F("SD failed, or not present"));
while (1);
}
Serial.println("SD OK!");
// Load list of tracks
Serial.println("Track Listing");
Serial.println("=============");
totalTracks = 0;
loadTracks(SD.open("/"), 0);
currentTrack = 0;
// Setup interrupts (DREQ) for playback
musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);
}
//-----------------------------------------------------------------------------
void loop() {
// Check and set volume
updateVolume();
// Update status LED
updateStatusLED();
// Auto play next track if feature enabled
if (AUTO_PLAY_NEXT) {
if (currentMode==PLAYING && musicPlayer.stopped()) {
currentTrack = ++currentTrack < totalTracks ? currentTrack : 0;
Serial.print("Next ");
Serial.print(currentTrack); Serial.print("=");
Serial.println(trackListing[currentTrack]);
musicPlayer.startPlayingFile(trackListing[currentTrack]);
currentMode = PLAYING;
}
}
// Start / Stop
if (!digitalRead(BUTTON_PLAY)) {
if (musicPlayer.stopped()) {
Serial.print("Start ");
Serial.print(currentTrack); Serial.print("=");
Serial.println(trackListing[currentTrack]);
musicPlayer.startPlayingFile(trackListing[currentTrack]);
currentMode = PLAYING;
} else {
Serial.println("Stopped.");
musicPlayer.stopPlaying();
currentMode = STOPPED;
}
delay(250);
}
// Pause / Resume
if (!digitalRead(BUTTON_PAUSE)) {
if (!musicPlayer.stopped()) {
if (musicPlayer.paused()) {
Serial.println("Resumed");
musicPlayer.pausePlaying(false);
currentMode = PLAYING;
} else {
Serial.println("Paused");
musicPlayer.pausePlaying(true);
currentMode = PAUSED;
}
}
delay(250);
}
// Next
if (!digitalRead(BUTTON_NEXT)) {
if (!musicPlayer.stopped()) {
Serial.println("Stopping current playback.");
musicPlayer.stopPlaying();
}
currentTrack = ++currentTrack < totalTracks ? currentTrack : 0;
Serial.print("Next ");
Serial.print(currentTrack); Serial.print("=");
Serial.println(trackListing[currentTrack]);
musicPlayer.startPlayingFile(trackListing[currentTrack]);
currentMode = PLAYING;
delay(250);
}
}
//-----------------------------------------------------------------------------
void updateVolume() {
// Read current value
currentKnob = analogRead(KNOB_VOLUME);
// Only update if it's changed
if (currentKnob != previousKnob) {
previousKnob = currentKnob;
volume = map(currentKnob, KNOB_MIN, KNOB_MAX, VOL_MIN, VOL_MAX);
musicPlayer.setVolume(volume, volume);
}
}
//-----------------------------------------------------------------------------
void updateStatusLED() {
if (musicPlayer.paused()) {
// Blink it like a polaroid
currentMillis = millis();
if (currentMillis - previousMillis > BLINK_RATE) {
previousMillis = currentMillis;
digitalWrite(LED_STATUS, !digitalRead(LED_STATUS));
}
} else if (!musicPlayer.stopped()) {
// It's so on again
digitalWrite(LED_STATUS, HIGH);
} else {
// It's so off again
digitalWrite(LED_STATUS, LOW);
}
}
//-----------------------------------------------------------------------------
void loadTracks(File dir, int level) {
while (true) {
File entry = dir.openNextFile();
if (!entry) return;
if (entry.isDirectory()) {
// Recursive call to scan next dir level
loadTracks(entry, level + 1);
} else {
// Only add files in root dir
if (level == 0) {
// And only if they have good names
if (nameCheck(entry.name())) {
strncpy(trackListing[totalTracks], entry.name(), 12);
Serial.print(totalTracks); Serial.print("=");
Serial.println(trackListing[totalTracks]);
totalTracks++;
}
}
}
entry.close();
// Stop scanning if we hit max
if (totalTracks >= TRACKS_MAX) return;
}
}
//-----------------------------------------------------------------------------
bool nameCheck(char* name) {
int len = strlen(name);
// Check length
if (len <= 4) return false;
// Check extension
char* ext = strrchr(name,'.');
if (!(
strcmp(ext,".MP3") == 0 ||
strcmp(ext,".OGG") == 0
)) return false;
// Check first character
switch(name[0]) {
case '_': return false;
}
return true;
}

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Carter Nelson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,2 @@
# Gordon_Cole_MP3_Player
Arduino code for simple MP3 player.