diff --git a/components/spotify/Shim.cpp b/components/spotify/Shim.cpp index 8615c78d..37c9b5d1 100644 --- a/components/spotify/Shim.cpp +++ b/components/spotify/Shim.cpp @@ -39,13 +39,13 @@ class chunkManager : public bell::Task { public: std::atomic isRunning = true; std::atomic isPaused = true; - std::atomic discard = true; - chunkManager(std::shared_ptr centralAudioBuffer, std::function trackHandler, - std::function dataHandler); + chunkManager(std::function trackHandler, std::function dataHandler); + size_t writePCM(uint8_t* data, size_t bytes, std::string_view trackId, size_t sequence); + void flush(); void teardown(); private: - std::shared_ptr centralAudioBuffer; + std::unique_ptr centralAudioBuffer; std::function trackHandler; std::function dataHandler; std::mutex runningMutex; @@ -53,20 +53,27 @@ private: void runTask() override; }; -chunkManager::chunkManager(std::shared_ptr centralAudioBuffer, - std::function trackHandler, std::function dataHandler) +chunkManager::chunkManager(std::function trackHandler, std::function dataHandler) : bell::Task("chunker", 4 * 1024, 0, 0) { - this->centralAudioBuffer = centralAudioBuffer; + this->centralAudioBuffer = std::make_unique(32); this->trackHandler = trackHandler; this->dataHandler = dataHandler; startTask(); } +size_t chunkManager::writePCM(uint8_t* data, size_t bytes, std::string_view trackId, size_t sequence) { + return centralAudioBuffer->writePCM(data, bytes, sequence); +} + void chunkManager::teardown() { isRunning = false; std::scoped_lock lock(runningMutex); } +void chunkManager::flush() { + centralAudioBuffer->clearBuffer(); +} + void chunkManager::runTask() { std::scoped_lock lock(runningMutex); size_t lastHash = 0; @@ -89,11 +96,10 @@ void chunkManager::runTask() { if (lastHash != chunk->trackHash) { CSPOT_LOG(info, "hash update %x => %x", lastHash, chunk->trackHash); lastHash = chunk->trackHash; - discard = false; trackHandler(); } - if (!discard) dataHandler(chunk->pcmData, chunk->pcmSize); + dataHandler(chunk->pcmData, chunk->pcmSize); } } @@ -105,7 +111,6 @@ class cspotPlayer : public bell::Task { private: std::string name; bell::WrappedSemaphore clientConnected; - std::shared_ptr centralAudioBuffer; int startOffset, volume = 0, bitrate = 160; httpd_handle_t serverHandle; @@ -225,8 +230,7 @@ esp_err_t cspotPlayer::handlePOST(httpd_req_t *request) { void cspotPlayer::eventHandler(std::unique_ptr event) { switch (event->eventType) { case cspot::SpircHandler::EventType::PLAYBACK_START: { - chunker->discard = true; - centralAudioBuffer->clearBuffer(); + chunker->flush(); // we are not playing anymore trackStatus = TRACK_INIT; @@ -257,17 +261,17 @@ void cspotPlayer::eventHandler(std::unique_ptr event case cspot::SpircHandler::EventType::PREV: case cspot::SpircHandler::EventType::FLUSH: { // FLUSH is sent when there is no next, just clean everything - centralAudioBuffer->clearBuffer(); + chunker->flush(); cmdHandler(CSPOT_FLUSH); break; } case cspot::SpircHandler::EventType::DISC: - centralAudioBuffer->clearBuffer(); + chunker->flush(); cmdHandler(CSPOT_DISC); chunker->teardown(); break; case cspot::SpircHandler::EventType::SEEK: { - centralAudioBuffer->clearBuffer(); + chunker->flush(); cmdHandler(CSPOT_SEEK, std::get(event->data)); break; } @@ -372,7 +376,6 @@ void cspotPlayer::runTask() { CSPOT_LOG(info, "Spotify client connected for %s", name.c_str()); - centralAudioBuffer = std::make_shared(32); auto ctx = cspot::Context::createFromBlob(blob); if (bitrate == 320) ctx->config.audioFormat = AudioFormat_OGG_VORBIS_320; @@ -385,11 +388,20 @@ void cspotPlayer::runTask() { // Auth successful if (token.size() > 0) { spirc = std::make_unique(ctx); + + // Create a player, pass the track handler + chunker = std::make_unique( + [this](void) { + return trackHandler(); + }, + [this](const uint8_t* data, size_t bytes) { + return dataHandler(data, bytes); + }); // set call back to calculate a hash on trackId spirc->getTrackPlayer()->setDataCallback( [this](uint8_t* data, size_t bytes, std::string_view trackId, size_t sequence) { - return centralAudioBuffer->writePCM(data, bytes, sequence); + return chunker->writePCM(data, bytes, trackId, sequence); }); // set event (PLAY, VOLUME...) handler @@ -401,15 +413,6 @@ void cspotPlayer::runTask() { // Start handling mercury messages ctx->session->startTask(); - // Create a player, pass the tack handler - chunker = std::make_unique(centralAudioBuffer, - [this](void) { - return trackHandler(); - }, - [this](const uint8_t* data, size_t bytes) { - return dataHandler(data, bytes); - }); - // set volume at connection cmdHandler(CSPOT_VOLUME, volume); @@ -447,7 +450,6 @@ void cspotPlayer::runTask() { } // we want to release memory ASAP and for sure - centralAudioBuffer.reset(); ctx.reset(); token.clear();