/*
 * Copyright (C) 2018 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.annotation.NonNull;
import android.annotation.Nullable;
import android.media.AudioTrack;
import android.media.MediaPlayer;
import android.media.audiofx.AudioEffect;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.StringTokenizer;

DynamicsProcessing is an audio effect for equalizing and changing dynamic range properties of the sound. It is composed of multiple stages including equalization, multi-band compression and limiter.

The number of bands and active stages is configurable, and most parameters can be controlled in realtime, such as gains, attack/release times, thresholds, etc.

The effect is instantiated and controlled by channels. Each channel has the same basic architecture, but all of their parameters are independent from other channels.

The basic channel configuration is:

   Channel 0          Channel 1       ....       Channel N-1
     Input              Input                       Input
       |                  |                           |
  +----v----+        +----v----+                 +----v----+
  |inputGain|        |inputGain|                 |inputGain|
  +---------+        +---------+                 +---------+
       |                  |                           |
 +-----v-----+      +-----v-----+               +-----v-----+
 |   PreEQ   |      |   PreEQ   |               |   PreEQ   |
 +-----------+      +-----------+               +-----------+
       |                  |                           |
 +-----v-----+      +-----v-----+               +-----v-----+
 |    MBC    |      |    MBC    |               |    MBC    |
 +-----------+      +-----------+               +-----------+
       |                  |                           |
 +-----v-----+      +-----v-----+               +-----v-----+
 |  PostEQ   |      |  PostEQ   |               |  PostEQ   |
 +-----------+      +-----------+               +-----------+
       |                  |                           |
 +-----v-----+      +-----v-----+               +-----v-----+
 |  Limiter  |      |  Limiter  |               |  Limiter  |
 +-----------+      +-----------+               +-----------+
       |                  |                           |
    Output             Output                      Output

Where the stages are: inputGain: input gain factor in decibels (dB). 0 dB means no change in level. PreEQ: Multi-band Equalizer. MBC: Multi-band Compressor PostEQ: Multi-band Equalizer Limiter: Single band compressor/limiter.

An application creates a DynamicsProcessing object to instantiate and control this audio effect in the audio framework. A DynamicsProcessor.Config and DynamicsProcessor.Config.Builder are available to help configure the multiple stages and each band parameters if desired.

See each stage documentation for further details.

If no Config is specified during creation, a default configuration is chosen.

To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer, specify the audio session ID of this AudioTrack or MediaPlayer when constructing the effect (see AudioTrack.getAudioSessionId() and MediaPlayer.getAudioSessionId()).

To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer, specify the audio session ID of this AudioTrack or MediaPlayer when constructing the DynamicsProcessing.

See MediaPlayer.getAudioSessionId() for details on audio sessions.

See AudioEffect class for more details on controlling audio effects.

/** * DynamicsProcessing is an audio effect for equalizing and changing dynamic range properties of the * sound. It is composed of multiple stages including equalization, multi-band compression and * limiter. * <p>The number of bands and active stages is configurable, and most parameters can be controlled * in realtime, such as gains, attack/release times, thresholds, etc. * <p>The effect is instantiated and controlled by channels. Each channel has the same basic * architecture, but all of their parameters are independent from other channels. * <p>The basic channel configuration is: * <pre> * * Channel 0 Channel 1 .... Channel N-1 * Input Input Input * | | | * +----v----+ +----v----+ +----v----+ * |inputGain| |inputGain| |inputGain| * +---------+ +---------+ +---------+ * | | | * +-----v-----+ +-----v-----+ +-----v-----+ * | PreEQ | | PreEQ | | PreEQ | * +-----------+ +-----------+ +-----------+ * | | | * +-----v-----+ +-----v-----+ +-----v-----+ * | MBC | | MBC | | MBC | * +-----------+ +-----------+ +-----------+ * | | | * +-----v-----+ +-----v-----+ +-----v-----+ * | PostEQ | | PostEQ | | PostEQ | * +-----------+ +-----------+ +-----------+ * | | | * +-----v-----+ +-----v-----+ +-----v-----+ * | Limiter | | Limiter | | Limiter | * +-----------+ +-----------+ +-----------+ * | | | * Output Output Output * </pre> * * <p>Where the stages are: * inputGain: input gain factor in decibels (dB). 0 dB means no change in level. * PreEQ: Multi-band Equalizer. * MBC: Multi-band Compressor * PostEQ: Multi-band Equalizer * Limiter: Single band compressor/limiter. * * <p>An application creates a DynamicsProcessing object to instantiate and control this audio * effect in the audio framework. A DynamicsProcessor.Config and DynamicsProcessor.Config.Builder * are available to help configure the multiple stages and each band parameters if desired. * <p>See each stage documentation for further details. * <p>If no Config is specified during creation, a default configuration is chosen. * <p>To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer, * specify the audio session ID of this AudioTrack or MediaPlayer when constructing the effect * (see {@link AudioTrack#getAudioSessionId()} and {@link MediaPlayer#getAudioSessionId()}). * * <p>To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer, specify the audio * session ID of this AudioTrack or MediaPlayer when constructing the DynamicsProcessing. * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions. * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling audio * effects. */
public final class DynamicsProcessing extends AudioEffect { private final static String TAG = "DynamicsProcessing"; // These parameter constants must be synchronized with those in // /system/media/audio_effects/include/audio_effects/effect_dynamicsprocessing.h private static final int PARAM_GET_CHANNEL_COUNT = 0x10; private static final int PARAM_INPUT_GAIN = 0x20; private static final int PARAM_ENGINE_ARCHITECTURE = 0x30; private static final int PARAM_PRE_EQ = 0x40; private static final int PARAM_PRE_EQ_BAND = 0x45; private static final int PARAM_MBC = 0x50; private static final int PARAM_MBC_BAND = 0x55; private static final int PARAM_POST_EQ = 0x60; private static final int PARAM_POST_EQ_BAND = 0x65; private static final int PARAM_LIMITER = 0x70;
Index of variant that favors frequency resolution. Frequency domain based implementation.
/** * Index of variant that favors frequency resolution. Frequency domain based implementation. */
public static final int VARIANT_FAVOR_FREQUENCY_RESOLUTION = 0;
Index of variant that favors time resolution resolution. Time domain based implementation.
/** * Index of variant that favors time resolution resolution. Time domain based implementation. */
public static final int VARIANT_FAVOR_TIME_RESOLUTION = 1;
Maximum expected channels to be reported by effect
/** * Maximum expected channels to be reported by effect */
private static final int CHANNEL_COUNT_MAX = 32;
Number of channels in effect architecture
/** * Number of channels in effect architecture */
private int mChannelCount = 0;
Registered listener for parameter changes.
/** * Registered listener for parameter changes. */
private OnParameterChangeListener mParamListener = null;
Listener used internally to to receive raw parameter change events from AudioEffect super class
/** * Listener used internally to to receive raw parameter change events * 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:
  • audioSession – system-wide unique audio session identifier. The DynamicsProcessing will be attached to the MediaPlayer or AudioTrack in the same audio session.
/** * Class constructor. * @param audioSession system-wide unique audio session identifier. The DynamicsProcessing * will be attached to the MediaPlayer or AudioTrack in the same audio session. */
public DynamicsProcessing(int audioSession) { this(0 /*priority*/, audioSession); }
Params:
  • priority – the priority level requested by the application for controlling the DynamicsProcessing 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. The DynamicsProcessing will be attached to the MediaPlayer or AudioTrack in the same audio session.
@hide Class constructor for the DynamicsProcessing audio effect.
/** * @hide * Class constructor for the DynamicsProcessing audio effect. * @param priority the priority level requested by the application for controlling the * DynamicsProcessing 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. The DynamicsProcessing * will be attached to the MediaPlayer or AudioTrack in the same audio session. */
public DynamicsProcessing(int priority, int audioSession) { this(priority, audioSession, null); }
Class constructor for the DynamicsProcessing audio effect
Params:
  • priority – the priority level requested by the application for controlling the DynamicsProcessing 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. The DynamicsProcessing will be attached to the MediaPlayer or AudioTrack in the same audio session.
  • cfg – Config object used to setup the audio effect, including bands per stage, and specific parameters for each stage/band. Use Builder to create a Config object that suits your needs. A null cfg parameter will create and use a default configuration for the effect
/** * Class constructor for the DynamicsProcessing audio effect * @param priority the priority level requested by the application for controlling the * DynamicsProcessing 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. The DynamicsProcessing * will be attached to the MediaPlayer or AudioTrack in the same audio session. * @param cfg Config object used to setup the audio effect, including bands per stage, and * specific parameters for each stage/band. Use * {@link android.media.audiofx.DynamicsProcessing.Config.Builder} to create a * Config object that suits your needs. A null cfg parameter will create and use a default * configuration for the effect */
public DynamicsProcessing(int priority, int audioSession, @Nullable Config cfg) { super(EFFECT_TYPE_DYNAMICS_PROCESSING, EFFECT_TYPE_NULL, priority, audioSession); if (audioSession == 0) { Log.w(TAG, "WARNING: attaching a DynamicsProcessing to global output mix is" + "deprecated!"); } final Config config; mChannelCount = getChannelCount(); if (cfg == null) { //create a default configuration and effect, with the number of channels this effect has DynamicsProcessing.Config.Builder builder = new DynamicsProcessing.Config.Builder( CONFIG_DEFAULT_VARIANT, mChannelCount, CONFIG_DEFAULT_USE_PREEQ, CONFIG_DEFAULT_PREEQ_BANDS, CONFIG_DEFAULT_USE_MBC, CONFIG_DEFAULT_MBC_BANDS, CONFIG_DEFAULT_USE_POSTEQ, CONFIG_DEFAULT_POSTEQ_BANDS, CONFIG_DEFAULT_USE_LIMITER); config = builder.build(); } else { //validate channels are ok. decide what to do: replicate channels if more config = new DynamicsProcessing.Config(mChannelCount, cfg); } //configure engine setEngineArchitecture(config.getVariant(), config.getPreferredFrameDuration(), config.isPreEqInUse(), config.getPreEqBandCount(), config.isMbcInUse(), config.getMbcBandCount(), config.isPostEqInUse(), config.getPostEqBandCount(), config.isLimiterInUse()); //update all the parameters for (int ch = 0; ch < mChannelCount; ch++) { updateEngineChannelByChannelIndex(ch, config.getChannelByChannelIndex(ch)); } }
Returns the Config object used to setup this effect.
Returns:Config Current Config object used to setup this DynamicsProcessing effect.
/** * Returns the Config object used to setup this effect. * @return Config Current Config object used to setup this DynamicsProcessing effect. */
public Config getConfig() { //Query engine architecture to create config object Number[] params = { PARAM_ENGINE_ARCHITECTURE }; Number[] values = { 0 /*0 variant */, 0.0f /* 1 preferredFrameDuration */, 0 /*2 preEqInUse */, 0 /*3 preEqBandCount */, 0 /*4 mbcInUse */, 0 /*5 mbcBandCount*/, 0 /*6 postEqInUse */, 0 /*7 postEqBandCount */, 0 /*8 limiterInUse */}; byte[] paramBytes = numberArrayToByteArray(params); byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size. getParameter(paramBytes, valueBytes); byteArrayToNumberArray(valueBytes, values); DynamicsProcessing.Config.Builder builder = new DynamicsProcessing.Config.Builder( values[0].intValue(), mChannelCount, values[2].intValue() > 0 /*use preEQ*/, values[3].intValue() /*pre eq bands*/, values[4].intValue() > 0 /*use mbc*/, values[5].intValue() /*mbc bands*/, values[6].intValue() > 0 /*use postEQ*/, values[7].intValue()/*postEq bands*/, values[8].intValue() > 0 /*use Limiter*/). setPreferredFrameDuration(values[1].floatValue()); Config config = builder.build(); for (int ch = 0; ch < mChannelCount; ch++) { Channel channel = queryEngineByChannelIndex(ch); config.setChannelTo(ch, channel); } return config; } private static final int CONFIG_DEFAULT_VARIANT = VARIANT_FAVOR_FREQUENCY_RESOLUTION; private static final boolean CONFIG_DEFAULT_USE_PREEQ = true; private static final int CONFIG_DEFAULT_PREEQ_BANDS = 6; private static final boolean CONFIG_DEFAULT_USE_MBC = true; private static final int CONFIG_DEFAULT_MBC_BANDS = 6; private static final boolean CONFIG_DEFAULT_USE_POSTEQ = true; private static final int CONFIG_DEFAULT_POSTEQ_BANDS = 6; private static final boolean CONFIG_DEFAULT_USE_LIMITER = true; private static final float CHANNEL_DEFAULT_INPUT_GAIN = 0; // dB private static final float CONFIG_PREFERRED_FRAME_DURATION_MS = 10.0f; //milliseconds private static final float EQ_DEFAULT_GAIN = 0; // dB private static final boolean PREEQ_DEFAULT_ENABLED = true; private static final boolean POSTEQ_DEFAULT_ENABLED = true; private static final boolean MBC_DEFAULT_ENABLED = true; private static final float MBC_DEFAULT_ATTACK_TIME = 3; // ms private static final float MBC_DEFAULT_RELEASE_TIME = 80; // ms private static final float MBC_DEFAULT_RATIO = 1; // N:1 private static final float MBC_DEFAULT_THRESHOLD = -45; // dB private static final float MBC_DEFAULT_KNEE_WIDTH = 0; // dB private static final float MBC_DEFAULT_NOISE_GATE_THRESHOLD = -90; // dB private static final float MBC_DEFAULT_EXPANDER_RATIO = 1; // 1:N private static final float MBC_DEFAULT_PRE_GAIN = 0; // dB private static final float MBC_DEFAULT_POST_GAIN = 0; // dB private static final boolean LIMITER_DEFAULT_ENABLED = true; private static final int LIMITER_DEFAULT_LINK_GROUP = 0;//; private static final float LIMITER_DEFAULT_ATTACK_TIME = 1; // ms private static final float LIMITER_DEFAULT_RELEASE_TIME = 60; // ms private static final float LIMITER_DEFAULT_RATIO = 10; // N:1 private static final float LIMITER_DEFAULT_THRESHOLD = -2; // dB private static final float LIMITER_DEFAULT_POST_GAIN = 0; // dB private static final float DEFAULT_MIN_FREQUENCY = 220; // Hz private static final float DEFAULT_MAX_FREQUENCY = 20000; // Hz private static final float mMinFreqLog = (float)Math.log10(DEFAULT_MIN_FREQUENCY); private static final float mMaxFreqLog = (float)Math.log10(DEFAULT_MAX_FREQUENCY);
base class for the different stages.
/** * base class for the different stages. */
public static class Stage { private boolean mInUse; private boolean mEnabled;
Class constructor for stage
Params:
  • inUse – true if this stage is set to be used. False otherwise. Stages that are not set "inUse" at initialization time are not available to be used at any time.
  • enabled – true if this stage is currently used to process sound. When disabled, the stage is bypassed and the sound is copied unaltered from input to output.
/** * Class constructor for stage * @param inUse true if this stage is set to be used. False otherwise. Stages that are not * set "inUse" at initialization time are not available to be used at any time. * @param enabled true if this stage is currently used to process sound. When disabled, * the stage is bypassed and the sound is copied unaltered from input to output. */
public Stage(boolean inUse, boolean enabled) { mInUse = inUse; mEnabled = enabled; }
returns enabled state of the stage
Returns:true if stage is enabled for processing, false otherwise
/** * returns enabled state of the stage * @return true if stage is enabled for processing, false otherwise */
public boolean isEnabled() { return mEnabled; }
sets enabled state of the stage
Params:
  • enabled – true for enabled, false otherwise
/** * sets enabled state of the stage * @param enabled true for enabled, false otherwise */
public void setEnabled(boolean enabled) { mEnabled = enabled; }
returns inUse state of the stage.
Returns:inUse state of the stage. True if this stage is currently used to process sound. When false, the stage is bypassed and the sound is copied unaltered from input to output.
/** * returns inUse state of the stage. * @return inUse state of the stage. True if this stage is currently used to process sound. * When false, the stage is bypassed and the sound is copied unaltered from input to output. */
public boolean isInUse() { return mInUse; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format(" Stage InUse: %b\n", isInUse())); if (isInUse()) { sb.append(String.format(" Stage Enabled: %b\n", mEnabled)); } return sb.toString(); } }
Base class for stages that hold bands
/** * Base class for stages that hold bands */
public static class BandStage extends Stage{ private int mBandCount;
Class constructor for BandStage
Params:
  • inUse – true if this stage is set to be used. False otherwise. Stages that are not set "inUse" at initialization time are not available to be used at any time.
  • enabled – true if this stage is currently used to process sound. When disabled, the stage is bypassed and the sound is copied unaltered from input to output.
  • bandCount – number of bands this stage will handle. If stage is not inUse, bandcount is set to 0
/** * Class constructor for BandStage * @param inUse true if this stage is set to be used. False otherwise. Stages that are not * set "inUse" at initialization time are not available to be used at any time. * @param enabled true if this stage is currently used to process sound. When disabled, * the stage is bypassed and the sound is copied unaltered from input to output. * @param bandCount number of bands this stage will handle. If stage is not inUse, bandcount * is set to 0 */
public BandStage(boolean inUse, boolean enabled, int bandCount) { super(inUse, enabled); mBandCount = isInUse() ? bandCount : 0; }
gets number of bands held in this stage
Returns:number of bands held in this stage
/** * gets number of bands held in this stage * @return number of bands held in this stage */
public int getBandCount() { return mBandCount; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()); if (isInUse()) { sb.append(String.format(" Band Count: %d\n", mBandCount)); } return sb.toString(); } }
Base class for bands
/** * Base class for bands */
public static class BandBase { private boolean mEnabled; private float mCutoffFrequency;
Class constructor for BandBase
Params:
  • enabled – true if this band is currently used to process sound. When false, the band is effectively muted and sound set to zero.
  • cutoffFrequency – topmost frequency number (in Hz) this band will process. The effective bandwidth for the band is then computed using this and the previous band topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
/** * Class constructor for BandBase * @param enabled true if this band is currently used to process sound. When false, * the band is effectively muted and sound set to zero. * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The * effective bandwidth for the band is then computed using this and the previous band * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on. */
public BandBase(boolean enabled, float cutoffFrequency) { mEnabled = enabled; mCutoffFrequency = cutoffFrequency; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format(" Enabled: %b\n", mEnabled)); sb.append(String.format(" CutoffFrequency: %f\n", mCutoffFrequency)); return sb.toString(); }
returns enabled state of the band
Returns:true if bands is enabled for processing, false otherwise
/** * returns enabled state of the band * @return true if bands is enabled for processing, false otherwise */
public boolean isEnabled() { return mEnabled; }
sets enabled state of the band
Params:
  • enabled – true for enabled, false otherwise
/** * sets enabled state of the band * @param enabled true for enabled, false otherwise */
public void setEnabled(boolean enabled) { mEnabled = enabled; }
gets cutoffFrequency for this band in Hertz (Hz)
Returns:cutoffFrequency for this band in Hertz (Hz)
/** * gets cutoffFrequency for this band in Hertz (Hz) * @return cutoffFrequency for this band in Hertz (Hz) */
public float getCutoffFrequency() { return mCutoffFrequency; }
sets topmost frequency number (in Hz) this band will process. The effective bandwidth for the band is then computed using this and the previous band topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
Params:
  • frequency –
/** * sets topmost frequency number (in Hz) this band will process. The * effective bandwidth for the band is then computed using this and the previous band * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on. * @param frequency */
public void setCutoffFrequency(float frequency) { mCutoffFrequency = frequency; } }
Class for Equalizer Bands Equalizer bands have three controllable parameters: enabled/disabled, cutoffFrequency and gain
/** * Class for Equalizer Bands * Equalizer bands have three controllable parameters: enabled/disabled, cutoffFrequency and * gain */
public final static class EqBand extends BandBase { private float mGain;
Class constructor for EqBand
Params:
  • enabled – true if this band is currently used to process sound. When false, the band is effectively muted and sound set to zero.
  • cutoffFrequency – topmost frequency number (in Hz) this band will process. The effective bandwidth for the band is then computed using this and the previous band topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
  • gain – of equalizer band in decibels (dB). A gain of 0 dB means no change in level.
/** * Class constructor for EqBand * @param enabled true if this band is currently used to process sound. When false, * the band is effectively muted and sound set to zero. * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The * effective bandwidth for the band is then computed using this and the previous band * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on. * @param gain of equalizer band in decibels (dB). A gain of 0 dB means no change in level. */
public EqBand(boolean enabled, float cutoffFrequency, float gain) { super(enabled, cutoffFrequency); mGain = gain; }
Class constructor for EqBand
Params:
  • cfg – copy constructor
/** * Class constructor for EqBand * @param cfg copy constructor */
public EqBand(EqBand cfg) { super(cfg.isEnabled(), cfg.getCutoffFrequency()); mGain = cfg.mGain; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()); sb.append(String.format(" Gain: %f\n", mGain)); return sb.toString(); }
gets current gain of band in decibels (dB)
Returns:current gain of band in decibels (dB)
/** * gets current gain of band in decibels (dB) * @return current gain of band in decibels (dB) */
public float getGain() { return mGain; }
sets current gain of band in decibels (dB)
Params:
  • gain – desired in decibels (db)
/** * sets current gain of band in decibels (dB) * @param gain desired in decibels (db) */
public void setGain(float gain) { mGain = gain; } }
Class for Multi-Band compressor bands MBC bands have multiple controllable parameters: enabled/disabled, cutoffFrequency, attackTime, releaseTime, ratio, threshold, kneeWidth, noiseGateThreshold, expanderRatio, preGain and postGain.
/** * Class for Multi-Band compressor bands * MBC bands have multiple controllable parameters: enabled/disabled, cutoffFrequency, * attackTime, releaseTime, ratio, threshold, kneeWidth, noiseGateThreshold, expanderRatio, * preGain and postGain. */
public final static class MbcBand extends BandBase{ private float mAttackTime; private float mReleaseTime; private float mRatio; private float mThreshold; private float mKneeWidth; private float mNoiseGateThreshold; private float mExpanderRatio; private float mPreGain; private float mPostGain;
Class constructor for MbcBand
Params:
  • enabled – true if this band is currently used to process sound. When false, the band is effectively muted and sound set to zero.
  • cutoffFrequency – topmost frequency number (in Hz) this band will process. The effective bandwidth for the band is then computed using this and the previous band topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
  • attackTime – Attack Time for compressor in milliseconds (ms)
  • releaseTime – Release Time for compressor in milliseconds (ms)
  • ratio – Compressor ratio (N:1) (input:output)
  • threshold – Compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS).
  • kneeWidth – Width in decibels (dB) around compressor threshold point.
  • noiseGateThreshold – Noise gate threshold in decibels (dB) from 0 dB Full Scale (dBFS).
  • expanderRatio – Expander ratio (1:N) (input:output) for signals below the Noise Gate Threshold.
  • preGain – Gain applied to the signal BEFORE the compression.
  • postGain – Gain applied to the signal AFTER compression.
/** * Class constructor for MbcBand * @param enabled true if this band is currently used to process sound. When false, * the band is effectively muted and sound set to zero. * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The * effective bandwidth for the band is then computed using this and the previous band * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on. * @param attackTime Attack Time for compressor in milliseconds (ms) * @param releaseTime Release Time for compressor in milliseconds (ms) * @param ratio Compressor ratio (N:1) (input:output) * @param threshold Compressor threshold measured in decibels (dB) from 0 dB Full Scale * (dBFS). * @param kneeWidth Width in decibels (dB) around compressor threshold point. * @param noiseGateThreshold Noise gate threshold in decibels (dB) from 0 dB Full Scale * (dBFS). * @param expanderRatio Expander ratio (1:N) (input:output) for signals below the Noise Gate * Threshold. * @param preGain Gain applied to the signal BEFORE the compression. * @param postGain Gain applied to the signal AFTER compression. */
public MbcBand(boolean enabled, float cutoffFrequency, float attackTime, float releaseTime, float ratio, float threshold, float kneeWidth, float noiseGateThreshold, float expanderRatio, float preGain, float postGain) { super(enabled, cutoffFrequency); mAttackTime = attackTime; mReleaseTime = releaseTime; mRatio = ratio; mThreshold = threshold; mKneeWidth = kneeWidth; mNoiseGateThreshold = noiseGateThreshold; mExpanderRatio = expanderRatio; mPreGain = preGain; mPostGain = postGain; }
Class constructor for MbcBand
Params:
  • cfg – copy constructor
/** * Class constructor for MbcBand * @param cfg copy constructor */
public MbcBand(MbcBand cfg) { super(cfg.isEnabled(), cfg.getCutoffFrequency()); mAttackTime = cfg.mAttackTime; mReleaseTime = cfg.mReleaseTime; mRatio = cfg.mRatio; mThreshold = cfg.mThreshold; mKneeWidth = cfg.mKneeWidth; mNoiseGateThreshold = cfg.mNoiseGateThreshold; mExpanderRatio = cfg.mExpanderRatio; mPreGain = cfg.mPreGain; mPostGain = cfg.mPostGain; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()); sb.append(String.format(" AttackTime: %f (ms)\n", mAttackTime)); sb.append(String.format(" ReleaseTime: %f (ms)\n", mReleaseTime)); sb.append(String.format(" Ratio: 1:%f\n", mRatio)); sb.append(String.format(" Threshold: %f (dB)\n", mThreshold)); sb.append(String.format(" NoiseGateThreshold: %f(dB)\n", mNoiseGateThreshold)); sb.append(String.format(" ExpanderRatio: %f:1\n", mExpanderRatio)); sb.append(String.format(" PreGain: %f (dB)\n", mPreGain)); sb.append(String.format(" PostGain: %f (dB)\n", mPostGain)); return sb.toString(); }
gets attack time for compressor in milliseconds (ms)
Returns:attack time for compressor in milliseconds (ms)
/** * gets attack time for compressor in milliseconds (ms) * @return attack time for compressor in milliseconds (ms) */
public float getAttackTime() { return mAttackTime; }
sets attack time for compressor in milliseconds (ms)
Params:
  • attackTime – desired for compressor in milliseconds (ms)
/** * sets attack time for compressor in milliseconds (ms) * @param attackTime desired for compressor in milliseconds (ms) */
public void setAttackTime(float attackTime) { mAttackTime = attackTime; }
gets release time for compressor in milliseconds (ms)
Returns:release time for compressor in milliseconds (ms)
/** * gets release time for compressor in milliseconds (ms) * @return release time for compressor in milliseconds (ms) */
public float getReleaseTime() { return mReleaseTime; }
sets release time for compressor in milliseconds (ms)
Params:
  • releaseTime – desired for compressor in milliseconds (ms)
/** * sets release time for compressor in milliseconds (ms) * @param releaseTime desired for compressor in milliseconds (ms) */
public void setReleaseTime(float releaseTime) { mReleaseTime = releaseTime; }
gets the compressor ratio (N:1)
Returns:compressor ratio (N:1)
/** * gets the compressor ratio (N:1) * @return compressor ratio (N:1) */
public float getRatio() { return mRatio; }
sets compressor ratio (N:1)
Params:
  • ratio – desired for the compressor (N:1)
/** * sets compressor ratio (N:1) * @param ratio desired for the compressor (N:1) */
public void setRatio(float ratio) { mRatio = ratio; }
gets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS). Thresholds are negative. A threshold of 0 dB means no compression will take place.
Returns:compressor threshold in decibels (dB)
/** * gets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS). * Thresholds are negative. A threshold of 0 dB means no compression will take place. * @return compressor threshold in decibels (dB) */
public float getThreshold() { return mThreshold; }
sets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS). Thresholds are negative. A threshold of 0 dB means no compression will take place.
Params:
  • threshold – desired for compressor in decibels(dB)
/** * sets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS). * Thresholds are negative. A threshold of 0 dB means no compression will take place. * @param threshold desired for compressor in decibels(dB) */
public void setThreshold(float threshold) { mThreshold = threshold; }
get Knee Width in decibels (dB) around compressor threshold point. Widths are always positive, with higher values representing a wider area of transition from the linear zone to the compression zone. A knee of 0 dB means a more abrupt transition.
Returns:Knee Width in decibels (dB)
/** * get Knee Width in decibels (dB) around compressor threshold point. Widths are always * positive, with higher values representing a wider area of transition from the linear zone * to the compression zone. A knee of 0 dB means a more abrupt transition. * @return Knee Width in decibels (dB) */
public float getKneeWidth() { return mKneeWidth; }
sets knee width in decibels (dB). See getKneeWidth for more information.
Params:
  • kneeWidth – desired in decibels (dB)
/** * sets knee width in decibels (dB). See * {@link android.media.audiofx.DynamicsProcessing.MbcBand#getKneeWidth} for more * information. * @param kneeWidth desired in decibels (dB) */
public void setKneeWidth(float kneeWidth) { mKneeWidth = kneeWidth; }
gets the noise gate threshold in decibels (dB) from 0 dB Full Scale (dBFS). Noise gate thresholds are negative. Signals below this level will be expanded according the expanderRatio parameter. A Noise Gate Threshold of -75 dB means very quiet signals might be effectively removed from the signal.
Returns:Noise Gate Threshold in decibels (dB)
/** * gets the noise gate threshold in decibels (dB) from 0 dB Full Scale (dBFS). Noise gate * thresholds are negative. Signals below this level will be expanded according the * expanderRatio parameter. A Noise Gate Threshold of -75 dB means very quiet signals might * be effectively removed from the signal. * @return Noise Gate Threshold in decibels (dB) */
public float getNoiseGateThreshold() { return mNoiseGateThreshold; }
sets noise gate threshod in decibels (dB). See getNoiseGateThreshold for more information.
Params:
  • noiseGateThreshold – desired in decibels (dB)
/** * sets noise gate threshod in decibels (dB). See * {@link android.media.audiofx.DynamicsProcessing.MbcBand#getNoiseGateThreshold} for more * information. * @param noiseGateThreshold desired in decibels (dB) */
public void setNoiseGateThreshold(float noiseGateThreshold) { mNoiseGateThreshold = noiseGateThreshold; }
gets Expander ratio (1:N) for signals below the Noise Gate Threshold.
Returns:Expander ratio (1:N)
/** * gets Expander ratio (1:N) for signals below the Noise Gate Threshold. * @return Expander ratio (1:N) */
public float getExpanderRatio() { return mExpanderRatio; }
sets Expander ratio (1:N) for signals below the Noise Gate Threshold.
Params:
  • expanderRatio – desired expander ratio (1:N)
/** * sets Expander ratio (1:N) for signals below the Noise Gate Threshold. * @param expanderRatio desired expander ratio (1:N) */
public void setExpanderRatio(float expanderRatio) { mExpanderRatio = expanderRatio; }
gets the gain applied to the signal BEFORE the compression. Measured in decibels (dB) where 0 dB means no level change.
Returns:preGain value in decibels (dB)
/** * gets the gain applied to the signal BEFORE the compression. Measured in decibels (dB) * where 0 dB means no level change. * @return preGain value in decibels (dB) */
public float getPreGain() { return mPreGain; }
sets the gain to be applied to the signal BEFORE the compression, measured in decibels (dB), where 0 dB means no level change.
Params:
  • preGain – desired in decibels (dB)
/** * sets the gain to be applied to the signal BEFORE the compression, measured in decibels * (dB), where 0 dB means no level change. * @param preGain desired in decibels (dB) */
public void setPreGain(float preGain) { mPreGain = preGain; }
gets the gain applied to the signal AFTER compression. Measured in decibels (dB) where 0 dB means no level change
Returns:postGain value in decibels (dB)
/** * gets the gain applied to the signal AFTER compression. Measured in decibels (dB) where 0 * dB means no level change * @return postGain value in decibels (dB) */
public float getPostGain() { return mPostGain; }
sets the gain to be applied to the siganl AFTER the compression. Measured in decibels (dB), where 0 dB means no level change.
Params:
  • postGain – desired value in decibels (dB)
/** * sets the gain to be applied to the siganl AFTER the compression. Measured in decibels * (dB), where 0 dB means no level change. * @param postGain desired value in decibels (dB) */
public void setPostGain(float postGain) { mPostGain = postGain; } }
Class for Equalizer stage
/** * Class for Equalizer stage */
public final static class Eq extends BandStage { private final EqBand[] mBands;
Class constructor for Equalizer (Eq) stage
Params:
  • inUse – true if Eq stage will be used, false otherwise.
  • enabled – true if Eq stage is enabled/disabled. This can be changed while effect is running
  • bandCount – number of bands for this Equalizer stage. Can't be changed while effect is running
/** * Class constructor for Equalizer (Eq) stage * @param inUse true if Eq stage will be used, false otherwise. * @param enabled true if Eq stage is enabled/disabled. This can be changed while effect is * running * @param bandCount number of bands for this Equalizer stage. Can't be changed while effect * is running */
public Eq(boolean inUse, boolean enabled, int bandCount) { super(inUse, enabled, bandCount); if (isInUse()) { mBands = new EqBand[bandCount]; for (int b = 0; b < bandCount; b++) { float freq = DEFAULT_MAX_FREQUENCY; if (bandCount > 1) { freq = (float)Math.pow(10, mMinFreqLog + b * (mMaxFreqLog - mMinFreqLog)/(bandCount -1)); } mBands[b] = new EqBand(true, freq, EQ_DEFAULT_GAIN); } } else { mBands = null; } }
Class constructor for Eq stage
Params:
  • cfg – copy constructor
/** * Class constructor for Eq stage * @param cfg copy constructor */
public Eq(Eq cfg) { super(cfg.isInUse(), cfg.isEnabled(), cfg.getBandCount()); if (isInUse()) { mBands = new EqBand[cfg.mBands.length]; for (int b = 0; b < mBands.length; b++) { mBands[b] = new EqBand(cfg.mBands[b]); } } else { mBands = null; } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()); if (isInUse()) { sb.append("--->EqBands: " + mBands.length + "\n"); for (int b = 0; b < mBands.length; b++) { sb.append(String.format(" Band %d\n", b)); sb.append(mBands[b].toString()); } } return sb.toString(); }
Helper function to check if band index is within range
Params:
  • band – index to check
/** * Helper function to check if band index is within range * @param band index to check */
private void checkBand(int band) { if (mBands == null || band < 0 || band >= mBands.length) { throw new IllegalArgumentException("band index " + band +" out of bounds"); } }
Sets EqBand object for given band index
Params:
  • band – index of band to be modified
  • bandCfg – EqBand object.
/** * Sets EqBand object for given band index * @param band index of band to be modified * @param bandCfg EqBand object. */
public void setBand(int band, EqBand bandCfg) { checkBand(band); mBands[band] = new EqBand(bandCfg); }
Gets EqBand object for band of interest.
Params:
  • band – index of band of interest
Returns:EqBand Object
/** * Gets EqBand object for band of interest. * @param band index of band of interest * @return EqBand Object */
public EqBand getBand(int band) { checkBand(band); return mBands[band]; } }
Class for Multi-Band Compressor (MBC) stage
/** * Class for Multi-Band Compressor (MBC) stage */
public final static class Mbc extends BandStage { private final MbcBand[] mBands;
Constructor for Multi-Band Compressor (MBC) stage
Params:
  • inUse – true if MBC stage will be used, false otherwise.
  • enabled – true if MBC stage is enabled/disabled. This can be changed while effect is running
  • bandCount – number of bands for this MBC stage. Can't be changed while effect is running
/** * Constructor for Multi-Band Compressor (MBC) stage * @param inUse true if MBC stage will be used, false otherwise. * @param enabled true if MBC stage is enabled/disabled. This can be changed while effect * is running * @param bandCount number of bands for this MBC stage. Can't be changed while effect is * running */
public Mbc(boolean inUse, boolean enabled, int bandCount) { super(inUse, enabled, bandCount); if (isInUse()) { mBands = new MbcBand[bandCount]; for (int b = 0; b < bandCount; b++) { float freq = DEFAULT_MAX_FREQUENCY; if (bandCount > 1) { freq = (float)Math.pow(10, mMinFreqLog + b * (mMaxFreqLog - mMinFreqLog)/(bandCount -1)); } mBands[b] = new MbcBand(true, freq, MBC_DEFAULT_ATTACK_TIME, MBC_DEFAULT_RELEASE_TIME, MBC_DEFAULT_RATIO, MBC_DEFAULT_THRESHOLD, MBC_DEFAULT_KNEE_WIDTH, MBC_DEFAULT_NOISE_GATE_THRESHOLD, MBC_DEFAULT_EXPANDER_RATIO, MBC_DEFAULT_PRE_GAIN, MBC_DEFAULT_POST_GAIN); } } else { mBands = null; } }
Class constructor for MBC stage
Params:
  • cfg – copy constructor
/** * Class constructor for MBC stage * @param cfg copy constructor */
public Mbc(Mbc cfg) { super(cfg.isInUse(), cfg.isEnabled(), cfg.getBandCount()); if (isInUse()) { mBands = new MbcBand[cfg.mBands.length]; for (int b = 0; b < mBands.length; b++) { mBands[b] = new MbcBand(cfg.mBands[b]); } } else { mBands = null; } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()); if (isInUse()) { sb.append("--->MbcBands: " + mBands.length + "\n"); for (int b = 0; b < mBands.length; b++) { sb.append(String.format(" Band %d\n", b)); sb.append(mBands[b].toString()); } } return sb.toString(); }
Helper function to check if band index is within range
Params:
  • band – index to check
/** * Helper function to check if band index is within range * @param band index to check */
private void checkBand(int band) { if (mBands == null || band < 0 || band >= mBands.length) { throw new IllegalArgumentException("band index " + band +" out of bounds"); } }
Sets MbcBand object for given band index
Params:
  • band – index of band to be modified
  • bandCfg – MbcBand object.
/** * Sets MbcBand object for given band index * @param band index of band to be modified * @param bandCfg MbcBand object. */
public void setBand(int band, MbcBand bandCfg) { checkBand(band); mBands[band] = new MbcBand(bandCfg); }
Gets MbcBand object for band of interest.
Params:
  • band – index of band of interest
Returns:MbcBand Object
/** * Gets MbcBand object for band of interest. * @param band index of band of interest * @return MbcBand Object */
public MbcBand getBand(int band) { checkBand(band); return mBands[band]; } }
Class for Limiter Stage Limiter is a single band compressor at the end of the processing chain, commonly used to protect the signal from overloading and distortion. Limiters have multiple controllable parameters: enabled/disabled, linkGroup, attackTime, releaseTime, ratio, threshold, and postGain.

Limiters can be linked in groups across multiple channels. Linked limiters will trigger the same limiting if any of the linked limiters starts compressing.

/** * Class for Limiter Stage * Limiter is a single band compressor at the end of the processing chain, commonly used to * protect the signal from overloading and distortion. Limiters have multiple controllable * parameters: enabled/disabled, linkGroup, attackTime, releaseTime, ratio, threshold, and * postGain. * <p>Limiters can be linked in groups across multiple channels. Linked limiters will trigger * the same limiting if any of the linked limiters starts compressing. */
public final static class Limiter extends Stage { private int mLinkGroup; private float mAttackTime; private float mReleaseTime; private float mRatio; private float mThreshold; private float mPostGain;
Class constructor for Limiter Stage
Params:
  • inUse – true if MBC stage will be used, false otherwise.
  • enabled – true if MBC stage is enabled/disabled. This can be changed while effect is running
  • linkGroup – index of group assigned to this Limiter. Only limiters that share the same linkGroup index will react together.
  • attackTime – Attack Time for limiter compressor in milliseconds (ms)
  • releaseTime – Release Time for limiter compressor in milliseconds (ms)
  • ratio – Limiter Compressor ratio (N:1) (input:output)
  • threshold – Limiter Compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS).
  • postGain – Gain applied to the signal AFTER compression.
/** * Class constructor for Limiter Stage * @param inUse true if MBC stage will be used, false otherwise. * @param enabled true if MBC stage is enabled/disabled. This can be changed while effect * is running * @param linkGroup index of group assigned to this Limiter. Only limiters that share the * same linkGroup index will react together. * @param attackTime Attack Time for limiter compressor in milliseconds (ms) * @param releaseTime Release Time for limiter compressor in milliseconds (ms) * @param ratio Limiter Compressor ratio (N:1) (input:output) * @param threshold Limiter Compressor threshold measured in decibels (dB) from 0 dB Full * Scale (dBFS). * @param postGain Gain applied to the signal AFTER compression. */
public Limiter(boolean inUse, boolean enabled, int linkGroup, float attackTime, float releaseTime, float ratio, float threshold, float postGain) { super(inUse, enabled); mLinkGroup = linkGroup; mAttackTime = attackTime; mReleaseTime = releaseTime; mRatio = ratio; mThreshold = threshold; mPostGain = postGain; }
Class Constructor for Limiter
Params:
  • cfg – copy constructor
/** * Class Constructor for Limiter * @param cfg copy constructor */
public Limiter(Limiter cfg) { super(cfg.isInUse(), cfg.isEnabled()); mLinkGroup = cfg.mLinkGroup; mAttackTime = cfg.mAttackTime; mReleaseTime = cfg.mReleaseTime; mRatio = cfg.mRatio; mThreshold = cfg.mThreshold; mPostGain = cfg.mPostGain; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()); if (isInUse()) { sb.append(String.format(" LinkGroup: %d (group)\n", mLinkGroup)); sb.append(String.format(" AttackTime: %f (ms)\n", mAttackTime)); sb.append(String.format(" ReleaseTime: %f (ms)\n", mReleaseTime)); sb.append(String.format(" Ratio: 1:%f\n", mRatio)); sb.append(String.format(" Threshold: %f (dB)\n", mThreshold)); sb.append(String.format(" PostGain: %f (dB)\n", mPostGain)); } return sb.toString(); }
Gets the linkGroup index for this Limiter Stage. Only limiters that share the same linkGroup index will react together.
Returns:linkGroup index.
/** * Gets the linkGroup index for this Limiter Stage. Only limiters that share the same * linkGroup index will react together. * @return linkGroup index. */
public int getLinkGroup() { return mLinkGroup; }
Sets the linkGroup index for this limiter Stage.
Params:
  • linkGroup – desired linkGroup index
/** * Sets the linkGroup index for this limiter Stage. * @param linkGroup desired linkGroup index */
public void setLinkGroup(int linkGroup) { mLinkGroup = linkGroup; }
gets attack time for limiter compressor in milliseconds (ms)
Returns:attack time for limiter compressor in milliseconds (ms)
/** * gets attack time for limiter compressor in milliseconds (ms) * @return attack time for limiter compressor in milliseconds (ms) */
public float getAttackTime() { return mAttackTime; }
sets attack time for limiter compressor in milliseconds (ms)
Params:
  • attackTime – desired for limiter compressor in milliseconds (ms)
/** * sets attack time for limiter compressor in milliseconds (ms) * @param attackTime desired for limiter compressor in milliseconds (ms) */
public void setAttackTime(float attackTime) { mAttackTime = attackTime; }
gets release time for limiter compressor in milliseconds (ms)
Returns:release time for limiter compressor in milliseconds (ms)
/** * gets release time for limiter compressor in milliseconds (ms) * @return release time for limiter compressor in milliseconds (ms) */
public float getReleaseTime() { return mReleaseTime; }
sets release time for limiter compressor in milliseconds (ms)
Params:
  • releaseTime – desired for limiter compressor in milliseconds (ms)
/** * sets release time for limiter compressor in milliseconds (ms) * @param releaseTime desired for limiter compressor in milliseconds (ms) */
public void setReleaseTime(float releaseTime) { mReleaseTime = releaseTime; }
gets the limiter compressor ratio (N:1)
Returns:limiter compressor ratio (N:1)
/** * gets the limiter compressor ratio (N:1) * @return limiter compressor ratio (N:1) */
public float getRatio() { return mRatio; }
sets limiter compressor ratio (N:1)
Params:
  • ratio – desired for the limiter compressor (N:1)
/** * sets limiter compressor ratio (N:1) * @param ratio desired for the limiter compressor (N:1) */
public void setRatio(float ratio) { mRatio = ratio; }
gets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place.
Returns:limiter compressor threshold in decibels (dB)
/** * gets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale * (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place. * @return limiter compressor threshold in decibels (dB) */
public float getThreshold() { return mThreshold; }
sets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place.
Params:
  • threshold – desired for limiter compressor in decibels(dB)
/** * sets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale * (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place. * @param threshold desired for limiter compressor in decibels(dB) */
public void setThreshold(float threshold) { mThreshold = threshold; }
gets the gain applied to the signal AFTER limiting. Measured in decibels (dB) where 0 dB means no level change
Returns:postGain value in decibels (dB)
/** * gets the gain applied to the signal AFTER limiting. Measured in decibels (dB) where 0 * dB means no level change * @return postGain value in decibels (dB) */
public float getPostGain() { return mPostGain; }
sets the gain to be applied to the siganl AFTER the limiter. Measured in decibels (dB), where 0 dB means no level change.
Params:
  • postGain – desired value in decibels (dB)
/** * sets the gain to be applied to the siganl AFTER the limiter. Measured in decibels * (dB), where 0 dB means no level change. * @param postGain desired value in decibels (dB) */
public void setPostGain(float postGain) { mPostGain = postGain; } }
Class for Channel configuration parameters. It is composed of multiple stages, which can be used/enabled independently. Stages not used or disabled will be bypassed and the sound would be unaffected by them.
/** * Class for Channel configuration parameters. It is composed of multiple stages, which can be * used/enabled independently. Stages not used or disabled will be bypassed and the sound would * be unaffected by them. */
public final static class Channel { private float mInputGain; private Eq mPreEq; private Mbc mMbc; private Eq mPostEq; private Limiter mLimiter;
Class constructor for Channel configuration.
Params:
  • inputGain – value in decibels (dB) of level change applied to the audio before processing. A value of 0 dB means no change.
  • preEqInUse – true if PreEq stage will be used, false otherwise. This can't be changed later.
  • preEqBandCount – number of bands for PreEq stage. This can't be changed later.
  • mbcInUse – true if Mbc stage will be used, false otherwise. This can't be changed later.
  • mbcBandCount – number of bands for Mbc stage. This can't be changed later.
  • postEqInUse – true if PostEq stage will be used, false otherwise. This can't be changed later.
  • postEqBandCount – number of bands for PostEq stage. This can't be changed later.
  • limiterInUse – true if Limiter stage will be used, false otherwise. This can't be changed later.
/** * Class constructor for Channel configuration. * @param inputGain value in decibels (dB) of level change applied to the audio before * processing. A value of 0 dB means no change. * @param preEqInUse true if PreEq stage will be used, false otherwise. This can't be * changed later. * @param preEqBandCount number of bands for PreEq stage. This can't be changed later. * @param mbcInUse true if Mbc stage will be used, false otherwise. This can't be changed * later. * @param mbcBandCount number of bands for Mbc stage. This can't be changed later. * @param postEqInUse true if PostEq stage will be used, false otherwise. This can't be * changed later. * @param postEqBandCount number of bands for PostEq stage. This can't be changed later. * @param limiterInUse true if Limiter stage will be used, false otherwise. This can't be * changed later. */
public Channel (float inputGain, boolean preEqInUse, int preEqBandCount, boolean mbcInUse, int mbcBandCount, boolean postEqInUse, int postEqBandCount, boolean limiterInUse) { mInputGain = inputGain; mPreEq = new Eq(preEqInUse, PREEQ_DEFAULT_ENABLED, preEqBandCount); mMbc = new Mbc(mbcInUse, MBC_DEFAULT_ENABLED, mbcBandCount); mPostEq = new Eq(postEqInUse, POSTEQ_DEFAULT_ENABLED, postEqBandCount); mLimiter = new Limiter(limiterInUse, LIMITER_DEFAULT_ENABLED, LIMITER_DEFAULT_LINK_GROUP, LIMITER_DEFAULT_ATTACK_TIME, LIMITER_DEFAULT_RELEASE_TIME, LIMITER_DEFAULT_RATIO, LIMITER_DEFAULT_THRESHOLD, LIMITER_DEFAULT_POST_GAIN); }
Class constructor for Channel configuration
Params:
  • cfg – copy constructor
/** * Class constructor for Channel configuration * @param cfg copy constructor */
public Channel(Channel cfg) { mInputGain = cfg.mInputGain; mPreEq = new Eq(cfg.mPreEq); mMbc = new Mbc(cfg.mMbc); mPostEq = new Eq(cfg.mPostEq); mLimiter = new Limiter(cfg.mLimiter); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format(" InputGain: %f\n", mInputGain)); sb.append("-->PreEq\n"); sb.append(mPreEq.toString()); sb.append("-->MBC\n"); sb.append(mMbc.toString()); sb.append("-->PostEq\n"); sb.append(mPostEq.toString()); sb.append("-->Limiter\n"); sb.append(mLimiter.toString()); return sb.toString(); }
Gets inputGain value in decibels (dB). 0 dB means no change;
Returns:gain value in decibels (dB)
/** * Gets inputGain value in decibels (dB). 0 dB means no change; * @return gain value in decibels (dB) */
public float getInputGain() { return mInputGain; }
Sets inputGain value in decibels (dB). 0 dB means no change;
Params:
  • inputGain – desired gain value in decibels (dB)
/** * Sets inputGain value in decibels (dB). 0 dB means no change; * @param inputGain desired gain value in decibels (dB) */
public void setInputGain(float inputGain) { mInputGain = inputGain; }
Gets PreEq configuration stage
Returns:PreEq configuration stage
/** * Gets PreEq configuration stage * @return PreEq configuration stage */
public Eq getPreEq() { return mPreEq; }
Sets PreEq configuration stage. New PreEq stage must have the same number of bands than original PreEq stage.
Params:
  • preEq – configuration
/** * Sets PreEq configuration stage. New PreEq stage must have the same number of bands than * original PreEq stage. * @param preEq configuration */
public void setPreEq(Eq preEq) { if (preEq.getBandCount() != mPreEq.getBandCount()) { throw new IllegalArgumentException("PreEqBandCount changed from " + mPreEq.getBandCount() + " to " + preEq.getBandCount()); } mPreEq = new Eq(preEq); }
Gets EqBand for PreEq stage for given band index.
Params:
  • band – index of band of interest from PreEq stage
Returns:EqBand configuration
/** * Gets EqBand for PreEq stage for given band index. * @param band index of band of interest from PreEq stage * @return EqBand configuration */
public EqBand getPreEqBand(int band) { return mPreEq.getBand(band); }
Sets EqBand for PreEq stage for given band index
Params:
  • band – index of band of interest from PreEq stage
  • preEqBand – configuration to be set.
/** * Sets EqBand for PreEq stage for given band index * @param band index of band of interest from PreEq stage * @param preEqBand configuration to be set. */
public void setPreEqBand(int band, EqBand preEqBand) { mPreEq.setBand(band, preEqBand); }
Gets Mbc configuration stage
Returns:Mbc configuration stage
/** * Gets Mbc configuration stage * @return Mbc configuration stage */
public Mbc getMbc() { return mMbc; }
Sets Mbc configuration stage. New Mbc stage must have the same number of bands than original Mbc stage.
Params:
  • mbc –
/** * Sets Mbc configuration stage. New Mbc stage must have the same number of bands than * original Mbc stage. * @param mbc */
public void setMbc(Mbc mbc) { if (mbc.getBandCount() != mMbc.getBandCount()) { throw new IllegalArgumentException("MbcBandCount changed from " + mMbc.getBandCount() + " to " + mbc.getBandCount()); } mMbc = new Mbc(mbc); }
Gets MbcBand configuration for Mbc stage, for given band index.
Params:
  • band – index of band of interest from Mbc stage
Returns:MbcBand configuration
/** * Gets MbcBand configuration for Mbc stage, for given band index. * @param band index of band of interest from Mbc stage * @return MbcBand configuration */
public MbcBand getMbcBand(int band) { return mMbc.getBand(band); }
Sets MbcBand for Mbc stage for given band index
Params:
  • band – index of band of interest from Mbc Stage
  • mbcBand – configuration to be set
/** * Sets MbcBand for Mbc stage for given band index * @param band index of band of interest from Mbc Stage * @param mbcBand configuration to be set */
public void setMbcBand(int band, MbcBand mbcBand) { mMbc.setBand(band, mbcBand); }
Gets PostEq configuration stage
Returns:PostEq configuration stage
/** * Gets PostEq configuration stage * @return PostEq configuration stage */
public Eq getPostEq() { return mPostEq; }
Sets PostEq configuration stage. New PostEq stage must have the same number of bands than original PostEq stage.
Params:
  • postEq – configuration
/** * Sets PostEq configuration stage. New PostEq stage must have the same number of bands than * original PostEq stage. * @param postEq configuration */
public void setPostEq(Eq postEq) { if (postEq.getBandCount() != mPostEq.getBandCount()) { throw new IllegalArgumentException("PostEqBandCount changed from " + mPostEq.getBandCount() + " to " + postEq.getBandCount()); } mPostEq = new Eq(postEq); }
Gets EqBand for PostEq stage for given band index.
Params:
  • band – index of band of interest from PostEq stage
Returns:EqBand configuration
/** * Gets EqBand for PostEq stage for given band index. * @param band index of band of interest from PostEq stage * @return EqBand configuration */
public EqBand getPostEqBand(int band) { return mPostEq.getBand(band); }
Sets EqBand for PostEq stage for given band index
Params:
  • band – index of band of interest from PostEq stage
  • postEqBand – configuration to be set.
/** * Sets EqBand for PostEq stage for given band index * @param band index of band of interest from PostEq stage * @param postEqBand configuration to be set. */
public void setPostEqBand(int band, EqBand postEqBand) { mPostEq.setBand(band, postEqBand); }
Gets Limiter configuration stage
Returns:Limiter configuration stage
/** * Gets Limiter configuration stage * @return Limiter configuration stage */
public Limiter getLimiter() { return mLimiter; }
Sets Limiter configuration stage.
Params:
  • limiter – configuration stage.
/** * Sets Limiter configuration stage. * @param limiter configuration stage. */
public void setLimiter(Limiter limiter) { mLimiter = new Limiter(limiter); } }
Class for Config object, used by DynamicsProcessing to configure and update the audio effect. use Builder to instantiate objects of this type.
/** * Class for Config object, used by DynamicsProcessing to configure and update the audio effect. * use Builder to instantiate objects of this type. */
public final static class Config { private final int mVariant; private final int mChannelCount; private final boolean mPreEqInUse; private final int mPreEqBandCount; private final boolean mMbcInUse; private final int mMbcBandCount; private final boolean mPostEqInUse; private final int mPostEqBandCount; private final boolean mLimiterInUse; private final float mPreferredFrameDuration; private final Channel[] mChannel;
Params:
  • variant – index of variant used for effect engine. See DynamicsProcessing.VARIANT_FAVOR_FREQUENCY_RESOLUTION and DynamicsProcessing.VARIANT_FAVOR_TIME_RESOLUTION.
  • frameDurationMs – preferred frame duration in milliseconds (ms).
  • channelCount – Number of channels to be configured.
  • preEqInUse – true if PreEq stage will be used, false otherwise.
  • preEqBandCount – number of bands for PreEq stage.
  • mbcInUse – true if Mbc stage will be used, false otherwise.
  • mbcBandCount – number of bands for Mbc stage.
  • postEqInUse – true if PostEq stage will be used, false otherwise.
  • postEqBandCount – number of bands for PostEq stage.
  • limiterInUse – true if Limiter stage will be used, false otherwise.
  • channel – array of Channel objects to be used for this configuration.
@hide Class constructor for config. None of these parameters can be changed later.
/** * @hide * Class constructor for config. None of these parameters can be changed later. * @param variant index of variant used for effect engine. See * {@link #VARIANT_FAVOR_FREQUENCY_RESOLUTION} and {@link #VARIANT_FAVOR_TIME_RESOLUTION}. * @param frameDurationMs preferred frame duration in milliseconds (ms). * @param channelCount Number of channels to be configured. * @param preEqInUse true if PreEq stage will be used, false otherwise. * @param preEqBandCount number of bands for PreEq stage. * @param mbcInUse true if Mbc stage will be used, false otherwise. * @param mbcBandCount number of bands for Mbc stage. * @param postEqInUse true if PostEq stage will be used, false otherwise. * @param postEqBandCount number of bands for PostEq stage. * @param limiterInUse true if Limiter stage will be used, false otherwise. * @param channel array of Channel objects to be used for this configuration. */
public Config(int variant, float frameDurationMs, int channelCount, boolean preEqInUse, int preEqBandCount, boolean mbcInUse, int mbcBandCount, boolean postEqInUse, int postEqBandCount, boolean limiterInUse, Channel[] channel) { mVariant = variant; mPreferredFrameDuration = frameDurationMs; mChannelCount = channelCount; mPreEqInUse = preEqInUse; mPreEqBandCount = preEqBandCount; mMbcInUse = mbcInUse; mMbcBandCount = mbcBandCount; mPostEqInUse = postEqInUse; mPostEqBandCount = postEqBandCount; mLimiterInUse = limiterInUse; mChannel = new Channel[mChannelCount]; //check if channelconfig is null or has less channels than channel count. //options: fill the missing with default options. // or fail? for (int ch = 0; ch < mChannelCount; ch++) { if (ch < channel.length) { mChannel[ch] = new Channel(channel[ch]); //copy create } else { //create a new one from scratch? //fail? } } } //a version that will scale to necessary number of channels
Params:
  • channelCount – limit configuration to this number of channels. if channelCount is greater than number of channels in cfg, the constructor will duplicate the last channel found as many times as necessary to create a Config with channelCount number of channels. If channelCount is less than channels in cfg, the extra channels in cfg will be ignored.
  • cfg – copy constructor paremter.
@hide Class constructor for Configuration.
/** * @hide * Class constructor for Configuration. * @param channelCount limit configuration to this number of channels. if channelCount is * greater than number of channels in cfg, the constructor will duplicate the last channel * found as many times as necessary to create a Config with channelCount number of channels. * If channelCount is less than channels in cfg, the extra channels in cfg will be ignored. * @param cfg copy constructor paremter. */
public Config(int channelCount, Config cfg) { mVariant = cfg.mVariant; mPreferredFrameDuration = cfg.mPreferredFrameDuration; mChannelCount = cfg.mChannelCount; mPreEqInUse = cfg.mPreEqInUse; mPreEqBandCount = cfg.mPreEqBandCount; mMbcInUse = cfg.mMbcInUse; mMbcBandCount = cfg.mMbcBandCount; mPostEqInUse = cfg.mPostEqInUse; mPostEqBandCount = cfg.mPostEqBandCount; mLimiterInUse = cfg.mLimiterInUse; if (mChannelCount != cfg.mChannel.length) { throw new IllegalArgumentException("configuration channel counts differ " + mChannelCount + " !=" + cfg.mChannel.length); } if (channelCount < 1) { throw new IllegalArgumentException("channel resizing less than 1 not allowed"); } mChannel = new Channel[channelCount]; for (int ch = 0; ch < channelCount; ch++) { if (ch < mChannelCount) { mChannel[ch] = new Channel(cfg.mChannel[ch]); } else { //duplicate last mChannel[ch] = new Channel(cfg.mChannel[mChannelCount-1]); } } }
Params:
  • cfg – Configuration object copy constructor
@hide Class constructor for Config
/** * @hide * Class constructor for Config * @param cfg Configuration object copy constructor */
public Config(@NonNull Config cfg) { this(cfg.mChannelCount, cfg); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format("Variant: %d\n", mVariant)); sb.append(String.format("PreferredFrameDuration: %f\n", mPreferredFrameDuration)); sb.append(String.format("ChannelCount: %d\n", mChannelCount)); sb.append(String.format("PreEq inUse: %b, bandCount:%d\n",mPreEqInUse, mPreEqBandCount)); sb.append(String.format("Mbc inUse: %b, bandCount: %d\n",mMbcInUse, mMbcBandCount)); sb.append(String.format("PostEq inUse: %b, bandCount: %d\n", mPostEqInUse, mPostEqBandCount)); sb.append(String.format("Limiter inUse: %b\n", mLimiterInUse)); for (int ch = 0; ch < mChannel.length; ch++) { sb.append(String.format("==Channel %d\n", ch)); sb.append(mChannel[ch].toString()); } return sb.toString(); } private void checkChannel(int channelIndex) { if (channelIndex < 0 || channelIndex >= mChannel.length) { throw new IllegalArgumentException("ChannelIndex out of bounds"); } } //getters and setters
Returns:variant of effect engine
/** * Gets variant for effect engine See {@link #VARIANT_FAVOR_FREQUENCY_RESOLUTION} and * {@link #VARIANT_FAVOR_TIME_RESOLUTION}. * @return variant of effect engine */
public int getVariant() { return mVariant; }
Gets preferred frame duration in milliseconds (ms).
Returns:preferred frame duration in milliseconds (ms)
/** * Gets preferred frame duration in milliseconds (ms). * @return preferred frame duration in milliseconds (ms) */
public float getPreferredFrameDuration() { return mPreferredFrameDuration; }
Gets if preEq stage is in use
Returns:true if preEq stage is in use;
/** * Gets if preEq stage is in use * @return true if preEq stage is in use; */
public boolean isPreEqInUse() { return mPreEqInUse; }
Gets number of bands configured for the PreEq stage.
Returns:number of bands configured for the PreEq stage.
/** * Gets number of bands configured for the PreEq stage. * @return number of bands configured for the PreEq stage. */
public int getPreEqBandCount() { return mPreEqBandCount; }
Gets if Mbc stage is in use
Returns:true if Mbc stage is in use;
/** * Gets if Mbc stage is in use * @return true if Mbc stage is in use; */
public boolean isMbcInUse() { return mMbcInUse; }
Gets number of bands configured for the Mbc stage.
Returns:number of bands configured for the Mbc stage.
/** * Gets number of bands configured for the Mbc stage. * @return number of bands configured for the Mbc stage. */
public int getMbcBandCount() { return mMbcBandCount; }
Gets if PostEq stage is in use
Returns:true if PostEq stage is in use;
/** * Gets if PostEq stage is in use * @return true if PostEq stage is in use; */
public boolean isPostEqInUse() { return mPostEqInUse; }
Gets number of bands configured for the PostEq stage.
Returns:number of bands configured for the PostEq stage.
/** * Gets number of bands configured for the PostEq stage. * @return number of bands configured for the PostEq stage. */
public int getPostEqBandCount() { return mPostEqBandCount; }
Gets if Limiter stage is in use
Returns:true if Limiter stage is in use;
/** * Gets if Limiter stage is in use * @return true if Limiter stage is in use; */
public boolean isLimiterInUse() { return mLimiterInUse; } //channel
Gets the Channel configuration object by using the channel index
Params:
  • channelIndex – of desired Channel object
Returns:Channel configuration object
/** * Gets the Channel configuration object by using the channel index * @param channelIndex of desired Channel object * @return Channel configuration object */
public Channel getChannelByChannelIndex(int channelIndex) { checkChannel(channelIndex); return mChannel[channelIndex]; }
Sets the chosen Channel object in the selected channelIndex Note that all the stages should have the same number of bands than the existing Channel object.
Params:
  • channelIndex – index of channel to be replaced
  • channel – Channel configuration object to be set
/** * Sets the chosen Channel object in the selected channelIndex * Note that all the stages should have the same number of bands than the existing Channel * object. * @param channelIndex index of channel to be replaced * @param channel Channel configuration object to be set */
public void setChannelTo(int channelIndex, Channel channel) { checkChannel(channelIndex); //check all things are compatible if (mMbcBandCount != channel.getMbc().getBandCount()) { throw new IllegalArgumentException("MbcBandCount changed from " + mMbcBandCount + " to " + channel.getPreEq().getBandCount()); } if (mPreEqBandCount != channel.getPreEq().getBandCount()) { throw new IllegalArgumentException("PreEqBandCount changed from " + mPreEqBandCount + " to " + channel.getPreEq().getBandCount()); } if (mPostEqBandCount != channel.getPostEq().getBandCount()) { throw new IllegalArgumentException("PostEqBandCount changed from " + mPostEqBandCount + " to " + channel.getPostEq().getBandCount()); } mChannel[channelIndex] = new Channel(channel); }
Sets ALL channels to the chosen Channel object. Note that all the stages should have the same number of bands than the existing ones.
Params:
  • channel – Channel configuration object to be set.
/** * Sets ALL channels to the chosen Channel object. Note that all the stages should have the * same number of bands than the existing ones. * @param channel Channel configuration object to be set. */
public void setAllChannelsTo(Channel channel) { for (int ch = 0; ch < mChannel.length; ch++) { setChannelTo(ch, channel); } } //===channel params
Gets inputGain value in decibels (dB) for channel indicated by channelIndex
Params:
  • channelIndex – index of channel of interest
Returns:inputGain value in decibels (dB). 0 dB means no change.
/** * Gets inputGain value in decibels (dB) for channel indicated by channelIndex * @param channelIndex index of channel of interest * @return inputGain value in decibels (dB). 0 dB means no change. */
public float getInputGainByChannelIndex(int channelIndex) { checkChannel(channelIndex); return mChannel[channelIndex].getInputGain(); }
Sets the inputGain value in decibels (dB) for the channel indicated by channelIndex.
Params:
  • channelIndex – index of channel of interest
  • inputGain – desired value in decibels (dB).
/** * Sets the inputGain value in decibels (dB) for the channel indicated by channelIndex. * @param channelIndex index of channel of interest * @param inputGain desired value in decibels (dB). */
public void setInputGainByChannelIndex(int channelIndex, float inputGain) { checkChannel(channelIndex); mChannel[channelIndex].setInputGain(inputGain); }
Sets the inputGain value in decibels (dB) for ALL channels
Params:
  • inputGain – desired value in decibels (dB)
/** * Sets the inputGain value in decibels (dB) for ALL channels * @param inputGain desired value in decibels (dB) */
public void setInputGainAllChannelsTo(float inputGain) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setInputGain(inputGain); } } //=== PreEQ
Gets PreEq stage from channel indicated by channelIndex
Params:
  • channelIndex – index of channel of interest
Returns:PreEq stage configuration object
/** * Gets PreEq stage from channel indicated by channelIndex * @param channelIndex index of channel of interest * @return PreEq stage configuration object */
public Eq getPreEqByChannelIndex(int channelIndex) { checkChannel(channelIndex); return mChannel[channelIndex].getPreEq(); }
Sets the PreEq stage configuration for the channel indicated by channelIndex. Note that new preEq stage must have the same number of bands than original preEq stage
Params:
  • channelIndex – index of channel to be set
  • preEq – desired PreEq configuration to be set
/** * Sets the PreEq stage configuration for the channel indicated by channelIndex. Note that * new preEq stage must have the same number of bands than original preEq stage * @param channelIndex index of channel to be set * @param preEq desired PreEq configuration to be set */
public void setPreEqByChannelIndex(int channelIndex, Eq preEq) { checkChannel(channelIndex); mChannel[channelIndex].setPreEq(preEq); }
Sets the PreEq stage configuration for ALL channels. Note that new preEq stage must have the same number of bands than original preEq stages.
Params:
  • preEq – desired PreEq configuration to be set
/** * Sets the PreEq stage configuration for ALL channels. Note that new preEq stage must have * the same number of bands than original preEq stages. * @param preEq desired PreEq configuration to be set */
public void setPreEqAllChannelsTo(Eq preEq) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setPreEq(preEq); } } public EqBand getPreEqBandByChannelIndex(int channelIndex, int band) { checkChannel(channelIndex); return mChannel[channelIndex].getPreEqBand(band); } public void setPreEqBandByChannelIndex(int channelIndex, int band, EqBand preEqBand) { checkChannel(channelIndex); mChannel[channelIndex].setPreEqBand(band, preEqBand); } public void setPreEqBandAllChannelsTo(int band, EqBand preEqBand) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setPreEqBand(band, preEqBand); } } //=== MBC public Mbc getMbcByChannelIndex(int channelIndex) { checkChannel(channelIndex); return mChannel[channelIndex].getMbc(); } public void setMbcByChannelIndex(int channelIndex, Mbc mbc) { checkChannel(channelIndex); mChannel[channelIndex].setMbc(mbc); } public void setMbcAllChannelsTo(Mbc mbc) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setMbc(mbc); } } public MbcBand getMbcBandByChannelIndex(int channelIndex, int band) { checkChannel(channelIndex); return mChannel[channelIndex].getMbcBand(band); } public void setMbcBandByChannelIndex(int channelIndex, int band, MbcBand mbcBand) { checkChannel(channelIndex); mChannel[channelIndex].setMbcBand(band, mbcBand); } public void setMbcBandAllChannelsTo(int band, MbcBand mbcBand) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setMbcBand(band, mbcBand); } } //=== PostEQ public Eq getPostEqByChannelIndex(int channelIndex) { checkChannel(channelIndex); return mChannel[channelIndex].getPostEq(); } public void setPostEqByChannelIndex(int channelIndex, Eq postEq) { checkChannel(channelIndex); mChannel[channelIndex].setPostEq(postEq); } public void setPostEqAllChannelsTo(Eq postEq) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setPostEq(postEq); } } public EqBand getPostEqBandByChannelIndex(int channelIndex, int band) { checkChannel(channelIndex); return mChannel[channelIndex].getPostEqBand(band); } public void setPostEqBandByChannelIndex(int channelIndex, int band, EqBand postEqBand) { checkChannel(channelIndex); mChannel[channelIndex].setPostEqBand(band, postEqBand); } public void setPostEqBandAllChannelsTo(int band, EqBand postEqBand) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setPostEqBand(band, postEqBand); } } //Limiter public Limiter getLimiterByChannelIndex(int channelIndex) { checkChannel(channelIndex); return mChannel[channelIndex].getLimiter(); } public void setLimiterByChannelIndex(int channelIndex, Limiter limiter) { checkChannel(channelIndex); mChannel[channelIndex].setLimiter(limiter); } public void setLimiterAllChannelsTo(Limiter limiter) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setLimiter(limiter); } } public final static class Builder { private int mVariant; private int mChannelCount; private boolean mPreEqInUse; private int mPreEqBandCount; private boolean mMbcInUse; private int mMbcBandCount; private boolean mPostEqInUse; private int mPostEqBandCount; private boolean mLimiterInUse; private float mPreferredFrameDuration = CONFIG_PREFERRED_FRAME_DURATION_MS; private Channel[] mChannel; public Builder(int variant, int channelCount, boolean preEqInUse, int preEqBandCount, boolean mbcInUse, int mbcBandCount, boolean postEqInUse, int postEqBandCount, boolean limiterInUse) { mVariant = variant; mChannelCount = channelCount; mPreEqInUse = preEqInUse; mPreEqBandCount = preEqBandCount; mMbcInUse = mbcInUse; mMbcBandCount = mbcBandCount; mPostEqInUse = postEqInUse; mPostEqBandCount = postEqBandCount; mLimiterInUse = limiterInUse; mChannel = new Channel[mChannelCount]; for (int ch = 0; ch < mChannelCount; ch++) { this.mChannel[ch] = new Channel(CHANNEL_DEFAULT_INPUT_GAIN, this.mPreEqInUse, this.mPreEqBandCount, this.mMbcInUse, this.mMbcBandCount, this.mPostEqInUse, this.mPostEqBandCount, this.mLimiterInUse); } } private void checkChannel(int channelIndex) { if (channelIndex < 0 || channelIndex >= mChannel.length) { throw new IllegalArgumentException("ChannelIndex out of bounds"); } } public Builder setPreferredFrameDuration(float frameDuration) { if (frameDuration < 0) { throw new IllegalArgumentException("Expected positive frameDuration"); } mPreferredFrameDuration = frameDuration; return this; } public Builder setInputGainByChannelIndex(int channelIndex, float inputGain) { checkChannel(channelIndex); mChannel[channelIndex].setInputGain(inputGain); return this; } public Builder setInputGainAllChannelsTo(float inputGain) { for (int ch = 0; ch < mChannel.length; ch++) { mChannel[ch].setInputGain(inputGain); } return this; } public Builder setChannelTo(int channelIndex, Channel channel) { checkChannel(channelIndex); //check all things are compatible if (mMbcBandCount != channel.getMbc().getBandCount()) { throw new IllegalArgumentException("MbcBandCount changed from " + mMbcBandCount + " to " + channel.getPreEq().getBandCount()); } if (mPreEqBandCount != channel.getPreEq().getBandCount()) { throw new IllegalArgumentException("PreEqBandCount changed from " + mPreEqBandCount + " to " + channel.getPreEq().getBandCount()); } if (mPostEqBandCount != channel.getPostEq().getBandCount()) { throw new IllegalArgumentException("PostEqBandCount changed from " + mPostEqBandCount + " to " + channel.getPostEq().getBandCount()); } mChannel[channelIndex] = new Channel(channel); return this; } public Builder setAllChannelsTo(Channel channel) { for (int ch = 0; ch < mChannel.length; ch++) { setChannelTo(ch, channel); } return this; } public Builder setPreEqByChannelIndex(int channelIndex, Eq preEq) { checkChannel(channelIndex); mChannel[channelIndex].setPreEq(preEq); return this; } public Builder setPreEqAllChannelsTo(Eq preEq) { for (int ch = 0; ch < mChannel.length; ch++) { setPreEqByChannelIndex(ch, preEq); } return this; } public Builder setMbcByChannelIndex(int channelIndex, Mbc mbc) { checkChannel(channelIndex); mChannel[channelIndex].setMbc(mbc); return this; } public Builder setMbcAllChannelsTo(Mbc mbc) { for (int ch = 0; ch < mChannel.length; ch++) { setMbcByChannelIndex(ch, mbc); } return this; } public Builder setPostEqByChannelIndex(int channelIndex, Eq postEq) { checkChannel(channelIndex); mChannel[channelIndex].setPostEq(postEq); return this; } public Builder setPostEqAllChannelsTo(Eq postEq) { for (int ch = 0; ch < mChannel.length; ch++) { setPostEqByChannelIndex(ch, postEq); } return this; } public Builder setLimiterByChannelIndex(int channelIndex, Limiter limiter) { checkChannel(channelIndex); mChannel[channelIndex].setLimiter(limiter); return this; } public Builder setLimiterAllChannelsTo(Limiter limiter) { for (int ch = 0; ch < mChannel.length; ch++) { setLimiterByChannelIndex(ch, limiter); } return this; } public Config build() { return new Config(mVariant, mPreferredFrameDuration, mChannelCount, mPreEqInUse, mPreEqBandCount, mMbcInUse, mMbcBandCount, mPostEqInUse, mPostEqBandCount, mLimiterInUse, mChannel); } } } //=== CHANNEL public Channel getChannelByChannelIndex(int channelIndex) { return queryEngineByChannelIndex(channelIndex); } public void setChannelTo(int channelIndex, Channel channel) { updateEngineChannelByChannelIndex(channelIndex, channel); } public void setAllChannelsTo(Channel channel) { for (int ch = 0; ch < mChannelCount; ch++) { setChannelTo(ch, channel); } } //=== channel params public float getInputGainByChannelIndex(int channelIndex) { return getTwoFloat(PARAM_INPUT_GAIN, channelIndex); } public void setInputGainbyChannel(int channelIndex, float inputGain) { setTwoFloat(PARAM_INPUT_GAIN, channelIndex, inputGain); } public void setInputGainAllChannelsTo(float inputGain) { for (int ch = 0; ch < mChannelCount; ch++) { setInputGainbyChannel(ch, inputGain); } } //=== PreEQ public Eq getPreEqByChannelIndex(int channelIndex) { return queryEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex); } public void setPreEqByChannelIndex(int channelIndex, Eq preEq) { updateEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex, preEq); } public void setPreEqAllChannelsTo(Eq preEq) { for (int ch = 0; ch < mChannelCount; ch++) { setPreEqByChannelIndex(ch, preEq); } } public EqBand getPreEqBandByChannelIndex(int channelIndex, int band) { return queryEngineEqBandByChannelIndex(PARAM_PRE_EQ_BAND, channelIndex, band); } public void setPreEqBandByChannelIndex(int channelIndex, int band, EqBand preEqBand) { updateEngineEqBandByChannelIndex(PARAM_PRE_EQ_BAND, channelIndex, band, preEqBand); } public void setPreEqBandAllChannelsTo(int band, EqBand preEqBand) { for (int ch = 0; ch < mChannelCount; ch++) { setPreEqBandByChannelIndex(ch, band, preEqBand); } } //=== MBC public Mbc getMbcByChannelIndex(int channelIndex) { return queryEngineMbcByChannelIndex(channelIndex); } public void setMbcByChannelIndex(int channelIndex, Mbc mbc) { updateEngineMbcByChannelIndex(channelIndex, mbc); } public void setMbcAllChannelsTo(Mbc mbc) { for (int ch = 0; ch < mChannelCount; ch++) { setMbcByChannelIndex(ch, mbc); } } public MbcBand getMbcBandByChannelIndex(int channelIndex, int band) { return queryEngineMbcBandByChannelIndex(channelIndex, band); } public void setMbcBandByChannelIndex(int channelIndex, int band, MbcBand mbcBand) { updateEngineMbcBandByChannelIndex(channelIndex, band, mbcBand); } public void setMbcBandAllChannelsTo(int band, MbcBand mbcBand) { for (int ch = 0; ch < mChannelCount; ch++) { setMbcBandByChannelIndex(ch, band, mbcBand); } } //== PostEq public Eq getPostEqByChannelIndex(int channelIndex) { return queryEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex); } public void setPostEqByChannelIndex(int channelIndex, Eq postEq) { updateEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex, postEq); } public void setPostEqAllChannelsTo(Eq postEq) { for (int ch = 0; ch < mChannelCount; ch++) { setPostEqByChannelIndex(ch, postEq); } } public EqBand getPostEqBandByChannelIndex(int channelIndex, int band) { return queryEngineEqBandByChannelIndex(PARAM_POST_EQ_BAND, channelIndex, band); } public void setPostEqBandByChannelIndex(int channelIndex, int band, EqBand postEqBand) { updateEngineEqBandByChannelIndex(PARAM_POST_EQ_BAND, channelIndex, band, postEqBand); } public void setPostEqBandAllChannelsTo(int band, EqBand postEqBand) { for (int ch = 0; ch < mChannelCount; ch++) { setPostEqBandByChannelIndex(ch, band, postEqBand); } } //==== Limiter public Limiter getLimiterByChannelIndex(int channelIndex) { return queryEngineLimiterByChannelIndex(channelIndex); } public void setLimiterByChannelIndex(int channelIndex, Limiter limiter) { updateEngineLimiterByChannelIndex(channelIndex, limiter); } public void setLimiterAllChannelsTo(Limiter limiter) { for (int ch = 0; ch < mChannelCount; ch++) { setLimiterByChannelIndex(ch, limiter); } }
Gets the number of channels in the effect engine
Returns:number of channels currently in use by the effect engine
/** * Gets the number of channels in the effect engine * @return number of channels currently in use by the effect engine */
public int getChannelCount() { return getOneInt(PARAM_GET_CHANNEL_COUNT); } //=== Engine calls private void setEngineArchitecture(int variant, float preferredFrameDuration, boolean preEqInUse, int preEqBandCount, boolean mbcInUse, int mbcBandCount, boolean postEqInUse, int postEqBandCount, boolean limiterInUse) { Number[] params = { PARAM_ENGINE_ARCHITECTURE }; Number[] values = { variant /* variant */, preferredFrameDuration, (preEqInUse ? 1 : 0), preEqBandCount, (mbcInUse ? 1 : 0), mbcBandCount, (postEqInUse ? 1 : 0), postEqBandCount, (limiterInUse ? 1 : 0)}; setNumberArray(params, values); } private void updateEngineEqBandByChannelIndex(int param, int channelIndex, int bandIndex, @NonNull EqBand eqBand) { Number[] params = {param, channelIndex, bandIndex}; Number[] values = {(eqBand.isEnabled() ? 1 : 0), eqBand.getCutoffFrequency(), eqBand.getGain()}; setNumberArray(params, values); } private Eq queryEngineEqByChannelIndex(int param, int channelIndex) { Number[] params = {param == PARAM_PRE_EQ ? PARAM_PRE_EQ : PARAM_POST_EQ, channelIndex}; Number[] values = {0 /*0 in use */, 0 /*1 enabled*/, 0 /*2 band count */}; byte[] paramBytes = numberArrayToByteArray(params); byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size. getParameter(paramBytes, valueBytes); byteArrayToNumberArray(valueBytes, values); int bandCount = values[2].intValue(); Eq eq = new Eq(values[0].intValue() > 0 /* in use */, values[1].intValue() > 0 /* enabled */, bandCount /*band count*/); for (int b = 0; b < bandCount; b++) { EqBand eqBand = queryEngineEqBandByChannelIndex(param == PARAM_PRE_EQ ? PARAM_PRE_EQ_BAND : PARAM_POST_EQ_BAND, channelIndex, b); eq.setBand(b, eqBand); } return eq; } private EqBand queryEngineEqBandByChannelIndex(int param, int channelIndex, int bandIndex) { Number[] params = {param, channelIndex, bandIndex}; Number[] values = {0 /*0 enabled*/, 0.0f /*1 cutoffFrequency */, 0.0f /*2 gain */}; byte[] paramBytes = numberArrayToByteArray(params); byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size. getParameter(paramBytes, valueBytes); byteArrayToNumberArray(valueBytes, values); return new EqBand(values[0].intValue() > 0 /* enabled */, values[1].floatValue() /* cutoffFrequency */, values[2].floatValue() /* gain*/); } private void updateEngineEqByChannelIndex(int param, int channelIndex, @NonNull Eq eq) { int bandCount = eq.getBandCount(); Number[] params = {param, channelIndex}; Number[] values = { (eq.isInUse() ? 1 : 0), (eq.isEnabled() ? 1 : 0), bandCount}; setNumberArray(params, values); for (int b = 0; b < bandCount; b++) { EqBand eqBand = eq.getBand(b); updateEngineEqBandByChannelIndex(param == PARAM_PRE_EQ ? PARAM_PRE_EQ_BAND : PARAM_POST_EQ_BAND, channelIndex, b, eqBand); } } private Mbc queryEngineMbcByChannelIndex(int channelIndex) { Number[] params = {PARAM_MBC, channelIndex}; Number[] values = {0 /*0 in use */, 0 /*1 enabled*/, 0 /*2 band count */}; byte[] paramBytes = numberArrayToByteArray(params); byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size. getParameter(paramBytes, valueBytes); byteArrayToNumberArray(valueBytes, values); int bandCount = values[2].intValue(); Mbc mbc = new Mbc(values[0].intValue() > 0 /* in use */, values[1].intValue() > 0 /* enabled */, bandCount /*band count*/); for (int b = 0; b < bandCount; b++) { MbcBand mbcBand = queryEngineMbcBandByChannelIndex(channelIndex, b); mbc.setBand(b, mbcBand); } return mbc; } private MbcBand queryEngineMbcBandByChannelIndex(int channelIndex, int bandIndex) { Number[] params = {PARAM_MBC_BAND, channelIndex, bandIndex}; Number[] values = {0 /*0 enabled */, 0.0f /*1 cutoffFrequency */, 0.0f /*2 AttackTime */, 0.0f /*3 ReleaseTime */, 0.0f /*4 Ratio */, 0.0f /*5 Threshold */, 0.0f /*6 KneeWidth */, 0.0f /*7 NoiseGateThreshold */, 0.0f /*8 ExpanderRatio */, 0.0f /*9 PreGain */, 0.0f /*10 PostGain*/}; byte[] paramBytes = numberArrayToByteArray(params); byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size. getParameter(paramBytes, valueBytes); byteArrayToNumberArray(valueBytes, values); return new MbcBand(values[0].intValue() > 0 /* enabled */, values[1].floatValue() /* cutoffFrequency */, values[2].floatValue()/*2 AttackTime */, values[3].floatValue()/*3 ReleaseTime */, values[4].floatValue()/*4 Ratio */, values[5].floatValue()/*5 Threshold */, values[6].floatValue()/*6 KneeWidth */, values[7].floatValue()/*7 NoiseGateThreshold */, values[8].floatValue()/*8 ExpanderRatio */, values[9].floatValue()/*9 PreGain */, values[10].floatValue()/*10 PostGain*/); } private void updateEngineMbcBandByChannelIndex(int channelIndex, int bandIndex, @NonNull MbcBand mbcBand) { Number[] params = { PARAM_MBC_BAND, channelIndex, bandIndex}; Number[] values = {(mbcBand.isEnabled() ? 1 : 0), mbcBand.getCutoffFrequency(), mbcBand.getAttackTime(), mbcBand.getReleaseTime(), mbcBand.getRatio(), mbcBand.getThreshold(), mbcBand.getKneeWidth(), mbcBand.getNoiseGateThreshold(), mbcBand.getExpanderRatio(), mbcBand.getPreGain(), mbcBand.getPostGain()}; setNumberArray(params, values); } private void updateEngineMbcByChannelIndex(int channelIndex, @NonNull Mbc mbc) { int bandCount = mbc.getBandCount(); Number[] params = { PARAM_MBC, channelIndex}; Number[] values = {(mbc.isInUse() ? 1 : 0), (mbc.isEnabled() ? 1 : 0), bandCount}; setNumberArray(params, values); for (int b = 0; b < bandCount; b++) { MbcBand mbcBand = mbc.getBand(b); updateEngineMbcBandByChannelIndex(channelIndex, b, mbcBand); } } private void updateEngineLimiterByChannelIndex(int channelIndex, @NonNull Limiter limiter) { Number[] params = { PARAM_LIMITER, channelIndex}; Number[] values = {(limiter.isInUse() ? 1 : 0), (limiter.isEnabled() ? 1 : 0), limiter.getLinkGroup(), limiter.getAttackTime(), limiter.getReleaseTime(), limiter.getRatio(), limiter.getThreshold(), limiter.getPostGain()}; setNumberArray(params, values); } private Limiter queryEngineLimiterByChannelIndex(int channelIndex) { Number[] params = {PARAM_LIMITER, channelIndex}; Number[] values = {0 /*0 in use (int)*/, 0 /*1 enabled (int)*/, 0 /*2 link group (int)*/, 0.0f /*3 attack time (float)*/, 0.0f /*4 release time (float)*/, 0.0f /*5 ratio (float)*/, 0.0f /*6 threshold (float)*/, 0.0f /*7 post gain(float)*/}; byte[] paramBytes = numberArrayToByteArray(params); byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size. getParameter(paramBytes, valueBytes); byteArrayToNumberArray(valueBytes, values); return new Limiter(values[0].intValue() > 0 /*in use*/, values[1].intValue() > 0 /*enabled*/, values[2].intValue() /*linkGroup*/, values[3].floatValue() /*attackTime*/, values[4].floatValue() /*releaseTime*/, values[5].floatValue() /*ratio*/, values[6].floatValue() /*threshold*/, values[7].floatValue() /*postGain*/); } private Channel queryEngineByChannelIndex(int channelIndex) { float inputGain = getTwoFloat(PARAM_INPUT_GAIN, channelIndex); Eq preEq = queryEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex); Mbc mbc = queryEngineMbcByChannelIndex(channelIndex); Eq postEq = queryEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex); Limiter limiter = queryEngineLimiterByChannelIndex(channelIndex); Channel channel = new Channel(inputGain, preEq.isInUse(), preEq.getBandCount(), mbc.isInUse(), mbc.getBandCount(), postEq.isInUse(), postEq.getBandCount(), limiter.isInUse()); channel.setInputGain(inputGain); channel.setPreEq(preEq); channel.setMbc(mbc); channel.setPostEq(postEq); channel.setLimiter(limiter); return channel; } private void updateEngineChannelByChannelIndex(int channelIndex, @NonNull Channel channel) { //send things with as few calls as possible setTwoFloat(PARAM_INPUT_GAIN, channelIndex, channel.getInputGain()); Eq preEq = channel.getPreEq(); updateEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex, preEq); Mbc mbc = channel.getMbc(); updateEngineMbcByChannelIndex(channelIndex, mbc); Eq postEq = channel.getPostEq(); updateEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex, postEq); Limiter limiter = channel.getLimiter(); updateEngineLimiterByChannelIndex(channelIndex, limiter); } //****** convenience methods: // private int getOneInt(int param) { final int[] params = { param }; final int[] result = new int[1]; checkStatus(getParameter(params, result)); return result[0]; } private void setTwoFloat(int param, int paramA, float valueSet) { final int[] params = { param, paramA }; final byte[] value; value = floatToByteArray(valueSet); checkStatus(setParameter(params, value)); } private byte[] numberArrayToByteArray(Number[] values) { int expectedBytes = 0; for (int i = 0; i < values.length; i++) { if (values[i] instanceof Integer) { expectedBytes += Integer.BYTES; } else if (values[i] instanceof Float) { expectedBytes += Float.BYTES; } else { throw new IllegalArgumentException("unknown value type " + values[i].getClass()); } } ByteBuffer converter = ByteBuffer.allocate(expectedBytes); converter.order(ByteOrder.nativeOrder()); for (int i = 0; i < values.length; i++) { if (values[i] instanceof Integer) { converter.putInt(values[i].intValue()); } else if (values[i] instanceof Float) { converter.putFloat(values[i].floatValue()); } } return converter.array(); } private void byteArrayToNumberArray(byte[] valuesIn, Number[] valuesOut) { int inIndex = 0; int outIndex = 0; while (inIndex < valuesIn.length && outIndex < valuesOut.length) { if (valuesOut[outIndex] instanceof Integer) { valuesOut[outIndex++] = byteArrayToInt(valuesIn, inIndex); inIndex += Integer.BYTES; } else if (valuesOut[outIndex] instanceof Float) { valuesOut[outIndex++] = byteArrayToFloat(valuesIn, inIndex); inIndex += Float.BYTES; } else { throw new IllegalArgumentException("can't convert " + valuesOut[outIndex].getClass()); } } if (outIndex != valuesOut.length) { throw new IllegalArgumentException("only converted " + outIndex + " values out of "+ valuesOut.length + " expected"); } } private void setNumberArray(Number[] params, Number[] values) { byte[] paramBytes = numberArrayToByteArray(params); byte[] valueBytes = numberArrayToByteArray(values); checkStatus(setParameter(paramBytes, valueBytes)); } private float getTwoFloat(int param, int paramA) { final int[] params = { param, paramA }; final byte[] result = new byte[4]; checkStatus(getParameter(params, result)); return byteArrayToFloat(result); }
@hide The OnParameterChangeListener interface defines a method called by the DynamicsProcessing when a parameter value has changed.
/** * @hide * The OnParameterChangeListener interface defines a method called by the DynamicsProcessing * 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 DynamicsProcessing engine.
Params:
  • effect – the DynamicsProcessing on which the interface is registered.
  • param – ID of the modified parameter. See PARAM_GENERIC_PARAM1 ...
  • 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 * DynamicsProcessing engine. * @param effect the DynamicsProcessing on which the interface is registered. * @param param ID of the modified parameter. See {@link #PARAM_GENERIC_PARAM1} ... * @param value the new parameter value. */
void onParameterChange(DynamicsProcessing effect, int param, int value); }
helper method to update effect architecture parameters
/** * helper method to update effect architecture parameters */
private void updateEffectArchitecture() { mChannelCount = getChannelCount(); }
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) { // only notify when the parameter was successfully change if (status != AudioEffect.SUCCESS) { return; } OnParameterChangeListener l = null; synchronized (mParamListenerLock) { if (mParamListener != null) { l = mParamListener; } } if (l != null) { int p = -1; int v = Integer.MIN_VALUE; if (param.length == 4) { p = byteArrayToInt(param, 0); } if (value.length == 4) { v = byteArrayToInt(value, 0); } if (p != -1 && v != Integer.MIN_VALUE) { l.onParameterChange(DynamicsProcessing.this, p, v); } } } }
Params:
  • listener – OnParameterChangeListener interface registered
@hide Registers an OnParameterChangeListener interface.
/** * @hide * Registers an OnParameterChangeListener interface. * @param listener OnParameterChangeListener interface registered */
public void setParameterListener(OnParameterChangeListener listener) { synchronized (mParamListenerLock) { if (mParamListener == null) { mBaseParamListener = new BaseParameterListener(); super.setParameterListener(mBaseParamListener); } mParamListener = listener; } }
@hide The Settings class regroups the DynamicsProcessing parameters. It is used in conjunction with the getProperties() and setProperties() methods to backup and restore all parameters in a single call.
/** * @hide * The Settings class regroups the DynamicsProcessing parameters. It is used in * conjunction with the getProperties() and setProperties() methods to backup and restore * all parameters in a single call. */
public static class Settings { public int channelCount; public float[] inputGain; 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("DynamicsProcessing")) { throw new IllegalArgumentException( "invalid settings for DynamicsProcessing: " + key); } try { key = st.nextToken(); if (!key.equals("channelCount")) { throw new IllegalArgumentException("invalid key name: " + key); } channelCount = Short.parseShort(st.nextToken()); if (channelCount > CHANNEL_COUNT_MAX) { throw new IllegalArgumentException("too many channels Settings:" + settings); } if (st.countTokens() != channelCount*1) { //check expected parameters. throw new IllegalArgumentException("settings: " + settings); } //check to see it is ok the size inputGain = new float[channelCount]; for (int ch = 0; ch < channelCount; ch++) { key = st.nextToken(); if (!key.equals(ch +"_inputGain")) { throw new IllegalArgumentException("invalid key name: " + key); } inputGain[ch] = Float.parseFloat(st.nextToken()); } } catch (NumberFormatException nfe) { throw new IllegalArgumentException("invalid value for key: " + key); } } @Override public String toString() { String str = new String ( "DynamicsProcessing"+ ";channelCount="+Integer.toString(channelCount)); for (int ch = 0; ch < channelCount; ch++) { str = str.concat(";"+ch+"_inputGain="+Float.toString(inputGain[ch])); } return str; } };
@hide Gets the DynamicsProcessing properties. This method is useful when a snapshot of current effect settings must be saved by the application.
Returns:a DynamicsProcessing.Settings object containing all current parameters values
/** * @hide * Gets the DynamicsProcessing properties. This method is useful when a snapshot of current * effect settings must be saved by the application. * @return a DynamicsProcessing.Settings object containing all current parameters values */
public DynamicsProcessing.Settings getProperties() { Settings settings = new Settings(); //TODO: just for testing, we are calling the getters one by one, this is // supposed to be done in a single (or few calls) and get all the parameters at once. settings.channelCount = getChannelCount(); if (settings.channelCount > CHANNEL_COUNT_MAX) { throw new IllegalArgumentException("too many channels Settings:" + settings); } { // get inputGainmB per channel settings.inputGain = new float [settings.channelCount]; for (int ch = 0; ch < settings.channelCount; ch++) { //TODO:with config settings.inputGain[ch] = getInputGain(ch); } } return settings; }
Params:
  • settings – a DynamicsProcessing.Settings object containing the properties to apply
@hide Sets the DynamicsProcessing properties. This method is useful when bass boost settings have to be applied from a previous backup.
/** * @hide * Sets the DynamicsProcessing properties. This method is useful when bass boost settings * have to be applied from a previous backup. * @param settings a DynamicsProcessing.Settings object containing the properties to apply */
public void setProperties(DynamicsProcessing.Settings settings) { if (settings.channelCount != settings.inputGain.length || settings.channelCount != mChannelCount) { throw new IllegalArgumentException("settings invalid channel count: " + settings.channelCount); } //TODO: for now calling multiple times. for (int ch = 0; ch < mChannelCount; ch++) { //TODO: use config setInputGain(ch, settings.inputGain[ch]); } } }