mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2026-01-28 13:20:49 +03:00
big merge
This commit is contained in:
131
components/spotify/cspot/src/Player.cpp
Normal file
131
components/spotify/cspot/src/Player.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "Player.h"
|
||||
#include "Logger.h"
|
||||
|
||||
// #include <valgrind/memcheck.h>
|
||||
|
||||
Player::Player(std::shared_ptr<MercuryManager> manager, std::shared_ptr<AudioSink> audioSink): bell::Task("player", 10 * 1024, +0, 1)
|
||||
{
|
||||
this->audioSink = audioSink;
|
||||
this->manager = manager;
|
||||
startTask();
|
||||
}
|
||||
|
||||
void Player::pause()
|
||||
{
|
||||
this->currentTrack->audioStream->isPaused = true;
|
||||
}
|
||||
|
||||
void Player::play()
|
||||
{
|
||||
this->currentTrack->audioStream->isPaused = false;
|
||||
}
|
||||
|
||||
void Player::setVolume(uint32_t volume)
|
||||
{
|
||||
this->volume = (volume / (double)MAX_VOLUME) * 255;
|
||||
|
||||
// Calculate and cache log volume value
|
||||
auto vol = 255 - this->volume;
|
||||
uint32_t value = (log10(255 / ((float)vol + 1)) * 105.54571334);
|
||||
if (value >= 254) value = 256;
|
||||
logVolume = value << 8; // *256
|
||||
|
||||
// Pass volume event to the sink if volume is sink-handled
|
||||
if (!this->audioSink->softwareVolumeControl)
|
||||
{
|
||||
this->audioSink->volumeChanged(volume);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::seekMs(size_t positionMs)
|
||||
{
|
||||
this->currentTrack->audioStream->seekMs(positionMs);
|
||||
// VALGRIND_DO_LEAK_CHECK;
|
||||
}
|
||||
|
||||
void Player::feedPCM(std::vector<uint8_t>& data)
|
||||
{
|
||||
// Simple digital volume control alg
|
||||
// @TODO actually extract it somewhere
|
||||
if (this->audioSink->softwareVolumeControl)
|
||||
{
|
||||
int16_t* psample;
|
||||
uint32_t pmax;
|
||||
psample = (int16_t*)(data.data());
|
||||
for (int32_t i = 0; i < (data.size() / 2); i++)
|
||||
{
|
||||
int32_t temp;
|
||||
// Offset data for unsigned sinks
|
||||
if (this->audioSink->usign)
|
||||
{
|
||||
temp = ((int32_t)psample[i] + 0x8000) * logVolume;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = ((int32_t)psample[i]) * logVolume;
|
||||
}
|
||||
psample[i] = (temp >> 16) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
this->audioSink->feedPCMFrames(data);
|
||||
}
|
||||
|
||||
void Player::runTask()
|
||||
{
|
||||
std::scoped_lock lock(this->runningMutex);
|
||||
this->isRunning = true;
|
||||
while (isRunning)
|
||||
{
|
||||
if (this->trackQueue.wpop(currentTrack)) {
|
||||
currentTrack->audioStream->startPlaybackLoop();
|
||||
currentTrack->loadedTrackCallback = nullptr;
|
||||
currentTrack->audioStream->streamFinishedCallback = nullptr;
|
||||
currentTrack->audioStream->audioSink = nullptr;
|
||||
currentTrack->audioStream->pcmCallback = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::stop() {
|
||||
this->isRunning = false;
|
||||
CSPOT_LOG(info, "Stopping player");
|
||||
this->trackQueue.clear();
|
||||
cancelCurrentTrack();
|
||||
CSPOT_LOG(info, "Track cancelled");
|
||||
std::scoped_lock lock(this->runningMutex);
|
||||
CSPOT_LOG(info, "Done");
|
||||
}
|
||||
|
||||
void Player::cancelCurrentTrack()
|
||||
{
|
||||
if (currentTrack != nullptr)
|
||||
{
|
||||
if (currentTrack->audioStream != nullptr && currentTrack->audioStream->isRunning)
|
||||
{
|
||||
currentTrack->audioStream->isRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handleLoad(std::shared_ptr<TrackReference> trackReference, std::function<void()>& trackLoadedCallback, uint32_t position_ms, bool isPaused)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(loadTrackMutex);
|
||||
cancelCurrentTrack();
|
||||
|
||||
pcmDataCallback framesCallback = [=](std::vector<uint8_t>& frames) {
|
||||
this->feedPCM(frames);
|
||||
};
|
||||
|
||||
auto loadedLambda = trackLoadedCallback;
|
||||
|
||||
auto track = std::make_shared<SpotifyTrack>(this->manager, trackReference, position_ms, isPaused);
|
||||
track->trackInfoReceived = this->trackChanged;
|
||||
track->loadedTrackCallback = [this, track, framesCallback, loadedLambda]() {
|
||||
loadedLambda();
|
||||
track->audioStream->streamFinishedCallback = this->endOfFileCallback;
|
||||
track->audioStream->audioSink = this->audioSink;
|
||||
track->audioStream->pcmCallback = framesCallback;
|
||||
this->trackQueue.push(track);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user