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

Commit d8cc81aa authored by Daniel Hillenbrand's avatar Daniel Hillenbrand Committed by Bruno Martins
Browse files

hal: Support the audio amplifier hook

* Original legacy HAL commit:
  Ib236598a5888b2af19bcfb81e285f644a0e84c0d
* Example: http://review.cyanogenmod.org/38221

 (cyanogen: Refactored to be an audio_extn)

Change-Id: Ic944a9f7059c78b79322dae9c787cdd8bb029cff

audio: add amplifier stream start/standby operations

Change-Id: I5de7ad7a0467e7cf822c9c0870a755c03d05e884

hal: Convert libaudioamp to audio_amplifier HAL

Change-Id: I1d0f63a46989d1792d7a5e08d2bdb6344ebafa31

hal: Notify amplifier of device enable/disable

Change-Id: Ice808c9b55a9e3bc8bafe5ca3ff555377d38dd8f

hal: enable amplifier earlier

Change-Id: Id876e8f836e3ce1ee5f8186ca9c0e6ef5f37182c

hal: only open the amplifier once

Change-Id: Ie9bbff74123e90b71e95809a84dcb3bbe9ba82fe

hal: notify amplifier of parameter changes

Change-Id: Iecc020c0347ae7c43d27183186e06dcefef7a0dd

hal: Clean up audio amplifier usage

 * Externalize it into an extension file similar to the rest.

Change-Id: I03de7efa9bab8870099028170fa471dfffe1ce84

hal: switch audio_extn_set_parameters and amplifier_set_parameters

Switch set_param calls so amplifier_set_parameters can be used
to set ANC parameter. audio_extn_set_parameters will pick it up
and refresh device selection for anc playback.

Change-Id: I4fda3f9a76db14a20af2c8c7be8c90a63a5f1153
parent 33d25d57
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ endif
LOCAL_SHARED_LIBRARIES := \
	liblog \
	libcutils \
	libhardware \
	libtinyalsa \
	libtinycompress_vendor \
	libaudioroute \
@@ -327,6 +328,7 @@ LOCAL_C_INCLUDES += \
	external/tinycompress/include \
	system/media/audio_utils/include \
	external/expat/lib \
	hardware/libhardware/include \
	$(call include-path-for, audio-route) \
	$(call include-path-for, audio-effects) \
	$(LOCAL_PATH)/$(AUDIO_PLATFORM) \
@@ -419,6 +421,11 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_BATTERY_LISTENER)), true)
    LOCAL_STATIC_LIBRARIES := libhealthhalutils
endif

ifneq ($(strip $(AUDIO_FEATURE_ENABLED_EXT_AMPLIFIER)),false)
    LOCAL_CFLAGS += -DEXT_AMPLIFIER_ENABLED
    LOCAL_SRC_FILES += audio_extn/audio_amplifier.c
endif

LOCAL_CFLAGS += -Wall -Werror
LOCAL_CLANG_CFLAGS += -Wno-unused-variable -Wno-unused-function -Wno-missing-field-initializers

+146 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016 The CyanogenMod Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "audio_amplifier"

#include <stdbool.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <cutils/log.h>

#include "audio_hw.h"
#include "platform.h"

struct amplifier_data {
    struct audio_device *adev;
    amplifier_device_t *hw;
};

struct amplifier_data amp;

int amplifier_open(void* adev)
{
    int rc;
    amplifier_module_t *module;
    amp.adev = (struct audio_device *)adev;

    rc = hw_get_module(AMPLIFIER_HARDWARE_MODULE_ID,
            (const hw_module_t **) &module);
    if (rc) {
        ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
                __func__, strerror(-rc));
        return -ENODEV;
    }

    rc = amplifier_device_open((const hw_module_t *) module, &amp.hw);
    if (rc) {
        ALOGV("%s: Failed to open amplifier hardware device: %s\n",
                __func__, strerror(-rc));
        amp.hw = NULL;

        return -ENODEV;
    }

    return 0;
}

int amplifier_set_input_devices(uint32_t devices)
{
    if (amp.hw && amp.hw->set_input_devices)
        return amp.hw->set_input_devices(amp.hw, devices);

    return 0;
}

int amplifier_set_output_devices(uint32_t devices)
{
    if (amp.hw && amp.hw->set_output_devices)
        return amp.hw->set_output_devices(amp.hw, devices);

    return 0;
}

int amplifier_enable_devices(uint32_t devices, bool enable)
{
    bool is_output = devices < SND_DEVICE_OUT_END;

    if (amp.hw && amp.hw->enable_output_devices && is_output)
        return amp.hw->enable_output_devices(amp.hw, devices, enable);

    if (amp.hw && amp.hw->enable_input_devices && !is_output)
        return amp.hw->enable_input_devices(amp.hw, devices, enable);

    return 0;
}

int amplifier_set_mode(audio_mode_t mode)
{
    if (amp.hw && amp.hw->set_mode)
        return amp.hw->set_mode(amp.hw, mode);

    return 0;
}

int amplifier_output_stream_start(struct audio_stream_out *stream,
        bool offload)
{
    if (amp.hw && amp.hw->output_stream_start)
        return amp.hw->output_stream_start(amp.hw, stream, offload);

    return 0;
}

int amplifier_input_stream_start(struct audio_stream_in *stream)
{
    if (amp.hw && amp.hw->input_stream_start)
        return amp.hw->input_stream_start(amp.hw, stream);

    return 0;
}

int amplifier_output_stream_standby(struct audio_stream_out *stream)
{
    if (amp.hw && amp.hw->output_stream_standby)
        return amp.hw->output_stream_standby(amp.hw, stream);

    return 0;
}

int amplifier_input_stream_standby(struct audio_stream_in *stream)
{
    if (amp.hw && amp.hw->input_stream_standby)
        return amp.hw->input_stream_standby(amp.hw, stream);

    return 0;
}

int amplifier_set_parameters(struct str_parms *parms)
{
    if (amp.hw && amp.hw->set_parameters)
        return amp.hw->set_parameters(amp.hw, parms);

    return 0;
}

int amplifier_close(void)
{
    if (amp.hw)
        amplifier_device_close(amp.hw);

    amp.hw = NULL;

    return 0;
}
+48 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016 The CyanogenMod Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef EXTN_AMPLIFIER_H
#define EXTN_AMPLIFIER_H

#ifndef EXT_AMPLIFIER_ENABLED
#define amplifier_open(adev) (0)
#define amplifier_set_input_devices(devices) (0)
#define amplifier_set_output_devices(devices) (0)
#define amplifier_enable_devices(devices, enable) (0)
#define amplifier_set_mode(mode) (0)
#define amplifier_output_stream_start(stream, offload) (0)
#define amplifier_input_stream_start(stream) (0)
#define amplifier_output_stream_standby(stream) (0)
#define amplifier_input_stream_standby(stream) (0)
#define amplifier_set_parameters(parms) (0)
#define amplifier_close() (0)
#else

int amplifier_open(void* adev);
int amplifier_set_input_devices(uint32_t devices);
int amplifier_set_output_devices(uint32_t devices);
int amplifier_enable_devices(uint32_t devices, bool enable);
int amplifier_set_mode(audio_mode_t mode);
int amplifier_output_stream_start(struct audio_stream_out *stream,
        bool offload);
int amplifier_input_stream_start(struct audio_stream_in *stream);
int amplifier_output_stream_standby(struct audio_stream_out *stream);
int amplifier_input_stream_standby(struct audio_stream_in *stream);
int amplifier_set_parameters(struct str_parms *parms);
int amplifier_close(void);
#endif

#endif
+32 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@
#include "audio_extn.h"
#include "voice_extn.h"
#include "ip_hdlr_intf.h"
#include "audio_amplifier.h"

#include "sound/compress_params.h"
#include "sound/asound.h"
@@ -1095,6 +1096,7 @@ int enable_snd_device(struct audio_device *adev,
            return -EINVAL;
        }
        audio_extn_dev_arbi_acquire(snd_device);
        amplifier_enable_devices(snd_device, true);
        audio_route_apply_and_update_path(adev->audio_route, device_name);

        if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
@@ -1158,6 +1160,7 @@ int disable_snd_device(struct audio_device *adev,
            }
        } else {
            audio_route_reset_and_update_path(adev->audio_route, device_name);
            amplifier_enable_devices(snd_device, false);
        }

        if (SND_DEVICE_OUT_BT_A2DP == snd_device)
@@ -2304,6 +2307,10 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
            voice_set_sidetone(adev, out_snd_device, true);
    }

    /* Rely on amplifier_set_devices to distinguish between in/out devices */
    amplifier_set_input_devices(in_snd_device);
    amplifier_set_output_devices(out_snd_device);

    /* Applicable only on the targets that has external modem.
     * Enable device command should be sent to modem only after
     * enabling voice call mixer controls
@@ -3506,6 +3513,9 @@ static int out_standby(struct audio_stream *stream)
            stop_compressed_output_l(out);

        pthread_mutex_lock(&adev->lock);

        amplifier_output_stream_standby((struct audio_stream_out *) stream);

        out->standby = true;
        if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
            voice_extn_compress_voip_close_output_stream(stream);
@@ -4441,6 +4451,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
            ret = voice_extn_compress_voip_start_output_stream(out);
        else
            ret = start_output_stream(out);

        if (ret == 0)
            amplifier_output_stream_start(stream,
                    is_offload_usecase(out->usecase));

        pthread_mutex_unlock(&adev->lock);
        /* ToDo: If use case is compress offload should return 0 */
        if (ret != 0) {
@@ -5158,6 +5173,9 @@ static int in_standby(struct audio_stream *stream)
            adev->adm_deregister_stream(adev->adm_data, in->capture_handle);

        pthread_mutex_lock(&adev->lock);

        amplifier_input_stream_standby((struct audio_stream_in *) stream);

        in->standby = true;
        if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
            do_stop = false;
@@ -5395,6 +5413,11 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
            ret = voice_extn_compress_voip_start_input_stream(in);
        else
            ret = start_input_stream(in);

        if (ret == 0)
            amplifier_input_stream_start(stream);


        pthread_mutex_unlock(&adev->lock);
        if (ret != 0) {
            goto exit;
@@ -6587,6 +6610,7 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
        }
    }

    amplifier_set_parameters(parms);
    audio_extn_set_parameters(adev, parms);
done:
    str_parms_destroy(parms);
@@ -6706,6 +6730,8 @@ static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
    pthread_mutex_lock(&adev->lock);
    if (adev->mode != mode) {
        ALOGD("%s: mode %d\n", __func__, mode);
        if (amplifier_set_mode(mode) != 0)
            ALOGE("Failed setting amplifier mode");
        adev->mode = mode;
        if ((mode == AUDIO_MODE_NORMAL) && voice_is_in_call(adev)) {
            list_for_each(node, &adev->usecase_list) {
@@ -7241,6 +7267,8 @@ static int adev_close(hw_device_t *device)
    pthread_mutex_lock(&adev_init_lock);

    if ((--audio_device_ref_count) == 0) {
        if (amplifier_close() != 0)
            ALOGE("Amplifier close failed");
        audio_extn_snd_mon_unregister_listener(adev);
        audio_extn_sound_trigger_deinit(adev);
        audio_extn_listen_deinit(adev);
@@ -7601,6 +7629,10 @@ static int adev_open(const hw_module_t *module, const char *name,
    adev->vr_audio_mode_enabled = false;

    audio_extn_ds2_enable(adev);

    if (amplifier_open(adev) != 0)
        ALOGE("Amplifier initialization failed");

    *device = &adev->device.common;
    adev->dsp_bit_width_enforce_mode =
        adev_init_dsp_bit_width_enforce_mode(adev->mixer);
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@

#include <stdlib.h>
#include <cutils/list.h>
#include <hardware/audio_amplifier.h>
#include <hardware/audio.h>
#include <tinyalsa/asoundlib.h>
#include <tinycompress/tinycompress.h>
@@ -535,6 +536,7 @@ struct audio_device {
    struct audio_device_config_param *device_cfg_params;
    unsigned int interactive_usecase_state;
    bool dp_allowed_for_voice;
    amplifier_device_t *amp;
};

int select_devices(struct audio_device *adev,