[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