使用alsalib时的奇怪C行为

问题描述 投票:3回答:2

在尝试使用ALSA库时,我的C代码出现了奇怪的行为。我使用此代码生成设备的sid

snd_mixer_selem_id_t*
getSid(){
  snd_mixer_selem_id_t *sid;
  snd_mixer_selem_id_alloca(&sid);
  snd_mixer_selem_id_set_index(sid,0);
  snd_mixer_selem_id_set_name(sid, selem_name);

  return sid;
}

然后我尝试通过以下方式访问此功能:>

snd_mixer_t *handle = getHandle();
snd_mixer_selem_id_t *sid = getSid();

snd_mixer_elem_t *elem = snd_mixer_find_selem(handle,sid);

getHandle()是获取卡处理程序的等效功能,但此功能正在起作用。奇怪的是,如果我在使用snd_mixer_find_selem函数之前直接使用该函数的代码,则它可以正常工作。我不得不说我是C语言的新手,这是我的第一个项目,因此这可能是指针的初学者错误。

错误消息是simple.c:282: snd_mixer_selem_get_playback_volume_range: Assertion 'elem' failed.

所以有人知道这是什么问题吗?

这是我使用的代码的最小示例:

#include <alsa/asoundlib.h>

static const char *selem_name = "Master";
static const char *card = "default";

snd_mixer_t*
getHandle(){
  snd_mixer_t *handle;

  snd_mixer_open(&handle, 0);
  snd_mixer_attach(handle, card);
  snd_mixer_selem_register(handle, NULL, NULL);
  snd_mixer_load(handle);

  return handle;
}

snd_mixer_selem_id_t*
getSid(){
  snd_mixer_selem_id_t *sid;
  snd_mixer_selem_id_alloca(&sid);
  snd_mixer_selem_id_set_index(sid,0);
  snd_mixer_selem_id_set_name(sid, selem_name);

  return sid;
}

void
incMasterVol(long step){ // Step is a value in [-100,100]
  long min,max,curr;

  snd_mixer_t *handle = getHandle();

/*snd_mixer_open(&handle, 0);
  snd_mixer_attach(handle, card);
  snd_mixer_selem_register(handle, NULL, NULL);
  snd_mixer_load(handle);*/

  snd_mixer_selem_id_t *sid;
  snd_mixer_selem_id_alloca(&sid);
  snd_mixer_selem_id_set_index(sid,0);
  snd_mixer_selem_id_set_name(sid, selem_name);

  snd_mixer_elem_t *elem = snd_mixer_find_selem(handle,sid);

  snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
  snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_SIDE_LEFT, &curr);
  curr = curr * 100/max;
  if(curr + step > 100)
    curr = 100;
  else if(curr + step < 0)
    curr = 0;
  else
    curr += step;
  snd_mixer_selem_set_playback_volume_all(elem, curr * max / 100);

  snd_mixer_close(handle);
}

void
toggleMasterVol(){
 int swiVal;
 snd_mixer_t *handle = getHandle();
 snd_mixer_elem_t *elem = snd_mixer_find_selem(handle,getSid());

 snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_SIDE_LEFT, &swiVal);
 snd_mixer_selem_set_playback_switch_all(elem, !swiVal);

 snd_mixer_close(handle);
}

int
main(int argc, char *argv[]){
  incMasterVol(5);
}

在尝试使用ALSA库时,我的C代码出现了奇怪的行为。我使用此代码生成设备的sid snd_mixer_selem_id_t * getSid(){snd_mixer_selem_id_t * sid; ...

c alsa
2个回答
6
投票

我认为是从alloca() syscall派生的>

alloca在堆栈帧中分配,因此,当getSid()返回时,分配的变量将被释放,并且最终会得到一个悬空指针...(并且当将其放在主函数中时,它会起作用,因为alloca分配主激活记录上的空间)


0
投票

在遇到相同问题并进行了一些搜索之后,我为您提供了一个提示:更改selem_name的值,并在必要时更改card的值!通过发出以下系统命令找出正确的卡名称:

© www.soinside.com 2019 - 2024. All rights reserved.