/*
 * Copyright (C) 2010 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;

import android.media.audiofx.AudioEffect;
import java.util.StringTokenizer;


A sound generated within a room travels in many directions. The listener first hears the direct sound from the source itself. Later, he or she hears discrete echoes caused by sound bouncing off nearby walls, the ceiling and the floor. As sound waves arrive after undergoing more and more reflections, individual reflections become indistinguishable and the listener hears continuous reverberation that decays over time. Reverb is vital for modeling a listener's environment. It can be used in music applications to simulate music being played back in various environments, or in games to immerse the listener within the game's environment. The PresetReverb class allows an application to configure the global reverb using a reverb preset. This is primarily used for adding some reverb in a music playback context. Applications requiring control over a more advanced environmental reverb are advised to use the EnvironmentalReverb class.

An application creates a PresetReverb object to instantiate and control a reverb engine in the audio framework.

The methods, parameter types and units exposed by the PresetReverb implementation are directly mapping those defined by the OpenSL ES 1.0.1 Specification (http://www.khronos.org/opensles/) for the SLPresetReverbItf interface. Please refer to this specification for more details.

The PresetReverb is an output mix auxiliary effect and should be created on Audio session 0. In order for a MediaPlayer or AudioTrack to be fed into this effect, they must be explicitely attached to it and a send level must be specified. Use the effect ID returned by getId() method to designate this particular effect when attaching it to the MediaPlayer or AudioTrack.

Creating a reverb on the output mix (audio session 0) requires permission MODIFY_AUDIO_SETTINGS.MODIFY_AUDIO_SETTINGS

See AudioEffect class for more details on controlling audio effects.

/** * A sound generated within a room travels in many directions. The listener first hears the * direct sound from the source itself. Later, he or she hears discrete echoes caused by sound * bouncing off nearby walls, the ceiling and the floor. As sound waves arrive after * undergoing more and more reflections, individual reflections become indistinguishable and * the listener hears continuous reverberation that decays over time. * Reverb is vital for modeling a listener's environment. It can be used in music applications * to simulate music being played back in various environments, or in games to immerse the * listener within the game's environment. * The PresetReverb class allows an application to configure the global reverb using a reverb preset. * This is primarily used for adding some reverb in a music playback context. Applications * requiring control over a more advanced environmental reverb are advised to use the * {@link android.media.audiofx.EnvironmentalReverb} class. * <p>An application creates a PresetReverb object to instantiate and control a reverb engine in the * audio framework. * <p>The methods, parameter types and units exposed by the PresetReverb implementation are * directly mapping those defined by the OpenSL ES 1.0.1 Specification * (http://www.khronos.org/opensles/) for the SLPresetReverbItf interface. * Please refer to this specification for more details. * <p>The PresetReverb is an output mix auxiliary effect and should be created on * Audio session 0. In order for a MediaPlayer or AudioTrack to be fed into this effect, * they must be explicitely attached to it and a send level must be specified. Use the effect ID * returned by getId() method to designate this particular effect when attaching it to the * MediaPlayer or AudioTrack. * <p>Creating a reverb on the output mix (audio session 0) requires permission * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS} * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling * audio effects. */
public class PresetReverb extends AudioEffect { private final static String TAG = "PresetReverb"; // These constants must be synchronized with those in // frameworks/base/include/media/EffectPresetReverbApi.h
Preset. Parameter ID for OnParameterChangeListener
/** * Preset. Parameter ID for * {@link android.media.audiofx.PresetReverb.OnParameterChangeListener} */
public static final int PARAM_PRESET = 0;
No reverb or reflections
/** * No reverb or reflections */
public static final short PRESET_NONE = 0;
Reverb preset representing a small room less than five meters in length
/** * Reverb preset representing a small room less than five meters in length */
public static final short PRESET_SMALLROOM = 1;
Reverb preset representing a medium room with a length of ten meters or less
/** * Reverb preset representing a medium room with a length of ten meters or less */
public static final short PRESET_MEDIUMROOM = 2;
Reverb preset representing a large-sized room suitable for live performances
/** * Reverb preset representing a large-sized room suitable for live performances */
public static final short PRESET_LARGEROOM = 3;
Reverb preset representing a medium-sized hall
/** * Reverb preset representing a medium-sized hall */
public static final short PRESET_MEDIUMHALL = 4;
Reverb preset representing a large-sized hall suitable for a full orchestra
/** * Reverb preset representing a large-sized hall suitable for a full orchestra */
public static final short PRESET_LARGEHALL = 5;
Reverb preset representing a synthesis of the traditional plate reverb
/** * Reverb preset representing a synthesis of the traditional plate reverb */
public static final short PRESET_PLATE = 6;
Registered listener for parameter changes.
/** * Registered listener for parameter changes. */
private OnParameterChangeListener mParamListener = null;
Listener used internally to to receive raw parameter change event from AudioEffect super class
/** * Listener used internally to to receive raw parameter change event from AudioEffect super class */
private BaseParameterListener mBaseParamListener = null;
Lock for access to mParamListener
/** * Lock for access to mParamListener */
private final Object mParamListenerLock = new Object();
Class constructor.
Params:
  • priority – the priority level requested by the application for controlling the PresetReverb engine. As the same engine can be shared by several applications, this parameter indicates how much the requesting application needs control of effect parameters. The normal priority is 0, above normal is a positive number, below normal a negative number.
  • audioSession – system wide unique audio session identifier. If audioSession is not 0, the PresetReverb will be attached to the MediaPlayer or AudioTrack in the same audio session. Otherwise, the PresetReverb will apply to the output mix. As the PresetReverb is an auxiliary effect it is recommended to instantiate it on audio session 0 and to attach it to the MediaPLayer auxiliary output.
Throws:
/** * Class constructor. * @param priority the priority level requested by the application for controlling the * PresetReverb engine. As the same engine can be shared by several applications, this * parameter indicates how much the requesting application needs control of effect parameters. * The normal priority is 0, above normal is a positive number, below normal a negative number. * @param audioSession system wide unique audio session identifier. If audioSession * is not 0, the PresetReverb will be attached to the MediaPlayer or AudioTrack in the * same audio session. Otherwise, the PresetReverb will apply to the output mix. * As the PresetReverb is an auxiliary effect it is recommended to instantiate it on * audio session 0 and to attach it to the MediaPLayer auxiliary output. * * @throws java.lang.IllegalArgumentException * @throws java.lang.UnsupportedOperationException * @throws java.lang.RuntimeException */
public PresetReverb(int priority, int audioSession) throws IllegalArgumentException, UnsupportedOperationException, RuntimeException { super(EFFECT_TYPE_PRESET_REVERB, EFFECT_TYPE_NULL, priority, audioSession); }
Enables a preset on the reverb.

The reverb PRESET_NONE disables any reverb from the current output but does not free the resources associated with the reverb. For an application to signal to the implementation to free the resources, it must call the release() method.

Params:
  • preset – this must be one of the the preset constants defined in this class. e.g. PRESET_SMALLROOM
Throws:
/** * Enables a preset on the reverb. * <p>The reverb PRESET_NONE disables any reverb from the current output but does not free the * resources associated with the reverb. For an application to signal to the implementation * to free the resources, it must call the release() method. * @param preset this must be one of the the preset constants defined in this class. * e.g. {@link #PRESET_SMALLROOM} * @throws IllegalStateException * @throws IllegalArgumentException * @throws UnsupportedOperationException */
public void setPreset(short preset) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkStatus(setParameter(PARAM_PRESET, preset)); }
Gets current reverb preset.
Throws:
Returns:the preset that is set at the moment.
/** * Gets current reverb preset. * @return the preset that is set at the moment. * @throws IllegalStateException * @throws IllegalArgumentException * @throws UnsupportedOperationException */
public short getPreset() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { short[] value = new short[1]; checkStatus(getParameter(PARAM_PRESET, value)); return value[0]; }
The OnParameterChangeListener interface defines a method called by the PresetReverb when a parameter value has changed.
/** * The OnParameterChangeListener interface defines a method called by the PresetReverb * when a parameter value has changed. */
public interface OnParameterChangeListener {
Method called when a parameter value has changed. The method is called only if the parameter was changed by another application having the control of the same PresetReverb engine.
Params:
  • effect – the PresetReverb on which the interface is registered.
  • status – status of the set parameter operation.
  • param – ID of the modified parameter. See PresetReverb.PARAM_PRESET ...
  • value – the new parameter value.
/** * Method called when a parameter value has changed. The method is called only if the * parameter was changed by another application having the control of the same * PresetReverb engine. * @param effect the PresetReverb on which the interface is registered. * @param status status of the set parameter operation. * @param param ID of the modified parameter. See {@link #PARAM_PRESET} ... * @param value the new parameter value. */
void onParameterChange(PresetReverb effect, int status, int param, short value); }
Listener used internally to receive unformatted parameter change events from AudioEffect super class.
/** * Listener used internally to receive unformatted parameter change events from AudioEffect * super class. */
private class BaseParameterListener implements AudioEffect.OnParameterChangeListener { private BaseParameterListener() { } public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) { OnParameterChangeListener l = null; synchronized (mParamListenerLock) { if (mParamListener != null) { l = mParamListener; } } if (l != null) { int p = -1; short v = -1; if (param.length == 4) { p = byteArrayToInt(param, 0); } if (value.length == 2) { v = byteArrayToShort(value, 0); } if (p != -1 && v != -1) { l.onParameterChange(PresetReverb.this, status, p, v); } } } }
Registers an OnParameterChangeListener interface.
Params:
  • listener – OnParameterChangeListener interface registered
/** * Registers an OnParameterChangeListener interface. * @param listener OnParameterChangeListener interface registered */
public void setParameterListener(OnParameterChangeListener listener) { synchronized (mParamListenerLock) { if (mParamListener == null) { mParamListener = listener; mBaseParamListener = new BaseParameterListener(); super.setParameterListener(mBaseParamListener); } } }
The Settings class regroups all preset reverb parameters. It is used in conjuntion with getProperties() and setProperties() methods to backup and restore all parameters in a single call.
/** * The Settings class regroups all preset reverb parameters. It is used in * conjuntion with getProperties() and setProperties() methods to backup and restore * all parameters in a single call. */
public static class Settings { public short preset; public Settings() { }
Settings class constructor from a key=value; pairs formatted string. The string is typically returned by Settings.toString() method.
Throws:
  • IllegalArgumentException – if the string is not correctly formatted.
/** * Settings class constructor from a key=value; pairs formatted string. The string is * typically returned by Settings.toString() method. * @throws IllegalArgumentException if the string is not correctly formatted. */
public Settings(String settings) { StringTokenizer st = new StringTokenizer(settings, "=;"); int tokens = st.countTokens(); if (st.countTokens() != 3) { throw new IllegalArgumentException("settings: " + settings); } String key = st.nextToken(); if (!key.equals("PresetReverb")) { throw new IllegalArgumentException( "invalid settings for PresetReverb: " + key); } try { key = st.nextToken(); if (!key.equals("preset")) { throw new IllegalArgumentException("invalid key name: " + key); } preset = Short.parseShort(st.nextToken()); } catch (NumberFormatException nfe) { throw new IllegalArgumentException("invalid value for key: " + key); } } @Override public String toString() { String str = new String ( "PresetReverb"+ ";preset="+Short.toString(preset) ); return str; } };
Gets the preset reverb properties. This method is useful when a snapshot of current preset reverb settings must be saved by the application.
Throws:
Returns:a PresetReverb.Settings object containing all current parameters values
/** * Gets the preset reverb properties. This method is useful when a snapshot of current * preset reverb settings must be saved by the application. * @return a PresetReverb.Settings object containing all current parameters values * @throws IllegalStateException * @throws IllegalArgumentException * @throws UnsupportedOperationException */
public PresetReverb.Settings getProperties() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { Settings settings = new Settings(); short[] value = new short[1]; checkStatus(getParameter(PARAM_PRESET, value)); settings.preset = value[0]; return settings; }
Sets the preset reverb properties. This method is useful when preset reverb settings have to be applied from a previous backup.
Params:
  • settings – a PresetReverb.Settings object containing the properties to apply
Throws:
/** * Sets the preset reverb properties. This method is useful when preset reverb settings have to * be applied from a previous backup. * @param settings a PresetReverb.Settings object containing the properties to apply * @throws IllegalStateException * @throws IllegalArgumentException * @throws UnsupportedOperationException */
public void setProperties(PresetReverb.Settings settings) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkStatus(setParameter(PARAM_PRESET, settings.preset)); } }