AudioInputDescriptor.cpp revision 53615e29c99c5e9d2ca77aaefd7bf5c770513120
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2015 The Android Open Source Project
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License.
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License.
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "APM::AudioInputDescriptor"
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0
1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioInputDescriptor.h"
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "IOProfile.h"
2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioGain.h"
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "HwModule.h"
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioPolicy.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <policy.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : mId(0), mIoHandle(0),
3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0),
3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false)
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (profile != NULL) {
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mSamplingRate = profile->pickSamplingRate();
36e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mFormat = profile->pickFormat();
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mChannelMask = profile->pickChannelMask();
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (profile->mGains.size() > 0) {
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            profile->mGains[0]->getDefaultConfig(&mGain);
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioInputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mId = AudioPort::getNextUniqueId();
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mIoHandle = ioHandle;
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianaudio_module_handle_t AudioInputDescriptor::getModuleHandle() const
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
524ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return mProfile->getModuleHandle();
534ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
544ff14bae91075eb274eb1c2975982358946e7e63John Grossman
554ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                             const struct audio_port_config *srcConfig) const
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOG_ASSERT(mProfile != 0,
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "toAudioPortConfig() called on input with null profile %d", mIoHandle);
60243f5f91755c01614a8cafe90b0806396e22d553Eric Laurent    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
61c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kasten                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
62243f5f91755c01614a8cafe90b0806396e22d553Eric Laurent    if (srcConfig != NULL) {
6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dstConfig->config_mask |= srcConfig->config_mask;
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dstConfig->id = mId;
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dstConfig->role = AUDIO_PORT_ROLE_SINK;
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dstConfig->type = AUDIO_PORT_TYPE_MIX;
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dstConfig->ext.mix.handle = mIoHandle;
7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dstConfig->ext.mix.usecase.source = mInputSource;
7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioInputDescriptor::toAudioPort(struct audio_port *port) const
7765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
794ff14bae91075eb274eb1c2975982358946e7e63John Grossman
804ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mProfile->toAudioPort(port);
81004f719467c498942c40de9f260be601ee45e630Glenn Kasten    port->id = mId;
82004f719467c498942c40de9f260be601ee45e630Glenn Kasten    toAudioPortConfig(&port->active_config);
83004f719467c498942c40de9f260be601ee45e630Glenn Kasten    port->ext.mix.hw_module = mProfile->mModule->mHandle;
8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    port->ext.mix.handle = mIoHandle;
8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioInputDescriptor::dump(int fd)
8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
944ff14bae91075eb274eb1c2975982358946e7e63John Grossman    snprintf(buffer, SIZE, " ID: %d\n", mId);
954ff14bae91075eb274eb1c2975982358946e7e63John Grossman    result.append(buffer);
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
9865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
9965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
10065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
10165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
103    result.append(buffer);
104    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
105    result.append(buffer);
106    snprintf(buffer, SIZE, " Open Ref Count %d\n", mOpenRefCount);
107    result.append(buffer);
108
109    write(fd, result.string(), result.size());
110
111    return NO_ERROR;
112}
113
114bool AudioInputCollection::isSourceActive(audio_source_t source) const
115{
116    for (size_t i = 0; i < size(); i++) {
117        const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
118        if (inputDescriptor->mRefCount == 0) {
119            continue;
120        }
121        if (inputDescriptor->mInputSource == (int)source) {
122            return true;
123        }
124    }
125    return false;
126}
127
128sp<AudioInputDescriptor> AudioInputCollection::getInputFromId(audio_port_handle_t id) const
129{
130    sp<AudioInputDescriptor> inputDesc = NULL;
131    for (size_t i = 0; i < size(); i++) {
132        inputDesc = valueAt(i);
133        if (inputDesc->mId == id) {
134            break;
135        }
136    }
137    return inputDesc;
138}
139
140uint32_t AudioInputCollection::activeInputsCount() const
141{
142    uint32_t count = 0;
143    for (size_t i = 0; i < size(); i++) {
144        const sp<AudioInputDescriptor>  desc = valueAt(i);
145        if (desc->mRefCount > 0) {
146            count++;
147        }
148    }
149    return count;
150}
151
152audio_io_handle_t AudioInputCollection::getActiveInput(bool ignoreVirtualInputs)
153{
154    for (size_t i = 0; i < size(); i++) {
155        const sp<AudioInputDescriptor>  input_descriptor = valueAt(i);
156        if ((input_descriptor->mRefCount > 0)
157                && (!ignoreVirtualInputs || !is_virtual_input_device(input_descriptor->mDevice))) {
158            return keyAt(i);
159        }
160    }
161    return 0;
162}
163
164audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
165{
166    sp<AudioInputDescriptor> inputDesc = valueFor(handle);
167    audio_devices_t devices = inputDesc->mProfile->mSupportedDevices.types();
168    return devices;
169}
170
171status_t AudioInputCollection::dump(int fd) const
172{
173    const size_t SIZE = 256;
174    char buffer[SIZE];
175
176    snprintf(buffer, SIZE, "\nInputs dump:\n");
177    write(fd, buffer, strlen(buffer));
178    for (size_t i = 0; i < size(); i++) {
179        snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
180        write(fd, buffer, strlen(buffer));
181        valueAt(i)->dump(fd);
182    }
183
184    return NO_ERROR;
185}
186
187}; //namespace android
188