Use early return to avoid additional indentation
This commit is contained in:
parent
8fe2e294f8
commit
16f3246bcf
@ -253,66 +253,67 @@ sc_audio_player_frame_sink_push(struct sc_frame_sink *sink,
|
|||||||
}
|
}
|
||||||
|
|
||||||
atomic_store_explicit(&ap->received, true, memory_order_relaxed);
|
atomic_store_explicit(&ap->received, true, memory_order_relaxed);
|
||||||
|
if (!played) {
|
||||||
|
// Nothing more to do
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (played) {
|
// Number of samples added (or removed, if negative) for compensation
|
||||||
// Number of samples added (or removed, if negative) for compensation
|
int32_t instant_compensation = (int32_t) written - frame->nb_samples;
|
||||||
int32_t instant_compensation = (int32_t) written - frame->nb_samples;
|
// Inserting silence instantly increases buffering
|
||||||
// Inserting silence instantly increases buffering
|
int32_t inserted_silence = (int32_t) underflow;
|
||||||
int32_t inserted_silence = (int32_t) underflow;
|
// Dropping input samples instantly decreases buffering
|
||||||
// Dropping input samples instantly decreases buffering
|
int32_t dropped = (int32_t) skipped_samples;
|
||||||
int32_t dropped = (int32_t) skipped_samples;
|
|
||||||
|
|
||||||
// The compensation must apply instantly, it must not be smoothed
|
// The compensation must apply instantly, it must not be smoothed
|
||||||
ap->avg_buffering.avg +=
|
ap->avg_buffering.avg += instant_compensation + inserted_silence - dropped;
|
||||||
instant_compensation + inserted_silence - dropped;
|
|
||||||
|
|
||||||
// However, the buffering level must be smoothed
|
// However, the buffering level must be smoothed
|
||||||
sc_average_push(&ap->avg_buffering, can_read);
|
sc_average_push(&ap->avg_buffering, can_read);
|
||||||
|
|
||||||
#ifndef SC_AUDIO_PLAYER_NDEBUG
|
#ifndef SC_AUDIO_PLAYER_NDEBUG
|
||||||
LOGD("[Audio] can_read=%" PRIu32 " avg_buffering=%f",
|
LOGD("[Audio] can_read=%" PRIu32 " avg_buffering=%f",
|
||||||
can_read, sc_average_get(&ap->avg_buffering));
|
can_read, sc_average_get(&ap->avg_buffering));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ap->samples_since_resync += written;
|
ap->samples_since_resync += written;
|
||||||
if (ap->samples_since_resync >= ap->sample_rate) {
|
if (ap->samples_since_resync >= ap->sample_rate) {
|
||||||
// Recompute compensation every second
|
// Recompute compensation every second
|
||||||
ap->samples_since_resync = 0;
|
ap->samples_since_resync = 0;
|
||||||
|
|
||||||
float avg = sc_average_get(&ap->avg_buffering);
|
float avg = sc_average_get(&ap->avg_buffering);
|
||||||
int diff = ap->target_buffering - avg;
|
int diff = ap->target_buffering - avg;
|
||||||
|
|
||||||
// Enable compensation when the difference exceeds +/- 4ms.
|
// Enable compensation when the difference exceeds +/- 4ms.
|
||||||
// Disable compensation when the difference is lower than +/- 1ms.
|
// Disable compensation when the difference is lower than +/- 1ms.
|
||||||
int threshold = ap->compensation != 0
|
int threshold = ap->compensation != 0
|
||||||
? ap->sample_rate / 1000 /* 1ms */
|
? ap->sample_rate / 1000 /* 1ms */
|
||||||
: ap->sample_rate * 4 / 1000; /* 4ms */
|
: ap->sample_rate * 4 / 1000; /* 4ms */
|
||||||
|
|
||||||
if (abs(diff) < threshold) {
|
if (abs(diff) < threshold) {
|
||||||
// Do not compensate for small values, the error is just noise
|
// Do not compensate for small values, the error is just noise
|
||||||
diff = 0;
|
diff = 0;
|
||||||
} else if (diff < 0 && can_read < ap->target_buffering) {
|
} else if (diff < 0 && can_read < ap->target_buffering) {
|
||||||
// Do not accelerate if the instant buffering level is below
|
// Do not accelerate if the instant buffering level is below the
|
||||||
// the target, this would increase underflow
|
// target, this would increase underflow
|
||||||
diff = 0;
|
diff = 0;
|
||||||
}
|
}
|
||||||
// Compensate the diff over 4 seconds (but will be recomputed after
|
// Compensate the diff over 4 seconds (but will be recomputed after 1
|
||||||
// 1 second)
|
// second)
|
||||||
int distance = 4 * ap->sample_rate;
|
int distance = 4 * ap->sample_rate;
|
||||||
// Limit compensation rate to 2%
|
// Limit compensation rate to 2%
|
||||||
int abs_max_diff = distance / 50;
|
int abs_max_diff = distance / 50;
|
||||||
diff = CLAMP(diff, -abs_max_diff, abs_max_diff);
|
diff = CLAMP(diff, -abs_max_diff, abs_max_diff);
|
||||||
LOGV("[Audio] Buffering: target=%" PRIu32 " avg=%f cur=%" PRIu32
|
LOGV("[Audio] Buffering: target=%" PRIu32 " avg=%f cur=%" PRIu32
|
||||||
" compensation=%d", ap->target_buffering, avg, can_read, diff);
|
" compensation=%d", ap->target_buffering, avg, can_read, diff);
|
||||||
|
|
||||||
if (diff != ap->compensation) {
|
if (diff != ap->compensation) {
|
||||||
int ret = swr_set_compensation(swr_ctx, diff, distance);
|
int ret = swr_set_compensation(swr_ctx, diff, distance);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOGW("Resampling compensation failed: %d", ret);
|
LOGW("Resampling compensation failed: %d", ret);
|
||||||
// not fatal
|
// not fatal
|
||||||
} else {
|
} else {
|
||||||
ap->compensation = diff;
|
ap->compensation = diff;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user