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 * Noise Suppressor (NS).
230f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>Noise suppression (NS) is an audio pre-processing which removes background noise from the
240f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * captured signal. The component of the signal considered as noise can be either stationary
250f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * (car/airplane engine, AC system) or non-stationary (other peoples conversations, car horn) for
260f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * more advanced implementations.
270f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>NS is mostly used by voice communication applications (voice chat, video conferencing,
280f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * SIP calls).
290f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>An application creates a NoiseSuppressor object to instantiate and control an NS
300f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * engine in the audio framework.
310f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>To attach the NoiseSuppressor to a particular {@link android.media.AudioRecord},
32855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * specify the audio session ID of this AudioRecord when creating the NoiseSuppressor.
330f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * The audio session is retrieved by calling
340f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance.
350f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>On some devices, NS can be inserted by default in the capture path by the platform
36855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should
37855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * call NoiseSuppressor.getEnable() after creating the NS to check the default NS activation
38855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent * state on a particular AudioRecord session.
390f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
400f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent * controlling audio effects.
410f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent */
420f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
430f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurentpublic class NoiseSuppressor extends AudioEffect {
440f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
450f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    private final static String TAG = "NoiseSuppressor";
460f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
470f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
48855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * Checks if the device implements noise suppression.
49855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @return true if the device implements noise suppression, false otherwise.
50855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     */
51855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    public static boolean isAvailable() {
52855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_NS);
53855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    }
54855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent
55855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    /**
56855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * Creates a NoiseSuppressor and attaches it to the AudioRecord on the audio
57855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * session specified.
58855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @param audioSession system wide unique audio session identifier. The NoiseSuppressor
59855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * will be applied to the AudioRecord with the same audio session.
60855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @return NoiseSuppressor created or null if the device does not implement noise
61855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * suppression.
62855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     */
63855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    public static NoiseSuppressor create(int audioSession) {
64855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        NoiseSuppressor ns = null;
65855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        try {
66855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            ns = new NoiseSuppressor(audioSession);
67855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        } catch (IllegalArgumentException e) {
68855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            Log.w(TAG, "not implemented on this device "+ns);
69855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        } catch (UnsupportedOperationException e) {
70855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            Log.w(TAG, "not enough resources");
71855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        } catch (RuntimeException e) {
72855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            Log.w(TAG, "not enough memory");
73855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        } finally {
74855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            return ns;
75855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        }
76855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    }
77855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent
78855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    /**
790f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * Class constructor.
80855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * <p> The constructor is not guarantied to succeed and throws the following exceptions:
810f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * <ul>
820f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *  <li>IllegalArgumentException is thrown if the device does not implement an NS</li>
830f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *  <li>UnsupportedOperationException is thrown is the resources allocated to audio
840f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *  pre-procesing are currently exceeded.</li>
85855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     *  <li>RuntimeException is thrown if a memory allocation error occurs.</li>
860f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * </ul>
870f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *
880f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @param audioSession system wide unique audio session identifier. The NoiseSuppressor
890f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * will be applied to the AudioRecord with the same audio session.
900f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     *
910f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws java.lang.IllegalArgumentException
920f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws java.lang.UnsupportedOperationException
930f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws java.lang.RuntimeException
940f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
95855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    private NoiseSuppressor(int audioSession)
960f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
970f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        super(EFFECT_TYPE_NS, EFFECT_TYPE_NULL, 0, audioSession);
980f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
990f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent}
100