141 lines
3.5 KiB
C
141 lines
3.5 KiB
C
#include <assert.h>
|
|
|
|
#include "app_config.h"
|
|
#include "app_audio.h"
|
|
#include "dram_mem.h"
|
|
|
|
#include "audio_scene.h"
|
|
#include "co_list.h"
|
|
#include "fr_device_pa.h"
|
|
|
|
#define APP_AUDIO_DATA_READY_THD 6
|
|
#define APP_AUDIO_DATA_BUFFER_MAX 12
|
|
|
|
enum app_audio_mode_t {
|
|
APP_AUDIO_MODE_IDLE,
|
|
APP_AUDIO_MODE_A2DP_SINK,
|
|
APP_AUDIO_MODE_A2DP_SOURCE,
|
|
APP_AUDIO_MODE_SCO,
|
|
APP_AUDIO_MODE_TONE,
|
|
APP_AUDIO_MODE_VOICE_RECOGNIZE,
|
|
};
|
|
|
|
static enum app_audio_mode_t audio_mode = APP_AUDIO_MODE_IDLE;
|
|
static uint32_t audio_data_counter = 0;
|
|
static audio_scene_t *audio_scene;
|
|
|
|
static void app_audio_stop(void)
|
|
{
|
|
switch(audio_mode) {
|
|
case APP_AUDIO_MODE_A2DP_SINK:
|
|
app_audio_a2dp_sink_stop();
|
|
break;
|
|
case APP_AUDIO_MODE_SCO:
|
|
app_audio_sco_stop();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void app_audio_a2dp_sink_start(audio_type_t audio_type, uint32_t sample_rate)
|
|
{
|
|
audio_scene_param_a2dp_sink_t param;
|
|
|
|
if (audio_mode == APP_AUDIO_MODE_A2DP_SINK) {
|
|
return;
|
|
}
|
|
|
|
if (audio_mode != APP_AUDIO_MODE_IDLE) {
|
|
app_audio_stop();
|
|
}
|
|
|
|
param.sample_rate = sample_rate;
|
|
param.channels = 2;
|
|
param.audio_type = audio_type;
|
|
param.hw_type = AUDIO_HW_TYPE_CODEC;
|
|
param.hw_base_addr = I2S0_BASE;
|
|
|
|
assert(audio_mode == APP_AUDIO_MODE_IDLE);
|
|
|
|
audio_scene = audio_scene_create(AUDIO_SCENE_TYPE_A2DP_SINK, ¶m);
|
|
assert(audio_scene != NULL);
|
|
audio_mode = APP_AUDIO_MODE_A2DP_SINK;
|
|
}
|
|
|
|
void app_audio_a2dp_sink_stop(void)
|
|
{
|
|
if (audio_mode == APP_AUDIO_MODE_A2DP_SINK) {
|
|
audio_scene_destroy(audio_scene);
|
|
audio_mode = APP_AUDIO_MODE_IDLE;
|
|
device_pa_disable();
|
|
}
|
|
}
|
|
|
|
void app_audio_a2dp_sink_play(uint8_t *buffer, uint32_t length)
|
|
{
|
|
if (audio_mode == APP_AUDIO_MODE_A2DP_SINK) {
|
|
if (audio_scene_dac_is_ready(audio_scene)) {
|
|
device_pa_enable();
|
|
}
|
|
audio_scene_recv_raw_data(audio_scene, true, buffer, length);
|
|
}
|
|
}
|
|
|
|
void app_audio_sco_start(audio_type_t audio_type,audio_sence_report_encoded_frame report_enc_cb, void *report_enc_arg)
|
|
{
|
|
audio_scene_param_sco_t param;
|
|
|
|
if (audio_mode == APP_AUDIO_MODE_SCO) {
|
|
return;
|
|
}
|
|
|
|
if (audio_mode != APP_AUDIO_MODE_IDLE) {
|
|
app_audio_stop();
|
|
}
|
|
|
|
if (audio_type == AUDIO_TYPE_MSBC) {
|
|
printf("SCO: msbc.\r\n");
|
|
param.sample_rate = 16000;
|
|
}
|
|
else {
|
|
printf("SCO: cvsd.\r\n");
|
|
param.sample_rate = 8000;
|
|
}
|
|
param.audio_type = audio_type;
|
|
param.hw_type = AUDIO_HW_TYPE_CODEC;
|
|
param.hw_base_addr = I2S0_BASE;
|
|
param.report_enc_cb = report_enc_cb;
|
|
param.report_enc_arg = report_enc_arg;
|
|
|
|
assert(audio_mode == APP_AUDIO_MODE_IDLE);
|
|
|
|
audio_scene = audio_scene_create(AUDIO_SCENE_TYPE_SCO, ¶m);
|
|
audio_mode = APP_AUDIO_MODE_SCO;
|
|
assert(audio_scene != NULL);
|
|
}
|
|
|
|
void app_audio_sco_stop(void)
|
|
{
|
|
if (audio_mode == APP_AUDIO_MODE_SCO) {
|
|
audio_scene_destroy(audio_scene);
|
|
audio_mode = APP_AUDIO_MODE_IDLE;
|
|
device_pa_disable();
|
|
}
|
|
}
|
|
|
|
void app_audio_sco_recv(bool valid, uint8_t audio_type, uint8_t *buffer, uint32_t length)
|
|
{
|
|
if (audio_mode == APP_AUDIO_MODE_SCO) {
|
|
if (audio_scene_dac_is_ready(audio_scene)) {
|
|
device_pa_enable();
|
|
}
|
|
if (audio_type == AUDIO_TYPE_MSBC) {
|
|
audio_scene_recv_raw_data(audio_scene, valid, buffer+2, length-3);
|
|
}
|
|
else {
|
|
audio_scene_recv_raw_data(audio_scene, valid, buffer, length);
|
|
}
|
|
}
|
|
}
|