mcu_hi3321_watch/tjd/ui/app/play_dial/TjdUiAppPlayDialModel.cpp
2025-05-26 20:15:20 +08:00

862 lines
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* Copyright (c) TJD Technologies Co., Ltd. 2024. All rights reserved.
*
* Description: TjdUiAppPlayDialModel.cpp
*
* Author: liuguanwu
*
* Create: 2024-10
*--------------------------------------------------------------------------*/
#include "TjdUiAppPlayDialModel.h"
#include "TjdUiAppPlayDialPresenter.h"
#include "TjdUiAppPlayDialView.h"
#include "TjdUiImageIds.h"
#include "TjdUiScreenManage.h"
#include "audio_capturer.h"
#include "ble_port_protocol.h"
#include "cJSON.h"
#include "common/image_cache_manager.h"
#include "graphic_service.h"
#include "hal_tick.h"
#include "power_display_service.h"
#include "rtc_api.h"
#include "sql_setting.h"
#include "sys_config.h"
#include "sys_typedef.h"
#include "thread_adapter.h"
#include <algorithm>
#include <atomic>
#include <cstring>
#include <dirent.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>
namespace TJD {
#define ENABLE_PRINT_INFO 0
#if ENABLE_PRINT_INFO
#define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制
#define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开
#define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印一般常开
#define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开
#else
#define static_print_info(...)
#define static_print_warn(...)
#define static_print_error(...)
#define static_print_debug(...)
#endif
#define LOAD_BUFFER_SIZE 8 * 1024
#define LEFUN_AI_STORY_FILE_PATH "/user/tjd_wfp/lefun_ai_record.json" // TJD_FS_DIR_WFP
#define TJD_DIAL_WF_CONFIG_PATH "/user/tjd_wf/wf_config_0.json"
#define TJD_FS_DIR_WFP_E TJD_FS_DIR_WFP "/"
static MutexId g_lefun_ai_mutex = 0;
static bool story_question_flag = false;
static bool story_answer_flag = false;
static struct data_flow *data_flow = nullptr;
static std::shared_ptr<OHOS::Audio::AudioCapturer> lefunAiCapturer_{nullptr};
std::string g_PlayDialQuestion = "";
std::string g_PlayDialAnswer = "";
std::string g_PlayDialPath = "";
std::string g_PlayDialPreviewPath = "";
extern osThreadId_t resend_audio_data_id;
TjdUiAppPlayDialModel::TjdUiAppPlayDialModel() { wfFileList.clear(); }
TjdUiAppPlayDialModel::~TjdUiAppPlayDialModel()
{
for (int16_t i = 0; i < wfFileList.size(); i++) {
OHOS::ImageCacheManager::GetInstance().UnloadSingleRes(wfFileList.data()[i]);
}
wfFileList.clear();
}
int TjdUiAppPlayDialModel::FileExists(const char *filename)
{
FILE *file = fopen(filename, "r");
if (file) {
fclose(file);
return 1; // 文件存在
}
return 0; // 文件不存在
}
int TjdUiAppPlayDialModel::FileDelete(const char *filename) { return unlink(filename); }
void TjdUiAppPlayDialModel::addRecord(History *history, std::string question, std::string answer)
{
if (history == nullptr || history->records == nullptr) {
return;
}
if (history->total_records >= MAX_HISTORY) {
for (int i = 1; i < MAX_HISTORY; i++) {
history->records[i - 1] = history->records[i];
}
history->total_records--;
}
if (history->total_records < MAX_HISTORY) {
history->records[history->total_records].question = question;
history->records[history->total_records].answer = answer;
history->total_records++;
}
}
void TjdUiAppPlayDialModel::saveToJson(const History *history, const char *filename)
{
// 检查输入参数
if (!history || history->total_records < 0) {
printf("Error: Invalid history object\n");
return;
}
// 创建 JSON 对象
cJSON *json = cJSON_CreateObject();
if (!json) {
printf("Error creating JSON object\n");
return;
}
// 创建历史记录数组
cJSON *historyArray = cJSON_CreateArray();
if (!historyArray) {
printf("Error creating JSON array\n");
cJSON_Delete(json);
return;
}
// 将 total_records 添加到 JSON 对象中
cJSON_AddNumberToObject(json, "total_records", history->total_records);
// 遍历历史记录并添加到 JSON 数组中
for (int i = 0; i < history->total_records; i++) {
const std::string &question = history->records[i].question;
const std::string &answer = history->records[i].answer;
cJSON *item = cJSON_CreateObject();
if (!item) {
printf("Error creating JSON item for record \n");
continue;
}
if (item == nullptr) {
return;
}
cJSON_AddStringToObject(item, "question", question.c_str());
cJSON_AddStringToObject(item, "answer", answer.c_str());
// 将记录添加到历史记录数组
cJSON_AddItemToArray(historyArray, item);
}
// 将历史记录数组添加到 JSON 对象
cJSON_AddItemToObject(json, "history", historyArray);
// 打开文件以写入 JSON 数据
FILE *file = fopen(filename, "w");
if (!file) {
printf("Error opening file: ");
cJSON_Delete(json);
return;
}
// 将 JSON 对象转换为字符串并写入文件
char *jsonString = cJSON_Print(json);
if (jsonString) {
fprintf(file, "%s\n", jsonString);
free(jsonString); // 释放 JSON 字符串
}
// 关闭文件和删除 JSON 对象
fclose(file);
cJSON_Delete(json);
}
void TjdUiAppPlayDialModel::displayHistory(const History *history)
{
printf("displayHistory %d\n", history->total_records);
for (int i = 0; i < history->total_records; i++) {
// 打印每个记录的 question 和 answer
printf("Record %d:\n", i + 1);
printf("Question: %s\n", history->records[i].question.c_str());
printf("Answer: %s\n", history->records[i].answer.c_str());
printf("------------------\n");
}
}
void TjdUiAppPlayDialModel::loadFromJson(History *history)
{
char *filename = LEFUN_AI_STORY_FILE_PATH;
FILE *file = fopen(filename, "r");
if (!file) {
// 文件不存在,创建初始 JSON
createInitialJson(filename);
return; // 返回以避免进一步处理
}
char *buffer = (char *)malloc(LOAD_BUFFER_SIZE);
if (!buffer) {
printf("Error: Failed to allocate memory for buffer.\n");
fclose(file);
return;
}
size_t bytesRead = fread(buffer, sizeof(char), LOAD_BUFFER_SIZE - 1, file);
buffer[bytesRead] = '\0';
fclose(file);
cJSON *json = cJSON_Parse(buffer);
if (json) {
cJSON *totalRecordsItem = cJSON_GetObjectItem(json, "total_records");
history->total_records = totalRecordsItem ? totalRecordsItem->valueint : 0;
cJSON *historyArray = cJSON_GetObjectItem(json, "history");
cJSON *record = NULL;
int index = 0; // 当前存储记录的索引
cJSON_ArrayForEach(record, historyArray)
{
if (index < 10) {
// 获取问题和答案
cJSON *questionItem = cJSON_GetObjectItem(record, "question");
cJSON *answerItem = cJSON_GetObjectItem(record, "answer");
if (questionItem && questionItem->valuestring && answerItem && answerItem->valuestring) {
history->records[index].question = questionItem->valuestring;
history->records[index].answer = answerItem->valuestring;
index++;
} else {
fprintf(stderr, "Warning: Missing question or answer in record %d\n", index);
}
}
history->total_records = index;
}
cJSON_Delete(json);
} else {
static_print_warn("Error parsing JSON json null\n");
}
free(buffer);
}
uint8_t TjdUiAppPlayDialModel::get_total_records_from_json()
{
FILE *file = fopen(LEFUN_AI_STORY_FILE_PATH, "r");
if (file == NULL) {
printf("Could not open file %s\n", LEFUN_AI_STORY_FILE_PATH);
return 0; // 返回 0 表示文件未未初始化,直接返回
}
// 获取文件大小
fseek(file, 0, SEEK_END);
long length = ftell(file);
fseek(file, 0, SEEK_SET);
// 读取文件内容
char *data = (char *)malloc(length + 1);
fread(data, 1, length, file);
data[length] = '\0'; // 确保字符串以 null 结尾
fclose(file);
cJSON *json = cJSON_Parse(data);
free(data);
if (json == NULL) {
printf("Error parsing JSON\n");
return -1; // 返回 -1 表示解析错误
}
cJSON *total_records_item = cJSON_GetObjectItem(json, "total_records");
uint8_t total_records = total_records_item ? total_records_item->valueint : -1; // 默认返回 -1
cJSON_Delete(json);
return total_records;
}
void TjdUiAppPlayDialModel::createInitialJson(const char *filename)
{
cJSON *json = cJSON_CreateObject();
cJSON_AddNumberToObject(json, "total_records", 0);
cJSON *historyArray = cJSON_CreateArray();
cJSON_AddItemToObject(json, "history", historyArray);
FILE *file = fopen(filename, "w");
if (file) {
char *jsonString = cJSON_Print(json);
fprintf(file, "%s\n", jsonString);
free(jsonString);
fclose(file);
}
cJSON_Delete(json);
}
uint8_t TjdUiAppPlayDialModel::UpdateHistoryFileList(uint8_t max_file)
{
std::string fullPath;
for (int16_t i = 0; i < wfFileList.size(); i++) {
OHOS::ImageCacheManager::GetInstance().UnloadSingleRes(wfFileList.data()[i]);
}
wfFileList.clear();
// 云表盘:打开目录
struct dirent *direntp;
DIR *dirp = opendir(TJD_FS_DIR_WFP);
// 遍历文件
if (dirp != nullptr) {
std::string DirPrePath(TJD_FS_DIR_WFP);
while ((direntp = readdir(dirp)) != nullptr) {
std::string filename(direntp->d_name);
fullPath = TJD_FS_DIR_WFP_E + filename;
printf("filename(%s-%s)\n", filename.c_str(), fullPath.c_str());
if (filename.find(".bin") != std::string::npos && filename.find("wfp_bg") != std::string::npos) {
std::string number;
std::size_t pos1 = filename.find_last_of('_');
if (pos1 != std::string::npos) {
// 查找 .bin 的位置
std::size_t pos2 = filename.find(".bwf", pos1);
if (pos2 != std::string::npos) {
// 提取下划线和 .bin 之间的子字符串
number = filename.substr(pos1 + 1, pos2 - pos1 - 1);
static_print_debug("FindWfFile number: %s\n", number.c_str());
}
}
wfFileList.push_back(fullPath);
printf(".bin filename(%s)\n", fullPath.c_str());
} else if (filename.find(".hbm") != std::string::npos &&
filename.find("wfp_preview") != std::string::npos) {
printf(".hbm filename(%s)\n", fullPath.c_str());
} else {
FileDelete(fullPath.c_str());
}
}
}
// 关闭目录
closedir(dirp);
std::sort(wfFileList.begin(), wfFileList.end(), std::greater<std::string>());
while (wfFileList.size() > max_file) {
FileDelete(wfFileList[wfFileList.size() - 1].c_str());
wfFileList.pop_back();
}
printf("wfFileList.size(%d)\n", wfFileList.size());
return wfFileList.size();
}
std::vector<std::string> *TjdUiAppPlayDialModel::GetHistoryFileList() { return &wfFileList; }
uint8_t TjdUiAppPlayDialModel::MakeingWfConfig0Json(const char *filename)
{
if (FileExists(filename) == 0) {
static_print_error("Error opening file:[%s]", filename);
return -1;
}
std::string fullPath = filename;
if (strcmp(filename, PLAY_DIAL_DRAW_BIN_TEMP_PATH) == 0) {
uint64_t timestamp = 0;
tjd_driver_rtc_get_ops()->get_timestamp(&timestamp);
fullPath.clear();
fullPath.append(TJD_FS_DIR_WFP);
fullPath.append("/wfp_bg_");
fullPath.append(std::to_string(timestamp));
fullPath.append(".bin");
printf("g_PlayDialPreviewPath rename():%s,%s\n", filename, fullPath.c_str());
// PLAY_DIAL_DRAW_BIN_PATH 不使用固定文件名
if (0 != rename(filename, fullPath.c_str())) {
printf("TjdUiAppPlayDialModel:fail rename():%s,%s\n", filename, fullPath.c_str());
fullPath.clear();
return -1;
}
}
// 创建 JSON 对象
cJSON *json = cJSON_CreateObject();
if (!json) {
static_print_error("Error creating JSON object");
fullPath.clear();
return -1;
}
// 将 wf_type 添加到 JSON 对象中
cJSON_AddNumberToObject(json, "wf_type", 0);
// cJSON_AddNumberToObject(json, "wf_type", param_data.setting_mode);
// 将 wf_preview 添加到 JSON 对象中
cJSON_AddStringToObject(json, "wf_preview", fullPath.c_str());
// 将 bg_res 添加到 JSON 对象中
cJSON_AddStringToObject(json, "bg_res", fullPath.c_str());
// 将 img_number 添加到 JSON 对象中
cJSON_AddNumberToObject(json, "img_number", 1);
// 将 video_preview 添加到 JSON 对象中
// cJSON_AddStringToObject(json, "video_preview", TJD_CUSTOM_DIAL_VIDEO_PREVIEW_PATH);
cJSON_AddNullToObject(json, "video_preview");
// tjd_set_custom_dial_file_num(0);
// tjd_set_custom_dial_file_mask(false);
fullPath.clear();
// 打开文件以写入 JSON 数据
FILE *file = fopen(TJD_DIAL_WF_CONFIG_PATH, "w");
if (!file) {
static_print_error("Error opening file: ");
cJSON_Delete(json);
return -1;
}
// 将 JSON 对象转换为字符串并写入文件
char *jsonString = cJSON_Print(json);
if (jsonString) {
fprintf(file, "%s\n", jsonString);
free(jsonString); // 释放 JSON 字符串
}
// 关闭文件和删除 JSON 对象
fclose(file);
cJSON_Delete(json);
return 0;
}
void TjdUiAppPlayDialModel::AudioInit(void)
{
if (audioInitStatus_) {
static_print_info("PlayDialModel audioInitStatus_ is true");
return;
}
Audio::AudioManager &amIntance = Audio::AudioManager::GetInstance();
audioInitStatus_ = amIntance.Initialize();
playerCtr_ = std::make_shared<OHOS::Media::Player>();
// playerCallback_ = std::make_shared<RecordPlayerCallbackImpl>();
static_print_info("PlayDialModel AudioInit end!");
}
int TjdUiAppPlayDialModel::RecordStart()
{
printf("TjdUiAppPlayDialModel::RecordStart()\n");
if (recordIsRuning_) {
static_print_warn("PlayDialModel RecordStart failed, recordIsRuning_ is true");
return OHOS_FAILURE;
}
Audio::AudioManager &amIntance = Audio::AudioManager::GetInstance();
if (!isActivateAudioInterrupt_) {
static_print_info("ActivateAudioInterrupt");
// 申请焦点
sessionId_ = amIntance.MakeSessionId();
if (sessionId_ == AUDIO_SESSION_ID_NONE) {
static_print_warn("session invalid");
return OHOS_FAILURE;
}
std::shared_ptr<PlayDialInterruptListener> recordInterruptListener_ =
std::make_shared<PlayDialInterruptListener>();
interrupt_ = {AUDIO_STREAM_VOICE_RECORD, sessionId_, recordInterruptListener_};
// 激活音频中断 5s超时
if (amIntance.ActivateAudioInterrupt(interrupt_) == INTERRUPT_FAILED) {
static_print_warn("ActivateAudioInterrupt faild");
return OHOS_FAILURE;
}
isActivateAudioInterrupt_ = true;
}
lefunAiCapturer_ = std::make_shared<OHOS::Audio::AudioCapturer>();
url_ = std::string("/user/") + "lefunAi_test.opus";
pfd_.open(url_, std::ios::out | std::ios::binary);
if (!pfd_.is_open()) {
static_print_warn("open file failed");
lefunAiCapturer_.reset();
(void)amIntance.DeactivateAudioInterrupt(interrupt_);
return -1;
}
// 设置音频参数
OHOS::Audio::AudioCapturerInfo info = {};
info.inputSource = AUDIO_MIC;
info.audioFormat = AudioCodecFormat::OPUS;
info.sampleRate = 16000;
info.channelCount = 1;
info.streamType = AUDIO_STREAM_VOICE_RECORD;
info.bitWidth = AudioBitWidth::BIT_WIDTH_16;
info.sessionID = sessionId_;
if (lefunAiCapturer_->SetCapturerInfo(info) != 0) {
static_print_warn("{%s,%d} set capturer info failed", __func__, __LINE__);
(void)amIntance.DeactivateAudioInterrupt(interrupt_);
return -1;
}
// 获取每帧大小
size_t frameCount = lefunAiCapturer_->GetFrameCount();
if (!frameCount) {
static_print_warn("Can't GetFrameCount");
(void)lefunAiCapturer_->Release();
(void)amIntance.DeactivateAudioInterrupt(interrupt_);
return -1;
}
framesize_ = frameCount * info.channelCount * info.bitWidth / 8;
static_print_info("framesize_:%d", framesize_);
lefunAiRecordBuffer_ = new uint8_t[framesize_];
if (!lefunAiCapturer_->Start()) {
static_print_warn("{%s,%d} start failed", __func__, __LINE__);
lefunAiCapturer_.reset();
(void)amIntance.DeactivateAudioInterrupt(interrupt_);
// delete lefunAiCapturer_;
return -1;
}
recordIsRuning_ = false;
MediaThreadattr attr = {"lefun_ai_record", 0x2000, THREAD_SCHED_INVALID, 0, true};
threadIdHandle_ = MediaThreadCreate(
[](void *arg) -> void * {
TjdUiAppPlayDialModel::GetInstance().AudioCaptureProcess();
return nullptr;
},
NULL, &attr);
if (threadIdHandle_ == nullptr) {
static_print_warn("thread create failed");
return -1;
}
return 0;
}
void TjdUiAppPlayDialModel::RecordStop()
{
printf("TjdUiAppPlayDialModel::RecordStop()\n");
if (recordIsRuning_) {
{
std::lock_guard<std::mutex> lock(pauseMutex_);
needStop_.store(true);
needPause_.store(false); // 确保线程不会因为暂停而阻塞
}
pauseCondVar_.notify_all(); // 唤醒等待的线程
static_print_debug("LefunAi RecordStop wait thread join");
osThreadJoin(threadIdHandle_);
static_print_debug("LefunAi RecordStop thread join end");
}
LefunAiRequestEndAudioTransmit();
}
void TjdUiAppPlayDialModel::AudioCaptureProcess(void)
{
static_print_info("TjdUiAppPlayDialModel AudioCaptureProcess start");
recordIsRuning_ = true;
while (!needStop_) {
// 检查是否需要暂停和停止
std::unique_lock<std::mutex> lock(pauseMutex_);
uint64_t pauseStartTime = OHOS::HALTick::GetInstance().GetTime();
pauseCondVar_.wait(lock, [this] { return !needPause_ || needStop_; });
if (needStop_) {
static_print_debug("needStop_ is true");
break;
}
memset(lefunAiRecordBuffer_, 0, framesize_);
ret = lefunAiCapturer_->Read(lefunAiRecordBuffer_, framesize_, false);
printf("lefunAiCapturer_->Read ret:%d\n", ret);
if (ret == -1) {
static_print_warn("audioCap Read failed:0x%x", ret);
continue;
}
if (ret == OHOS::Media::ERR_RETRY_READ) {
usleep(10000);
continue;
}
pfd_.write((const char *)lefunAiRecordBuffer_, ret);
if (!pfd_) {
static_print_warn("errno:%d, errmsg:%s", errno, strerror(errno));
break;
}
TransmitAudioData(lefunAiRecordBuffer_ + 8, ret - 8);
}
static_print_info("AudioCaptureProcess end");
pfd_.close();
RecordDestroy();
}
static void resend_audio_task(void *argument)
{
osDelay(500);
// 打开文件
std::ifstream inputFile("/user/lefunAi_test.opus", std::ios::in | std::ios::binary);
if (!inputFile.is_open()) {
printf("Failed to open file: %s", "/user/lefunAi_test.opus");
return;
}
// 定义缓冲区每次读取168字节
const size_t bufferSize = 168;
uint8_t buffer[168];
// 循环读取文件并发送数据
while (inputFile.read(reinterpret_cast<char *>(buffer), bufferSize)) {
size_t bytesRead = inputFile.gcount(); // 获取实际读取的字节数
if (bytesRead > 8) {
// 只传输从第9个字节开始的数据
printf("Read %zu bytes from file\n", bytesRead);
TjdUiAppPlayDialModel::GetInstance().TransmitAudioData(buffer + 8,
bytesRead - 8); // 发送数据跳过前8个字节
osDelay(10); // 等待10ms防止数据过快导致传输失败
}
}
printf("AudioCaptureFromFile end");
inputFile.close();
TjdUiAppPlayDialModel::GetInstance().LefunAiRequestEndAudioTransmit();
osThreadTerminate(resend_audio_data_id);
}
void TjdUiAppPlayDialModel::ResendAudioData()
{
static_print_info("ResendAudioData start");
osThreadAttr_t task_attr = {"resend_audio_data_task", 0, NULL, 0, NULL, 0x1000, (osPriority_t)17, 0, 0};
resend_audio_data_id = osThreadNew(resend_audio_task, NULL, &task_attr);
if (resend_audio_data_id == NULL) {
static_print_error("resend_audio_data_task failed");
return;
}
}
void TjdUiAppPlayDialModel::RecordDestroy(void)
{
static_print_debug("RecordDestroy");
Audio::AudioManager &amIntance = Audio::AudioManager::GetInstance();
MediaMutexLock(g_lefun_ai_mutex);
if (!lefunAiCapturer_->Stop()) {
static_print_warn("Stop failed");
}
if (!lefunAiCapturer_->Release()) {
static_print_warn("Release failed");
}
delete lefunAiRecordBuffer_;
lefunAiRecordBuffer_ = nullptr;
if (amIntance.DeactivateAudioInterrupt(interrupt_) != 0) {
static_print_warn("deactivate audio interrupt failed");
}
needStop_ = false;
needPause_ = false;
lefunAiCapturer_.reset();
lefunAiCapturer_ = nullptr;
isActivateAudioInterrupt_ = false;
recordIsRuning_ = false;
MediaMutexUnLock(g_lefun_ai_mutex);
}
void TjdUiAppPlayDialModel::RequestIntoLefunAi()
{
// tjd_lefun_ai_request_into_lefun_ai();
// tjd_ble_upload_ai_func_attribute();
tjd_lefun_ai_request_into_play_dial();
tjd_ble_upload_play_dial_func_attribute((ai_picture_style_t)(TjdUiAppPlayDialModel::GetInstance().dialStyle_), 0,
0);
printf("TjdUiAppPlayDialModel::RequestIntoLefunAi() dialStyle_:%d\n", dialStyle_);
}
void TjdUiAppPlayDialModel::LefunAiRequestIntoAudioTransmit() { tjd_lefun_ai_request_into_audio_transmit(); }
void TjdUiAppPlayDialModel::LefunAiRequestStartAudioTransmit() { tjd_lefun_ai_request_start_audio_transmit(); }
void TjdUiAppPlayDialModel::LefunAiRequestExitLefunAi()
{
// tjd_lefun_ai_request_exit_lefun_ai();
tjd_lefun_ai_request_exit_play_dial();
}
void TjdUiAppPlayDialModel::LefunAiRequestEndAudioTransmit() { tjd_lefun_ai_request_end_audio_transmit(); }
void TjdUiAppPlayDialModel::LefunAiRequestImageData()
{
printf("TjdUiAppPlayDialModel::LefunAiRequestImageData()\n");
tjd_play_dial_request_diagram_generation(0, 0); //流id无效首次传0。
}
void TjdUiAppPlayDialModel::LefunAiRequestTransmitImageData()
{
printf("TjdUiAppPlayDialModel::LefunAiRequestTransmitImageData()\n");
tjd_play_dial_request_diagram_transmit(0); //原图0。
}
void TjdUiAppPlayDialModel::TransmitAudioData(uint8_t *data, uint16_t len) { tjd_ble_transmit_audio_data(data, len); }
bool TjdUiAppPlayDialModel::GetAiAudioTransFlag() { return tjd_ble_get_ai_audio_trans_flag(); }
void TjdUiAppPlayDialModel::lefun_ai_data_callback(struct data_flow *data)
{
printf("PlayDialModel data_callback");
// static_print_info("PlayDialModel data_callback");
GraphicService::GetInstance()->PostGraphicEvent([&]() {
if (data == nullptr || data->data == nullptr)
return;
data_flow = data;
if (data_flow->data_flow_type == 0) {
story_question_flag = true;
// TjdUiAppPlayDialModel::question.clear();
g_PlayDialQuestion = std::string((char *)data_flow->data, data_flow->len);
// TjdUiAppPlayDialModel::g_PlayDialQuestion(std::string((char *)data_flow->data));
printf("PlayDialModel data_callback g_PlayDialQuestion:%s\n", g_PlayDialQuestion.c_str());
} else if (data_flow->data_flow_type == 1) {
story_answer_flag = true;
// TjdUiAppPlayDialModel::g_PlayDialAnswer.clear();
// TjdUiAppPlayDialModel::g_PlayDialAnswer.append(std::string((char *)data_flow->data));
g_PlayDialAnswer += std::string((char *)data_flow->data);
}
if (story_question_flag && story_answer_flag) {
// TjdUiAppPlayDialView::GetInstance().ShowView(PLAYDIAL_AI_MAKING);//saimen
}
});
}
static OHOS::GraphicTimer *waiterTimer_ = nullptr; // 运动进行中计时器
std::atomic<bool> PlayDialWaiterTimerStart(false);
static void WaiterTimerCallback(void *arg)
{
printf("PlayDialModel WaiterTimerCallback\n");
if (PlayDialWaiterTimerStart.load()) {
printf("PlayDialModel WaiterTimerCallback start\n");
PlayDialWaiterTimerStart.store(false);
waiterTimer_->Stop();
waiterTimer_->Start();
return;
}
PlayDialWaiterTimerStart.store(false);
if (data_flow->data != NULL) {
free(data_flow->data);
data_flow->data = NULL;
}
data_flow->len = 0;
data_flow->data_flow_id = 0;
data_flow->data_flow_type = 0;
// 保存历史记录到 JSON 文件
GraphicService::GetInstance()->PostGraphicEvent([&]() {
TjdUiAppPlayDialModel::History lefunAiHistory;
TjdUiAppPlayDialModel::GetInstance().loadFromJson(&lefunAiHistory);
// printf("line = %d=======lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
story_answer_flag = false;
TjdUiAppPlayDialModel::GetInstance().addRecord(&lefunAiHistory, g_PlayDialQuestion, g_PlayDialAnswer);
// printf("line = %d=========lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
TjdUiAppPlayDialModel::GetInstance().saveToJson(&lefunAiHistory, LEFUN_AI_STORY_FILE_PATH);
g_PlayDialQuestion.clear();
g_PlayDialAnswer.clear();
});
}
void TjdUiAppPlayDialModel::DeleDataFlow(void)
{
if (data_flow->data != NULL) {
free(data_flow->data);
data_flow->data = NULL;
}
if (data_flow) {
data_flow->len = 0;
data_flow->data_flow_id = 0;
data_flow->data_flow_type = 0;
}
// 保存历史记录到 JSON 文件
History lefunAiHistory;
// printf("line = %d==================\n", __LINE__);
TjdUiAppPlayDialModel::GetInstance().loadFromJson(&lefunAiHistory);
// printf("line = %d=======lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
story_answer_flag = false;
TjdUiAppPlayDialModel::GetInstance().addRecord(&lefunAiHistory, g_PlayDialQuestion, g_PlayDialAnswer);
// printf("line = %d=========lefunAiHistory=%d==========\n", __LINE__, lefunAiHistory.total_records);
TjdUiAppPlayDialModel::GetInstance().saveToJson(&lefunAiHistory, LEFUN_AI_STORY_FILE_PATH);
g_PlayDialQuestion.clear();
g_PlayDialAnswer.clear();
}
void TjdUiAppPlayDialModel::lefun_ai_data_end_callback(struct data_flow *data)
{
printf("TjdUiAppPlayDialModel::lefun_ai_data_end_callback()\n");
TjdUiAppPlayDialView::GetInstance().Result_ = AI_RESULT_SELECT_TXT;
PlayDialWaiterTimerStart.store(true);
GraphicService::GetInstance()->PostGraphicEvent([&]() {
if (data == nullptr || data->data == nullptr) {
return;
}
data_flow = data;
if (story_question_flag && story_answer_flag) {
// TjdUiAppPlayDialView::GetInstance().ShowView(PLAYDIAL_AI_MAKING);//saimen
}
// if (waiterTimer_ == nullptr) {
// waiterTimer_ = new OHOS::GraphicTimer(5000, WaiterTimerCallback, (void *)data, false);
// waiterTimer_->Start();
// }
});
}
void TjdUiAppPlayDialModel::play_dial_app_ready_callback(bool isSuccess)
{
printf("TjdUiAppPlayDialModel::play_dial_app_ready_callback():%d\n", isSuccess);
TjdUiAppPlayDialView::GetInstance().Result_ = AI_RESULT_APP_DONE;
}
void TjdUiAppPlayDialModel::play_dial_original_end_callback(char *original_picture_name)
{
TjdUiAppPlayDialView::GetInstance().Result_ = AI_RESULT_SELECT_IMG;
g_PlayDialPath = std::string(original_picture_name);
printf("TjdUiAppPlayDialModel::play_dial_original_end_callback():%s-%s\n", original_picture_name,
g_PlayDialPath.c_str());
}
void TjdUiAppPlayDialModel::RegisterLefunAiDataCallback(lefun_ai_data_callback_t callback)
{
register_lefun_ai_data_callback(callback);
}
void TjdUiAppPlayDialModel::UnregisterLefunAiDataCallback() { unregister_lefun_ai_data_callback(); }
void TjdUiAppPlayDialModel::RegisterLefunAiDataEndCallback(lefun_ai_data_callback_t callback)
{
register_lefun_ai_data_end_callback(callback);
}
void TjdUiAppPlayDialModel::UnregisterLefunAiDataEndCallback() { unregister_lefun_ai_data_end_callback(); }
void TjdUiAppPlayDialModel::RegisterAppImageReadyCallback(play_dial_request_generate_picture_callback_t callback)
{
register_play_dial_request_generate_picture_callback(callback);
}
void TjdUiAppPlayDialModel::UnregisterAppImageReadyCallback()
{
unregister_play_dial_request_generate_picture_callback();
}
void TjdUiAppPlayDialModel::RegisterOriginalImageEndCallback(play_dial_original_callback_t callback)
{
register_play_dial_original_callback(callback);
}
void TjdUiAppPlayDialModel::UnregisterOriginalImageEndCallback() { unregister_play_dial_original_callback(); }
} // namespace TJD