Android’s AudioEffect class
You can control the audio effects on an Android device. You’ll need to use one of the AudioEffect class’s derived classes:
- Equalizer
- Virtualizer
- BassBoost
- PresetReverb
- EnvironmentalReverb
You can apply these effects to an AudioTrack or the MediaPlayer.
Using an audio effect in your app
To use the audio effect in your app, you create an AudioEffect object. A corresponding effect engine is then created in the device’s audio framework.
If an effect engine has already been created by another app, then your app will use that one and not create a new one.
You pass a priority parameter when you create the effect object. This determines who controls the effect engine.
Your app will control the engine if your priority is higher than the existing owner’s. If not, then the existing app keeps control of the effect engine.
You can use appropriate listeners to notify you of changes in the effect engine state or in the control of ownership.
The Equalizer effect
The Equalizer class is a derived class of the AudioEffect class.
You use the Equalizer effect to get rid of unwanted sounds or to make certain sounds more prominent.
To use the equalizer effect in your app, you create an Equalizer object which instantiates an equalizer engine in the audio framework. If another app has already created an equalizer engine then your app will use that one.
Which app controls the engine depends on the priority passed as a parameter when the Equalizer object was created. The Equalizer with the highest priority keeps control of the engine.
Each equalizer engine controls a number of frequency bands. Each of these is able to filter the audio signal falling within their specific frequency range.
The app can use predefined equalizer pre-sets or have more precise control of the gain in each frequency band controlled by the equalizer.
You attach the Equalizer to an AudioTrack or MediaPlayer using the audio session ID of the track or player when you construct the Equalizer.
Our Equalizer tutorial
Our tutorial app shows you how to use the Equalizer effect.
When the app starts, an audio file starts playing using the Normal equalizer pre-set.
The user can change the pre-set by selecting one of the supported Equalizer pre-sets from a Spinner drop-down list.
There are also a number of SeekBar sliders representing each of the frequency bands controlled by the equalizer. The user can slide these to fine-tune each of the frequency bands for the chosen equalizer pre-set.
A visual representation of the audio wave is displayed at the top of the screen.
The Normal equalizer pre-set is used by default when the app starts. The user can change the audio frequency by either selecting one of the equalizer pre-sets from the Spinner or by sliding the individual frequency band sliders
The list of equalizer pre-sets displayed in the Spinner depends on the number of pre-sets supported by the equalizer engine
Starting off: The Activity’s onCreate() method
This where we create the player and equalizer:
We create our MediaPlayer and Equalizer objects in the activity’s onCreate() method
Note the following:
- setContentView – we set the layout file to use. Our LinearLayout container has three linear layouts, one for the Spinner, one for the waveform and one for the frequency band sliders
- setVolumeControlStream – we specify here that we want the device’s volume controls to control our audio stream
- mMediaPlayer – we create our MediaPlayer object, passing two parameters to the constructor:
- the context
- the resource Id of our sound file. Our file is stored in the res/raw folder. You can use your own sound file
- start – we start the media player
- mEqualizer – our Equalizer object. We pass two parameters:
- the priority – an equalizer engine can be shared by a number of apps. Each app provides a priority when they create their equalizer object. The app with the highest priority controls the engine
- session ID – this is an unique ID for this audio session. The equalizer will be attached to the media player in the same audio session
- setEnabled – applies the equalizer effect to audio being played
- setUpVisualizerFxAndUI – we call this method to set up and display the audio waveform
- setupEqualizerFxAndUi – we call this method to set up and display the frequency band sliders
- setEnabled – we pass true to enabled the visualization engine
- setOnCompleteListener – we register this interface callback to listen for when the audio stops playing
- setEnabled – we pass false to disable the visualization engine. It’s no longer needed as the audio has stopped playing
The setupVisualizerFxAndUI() method
We create our custom View class, VisualizerView which we use to draw the audio waveform on the screen. You may want to have a look at Creating Custom Views for more on custom views.
We use the setupVisualizerFxAndUI() method to create our VisualizerView view and the Visualizer object which we then attach to the media player.
We use the OnDataCaptureListener interface’s onWaveFormDataCapture() method to update the displayed waveform as the audio plays. Its parameters contain information about the audio frequency which is then displayed as a waveform.
The setupEqualizerFxAndUI() method
This method gets and displays the frequency bands supported by the equalizer. Each band is represented by a SeekBar. The user can drag the slider to change the frequency for that band.
Display the Equalizer Heading
We display a heading above the seek bars:
We get a reference to the layout that we’ll use to display the frequency sliders and also create a TextView object to display a heading
Note the following:
- mLinearLayout – we get a reference to our linear layout in the layout file which we’ll use to display the seek bars
- equalizerHeading – we create a new TextView object to display the heading text for the SeekBar layout
- We set the text to display, it’s size, gravity and then add the text view to the layout
- numberFrequencyBands – we get the number of frequency bands supported by this equalizer engine
- lowerEqualizerBandLevel – we call getBandLevelRange() to get the frequency band level ranges. This method returns an array containing both the lower and upper level ranges. Here we’re interested in the lower range, the first item, indexed as 0, in the array
- upperEqualizerBandLevel – here we’re interested in the upper range, the second item, indexed as 1, in the array
Display the Center Frequency for each Frequency band
We display the center frequency for each band above each SeekBar:
We get and display the center frequency for each of the frequency bands
Note the following:
- we loop through all the frequency bands and display their center frequency above the seek bar slider
- frequencyHeaderTextview – we create a new TextView object to display the center frequencies
- setLayoutParams – we set the layout parameters for the text view. You may want to look at Android: Programmatically adding layouts
- setGravity – we want the text view to display in the center of the seek bar so we set the gravity to CENTER_HORIZONTAL
- getCenterFreq – we get the center frequency for each band, convert it from milliHertz to Hertz and set it to display in the text view
- addView – we add the text view to our layout
Setting up the layouts for SeekBar sliders
We create a layout for each of the SeekBar sliders:
We create a horizontal LinearLayout as well as text views for the lower and upper frequency levels for each of the seek bars
Note the following:
- seekBarRowLayout – we create a new linear layout to display the SeekBar sliders
- setOrientation – we set the orientation of the layout to horizontal. We’re going to create one of these layouts for each of the sliders. The layout will display the band’s lower frequency range, the slider and the band’s upper frequency range, all in a horizontal line
- lowerEqualizerBandLevelTextview – we create a new text view for the lower range level
- setLayoutParams – we set the layout parameters for the lowerEqualizerBandLevelTextview text view
- setText – we set the text view to display the band’s lower level, lowerEqualizerBandLevel which we convert from milliBels to deciBels
- upperEqualizerBandLevelTextview - we create a new text view for the upper range level
- setLayoutParams – we set the layout parameters for the upperEqualizerBandLevelTextview text view
- setText – we set the text view to display the band’s upper level, upperEqualizerBandLevel which we convert from milliBels to decibels
Creating the SeekBar sliders
Create the seek bars:
We create the SeekBar sliders and set their progress levels
Note the following:
- layoutParams – we set up the layout parameters which we’ll use for each of the SeekBar views
- seekBar – we create a new SeekBar object for each of the seek bars
- setId – we set the ID for each of the seek bars. We need an ID to get a reference to each of the seek bars. We’ll need to identify them when we update their progress when the user selects a pre-set from the Spinner’s drop-down list
- setLayoutParams – we set the SeekBar to use the layout parameters that we have just defined
- setMax – we set the upper level for the progress of this SeekBar
- setProgress – we set the progress of the slider to the current frequency level for this frequency band
Handling changes in the slider position
We update the frequency band’s setting depending on the position of the slider:
We use onProgressChanged() to set the frequency bands to their new levels which change when the user moves the sliders
Note the following:
- setOnSeekBarChangedListener – an interface that listens for when the user moves the seek bar slider
- onProgressChanged – triggered when the slider has moved, indicating a change in the seek bar’s progress
- setBandLevel – we set this equalizer band to the new level which we calculate by adding the progress to the lower level for this band
Adding the upper and lower levels and the seek bar slider to the row layout
We add the frequency band’s range levels and the seek bar to the individual SeekBar layout:
We add the lower and upper frequency band levels and the sliders to the row layout and then add the row to the parent linear layout
Note the following:
- addView – we add the lower and upper frequency band levels and the sliders, in the order that they will appear, to the horizontal row layout
- we then add the row layout to the parent seek bar layout which displays all the seek bar rows, one below the other
- equalizeSound – we call the equalizeSound() method to display the equalizer pre-sets Spinner
The equalizeSound() method
The equalizeSound() method gets and displays the equalizer pre-sets supported by this equalizer. The method also updates the equalizer’s frequency bands to those of the selected pre-set.
Setting up the Spinner
We create a Spinner and an adapter. Have look at, Android Adapters: What are Adapters? for more on adapters.
Our Spinner displays a list of supported Equalizer pre-sets
Note the following:
- equalizerPresetNames – we create an ArrayList object which we’ll populate with the names of the supported equalizer pre-sets
- equalizerPresetSpinnerAdapter – we create an Adapter which we’ll use to display the supported equalizer pre-sets in the Spinner. There are three parameters:
- the context
- the layout to be used in the Spinner
- the list of pre-set names that will be displayed in the Spinner
- setDropDownViewResource – the layout to be used for the Spinner’s drop-down list
- equalizerPresetSpinner – we get a reference to our Spinner defined in the layout file
Getting the list of pre-set names
We get all the names of the frequency pre-sets supported by this equalizer:
We load up our array list of supported equalizer pre-set names and set the adapter to be used by the Spinner
Note the following:
- getNumberOfPresets – we get the number of pre-sets supported by this equalizer. Each equalizer has a number of pre-sets. These are groups of common frequency settings with names like, Pop, Folk, Classical, etc.
- getPresetName – we loop through all the supported pre-sets, get their names and add them to our equalizerPresetNames array list. We’ll display this list in the Spinner
Selecting an equalizer pre-set from the Spinner
The user can select a pre-set from the Spinner’s drop-down list:
Once the user selects a pre-set from the Spinner drop-down list, we set the equalizer to use this pre-set and update the frequency band sliders to show the new settings
Note the following:
- setOnItemSelectedListener – an interface callback that listens for when a Spinner item has been selected
- onItemSelected – triggered when the user selects one of the Spinner items
- usePreset – sets the equalizer to the selected pre-set
- numberFrequencyBands – we get the number of frequency bands supported by this equalizer engine
- lowerEqualizerBandLevel – we call getBandLevelRange() to get the lower frequency band level range. This method returns an array containing both the lower and upper level ranges. We’re interested in the first item, indexed as 0, in the array
- for loop – we loop through the bands and:
- get a reference to each of the seek bars using findViewById(), passing the individual Id’s for each of the seek bars as a parameter
- set the position of the seek bar’s slider to the gain level of this frequency band minus it’s lower frequency range level
Releasing resources
You should release the resources used to play the audio when you’re finished. We do this in the activity’s onPause() method.
The activity is about to be destroyed so we can release all the resources
Note the following:
- if the media player still exists and the activity is about to be destroyed, we can safely release it, the visualizer and the equalizer as they will no longer be used
- release – release all the resources used by these objects
- null – we set the media player to null to help the Garbage Collector identify it as reclaimable
This tutorial app is based on the official sample app which you can find in your Android SDK package (samples>android-10>ApiDemos>src>com>example>android>apis>media). We modified some code and used some code verbatim.
You may also be interested in:
- Using Android’s SoundPool class: A tutorial
- Recording and playing back audio files
I hope that you have found this tutorial helpful.
This project was created using .
You can download the project files here
Are you using Eclipse or another IDE? Here's how you can use this project's Android Studio files.