#include #include "audio_scene.h" #include "audio_rpmsg.h" #include "dsp.h" #include "dsp_mem.h" #include "FreeRTOS.h" #define VOICE_RECOGNIZE_PCM_BUFFER_MAX_SIZE 128 static void voice_recognize_launch(int16_t *mic_pcm, uint32_t samples) { struct rpmsg_sync_msg_voice_recognize_launch_t sync_msg; if (((uint32_t)mic_pcm >= DSP_DRAM_MCU_BASE_ADDR) && ((uint32_t)mic_pcm < (DSP_DRAM_MCU_BASE_ADDR+DSP_DRAM_SIZE))) { mic_pcm = (void *)MCU_SRAM_2_DSP_DRAM(mic_pcm); } sync_msg.mic_pcm = mic_pcm; sync_msg.samples = samples; rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_VOICE_RECOGNIZE_LAUNCH, (void *)&sync_msg, NULL); } static void hw_receive_adc_pcm_cb(uint32_t samples) { audio_scene_evt_t *evt = (void *)pvPortMalloc(sizeof(audio_scene_evt_t)); if (evt) { evt->type = AUDIO_SCENE_EVT_TYPE_ADC_NEW_SAMPLES; evt->p.adc_new_samples = samples; audio_scene_send_event(evt); } } static void voice_recognize_init(void) { voice_recognize_env_t *env; audio_scene_param_voice_recognize_t *param; env = &audio_scene_env.env.voice_recognize; param = &audio_scene_env.scene->param.voice_recognize; /* initialize audio hardware */ env->audio_hw = audio_hw_create(param->hw_type, NULL, param->hw_base_addr, AUDIO_HW_DIR_IN, param->sample_rate, AUDIO_CHANNELS_MONO); env->audio_hw_output = audio_hw_output_add(env->audio_hw, hw_receive_adc_pcm_cb); /* allocate PCM buffer to save MIC data */ env->pcm = dsp_mem_alloc(sizeof(int16_t) * VOICE_RECOGNIZE_PCM_BUFFER_MAX_SIZE); /* TODO, notice DSP to prepare for voice recognization */ } void voice_recognize_destroy(void) { if (audio_scene_env.scene && (audio_scene_env.scene->type == AUDIO_SCENE_TYPE_VOICE_RECOGNIZE)) { voice_recognize_env_t *env = &audio_scene_env.env.voice_recognize; /* release audio hardware */ audio_hw_destroy(env->audio_hw); /* release pcm buffer */ dsp_mem_free(env->pcm); /* TODO, notice DSP to release resources for voice recognization */ } } void voice_recognize_task(void *arg) { audio_scene_t *scene = audio_scene_env.scene; audio_scene_evt_t *evt; bool exit = false; if (scene == NULL) { return; } /* initialize necessary audio decoder and hardware */ voice_recognize_init(); while (exit == false) { ulTaskNotifyTake(pdFALSE, portMAX_DELAY); GLOBAL_INT_DISABLE(); evt = (void *)co_list_pop_front(&audio_scene_env.evt_list); GLOBAL_INT_RESTORE(); if (evt) { switch (evt->type) { case AUDIO_SCENE_EVT_TYPE_ADC_NEW_SAMPLES: { voice_recognize_env_t *voice_recognize = &audio_scene_env.env.voice_recognize; uint32_t adc_samples = evt->p.adc_new_samples; /* save adc data into framebuffer */ while ( adc_samples ) { uint32_t samples = adc_samples > VOICE_RECOGNIZE_PCM_BUFFER_MAX_SIZE ? VOICE_RECOGNIZE_PCM_BUFFER_MAX_SIZE : adc_samples; audio_hw_read_pcm(voice_recognize->audio_hw_output, &voice_recognize->pcm[0], samples, AUDIO_CHANNELS_MONO); voice_recognize_launch(&voice_recognize->pcm[0], samples); adc_samples -= samples; } } break; case AUDIO_SCENE_EVT_TYPE_DESTROY: exit = true; break; default: assert(0); break; } vPortFree(evt); } } audio_scene_task_destroy(); }