proper solution to track "plop" - release

This commit is contained in:
philippe44
2023-04-17 19:34:49 +02:00
parent 4ee9878a6f
commit f4388a8c0a

View File

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