【问题标题】:Finding all the devices I can use to play PCM with ALSA找到我可以用来和 ALSA 一起玩 PCM 的所有设备
【发布时间】:2011-10-15 12:25:33
【问题描述】:

我使用 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 功能来获取可用设备及其各自名称的列表?

【问题讨论】:

    标签: linux audio alsa


    【解决方案1】:

    只是为了笑,您的程序已重新格式化:

    #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;
    
    }
    

    【讨论】:

      【解决方案2】:

      这是我对 linux/unix 项目的第一个要求,我需要了解所有可用的音频设备功能和名称。然后我需要使用这些设备来捕捉和回放音频。我所做的很简单。有一个 linux/unix 命令用于通过 linux 中的 alsa 实用程序查找设备。

      它是:

      aplay -l
      

      现在我所做的只是制作一个程序,让 alsa 像这样输出。

      为了大家的帮助,我制作了一个 (.so) 库和一个示例应用程序,演示了该库在 c++ 中的使用。

      我的库的输出是这样的-

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

      这个库还可以捕捉和播放实时音频数据。

      它与IdeaAudio library with Duplex Alsa Audio 中的文档一起提供

      【讨论】:

      • 嗨 :) 这个库看起来不错,但是有没有 Java 包装器呢?
      • 抱歉,目前我们没有。
      • 好吧;你知道如何获得扬声器或耳机路径吗?我尝试了很多次,但是像 hw:0,0 甚至 hw:0,1 这样的路径总是返回麦克风 :( 我有双工插孔,它支持耳机或麦克风 ...
      • IdeaAudioEngineTest 的执行将返回所有插入的捕获和播放设备名称。然后你只需要在库捕获和回放 API 上使用它们作为输入。该项目的完整源代码可在 [这里|github.com/robelsharma/IdeaAudio/].
      • 谢谢,但我的意思是可以使用 aplay util 来获取扬声器/耳机设备路径吗?
      【解决方案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);
      

      【讨论】:

      • name 在 if 语句的第二部分 0 != strcmp("null", name) 不被释放,而名称确实等于 "null"。如果在 if 中添加一个额外的 if 以在 name 不等于 "null" 时对 name 做一些有用的事情,但始终释放它。
      猜你喜欢
      • 2011-12-31
      • 2016-05-09
      • 2016-06-13
      • 2019-03-20
      • 2012-12-20
      • 2013-11-17
      • 2016-08-28
      • 2020-11-19
      • 1970-01-01
      相关资源
      最近更新 更多