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(); String _serial_buffer = String();
void _execute_serial_command(String cmd); void _execute_serial_command(String cmd);
void _execute_command_ls(String path); void _execute_command_ls(String path);
void _execute_command_ids();
void _execute_command_help(); void _execute_command_help();
unsigned long _button_last_pressed_at[NUM_BUTTONS]; unsigned long _button_last_pressed_at[NUM_BUTTONS];
bool _check_button(uint8_t btn); bool _check_button(uint8_t btn);

View File

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

View File

@ -66,7 +66,7 @@ void Controller::_check_rfid() {
_no_rfid_card_count = 0; _no_rfid_card_count = 0;
String temp = String(uid, HEX); String temp = String(uid, HEX);
String s_uid = ""; 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("0");
} }
s_uid.concat(temp); s_uid.concat(temp);
@ -125,6 +125,8 @@ void Controller::_execute_serial_command(String cmd) {
_player->track_prev(); _player->track_prev();
} else if (cmd.equals("n")) { } else if (cmd.equals("n")) {
_player->track_next(); _player->track_next();
} else if (cmd.equals("ids")) {
_execute_command_ids();
} else { } else {
ERROR("Unknown command: %s\n", cmd.c_str()); 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) { void Controller::_execute_command_ls(String path) {
INFO("Listing contents of %s:\n", path.c_str()); INFO("Listing contents of %s:\n", path.c_str());
std::list<String> files = _player->ls(path); 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()); 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() { void Controller::_execute_command_help() {
INFO("Valid commands are:"); INFO("Valid commands are:");
INFO(" help - Displays this help\n"); INFO(" help - Displays this help\n");
INFO(" ls [dir] - Lists the contents of [dir] or, if not given, of /\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(" play [id] - Plays the album with the given id\n");
INFO(" sys [file]- Plays the file as system sound\n"); INFO(" sys [file]- Plays the file as system sound\n");
INFO(" stop - Stops playback\n"); INFO(" stop - Stops playback\n");

View File

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