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\$
4
  • \$\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\$ Commented May 9, 2015 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
    Commented May 9, 2015 at 21:06
  • \$\begingroup\$ Yes, you're right. Typo. So, is this solution ok for you? \$\endgroup\$ Commented May 9, 2015 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
    Commented May 10, 2015 at 8:49

1 Answer 1

7
\$\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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .