From 5a4277dfad7bf7a996df7d5c5c17826d13a4e663 Mon Sep 17 00:00:00 2001 From: mojingtao Date: Tue, 5 Nov 2024 09:52:55 +0800 Subject: [PATCH] second commit --- doubao_chat/apps/wifi_daobao/aduio_record.c | 405 ----------- .../apps/wifi_daobao/aduio_record_queue.c | 385 ---------- doubao_chat/apps/wifi_daobao/chat_http.c | 175 ----- doubao_chat/apps/wifi_daobao/chat_http2.c | 117 --- doubao_chat/apps/wifi_daobao/chat_lwip_http.c | 173 ----- .../apps/wifi_daobao/chat_lwip_http_old.c | 164 ----- .../wifi_daobao/chat_lwip_http_stream_demo.c | 179 ----- doubao_chat/apps/wifi_daobao/stt_websocket.c | 595 ---------------- .../apps/wifi_daobao/stt_websocket_local.c | 664 ------------------ 9 files changed, 2857 deletions(-) delete mode 100644 doubao_chat/apps/wifi_daobao/aduio_record.c delete mode 100644 doubao_chat/apps/wifi_daobao/aduio_record_queue.c delete mode 100644 doubao_chat/apps/wifi_daobao/chat_http.c delete mode 100644 doubao_chat/apps/wifi_daobao/chat_http2.c delete mode 100644 doubao_chat/apps/wifi_daobao/chat_lwip_http.c delete mode 100644 doubao_chat/apps/wifi_daobao/chat_lwip_http_old.c delete mode 100644 doubao_chat/apps/wifi_daobao/chat_lwip_http_stream_demo.c delete mode 100644 doubao_chat/apps/wifi_daobao/stt_websocket.c delete mode 100644 doubao_chat/apps/wifi_daobao/stt_websocket_local.c diff --git a/doubao_chat/apps/wifi_daobao/aduio_record.c b/doubao_chat/apps/wifi_daobao/aduio_record.c deleted file mode 100644 index ddf52dad..00000000 --- a/doubao_chat/apps/wifi_daobao/aduio_record.c +++ /dev/null @@ -1,405 +0,0 @@ -#include "server/audio_server.h" -#include "server/server_core.h" -#include "system/app_core.h" -#include "generic/circular_buf.h" -#include "os/os_api.h" -#include "app_config.h" -#include "system/includes.h" -#include "wifi/wifi_connect.h" -#include "syscfg/syscfg_id.h" -#include "storage_device.h" -#include "fs/fs.h" -#include -#include "aduio_record.h" -#include "device/device.h" -#include "asm/clock.h" - -//#define RECORD -#ifdef RECORD - -//全局变量 -OS_SEM voice_start_sem; -OS_SEM voice_msg_sem; -struct record_message record_msg; - -//静态全局变量 -static struct timer_hdl timer4_hal; - -static const u32 timer_div[] = { - /*0000*/ 1, - /*0001*/ 4, - /*0010*/ 16, - /*0011*/ 64, - /*0100*/ 2, - /*0101*/ 8, - /*0110*/ 32, - /*0111*/ 128, - /*1000*/ 256, - /*1001*/ 4 * 256, - /*1010*/ 16 * 256, - /*1011*/ 64 * 256, - /*1100*/ 2 * 256, - /*1101*/ 8 * 256, - /*1110*/ 32 * 256, - /*1111*/ 128 * 256, -}; - -//静态函数 -static struct record_hdl record_handler; - -#define __this (&record_handler) - -static SEC_USED(.volatile_ram) JL_TIMER_TypeDef *TMR = JL_TIMER4;//选择定时器4 -static SEC_USED(.volatile_ram) u8 timer_irq = IRQ_TIMER4_IDX;//选择定时器4 - -static SEC_USED(.volatile_ram) u32 timer_clk = 0; - -static AWINLINE TSEC void timer_cfg(u32 freq, u32 us) -{ - u8 timer_index[16] = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15}; - u32 timer_table[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; - u32 clock = timer_clk; - u8 psc = 0; - u8 tmp = 0; - u32 prd = 0; - u32 ts = us / (1000 * 1000);//计算秒 - u32 tu = us % (1000 * 1000);//计算秒剩余us - u8 i; - float tp = 0; - - if (freq >= clock) { - freq = clock; - } else if (freq <= 1) { - freq = 1; - if (ts) { - tp = (float)tu / (1000 * 1000); - } - } - /*求prd值*/ - prd = clock / freq; - if (prd > 65535) { - for (psc = 0; psc < 16; psc++) { - prd = (u32)(clock / (timer_table[psc]) / freq); - if (prd <= 65535) { - break; - } else if (psc == 15) { - prd = 65535; - break; - } - } - } - prd = ts ? (prd * ts + tp * prd) : prd; - psc = timer_index[psc]; - TMR->CON = 0; - TMR->CNT = 0; - TMR->CON |= BIT(14); - TMR->PRD = prd; - TMR->CON |= psc << 4; //lsb_clk分频 - TMR->CON |= BIT(0); -} - -static void TSEC timer_set(u32 us)//设置时间,该函数可以在中断调用重新设置定时器值 -{ - u32 freq = 1000000 / us; - timer_cfg(freq, us); -} - -extern void timer4_stop(void); -static ___interrupt TSEC void timer_isr(void)//中断 -{ - if (TMR->CON & BIT(15)) { - TMR->CON |= BIT(14); - //todo,中断函数执行程序... - if(!__this->start_flag){ - __this->end_flag = 1; - printf("---->end\r\n"); - timer4_stop(); - } - } -} - -static void timer4_resume(void) //定时器继续 -{ - if (timer4_hal.run == 0) { - return; - } - u32 prd_cnt; - u8 index; - //precesion = PRD * index / CLK - for (index = 0; index < (sizeof(timer_div) / sizeof(timer_div[0])); index++) { - prd_cnt = timer4_hal.precesion * (APP_TIMER_CLK / 1000) / timer_div[index]; - if (prd_cnt > MIN_TIME_CNT && prd_cnt < MAX_TIME_CNT) { - break; - } - } - - timer4_hal.index = index; - timer4_hal.prd = prd_cnt; - JL_TIMER4->CNT = timer4_hal.ticks; - JL_TIMER4->PRD = prd_cnt; - JL_TIMER4->CON = (index << 4) | BIT(0) | BIT(3); -} - -void timer4_stop(void) //定时器停止 -{ - printf("--->Stop\r\n"); - JL_TIMER4->CON = BIT(14); - timer4_hal.run = 0; - timer4_hal.precesion = 0; -} - - - -void timer4_run(u32 precesion) //定时器开始 -{ - if (timer4_hal.precesion == precesion) { - return; - } - printf("-->Run %d\r\n", precesion); - JL_TIMER4->CON = BIT(14); - timer4_hal.precesion = precesion; - timer4_hal.run = 1; - timer4_hal.ticks = 0; - timer4_resume(); -} - - -//编码器输出MP3数据 -static int record_vfs_fwrite(void *file, void *data, u32 len) -{ - static u8 *recognition_buffer = NULL; - static u32 buffer_filled = 0; - - if (!recognition_buffer) { - recognition_buffer = malloc(SPEECH_RECOGNITION_BUFFER_SIZE); - if (!recognition_buffer) { - log_e("Failed to allocate recognition buffer\n"); - return 0; - } - } - // 将新数据添加到缓冲区 - if (buffer_filled + len <= SPEECH_RECOGNITION_BUFFER_SIZE) { - memcpy(recognition_buffer + buffer_filled, data, len); - buffer_filled += len; - } else { - // 改变全局变量,发送信号量 - record_msg.msg = recognition_buffer; - record_msg.msg_size = buffer_filled; - if(__this->end_flag){ - __this->end_flag = 0; - record_msg.end = 1; - os_sem_post(&__this->stop_sem); - } - else - record_msg.end = 0; - //发送信号量 - if(__this->start_flag||record_msg.end){ - os_sem_post(&voice_msg_sem); - } - - if(__this->stop_flag){ - __this->start_flag = 0; - __this->stop_flag = 0; - } - - // 重置缓冲区 - buffer_filled = 0; - memcpy(recognition_buffer, data, len); - buffer_filled = len; - } - return len; -} - -//解码器读取MP3数据 -static int record_vfs_fread(void *file, void *data, u32 len) -{ - return len; -} - -static int record_vfs_fclose(void *file) -{ - return 0; -} - -static int record_vfs_flen(void *file) -{ - return 0; -} - -static const struct audio_vfs_ops record_vfs_ops = { - .fwrite = record_vfs_fwrite, - .fread = record_vfs_fread, - .fclose = record_vfs_fclose, - .flen = record_vfs_flen, -}; - -static int record_close(void) -{ - union audio_req req = {0}; - - log_d("----------record close----------\n"); - - if (__this->enc_server) { - req.enc.cmd = AUDIO_ENC_CLOSE; - server_request(__this->enc_server, AUDIO_REQ_ENC, &req); - } - - return 0; -} - -static void enc_server_event_handler(void *priv, int argc, int *argv) -{ - switch (argv[0]) { - case AUDIO_SERVER_EVENT_ERR: - case AUDIO_SERVER_EVENT_END: - record_close(); - break; - case AUDIO_SERVER_EVENT_SPEAK_START: - log_i("speak start ! \n"); - __this->start_flag = 1; - __this->end_flag = 0; - os_sem_post(&voice_start_sem); - timer_set(2000 * 1000); - timer4_stop(); - break; - case AUDIO_SERVER_EVENT_SPEAK_STOP: - log_i("speak stop ! \n"); - __this->stop_flag = 1; - timer4_run(2000); - break; - default: - break; - } -} - -static int encoder_init(int sample_rate, u8 channel) -{ - int err; - union audio_req req = {0}; - - log_d("----------encoder_init----------\n"); - - if (channel > 2) { - channel = 2; - } - - os_sem_create(&__this->stop_sem, 0); - os_sem_create(&voice_msg_sem, 0); - os_sem_create(&voice_start_sem, 0); - - __this->start_flag = 0; - __this->stop_flag = 0; - __this->end_flag = 0; - - /****************初始化编码器*******************/ - memset(&req, 0, sizeof(union audio_req)); - - //BIT(x)用来区分上层需要获取哪个通道的数据 - if (channel == 2) { - req.enc.channel_bit_map = BIT(CONFIG_AUDIO_ADC_CHANNEL_L) | BIT(CONFIG_AUDIO_ADC_CHANNEL_R); - } else { - req.enc.channel_bit_map = BIT(CONFIG_AUDIO_ADC_CHANNEL_L); - } - req.enc.frame_size = sample_rate / 100 * 4 * channel; //收集够多少字节MP3数据就回调一次fwrite - req.enc.output_buf_len = req.enc.frame_size * 3; //底层缓冲buf至少设成3倍frame_size - req.enc.cmd = AUDIO_ENC_OPEN; - req.enc.channel = channel; - req.enc.volume = __this->gain; - req.enc.sample_rate = sample_rate; - req.enc.format = "mp3"; - req.enc.sample_source = __this->sample_source; - req.enc.vfs_ops = &record_vfs_ops; - req.enc.file = NULL; - if (channel == 1 && !strcmp(__this->sample_source, "mic") && (sample_rate == 8000 || sample_rate == 16000)) { - req.enc.use_vad = 1; //打开VAD断句功能 - req.enc.dns_enable = 1; //打开降噪功能 - req.enc.vad_auto_refresh = 1; //VAD自动刷新 - } - - err = server_request(__this->enc_server, AUDIO_REQ_ENC, &req); - if (err) { - return -1; - } - - return 0; -} - -static int record_mode_init(void) -{ - log_i("record_play_main\n"); - - memset(__this, 0, sizeof(struct record_hdl)); - -#ifdef CONFIG_STORE_VOLUME - if (syscfg_read(CFG_MUSIC_VOL, &__this->volume, sizeof(__this->volume)) < 0 || - __this->volume < MIN_VOLUME_VALUE || __this->volume > MAX_VOLUME_VALUE) { - __this->volume = INIT_VOLUME_VALUE; - } -#else - __this->volume = INIT_VOLUME_VALUE; -#endif - if (__this->volume < 0 || __this->volume > MAX_VOLUME_VALUE) { - __this->volume = INIT_VOLUME_VALUE; - } - - __this->sample_source = "mic"; - __this->channel = CONFIG_AUDIO_RECORDER_CHANNEL; - __this->gain = CONFIG_AUDIO_ADC_GAIN; - __this->sample_rate = CONFIG_AUDIO_RECORDER_SAMPLERATE; - - __this->enc_server = server_open("audio_server", "enc"); - server_register_event_handler_to_task(__this->enc_server, NULL, enc_server_event_handler, "app_core"); - - return encoder_init(__this->sample_rate, __this->channel); -} - -static void record_run_task(void){ - - union audio_req req = {0}; - record_mode_init(); - timer_clk = clk_get("timer");//先获取定时器的时钟源 - request_irq(timer_irq, 3, timer_isr, 0);//注册中断函数定和中断优先级 - - while(1){ - //等待信号量 - os_sem_pend(&__this->stop_sem, 0); - //os_time_dly(1000); - req.enc.cmd = AUDIO_ENC_PP; - server_request(__this->enc_server, AUDIO_REQ_ENC, &req); - } - -} - -static void record_run_task_create(void) -{ - thread_fork("record_run_task", 15, 1024 * 3 , 0, NULL, record_run_task, NULL); -} - -static void record_start(void *priv) -{ - enum wifi_sta_connect_state state; - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(500); - } - record_run_task_create(); -} - -static int record_init_task(void) -{ - - if (thread_fork("record_start", 10, 512, 0, NULL, record_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} -late_initcall(record_init_task); - -#endif //RECORD - - - diff --git a/doubao_chat/apps/wifi_daobao/aduio_record_queue.c b/doubao_chat/apps/wifi_daobao/aduio_record_queue.c deleted file mode 100644 index 860bad8b..00000000 --- a/doubao_chat/apps/wifi_daobao/aduio_record_queue.c +++ /dev/null @@ -1,385 +0,0 @@ -#include "aduio_record.h" - -//#define RECORD -#ifdef RECORD - -//全局变量 -OS_SEM voice_start_sem; - -//静态全局变量 -static struct timer_hdl timer4_hal; - -static const u32 timer_div[] = { - /*0000*/ 1, - /*0001*/ 4, - /*0010*/ 16, - /*0011*/ 64, - /*0100*/ 2, - /*0101*/ 8, - /*0110*/ 32, - /*0111*/ 128, - /*1000*/ 256, - /*1001*/ 4 * 256, - /*1010*/ 16 * 256, - /*1011*/ 64 * 256, - /*1100*/ 2 * 256, - /*1101*/ 8 * 256, - /*1110*/ 32 * 256, - /*1111*/ 128 * 256, -}; - -//静态函数 -static struct record_hdl record_handler; - -#define __this (&record_handler) - -static SEC_USED(.volatile_ram) JL_TIMER_TypeDef *TMR = JL_TIMER4;//选择定时器4 -static SEC_USED(.volatile_ram) u8 timer_irq = IRQ_TIMER4_IDX;//选择定时器4 - -static SEC_USED(.volatile_ram) u32 timer_clk = 0; - - -static AWINLINE TSEC void timer_cfg(u32 freq, u32 us) -{ - u8 timer_index[16] = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15}; - u32 timer_table[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; - u32 clock = timer_clk; - u8 psc = 0; - u8 tmp = 0; - u32 prd = 0; - u32 ts = us / (1000 * 1000);//计算秒 - u32 tu = us % (1000 * 1000);//计算秒剩余us - u8 i; - float tp = 0; - - if (freq >= clock) { - freq = clock; - } else if (freq <= 1) { - freq = 1; - if (ts) { - tp = (float)tu / (1000 * 1000); - } - } - /*求prd值*/ - prd = clock / freq; - if (prd > 65535) { - for (psc = 0; psc < 16; psc++) { - prd = (u32)(clock / (timer_table[psc]) / freq); - if (prd <= 65535) { - break; - } else if (psc == 15) { - prd = 65535; - break; - } - } - } - prd = ts ? (prd * ts + tp * prd) : prd; - psc = timer_index[psc]; - TMR->CON = 0; - TMR->CNT = 0; - TMR->CON |= BIT(14); - TMR->PRD = prd; - TMR->CON |= psc << 4; //lsb_clk分频 - TMR->CON |= BIT(0); -} - -static void TSEC timer_set(u32 us)//设置时间,该函数可以在中断调用重新设置定时器值 -{ - u32 freq = 1000000 / us; - timer_cfg(freq, us); -} - -extern void timer4_stop(void); -static ___interrupt TSEC void timer_isr(void)//中断 -{ - if (TMR->CON & BIT(15)) { - TMR->CON |= BIT(14); - //todo,中断函数执行程序... - if(!__this->start_flag){ - __this->end_flag = 1; - printf("---->end\r\n"); - timer4_stop(); - } - } -} - -static void timer4_resume(void) //定时器继续 -{ - if (timer4_hal.run == 0) { - return; - } - u32 prd_cnt; - u8 index; - //precesion = PRD * index / CLK - for (index = 0; index < (sizeof(timer_div) / sizeof(timer_div[0])); index++) { - prd_cnt = timer4_hal.precesion * (APP_TIMER_CLK / 1000) / timer_div[index]; - if (prd_cnt > MIN_TIME_CNT && prd_cnt < MAX_TIME_CNT) { - break; - } - } - - timer4_hal.index = index; - timer4_hal.prd = prd_cnt; - JL_TIMER4->CNT = timer4_hal.ticks; - JL_TIMER4->PRD = prd_cnt; - JL_TIMER4->CON = (index << 4) | BIT(0) | BIT(3); -} - -static void timer4_stop(void) //定时器停止 -{ - printf("--->Stop\r\n"); - JL_TIMER4->CON = BIT(14); - timer4_hal.run = 0; - timer4_hal.precesion = 0; -} - - - -static void timer4_run(u32 precesion) //定时器开始 -{ - if (timer4_hal.precesion == precesion) { - return; - } - printf("-->Run %d\r\n", precesion); - JL_TIMER4->CON = BIT(14); - timer4_hal.precesion = precesion; - timer4_hal.run = 1; - timer4_hal.ticks = 0; - timer4_resume(); -} - - -//编码器输出MP3数据 -static int record_vfs_fwrite(void *file, void *data, u32 len) -{ - static u8 *recognition_buffer = NULL; - static u32 buffer_filled = 0; - int argv[4]; - int err; - - if (!recognition_buffer) { - recognition_buffer = malloc(SPEECH_RECOGNITION_BUFFER_SIZE); - if (!recognition_buffer) { - log_e("Failed to allocate recognition buffer\n"); - return 0; - } - } - // 将新数据添加到缓冲区 - if (buffer_filled + len <= SPEECH_RECOGNITION_BUFFER_SIZE) { - memcpy(recognition_buffer + buffer_filled, data, len); - buffer_filled += len; - } else { - rec_msg *qmsg = calloc(1,sizeof(rec_msg)); - memcpy(qmsg->msg,recognition_buffer,buffer_filled); - qmsg->msg_size = buffer_filled; - if(__this->end_flag){ - __this->end_flag = 0; - qmsg->end = 1; - os_sem_post(&__this->stop_sem); - } - else - qmsg->end = 0; - - //发送消息队列 - if(__this->start_flag||qmsg->end){ - argv[0]=(int)qmsg; - err = os_taskq_post_type("websockets_stt_client_main_thread", Q_USER, 4, argv); - if (err == OS_Q_FULL) { - return len; - } - } - - if(__this->stop_flag){ - __this->start_flag = 0; - __this->stop_flag = 0; - } - - // 重置缓冲区 - buffer_filled = 0; - memcpy(recognition_buffer, data, len); - buffer_filled = len; - } - return len; -} - -//解码器读取MP3数据 -static int record_vfs_fread(void *file, void *data, u32 len) -{ - return len; -} - -static int record_vfs_fclose(void *file) -{ - return 0; -} - -static int record_vfs_flen(void *file) -{ - return 0; -} - -static const struct audio_vfs_ops record_vfs_ops = { - .fwrite = record_vfs_fwrite, - .fread = record_vfs_fread, - .fclose = record_vfs_fclose, - .flen = record_vfs_flen, -}; - -static int record_close(void) -{ - union audio_req req = {0}; - - log_d("----------record close----------\n"); - - if (__this->enc_server) { - req.enc.cmd = AUDIO_ENC_CLOSE; - server_request(__this->enc_server, AUDIO_REQ_ENC, &req); - } - - return 0; -} - -static void enc_server_event_handler(void *priv, int argc, int *argv) -{ - switch (argv[0]) { - case AUDIO_SERVER_EVENT_ERR: - case AUDIO_SERVER_EVENT_END: - record_close(); - break; - case AUDIO_SERVER_EVENT_SPEAK_START: - log_i("speak start ! \n"); - __this->start_flag = 1; - __this->end_flag = 0; - os_sem_set(&voice_start_sem,0); - os_sem_post(&voice_start_sem); - timer_set(2000 * 1000); - timer4_stop(); - break; - case AUDIO_SERVER_EVENT_SPEAK_STOP: - log_i("speak stop ! \n"); - __this->stop_flag = 1; - timer4_run(2000); - break; - default: - break; - } -} - -static int encoder_init(int sample_rate, u8 channel) -{ - int err; - union audio_req req = {0}; - - log_d("----------encoder_init----------\n"); - - if (channel > 2) { - channel = 2; - } - - os_sem_create(&__this->stop_sem, 0); - os_sem_create(&voice_start_sem, 0); - - __this->start_flag = 0; - __this->stop_flag = 0; - __this->end_flag = 0; - - /****************初始化编码器*******************/ - memset(&req, 0, sizeof(union audio_req)); - - //BIT(x)用来区分上层需要获取哪个通道的数据 - if (channel == 2) { - req.enc.channel_bit_map = BIT(CONFIG_AUDIO_ADC_CHANNEL_L) | BIT(CONFIG_AUDIO_ADC_CHANNEL_R); - } else { - req.enc.channel_bit_map = BIT(CONFIG_AUDIO_ADC_CHANNEL_L); - } - req.enc.frame_size = sample_rate / 100 * 4 * channel; //收集够多少字节MP3数据就回调一次fwrite - req.enc.output_buf_len = req.enc.frame_size * 3; //底层缓冲buf至少设成3倍frame_size - req.enc.cmd = AUDIO_ENC_OPEN; - req.enc.channel = channel; - req.enc.volume = __this->gain; - req.enc.sample_rate = sample_rate; - req.enc.format = "mp3"; - req.enc.sample_source = __this->sample_source; - req.enc.vfs_ops = &record_vfs_ops; - req.enc.file = NULL; - if (channel == 1 && !strcmp(__this->sample_source, "mic") && (sample_rate == 8000 || sample_rate == 16000)) { - req.enc.use_vad = 1; //打开VAD断句功能 - req.enc.dns_enable = 1; //打开降噪功能 - req.enc.vad_auto_refresh = 1; //VAD自动刷新 - } - - err = server_request(__this->enc_server, AUDIO_REQ_ENC, &req); - if (err) { - return -1; - } - - return 0; -} - -static int record_mode_init(void) -{ - log_i("record_play_main\n"); - - memset(__this, 0, sizeof(struct record_hdl)); - - __this->sample_source = "mic"; - __this->channel = CONFIG_AUDIO_RECORDER_CHANNEL; - __this->gain = CONFIG_AUDIO_ADC_GAIN; - __this->sample_rate = CONFIG_AUDIO_RECORDER_SAMPLERATE; - - __this->enc_server = server_open("audio_server", "enc"); - server_register_event_handler_to_task(__this->enc_server, NULL, enc_server_event_handler, "app_core"); - - return encoder_init(__this->sample_rate, __this->channel); -} - -static void record_run_task(void){ - - union audio_req req = {0}; - record_mode_init(); - timer_clk = clk_get("timer");//先获取定时器的时钟源 - request_irq(timer_irq, 3, timer_isr, 0);//注册中断函数定和中断优先级 - - while(1){ - //等待信号量 - os_sem_pend(&__this->stop_sem, 0); - //os_time_dly(1000); - req.enc.cmd = AUDIO_ENC_PP; - server_request(__this->enc_server, AUDIO_REQ_ENC, &req); - } - -} - -static void record_run_task_create(void) -{ - thread_fork("record_run_task", 15, 1024 * 3 , 0, NULL, record_run_task, NULL); -} - -static void record_start(void *priv) -{ - enum wifi_sta_connect_state state; - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(500); - } - record_run_task_create(); -} -//程序入口 -static int record_init_task(void) -{ - - if (thread_fork("record_start", 10, 512, 0, NULL, record_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} -late_initcall(record_init_task); - -#endif //RECORD - - - diff --git a/doubao_chat/apps/wifi_daobao/chat_http.c b/doubao_chat/apps/wifi_daobao/chat_http.c deleted file mode 100644 index 0c8db1b4..00000000 --- a/doubao_chat/apps/wifi_daobao/chat_http.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - 主要问题是如何接收处理传过来的文字 -*/ -#include "system/includes.h" -#include "wifi/wifi_connect.h" -#include "http/http_cli.h" -#include "app_config.h" - -//#define CHAT -#ifdef CHAT -//选择其中一种进行测试 -//#define HTTP_GET_TEST -#define HTTP_POST_TEST -//#define HTTP_PUT_TEST - -#define HTTP_DEMO_URL "https://ark.cn-beijing.volces.com/api/v3/chat/completions" - -//#define HTTP_DEMO_URL "https://www.baidu.com/search/error.html" - -//#define HTTP_DEMO_URL "https://jsonplaceholder.typicode.com/posts" - -#define HTTP_DEMO_DATA "{\"model\":\"ep-20241010174456-nhgs5\", \"messages\":[{\"role\":\"user\", \"content\":\"我爱你豆包\"}]}" - -//#define HTTP_DEMO_DATA "{\"name\":\"xiao ming\", \"age\":12}" - -//#define HTTP_DEMO_DATA "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}" - - -#define LOG_HTTP_HEAD_OPTION \ - "POST /api/v3/chat/completions HTTP/1.1\r\n"\ - "Host: ark.cn-beijing.volces.com\r\n"\ - "Content-type: application/json\r\n"\ - "Content-length: %d\r\n"\ - "Authorization: Bearer f311cc81-1c5b-42c3-bb8a-1b10d1348080\r\n\r\n" - -//#define LOG_HTTP_HEAD_OPTION \ -// "POST /search/error.html HTTP/1.1\r\n"\ -// "Host: www.baidu.com\r\n"\ -// "Connection: close\r\n"\ -// "Cache-Control: no-store\r\n"\ -// "Content-type: application/json\r\n"\ -// "Content-length: 30\r\n"\ -// "Accept: */*\r\n"\ -// "Accept-Language: zh-CN,zh,q=0.8\r\n"\ -// "Cookie: loginType=hardware; appId=1000000001; deviceSN=A4W0H02B000001; credential=56fb1f8df901f13fea8bf12ac2109c58; randNum=2dcf4629\r\n\r\n" - -//#define LOG_HTTP_HEAD_OPTION \ -// "POST /post HTTP/1.1\r\n"\ -// "Host: jsonplaceholder.typicode.com\r\n"\ -// "Connection: close\r\n"\ -// "Cache-Control: no-store\r\n"\ -// "Content-type: application/json\r\n"\ -// "Content-length: 44\r\n"\ -// "Accept: */*\r\n"\ -// "Accept-Language: zh-CN,zh,q=0.8\r\n\r\n"\ - - -#define USER_HEADER_BUF_SIZE 2 * 1024 - -httpin_error httpcli_put(httpcli_ctx *ctx) -{ - return httpcli_post(ctx); -} - -static void http_test_task(void *priv) -{ - int ret = 0; - http_body_obj http_body_buf; - char *user_header_buf = NULL; - - user_header_buf = calloc(1, USER_HEADER_BUF_SIZE); - if (!user_header_buf) { - printf("calloc faile\n"); - return; - } - - sprintf(user_header_buf, LOG_HTTP_HEAD_OPTION, strlen(HTTP_DEMO_DATA)); - - printf(" . user_header_buf :\r\n%s\r\n",user_header_buf); - - httpcli_ctx *ctx = (httpcli_ctx *)calloc(1, sizeof(httpcli_ctx)); - if (!ctx) { - printf("calloc faile\n"); - return; - } - - memset(&http_body_buf, 0x0, sizeof(http_body_obj)); - - http_body_buf.recv_len = 0; - http_body_buf.buf_len = 4 * 1024; - http_body_buf.buf_count = 1; - http_body_buf.p = (char *) malloc(http_body_buf.buf_len * http_body_buf.buf_count); - if (!http_body_buf.p) { - free(ctx); - return; - } - - ctx->url = HTTP_DEMO_URL; - ctx->timeout_millsec = 5000; - ctx->priv = &http_body_buf; - ctx->connection = "close"; - -// ctx->mode = MODE_HTTPS; - -#if (defined HTTP_POST_TEST) - printf("http post test start\n\n"); - ctx->data_format = "application/json"; - ctx->post_data = HTTP_DEMO_DATA; - ctx->data_len = strlen(HTTP_DEMO_DATA); -// ctx->user_http_header = LOG_HTTP_HEAD_OPTION; //添加该参数, 则自定义申请头部内容 - - ctx->user_http_header = user_header_buf; //添加该参数, 则自定义申请头部内容 - ret = httpcli_post(ctx); -#elif (defined HTTP_GET_TEST) - printf("http get test start\n\n"); - ret = httpcli_get(ctx); -#elif (defined HTTP_PUT_TEST) - printf("http put test start\n\n"); - ret = httpcli_put(ctx); -#endif - - if (ret != HERROR_OK) { - printf("http client test faile\n"); - } else { - if (http_body_buf.recv_len > 0) { - printf("\nReceive %d Bytes from (%s)\n", http_body_buf.recv_len, HTTP_DEMO_URL); - printf("%s\n", http_body_buf.p); - } - } - - //关闭连接 - httpcli_close(ctx); - - if (http_body_buf.p) { - free(http_body_buf.p); - http_body_buf.p = NULL; - } - - if (ctx) { - free(ctx); - ctx = NULL; - } -} - -static void http_test_start(void *priv) -{ - enum wifi_sta_connect_state state; - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(1000); - } - - if (thread_fork("http_test_task", 10, 1024 * 10, 0, NULL, http_test_task, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -//应用程序入口,需要运行在STA模式下 -void c_main(void *priv) -{ - if (thread_fork("http_test_start", 10, 512, 0, NULL, http_test_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -late_initcall(c_main); -#endif //CHAT - - - diff --git a/doubao_chat/apps/wifi_daobao/chat_http2.c b/doubao_chat/apps/wifi_daobao/chat_http2.c deleted file mode 100644 index c0d6b607..00000000 --- a/doubao_chat/apps/wifi_daobao/chat_http2.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - 主要问题是如何接收处理传过来的文字 -*/ -#include "system/includes.h" -#include "wifi/wifi_connect.h" -#include "http/http_cli.h" -#include "app_config.h" - -#define CHAT -#ifdef CHAT -//选择其中一种进行测试 -//#define HTTP_GET_TEST -#define HTTP_POST_TEST -//#define HTTP_PUT_TEST - -#define HTTP_POST_TEST - -#define HTTP_DEMO_URL "http://ark.cn-beijing.volces.com/api/v3/chat/completions" -#define HTTP_DEMO_DATA "{\"model\": \"ep-20240807114601-mvhsx\", \"messages\": [{\"role\": \"system\",\"content\": \"你是豆包,是由字节跳动开发的 AI 人工智能助手.\"},{\"role\": \"user\",\"content\": \"常见的十字花科植物有哪些?\"}]}" - -#define LOG_HTTP_HEAD_OPTION \ - "POST /api/v3/chat/completions HTTP/1.1\r\n"\ - "Host: ark.cn-beijing.volces.com\r\n"\ - "Connection: close\r\n"\ - "Content-Type: application/json\r\n"\ - "Authorization: Bearer 0b559a45-023b-4453-98bd-637daabe257a\r\n"\ - "Content-Length: 256\r\n"\ - "Accept: */*\r\n\r\n" - -static void http_test_task(void *priv) -{ - int ret = 0; - http_body_obj http_body_buf; - httpcli_ctx *ctx = (httpcli_ctx *)calloc(1, sizeof(httpcli_ctx)); - if (!ctx) { - printf("calloc faile\n"); - return; - } - - memset(&http_body_buf, 0x0, sizeof(http_body_obj)); - - http_body_buf.recv_len = 0; - http_body_buf.buf_len = 4 * 1024; - http_body_buf.buf_count = 1; - http_body_buf.p = (char *) malloc(http_body_buf.buf_len * http_body_buf.buf_count); - if (!http_body_buf.p) { - free(ctx); - return; - } - - ctx->url = HTTP_DEMO_URL; - ctx->timeout_millsec = 5000; - ctx->priv = &http_body_buf; - ctx->connection = "close"; - - printf("http post test start\n\n"); - ctx->data_format = "application/json"; - ctx->post_data = HTTP_DEMO_DATA; - ctx->data_len = strlen(HTTP_DEMO_DATA); - ctx->user_http_header = LOG_HTTP_HEAD_OPTION; // 添加自定义头部内容 - ret = httpcli_post(ctx); - - if (ret != HERROR_OK) { - printf("http client test faile\n"); - } else { - if (http_body_buf.recv_len > 0) { - printf("\nReceive %d Bytes from (%s)\n", http_body_buf.recv_len, HTTP_DEMO_URL); - printf("%s\n", http_body_buf.p); - } - } - - //关闭连接 - httpcli_close(ctx); - - if (http_body_buf.p) { - free(http_body_buf.p); - http_body_buf.p = NULL; - } - - if (ctx) { - free(ctx); - ctx = NULL; - } -} - - -static void http_test_start(void *priv) -{ - enum wifi_sta_connect_state state; - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(1000); - } - - if (thread_fork("http_test_task", 10, 1024 * 10, 0, NULL, http_test_task, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -//应用程序入口,需要运行在STA模式下 -void c_main(void *priv) -{ - if (thread_fork("http_test_start", 10, 512, 0, NULL, http_test_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -late_initcall(c_main); -#endif //CHAT - - - diff --git a/doubao_chat/apps/wifi_daobao/chat_lwip_http.c b/doubao_chat/apps/wifi_daobao/chat_lwip_http.c deleted file mode 100644 index 8dc8f8d8..00000000 --- a/doubao_chat/apps/wifi_daobao/chat_lwip_http.c +++ /dev/null @@ -1,173 +0,0 @@ -#include "system/includes.h" -#include "wifi/wifi_connect.h" -#include "apps/http_client.h" -#include "app_config.h" -#include "cJSON.h" - -//#define chat_lwip -#ifdef chat_lwip - -#define HTTP_DEMO_URL "https://ark.cn-beijing.volces.com/api/v3/chat/completions" - -#define HTTP_DEMO_DATA "{\"model\":\"ep-20241018142738-n7wv9\", \"messages\":[{\"role\":\"user\", \"content\":\"豆包,介绍一下上甘岭战役\"}]}" - -#define AUTHORIZATION "Bearer f311cc81-1c5b-42c3-bb8a-1b10d1348080" - -#define BUFFER_SIZE 4096 * 3 - -static char buffer[BUFFER_SIZE]={0}; -static uint16_t total_received = 0; - -extern unsigned char chat_msg[4 * 1024]; - -extern OS_SEM chat_sem; - -static bool is_json_complete(const char *buffer) -{ - // 尝试解析 JSON - cJSON *json = cJSON_Parse(buffer); - if (json) { - cJSON_Delete(json); - return true; - } - return false; -} - -static void process_json(cJSON *json) -{ - // 处理 JSON 数据 - cJSON *choices = cJSON_GetObjectItem(json, "choices"); - if (cJSON_IsArray(choices)) { - int array_size = cJSON_GetArraySize(choices); - for (int i = 0; i < array_size; i++) { - cJSON *choice = cJSON_GetArrayItem(choices, i); - if (cJSON_IsObject(choice)) { - cJSON *message = cJSON_GetObjectItem(choice, "message"); - if (cJSON_IsObject(message)) { - cJSON *content = cJSON_GetObjectItem(message, "content"); - if (cJSON_IsString(content) && content->valuestring != NULL) { - printf("content: %s \r\n", content->valuestring); - } - } - } - } - } -} - -static err_t http_rev_func(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) -{ - LWIP_PLATFORM_DIAG(("this is http_rev_func\r\n")); - - if (err != ERR_OK || p == NULL) { - LWIP_DEBUGF(LWIP_DEBUG, ("http_rev_func: ERR_OK=%d, p=%p\n", err, p)); - return err; - } - - // 将接收到的数据复制到静态缓冲区 - uint16_t len = p->len; - memcpy(buffer + total_received, p->payload, len); - total_received += len; - - printf("payload: %s\r\n",(char *)p->payload); - - // 检查是否接收完整条消息 - if (is_json_complete(buffer)) { - // 处理完整的消息 - cJSON *json = cJSON_Parse(buffer); - if (json) { - process_json(json); - cJSON_Delete(json); - } else { - LWIP_DEBUGF(LWIP_DEBUG, ("Failed to parse JSON\n")); - } - - // 重置状态 - total_received = 0; - memset(buffer,0,sizeof(buffer)); - } - tcp_recved(tpcb, p->len);//通知 lwIP 应用程序已处理了 len 字节的数据,增加接收窗口 - pbuf_free(p); - return ERR_OK; -} - -static void http_chat_task(void *priv) -{ - const char *server_name = "ark.cn-beijing.volces.com"; // 服务器名称 - u16_t port = 80; // 端口 - const char *uri = "/api/v3/chat/completions"; // 请求的 URI - - cJSON *root = cJSON_CreateObject(); - - cJSON_AddStringToObject(root, "model", "ep-20241010174456-nhgs5"); - - cJSON *messages = cJSON_AddArrayToObject(root, "messages"); - - httpc_connection_t setting = { .use_proxy = 0, - .result_fn = NULL, - .headers_done_fn = NULL, - .use_post = 1, - .authorization =AUTHORIZATION, - .arglen = strlen(HTTP_DEMO_DATA), - .args = HTTP_DEMO_DATA - }; - - while(1){ - - os_sem_pend(&chat_sem, 0); - - cJSON *session = cJSON_CreateObject(); - - cJSON_AddStringToObject(session, "role", "user"); - - cJSON_AddStringToObject(session, "content", chat_msg); - - cJSON_AddItemToArray(messages, session); - - char *http_data = cJSON_Print(root); - - cJSON_Delete(root); - - setting.arglen = strlen(http_data); - - setting.args = http_data; - - httpc_get_file_dns(server_name, port, uri, &setting,http_rev_func, NULL, NULL); - - free(http_data); - } - -} - - -static void http_chat_start(void *priv) -{ - enum wifi_sta_connect_state state; - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(1000); - } - - if (thread_fork("http_chat_task", 10, 1024 * 10, 0, NULL, http_chat_task, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } - -} - -//应用程序入口,需要运行在STA模式下 -static int chat_lwip_http(void) -{ - if (thread_fork("http_chat_start", 15, 512, 0, NULL, http_chat_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -late_initcall(chat_lwip_http); -#endif //CHAT - - - diff --git a/doubao_chat/apps/wifi_daobao/chat_lwip_http_old.c b/doubao_chat/apps/wifi_daobao/chat_lwip_http_old.c deleted file mode 100644 index 27fdede4..00000000 --- a/doubao_chat/apps/wifi_daobao/chat_lwip_http_old.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "system/includes.h" -#include "wifi/wifi_connect.h" -#include "apps/http_client.h" -#include "app_config.h" -#include "cJSON.h" - -//#define chat_lwip -#ifdef chat_lwip - -#define HTTP_DEMO_URL "https://ark.cn-beijing.volces.com/api/v3/chat/completions" - -#define HTTP_DEMO_DATA "{\"model\":\"ep-20241018142738-n7wv9\", \"messages\":[{\"role\":\"user\", \"content\":\"讲一个简短的故事\"}]}" - -#define AUTHORIZATION "Bearer f311cc81-1c5b-42c3-bb8a-1b10d1348080" - -#define BUFFER_SIZE 4096 * 3 - -static char buffer[BUFFER_SIZE]={0}; -static uint16_t total_received = 0; - -char *chat_req = NULL; - -OS_SEM tts_sem; - -static OS_SEM demo_sem; - -static bool is_json_complete(const char *buffer) -{ - // 尝试解析 JSON - cJSON *json = cJSON_Parse(buffer); - if (json) { - cJSON_Delete(json); - return true; - } - return false; -} - -static void process_json(cJSON *json) -{ - // 处理 JSON 数据 - cJSON *choices = cJSON_GetObjectItem(json, "choices"); - if (cJSON_IsArray(choices)) { - int array_size = cJSON_GetArraySize(choices); - for (int i = 0; i < array_size; i++) { - cJSON *choice = cJSON_GetArrayItem(choices, i); - if (cJSON_IsObject(choice)) { - cJSON *message = cJSON_GetObjectItem(choice, "message"); - if (cJSON_IsObject(message)) { - cJSON *content = cJSON_GetObjectItem(message, "content"); - if (cJSON_IsString(content) && content->valuestring != NULL) { - printf("content: %s \r\n", content->valuestring); - int content_len=strlen(content->valuestring); - chat_req = calloc(1,content_len); - memcpy(chat_req,content->valuestring,content_len); - if(chat_req!=NULL){ - os_sem_post(&tts_sem); - } - } - } - } - } - } -} - -static err_t http_rev_func(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) -{ - LWIP_PLATFORM_DIAG(("this is http_rev_func\r\n")); - - if (err != ERR_OK || p == NULL) { - LWIP_DEBUGF(LWIP_DEBUG, ("http_rev_func: ERR_OK=%d, p=%p\n", err, p)); - return err; - } - - // 将接收到的数据复制到静态缓冲区 - uint16_t len = p->len; - memcpy(buffer + total_received, p->payload, len); - total_received += len; - - printf("payload: %s\r\n",(char *)p->payload); - - // 检查是否接收完整条消息 - if (is_json_complete(buffer)) { - // 处理完整的消息 - cJSON *json = cJSON_Parse(buffer); - if (json) { - process_json(json); - cJSON_Delete(json); - } else { - LWIP_DEBUGF(LWIP_DEBUG, ("Failed to parse JSON\n")); - } - - // 重置状态 - total_received = 0; - memset(buffer,0,sizeof(buffer)); - } - tcp_recved(tpcb, p->len);//通知 lwIP 应用程序已处理了 len 字节的数据,增加接收窗口 - pbuf_free(p); - return ERR_OK; -} - -static void http_chat_task(void *priv) -{ - const char *server_name = "ark.cn-beijing.volces.com"; // 服务器名称 - u16_t port = 80; // 端口 - const char *uri = "/api/v3/chat/completions"; // 请求的 URI - - cJSON *root = cJSON_CreateObject(); - - cJSON_AddStringToObject(root, "model", "ep-20241010174456-nhgs5"); - - cJSON *messages = cJSON_AddArrayToObject(root, "messages"); - - httpc_connection_t setting = { .use_proxy = 0, - .result_fn = NULL, - .headers_done_fn = NULL, - .use_post = 1, - .authorization =AUTHORIZATION, - .arglen = strlen(HTTP_DEMO_DATA), - .args = HTTP_DEMO_DATA - }; - - while(1){ - os_sem_pend(&demo_sem,0); - - httpc_get_file_dns(server_name, port, uri, &setting,http_rev_func, NULL, NULL); - } - -} - - -static void http_chat_start(void *priv) -{ - enum wifi_sta_connect_state state; - os_sem_create(&tts_sem,0); - os_sem_create(&demo_sem,1); - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(1000); - } - - if (thread_fork("http_chat_task", 10, 1024 * 10, 0, NULL, http_chat_task, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } - -} - -//应用程序入口,需要运行在STA模式下 -static int chat_lwip_http(void) -{ - if (thread_fork("http_chat_start", 15, 512, 0, NULL, http_chat_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -late_initcall(chat_lwip_http); -#endif //CHAT - - - diff --git a/doubao_chat/apps/wifi_daobao/chat_lwip_http_stream_demo.c b/doubao_chat/apps/wifi_daobao/chat_lwip_http_stream_demo.c deleted file mode 100644 index 43012a1a..00000000 --- a/doubao_chat/apps/wifi_daobao/chat_lwip_http_stream_demo.c +++ /dev/null @@ -1,179 +0,0 @@ -#include "system/includes.h" -#include "wifi/wifi_connect.h" -#include "apps/http_client.h" -#include "app_config.h" -#include "cJSON.h" - -//#define chat_lwip_stream -#ifdef chat_lwip_stream - -#define HTTP_DEMO_URL "https://ark.cn-beijing.volces.com/api/v3/chat/completions" - -#define HTTP_DEMO_DATA "{\"model\":\"ep-20241018142738-n7wv9\",\"stream\": true,\"messages\":[{\"role\":\"user\", \"content\":\"写一篇六百字的作文\"}]}" - -#define AUTHORIZATION "Bearer f311cc81-1c5b-42c3-bb8a-1b10d1348080" - -static char buffer[2*1024] = {0}; // 用于存储不完整数据块的缓冲区 -static size_t buffer_len = 0; - -char accumulated_content[10*1024] = {0}; -static size_t accumulated_length = 0; -static size_t add_length = 0; - -static OS_SEM csem; - -OS_SEM tts_sem; - -static void process_sse_chunk(const char *chunk) -{ - int argv[4]; - const char *data_start = strstr(chunk, "data:"); - if (!data_start) { - return; - } - data_start += 5; - while (isspace(*data_start)) data_start++; - - if (strcmp(data_start, "[DONE]") == 0) { - printf("SSE stream ended\r\n"); - printf("answer: %s\r\n",accumulated_content); - } else { - cJSON *json = cJSON_Parse(data_start); - if (json) { - cJSON *choices = cJSON_GetObjectItem(json, "choices"); - if (cJSON_IsArray(choices)) { - cJSON *choice = cJSON_GetArrayItem(choices, 0); - if (cJSON_IsObject(choice)) { - cJSON *delta = cJSON_GetObjectItem(choice, "delta"); - if (cJSON_IsObject(delta)) { - cJSON *content = cJSON_GetObjectItem(delta, "content"); - if (cJSON_IsString(content) && content->valuestring) { - - size_t new_content_length = strlen(content->valuestring); - //printf("Chunk content: %s", content->valuestring); - if (accumulated_length + new_content_length < 10*1024) { - strcat(accumulated_content, content->valuestring); - accumulated_length += new_content_length; - } - add_length+=new_content_length; - if(strcmp(content->valuestring,",")==0||strcmp(content->valuestring,":")==0||strcmp(content->valuestring,":")==0|| - strcmp(content->valuestring,"。")==0||strcmp(content->valuestring,"!")==0||strcmp(content->valuestring,"?")==0|| - strcmp(content->valuestring,";")==0){ - printf("sentence:%s\r\n",accumulated_content+(accumulated_length-add_length)); - argv[0]=accumulated_length; - argv[1]=add_length; - os_sem_set(&tts_sem,0); - os_sem_post(&tts_sem); - os_taskq_post_type("websockets_tts_client_main_thread", Q_USER, 20, argv); - add_length = 0; - } - - } - } - } - } - cJSON_Delete(json); - } - } - -} - -static err_t http_rev_func(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) -{ - //LWIP_PLATFORM_DIAG(("this is http_rev_func\r\n")); - - if (p == NULL) { - // 连接关闭 - LWIP_PLATFORM_DIAG(("this is http_rev_func close\r\n")); - return ERR_OK; - } - - // 将新数据追加到缓冲区 - if (buffer_len + p->len < sizeof(buffer)) { - memcpy(buffer + buffer_len, p->payload, p->len); - buffer_len += p->len; - buffer[buffer_len] = '\0'; - } else { - printf("缓冲区溢出,丢弃数据\r\n"); - } -// printf("buffer: %.*s\r\n", buffer_len, buffer); -// -// printf("buffer_len: %d\r\n",buffer_len); - - // 处理完整的数据块 - char *start = buffer; - char *end; - while ((end = strstr(start, "\n\n")) != NULL) { - *end = '\0'; - process_sse_chunk(start); - start = end + 2; - } - - // 将剩余的不完整数据块移到缓冲区开头 - if (start != buffer) { - buffer_len = strlen(start); - memmove(buffer, start, buffer_len + 1); - } - tcp_recved(tpcb, p->len);//通知 lwIP 应用程序已处理了 len 字节的数据,增加接收窗口 - pbuf_free(p); - return ERR_OK; -} - -static void http_chat_task(void *priv) -{ - const char *server_name = "ark.cn-beijing.volces.com"; // 服务器名称 - u16_t port = 80; // 端口 - const char *uri = "/api/v3/chat/completions"; // 请求的 URI - - httpc_connection_t setting = { .use_proxy = 0, - .result_fn = NULL, - .headers_done_fn = NULL, - .use_post = 1, - .authorization =AUTHORIZATION, - .arglen = strlen(HTTP_DEMO_DATA), - .args = HTTP_DEMO_DATA - }; - - while(1){ - os_sem_pend(&csem,0); - add_length = 0; - httpc_get_file_dns(server_name, port, uri, &setting,http_rev_func, NULL, NULL); - } - -} - - -static void http_chat_start(void *priv) -{ - enum wifi_sta_connect_state state; - os_sem_create(&csem,1); - os_sem_create(&tts_sem,0); - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(1000); - } - - if (thread_fork("http_chat_task", 10, 1024 * 10, 0, NULL, http_chat_task, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } - -} - -//应用程序入口,需要运行在STA模式下 -static int chat_lwip_http(void) -{ - if (thread_fork("http_chat_start", 15, 512, 0, NULL, http_chat_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -late_initcall(chat_lwip_http); -#endif //CHAT - - - diff --git a/doubao_chat/apps/wifi_daobao/stt_websocket.c b/doubao_chat/apps/wifi_daobao/stt_websocket.c deleted file mode 100644 index 9ad83c15..00000000 --- a/doubao_chat/apps/wifi_daobao/stt_websocket.c +++ /dev/null @@ -1,595 +0,0 @@ -#include "web_socket/websocket_api.h" -#include "wifi/wifi_connect.h" -#include "system/includes.h" -#include "fs/fs.h" -#include "asm/sfc_norflash_api.h" -#include "cJSON.h" -#include "aduio_record.h" -#ifdef WEBSOCKET_MEMHEAP_DEBUG -#include "mem_leak_test.h" -#endif - -#include "app_config.h" - -//#define stt -#ifdef stt - -// 定义消息类型常量 -#define SERVER_FULL_RESPONSE 0b1001 -#define SERVER_ACK 0b1011 -#define SERVER_ERROR_RESPONSE 0b1111 - -// 定义压缩和序列化方法常量 -#define GZIP 1 -#define JSON 1 -#define NO_SERIALIZATION 0 - -// 定义响应结构体,用于存储原始响应数据 -typedef struct { - uint8_t protocol_version; - uint8_t header_size; - uint8_t message_type; - uint8_t message_type_specific_flags; - uint8_t serialization_method; - uint8_t message_compression; - uint8_t reserved; - uint8_t* header_extensions; - uint8_t* payload; - size_t payload_size; -} Response; - -// 定义解析后的响应结构体,用于存储处理后的数据 -typedef struct { - unsigned char* payload_msg; - size_t payload_size; -} ParsedResponse; - -typedef struct { - char* appid; - char* cluster; - char* token; - char* uid; - int nbest; - char* workflow; - int show_language; - int show_utterances; - char* result_type; - char* format; - int rate; - char* language; - int bits; - int channel; - char* codec; -} AsrWsClient; - - -#define STT_DEFAULT_VERSION 0b0001 -#define STT_DEFAULT_MESSAGE_TYPE 0b0001 -#define STT_DEFAULT_MESSAGE_TYPE_SPECIFIC_FLAGS 0b0000 -#define STT_DEFAULT_SERIAL_METHOD 0b0001 -#define STT_DEFAULT_COMPRESSION_TYPE 0b0000 -#define STT_DEFAULT_RESERVED_DATA 0 -#define STT_DEFAULT_EXTENSION_HEADER NULL -#define STT_DEFAULT_EXTENSION_HEADER_LENGTH 0 - -#define DEFAULT_HEADR STT_DEFAULT_VERSION,STT_DEFAULT_MESSAGE_TYPE,STT_DEFAULT_MESSAGE_TYPE_SPECIFIC_FLAGS,\ - STT_DEFAULT_SERIAL_METHOD,STT_DEFAULT_COMPRESSION_TYPE,STT_DEFAULT_RESERVED_DATA,\ - STT_DEFAULT_EXTENSION_HEADER,STT_DEFAULT_EXTENSION_HEADER_LENGTH - -#define OBJ_URL "wss://openspeech.bytedance.com/api/v2/asr" - -extern OS_SEM voice_msg_sem; - -extern OS_SEM voice_start_sem; - -OS_SEM chat_sem; - -unsigned char chat_msg[4 * 1024]; - -extern struct record_message record_msg; - -static void websockets_callback(u8 *buf, u32 len, u8 type) -{ - if(buf!=NULL&&type!=0x89){ - - ParsedResponse *req=NULL; - - printf(" . len: %d, . type: %x \r\n",len,type); - - extern ParsedResponse* parse_response(const uint8_t* res, size_t res_size); - - req=parse_response(buf, len); - - printf(" . msg: %s\r\n",req->payload_msg); - - cJSON* json = cJSON_Parse(req->payload_msg); - - if(json!=NULL){ - cJSON *sequence = cJSON_GetObjectItem(json, "sequence"); - if(cJSON_IsNumber(sequence)){ - if(sequence->valueint<0){ - cJSON *results = cJSON_GetObjectItem(json, "result"); - if (cJSON_IsArray(results)) { - int array_size = cJSON_GetArraySize(results); - for (int i = 0; i < array_size; i++) { - cJSON *result = cJSON_GetArrayItem(results, i); - cJSON *text = cJSON_GetObjectItem(result,"text"); - if (cJSON_IsString(text) && (text->valuestring != NULL)) { - printf("text: %s\r\n", (unsigned char*)text->valuestring); - sprintf(chat_msg,"%s",text->valuestring); - os_sem_post(&chat_sem); - } - } - } - } - } - - } - free(req); - } -} - - -/******************************************************************************* -* Websocket Client api -*******************************************************************************/ -static void websockets_client_reg(struct websocket_struct *websockets_info, char mode) -{ - memset(websockets_info, 0, sizeof(struct websocket_struct)); - websockets_info->_init = websockets_client_socket_init; - websockets_info->_exit = websockets_client_socket_exit; - websockets_info->_handshack = webcockets_client_socket_handshack; - websockets_info->_send = websockets_client_socket_send; - websockets_info->_recv_thread = websockets_client_socket_recv_thread; - websockets_info->_heart_thread = websockets_client_socket_heart_thread; - websockets_info->_recv_cb = websockets_callback; - websockets_info->_recv = NULL; - - websockets_info->websocket_mode = mode; - -#if 0 - //应用层指定申请接收内存大小(申请即可,不用释放,内部会释放),默认不使用 - websockets_info->recv_buf_size = 30 * 1024; - websockets_info->recv_buf = malloc(websockets_info->recv_buf_size); -#endif -} - -static int websockets_client_init(struct websocket_struct *websockets_info, u8 *url, const char *origin_str, const char *user_agent_str) -{ - websockets_info->ip_or_url = url; - websockets_info->origin_str = origin_str; - websockets_info->user_agent_str = user_agent_str; - websockets_info->recv_time_out = 5000; - - //应用层和库的版本检测,结构体不一样则返回出错 - int err = websockets_struct_check(sizeof(struct websocket_struct)); - if (err == FALSE) { - return err; - } - return websockets_info->_init(websockets_info); -} - -static int websockets_client_handshack(struct websocket_struct *websockets_info) -{ - return websockets_info->_handshack(websockets_info); -} - -static int websockets_client_send(struct websocket_struct *websockets_info, u8 *buf, int len, char type) -{ - //SSL加密时一次发送数据不能超过16K,用户需要自己分包 - return websockets_info->_send(websockets_info, buf, len, type); -} - -static void websockets_client_exit(struct websocket_struct *websockets_info) -{ - websockets_info->_exit(websockets_info); -} - -static uint8_t* generate_header( - uint8_t version, - uint8_t message_type, - uint8_t message_type_specific_flags, - uint8_t serial_method, - uint8_t compression_type, - uint8_t reserved_data, - const uint8_t* extension_header, - size_t extension_header_length -) { - size_t header_size = (extension_header_length / 4) + 1; - size_t total_size = header_size * 4; - - uint8_t* header = (uint8_t*)malloc(total_size); - if (header == NULL) { - return NULL; - } - - // 设置基本头部(4字节) - header[0] = (version << 4) | (header_size & 0x0F); - printf(" .header[0]: %x \r\n",header[0]); - header[1] = (message_type << 4) | (message_type_specific_flags & 0x0F); - printf(" .header[1]: %x \r\n",header[1]); - header[2] = (serial_method << 4) | (compression_type & 0x0F); - printf(" .header[2]: %x \r\n",header[2]); - header[3] = reserved_data; - printf(" .header[3]: %x \r\n",header[3]); - - // 复制扩展头部(如果有的话) - if (extension_header_length > 0 && extension_header != NULL) { - memcpy(header + 4, extension_header, extension_header_length); - } - return header; -} - -static char* construct_request(AsrWsClient* client, const char* reqid) { - cJSON* root = cJSON_CreateObject(); - if (root == NULL) { - goto fail; - } - - // App object - cJSON* app = cJSON_AddObjectToObject(root, "app"); - if (app == NULL || - !cJSON_AddStringToObject(app, "appid", client->appid) || - !cJSON_AddStringToObject(app, "cluster", client->cluster) || - !cJSON_AddStringToObject(app, "token", client->token)) { - goto fail; - } - - // User object - cJSON* user = cJSON_AddObjectToObject(root, "user"); - if (user == NULL || - !cJSON_AddStringToObject(user, "uid", client->uid)) { - goto fail; - } - - // Audio object - cJSON* audio = cJSON_AddObjectToObject(root, "audio"); - if (audio == NULL || - !cJSON_AddStringToObject(audio, "format", client->format)|| - !cJSON_AddNumberToObject(audio, "rate", client->rate) || - !cJSON_AddStringToObject(audio, "language", client->language) || - !cJSON_AddNumberToObject(audio, "bits", client->bits) || - !cJSON_AddNumberToObject(audio, "channel", client->channel) || - !cJSON_AddStringToObject(audio, "codec", client->codec)) { - goto fail; - } - - - // Request object - cJSON* request = cJSON_AddObjectToObject(root, "request"); - if (request == NULL || - !cJSON_AddStringToObject(request, "reqid", reqid) || - !cJSON_AddNumberToObject(request, "nbest", client->nbest) || - !cJSON_AddStringToObject(request, "workflow", client->workflow) || - !cJSON_AddBoolToObject(request, "show_utterances", client->show_utterances) || - !cJSON_AddStringToObject(request, "result_type", client->result_type) || - !cJSON_AddNumberToObject(request, "sequence", 1)) { - goto fail; - } - - - char* json_string = cJSON_Print(root); - cJSON_Delete(root); - return json_string; - -fail: - if (root != NULL) { - cJSON_Delete(root); - } - return NULL; -} - -static ParsedResponse* parse_response(const uint8_t* res, size_t res_size) { - // 检查响应大小是否足够 - if (res_size < 4) return NULL; - - // 解析响应头部 - Response response = { - .protocol_version = res[0] >> 4, - .header_size = res[0] & 0x0f, - .message_type = res[1] >> 4, - .message_type_specific_flags = res[1] & 0x0f, - .serialization_method = res[2] >> 4, - .message_compression = res[2] & 0x0f, - .reserved = res[3] - }; - - // 提取头部扩展 - size_t header_extensions_size = 4 * (response.header_size - 1); - response.header_extensions = (uint8_t*)malloc(header_extensions_size); - memcpy(response.header_extensions, res + 4, header_extensions_size); - - // 设置payload指针和大小 - response.payload = (uint8_t*)res + response.header_size * 4; - response.payload_size = res_size - response.header_size * 4; - - // 分配ParsedResponse结构体内存 - ParsedResponse* result = (ParsedResponse*)malloc(sizeof(ParsedResponse)); - memset(result, 0, sizeof(ParsedResponse)); - - // 根据消息类型处理payload - switch (response.message_type) { - case SERVER_FULL_RESPONSE: - // 解析payload大小(前4字节) - result->payload_size = ntohl(*(int32_t*)response.payload); - response.payload += 4; - response.payload_size -= 4; - break; - case SERVER_ACK: - if (response.payload_size >= 8) { - // 如果有额外的payload,解析其大小(接下来的4字节) - result->payload_size = ntohl(*(uint32_t*)(response.payload + 4)); - response.payload += 8; - response.payload_size -= 8; - } - break; - case SERVER_ERROR_RESPONSE: - result->payload_size = ntohl(*(uint32_t*)(response.payload + 4)); - response.payload += 8; - response.payload_size -= 8; - break; - } - - // 处理payload(如果存在) - if (response.payload_size > 0) { - - // 根据序列化方法处理payload - if (response.serialization_method == JSON) { - // 解析JSON - cJSON* json = cJSON_Parse((char*)response.payload); - if (json) { - - result->payload_msg = cJSON_Print(json); - - cJSON_Delete(json); - } - } else if (response.serialization_method != NO_SERIALIZATION) { - // 如果不是JSON也不是NO_SERIALIZATION,则直接复制字符串 - result->payload_msg = strdup((char*)response.payload); - } - } - - // 清理临时分配的内存 - free(response.header_extensions); - return result; -} - -static void generate_uuid(char *uuid_out) -{ - const char *c = "89ab"; - char *p = uuid_out; - for (int n = 0; n < 16; ++n) { - int b = rand() % 255; - switch (n) { - case 6: - sprintf(p, "4%x", b % 15); - break; - case 8: - sprintf(p, "%c%x", c[rand() % strlen(c)], b % 15); - break; - default: - sprintf(p, "%02x", b); - break; - } - - p += 2; - - switch (n) { - case 3: - case 5: - case 7: - case 9: - *p++='-'; - break; - } - } - *p = 0; -} - -/******************************************************************************* -* Websocket Client.c -*******************************************************************************/ -static void websockets_stt_client_main_thread(void *priv) -{ - int err; - char mode = WEBSOCKET_MODE; - u8 url[256] = OBJ_URL; - const char *origin_str = "wss://openspeech.bytedance.com/api/v2/asr"; - const char *user_agent_str = "Authorization: Bearer; BNA-XBIrEisvMczcmc-Sm4B3H-PmfqlL"; - char *websocket_header = NULL; - char *payload = NULL; - uint32_t payloadsize; - size_t total_length; - size_t header_length; - size_t payload_length; - char *full_client_request=NULL; - u8 uuid[16] = {0}; - - char *aduio_client_request=NULL; - - AsrWsClient STTPayload={ - .appid="8571950639", - .cluster="volcengine_streaming_common", - .token="BNA-XBIrEisvMczcmc-Sm4B3H-PmfqlL", - .uid="388808088185088", - .nbest=1, - .workflow="audio_in,resample,partition,vad,fe,decode,itn,nlu_punctuate", - .show_language=false, - .show_utterances=false, - .result_type="full", - .format="mp3", - .rate=16000, - .language="zh-CN", - .bits=16, - .channel=1, - .codec="raw", - - }; - - os_sem_create(&chat_sem,0); - - printf(" . ----------------- stt Client Websocket ------------------\r\n"); - - /* 0 . malloc buffer */ - struct websocket_struct *websockets_info = malloc(sizeof(struct websocket_struct)); - if (!websockets_info) { - return; - } - /* 1 . register */ - websockets_client_reg(websockets_info, mode); - - /* 2 . init */ - err = websockets_client_init(websockets_info, url, origin_str, user_agent_str); - if (FALSE == err) { - printf(" . ! Cilent websocket init error !!!\r\n"); - goto exit_ws; - } - - /* 3 . hanshack */ - err = websockets_client_handshack(websockets_info); - if (FALSE == err) { - printf(" . ! Handshake error !!!\r\n"); - goto exit_ws; - } - printf(" . Handshake success \r\n"); - - /* 4 . CreateThread */ - thread_fork("websocket_client_heart", 19, 512, 0, - &websockets_info->ping_thread_id, - websockets_info->_heart_thread, - websockets_info); - thread_fork("websocket_client_recv", 18, 512, 0, - &websockets_info->recv_thread_id, - websockets_info->_recv_thread, - websockets_info); - - websockets_sleep(1000); - - /* 5 . recv or send data */ - while (1) { - //接收信号量0 - os_sem_pend(&voice_start_sem, 0); //获取信号量 - - websocket_header=generate_header(DEFAULT_HEADR); - - header_length=4+STT_DEFAULT_EXTENSION_HEADER_LENGTH; - - generate_uuid(uuid); - - payload=construct_request(&STTPayload, uuid); - - printf(" . Payload :%s \r\n",payload); - - payload_length=strlen(payload); - - payloadsize=htonl(payload_length); - - total_length=header_length+4+payload_length; - - full_client_request=(char *)malloc(total_length+1); - if (full_client_request == NULL) { - printf(" . ! malloc err !!!\r\n"); - goto exit_ws; - } - memcpy(full_client_request, websocket_header, header_length); - - memcpy(full_client_request + header_length, &payloadsize, 4); - - memcpy(full_client_request + 4 + header_length,payload,payload_length+1); - - err = websockets_client_send(websockets_info, (u8 *)full_client_request, total_length, WCT_TXTDATA); - if (FALSE == err) { - printf(" . ! send err !!!\r\n"); - goto exit_ws; - } - - free(full_client_request); - - //websockets_sleep(1000); - - while(1){ - os_sem_pend(&voice_msg_sem, 0); - - if(record_msg.end){ - websocket_header=generate_header(STT_DEFAULT_VERSION,0b0010,0b0010,0b0000,\ - STT_DEFAULT_COMPRESSION_TYPE,STT_DEFAULT_RESERVED_DATA,\ - STT_DEFAULT_EXTENSION_HEADER,STT_DEFAULT_EXTENSION_HEADER_LENGTH); - }else{ - websocket_header=generate_header(STT_DEFAULT_VERSION,0b0010,0b0000,0b0000,\ - STT_DEFAULT_COMPRESSION_TYPE,STT_DEFAULT_RESERVED_DATA,\ - STT_DEFAULT_EXTENSION_HEADER,STT_DEFAULT_EXTENSION_HEADER_LENGTH); - } - - payloadsize=htonl(record_msg.msg_size); - - total_length=header_length+4+record_msg.msg_size; - - aduio_client_request=(char *)malloc(total_length+1); - - if (aduio_client_request == NULL) { - printf(" . ! malloc err !!!\r\n"); - goto exit_ws; - } - - memcpy(aduio_client_request, websocket_header, header_length); - - memcpy(aduio_client_request + header_length, &payloadsize, 4); - - memcpy(aduio_client_request + 4 + header_length,record_msg.msg,record_msg.msg_size+1); - - err = websockets_client_send(websockets_info, (u8 *)aduio_client_request, total_length, WCT_TXTDATA); - if (FALSE == err) { - printf(" . ! send err !!!\r\n"); - goto exit_ws; - } - - free(aduio_client_request); - - } - - } - -exit_ws: - /* 6 . exit */ - if (websockets_info->ping_thread_id) { - thread_kill(&websockets_info->ping_thread_id, KILL_REQ); - } - if (websockets_info->recv_thread_id) { - thread_kill(&websockets_info->recv_thread_id, KILL_REQ); - } - - websockets_client_exit(websockets_info); - free(websockets_info); -} - -static void websocket_client_thread_create(void) -{ - thread_fork("websockets_stt_client_main_thread", 15, 1024 * 250, 0, 0, websockets_stt_client_main_thread, NULL); -} - -static void http_websocket_start(void *priv) -{ - enum wifi_sta_connect_state state; - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(500); - } - - websocket_client_thread_create(); -} - -//应用程序入口,需要运行在STA模式下 -static int stt_websocket_init(void) -{ - if (thread_fork("http_websocket_start", 10, 512, 0, NULL, http_websocket_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -late_initcall(stt_websocket_init); -#endif // stt diff --git a/doubao_chat/apps/wifi_daobao/stt_websocket_local.c b/doubao_chat/apps/wifi_daobao/stt_websocket_local.c deleted file mode 100644 index d8d1429e..00000000 --- a/doubao_chat/apps/wifi_daobao/stt_websocket_local.c +++ /dev/null @@ -1,664 +0,0 @@ -#include "web_socket/websocket_api.h" -#include "wifi/wifi_connect.h" -#include "system/includes.h" -#include "fs/fs.h" -#include "asm/sfc_norflash_api.h" -#include "cJSON.h" -#include "aduio_record.h" -#ifdef WEBSOCKET_MEMHEAP_DEBUG -#include "mem_leak_test.h" -#endif - -#include "app_config.h" - -//#define stt_local -#ifdef stt_local - -// 定义消息类型常量 -#define SERVER_FULL_RESPONSE 0b1001 -#define SERVER_ACK 0b1011 -#define SERVER_ERROR_RESPONSE 0b1111 - -// 定义压缩和序列化方法常量 -#define GZIP 1 -#define JSON 1 -#define NO_SERIALIZATION 0 - -// 定义响应结构体,用于存储原始响应数据 -typedef struct { - uint8_t protocol_version; - uint8_t header_size; - uint8_t message_type; - uint8_t message_type_specific_flags; - uint8_t serialization_method; - uint8_t message_compression; - uint8_t reserved; - uint8_t* header_extensions; - uint8_t* payload; - size_t payload_size; -} Response; - -// 定义解析后的响应结构体,用于存储处理后的数据 -typedef struct { - unsigned char* payload_msg; - size_t payload_size; -} ParsedResponse; - -typedef struct { - char* appid; - char* cluster; - char* token; - char* uid; - int nbest; - char* workflow; - int show_language; - int show_utterances; - char* result_type; - char* format; - int rate; - char* language; - int bits; - int channel; - char* codec; -} AsrWsClient; - -typedef struct { - unsigned char* data; - size_t size; - bool is_last; -} DataSegment; - -typedef struct { - unsigned char* data; - size_t data_len; - size_t chunk_size; - size_t current_offset; -} DataSlicer; - - -#define STT_DEFAULT_VERSION 0b0001 -#define STT_DEFAULT_MESSAGE_TYPE 0b0001 -#define STT_DEFAULT_MESSAGE_TYPE_SPECIFIC_FLAGS 0b0000 -#define STT_DEFAULT_SERIAL_METHOD 0b0001 -#define STT_DEFAULT_COMPRESSION_TYPE 0b0000 -#define STT_DEFAULT_RESERVED_DATA 0 -#define STT_DEFAULT_EXTENSION_HEADER NULL -#define STT_DEFAULT_EXTENSION_HEADER_LENGTH 0 - -#define DEFAULT_HEADR STT_DEFAULT_VERSION,STT_DEFAULT_MESSAGE_TYPE,STT_DEFAULT_MESSAGE_TYPE_SPECIFIC_FLAGS,\ - STT_DEFAULT_SERIAL_METHOD,STT_DEFAULT_COMPRESSION_TYPE,STT_DEFAULT_RESERVED_DATA,\ - STT_DEFAULT_EXTENSION_HEADER,STT_DEFAULT_EXTENSION_HEADER_LENGTH - -#define OBJ_URL "wss://openspeech.bytedance.com/api/v2/asr" - -static OS_SEM x_sem; - -OS_SEM chat_sem; - -unsigned char chat_msg[4 * 1024]; - -static void websockets_callback(u8 *buf, u32 len, u8 type) -{ - if(buf!=NULL&&type!=0x89){ - - ParsedResponse *req=NULL; - - printf(" . len: %d, . type: %x \r\n",len,type); - - extern ParsedResponse* parse_response(const uint8_t* res, size_t res_size); - - req=parse_response(buf, len); - - printf(" . msg: %s\r\n",req->payload_msg); - - cJSON* json = cJSON_Parse(req->payload_msg); - - free(req); - - if(json!=NULL){ - cJSON *sequence = cJSON_GetObjectItem(json, "sequence"); - if(cJSON_IsNumber(sequence)){ - if(sequence->valueint<0){ - cJSON *results = cJSON_GetObjectItem(json, "result"); - if (cJSON_IsArray(results)) { - int array_size = cJSON_GetArraySize(results); - for (int i = 0; i < array_size; i++) { - cJSON *result = cJSON_GetArrayItem(results, i); - cJSON *text = cJSON_GetObjectItem(result,"text"); - if (cJSON_IsString(text) && (text->valuestring != NULL)) { - printf("text: %s\r\n", (unsigned char*)text->valuestring); - sprintf(chat_msg,"%s",text->valuestring); - os_sem_post(&chat_sem); - } - } - } - } - } - - } - } -} - - -/******************************************************************************* -* Websocket Client api -*******************************************************************************/ -static void websockets_client_reg(struct websocket_struct *websockets_info, char mode) -{ - memset(websockets_info, 0, sizeof(struct websocket_struct)); - websockets_info->_init = websockets_client_socket_init; - websockets_info->_exit = websockets_client_socket_exit; - websockets_info->_handshack = webcockets_client_socket_handshack; - websockets_info->_send = websockets_client_socket_send; - websockets_info->_recv_thread = websockets_client_socket_recv_thread; - websockets_info->_heart_thread = websockets_client_socket_heart_thread; - websockets_info->_recv_cb = websockets_callback; - websockets_info->_recv = NULL; - - websockets_info->websocket_mode = mode; - -#if 0 - //应用层指定申请接收内存大小(申请即可,不用释放,内部会释放),默认不使用 - websockets_info->recv_buf_size = 30 * 1024; - websockets_info->recv_buf = malloc(websockets_info->recv_buf_size); -#endif -} - -static int websockets_client_init(struct websocket_struct *websockets_info, u8 *url, const char *origin_str, const char *user_agent_str) -{ - websockets_info->ip_or_url = url; - websockets_info->origin_str = origin_str; - websockets_info->user_agent_str = user_agent_str; - websockets_info->recv_time_out = 5000; - - //应用层和库的版本检测,结构体不一样则返回出错 - int err = websockets_struct_check(sizeof(struct websocket_struct)); - if (err == FALSE) { - return err; - } - return websockets_info->_init(websockets_info); -} - -static int websockets_client_handshack(struct websocket_struct *websockets_info) -{ - return websockets_info->_handshack(websockets_info); -} - -static int websockets_client_send(struct websocket_struct *websockets_info, u8 *buf, int len, char type) -{ - //SSL加密时一次发送数据不能超过16K,用户需要自己分包 - return websockets_info->_send(websockets_info, buf, len, type); -} - -static void websockets_client_exit(struct websocket_struct *websockets_info) -{ - websockets_info->_exit(websockets_info); -} - -static uint8_t* generate_header( - uint8_t version, - uint8_t message_type, - uint8_t message_type_specific_flags, - uint8_t serial_method, - uint8_t compression_type, - uint8_t reserved_data, - const uint8_t* extension_header, - size_t extension_header_length -) { - size_t header_size = (extension_header_length / 4) + 1; - size_t total_size = header_size * 4; - - uint8_t* header = (uint8_t*)malloc(total_size); - if (header == NULL) { - return NULL; - } - - // 设置基本头部(4字节) - header[0] = (version << 4) | (header_size & 0x0F); - printf(" .header[0]: %x \r\n",header[0]); - header[1] = (message_type << 4) | (message_type_specific_flags & 0x0F); - printf(" .header[1]: %x \r\n",header[1]); - header[2] = (serial_method << 4) | (compression_type & 0x0F); - printf(" .header[2]: %x \r\n",header[2]); - header[3] = reserved_data; - printf(" .header[3]: %x \r\n",header[3]); - - // 复制扩展头部(如果有的话) - if (extension_header_length > 0 && extension_header != NULL) { - memcpy(header + 4, extension_header, extension_header_length); - } - return header; -} - -static char* construct_request(AsrWsClient* client, const char* reqid) { - cJSON* root = cJSON_CreateObject(); - if (root == NULL) { - goto fail; - } - - // App object - cJSON* app = cJSON_AddObjectToObject(root, "app"); - if (app == NULL || - !cJSON_AddStringToObject(app, "appid", client->appid) || - !cJSON_AddStringToObject(app, "cluster", client->cluster) || - !cJSON_AddStringToObject(app, "token", client->token)) { - goto fail; - } - - // User object - cJSON* user = cJSON_AddObjectToObject(root, "user"); - if (user == NULL || - !cJSON_AddStringToObject(user, "uid", client->uid)) { - goto fail; - } - - // Audio object - cJSON* audio = cJSON_AddObjectToObject(root, "audio"); - if (audio == NULL || - !cJSON_AddStringToObject(audio, "format", client->format)|| - !cJSON_AddNumberToObject(audio, "rate", client->rate) || - !cJSON_AddStringToObject(audio, "language", client->language) || - !cJSON_AddNumberToObject(audio, "bits", client->bits) || - !cJSON_AddNumberToObject(audio, "channel", client->channel) || - !cJSON_AddStringToObject(audio, "codec", client->codec)) { - goto fail; - } - - - // Request object - cJSON* request = cJSON_AddObjectToObject(root, "request"); - if (request == NULL || - !cJSON_AddStringToObject(request, "reqid", reqid) || - !cJSON_AddNumberToObject(request, "nbest", client->nbest) || - !cJSON_AddStringToObject(request, "workflow", client->workflow) || - !cJSON_AddBoolToObject(request, "show_utterances", client->show_utterances) || - !cJSON_AddStringToObject(request, "result_type", client->result_type) || - !cJSON_AddNumberToObject(request, "sequence", 1)) { - goto fail; - } - - - char* json_string = cJSON_Print(root); - cJSON_Delete(root); - return json_string; - -fail: - if (root != NULL) { - cJSON_Delete(root); - } - return NULL; -} - -static ParsedResponse* parse_response(const uint8_t* res, size_t res_size) { - // 检查响应大小是否足够 - if (res_size < 4) return NULL; - - // 解析响应头部 - Response response = { - .protocol_version = res[0] >> 4, - .header_size = res[0] & 0x0f, - .message_type = res[1] >> 4, - .message_type_specific_flags = res[1] & 0x0f, - .serialization_method = res[2] >> 4, - .message_compression = res[2] & 0x0f, - .reserved = res[3] - }; - - // 提取头部扩展 - size_t header_extensions_size = 4 * (response.header_size - 1); - response.header_extensions = (uint8_t*)malloc(header_extensions_size); - memcpy(response.header_extensions, res + 4, header_extensions_size); - - // 设置payload指针和大小 - response.payload = (uint8_t*)res + response.header_size * 4; - response.payload_size = res_size - response.header_size * 4; - - // 分配ParsedResponse结构体内存 - ParsedResponse* result = (ParsedResponse*)malloc(sizeof(ParsedResponse)); - memset(result, 0, sizeof(ParsedResponse)); - - // 根据消息类型处理payload - switch (response.message_type) { - case SERVER_FULL_RESPONSE: - // 解析payload大小(前4字节) - result->payload_size = ntohl(*(int32_t*)response.payload); - response.payload += 4; - response.payload_size -= 4; - break; - case SERVER_ACK: - if (response.payload_size >= 8) { - // 如果有额外的payload,解析其大小(接下来的4字节) - result->payload_size = ntohl(*(uint32_t*)(response.payload + 4)); - response.payload += 8; - response.payload_size -= 8; - } - break; - case SERVER_ERROR_RESPONSE: - result->payload_size = ntohl(*(uint32_t*)(response.payload + 4)); - response.payload += 8; - response.payload_size -= 8; - break; - } - - // 处理payload(如果存在) - if (response.payload_size > 0) { - - // 根据序列化方法处理payload - if (response.serialization_method == JSON) { - // 解析JSON - cJSON* json = cJSON_Parse((char*)response.payload); - if (json) { - - result->payload_msg = cJSON_Print(json); - - cJSON_Delete(json); - } - } else if (response.serialization_method != NO_SERIALIZATION) { - // 如果不是JSON也不是NO_SERIALIZATION,则直接复制字符串 - result->payload_msg = strdup((char*)response.payload); - } - } - - // 清理临时分配的内存 - free(response.header_extensions); - return result; -} - -static void generate_uuid(char *uuid_out) -{ - const char *c = "89ab"; - char *p = uuid_out; - for (int n = 0; n < 16; ++n) { - int b = rand() % 255; - switch (n) { - case 6: - sprintf(p, "4%x", b % 15); - break; - case 8: - sprintf(p, "%c%x", c[rand() % strlen(c)], b % 15); - break; - default: - sprintf(p, "%02x", b); - break; - } - - p += 2; - - switch (n) { - case 3: - case 5: - case 7: - case 9: - *p++='-'; - break; - } - } - *p = 0; -} - -DataSlicer* create_data_slicer(unsigned char* data, size_t data_len, size_t chunk_size) { - DataSlicer* slicer = (DataSlicer*)malloc(sizeof(DataSlicer)); - slicer->data = data; - slicer->data_len = data_len; - slicer->chunk_size = chunk_size; - slicer->current_offset = 0; - return slicer; -} - -DataSegment* slice_data(DataSlicer* slicer) { - if (slicer->current_offset >= slicer->data_len) { - return NULL; - } - - DataSegment* segment = (DataSegment*)malloc(sizeof(DataSegment)); - size_t remaining = slicer->data_len - slicer->current_offset; - size_t segment_size = (remaining < slicer->chunk_size) ? remaining : slicer->chunk_size; - - segment->data = (unsigned char*)malloc(segment_size); - memcpy(segment->data, slicer->data + slicer->current_offset, segment_size); - segment->size = segment_size; - segment->is_last = (slicer->current_offset + segment_size >= slicer->data_len); - - slicer->current_offset += segment_size; - - return segment; -} - -/******************************************************************************* -* Websocket Client.c -*******************************************************************************/ -static void websockets_stt_client_main_thread(void *priv) -{ - int err; - char mode = WEBSOCKET_MODE; - u8 url[256] = OBJ_URL; - const char *origin_str = "wss://openspeech.bytedance.com/api/v2/asr"; - const char *user_agent_str = "Authorization: Bearer; BNA-XBIrEisvMczcmc-Sm4B3H-PmfqlL"; - char *websocket_header = NULL; - char *payload = NULL; - uint32_t payloadsize; - size_t total_length; - size_t header_length; - size_t payload_length; - char *full_client_request=NULL; - u8 uuid[16] = {0}; - - char *aduio_client_request=NULL; - - AsrWsClient STTPayload={ - .appid="8571950639", - .cluster="volcengine_streaming_common", - .token="BNA-XBIrEisvMczcmc-Sm4B3H-PmfqlL", - .uid="388808088185088", - .nbest=1, - .workflow="audio_in,resample,partition,vad,fe,decode,itn,nlu_punctuate", - .show_language=false, - .show_utterances=false, - .result_type="full", - .format="mp3", - .rate=16000, - .language="zh-CN", - .bits=16, - .channel=1, - .codec="raw", - - }; - - char name[128]; - char aduio[100*1024]={0}; - int aduio_len; - FILE *f = fopen("mnt/sdfile/res/demo/story.mp3", "r"); - if (!f) { - printf("fopen err!\n"); - }else{ - fget_name(f, name, sizeof(name)); - printf("file_name: %s\n", name); - - aduio_len = fread(aduio, 1, sizeof(aduio), f); - if(aduio_len > 0) - { - printf("aduio_len:%d\r\n",aduio_len); - } - } - - DataSlicer* slicer = create_data_slicer((unsigned char*)aduio, aduio_len, 10*1024); - - DataSegment* segment; - - os_sem_create(&chat_sem,0); - - printf(" . ----------------- stt Client Websocket ------------------\r\n"); - - /* 0 . malloc buffer */ - struct websocket_struct *websockets_info = malloc(sizeof(struct websocket_struct)); - if (!websockets_info) { - return; - } - /* 1 . register */ - websockets_client_reg(websockets_info, mode); - - /* 2 . init */ - err = websockets_client_init(websockets_info, url, origin_str, user_agent_str); - if (FALSE == err) { - printf(" . ! Cilent websocket init error !!!\r\n"); - goto exit_ws; - } - - /* 3 . hanshack */ - err = websockets_client_handshack(websockets_info); - if (FALSE == err) { - printf(" . ! Handshake error !!!\r\n"); - goto exit_ws; - } - printf(" . Handshake success \r\n"); - - /* 4 . CreateThread */ - thread_fork("websocket_client_heart", 19, 512, 0, - &websockets_info->ping_thread_id, - websockets_info->_heart_thread, - websockets_info); - thread_fork("websocket_client_recv", 18, 512, 0, - &websockets_info->recv_thread_id, - websockets_info->_recv_thread, - websockets_info); - - websockets_sleep(1000); - - /* 5 . recv or send data */ - while (1) { - //接收信号量0 - os_sem_pend(&x_sem, 0); //获取信号量 - - websocket_header=generate_header(DEFAULT_HEADR); - - header_length=4+STT_DEFAULT_EXTENSION_HEADER_LENGTH; - - generate_uuid(uuid); - - payload=construct_request(&STTPayload, uuid); - - printf(" . Payload :%s \r\n",payload); - - payload_length=strlen(payload); - - payloadsize=htonl(payload_length); - - total_length=header_length+4+payload_length; - - full_client_request=(char *)malloc(total_length+1); - if (full_client_request == NULL) { - printf(" . ! malloc err !!!\r\n"); - goto exit_ws; - } - memcpy(full_client_request, websocket_header, header_length); - - memcpy(full_client_request + header_length, &payloadsize, 4); - - memcpy(full_client_request + 4 + header_length,payload,payload_length+1); - - err = websockets_client_send(websockets_info, (u8 *)full_client_request, total_length, WCT_TXTDATA); - if (FALSE == err) { - printf(" . ! send err !!!\r\n"); - goto exit_ws; - } - - free(payload); - free(full_client_request); - - websockets_sleep(1000); - - while(1){ - segment = slice_data(slicer); - - if(segment!=NULL){ - - if(segment->is_last){ - websocket_header=generate_header(STT_DEFAULT_VERSION,0b0010,0b0010,0b0000,\ - STT_DEFAULT_COMPRESSION_TYPE,STT_DEFAULT_RESERVED_DATA,\ - STT_DEFAULT_EXTENSION_HEADER,STT_DEFAULT_EXTENSION_HEADER_LENGTH); - }else{ - websocket_header=generate_header(STT_DEFAULT_VERSION,0b0010,0b0000,0b0000,\ - STT_DEFAULT_COMPRESSION_TYPE,STT_DEFAULT_RESERVED_DATA,\ - STT_DEFAULT_EXTENSION_HEADER,STT_DEFAULT_EXTENSION_HEADER_LENGTH); - } - - payloadsize=htonl(segment->size); - - total_length=header_length+4+segment->size; - - aduio_client_request=(char *)malloc(total_length+1); - - if (aduio_client_request == NULL) { - printf(" . ! malloc err !!!\r\n"); - goto exit_ws; - } - - memcpy(aduio_client_request, websocket_header, header_length); - - memcpy(aduio_client_request + header_length, &payloadsize, 4); - - memcpy(aduio_client_request + 4 + header_length,segment->data,segment->size+1); - - err = websockets_client_send(websockets_info, (u8 *)aduio_client_request, total_length, WCT_TXTDATA); - if (FALSE == err) { - printf(" . ! send err !!!\r\n"); - goto exit_ws; - } - free(aduio_client_request); - }else{ - break; - } - free(segment); - websockets_sleep(1000); - - } - - } - -exit_ws: - /* 6 . exit */ - if (websockets_info->ping_thread_id) { - thread_kill(&websockets_info->ping_thread_id, KILL_REQ); - } - if (websockets_info->recv_thread_id) { - thread_kill(&websockets_info->recv_thread_id, KILL_REQ); - } - - websockets_client_exit(websockets_info); - - free(slicer); - free(websockets_info); -} - -static void websocket_client_thread_create(void) -{ - thread_fork("websockets_stt_client_main_thread", 15, 1024 * 250, 0, 0, websockets_stt_client_main_thread, NULL); -} - -static void http_websocket_start(void *priv) -{ - enum wifi_sta_connect_state state; - os_sem_create(&x_sem,1); - while (1) { - printf("Connecting to the network...\n"); - state = wifi_get_sta_connect_state(); - if (WIFI_STA_NETWORK_STACK_DHCP_SUCC == state) { - printf("Network connection is successful!\n"); - break; - } - os_time_dly(500); - } - - websocket_client_thread_create(); -} - -//应用程序入口,需要运行在STA模式下 -static int stt_websocket_init(void) -{ - if (thread_fork("http_websocket_start", 10, 512, 0, NULL, http_websocket_start, NULL) != OS_NO_ERR) { - printf("thread fork fail\n"); - } -} - -late_initcall(stt_websocket_init); -#endif // stt