gpt4 book ai didi

android - 使用 NDK 精确的 POSIX 线程计时

转载 作者:行者123 更新时间:2023-11-30 17:50:44 24 4
gpt4 key购买 nike

我正在编写一个简单的 NDK OpenSL ES 音频应用程序,它记录用户在虚拟钢琴键盘上的触摸,然后通过设定的循环永远播放它们。经过大量实验和阅读后,我决定使用单独的 POSIX 循环来实现此目的。正如您在代码中看到的,它从 sleep 时间中减去任何处理时间,以使每个循环的间隔尽可能接近所需的 sleep 间隔(在本例中为 5000000 纳秒。

void init_timing_loop() {
pthread_t fade_in;
pthread_create(&fade_in, NULL, timing_loop, (void*)NULL);
}

void* timing_loop(void* args) {

while (1) {

clock_gettime(CLOCK_MONOTONIC, &timing.start_time_s);

tic_counter(); // simple logic gates that cycle the current tic
play_all_parts(); // for-loops through all parts and plays any notes (From an OpenSL buffer) that fall on the current tic

clock_gettime(CLOCK_MONOTONIC, &timing.finish_time_s);

timing.diff_time_s.tv_nsec = (5000000 - (timing.finish_time_s.tv_nsec - timing.start_time_s.tv_nsec));

nanosleep(&timing.diff_time_s, NULL);
}

return NULL;
}

问题是,即使使用这个,结果也更好,但相当不一致。有时音符会一次延迟甚至 50 毫秒,这会导致播放非常不稳定。

有更好的方法来解决这个问题吗?为了调试,我运行了以下代码:

gettimeofday(&timing.curr_time, &timing.tzp);
__android_log_print(ANDROID_LOG_DEBUG, "timing_loop", "gettimeofday: %d %d",
timing.curr_time.tv_sec, timing.curr_time.tv_usec);

这提供了相当一致的读数 - 这并不反射(reflect)播放的任何不准确性。 Android 是否还有其他因素阻碍了准确计时?或者 OpenSL ES 是一个潜在问题吗?所有缓冲区数据都加载到内存中 - 那里会存在瓶颈吗?

如果需要的话,很高兴发布更多 OpenSL 代码...但在这个阶段,我正在尝试弄清楚这个线程循环是否准确,或者是否有更好的方法来实现。

最佳答案

使用clock_gettime时也应该考虑秒数,您可能会得到比timing.finish_time_s.tv_nsec更大的timing.start_time_s.tv_nsec。当 tv_sec 增加时,tv_nsec 从零开始。

timing.diff_time_s.tv_nsec =
(5000000 - (timing.finish_time_s.tv_nsec - timing.start_time_s.tv_nsec));

尝试类似的事情

#define NS_IN_SEC 1000000000
(timing.finish_time_s.tv_sec * NS_IN_SEC + timing.finish_time_s.tv_nsec) -
(timing.start_time_s.tv_nsec * NS_IN_SEC + timing.start_time_s.tv_nsec)

关于android - 使用 NDK 精确的 POSIX 线程计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17099162/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com