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