[pulseaudio-discuss] pcm_params.c:2351: sndrv_pcm_hw_params: Assertion `err >= 0' failed. when Pulse (via ALSA) called from C

Nick Thompson rextanka at comcast.net
Thu Apr 24 18:31:24 PDT 2008


So I figured this out.

OK turns out my issue was how I was configuring the hardware.  I do  
think that an ALSA app that runs under ALSA should run unmodified, so  
this might be a bug (and judging from the traffic about the symptom I  
was seeing, it might also be fixed in a later release than the one I  
am using).

Either way when my app was causing the crash when I used the app with  
ALSA through  pulseaudio,  I was setting buffer and period thusly:

     // Set number of periods.
     if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods,  
0) < 0) {
     	fprintf(stderr, "Error setting periods.\n");
     	return(-1);
     }

     // Set buffer size (in frames).
     if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams,  
(periodsize * periods)>>2) < 0) {
         fprintf(stderr, "Error setting buffersize to %d.\n",   
((periodsize * periods)>>2));
         return(-1);
     }

In debugging why ALSA barfed it became apparent that some parameters  
seemed not to be set correctly (I presume the alsa-pulse plugin might  
not be totally correct, since with vanilla alsa it was OK, but then  
again maybe I got lucky).

Changing the buffer setup code (mostly cribbed from aplay.c) to the  
following allowed the app to work fine with the version of pulse and  
ALSA I have installed.

     // set up a sensible default buffer time.  A resonable buffer size
     // is 2048 sample frames, so work back from there...
     //

     if (buffer_time == 0 && buffer_frames == 0) {
	if(snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time, 0) <  
0 ) {
	    fprintf(stderr, "Error getting max buffer time\n");
	    return(-1) ;
	}
	if (buffer_time > 500000) {
             // original code just dumped 500000 in here, I'd rather  
do this based on
             // the sample rate of the device.  Buffer time is in  
uSeconds
             buffer_time = (int)(((1.0/exact_rate) * 2048.0) *  
1000000.0) ;
             fprintf(stderr,"%d - buffertime\n", buffer_time);
         }
     }

     if (period_time == 0 && period_frames == 0) {
	if (buffer_time > 0)
	    period_time = buffer_time / 4;
	else
	    period_frames = buffer_frames / 4;
     }
     if (period_time > 0) {
	if(snd_pcm_hw_params_set_period_time_near(pcm_handle, hwparams,  
&period_time, 0) <0) {
	    fprintf(stderr,"Error could not set period time\n") ;
	    return(-1) ;
	} else {
	    if( snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams,  
&period_frames, 0)) {
		fprintf(stderr,"Error setting period size\n") ;
		return (-1) ;
	    }
	}
     }

     if (buffer_time > 0) {
	if(snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hwparams,  
&buffer_time, 0)<0) {
	    fprintf(stderr,"Can't set buffer time (near)\n") ;
	    return(-1) ;
	}
     } else {
	if(snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams,  
&buffer_frames)<0) {
	    fprintf(stderr,"Error can't set buffer size (near)\n") ;
	    return(-1) ;
	}
     }

Hope this is helpful to someone :)

Nick


On Apr 24, 2008, at 12:09 PM, Nick Thompson wrote:

> Hi all,
>
> This is my first post here, and I'm new to Pulse and ALSA and
> linux :)  So I hope this is not a total noob question.
>
> I'm having some issues interfacing interfacing an C based alsa program
> through pulse.  I'm using a multi output device setup with an HDA
> based RealTek ALC 883 audio codec on my MLB (an Asus P5K) and a USB
> Audio Device 1.0 spec compliant USB device (a Lexicon Alpha).
>



More information about the pulseaudio-discuss mailing list