#include "sys_config.h" #include "typesdef.h" #include "list.h" #include "dev.h" #include "devid.h" #include "string.h" #include "osal/task.h" #include "osal/semaphore.h" #include "osal/msgqueue.h" #include "osal/string.h" #include "hal/audac.h" #include "stream_frame.h" #include "osal_file.h" #include "stream_frame.h" #include "dev/audio/components/fade/aufade.h" #include "sonic_process.h" #ifdef PSRAM_HEAP #define ADUIO_MALLOC os_malloc_psram #define ADUIO_FREE os_free_psram #define ADUIO_ZALLOC os_zalloc_psram #define AUDIONUM (16) #else #define ADUIO_MALLOC os_malloc #define ADUIO_FREE os_free #define ADUIO_ZALLOC os_zalloc #define AUDIONUM (8) #endif #define SONIC_PROCESS 0 #define FADE_PROCESS 1 #define AUDIOLEN 1024 #define CACHE_BUF_LEN 1024 static int prev_filter_type = 0; static stream *global_audio_dac_s = NULL; struct audio_da_config; typedef int32 (*audio_da_write)(struct audio_da_config *audio, void* buf, uint32 len); static uint32_t empty_buf[AUDIOLEN/4]; #if SONIC_PROCESS struct sonic_process_priv { sonicStream sonic_s; int samplingRate; int channel; float pitch; float speed; struct os_task task_hdl; struct os_semaphore sema; struct data_structure *r_current_data; struct data_structure *s_current_data; }; static struct sonic_process_priv *sonic_priv = NULL; #endif struct audio_dac_priv { struct os_semaphore cache_sema; struct os_task cache_task_hdl; uint32_t s_offset; uint32_t d_offset; uint32_t res_len; uint32_t buf_len; uint32_t buf_index; int8_t status; int16_t *buf[4]; struct data_structure *current_data; #if FADE_PROCESS struct os_msgqueue fade_msg; struct os_task fade_task_hdl; uint8_t fade_mode; #endif }; static struct audio_dac_priv *audac_priv = NULL; typedef struct audio_da_config { struct audac_device *dac; void *current_node; void *reg_node; audio_da_write irq_func; void *play_empty_buf; //作为喇叭的时候,需要配置,size与buf_size一致,可以是malloc也可以是固定,如果是malloc,需要自己去free int buf_size; uint8_t audio_hz; uint8_t is_empty; }audio_da_config; audio_da_config global_audio_da; int get_audio_dac_set_filter_type(void); void audio_dac_set_filter_type(int filter_type); int audio_dac_get_samplingrate(void); #ifndef PSRAM_HEAP static void *audio_dac_get_buf(void *priv_el,void *el_point,int *buf_size) { stream *dest = (stream *)priv_el; struct data_structure *data_s = recv_real_data(dest); void *buf = NULL; void **point = (void**)el_point; if(data_s) { buf = get_stream_real_data(data_s); *buf_size = get_stream_real_data_len(data_s); *point = (void*)data_s; } else { *point = NULL; return NULL; } return buf; } static void audio_dac_free_buf(void *el_point) { struct data_structure *data_s = (struct data_structure *)el_point; if(!data_s) { return; } free_data(data_s); data_s = NULL; } #endif void audio_dac_irq(uint32 irq, uint32 irq_data) { audio_da_config *audio_da_cfg = (audio_da_config *)irq_data; #ifndef PSRAM_HEAP void *buf = NULL; int32_t buf_size = 0; #endif //满 if (irq & AUDAC_IRQ_FLAG_FULL) { if(audio_da_cfg->current_node) { #ifdef PSRAM_HEAP os_sema_up(&audac_priv->cache_sema); #else audio_dac_free_buf(audio_da_cfg->current_node); #endif audio_da_cfg->current_node = NULL; } else { audio_da_cfg->is_empty = 1; } if(audio_da_cfg->reg_node) { #if FADE_PROCESS if(audac_priv->fade_mode == 1) { audac_priv->fade_mode = 0; if(os_msgq_put(&audac_priv->fade_msg, audac_priv->fade_mode, 0) < 0) { audac_priv->fade_mode = 1; } } #endif audio_da_cfg->current_node = audio_da_cfg->reg_node; audio_da_cfg->reg_node = NULL; } } //半 if (irq & AUDAC_IRQ_FLAG_HALF) { #ifdef PSRAM_HEAP if(audio_da_cfg->reg_node) { os_sema_up(&audac_priv->cache_sema); } if(audac_priv->status > 0) { audac_priv->status--; audio_da_cfg->reg_node = audac_priv->buf[audac_priv->buf_index%4]; audac_priv->buf_index++; audio_da_cfg->irq_func(audio_da_cfg , audio_da_cfg->reg_node, audac_priv->buf_len); audio_da_cfg->is_empty = 0; } #else buf = audio_dac_get_buf(global_audio_dac_s, &audio_da_cfg->reg_node, &buf_size); if(buf) { audio_da_cfg->irq_func(audio_da_cfg, buf, buf_size); audio_da_cfg->is_empty = 0; } #endif else { if(audio_da_cfg->play_empty_buf) { #if FADE_PROCESS if(audac_priv->fade_mode == 0) { audac_priv->fade_mode = 1; if(os_msgq_put(&audac_priv->fade_msg, audac_priv->fade_mode, 0) < 0) { audac_priv->fade_mode = 0; } } #endif audio_da_cfg->irq_func(audio_da_cfg , audio_da_cfg->play_empty_buf, audio_da_cfg->buf_size); } } } } static int32 global_audio_da_write(struct audio_da_config *audio, void* buf, uint32 len) { audac_write(audio->dac, buf, len); return 0; } #if SONIC_PROCESS static int opcode_func_sonic_r(stream *s,void *priv,int opcode) { int res = 0; switch(opcode) { case STREAM_OPEN_EXIT: { enable_stream(s,1); s->priv = (void*)SOUND_ALL; } break; case STREAM_OPEN_FAIL: break; //在发送到这个流的时候,进行数据包过滤 //在发送到这个流的时候,进行数据包过滤 case STREAM_FILTER_DATA: { struct data_structure *data = (struct data_structure *)priv; int filter_type = (int)get_audio_dac_set_filter_type(); //os_printf("%s:%d\n",__FUNCTION__,__LINE__); if(GET_DATA_TYPE1(data->type) != SOUND) { res = 1; break; } //永远不过滤 if(!filter_type || GET_DATA_TYPE2(data->type) == SOUND_ALL) { } else { //过滤不匹配的数据包 if(!(filter_type && (filter_type == GET_DATA_TYPE2(data->type)))) { //os_printf("filter_type:%X\tdata_type:%X\t%X\n",filter_type,GET_DATA_TYPE2(data->type),s); res = 1; break; } } } break; //流接收后,数据包也要检查是否需要过滤或者是不是因为逻辑条件符合需要过滤 case STREAM_RECV_FILTER_DATA: { struct data_structure *data = (struct data_structure *)priv; if(GET_DATA_TYPE1(data->type) != SOUND) { res = 1; break; } int filter_type = (int)get_audio_dac_set_filter_type(); //永远不过滤 if(!filter_type || GET_DATA_TYPE2(data->type) == SOUND_ALL) { } else { //过滤不匹配的数据包 if(!(filter_type && (GET_DATA_TYPE2(filter_type)== GET_DATA_TYPE2(data->type)))) { res = 1; } } } break; //接收到命令,可以尝试执行命令的接口 case STREAM_SEND_CMD: { uint32_t cmd = (uint32_t)priv; //只是接受支持的命令 if(GET_CMD_TYPE1(cmd) == CMD_AUDIO_DAC) { os_printf("!!!!!!!!!cmd:%X\n",cmd); s->priv = (void*)GET_CMD_TYPE2(cmd); } else if(GET_CMD_TYPE1(cmd) == CMD_AUDIO_DAC_MODIFY_HZ) { extern void audio_da_recfg(uint32_t hz); audio_da_recfg(GET_CMD_TYPE2(cmd)); } } break; default: //默认都返回成功 break; } return res; } static uint32_t get_sonic_data_len(void *data) { struct data_structure *d = (struct data_structure *)data; return (uint32_t)d->priv; } static uint32_t set_sonic_data_len(void *data,uint32_t len) { struct data_structure *d = (struct data_structure *)data; d->priv = (void*)len; return (uint32_t)len; } static stream_ops_func stream_sonic_ops = { .get_data_len = get_sonic_data_len, .set_data_len = set_sonic_data_len, }; static int opcode_func_sonic_s(stream *s,void *priv,int opcode) { int res = 0; switch(opcode) { case STREAM_OPEN_EXIT: { stream_data_dis_mem_custom(s); streamSrc_bind_streamDest(s,R_AUDIO_TEST); streamSrc_bind_streamDest(s,R_SPEAKER); } break; case STREAM_DATA_DIS: { struct data_structure *data = (struct data_structure *)priv; data->ops = &stream_sonic_ops; data->data = (void*)ADUIO_MALLOC(AUDIOLEN); } break; case STREAM_DATA_DESTORY: { struct data_structure *data = (struct data_structure *)priv; if(data->data) { ADUIO_FREE(data->data); } } break; default: //默认都返回成功 break; } return res; } void set_sonic_speed(struct sonic_process_priv *sonic_priv, float speed) { if(!sonic_priv) return; sonic_priv->speed = speed; os_sema_up(&sonic_priv->sema); } void set_sonic_pitch(struct sonic_process_priv *sonic_priv, float pitch) { sonic_priv->pitch = pitch; os_sema_up(&sonic_priv->sema); } void set_sonic_samplingRate(struct sonic_process_priv *sonic_priv, int samplingRate) { if(!sonic_priv) return; sonic_priv->samplingRate = samplingRate; os_sema_up(&sonic_priv->sema); } static void audac_sonic_process(void *d) { sonicStream sonic_s = (sonicStream)d; int16_t *sonic_stream_inbuf = NULL; int16_t *sonic_stream_outbuf = NULL; struct data_structure *sonic_data_r = NULL; struct data_structure *sonic_data_s = NULL; stream* sonic_stream_s = NULL; stream* sonic_stream_r = NULL; int sonicstream_cache = 0; volatile int sonicstream_input_len = 0; int sonicstream_output_len = 0; sonic_stream_s = open_stream_available(S_SONIC_PROCESS,AUDIONUM,0,opcode_func_sonic_s,NULL); sonic_stream_r = open_stream_available(R_SONIC_PROCESS,0,AUDIONUM,opcode_func_sonic_r,NULL); if(!sonic_stream_s || !sonic_stream_r) { os_printf("open sonic process stream err\n"); goto audac_sonic_process_end; } while(1) { if(os_sema_down(&sonic_priv->sema,0) == 1) { sonic_flush_stream(sonic_s); sonicstream_cache = sonicStream_output_available(sonic_s); while(sonicstream_cache > 0) { sonic_data_s = get_src_data_f(sonic_stream_s); sonic_priv->s_current_data = sonic_data_s; if(sonic_data_s) { sonic_stream_outbuf = get_stream_real_data(sonic_data_s); sonicstream_output_len = sonicStream_output_data(sonic_s, sonic_stream_outbuf, (AUDIOLEN>>1)); if(sonicstream_output_len > 0) { sonic_data_s->type = SET_DATA_TYPE(SOUND, GET_DATA_TYPE2(sonic_data_r->type)); set_stream_real_data_len(sonic_data_s,(sonicstream_output_len<<1)); send_data_to_stream(sonic_data_s); sonic_priv->s_current_data = NULL; sonicstream_cache -= sonicstream_output_len; } } else os_sleep_ms(1); } sonicStream_deinit(sonic_s); sonic_priv->sonic_s = sonicStream_init(sonic_priv->samplingRate,sonic_priv->channel,sonic_priv->speed,sonic_priv->pitch); } sonic_data_r = recv_real_data(sonic_stream_r); sonic_priv->r_current_data = sonic_data_r; if(sonic_data_r) { sonic_stream_inbuf = get_stream_real_data(sonic_data_r); sonicstream_input_len = get_stream_real_data_len(sonic_data_r); sonicStream_input_data(sonic_s, sonic_stream_inbuf, sonicstream_input_len/2); sonicstream_cache = sonicStream_output_available(sonic_s); while(sonicstream_cache >= (AUDIOLEN>>1)) { sonic_data_s = get_src_data_f(sonic_stream_s); sonic_priv->s_current_data = sonic_data_s; if(sonic_data_s) { sonic_stream_outbuf = get_stream_real_data(sonic_data_s); sonicstream_output_len = sonicStream_output_data(sonic_s, sonic_stream_outbuf, (AUDIOLEN>>1)); if(sonicstream_output_len > 0) { sonic_data_s->type = SET_DATA_TYPE(SOUND, GET_DATA_TYPE2(sonic_data_r->type)); set_stream_real_data_len(sonic_data_s,(sonicstream_output_len<<1)); send_data_to_stream(sonic_data_s); sonic_priv->s_current_data = NULL; sonicstream_cache -= sonicstream_output_len; } } else os_sleep_ms(1); } free_data(sonic_data_r); sonic_priv->r_current_data = NULL; } else { os_sleep_ms(1); } } audac_sonic_process_end: if(sonic_stream_s) { close_stream(sonic_stream_s); } if(sonic_stream_r) { close_stream(sonic_stream_r); } } #endif #if FADE_PROCESS static void audio_dac_fade(void *d) { uint32_t fade_mode = 0; struct aufade_device *fade = (struct aufade_device *)dev_get(HG_AUFADE_DEVID); while(1) { fade_mode = os_msgq_get(&audac_priv->fade_msg,-1); //fade out if(fade_mode == 1) { os_printf("\n*********fade mode:%d*********\n",fade_mode); aufade_ioctl(fade, AUFADE_IOCTL_CMD_SET_STEP, AUFADE_STEP_4, 0); aufade_ioctl(fade, AUFADE_IOCTL_CMD_SET_SAMPLE, AUFADE_SAMPLE_1, 0); aufade_start(fade, AUFADE_OUT); } else if(fade_mode == 0) { os_printf("\n*********fade mode:%d*********\n",fade_mode); aufade_ioctl(fade, AUFADE_IOCTL_CMD_SET_STEP, AUFADE_STEP_4, 0); aufade_ioctl(fade, AUFADE_IOCTL_CMD_SET_SAMPLE, AUFADE_SAMPLE_1, 0); aufade_start(fade, AUFADE_IN); } } } #endif void audac_priv_clear() { audac_priv->res_len = CACHE_BUF_LEN; audac_priv->d_offset = 0; audac_priv->s_offset = 0; } void audio_dac_cache(void *d) { stream *s = (stream *)d; struct data_structure *data = NULL; int16_t *s_buf = NULL; uint32_t get_buf_len = 0; uint8_t buf_index = 0; audac_priv_clear(); audac_priv->status = 0; audac_priv->buf_index = 0; while(1) { data = recv_real_data(s); if(data) { audac_priv->current_data = data; s_buf = get_stream_real_data(data); get_buf_len = get_stream_real_data_len(data); audac_priv->s_offset = 0; while(get_buf_len >= audac_priv->res_len) { hw_memcpy(audac_priv->buf[buf_index%4]+(audac_priv->d_offset/2), s_buf+(audac_priv->s_offset/2), audac_priv->res_len); get_buf_len -= audac_priv->res_len; audac_priv->buf_len = CACHE_BUF_LEN; audac_priv->s_offset += audac_priv->res_len; audac_priv->status++; os_sema_down(&audac_priv->cache_sema, -1); audac_priv->res_len = CACHE_BUF_LEN; audac_priv->d_offset = 0; buf_index++; } if(get_buf_len) { hw_memcpy(audac_priv->buf[buf_index%4]+(audac_priv->d_offset/2), s_buf+(audac_priv->s_offset/2), get_buf_len); audac_priv->res_len = CACHE_BUF_LEN - get_buf_len; audac_priv->d_offset = get_buf_len; audac_priv->s_offset = 0; get_buf_len = 0; } free_data(data); audac_priv->current_data = NULL; } else { if(audac_priv->status == 0) { if(audac_priv->d_offset > 0) { hw_memset(audac_priv->buf[buf_index%4]+(audac_priv->d_offset/2), 0, (CACHE_BUF_LEN-audac_priv->d_offset)); audac_priv->buf_len = CACHE_BUF_LEN; audac_priv->status++; os_sema_down(&audac_priv->cache_sema, -1); buf_index++; audac_priv_clear(); get_buf_len = 0; } else os_sleep_ms(1); } else os_sleep_ms(1); } } } static int opcode_func(stream *s,void *priv,int opcode) { int res = 0; switch(opcode) { case STREAM_OPEN_EXIT: { enable_stream(s,1); s->priv = (void*)SOUND_ALL; audac_priv = (struct audio_dac_priv*)ADUIO_ZALLOC(sizeof(struct audio_dac_priv)); if(audac_priv) { #ifdef PSRAM_HEAP audac_priv->buf[0] = (int16_t *)custom_malloc(CACHE_BUF_LEN); audac_priv->buf[1] = (int16_t *)custom_malloc(CACHE_BUF_LEN); audac_priv->buf[2] = (int16_t *)custom_malloc(CACHE_BUF_LEN); audac_priv->buf[3] = (int16_t *)custom_malloc(CACHE_BUF_LEN); os_sema_init(&audac_priv->cache_sema,3); OS_TASK_INIT("audio_dac_cache", &audac_priv->cache_task_hdl, audio_dac_cache, s, OS_TASK_PRIORITY_ABOVE_NORMAL, 1024); #endif #if FADE_PROCESS os_msgq_init(&audac_priv->fade_msg, 1); OS_TASK_INIT("audio_dac_fade", &audac_priv->fade_task_hdl, audio_dac_fade, NULL, OS_TASK_PRIORITY_ABOVE_NORMAL, 1024); #endif } #if SONIC_PROCESS sonic_priv = (struct sonic_process_priv*)ADUIO_ZALLOC(sizeof(struct sonic_process_priv)); if(sonic_priv) { sonic_priv->samplingRate = audio_dac_get_samplingrate(); sonic_priv->channel = 1; sonic_priv->pitch = 1.0; sonic_priv->speed = 1.0; sonic_priv->sonic_s = sonicStream_init(sonic_priv->samplingRate,sonic_priv->channel,sonic_priv->speed,sonic_priv->pitch); os_sema_init(&sonic_priv->sema,0); OS_TASK_INIT("audac_sonic_process", &sonic_priv->task_hdl, audac_sonic_process, sonic_priv->sonic_s, OS_TASK_PRIORITY_ABOVE_NORMAL-1, 1024); } #endif } break; //在发送到这个流的时候,进行数据包过滤 case STREAM_FILTER_DATA: { struct data_structure *data = (struct data_structure *)priv; int filter_type = (int)s->priv; //os_printf("%s:%d\n",__FUNCTION__,__LINE__); if(GET_DATA_TYPE1(data->type) != SOUND) { res = 1; break; } //永远不过滤 if(!filter_type || GET_DATA_TYPE2(data->type) == SOUND_ALL) { } else { //过滤不匹配的数据包 if(!(filter_type && (filter_type == GET_DATA_TYPE2(data->type)))) { //os_printf("filter_type:%X\tdata_type:%X\t%X\n",filter_type,GET_DATA_TYPE2(data->type),s); res = 1; break; } } } break; //流接收后,数据包也要检查是否需要过滤或者是不是因为逻辑条件符合需要过滤 case STREAM_RECV_FILTER_DATA: { struct data_structure *data = (struct data_structure *)priv; if(GET_DATA_TYPE1(data->type) != SOUND) { res = 1; break; } int filter_type = (int)s->priv; //永远不过滤 if(!filter_type || GET_DATA_TYPE2(data->type) == SOUND_ALL) { } else { //过滤不匹配的数据包 if(!(filter_type && (GET_DATA_TYPE2(filter_type)== GET_DATA_TYPE2(data->type)))) { res = 1; //_os_printf("FILTER\n"); } } } break; //接收到命令,可以尝试执行命令的接口 case STREAM_SEND_CMD: { uint32_t cmd = (uint32_t)priv; //只是接受支持的命令 if(GET_CMD_TYPE1(cmd) == CMD_AUDIO_DAC) { os_printf("!!!!!!!!!cmd:%X\n",cmd); s->priv = (void*)GET_CMD_TYPE2(cmd); } else if(GET_CMD_TYPE1(cmd) == CMD_AUDIO_DAC_MODIFY_HZ) { extern void audio_da_recfg(uint32_t hz); audio_da_recfg(GET_CMD_TYPE2(cmd)); } } break; default: break; } return res; } //优先创建音频的流 stream *audio_dac_stream_init(const char *name) { stream *s = open_stream_available(name,0,AUDIONUM,opcode_func,NULL); if(s) { global_audio_dac_s = s; } return s; } //关闭音频流 void audio_dac_stream_deinit() { int res; if(global_audio_dac_s) { res = close_stream(global_audio_dac_s); if(!res) { global_audio_dac_s = NULL; } } } void audio_da_init() { struct aufade_device *fade = (struct aufade_device *)dev_get(HG_AUFADE_DEVID); aufade_open(fade); os_printf("%s:%d\n",__FUNCTION__,__LINE__); struct audac_device *audio_da = (struct audac_device *)dev_get(HG_AUDAC_DEVID); memset(&global_audio_da,0,sizeof(global_audio_da)); audio_da_config *audio_da_cfg = &global_audio_da; audio_da_cfg->dac = audio_da; audio_da_cfg->buf_size = AUDIOLEN; audio_da_cfg->play_empty_buf = empty_buf; audio_da_cfg->irq_func = global_audio_da_write; audio_da_cfg->audio_hz = AUDAC_SAMPLE_RATE_8K; stream *dest = audio_dac_stream_init(R_SPEAKER); *((uint32_t*)0x4000802c) |= 0x690000; audac_open(audio_da, audio_da_cfg->audio_hz ); audac_request_irq(audio_da, AUDAC_IRQ_FLAG_HALF | AUDAC_IRQ_FLAG_FULL, (audac_irq_hdl)audio_dac_irq, (uint32_t)audio_da_cfg); audio_da_cfg->irq_func(audio_da_cfg , audio_da_cfg->play_empty_buf, audio_da_cfg->buf_size); global_audio_dac_s = dest; return; } void audio_da_deinit() { struct audac_device *audio_da = (struct audac_device *)dev_get(HG_AUDAC_DEVID); audio_da_config *audio_da_cfg = &global_audio_da; struct aufade_device *fade = (struct aufade_device *)dev_get(HG_AUFADE_DEVID); aufade_close(fade); audac_close(audio_da); prev_filter_type = get_audio_dac_set_filter_type(); audio_dac_set_filter_type(SOUND_NONE); //清除中断没有处理完的数据 #ifdef PSRAM_HEAP if(audac_priv->current_data) { free_data(audac_priv->current_data); audac_priv->current_data = NULL; } if(audio_da_cfg->reg_node) { os_sema_up(&audac_priv->cache_sema); } if(audio_da_cfg->current_node) { os_sema_up(&audac_priv->cache_sema); } #else if(audio_da_cfg->reg_node) { free_data(audio_da_cfg->reg_node); audio_da_cfg->reg_node = NULL; } if(audio_da_cfg->reg_node) { free_data(audio_da_cfg->reg_node); audio_da_cfg->reg_node = NULL; } #endif #ifdef SONIC_PRIV if(sonic_priv->r_current_data) { free_data(sonic_priv->r_current_data); sonic_priv->r_current_data = NULL; } if(sonic_priv->s_current_data) { force_del_data(sonic_priv->s_current_data); sonic_priv->s_current_data = NULL; } #endif } void audio_da_reinit() { struct audac_device *audio_da = (struct audac_device *)dev_get(HG_AUDAC_DEVID); struct aufade_device *fade = (struct aufade_device *)dev_get(HG_AUFADE_DEVID); aufade_open(fade); //这里成立的前提是原来stream已经创建过,否则可能有问题 stream *dest = audio_dac_stream_init(R_SPEAKER); memset(&global_audio_da,0,sizeof(global_audio_da)); audio_da_config *audio_da_cfg = &global_audio_da; audio_da_cfg->dac = audio_da; audio_da_cfg->buf_size = AUDIOLEN; audio_da_cfg->play_empty_buf = empty_buf; audio_da_cfg->irq_func = global_audio_da_write; audio_da_cfg->audio_hz = AUDAC_SAMPLE_RATE_8K; *((uint32_t*)0x4000802c) |= 0x690000; audac_open(audio_da, audio_da_cfg->audio_hz); os_printf("!!!!audio_da_cfg:%X\n",audio_da_cfg); audac_request_irq(audio_da, AUDAC_IRQ_FLAG_HALF | AUDAC_IRQ_FLAG_FULL, (audac_irq_hdl)audio_dac_irq, (uint32_t)audio_da_cfg); audio_da_cfg->irq_func(audio_da_cfg , audio_da_cfg->play_empty_buf, audio_da_cfg->buf_size); global_audio_dac_s = dest; //这个函数只是重新初始化dac硬件,所以流与init的时候有区别,这里需要关闭一次(实际内部没有关闭,与audio_dac_stream_init成对使用) audio_dac_stream_deinit(); audio_dac_set_filter_type(prev_filter_type); } //音频采样率重新修改 void audio_da_recfg(uint32_t hz) { os_printf("%s hz:%d\n",__FUNCTION__,hz); //识别采样率,如果一样,则直接退出 int8_t now_hz_enum = -1; switch(hz) { case 8000: now_hz_enum = AUDAC_SAMPLE_RATE_8K; break; case 11025: now_hz_enum = AUDAC_SAMPLE_RATE_11_025K; break; case 16000: now_hz_enum = AUDAC_SAMPLE_RATE_16K; break; case 22050: now_hz_enum = AUDAC_SAMPLE_RATE_22_05K; break; case 32000: now_hz_enum = AUDAC_SAMPLE_RATE_32K; break; case 44100: now_hz_enum = AUDAC_SAMPLE_RATE_44_1K; break; case 48000: now_hz_enum = AUDAC_SAMPLE_RATE_48K; break; case 24000: now_hz_enum = AUDAC_SAMPLE_RATE_24K; break; case 12000: now_hz_enum = AUDAC_SAMPLE_RATE_12K; break; default: now_hz_enum = -1; break; } audio_da_config *audio_da_cfg = &global_audio_da; os_printf("now_hz_enum:%d\tlast now_hz_enum:%d\n",now_hz_enum,audio_da_cfg->audio_hz); //采样率不需要修改或者采样率设置错误 if(audio_da_cfg->audio_hz == now_hz_enum || now_hz_enum == -1) { return; } struct audac_device *audac_dev = (struct audac_device *)dev_get(HG_AUDAC_DEVID); //将当前流的数据也删除,然后才可以接收其他正确采样率的数据 int last_type = get_audio_dac_set_filter_type(); audio_dac_set_filter_type(SOUND_NONE); #if SONIC_PROCESS set_sonic_samplingRate(sonic_priv, hz); #endif //等待播放数据完毕,然后切换采样率 uint32_t count = 0; //等待中断数据播放完毕 while( !(audio_da_cfg->is_empty) && count++<1000) { os_sleep_ms(1); } audac_ioctl(audac_dev,AUDAC_IOCTL_CMD_CHANGE_SAMPLE_RATE,now_hz_enum,0); audio_dac_set_filter_type(last_type); audio_da_cfg->audio_hz = now_hz_enum; os_printf("audio_da_cfg:%X\tnow_hz_enum:%d\n",audio_da_cfg,now_hz_enum); audio_da_cfg->irq_func(audio_da_cfg , audio_da_cfg->play_empty_buf, audio_da_cfg->buf_size); } //写一些通用dac输出的接口 /*********************************************************** 设置接收和播放声音的类型(只是将当前不匹配的音频都会过滤掉) 使用场景:比如进入音乐播放后,就不再响应按键的音频了 ***********************************************************/ void audio_dac_set_filter_type(int filter_type) { if(global_audio_dac_s) { os_printf("filter_type:%d\t%X\n",filter_type,global_audio_dac_s); global_audio_dac_s->priv = (void*)filter_type; } } void print_audio_dac_set_filter_type() { if(global_audio_dac_s) { os_printf("type:%X\n",global_audio_dac_s->priv); } } int get_audio_dac_set_filter_type(void) { if(global_audio_dac_s) { return (int)global_audio_dac_s->priv; } return 0; } int audio_dac_get_samplingrate(void) { audio_da_config *play = &global_audio_da; int32_t samplingrate = -1; switch(play->audio_hz) { case AUDAC_SAMPLE_RATE_8K: samplingrate = 8000; break; case AUDAC_SAMPLE_RATE_11_025K: samplingrate = 11025; break; case AUDAC_SAMPLE_RATE_12K: samplingrate = 12000; break; case AUDAC_SAMPLE_RATE_16K: samplingrate = 16000; break; case AUDAC_SAMPLE_RATE_22_05K: samplingrate = 22050; break; case AUDAC_SAMPLE_RATE_24K: samplingrate = 24000; break; case AUDAC_SAMPLE_RATE_32K: samplingrate = 32000; break; case AUDAC_SAMPLE_RATE_44_1K: samplingrate = 44100; break; case AUDAC_SAMPLE_RATE_48K: samplingrate = 48000; break; } printf("now DAC samplingrate:%d\n",samplingrate); return samplingrate; }