LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 07-09-2004, 03:12 PM   #1
vasudevadas
Member
 
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519

Rep: Reputation: 30
Assertion `pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED' failed


Hi all,

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:

Code:
$ ./arctracker --alsa tetris.dtr
File is DESKTOP TRACKER format.
Module name: Tetris - Dr Spin Version
Author:  Kelvin Phillips 1993
Playing position 1 of 27arctracker: pcm.c:1071: snd_pcm_writei: Assertion `pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED' failed.
Aborted
arctracker is the name of my program (tetris.dtr is the name of the modfile I am attempting to play).

The edited highlights of my code are:

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;

    *tmp_srate = (unsigned int)*p_sample_rate;

    if ((err = snd_pcm_open(p_pb_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
        fprintf(stderr, "Cannot open audio device %s (%s)\n", PCM_DEVICE, snd_strerror(err));
        retcode = alsa_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;
        }

    if (retcode == success)
        if ((err = snd_pcm_hw_params_set_format (*p_pb_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
            fprintf (stderr, "Cannot set sample format (%s)\n", snd_strerror (err));
            retcode = alsa_error;
        }

    if (retcode == success) {
        *p_sample_format = bits_16_signed_little_endian;
        if ((err = snd_pcm_hw_params_set_rate_near (*p_pb_handle, hw_params, tmp_srate, 0)) < 0) {
            fprintf (stderr, "Cannot set sample rate (%s)\n", snd_strerror (err));
            retcode = alsa_error;
        }
    }

    if (retcode == success) {
        *p_sample_rate = (long)*tmp_srate;
        if ((err = snd_pcm_hw_params_set_channels (*p_pb_handle, hw_params, 2)) < 0) {
            fprintf (stderr, "Cannot set channel count (%s)\n", snd_strerror (err));
            retcode = alsa_error;
        }
    }

    if (retcode == success) {
        *p_stereo_mode = stereo;
        if ((err = snd_pcm_hw_params (*p_pb_handle, hw_params)) < 0) {
            fprintf (stderr, "Cannot set parameters (%s)\n", snd_strerror (err));
            retcode = alsa_error;
        }
    }

    if (retcode == success) {
        snd_pcm_hw_params_free (hw_params);

        if ((err = snd_pcm_prepare (*p_pb_handle)) < 0) {
            fprintf (stderr, "Cannot prepare audio interface for use (%s)\n", snd_strerror (err));
            retcode = alsa_error;
        }
    }

    return (retcode);
}

<snip>
in a completely different function, the sound data is written like this:

                        if ((err = snd_pcm_writei (p_pb_handle, audio_buffer, BUF_SIZE)) != BUF_SIZE) {
                                fprintf (stderr, "write to audio interface failed (%s)\n", snd_strerror (err));
                                return (alsa_error); /* bomb out */
                        }
<snip>
Googling for the error message does not produce many hits, and no apparent help. Any good suggestions will be highly appreciated!

BTW: PCM_DEVICE is #defined to "plughw:0,0"

Thanks.
 
Old 07-11-2004, 02:40 PM   #2
lackluster
Member
 
Registered: Apr 2002
Location: D.C - USA
Distribution: slackware-current
Posts: 488

Rep: Reputation: 30
Never programmed with ALSA, sorry. Try putting

Code:
    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).
 
Old 07-11-2004, 03:05 PM   #3
vasudevadas
Member
 
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519

Original Poster
Rep: Reputation: 30
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:

Code:
main(int argc, char *argv[])
{
<snip>
        long sample_rate = DEFAULT_SAMPLERATE;
<snip>
        snd_pcm_t *pb_handle;
<snip>
        mono_stereo stereo_mode;
<snip>
        format sample_format;
<snip>
                        printf("Calling initialise_alsa\n");
                        retcode = initialise_alsa(&pb_handle,
                                                                        &sample_rate,
                                                                        &stereo_mode,
                                                                        &sample_format);
<snip>
When I run it I get the following debug messages:

Code:
$ ./arctracker --alsa tetris.dtr
File is DESKTOP TRACKER format.
Module name: Tetris - Dr Spin Version
Author:  Kelvin Phillips 1993
Calling initialise_alsa
In function initialise_alsa
foo
Segmentation fault
So it fails on the line "*tmp_srate = (unsigned int)*p_sample_rate;" although I'm not sure why. The cast ought to make that legitimate, no?
 
Old 07-12-2004, 12:53 PM   #4
lackluster
Member
 
Registered: Apr 2002
Location: D.C - USA
Distribution: slackware-current
Posts: 488

Rep: Reputation: 30
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.
 
Old 07-12-2004, 02:37 PM   #5
vasudevadas
Member
 
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519

Original Poster
Rep: Reputation: 30
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.

Thanks for your help!
 
Old 07-15-2004, 06:57 AM   #6
vasudevadas
Member
 
Registered: Jul 2003
Location: Bedford, UK
Distribution: Slackware 11.0, LFS 6.1
Posts: 519

Original Poster
Rep: Reputation: 30
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.

Thanks again for your help.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
assertion failed TIFFDC101 General 3 09-19-2005 09:41 PM
assertion (heads<256) @disk_dos.C:486 in function probe_partition_for_geom() failed Doug.Gentry Fedora 16 06-06-2005 12:14 PM
Problem installing FC3 - Assertion Failed cevilgenius Linux - Software 1 03-26-2005 07:30 AM
HD problem installing Fedora - "assertion failed" vinthund Linux - Software 1 02-24-2005 09:45 PM
K3b Quit Working--Assertion Failed Error mooreted Linux - Software 3 04-17-2004 01:54 PM


All times are GMT -5. The time now is 11:48 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration