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.
I am writing a program that tries to output sound using the ALSA API. I have already succesfully made it work through OSS (emulated) and aRts so I know there are no hardware issues. Anyway, to get to the point: at runtime, I get the following error:
if (retcode == success)
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "Cannot allocate hardware parameter structure (%s)\n", snd_strerror (err));
retcode = alsa_error;
}
if (retcode == success)
if ((err = snd_pcm_hw_params_any (*p_pb_handle, hw_params)) < 0) {
fprintf (stderr, "Cannot initialize hardware parameter structure (%s)\n", snd_strerror (err));
retcode = alsa_error;
}
if (retcode == success)
if ((err = snd_pcm_hw_params_set_access (*p_pb_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "Cannot set access type (%s)\n", snd_strerror (err));
retcode = alsa_error;
}
and friends directly before you call the snd_pcm_writei function. At least then you can confirm the most obvious of suspicisions: for some reason (not called first, whatever), you're not setting the params with your specified access before calling that function (or the flags are being modified elsewhere).
Hmm. You may well be on the right track there. I tried commenting out entirely the section that opens the device and sets its parameters, and I got the very same error.
Looking closer at the problem, I find something which I am unable to explain: I now get a segfault where one didn't appear before. I think that this is probably related to the original problem, although I don't know why it didn't segfault before. It only started doing this when I put some debug messages in. Can't figure out why it's segfaulting though. Maybe you can.
This is the beginning of the function that opens the audio device and sets its parameters:
Code:
return_status initialise_alsa(snd_pcm_t **p_pb_handle,
long *p_sample_rate,
mono_stereo *p_stereo_mode,
format *p_sample_format)
{
return_status retcode = success;
int err;
unsigned int *tmp_srate;
snd_pcm_hw_params_t *hw_params;
printf("In function initialise_alsa\n");
printf("foo\n");
*tmp_srate = (unsigned int)*p_sample_rate;
printf("bar\n");
These are edited highlights from the main() function, which calls the function quoted above:
That's a valid error. Your tmp_srate pointer is unintalized. It is not pointing to anything. So when you say *tmp_srate = (unsigned int)*p_sample_rate; you're saying put the value stored at memory location p_sample_rate into the value tmp_srate stored at memory location <unknown>. Segfault. If you're not going to use tmp_srate as a pointer, take off the * notation.
As for the orginal problem....
Quote:
I tried commenting out entirely the section that opens the device and sets its parameters, and I got the very same error.
Yes, I imagine it would give you the same error. What I mean is the init stuff looked good before, it was probably doing things right, but somewhere betwen the init stuff and the snd_pcm_writei call something happend. So maybe at the end of the initialise_alsa function you can throw in a short call to snd_pcm_writei and see if it works there.
Ha ha, of course I was just testing you with the uninitialised pointer. Ahem.
So I fixed that (blush) and did what you said, made a call to snd_pcm_writei() immediately after initialising the device. Works fine that time, then bombs out later. So you're right, something is happening between there and there. Probably passing the pointer to the device wrongly or something, I shall look into that shortly.
Just to wrap this thread up, I had my function arguments in a twist and so my device handle was being thrown away which was causing the error. Having fixed that the program now works beautifully.
I also discovered (by my program making a horrible noise) that the last argument to snd_pcm_writei is not the buffer size (as described in one of the ALSA tutorials and as in the OSS and aRts APIs) but actually the number of frames in the buffer. In the case of stereo 16-bit sound this is actually the buffer size >> 2.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.