You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为snd_rawmidi_open()获取正确的设备编号?

获取ALSA无线MIDI设备的hw编号用于snd_rawmidi_open

要拿到目标设备的hw:X,Y,Z格式编号,你需要在遍历声卡的基础上,进一步遍历每个声卡下的RawMidi子设备,结合声卡编号、子设备编号和子设备序号生成目标字符串,具体步骤和代码示例如下:

核心思路

  1. 用snd_card_next()遍历所有声卡,记录每个声卡的card编号(即hw:后的第一个数字,比如示例中的5)。
  2. 对每个声卡,打开并遍历其下的所有RawMidi子设备,获取子设备的device编号(第二个数字)和subdevice编号(第三个数字)。
  3. 对比RawMidi设备的名称,找到目标无线收发器后,拼接出hw:%d,%d,%d格式的设备标识。

代码示例

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

int main() {
    int card = -1;
    snd_card_t *card_handle;
    snd_rawmidi_info_t *rmidi_info;
    int err;

    // 初始化RawMidi信息结构体
    snd_rawmidi_info_alloca(&rmidi_info);

    // 遍历所有声卡
    while (snd_card_next(&card) >= 0 && card >= 0) {
        // 打开声卡
        if ((err = snd_card_open(&card_handle, card)) < 0) {
            fprintf(stderr, "无法打开声卡 %d: %s\n", card, snd_strerror(err));
            continue;
        }

        // 获取声卡长名称(可选,用于辅助验证)
        const char *card_name = snd_card_get_longname(card_handle);
        printf("当前声卡 %d: %s\n", card, card_name);

        // 遍历该声卡下的所有RawMidi设备
        int device = -1;
        while (snd_rawmidi_next_device(&device) >= 0 && device >= 0) {
            // 设置要查询的设备信息
            snd_rawmidi_info_set_card(rmidi_info, card);
            snd_rawmidi_info_set_device(rmidi_info, device);
            snd_rawmidi_info_set_subdevice(rmidi_info, 0); // 先查第一个子设备

            // 获取RawMidi设备信息
            if ((err = snd_rawmidi_info(rmidi_info)) < 0) {
                fprintf(stderr, "无法获取RawMidi设备信息 %d:%d: %s\n", card, device, snd_strerror(err));
                continue;
            }

            // 获取设备名称和子设备序号
            const char *rmidi_name = snd_rawmidi_info_get_name(rmidi_info);
            int subdevice = snd_rawmidi_info_get_subdevice(rmidi_info);

            // 匹配目标设备名称(根据实际名称调整匹配逻辑)
            if (strstr(rmidi_name, "Wireless USB Midi Tranceiver") != NULL) {
                char device_id[32];
                snprintf(device_id, sizeof(device_id), "hw:%d,%d,%d", card, device, subdevice);
                printf("找到目标设备: %s\n", device_id);
                // 此处可保存device_id,后续用于snd_rawmidi_open
            }
        }

        // 关闭声卡句柄
        snd_card_close(card_handle);
    }

    return 0;
}

关键说明

  • snd_card_next(&card):每次调用更新card为下一个声卡编号,返回非0时表示遍历结束。
  • snd_rawmidi_next_device(&device):遍历当前声卡下的所有RawMidi设备,更新device为子设备编号。
  • snd_rawmidi_info_get_subdevice():获取子设备序号(通常为0,对应示例中的第三个数字)。
  • 匹配设备名称时推荐用strstr模糊匹配,避免因名称截断(如示例中显示的Wireless USB Midi Tranceiver MI)导致匹配失败。

编译时需链接ALSA库:gcc your_code.c -o find_midi -lasound

内容的提问来源于stack exchange,提问作者Cheetaiean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:10:14