Browse Source

try to fix misc cspot issues + silence network manager log

philippe44 2 years ago
parent
commit
922889fee2

+ 5 - 2
components/spotify/Shim.cpp

@@ -126,9 +126,12 @@ static void cspotTask(void *pvParameters) {
             case CSpotEventType::PLAY_PAUSE: {
                 bool isPaused = std::get<bool>(event.data);
 				if (isPaused) cspot.cHandler(CSPOT_PAUSE);
-				else cspot.cHandler(CSPOT_PLAY);
+				else cspot.cHandler(CSPOT_PLAY, false);
                 break;
             }
+			case CSpotEventType::PLAYBACK_START:
+				cspot.cHandler(CSPOT_PLAY, (int) std::get<bool>(event.data));
+				break;
 			case CSpotEventType::LOAD:
 				cspot.cHandler(CSPOT_LOAD, std::get<int>(event.data), -1);
 				break;
@@ -347,7 +350,7 @@ void ShimHTTPServer::registerHandler(bell::RequestType requestType, const std::s
 		.user_ctx = NULL,
 	};
 
-	// find athe first free spot and register handler
+	// find the first free spot and register handler
 	for (int i = 0; i < sizeof(uriHandlers)/sizeof(bell::httpHandler); i++) {
 		if (!uriHandlers[i]) {
 			uriHandlers[i] = handler;

+ 2 - 2
components/spotify/cspot/include/Player.h

@@ -32,19 +32,19 @@ public:
     std::function<void()> endOfFileCallback;
     int volume = 255;
     uint32_t logVolume;
+	bool needFlush = false;	
     std::atomic<bool> isRunning = false;
     trackChangedCallback trackChanged;
     std::mutex runningMutex;
 
     void setVolume(uint32_t volume);
-    void handleLoad(std::shared_ptr<TrackReference> track, std::function<void()> &trackLoadedCallback, uint32_t position_ms, bool isPaused);
+    void handleLoad(std::shared_ptr<TrackReference> track, std::function<void(bool)> &trackLoadedCallback, uint32_t position_ms, bool isPaused);
     void pause();
     void cancelCurrentTrack();
     void seekMs(size_t positionMs);
     void feedPCM(uint8_t *data, size_t len);
     void play();
     void stop();
-
 };
 
 #endif

+ 7 - 2
components/spotify/cspot/src/ChunkedAudioStream.cpp

@@ -5,8 +5,13 @@
 static size_t vorbisReadCb(void *ptr, size_t size, size_t nmemb, ChunkedAudioStream *self)
 {
     size_t readSize = 0;
-    while (readSize < nmemb * size && self->byteStream->position() < self->byteStream->size()) {
-        readSize += self->byteStream->read((uint8_t *) ptr + readSize, (size * nmemb) - readSize);
+    while (readSize < nmemb * size && self->byteStream->position() < self->byteStream->size() && self->isRunning) {
+		size_t bytes = self->byteStream->read((uint8_t *) ptr + readSize, (size * nmemb) - readSize);
+		if (bytes <= 0) {
+			CSPOT_LOG(info, "unexpected end/error of stream");
+			return readSize;
+		}	
+		readSize += bytes;
     }
     return readSize;
 }

+ 0 - 1
components/spotify/cspot/src/MercuryManager.cpp

@@ -115,7 +115,6 @@ std::shared_ptr<AudioChunk> MercuryManager::fetchAudioChunk(std::vector<uint8_t>
     this->session->shanConn->sendPacket(static_cast<uint8_t>(MercuryType::AUDIO_CHUNK_REQUEST_COMMAND), buffer);
 
     // Used for broken connection detection
-CSPOT_LOG(info, "requesting Chunk %hu", this->audioChunkSequence - 1);				
     this->lastRequestTimestamp = this->timeProvider->getSyncedTimestamp();
     return this->audioChunkManager->registerNewChunk(this->audioChunkSequence - 1, audioKey, startPos, endPos);
 }

+ 5 - 4
components/spotify/cspot/src/Player.cpp

@@ -114,7 +114,7 @@ void Player::runTask()
         }
         else
         {
-            usleep(10000);
+            usleep(20000);
         }
 
     }
@@ -147,7 +147,7 @@ void Player::cancelCurrentTrack()
     }
 }
 
-void Player::handleLoad(std::shared_ptr<TrackReference> trackReference, std::function<void()>& trackLoadedCallback, uint32_t position_ms, bool isPaused)
+void Player::handleLoad(std::shared_ptr<TrackReference> trackReference, std::function<void(bool)>& trackLoadedCallback, uint32_t position_ms, bool isPaused)
 {
     std::lock_guard<std::mutex> guard(loadTrackMutex);
 
@@ -166,7 +166,9 @@ void Player::handleLoad(std::shared_ptr<TrackReference> trackReference, std::fun
 
     this->nextTrack->trackInfoReceived = this->trackChanged;
     this->nextTrack->loadedTrackCallback = [this, framesCallback, trackLoadedCallback]() {
-        trackLoadedCallback();
+		bool needFlush = currentTrack != nullptr && currentTrack->audioStream != nullptr && currentTrack->audioStream->isRunning;
+		cancelCurrentTrack();		
+        trackLoadedCallback(needFlush);
 
         this->nextTrackMutex.lock();
         this->nextTrack->audioStream->streamFinishedCallback = this->endOfFileCallback;
@@ -175,7 +177,6 @@ void Player::handleLoad(std::shared_ptr<TrackReference> trackReference, std::fun
         this->nextTrack->loaded = true;
         this->nextTrackMutex.unlock();
 
-        cancelCurrentTrack();
     };
     this->nextTrackMutex.unlock();
 }

+ 2 - 2
components/spotify/cspot/src/SpircController.cpp

@@ -190,10 +190,10 @@ void SpircController::handleFrame(std::vector<uint8_t> &data) {
 void SpircController::loadTrack(uint32_t position_ms, bool isPaused) {
     sendEvent(CSpotEventType::LOAD, (int) position_ms);
     state->setPlaybackState(PlaybackState::Loading);
-    std::function<void()> loadedLambda = [=]() {
+    std::function<void(bool)> loadedLambda = [=](bool needFlush) {
         // Loading finished, notify that playback started
         setPause(isPaused, false);
-        sendEvent(CSpotEventType::PLAYBACK_START);
+        sendEvent(CSpotEventType::PLAYBACK_START, needFlush);
     };
 
     player->handleLoad(state->getCurrentTrack(), loadedLambda, position_ms,

+ 1 - 1
components/spotify/cspot/src/SpotifyTrack.cpp

@@ -106,7 +106,7 @@ void SpotifyTrack::trackInformationCallback(std::unique_ptr<MercuryResponse> res
         altIndex++;
         CSPOT_LOG(info, "Trying alternative %d", altIndex);
     
-        if(altIndex > trackInfo.alternative_count) {
+        if(altIndex >= trackInfo.alternative_count) {
             // no alternatives for song
             return;
         }

+ 22 - 15
components/squeezelite/decode_external.c

@@ -47,7 +47,7 @@ static EXT_RAM_ATTR struct {
 } raop_sync;
 #endif
 
-static bool abort_sink ;
+static enum { SINK_RUNNING, SINK_ABORT, SINK_DISCARD } sink_state;
 
 #define LOCK_O   mutex_lock(outputbuf->mutex)
 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
@@ -77,10 +77,10 @@ static void sink_data_handler(const uint8_t *data, uint32_t len)
 	} 
 
 	LOCK_O;
-	abort_sink = false;
+	if (sink_state == SINK_ABORT) sink_state = SINK_RUNNING;
 
 	// there will always be room at some point
-	while (len && wait && !abort_sink) {
+	while (len && wait && sink_state == SINK_RUNNING) {
 		bytes = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / (BYTES_PER_FRAME / 4);
 		bytes = min(len, bytes);
 #if BYTES_PER_FRAME == 4
@@ -95,7 +95,7 @@ static void sink_data_handler(const uint8_t *data, uint32_t len)
 #endif	
 		_buf_inc_writep(outputbuf, bytes * BYTES_PER_FRAME / 4);
 		space = _buf_space(outputbuf);
-		
+
 		len -= bytes;
 		data += bytes;
 				
@@ -156,7 +156,7 @@ static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, va_list args)
 		_buf_flush(outputbuf);
 		output.state = OUTPUT_STOPPED;
 		output.stop_time = gettime_ms();
-		abort_sink = true;
+		sink_state = SINK_ABORT;
 		LOG_INFO("BT stop");
 		break;
 	case BT_SINK_PAUSE:		
@@ -295,7 +295,7 @@ static bool raop_sink_cmd_handler(raop_event_t event, va_list args)
 			_buf_flush(outputbuf);
 			raop_state = event;
 			if (output.state > OUTPUT_STOPPED) output.state = OUTPUT_STOPPED;
-			abort_sink = true;
+			sink_state = SINK_ABORT;
 			output.frames_played = 0;
 			output.stop_time = gettime_ms();
 			break;
@@ -357,35 +357,42 @@ static bool cspot_cmd_handler(cspot_event_t cmd, va_list args)
 		break;
 	case CSPOT_DISC:
 		_buf_flush(outputbuf);
-		abort_sink = true;
+		sink_state = SINK_ABORT;
 		output.external = 0;
 		output.state = OUTPUT_STOPPED;
 		output.stop_time = gettime_ms();
 		LOG_INFO("CSpot disconnected");
 		break;
 	case CSPOT_TRACK:
-		_buf_flush(outputbuf);		
-		abort_sink = true;
 		LOG_INFO("CSpot sink new track rate %d", output.next_sample_rate);
 		break;
-	case CSPOT_PLAY:
+	case CSPOT_PLAY: {
+		int flush = va_arg(args, int);
+		if (flush) {
+			_buf_flush(outputbuf);		
+			sink_state = SINK_ABORT;
+		} else {
+			sink_state = SINK_RUNNING;			
+		}		
 		output.state = OUTPUT_RUNNING;
 		LOG_INFO("CSpot play");
 		break;
+	}	
 	case CSPOT_SEEK:
-		//TODO: can it be merged with flush (shall we stop)
 		_buf_flush(outputbuf);		
-		abort_sink = true;
+		sink_state = SINK_ABORT;
 		LOG_INFO("CSpot seek by %d", va_arg(args, int));
 		break;
 	case CSPOT_FLUSH:
 		_buf_flush(outputbuf);
-		abort_sink = true;
-		__attribute__ ((fallthrough));
+		sink_state = SINK_DISCARD;
+		output.state = OUTPUT_STOPPED;
+		LOG_INFO("CSpot flush");	
+		break;		
 	case CSPOT_PAUSE:		
 		output.state = OUTPUT_STOPPED;
 		output.stop_time = gettime_ms();
-		LOG_INFO("CSpot pause/flush");
+		LOG_INFO("CSpot pause");
 		break;
 	case CSPOT_VOLUME: {
 		u32_t volume = va_arg(args, u32_t);

+ 1 - 1
components/wifi-manager/network_manager.c

@@ -294,7 +294,7 @@ void network_start() {
 }
 
 static void event_logger(uint32_t state_machine, uint32_t state, uint32_t event) {
-    ESP_LOGI(TAG, "Handling network manager event state Id %d->[%s]", state, event_to_string(event));
+    ESP_LOGD(TAG, "Handling network manager event state Id %d->[%s]", state, event_to_string(event));
 }
 static const char * get_state_machine_result_string(state_machine_result_t result) {
     switch(result) {