10f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent/*
20f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * Copyright (C) 2011 The Android Open Source Project
30f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent *
40f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
50f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * you may not use this file except in compliance with the License.
60f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * You may obtain a copy of the License at
70f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent *
80f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
90f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent *
100f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * Unless required by applicable law or agreed to in writing, software
110f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
120f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * See the License for the specific language governing permissions and
140f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * limitations under the License.
150f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent */
160f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
170f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurentpackage android.media.audiofx;
180f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
19855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurentimport android.util.Log;
20855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent
210f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent/**
220f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * Acoustic Echo Canceler (AEC).
230f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>Acoustic Echo Canceler (AEC) is an audio pre-processing which removes the contribution of the
240f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * signal received from the remote party from the captured audio signal.
250f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>AEC is used by voice communication applications (voice chat, video conferencing, SIP calls)
260f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * where the presence of echo with significant delay in the signal received from the remote party
270f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * is highly disturbing. AEC is often used in conjunction with noise suppression (NS).
280f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>An application creates an AcousticEchoCanceler object to instantiate and control an AEC
290f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * engine in the audio capture path.
300f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>To attach the AcousticEchoCanceler to a particular {@link android.media.AudioRecord},
31855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * specify the audio session ID of this AudioRecord when creating the AcousticEchoCanceler.
320f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * The audio session is retrieved by calling
330f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance.
340f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>On some devices, an AEC can be inserted by default in the capture path by the platform
35855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should
36855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * call AcousticEchoCanceler.getEnable() after creating the AEC to check the default AEC activation
37855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * state on a particular AudioRecord session.
380f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
390f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * controlling audio effects.
400f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent */
410f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
420f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurentpublic class AcousticEchoCanceler extends AudioEffect {
430f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
440f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    private final static String TAG = "AcousticEchoCanceler";
450f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
460f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
47855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * Checks if the device implements acoustic echo cancellation.
48855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @return true if the device implements acoustic echo cancellation, false otherwise.
49855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     */
50855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    public static boolean isAvailable() {
51855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_AEC);
52855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    }
53855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent
54855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    /**
55855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * Creates an AcousticEchoCanceler and attaches it to the AudioRecord on the audio
56855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * session specified.
57855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @param audioSession system wide unique audio session identifier. The AcousticEchoCanceler
58855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * will be applied to the AudioRecord with the same audio session.
59855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @return AcousticEchoCanceler created or null if the device does not implement AEC.
60855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     */
61855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    public static AcousticEchoCanceler create(int audioSession) {
62855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        AcousticEchoCanceler aec = null;
63855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        try {
64855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            aec = new AcousticEchoCanceler(audioSession);
65855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        } catch (IllegalArgumentException e) {
66855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            Log.w(TAG, "not implemented on this device"+ aec);
67855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        } catch (UnsupportedOperationException e) {
68855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            Log.w(TAG, "not enough resources");
69855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        } catch (RuntimeException e) {
70855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            Log.w(TAG, "not enough memory");
71855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        }
72b304ba5bc8fbc6034cf232cbbeeb3a34a5ce5b9fEric Laurent        return aec;
73855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    }
74855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent
75855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    /**
760f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * Class constructor.
77855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * <p> The constructor is not guarantied to succeed and throws the following exceptions:
780f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * <ul>
790f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *  <li>IllegalArgumentException is thrown if the device does not implement an AEC</li>
800f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *  <li>UnsupportedOperationException is thrown is the resources allocated to audio
810f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *  pre-procesing are currently exceeded.</li>
82855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     *  <li>RuntimeException is thrown if a memory allocation error occurs.</li>
830f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * </ul>
840f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *
850f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @param audioSession system wide unique audio session identifier. The AcousticEchoCanceler
860f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * will be applied to the AudioRecord with the same audio session.
870f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *
880f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws java.lang.IllegalArgumentException
890f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws java.lang.UnsupportedOperationException
900f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws java.lang.RuntimeException
910f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
928dfc10571a83389593fc11b92fbf9fc1f22c9f21Eric Laurent    private AcousticEchoCanceler(int audioSession)
930f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
940f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        super(EFFECT_TYPE_AEC, EFFECT_TYPE_NULL, 0, audioSession);
950f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
960f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent}
97