c++ ALSA从控制事件(snd_ctl_event_t)获取简单混合器元素(snd_mixer_elem_t使用)

eh57zj3b  于 2023-01-10  发布在  其他
关注(0)|答案(1)|浏览(201)

我打开了一个声卡控件,正在轮询ALSA控件事件。使用gtkIOStream ALSA::Control类从事件流中提取事件,如下所示:

snd_ctl_event_t *event;
snd_ctl_event_alloca(&event);
int err = snd_ctl_read(ctl, event);
if (err < 0)
  return ALSADebug().evaluateError(err, "snd_ctl_read error when handling poll events\n");

我现在尝试从事件中获取匹配的简单混音器元素,但在某些情况下,一些ALSA简单混音器有重复的元素。例如,回放混音器中的一个元素与捕获混音器部分中的一个元素同名。如果名称是从控制事件中提取的,如下所示:
第一个月
不可能分辨出是哪个混合器元件(snd_mixer_elem_t),因为存在具有相同名称的两个混合器元素。当迭代通过简单混合器元素的已知集合时,我们将在找到第一个后返回-当我们基于mixer元素名称中的键搜索mixer元素时,存在另一个简单问题。使用snd_mixer_在每个简单mixer元素上进行搜索selem获取名称ALSA函数。
有没有办法不使用mixer元素名称就找到触发ASLA Control事件的确切mixer简单mixer元素?例如,有没有办法使用ALSA控制元素的numid(snd_ctl_event_elem_get_numid)以某种方式将Control numidMap回确切的简单mixer元素?

unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj)

是否有其他方法可以使用?

nkhmeac6

nkhmeac61#

ALSA控制接口不能用于管理状态改变的alsa混合器元素。要捕捉元素的alsa混合器事件,最好使用ALSA混合器元素回调方法。
处理混合器元素更改的完整实现是implemented here
它可以归结为以下C++代码,从打开ALSA卡开始:

int openCard(std::string card){
  int err=0;
  if (handle)
    if ((err=close())<0)
      return err;
  if ((err=open())<0)
    return err;
  if ((err=attach(card))<0)
    return err;
  if ((err=registerMixer())<0)
    return err;
  if ((err=load())<0)
    return err;
  return err;
}

加载后,在每个混音器元素上启用回调:

Mixer::addElem(elem);
  snd_mixer_elem_set_callback_private(elem, this);
  snd_mixer_elem_set_callback(elem, handleValueEventsStatic);

回调允许您获取C++ ALSA::MixerEvents类示例,以使用以下内容处理事件:

static int handleValueEventsStatic(snd_mixer_elem_t *elem, unsigned int mask) {
    if (mask & SND_CTL_EVENT_MASK_VALUE){
    MixerElement me(elem);
    return static_cast<MixerEvents *>(snd_mixer_elem_get_callback_private(elem))->handleValueEvents(me);
  }
    return 0;
}

MixerEvents类的一个可用应用程序是given here

相关问题