1*05767d91SRobert Wu /*
2*05767d91SRobert Wu * Copyright 2021 The Android Open Source Project
3*05767d91SRobert Wu *
4*05767d91SRobert Wu * Licensed under the Apache License, Version 2.0 (the "License");
5*05767d91SRobert Wu * you may not use this file except in compliance with the License.
6*05767d91SRobert Wu * You may obtain a copy of the License at
7*05767d91SRobert Wu *
8*05767d91SRobert Wu * http://www.apache.org/licenses/LICENSE-2.0
9*05767d91SRobert Wu *
10*05767d91SRobert Wu * Unless required by applicable law or agreed to in writing, software
11*05767d91SRobert Wu * distributed under the License is distributed on an "AS IS" BASIS,
12*05767d91SRobert Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*05767d91SRobert Wu * See the License for the specific language governing permissions and
14*05767d91SRobert Wu * limitations under the License.
15*05767d91SRobert Wu */
16*05767d91SRobert Wu
17*05767d91SRobert Wu #include <gtest/gtest.h>
18*05767d91SRobert Wu #include <oboe/Oboe.h>
19*05767d91SRobert Wu
20*05767d91SRobert Wu #include <tuple>
21*05767d91SRobert Wu
22*05767d91SRobert Wu using namespace oboe;
23*05767d91SRobert Wu
24*05767d91SRobert Wu class FramesProcessedCallback : public AudioStreamDataCallback {
25*05767d91SRobert Wu public:
onAudioReady(AudioStream * oboeStream,void * audioData,int32_t numFrames)26*05767d91SRobert Wu DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
27*05767d91SRobert Wu return DataCallbackResult::Continue;
28*05767d91SRobert Wu }
29*05767d91SRobert Wu };
30*05767d91SRobert Wu
31*05767d91SRobert Wu using StreamFramesProcessedParams = std::tuple<Direction, int32_t>;
32*05767d91SRobert Wu
33*05767d91SRobert Wu class StreamFramesProcessed : public ::testing::Test,
34*05767d91SRobert Wu public ::testing::WithParamInterface<StreamFramesProcessedParams> {
35*05767d91SRobert Wu
36*05767d91SRobert Wu protected:
37*05767d91SRobert Wu void TearDown() override;
38*05767d91SRobert Wu
39*05767d91SRobert Wu static constexpr int PROCESS_TIME_SECONDS = 5;
40*05767d91SRobert Wu
41*05767d91SRobert Wu AudioStreamBuilder mBuilder;
42*05767d91SRobert Wu AudioStream *mStream = nullptr;
43*05767d91SRobert Wu };
44*05767d91SRobert Wu
TearDown()45*05767d91SRobert Wu void StreamFramesProcessed::TearDown() {
46*05767d91SRobert Wu if (mStream != nullptr) {
47*05767d91SRobert Wu mStream->close();
48*05767d91SRobert Wu mStream = nullptr;
49*05767d91SRobert Wu }
50*05767d91SRobert Wu }
51*05767d91SRobert Wu
TEST_P(StreamFramesProcessed,VerifyFramesProcessed)52*05767d91SRobert Wu TEST_P(StreamFramesProcessed, VerifyFramesProcessed) {
53*05767d91SRobert Wu const Direction direction = std::get<0>(GetParam());
54*05767d91SRobert Wu const int32_t sampleRate = std::get<1>(GetParam());
55*05767d91SRobert Wu
56*05767d91SRobert Wu AudioStreamDataCallback *callback = new FramesProcessedCallback();
57*05767d91SRobert Wu mBuilder.setDirection(direction)
58*05767d91SRobert Wu ->setFormat(AudioFormat::I16)
59*05767d91SRobert Wu ->setSampleRate(sampleRate)
60*05767d91SRobert Wu ->setSampleRateConversionQuality(SampleRateConversionQuality::Medium)
61*05767d91SRobert Wu ->setPerformanceMode(PerformanceMode::LowLatency)
62*05767d91SRobert Wu ->setSharingMode(SharingMode::Exclusive)
63*05767d91SRobert Wu ->setDataCallback(callback);
64*05767d91SRobert Wu mStream = nullptr;
65*05767d91SRobert Wu Result r = mBuilder.openStream(&mStream);
66*05767d91SRobert Wu ASSERT_EQ(r, Result::OK) << "Failed to open stream." << convertToText(r);
67*05767d91SRobert Wu
68*05767d91SRobert Wu r = mStream->start();
69*05767d91SRobert Wu ASSERT_EQ(r, Result::OK) << "Failed to start stream." << convertToText(r);
70*05767d91SRobert Wu sleep(PROCESS_TIME_SECONDS);
71*05767d91SRobert Wu
72*05767d91SRobert Wu // The frames written should be close to sampleRate * PROCESS_TIME_SECONDS
73*05767d91SRobert Wu const int kDeltaFramesWindowInFrames = 30000;
74*05767d91SRobert Wu const int64_t framesWritten = mStream->getFramesWritten();
75*05767d91SRobert Wu const int64_t framesRead = mStream->getFramesRead();
76*05767d91SRobert Wu EXPECT_NEAR(framesWritten, sampleRate * PROCESS_TIME_SECONDS, kDeltaFramesWindowInFrames);
77*05767d91SRobert Wu EXPECT_NEAR(framesRead, sampleRate * PROCESS_TIME_SECONDS, kDeltaFramesWindowInFrames);
78*05767d91SRobert Wu }
79*05767d91SRobert Wu
80*05767d91SRobert Wu INSTANTIATE_TEST_CASE_P(
81*05767d91SRobert Wu StreamFramesProcessedTest,
82*05767d91SRobert Wu StreamFramesProcessed,
83*05767d91SRobert Wu ::testing::Values(
84*05767d91SRobert Wu StreamFramesProcessedParams({Direction::Output, 8000}),
85*05767d91SRobert Wu StreamFramesProcessedParams({Direction::Output, 44100}),
86*05767d91SRobert Wu StreamFramesProcessedParams({Direction::Output, 96000}),
87*05767d91SRobert Wu StreamFramesProcessedParams({Direction::Input, 8000}),
88*05767d91SRobert Wu StreamFramesProcessedParams({Direction::Input, 44100}),
89*05767d91SRobert Wu StreamFramesProcessedParams({Direction::Input, 96000})
90*05767d91SRobert Wu )
91*05767d91SRobert Wu );
92