1 /*
2 * Copyright 2023 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 <stdlib.h>
18 #include <aaudio/AAudioExtensions.h>
19
20 #include "common/OboeDebug.h"
21 #include "oboe/AudioClock.h"
22 #include "TestRapidCycle.h"
23
24 using namespace oboe;
25
26 // start a thread to cycle through stream tests
start(bool useOpenSL)27 int32_t TestRapidCycle::start(bool useOpenSL) {
28 mThreadEnabled = true;
29 mCycleCount = 0;
30 mCycleThread = std::thread([this, useOpenSL]() {
31 cycleRapidly(useOpenSL);
32 });
33 return 0;
34 }
stop()35 int32_t TestRapidCycle::stop() {
36 mThreadEnabled = false;
37 mCycleThread.join();
38 return 0;
39 }
40
cycleRapidly(bool useOpenSL)41 void TestRapidCycle::cycleRapidly(bool useOpenSL) {
42 while(mThreadEnabled && (oneCycle(useOpenSL) == 0));
43 }
44
oneCycle(bool useOpenSL)45 int32_t TestRapidCycle::oneCycle(bool useOpenSL) {
46 mCycleCount++;
47 mDataCallback = std::make_shared<MyDataCallback>();
48
49 AudioStreamBuilder builder;
50 oboe::Result result = builder.setFormat(oboe::AudioFormat::Float)
51 ->setAudioApi(useOpenSL ? oboe::AudioApi::OpenSLES : oboe::AudioApi::AAudio)
52 ->setPerformanceMode(oboe::PerformanceMode::LowLatency)
53 ->setChannelCount(kChannelCount)
54 ->setDataCallback(mDataCallback)
55 ->setUsage(oboe::Usage::Notification)
56 ->openStream(mStream);
57 if (result != oboe::Result::OK) {
58 return (int32_t) result;
59 }
60
61 mStream->setDelayBeforeCloseMillis(0);
62
63 result = mStream->requestStart();
64 if (result != oboe::Result::OK) {
65 mStream->close();
66 return (int32_t) result;
67 }
68 // Sleep for some random time.
69 int32_t durationMicros = (int32_t)(drand48() * kMaxSleepMicros);
70 LOGD("TestRapidCycle::oneCycle() - Sleep for %d micros", durationMicros);
71 usleep(durationMicros);
72 LOGD("TestRapidCycle::oneCycle() - Woke up, close stream");
73 mDataCallback->returnStop = true;
74 result = mStream->close();
75 return (int32_t) result;
76 }
77
78 // Callback that sleeps then touches the audio buffer.
onAudioReady(AudioStream * audioStream,void * audioData,int32_t numFrames)79 DataCallbackResult TestRapidCycle::MyDataCallback::onAudioReady(
80 AudioStream *audioStream,
81 void *audioData,
82 int32_t numFrames) {
83 float *floatData = (float *) audioData;
84 const int numSamples = numFrames * kChannelCount;
85
86 // Fill buffer with white noise.
87 for (int i = 0; i < numSamples; i++) {
88 floatData[i] = ((float) drand48() - 0.5f) * 2 * 0.1f;
89 }
90 usleep(500); // half a millisecond
91 if (returnStop) {
92 usleep(20 * 1000);
93 return DataCallbackResult::Stop;
94 } else {
95 return DataCallbackResult::Continue;
96 }
97 }
98