Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2018 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 /*
     18  * Test FlowGraph
     19  */
     20 
     21 #include <iostream>
     22 
     23 #include <gtest/gtest.h>
     24 
     25 #include "flowgraph/ClipToRange.h"
     26 #include "flowgraph/MonoToMultiConverter.h"
     27 #include "flowgraph/SourceFloat.h"
     28 #include "flowgraph/RampLinear.h"
     29 #include "flowgraph/SinkFloat.h"
     30 #include "flowgraph/SinkI16.h"
     31 #include "flowgraph/SinkI24.h"
     32 #include "flowgraph/SourceI16.h"
     33 #include "flowgraph/SourceI24.h"
     34 
     35 using namespace flowgraph;
     36 
     37 constexpr int kBytesPerI24Packed = 3;
     38 
     39 TEST(test_flowgraph, module_sinki16) {
     40     static const float input[] = {1.0f, 0.5f, -0.25f, -1.0f, 0.0f, 53.9f, -87.2f};
     41     static const int16_t expected[] = {32767, 16384, -8192, -32768, 0, 32767, -32768};
     42     int16_t output[20];
     43     SourceFloat sourceFloat{1};
     44     SinkI16 sinkI16{1};
     45 
     46     int numInputFrames = sizeof(input) / sizeof(input[0]);
     47     sourceFloat.setData(input, numInputFrames);
     48     sourceFloat.output.connect(&sinkI16.input);
     49 
     50     int numOutputFrames = sizeof(output) / sizeof(int16_t);
     51     int32_t numRead = sinkI16.read(output, numOutputFrames);
     52     ASSERT_EQ(numInputFrames, numRead);
     53     for (int i = 0; i < numRead; i++) {
     54         EXPECT_EQ(expected[i], output[i]);
     55     }
     56 }
     57 
     58 TEST(test_flowgraph, module_mono_to_stereo) {
     59     static const float input[] = {1.0f, 2.0f, 3.0f};
     60     float output[100] = {};
     61     SourceFloat sourceFloat{1};
     62     MonoToMultiConverter monoToStereo{2};
     63     SinkFloat sinkFloat{2};
     64 
     65     sourceFloat.setData(input, 3);
     66 
     67     sourceFloat.output.connect(&monoToStereo.input);
     68     monoToStereo.output.connect(&sinkFloat.input);
     69 
     70     int32_t numRead = sinkFloat.read(output, 8);
     71     ASSERT_EQ(3, numRead);
     72     EXPECT_EQ(input[0], output[0]);
     73     EXPECT_EQ(input[0], output[1]);
     74     EXPECT_EQ(input[1], output[2]);
     75     EXPECT_EQ(input[1], output[3]);
     76 }
     77 
     78 TEST(test_flowgraph, module_ramp_linear) {
     79     constexpr int rampSize = 5;
     80     constexpr int numOutput = 100;
     81     constexpr float value = 1.0f;
     82     constexpr float target = 100.0f;
     83     float output[numOutput] = {};
     84     RampLinear rampLinear{1};
     85     SinkFloat sinkFloat{1};
     86 
     87     rampLinear.input.setValue(value);
     88     rampLinear.setLengthInFrames(rampSize);
     89     rampLinear.setTarget(target);
     90     rampLinear.forceCurrent(0.0f);
     91 
     92     rampLinear.output.connect(&sinkFloat.input);
     93 
     94     int32_t numRead = sinkFloat.read(output, numOutput);
     95     ASSERT_EQ(numOutput, numRead);
     96     constexpr float tolerance = 0.0001f; // arbitrary
     97     int i = 0;
     98     for (; i < rampSize; i++) {
     99         float expected = i * value * target / rampSize;
    100         EXPECT_NEAR(expected, output[i], tolerance);
    101     }
    102     for (; i < numOutput; i++) {
    103         float expected = value * target;
    104         EXPECT_NEAR(expected, output[i], tolerance);
    105     }
    106 }
    107 
    108 // It is easiest to represent packed 24-bit data as a byte array.
    109 // This test will read from input, convert to float, then write
    110 // back to output as bytes.
    111 TEST(test_flowgraph, module_packed_24) {
    112     static const uint8_t input[] = {0x01, 0x23, 0x45,
    113                                     0x67, 0x89, 0xAB,
    114                                     0xCD, 0xEF, 0x5A};
    115     uint8_t output[99] = {};
    116     SourceI24 sourceI24{1};
    117     SinkI24 sinkI24{1};
    118 
    119     int numInputFrames = sizeof(input) / kBytesPerI24Packed;
    120     sourceI24.setData(input, numInputFrames);
    121     sourceI24.output.connect(&sinkI24.input);
    122 
    123     int32_t numRead = sinkI24.read(output, sizeof(output) / kBytesPerI24Packed);
    124     ASSERT_EQ(numInputFrames, numRead);
    125     for (size_t i = 0; i < sizeof(input); i++) {
    126         EXPECT_EQ(input[i], output[i]);
    127     }
    128 }
    129 
    130 TEST(test_flowgraph, module_clip_to_range) {
    131     constexpr float myMin = -2.0f;
    132     constexpr float myMax = 1.5f;
    133 
    134     static const float input[] = {-9.7, 0.5f, -0.25, 1.0f, 12.3};
    135     static const float expected[] = {myMin, 0.5f, -0.25, 1.0f, myMax};
    136     float output[100];
    137     SourceFloat sourceFloat{1};
    138     ClipToRange clipper{1};
    139     SinkFloat sinkFloat{1};
    140 
    141     int numInputFrames = sizeof(input) / sizeof(input[0]);
    142     sourceFloat.setData(input, numInputFrames);
    143 
    144     clipper.setMinimum(myMin);
    145     clipper.setMaximum(myMax);
    146 
    147     sourceFloat.output.connect(&clipper.input);
    148     clipper.output.connect(&sinkFloat.input);
    149 
    150     int numOutputFrames = sizeof(output) / sizeof(output[0]);
    151     int32_t numRead = sinkFloat.read(output, numOutputFrames);
    152     ASSERT_EQ(numInputFrames, numRead);
    153     constexpr float tolerance = 0.000001f; // arbitrary
    154     for (int i = 0; i < numRead; i++) {
    155         EXPECT_NEAR(expected[i], output[i], tolerance);
    156     }
    157 }
    158