Skip to content

Commit c759d06

Browse files
committed
framework/src/media, os/audio : Add changeDSPFlow api for change dsp flow rule on real-time.
If we apply add_dsp_flow_rules_extract_raw_data using api added, We can extract recording data not preprocessing with AEC.
1 parent fab169e commit c759d06

File tree

9 files changed

+185
-10
lines changed

9 files changed

+185
-10
lines changed

apps/examples/wakerec/wakerec.cxx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <media/voice/SpeechDetectorListenerInterface.h>
4141
#include <media/FocusManager.h>
4242
#include <media/stream_info.h>
43+
#include <audio/SoundManager.h>
4344
#include <iostream>
4445
#include <memory>
4546
#include <functional>
@@ -124,7 +125,7 @@ class WakeRec : public media::voice::SpeechDetectorListenerInterface,public Focu
124125
return;
125126
}
126127

127-
if (mr.setDuration(7) == RECORDER_ERROR_NONE && mr.prepare() == RECORDER_ERROR_NONE) {
128+
if (mr.setDuration(15) == RECORDER_ERROR_NONE && mr.prepare() == RECORDER_ERROR_NONE) {
128129
printf("#### [MR] prepare succeeded.\n");
129130
} else {
130131
printf("#### [MR] prepare failed.\n");
@@ -347,7 +348,12 @@ int wakerec_main(int argc, char *argv[])
347348
return -1;
348349
}
349350
auto recorder = std::shared_ptr<WakeRec>(new WakeRec());
350-
if (argc == 2 && atoi(argv[1]) == 0) {
351+
if (atoi(argv[1]) == 0) {
352+
uint8_t select_dsp_rules = atoi(argv[2]);
353+
if (changeDSPFlow(select_dsp_rules)) {
354+
printf("Success changeDSPFlow\n");
355+
}
356+
351357
printf("disable KD!!\n");
352358
recorder->initWakeRec(false);
353359
recorder->startRecord();

framework/include/audio/SoundManager.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ bool setStreamMute(stream_policy_t stream_policy, bool mute);
8282
*/
8383
bool getStreamMuteState(stream_policy_t stream_policy, bool *mute);
8484

85+
/**
86+
* @brief Change dsp flow rule.
87+
* @param[in] dwp flow rule number to be changed.
88+
* @return true if the operation was successful, false otherwise.
89+
*/
90+
bool changeDSPFlow(uint8_t dsp_flow_num);
91+
8592
#if defined(__cplusplus)
8693
}
8794
#endif

framework/src/audio/SoundManager.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,20 @@ bool getStreamMuteState(stream_policy_t stream_policy, bool *mute)
9797
return true;
9898
}
9999

100+
bool changeDSPFlow(uint8_t dsp_flow_num)
101+
{
102+
if (dsp_flow_num == 0) {
103+
meddbg("dsp_flow_num can not be 0, it starts from 1\n");
104+
return false;
105+
}
106+
107+
meddbg("SoundManager : changeDSPFlow. dsp_flow_num: %d\n", dsp_flow_num);
108+
audio_manager_result_t res = change_input_dsp_flow(dsp_flow_num);
109+
if (res != AUDIO_MANAGER_SUCCESS) {
110+
meddbg("change_output_dsp_flow failed dsp_flow_num : %d, ret : %d\n", dsp_flow_num, res);
111+
return false;
112+
}
113+
return true;
114+
}
115+
116+

framework/src/media/audio/audio_manager.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,6 +2818,27 @@ audio_manager_result_t get_audio_stream_mute_state(stream_policy_t stream_policy
28182818
return AUDIO_MANAGER_SUCCESS;
28192819
}
28202820

2821+
audio_manager_result_t change_input_dsp_flow(uint8_t dsp_flow_num)
2822+
{
2823+
audio_manager_result_t ret;
2824+
struct audio_caps_desc_s caps_desc;
2825+
audio_card_info_t *card;
2826+
char card_path[AUDIO_DEVICE_FULL_PATH_LENGTH];
2827+
2828+
card = &g_audio_in_cards[g_actual_audio_in_card_id];
2829+
get_card_path(card_path, card->card_id, card->device_id, INPUT);
2830+
2831+
pthread_mutex_lock(&(card->card_mutex));
2832+
2833+
ret = control_audio_stream_device(card_path, AUDIOIOC_CHANGEDSPFLOW, (unsigned long)dsp_flow_num);
2834+
if (ret != AUDIO_MANAGER_SUCCESS) {
2835+
meddbg("Fail to change dsp flow, ret = %d errno : %d\n", ret, get_errno());
2836+
}
2837+
2838+
pthread_mutex_unlock(&(card->card_mutex));
2839+
return ret;
2840+
}
2841+
28212842
#ifdef CONFIG_DEBUG_MEDIA_INFO
28222843
void print_audio_card_info(audio_io_direction_t direct)
28232844
{

framework/src/media/audio/audio_manager.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,21 @@ audio_manager_result_t set_audio_stream_mute_from_json(stream_policy_t stream_po
898898
****************************************************************************/
899899
audio_manager_result_t get_audio_stream_mute_state(stream_policy_t stream_policy, bool *mute);
900900

901+
/****************************************************************************
902+
* Name: change_input_dsp_flow
903+
*
904+
* Description:
905+
* It changes the current dsp flow to dsp flow of given number.
906+
*
907+
* Input parameter:
908+
* stream_policy: dwp flow rule number to be changed.
909+
* mute: pointer to store the mute state of given stream policy.
910+
*
911+
* Return Value:
912+
* On success, AUDIO_MANAGER_SUCCESS. Otherwise, a negative value.
913+
****************************************************************************/
914+
audio_manager_result_t change_input_dsp_flow(uint8_t dsp_flow_num);
915+
901916
#ifdef CONFIG_DEBUG_MEDIA_INFO
902917
/****************************************************************************
903918
* Name: dump_audio_card_info

os/drivers/ai-soc/ndp120/src/ndp120_api.c

Lines changed: 109 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ static struct ndp120_dev_s *_ndp_debug_handle = NULL;
125125
/****************************************************************************
126126
* Function Prototypes
127127
****************************************************************************/
128-
int ndp120_init(struct ndp120_dev_s *dev, bool reinit);
128+
int ndp120_init(struct ndp120_dev_s *dev, uint8_t dsp_fw_num);
129129
void ndp120_aec_enable(struct ndp120_dev_s *dev);
130130
void ndp120_aec_disable(struct ndp120_dev_s *dev);
131131
void ndp120_test_internal_passthrough_switch(struct ndp120_dev_s *dev, int internal);
@@ -965,6 +965,65 @@ void add_dsp_flow_rules(struct syntiant_ndp_device_s *ndp)
965965

966966
}
967967

968+
static
969+
void add_dsp_flow_rules_extract_raw_data(struct syntiant_ndp_device_s *ndp)
970+
{
971+
int s = 0;
972+
ndp120_dsp_data_flow_setup_t setup;
973+
974+
int src_pcm = 0;
975+
int src_func = 0;
976+
int src_nn = 0;
977+
978+
memset(&setup, 0, sizeof(setup));
979+
980+
// ----------
981+
// COMBINED NORMAL + AEC FLOW
982+
/* PCM7->FUNCx */
983+
setup.src_pcm_audio[src_pcm].src_param = NDP120_DSP_DATA_FLOW_SRC_PARAM_AUD0_STEREO;
984+
#ifdef CONFIG_NDP120_AEC_SUPPORT
985+
setup.src_pcm_audio[src_pcm].src_param |= NDP120_DSP_DATA_FLOW_SRC_PARAM_AUD1_LEFT;
986+
#endif
987+
setup.src_pcm_audio[src_pcm].dst_param = FF_ID;
988+
setup.src_pcm_audio[src_pcm].dst_type = NDP120_DSP_DATA_FLOW_DST_TYPE_FUNCTION;
989+
setup.src_pcm_audio[src_pcm].algo_config_index = 0;
990+
setup.src_pcm_audio[src_pcm].set_id = COMBINED_FLOW_SET_ID;
991+
setup.src_pcm_audio[src_pcm].algo_exec_property = 0;
992+
src_pcm++;
993+
994+
/* FUNCx->NN0 */
995+
setup.src_function[src_func].src_param = FF_ID;
996+
setup.src_function[src_func].dst_param = KEYWORD_NETWORK_ID;
997+
setup.src_function[src_func].dst_type = NDP120_DSP_DATA_FLOW_DST_TYPE_NN;
998+
setup.src_function[src_func].algo_config_index = -1;
999+
setup.src_function[src_func].set_id = COMBINED_FLOW_SET_ID;
1000+
setup.src_function[src_func].algo_exec_property = 0;
1001+
src_func++;
1002+
1003+
/* PCMx->HOST_EXT_AUDIO */
1004+
setup.src_pcm_audio[src_pcm].src_param = NDP120_DSP_DATA_FLOW_SRC_PARAM_AUD0_LEFT;
1005+
setup.src_pcm_audio[src_pcm].dst_param = NDP120_DSP_DATA_FLOW_DST_SUBTYPE_AUDIO;
1006+
setup.src_pcm_audio[src_pcm].dst_type = NDP120_DSP_DATA_FLOW_DST_TYPE_HOST_EXTRACT;
1007+
setup.src_pcm_audio[src_pcm].algo_config_index = 0;
1008+
setup.src_pcm_audio[src_pcm].set_id = COMBINED_FLOW_SET_ID;
1009+
setup.src_pcm_audio[src_pcm].algo_exec_property = 0;
1010+
src_pcm++;
1011+
1012+
/* NN0->MCU */
1013+
setup.src_nn[src_nn].src_param = 0;
1014+
setup.src_nn[src_nn].dst_param = 0;
1015+
setup.src_nn[src_nn].dst_type = NDP120_DSP_DATA_FLOW_DST_TYPE_MCU;
1016+
setup.src_nn[src_nn].algo_config_index = -1;
1017+
setup.src_nn[src_nn].set_id = COMBINED_FLOW_SET_ID;
1018+
setup.src_nn[src_nn].algo_exec_property = 0;
1019+
src_nn++;
1020+
1021+
auddbg("Applied flow rules extract raw data\n");
1022+
s = syntiant_ndp120_dsp_flow_setup_apply(ndp, &setup);
1023+
check_status("syntiant_ndp120_dsp_flow_setup_apply", s);
1024+
1025+
}
1026+
9681027
#if BT_MIC_SUPPORT == 1
9691028
static
9701029
void add_dsp_flow_rules_btmic(struct syntiant_ndp_device_s *ndp)
@@ -1237,7 +1296,7 @@ check_firmware_aliveness(struct ndp120_dev_s *dev, uint32_t wait_period_ms)
12371296

12381297
dev->lower->reset();
12391298

1240-
s = ndp120_init(dev, true);
1299+
s = ndp120_init(dev, dev->cur_dsp_flow_num);
12411300

12421301
if (s) {
12431302
/* For now do nothing, there may be some cases where init might
@@ -1285,7 +1344,7 @@ ndp120_app_device_health_check(void)
12851344
}
12861345
#endif
12871346

1288-
int ndp120_init(struct ndp120_dev_s *dev, bool reinit)
1347+
int ndp120_init(struct ndp120_dev_s *dev, uint8_t dsp_fw_num)
12891348
{
12901349
/* File names */
12911350
int s;
@@ -1310,7 +1369,7 @@ int ndp120_init(struct ndp120_dev_s *dev, bool reinit)
13101369
/* save handle so we can use it from debug routine later, e.g. from other util/shell */
13111370
_ndp_debug_handle = dev;
13121371

1313-
if (!reinit) {
1372+
if (dsp_fw_num == 0) {
13141373
s = pthread_mutex_init(&dev->ndp_mutex_mbsync, NULL);
13151374
if (s) {
13161375
auddbg("failed to initialize mb sync mutex variable\n");
@@ -1380,8 +1439,22 @@ int ndp120_init(struct ndp120_dev_s *dev, bool reinit)
13801439
#if BT_MIC_SUPPORT == 1
13811440
// add special rules for BT-mic
13821441
add_dsp_flow_rules_btmic(dev->ndp);
1442+
dev->cur_dsp_flow_num = 1;
13831443
#else
1384-
add_dsp_flow_rules(dev->ndp);
1444+
switch(dsp_fw_num) {
1445+
case 1:
1446+
add_dsp_flow_rules(dev->ndp);
1447+
dev->cur_dsp_flow_num = 1;
1448+
break;
1449+
case 2:
1450+
add_dsp_flow_rules_extract_raw_data(dev->ndp);
1451+
dev->cur_dsp_flow_num = 2;
1452+
break;
1453+
default:
1454+
add_dsp_flow_rules(dev->ndp);
1455+
dev->cur_dsp_flow_num = 1;
1456+
break;
1457+
}
13851458
#endif
13861459

13871460
struct syntiant_ndp120_config_tank_s tank_config;
@@ -1444,7 +1517,7 @@ int ndp120_init(struct ndp120_dev_s *dev, bool reinit)
14441517
#endif
14451518

14461519
#ifdef CONFIG_NDP120_ALIVE_CHECK
1447-
if (!reinit) {
1520+
if (dsp_fw_num == 0) {
14481521
pid_t pid = kernel_thread("NDP_health_check", 100, 4096, ndp120_app_device_health_check, NULL);
14491522
if (pid < 0) {
14501523
auddbg("Device health check thread creation failed\n");
@@ -1835,7 +1908,7 @@ int ndp120_change_kd(struct ndp120_dev_s *dev)
18351908

18361909
dev->lower->reset();
18371910

1838-
s = ndp120_init(dev, true);
1911+
s = ndp120_init(dev, dev->cur_dsp_flow_num);
18391912

18401913
if (s) {
18411914
/* For now do nothing, there may be some cases where init might
@@ -2015,3 +2088,32 @@ void ndp120_aec_disable(struct ndp120_dev_s *dev)
20152088
dev->extclk_inuse = false;
20162089
}
20172090
#endif
2091+
2092+
void ndp120_change_dsp_flow(struct ndp120_dev_s *dev, uint8_t dsp_flow_num)
2093+
{
2094+
#if BT_MIC_SUPPORT == 1
2095+
auddbg("To change dsp flow is not spported when BT_MIC_SUPPORT.\n");
2096+
return;
2097+
#endif
2098+
2099+
int s;
2100+
ndp120_semtake(dev);
2101+
dev->lower->irq_enable(false);
2102+
2103+
s = syntiant_ndp_uninit(dev->ndp, false, SYNTIANT_NDP_INIT_MODE_RESET);
2104+
audvdbg("uninit : %d\n", s);
2105+
2106+
dev->lower->reset();
2107+
2108+
s = ndp120_init(dev, dsp_flow_num);
2109+
if (s) {
2110+
/* For now do nothing, there may be some cases where init might
2111+
* have failed due to no memory, so retry after some time */
2112+
auddbg("reinit failed!\n");
2113+
} else {
2114+
/* re enable interrupts */
2115+
dev->lower->irq_enable(true);
2116+
}
2117+
2118+
ndp120_semgive(dev);
2119+
}

os/drivers/audio/ndp120_voice.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,11 @@ static int ndp120_ioctl(FAR struct audio_lowerhalf_s *dev, int cmd, unsigned lon
725725
ndp120_change_kd(priv);
726726
break;
727727
}
728+
case AUDIOIOC_CHANGEDSPFLOW: {
729+
uint8_t dsp_flow_num = (uint8_t)arg;
730+
ndp120_change_dsp_flow(priv, dsp_flow_num);
731+
break;
732+
}
728733
default:
729734
audvdbg("ndp120_ioctl received unkown cmd 0x%x\n", cmd);
730735
ret = -EINVAL;
@@ -906,7 +911,7 @@ FAR struct audio_lowerhalf_s *ndp120_lowerhalf_initialize(FAR struct spi_dev_s *
906911
int retry = NDP120_INIT_RETRY_COUNT;
907912
while (retry--) {
908913
lower->reset();
909-
ret = ndp120_init(priv, false);
914+
ret = ndp120_init(priv, 0);
910915
if (ret != OK) {
911916
auddbg("ndp120 init failed\n");
912917
} else {

os/drivers/audio/ndp120_voice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct ndp120_dev_s {
8484
bool keyword_correction;
8585
struct pm_domain_s *pm_domain;
8686
uint32_t sample_ready_cnt;
87+
uint8_t cur_dsp_flow_num;
8788

8889
/* moved to using pthread cond variable for parity with reference implementation in ilib examples */
8990
pthread_mutex_t ndp_mutex_mbsync;

os/include/tinyara/audio/audio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
#define AUDIOIOC_GETKDDATA _AUDIOIOC(26)
155155
#define AUDIOIOC_ENABLEDMIC _AUDIOIOC(27)
156156
#define AUDIOIOC_CHANGEKD _AUDIOIOC(28)
157+
#define AUDIOIOC_CHANGEDSPFLOW _AUDIOIOC(29)
157158

158159
/* Audio Device Types *******************************************************/
159160
/* The audio interface support different types of audio devices for

0 commit comments

Comments
 (0)