[Vorbis-dev] Sound glitch when using libvorbisfile and libao

Marshall Mason marshallmason2 at gmail.com
Fri Jun 26 18:50:51 PDT 2015


Hi Gunter,
I've solved the sound glitch. Since it was hard to reproduce, it took me a
while, but I eventually figured it out.

What I needed to do was fill the buffer with more data before handing it
off to ao_play. It requires lots of bookkeeping, pointer arithmetic, and a
sufficiently large buffer.

First, the bigger buffer. I just pulled this code from ogg123:

#define PRIMAGIC (2*2*2*2*3*3*3*5*7)
#define AUDIO_CHUNK_SIZE ((16384 + PRIMAGIC - 1)/ PRIMAGIC * PRIMAGIC)
char convbuffer[AUDIO_CHUNK_SIZE];
const int convsize = AUDIO_CHUNK_SIZE;

The loop is now more convoluted. Here's the old one, for reference:

long bytes_read = 0;
do {
    bytes_read = decode_vorbisfile(&vf);
    ao_play(device, pcmout, bytes_read);
} while (bytes_read > 0);

Here's the new loop, which now works:

long bytes_filled = 0;
long bytes_remaining = convsize;
while (1) {
    while (bytes_remaining >= 4096) {
        int current_section;
        long bytes_read = ov_read(&vf, convbuffer + bytes_filled,
bytes_remaining, 0, 2, 1, &current_section);
        if (bytes_read == 0) break;
        bytes_remaining -= bytes_read;
        bytes_filled += bytes_read;
    }
    if (bytes_filled == 0) break;
    ao_play(device, convbuffer, bytes_filled);
    bytes_remaining = convsize;
    bytes_filled = 0;
}

I'm not sure why, when the system is busy, the buffer needs more data
before ao_play is called. All I can think of is that there might be some
sort of race condition and ov_read is filling the buffer too slowly to keep
up with ao_play.

Thanks,
Marshall

On Sun, Jun 14, 2015 at 10:02 AM, Marshall Mason <marshallmason2 at gmail.com>
wrote:

> Hi Gunter,
> I think this problem started happening when I upgraded from Debian Wheezy
> to Debian Jessie. If nothing looks amiss in my code, it probably is a sound
> driver problem. But since it works 100% of the time in ogg123, I feel I
> must have missed some corner case.
>
> My audio driver is almost always active. I usually have my music player
> going in the background when I do my testing. The problem surfaces more
> reliably after watching a bunch of YouTube videos, but not consistently
> enough to use it as a test case.
>
> I'll keep poking at it, and will give an update if I figure it out.
>
> Thanks for your responses.
>
> Marshall
>
> On Sun, Jun 14, 2015 at 12:51 AM, Gunter Königsmann <gunter at peterpall.de>
> wrote:
>
>> Dear Marshall,
>>
>> I spent most of yesterday finding out that wxWidget's wxStringArray
>> sometimes drops whitespace in a new entry depending on the character the
>> last entry ended with - so I know what you mean. But your code looks clean
>> and after listening to the bell for what felt too long I started using your
>> program as a regular audio player.
>> I too assume the problem lies in the audio driver your soundcard is using
>> and has to be triggered by using some exact timing. One potential way to
>> test for this would be keeping the audio driver active between running
>> instances of your program: You said the problem always turns up when
>> starting the playback. Is it possible for you to constantly play back
>> silent audio in the background while testing? Alsa can be configured to
>> automatically mix all streams that are being played back simultaneously and
>> the sound servers all support this feature, too.
>>
>> Kind regards,
>>
>>      Gunter.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/vorbis-dev/attachments/20150626/af3b77e3/attachment.htm 


More information about the Vorbis-dev mailing list