Nick Sonneveld
Nick Sonneveld

Reputation: 3436

openal: Get the current playing position of a source

How do you get the current position of a playing source in openal? I guess I mean, what position in the audio is currently playing on the hardware after its gone through your buffers, openal's buffers, the hardware buffers, etc.

I've had a brief look at the api but I'm not quite sure what AL_SAMPLE_OFFSET/AL_BYTE_OFFSET/AL_SEC_OFFSET are meant to represent. If I am playing a streaming source, I don't seem to get a constantly increasing number, it seems maybe I'm getting a position in the current playing buffer? (or of all buffers?)

for example, while playing, I loop and run this code:

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

and get

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

which doesn't seem to be increasing.

This is on macos 10.7 with latest xcode 4.3 but I'm assuming it should be similar on other platforms.

update:

I've tried increasing the buffer size and it does actually look like its only the current position in the currently playing buffer:

 - 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

So given that, is there a decent way of keeping track as openal plays through multiple different buffers?

Upvotes: 2

Views: 4207

Answers (2)

Kenny
Kenny

Reputation: 132

I know it pretty late, but if your are using libsndfile you can get position of current stream playback by just seeking file with mode SEEK_CUR and then converting samples to seconds. (of course if you are deviding buffer chunks by samples.) In my case my sample chunk is 8192 per buffer, and my buffers count that im streaming is 4. If you are using byte offset instead of samples it becomes a little harder, since you need also convert byte offset to samples and then you need to multiple it by channels count aswell.

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

float GetCurrentPlayTime() {

    float sampleRate    = 48000; // You get the sample rate from SF_INFO.
    float bufferSampels = 8192;  // Samples per buffer that give nice chuck at 44.1HZ.
    float bufferCount   = 4;     // Count of streaming buffers.

    // 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 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 playSamplesOffset = ((float) bufferSamples / sampleRate) * bufferCount;
    position = position - playSamplesOffset;

    return position;
}

Result in my case: Playback

Upvotes: 0

Mārtiņš Možeiko
Mārtiņš Možeiko

Reputation: 12927

Those offsets are from beginning of queued buffers. You need to manually count size of already unqueued buffers and add to this number.

Here, if you read the documentation, it says on page 40:

The position is relative to the beginning of all the queued buffers for the source, and any queued buffers traversed by a set call will be marked as processed.

Upvotes: 2

Related Questions