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