snd_pcm_hw_params_set_rate_near() returns huge value
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
snd_pcm_hw_params_set_rate_near() returns huge value
I wrote a sample program as follows to OPEN ALSA sound device and set its hw params -
Code:
/* Open PCM device for playback. */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
fprintf(stderr,
"unable to open pcm device: %s\n",
snd_strerror(rc));
return 1;
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(¶ms);
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
/* One channel (mono) */
snd_pcm_hw_params_set_channels(handle, params, 1);
/* 8000 bits/second sampling rate */
val = 8000;
snd_pcm_hw_params_set_rate_near(handle, params,
&val, &dir);
/* Set period size to 32 frames. */
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle,
params, &frames, &dir);
fflush(stderr);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
Above lines of code works fine if I run it as an independent test program.
When I use the same lines of code in my application, it is failing in snd_pcm_hw_params_any(). It returns "Operation not permitted". So I changed the device name to "plughw:0,0", instead of "default".
With this change, its failing at snd_pcm_hw_params_set_rate_near(). It returns some huge value 192000. Also, following snd_pcm_hw_params_set_period_size() also fails with 699050.
Any idea, why I'm getting this error? Is link to some other library or some header file inclusion, in my application causing this error? I am trying to play 8k, 16 bit PCM audio.
I appreciate your help on this.
So should that be a signed value but you're treating it as unsigned?
Actually both methods are documented as returning like that.
I've assigned the return value to an integer and also printing as integer. It is strange that when I run it as a independent test program, it works fine. Only when I integrate it with my application it is failing. While compiling my test program, I linked with all the libraries I use in my application. Still my test program works fine. I am trying to figure out under what conditions it fails.
An access problem? Is your integrated version running under a different user or environment than your independent test one?
Also again I may not be good with C, but when it returns 0 you'll not notice a problem with signed vs unsigned, but why would a method that's documented to return a negative error value be giving you a large positive value unless you're handling the representation wrong? A quick google indicates you can compile C ints to be signed or unsigned, there's a default but not a strict signedness. I would try get the correct negative error number/code and see what that tells you.
I realize this thread is 5 years old but I've run into the same issue myself.
ALSA has two API versions. It looks like in some cases a weird link issue can occur and cause the wrong version of a function to be called. For example, snd_pcm_hw_params_set_rate_near() in the old API expects the sample rate argument as an integer rather than an int*, and returns the newly set rate - which is why you're getting 192000 instead of 0.
I've posted a question about this to Stack Overflow, with the title "ALSA unexpected results when called from shared library" (sorry, can't post a URL here).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.