Re: Sound glitch when using libvorbisfile and libao

Gunter Königsmann <[email protected]> Sat, 27 Jun 2015 20:10:25 +0200
Newsgroups gmane.comp.multimedia.ogg.vorbis.devel
Message-ID <[email protected]>
--===============1035671412==
Content-Type: multipart/alternative; boundary="=-Rjm8Fh4Ma/8hS+66H2r8"

--=-Rjm8Fh4Ma/8hS+66H2r8
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: quoted-printable

That might be it: Did do all my tests on a quite powerful system with=20
only a single demanding process working.
I wonder if libao does a separate system call for every data buffer you=20
gave it and therefore the overhead spent per sample increased.
Or if sending data to your sound driver exactly when a buffer has been=20
played back triggers some race condition or... ...but you are right: =20
you never know if something that seems to trigger bugs only=20
sporadically and only on very few systems isn't a big bug that will=20
keep you busy for years lateron.

Kind regards,

 Gunter.

On Sa, Jun 27, 2015 at 3:50 , Marshall Mason <[email protected]>=20
wrote:
> Hi Gunter,
> I've solved the sound glitch. Since it was hard to reproduce, it took=20
> me a while, but I eventually figured it out.
>=20
> What I needed to do was fill the buffer with more data before handing=20
> it off to ao_play. It requires lots of bookkeeping, pointer=20
> arithmetic, and a sufficiently large buffer.
>=20
> First, the bigger buffer. I just pulled this code from ogg123:
>=20
> #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 =3D AUDIO_CHUNK_SIZE;
>=20
> The loop is now more convoluted. Here's the old one, for reference:
>=20
> long bytes_read =3D 0;
> do {
>     bytes_read =3D decode_vorbisfile(&vf);
>     ao_play(device, pcmout, bytes_read);
> } while (bytes_read > 0);
>=20
> Here's the new loop, which now works:
>=20
> long bytes_filled =3D 0;
> long bytes_remaining =3D convsize;
> while (1) {
>     while (bytes_remaining >=3D 4096) {
>         int current_section;
>         long bytes_read =3D ov_read(&vf, convbuffer + bytes_filled,=20
> bytes_remaining, 0, 2, 1, &current_section);
>         if (bytes_read =3D=3D 0) break;
>         bytes_remaining -=3D bytes_read;
>         bytes_filled +=3D bytes_read;
>     }
>     if (bytes_filled =3D=3D 0) break;
>     ao_play(device, convbuffer, bytes_filled);
>     bytes_remaining =3D convsize;
>     bytes_filled =3D 0;
> }
>=20
> I'm not sure why, when the system is busy, the buffer needs more data=20
> before ao_play is called. All I can think of is that there might be=20
> some sort of race condition and ov_read is filling the buffer too=20
> slowly to keep up with ao_play.
>=20
> Thanks,
> Marshall
>=20
> On Sun, Jun 14, 2015 at 10:02 AM, Marshall Mason=20
> <[email protected]> wrote:
>> Hi Gunter,
>> I think this problem started happening when I upgraded from Debian=20
>> Wheezy to Debian Jessie. If nothing looks amiss in my code, it=20
>> probably is a sound driver problem. But since it works 100% of the=20
>> time in ogg123, I feel I must have missed some corner case.
>>=20
>> My audio driver is almost always active. I usually have my music=20
>> player going in the background when I do my testing. The problem=20
>> surfaces more reliably after watching a bunch of YouTube videos, but=20
>> not consistently enough to use it as a test case.
>>=20
>> I'll keep poking at it, and will give an update if I figure it out.
>>=20
>> Thanks for your responses.
>>=20
>> Marshall
>>=20
>> On Sun, Jun 14, 2015 at 12:51 AM, Gunter K=C3=B6nigsmann=20
>> <[email protected]> wrote:
>>> Dear Marshall,
>>>=20
>>> I spent most of yesterday finding out that wxWidget's wxStringArray=20
>>> sometimes drops whitespace in a new entry depending on the=20
>>> character the last entry ended with - so I know what you mean. But=20
>>> your code looks clean and after listening to the bell for what felt=20
>>> 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=20
>>> using and has to be triggered by using some exact timing. One=20
>>> potential way to test for this would be keeping the audio driver=20
>>> active between running instances of your program: You said the=20
>>> problem always turns up when starting the playback. Is it possible=20
>>> for you to constantly play back silent audio in the background=20
>>> while testing? Alsa can be configured to automatically mix all=20
>>> streams that are being played back simultaneously and the sound=20
>>> servers all support this feature, too.
>>>=20
>>> Kind regards,
>>>=20
>>>      Gunter.
>>=20
>=20
=

--=-Rjm8Fh4Ma/8hS+66H2r8
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

That might be it: Did do all my tests on a quite powerful system with only =
a single demanding process working.<div>I wonder if libao does a separate s=
ystem call for every data buffer you gave it and therefore the overhead spe=
nt per sample increased.</div><div>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: &nbsp;you never know if something that seems to tr=
igger bugs only sporadically and only on very few systems isn't a big bug t=
hat will keep you busy for years lateron.</div><div><br></div><div>Kind reg=
ards,</div><div><br></div><div>&nbsp;Gunter.<br><br>On Sa, Jun 27, 2015 at =
3:50 , Marshall Mason &lt;[email protected]&gt; wrote:<br>
<blockquote type=3D"cite"><div dir=3D"ltr"><div>Hi Gunter,</div><div>I've s=
olved the sound glitch. Since it was hard to reproduce, it took me a while,=
 but I eventually figured it out.</div><div><br></div><div>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.</div><div><br></div><div>First, the bigger buffer. I just pulled t=
his code from ogg123:</div><div><br></div><div>#define PRIMAGIC (2*2*2*2*3*=
3*3*5*7)</div><div>#define AUDIO_CHUNK_SIZE ((16384 + PRIMAGIC - 1)/ PRIMAG=
IC * PRIMAGIC)</div><div>char convbuffer[AUDIO_CHUNK_SIZE];</div><div>const=
 int convsize =3D AUDIO_CHUNK_SIZE;</div><div><br></div><div>The loop is no=
w more convoluted. Here's the old one, for reference:</div><div><br></div><=
div>long bytes_read =3D 0;</div><div>do {</div><div>&nbsp; &nbsp; bytes_rea=
d =3D decode_vorbisfile(&amp;vf);</div><div>&nbsp; &nbsp; ao_play(device, p=
cmout, bytes_read);</div><div>} while (bytes_read &gt; 0);</div><div><br></=
div><div>Here's the new loop, which now works:</div><div><br></div><div>lon=
g bytes_filled =3D 0;</div><div>long bytes_remaining =3D convsize;</div><di=
v>while (1) {</div><div>&nbsp; &nbsp; while (bytes_remaining &gt;=3D 4096) =
{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int current_section;</div><div>&nbs=
p; &nbsp; &nbsp; &nbsp; long bytes_read =3D ov_read(&amp;vf, convbuffer + b=
ytes_filled, bytes_remaining, 0, 2, 1, &amp;current_section);</div><div>&nb=
sp; &nbsp; &nbsp; &nbsp; if (bytes_read =3D=3D 0) break;</div><div>&nbsp; &=
nbsp; &nbsp; &nbsp; bytes_remaining -=3D bytes_read;</div><div>&nbsp; &nbsp=
; &nbsp; &nbsp; bytes_filled +=3D bytes_read;</div><div>&nbsp; &nbsp; }</di=
v><div>&nbsp; &nbsp; if (bytes_filled =3D=3D 0) break;</div><div>&nbsp; &nb=
sp; ao_play(device, convbuffer, bytes_filled);</div><div>&nbsp; &nbsp; byte=
s_remaining =3D convsize;</div><div>&nbsp; &nbsp; bytes_filled =3D 0;</div>=
<div>}</div><div><br></div><div>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.</div><div><br></div><div>Thanks,=
</div><div>Marshall</div></div><div class=3D"gmail_extra"><br><div class=3D=
"gmail_quote">On Sun, Jun 14, 2015 at 10:02 AM, Marshall Mason <span dir=3D=
"ltr">&lt;<a href=3D"mailto:[email protected]" target=3D"_blank">mar=
[email protected]</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr">Hi Gunter,<div>I think this problem started happening w=
hen 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.</div><di=
v><br></div><div>My audio driver is almost always active. I usually have my=
 music player going in the background when I do my testing. The problem sur=
faces more reliably after watching a bunch of YouTube videos, but not consi=
stently enough to use it as a test case.</div><div><br></div><div>I'll keep=
 poking at it, and will give an update if I figure it out.</div><div><br></=
div><div>Thanks for your responses.</div><span class=3D"HOEnZb"><font color=
=3D"#888888"><div><br></div><div>Marshall</div></font></span></div><div cla=
ss=3D"HOEnZb"><div class=3D"h5"><div class=3D"gmail_extra"><br><div class=
=3D"gmail_quote">On Sun, Jun 14, 2015 at 12:51 AM, Gunter K=C3=B6nigsmann <=
span dir=3D"ltr">&lt;<a href=3D"mailto:[email protected]" target=3D"_blan=
k">[email protected]</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex">Dear Marshall,<div><br></div><div>I spent most of yesterday finding out=
 that wxWidget's wxStringArray sometimes drops whitespace in a new entry de=
pending on the character the last entry ended with - so I know what you mea=
n. 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.</div><div>=
I too assume the problem lies in the audio driver your soundcard is using a=
nd has to be triggered by using some exact timing. One potential way to tes=
t for this would be keeping the audio driver active between running instanc=
es 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 th=
e background while testing? Alsa can be configured to automatically mix all=
 streams that are being played back simultaneously and the sound servers al=
l support this feature, too.</div><div><br></div><div>Kind regards,</div><d=
iv><br></div><div>&nbsp; &nbsp; &nbsp;Gunter.</div></blockquote></div><br><=
/div>
</div></div></blockquote></div><br></div>
</blockquote></div>=

--=-Rjm8Fh4Ma/8hS+66H2r8--


--===============1035671412==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Vorbis-dev mailing list
[email protected]
http://lists.xiph.org/mailman/listinfo/vorbis-dev

--===============1035671412==--