Ошибка сегментации в примере захвата ALSA

Я учусь использовать ALSA для чтения данных с микрофона. Я нашел пример программы, чтобы сделать это, и у меня возникли проблемы с ее запуском. Программа компилируется правильно, но когда я хочу ее запустить, я получаю ошибку Segmentation fault. Вот мой код:

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

static char *urzadzenie = "default";

main (int argc, char *argv[])
{
    int i;
    int err;
    short buf[128];
    snd_pcm_t *capture_handle;
    snd_pcm_hw_params_t *hw_params;
    fprintf(stderr, "Poczatek programu\n");
    if ((err = snd_pcm_open (&capture_handle, urzadzenie, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
        fprintf (stderr, "cannot open audio device %s (%s)\n", 
             urzadzenie,
             snd_strerror (err));
        exit (1);
    }
       fprintf(stderr, "Otwarto");
    if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
        fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
             snd_strerror (err));
        exit (1);
    }
    fprintf(stderr, "Zrobiono jakis malloc\n");
    if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) {
        fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
             snd_strerror (err));
        exit (1);
    }
        fprintf(stderr, "Inicjalizowano parametry\n");
    if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf (stderr, "cannot set access type (%s)\n",
             snd_strerror (err));
        exit (1);
    }
    fprintf(stderr, "Ustalono typ\n");
    if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
        fprintf (stderr, "cannot set sample format (%s)\n",
             snd_strerror (err));
        exit (1);
    }
    fprintf(stderr, "Ustalono probkowanie - format\n");
    if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, 44100, 0)) < 0) {
        fprintf (stderr, "cannot set sample rate (%s)\n",
             snd_strerror (err));
        exit (1);
    }
    fprintf(stderr, "Ustalono probkowanie - czas\n");
    if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, 2)) < 0) {
        fprintf (stderr, "cannot set channel count (%s)\n",
             snd_strerror (err));
        exit (1);
    }
    fprintf(stderr, "Ustalono liczbe kanalow\n");
    if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) {
        fprintf (stderr, "cannot set parameters (%s)\n",
             snd_strerror (err));
        exit (1);
    }
    fprintf(stderr, "Ustalono parametry\n");
    snd_pcm_hw_params_free (hw_params);

    if ((err = snd_pcm_prepare (capture_handle)) < 0) {
        fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
             snd_strerror (err));
        exit (1);
    }
    fprintf(stderr, "Przygotowano interfejs audio\n");
    for (i = 0; i < 10; ++i) {
        if ((err = snd_pcm_readi (capture_handle, buf, 128)) != 128) {
            fprintf (stderr, "read from audio interface failed (%s)\n",
                 snd_strerror (err));
            exit (1);
        }
    fprintf(stderr, buf);
    }

    snd_pcm_close (capture_handle);
    exit (0);
}

И вот результат:

osboxes@osboxes:~/z$ ./wynik
Poczatek programu
OtwartoZrobiono jakis malloc
Inicjalizowano parametry
Ustalono typ
Ustalono probkowanie - format
Segmentation fault (core dumped)

Похоже, что следующая строка является проблемой:

if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, 44100, 0)) < 0)

Может ли кто-нибудь помочь мне с этой проблемой? Я новичок, и у меня никогда не было таких ошибок при кодировании.

РЕДАКТИРОВАТЬ: Следуя совету, я включил предупреждения во время компиляции, и вот они:

main.c: В функции «main»:

main.c:48:3: предупреждение: передача аргумента 3 из ‘snd_pcm_hw_params_set_rate_near’

делает указатель из целого числа без приведения [включено по умолчанию]

если ((ошибка = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, >44100, 0)) ‹ 0) {

В файле, включенном из /usr/include/alsa/asoundlib.h:54:0, из main.c:3: /usr/include/alsa/pcm.h:747:5: примечание: ожидается 'unsigned int *', но аргумент > имеет тип 'int'

int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int без знака *val, int *dir);

Таким образом, похоже, что третий аргумент snd_pcm_hw_params_set_rate_near должен быть указателем, и компилятор преобразует целое число в указатель. Но я все еще не знаю, что делать.


person kkalwa    schedule 02.02.2018    source источник
comment
Всегда лучше иметь свой код на английском языке, чтобы другим было легче анализировать ваш код и отвечать.   -  person Marcin Zukowski    schedule 02.02.2018
comment
Включить предупреждения при компиляции.   -  person CL.    schedule 02.02.2018
comment
Я добавил в свой пост предупреждения, полученные во время компиляции.   -  person kkalwa    schedule 02.02.2018


Ответы (1)


Третий параметр snd_pcm_hw_params_set_rate_nearin-out. Вы устанавливаете его с желаемым значением, и по возвращении оно имеет фактически установленное значение. Так,

    unsigned int rate = 41000;
    if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &rate, 0)) < 0) {
        handle_error;
    } else {
        printf("The rate set is %u\n", rate);
    }
person user58697    schedule 02.02.2018
comment
Это помогло. Спасибо. - person kkalwa; 03.02.2018