From d50168d62f7e7659f46de0d9573ccc574e4b980e Mon Sep 17 00:00:00 2001 From: hwwuhaobo Date: Fri, 7 Jul 2023 15:03:10 +0800 Subject: [PATCH 1/3] add fast audio stream Signed-off-by: hwwuhaobo fix confilct Signed-off-by: Bobie --- .../audiostream/include/fast_audio_stream.h | 190 ++++ services/audio_service/BUILD.gn | 34 + .../client/include/audio_service_client.h | 3 +- .../client/src/fast_audio_stream.cpp | 829 ++++++++++++++++++ .../client/src/i_audio_stream.cpp | 2 + .../fast_audio_stream_playback_test.cpp | 192 ++++ 6 files changed, 1249 insertions(+), 1 deletion(-) create mode 100644 frameworks/native/audiostream/include/fast_audio_stream.h create mode 100644 services/audio_service/client/src/fast_audio_stream.cpp create mode 100644 services/audio_service/test/example/fast_audio_stream_playback_test.cpp diff --git a/frameworks/native/audiostream/include/fast_audio_stream.h b/frameworks/native/audiostream/include/fast_audio_stream.h new file mode 100644 index 0000000000..da6517c0fb --- /dev/null +++ b/frameworks/native/audiostream/include/fast_audio_stream.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FAST_AUDIO_STREAM_H +#define FAST_AUDIO_STREAM_H + +#include +#include +#include "timestamp.h" +#include "event_handler.h" +#include "event_runner.h" +#include "audio_info.h" + +#include "audio_process_in_client.h" +#include "i_audio_stream.h" + +namespace OHOS { +namespace AudioStandard { + +class FastAudioStreamCallback : public AudioDataCallback { +public: + FastAudioStreamCallback(const std::shared_ptr &procClient, + const std::shared_ptr &callback) + : procClient_(procClient), renderCallback_(callback) {}; + virtual ~FastAudioStreamCallback() = default; + + void OnHandleData(size_t length) override; + +private: + // static constexpr long WAV_HEADER_SIZE = 42; + std::shared_ptr procClient_ = nullptr; + std::shared_ptr renderCallback_ = nullptr; + // int32_t loopCount_ = 2; // play 2 times + // AudioMode clientMode_ = AUDIO_MODE_PLAYBACK; + // bool needSkipWavHeader_ = true; + // bool renderFinish_ = false; + // FILE *spkWavFile_ = nullptr; + // FILE *micWavFile_ = nullptr; +}; + + + +class FastAudioStream : public IAudioStream { +public: + FastAudioStream(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid); + virtual ~FastAudioStream(); + + void SetClientID(int32_t clientPid, int32_t clientUid) override; + + void SetRendererInfo(const AudioRendererInfo &rendererInfo) override; + void SetCapturerInfo(const AudioCapturerInfo &capturerInfo) override; + int32_t SetAudioStreamInfo(const AudioStreamParams info, + const std::shared_ptr &proxyObj) override; + int32_t GetAudioStreamInfo(AudioStreamParams &info) override; + bool VerifyClientMicrophonePermission(uint32_t appTokenId, int32_t appUid, bool privacyFlag, + AudioPermissionState state) override; + bool getUsingPemissionFromPrivacy(const std::string &permissionName, uint32_t appTokenId, + AudioPermissionState state) override; + int32_t GetAudioSessionID(uint32_t &sessionID) override; + State GetState() override; + bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) override; + int32_t GetBufferSize(size_t &bufferSize) override; + int32_t GetFrameCount(uint32_t &frameCount) override; + int32_t GetLatency(uint64_t &latency) override; + int32_t SetAudioStreamType(AudioStreamType audioStreamType) override; + int32_t SetVolume(float volume) override; + float GetVolume() override; + int32_t SetRenderRate(AudioRendererRate renderRate) override; + AudioRendererRate GetRenderRate() override; + int32_t SetStreamCallback(const std::shared_ptr &callback) override; + + // callback mode api + int32_t SetRenderMode(AudioRenderMode renderMode) override; + AudioRenderMode GetRenderMode() override; + int32_t SetRendererWriteCallback(const std::shared_ptr &callback) override; + int32_t SetCaptureMode(AudioCaptureMode captureMode) override; + AudioCaptureMode GetCaptureMode() override; + int32_t SetCapturerReadCallback(const std::shared_ptr &callback) override; + int32_t GetBufferDesc(BufferDesc &bufDesc) override; + int32_t GetBufQueueState(BufferQueueState &bufState) override; + int32_t Enqueue(const BufferDesc &bufDesc) override; + int32_t Clear() override; + + int32_t SetLowPowerVolume(float volume) override; + float GetLowPowerVolume() override; + float GetSingleStreamVolume() override; + AudioEffectMode GetAudioEffectMode() override; + int32_t SetAudioEffectMode(AudioEffectMode effectMode) override; + + void SetInnerCapturerState(bool isInnerCapturer) override; + void SetPrivacyType(AudioPrivacyType privacyType) override; + + // std::vector GetSupportedFormats() const; + // std::vector GetSupportedEncodingTypes() const; + // std::vector GetSupportedSamplingRates() const; + + // Common APIs + bool StartAudioStream(StateChangeCmdType cmdType = CMD_FROM_CLIENT) override; + bool PauseAudioStream(StateChangeCmdType cmdType = CMD_FROM_CLIENT) override; + bool StopAudioStream() override; + bool ReleaseAudioStream(bool releaseRunner = true) override; + bool FlushAudioStream() override; + + // Playback related APIs + bool DrainAudioStream() override; + size_t Write(uint8_t *buffer, size_t buffer_size) override; + + // Recording related APIs + int32_t Read(uint8_t &buffer, size_t userSize, bool isBlockingRead) override; + + uint32_t GetUnderflowCount() override; + void SetRendererPositionCallback(int64_t markPosition, const std::shared_ptr &callback) + override; + void UnsetRendererPositionCallback() override; + void SetRendererPeriodPositionCallback(int64_t markPosition, + const std::shared_ptr &callback) override; + void UnsetRendererPeriodPositionCallback() override; + void SetCapturerPositionCallback(int64_t markPosition, const std::shared_ptr &callback) + override; + void UnsetCapturerPositionCallback() override; + void SetCapturerPeriodPositionCallback(int64_t markPosition, + const std::shared_ptr &callback) override; + void UnsetCapturerPeriodPositionCallback() override; + int32_t SetRendererSamplingRate(uint32_t sampleRate) override; + uint32_t GetRendererSamplingRate() override; + int32_t SetBufferSizeInMsec(int32_t bufferSizeInMsec) override; + void SetApplicationCachePath(const std::string cachePath) override; + + +private: + // AudioStreamType eStreamType_; + // AudioMode eMode_; + // State state_; + // bool resetTime_; + // uint64_t resetTimestamp_; + // struct timespec baseTimestamp_ = {0}; + // AudioRenderMode renderMode_; + // AudioCaptureMode captureMode_; + // std::queue freeBufferQ_; + // std::queue filledBufferQ_; + // std::array, MAX_WRITECB_NUM_BUFFERS> writeBufferPool_ = {}; + // std::array, MAX_READCB_NUM_BUFFERS> readBufferPool_ = {}; + // std::unique_ptr writeThread_ = nullptr; + // std::unique_ptr readThread_ = nullptr; + // bool isReadyToWrite_; + // bool isReadyToRead_; + // void WriteCbTheadLoop(); + // void ReadCbThreadLoop(); + // std::unique_ptr audioStreamTracker_; + // AudioRendererInfo rendererInfo_; + // AudioCapturerInfo capturerInfo_; + // uint32_t sessionId_; + + // bool isFirstRead_; + // bool isFirstWrite_; + + // std::mutex bufferQueueLock_; + // std::condition_variable bufferQueueCV_; + AudioStreamType eStreamType_; + AudioMode eMode_; + std::shared_ptr spkProcessClient_ = nullptr; + std::shared_ptr spkProcClientCb_ = nullptr; + AudioRendererInfo rendererInfo_; + AudioCapturerInfo capturerInfo_; + State state_; + uint32_t sessionId_; + std::string cachePath_ = ""; + uint32_t rendererSampleRate_; + uint32_t underFlowCount_; + AudioEffectMode effectMode_; + AudioRenderMode renderMode_; + AudioCaptureMode captureMode_; + AudioRendererRate renderRate_; + int32_t clientPid_ = 0; + int32_t clientUid_ = 0; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // FAST_AUDIO_STREAM_H diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index 97d109a738..f0172f249c 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -116,6 +116,7 @@ ohos_shared_library("audio_client") { "client/src/audio_stream_manager.cpp", "client/src/audio_stream_tracker.cpp", "client/src/audio_system_manager.cpp", + "client/src/fast_audio_stream.cpp", "client/src/i_audio_stream.cpp", "client/src/policy_provider_stub.cpp", ] @@ -403,6 +404,39 @@ ohos_executable("audio_service_playback_test") { subsystem_name = "multimedia" } +ohos_executable("audio_faststream_playback_test") { + install_enable = false + + sources = [ "test/example/fast_audio_stream_playback_test.cpp" ] + + configs = [ ":audio_client_public_config" ] + + deps = [ + ":audio_client", + "../../frameworks/native/audiorenderer:audio_renderer", + ] + + include_dirs = [ + "../../../../foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "../../../../utils/system/safwk/native/include", + "../../../../commonlibrary/c_utils/base/include", + "$pulseaudio_dir/src", + "$pulseaudio_dir/confgure/src", + "$pulseaudio_dir/include", + "$pulseaudio_build_path/include", + "//third_party/bounds_checking_function/include", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "init:libbegetutil", + ] + + part_name = "audio_framework" + subsystem_name = "multimedia" +} + ohos_executable("audio_service_record_test") { install_enable = false diff --git a/services/audio_service/client/include/audio_service_client.h b/services/audio_service/client/include/audio_service_client.h index 5ffb28e26e..648bf157b2 100644 --- a/services/audio_service/client/include/audio_service_client.h +++ b/services/audio_service/client/include/audio_service_client.h @@ -277,8 +277,9 @@ public: uint8_t GetSampleSize() const; void SetStreamInnerCapturerState(bool isInnerCapturer); - void SetStreamPrivacyType(AudioPrivacyType privacyType); + void SetInnerCapturerState(bool isInnerCapturer) override; + void SetPrivacyType(AudioPrivacyType privacyType) override; /** * Provides the underflow count required for this audio stream diff --git a/services/audio_service/client/src/fast_audio_stream.cpp b/services/audio_service/client/src/fast_audio_stream.cpp new file mode 100644 index 0000000000..eff0682906 --- /dev/null +++ b/services/audio_service/client/src/fast_audio_stream.cpp @@ -0,0 +1,829 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "audio_errors.h" +#include "audio_log.h" +#include "audio_utils.h" + +#include "fast_audio_stream.h" + +using namespace std; + +namespace OHOS { +namespace AudioStandard { +FastAudioStream::FastAudioStream(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid) + : eStreamType_(eStreamType), + eMode_(eMode), + state_(NEW), + renderMode_(RENDER_MODE_NORMAL), + captureMode_(CAPTURE_MODE_NORMAL) +{ + AUDIO_DEBUG_LOG("FastAudioStream ctor, appUID = %{public}d", appUid); + // audioStreamTracker_ = std::make_unique(eMode, appUid); +} + +FastAudioStream::~FastAudioStream() +{ + if (state_ != RELEASED && state_ != NEW) { + ReleaseAudioStream(false); + } +} + +void FastAudioStream::SetClientID(int32_t clientPid, int32_t clientUid) +{ + //todo + AUDIO_DEBUG_LOG("Set client PID: %{public}d, UID: %{public}d", clientPid, clientUid); + clientPid_ = clientPid; + clientUid_ = clientUid; +} + +void FastAudioStream::SetRendererInfo(const AudioRendererInfo &rendererInfo) +{ + rendererInfo_ = rendererInfo; +} + +void FastAudioStream::SetCapturerInfo(const AudioCapturerInfo &capturerInfo) +{ + capturerInfo_ = capturerInfo; +} + +int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, + const std::shared_ptr &proxyObj) +{ + AUDIO_INFO_LOG("FastAudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d," + " stream type: %{public}d", info.samplingRate, info.channels, info.format, eStreamType_); + // if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) { + // AUDIO_ERR_LOG("FastAudioStream: Unsupported audio parameter"); + // return ERR_NOT_SUPPORTED; + // } + if (state_ != NEW) { + AUDIO_INFO_LOG("FastAudioStream: State is not new, release existing stream"); + StopAudioStream(); + ReleaseAudioStream(false); + } + if (eMode_ == AUDIO_MODE_PLAYBACK) { + AUDIO_DEBUG_LOG("FastAudioStream: Initialize playback"); + // if (!IsRendererChannelValid(info.channels)) { + // AUDIO_ERR_LOG("FastAudioStream: Invalid sink channel %{public}d", info.channels); + // return ERR_NOT_SUPPORTED; + // } + AudioProcessConfig config; + config.appInfo.appPid = clientPid_; + config.appInfo.appUid = clientUid_; + config.audioMode = eMode_; + config.rendererInfo.contentType = CONTENT_TYPE_MUSIC; + config.rendererInfo.streamUsage = STREAM_USAGE_MEDIA; + config.rendererInfo.rendererFlags = 4; // 4 for test + config.streamInfo.channels = STEREO; + config.streamInfo.encoding = ENCODING_PCM; + config.streamInfo.format = SAMPLE_S16LE; + config.streamInfo.samplingRate = SAMPLE_RATE_48000; + config.isRemote = true; + spkProcessClient_ = AudioProcessInClient::Create(config); + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_INVALID_HANDLE, + "Client test creat process client fail."); + } else if (eMode_ == AUDIO_MODE_RECORD) { + AUDIO_DEBUG_LOG("FastAudioStream: Initialize recording"); + // if (!IsCapturerChannelValid(info.channels)) { + // AUDIO_ERR_LOG("FastAudioStream: Invalid source channel %{public}d", info.channels); + // return ERR_NOT_SUPPORTED; + // } + } else { + AUDIO_ERR_LOG("FastAudioStream: error eMode."); + return ERR_INVALID_OPERATION; + } + + state_ = PREPARED; + return SUCCESS; +} + +int32_t FastAudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo) +{ + AUDIO_INFO_LOG("GetAudioStreamInfo in"); + // if (GetAudioStreamParams(audioStreamInfo) != 0) { + // return ERR_OPERATION_FAILED; + // } + + return SUCCESS; +} + +bool FastAudioStream::VerifyClientMicrophonePermission(uint32_t appTokenId, int32_t appUid, bool privacyFlag, + AudioPermissionState state) +{ + AUDIO_INFO_LOG("VerifyClientPermission in"); + // return AudioServiceClient::VerifyClientPermission(permissionName, appTokenId, appUid, privacyFlag, state); + return true; +} + +bool FastAudioStream::getUsingPemissionFromPrivacy(const std::string &permissionName, uint32_t appTokenId, + AudioPermissionState state) +{ + AUDIO_INFO_LOG("getUsingPemissionFromPrivacy in"); + // return AudioServiceClient::getUsingPemissionFromPrivacy(permissionName, appTokenId, state); + return true; +} + +int32_t FastAudioStream::GetAudioSessionID(uint32_t &sessionID) +{ + // wuhaobo todo SessionId 如何实现? AudioServiceClient::GetSessionID + AUDIO_INFO_LOG("GetAudioSessionID in"); + sessionID = 1; // test + // if ((state_ == RELEASED) || (state_ == NEW)) { + // return ERR_ILLEGAL_STATE; + // } + + // if (GetSessionID(sessionID) != -1) { + // return ERR_INVALID_INDEX; + // } + + // sessionId_ = sessionID; + + return SUCCESS; +} + +State FastAudioStream::GetState() +{ + return state_; +} + +bool FastAudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) +{ + AUDIO_INFO_LOG("GetAudioTime in"); + // if (state_ == STOPPED) { + // return false; + // } + // uint64_t paTimeStamp = 0; + // if (GetCurrentTimeStamp(paTimeStamp) == SUCCESS) { + // if (resetTime_) { + // AUDIO_INFO_LOG("AudioStream::GetAudioTime resetTime_ %{public}d", resetTime_); + // resetTime_ = false; + // resetTimestamp_ = paTimeStamp; + // } + + // timestamp.time.tv_sec = static_cast((paTimeStamp - resetTimestamp_) / TIME_CONVERSION_US_S); + // timestamp.time.tv_nsec + // = static_cast(((paTimeStamp - resetTimestamp_) - (timestamp.time.tv_sec * TIME_CONVERSION_US_S)) + // * TIME_CONVERSION_NS_US); + // timestamp.time.tv_sec += baseTimestamp_.tv_sec; + // timestamp.time.tv_nsec += baseTimestamp_.tv_nsec; + // timestamp.time.tv_sec += (timestamp.time.tv_nsec / TIME_CONVERSION_NS_S); + // timestamp.time.tv_nsec = (timestamp.time.tv_nsec % TIME_CONVERSION_NS_S); + + // return true; + // } + return false; +} + +int32_t FastAudioStream::GetBufferSize(size_t &bufferSize) +{ + AUDIO_INFO_LOG("GetBufferSize in"); + // if (GetMinimumBufferSize(bufferSize) != 0) { + // return ERR_OPERATION_FAILED; + // } + + return SUCCESS; +} + +int32_t FastAudioStream::GetFrameCount(uint32_t &frameCount) +{ + AUDIO_INFO_LOG("GetFrameCount in"); + // if (GetMinimumFrameCount(frameCount) != 0) { + // return ERR_OPERATION_FAILED; + // } + + return SUCCESS; +} + +int32_t FastAudioStream::GetLatency(uint64_t &latency) +{ + AUDIO_INFO_LOG("GetLatency in"); + // if (GetAudioLatency(latency) != SUCCESS) { + // return ERR_OPERATION_FAILED; + // } else { + // return SUCCESS; + // } + return SUCCESS; +} + +int32_t FastAudioStream::SetAudioStreamType(AudioStreamType audioStreamType) +{ + AUDIO_INFO_LOG("SetAudioStreamType in"); + return SUCCESS; +} + +int32_t FastAudioStream::SetVolume(float volume) +{ + AUDIO_INFO_LOG("SetVolume in"); + // return SetStreamVolume(volume); + return SUCCESS; +} + +float FastAudioStream::GetVolume() +{ + return 0.0f; +} + +int32_t FastAudioStream::SetRenderRate(AudioRendererRate renderRate) +{ + renderRate_ = renderRate; + return SUCCESS; +} + +AudioRendererRate FastAudioStream::GetRenderRate() +{ + return renderRate_; +} + +int32_t FastAudioStream::SetStreamCallback(const std::shared_ptr &callback) +{ + AUDIO_INFO_LOG("SetStreamCallback in"); + // if (callback == nullptr) { + // AUDIO_ERR_LOG("AudioStream::SetStreamCallback failed. callback == nullptr"); + // return ERR_INVALID_PARAM; + // } + + // SaveStreamCallback(callback); + + return SUCCESS; +} + +int32_t FastAudioStream::SetRenderMode(AudioRenderMode renderMode) +{ + AUDIO_INFO_LOG("SetRenderMode in"); + renderMode_ = renderMode; + // int32_t ret = SetAudioRenderMode(renderMode); + // if (ret) { + // AUDIO_ERR_LOG("AudioStream::SetRenderMode: renderMode: %{public}d failed", renderMode); + // return ERR_OPERATION_FAILED; + // } + // renderMode_ = renderMode; + + // lock_guard lock(bufferQueueLock_); + + // for (int32_t i = 0; i < MAX_WRITECB_NUM_BUFFERS; ++i) { + // size_t length; + // GetMinimumBufferSize(length); + // AUDIO_INFO_LOG("AudioServiceClient:: GetMinimumBufferSize: %{public}zu", length); + + // writeBufferPool_[i] = std::make_unique(length); + // if (writeBufferPool_[i] == nullptr) { + // AUDIO_INFO_LOG( + // "AudioServiceClient::GetBufferDescriptor writeBufferPool_[i]==nullptr. Allocate memory failed."); + // return ERR_OPERATION_FAILED; + // } + + // BufferDesc bufDesc {}; + // bufDesc.buffer = writeBufferPool_[i].get(); + // bufDesc.bufLength = length; + // freeBufferQ_.emplace(bufDesc); + // } + return SUCCESS; +} + +AudioRenderMode FastAudioStream::GetRenderMode() +{ + AUDIO_INFO_LOG("GetRenderMode in"); + return renderMode_; +} + +int32_t FastAudioStream::SetRendererWriteCallback(const std::shared_ptr &callback) +{ + AUDIO_INFO_LOG("SetRendererWriteCallback in."); + if (!callback || !spkProcessClient_) { + AUDIO_ERR_LOG("SetRendererWriteCallback callback is nullptr"); + return ERR_INVALID_PARAM; + } + spkProcClientCb_ = std::make_shared(spkProcessClient_, callback); + int32_t ret = spkProcessClient_->SaveDataCallback(spkProcClientCb_); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret); + return SUCCESS; +} + +int32_t FastAudioStream::SetCaptureMode(AudioCaptureMode captureMode) +{ + AUDIO_INFO_LOG("SetCaptureMode in."); + captureMode_ = captureMode; + // int32_t ret = SetAudioCaptureMode(captureMode); + // if (ret) { + // AUDIO_ERR_LOG("FastAudioStream::SetCaptureMode: captureMode: %{public}d failed", captureMode); + // return ERR_OPERATION_FAILED; + // } + // captureMode_ = captureMode; + + // lock_guard lock(bufferQueueLock_); + + // for (int32_t i = 0; i < MAX_READCB_NUM_BUFFERS; ++i) { + // size_t length; + // GetMinimumBufferSize(length); + // AUDIO_INFO_LOG("FastAudioStream::SetCaptureMode: length %{public}zu", length); + + // readBufferPool_[i] = std::make_unique(length); + // if (readBufferPool_[i] == nullptr) { + // AUDIO_INFO_LOG("FastAudioStream::SetCaptureMode readBufferPool_[i]==nullptr. Allocate memory failed."); + // return ERR_OPERATION_FAILED; + // } + + // BufferDesc bufDesc {}; + // bufDesc.buffer = readBufferPool_[i].get(); + // bufDesc.bufLength = length; + // freeBufferQ_.emplace(bufDesc); + // } + return SUCCESS; +} + +AudioCaptureMode FastAudioStream::GetCaptureMode() +{ + // return GetAudioCaptureMode(); + return captureMode_; +} + +int32_t FastAudioStream::SetCapturerReadCallback(const std::shared_ptr &callback) +{ + AUDIO_INFO_LOG("SetCapturerReadCallback in."); + return SUCCESS; + // if (captureMode_ != CAPTURE_MODE_CALLBACK) { + // AUDIO_ERR_LOG("SetCapturerReadCallback not supported. Capture mode is not callback."); + // return ERR_INCORRECT_MODE; + // } + + // if (!callback) { + // AUDIO_ERR_LOG("SetCapturerReadCallback callback is nullptr"); + // return ERR_INVALID_PARAM; + // } + // return AudioServiceClient::SetCapturerReadCallback(callback); +} + +int32_t FastAudioStream::GetBufferDesc(BufferDesc &bufDesc) +{ + AUDIO_INFO_LOG("GetBufferDesc in."); + if (!spkProcessClient_) { + AUDIO_ERR_LOG("spkClient is null."); + } + int32_t ret = spkProcessClient_->GetBufferDesc(bufDesc); + if (ret != SUCCESS || bufDesc.buffer == nullptr || bufDesc.bufLength ==0) { + AUDIO_ERR_LOG("GetBufferDesc failed."); + return -1; + } + return SUCCESS; +} + +int32_t FastAudioStream::GetBufQueueState(BufferQueueState &bufState) +{ + AUDIO_INFO_LOG("GetBufQueueState in."); + // if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) { + // AUDIO_ERR_LOG("AudioStream::GetBufQueueState not supported. Render or Capture mode is not callback."); + // return ERR_INCORRECT_MODE; + // } + + // lock_guard lock(bufferQueueLock_); + + // if (renderMode_ == RENDER_MODE_CALLBACK) { + // bufState.numBuffers = filledBufferQ_.size(); + // } + + // if (captureMode_ == CAPTURE_MODE_CALLBACK) { + // bufState.numBuffers = freeBufferQ_.size(); + // } + + return SUCCESS; +} + +int32_t FastAudioStream::Enqueue(const BufferDesc &bufDesc) +{ + AUDIO_INFO_LOG("Enqueue in"); + if (!spkProcessClient_) { + AUDIO_ERR_LOG("spkClient is null."); + } + int32_t ret = spkProcessClient_->Enqueue(bufDesc); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("Enqueue failed."); + return -1; + } + return SUCCESS; +} + +int32_t FastAudioStream::Clear() +{ + AUDIO_INFO_LOG("Clear in."); + // if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) { + // AUDIO_ERR_LOG("AudioStream::Clear not supported. Render or capture mode is not callback."); + // return ERR_INCORRECT_MODE; + // } + + // lock_guard lock(bufferQueueLock_); + + // while (!filledBufferQ_.empty()) { + // freeBufferQ_.emplace(filledBufferQ_.front()); + // filledBufferQ_.pop(); + // } + + return SUCCESS; +} + +int32_t FastAudioStream::SetLowPowerVolume(float volume) +{ + AUDIO_INFO_LOG("SetLowPowerVolume in."); + // return SetStreamLowPowerVolume(volume); + return 0.0f; +} + +float FastAudioStream::GetLowPowerVolume() +{ + AUDIO_INFO_LOG("GetLowPowerVolume in."); + // return GetStreamLowPowerVolume(); + return 0.0f; +} + +float FastAudioStream::GetSingleStreamVolume() +{ + AUDIO_INFO_LOG("GetSingleStreamVolume in."); + // return GetSingleStreamVol(); + return 0.0f; +} + +AudioEffectMode FastAudioStream::GetAudioEffectMode() +{ + AUDIO_INFO_LOG("GetAudioEffectMode in."); + return effectMode_; +} + +int32_t FastAudioStream::SetAudioEffectMode(AudioEffectMode effectMode) +{ + AUDIO_INFO_LOG("SetAudioEffectMode in."); + // return SetStreamAudioEffectMode(effectMode); + return SUCCESS; +} + +bool FastAudioStream::StartAudioStream(StateChangeCmdType cmdType) +{ + AUDIO_INFO_LOG("StartAudioStream in."); + if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) { + AUDIO_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_); + return false; + } + + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + int32_t ret = spkProcessClient_->Start(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret); + state_ = RUNNING; + + // int32_t ret = StartStream(cmdType); + // if (ret != SUCCESS) { + // AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret); + // return false; + // } + + // resetTime_ = true; + // int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_); + // if (retCode != 0) { + // AUDIO_ERR_LOG("AudioStream::StartAudioStream get system elapsed time failed: %d", retCode); + // } + + // isFirstRead_ = true; + // isFirstWrite_ = true; + // state_ = RUNNING; + + // if (renderMode_ == RENDER_MODE_CALLBACK) { + // isReadyToWrite_ = true; + // writeThread_ = std::make_unique(&AudioStream::WriteCbTheadLoop, this); + // } else if (captureMode_ == CAPTURE_MODE_CALLBACK) { + // isReadyToRead_ = true; + // readThread_ = std::make_unique(&AudioStream::ReadCbThreadLoop, this); + // } + + AUDIO_INFO_LOG("StartAudioStream SUCCESS, sessionId: %{public}d", sessionId_); + return true; +} + +bool FastAudioStream::PauseAudioStream(StateChangeCmdType cmdType) +{ + AUDIO_INFO_LOG("PauseAudioStream in"); + if (state_ != RUNNING) { + AUDIO_ERR_LOG("PauseAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); + return false; + } + State oldState = state_; + // Update state to stop write thread + state_ = PAUSED; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + int32_t ret = spkProcessClient_->Pause(); + if (ret != SUCCESS) { + AUDIO_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret); + state_ = oldState; + return false; + } + + // if (captureMode_ == CAPTURE_MODE_CALLBACK) { + // isReadyToRead_ = false; + // if (readThread_ && readThread_->joinable()) { + // readThread_->join(); + // } + // } + + // // Ends the WriteCb thread + // if (renderMode_ == RENDER_MODE_CALLBACK) { + // isReadyToWrite_ = false; + // // wake write thread to make pause faster + // bufferQueueCV_.notify_all(); + // if (writeThread_ && writeThread_->joinable()) { + // writeThread_->join(); + // } + // } + + // AUDIO_DEBUG_LOG("AudioStream::PauseAudioStream:renderMode_ : %{public}d state_: %{public}d", renderMode_, state_); + // int32_t ret = PauseStream(cmdType); + // if (ret != SUCCESS) { + // AUDIO_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret); + // state_ = oldState; + // return false; + // } + + AUDIO_INFO_LOG("PauseAudioStream SUCCESS, sessionId: %{public}d", sessionId_); + + // flush stream after stream paused + // FlushAudioStream(); + + return true; +} + +bool FastAudioStream::StopAudioStream() +{ + AUDIO_INFO_LOG("StopAudioStream in."); + if ((state_ != RUNNING) && (state_ != PAUSED)) { + AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); + return false; + } + State oldState = state_; + state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads + + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + int32_t ret = spkProcessClient_->Stop(); + if (ret != SUCCESS) { + AUDIO_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret); + state_ = oldState; + return false; + } + // if (captureMode_ == CAPTURE_MODE_CALLBACK) { + // isReadyToRead_ = false; + // if (readThread_ && readThread_->joinable()) { + // readThread_->join(); + // } + // } + + // if (renderMode_ == RENDER_MODE_CALLBACK) { + // isReadyToWrite_ = false; + // if (writeThread_ && writeThread_->joinable()) { + // writeThread_->join(); + // } + // } + + // int32_t ret = StopStream(); + // if (ret != SUCCESS) { + // AUDIO_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret); + // state_ = oldState; + // return false; + // } + + AUDIO_INFO_LOG("StopAudioStream SUCCESS, sessionId: %{public}d", sessionId_); + return true; +} + +bool FastAudioStream::FlushAudioStream() +{ + AUDIO_INFO_LOG("FlushAudioStream in."); + // Trace trace("AudioStream::FlushAudioStream"); + // if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) { + // AUDIO_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); + // return false; + // } + + // int32_t ret = FlushStream(); + // if (ret != SUCCESS) { + // AUDIO_DEBUG_LOG("Flush stream fail,ret:%{public}d", ret); + // return false; + // } + + // AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_); + return true; +} + +bool FastAudioStream::DrainAudioStream() +{ + AUDIO_INFO_LOG("DrainAudioStream in."); + // if (state_ != RUNNING) { + // AUDIO_ERR_LOG("DrainAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); + // return false; + // } + + // int32_t ret = DrainStream(); + // if (ret != SUCCESS) { + // AUDIO_DEBUG_LOG("Drain stream fail,ret:%{public}d", ret); + // return false; + // } + + AUDIO_INFO_LOG("Drain stream SUCCESS"); + return true; +} + +bool FastAudioStream::ReleaseAudioStream(bool releaseRunner) +{ + AUDIO_INFO_LOG("ReleaseAudiostream in"); + if (state_ == RELEASED || state_ == NEW) { + AUDIO_ERR_LOG("Illegal state: state = %{public}u", state_); + return false; + } + // If state_ is RUNNING try to Stop it first and Release + if (state_ == RUNNING) { + StopAudioStream(); + } + + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + spkProcessClient_->Release(); + state_ = RELEASED; + AUDIO_INFO_LOG("ReleaseAudiostream SUCCESS, sessionId: %{public}d", sessionId_); + return true; +} + +int32_t FastAudioStream::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead) +{ + AUDIO_INFO_LOG("Write in."); + return 1; + // if (userSize <= 0) { + // AUDIO_ERR_LOG("Invalid userSize:%{public}zu", userSize); + // return ERR_INVALID_PARAM; + // } + + // if (state_ != RUNNING) { + // AUDIO_ERR_LOG("Read: State is not RUNNNIG. Illegal state:%{public}u", state_); + // return ERR_ILLEGAL_STATE; + // } + + // if (isFirstRead_) { + // FlushAudioStream(); + // isFirstRead_ = false; + // } + + // StreamBuffer stream; + // stream.buffer = &buffer; + // stream.bufferLen = userSize; + // int32_t readLen = ReadStream(stream, isBlockingRead); + // if (readLen < 0) { + // AUDIO_ERR_LOG("ReadStream fail,ret:%{public}d", readLen); + // return ERR_INVALID_READ; + // } + + // return readLen; +} + +size_t FastAudioStream::Write(uint8_t *buffer, size_t buffer_size) +{ + AUDIO_INFO_LOG("Write in."); + // Trace trace("AudioStream::Write"); + // if (renderMode_ == RENDER_MODE_CALLBACK) { + // AUDIO_ERR_LOG("AudioStream::Write not supported. RenderMode is callback"); + // return ERR_INCORRECT_MODE; + // } + + // if ((buffer == nullptr) || (buffer_size <= 0)) { + // AUDIO_ERR_LOG("Invalid buffer size:%{public}zu", buffer_size); + // return ERR_INVALID_PARAM; + // } + + // if (state_ != RUNNING) { + // AUDIO_ERR_LOG("Write: Illegal state:%{public}u", state_); + // // To allow context switch for APIs running in different thread contexts + // std::this_thread::sleep_for(std::chrono::microseconds(WRITE_RETRY_DELAY_IN_US)); + // return ERR_ILLEGAL_STATE; + // } + + // int32_t writeError; + // StreamBuffer stream; + // stream.buffer = buffer; + // stream.bufferLen = buffer_size; + + // if (isFirstWrite_) { + // if (RenderPrebuf(stream.bufferLen)) { + // return ERR_WRITE_FAILED; + // } + // isFirstWrite_ = false; + // } + + // size_t bytesWritten = WriteStream(stream, writeError); + // if (writeError != 0) { + // AUDIO_ERR_LOG("WriteStream fail,writeError:%{public}d", writeError); + // return ERR_WRITE_FAILED; + // } + // return bytesWritten; + return 1; +} + +uint32_t FastAudioStream::GetUnderflowCount() +{ + AUDIO_INFO_LOG("GetUnderflowCount in."); + return underFlowCount_; +} + +void FastAudioStream::SetRendererPositionCallback(int64_t markPosition, + const std::shared_ptr &callback) +{ + AUDIO_INFO_LOG("Registering render frame position callback mark position"); +} + +void FastAudioStream::UnsetRendererPositionCallback() +{ + AUDIO_INFO_LOG("Unregistering render frame position callback"); +} + +void FastAudioStream::SetRendererPeriodPositionCallback(int64_t periodPosition, + const std::shared_ptr &callback) +{ + AUDIO_INFO_LOG("Registering render period position callback"); +} + +void FastAudioStream::UnsetRendererPeriodPositionCallback() +{ + AUDIO_INFO_LOG("Unregistering render period position callback"); +} + +void FastAudioStream::SetCapturerPositionCallback(int64_t markPosition, + const std::shared_ptr &callback) +{ + AUDIO_INFO_LOG("Registering capture frame position callback, mark position"); +} + +void FastAudioStream::UnsetCapturerPositionCallback() +{ + AUDIO_INFO_LOG("Unregistering capture frame position callback"); +} + +void FastAudioStream::SetCapturerPeriodPositionCallback(int64_t periodPosition, + const std::shared_ptr &callback) +{ + AUDIO_INFO_LOG("Registering period position callback"); +} + +void FastAudioStream::UnsetCapturerPeriodPositionCallback() +{ + AUDIO_INFO_LOG("Unregistering period position callback"); +} + +int32_t FastAudioStream::SetRendererSamplingRate(uint32_t sampleRate) +{ + AUDIO_INFO_LOG("SetStreamRendererSamplingRate %{public}d", sampleRate); + if (sampleRate <= 0) { + return -1; + } + rendererSampleRate_ = sampleRate; + return SUCCESS; +} + +uint32_t FastAudioStream::GetRendererSamplingRate() +{ + AUDIO_DEBUG_LOG("GetRendererSamplingRate in"); + return rendererSampleRate_; +} + +int32_t FastAudioStream::SetBufferSizeInMsec(int32_t bufferSizeInMsec) +{ + AUDIO_DEBUG_LOG("SetBufferSizeInMsec in"); + return SUCCESS; +} + +void FastAudioStream::SetApplicationCachePath(const std::string cachePath) +{ + AUDIO_DEBUG_LOG("SetApplicationCachePath in"); + cachePath_ = cachePath; +} +void FastAudioStream::SetInnerCapturerState(bool isInnerCapturer) +{ + AUDIO_DEBUG_LOG("SetInnerCapturerState in"); +} + +void FastAudioStream::SetPrivacyType(AudioPrivacyType privacyType) +{ + AUDIO_DEBUG_LOG("SetPrivacyType in"); +} + +void FastAudioStreamCallback::OnHandleData(size_t length) +{ + CHECK_AND_RETURN_LOG(renderCallback_!= nullptr, "%{public}s renderCallback_ is null.", __func__); + renderCallback_->OnWriteData(length); +} +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_service/client/src/i_audio_stream.cpp b/services/audio_service/client/src/i_audio_stream.cpp index 1f77b05c3b..9923d066b8 100644 --- a/services/audio_service/client/src/i_audio_stream.cpp +++ b/services/audio_service/client/src/i_audio_stream.cpp @@ -18,6 +18,7 @@ #include "audio_log.h" #include "audio_stream.h" +#include "fast_audio_stream.h" namespace OHOS { namespace AudioStandard { @@ -130,6 +131,7 @@ std::shared_ptr IAudioStream::GetPlaybackStream(StreamClass stream (void)params; // todo: use params eStreamType uid to create fast stream AUDIO_INFO_LOG("Create fast stream"); + return std::make_shared(eStreamType, AUDIO_MODE_PLAYBACK, appUid); } if (streamClass == PA_STREAM) { return std::make_shared(eStreamType, AUDIO_MODE_PLAYBACK, appUid); diff --git a/services/audio_service/test/example/fast_audio_stream_playback_test.cpp b/services/audio_service/test/example/fast_audio_stream_playback_test.cpp new file mode 100644 index 0000000000..285efa40f8 --- /dev/null +++ b/services/audio_service/test/example/fast_audio_stream_playback_test.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "audio_renderer.h" +#include "audio_log.h" +#include "audio_utils.h" +#include "audio_errors.h" +#include "parameter.h" +#include "pcm2wav.h" + +namespace OHOS { +namespace AudioStandard { +class PlaybackTest : public AudioRendererWriteCallback, + public std::enable_shared_from_this { +public: + int32_t InitRenderer(); + int32_t StartPlay(); + int32_t StopPlay(); + void OnWriteData(size_t length) override; + bool OpenSpkFile(const std::string spkFilePath); + +private: + std::unique_ptr audioRenderer_ = nullptr; + static constexpr long WAV_HEADER_SIZE = 42; + int32_t loopCount_ = 2; // play 2 times + bool needSkipWavHeader_ = true; + bool renderFinish_ = false; + FILE *spkWavFile_ = nullptr; +}; + +void PlaybackTest::OnWriteData(size_t length) +{ + BufferDesc bufDesc; + if (audioRenderer_ == nullptr) { + AUDIO_ERR_LOG("audioRenderer is nullptr."); + return; + } + audioRenderer_ -> GetBufferDesc(bufDesc); + + if (spkWavFile_ == nullptr) { + AUDIO_ERR_LOG("spkWavFile_ is nullptr."); + return; + } + if (needSkipWavHeader_) { + fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET); + needSkipWavHeader_ = false; + } + if (feof(spkWavFile_)) { + loopCount_--; + if (loopCount_ < 0) { + fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET); // infinite loop + } else if (loopCount_ == 0) { + renderFinish_ = true; + // g_autoRunCV.notify_all(); + } else { + fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET); + } + } + if (renderFinish_) { + AUDIO_INFO_LOG("%{public}s render finish.", __func__); + return; + } + fread(bufDesc.buffer, 1, bufDesc.bufLength, spkWavFile_); + audioRenderer_->Enqueue(bufDesc); +} + +bool PlaybackTest::OpenSpkFile(const std::string spkFilePath) +{ + if (spkWavFile_ != nullptr) { + AUDIO_ERR_LOG("Spk file has been opened, spkFilePath %{public}s", spkFilePath.c_str()); + return true; + } + + char path[PATH_MAX] = { 0x00 }; + if ((strlen(spkFilePath.c_str()) > PATH_MAX) || (realpath(spkFilePath.c_str(), path) == nullptr)) { + return false; + } + AUDIO_INFO_LOG("spk path = %{public}s", path); + spkWavFile_ = fopen(path, "rb"); + if (spkWavFile_ == nullptr) { + AUDIO_ERR_LOG("Unable to open wave file"); + return false; + } + return true; +} + +int32_t PlaybackTest::InitRenderer() +{ + AudioStandard::AudioRendererOptions rendererOptions = { + { + static_cast(48000), + AudioStandard::AudioEncodingType::ENCODING_PCM, + static_cast(1), + static_cast(2), + }, + { + static_cast(2), + static_cast(1), + 4, // fast audio stream + } + }; + audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions); + if (audioRenderer_ == nullptr) { + AUDIO_ERR_LOG("wuhaobo Audio renderer create failed."); + return -1; + } + // obTestCb_ = std::make_shared(); + std::string path = "/data/test.wav"; + OpenSpkFile(path); + int32_t ret = audioRenderer_ -> SetRendererWriteCallback(shared_from_this()); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret); + AUDIO_INFO_LOG("wuhaobo Audio renderer create success."); + return 0; +} + +int32_t PlaybackTest::StartPlay() +{ + if (audioRenderer_ == nullptr) { + AUDIO_ERR_LOG("wuhaobo Audiorenderer init failed."); + return -1; + } + if (!audioRenderer_->Start()) { + AUDIO_ERR_LOG("wuhaobo Audio renderer start failed."); + return -1; + } + return 0; +} + +int32_t PlaybackTest::StopPlay() +{ + if (audioRenderer_ == nullptr) { + AUDIO_ERR_LOG("wuhaobo Audiorenderer init failed."); + return -1; + } + if (!audioRenderer_->Stop()) { + AUDIO_ERR_LOG("wuhaobo Audio renderer stop failed."); + return -1; + } + return 0; +} + +bool SetSysPara(std::string key, int32_t &value) +{ + auto res = SetParameter(key.c_str(), std::to_string(value).c_str()); + if (res < 0) { + AUDIO_WARNING_LOG("SetSysPara fail, key:%{public}s res:%{public}d", key.c_str(), res); + return false; + } + AUDIO_INFO_LOG("SetSysPara success."); + return true; +} +} +} + +using namespace OHOS::AudioStandard; +using namespace std; +int main(int argc, char* argv[]) +{ + cout << "oh audio stream test." << endl; + std::shared_ptr playTest = std::make_shared(); + int32_t val = 1; + SetSysPara("persist.multimedia.audio.mmap.enable", val); + + int32_t ret = playTest->InitRenderer(); + if (ret != 0) { + cout << "Init Renderer error !" << endl; + return -1; + } + cout << "Init Renderer success !" << endl; + ret = playTest->StartPlay(); + if (ret != 0) { + cout << "Start Play error !" << endl; + return -1; + } + cout << "Playing ..." << endl; + usleep(2000000000); + return 0; +} -- Gitee From abfb8225afafe84c5077fa58523c0bf25cbad6ea Mon Sep 17 00:00:00 2001 From: hwwuhaobo Date: Fri, 7 Jul 2023 15:03:10 +0800 Subject: [PATCH 2/3] add fast audio stream Signed-off-by: hwwuhaobo --- .../audiostream/include/fast_audio_stream.h | 46 +-- services/audio_service/BUILD.gn | 4 +- .../client/include/audio_service_client.h | 3 +- .../client/src/fast_audio_stream.cpp | 327 +----------------- .../fast_audio_stream_playback_test.cpp | 48 +-- 5 files changed, 35 insertions(+), 393 deletions(-) diff --git a/frameworks/native/audiostream/include/fast_audio_stream.h b/frameworks/native/audiostream/include/fast_audio_stream.h index da6517c0fb..d7449aed1c 100644 --- a/frameworks/native/audiostream/include/fast_audio_stream.h +++ b/frameworks/native/audiostream/include/fast_audio_stream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -38,19 +38,10 @@ public: void OnHandleData(size_t length) override; private: - // static constexpr long WAV_HEADER_SIZE = 42; std::shared_ptr procClient_ = nullptr; std::shared_ptr renderCallback_ = nullptr; - // int32_t loopCount_ = 2; // play 2 times - // AudioMode clientMode_ = AUDIO_MODE_PLAYBACK; - // bool needSkipWavHeader_ = true; - // bool renderFinish_ = false; - // FILE *spkWavFile_ = nullptr; - // FILE *micWavFile_ = nullptr; }; - - class FastAudioStream : public IAudioStream { public: FastAudioStream(AudioStreamType eStreamType, AudioMode eMode, int32_t appUid); @@ -97,14 +88,12 @@ public: float GetSingleStreamVolume() override; AudioEffectMode GetAudioEffectMode() override; int32_t SetAudioEffectMode(AudioEffectMode effectMode) override; + int64_t GetFramesWritten() override; + int64_t GetFramesRead() override; void SetInnerCapturerState(bool isInnerCapturer) override; void SetPrivacyType(AudioPrivacyType privacyType) override; - // std::vector GetSupportedFormats() const; - // std::vector GetSupportedEncodingTypes() const; - // std::vector GetSupportedSamplingRates() const; - // Common APIs bool StartAudioStream(StateChangeCmdType cmdType = CMD_FROM_CLIENT) override; bool PauseAudioStream(StateChangeCmdType cmdType = CMD_FROM_CLIENT) override; @@ -137,36 +126,7 @@ public: int32_t SetBufferSizeInMsec(int32_t bufferSizeInMsec) override; void SetApplicationCachePath(const std::string cachePath) override; - private: - // AudioStreamType eStreamType_; - // AudioMode eMode_; - // State state_; - // bool resetTime_; - // uint64_t resetTimestamp_; - // struct timespec baseTimestamp_ = {0}; - // AudioRenderMode renderMode_; - // AudioCaptureMode captureMode_; - // std::queue freeBufferQ_; - // std::queue filledBufferQ_; - // std::array, MAX_WRITECB_NUM_BUFFERS> writeBufferPool_ = {}; - // std::array, MAX_READCB_NUM_BUFFERS> readBufferPool_ = {}; - // std::unique_ptr writeThread_ = nullptr; - // std::unique_ptr readThread_ = nullptr; - // bool isReadyToWrite_; - // bool isReadyToRead_; - // void WriteCbTheadLoop(); - // void ReadCbThreadLoop(); - // std::unique_ptr audioStreamTracker_; - // AudioRendererInfo rendererInfo_; - // AudioCapturerInfo capturerInfo_; - // uint32_t sessionId_; - - // bool isFirstRead_; - // bool isFirstWrite_; - - // std::mutex bufferQueueLock_; - // std::condition_variable bufferQueueCV_; AudioStreamType eStreamType_; AudioMode eMode_; std::shared_ptr spkProcessClient_ = nullptr; diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index f0172f249c..7b2a394ae3 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -428,9 +428,9 @@ ohos_executable("audio_faststream_playback_test") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_single", + "hilog:libhilog", "init:libbegetutil", + "ipc:ipc_single", ] part_name = "audio_framework" diff --git a/services/audio_service/client/include/audio_service_client.h b/services/audio_service/client/include/audio_service_client.h index 648bf157b2..5ffb28e26e 100644 --- a/services/audio_service/client/include/audio_service_client.h +++ b/services/audio_service/client/include/audio_service_client.h @@ -277,9 +277,8 @@ public: uint8_t GetSampleSize() const; void SetStreamInnerCapturerState(bool isInnerCapturer); + void SetStreamPrivacyType(AudioPrivacyType privacyType); - void SetInnerCapturerState(bool isInnerCapturer) override; - void SetPrivacyType(AudioPrivacyType privacyType) override; /** * Provides the underflow count required for this audio stream diff --git a/services/audio_service/client/src/fast_audio_stream.cpp b/services/audio_service/client/src/fast_audio_stream.cpp index eff0682906..7917c35395 100644 --- a/services/audio_service/client/src/fast_audio_stream.cpp +++ b/services/audio_service/client/src/fast_audio_stream.cpp @@ -35,7 +35,6 @@ FastAudioStream::FastAudioStream(AudioStreamType eStreamType, AudioMode eMode, i captureMode_(CAPTURE_MODE_NORMAL) { AUDIO_DEBUG_LOG("FastAudioStream ctor, appUID = %{public}d", appUid); - // audioStreamTracker_ = std::make_unique(eMode, appUid); } FastAudioStream::~FastAudioStream() @@ -68,10 +67,6 @@ int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, { AUDIO_INFO_LOG("FastAudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d," " stream type: %{public}d", info.samplingRate, info.channels, info.format, eStreamType_); - // if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) { - // AUDIO_ERR_LOG("FastAudioStream: Unsupported audio parameter"); - // return ERR_NOT_SUPPORTED; - // } if (state_ != NEW) { AUDIO_INFO_LOG("FastAudioStream: State is not new, release existing stream"); StopAudioStream(); @@ -79,10 +74,6 @@ int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, } if (eMode_ == AUDIO_MODE_PLAYBACK) { AUDIO_DEBUG_LOG("FastAudioStream: Initialize playback"); - // if (!IsRendererChannelValid(info.channels)) { - // AUDIO_ERR_LOG("FastAudioStream: Invalid sink channel %{public}d", info.channels); - // return ERR_NOT_SUPPORTED; - // } AudioProcessConfig config; config.appInfo.appPid = clientPid_; config.appInfo.appUid = clientUid_; @@ -100,10 +91,6 @@ int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, "Client test creat process client fail."); } else if (eMode_ == AUDIO_MODE_RECORD) { AUDIO_DEBUG_LOG("FastAudioStream: Initialize recording"); - // if (!IsCapturerChannelValid(info.channels)) { - // AUDIO_ERR_LOG("FastAudioStream: Invalid source channel %{public}d", info.channels); - // return ERR_NOT_SUPPORTED; - // } } else { AUDIO_ERR_LOG("FastAudioStream: error eMode."); return ERR_INVALID_OPERATION; @@ -116,9 +103,6 @@ int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, int32_t FastAudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo) { AUDIO_INFO_LOG("GetAudioStreamInfo in"); - // if (GetAudioStreamParams(audioStreamInfo) != 0) { - // return ERR_OPERATION_FAILED; - // } return SUCCESS; } @@ -127,7 +111,6 @@ bool FastAudioStream::VerifyClientMicrophonePermission(uint32_t appTokenId, int3 AudioPermissionState state) { AUDIO_INFO_LOG("VerifyClientPermission in"); - // return AudioServiceClient::VerifyClientPermission(permissionName, appTokenId, appUid, privacyFlag, state); return true; } @@ -135,24 +118,13 @@ bool FastAudioStream::getUsingPemissionFromPrivacy(const std::string &permission AudioPermissionState state) { AUDIO_INFO_LOG("getUsingPemissionFromPrivacy in"); - // return AudioServiceClient::getUsingPemissionFromPrivacy(permissionName, appTokenId, state); return true; } int32_t FastAudioStream::GetAudioSessionID(uint32_t &sessionID) { - // wuhaobo todo SessionId 如何实现? AudioServiceClient::GetSessionID AUDIO_INFO_LOG("GetAudioSessionID in"); sessionID = 1; // test - // if ((state_ == RELEASED) || (state_ == NEW)) { - // return ERR_ILLEGAL_STATE; - // } - - // if (GetSessionID(sessionID) != -1) { - // return ERR_INVALID_INDEX; - // } - - // sessionId_ = sessionID; return SUCCESS; } @@ -165,37 +137,12 @@ State FastAudioStream::GetState() bool FastAudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) { AUDIO_INFO_LOG("GetAudioTime in"); - // if (state_ == STOPPED) { - // return false; - // } - // uint64_t paTimeStamp = 0; - // if (GetCurrentTimeStamp(paTimeStamp) == SUCCESS) { - // if (resetTime_) { - // AUDIO_INFO_LOG("AudioStream::GetAudioTime resetTime_ %{public}d", resetTime_); - // resetTime_ = false; - // resetTimestamp_ = paTimeStamp; - // } - - // timestamp.time.tv_sec = static_cast((paTimeStamp - resetTimestamp_) / TIME_CONVERSION_US_S); - // timestamp.time.tv_nsec - // = static_cast(((paTimeStamp - resetTimestamp_) - (timestamp.time.tv_sec * TIME_CONVERSION_US_S)) - // * TIME_CONVERSION_NS_US); - // timestamp.time.tv_sec += baseTimestamp_.tv_sec; - // timestamp.time.tv_nsec += baseTimestamp_.tv_nsec; - // timestamp.time.tv_sec += (timestamp.time.tv_nsec / TIME_CONVERSION_NS_S); - // timestamp.time.tv_nsec = (timestamp.time.tv_nsec % TIME_CONVERSION_NS_S); - - // return true; - // } return false; } int32_t FastAudioStream::GetBufferSize(size_t &bufferSize) { AUDIO_INFO_LOG("GetBufferSize in"); - // if (GetMinimumBufferSize(bufferSize) != 0) { - // return ERR_OPERATION_FAILED; - // } return SUCCESS; } @@ -203,9 +150,6 @@ int32_t FastAudioStream::GetBufferSize(size_t &bufferSize) int32_t FastAudioStream::GetFrameCount(uint32_t &frameCount) { AUDIO_INFO_LOG("GetFrameCount in"); - // if (GetMinimumFrameCount(frameCount) != 0) { - // return ERR_OPERATION_FAILED; - // } return SUCCESS; } @@ -213,11 +157,6 @@ int32_t FastAudioStream::GetFrameCount(uint32_t &frameCount) int32_t FastAudioStream::GetLatency(uint64_t &latency) { AUDIO_INFO_LOG("GetLatency in"); - // if (GetAudioLatency(latency) != SUCCESS) { - // return ERR_OPERATION_FAILED; - // } else { - // return SUCCESS; - // } return SUCCESS; } @@ -230,7 +169,6 @@ int32_t FastAudioStream::SetAudioStreamType(AudioStreamType audioStreamType) int32_t FastAudioStream::SetVolume(float volume) { AUDIO_INFO_LOG("SetVolume in"); - // return SetStreamVolume(volume); return SUCCESS; } @@ -253,12 +191,6 @@ AudioRendererRate FastAudioStream::GetRenderRate() int32_t FastAudioStream::SetStreamCallback(const std::shared_ptr &callback) { AUDIO_INFO_LOG("SetStreamCallback in"); - // if (callback == nullptr) { - // AUDIO_ERR_LOG("AudioStream::SetStreamCallback failed. callback == nullptr"); - // return ERR_INVALID_PARAM; - // } - - // SaveStreamCallback(callback); return SUCCESS; } @@ -267,32 +199,6 @@ int32_t FastAudioStream::SetRenderMode(AudioRenderMode renderMode) { AUDIO_INFO_LOG("SetRenderMode in"); renderMode_ = renderMode; - // int32_t ret = SetAudioRenderMode(renderMode); - // if (ret) { - // AUDIO_ERR_LOG("AudioStream::SetRenderMode: renderMode: %{public}d failed", renderMode); - // return ERR_OPERATION_FAILED; - // } - // renderMode_ = renderMode; - - // lock_guard lock(bufferQueueLock_); - - // for (int32_t i = 0; i < MAX_WRITECB_NUM_BUFFERS; ++i) { - // size_t length; - // GetMinimumBufferSize(length); - // AUDIO_INFO_LOG("AudioServiceClient:: GetMinimumBufferSize: %{public}zu", length); - - // writeBufferPool_[i] = std::make_unique(length); - // if (writeBufferPool_[i] == nullptr) { - // AUDIO_INFO_LOG( - // "AudioServiceClient::GetBufferDescriptor writeBufferPool_[i]==nullptr. Allocate memory failed."); - // return ERR_OPERATION_FAILED; - // } - - // BufferDesc bufDesc {}; - // bufDesc.buffer = writeBufferPool_[i].get(); - // bufDesc.bufLength = length; - // freeBufferQ_.emplace(bufDesc); - // } return SUCCESS; } @@ -319,37 +225,11 @@ int32_t FastAudioStream::SetCaptureMode(AudioCaptureMode captureMode) { AUDIO_INFO_LOG("SetCaptureMode in."); captureMode_ = captureMode; - // int32_t ret = SetAudioCaptureMode(captureMode); - // if (ret) { - // AUDIO_ERR_LOG("FastAudioStream::SetCaptureMode: captureMode: %{public}d failed", captureMode); - // return ERR_OPERATION_FAILED; - // } - // captureMode_ = captureMode; - - // lock_guard lock(bufferQueueLock_); - - // for (int32_t i = 0; i < MAX_READCB_NUM_BUFFERS; ++i) { - // size_t length; - // GetMinimumBufferSize(length); - // AUDIO_INFO_LOG("FastAudioStream::SetCaptureMode: length %{public}zu", length); - - // readBufferPool_[i] = std::make_unique(length); - // if (readBufferPool_[i] == nullptr) { - // AUDIO_INFO_LOG("FastAudioStream::SetCaptureMode readBufferPool_[i]==nullptr. Allocate memory failed."); - // return ERR_OPERATION_FAILED; - // } - - // BufferDesc bufDesc {}; - // bufDesc.buffer = readBufferPool_[i].get(); - // bufDesc.bufLength = length; - // freeBufferQ_.emplace(bufDesc); - // } return SUCCESS; } AudioCaptureMode FastAudioStream::GetCaptureMode() { - // return GetAudioCaptureMode(); return captureMode_; } @@ -357,16 +237,6 @@ int32_t FastAudioStream::SetCapturerReadCallback(const std::shared_ptr lock(bufferQueueLock_); - - // if (renderMode_ == RENDER_MODE_CALLBACK) { - // bufState.numBuffers = filledBufferQ_.size(); - // } - - // if (captureMode_ == CAPTURE_MODE_CALLBACK) { - // bufState.numBuffers = freeBufferQ_.size(); - // } return SUCCESS; } @@ -421,17 +277,6 @@ int32_t FastAudioStream::Enqueue(const BufferDesc &bufDesc) int32_t FastAudioStream::Clear() { AUDIO_INFO_LOG("Clear in."); - // if ((renderMode_ != RENDER_MODE_CALLBACK) && (captureMode_ != CAPTURE_MODE_CALLBACK)) { - // AUDIO_ERR_LOG("AudioStream::Clear not supported. Render or capture mode is not callback."); - // return ERR_INCORRECT_MODE; - // } - - // lock_guard lock(bufferQueueLock_); - - // while (!filledBufferQ_.empty()) { - // freeBufferQ_.emplace(filledBufferQ_.front()); - // filledBufferQ_.pop(); - // } return SUCCESS; } @@ -439,21 +284,18 @@ int32_t FastAudioStream::Clear() int32_t FastAudioStream::SetLowPowerVolume(float volume) { AUDIO_INFO_LOG("SetLowPowerVolume in."); - // return SetStreamLowPowerVolume(volume); return 0.0f; } float FastAudioStream::GetLowPowerVolume() { AUDIO_INFO_LOG("GetLowPowerVolume in."); - // return GetStreamLowPowerVolume(); return 0.0f; } float FastAudioStream::GetSingleStreamVolume() { AUDIO_INFO_LOG("GetSingleStreamVolume in."); - // return GetSingleStreamVol(); return 0.0f; } @@ -466,7 +308,18 @@ AudioEffectMode FastAudioStream::GetAudioEffectMode() int32_t FastAudioStream::SetAudioEffectMode(AudioEffectMode effectMode) { AUDIO_INFO_LOG("SetAudioEffectMode in."); - // return SetStreamAudioEffectMode(effectMode); + return SUCCESS; +} + +int64_t FastAudioStream::GetFramesWritten() +{ + AUDIO_INFO_LOG("GetFramesWritten in."); + return SUCCESS; +} + +int64_t FastAudioStream::GetFramesRead() +{ + AUDIO_INFO_LOG("GetFramesRead in."); return SUCCESS; } @@ -483,30 +336,6 @@ bool FastAudioStream::StartAudioStream(StateChangeCmdType cmdType) CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret); state_ = RUNNING; - // int32_t ret = StartStream(cmdType); - // if (ret != SUCCESS) { - // AUDIO_ERR_LOG("StartStream Start failed:%{public}d", ret); - // return false; - // } - - // resetTime_ = true; - // int32_t retCode = clock_gettime(CLOCK_MONOTONIC, &baseTimestamp_); - // if (retCode != 0) { - // AUDIO_ERR_LOG("AudioStream::StartAudioStream get system elapsed time failed: %d", retCode); - // } - - // isFirstRead_ = true; - // isFirstWrite_ = true; - // state_ = RUNNING; - - // if (renderMode_ == RENDER_MODE_CALLBACK) { - // isReadyToWrite_ = true; - // writeThread_ = std::make_unique(&AudioStream::WriteCbTheadLoop, this); - // } else if (captureMode_ == CAPTURE_MODE_CALLBACK) { - // isReadyToRead_ = true; - // readThread_ = std::make_unique(&AudioStream::ReadCbThreadLoop, this); - // } - AUDIO_INFO_LOG("StartAudioStream SUCCESS, sessionId: %{public}d", sessionId_); return true; } @@ -529,36 +358,8 @@ bool FastAudioStream::PauseAudioStream(StateChangeCmdType cmdType) return false; } - // if (captureMode_ == CAPTURE_MODE_CALLBACK) { - // isReadyToRead_ = false; - // if (readThread_ && readThread_->joinable()) { - // readThread_->join(); - // } - // } - - // // Ends the WriteCb thread - // if (renderMode_ == RENDER_MODE_CALLBACK) { - // isReadyToWrite_ = false; - // // wake write thread to make pause faster - // bufferQueueCV_.notify_all(); - // if (writeThread_ && writeThread_->joinable()) { - // writeThread_->join(); - // } - // } - - // AUDIO_DEBUG_LOG("AudioStream::PauseAudioStream:renderMode_ : %{public}d state_: %{public}d", renderMode_, state_); - // int32_t ret = PauseStream(cmdType); - // if (ret != SUCCESS) { - // AUDIO_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret); - // state_ = oldState; - // return false; - // } - AUDIO_INFO_LOG("PauseAudioStream SUCCESS, sessionId: %{public}d", sessionId_); - // flush stream after stream paused - // FlushAudioStream(); - return true; } @@ -579,26 +380,6 @@ bool FastAudioStream::StopAudioStream() state_ = oldState; return false; } - // if (captureMode_ == CAPTURE_MODE_CALLBACK) { - // isReadyToRead_ = false; - // if (readThread_ && readThread_->joinable()) { - // readThread_->join(); - // } - // } - - // if (renderMode_ == RENDER_MODE_CALLBACK) { - // isReadyToWrite_ = false; - // if (writeThread_ && writeThread_->joinable()) { - // writeThread_->join(); - // } - // } - - // int32_t ret = StopStream(); - // if (ret != SUCCESS) { - // AUDIO_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret); - // state_ = oldState; - // return false; - // } AUDIO_INFO_LOG("StopAudioStream SUCCESS, sessionId: %{public}d", sessionId_); return true; @@ -607,35 +388,12 @@ bool FastAudioStream::StopAudioStream() bool FastAudioStream::FlushAudioStream() { AUDIO_INFO_LOG("FlushAudioStream in."); - // Trace trace("AudioStream::FlushAudioStream"); - // if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) { - // AUDIO_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); - // return false; - // } - - // int32_t ret = FlushStream(); - // if (ret != SUCCESS) { - // AUDIO_DEBUG_LOG("Flush stream fail,ret:%{public}d", ret); - // return false; - // } - - // AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_); return true; } bool FastAudioStream::DrainAudioStream() { AUDIO_INFO_LOG("DrainAudioStream in."); - // if (state_ != RUNNING) { - // AUDIO_ERR_LOG("DrainAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); - // return false; - // } - - // int32_t ret = DrainStream(); - // if (ret != SUCCESS) { - // AUDIO_DEBUG_LOG("Drain stream fail,ret:%{public}d", ret); - // return false; - // } AUDIO_INFO_LOG("Drain stream SUCCESS"); return true; @@ -664,72 +422,11 @@ int32_t FastAudioStream::Read(uint8_t &buffer, size_t userSize, bool isBlockingR { AUDIO_INFO_LOG("Write in."); return 1; - // if (userSize <= 0) { - // AUDIO_ERR_LOG("Invalid userSize:%{public}zu", userSize); - // return ERR_INVALID_PARAM; - // } - - // if (state_ != RUNNING) { - // AUDIO_ERR_LOG("Read: State is not RUNNNIG. Illegal state:%{public}u", state_); - // return ERR_ILLEGAL_STATE; - // } - - // if (isFirstRead_) { - // FlushAudioStream(); - // isFirstRead_ = false; - // } - - // StreamBuffer stream; - // stream.buffer = &buffer; - // stream.bufferLen = userSize; - // int32_t readLen = ReadStream(stream, isBlockingRead); - // if (readLen < 0) { - // AUDIO_ERR_LOG("ReadStream fail,ret:%{public}d", readLen); - // return ERR_INVALID_READ; - // } - - // return readLen; } size_t FastAudioStream::Write(uint8_t *buffer, size_t buffer_size) { AUDIO_INFO_LOG("Write in."); - // Trace trace("AudioStream::Write"); - // if (renderMode_ == RENDER_MODE_CALLBACK) { - // AUDIO_ERR_LOG("AudioStream::Write not supported. RenderMode is callback"); - // return ERR_INCORRECT_MODE; - // } - - // if ((buffer == nullptr) || (buffer_size <= 0)) { - // AUDIO_ERR_LOG("Invalid buffer size:%{public}zu", buffer_size); - // return ERR_INVALID_PARAM; - // } - - // if (state_ != RUNNING) { - // AUDIO_ERR_LOG("Write: Illegal state:%{public}u", state_); - // // To allow context switch for APIs running in different thread contexts - // std::this_thread::sleep_for(std::chrono::microseconds(WRITE_RETRY_DELAY_IN_US)); - // return ERR_ILLEGAL_STATE; - // } - - // int32_t writeError; - // StreamBuffer stream; - // stream.buffer = buffer; - // stream.bufferLen = buffer_size; - - // if (isFirstWrite_) { - // if (RenderPrebuf(stream.bufferLen)) { - // return ERR_WRITE_FAILED; - // } - // isFirstWrite_ = false; - // } - - // size_t bytesWritten = WriteStream(stream, writeError); - // if (writeError != 0) { - // AUDIO_ERR_LOG("WriteStream fail,writeError:%{public}d", writeError); - // return ERR_WRITE_FAILED; - // } - // return bytesWritten; return 1; } diff --git a/services/audio_service/test/example/fast_audio_stream_playback_test.cpp b/services/audio_service/test/example/fast_audio_stream_playback_test.cpp index 285efa40f8..642d162bad 100644 --- a/services/audio_service/test/example/fast_audio_stream_playback_test.cpp +++ b/services/audio_service/test/example/fast_audio_stream_playback_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -22,6 +22,8 @@ #include "parameter.h" #include "pcm2wav.h" +static constexpr int32_t SLEEP_TIME_NS = 2000000000; + namespace OHOS { namespace AudioStandard { class PlaybackTest : public AudioRendererWriteCallback, @@ -29,13 +31,12 @@ class PlaybackTest : public AudioRendererWriteCallback, public: int32_t InitRenderer(); int32_t StartPlay(); - int32_t StopPlay(); void OnWriteData(size_t length) override; bool OpenSpkFile(const std::string spkFilePath); private: std::unique_ptr audioRenderer_ = nullptr; - static constexpr long WAV_HEADER_SIZE = 42; + static constexpr long WAV_HEADER_SIZE = 44; int32_t loopCount_ = 2; // play 2 times bool needSkipWavHeader_ = true; bool renderFinish_ = false; @@ -49,7 +50,7 @@ void PlaybackTest::OnWriteData(size_t length) AUDIO_ERR_LOG("audioRenderer is nullptr."); return; } - audioRenderer_ -> GetBufferDesc(bufDesc); + audioRenderer_->GetBufferDesc(bufDesc); if (spkWavFile_ == nullptr) { AUDIO_ERR_LOG("spkWavFile_ is nullptr."); @@ -65,7 +66,6 @@ void PlaybackTest::OnWriteData(size_t length) fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET); // infinite loop } else if (loopCount_ == 0) { renderFinish_ = true; - // g_autoRunCV.notify_all(); } else { fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET); } @@ -102,52 +102,38 @@ int32_t PlaybackTest::InitRenderer() { AudioStandard::AudioRendererOptions rendererOptions = { { - static_cast(48000), + AudioStandard::AudioSamplingRate::SAMPLE_RATE_48000, AudioStandard::AudioEncodingType::ENCODING_PCM, - static_cast(1), - static_cast(2), + AudioStandard::AudioSampleFormat::SAMPLE_S16LE, + AudioStandard::AudioChannel::STEREO, }, { - static_cast(2), - static_cast(1), + AudioStandard::ContentType::CONTENT_TYPE_MUSIC, + AudioStandard::StreamUsage::STREAM_USAGE_MEDIA, 4, // fast audio stream } }; audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions); if (audioRenderer_ == nullptr) { - AUDIO_ERR_LOG("wuhaobo Audio renderer create failed."); + AUDIO_ERR_LOG("Audio renderer create failed."); return -1; } - // obTestCb_ = std::make_shared(); std::string path = "/data/test.wav"; OpenSpkFile(path); - int32_t ret = audioRenderer_ -> SetRendererWriteCallback(shared_from_this()); + int32_t ret = audioRenderer_->SetRendererWriteCallback(shared_from_this()); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret); - AUDIO_INFO_LOG("wuhaobo Audio renderer create success."); + AUDIO_INFO_LOG("Audio renderer create success."); return 0; } int32_t PlaybackTest::StartPlay() { if (audioRenderer_ == nullptr) { - AUDIO_ERR_LOG("wuhaobo Audiorenderer init failed."); + AUDIO_ERR_LOG("Audiorenderer init failed."); return -1; } if (!audioRenderer_->Start()) { - AUDIO_ERR_LOG("wuhaobo Audio renderer start failed."); - return -1; - } - return 0; -} - -int32_t PlaybackTest::StopPlay() -{ - if (audioRenderer_ == nullptr) { - AUDIO_ERR_LOG("wuhaobo Audiorenderer init failed."); - return -1; - } - if (!audioRenderer_->Stop()) { - AUDIO_ERR_LOG("wuhaobo Audio renderer stop failed."); + AUDIO_ERR_LOG("Audio renderer start failed."); return -1; } return 0; @@ -187,6 +173,6 @@ int main(int argc, char* argv[]) return -1; } cout << "Playing ..." << endl; - usleep(2000000000); + usleep(SLEEP_TIME_NS); return 0; -} +} \ No newline at end of file -- Gitee From 8398293828597f11315739c24573cf5907dc9847 Mon Sep 17 00:00:00 2001 From: "hezhiqiang19@huawei.com" Date: Mon, 24 Jul 2023 18:39:19 +0800 Subject: [PATCH 3/3] add method for fast audio stream Signed-off-by: hezhiqiang19@huawei.com Change-Id: I9a8095ef6c20072366941dadd9c333ee9fd49403 --- .../audiostream/include/fast_audio_stream.h | 10 +- .../client/include/audio_process_in_client.h | 3 + .../client/src/audio_process_in_client.cpp | 21 +- .../client/src/fast_audio_stream.cpp | 230 +++++++++++------- 4 files changed, 171 insertions(+), 93 deletions(-) diff --git a/frameworks/native/audiostream/include/fast_audio_stream.h b/frameworks/native/audiostream/include/fast_audio_stream.h index d7449aed1c..a7ae30643c 100644 --- a/frameworks/native/audiostream/include/fast_audio_stream.h +++ b/frameworks/native/audiostream/include/fast_audio_stream.h @@ -23,6 +23,7 @@ #include "audio_info.h" #include "audio_process_in_client.h" +#include "audio_stream_tracker.h" #include "i_audio_stream.h" namespace OHOS { @@ -131,17 +132,18 @@ private: AudioMode eMode_; std::shared_ptr spkProcessClient_ = nullptr; std::shared_ptr spkProcClientCb_ = nullptr; + std::unique_ptr audioStreamTracker_; AudioRendererInfo rendererInfo_; AudioCapturerInfo capturerInfo_; + AudioStreamParams streamInfo_; + AudioProcessConfig processconfig_; State state_; uint32_t sessionId_; std::string cachePath_ = ""; - uint32_t rendererSampleRate_; - uint32_t underFlowCount_; - AudioEffectMode effectMode_; + uint32_t underflowCount_; AudioRenderMode renderMode_; AudioCaptureMode captureMode_; - AudioRendererRate renderRate_; + AudioRendererRate renderRate_ = RENDER_RATE_NORMAL; int32_t clientPid_ = 0; int32_t clientUid_ = 0; }; diff --git a/services/audio_service/client/include/audio_process_in_client.h b/services/audio_service/client/include/audio_process_in_client.h index 4efa2ce601..cbabb0d0dd 100644 --- a/services/audio_service/client/include/audio_process_in_client.h +++ b/services/audio_service/client/include/audio_process_in_client.h @@ -49,6 +49,7 @@ class ClientUnderrunCallBack { class AudioProcessInClient { public: static constexpr int32_t PROCESS_VOLUME_MAX = 1 << 16; // 0 ~ 65536 + static bool CheckIfSupport(const AudioProcessConfig &config); static std::shared_ptr Create(const AudioProcessConfig &config); virtual ~AudioProcessInClient() = default; @@ -88,6 +89,8 @@ public: virtual float GetVolume() = 0; + virtual uint32_t GetUnderflowCount() = 0; + virtual int64_t GetFramesWritten() = 0; virtual int64_t GetFramesRead() = 0; diff --git a/services/audio_service/client/src/audio_process_in_client.cpp b/services/audio_service/client/src/audio_process_in_client.cpp index c8fe9f69e4..1ce1d61984 100644 --- a/services/audio_service/client/src/audio_process_in_client.cpp +++ b/services/audio_service/client/src/audio_process_in_client.cpp @@ -79,6 +79,8 @@ public: float GetVolume() override; + uint32_t GetUnderflowCount() override; + int64_t GetFramesWritten() override; int64_t GetFramesRead() override; @@ -89,7 +91,6 @@ public: static const sptr GetAudioServerProxy(); static void AudioServerDied(pid_t pid); - static bool CheckIfSupport(const AudioProcessConfig &config); static constexpr AudioStreamInfo g_targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; private: @@ -159,6 +160,7 @@ private: std::mutex loopThreadLock_; std::condition_variable threadStatusCV_; + std::atomic underflowCount_ = 0; std::string cachePath_; #ifdef DUMP_CLIENT FILE *dcp_ = nullptr; @@ -223,7 +225,7 @@ std::shared_ptr AudioProcessInClient::Create(const AudioPr { AUDIO_INFO_LOG("Create with config: render flag %{public}d, capturer flag %{public}d, isRemote %{public}d.", config.rendererInfo.rendererFlags, config.capturerInfo.capturerFlags, config.isRemote); - if (config.audioMode == AUDIO_MODE_PLAYBACK && !AudioProcessInClientInner::CheckIfSupport(config)) { + if (config.audioMode == AUDIO_MODE_PLAYBACK && !AudioProcessInClient::CheckIfSupport(config)) { AUDIO_ERR_LOG("CheckIfSupport failed!"); return nullptr; } @@ -270,7 +272,12 @@ AudioProcessInClientInner::~AudioProcessInClientInner() int32_t AudioProcessInClientInner::GetSessionID(uint32_t &sessionID) { // note: Get the session id from server. - sessionID = 0; // 0 for debug + int32_t pid = processConfig_.appInfo.appUid; + if (pid < 0) { + AUDIO_ERR_LOG("GetSessionID failed:%{public}d", pid); + return ERR_OPERATION_FAILED; + } + sessionID = static_cast(pid); // using pid as sessionID temporarily return SUCCESS; } @@ -332,6 +339,11 @@ float AudioProcessInClientInner::GetVolume() return volumeInFloat_; } +uint32_t AudioProcessInClientInner::GetUnderflowCount() +{ + return underflowCount_.load(); +} + int64_t AudioProcessInClientInner::GetFramesWritten() { if (processConfig_.audioMode != AUDIO_MODE_PLAYBACK) { @@ -551,7 +563,7 @@ int32_t AudioProcessInClientInner::GetBufferDesc(BufferDesc &bufDesc) const return SUCCESS; } -bool AudioProcessInClientInner::CheckIfSupport(const AudioProcessConfig &config) +bool AudioProcessInClient::CheckIfSupport(const AudioProcessConfig &config) { if (config.streamInfo.encoding != ENCODING_PCM || config.streamInfo.samplingRate != SAMPLE_RATE_48000) { return false; @@ -1180,6 +1192,7 @@ bool AudioProcessInClientInner::FinishHandleCurrent(uint64_t &curWritePos, int64 clientWriteCost = tempSpan->writeDoneTime - tempSpan->writeStartTime; if (clientWriteCost > MAX_WRITE_COST_DURATION_NANO) { AUDIO_WARNING_LOG("Client write cost too long..."); + underflowCount_++; // todo // handle write time out: send underrun msg to client, reset time model with latest server handle time. } diff --git a/services/audio_service/client/src/fast_audio_stream.cpp b/services/audio_service/client/src/fast_audio_stream.cpp index 7917c35395..507eab8da2 100644 --- a/services/audio_service/client/src/fast_audio_stream.cpp +++ b/services/audio_service/client/src/fast_audio_stream.cpp @@ -31,10 +31,12 @@ FastAudioStream::FastAudioStream(AudioStreamType eStreamType, AudioMode eMode, i : eStreamType_(eStreamType), eMode_(eMode), state_(NEW), - renderMode_(RENDER_MODE_NORMAL), - captureMode_(CAPTURE_MODE_NORMAL) + renderMode_(RENDER_MODE_CALLBACK), + captureMode_(CAPTURE_MODE_CALLBACK) { - AUDIO_DEBUG_LOG("FastAudioStream ctor, appUID = %{public}d", appUid); + AUDIO_INFO_LOG("FastAudioStream ctor, appUID = %{public}d", appUid); + audioStreamTracker_ = std::make_unique(eMode, appUid); + AUDIO_DEBUG_LOG("AudioStreamTracker created"); } FastAudioStream::~FastAudioStream() @@ -46,8 +48,7 @@ FastAudioStream::~FastAudioStream() void FastAudioStream::SetClientID(int32_t clientPid, int32_t clientUid) { - //todo - AUDIO_DEBUG_LOG("Set client PID: %{public}d, UID: %{public}d", clientPid, clientUid); + AUDIO_INFO_LOG("Set client PID: %{public}d, UID: %{public}d", clientPid, clientUid); clientPid_ = clientPid; clientUid_ = clientUid; } @@ -67,6 +68,11 @@ int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, { AUDIO_INFO_LOG("FastAudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d," " stream type: %{public}d", info.samplingRate, info.channels, info.format, eStreamType_); + if (spkProcessClient_ != nullptr) { + AUDIO_ERR_LOG("Process is already inited, reset stream info is not supported."); + return ERR_INVALID_OPERATION; + } + streamInfo_ = info; if (state_ != NEW) { AUDIO_INFO_LOG("FastAudioStream: State is not new, release existing stream"); StopAudioStream(); @@ -78,16 +84,19 @@ int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, config.appInfo.appPid = clientPid_; config.appInfo.appUid = clientUid_; config.audioMode = eMode_; - config.rendererInfo.contentType = CONTENT_TYPE_MUSIC; - config.rendererInfo.streamUsage = STREAM_USAGE_MEDIA; - config.rendererInfo.rendererFlags = 4; // 4 for test - config.streamInfo.channels = STEREO; - config.streamInfo.encoding = ENCODING_PCM; - config.streamInfo.format = SAMPLE_S16LE; - config.streamInfo.samplingRate = SAMPLE_RATE_48000; - config.isRemote = true; + config.rendererInfo.contentType = rendererInfo_.contentType; + config.rendererInfo.streamUsage = rendererInfo_.streamUsage; + config.rendererInfo.rendererFlags = STREAM_FLAG_FAST; + config.streamInfo.channels = static_cast(info.channels); + config.streamInfo.encoding = static_cast(info.encoding); + config.streamInfo.format = static_cast(info.format); + config.streamInfo.samplingRate = static_cast(info.samplingRate); + config.isRemote = false; // note: + CHECK_AND_RETURN_RET_LOG(AudioProcessInClient::CheckIfSupport(config), ERR_INVALID_PARAM, + "Stream is not supported."); + processconfig_ = config; spkProcessClient_ = AudioProcessInClient::Create(config); - CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_INVALID_HANDLE, + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_INVALID_PARAM, "Client test creat process client fail."); } else if (eMode_ == AUDIO_MODE_RECORD) { AUDIO_DEBUG_LOG("FastAudioStream: Initialize recording"); @@ -97,13 +106,18 @@ int32_t FastAudioStream::SetAudioStreamInfo(const AudioStreamParams info, } state_ = PREPARED; + if (audioStreamTracker_ != nullptr && audioStreamTracker_.get()) { + spkProcessClient_->GetSessionID(sessionId_); + AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_); + audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj); + } return SUCCESS; } int32_t FastAudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo) { AUDIO_INFO_LOG("GetAudioStreamInfo in"); - + audioStreamInfo = streamInfo_; return SUCCESS; } @@ -111,6 +125,7 @@ bool FastAudioStream::VerifyClientMicrophonePermission(uint32_t appTokenId, int3 AudioPermissionState state) { AUDIO_INFO_LOG("VerifyClientPermission in"); + // note: add support later return true; } @@ -118,15 +133,17 @@ bool FastAudioStream::getUsingPemissionFromPrivacy(const std::string &permission AudioPermissionState state) { AUDIO_INFO_LOG("getUsingPemissionFromPrivacy in"); + // note: add support later return true; } int32_t FastAudioStream::GetAudioSessionID(uint32_t &sessionID) { - AUDIO_INFO_LOG("GetAudioSessionID in"); - sessionID = 1; // test - - return SUCCESS; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_OPERATION_FAILED, + "GetAudioSessionID failed: null process"); + int32_t ret = spkProcessClient_->GetSessionID(sessionID); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetSessionID error."); + return ret; } State FastAudioStream::GetState() @@ -136,51 +153,70 @@ State FastAudioStream::GetState() bool FastAudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) { - AUDIO_INFO_LOG("GetAudioTime in"); - return false; + CHECK_AND_RETURN_RET_LOG(base == Timestamp::MONOTONIC, false, "GetAudioTime failed: invalid base"); + + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "GetAudioTime failed: null process"); + int64_t timeSec = 0; + int64_t timeNsec = 0; + int32_t ret = spkProcessClient_->GetAudioTime(timestamp.framePosition, timeSec, timeNsec); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "GetBufferSize error."); + timestamp.time.tv_sec = timeSec; + timestamp.time.tv_nsec = timeNsec; + return true; } int32_t FastAudioStream::GetBufferSize(size_t &bufferSize) { - AUDIO_INFO_LOG("GetBufferSize in"); - - return SUCCESS; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_OPERATION_FAILED, "GetBufferSize failed: null process"); + int32_t ret = spkProcessClient_->GetBufferSize(bufferSize); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetBufferSize error."); + return ret; } int32_t FastAudioStream::GetFrameCount(uint32_t &frameCount) { - AUDIO_INFO_LOG("GetFrameCount in"); - - return SUCCESS; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_OPERATION_FAILED, "GetFrameCount failed: null process"); + int32_t ret = spkProcessClient_->GetFrameCount(frameCount); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetFrameCount error."); + return ret; } int32_t FastAudioStream::GetLatency(uint64_t &latency) { - AUDIO_INFO_LOG("GetLatency in"); - return SUCCESS; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_OPERATION_FAILED, "GetLatency failed: null process"); + int32_t ret = spkProcessClient_->GetLatency(latency); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetLatency error."); + return ret; } int32_t FastAudioStream::SetAudioStreamType(AudioStreamType audioStreamType) { - AUDIO_INFO_LOG("SetAudioStreamType in"); - return SUCCESS; + // Stream type can only be set when create. + AUDIO_ERR_LOG("Unsupported operation: SetAudioStreamType"); + return ERR_INVALID_OPERATION; } int32_t FastAudioStream::SetVolume(float volume) { - AUDIO_INFO_LOG("SetVolume in"); - return SUCCESS; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_OPERATION_FAILED, "SetVolume failed: null process"); + int32_t ret = spkProcessClient_->SetVolume(volume); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetVolume error."); + return ret; } float FastAudioStream::GetVolume() { - return 0.0f; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, 1.0f, "SetVolume failed: null process"); // 1.0f for default + return spkProcessClient_->GetVolume(); } int32_t FastAudioStream::SetRenderRate(AudioRendererRate renderRate) { - renderRate_ = renderRate; - return SUCCESS; + if (RENDER_RATE_NORMAL == renderRate) { + return SUCCESS; + } + AUDIO_ERR_LOG("Unsupported operation: SetRenderRate"); + return ERR_INVALID_OPERATION; } AudioRendererRate FastAudioStream::GetRenderRate() @@ -191,14 +227,16 @@ AudioRendererRate FastAudioStream::GetRenderRate() int32_t FastAudioStream::SetStreamCallback(const std::shared_ptr &callback) { AUDIO_INFO_LOG("SetStreamCallback in"); - + // note: need add support return SUCCESS; } int32_t FastAudioStream::SetRenderMode(AudioRenderMode renderMode) { - AUDIO_INFO_LOG("SetRenderMode in"); - renderMode_ = renderMode; + if (renderMode != RENDER_MODE_CALLBACK || eMode_ != AUDIO_MODE_PLAYBACK) { + AUDIO_ERR_LOG("SetRenderMode is not supported."); + return ERR_INVALID_OPERATION; + } return SUCCESS; } @@ -223,8 +261,10 @@ int32_t FastAudioStream::SetRendererWriteCallback(const std::shared_ptr &callback) { AUDIO_INFO_LOG("SetCapturerReadCallback in."); + // note: need add support return SUCCESS; } @@ -256,7 +297,7 @@ int32_t FastAudioStream::GetBufferDesc(BufferDesc &bufDesc) int32_t FastAudioStream::GetBufQueueState(BufferQueueState &bufState) { AUDIO_INFO_LOG("GetBufQueueState in."); - + // note: add support return SUCCESS; } @@ -276,7 +317,7 @@ int32_t FastAudioStream::Enqueue(const BufferDesc &bufDesc) int32_t FastAudioStream::Clear() { - AUDIO_INFO_LOG("Clear in."); + AUDIO_INFO_LOG("Clear will do nothing."); return SUCCESS; } @@ -284,43 +325,47 @@ int32_t FastAudioStream::Clear() int32_t FastAudioStream::SetLowPowerVolume(float volume) { AUDIO_INFO_LOG("SetLowPowerVolume in."); - return 0.0f; + return 1.0f; } float FastAudioStream::GetLowPowerVolume() { AUDIO_INFO_LOG("GetLowPowerVolume in."); - return 0.0f; + return 1.0f; } float FastAudioStream::GetSingleStreamVolume() { AUDIO_INFO_LOG("GetSingleStreamVolume in."); - return 0.0f; + return 1.0f; } AudioEffectMode FastAudioStream::GetAudioEffectMode() { - AUDIO_INFO_LOG("GetAudioEffectMode in."); - return effectMode_; + AUDIO_ERR_LOG("GetAudioEffectMode not supported"); + return EFFECT_NONE; } int32_t FastAudioStream::SetAudioEffectMode(AudioEffectMode effectMode) { - AUDIO_INFO_LOG("SetAudioEffectMode in."); - return SUCCESS; + AUDIO_ERR_LOG("SetAudioEffectMode not supported"); + return ERR_NOT_SUPPORTED; } int64_t FastAudioStream::GetFramesWritten() { - AUDIO_INFO_LOG("GetFramesWritten in."); - return SUCCESS; + int64_t result = -1; // -1 invalid frame + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, result, "GetFramesWritten failed: null process"); + result = spkProcessClient_->GetFramesWritten(); + return result; } int64_t FastAudioStream::GetFramesRead() { - AUDIO_INFO_LOG("GetFramesRead in."); - return SUCCESS; + int64_t result = -1; // -1 invalid frame + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, result, "GetFramesRead failed: null process"); + result = spkProcessClient_->GetFramesRead(); + return result; } bool FastAudioStream::StartAudioStream(StateChangeCmdType cmdType) @@ -331,12 +376,17 @@ bool FastAudioStream::StartAudioStream(StateChangeCmdType cmdType) return false; } - CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "Start failed, process is null."); int32_t ret = spkProcessClient_->Start(); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret); state_ = RUNNING; AUDIO_INFO_LOG("StartAudioStream SUCCESS, sessionId: %{public}d", sessionId_); + + if (audioStreamTracker_ != nullptr && audioStreamTracker_.get()) { + AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Running"); + audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_); + } return true; } @@ -348,24 +398,26 @@ bool FastAudioStream::PauseAudioStream(StateChangeCmdType cmdType) return false; } State oldState = state_; - // Update state to stop write thread + state_ = PAUSED; - CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "Pause failed, process is null."); int32_t ret = spkProcessClient_->Pause(); if (ret != SUCCESS) { - AUDIO_DEBUG_LOG("StreamPause fail,ret:%{public}d", ret); + AUDIO_ERR_LOG("StreamPause fail,ret:%{public}d", ret); state_ = oldState; return false; } AUDIO_INFO_LOG("PauseAudioStream SUCCESS, sessionId: %{public}d", sessionId_); - + if (audioStreamTracker_ != nullptr && audioStreamTracker_.get()) { + AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for Pause"); + audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_); + } return true; } bool FastAudioStream::StopAudioStream() { - AUDIO_INFO_LOG("StopAudioStream in."); if ((state_ != RUNNING) && (state_ != PAUSED)) { AUDIO_ERR_LOG("StopAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); return false; @@ -373,15 +425,19 @@ bool FastAudioStream::StopAudioStream() State oldState = state_; state_ = STOPPED; // Set it before stopping as Read/Write and Stop can be called from different threads - CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "Stop failed, process is null."); int32_t ret = spkProcessClient_->Stop(); if (ret != SUCCESS) { - AUDIO_DEBUG_LOG("StreamStop fail,ret:%{public}d", ret); + AUDIO_ERR_LOG("StreamStop fail,ret:%{public}d", ret); state_ = oldState; return false; } AUDIO_INFO_LOG("StopAudioStream SUCCESS, sessionId: %{public}d", sessionId_); + if (audioStreamTracker_ != nullptr && audioStreamTracker_.get()) { + AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for stop"); + audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_); + } return true; } @@ -393,15 +449,12 @@ bool FastAudioStream::FlushAudioStream() bool FastAudioStream::DrainAudioStream() { - AUDIO_INFO_LOG("DrainAudioStream in."); - AUDIO_INFO_LOG("Drain stream SUCCESS"); return true; } bool FastAudioStream::ReleaseAudioStream(bool releaseRunner) { - AUDIO_INFO_LOG("ReleaseAudiostream in"); if (state_ == RELEASED || state_ == NEW) { AUDIO_ERR_LOG("Illegal state: state = %{public}u", state_); return false; @@ -411,40 +464,48 @@ bool FastAudioStream::ReleaseAudioStream(bool releaseRunner) StopAudioStream(); } - CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__); + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "Release failed, process is null."); spkProcessClient_->Release(); state_ = RELEASED; AUDIO_INFO_LOG("ReleaseAudiostream SUCCESS, sessionId: %{public}d", sessionId_); + if (audioStreamTracker_ != nullptr && audioStreamTracker_.get()) { + AUDIO_DEBUG_LOG("AudioStream:Calling Update tracker for release"); + audioStreamTracker_->UpdateTracker(sessionId_, state_, rendererInfo_, capturerInfo_); + } return true; } int32_t FastAudioStream::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead) { - AUDIO_INFO_LOG("Write in."); - return 1; + AUDIO_ERR_LOG("Unsupported operation: read"); + return ERR_INVALID_OPERATION; } size_t FastAudioStream::Write(uint8_t *buffer, size_t buffer_size) { - AUDIO_INFO_LOG("Write in."); - return 1; + AUDIO_ERR_LOG("Unsupported operation: Write"); + return ERR_INVALID_OPERATION; } uint32_t FastAudioStream::GetUnderflowCount() { AUDIO_INFO_LOG("GetUnderflowCount in."); - return underFlowCount_; + CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, 0, "process client is null."); + underflowCount_ = spkProcessClient_->GetUnderflowCount(); + return underflowCount_; } void FastAudioStream::SetRendererPositionCallback(int64_t markPosition, const std::shared_ptr &callback) { AUDIO_INFO_LOG("Registering render frame position callback mark position"); + // note: need support } void FastAudioStream::UnsetRendererPositionCallback() { AUDIO_INFO_LOG("Unregistering render frame position callback"); + // note: need support } void FastAudioStream::SetRendererPeriodPositionCallback(int64_t periodPosition, @@ -482,44 +543,43 @@ void FastAudioStream::UnsetCapturerPeriodPositionCallback() int32_t FastAudioStream::SetRendererSamplingRate(uint32_t sampleRate) { - AUDIO_INFO_LOG("SetStreamRendererSamplingRate %{public}d", sampleRate); - if (sampleRate <= 0) { - return -1; - } - rendererSampleRate_ = sampleRate; - return SUCCESS; + AUDIO_ERR_LOG("SetRendererSamplingRate is not supported"); + + return ERR_OPERATION_FAILED; } uint32_t FastAudioStream::GetRendererSamplingRate() { - AUDIO_DEBUG_LOG("GetRendererSamplingRate in"); - return rendererSampleRate_; + AUDIO_INFO_LOG("GetRendererSamplingRate in"); + return streamInfo_.samplingRate; } int32_t FastAudioStream::SetBufferSizeInMsec(int32_t bufferSizeInMsec) { - AUDIO_DEBUG_LOG("SetBufferSizeInMsec in"); - return SUCCESS; + AUDIO_ERR_LOG("SetBufferSizeInMsec is not supported"); + // note: add support + return ERR_NOT_SUPPORTED; } void FastAudioStream::SetApplicationCachePath(const std::string cachePath) { - AUDIO_DEBUG_LOG("SetApplicationCachePath in"); + AUDIO_INFO_LOG("SetApplicationCachePath to %{public}s", cachePath.c_str()); + cachePath_ = cachePath; } void FastAudioStream::SetInnerCapturerState(bool isInnerCapturer) { - AUDIO_DEBUG_LOG("SetInnerCapturerState in"); + AUDIO_ERR_LOG("SetInnerCapturerState is not supported"); } void FastAudioStream::SetPrivacyType(AudioPrivacyType privacyType) { - AUDIO_DEBUG_LOG("SetPrivacyType in"); + AUDIO_ERR_LOG("SetPrivacyType is not supported"); } void FastAudioStreamCallback::OnHandleData(size_t length) { - CHECK_AND_RETURN_LOG(renderCallback_!= nullptr, "%{public}s renderCallback_ is null.", __func__); + CHECK_AND_RETURN_LOG(renderCallback_!= nullptr, "OnHandleData failed: renderCallback_ is null."); renderCallback_->OnWriteData(length); } } // namespace AudioStandard -- Gitee