xref: /aosp_15_r20/frameworks/av/services/audioflinger/datapath/AudioStreamIn.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  *
3*ec779b8eSAndroid Build Coastguard Worker  * Copyright 2023, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker  *
5*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker  *
9*ec779b8eSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker  *
11*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker  */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AudioFlinger"
19*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
20*ec779b8eSAndroid Build Coastguard Worker #include "AudioStreamIn.h"
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <media/audiohal/DeviceHalInterface.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <media/audiohal/StreamHalInterface.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <system/audio.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker #include "AudioHwDevice.h"
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker namespace android {
30*ec779b8eSAndroid Build Coastguard Worker 
31*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
AudioStreamIn(AudioHwDevice * dev,audio_input_flags_t flags)32*ec779b8eSAndroid Build Coastguard Worker AudioStreamIn::AudioStreamIn(AudioHwDevice *dev, audio_input_flags_t flags)
33*ec779b8eSAndroid Build Coastguard Worker         : audioHwDev(dev)
34*ec779b8eSAndroid Build Coastguard Worker         , flags(flags)
35*ec779b8eSAndroid Build Coastguard Worker {
36*ec779b8eSAndroid Build Coastguard Worker }
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker // This must be defined here together with the HAL includes above and
39*ec779b8eSAndroid Build Coastguard Worker // not solely in the header.
40*ec779b8eSAndroid Build Coastguard Worker AudioStreamIn::~AudioStreamIn() = default;
41*ec779b8eSAndroid Build Coastguard Worker 
hwDev() const42*ec779b8eSAndroid Build Coastguard Worker sp<DeviceHalInterface> AudioStreamIn::hwDev() const
43*ec779b8eSAndroid Build Coastguard Worker {
44*ec779b8eSAndroid Build Coastguard Worker     return audioHwDev->hwDevice();
45*ec779b8eSAndroid Build Coastguard Worker }
46*ec779b8eSAndroid Build Coastguard Worker 
getCapturePosition(int64_t * frames,int64_t * time)47*ec779b8eSAndroid Build Coastguard Worker status_t AudioStreamIn::getCapturePosition(int64_t* frames, int64_t* time)
48*ec779b8eSAndroid Build Coastguard Worker {
49*ec779b8eSAndroid Build Coastguard Worker     if (stream == nullptr) {
50*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
51*ec779b8eSAndroid Build Coastguard Worker     }
52*ec779b8eSAndroid Build Coastguard Worker 
53*ec779b8eSAndroid Build Coastguard Worker     int64_t halPosition = 0;
54*ec779b8eSAndroid Build Coastguard Worker     const status_t status = stream->getCapturePosition(&halPosition, time);
55*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
56*ec779b8eSAndroid Build Coastguard Worker         return status;
57*ec779b8eSAndroid Build Coastguard Worker     }
58*ec779b8eSAndroid Build Coastguard Worker 
59*ec779b8eSAndroid Build Coastguard Worker     if (mHalFormatHasProportionalFrames &&
60*ec779b8eSAndroid Build Coastguard Worker             (flags & AUDIO_INPUT_FLAG_DIRECT) == AUDIO_INPUT_FLAG_DIRECT) {
61*ec779b8eSAndroid Build Coastguard Worker         // For DirectRecord reset position to 0 on standby.
62*ec779b8eSAndroid Build Coastguard Worker         const uint64_t adjustedPosition = (halPosition <= mFramesReadAtStandby) ?
63*ec779b8eSAndroid Build Coastguard Worker                 0 : (halPosition - mFramesReadAtStandby);
64*ec779b8eSAndroid Build Coastguard Worker         // Scale from HAL sample rate to application rate.
65*ec779b8eSAndroid Build Coastguard Worker         *frames = adjustedPosition / mRateMultiplier;
66*ec779b8eSAndroid Build Coastguard Worker     } else {
67*ec779b8eSAndroid Build Coastguard Worker         // For compressed formats and linear PCM.
68*ec779b8eSAndroid Build Coastguard Worker         *frames = halPosition;
69*ec779b8eSAndroid Build Coastguard Worker     }
70*ec779b8eSAndroid Build Coastguard Worker 
71*ec779b8eSAndroid Build Coastguard Worker     return status;
72*ec779b8eSAndroid Build Coastguard Worker }
73*ec779b8eSAndroid Build Coastguard Worker 
open(audio_io_handle_t handle,audio_devices_t deviceType,struct audio_config * config,const char * address,audio_source_t source,audio_devices_t outputDevice,const char * outputDeviceAddress)74*ec779b8eSAndroid Build Coastguard Worker status_t AudioStreamIn::open(
75*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t handle,
76*ec779b8eSAndroid Build Coastguard Worker         audio_devices_t deviceType,
77*ec779b8eSAndroid Build Coastguard Worker         struct audio_config *config,
78*ec779b8eSAndroid Build Coastguard Worker         const char *address,
79*ec779b8eSAndroid Build Coastguard Worker         audio_source_t source,
80*ec779b8eSAndroid Build Coastguard Worker         audio_devices_t outputDevice,
81*ec779b8eSAndroid Build Coastguard Worker         const char *outputDeviceAddress)
82*ec779b8eSAndroid Build Coastguard Worker {
83*ec779b8eSAndroid Build Coastguard Worker     sp<StreamInHalInterface> inStream;
84*ec779b8eSAndroid Build Coastguard Worker 
85*ec779b8eSAndroid Build Coastguard Worker     int status = hwDev()->openInputStream(
86*ec779b8eSAndroid Build Coastguard Worker             handle,
87*ec779b8eSAndroid Build Coastguard Worker             deviceType,
88*ec779b8eSAndroid Build Coastguard Worker             config,
89*ec779b8eSAndroid Build Coastguard Worker             flags,
90*ec779b8eSAndroid Build Coastguard Worker             address,
91*ec779b8eSAndroid Build Coastguard Worker             source,
92*ec779b8eSAndroid Build Coastguard Worker             outputDevice,
93*ec779b8eSAndroid Build Coastguard Worker             outputDeviceAddress,
94*ec779b8eSAndroid Build Coastguard Worker             &inStream);
95*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioStreamIn::open(), HAL returned stream %p, sampleRate %d, format %#x,"
96*ec779b8eSAndroid Build Coastguard Worker             " channelMask %#x, status %d", inStream.get(), config->sample_rate, config->format,
97*ec779b8eSAndroid Build Coastguard Worker             config->channel_mask, status);
98*ec779b8eSAndroid Build Coastguard Worker 
99*ec779b8eSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
100*ec779b8eSAndroid Build Coastguard Worker         stream = inStream;
101*ec779b8eSAndroid Build Coastguard Worker         mHalFormatHasProportionalFrames = audio_has_proportional_frames(config->format);
102*ec779b8eSAndroid Build Coastguard Worker         status = stream->getFrameSize(&mHalFrameSize);
103*ec779b8eSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(status != OK, "Error retrieving frame size from HAL: %d", status);
104*ec779b8eSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(mHalFrameSize == 0, "Error frame size was %zu but must be greater than"
105*ec779b8eSAndroid Build Coastguard Worker                 " zero", mHalFrameSize);
106*ec779b8eSAndroid Build Coastguard Worker     }
107*ec779b8eSAndroid Build Coastguard Worker 
108*ec779b8eSAndroid Build Coastguard Worker     return status;
109*ec779b8eSAndroid Build Coastguard Worker }
110*ec779b8eSAndroid Build Coastguard Worker 
getAudioProperties() const111*ec779b8eSAndroid Build Coastguard Worker audio_config_base_t AudioStreamIn::getAudioProperties() const
112*ec779b8eSAndroid Build Coastguard Worker {
113*ec779b8eSAndroid Build Coastguard Worker     audio_config_base_t result = AUDIO_CONFIG_BASE_INITIALIZER;
114*ec779b8eSAndroid Build Coastguard Worker     if (stream->getAudioProperties(&result) != OK) {
115*ec779b8eSAndroid Build Coastguard Worker         result.sample_rate = 0;
116*ec779b8eSAndroid Build Coastguard Worker         result.channel_mask = AUDIO_CHANNEL_INVALID;
117*ec779b8eSAndroid Build Coastguard Worker         result.format = AUDIO_FORMAT_INVALID;
118*ec779b8eSAndroid Build Coastguard Worker     }
119*ec779b8eSAndroid Build Coastguard Worker     return result;
120*ec779b8eSAndroid Build Coastguard Worker }
121*ec779b8eSAndroid Build Coastguard Worker 
standby()122*ec779b8eSAndroid Build Coastguard Worker status_t AudioStreamIn::standby()
123*ec779b8eSAndroid Build Coastguard Worker {
124*ec779b8eSAndroid Build Coastguard Worker     mFramesReadAtStandby = mFramesRead;
125*ec779b8eSAndroid Build Coastguard Worker     return stream->standby();
126*ec779b8eSAndroid Build Coastguard Worker }
127*ec779b8eSAndroid Build Coastguard Worker 
read(void * buffer,size_t bytes,size_t * read)128*ec779b8eSAndroid Build Coastguard Worker status_t AudioStreamIn::read(void* buffer, size_t bytes, size_t* read)
129*ec779b8eSAndroid Build Coastguard Worker {
130*ec779b8eSAndroid Build Coastguard Worker     const status_t result = stream->read(buffer, bytes, read);
131*ec779b8eSAndroid Build Coastguard Worker     if (result == OK && *read > 0 && mHalFrameSize > 0) {
132*ec779b8eSAndroid Build Coastguard Worker         mFramesRead += *read / mHalFrameSize;
133*ec779b8eSAndroid Build Coastguard Worker     }
134*ec779b8eSAndroid Build Coastguard Worker     return result;
135*ec779b8eSAndroid Build Coastguard Worker }
136*ec779b8eSAndroid Build Coastguard Worker 
137*ec779b8eSAndroid Build Coastguard Worker } // namespace android
138