diff --git a/TODO.md b/TODO.md index aebb00b..0a08127 100644 --- a/TODO.md +++ b/TODO.md @@ -5,8 +5,8 @@ ------------------------------------------------------------------- - -7. 将aiui的配置,设备ID的配置,唤醒词的配置,是否记录语音的配置导出,通过config.hpp进行配置 +6. 完善aiui_service库 OK +7. 将aiui的配置,设备ID的配置,唤醒词的配置,是否记录语音的配置导出,通过config.hpp进行配置 OK 8. 使用最新的黑板进行测试 5. 烧录stm32程序,测试主机和stm32之间的通信 9. 重构工程的Cmake文件,和iflytool.sh文件 @@ -22,6 +22,4 @@ 14. 设备ID 15. 尝试加入降噪,AGC功能。 -------------------------------------------------------------------- - - +------------------------------------------------------------------- \ No newline at end of file diff --git a/dep/zlinuxcomponents b/dep/zlinuxcomponents index 938de99..6fc40ee 160000 --- a/dep/zlinuxcomponents +++ b/dep/zlinuxcomponents @@ -1 +1 @@ -Subproject commit 938de9936e25f18ce7e07906dfc1bb9937ad231f +Subproject commit 6fc40ee9db4094c2994c74aba684fe8577d2be2a diff --git a/src/configs/zconfig.hpp b/src/configs/zconfig.hpp index fd60fee..7d85994 100644 --- a/src/configs/zconfig.hpp +++ b/src/configs/zconfig.hpp @@ -14,13 +14,24 @@ #include "iflytopcpp/core/components/config_template/config_template.hpp" -#define ConfigELEMENT_LIST(marco) \ - /**/ \ - marco(string /* */, deviceId, "") /**/ \ - marco(string /* */, lightControlMode, "auto") /*照明灯控制模式 auto/manual*/ \ - marco(int /* */, lightAutoOpenHour, 18) /**/ \ - marco(int /* */, lightAutoOpenMin, 0) /**/ \ - marco(int /* */, lightAutoCloseHour, 6) /**/ \ +#define ConfigELEMENT_LIST(marco) \ + marco(string /* */, deviceId, "") /*录音设备配置*/ \ + marco(string /* */, recoder_device_name, "recorder") /*录音设备配置*/ \ + marco(int /* */, recoder_ch_number, 5) /*录音设备配置*/ \ + marco(int /* */, recoder_sample_rate, 16000) /*录音设备配置*/ \ + marco(int /* */, recoder_period_time_ms, 50) /*录音设备配置*/ \ + marco(string /* */, wakeup_module_path, "./precise/precise-engine") /*唤醒词配置*/ \ + marco(string /* */, wakeup_lib_module, "xiaomaoxiaomao/xiaomaoxiaomao.pb") /*唤醒词配置*/ \ + marco(string /* */, wakeup_chunk_length, "1600") /*唤醒词配置,对应50ms*/ \ + marco(bool /* */, voice_logger_enable, true) /*是否记录语音配置*/ \ + marco(string /* */, aiui_appid, "5938b7c7") /*唤醒词配置,对应50ms*/ \ + marco(string /* */, aiui_appkey, "19c1f7becc78eedc7826b485aabe30de") /*唤醒词配置,对应50ms*/ \ + marco(string /* */, aiui_auth_id, "") /*唤醒词配置,对应50ms*/ \ + marco(string /* */, aiui_scene, "main_box") /*唤醒词配置,对应50ms*/ \ + marco(string /* */, lightControlMode, "auto") /*照明灯控制模式 auto/manual*/ \ + marco(int /* */, lightAutoOpenHour, 18) /**/ \ + marco(int /* */, lightAutoOpenMin, 0) /**/ \ + marco(int /* */, lightAutoCloseHour, 6) /**/ \ marco(int /* */, lightAutoCloseMin, 0) /**/ configTemplateDEFILE_CONFIG_SERVICE2( // diff --git a/src/main.cpp b/src/main.cpp index a548b6a..a4bf48e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -132,13 +132,20 @@ void Main::buildVoiceProcessService() { * @brief 音频处理相关组建初始化 */ + auto config = GET_SERVICE(ZConfig); + // AudioLoggingService BUILD_AND_REG_SERRVICE(AudioLoggingService); - GET_SERVICE(AudioLoggingService)->initialize(); + GET_SERVICE(AudioLoggingService)->initialize(config->get_voice_logger_enable()); // 音频采集 BUILD_AND_REG_SERRVICE(AudioRecoderService); - GET_SERVICE(AudioRecoderService)->initialize("recorder", 5, 16000, SND_PCM_FORMAT_S16_LE); + GET_SERVICE(AudioRecoderService) + ->initialize(config->get_recoder_device_name().c_str(), // + config->get_recoder_ch_number(), // + config->get_recoder_sample_rate(), // + SND_PCM_FORMAT_S16_LE, // + config->get_recoder_period_time_ms()); // BfWakeupVProcesser BUILD_AND_REG_SERRVICE(BfWakeupVProcesser); @@ -150,24 +157,31 @@ void Main::buildVoiceProcessService() { // WakeupProcesser BUILD_AND_REG_SERRVICE(WakeupProcesser); - GET_SERVICE(WakeupProcesser)->initialize("./precise/precise-engine", "xiaomaoxiaomao/xiaomaoxiaomao.pb", "1600"); + GET_SERVICE(WakeupProcesser) + ->initialize(config->get_wakeup_lib_module(), // + config->get_wakeup_module_path(), // + config->get_wakeup_chunk_length()); // AsrProcesser - const char *appid = "5938b7c7"; // 应用ID,在AIUI开放平台创建并设置 - const char *key = "19c1f7becc78eedc7826b485aabe30de"; // 接口密钥,在AIUI开放平台查看 + const char *appid = config->get_aiui_appid().c_str(); + const char *appkey = config->get_aiui_appkey().c_str(); json paramj; paramj["result_level"] = "plain"; - paramj["auth_id"] = "ac30105366ea460f9ff08ddac0c4f71e"; //相当于设备ID,设备唯一 + paramj["auth_id"] = config->get_aiui_auth_id(); paramj["data_type"] = "audio"; paramj["aue"] = "raw"; paramj["vad_info"] = "end"; paramj["cloud_vad_eos"] = "700"; paramj["close_delay"] = "200"; - paramj["scene"] = "main_box"; + paramj["scene"] = config->get_aiui_scene(); paramj["sample_rate"] = "16000"; paramj["context"] = R"({"sdk_support":["nlp","tts","vad","iat"]})"; BUILD_AND_REG_SERRVICE(AiuiService); - GET_SERVICE(AiuiService)->initialize(appid, key, paramj.dump()); + + logger->info("appid {}", appid); + logger->info("param {}", paramj.dump(0)); + + GET_SERVICE(AiuiService)->initialize(appid, appkey, paramj.dump()); } int Main::main(int argc, char *argv[]) { diff --git a/src/service/voiceprocess/audio_logging_service.cpp b/src/service/voiceprocess/audio_logging_service.cpp index b623376..6ec6988 100644 --- a/src/service/voiceprocess/audio_logging_service.cpp +++ b/src/service/voiceprocess/audio_logging_service.cpp @@ -21,6 +21,35 @@ static string gettimestamp() { return fmt::format("{:0>4}{:0>2}{:0>2}{:0>2}{:0>2}{:0>2}", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } + +AudioLoggingService::WavRecorder::WavRecorder(string filename) { + m_file.open(filename, ios::binary | ios::trunc); + m_filename = filename; +} +void AudioLoggingService::WavRecorder::writeHeader(uint32_t sample_rate, uint16_t bits_per_sample, + uint16_t num_channels, uint32_t num_samples) { + wavHeader.initialize(sample_rate, bits_per_sample, num_channels, 0); + m_file.write((char*)wavHeader.data(), wavHeader.size()); +} +void AudioLoggingService::WavRecorder::dumpheader(logger_t logger) { wavHeader.dump(logger); } +void AudioLoggingService::WavRecorder::writeVoice(shared_ptr audioClip) { + if (!audioClip) return; + m_durationMS += audioClip->getAudioDurationMs(); + m_totalsize += audioClip->size(); + + // 写入音频文件 + m_file.seekp(0, ios::end); + m_file.write((char*)audioClip->data(), audioClip->size()); + + // 更新wav头 + wavHeader.resize(m_totalsize); + m_file.seekp(4, ios::beg); + m_file.write((char*)&wavHeader.header.chunk_size, 4); + m_file.seekp(40, ios::beg); + m_file.write((char*)&wavHeader.header.subchunk2_size, 4); +} +string AudioLoggingService::WavRecorder::getFilename() { return m_filename; } + void AudioLoggingService::cleanupLogVoiceByTime(string prefix, size_t maxnum) { vector files; LinuxCoreUtils().ls(fmt::format("ls -1 -trd {}", prefix), files); @@ -32,21 +61,24 @@ void AudioLoggingService::cleanupLogVoiceByTime(string prefix, size_t maxnum) { } } -void AudioLoggingService::initialize() { - FileUtils().makeDirIfNoExist("./voice/rt/"); - FileUtils().makeDirIfNoExist("./voice/wakeup/"); +void AudioLoggingService::initialize(bool enableLogger) { + m_enableLogger = enableLogger; + FileUtils().makeDirIfNoExist("./voicelog/rt/"); + FileUtils().makeDirIfNoExist("./voicelog/wakeup/"); } void AudioLoggingService::loggerMICVoice(shared_ptr audioClip) { + if (!m_enableLogger) return; /** * @brief MIC的语音会存储在两个地方 - * 1. ./voice/rt/mic_voice_*.wav - * 2. ./voice/wakeup/mic_voice_*.wav + * 1. ./voicelog/rt/mic_voice_*.wav + * 2. ./voicelog/wakeup/mic_voice_*.wav * */ if (!m_rtMicVoiceFile) { - cleanupLogVoiceByTime("./voice/rt/mic_voice_*.wav", RT_STORAGE_CLIP_NUMS); - m_rtMicVoiceFile.reset(new WavRecorder("./voice/rt/mic_voice_" + gettimestamp() + ".wav")); + cleanupLogVoiceByTime("./voicelog/rt/mic_voice_*.wav", RT_STORAGE_CLIP_NUMS); + m_rtMicVoiceFile.reset(new WavRecorder("./voicelog/rt/mic_voice_" + gettimestamp() + ".wav")); + logger->info("create new rt mic voice file: {}", m_rtMicVoiceFile->m_filename); m_rtMicVoiceFile->writeHeader(audioClip->getRate(), audioClip->getBitsPerSample(), audioClip->getCh(), 0); m_rtMicVoiceFile->writeVoice(audioClip); } else { @@ -63,8 +95,8 @@ void AudioLoggingService::loggerMICVoice(shared_ptr audioClip) { lock_guard lock(m_mutex); if (m_wakeupState) { if (!m_wakeupMicVoiceFile) { - cleanupLogVoiceByTime("./voice/wakeup/mic_voice_*.wav", WAKEUP_STORAGE_CLIP_NUMS); - m_wakeupMicVoiceFile.reset(new WavRecorder("./voice/wakeup/mic_voice_" + m_wakeupsessionid + ".wav")); + cleanupLogVoiceByTime("./voicelog/wakeup/mic_voice_*.wav", WAKEUP_STORAGE_CLIP_NUMS); + m_wakeupMicVoiceFile.reset(new WavRecorder("./voicelog/wakeup/mic_voice_" + m_wakeupsessionid + ".wav")); m_wakeupMicVoiceFile->writeHeader(audioClip->getRate(), audioClip->getBitsPerSample(), audioClip->getCh(), 0); m_wakeupMicVoiceFile->writeVoice(audioClip); } else { @@ -97,13 +129,14 @@ void AudioLoggingService::endwakeup() { * @param audioClip */ void AudioLoggingService::loggerBeforeWakeupVoice(shared_ptr audioClip) { + if (!m_enableLogger) return; /** * @brief - * 1. ./voice/rt/beforewakeup*.wav + * 1. ./voicelog/rt/beforewakeup*.wav */ if (!m_rtBfwakeupVoiceFile) { - cleanupLogVoiceByTime("./voice/rt/rtbfwakeup*.wav", RT_STORAGE_CLIP_NUMS); - m_rtBfwakeupVoiceFile.reset(new WavRecorder("./voice/rt/rtbfwakeup" + gettimestamp() + ".wav")); + cleanupLogVoiceByTime("./voicelog/rt/rtbfwakeup*.wav", RT_STORAGE_CLIP_NUMS); + m_rtBfwakeupVoiceFile.reset(new WavRecorder("./voicelog/rt/rtbfwakeup" + gettimestamp() + ".wav")); m_rtBfwakeupVoiceFile->writeHeader(audioClip->getRate(), audioClip->getBitsPerSample(), audioClip->getCh(), 0); m_rtBfwakeupVoiceFile->writeVoice(audioClip); } else { @@ -120,15 +153,16 @@ void AudioLoggingService::loggerBeforeWakeupVoice(shared_ptr audioCli * @param audioClip */ void AudioLoggingService::loggerASRVoice(shared_ptr audioClip) { + if (!m_enableLogger) return; /** * @brief - * ./voice/wakeup/asr*.wav + * ./voicelog/wakeup/asr*.wav */ lock_guard lock(m_mutex); if (!m_wakeupState) return; if (!m_asrFile) { - cleanupLogVoiceByTime("./voice/wakeup/asr*.wav", WAKEUP_STORAGE_CLIP_NUMS); - m_asrFile.reset(new WavRecorder("./voice/wakeup/asr" + m_wakeupsessionid + ".wav")); + cleanupLogVoiceByTime("./voicelog/wakeup/asr*.wav", WAKEUP_STORAGE_CLIP_NUMS); + m_asrFile.reset(new WavRecorder("./voicelog/wakeup/asr" + m_wakeupsessionid + ".wav")); m_asrFile->writeHeader(audioClip->getRate(), audioClip->getBitsPerSample(), audioClip->getCh(), 0); m_asrFile->writeVoice(audioClip); } else { diff --git a/src/service/voiceprocess/audio_logging_service.hpp b/src/service/voiceprocess/audio_logging_service.hpp index da6260a..92d08e0 100644 --- a/src/service/voiceprocess/audio_logging_service.hpp +++ b/src/service/voiceprocess/audio_logging_service.hpp @@ -61,28 +61,14 @@ class AudioLoggingService : public enable_shared_from_this uint32_t m_totalsize; WAVHeader wavHeader; - WavRecorder(string filename) { m_file.open(filename, ios::binary | ios::trunc); } - void writeHeader(uint32_t sample_rate, uint16_t bits_per_sample, uint16_t num_channels, uint32_t num_samples) { - wavHeader.initialize(sample_rate, bits_per_sample, num_channels, 0); - m_file.write((char*)wavHeader.data(), wavHeader.size()); - } - void dumpheader(logger_t logger) { wavHeader.dump(logger); } - void writeVoice(shared_ptr audioClip) { - if (!audioClip) return; - m_durationMS += audioClip->getAudioDurationMs(); - m_totalsize += audioClip->size(); - - // 写入音频文件 - m_file.seekp(0, ios::end); - m_file.write((char*)audioClip->data(), audioClip->size()); - - // 更新wav头 - wavHeader.resize(m_totalsize); - m_file.seekp(4, ios::beg); - m_file.write((char*)&wavHeader.header.chunk_size, 4); - m_file.seekp(40, ios::beg); - m_file.write((char*)&wavHeader.header.subchunk2_size, 4); - } + string m_filename; + + WavRecorder(string filename); + void writeHeader(uint32_t sample_rate, uint16_t bits_per_sample, uint16_t num_channels, uint32_t num_samples); + void dumpheader(logger_t logger); + void writeVoice(shared_ptr audioClip); + + string getFilename(); }; bool m_wakeupState = false; @@ -96,11 +82,12 @@ class AudioLoggingService : public enable_shared_from_this string m_wakeupsessionid; mutex m_mutex; + bool m_enableLogger; public: AudioLoggingService(){}; - void initialize(); + void initialize(bool enableLogger); void loggerMICVoice(shared_ptr audioClip); void loggerBeforeWakeupVoice(shared_ptr audioClip); diff --git a/src/service/voiceprocess/audio_recoder_service.cpp b/src/service/voiceprocess/audio_recoder_service.cpp index c3a8aac..ab33f43 100644 --- a/src/service/voiceprocess/audio_recoder_service.cpp +++ b/src/service/voiceprocess/audio_recoder_service.cpp @@ -4,11 +4,11 @@ using namespace std; using namespace iflytop; using namespace core; -// #define TEST +// #define TEST AudioRecoderService::AudioRecoderService() {} void AudioRecoderService::initialize(const char *pcmName, unsigned int channels, unsigned int sample_rate, - snd_pcm_format_t format) { + snd_pcm_format_t format, int rec_period_time_ms) { #ifdef TEST logger->info("In Test Mode"); m_inputFileStream.open("test_in_audio.wav", ios::in | ios::binary); @@ -19,7 +19,7 @@ void AudioRecoderService::initialize(const char *pcmName, unsigned int channels, m_inputFileStream.seekg(44, ios::beg); #else m_audioRecoder = make_shared(); - m_audioRecoder->initialize(pcmName, channels, sample_rate, format); + m_audioRecoder->initialize(pcmName, channels, sample_rate, format, rec_period_time_ms); m_audioRecoder->onRecordData.connect([this](shared_ptr audioclip) { onRecordData(audioclip); }); #endif } diff --git a/src/service/voiceprocess/audio_recoder_service.hpp b/src/service/voiceprocess/audio_recoder_service.hpp index 1adefc6..0548f03 100644 --- a/src/service/voiceprocess/audio_recoder_service.hpp +++ b/src/service/voiceprocess/audio_recoder_service.hpp @@ -22,10 +22,6 @@ * * service: AudioRecoderService * - * 监听事件: - * 依赖状态: - * 依赖服务: - * 作用: * */ @@ -46,7 +42,9 @@ class AudioRecoderService : public enable_shared_from_this public: AudioRecoderService(); - void initialize(const char *pcmName, unsigned int channels, unsigned int sample_rate, snd_pcm_format_t format); + void initialize(const char *pcmName, unsigned int channels, unsigned int sample_rate, + snd_pcm_format_t format, + int rec_period_time_ms); void startRecord(); }; } // namespace iflytop \ No newline at end of file