当我尝试使用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;
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试通过访问此功能
snd_mixer_t *handle = getHandle();
snd_mixer_selem_id_t *sid = getSid();
snd_mixer_elem_t *elem = snd_mixer_find_selem(handle,sid);
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
我认为这源于alloca()系统调用
alloca在堆栈框架中分配,所以当getSid()返回时,你的已分配变量被释放,你最终得到一个dandling指针...(当你把它放在main函数中时,它工作,因为alloca在主激活记录上分配空间)
这只是一个建议,但我认为你应该使用malloc(在堆上分配空间,所以动态内存被分配,直到你调用free()它)
尝试用snd_mixer_selem_id_malloc():)
| 归档时间: |
|
| 查看次数: |
2407 次 |
| 最近记录: |