|
|
|
@ -28,6 +28,58 @@ static int decode_bad(void* arg, const uint8_t*, int, int16_t*, int) { |
|
|
|
static void push(call_jitter* j, int id, int64_t received_ms = -1) { |
|
|
|
static void push(call_jitter* j, int id, int64_t received_ms = -1) { |
|
|
|
call_jitter_push(j, (const uint8_t*)&id, sizeof(id), (uint32_t)(id * 20), received_ms < 0 ? id * 20 : received_ms, nullptr); |
|
|
|
call_jitter_push(j, (const uint8_t*)&id, sizeof(id), (uint32_t)(id * 20), received_ms < 0 ? id * 20 : received_ms, nullptr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void test_audio_clock() { |
|
|
|
|
|
|
|
const uint64_t id = 987; |
|
|
|
|
|
|
|
CHECK(call_audio_start(id) == 0); |
|
|
|
|
|
|
|
auto* encoder = opus_codec_encoder_create(48000, 1); |
|
|
|
|
|
|
|
CHECK(encoder); |
|
|
|
|
|
|
|
int delay = 0; CHECK(opus_codec_encoder_delay(encoder, &delay) == 0); |
|
|
|
|
|
|
|
int16_t voice[960], output[480]; uint8_t packet[512]; |
|
|
|
|
|
|
|
int sent = 0, valid = 0; |
|
|
|
|
|
|
|
uint64_t written = 0; |
|
|
|
|
|
|
|
int64_t previous = -1; |
|
|
|
|
|
|
|
call_clock_snapshot clock{}; |
|
|
|
|
|
|
|
CHECK(call_audio_get_clock(id, 0, &clock) == 0 && !clock.valid); |
|
|
|
|
|
|
|
uint64_t epoch = clock.epoch; |
|
|
|
|
|
|
|
// Начальный burst заставляет настоящий jitter менять темп; PTS не зависит от send_ts.
|
|
|
|
|
|
|
|
for (int tick = 0; tick < 4000; tick++) { |
|
|
|
|
|
|
|
int count = tick == 0 ? 30 : (tick % 2 == 0 ? 1 : 0); |
|
|
|
|
|
|
|
for (int i = 0; i < count; i++, sent++) { |
|
|
|
|
|
|
|
for (int s = 0; s < 960; s++) voice[s] = (int16_t)(8000 * std::sin((sent * 960ll + s) * 0.09)); |
|
|
|
|
|
|
|
int len = opus_codec_encode(encoder, voice, 960, packet, sizeof(packet)); CHECK(len > 0); |
|
|
|
|
|
|
|
call_capture_time timing{1000000 + sent * 20000ll, 9, (uint32_t)delay}; |
|
|
|
|
|
|
|
call_audio_on_media(nullptr, id, (uint16_t)sent, 0, packet, len, &timing); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
CHECK(call_audio_pull_pcm(id, output, 480) == 480); written += 480; |
|
|
|
|
|
|
|
int64_t now = tick * 10000ll; |
|
|
|
|
|
|
|
call_audio_playback_progress(id, epoch, written, now, now, 1); |
|
|
|
|
|
|
|
CHECK(call_audio_get_clock(id, now, &clock) == 0 && clock.written_samples == written); |
|
|
|
|
|
|
|
if (clock.valid) { |
|
|
|
|
|
|
|
valid++; |
|
|
|
|
|
|
|
CHECK(clock.source_epoch == 9 && clock.pts_us >= previous); |
|
|
|
|
|
|
|
CHECK(clock.pts_us <= 1000000 + sent * 20000ll); |
|
|
|
|
|
|
|
CHECK(clock.pts_us > 1000000 + sent * 20000ll - 700000); |
|
|
|
|
|
|
|
previous = clock.pts_us; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
CHECK(valid > 3900); |
|
|
|
|
|
|
|
// Underrun и местные тоны продолжают device-position, но удерживают source-PTS.
|
|
|
|
|
|
|
|
int64_t held = -1; |
|
|
|
|
|
|
|
for (int tick = 4000; tick < 4300; tick++) { |
|
|
|
|
|
|
|
CHECK(call_audio_pull_pcm(id, output, 480) == 480); written += 480; |
|
|
|
|
|
|
|
call_audio_playback_progress(id, epoch, written, tick * 10000ll, tick * 10000ll, 1); |
|
|
|
|
|
|
|
CHECK(call_audio_get_clock(id, tick * 10000ll, &clock) == 0 && clock.valid); |
|
|
|
|
|
|
|
if (tick == 4200) held = clock.pts_us; |
|
|
|
|
|
|
|
if (tick > 4200) CHECK(clock.pts_us == held); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
call_audio_reset_io(id, 1); |
|
|
|
|
|
|
|
CHECK(call_audio_get_clock(id, 43000000, &clock) == 0 && clock.epoch != epoch && !clock.valid); |
|
|
|
|
|
|
|
call_audio_playback_progress(id, epoch, written, 43000000, 43000000, 1); |
|
|
|
|
|
|
|
CHECK(call_audio_get_clock(id, 43000000, &clock) == 0 && !clock.valid); |
|
|
|
|
|
|
|
call_audio_stop(); opus_codec_encoder_destroy(encoder); |
|
|
|
|
|
|
|
std::printf("audio clock: real Opus, burst/tempo, device progress, local tones and reset checked\n"); |
|
|
|
|
|
|
|
} |
|
|
|
int main() { |
|
|
|
int main() { |
|
|
|
{ |
|
|
|
{ |
|
|
|
call_jitter_window w; |
|
|
|
call_jitter_window w; |
|
|
|
@ -58,6 +110,7 @@ int main() { |
|
|
|
} |
|
|
|
} |
|
|
|
debug_set_level(DEBUG_LEVEL_WARN); |
|
|
|
debug_set_level(DEBUG_LEVEL_WARN); |
|
|
|
debug_enable_console(1); |
|
|
|
debug_enable_console(1); |
|
|
|
|
|
|
|
test_audio_clock(); |
|
|
|
int16_t pcm[480]; |
|
|
|
int16_t pcm[480]; |
|
|
|
int depth, tempo; |
|
|
|
int depth, tempo; |
|
|
|
uint32_t dropped, under; |
|
|
|
uint32_t dropped, under; |
|
|
|
|