mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 20:47:08 +03:00
proper solution to track "plop" - release
This commit is contained in:
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user