update CSpot

This commit is contained in:
philippe44
2022-03-04 20:06:19 -08:00
parent 7b1d1ad45e
commit 57b77766ff
28 changed files with 226 additions and 110 deletions

View File

@@ -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, &currentSection);
long ret = ov_read(&vorbisFile, (char *)&pcmOut[0], pcmOut_len, &currentSection);
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);
}
}

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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));

View File

@@ -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);