Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1715a46 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: add audio port gain control

Implement setAudioPortConfig() API to configure an
audio port.
Currently limited to gain control.

Bug: 14815883.

Change-Id: Ic1b268e5ba5c277e9f5b8fa63c81dd7c0b250024
parent 1afeecb8
Loading
Loading
Loading
Loading
+28 −3
Original line number Original line Diff line number Diff line
@@ -404,13 +404,38 @@ status_t AudioFlinger::PatchPanel::listAudioPatches(unsigned int *num_patches __
}
}


/* Set audio port configuration */
/* Set audio port configuration */
status_t AudioFlinger::PatchPanel::setAudioPortConfig(
status_t AudioFlinger::PatchPanel::setAudioPortConfig(const struct audio_port_config *config)
        const struct audio_port_config *config __unused)
{
{
    ALOGV("setAudioPortConfig");
    ALOGV("setAudioPortConfig");
    return NO_ERROR;
    status_t status = NO_ERROR;

    sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
    if (audioflinger == 0) {
        return NO_INIT;
    }

    audio_module_handle_t module;
    if (config->type == AUDIO_PORT_TYPE_DEVICE) {
        module = config->ext.device.hw_module;
    } else {
        module = config->ext.mix.hw_module;
    }

    ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(module);
    if (index < 0) {
        ALOGW("setAudioPortConfig() bad hw module %d", module);
        return BAD_VALUE;
    }
    }


    AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
    if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
        audio_hw_device_t *hwDevice = audioHwDevice->hwDevice();
        return hwDevice->set_audio_port_config(hwDevice, config);
    } else {
        return INVALID_OPERATION;
    }
    return NO_ERROR;
}




}; // namespace android
}; // namespace android
+7 −0
Original line number Original line Diff line number Diff line
@@ -195,6 +195,13 @@ status_t AudioPolicyService::AudioPolicyClient::releaseAudioPatch(audio_patch_ha
    return mAudioPolicyService->clientReleaseAudioPatch(handle, delayMs);
    return mAudioPolicyService->clientReleaseAudioPatch(handle, delayMs);
}
}


status_t AudioPolicyService::AudioPolicyClient::setAudioPortConfig(
                                                        const struct audio_port_config *config,
                                                        int delayMs)
{
    return mAudioPolicyService->clientSetAudioPortConfig(config, delayMs);
}

void AudioPolicyService::AudioPolicyClient::onAudioPortListUpdate()
void AudioPolicyService::AudioPolicyClient::onAudioPortListUpdate()
{
{
    mAudioPolicyService->onAudioPortListUpdate();
    mAudioPolicyService->onAudioPortListUpdate();
+3 −0
Original line number Original line Diff line number Diff line
@@ -273,6 +273,9 @@ public:
    virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
    virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
                                       int delayMs) = 0;
                                       int delayMs) = 0;


    /* Set audio port configuration */
    virtual status_t setAudioPortConfig(const struct audio_port_config *config, int delayMs) = 0;

    virtual void onAudioPortListUpdate() = 0;
    virtual void onAudioPortListUpdate() = 0;


    virtual void onAudioPatchListUpdate() = 0;
    virtual void onAudioPatchListUpdate() = 0;
+94 −3
Original line number Original line Diff line number Diff line
@@ -2026,9 +2026,93 @@ status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config __unused)
status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
{
{
    return NO_ERROR;
    ALOGV("setAudioPortConfig()");

    if (config == NULL) {
        return BAD_VALUE;
    }
    ALOGV("setAudioPortConfig() on port handle %d", config->id);
    // Only support gain configuration for now
    if (config->config_mask != AUDIO_PORT_CONFIG_GAIN || config->gain.index < 0) {
        return BAD_VALUE;
    }

    sp<AudioPort> portDesc;
    struct audio_port_config portConfig;
    if (config->type == AUDIO_PORT_TYPE_MIX) {
        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
            AudioOutputDescriptor *outputDesc = getOutputFromId(config->id);
            if (outputDesc == NULL) {
                return BAD_VALUE;
            }
            portDesc = outputDesc->mProfile;
            outputDesc->toAudioPortConfig(&portConfig);
        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
            AudioInputDescriptor *inputDesc = getInputFromId(config->id);
            if (inputDesc == NULL) {
                return BAD_VALUE;
            }
            portDesc = inputDesc->mProfile;
            inputDesc->toAudioPortConfig(&portConfig);
        } else {
            return BAD_VALUE;
        }
    } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
        sp<DeviceDescriptor> deviceDesc;
        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
            deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
            deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
        } else {
            return BAD_VALUE;
        }
        if (deviceDesc == NULL) {
            return BAD_VALUE;
        }
        portDesc = deviceDesc;
        deviceDesc->toAudioPortConfig(&portConfig);
    } else {
        return BAD_VALUE;
    }

    if ((size_t)config->gain.index >= portDesc->mGains.size()) {
        return INVALID_OPERATION;
    }
    const struct audio_gain *gain = &portDesc->mGains[config->gain.index]->mGain;
    if ((config->gain.mode & ~gain->mode) != 0) {
        return BAD_VALUE;
    }
    if ((config->gain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
        if ((config->gain.values[0] < gain->min_value) ||
                    (config->gain.values[0] > gain->max_value)) {
            return BAD_VALUE;
        }
    } else {
        if ((config->gain.channel_mask & ~gain->channel_mask) != 0) {
            return BAD_VALUE;
        }
        size_t numValues = popcount(config->gain.channel_mask);
        for (size_t i = 0; i < numValues; i++) {
            if ((config->gain.values[i] < gain->min_value) ||
                    (config->gain.values[i] > gain->max_value)) {
                return BAD_VALUE;
            }
        }
    }
    if ((config->gain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
        if ((config->gain.ramp_duration_ms < gain->min_ramp_ms) ||
                    (config->gain.ramp_duration_ms > gain->max_ramp_ms)) {
            return BAD_VALUE;
        }
    }

    portConfig.gain = config->gain;

    status_t status = mpClientInterface->setAudioPortConfig(&portConfig, 0);

    return status;
}
}


void AudioPolicyManager::clearAudioPatches(uid_t uid)
void AudioPolicyManager::clearAudioPatches(uid_t uid)
@@ -4861,7 +4945,13 @@ void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const
        port->formats[i] = mFormats[i];
        port->formats[i] = mFormats[i];
    }
    }
    port->num_formats = i;
    port->num_formats = i;
    port->num_gains = 0;

    ALOGV("AudioPort::toAudioPort() num gains %d", mGains.size());

    for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) {
        port->gains[i] = mGains[i]->mGain;
    }
    port->num_gains = i;
}
}




@@ -5417,6 +5507,7 @@ void AudioPolicyManager::DeviceDescriptor::toAudioPortConfig(


void AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const
void AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const
{
{
    ALOGV("DeviceVector::toAudioPort() handle %d type %x", mId, mDeviceType);
    AudioPort::toAudioPort(port);
    AudioPort::toAudioPort(port);
    port->id = mId;
    port->id = mId;
    toAudioPortConfig(&port->active_config);
    toAudioPortConfig(&port->active_config);
+29 −0
Original line number Original line Diff line number Diff line
@@ -226,6 +226,12 @@ void AudioPolicyService::doOnAudioPatchListUpdate()
    }
    }
}
}


status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
                                                      int delayMs)
{
    return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
}

AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
                                                     const sp<IAudioPolicyServiceClient>& client,
                                                     const sp<IAudioPolicyServiceClient>& client,
                                                     uid_t uid)
                                                     uid_t uid)
@@ -506,6 +512,16 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
                    svc->doOnAudioPatchListUpdate();
                    svc->doOnAudioPatchListUpdate();
                    mLock.lock();
                    mLock.lock();
                    }break;
                    }break;
                case SET_AUDIOPORT_CONFIG: {
                    SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
                    ALOGV("AudioCommandThread() processing set port config");
                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
                    if (af == 0) {
                        command->mStatus = PERMISSION_DENIED;
                    } else {
                        command->mStatus = af->setAudioPortConfig(&data->mConfig);
                    }
                    } break;
                default:
                default:
                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
                }
                }
@@ -716,6 +732,19 @@ void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
    sendCommand(command);
    sendCommand(command);
}
}


status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
                                            const struct audio_port_config *config, int delayMs)
{
    sp<AudioCommand> command = new AudioCommand();
    command->mCommand = SET_AUDIOPORT_CONFIG;
    SetAudioPortConfigData *data = new SetAudioPortConfigData();
    data->mConfig = *config;
    command->mParam = data;
    command->mWaitStatus = true;
    ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
    return sendCommand(command, delayMs);
}

status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
{
{
    {
    {
Loading