问题描述
我正在通过libasound2-dev:armhf 1.1.8-1+rpt1
使用ALSA。我已经卸载了pulseAudio,因为这是针对RaspBerry Pi 4上的单设备,单应用程序的设备。
我以以下方式使用libasound
:
- 使用
SND_PCM_STREAM_CAPTURE
遍历所有卡和设备 - 找到第一个
snd_ctl_pcm_info
不会失败的第一个-ENOENT
呼叫时停止-这正是arecord
的工作方式 - 通过
hw:2,0
打开snd_pcm_open
上的USB麦克风(对我来说)总是 - 设置一些参数-单声道44.1 kHz
S16_LE
- 在同时具有
snd_ctl_elem_write
接口的Auto Gain Control
和Mic Capture Volume
元素上调用SND_CTL_ELEM_IFACE_mixer
–这些值似乎在以后的读取中仍然存在 - 基于ALSA test/pcm.c中的“直接写”访问模式来阻止mmap读取
捕获的数据看似理智,但非常安静(从未超过2000/65535)。增益似乎并未注意上述元素设置。这是因为这些元素在混合器界面上,并且hw:
绕过了混合器吗?
代码很长,但这是设置元素的部分:
static void describe_set_elems(const CaptureContext *restrict ctx)
{
snd_ctl_elem_list_t *elements;
snd_ctl_elem_list_alloca(&elements);
check_snd(snd_ctl_elem_list(ctx->ctl,elements));
int n_elements = snd_ctl_elem_list_get_count(elements);
check_snd(snd_ctl_elem_list_alloc_space(elements,n_elements));
// It's goofy that we have to call this a second time,but it's needed
check_snd(snd_ctl_elem_list(ctx->ctl,elements));
assert(n_elements == snd_ctl_elem_list_get_count(elements));
snd_ctl_elem_id_t *id;
snd_ctl_elem_id_alloca(&id);
assert(id);
snd_ctl_elem_info_t *elem;
snd_ctl_elem_info_alloca(&elem);
assert(elem);
snd_ctl_elem_value_t *value;
snd_ctl_elem_value_alloca(&value);
assert(value);
bool vol_set = false,agc_set = false;
puts(
"Control elements ---------------------------------------------------\n"
);
for (int e = 0; e < n_elements; e++)
{
snd_ctl_elem_list_get_id(elements,e,id);
snd_ctl_elem_info_set_id(elem,id);
check_snd(snd_ctl_elem_info(ctx->ctl,elem));
snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem);
const char *item_name;
unsigned items;
if (type == SND_CTL_ELEM_TYPE_ENUMERATED)
{
item_name = snd_ctl_elem_info_get_item_name(elem);
items = snd_ctl_elem_info_get_items(elem);
}
else
{
item_name = "<non-enumerated>";
items = 0;
}
char min[32],max[32],step[32];
long max_int;
switch (type)
{
case SND_CTL_ELEM_TYPE_INTEGER:
max_int = snd_ctl_elem_info_get_max(elem);
snprintf(min,32,"%ld",snd_ctl_elem_info_get_min(elem));
snprintf(max,max_int);
snprintf(step,snd_ctl_elem_info_get_step(elem));
break;
case SND_CTL_ELEM_TYPE_integer64:
snprintf(min,"%lld",snd_ctl_elem_info_get_min64(elem));
snprintf(max,snd_ctl_elem_info_get_max64(elem));
snprintf(step,snd_ctl_elem_info_get_step64(elem));
break;
default:
strncpy(min,"<non-integer>",32);
strncpy(max,32);
strncpy(step,32);
}
const char *name = snd_ctl_elem_info_get_name(elem);
bool readable = snd_ctl_elem_info_is_readable(elem),writable = snd_ctl_elem_info_is_writable(elem);
const int index = snd_ctl_elem_info_get_index(elem);
printf(
" name : %s\n"
" type : %s\n"
" numid : %u\n"
" count : %u\n"
" device : %u\n"
" subdevice : %u\n"
" dimension : %d\n"
" dimensions : %d\n"
" index : %u\n"
" interface : %s\n"
" item name : %s\n"
" items : %u\n"
" min : %s\n"
" max : %s\n"
" step : %s\n"
" owner : %d\n"
" inactive : %d\n"
" locked : %d\n"
" is owner : %d\n"
" is user : %d\n"
" is readable : %d\n"
" is writable : %d\n"
" is volatile : %d\n"
" tlv commandable : %d\n"
" tlv readable : %d\n"
" tlv writeable : %d\n",name,snd_ctl_elem_type_name(
snd_ctl_elem_info_get_type(elem)
),snd_ctl_elem_info_get_numid(elem),snd_ctl_elem_info_get_count(elem),snd_ctl_elem_info_get_device(elem),snd_ctl_elem_info_get_subdevice(elem),snd_ctl_elem_info_get_dimension(elem,e),snd_ctl_elem_info_get_dimensions(elem),index,snd_ctl_elem_iface_name(
snd_ctl_elem_info_get_interface(elem)
),item_name,items,min,max,step,snd_ctl_elem_info_get_owner(elem),snd_ctl_elem_info_is_inactive(elem),snd_ctl_elem_info_is_locked(elem),snd_ctl_elem_info_is_owner(elem),snd_ctl_elem_info_is_user(elem),readable,writable,snd_ctl_elem_info_is_volatile(elem),snd_ctl_elem_info_is_tlv_commandable(elem),snd_ctl_elem_info_is_tlv_readable(elem),snd_ctl_elem_info_is_tlv_writable(elem)
);
snd_ctl_elem_value_set_id(value,id);
bool is_agc = false,is_vol = false;
if (!strcmp(name,"Auto Gain Control"))
is_agc = true;
else if (!strcmp(name,"Mic Capture Volume"))
is_vol = true;
if (is_vol || is_agc)
{
assert(writable);
if (is_vol)
{
snd_ctl_elem_value_set_integer(
value,(long)(VOLUME * max_int)
);
vol_set = true;
}
else if (is_agc)
{
snd_ctl_elem_value_set_boolean(value,AGC);
agc_set = true;
}
check_snd(snd_ctl_elem_write(ctx->ctl,value));
}
if (readable)
{
check_snd(snd_ctl_elem_read(ctx->ctl,value));
char val_str[64];
switch (type)
{
case SND_CTL_ELEM_TYPE_INTEGER:
snprintf(
val_str,64,snd_ctl_elem_value_get_integer(value,index)
);
break;
case SND_CTL_ELEM_TYPE_integer64:
snprintf(
val_str,snd_ctl_elem_value_get_integer64(value,index)
);
break;
case SND_CTL_ELEM_TYPE_BOOLEAN:
strncpy(
val_str,snd_ctl_elem_value_get_boolean(value,index)
? "TRUE" : "FALSE",64
);
break;
default:
strncpy(val_str,"Unsupported type",64);
break;
}
printf(
" value : %s\n",val_str
);
}
putchar('\n');
}
assert(vol_set);
assert(agc_set);
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)