提供实时的AI录音数据上传接口(蓝牙接口待添加) 1647/4
authorluozheng <1732036298@qq.com>
Tue, 18 Feb 2025 03:12:46 +0000 (11:12 +0800)
committerluozheng <1732036298@qq.com>
Tue, 18 Feb 2025 03:12:46 +0000 (11:12 +0800)
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp
code/sdk/middleware/services/media/foundation/sample/wrapper/audio_capture_wrapper.cpp
code/sdk/middleware/services/media/foundation/sample/wrapper/audio_capture_wrapper.h

index 60f0c4f..7dfd132 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:14:50
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2025-02-17 10:59:24
+ * @LastEditTime: 2025-02-18 11:07:51
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp
  */
 #include "aivoice/include/AiVoiceModel.h"
@@ -505,7 +505,8 @@ namespace OHOS
     {
 #endif
         int32_t AudioCaptureSample(int32_t argc, const char *argv[]);
-
+        int32_t streamingRecordAndSend_AI(void);
+        #define IS_SUPPORT_REALTIME_RECORD_SEND_AI 0
 #ifdef __cplusplus
     };
 #endif
@@ -523,6 +524,9 @@ namespace OHOS
         if ((view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID) != nullptr) &&
             (view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->IsVisible()))
         {
+#if IS_SUPPORT_REALTIME_RECORD_SEND_AI
+            streamingRecordAndSend_AI();//实时发送录音数据
+#else
             std::string audioPath = AiVoiceModel::GetInstance().GetAIAudioPath();
             if (uapi_delete_files(audioPath.c_str())) // 先删除文件
             {
@@ -540,7 +544,8 @@ namespace OHOS
             const char *defaultArgs[6] = {"01", "msbc", "16000", "1", "16", audioPath.c_str()};
 #endif
             uapi_save_runtime_log(RUNTIME_LOG_RECORD_START_AI);//TOOD*
-            AudioCaptureSample(6, (const char **)defaultArgs);
+            AudioCaptureSample(6, (const char **)defaultArgs);            
+#endif
         }
         return;
     }
index b475d99..f1aff05 100755 (executable)
@@ -416,6 +416,121 @@ EXIT:
     return -1;
 }
 
+/* ------------------------------- AI录音数据上传接口 ------------------------------- */
+#define AI_RECORD_TEST 1 //若需要调试可以打开该宏
+static void* AudioCaptureProcess_AI(void* arg)
+{
+    #if AI_RECORD_TEST
+    FILE *pfd = (FILE *)arg;
+    #endif 
+    int32_t readCnt = 0;
+    Timestamp timeStamp;
+    g_audioSourceProcessInput.bThreadRun = true;
+    while (!g_sample.needStop && !g_interruptHintStop) {
+        int32_t ret = g_audioCap->Read(g_audioSourceProcessInput.buffer, g_audioSourceProcessInput.framesize, false);
+        if (ret == -1) {
+            MEDIA_ERR_LOG("audioCap Read failed:0x%x", ret);
+            continue;
+        }
+        if (ret == ERR_RETRY_READ) {
+            usleep(READ_RETRY_TIME_US);
+            continue;
+        }
+        #if AI_RECORD_TEST
+        int32_t writeLen = fwrite(g_audioSourceProcessInput.buffer, 1, ret, pfd);
+        if (writeLen != ret) {
+            MEDIA_ERR_LOG("errno:%d, errmsg:%s", errno, strerror(errno));
+            break;
+        }
+        #endif
+        // 蓝牙接口发送实时录音数据
+
+        if (readCnt++ > READ_COUNT_MAX) {
+            break;
+        }
+        if (readCnt % GET_AUDIO_TIME_INTERVAL_TIMES == 0) {
+            if (g_audioCap->GetAudioTime(timeStamp, Timestamp::Timebase::MONOTONIC)) {
+                MEDIA_INFO_LOG("read %d frames timestamp seconds:%ld, nanoseconds:%ld",
+                    readCnt, timeStamp.time.tv_sec, timeStamp.time.tv_nsec);
+            }
+        }
+        MEDIA_INFO_LOG("audioCap Read readCnt = %d, size = %d", readCnt, ret);
+    }
+    #if AI_RECORD_TEST
+    fclose(pfd);
+    #endif
+    AudioCaptureStop();
+    MEDIA_INFO_LOG("AudioCaptureProcess end");
+    return NULL;
+}
+
+int32_t streamingRecordAndSend_AI(void)
+{
+    const char *argv[] = {"01", "pcm", "16000", "1", "16", "/user/aiRecord.pcm"};
+    int32_t argc = 6;
+    if (g_audioSourceProcessInput.bThreadRun) {
+        return HandleAudioCaptureCmd(argc, argv);
+    }
+    std::string filePath = "";
+    g_sample.needStop = false;
+    g_interruptHintStop = false;
+    g_sample.mutex = MediaMutexCreate(nullptr);
+    if (g_sample.mutex == nullptr) {
+        MEDIA_ERR_LOG("create mutex failed");
+        g_audioSourceProcessInput.bThreadRun = false;
+        return -1;
+    }
+    SampleAudioCapturerInfo audioCapturerInfo = {};
+    AudioSession sessionId = AUDIO_SESSION_ID_NONE;
+    FILE *pfd = nullptr;
+    MediaThreadattr attr = { "AudioCaptureTask", 0x2000, THREAD_SCHED_INVALID, 0, true };
+    int32_t ret = CheckInputParam(argc, argv);
+    if (ret != 0) {
+        goto EXIT;
+    }
+    ret = AudioCaptureGetInfo(argv, audioCapturerInfo, filePath);
+    if (ret != 0) {
+        goto EXIT;
+    }
+    ret = ActivateAudioInterrupt(sessionId);
+    if (ret != 0) {
+        goto EXIT;
+    }
+    g_audioCap = std::make_shared<AudioCapturer>();
+    if (g_audioCap == nullptr || g_audioCap.get() == nullptr) {
+        MEDIA_ERR_LOG("audio capture is nullptr");
+        (void)g_amInstance.DeactivateAudioInterrupt(g_sample.interrupt);
+        goto EXIT;
+    }
+    #if AI_RECORD_TEST
+    pfd = fopen(filePath.c_str(), "w+");
+    if (pfd == NULL) {
+        MEDIA_ERR_LOG("open file failed");
+        g_audioCap.reset();
+        (void)g_amInstance.DeactivateAudioInterrupt(g_sample.interrupt);
+        goto EXIT;
+    }
+    #endif
+    audioCapturerInfo.sessionID = sessionId;
+    audioCapturerInfo.inputSource = AUDIO_MIC;
+    audioCapturerInfo.streamType = AUDIO_STREAM_VOICE_RECORD;
+    ret = AudioCaptureSetInfo(audioCapturerInfo);
+    if (ret != 0) {
+        fclose(pfd);
+        g_audioCap.reset();
+        (void)g_amInstance.DeactivateAudioInterrupt(g_sample.interrupt);
+        goto EXIT;
+    }
+    g_sample.audioCaptureProcess = MediaThreadCreate(AudioCaptureProcess_AI, pfd, &attr);
+    if (g_sample.audioCaptureProcess == nullptr) {
+        MEDIA_ERR_LOG("thread create failed");
+        goto EXIT;
+    }
+    return 0;
+EXIT:
+    g_audioSourceProcessInput.bThreadRun = false;
+    return -1;
+}
 #ifdef __cplusplus
 };
 #endif