Browse Source

more synchro tweaks

philippe44 5 years ago
parent
commit
c71b12b74f
1 changed files with 18 additions and 25 deletions
  1. 18 25
      components/squeezelite/output_i2s.c

+ 18 - 25
components/squeezelite/output_i2s.c

@@ -242,11 +242,11 @@ static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32
  * Main output thread
  */
 static void *output_thread_i2s() {
-	frames_t frames = 0;
+	frames_t iframes = FRAME_BLOCK, oframes;
 	size_t bytes;
 	uint32_t timer_start = 0;
-	int discard = DMA_BUF_COUNT * DMA_BUF_LEN;
-	uint32_t jitter = gettime_ms();
+	int discard = 0;
+	uint32_t fullness = gettime_ms();
 		
 	while (running) {
 			
@@ -266,31 +266,26 @@ static void *output_thread_i2s() {
 		}
 		
 		output.updated = gettime_ms();
+		output.frames_played_dmp = output.frames_played;
 		// try to estimate how much we have consumed from the DMA buffer
-		output.frames_played_dmp = output.frames_played - ((output.updated - jitter) * output.current_sample_rate) / 1000;
-		output.device_frames = DMA_BUF_COUNT * DMA_BUF_LEN;
+		output.device_frames = DMA_BUF_COUNT * DMA_BUF_LEN - ((output.updated - fullness) * output.current_sample_rate) / 1000;
 		
-		frames = _output_frames( FRAME_BLOCK ); 
+		oframes = _output_frames( iframes ); 
 		
-		SET_MIN_MAX_SIZED(frames,rec,FRAME_BLOCK);
+		SET_MIN_MAX_SIZED(oframes,rec,iframes);
 		SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
 		SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
 		SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
 		
-		// must skip first frames as buffer already filled with silence
-		// if (output.state < OUTPUT_RUNNING || output.state == OUTPUT_START_AT) {
+		// must skip first whatever is in the pipe (not when resuming)
 		if (output.state == OUTPUT_START_AT) {
-			discard = DMA_BUF_COUNT * DMA_BUF_LEN;
+			discard = output.frames_played_dmp ? 0 : output.device_frames;
 		} else if (discard) {
-			discard -= output.frames_played + frames;
-			if (discard < 0) {
-				frames += discard;
-				discard = 0;
-			} else {
-				UNLOCK;
-				continue;
-			}
-		}	
+			discard -= oframes;
+			iframes = discard ? min(FRAME_BLOCK, discard) : FRAME_BLOCK;
+			UNLOCK;
+			continue;
+		}
 		
 		UNLOCK;
 		
@@ -313,16 +308,14 @@ static void *output_thread_i2s() {
 		}
 		
 		// we assume that here we have been able to entirely fill the DMA buffers
-		i2s_write(CONFIG_I2S_NUM, obuf, frames * bytes_per_frame, &bytes, portMAX_DELAY);
-		jitter = gettime_ms();
+		i2s_write(CONFIG_I2S_NUM, obuf, oframes * bytes_per_frame, &bytes, portMAX_DELAY);
+		fullness = gettime_ms();
 			
-		if (bytes != frames * bytes_per_frame) {
-			LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", frames * bytes_per_frame, bytes);
+		if (bytes != oframes * bytes_per_frame) {
+			LOG_WARN("I2S DMA Overflow! available bytes: %d, I2S wrote %d bytes", oframes * bytes_per_frame, bytes);
 		}
 			
 		SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time);
-			
-		frames = 0;
 		
 	}