Added serial command ids; id-to-folder mapping now works.
This commit is contained in:
parent
0531b599fe
commit
e20e6b7d3e
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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");
|
||||||
|
@ -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 "";
|
||||||
|
Loading…
Reference in New Issue
Block a user