1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <vector> 20 21 #include "core-impl/Stream.h" 22 #include "deprecated/StreamSwitcher.h" 23 #include "r_submix/SubmixRoute.h" 24 25 namespace aidl::android::hardware::audio::core { 26 27 class StreamRemoteSubmix : public StreamCommonImpl { 28 public: 29 StreamRemoteSubmix( 30 StreamContext* context, const Metadata& metadata, 31 const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress); 32 ~StreamRemoteSubmix(); 33 34 // Methods of 'DriverInterface'. 35 ::android::status_t init() override; 36 ::android::status_t drain(StreamDescriptor::DrainMode) override; 37 ::android::status_t flush() override; 38 ::android::status_t pause() override; 39 ::android::status_t standby() override; 40 ::android::status_t start() override; 41 ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount, 42 int32_t* latencyMs) override; 43 ::android::status_t refinePosition(StreamDescriptor::Position* position) override; 44 void shutdown() override; 45 46 // Overridden methods of 'StreamCommonImpl', called on a Binder thread. 47 ndk::ScopedAStatus prepareToClose() override; 48 49 private: 50 long getDelayInUsForFrameCount(size_t frameCount); 51 size_t getStreamPipeSizeInFrames(); 52 ::android::status_t outWrite(void* buffer, size_t frameCount, size_t* actualFrameCount); 53 ::android::status_t inRead(void* buffer, size_t frameCount, size_t* actualFrameCount); 54 55 const ::aidl::android::media::audio::common::AudioDeviceAddress mDeviceAddress; 56 const bool mIsInput; 57 r_submix::AudioConfig mStreamConfig; 58 std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr; 59 60 // Limit for the number of error log entries to avoid spamming the logs. 61 static constexpr int kMaxErrorLogs = 5; 62 // The duration of kMaxReadFailureAttempts * READ_ATTEMPT_SLEEP_MS must be strictly inferior 63 // to the duration of a record buffer at the current record sample rate (of the device, not of 64 // the recording itself). Here we have: 3 * 5ms = 15ms < 1024 frames * 1000 / 48000 = 21.333ms 65 static constexpr int kMaxReadFailureAttempts = 3; 66 // 5ms between two read attempts when pipe is empty 67 static constexpr int kReadAttemptSleepUs = 5000; 68 69 int64_t mStartTimeNs = 0; 70 long mFramesSinceStart = 0; 71 int mReadErrorCount = 0; 72 int mReadFailureCount = 0; 73 int mWriteShutdownCount = 0; 74 }; 75 76 class StreamInRemoteSubmix final : public StreamIn, public deprecated::StreamSwitcher { 77 public: 78 friend class ndk::SharedRefBase; 79 StreamInRemoteSubmix( 80 StreamContext&& context, 81 const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, 82 const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones); 83 84 private: 85 DeviceSwitchBehavior switchCurrentStream( 86 const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) 87 override; 88 std::unique_ptr<deprecated::StreamCommonInterfaceEx> createNewStream( 89 const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices, 90 StreamContext* context, const Metadata& metadata) override; onClose(StreamDescriptor::State)91 void onClose(StreamDescriptor::State) override { defaultOnClose(); } 92 ndk::ScopedAStatus getActiveMicrophones( 93 std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return) 94 override; 95 }; 96 97 class StreamOutRemoteSubmix final : public StreamOut, public deprecated::StreamSwitcher { 98 public: 99 friend class ndk::SharedRefBase; 100 StreamOutRemoteSubmix( 101 StreamContext&& context, 102 const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, 103 const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& 104 offloadInfo); 105 106 private: 107 DeviceSwitchBehavior switchCurrentStream( 108 const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) 109 override; 110 std::unique_ptr<deprecated::StreamCommonInterfaceEx> createNewStream( 111 const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices, 112 StreamContext* context, const Metadata& metadata) override; onClose(StreamDescriptor::State)113 void onClose(StreamDescriptor::State) override { defaultOnClose(); } 114 }; 115 116 } // namespace aidl::android::hardware::audio::core 117