Skip to content

Commit bea46a4

Browse files
author
CarlosDerSeher
committed
estimate sync quality based on pcm frames fed to DMA
fix #148 Signed-off-by: CarlosDerSeher <karl_osterseher@gmx.at>
1 parent b0591e8 commit bea46a4

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

components/lightsnapcast/player.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "driver/i2s_common.h"
1010
#include "freertos/FreeRTOS.h"
11+
#include "freertos/portmacro.h"
1112
#include "freertos/semphr.h"
1213
#include "freertos/task.h"
1314

@@ -181,12 +182,12 @@ static esp_err_t player_setup_i2s(snapcastSetting_t *setting) {
181182
}
182183

183184
#if USE_SAMPLE_INSERTION
184-
i2sDmaBufCnt = 22;
185+
i2sDmaBufCnt = 3;
185186
// OPUS has a minimum frame size of 120
186187
// with DMA buffer set to this value sync algorithm
187188
// works for all decoders. We set it to 100 so
188189
// there will be free space for sample stuffing in each round
189-
i2sDmaBufMaxLen = 100;
190+
i2sDmaBufMaxLen = 1024;
190191
#else
191192
int fi2s_clk;
192193
const int __dmaBufMaxLen = 1024;
@@ -1596,6 +1597,7 @@ static void player_task(void *pvParameters) {
15961597

15971598
if ((dir_insert_sample > 0) && (size >= sampleSizeInBytes)) {
15981599
size -= sampleSizeInBytes;
1600+
dir_insert_sample = 0;
15991601
}
16001602

16011603
i2s_channel_write(tx_chan, p_payload, size, &written, portMAX_DELAY);
@@ -1610,12 +1612,12 @@ static void player_task(void *pvParameters) {
16101612
ESP_LOGE(TAG, "i2s_playback_task: I2S write error %d", 1);
16111613
}
16121614
else {
1615+
samples_written += (written / framesToBytes);
1616+
dir_insert_sample = 0;
16131617
chunkStart += (1000000ll * (written / framesToBytes) / scSet.sr);
16141618
}
16151619
}
16161620

1617-
dir_insert_sample = 0;
1618-
16191621
if (size == 0) {
16201622
if (fragment->nextFragment != NULL) {
16211623
fragment = fragment->nextFragment;
@@ -1764,22 +1766,24 @@ static void player_task(void *pvParameters) {
17641766
if (server_now(&serverNow, &diff2Server) >= 0) {
17651767
{
17661768
int64_t now_us = esp_timer_get_time();
1769+
// actually played out samples
1770+
int64_t samples_played = samples_written - i2sDmaBufCnt * i2sDmaBufMaxLen;
1771+
#if 0
17671772
// actually played out samples estimate based on clock
1768-
double samples_played_est = (now_us - playback_start_time_us) * ((float)scSet.sr / 1e6);
1769-
int64_t target_play_local_us = chunkStart - diff2Server + buf_us - outputBufferDacTime_us;
1773+
//double samples_played_est = (now_us - playback_start_time_us) * ((float)scSet.sr / 1e6);
17701774
// samples expected to have played
17711775
double samples_expected = (target_play_local_us - playback_start_time_us) * ((float)scSet.sr / 1e6);
1772-
// actually played out samples
1773-
uint64_t samples_played = samples_written - i2sDmaBufCnt * i2sDmaBufMaxLen;
1774-
// Ideal playout time based on local audio clock
1775-
int64_t actual_play_local_us = playback_start_time_us + (int64_t)((samples_played_est * 1e6) / scSet.sr);
1776+
double error_samples = samples_expected - samples_played;
1777+
ESP_LOGI(TAG, "%0.2lf", error_samples);
1778+
#endif
17761779

1777-
double error_samples = samples_expected - samples_played_est;
1780+
// expected play out based on timestamp
1781+
int64_t target_play_local_us = chunkStart - diff2Server + buf_us - outputBufferDacTime_us;
1782+
// Ideal playout time based on local audio clock
1783+
int64_t actual_play_local_us = playback_start_time_us + (int64_t)((samples_played * 1000000ll) / (int64_t)scSet.sr);
17781784
int64_t error_us = actual_play_local_us - target_play_local_us;
1779-
1780-
//ESP_LOGI(TAG, "%0.2lf, %lld, %llu/%llu", error_samples, error_us, (uint64_t)samples_played_est, samples_played);
1781-
// ESP_LOGI(TAG, "%0.2lf, %lld", error_samples, error_us);
1782-
1785+
// ESP_LOGI(TAG, "%lld", error_us);
1786+
17831787
age = error_us;
17841788
}
17851789

@@ -1861,7 +1865,7 @@ static void player_task(void *pvParameters) {
18611865
adjust_apll(dir);
18621866
}
18631867
#endif
1864-
ESP_LOGI(TAG, "%d, %lldus, %lldus, %lldus, q:%d, %lld, %lld", dir,
1868+
ESP_LOGD(TAG, "%d, %lldus, %lldus, %lldus, q:%d, %lld, %lld", dir,
18651869
age, shortMedian, miniMedian,
18661870
uxQueueMessagesWaiting(pcmChkQHdl), insertedSamplesCounter,
18671871
chunkDuration_us);

0 commit comments

Comments
 (0)