From 431b2643d3ff419cb7a1b2bcf652a9c9746055d3 Mon Sep 17 00:00:00 2001 From: ZJY <1400329747@qq.com> Date: Fri, 5 Jul 2024 18:10:35 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E7=AC=AC=E4=BA=94=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 9/1 | 0 9/mt | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 9/1 delete mode 100644 9/mt diff --git a/9/1 b/9/1 deleted file mode 100644 index e69de29..0000000 diff --git a/9/mt b/9/mt deleted file mode 100644 index e69de29..0000000 -- Gitee From 8a0717dc0ad3d7a4100dd15d460acedf5d9a48cf Mon Sep 17 00:00:00 2001 From: ZJY <1400329747@qq.com> Date: Fri, 5 Jul 2024 18:13:56 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=AC=AC=E4=BA=94=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wake.c" | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 "9/\347\254\254\344\272\224\346\254\241\344\275\234\344\270\232/wake.c" diff --git "a/9/\347\254\254\344\272\224\346\254\241\344\275\234\344\270\232/wake.c" "b/9/\347\254\254\344\272\224\346\254\241\344\275\234\344\270\232/wake.c" new file mode 100644 index 0000000..bc358b7 --- /dev/null +++ "b/9/\347\254\254\344\272\224\346\254\241\344\275\234\344\270\232/wake.c" @@ -0,0 +1,231 @@ +#include "snowboy/snowboy-detect-c-wrapper.h" +#include +#include +#include +#include "record.h" +#include "stt.h" +#include "config.h" +#include "http.h" + +// 百度云千帆应用ID +char* app_id = "9df5176d-a0ce-43b7-ad6c-805500d625f7"; + +// 创建会话函数 +char* create_conversation(char* authtoken) +{ + char* url = "https://qianfan.baidubce.com/v2/app/conversation"; + char* auth; + asprintf(&auth, "Authorization: Bearer %s", authtoken); + + struct curl_slist* headers = NULL; + headers = curl_slist_append(headers, "Content-Type: application/json;charset=utf-8"); + headers = curl_slist_append(headers, auth); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddStringToObject(obj, "app_id", app_id); + char* json = cJSON_Print(obj); + + size_t size = strlen(json); + char* response = http_post(url, headers, json, &size); + cJSON_Delete(obj); + free(json); + free(auth); + curl_slist_free_all(headers); + + if (!response) { + return NULL; + } + + obj = cJSON_ParseWithLength(response, size); + free(response); + + if (!obj) { + fprintf(stderr, "解析 JSON 失败: [%s]\n", cJSON_GetErrorPtr()); + return NULL; + } + + cJSON* conversation_id = cJSON_GetObjectItem(obj, "conversation_id"); + if (!conversation_id) { + fprintf(stderr, "conversation_id 字段不存在\n"); + cJSON_Delete(obj); + return NULL; + } + + char* retval = strdup(conversation_id->valuestring); + cJSON_Delete(obj); + return retval; +} + +// 调用对话API函数 +char* chat(char* authtoken, char* conv_id, char* query) +{ + char* url = "https://qianfan.baidubce.com/v2/app/conversation/runs"; + char* auth; + asprintf(&auth, "Authorization: Bearer %s", authtoken); + + struct curl_slist* headers = NULL; + headers = curl_slist_append(headers, "Content-Type: application/json;charset=utf-8"); + headers = curl_slist_append(headers, auth); + + cJSON* obj = cJSON_CreateObject(); + cJSON_AddStringToObject(obj, "app_id", app_id); + cJSON_AddStringToObject(obj, "conversation_id", conv_id); + cJSON_AddStringToObject(obj, "query", query); + cJSON_AddBoolToObject(obj, "stream", false); + char* json = cJSON_Print(obj); + + size_t size = strlen(json); + char* response = http_post(url, headers, json, &size); + cJSON_Delete(obj); + free(json); + curl_slist_free_all(headers); + free(auth); + + if (!response) { + return NULL; + } + + obj = cJSON_ParseWithLength(response, size); + free(response); + + if (!obj) { + fprintf(stderr, "解析 JSON 失败: [%s]\n", cJSON_GetErrorPtr()); + return NULL; + } + + cJSON* answer = cJSON_GetObjectItem(obj, "answer"); + if (!answer) { + fprintf(stderr, "answer 字段不存在\n"); + puts(cJSON_Print(obj)); + cJSON_Delete(obj); + return NULL; + } + + char* retval = strdup(answer->valuestring); + cJSON_Delete(obj); + return retval; +} + +int main() +{ + // 读取配置文件中的平台密钥 + cJSON* config = read_config("config.json"); + if (!config) { + return EXIT_FAILURE; + } + + cJSON* authtoken = cJSON_GetObjectItem(config, "authtoken"); + if (!authtoken) { + fprintf(stderr, "配置文件错误: 找不到 'authtoken' 字段\n"); + cJSON_Delete(config); + return EXIT_FAILURE; + } + + printf("%s\n", authtoken->valuestring); + + // 创建百度云千帆会话 + char* conv_id = create_conversation(authtoken->valuestring); + printf("conv_id: %s\n", conv_id); + + // 创建 Snowboy 检测器 + SnowboyDetect* detector = SnowboyDetectConstructor("common.res", "1.pmdl"); + if (!detector) { + return EXIT_FAILURE; + } + SnowboyDetectSetSensitivity(detector, "0.5"); + + int bits = SnowboyDetectBitsPerSample(detector); + int channels = SnowboyDetectNumChannels(detector); + int rate = SnowboyDetectSampleRate(detector); + + printf("采样深度: %d\n", bits); + printf("声道数量: %d\n", channels); + printf("采样频率: %d\n", rate); + + // 打开音频采集设备 + snd_pcm_uframes_t period = 999; + snd_pcm_t* capture = record_open("hw:0,0", SND_PCM_FORMAT_S16_LE, channels, rate, &period); + if (!capture) { + return EXIT_FAILURE; + } + + char* buffer = malloc(snd_pcm_frames_to_bytes(capture, period)); + if (!buffer) { + perror("malloc"); + record_close(capture); + SnowboyDetectDestructor(detector); + return EXIT_FAILURE; + } + + int recording = 0; + int silence = 0; + FILE* memstream = NULL; + char* audio = NULL; + size_t audio_size = 0; + + while (1) + { + snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); + if (frames < 0) { + fprintf(stderr, "Error from read: %s\n", snd_strerror(frames)); + snd_pcm_recover(capture, frames, 0); + continue; + } + + int status = SnowboyDetectRunDetection(detector, (int16_t*)buffer, snd_pcm_frames_to_bytes(capture, frames) / sizeof(int16_t), 0); + if (status > 0) { + printf("检测到唤醒词,开始录音\n"); + recording = 1; + memstream = open_memstream(&audio, &audio_size); + if (!memstream) { + perror("open_memstream"); + continue; + } + } + + if (recording) { + if (status == -2) { + silence++; + } + if (status == 0) { + silence = 0; + } + if (silence > 32) { + printf("停止录音\n"); + recording = 0; + silence = 0; + if (memstream) { + fclose(memstream); + memstream = NULL; + } + if (audio_size) { + snd_pcm_drop(capture); + char* text = speech_to_text(audio, audio_size); + if (text) { + printf("用户输入: %s\n", text); + char* answer = chat(authtoken->valuestring, conv_id, text); + if (answer) { + printf("应用回答: %s\n", answer); + free(answer); + } + free(text); + } + snd_pcm_prepare(capture); + } + free(audio); + audio = NULL; + audio_size = 0; + } + if (memstream) { + fwrite(buffer, 1, snd_pcm_frames_to_bytes(capture, frames), memstream); + } + } + } + + free(buffer); + record_close(capture); + SnowboyDetectDestructor(detector); + cJSON_Delete(config); + + return EXIT_SUCCESS; +} -- Gitee