Home | History | Annotate | Download | only in lb2
      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