Bug 208678 - Sound: analogue audio output on Raspberry pi
Summary: Sound: analogue audio output on Raspberry pi
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: arm Any
: --- Affects Only Me
Assignee: Oleksandr Tymoshenko
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-10 18:13 UTC by Sylvain Garrigues
Modified: 2016-04-15 17:16 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sylvain Garrigues 2016-04-10 18:13:12 UTC
The first point of this bug is a continuous flow of warnings when using sysctl hw.snd.verbose=4 and playing sound (see "how to reproduce" below).

The second point is that since February, a new firmware option (audio_pwm_mode=2) has been added which greatly improves the analogue audio output:
https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=136445

With this option, there is almost no more white noise on analogue output, making the RPI2 great again for music listening. Except that there are small distortions in the sound and I believe they are related to our kernel driver anyway (related to first point?) as 
1/ there are no distortions when using omxplayer to play the sound in userland
2/ I have no such problem using NetBSD. I looked at the difference in the driver and they do some prefilling before playing and have a bigger VCHIQ audio buffer size and send more audio messages at once if I am correct.


How to reproduce:
# pkg install mpg123
# sysctl hw.snd.verbose=4
# fetch http://www.noiseaddicts.com/samples_1w72b820/4190.mp3     
# mpg123 4190.mp3 ==> sound is distorted with audio_pwm_mode=2, it is not without this option, but in both cases I have LOTS of warnings in dmesg

Check dmesg:
….
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=124000, old=124000 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=0, old=0 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=0, old=0 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=4000, old=4000 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=8000, old=8000 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=12000, old=12000 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=16000, old=16000 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=20000, old=20000 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=24000, old=24000 delta=0 amt=0 ready=8192 free=119808
feed_root: (virtual) appending 3128 bytes (count=3364 l=236 feed=480)
pcm0: chn_sync(): timeout=4 count=51 hcount=51 resid=0 residp=0 minflush=0 ret=0
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=28000, old=28000 delta=0 amt=0 ready=8192 free=119808
pcm0: chn_trigger() pcm0:play:dsp0.p0: calling go=0xffffffff , prev=0x00000001
pcm0: chn_trigger() pcm0:virtual:dsp0.vp0: calling go=0xffffffff , prev=0x00000001
pcm0: chn_resizebuf(): PCMDIR_PLAY (hardware) timeout=4 b[128000/4000/2] bs[8192/4096/2] limit=0
pcm0: chn_resizebuf(): PCMDIR_PLAY (virtual) timeout=4 b[0/0/0] bs[65536/2048/32] limit=7526
Comment 1 commit-hook freebsd_committer freebsd_triage 2016-04-13 05:28:57 UTC
A commit references this bug:

Author: gonzo
Date: Wed Apr 13 05:28:27 UTC 2016
New revision: 297911
URL: https://svnweb.freebsd.org/changeset/base/297911

Log:
  Multiple fixes in VCHI audio driver:

  - Pre-buffer audio data to VideoCore so there are no audible glitches when
      driver is too late to provide samples
  - Start actual playback when there is some prebuffered audio,
      it fixes audible noisy click in the beginning of playback
  - Use #defines instead of hardcoded values where appropriate
  - Fix copy-pasted comment

  PR:		208678

Changes:
  head/sys/arm/broadcom/bcm2835/bcm2835_audio.c
Comment 2 Oleksandr Tymoshenko freebsd_committer freebsd_triage 2016-04-13 05:54:37 UTC
Could you please test r297911 and let me know if it fixed audio issues? 

Warning messages is still going to be printed but in this case I believe it's bogus

Thank you
Comment 3 Sylvain Garrigues 2016-04-13 09:23:02 UTC
Hi Oleksandr,

You rock, it fixed my sound issues (which sounded like buffer underrun) even with audio_pwm_mode=2!

What is your rationale behind the VCHIQ_AUDIO_PREBUFFER=10 value?

You are right about the verbose messages in dmesg however with sysctl hw.snd.verbose=4, I still have a continuous flow of warnings in dmesg while playing any sound:

pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=96000, old=96000 delta=0 amt=0 ready=8192 free=119808
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow ! hwptr=100000, old=100000 delta=0 amt=0 ready=8192 free=119808

I am no expert at kernel sound code here but I just wonder if we play well with the latency framework (all those sysctl hw.snd* and sysctl dev.pcm* tunables). Most seem to have no effect.

In particular, as I was expecting problems with buffers underrun, I looked at other drivers in the src tree (at least the specific arm ones) and they seem to do more stuff than your driver in bcmchan_setblocksize:

---
allwinner/a10_codec.c:
---
static uint32_t
a10codec_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
{
        struct a10codec_chinfo *ch = data;
                
        ch->blocksize = blocksize & ~3;
                
        return (ch->blocksize);
}


---
freescale/imx/imx6_ssi.c:
---
static uint32_t
ssichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
{
        struct sc_chinfo *ch = data;
        struct sc_pcminfo *scp = ch->parent;
        struct sc_info *sc = scp->sc;
 
        sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize);
 
        setup_dma(scp);

        return (sndbuf_getblksz(ch->buffer));
}

Is it something worth looking? Are these PCMDIR_PLAY DMA completion too fast/slow really bogus?

Anyway Oleksandr, you are just incredible and fixed the song problem very fast, great work.
Comment 4 Oleksandr Tymoshenko freebsd_committer freebsd_triage 2016-04-13 17:47:55 UTC
10 was taken out of thin air. No particular rationale behind it.

I think this "fast/slow" is due to the way VCHI part works. When you enqueue audio buffer on "real" hardware the "finished" callback called when all audiosamples are played.   So once you enqueued several buffers there is always delta between buffer head and buffer tail and head moves every N milliseconds where N is time required to play all the samples in one chunk. When you enqueue audio buffer to VCHI I believe samples are copied to some internal buffer on VideoCore side and API call returns immediately, so tail of the buffer always catches up with its head almost immediately. 

Mind you this is just educated guess, I didn't check this theory.
Comment 5 Sylvain Garrigues 2016-04-13 23:35:07 UTC
Makes sense.

Can anybody from freebsd-sound help and explain other possible causes for 
pcm0: WARNING: PCMDIR_PLAY DMA completion too fast/slow
?

If not, I am willing to clause this bug as the symptoms are gone, it just remains the invisible warnings.
Comment 6 Sylvain Garrigues 2016-04-15 17:16:55 UTC
OK. Closing the bug if nobody else can help.