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