信号量同步数据,实现d40的speark提示音和播放数据流同步;不阻塞的进程需要注意了

其他:线程严禁不加阻塞

线程严禁空转

线程严禁在做一些简单的判断标志位的操作同时,去在其他的线程改变标志位

信号量同步数据,实现d40的speark提示音和播放数据流同步

注意信号量初始化应该为0,这样子在awi_audio2_speaker_proc准备好可以开始awi_alsa_play2_write的时候,在给出满信号量,实现数据的开始同步    

#include "awi_audio2_speaker.h"
#include "awi_audio2_tips.h"
#include "awi_audio2_module.h"

typedef enum {
	/*1*/AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_START,
	/*2*/AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_DATA,
	/*3*/AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_STOP,
}awi_audio2_speaker_msg_event_t;

typedef void(*_msg_callback_func)(void *ths);

typedef struct {
	awi_queue_node_t hoard_n;
	awi_queue_node_t q_n;
	uint8_t buffer[AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE];
	void *cb_ths;
	_msg_callback_func cb_func;
	awi_audio2_speaker_msg_event_t event;		
}awi_audio2_speaker_msg_t;

static awi_alsa_play2_params_t speaker_params = {
		.sample_rate = AWI_AUDIO2_SPEAKER_PLAY_SAMPLE_RATE,
		.channel = AWI_AUDIO2_SPEAKER_PLAY_CHANNEL,
		.format = SND_PCM_FORMAT_S16_LE,
		.period_time = AWI_AUDIO2_SPEAKER_PLAY_STEP_MS * 1000,
		.buffer_time = AWI_AUDIO2_SPEAKER_PLAY_STEP_MS * 4 * 1000,
		.dev_name = AWI_AUDIO2_SPEAKER_PLAY_DEV_NAME,
};

static uint8_t algo_buffer[AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE];
static uint8_t date_buffer[AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE];	

static awi_audio2_module_t *audio2;

static awi_audio2_speaker_msg_t* awi_audio2_speaker_msg_new(awi_audio2_speaker_t *speaker)
{
	return (awi_audio2_speaker_msg_t*)awi_malloc(sizeof(awi_audio2_speaker_msg_t));
}

static void awi_audio2_speaker_msg_del(awi_audio2_speaker_msg_t *msg)
{
	if(NULL != msg) {
		awi_free(msg);
	}
}

static awi_audio2_speaker_msg_t* awi_audio2_speaker_pop_msg(awi_audio2_speaker_t *speaker)
{
	awi_audio2_speaker_msg_t *msg;

	msg = (awi_audio2_speaker_msg_t*)awi_lockhoard_pop(&speaker->msg_hoard);
	if(NULL != msg) {
		msg->cb_func = NULL;
		msg->cb_ths = NULL;
	}
	return msg;	
}

static void awi_audio2_speaker_push_msg(awi_audio2_speaker_t *speaker, awi_audio2_speaker_msg_t *msg)
{
	awi_lockhoard_push(&speaker->msg_hoard, msg);
}

static void awi_to_tip(const short* pv_src, short *pv_dst, int frames)
{
	float ratio = AWI_AUDIO2_MODULE_AUDIO_IN_TIPS_GAIN * audio2->tips_volume / AWI_AUDIO2_MODULE_PLAY_VOLUME_MAX;
	for(int i = 0; i < frames; ++i) {
		pv_dst[i] = ratio * pv_src[i];
	}
}

static void awi_to_mix(const short* pv_src, const short* pv_tip_src, short *pv_dst, int frames)
{
	float ratio = AWI_AUDIO2_MODULE_AUDIO_IN_TIPS_GAIN * audio2->tips_volume / AWI_AUDIO2_MODULE_PLAY_VOLUME_MAX;	
	for(int i = 0; i < frames; ++i) {
		pv_dst[i] = pv_src[i] + ratio * pv_tip_src[i];
	}
}

static void d40_awi_arrange_speaker_data_to_one(const short *src_buff, short *dst_buff, int len)
{
	for(int i = 0, j = 0; i < len; i += 1, j +=2)
	{
		dst_buff[i] = src_buff[j];
	}
}

static void d40_awi_arrange_speaker_data_to_two(const short *src_buff, short *dst_buff, int len)
{
	for(int i = 0, j = 0; i < len; i += 2, j +=1)
	{
		dst_buff[i] = src_buff[j];
		dst_buff[i+1] = src_buff[j];
	}
}

static void awi_audio2_speaker_clean_cache_q(awi_audio2_speaker_t *speaker, awi_lockqueue_t *q)
{
	while(1) {
		awi_queue_node_t *qn = awi_lockqueue_pop(q);
		if(NULL == qn) {
			break;
		}
		awi_audio2_speaker_msg_t *msg = awi_offset(qn, awi_audio2_speaker_msg_t, q_n);
		if(NULL != msg->cb_func) {
			msg->cb_func(msg->cb_ths);
		}
		awi_audio2_speaker_push_msg(speaker, msg);
	}
}

static void awi_audio2_speaker_on_tips(awi_audio2_speaker_t *speaker, awi_audio2_tips_event_t event, const uint8_t *buffer, int bytes,
			void *cb_ths, awi_audio2_tips_cb_func cb_func)
{
	awi_audio2_speaker_msg_t *msg;

	switch(event) {
	case AWI_AUDIO2_TIPS_EVENT_START:
		msg = awi_audio2_speaker_pop_msg(speaker);
		if(NULL != msg) {
			msg->event = AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_START;
			msg->cb_func = cb_func;
			msg->cb_ths = cb_ths;
			awi_blockqueue_push(&speaker->msg_tip_bq, &msg->q_n);
		} else if(cb_func != NULL) {
			cb_func(cb_ths);
		}
		break;
	case AWI_AUDIO2_TIPS_EVENT_DATA:
		msg = awi_audio2_speaker_pop_msg(speaker);
		if(NULL != msg) {
			msg->event = AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_DATA;
			memcpy(msg->buffer, buffer, bytes);
			msg->cb_func = cb_func;
			msg->cb_ths = cb_ths;
			awi_blockqueue_push(&speaker->msg_tip_bq, &msg->q_n);
		} else if(cb_func != NULL) {
			cb_func(cb_ths);
		}
		break;
	case AWI_AUDIO2_TIPS_EVENT_STOP:
		msg = awi_audio2_speaker_pop_msg(speaker);
		if(NULL != msg) {
			msg->event = AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_STOP;
			msg->cb_func = cb_func;
			msg->cb_ths = cb_ths;
			awi_blockqueue_push(&speaker->msg_tip_bq, &msg->q_n);
		} else if(cb_func != NULL) {
			cb_func(cb_ths);
		}
		break;
	}
}

static void* awi_audio2_speaker_for_tip_proc(void *arg)
{
	awi_audio2_speaker_t *speaker;
	awi_queue_node_t *qn;
	awi_audio2_speaker_msg_t *msg;

	speaker = (awi_audio2_speaker_t*)arg;

	while(speaker->runing) {
		qn = awi_blockqueue_pop(&speaker->msg_tip_bq, -1);
		if(NULL == qn) {
			continue;
		}
		msg = awi_offset(qn, awi_audio2_speaker_msg_t, q_n);
		switch(msg->event) {
		case AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_START:
			// aw_print("AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_START");
			awi_audio2_speaker_start(speaker);
			if(audio2->is_tipsing == false) {
				audio2->is_tipsing = true;
			}
			break;
		case AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_STOP:
			// aw_print("AWI_speaker_MODULE_MSG_EVENT_TIPS_STOP");
			if(audio2->is_tipsing == true) {
				audio2->is_tipsing = false;
				awi_audio2_speaker_clean_cache_q(speaker, &speaker->msg_tip_q);
			}
			if(audio2->bt_ining == false && audio2->uac_outing == false && 
				audio2->is_tipsing == false) {
				awi_audio2_speaker_stop(speaker);
			}
			break;
		case AWI_AUDIO2_SPEAKER_MSG_EVENT_TIPS_DATA:
			if(audio2->is_tipsing == true) {
				awi_lockqueue_push(&speaker->msg_tip_q, &msg->q_n);
				msg = NULL;			
			}
		default:
			break;
		}

		if(NULL != msg) {
			if(NULL != msg->cb_func) {
				msg->cb_func(msg->cb_ths);
			}
			awi_audio2_speaker_push_msg(speaker, msg);
		}			
	}
	awi_audio2_speaker_clean_cache_q(speaker, &speaker->msg_tip_q);
	return NULL;
}


static void* awi_audio2_speaker_date_proc(void *arg)
{
	awi_audio2_speaker_t *speaker;
	// uint8_t buffer[AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE];	
	awi_audio2_speaker_msg_t *msg = NULL;
	awi_audio2_speaker_msg_t *tip_msg = NULL;
	speaker = (awi_audio2_speaker_t*)arg;

	while(speaker->runing == true) {
		// if(speaker->playing == true) {
			awi_queue_node_t *qn;
			awi_queue_node_t *qn_tip;
			qn = awi_lockqueue_pop(&speaker->msg_q);
			qn_tip = awi_lockqueue_pop(&speaker->msg_tip_q);
			if(NULL == qn && NULL == qn_tip) {
				memset(date_buffer, 0x00, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
				//aw_print("-20");//debug
			} else if(NULL != qn && NULL == qn_tip){
				msg = awi_offset(qn, awi_audio2_speaker_msg_t, q_n);
				memcpy(date_buffer, msg->buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
				//aw_print("-21");//debug
			}else if(NULL == qn && NULL != qn_tip){
				tip_msg = awi_offset(qn_tip, awi_audio2_speaker_msg_t, q_n);
				awi_to_tip((const short*)tip_msg->buffer, (short*)date_buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE/2);
				//aw_print("-22");//debug
			}else if(NULL != qn && NULL != qn_tip){
				msg = awi_offset(qn, awi_audio2_speaker_msg_t, q_n);
				tip_msg = awi_offset(qn_tip, awi_audio2_speaker_msg_t, q_n);
				awi_to_mix((const short*)msg->buffer, (const short*)tip_msg->buffer, (short*)date_buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE/2);
				//aw_print("-23");//debug
			}
		// } else {
		// 	memset(date_buffer, 0x00, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
		// 	//aw_print("-24");//debug
		// }
		if(NULL != tip_msg){
			if(NULL != tip_msg->cb_func) {
				tip_msg->cb_func(tip_msg->cb_ths);
			}			
			awi_audio2_speaker_push_msg(speaker, tip_msg);
			tip_msg = NULL;
		}	
		if(NULL != msg){
			awi_audio2_speaker_push_msg(speaker, msg);
			msg = NULL;
		}			
		if (speaker->is_record){
			d40_awi_arrange_speaker_data_to_one((const short*)date_buffer, (short*)algo_buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE / 2);
			audioAlg_playDataPreProcess(speaker->algo, (short *)algo_buffer);
			d40_awi_arrange_speaker_data_to_two((const short*)algo_buffer, (short*)date_buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE / 2);
			//aw_print("-25");//debug
		}
		// if(speaker->init_ok){
			awi_sem_require(&speaker->cache_sem, AWI_TIME_INFINITE);
			awi_audio2_speaker_msg_t *date_msg;
			date_msg = awi_audio2_speaker_pop_msg(speaker);
			if(NULL == date_msg) {
				aw_print("failed to pop msg");
				return NULL;
			}
			memcpy(date_msg->buffer, date_buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
			awi_lockqueue_push(&speaker->msg_date_q, &date_msg->q_n);
			//aw_print("-26");//debug
			while(true) {
				if(speaker->msg_date_q.length > AWI_AUDIO2_SPEAKER_MAX_QUEUE_LENGTH) {
					awi_queue_node_t *qn = awi_lockqueue_pop(&speaker->msg_date_q);
					//aw_print("-27");//debug
					if(NULL == qn) {
						break;
					}					
					date_msg = awi_offset(qn, awi_audio2_speaker_msg_t, hoard_n);
					if (date_msg != NULL){
						awi_audio2_speaker_push_msg(speaker, date_msg);
					}
				} else {
					break;
				}
			}					
		// }
	}
	return NULL;
}

static void* awi_audio2_speaker_proc(void *arg)
{
	int write; 
	int first_run_sem = 0;
	awi_audio2_speaker_t *speaker;
	awi_alsa_play2_t *ap = NULL;
	awi_alsa_play2_params_t *ap_params;
	snd_pcm_uframes_t frames;

	speaker = (awi_audio2_speaker_t*)arg;
	ap_params = &speaker_params;
	frames = ap_params->period_time * ap_params->sample_rate / (1000 * 1000);
	ap = awi_alsa_play2_new(ap_params);
	if(NULL == ap) {
		aw_print("failed to new alsa play");
		goto fail;
	}
	awi_alsa_play2_set_tag(ap, "speaker");

	while(speaker->runing == true) {
		if(speaker->playing == true) {
			awi_queue_node_t *qn;
			qn = awi_lockqueue_pop(&speaker->msg_date_q);
			//aw_print("-11");//debug
			if(NULL == qn) {
				memset(speaker->buffer, 0x00, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
				//aw_print("-12");//debug
			} else {
				awi_audio2_speaker_msg_t *date_msg = awi_offset(qn, awi_audio2_speaker_msg_t, q_n);
				if (date_msg != NULL){
					memcpy(speaker->buffer, date_msg->buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
					awi_audio2_speaker_push_msg(speaker, date_msg);
					awi_sem_release(&speaker->cache_sem, 1);
					//aw_print("-13");//debug
				}
			}
		} else {
			memset(speaker->buffer, 0x00, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
			// usleep(1000);
			//aw_print("-14");//debug
		}
		if(speaker->init_ok){
			//aw_print("-15");//debug
			if(first_run_sem == 0){
				awi_sem_release(&speaker->cache_sem, AWI_AUDIO2_SPEAKER_CACHE_NUM);//注意信号量初始化应该为0,这样子在awi_audio2_speaker_proc准备好可以开始awi_alsa_play2_write的时候,在给出满信号量,实现数据的开始同步	
				first_run_sem = 1;
				//aw_print("-30");//debug
			}
			write = awi_alsa_play2_write(ap, (uint8_t*)speaker->buffer, AWI_AUDIO2_SPEAKER_PLAY_FRAMES);
			//aw_print("-16");//debug
			if (write != frames){
				aw_print("unexpect writed %d/%ld", write, frames);
				if(NULL != ap) {
					awi_alsa_play2_del(ap);
				}
				ap = awi_alsa_play2_new(ap_params);
				if(NULL == ap) {
					aw_print("failed to new alsa write");
				}
				awi_alsa_play2_set_tag(ap, "speark");
			}			
		}
	}
	awi_alsa_play2_del(ap);
	return NULL;
fail:
	if(NULL != ap) {
		awi_alsa_play2_del(ap);
	}
	return NULL;
}

awi_audio2_speaker_t* awi_audio2_speaker_new(void *_audio2)
{
	awi_audio2_speaker_t *speaker;
	audio2 = _audio2;
	speaker = (awi_audio2_speaker_t*)awi_malloc(sizeof(awi_audio2_speaker_t));
	if(NULL == speaker) {
		aw_print("failed to malloc speaker");
		goto fail;
	}
	memset(speaker, 0, sizeof(awi_audio2_speaker_t));

	speaker->algo = audio2->algo;
	awi_lockqueue_init(&speaker->msg_q);
	awi_lockqueue_init(&speaker->msg_tip_q);
	awi_lockqueue_init(&speaker->msg_date_q);

	awi_blockqueue_init(&speaker->msg_tip_bq);		
	awi_lockhoard_init(&speaker->msg_hoard, offsetof(awi_audio2_speaker_msg_t, hoard_n), 15,
						(awi_hoard_new_handler)awi_audio2_speaker_msg_new,
						(awi_hoard_del_handler)awi_audio2_speaker_msg_del,
						speaker);
	awi_sem_init(&speaker->cache_sem, 0);//注意信号量初始化应该为0,这样子在awi_audio2_speaker_proc准备好可以开始awi_alsa_play2_write的时候,在给出满信号量,实现数据的开始同步					
	speaker->runing = true;
	speaker->init_ok = false;	

	audio2->tips = awi_audio2_tips_new(audio2->is_abroad);
	if(NULL == audio2->tips) {
		aw_print("failed to new tips"); 
		goto fail;
	}
	awi_audio2_tips_set_notify_func(audio2->tips, speaker, (awi_audio2_tips_notify_func)awi_audio2_speaker_on_tips);
	pthread_create(&speaker->proc_tid, NULL, awi_audio2_speaker_proc, speaker);
	pthread_create(&speaker->tip_tid, NULL, awi_audio2_speaker_for_tip_proc, speaker);
	pthread_create(&speaker->date_tid, NULL, awi_audio2_speaker_date_proc, speaker);	
	return speaker;
fail:
	if(NULL != speaker) {
		awi_free(speaker);
	}
	return NULL;
}




/***********************test**************************/
static void* awi_audio2_speaker_for_test_proc(void *arg)
{
	awi_audio2_speaker_t *speaker;
	awi_alsa_play2_t *ap = NULL;
	awi_alsa_play2_params_t *ap_params;
	// uint8_t buffer[AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE];	

	speaker = (awi_audio2_speaker_t*)arg;
	ap_params = &speaker_params;
	ap = awi_alsa_play2_new(ap_params);
	if(NULL == ap) {
		aw_print("failed to new alsa play");
		goto fail;
	}
	awi_alsa_play2_set_tag(ap, "speaker");

	while(speaker->runing == true) {
		if(speaker->playing == true) {
			awi_queue_node_t *qn;
			qn = awi_lockqueue_pop(&speaker->msg_q);
			if(NULL == qn) {
				memset(speaker->buffer, 0x00, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
			} else {
				awi_audio2_speaker_msg_t *msg = awi_offset(qn, awi_audio2_speaker_msg_t, q_n);
				memcpy(speaker->buffer, msg->buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
				awi_audio2_speaker_push_msg(speaker, msg);
			}
		} else {
			memset(speaker->buffer, 0x00, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE);
		}
		if (speaker->is_record){
			d40_awi_arrange_speaker_data_to_one((const short*)speaker->buffer, (short*)algo_buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE / 2);
			audioAlg_playDataPreProcess(speaker->algo, (short *)algo_buffer);
			d40_awi_arrange_speaker_data_to_two((const short*)algo_buffer, (short*)speaker->buffer, AWI_AUDIO2_SPEAKER_PLAY_BUFFER_SIZE / 2);
		}	
		if(speaker->init_ok){
			awi_alsa_play2_write(ap, (uint8_t*)speaker->buffer, AWI_AUDIO2_SPEAKER_PLAY_FRAMES);
		}
	}

	awi_alsa_play2_del(ap);
	return NULL;
fail:
	if(NULL != ap) {
		awi_alsa_play2_del(ap);
	}
	return NULL;
}


awi_audio2_speaker_t* awi_audio2_speaker_new_for_test(void *algo)
{
	awi_audio2_speaker_t *speaker;
	speaker = (awi_audio2_speaker_t*)awi_malloc(sizeof(awi_audio2_speaker_t));
	if(NULL == speaker) {
		aw_print("failed to malloc speaker");
		goto fail;
	}
	memset(speaker, 0, sizeof(awi_audio2_speaker_t));

	speaker->algo = algo;
	awi_lockqueue_init(&speaker->msg_q);
	awi_lockhoard_init(&speaker->msg_hoard, offsetof(awi_audio2_speaker_msg_t, hoard_n), 10,
						(awi_hoard_new_handler)awi_audio2_speaker_msg_new,
						(awi_hoard_del_handler)awi_audio2_speaker_msg_del,
						speaker);
	speaker->runing = true;
	
	pthread_create(&speaker->proc_tid, NULL, awi_audio2_speaker_for_test_proc, speaker);

	return speaker;
fail:
	if(NULL != speaker) {
		awi_free(speaker);
	}
	return NULL;
}
/***********************test**************************/




int awi_audio2_speaker_del(awi_audio2_speaker_t *speaker)
{
	if(NULL != speaker) {
		speaker->runing = false;
				awi_blockqueue_wake(&speaker->msg_tip_bq);	
		pthread_join(speaker->proc_tid, NULL);
		pthread_join(speaker->tip_tid, NULL);		
		awi_lockqueue_clean(&speaker->msg_q);
		awi_lockqueue_clean(&speaker->msg_tip_q);
		awi_blockqueue_clean(&speaker->msg_tip_bq);
		awi_lockhoard_clean(&speaker->msg_hoard);

		awi_free(speaker);
	}
	return 0;
}

int awi_audio2_speaker_start(awi_audio2_speaker_t *speaker)
{
	awi_queue_node_t *qn;
	awi_queue_node_t *qn_tip;	

	if(speaker->playing == false) {
		while(true) {
			qn = awi_lockqueue_pop(&speaker->msg_q);
			qn_tip = awi_lockqueue_pop(&speaker->msg_tip_q);
			if(NULL != qn) {
				awi_audio2_speaker_msg_t *msg = awi_offset(qn, awi_audio2_speaker_msg_t, q_n);
				awi_audio2_speaker_push_msg(speaker, msg);
			}
			if(NULL != qn_tip) {
				awi_audio2_speaker_msg_t *tip_msg = awi_offset(qn_tip, awi_audio2_speaker_msg_t, q_n);
				awi_audio2_speaker_push_msg(speaker, tip_msg);
			}			
			if(NULL == qn_tip && NULL == qn) {
				break;
			}			

		}
	}
	speaker->playing = true;
	return 0;
}

int awi_audio2_speaker_data(awi_audio2_speaker_t *speaker, const uint8_t *data, int bytes)
{	 
	if(speaker->playing == true) {
		awi_audio2_speaker_msg_t *msg;

		msg = awi_audio2_speaker_pop_msg(speaker);
		if(NULL == msg) {
			aw_print("failed to pop msg");
			return -1;
		}
		memcpy(msg->buffer, data, bytes);
		awi_lockqueue_push(&speaker->msg_q, &msg->q_n);
		while(true) {
			if(speaker->msg_q.length > AWI_AUDIO2_SPEAKER_MAX_QUEUE_LENGTH) {
				awi_queue_node_t *qn = awi_lockqueue_pop(&speaker->msg_q);
				if(NULL == qn) {
					break;
				}					
				msg = awi_offset(qn, awi_audio2_speaker_msg_t, hoard_n);
				awi_audio2_speaker_push_msg(speaker, msg);
			} else {
				break;
			}
		}
	}
	return 0;
}

int awi_audio2_speaker_stop(awi_audio2_speaker_t *speaker)
{
	speaker->playing = false;
	return 0;
}

int awi_audio2_speaker_record_start(awi_audio2_speaker_t *speaker)
{
	speaker->is_record = true;
	return 0;
}

int awi_audio2_speaker_record_stop(awi_audio2_speaker_t *speaker)
{
	speaker->is_record = false;
	return 0;
}
int awi_audio2_speaker_init_ok(awi_audio2_speaker_t *speaker)
{
	speaker->init_ok = true;
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

文武先生hh

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

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

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

打赏作者

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

抵扣说明:

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

余额充值