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

Commit 0f7f4ece authored by Eric Laurent's avatar Eric Laurent
Browse files

Added APIs for audio preprocessing

Added APIs to control pre processes applied on captured audio.
Those APIs are still hidden until reviewed by API council.

Three types of standard pre processes are supported:
- Automatic Gain Control (AGC) by AutomaticGainControl class
- Acoustic Echo Cancellation (AEC) by AcousticEchoCanceler class
- Noise Suppression (NS) by NoiseSuppressor class

A method is added to AudioEffect class to query audio pre processings
applied by default by the platform on a given AudioRecord session ID.

Change-Id: I0b9fceeb8c704dd06319c3b52b85c96fe871d51d
parent 84e35d99
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <sys/types.h>

#include <media/IAudioFlinger.h>
#include <media/IAudioPolicyService.h>
#include <media/IEffect.h>
#include <media/IEffectClient.h>
#include <hardware/audio_effect.h>
@@ -110,6 +111,36 @@ public:
    static status_t getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor);


    /*
     * Returns a list of descriptors corresponding to the pre processings enabled by default
     * on an AudioRecord with the supplied audio session ID.
     *
     * Parameters:
     *      audioSession:  audio session ID.
     *      descriptors: address where the effect descriptors should be returned.
     *      count: as input, the maximum number of descriptor than should be returned
     *             as output, the number of descriptor returned if status is NO_ERROR or the actual
     *             number of enabled pre processings if status is NO_MEMORY
     *
     * Returned status (from utils/Errors.h) can be:
     *      NO_ERROR        successful operation.
     *      NO_MEMORY       the number of descriptor to return is more than the maximum number
     *                      indicated by count.
     *      PERMISSION_DENIED could not get AudioFlinger interface
     *      NO_INIT         effect library failed to initialize
     *      BAD_VALUE       invalid audio session or descriptor pointers
     *
     * Returned value
     *   *descriptor updated with descriptors of pre processings enabled by default
     *   *count      number of descriptors returned if returned status is N_ERROR.
     *               total number of pre processing enabled by default if returned status is
     *               NO_MEMORY. This happens if the count passed as input is less than the number
     *               of descriptors to return
     */
    static status_t queryDefaultPreProcessing(int audioSession,
                                              effect_descriptor_t *descriptors,
                                              uint32_t *count);

    /*
     * Events used by callback function (effect_callback_t).
     */
+3 −0
Original line number Diff line number Diff line
@@ -85,6 +85,9 @@ public:
                                    int id) = 0;
    virtual status_t unregisterEffect(int id) = 0;
    virtual bool     isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
    virtual status_t queryDefaultPreProcessing(int audioSession,
                                              effect_descriptor_t *descriptors,
                                              uint32_t *count) = 0;
};


+67 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source 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.
 */

package android.media.audiofx;

/**
 * Acoustic Echo Canceler (AEC).
 * <p>Acoustic Echo Canceler (AEC) is an audio pre-processing which removes the contribution of the
 * signal received from the remote party from the captured audio signal.
 * <p>AEC is used by voice communication applications (voice chat, video conferencing, SIP calls)
 * where the presence of echo with significant delay in the signal received from the remote party
 * is highly disturbing. AEC is often used in conjunction with noise suppression (NS).
 * <p>An application creates an AcousticEchoCanceler object to instantiate and control an AEC
 * engine in the audio capture path.
 * <p>To attach the AcousticEchoCanceler to a particular {@link android.media.AudioRecord},
 * specify the audio session ID of this AudioRecord when constructing the AcousticEchoCanceler.
 * The audio session is retrieved by calling
 * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance.
 * <p>On some devices, an AEC can be inserted by default in the capture path by the platform
 * according to the {@link android.media.MediaRecorder.AudioSource} used. The application can
 * query which pre-processings are currently applied to an AudioRecord instance by calling
 * {@link android.media.audiofx.AudioEffect#queryPreProcessings(int)} with the audio session of the
 * AudioRecord.
 * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
 * controlling audio effects.
 * @hide
 */

public class AcousticEchoCanceler extends AudioEffect {

    private final static String TAG = "AcousticEchoCanceler";

    /**
     * Class constructor.
     * <p> The application must catch exceptions when creating an AcousticEchoCanceler as the
     * constructor is not guarantied to succeed:
     * <ul>
     *  <li>IllegalArgumentException is thrown if the device does not implement an AEC</li>
     *  <li>UnsupportedOperationException is thrown is the resources allocated to audio
     *  pre-procesing are currently exceeded.</li>
     * </ul>
     *
     * @param audioSession system wide unique audio session identifier. The AcousticEchoCanceler
     * will be applied to the AudioRecord with the same audio session.
     *
     * @throws java.lang.IllegalArgumentException
     * @throws java.lang.UnsupportedOperationException
     * @throws java.lang.RuntimeException
     */
    public AcousticEchoCanceler(int audioSession)
            throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
        super(EFFECT_TYPE_AEC, EFFECT_TYPE_NULL, 0, audioSession);
    }
}
+50 −3
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ public class AudioEffect {

    private final static String TAG = "AudioEffect-JAVA";

    // effect type UUIDs are taken from hardware/libhardware/include/hardware/audio_effect.h

    /**
     * The following UUIDs define effect types corresponding to standard audio
     * effects whose implementation and interface conform to the OpenSL ES
@@ -104,6 +106,27 @@ public class AudioEffect {
    public static final UUID EFFECT_TYPE_VIRTUALIZER = UUID
            .fromString("37cc2c00-dddd-11db-8577-0002a5d5c51b");

    /**
     * UUID for Automatic Gain Control (AGC) audio pre-processing
     * @hide
     */
    public static final UUID EFFECT_TYPE_AGC = UUID
            .fromString("0a8abfe0-654c-11e0-ba26-0002a5d5c51b");

    /**
     * UUID for Acoustic Echo Canceler (AEC) audio pre-processing
     * @hide
     */
    public static final UUID EFFECT_TYPE_AEC = UUID
            .fromString("7b491460-8d4d-11e0-bd61-0002a5d5c51b");

    /**
     * UUID for Noise Suppressor (NS) audio pre-processing
     * @hide
     */
    public static final UUID EFFECT_TYPE_NS = UUID
            .fromString("58b4b260-8e06-11e0-aa8e-0002a5d5c51b");

    /**
     * Null effect UUID. Used when the UUID for effect type of
     * @hide
@@ -180,7 +203,8 @@ public class AudioEffect {
     * <ul>
     *  <li>type: UUID corresponding to the OpenSL ES interface implemented by this effect</li>
     *  <li>uuid: UUID for this particular implementation</li>
     *  <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li>
     *  <li>connectMode: {@link #EFFECT_INSERT}, {@link #EFFECT_AUXILIARY} or
     *  {at_link #EFFECT_PRE_PROCESSING}</li>
     *  <li>name: human readable effect name</li>
     *  <li>implementor: human readable effect implementor name</li>
     * </ul>
@@ -212,11 +236,13 @@ public class AudioEffect {
         */
        public UUID uuid;
        /**
         *  Indicates if the effect is of insert category {@link #EFFECT_INSERT} or auxiliary
         *  category {@link #EFFECT_AUXILIARY}. Insert effects (Typically an Equalizer) are applied
         *  Indicates if the effect is of insert category {@link #EFFECT_INSERT}, auxiliary
         *  category {@link #EFFECT_AUXILIARY} or pre processing category
         *  {at_link #EFFECT_PRE_PROCESSING}. Insert effects (Typically an Equalizer) are applied
         *  to the entire audio source and usually not shared by several sources. Auxiliary effects
         *  (typically a reverberator) are applied to part of the signal (wet) and the effect output
         *  is added to the original signal (dry).
         *  Audio pre processing are applied to audio captured on a particular AudioRecord.
         */
        public String connectMode;
        /**
@@ -243,6 +269,12 @@ public class AudioEffect {
     * attaching it to the MediaPlayer or AudioTrack.
     */
    public static final String EFFECT_AUXILIARY = "Auxiliary";
    /**
     * Effect connection mode is pre processing.
     * The audio pre processing effects are attached to an audio input (AudioRecord).
     * @hide
     */
    public static final String EFFECT_PRE_PROCESSING = "Pre Processing";

    // --------------------------------------------------------------------------
    // Member variables
@@ -410,6 +442,19 @@ public class AudioEffect {
        return (Descriptor[]) native_query_effects();
    }

    /**
     * Query all audio pre processing effects applied to the AudioRecord with the supplied
     * audio session ID. Returns an array of {@link android.media.audiofx.AudioEffect.Descriptor}
     * objects.
     * @param audioSession system wide unique audio session identifier.
     * @throws IllegalStateException
     * @hide
     */

    static public Descriptor[] queryPreProcessings(int audioSession) {
        return (Descriptor[]) native_query_pre_processing(audioSession);
    }

    // --------------------------------------------------------------------------
    // Control methods
    // --------------------
@@ -1155,6 +1200,8 @@ public class AudioEffect {

    private static native Object[] native_query_effects();

    private static native Object[] native_query_pre_processing(int audioSession);

    // ---------------------------------------------------------
    // Utility methods
    // ------------------
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source 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.
 */

package android.media.audiofx;

/**
 * Automatic Gain Control (AGC).
 * <p>Automatic Gain Control (AGC) is an audio pre-processing which automatically normalizes the
 * output of the captured signal by boosting or lowering input from the microphone to match a preset
 * level so that that the output signal level is virtually constant.
 * AGC can be used by applications where the input signal dynamic range is not important but where
 * a constant strong capture level is desired.
 * <p>An application creates a AutomaticGainControl object to instantiate and control an AGC
 * engine in the audio framework.
 * <p>To attach the AutomaticGainControl to a particular {@link android.media.AudioRecord},
 * specify the audio session ID of this AudioRecord when constructing the AutomaticGainControl.
 * The audio session is retrieved by calling
 * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance.
 * <p>On some devices, an AGC can be inserted by default in the capture path by the platform
 * according to the {@link android.media.MediaRecorder.AudioSource} used. The application can
 * query which pre-processings are currently applied to an AudioRecord instance by calling
 * {@link android.media.audiofx.AudioEffect#queryPreProcessings(int)} with the audio session of the
 * AudioRecord.
 * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
 * controlling audio effects.
 * @hide
 */

public class AutomaticGainControl extends AudioEffect {

    private final static String TAG = "AutomaticGainControl";

    /**
     * Class constructor.
     * <p> The application must catch exceptions when creating an AutomaticGainControl as the
     * constructor is not guarantied to succeed:
     * <ul>
     *  <li>IllegalArgumentException is thrown if the device does not implement an AGC</li>
     *  <li>UnsupportedOperationException is thrown is the resources allocated to audio
     *  pre-procesing are currently exceeded.</li>
     * </ul>
     *
     * @param audioSession system wide unique audio session identifier. The AutomaticGainControl
     * will be applied to the AudioRecord with the same audio session.
     *
     * @throws java.lang.IllegalArgumentException
     * @throws java.lang.UnsupportedOperationException
     * @throws java.lang.RuntimeException
     */
    public AutomaticGainControl(int audioSession)
            throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
        super(EFFECT_TYPE_AGC, EFFECT_TYPE_NULL, 0, audioSession);
    }
}
Loading