2
\$\begingroup\$

I require to implement a statically played sound class which supports looping of the audio data - and requires this to be changed at runtime (e.g., turning off looping).

Maybe I understand something horribly wrong, but this is how I understood how to implement looping at all, and came to the following solution:

  • I have exactly one buffer containing all the audio data.
  • If looping is enabled, ensure that the source playing the sound has this buffer queued twice, so it replays the sound when the end of the current buffer has been reached:

    if (Loop && _source.BuffersQueued == 1)
    {
        _source.QueueBuffers(_buffer);
    }
    
  • If a buffer has been processed (e.g. right after the sound audibly loops), it is unqueued and dismissed.

    if (_source.BuffersProcessed > 0)
    {
        _source.UnqueueBuffers(_source.BuffersProcessed); // Unqueue outdated buffers
    }
    

Here I ran into the first problem: If the user sets the sound to not loop anymore, I cannot unqueue the upcoming buffer (to make it not loop over another time while looping has already been turned off).

This is because I only found methods to unqueue by the handle of the buffer, but since I queue the same buffer twice, the handle is always the same to the one currently playing. OpenAL tries to unqueue the currently played buffer then, which obviously fails.

Unqueuing by the number of processed buffers also doesn't help, as no buffer has been marked as processed yet.

Do I really need to completely duplicate the buffer with all the audio data, keep it stored twice in memory, just to have two different buffer handles to unqueue the second buffer if looping gets disabled?

\$\endgroup\$
  • \$\begingroup\$ Maybe I understand something completely wrong, but can't you just do alBufferi(buffer, AL_LOOPING, 0); to disable looping and alBufferi(buffer, AL_LOOPING, 1); to enable it? Why use queues for it? \$\endgroup\$ – HolyBlackCat May 9 '15 at 20:38
  • \$\begingroup\$ @HolyBlackCat: You probably mean setting that on the source, not the buffer, with alSourcei(Source, AL_LOOPING, AL_TRUE);? \$\endgroup\$ – Ray Koopa May 9 '15 at 21:06
  • \$\begingroup\$ Yes, you're right. Typo. So, is this solution ok for you? \$\endgroup\$ – HolyBlackCat May 9 '15 at 23:07
  • \$\begingroup\$ Yeah, I tried it now. Generally it's exactly what I need. It behaves slightly weird if I set it at runtime, sometimes, when a previous non-looped source has finished playing, and I set it to loop, it starts playback automatically again - sometimes not. I'll find out why (my code is really basic, the error shouldnt be there...). Can you post it as an answer so I can accept it? =3c \$\endgroup\$ – Ray Koopa May 10 '15 at 8:49
6
\$\begingroup\$

There is a simpler way to do looping:

alSourcei(source, AL_LOOPING, 1); enables it for a source and
alSourcei(source, AL_LOOPING, 0); disables it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.