1 /* 2 * Copyright (C) 2017 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 #include <memory> 18 19 #include <android/log.h> 20 21 #include "lb2/logging.h" 22 #include "lb2/loopback2.h" 23 #include "lb2/loopback_test.h" 24 #include "lb2/sound_system_aaudio.h" 25 #include "lb2/sound_system_echo.h" 26 27 // The Java layer always uses "mono" mode for native tests. 28 static constexpr int CHANNEL_COUNT = 1; 29 30 struct LbData { 31 std::unique_ptr<TestContext> testContext; 32 std::unique_ptr<SoundSystem> soundSys; 33 std::unique_ptr<LoopbackTest> currentTest; 34 }; 35 36 int lb2ComputeDefaultSettings(int performanceMode, int *samplingRate, 37 int *playerBufferFrameCount, int *recorderBufferFrameCount) { 38 SoundSystemAAudio ss; 39 return ss.probeDefaultSettings(static_cast<PerformanceMode>(performanceMode), 40 samplingRate, playerBufferFrameCount, recorderBufferFrameCount) ? 41 STATUS_SUCCESS : STATUS_FAIL; 42 } 43 44 int lb2Init(void **ppLbData, int samplingRate, int frameCount, int /*micSource*/, 45 int performanceMode, int testType, double frequency1, char* byteBufferPtr, 46 int byteBufferLength, short* loopbackTone, int /*maxRecordedLateCallbacks*/, 47 int ignoreFirstFrames) { 48 *ppLbData = nullptr; 49 std::unique_ptr<LbData> lbData(new LbData()); // will auto-release in case if init fails. 50 switch (testType) { 51 case TEST_TYPE_LATENCY: 52 lbData->testContext.reset(new LatencyTestContext( 53 static_cast<PerformanceMode>(performanceMode), frameCount, 54 CHANNEL_COUNT, samplingRate, ignoreFirstFrames, loopbackTone)); 55 break; 56 case TEST_TYPE_BUFFER_PERIOD: { 57 // TODO: Get rid of ByteBuffer. 58 static_assert( 59 sizeof(sample_t) == sizeof(short), "byteBuffer only supports short samples"); 60 AudioBufferView<sample_t> byteBuffer( 61 reinterpret_cast<sample_t*>(byteBufferPtr), byteBufferLength, CHANNEL_COUNT); 62 lbData->testContext.reset(new GlitchTestContext( 63 static_cast<PerformanceMode>(performanceMode),frameCount, 64 CHANNEL_COUNT, samplingRate, frequency1, std::move(byteBuffer))); 65 break; 66 } 67 default: 68 ALOGE("Invalid test type: %d", testType); 69 return STATUS_FAIL; 70 } 71 // TODO: Implement switching from the Java side. 72 lbData->soundSys.reset(new SoundSystemAAudio(lbData->testContext.get())); 73 // lbData->soundSys.reset(new SoundSystemEcho(lbData->testContext.get())); 74 switch (testType) { 75 case TEST_TYPE_LATENCY: 76 lbData->currentTest.reset(new LatencyTest( 77 lbData->soundSys.get(), 78 static_cast<LatencyTestContext*>(lbData->testContext.get()))); 79 break; 80 case TEST_TYPE_BUFFER_PERIOD: 81 lbData->currentTest.reset(new GlitchTest( 82 lbData->soundSys.get(), 83 static_cast<GlitchTestContext*>(lbData->testContext.get()))); 84 break; 85 } 86 if (!lbData->currentTest->init()) return STATUS_FAIL; 87 *ppLbData = lbData.release(); 88 return STATUS_SUCCESS; 89 } 90 91 int lb2ProcessNext(void *pLbData, double *pSamples, long maxSamples) { 92 if (pLbData == nullptr) return 0; 93 LbData *lbData = static_cast<LbData*>(pLbData); 94 return lbData->currentTest->collectRecording( 95 AudioBufferView<double>(pSamples, maxSamples / CHANNEL_COUNT, CHANNEL_COUNT)); 96 } 97 98 int lb2Destroy(void **ppCtx) { 99 LbData** ppLbData = reinterpret_cast<LbData**>(ppCtx); 100 if (ppLbData != nullptr) { 101 delete *ppLbData; 102 *ppLbData = nullptr; 103 return STATUS_SUCCESS; 104 } else { 105 return STATUS_FAIL; 106 } 107 } 108 109 int* lb2GetRecorderBufferPeriod(void*) { 110 static int *bufferPeriod = new int[1002](); 111 return bufferPeriod; 112 } 113 114 int lb2GetRecorderMaxBufferPeriod(void*) { 115 return 0; 116 } 117 118 int64_t lb2GetRecorderVarianceBufferPeriod(void*) { 119 return 0; 120 } 121 122 int* lb2GetPlayerBufferPeriod(void*) { 123 static int *bufferPeriod = new int[1002](); 124 return bufferPeriod; 125 } 126 127 int lb2GetPlayerMaxBufferPeriod(void*) { 128 return 0; 129 } 130 131 int64_t lb2GetPlayerVarianceBufferPeriod(void*) { 132 return 0; 133 } 134 135 int lb2GetCaptureRank(void*) { 136 return 0; 137 } 138 139 int lb2GetPlayerTimeStampsAndExpectedBufferPeriod(void*, callbackTimeStamps **ppTSs) { 140 static callbackTimeStamps tss = { 141 new int[10], //int* timeStampsMs 142 new short[10], //short* callbackDurations 143 0, //short index 144 {0,0}, //struct timespec startTime; 145 0, //int capacity 146 false //bool exceededCapacity 147 }; 148 *ppTSs = &tss; 149 return 0; 150 } 151 152 int lb2GetRecorderTimeStampsAndExpectedBufferPeriod(void*, callbackTimeStamps **ppTSs) { 153 static callbackTimeStamps tss = { 154 new int[10], //int* timeStampsMs 155 new short[10], //short* callbackDurations 156 0, //short index 157 {0,0}, //struct timespec startTime; 158 0, //int capacity 159 false //bool exceededCapacity 160 }; 161 *ppTSs = &tss; 162 return 0; 163 } 164