blob: 228dc404fbda5eb86622ca5ba5809a56ec7f12c4 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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 <memory>
#include <android/log.h>
#include "lb2/logging.h"
#include "lb2/loopback2.h"
#include "lb2/loopback_test.h"
#include "lb2/sound_system_aaudio.h"
#include "lb2/sound_system_echo.h"
// The Java layer always uses "mono" mode for native tests.
static constexpr int CHANNEL_COUNT = 1;
struct LbData {
std::unique_ptr<TestContext> testContext;
std::unique_ptr<SoundSystem> soundSys;
std::unique_ptr<LoopbackTest> currentTest;
};
int lb2ComputeDefaultSettings(int performanceMode, int *samplingRate,
int *playerBufferFrameCount, int *recorderBufferFrameCount) {
SoundSystemAAudio ss;
return ss.probeDefaultSettings(static_cast<PerformanceMode>(performanceMode),
samplingRate, playerBufferFrameCount, recorderBufferFrameCount) ?
STATUS_SUCCESS : STATUS_FAIL;
}
int lb2Init(void **ppLbData, int samplingRate, int frameCount, int /*micSource*/,
int performanceMode, int testType, double frequency1, char* byteBufferPtr,
int byteBufferLength, short* loopbackTone, int /*maxRecordedLateCallbacks*/,
int ignoreFirstFrames) {
*ppLbData = nullptr;
std::unique_ptr<LbData> lbData(new LbData()); // will auto-release in case if init fails.
switch (testType) {
case TEST_TYPE_LATENCY:
lbData->testContext.reset(new LatencyTestContext(
static_cast<PerformanceMode>(performanceMode), frameCount,
CHANNEL_COUNT, samplingRate, ignoreFirstFrames, loopbackTone));
break;
case TEST_TYPE_BUFFER_PERIOD: {
// TODO: Get rid of ByteBuffer.
static_assert(
sizeof(sample_t) == sizeof(short), "byteBuffer only supports short samples");
AudioBufferView<sample_t> byteBuffer(
reinterpret_cast<sample_t*>(byteBufferPtr), byteBufferLength, CHANNEL_COUNT);
lbData->testContext.reset(new GlitchTestContext(
static_cast<PerformanceMode>(performanceMode),frameCount,
CHANNEL_COUNT, samplingRate, frequency1, std::move(byteBuffer)));
break;
}
default:
ALOGE("Invalid test type: %d", testType);
return STATUS_FAIL;
}
// TODO: Implement switching from the Java side.
lbData->soundSys.reset(new SoundSystemAAudio(lbData->testContext.get()));
// lbData->soundSys.reset(new SoundSystemEcho(lbData->testContext.get()));
switch (testType) {
case TEST_TYPE_LATENCY:
lbData->currentTest.reset(new LatencyTest(
lbData->soundSys.get(),
static_cast<LatencyTestContext*>(lbData->testContext.get())));
break;
case TEST_TYPE_BUFFER_PERIOD:
lbData->currentTest.reset(new GlitchTest(
lbData->soundSys.get(),
static_cast<GlitchTestContext*>(lbData->testContext.get())));
break;
}
if (!lbData->currentTest->init()) return STATUS_FAIL;
*ppLbData = lbData.release();
return STATUS_SUCCESS;
}
int lb2ProcessNext(void *pLbData, double *pSamples, long maxSamples) {
if (pLbData == nullptr) return 0;
LbData *lbData = static_cast<LbData*>(pLbData);
return lbData->currentTest->collectRecording(
AudioBufferView<double>(pSamples, maxSamples / CHANNEL_COUNT, CHANNEL_COUNT));
}
int lb2Destroy(void **ppCtx) {
LbData** ppLbData = reinterpret_cast<LbData**>(ppCtx);
if (ppLbData != nullptr) {
delete *ppLbData;
*ppLbData = nullptr;
return STATUS_SUCCESS;
} else {
return STATUS_FAIL;
}
}
int* lb2GetRecorderBufferPeriod(void*) {
static int *bufferPeriod = new int[1002]();
return bufferPeriod;
}
int lb2GetRecorderMaxBufferPeriod(void*) {
return 0;
}
int64_t lb2GetRecorderVarianceBufferPeriod(void*) {
return 0;
}
int* lb2GetPlayerBufferPeriod(void*) {
static int *bufferPeriod = new int[1002]();
return bufferPeriod;
}
int lb2GetPlayerMaxBufferPeriod(void*) {
return 0;
}
int64_t lb2GetPlayerVarianceBufferPeriod(void*) {
return 0;
}
int lb2GetCaptureRank(void*) {
return 0;
}
int lb2GetPlayerTimeStampsAndExpectedBufferPeriod(void*, callbackTimeStamps **ppTSs) {
static callbackTimeStamps tss = {
new int[10], //int* timeStampsMs
new short[10], //short* callbackDurations
0, //short index
{0,0}, //struct timespec startTime;
0, //int capacity
false //bool exceededCapacity
};
*ppTSs = &tss;
return 0;
}
int lb2GetRecorderTimeStampsAndExpectedBufferPeriod(void*, callbackTimeStamps **ppTSs) {
static callbackTimeStamps tss = {
new int[10], //int* timeStampsMs
new short[10], //short* callbackDurations
0, //short index
{0,0}, //struct timespec startTime;
0, //int capacity
false //bool exceededCapacity
};
*ppTSs = &tss;
return 0;
}