diff --git a/cmakepc.cmake b/cmakepc.cmake index 34901a3..90d0192 100644 --- a/cmakepc.cmake +++ b/cmakepc.cmake @@ -59,8 +59,8 @@ zadd_executable_simple(TARGET alsaplayer_main.out SRC dep/zlinuxcomponents/alsaplayer/alsaplayer_main.cpp) zadd_executable_simple(TARGET audio_recorder_main.out SRC dep/zlinuxcomponents/audio/audio_recorder_main.cpp) -zadd_executable_simple( - TARGET test_asr_main.out SRC src/service/voiceprocess/asr_service.cpp - src/test_asr_main.cpp) zadd_executable_simple(TARGET aiui_main.out SRC dep/zlinuxcomponents/aiui_ws/aiui_main.c) +# test_aiui_service.out +zadd_executable_simple(TARGET test_aiui_service.out SRC + src/test_aiui_service.cpp) diff --git a/dep/zlinuxcomponents b/dep/zlinuxcomponents index 2344b60..a72b77a 160000 --- a/dep/zlinuxcomponents +++ b/dep/zlinuxcomponents @@ -1 +1 @@ -Subproject commit 2344b60385743afbe743660579ee72e8e9760552 +Subproject commit a72b77a07bfe7c79abaf603998d98c63a18a7328 diff --git a/src/service/voiceprocess/asr_service.cpp b/src/service/voiceprocess/asr_service.cpp deleted file mode 100644 index eeca9d4..0000000 --- a/src/service/voiceprocess/asr_service.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "asr_service.hpp" - -#include "iflytopcpp/core/components/audio/wavheader.hpp" -#include "zlinuxcomponents/aiui_ws/aiui.h" -using namespace iflytop; -using namespace core; -using namespace std; - -static AiuiService *thisClass = nullptr; -static string getTTSFileName() { - static int i = 0; - i++; - if (i > 10) i = 0; - return fmt::format("/tmp/aiui_service_tts{}.wav", i); -} - -/** - * aiui的识别结果返回大致如下,先返回一个nlp识别结果的包,然后再返回多个包含tts音频数据的json包 - * nlp->tts0->tts1->...->ttsn - * 1. 通过json["data"]["sub"]来判断是什么包,sub的值有:nlp,tts - * 2. 通过json["data"]["is_last"]判断是否是当前种类的最后一包. - * 3. 通过json["data"]["is_finish"]判断是否是本次传输的最后一包 - * - */ -extern "C" { -extern size_t aiui_base64_decode(char *source, unsigned char *target, size_t targetlen); -} -void aiui_message_cb(const char *data, int len) { - if (thisClass) { - thisClass->call_aiui_message_cb(data, len); - } -} -void aiui_error_cb(int code, const char *str) { - if (thisClass) { - thisClass->call_aiui_error_cb(code, str); - } -} -AiuiService::AiuiService() { thisClass = this; } -int AiuiService::aiuiInit(const char *appid, const char *key, const char *param) { - thisClass = this; - return aiui_init(appid, key, param, aiui_message_cb, aiui_error_cb); -} -int AiuiService::aiuiWrite(const char *audio, int len) { return aiui_write(audio, len); } -int AiuiService::aiuiFinished() { return aiui_finished(); } -void AiuiService::aiuiDestroy() { - aiui_destroy(); - thisClass = nullptr; -} -void AiuiService::parseTTSContent(json &rxjson) { - if (!oneAsrResultTransmition) { - logger->error("oneAsrResultTransmition is null"); - return; - } - /** - * @brief 解码base64数据,并保存起来 - */ - string base64Data = rxjson["data"]["content"].get(); - size_t size = base64Data.size() * 3 / 4 + 50; - shared_ptr binary = make_shared(size); - size_t realsize = aiui_base64_decode((char *)base64Data.c_str(), binary->data(), size); - binary->resize(realsize); - oneAsrResultTransmition->ttsRawData.push_back(binary); -} - -void AiuiService::endOneAsrResultTransmition() { - /** - * @brief 如果是最后一包,则将接收到的tts保存成文件,然后同nlp结果打包在一起,然后上报。 - */ - string ttsFileName = getTTSFileName(); - FILE *fp = fopen(ttsFileName.c_str(), "wb"); - size_t ttsframetotalsize = 0; - for (auto &binary : oneAsrResultTransmition->ttsRawData) { - ttsframetotalsize += binary->size(); - } - WAVHeader wavHeader(16000, 16, 1, ttsframetotalsize / 2); - if (fp) { - fwrite(wavHeader.data(), 1, wavHeader.size(), fp); - for (auto &binary : oneAsrResultTransmition->ttsRawData) { - fwrite(binary->data(), 1, binary->size(), fp); - ttsframetotalsize += binary->size(); - } - fclose(fp); - } - oneAsrResultTransmition->asrResult["data"]["intent"]["answer"]["ttsurl"] = ttsFileName; - /** - * @brief 上报识别结果 - */ - onAsrResult(oneAsrResultTransmition->asrResult); - oneAsrResultTransmition.reset(); -} - -void AiuiService::call_aiui_message_cb(const char *data, int len) { - try { - if (!oneAsrResultTransmition) { - oneAsrResultTransmition = make_unique(); - logger->info("start rx aiui data"); - } - json rxjson = json::parse(data); - if (rxjson["action"].get() != "result") { - return; - } - - /** - * @brief 处理接收到的数据 - */ - if (rxjson["data"]["sub"].get() == "nlp") { - // 解析nlpcontent - oneAsrResultTransmition->asrResult = rxjson; - } else if (rxjson["data"]["sub"].get() == "tts") { - // 解析ttscontent - parseTTSContent(rxjson); - } - /** - * @brief 结束本次接收 - */ - if (rxjson["data"]["is_finish"].get()) { - logger->info("end rx aiui data"); - // will call onAsrResult in this function - endOneAsrResultTransmition(); - } - } catch (const std::exception &e) { - logger->error("AiuiService::call_aiui_message_cb error: {}", e.what()); - } -} -void AiuiService::call_aiui_error_cb(int code, const char *str) { - logger->error("AiuiService::call_aiui_error_cb error: {} => {}", code, str); - onError(code, str); -} \ No newline at end of file diff --git a/src/service/voiceprocess/asr_service.hpp b/src/service/voiceprocess/asr_service.hpp deleted file mode 100644 index 4e0e206..0000000 --- a/src/service/voiceprocess/asr_service.hpp +++ /dev/null @@ -1,90 +0,0 @@ -// -// Created by zwsd -// - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iflytopcpp/core/basic/ds/binary.hpp" -#include "iflytopcpp/core/basic/nlohmann/json.hpp" -#include "iflytopcpp/core/basic/nod/nod.hpp" -#include "iflytopcpp/core/spdlogfactory/logger.hpp" -#include "iflytopcpp/core/thread/thread.hpp" - -/** - * @brief - * - * service: AsrService - * - * 监听事件: - * 依赖状态: - * 依赖服务: - * 作用: - * - */ - -namespace iflytop { -using namespace std; -using namespace core; -using namespace nlohmann; - -class OneAsrResultTransmition { - public: - json asrResult; - list ttsResult; - list> ttsRawData; -}; - -class AiuiService : public enable_shared_from_this { - ENABLE_LOGGER(AiuiService); - - bool transFinished = false; - unique_ptr oneAsrResultTransmition; - - public: - nod::signal onAsrResult; - nod::signal onError; - - AiuiService(); - - int aiuiInit(const char *appid, const char *key, const char *param); - int aiuiWrite(const char *audio, int len); - int aiuiFinished(); - void aiuiDestroy(); - - void call_aiui_message_cb(const char *data, int len); - void call_aiui_error_cb(int code, const char *str); - - private: - void parseTTSContent(json &rxjson); - void endOneAsrResultTransmition(); -}; - -class AsrService : public enable_shared_from_this { - ENABLE_LOGGER(AsrService); - - public: - nod::signal onAsrResult; - nod::signal onVoiceEnd; - - private: - // - public: - AsrService(){}; - - void initialize(string appid, string key); - void startRequest(); - void endRequest(); - void writeVoice(uint16_t *voice, size_t voiceLen); - void writeVoice(string text); - void writeVoiceEnd(); -}; -} // namespace iflytop \ No newline at end of file diff --git a/src/test_aiui_service.cpp b/src/test_aiui_service.cpp new file mode 100644 index 0000000..9d9ae0c --- /dev/null +++ b/src/test_aiui_service.cpp @@ -0,0 +1,108 @@ +#include "zlinuxcomponents/zmainhelper.hpp" +// +#include "configs/config.hpp" +#include "iflytopcpp/core/spdlogfactory/logger.hpp" +#include "iflytopcpp/core/thread/thread.hpp" +#include "spdlog/spdlog.h" +#include "version.hpp" +#include "zlinuxcomponents/rootfs_auto_update/rootfs_auto_update.hpp" +#include "zservice_container/zservice_container.hpp" +// +#include "service/device_io_service.hpp" +#include "service/device_io_service_mock.hpp" +#include "service/light_control_service.hpp" +#include "service/report_service.hpp" +#include "zlinuxcomponents/aiui_ws/aiui_service.hpp" + +// +#include "zlinuxcomponents/alsaplayer/AudioPlayerAlsaImpl.hpp" +// #include "zlinuxcomponents/audio/audio_recoder.hpp" +#include + +#include +#include + +#include "zlinuxcomponents/aiui_ws/aiui.h" + +// +using namespace iflytop; +using namespace core; +using namespace std; +using namespace clipp; + +ZMAIN(); +void Main::onSIGINT() { exit(0); } +int Main::main(int argc, char *argv[]) { + string g_host_server_ip; + string g_device_id; + spdlog::flush_on(spdlog::level::debug); + + const char *appid = "5938b7c7"; // 应用ID,在AIUI开放平台创建并设置 + const char *key = "19c1f7becc78eedc7826b485aabe30de"; // 接口密钥,在AIUI开放平台查看 + const char *param = + "{\"result_level\":\"plain\",\"auth_id\":\"ac30105366ea460f9ff08ddac0c4f71e\",\"data_" + "type\":\"text\"," + "\"scene\":\"main_box\",\"sample_rate\":\"16000\", " + "\"context\":\"{\\\"sdk_support\\\":[\\\"nlp\\\",\\\"tts\\\"]}\"}"; + + json paramj; + paramj["result_level"] = "plain"; + paramj["auth_id"] = "ac30105366ea460f9ff08ddac0c4f71e"; + paramj["data_type"] = "text"; + paramj["scene"] = "main_box"; + paramj["sample_rate"] = "16000"; + paramj["context"] = R"({"sdk_support":["nlp","tts","vad","iat"]})"; + // logger->info("{}", paramj.dump()); + // logger->info("{}", param); + + shared_ptr aiuiService(new AiuiService()); + logger->info("test_asr_main.cpp"); + aiuiService->initialize(appid, key, paramj.dump()); + aiuiService->aiuiInit(); + aiuiService->onMessage.connect([&](json &rxjson) { + // + string action = rxjson["action"]; + if (action == "started") { + logger->info("rx started:{}", rxjson.dump()); + } + // + else if (action == "result") { + string sub = rxjson["data"]["sub"]; + if (sub == "nlp") { + logger->info("rx nlp:{}", rxjson.dump()); + } else if (sub == "tts") { + logger->info("rx tts:frame {}", rxjson["data"]["json_args"]["frame_id"].get()); + bool isendFrame = false; + string ttsurl; + aiuiService->parseTTSContent(rxjson, isendFrame, ttsurl); + if (isendFrame) { + logger->info("rx tts end,url={}", ttsurl); + } + } else if (sub == "iat") { + logger->info("rx iat:{}", rxjson.dump()); + } else if (sub == "vad") { + logger->info("rx vad:{}", rxjson.dump()); + } else { + logger->info("rx {}:{}", sub, rxjson.dump()); + } + } + // + else if (action == "error") { + logger->info("rx error:{}", rxjson.dump()); + } + // + else if (action == "vad") { + } else { + logger->info("rx unkown:{}", rxjson.dump()); + } + + try { + if (rxjson["data"]["is_finish"].get()) { + logger->info("end tx"); + } + } catch (...) { + } + }); + aiuiService->aiuiWrite("今天天气怎么样", strlen("今天天气怎么样")); + while (true) sleep(1000); +} diff --git a/src/test_asr_main.cpp b/src/test_asr_main.cpp deleted file mode 100644 index 8d76012..0000000 --- a/src/test_asr_main.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "zlinuxcomponents/zmainhelper.hpp" -// -#include "configs/config.hpp" -#include "iflytopcpp/core/spdlogfactory/logger.hpp" -#include "iflytopcpp/core/thread/thread.hpp" -#include "spdlog/spdlog.h" -#include "version.hpp" -#include "zlinuxcomponents/rootfs_auto_update/rootfs_auto_update.hpp" -#include "zservice_container/zservice_container.hpp" -#include "zwebservice/zwebservice.hpp" -// -#include "service/device_io_service.hpp" -#include "service/device_io_service_mock.hpp" -#include "service/light_control_service.hpp" -#include "service/main_control_service.hpp" -#include "service/report_service.hpp" -#include "service/voiceprocess/asr_service.hpp" -// -#include "zlinuxcomponents/alsaplayer/AudioPlayerAlsaImpl.hpp" -// #include "zlinuxcomponents/audio/audio_recoder.hpp" -#include - -#include -#include - -#include "zlinuxcomponents/aiui_ws/aiui.h" - -// -using namespace iflytop; -using namespace core; -using namespace std; -using namespace clipp; - -ZMAIN(); -/*********************************************************************************************************************** - * =======================================================Main======================================================== * - ***********************************************************************************************************************/ -static void onmessage(const char *data, int len) {} -static void onerror(int code, const char *str) { printf("aiui_init onerror %d => %s\n", code, str); } - -void Main::onSIGINT() { exit(0); } - -int Main::main(int argc, char *argv[]) { - string g_host_server_ip; - string g_device_id; - spdlog::flush_on(spdlog::level::debug); - - const char *appid = "5938b7c7"; // 应用ID,在AIUI开放平台创建并设置 - const char *key = "19c1f7becc78eedc7826b485aabe30de"; // 接口密钥,在AIUI开放平台查看 - const char *param = - "{\"result_level\":\"plain\",\"auth_id\":\"ac30105366ea460f9ff08ddac0c4f71e\",\"data_" - "type\":\"text\"," - "\"scene\":\"main_box\",\"sample_rate\":\"16000\", " - "\"context\":\"{\\\"sdk_support\\\":[\\\"nlp\\\",\\\"tts\\\"]}\"}"; - shared_ptr aiuiService(new AiuiService()); - logger->info("test_asr_main.cpp"); - aiuiService->aiuiInit(appid, key, param); - aiuiService->onAsrResult.connect([this](json j) { - logger->info("onAsrResult: {}", j.dump(2)); - }); - aiuiService->aiuiWrite("今天天气怎么样", strlen("今天天气怎么样")); -// aiuiService->aiuiFinished(); -// aiuiService->aiuiDestroy(); -#if 0 - - - aiui_init(appid, key, param, onmessage, onerror); - - const char *text = "播放音乐"; - - aiui_write(text, strlen(text)); - - aiui_finished(); - - aiui_destroy(); -#endif - - while (true) sleep(1000); -}