Started rewrite for using an I2S amplifier with less unnecessary features.
This commit is contained in:
@@ -1,33 +1,29 @@
|
||||
#include "playlist_manager.h"
|
||||
#include <SD.h>
|
||||
#include "spi_master.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <SD.h>
|
||||
|
||||
PlaylistManager::PlaylistManager() {
|
||||
scan_files();
|
||||
}
|
||||
SPIMaster::enable_sd();
|
||||
current_rfid_tag_id = String("");
|
||||
|
||||
void PlaylistManager::scan_files() {
|
||||
SPIMaster::select_sd();
|
||||
std::vector<String> folders;
|
||||
File root = SD.open("/");
|
||||
File entry;
|
||||
while (entry = root.openNextFile()) {
|
||||
Serial.println(entry.name());
|
||||
String foldername = entry.name();
|
||||
if (foldername.startsWith("/.")) continue;
|
||||
foldername.remove(foldername.length());
|
||||
folders.push_back(foldername);
|
||||
_check_for_special_chars(foldername);
|
||||
entry.close();
|
||||
while(File entry = root.openNextFile()) {
|
||||
if (entry.isDirectory()) {
|
||||
String filename("/");
|
||||
filename.concat(entry.name());
|
||||
if (!filename.startsWith("/.")) {
|
||||
Serial.println(filename);
|
||||
dirs.push_back(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_map.clear();
|
||||
if (!SD.exists("/_mapping.txt\n")) {
|
||||
ERROR("WARNING: File /_mapping.txt not found.\n");
|
||||
if (!SD.exists("/_mapping.txt")) {
|
||||
Serial.println("WARNING: /_mapping.txt not found!");
|
||||
} else {
|
||||
map.clear();
|
||||
File f = SD.open("/_mapping.txt");
|
||||
DEBUG("Reading /_mapping.txt...\n");
|
||||
Serial.println(" Reading /_mapping.txt...");
|
||||
while (f.available()) {
|
||||
char buffer[512];
|
||||
size_t pos = f.readBytesUntil('\n', buffer, 511);
|
||||
@@ -38,19 +34,19 @@ void PlaylistManager::scan_files() {
|
||||
if (eq>0 && eq<data.length()-1) {
|
||||
String rfid_id = data.substring(0, eq);
|
||||
String folder = data.substring(eq + 1);
|
||||
TRACE(" Adding mapping: %s=>%s\n", rfid_id.c_str(), folder.c_str());
|
||||
_map[rfid_id] = folder;
|
||||
Serial.printf(" Adding mapping: %s=>%s\n", rfid_id.c_str(), folder.c_str());
|
||||
map[rfid_id] = folder;
|
||||
|
||||
if (folder.charAt(0)=='/') {
|
||||
bool found=false;
|
||||
for (String f: folders) {
|
||||
for (String f: dirs) {
|
||||
if (f.equals(folder)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
INFO("WARNING: Found mapping for RFID id %s which maps to non-existing folder %s!\n", rfid_id.c_str(), folder.c_str());
|
||||
Serial.printf("WARNING: Found mapping for RFID id %s which maps to non-existing folder %s!\n", rfid_id.c_str(), folder.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,183 +54,40 @@ void PlaylistManager::scan_files() {
|
||||
f.close();
|
||||
}
|
||||
root.close();
|
||||
|
||||
_unmapped_folders.clear();
|
||||
for (String folder: folders) {
|
||||
bool found = false;
|
||||
for(std::map<String, String>::iterator it = _map.begin(); it != _map.end(); it++) {
|
||||
if (it->second.equals(folder)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Checking folder for media files
|
||||
File dir = SD.open(folder);
|
||||
while (entry = dir.openNextFile()) {
|
||||
String filename = entry.name();
|
||||
filename = filename.substring(folder.length() + 1);
|
||||
if (!filename.startsWith(".") && filename.endsWith(".mp3")) {
|
||||
found = true;
|
||||
}
|
||||
entry.close();
|
||||
if (found) break;
|
||||
}
|
||||
if (found) {
|
||||
_unmapped_folders.push_back(folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
SPIMaster::select_sd(false);
|
||||
}
|
||||
|
||||
void PlaylistManager::_check_for_special_chars(String s) {
|
||||
for(int i=0; i<s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c < 0x20 || c >= 0x7F) {
|
||||
ERROR("WARNING: Folder / file '%s' contains non-ascii chars!\n", s.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Playlist* PlaylistManager::get_playlist_for_id(String id) {
|
||||
if (!_map.count(id)) return NULL;
|
||||
String folder = _map[id];
|
||||
return get_playlist_for_folder(folder);
|
||||
}
|
||||
|
||||
Playlist* PlaylistManager::get_playlist_for_folder(String folder) {
|
||||
Playlist* p;
|
||||
if (!_playlists.count(folder)) {
|
||||
p = new Playlist(folder);
|
||||
_playlists[folder] = p;
|
||||
if (p->persistence == PERSIST_PERMANENTLY) {
|
||||
String search = folder;
|
||||
search += "=";
|
||||
SPIMaster::select_sd();
|
||||
if (SD.exists("/_positions.txt")) {
|
||||
File f = SD.open("/_positions.txt", "r");
|
||||
while (true) {
|
||||
String s = f.readStringUntil('\n');
|
||||
if (s.length()==0) break;
|
||||
if (s.startsWith(search)) {
|
||||
s = s.substring(search.length());
|
||||
int idx = s.indexOf(',');
|
||||
String title_index = s.substring(0, idx);
|
||||
uint32_t position = s.substring(idx+1).toInt();
|
||||
p->set_track_by_id(title_index);
|
||||
p->set_position(position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
SPIMaster::select_sd(false);
|
||||
}
|
||||
Playlist PlaylistManager::get_playlist(String rfid_id) {
|
||||
if (rfid_id.equals(current_rfid_tag_id)) {
|
||||
return current_playlist;
|
||||
} else {
|
||||
p = _playlists[folder];
|
||||
if (p->persistence == PERSIST_NONE) {
|
||||
p->reset();
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void PlaylistManager::dump_ids() {
|
||||
for (std::map<String, String>::iterator it = _map.begin(); it!=_map.end(); it++) {
|
||||
INFO(" %s -> %s\n", it->first.c_str(), it->second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
String PlaylistManager::json() {
|
||||
DynamicJsonDocument json(10240);
|
||||
json["_type"] = "playlist_manager";
|
||||
JsonObject folders = json.createNestedObject("folders");
|
||||
for (std::map<String, String>::iterator it = _map.begin(); it!=_map.end(); it++) {
|
||||
folders[it->second] = it->first;
|
||||
}
|
||||
JsonArray started = json.createNestedArray("started");
|
||||
for (std::map<String, Playlist*>::iterator it = _playlists.begin(); it!=_playlists.end(); it++) {
|
||||
if (it->second->is_fresh()) continue;
|
||||
started.add(it->first);
|
||||
}
|
||||
JsonArray unmapped = json.createNestedArray("unmapped");
|
||||
for(String folder : _unmapped_folders) {
|
||||
unmapped.add(folder);
|
||||
}
|
||||
return json.as<String>();
|
||||
}
|
||||
|
||||
bool PlaylistManager::add_mapping(String id, String folder) {
|
||||
DEBUG("Adding mapping: %s=>%s\n", id.c_str(), folder.c_str());
|
||||
_map[id] = folder;
|
||||
_save_mapping();
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlaylistManager::_save_mapping() {
|
||||
SPIMaster::select_sd();
|
||||
File f = SD.open("/_mapping.txt", "w");
|
||||
String s = create_mapping_txt();
|
||||
unsigned char* buf = new unsigned char[s.length()];
|
||||
s.getBytes(buf, s.length());
|
||||
f.write(buf, s.length()-1);
|
||||
f.close();
|
||||
SPIMaster::select_sd(false);
|
||||
delete buf;
|
||||
}
|
||||
|
||||
String PlaylistManager::create_mapping_txt() {
|
||||
String s;
|
||||
for(std::map<String, String>::iterator it = _map.begin(); it != _map.end(); it++) {
|
||||
s += it->first;
|
||||
s += "=";
|
||||
s += it->second;
|
||||
s += '\n';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void PlaylistManager::persist(Playlist* p) {
|
||||
if (p->persistence == PERSIST_NONE) {
|
||||
_playlists.erase(p->path());
|
||||
return;
|
||||
} else if (p->persistence == PERSIST_PERMANENTLY) {
|
||||
|
||||
String search = p->path();
|
||||
search += '=';
|
||||
|
||||
bool old_file_existed = false;
|
||||
|
||||
SPIMaster::select_sd();
|
||||
if (SD.exists("_positions.txt")) {
|
||||
SD.rename("/_positions.txt", "/_positions.temp.txt");
|
||||
old_file_existed = true;
|
||||
}
|
||||
File dst = SD.open("/_positions.txt", "w");
|
||||
|
||||
if (old_file_existed) {
|
||||
File src = SD.open("/_positions.temp.txt", "r");
|
||||
|
||||
while (true) {
|
||||
String line = src.readStringUntil('\n');
|
||||
line.trim();
|
||||
if (line.startsWith(search)) continue;
|
||||
dst.println(line);
|
||||
if (map.count(rfid_id)==0) {
|
||||
Serial.printf("No known playlist for id %s.\n", rfid_id);
|
||||
return current_playlist;
|
||||
} else {
|
||||
current_playlist = Playlist();
|
||||
String entry = map[rfid_id];
|
||||
if (entry.startsWith("/")) {
|
||||
File dir = SD.open(entry);
|
||||
while(File entry = dir.openNextFile()) {
|
||||
String filename = entry.name();
|
||||
String ext = filename.substring(filename.length()-4);
|
||||
if (!entry.isDirectory() &&
|
||||
!filename.startsWith(".") &&
|
||||
ext.equals(".mp3")) {
|
||||
Serial.printf("Adding %s to the list of files\n", filename);
|
||||
current_playlist.add_file(filename);
|
||||
}
|
||||
entry.close();
|
||||
}
|
||||
dir.close();
|
||||
}
|
||||
|
||||
src.close();
|
||||
SD.remove("/_positions.temp.txt");
|
||||
current_playlist.sort();
|
||||
current_rfid_tag_id = rfid_id;
|
||||
return current_playlist;
|
||||
}
|
||||
|
||||
dst.print(search);
|
||||
dst.print(p->get_current_track_id());
|
||||
dst.print(',');
|
||||
dst.println(p->get_position());
|
||||
dst.close();
|
||||
SPIMaster::select_sd(false);
|
||||
|
||||
_playlists.erase(p->path());
|
||||
}
|
||||
}
|
||||
|
||||
void PlaylistManager::set_audio_current_time(uint32_t time) {
|
||||
audio_current_time = time;
|
||||
}
|
||||
Reference in New Issue
Block a user