Marshall Mason
2015-Jun-14 17:02 UTC
[Vorbis-dev] Sound glitch when using libvorbisfile and libao
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/20150614/ce81f818/attachment.htm
Marshall Mason
2015-Jun-27 01:50 UTC
[Vorbis-dev] Sound glitch when using libvorbisfile and libao
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, ¤t_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
Gunter Königsmann
2015-Jun-27 18:10 UTC
[Vorbis-dev] Sound glitch when using libvorbisfile and libao
That might be it: Did do all my tests on a quite powerful system with only a single demanding process working. I wonder if libao does a separate system call for every data buffer you gave it and therefore the overhead spent per sample increased. Or if sending data to your sound driver exactly when a buffer has been played back triggers some race condition or... ...but you are right: you never know if something that seems to trigger bugs only sporadically and only on very few systems isn't a big bug that will keep you busy for years lateron. Kind regards, Gunter. On Sa, Jun 27, 2015 at 3:50 , Marshall Mason <marshallmason2 at gmail.com> wrote:> 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, ¤t_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/20150627/b311d717/attachment.htm