123 lines
4.0 KiB
C
123 lines
4.0 KiB
C
#include <assert.h>
|
|
|
|
#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();
|
|
}
|