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