openal:获取源的当前播放位置

问题描述 投票:0回答:2

如何获取 openal 中播放源的当前位置?我想我的意思是,在经过你的缓冲区、openal 缓冲区、硬件缓冲区等之后,音频当前在硬件上播放的位置。

我已经简要查看了 api,但我不太确定 AL_SAMPLE_OFFSET/AL_BYTE_OFFSET/AL_SEC_OFFSET 代表什么。如果我正在播放流媒体源,我似乎没有得到不断增加的数字,似乎我在当前播放缓冲区中获得了一个位置? (或所有缓冲区?)

例如,在玩游戏时,我循环并运行以下代码:

alGetSourcef( sources[0], AL_SAMPLE_OFFSET, &secoffset );
printf(" - %f samples\n", secoffset);

并得到

 - 0.000000 samples
 - 8192.000000 samples
 - 9216.000000 samples
 - 5632.000000 samples

似乎没有增加。

这是在带有最新 xcode 4.3 的 macos 10.7 上,但我假设它在其他平台上应该类似。

更新:

我尝试增加缓冲区大小,它实际上看起来只是当前播放缓冲区中的当前位置:

 - 0.000000 bytes
 - 18432.000000 bytes
 - 20480.000000 bytes
 - 36864.000000 bytes
 - 36864.000000 bytes
 - 55296.000000 bytes
 - 55296.000000 bytes
 - 73728.000000 bytes
refilling buffer 2408
re-queued buffer 2408
 - 16384.000000 bytes
 - 34816.000000 bytes
 - 34816.000000 bytes
 - 51200.000000 bytes
 - 51200.000000 bytes
 - 69632.000000 bytes
refilling buffer 2409
re-queued buffer 2409

鉴于此,有没有一种不错的方法可以在多个不同缓冲区中跟踪开放游戏?

audio streaming core-audio openal
2个回答
2
投票

这些偏移量是从排队缓冲区的开头开始的。您需要手动计算已未排队的缓冲区的大小并添加到此数字中。

这里,如果您阅读了文档,第 40 页上写着:

位置相对于所有排队缓冲区的开头 对于源,并且 set 调用遍历的任何排队缓冲区都将是 标记为已处理。


0
投票

我很晚才知道,但如果您使用

libsndfile
,您只需使用模式
SEEK_CUR
查找文件,然后将样本转换为秒即可获取当前流播放的位置。 (当然,如果您按样本划分缓冲区块。)在我的情况下,我的样本块是每个缓冲区
8192
,并且我的缓冲区计算即时流是
4
。如果您使用字节偏移量而不是样本,则会变得有点困难,因为您还需要将字节偏移量转换为样本,然后还需要将其乘以通道数。

float SamplesToSeconds(sf_count_t samples, int sampleRate) {
    float seconds = samples / (float) sampleRate;
    return seconds;
}

float GetCurrentPlayTime() {

    // Retrive the current read samples count.
    sf_count_t currentSamples = sf_seek(sndfile, 0, SF_SEEK_CUR);

    // Convert the current read samples to seconds.
    float sampleRate = 48000; // You get the sample rate from SF_INFO.
    float position = SamplesToSeconds(currentSamples);

    // playSamplesOffset - is offset that needs to be subtracked from position, because 'currentSamples' is means current read 
    // samples not the play one. 
    // In general its to tricky. So when play started it reads first 4 buffers and returns its 'currentSamples' but this is
    // not actualy play postion, play position here is should be 0.01 or something like that, im not sure here but it work for my case.
    float bufferSampels = 8192;
    float bufferCount = 4;
    float playSamplesOffset = ((float) bufferSamples / sampleRate) * bufferCount;
    position = position - playSamplesOffset;

    return position;
}

我的案例结果:

© www.soinside.com 2019 - 2024. All rights reserved.