From c4582f0aa425f8c9a100934c36c42ce094b349a8 Mon Sep 17 00:00:00 2001 From: saga Date: Sun, 21 Apr 2024 19:15:01 +0800 Subject: [PATCH] support voip 20ms lowlatency audio Signed-off-by: saga --- common/include/audio_types.h | 1 + common/include/daudio_constants.h | 1 - .../src/daudio_manager_callback.cpp | 1 + .../managersource/include/dmic_dev.h | 2 +- .../managersource/include/dspeaker_dev.h | 1 - .../managersource/src/dmic_dev.cpp | 19 ++++++++++++------- .../managersource/src/dspeaker_dev.cpp | 11 ++++++----- services/common/audioparam/audio_param.h | 3 ++- 8 files changed, 23 insertions(+), 16 deletions(-) diff --git a/common/include/audio_types.h b/common/include/audio_types.h index 7f3b84ca..f9391267 100644 --- a/common/include/audio_types.h +++ b/common/include/audio_types.h @@ -118,6 +118,7 @@ enum AudioCategory { AUDIO_IN_RINGTONE, /**< Ringtone */ AUDIO_IN_CALL, /**< Call */ AUDIO_MMAP_NOIRQ, /**< Mmap mode */ + AUDIO_MMAP_VOIP = 8, /**< Mmap Voip mode */ }; /** diff --git a/common/include/daudio_constants.h b/common/include/daudio_constants.h index 6034fc0b..1f9cf97d 100644 --- a/common/include/daudio_constants.h +++ b/common/include/daudio_constants.h @@ -66,7 +66,6 @@ constexpr uint32_t DAUDIO_MAX_RECV_DATA_LEN = 104857600; constexpr uint32_t DAUDIO_MAX_JSON_LEN = 1024; static constexpr int64_t AUDIO_OFFSET_FRAME_NUM = 10; -static constexpr int64_t LOW_LATENCY_INTERVAL_NS = 5000000; static constexpr int64_t LOW_LATENCY_CLIENT_INTERVAL_NS = 20000000; static constexpr int64_t MAX_TIME_INTERVAL_US = 23000; diff --git a/services/audiohdiproxy/src/daudio_manager_callback.cpp b/services/audiohdiproxy/src/daudio_manager_callback.cpp index 6cec5c11..ce50485e 100644 --- a/services/audiohdiproxy/src/daudio_manager_callback.cpp +++ b/services/audiohdiproxy/src/daudio_manager_callback.cpp @@ -77,6 +77,7 @@ int32_t DAudioManagerCallback::GetAudioParamHDF(const AudioParameter& param, Aud paramHDF.streamUsage = StreamUsage::STREAM_USAGE_MEDIA; break; case AUDIO_IN_COMMUNICATION: + case AUDIO_MMAP_VOIP: paramHDF.streamUsage = StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION; break; case AUDIO_IN_RINGTONE: diff --git a/services/audiomanager/managersource/include/dmic_dev.h b/services/audiomanager/managersource/include/dmic_dev.h index 87adce99..e1257abe 100644 --- a/services/audiomanager/managersource/include/dmic_dev.h +++ b/services/audiomanager/managersource/include/dmic_dev.h @@ -91,6 +91,7 @@ private: static constexpr size_t DATA_QUEUE_HALF_SIZE = DATA_QUEUE_MAX_SIZE >> 1U; static constexpr size_t LOW_LATENCY_DATA_QUEUE_MAX_SIZE = 30; static constexpr size_t LOW_LATENCY_DATA_QUEUE_HALF_SIZE = 10; + static constexpr size_t LOW_LATENCY_JITTER_TIME_MS = 50; static constexpr uint32_t MMAP_WAIT_FRAME_US = 5000; static constexpr const char* ENQUEUE_THREAD = "micEnqueueTh"; const std::string MIC_DEV_FILENAME = DUMP_FILE_PATH + "/source_mic_read_from_trans.pcm"; @@ -111,7 +112,6 @@ private: AudioParamHDF paramHDF_; AudioParam param_; - uint32_t timeInterval_ = 5; uint32_t insertFrameCnt_ = 0; std::atomic isExistedEmpty_ = false; size_t dataQueSize_ = 0; diff --git a/services/audiomanager/managersource/include/dspeaker_dev.h b/services/audiomanager/managersource/include/dspeaker_dev.h index dc68e221..4340a08b 100644 --- a/services/audiomanager/managersource/include/dspeaker_dev.h +++ b/services/audiomanager/managersource/include/dspeaker_dev.h @@ -100,7 +100,6 @@ private: AudioParamHDF paramHDF_; AudioParam param_; - uint32_t timeInterval_ = 5; sptr ashmem_ = nullptr; std::atomic isEnqueueRunning_ = false; int32_t ashmemLength_ = -1; diff --git a/services/audiomanager/managersource/src/dmic_dev.cpp b/services/audiomanager/managersource/src/dmic_dev.cpp index ddf186d2..b7466826 100644 --- a/services/audiomanager/managersource/src/dmic_dev.cpp +++ b/services/audiomanager/managersource/src/dmic_dev.cpp @@ -176,7 +176,11 @@ int32_t DMicDev::SetParameters(const int32_t streamId, const AudioParamHDF ¶ param_.comParam.bitFormat = paramHDF_.bitFormat; param_.comParam.codecType = AudioCodecType::AUDIO_CODEC_AAC; param_.comParam.frameSize = paramHDF_.frameSize; - param_.captureOpts.sourceType = SOURCE_TYPE_MIC; + if (paramHDF_.streamUsage == StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION) { + param_.captureOpts.sourceType = SOURCE_TYPE_VOICE_COMMUNICATION; + } else { + param_.captureOpts.sourceType = SOURCE_TYPE_MIC; + } param_.captureOpts.capturerFlags = paramHDF_.capturerFlags; return DH_SUCCESS; } @@ -386,11 +390,12 @@ void DMicDev::EnqueueThread() { writeIndex_ = 0; writeNum_ = 0; - DHLOGD("Enqueue thread start, lengthPerWrite length: %{public}d.", lengthPerTrans_); + int64_t timeIntervalns = paramHDF_.period * AUDIO_NS_PER_SECOND / AUDIO_MS_PER_SECOND; + DHLOGD("Enqueue thread start, lengthPerWrite length: %{public}d, interval: %{public}d.", lengthPerTrans_, + paramHDF_.period); FillJitterQueue(); while (ashmem_ != nullptr && isEnqueueRunning_.load()) { - int64_t timeOffset = UpdateTimeOffset(frameIndex_, LOW_LATENCY_INTERVAL_NS, - startTime_); + int64_t timeOffset = UpdateTimeOffset(frameIndex_, timeIntervalns, startTime_); DHLOGD("Write frameIndex: %{public}" PRId64", timeOffset: %{public}" PRId64, frameIndex_, timeOffset); std::shared_ptr audioData = nullptr; { @@ -419,10 +424,10 @@ void DMicDev::EnqueueThread() if (writeIndex_ >= ashmemLength_) { writeIndex_ = 0; } - writeNum_ += static_cast(CalculateSampleNum(param_.comParam.sampleRate, timeInterval_)); + writeNum_ += static_cast(CalculateSampleNum(param_.comParam.sampleRate, paramHDF_.period)); GetCurrentTime(writeTvSec_, writeTvNSec_); frameIndex_++; - AbsoluteSleep(startTime_ + frameIndex_ * LOW_LATENCY_INTERVAL_NS - timeOffset); + AbsoluteSleep(startTime_ + frameIndex_ * timeIntervalns - timeOffset); } } @@ -431,7 +436,7 @@ void DMicDev::FillJitterQueue() while (isEnqueueRunning_.load()) { { std::lock_guard lock(dataQueueMtx_); - if (dataQueue_.size() >= LOW_LATENCY_DATA_QUEUE_HALF_SIZE) { + if (dataQueue_.size() >= (LOW_LATENCY_JITTER_TIME_MS / paramHDF_.period)) { break; } } diff --git a/services/audiomanager/managersource/src/dspeaker_dev.cpp b/services/audiomanager/managersource/src/dspeaker_dev.cpp index 4a810487..232faebd 100644 --- a/services/audiomanager/managersource/src/dspeaker_dev.cpp +++ b/services/audiomanager/managersource/src/dspeaker_dev.cpp @@ -371,10 +371,11 @@ void DSpeakerDev::EnqueueThread() readIndex_ = 0; readNum_ = 0; frameIndex_ = 0; - DHLOGI("Enqueue thread start, lengthPerRead length: %{public}d.", lengthPerTrans_); + int64_t timeIntervalns = paramHDF_.period * AUDIO_NS_PER_SECOND / AUDIO_MS_PER_SECOND; + DHLOGI("Enqueue thread start, lengthPerRead length: %{public}d, interval: %{pubic}d.", lengthPerTrans_, + paramHDF_.period); while (ashmem_ != nullptr && isEnqueueRunning_.load()) { - int64_t timeOffset = UpdateTimeOffset(frameIndex_, LOW_LATENCY_INTERVAL_NS, - startTime_); + int64_t timeOffset = UpdateTimeOffset(frameIndex_, timeIntervalns, startTime_); DHLOGD("Read frameIndex: %{public}" PRId64", timeOffset: %{public}" PRId64, frameIndex_, timeOffset); auto readData = ashmem_->ReadFromAshmem(lengthPerTrans_, readIndex_); DHLOGI("Read from ashmem success! read index: %{public}d, readLength: %{public}d.", @@ -400,10 +401,10 @@ void DSpeakerDev::EnqueueThread() if (readIndex_ >= ashmemLength_) { readIndex_ = 0; } - readNum_ += static_cast(CalculateSampleNum(param_.comParam.sampleRate, timeInterval_)); + readNum_ += static_cast(CalculateSampleNum(param_.comParam.sampleRate, paramHDF_.period)); GetCurrentTime(readTvSec_, readTvNSec_); frameIndex_++; - AbsoluteSleep(startTime_ + frameIndex_ * LOW_LATENCY_INTERVAL_NS - timeOffset); + AbsoluteSleep(startTime_ + frameIndex_ * timeIntervalns - timeOffset); } } diff --git a/services/common/audioparam/audio_param.h b/services/common/audioparam/audio_param.h index 77453d21..fe8194dd 100644 --- a/services/common/audioparam/audio_param.h +++ b/services/common/audioparam/audio_param.h @@ -37,7 +37,8 @@ typedef enum { typedef enum { SOURCE_TYPE_INVALID = -1, SOURCE_TYPE_MIC, - SOURCE_TYPE_VOICE_CALL + SOURCE_TYPE_VOICE_CALL = 4, + SOURCE_TYPE_VOICE_COMMUNICATION = 7 } SourceType; typedef enum { -- Gitee