mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 13:07:03 +03:00
update CSpot
This commit is contained in:
@@ -77,7 +77,7 @@ void ChunkedAudioStream::seekMs(uint32_t positionMs)
|
||||
CSPOT_LOG(debug, "--- Finished seeking!");
|
||||
}
|
||||
|
||||
void ChunkedAudioStream::startPlaybackLoop()
|
||||
void ChunkedAudioStream::startPlaybackLoop(uint8_t *pcmOut, size_t pcmOut_len)
|
||||
{
|
||||
|
||||
isRunning = true;
|
||||
@@ -91,7 +91,6 @@ void ChunkedAudioStream::startPlaybackLoop()
|
||||
}
|
||||
|
||||
bool eof = false;
|
||||
std::vector<uint8_t> pcmOut(4096 / 4);
|
||||
byteStream->setEnableLoadAhead(true);
|
||||
|
||||
while (!eof && isRunning)
|
||||
@@ -100,7 +99,7 @@ void ChunkedAudioStream::startPlaybackLoop()
|
||||
{
|
||||
|
||||
this->seekMutex.lock();
|
||||
long ret = ov_read(&vorbisFile, (char *)&pcmOut[0], 4096 / 4, ¤tSection);
|
||||
long ret = ov_read(&vorbisFile, (char *)&pcmOut[0], pcmOut_len, ¤tSection);
|
||||
this->seekMutex.unlock();
|
||||
if (ret == 0)
|
||||
{
|
||||
@@ -117,8 +116,7 @@ void ChunkedAudioStream::startPlaybackLoop()
|
||||
else
|
||||
{
|
||||
// Write the actual data
|
||||
auto data = std::vector<uint8_t>(pcmOut.begin(), pcmOut.begin() + ret);
|
||||
pcmCallback(data);
|
||||
pcmCallback(pcmOut, ret);
|
||||
// audioSink->feedPCMFrames(data);
|
||||
}
|
||||
}
|
||||
@@ -170,4 +168,4 @@ void ChunkedAudioStream::seek(size_t dpos, Whence whence)
|
||||
break;
|
||||
}
|
||||
byteStream->seek(seekPos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ size_t ChunkedByteStream::read(uint8_t *buf, size_t nbytes) {
|
||||
if (chunk != nullptr) {
|
||||
// Wait for chunk if not loaded yet
|
||||
if (!chunk->isLoaded && !chunk->isFailed) {
|
||||
BELL_LOG(info, "cspot", "Chunk not loaded, waiting for %d", chunkIndex);
|
||||
chunk->isLoadedSemaphore->wait();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ void Player::seekMs(size_t positionMs)
|
||||
// VALGRIND_DO_LEAK_CHECK;
|
||||
}
|
||||
|
||||
void Player::feedPCM(std::vector<uint8_t>& data)
|
||||
void Player::feedPCM(uint8_t *data, size_t len)
|
||||
{
|
||||
// Simple digital volume control alg
|
||||
// @TODO actually extract it somewhere
|
||||
@@ -51,8 +51,8 @@ void Player::feedPCM(std::vector<uint8_t>& data)
|
||||
{
|
||||
int16_t* psample;
|
||||
uint32_t pmax;
|
||||
psample = (int16_t*)(data.data());
|
||||
for (int32_t i = 0; i < (data.size() / 2); i++)
|
||||
psample = (int16_t*)(data);
|
||||
for (int32_t i = 0; i < (len / 2); i++)
|
||||
{
|
||||
int32_t temp;
|
||||
// Offset data for unsigned sinks
|
||||
@@ -68,25 +68,27 @@ void Player::feedPCM(std::vector<uint8_t>& data)
|
||||
}
|
||||
}
|
||||
|
||||
this->audioSink->feedPCMFrames(data.data(), data.size());
|
||||
this->audioSink->feedPCMFrames(data, len);
|
||||
}
|
||||
|
||||
void Player::runTask()
|
||||
{
|
||||
uint8_t *pcmOut = (uint8_t *) malloc(4096 / 4);
|
||||
std::scoped_lock lock(this->runningMutex);
|
||||
this->isRunning = true;
|
||||
while (isRunning)
|
||||
{
|
||||
if (this->trackQueue.wpop(currentTrack)) {
|
||||
currentTrack->audioStream->startPlaybackLoop();
|
||||
currentTrack->audioStream->startPlaybackLoop(pcmOut, 4096 / 4);
|
||||
currentTrack->loadedTrackCallback = nullptr;
|
||||
currentTrack->audioStream->streamFinishedCallback = nullptr;
|
||||
currentTrack->audioStream->audioSink = nullptr;
|
||||
currentTrack->audioStream->pcmCallback = nullptr;
|
||||
} else {
|
||||
//usleep(100000);
|
||||
usleep(100);
|
||||
}
|
||||
}
|
||||
free(pcmOut);
|
||||
}
|
||||
|
||||
void Player::stop() {
|
||||
@@ -115,9 +117,9 @@ void Player::handleLoad(std::shared_ptr<TrackReference> trackReference, std::fun
|
||||
std::lock_guard<std::mutex> guard(loadTrackMutex);
|
||||
cancelCurrentTrack();
|
||||
|
||||
pcmDataCallback framesCallback = [=](std::vector<uint8_t>& frames) {
|
||||
this->feedPCM(frames);
|
||||
};
|
||||
pcmDataCallback framesCallback = [=](uint8_t *frames, size_t len) {
|
||||
this->feedPCM(frames, len);
|
||||
};
|
||||
|
||||
auto loadedLambda = trackLoadedCallback;
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ PlayerState::PlayerState(std::shared_ptr<TimeProvider> timeProvider)
|
||||
|
||||
innerFrame.device_state.name = strdup(configMan->deviceName.c_str());
|
||||
|
||||
innerFrame.state.track_count = 0;
|
||||
|
||||
// Prepare player's capabilities
|
||||
addCapability(CapabilityType_kCanBePlayer, 1);
|
||||
addCapability(CapabilityType_kDeviceType, 4);
|
||||
@@ -133,11 +135,44 @@ void PlayerState::updatePositionMs(uint32_t position)
|
||||
innerFrame.state.position_ms = position;
|
||||
innerFrame.state.position_measured_at = timeProvider->getSyncedTimestamp();
|
||||
}
|
||||
|
||||
void PlayerState::updateTracks()
|
||||
{
|
||||
CSPOT_LOG(info, "---- Track count %d", remoteFrame.state.track_count);
|
||||
std::swap(innerFrame.state.context_uri, remoteFrame.state.context_uri);
|
||||
std::swap(innerFrame.state.track, remoteFrame.state.track);
|
||||
|
||||
// free unused tracks
|
||||
if(innerFrame.state.track_count > remoteFrame.state.track_count)
|
||||
{
|
||||
for(uint16_t i = remoteFrame.state.track_count; i < innerFrame.state.track_count; ++i)
|
||||
{
|
||||
free(innerFrame.state.track[i].gid);
|
||||
}
|
||||
}
|
||||
|
||||
// reallocate memory for new tracks
|
||||
innerFrame.state.track = (TrackRef *) realloc(innerFrame.state.track, sizeof(TrackRef) * remoteFrame.state.track_count);
|
||||
|
||||
for(uint16_t i = 0; i < remoteFrame.state.track_count; ++i)
|
||||
{
|
||||
uint16_t gid_size = remoteFrame.state.track[i].gid->size;
|
||||
// allocate if need more tracks
|
||||
if(i >= innerFrame.state.track_count)
|
||||
{
|
||||
innerFrame.state.track[i].gid = (pb_bytes_array_t *) malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(gid_size));
|
||||
}
|
||||
memcpy(innerFrame.state.track[i].gid->bytes, remoteFrame.state.track[i].gid->bytes, gid_size);
|
||||
innerFrame.state.track[i].gid->size = gid_size;
|
||||
innerFrame.state.track[i].has_queued = remoteFrame.state.track[i].has_queued;
|
||||
innerFrame.state.track[i].queued = remoteFrame.state.track[i].queued;
|
||||
// not used?
|
||||
innerFrame.state.track[i].uri = NULL;
|
||||
innerFrame.state.track[i].context = NULL;
|
||||
}
|
||||
|
||||
innerFrame.state.context_uri = (char *) realloc(innerFrame.state.context_uri,
|
||||
strlen(remoteFrame.state.context_uri) + 1);
|
||||
strcpy(innerFrame.state.context_uri, remoteFrame.state.context_uri);
|
||||
|
||||
innerFrame.state.track_count = remoteFrame.state.track_count;
|
||||
innerFrame.state.has_playing_track_index = true;
|
||||
innerFrame.state.playing_track_index = remoteFrame.state.playing_track_index;
|
||||
@@ -236,4 +271,4 @@ void PlayerState::addCapability(CapabilityType typ, int intValue, std::vector<st
|
||||
|
||||
this->innerFrame.device_state.capabilities[capabilityIndex].stringValue_count = stringValue.size();
|
||||
this->capabilityIndex += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ SpircController::SpircController(std::shared_ptr<MercuryManager> manager,
|
||||
subscribe();
|
||||
}
|
||||
|
||||
SpircController::~SpircController() {
|
||||
}
|
||||
|
||||
void SpircController::subscribe() {
|
||||
mercuryCallback responseLambda = [=](std::unique_ptr<MercuryResponse> res) {
|
||||
// this->trackInformationCallback(std::move(res));
|
||||
|
||||
@@ -89,8 +89,13 @@ void SpotifyTrack::trackInformationCallback(std::unique_ptr<MercuryResponse> res
|
||||
std::swap(trackInfo.file, trackInfo.alternative[altIndex].file);
|
||||
std::swap(trackInfo.file_count, trackInfo.alternative[altIndex].file_count);
|
||||
std::swap(trackInfo.gid, trackInfo.alternative[altIndex].gid);
|
||||
|
||||
CSPOT_LOG(info, "Trying alternative %d", altIndex);
|
||||
altIndex++;
|
||||
|
||||
if(altIndex > trackInfo.alternative_count) {
|
||||
// no alternatives for song
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto trackId = pbArrayToVector(trackInfo.gid);
|
||||
|
||||
Reference in New Issue
Block a user