1 /*
2 * Copyright (C) 2024 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 <cmath>
18 #include <cstdlib>
19
20 #define LOG_TAG "AHAL_Stream"
21 #include <android-base/logging.h>
22 #include <audio_utils/clock.h>
23
24 #include "core-impl/DriverStubImpl.h"
25
26 namespace aidl::android::hardware::audio::core {
27
DriverStubImpl(const StreamContext & context,int asyncSleepTimeUs)28 DriverStubImpl::DriverStubImpl(const StreamContext& context, int asyncSleepTimeUs)
29 : mBufferSizeFrames(context.getBufferSizeInFrames()),
30 mFrameSizeBytes(context.getFrameSize()),
31 mSampleRate(context.getSampleRate()),
32 mIsAsynchronous(!!context.getAsyncCallback()),
33 mIsInput(context.isInput()),
34 mMixPortHandle(context.getMixPortHandle()),
35 mAsyncSleepTimeUs(asyncSleepTimeUs) {}
36
37 #define LOG_ENTRY() \
38 LOG(DEBUG) << "[" << (mIsInput ? "in" : "out") << "|ioHandle:" << mMixPortHandle << "] " \
39 << __func__;
40
init(DriverCallbackInterface *)41 ::android::status_t DriverStubImpl::init(DriverCallbackInterface* /*callback*/) {
42 LOG_ENTRY();
43 mIsInitialized = true;
44 return ::android::OK;
45 }
46
drain(StreamDescriptor::DrainMode)47 ::android::status_t DriverStubImpl::drain(StreamDescriptor::DrainMode) {
48 LOG_ENTRY();
49 if (!mIsInitialized) {
50 LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
51 }
52 if (!mIsInput) {
53 if (!mIsAsynchronous) {
54 static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
55 const size_t delayUs = static_cast<size_t>(
56 std::roundf(mBufferSizeFrames * kMicrosPerSecond / mSampleRate));
57 usleep(delayUs);
58 } else if (mAsyncSleepTimeUs) {
59 usleep(mAsyncSleepTimeUs);
60 }
61 }
62 return ::android::OK;
63 }
64
flush()65 ::android::status_t DriverStubImpl::flush() {
66 LOG_ENTRY();
67 if (!mIsInitialized) {
68 LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
69 }
70 return ::android::OK;
71 }
72
pause()73 ::android::status_t DriverStubImpl::pause() {
74 LOG_ENTRY();
75 if (!mIsInitialized) {
76 LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
77 }
78 return ::android::OK;
79 }
80
standby()81 ::android::status_t DriverStubImpl::standby() {
82 LOG_ENTRY();
83 if (!mIsInitialized) {
84 LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
85 }
86 mIsStandby = true;
87 return ::android::OK;
88 }
89
start()90 ::android::status_t DriverStubImpl::start() {
91 LOG_ENTRY();
92 if (!mIsInitialized) {
93 LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
94 }
95 mIsStandby = false;
96 mStartTimeNs = ::android::uptimeNanos();
97 mFramesSinceStart = 0;
98 return ::android::OK;
99 }
100
transfer(void * buffer,size_t frameCount,size_t * actualFrameCount,int32_t *)101 ::android::status_t DriverStubImpl::transfer(void* buffer, size_t frameCount,
102 size_t* actualFrameCount, int32_t*) {
103 // No LOG_ENTRY as this is called very often.
104 if (!mIsInitialized) {
105 LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
106 }
107 if (mIsStandby) {
108 LOG(FATAL) << __func__ << ": must not happen while in standby";
109 }
110 *actualFrameCount = frameCount;
111 if (mIsAsynchronous) {
112 if (mAsyncSleepTimeUs) usleep(mAsyncSleepTimeUs);
113 } else {
114 mFramesSinceStart += *actualFrameCount;
115 const long bufferDurationUs = (*actualFrameCount) * MICROS_PER_SECOND / mSampleRate;
116 const auto totalDurationUs =
117 (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
118 const long totalOffsetUs =
119 mFramesSinceStart * MICROS_PER_SECOND / mSampleRate - totalDurationUs;
120 LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
121 if (totalOffsetUs > 0) {
122 const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
123 LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
124 usleep(sleepTimeUs);
125 }
126 }
127 if (mIsInput) {
128 uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
129 for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
130 byteBuffer[i] = std::rand() % 255;
131 }
132 }
133 return ::android::OK;
134 }
135
shutdown()136 void DriverStubImpl::shutdown() {
137 LOG_ENTRY();
138 mIsInitialized = false;
139 }
140
141 } // namespace aidl::android::hardware::audio::core
142