1

I downloaded the ALSA sample source codes (https://gist.github.com/ghedo/963382) and test running under putty window, it works. However when put into the startup script (eg. rc.local) with or without "sudo", it crashed.

Note: The application only crashes after auto-run from power on; if run the script in putty (command line), no problem.

After added logging before each snd_xxx function calls, found the application stop after call snd_pcm_hw_params_any, meaning it crashes after snd_pcm_open and snd_pcm_hw_params_alloca. Following is code:

    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_open"); /////logged 
    if ((pcm = snd_pcm_open(&pcm_handle, acDev, /////PCM_DEVICE, acDev="default:0"
                    SND_PCM_STREAM_PLAYBACK, 0)) < 0)
    {
        sprintf(acLog, "[audio]Can't open \"%s\" PCM device. %s\n", acDev, snd_strerror(pcm));
        g_pLog->LogInfo(LOG_SYS, acLog);
        return -1;
    }


    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_hw_params_alloca");  /////logged
    /* Allocate parameters object and fill it with default values*/
    snd_pcm_hw_params_alloca(&params);

    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_hw_params_any");  /////logged and is the last line
    snd_pcm_hw_params_any(pcm_handle, params);

    g_pLog->LogInfo(LOG_SYS, "[audio]snd_pcm_hw_params_set_access");
    /* Set parameters */
    if (pcm = snd_pcm_hw_params_set_access(pcm_handle, params,
                    SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
...

After collect the core dump file and use gdb "bt full" to check, the result is:

root@linaro-ubuntu-desktop:/test# gdb ./AudioPlayer /opt/core.AudioPlayer.6277.1604311455.6
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabi".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /test/AudioPlayer...(no debugging symbols found)...done.
[New LWP 6277]
[Thread debugging using libthread_db enabled]
Core was generated by `/test/AudioPlayer'.
Program terminated with signal 6, Aborted.
#0  0x2ad8bed6 in ?? () from /lib/arm-linux-gnueabi/libc.so.6
(gdb) bt full
#0  0x2ad8bed6 in ?? () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#1  0x2ad9a0da in raise () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#2  0x2ad9c506 in abort () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#3  0x2ad951ec in __assert_fail () from /lib/arm-linux-gnueabi/libc.so.6
No symbol table info available.
#4  0x2ac6cb72 in snd_pcm_hw_refine () from /usr/lib/arm-linux-gnueabi/libasound.so.2
No symbol table info available.
#5  0x0000aca8 in main ()
No symbol table info available.

Note "snd_pcm_hw_refine" is not called directly from the application.

I am wondering what the difference is between running in putty and running from power-on startup script, and how to solve this failure. Appreciate if you can advise...

runningdog
  • 21
  • 5
  • Not much help without the debugging symbols. However, starting in rc.local -- make sure all prerequisites for alsa are already up and running before you attempt to start it. Also, the user that it is run by from rc.local may not have permissions through udev or whatever to access the audio devices (though sudo would). Only thoughts I have other than this being Off-Topic and better on [Super User](http://superuser.com/) or [Unix & Linux](http://unix.stackexchange.com/) – David C. Rankin Nov 02 '20 at 06:24
  • Any idea on how to avoid permission issue in source code level? I have tried following but no help: 1. to delay the snd_xxx call for 30s (to make sure driver up); 2. before calling first snd command (snd_pcm_open), read "/proc/asound/cards" to make sure the card is ready; 3. use another process run from rc.local to call this application with system("sudo ....") – runningdog Nov 02 '20 at 08:00
  • No, and not because I have no knowledge of alsa or it startup, but just because I have absolutely no idea what the startup on your device is. If you are still using rc.local -- that tells me your distro is still using init-files, or it has systemd and has simply decided to keep the old rc.local naming convention that it hooks in the boot process (somewhere). Also when your rc.local is hooked in the boot process makes a difference. The actual startup is generally `/path/to/alsactl restore`. But when that is called all `/dev/snd/control*` devices must already be setup. – David C. Rankin Nov 02 '20 at 18:40
  • You will get many, many more answers on the correct StackExchange sites. I’m voting to close this question because your question is not "Programming" related, it is more appropriate for the StackExchange sites [Super User](http://superuser.com/) or [Unix & Linux](http://unix.stackexchange.com/). (you may also try [AskUbuntu](https://askubuntu.com/)) You are 10 times more likely to find an answer at one of those sites. – David C. Rankin Nov 02 '20 at 18:42
  • Thanks David, however why this is not a Programming related issue? Is not every application (as this one) can be loaded automatically? So how to solve it by the application itself (in source code level)? – runningdog Nov 04 '20 at 00:01
  • It's not a programming question, because the question isn't about a anything related to programming, or a build error or a failed source code modification. The question is "How do I configure ALSA startup?" or "Why is ALSA failing to start?" That is what the SuperUser and Unix&Linux sites are for I linked to above. It's nothing personal, and I don't downvote these type questions, but you will really find more knowledgeable people on the appropriate sites. . – David C. Rankin Nov 04 '20 at 00:09

1 Answers1

0

The call to snd_pcm_open() open fails. The error code check then fails because pcm is unsigned. snd_pcm_hw_params_any() then crashes because pcm_handle is NULL.

There are lots of other errors in that code. Forget about it. Use something like this:

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

static void alsa_check(int result, const char *call)
{
    if (result < 0) {
        fprintf(stderr, "%s failed: %s\n", call, snd_strerror(result));
        exit(1);
    }
}
#define CHECK(f) alsa_check(f, #f)

static void play(snd_pcm_t *pcm, int frame_size)
{
#define FRAMES 50000
    void *buf, *data;
    int frames, rest;

    buf = malloc(FRAMES * frame_size);
    for (;;) {
        frames = fread(buf, frame_size, FRAMES, stdin);
        if (frames <= 0)
            break;
        rest = frames;
        data = buf;
        while (rest > 0) {
            frames = snd_pcm_writei(pcm, data, rest);
            if (frames < 0)
                CHECK(snd_pcm_recover(pcm, frames, 0));
            else {
                rest -= frames;
                data += frames * frame_size;
            }
        }
    }
    free(buf);
}

int main(int argc, char *argv[])
{
    const char *device = "default";
    snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
    snd_pcm_access_t access = SND_PCM_ACCESS_RW_INTERLEAVED;
    unsigned int channels, rate;
    unsigned int latency = 500000; /* 0.5 s */
    snd_pcm_t *pcm;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s rate channels < inputfile\n", argv[0]);
        return 1;
    }
    rate = atoi(argv[1]);
    channels = atoi(argv[2]);

    CHECK(snd_pcm_open(&pcm, device, SND_PCM_STREAM_PLAYBACK, 0));

    CHECK(snd_pcm_set_params(pcm, format, access, channels, rate, 1, latency));

    play(pcm, channels * snd_pcm_format_physical_width(format));

    CHECK(snd_pcm_drain(pcm));
    snd_pcm_close(pcm);
    return 0;
}
CL.
  • 173,858
  • 17
  • 217
  • 259
  • Thanks CL. Any alternative recommendation for me to try out? – runningdog Nov 04 '20 at 00:02
  • Something like this. – CL. Nov 04 '20 at 08:45
  • Hi CL, thank you for your source codes. I quickly compile and test it out but I only hear it for about 1s and end: `./play 32000 1 < /opt/test1.wav`, no errors print out. This audio file got about 4.5s, and run `aplay /opt/test1.wav` with result `Playing WAVE '/opt/test1.wav' : Signed 16 bit Little Endian, Rate 32000 Hz, Mono`, which can hear all 4.5s. – runningdog Nov 04 '20 at 09:49
  • Hmm, I thought short writes would not happen. Try now. – CL. Nov 04 '20 at 09:55
  • Hi CL, with the new update with rest/data, got a compile warning, `play.cc:33:34: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith] '. However, the result is same as before, only hear about 1s – runningdog Nov 04 '20 at 10:13
  • Hi CL, may I know if you have the same problem that the audio playback quit in 1s? Just wondering if it is my machine issue. – runningdog Nov 05 '20 at 01:13