diff --git a/include/controller.h b/include/controller.h index 87ba72e..48d25b2 100644 --- a/include/controller.h +++ b/include/controller.h @@ -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); diff --git a/include/player.h b/include/player.h index a6a9dae..dbefd74 100644 --- a/include/player.h +++ b/include/player.h @@ -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; public: + std::map id_to_folder_map; + Player(SPIMaster* s); void vol_up(); void vol_down(); diff --git a/src/controller.cpp b/src/controller.cpp index d156090..ed3e040 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -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 files = _player->ls(path); - for(std::list::iterator it=files.begin(); it!=files.end(); it++) { + for(std::list::iterator it=files.begin(); it!=files.end(); ++it) { INFO(" %s\n", (*it).c_str()); } } +void Controller::_execute_command_ids() { + for (std::map::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"); diff --git a/src/player.cpp b/src/player.cpp index ebbaccf..4ab74e2 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -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 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::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::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 "";