diff --git a/src/player.cpp b/src/player.cpp index 2d29603..93921a7 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -102,7 +102,7 @@ void Player::_sleep() { } void Player::_wakeup() { - if (_state != sleeping) return; + if (_state != sleeping && _state != recording) return; _stopped_at = millis(); DEBUG("Waking VS1053...\n"); set_volume(_volume, false); @@ -116,13 +116,14 @@ void Player::_wakeup() { } void Player::_record() { + DEBUG("Starting recording.\n"); + _set_volume(1, false); _write_control_register(SCI_AICTRL0, 8000U); // 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) - uint16_t mode = _read_control_register(SCI_MODE); - mode = mode | SM_RESET | SM_ADPCM; - _write_control_register(SCI_MODE, mode); + _write_control_register(SCI_MODE, _read_control_register(SCI_MODE) | SM_ADPCM); + DEBUG("SCI_MODE is now 0x%04X\n", _read_control_register(SCI_MODE)); _patch_adpcm(); _state = recording; } @@ -160,56 +161,66 @@ void Player::_write_control_register(uint8_t address, uint16_t value) { _wait(); _spi->select_vs1053_xcs(); SPI.beginTransaction(*_spi_settings); - _write_direct(address, value); - SPI.endTransaction(); - _spi->select_vs1053_xcs(false); -} - -void Player::_write_direct(uint8_t target, uint16_t value) { SPI.transfer(CMD_WRITE); - SPI.transfer(target); + SPI.transfer(address); SPI.transfer(value >> 8); SPI.transfer(value & 0xFF); + SPI.endTransaction(); + _spi->select_vs1053_xcs(false); _wait(); } void Player::_patch_adpcm() { + const uint16_t patch_data[] = { + 0x0007,0x0001, /*copy 1*/ + 0x8050, + 0x0006,0x0042, /*copy 66*/ + 0x0000,0x1790,0xf400,0x5400,0x0000,0x0a10,0xf400,0x5600, + 0xb080,0x0024,0x0007,0x9257,0x3f00,0x0024,0x0030,0x0297, + 0x3f00,0x0024,0x0000,0x004d,0x0014,0x958f,0x0000,0x1b4e, + 0x280f,0xe100,0x0006,0x2016,0x2a00,0x17ce,0x3e12,0xb817, + 0x3e14,0xf812,0x3e01,0xb811,0x0007,0x9717,0x0020,0xffd2, + 0x0030,0x11d1,0x3111,0x8024,0x3704,0xc024,0x3b81,0x8024, + 0x3101,0x8024,0x3b81,0x8024,0x3f04,0xc024,0x2808,0x4800, + 0x36f1,0x9811,0x2814,0x9c91,0x0000,0x004d,0x2814,0x9940, + 0x003f,0x0013, + 0x000a,0x0001, /*copy 1*/ + 0x0050, + }; + const uint8_t patch_size = 74; + DEBUG("Executing patch_adpcm()...\n"); + _spi->select_vs1053_xcs(); SPI.beginTransaction(*_spi_settings); - _write_direct(SCI_WRAMADDR, 0x8010); - _write_direct(SCI_WRAM, 0x3e12); - _write_direct(SCI_WRAM, 0xb817); - _write_direct(SCI_WRAM, 0x3e14); - _write_direct(SCI_WRAM, 0xf812); - _write_direct(SCI_WRAM, 0x3e01); - _write_direct(SCI_WRAM, 0xb811); - _write_direct(SCI_WRAM, 0x0007); - _write_direct(SCI_WRAM, 0x9717); - _write_direct(SCI_WRAM, 0x0020); - _write_direct(SCI_WRAM, 0xffd2); - _write_direct(SCI_WRAM, 0x0030); - _write_direct(SCI_WRAM, 0x11d1); - _write_direct(SCI_WRAM, 0x3111); - _write_direct(SCI_WRAM, 0x8024); - _write_direct(SCI_WRAM, 0x3704); - _write_direct(SCI_WRAM, 0xc024); - _write_direct(SCI_WRAM, 0x3b81); - _write_direct(SCI_WRAM, 0x8024); - _write_direct(SCI_WRAM, 0x3101); - _write_direct(SCI_WRAM, 0x8024); - _write_direct(SCI_WRAM, 0x3b81); - _write_direct(SCI_WRAM, 0x8024); - _write_direct(SCI_WRAM, 0x3f04); - _write_direct(SCI_WRAM, 0xc024); - _write_direct(SCI_WRAM, 0x2808); - _write_direct(SCI_WRAM, 0x4800); - _write_direct(SCI_WRAM, 0x36f1); - _write_direct(SCI_WRAM, 0x9811); - _write_direct(SCI_WRAMADDR, 0x8028); - _write_direct(SCI_WRAM, 0x2a00); - _write_direct(SCI_WRAM, 0x040e); + + for (int i=0; i> 8); + SPI.transfer(val & 0xFF); + _wait(); + } + } else { /* Copy run, copy n samples */ + while (n--) { + val = patch_data[i++]; + SPI.transfer(val >> 8); + SPI.transfer(val & 0xFF); + _wait(); + } + } + } + SPI.endTransaction(); _spi->select_vs1053_xcs(false); + + DEBUG("Patch sent.\n"); } void Player::_write_data(uint8_t* buffer) { @@ -629,6 +640,7 @@ bool Player::loop() { if (_state == recording) { uint16_t samples_available = _read_control_register(SCI_HDAT1); + //DEBUG("Samples available: %d\n", samples_available); if (samples_available >= 500) { unsigned long sum = 0; for (int i=0; i<500; i++) {