Added serial command ids; id-to-folder mapping now works.

This commit is contained in:
Fabian Schlenz 2019-11-13 06:51:38 +01:00
parent 0531b599fe
commit e20e6b7d3e
4 changed files with 45 additions and 32 deletions

View File

@ -24,6 +24,7 @@ private:
String _serial_buffer = String();
void _execute_serial_command(String cmd);
void _execute_command_ls(String path);
void _execute_command_ids();
void _execute_command_help();
unsigned long _button_last_pressed_at[NUM_BUTTONS];
bool _check_button(uint8_t btn);

View File

@ -8,6 +8,7 @@
#define SCI_MODE 0x00
#define SCI_STATUS 0x01
#define SCI_BASS 0x02
#define SCI_CLOCKF 0x03
#define SCI_DECODE_TIME 0x04
#define SCI_AUDATA 0x05
@ -16,6 +17,7 @@
#define SCI_WRAM 0x06
#define SCI_HDAT0 0x08
#define SCI_HDAT1 0x09
#define SCI_AIADDR 0x0A
#define SCI_AICTRL0 0x0C
#define SCI_AICTRL1 0x0D
#define SCI_AICTRL2 0x0E
@ -28,14 +30,10 @@
#define SM_RESET 0x0004
#define SM_CANCEL 0x0008
#define SM_SDINEW 0x0800
#define SM_ADPCM 0x1000
#define SS_DO_NOT_JUMP 0x8000
struct ID_to_Folder_Map {
const char* id;
const char* folder;
};
class Player {
private:
enum state { uninitialized, idle, playing, stopping,
@ -96,8 +94,9 @@ private:
uint32_t _skip_to;
SPIMaster* _spi;
unsigned long _stopped_at;
std::list<ID_to_Folder_Map> _id_to_folder_map;
public:
std::map<String, String> id_to_folder_map;
Player(SPIMaster* s);
void vol_up();
void vol_down();

View File

@ -66,7 +66,7 @@ void Controller::_check_rfid() {
_no_rfid_card_count = 0;
String temp = String(uid, HEX);
String s_uid = "";
for (int i=0; i<(8-s_uid.length()); i++) {
for (int i=0; i<(8-temp.length()); i++) {
s_uid.concat("0");
}
s_uid.concat(temp);
@ -125,6 +125,8 @@ void Controller::_execute_serial_command(String cmd) {
_player->track_prev();
} else if (cmd.equals("n")) {
_player->track_next();
} else if (cmd.equals("ids")) {
_execute_command_ids();
} else {
ERROR("Unknown command: %s\n", cmd.c_str());
}
@ -134,15 +136,22 @@ void Controller::_execute_serial_command(String cmd) {
void Controller::_execute_command_ls(String path) {
INFO("Listing contents of %s:\n", path.c_str());
std::list<String> files = _player->ls(path);
for(std::list<String>::iterator it=files.begin(); it!=files.end(); it++) {
for(std::list<String>::iterator it=files.begin(); it!=files.end(); ++it) {
INFO(" %s\n", (*it).c_str());
}
}
void Controller::_execute_command_ids() {
for (std::map<String, String>::iterator it = _player->id_to_folder_map.begin(); it!=_player->id_to_folder_map.end(); ++it) {
INFO(" %s -> %s\n", it->first.c_str(), it->second.c_str());
}
}
void Controller::_execute_command_help() {
INFO("Valid commands are:");
INFO(" help - Displays this help\n");
INFO(" ls [dir] - Lists the contents of [dir] or, if not given, of /\n");
INFO(" ids - Lists all known ID-to-folder mappings\n");
INFO(" play [id] - Plays the album with the given id\n");
INFO(" sys [file]- Plays the file as system sound\n");
INFO(" stop - Stops playback\n");

View File

@ -53,15 +53,15 @@ void Player::_init() {
DEBUG("VS1053 Init looking good.\n");
DEBUG("Upping VS1053 multiplier...\n");
_write_control_register(SCI_CLOCKF, 0x6000);
_write_control_register(SCI_CLOCKF, 0xC000);
delay(10);
_spi_settings = &_spi_settings_fast;
result = _read_control_register(SCI_CLOCKF);
DEBUG("SCI_CLOCKF: 0x%04X\n", result);
if (result != 0x6000) {
ERROR("Error: SCI_CLOCKF was 0x%04X, expected was 0x6000. Rebooting.\n", result);
if (result != 0xC000) {
ERROR("Error: SCI_CLOCKF was 0x%04X, expected was 0xC000. Rebooting.\n", result);
delay(500);
ESP.restart();
}
@ -119,14 +119,16 @@ void Player::_wakeup() {
void Player::_record() {
DEBUG("Starting recording.\n");
_set_volume(1, false);
_write_control_register(SCI_AICTRL0, 8000U); // Sampling rate 8000 Hz
set_volume(1, false);
_write_control_register(SCI_AICTRL0, 16000); // Sampling rate 8000 Hz
_write_control_register(SCI_AICTRL1, 2048U); // Manual gain, 2x
_write_control_register(SCI_AICTRL2, 2048U); // Maximum gain for autogain - ignored
_write_control_register(SCI_AICTRL3, 6); // 2 (left channel) + 4 (PCM)
_write_control_register(SCI_MODE, _read_control_register(SCI_MODE) | SM_ADPCM);
_write_control_register(SCI_AICTRL3, 4); // 2 (left channel) + 4 (PCM)
_write_control_register(SCI_BASS, 0);
_write_control_register(SCI_MODE, SM_ADPCM | SM_SDINEW);
DEBUG("SCI_MODE is now 0x%04X\n", _read_control_register(SCI_MODE));
_patch_adpcm();
_write_control_register(SCI_AIADDR, 0x3000);
_state = recording;
}
@ -189,13 +191,14 @@ void Player::_patch_adpcm() {
0x000a,0x0001, /*copy 1*/
0x0050,
};
const uint8_t patch_size = 74;
DEBUG("Executing patch_adpcm()...\n");
const uint16_t patch_size = 74;
DEBUG("Patching...\n");
_spi->select_vs1053_xcs();
SPI.beginTransaction(*_spi_settings);
for (int i=0; i<patch_size; i++) {
DEBUG(" %d\n", i);
unsigned short addr, n, val;
addr = patch_data[i++];
n = patch_data[i++];
@ -409,32 +412,34 @@ void Player::_fill_id_to_folder_map() {
File entry;
while (entry = root.openNextFile()) {
String foldername = entry.name();
// Remove trailing slash
foldername.remove(foldername.length());
TRACE("Looking at %s...\n", foldername.c_str());
if (!entry.isDirectory() || foldername.startsWith("/.")) continue;
if (!SD.exists(foldername + "/id.txt")) {
TRACE("Folder %s does not contain id.txt -> ignoring\n", foldername.c_str());
if (!SD.exists(foldername + "/ids.txt")) {
TRACE("Folder %s does not contain ids.txt -> ignoring\n", foldername.c_str());
continue;
}
TRACE("Reading contents of %s...\n", (foldername + "/id.txt").c_str());
File f = SD.open(foldername + "/id.txt");
TRACE("Reading contents of %s...\n", (foldername + "/ids.txt").c_str());
File f = SD.open(foldername + "/ids.txt");
String buffer = "";
while (f.available()) {
char c = f.read();
if (c=='\n' || c=='\r') {
if (buffer.length() > 0) {
ID_to_Folder_Map m = {buffer.c_str(), foldername.c_str()};
DEBUG("Adding mapping '%s'=>'%s'\n", m.id, m.folder);
_id_to_folder_map.push_back(m);
id_to_folder_map[buffer] = foldername;
DEBUG("Adding mapping '%s'=>'%s'\n", buffer.c_str(), foldername.c_str());
buffer = "";
}
} else {
buffer.concat(c);
}
}
f.close();
if (buffer.length() > 0) {
ID_to_Folder_Map m = {buffer.c_str(), foldername.c_str()};
DEBUG("Adding mapping '%s'=>'%s'\n", m.id, m.folder);
_id_to_folder_map.push_back(m);
id_to_folder_map[buffer] = foldername;
DEBUG("Adding mapping '%s'=>'%s'\n", buffer.c_str(), foldername.c_str());
}
entry.close();
}
@ -463,11 +468,10 @@ bool Player::play_id(String id) {
String Player::_foldername_for_id(String id) {
DEBUG("Searching for id %s...\n", id.c_str());
for(std::list<ID_to_Folder_Map>::iterator it=_id_to_folder_map.begin(); it!=_id_to_folder_map.end(); it++) {
if (id.equals((*it).id)) {
DEBUG("Found folder '%s' for id %s.\n", (*it).folder, id.c_str());
return (*it).folder;
}
std::map<String, String>::iterator it = id_to_folder_map.find(id);
if (it != id_to_folder_map.end()) {
DEBUG("Found folder '%s' for id %s.\n", it->first.c_str(), it->second.c_str());
return it->second;
}
DEBUG("No folder found for id %s.\n", id.c_str());
return "";