[Openal]How to calculate the true 'current-playing-time' for a streaming source?

Ed icelus2k5 at gmail.com
Tue Mar 4 00:55:53 PST 2008


On 04/03/2008, Keshav B Channa <kbc at dhruva.com> wrote:
> Well I don't know if it's so straight forward.
>  I stumbled across this situation:
>
>  Let's say 3 buffers have completed processing. Let's assume each buffer is
>  of 1 second.
>  Hence they add up to 3.0 seconds.
>  Let's say there are 2 buffers currently queued up.
>
>  If I call AL_SEC_OFFSET after 'n' ms then this is what I get.
>  Current buffer: AL_SEC_OFFSET = 500 ms (actual playing time = 3.0 + 0.5 =
>  3.5)
>  Current buffer: AL_SEC_OFFSET = 950 ms (actual playing time = 3.0 + 0.95 =
>  3.95)
>  Current buffer: AL_SEC_OFFSET = 1250 ms (actual playing time = 3.0 + 1.25 =
>  4.25)
>  Right now the buffer has been completed, but it hasn't gone into the
>  'processed' list yet.
>
>  Current buffer: AL_SEC_OFFSET = 1650 ms (actual playing time = 3.0 + 1.65 =
>  4.65)
>  Right now if the first buffer is marked as processed, then the actual
>  playing time would be:
>  3.0 + 1.0 = 4.0
>  But if we consider the "current playing buffer" time, also then the time
>  becomes 4.0 + 1.65 = 5.65, which is actually wrong.
>
>  If OpenAL returns the "bytes" processed for only the current-playing buffer,
>  then it would work fine.
>  But OpenAL seems to consider all buffers queued when determining the
>  AL_SEC_OFFSET value.
>
>  Am I right, or am I doing something wrong here.

I don't think I understand the problem. I wasn't suggesting you use
AL_BUFFERS_PROCESSED to measure stream position, because that (again)
only counts the number of buffers _in_the_current_queue_ that have
been processed. I have a working solution for this myself that
calculates the total byte offset into the stream from when it started
playing. The pseudocode for my simple player looks like this:

bytes_before_queue := 0
#fill buffers and queue
repeat
  buffers processed := alGetSourcei(AL_BUFFERS_PROCESSED)
  buffer_list := alSourceUnqueueBuffer(buffers_processed)
  foreach buffer in buffer_list:
       buffer_size := alGetBufferI(AL_SIZE)
       bytes_before_queue += buffer_size
       # refill and requeue buffers
  print "byte offset in stream: "+ bytes_before_queue +
alGetSourceI(AL_BYTE_OFFSET)
until done

(The point of the example was to show byte offsets not to show all the
streaming infrastructure... also obviously I mangled the function prototypes
to make what was happening clearer)

The reason (in case you're wondering) I didn't use AL_SEC_OFFSET is
there's no corresponding buffer call (e.g. AL_SIZE_SECONDS?) call and
my interface is meant to be fairly generic. But if you control the
format, you can can calculate sec offset from the byte offset of
course.

Your problem seemed to be something about race conditions between
AL_BUFFERS_PROCESSED and AL_SEC_OFFSET; but they're both consistent
for a given queue. So long as you track what you unqueue, you
shouldn't have any problems.

Ed


More information about the Openal mailing list