[alsa-devel] Intel HDA + HDMI - snd_pcm_drain buggy behaviour.

Takashi Iwai tiwai at suse.de
Mon Feb 17 10:02:28 CET 2014


At Sun, 16 Feb 2014 20:52:39 -0600,
Sander Jansen wrote:
> 
> Ok. Never mind. I was under the false impression that snd_pcm_drain would
> be able to handle partially filled periods. Making sure the last write
> fills at least a period seemed to have solved the issue.

Good to hear that you solved the issue by yourself.
As you found out, the ALSA core usually doesn't handle the partial
period drain.


Takashi

> 
> 
> On Sun, Feb 16, 2014 at 2:26 PM, Sander Jansen <s.jansen at gmail.com> wrote:
> 
> > Further investigation on my part I noticed a couple of mistakes I made
> > myself.
> >
> > 1. snd_pcm_drain() doesn't block in non-blocking mode. I fixed my code to
> > account for this now.
> > 2. snd_pcm_drain() doesn't block indefinitely in blocking mode. I must
> > have accidently put in a infinite loop somewhere myself.
> >
> > That leaves still with one unresolved issue, which is that calling
> > snd_pcm_drain() does indeed work in both blocking and non-blocking, but I'm
> > still hearing part of the audio that was already played before. I assume
> > this is some data in the ringbuffer that hasn't been overwritten by any new
> > data. I have been able to reproduce this on another PC (Intel G45 chipset)
> > as well (snd_intel_hda as well, but with analog output) so I don't think
> > it's HDMI related.
> >
> >
> > This is my drain code:
> >
> >     snd_pcm_state_t state = snd_pcm_state(handle);
> >     if (state==SND_PCM_STATE_RUNNING) {
> >
> >       /// block while draining
> >       //if ((result=snd_pcm_nonblock(handle,0))<0) {
> >       //  printf("[alsa] failed to set blocking mode. Reason:
> > %s\n",snd_strerror(result));
> >       //  return;
> >       //  }
> >
> >       result=snd_pcm_drain(handle);
> >       if (result==-EAGAIN) {
> >         printf("[alsa] waiting for drain\n");
> >         while(snd_pcm_state(handle)==SND_PCM_STATE_DRAINING){
> >           FXThread::sleep(500000000); // 50ms
> >           }
> >         printf("[alsa] drain complete. State:
> > %s\n",snd_pcm_state_name(snd_pcm_state(handle)));
> >         }
> >       else if (result<0) {
> >         printf("[alsa] drain failed. Reason: %s\n",snd_strerror(result));
> >         }
> >       else {
> >         printf("[alsa] drain complete\n");
> >         }
> >       }
> >
> > Anything else I'm doing wrong?
> >
> > Thanks,
> >
> > Sander
> >
> >
> > On Sat, Feb 15, 2014 at 6:44 PM, Sander Jansen <s.jansen at gmail.com> wrote:
> >
> >> All,
> >>
> >> When I play regular PCM audio through the HDMI that's connected to my
> >> amplifier I noticed  buggy behaviour when using the snd_pcm_drain() call.
> >> From my understanding of ALSA, during playback snd_pcm_drain() normally
> >> blocks until the playback buffer is empty.
> >>
> >> Here's what I'm experiencing:
> >>
> >> a. If the PCM handle is in BLOCKING mode, the snd_pcm_drain() function
> >> will block indefinitely (I've waited 30 seconds, before I gave up).
> >>
> >> b. In NON-BLOCKING mode, the first call to snd_pcm_drain results in a
> >> " Resource temporarily unavailable", subsequent call works but the pcm
> >> state has changed to DRAINING and takes about 1 sec to change to SETUP.
> >> Even though the audio has less than 0.5 seconds of actual playback left.
> >>
> >> So to make it work, I changed my single snd_pcm_drain() call into the
> >> following pseudo code:
> >> while(state==RUNNING && snd_pcm_drain()<0) {
> >>   state=snd_pcm_state()
> >>   }
> >>
> >> while(state==DRAINING && sleep(100)){
> >>   state=snd_pcm_state()
> >>   }
> >>
> >> Even though this seem to "sort of work", another problem with this
> >> approach I've noticed, is that part of the beginning of the playback buffer
> >> may be replayed at the end of the drain:
> >>
> >>   1. start playback at beginning of file
> >>   2. seek to close to the end of the file (snd_pcm_drop() gets called)
> >>   3. end of file reached, drain gets called, hear the end of the song +
> >> part of the beginning again?
> >>
> >> So I'm wondering whether this may be related to the drain issue I've
> >> noticed. I've attached the alsa-info.
> >>
> >> Thanks,
> >>
> >> Sander
> >>
> >>
> >>
> >
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 


More information about the Alsa-devel mailing list