alsa read报错-5,uac播放无声问题

文章描述了电脑在持续播放音乐时,频繁插拔D40电源可能导致音频无声的问题。通过排查发现是由于uac_out数据发送过快导致的,代码中对AWI_AUDIO2_UAC_OUT_PROC进行了调整,确保在连接和断开时不会立即读取数据,从而解决了问题。
摘要由CSDN通过智能技术生成

问题:电脑一直播放音乐的情况下,反复插拔d40的电源,就会概率性出现放音乐无声的问题,切换成电脑的喇叭播放后切回d40后,又能恢复播放

定位问题:

1.首先怀疑是不是AWI_UEVENT_EVENT_UAC_PLAY_START没有发出或者收到,加打印发现是有AWI_UEVENT_EVENT_UAC_PLAY_START的,进一步打开打印,发现问题如下

定位问题在uac_out读数据的时候出了问题

查看报错-5的错误类型

可以看出是uac_out数据送太快,awi_alsa_record2_read来不及读引起的,在看代码在awi_audio2_uac_out_proc中AWI_AUDIO2_UAC_OUT_MSG_EVENT_CONNECT和AWI_AUDIO2_UAC_OUT_MSG_EVENT_DISCONNECT导致了一开始没有直接read

所以修改代码如下,一开始就读

static void* awi_audio2_uac_out_proc(void *arg)
{
	awi_audio2_uac_out_t *uo;
	awi_alsa_record2_t *ar = NULL;
	awi_alsa_record2_params_t *ar_params;
	snd_pcm_uframes_t frames;
	awi_audio2_uac_out_msg_t *energy_msg;
	uint8_t buffer[AWI_AUDIO2_UAC_OUT_RECORD_BUFFER_SIZE];

	uo = (awi_audio2_uac_out_t*)arg;

	ar_params = &uac_out_params;
	ar = awi_alsa_record2_new(ar_params);
	if(NULL == ar) {
		aw_print("failed to new alsa record");
		goto fail;
	}
	awi_alsa_record2_set_tag(ar, "uac out");
	frames = uac_out_params.period_time * uac_out_params.sample_rate / (1000 * 1000);	

	while(uo->runing) {
		int readed = awi_alsa_record2_read(ar, buffer, frames);
		energy_msg = awi_audio2_uac_out_pop_msg(uo);
		if(NULL != energy_msg) {
			memcpy(energy_msg->buffer, buffer, AWI_AUDIO2_UAC_OUT_RECORD_BUFFER_SIZE);
			awi_blockqueue_push(&uo->msg_energy_q, &energy_msg->q_n);
		}
		if(readed == frames) {
			uo->is_play = true;
			if(uo->recording == true && uo->data_func != NULL) {
				uo->data_func(uo->data_ths, buffer, AWI_AUDIO2_UAC_OUT_RECORD_BUFFER_SIZE);
			}
		} else {
			uo->is_play = false;
#ifdef AUDIO2_DEBUG
			aw_print("unexpect readed %d/%ld", readed, frames);
#endif
			if(NULL != ar) {
				awi_alsa_record2_del(ar);
			}
			ar = awi_alsa_record2_new(ar_params);
			if(NULL == ar) {
				aw_print("failed to new alsa record");
			}
			awi_alsa_record2_set_tag(ar, "uac out");
		}
	}

fail:
	if(NULL != ar) {
		awi_alsa_record2_del(ar);
	}
	return NULL;
}

原来的错误代码如下

static void* awi_audio2_uac_out_proc(void *arg)
{
	awi_queue_node_t *qn;
	awi_audio2_uac_out_t *uo;
	awi_alsa_record2_t *ar = NULL;
	awi_alsa_record2_params_t *ar_params;
	snd_pcm_uframes_t frames;
	awi_audio2_uac_out_msg_t *energy_msg;
	uint8_t buffer[AWI_AUDIO2_UAC_OUT_RECORD_BUFFER_SIZE];


	uo = (awi_audio2_uac_out_t*)arg;
	frames = uac_out_params.period_time * uac_out_params.sample_rate / (1000 * 1000);
	while(uo->runing) {
		if(uo->is_connect == true) {
			qn = awi_blockqueue_pop(&uo->msg_q, 0);
		} else {
			qn = awi_blockqueue_pop(&uo->msg_q, -1);
			if(NULL == qn) {
				continue;
			}
		}
		if(NULL != qn) {
			awi_audio2_uac_out_msg_t *msg;

			msg = awi_offset(qn, awi_audio2_uac_out_msg_t, q_n);
			aw_print("msg event = %d", msg->event);
			if(msg->event == AWI_AUDIO2_UAC_OUT_MSG_EVENT_CONNECT) {
				uo->is_connect = true;
				if(ar == NULL) {
					aw_print("uac out connect");
					ar_params = &uac_out_params;
					ar = awi_alsa_record2_new(ar_params);
					if(NULL == ar) {
						aw_print("failed to new alsa record");
						goto fail;
					}
					awi_alsa_record2_set_tag(ar, "uac out");
				}
			} else if(msg->event == AWI_AUDIO2_UAC_OUT_MSG_EVENT_DISCONNECT) {
				uo->is_connect = false;
				if(ar != NULL) {
					aw_print("uac out disconnect");
					awi_alsa_record2_del(ar);
					ar = NULL;
				}
			}
			if (msg != NULL){
				awi_free(msg);
			}
			continue;
		}
		if(uo->is_connect == true && ar != NULL) {
			int readed = awi_alsa_record2_read(ar, buffer, frames);
			energy_msg = awi_audio2_uac_out_pop_msg(uo);
			if(NULL != energy_msg) {
				memcpy(energy_msg->buffer, buffer, AWI_AUDIO2_UAC_OUT_RECORD_BUFFER_SIZE);
				awi_blockqueue_push(&uo->msg_energy_q, &energy_msg->q_n);
			}
			if(readed == frames) {
				uo->is_play = true;
				if(uo->recording == true && uo->data_func != NULL) {
					uo->data_func(uo->data_ths, buffer, AWI_AUDIO2_UAC_OUT_RECORD_BUFFER_SIZE);
				}
			} else {
				uo->is_play = false;
#ifdef AUDIO2_DEBUG
				aw_print("unexpect readed %d/%ld", readed, frames);
#endif
				if(NULL != ar) {
					awi_alsa_record2_del(ar);
				}
				ar = awi_alsa_record2_new(ar_params);
				if(NULL == ar) {
					aw_print("failed to new alsa record");
				}
				awi_alsa_record2_set_tag(ar, "uac out");
			}
		}
	}

fail:
	if(NULL != ar) {
		awi_alsa_record2_del(ar);
	}
	return NULL;
}

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文武先生hh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值