1e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk/*
2e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Copyright (C) 2017 The Android Open Source Project
3e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk *
4e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Licensed under the Apache License, Version 2.0 (the "License");
5e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * you may not use this file except in compliance with the License.
6e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * You may obtain a copy of the License at
7e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk *
8e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk *      http://www.apache.org/licenses/LICENSE-2.0
9e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk *
10e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Unless required by applicable law or agreed to in writing, software
11e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * distributed under the License is distributed on an "AS IS" BASIS,
12e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * See the License for the specific language governing permissions and
14e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * limitations under the License.
15e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk */
16e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
17e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <iostream>
18e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
19e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <gtest/gtest.h>
20e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
21e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "utility/FixedBlockAdapter.h"
22e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "utility/FixedBlockWriter.h"
23e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "utility/FixedBlockReader.h"
24e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
25e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#define FIXED_BLOCK_SIZE   47
26e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#define TEST_BUFFER_SIZE   103
27e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
28e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk// Pass varying sized blocks.
29e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk// Frames contain a sequential index, which are easily checked.
30e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkclass TestBlockAdapter {
31e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkpublic:
32e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    TestBlockAdapter()
33e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            : mTestIndex(0), mLastIndex(0) {
34e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
35e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
36e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    ~TestBlockAdapter() = default;
37e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
38e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    void fillSequence(int32_t *indexBuffer, int32_t frameCount) {
39e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        ASSERT_LE(frameCount, TEST_BUFFER_SIZE);
40e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        for (int i = 0; i < frameCount; i++) {
41e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            indexBuffer[i] = mLastIndex++;
42e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        }
43e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
44e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
45e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int checkSequence(const int32_t *indexBuffer, int32_t frameCount) {
46e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        // This is equivalent to calling an output callback.
47e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        for (int i = 0; i < frameCount; i++) {
48e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            int32_t expected = mTestIndex++;
49e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            int32_t actual = indexBuffer[i];
50e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            EXPECT_EQ(expected, actual);
51e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            if (actual != expected) {
52e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk                return -1;
53e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            }
54e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        }
55e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return 0;
56e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
57e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
58e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t            mTestBuffer[TEST_BUFFER_SIZE];
59e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t            mTestIndex;
60e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t            mLastIndex;
61e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk};
62e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
63e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkclass TestBlockWriter : public TestBlockAdapter, FixedBlockProcessor {
64e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkpublic:
65e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    TestBlockWriter()
66e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            : mFixedBlockWriter(*this) {
67e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        mFixedBlockWriter.open(sizeof(int32_t) * FIXED_BLOCK_SIZE);
68e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
69e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
70e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    ~TestBlockWriter() {
71e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        mFixedBlockWriter.close();
72e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
73e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
74e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) override {
75e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        int32_t frameCount = numBytes / sizeof(int32_t);
76e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return checkSequence((int32_t *) buffer, frameCount);
77e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
78e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
79e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    // Simulate audio input from a variable sized callback.
80e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t testInputWrite(int32_t variableCount) {
81e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        fillSequence(mTestBuffer, variableCount);
82e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        int32_t sizeBytes = variableCount * sizeof(int32_t);
83e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return mFixedBlockWriter.processVariableBlock((uint8_t *) mTestBuffer, sizeBytes);
84e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
85e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
86e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkprivate:
87e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    FixedBlockWriter mFixedBlockWriter;
88e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk};
89e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
90e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkclass TestBlockReader : public TestBlockAdapter, FixedBlockProcessor {
91e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkpublic:
92e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    TestBlockReader()
93e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            : mFixedBlockReader(*this) {
94e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        mFixedBlockReader.open(sizeof(int32_t) * FIXED_BLOCK_SIZE);
95e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
96e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
97e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    ~TestBlockReader() {
98e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        mFixedBlockReader.close();
99e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
100e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
101e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) override {
102e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        int32_t frameCount = numBytes / sizeof(int32_t);
103e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        fillSequence((int32_t *) buffer, frameCount);
104e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return 0;
105e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
106e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
107e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    // Simulate audio output from a variable sized callback.
108e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t testOutputRead(int32_t variableCount) {
109e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        int32_t sizeBytes = variableCount * sizeof(int32_t);
110e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        int32_t result = mFixedBlockReader.processVariableBlock((uint8_t *) mTestBuffer, sizeBytes);
111e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        if (result >= 0) {
112e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk            result = checkSequence((int32_t *)mTestBuffer, variableCount);
113e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        }
114e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return result;
115e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
116e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
117e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkprivate:
118e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    FixedBlockReader   mFixedBlockReader;
119e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk};
120e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
121e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
122e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil BurkTEST(test_block_adapter, block_adapter_write) {
123e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    TestBlockWriter tester;
124e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int result = 0;
125e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    const int numLoops = 1000;
126e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
127e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    for (int i = 0; i<numLoops && result == 0; i++) {
128e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        long r = random();
129e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        int32_t size = (r % TEST_BUFFER_SIZE);
130e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        ASSERT_LE(size, TEST_BUFFER_SIZE);
131e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        ASSERT_GE(size, 0);
132e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        result = tester.testInputWrite(size);
133e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
134e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    ASSERT_EQ(0, result);
135e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk}
136e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
137e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil BurkTEST(test_block_adapter, block_adapter_read) {
138e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    TestBlockReader tester;
139e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int result = 0;
140e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    const int numLoops = 1000;
141e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
142e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    for (int i = 0; i < numLoops && result == 0; i++) {
143e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        long r = random();
144e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        int32_t size = (r % TEST_BUFFER_SIZE);
145e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        ASSERT_LE(size, TEST_BUFFER_SIZE);
146e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        ASSERT_GE(size, 0);
147e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        result = tester.testOutputRead(size);
148e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
149e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    ASSERT_EQ(0, result);
150e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk};
151e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
152