Поиск всех устройств, которые я могу использовать для воспроизведения PCM с ALSA

Я использую ALSA для воспроизведения сэмплов PCM. Я открываю поток PCM с помощью этой функции:

int snd_pcm_open(snd_pcm_t** pcmp,
        const char* name,
        snd_pcm_stream_t stream,
        int mode);

В настоящее время я использую «по умолчанию» в качестве параметра имени. Я хотел бы иметь возможность выбирать другие устройства. Чего я не могу понять, так это того, как я могу определить имена других доступных устройств.

Я подключил USB-микрофон к своей системе, и кажется, что aplay и amixer обнаруживают новое устройство. Как определить имя этого устройства? Есть ли функция ALSA для получения списка доступных устройств с соответствующими именами?


person Luca Carlon    schedule 28.07.2011    source источник


Ответы (3)


Я думаю, вы можете использовать snd_device_name_hint для перечисления устройств . Вот пример. Остерегайтесь, что я не скомпилировал его!

char **hints;
/* Enumerate sound devices */
int err = snd_device_name_hint(-1, "pcm", (void***)&hints);
if (err != 0)
   return;//Error! Just return

char** n = hints;
while (*n != NULL) {

    char *name = snd_device_name_get_hint(*n, "NAME");

    if (name != NULL && 0 != strcmp("null", name)) {
        //Copy name to another buffer and then free it
        free(name);
    }
    n++;
}//End of while

//Free hint buffer too
snd_device_name_free_hint((void**)hints);
person O.C.    schedule 29.07.2011
comment
name не освобождается во второй части оператора if 0 != strcmp("null", name), когда имя равно "null". Возможно, добавьте дополнительный if внутри if, чтобы сделать что-то полезное с именем, когда оно не равно "null", но всегда освобождайте его. - person hetepeperfan; 25.07.2018

Это были мои первые требования к проектам Linux/Unix, где мне нужно было знать обо всех доступных возможностях и именах аудиоустройств. Затем мне нужно использовать эти устройства для захвата и воспроизведения звука. То, что я сделал, довольно просто. Существует команда linux/unix, которая используется для поиска устройств с помощью утилиты alsa в Linux.

It is:

aplay -l

Теперь то, что я сделал, это просто сделал программу, чтобы alsa выдавала вот так.

Для всеобщей помощи я сделал библиотеку (.so) и образец приложения, демонстрирующий использование этой библиотеки в C++.

Вывод моей библиотеки выглядит так:

[root@~]# ./IdeaAudioEngineTest
HDA Intel plughw:0,0
HDA Intel plughw:0,2
USB Audio Device plughw:1,0

Эта библиотека также может захватывать и воспроизводить аудиоданные в реальном времени.

Он доступен с документацией в библиотеке IdeaAudio с Duplex Alsa Audio< /а>

person Robel Sharma    schedule 01.08.2013
comment
Привет :) библиотека выглядит красиво, но есть ли для нее Java-оболочка? - person user390525; 31.07.2015
comment
извините, в настоящее время у нас его нет. - person Robel Sharma; 03.08.2015
comment
Хорошо, тогда; Знаете ли вы, как получить динамики или наушники? Я пробовал много раз, но путь типа hw:0,0 или даже hw:0,1 всегда возвращает микрофон :( У меня есть дуплексный разъем, который поддерживает как наушники, так и микрофон... - person user390525; 05.08.2015
comment
спасибо, но я имел в виду, можно ли использовать утилиту aplay для получения путей к динамикам / наушникам? - person user390525; 06.08.2015
comment
Мы сделали это программно. Как мы это сделали, можно узнать здесь github.com/robelsharma/IdeaAudio/ blob/master/IdeaLib/ в функции AvailableAudioDevices(). - person Robel Sharma; 06.08.2015

Просто для ухмылки, ваша программа переформатирована:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>

#include <alsa/asoundlib.h>

void listdev(char *devname)

{

    char** hints;
    int    err;
    char** n;
    char*  name;
    char*  desc;
    char*  ioid;

    /* Enumerate sound devices */
    err = snd_device_name_hint(-1, devname, (void***)&hints);
    if (err != 0) {

        fprintf(stderr, "*** Cannot get device names\n");
        exit(1);

    }

    n = hints;
    while (*n != NULL) {

        name = snd_device_name_get_hint(*n, "NAME");
        desc = snd_device_name_get_hint(*n, "DESC");
        ioid = snd_device_name_get_hint(*n, "IOID");

        printf("Name of device: %s\n", name);
        printf("Description of device: %s\n", desc);
        printf("I/O type of device: %s\n", ioid);
        printf("\n");

        if (name && strcmp("null", name)) free(name);
        if (desc && strcmp("null", desc)) free(desc);
        if (ioid && strcmp("null", ioid)) free(ioid);
        n++;

    }

    //Free hint buffer too
    snd_device_name_free_hint((void**)hints);

}

int main(void)

{

    printf("PCM devices:\n");
    printf("\n");
    listdev("pcm");

    printf("MIDI devices:\n");
    printf("\n");
    listdev("rawmidi");

    return 0;

}
person Scott Franco    schedule 06.07.2019