1 /* 2 * Copyright (C) 2021 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 #ifndef AUDIO_TEST_UTILS_H_ 18 #define AUDIO_TEST_UTILS_H_ 19 20 #include <sys/stat.h> 21 #include <unistd.h> 22 #include <deque> 23 #include <memory> 24 #include <mutex> 25 #include <thread> 26 #include <utility> 27 28 #include <android-base/thread_annotations.h> 29 #include <binder/MemoryDealer.h> 30 #include <media/AidlConversion.h> 31 #include <media/AudioRecord.h> 32 #include <media/AudioTrack.h> 33 34 using namespace android; 35 36 struct MixPort { 37 std::string name; 38 std::string role; 39 std::string flags; 40 }; 41 42 struct Route { 43 std::string name; 44 std::string sources; 45 std::string sink; 46 }; 47 48 status_t listAudioPorts(std::vector<audio_port_v7>& portsVec); 49 status_t listAudioPatches(std::vector<struct audio_patch>& patchesVec); 50 status_t getPortByAttributes(audio_port_role_t role, audio_port_type_t type, 51 audio_devices_t deviceType, const std::string& address, 52 audio_port_v7& port); 53 status_t getPatchForOutputMix(audio_io_handle_t audioIo, audio_patch& patch); 54 status_t getPatchForInputMix(audio_io_handle_t audioIo, audio_patch& patch); 55 bool patchContainsOutputDevices(DeviceIdVector deviceIds, audio_patch patch); 56 bool patchContainsInputDevice(audio_port_handle_t deviceId, audio_patch patch); 57 bool checkPatchPlayback(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds); 58 bool checkPatchCapture(audio_io_handle_t audioIo, audio_port_handle_t deviceId); 59 std::string dumpPort(const audio_port_v7& port); 60 std::string dumpPortConfig(const audio_port_config& port); 61 std::string dumpPatch(const audio_patch& patch); 62 63 class OnAudioDeviceUpdateNotifier : public AudioSystem::AudioDeviceCallback { 64 public: 65 void onAudioDeviceUpdate(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds) override; 66 status_t waitForAudioDeviceCb(audio_port_handle_t expDeviceId = AUDIO_PORT_HANDLE_NONE); 67 std::pair<audio_io_handle_t, DeviceIdVector> getLastPortAndDevices() const; 68 69 private: 70 audio_io_handle_t mAudioIo GUARDED_BY(mMutex) = AUDIO_IO_HANDLE_NONE; 71 DeviceIdVector mDeviceIds GUARDED_BY(mMutex); 72 mutable std::mutex mMutex; 73 std::condition_variable mCondition; 74 }; 75 76 // Simple AudioPlayback class. 77 class AudioPlayback : public AudioTrack::IAudioTrackCallback { 78 friend sp<AudioPlayback>; 79 AudioPlayback(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, 80 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, 81 audio_session_t sessionId = AUDIO_SESSION_NONE, 82 AudioTrack::transfer_type transferType = AudioTrack::TRANSFER_SHARED, 83 audio_attributes_t* attributes = nullptr, audio_offload_info_t* info = nullptr); 84 85 public: 86 status_t loadResource(const char* name); 87 status_t create(); 88 sp<AudioTrack> getAudioTrackHandle(); 89 status_t start(); 90 status_t waitForConsumption(bool testSeek = false) EXCLUDES(mMutex); 91 status_t fillBuffer(); 92 status_t onProcess(bool testSeek = false); 93 void onBufferEnd() override EXCLUDES(mMutex); 94 void stop() EXCLUDES(mMutex); 95 96 bool mStopPlaying GUARDED_BY(mMutex); 97 mutable std::mutex mMutex; 98 99 enum State { 100 PLAY_NO_INIT, 101 PLAY_READY, 102 PLAY_STARTED, 103 PLAY_STOPPED, 104 }; 105 106 private: 107 ~AudioPlayback(); 108 const uint32_t mSampleRate; 109 const audio_format_t mFormat; 110 const audio_channel_mask_t mChannelMask; 111 const audio_output_flags_t mFlags; 112 const audio_session_t mSessionId; 113 const AudioTrack::transfer_type mTransferType; 114 const audio_attributes_t* mAttributes; 115 const audio_offload_info_t* mOffloadInfo; 116 117 size_t mBytesUsedSoFar; 118 State mState; 119 size_t mMemCapacity; 120 sp<MemoryDealer> mMemoryDealer; 121 sp<IMemory> mMemory; 122 123 sp<AudioTrack> mTrack; 124 }; 125 126 // hold pcm data sent by AudioRecord 127 class RawBuffer { 128 public: 129 RawBuffer(int64_t ptsPipeline = -1, int64_t ptsManual = -1, int32_t capacity = 0); 130 131 std::unique_ptr<uint8_t[]> mData; 132 int64_t mPtsPipeline; 133 int64_t mPtsManual; 134 int32_t mCapacity; 135 }; 136 137 // Simple AudioCapture 138 class AudioCapture : public AudioRecord::IAudioRecordCallback { 139 public: 140 AudioCapture(audio_source_t inputSource, uint32_t sampleRate, audio_format_t format, 141 audio_channel_mask_t channelMask, 142 audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, 143 audio_session_t sessionId = AUDIO_SESSION_ALLOCATE, 144 AudioRecord::transfer_type transferType = AudioRecord::TRANSFER_CALLBACK, 145 const audio_attributes_t* attributes = nullptr); 146 ~AudioCapture(); 147 size_t onMoreData(const AudioRecord::Buffer& buffer) override EXCLUDES(mMutex); 148 void onOverrun() override; 149 void onMarker(uint32_t markerPosition) override EXCLUDES(mMutex); 150 void onNewPos(uint32_t newPos) override EXCLUDES(mMutex); 151 void onNewIAudioRecord() override; 152 status_t create(); 153 status_t setRecordDuration(float durationInSec); 154 status_t enableRecordDump(); getRecordDumpFileName()155 std::string getRecordDumpFileName() const { return mFileName; } 156 sp<AudioRecord> getAudioRecordHandle(); 157 status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE, 158 audio_session_t triggerSession = AUDIO_SESSION_NONE); 159 status_t obtainBufferCb(RawBuffer& buffer) EXCLUDES(mMutex); 160 status_t obtainBuffer(RawBuffer& buffer) EXCLUDES(mMutex); 161 status_t audioProcess() EXCLUDES(mMutex); 162 status_t stop() EXCLUDES(mMutex); 163 uint32_t getMarkerPeriod() const EXCLUDES(mMutex); 164 uint32_t getMarkerPosition() const EXCLUDES(mMutex); 165 void setMarkerPeriod(uint32_t markerPeriod) EXCLUDES(mMutex); 166 void setMarkerPosition(uint32_t markerPosition) EXCLUDES(mMutex); 167 uint32_t waitAndGetReceivedCbMarkerAtPosition() const EXCLUDES(mMutex); 168 uint32_t waitAndGetReceivedCbMarkerCount() const EXCLUDES(mMutex); 169 170 uint32_t mFrameCount = 0; 171 uint32_t mNotificationFrames = 0; 172 int64_t mNumFramesToRecord = 0; 173 174 enum State { 175 REC_NO_INIT, 176 REC_READY, 177 REC_STARTED, 178 REC_STOPPED, 179 }; 180 181 private: 182 const audio_source_t mInputSource; 183 const uint32_t mSampleRate; 184 const audio_format_t mFormat; 185 const audio_channel_mask_t mChannelMask; 186 const audio_input_flags_t mFlags; 187 const audio_session_t mSessionId; 188 const AudioRecord::transfer_type mTransferType; 189 const audio_attributes_t* mAttributes; 190 191 size_t mMaxBytesPerCallback = 2048; 192 sp<AudioRecord> mRecord; 193 State mState = REC_NO_INIT; 194 bool mStopRecording GUARDED_BY(mMutex) = false; 195 std::string mFileName; 196 int mOutFileFd = -1; 197 198 mutable std::mutex mMutex; 199 std::condition_variable mCondition; 200 std::deque<RawBuffer> mBuffersReceived GUARDED_BY(mMutex); 201 202 mutable std::condition_variable mMarkerCondition; 203 uint32_t mMarkerPeriod GUARDED_BY(mMutex) = 0; 204 uint32_t mMarkerPosition GUARDED_BY(mMutex) = 0; 205 std::optional<uint32_t> mReceivedCbMarkerCount GUARDED_BY(mMutex); 206 std::optional<uint32_t> mReceivedCbMarkerAtPosition GUARDED_BY(mMutex); 207 208 int64_t mNumFramesReceived GUARDED_BY(mMutex) = 0; 209 int64_t mNumFramesLost GUARDED_BY(mMutex) = 0; 210 }; 211 212 #endif // AUDIO_TEST_UTILS_H_ 213