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 <atomic> 23 #include <chrono> 24 #include <cinttypes> 25 #include <deque> 26 #include <memory> 27 #include <mutex> 28 #include <thread> 29 30 #include <binder/MemoryDealer.h> 31 #include <media/AidlConversion.h> 32 #include <media/AudioRecord.h> 33 #include <media/AudioTrack.h> 34 35 using namespace android; 36 37 struct MixPort { 38 std::string name; 39 std::string role; 40 std::string flags; 41 }; 42 43 struct Route { 44 std::string name; 45 std::string sources; 46 std::string sink; 47 }; 48 49 status_t listAudioPorts(std::vector<audio_port_v7>& portsVec); 50 status_t listAudioPatches(std::vector<struct audio_patch>& patchesVec); 51 status_t getPortByAttributes(audio_port_role_t role, audio_port_type_t type, 52 audio_devices_t deviceType, const std::string& address, 53 audio_port_v7& port); 54 status_t getPatchForOutputMix(audio_io_handle_t audioIo, audio_patch& patch); 55 status_t getPatchForInputMix(audio_io_handle_t audioIo, audio_patch& patch); 56 bool patchContainsOutputDevice(audio_port_handle_t deviceId, audio_patch patch); 57 bool patchContainsInputDevice(audio_port_handle_t deviceId, audio_patch patch); 58 bool checkPatchPlayback(audio_io_handle_t audioIo, audio_port_handle_t deviceId); 59 bool checkPatchCapture(audio_io_handle_t audioIo, audio_port_handle_t deviceId); 60 std::string dumpPort(const audio_port_v7& port); 61 std::string dumpPortConfig(const audio_port_config& port); 62 std::string dumpPatch(const audio_patch& patch); 63 64 class OnAudioDeviceUpdateNotifier : public AudioSystem::AudioDeviceCallback { 65 public: 66 audio_io_handle_t mAudioIo = AUDIO_IO_HANDLE_NONE; 67 audio_port_handle_t mDeviceId = AUDIO_PORT_HANDLE_NONE; 68 std::mutex mMutex; 69 std::condition_variable mCondition; 70 71 void onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId); 72 status_t waitForAudioDeviceCb(audio_port_handle_t expDeviceId = AUDIO_PORT_HANDLE_NONE); 73 }; 74 75 // Simple AudioPlayback class. 76 class AudioPlayback : public AudioTrack::IAudioTrackCallback { 77 friend sp<AudioPlayback>; 78 AudioPlayback(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, 79 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, 80 audio_session_t sessionId = AUDIO_SESSION_NONE, 81 AudioTrack::transfer_type transferType = AudioTrack::TRANSFER_SHARED, 82 audio_attributes_t* attributes = nullptr, audio_offload_info_t* info = nullptr); 83 84 public: 85 status_t loadResource(const char* name); 86 status_t create(); 87 sp<AudioTrack> getAudioTrackHandle(); 88 status_t start(); 89 status_t waitForConsumption(bool testSeek = false); 90 status_t fillBuffer(); 91 status_t onProcess(bool testSeek = false); 92 virtual void onBufferEnd() override; 93 void stop(); 94 95 bool mStopPlaying; 96 std::mutex mMutex; 97 std::condition_variable mCondition; 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; 148 void onOverrun() override; 149 void onMarker(uint32_t markerPosition) override; 150 void onNewPos(uint32_t newPos) override; 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); 160 status_t obtainBuffer(RawBuffer& buffer); 161 status_t audioProcess(); 162 status_t stop(); 163 164 uint32_t mFrameCount; 165 uint32_t mNotificationFrames; 166 int64_t mNumFramesToRecord; 167 int64_t mNumFramesReceived; 168 int64_t mNumFramesLost; 169 uint32_t mMarkerPosition; 170 uint32_t mMarkerPeriod; 171 uint32_t mReceivedCbMarkerAtPosition; 172 uint32_t mReceivedCbMarkerCount; 173 bool mBufferOverrun; 174 175 enum State { 176 REC_NO_INIT, 177 REC_READY, 178 REC_STARTED, 179 REC_STOPPED, 180 }; 181 182 private: 183 const audio_source_t mInputSource; 184 const uint32_t mSampleRate; 185 const audio_format_t mFormat; 186 const audio_channel_mask_t mChannelMask; 187 const audio_input_flags_t mFlags; 188 const audio_session_t mSessionId; 189 const AudioRecord::transfer_type mTransferType; 190 const audio_attributes_t* mAttributes; 191 192 size_t mMaxBytesPerCallback = 2048; 193 sp<AudioRecord> mRecord; 194 State mState; 195 bool mStopRecording; 196 std::string mFileName; 197 int mOutFileFd = -1; 198 199 std::mutex mMutex; 200 std::condition_variable mCondition; 201 std::deque<RawBuffer> mBuffersReceived; 202 }; 203 204 #endif // AUDIO_TEST_UTILS_H_ 205