Android uses SoundPool to play sound effects

Introduction to this section:

Chapter 9 brings you multimedia development in Android. It is not so much multimedia development as it is the use of multimedia-related APIs. In the actual development, we have done some things that are related to multimedia: taking pictures, recording, Play music, play video...

Well, well, that’s it, right? For example, to play music, we just call MediaPlayer, find the music file, and then call the play method to play it... Of course, the real multimedia development is another field, audio and video Encoding and decoding, I can only look up to the scum for the time being, we know how to call these APIs! By the way, we still need to popularize some common sense of the Android multimedia framework:

On Android, the default multimedia framework is OpenCore . The advantage of OpenCore is that it takes into account cross-platform portability and has been verified by multiple parties, so it is relatively stable; but its disadvantage is that it is too large and complex, and it takes a lot of time to maintain. Starting from Android 2.0, Google introduced  Stagefright with a slightly simpler architecture . Of course, it did not completely abandon OpenCore. It mainly made an OMX layer and only referenced the omx-component part of OpenCore. There was a tendency to gradually replace OpenCORE, but a Stagefright vulnerability was discovered in August this year, which allows remote code execution by sending a specially crafted MMS message through the exploit.

This vulnerability affects both Android 2.2 and newer versions, and relatively weakly affects Android 4.1 and newer versions. 

I don’t know what’s going on (I don’t even know what JB I’m talking about), um, well, the science is over… Just know these things!

By the way, this multimedia framework is the Media Framework of the third layer ( Libraries ) of the Android architecture ! If you want to know the Android multimedia framework, see the official documentation:

Supported Media Formats

You can directly click Media and Camera here .

I almost forgot that the main character today is SoundPool . As in the title, SoundPool is generally used to play intensive, rapid and short-lived sound effects, such as special effects: Duang~, which is often used in games. You can also add this sound effect to your APP , For example, "Hello, Kugou" is played when Kugou Music enters. In fact, this idea is still good. It indirectly lets users know the current volume of the player. It’s not good for aunts to dance, isn’t it? In addition to adding it on the music player, you can also add it on ordinary apps, such as receiving push messages or new chat messages, and then playing notification sounds, such as the new version of the super class schedule, adding When you install this thing, a short "watch" sound will be played when you receive a push message! A SoundPool object can be seen as a collection of samples that can import resources from an APK or load files from the file system. It uses the MediaPlayer service to decode the audio into a raw 16-bit PCM stream. This feature allows applications to compress streams without suffering the CPU  load and delays associated with decompression while playing audio . SoundPool uses the concept of sound pools to manage multiple playback streams . If the maximum number of streams is exceeded, SoundPool will automatically stop the previously played streams based on priority. In addition, SoundPool also supports setting parameters such as sound quality, volume, and playback ratio. Well, without further ado, let’s start this section: Official API documentation: SoundPool


1. Introduction of related methods:

1) Construction method:

SoundPool (int maxStreams, int streamType, int srcQuality) parameters are:

  • ① Specify how many sounds are supported, and the maximum number of streams allowed to exist simultaneously in the SoundPool object.
  • ② Specify the sound type. The stream type can be divided into four types: STREAM_VOICE_CALLSTREAM_SYSTEMSTREAM_RING , STREAM_MUSIC  and  STREAM_ALARM . Defined in AudioManager.
  • ③ Specify the sound quality (sampling rate conversion quality), generally set to 0 directly!

The above construction method can be used in lower versions, but this construction method will become obsolete after API 21 (Android 5.0)! And to use a SoundPool.Builder stuff, we want to instantiate the SoundPool just call:

SoundPool.Builder spb = new SoundPool.Builder();
spb.setMaxStreams(10);
spb.setAudioAttributes(null); //Convert audio format
SoundPool sp = spb.build(); //Create SoundPool object

To use the above code, the TargetSDK version must be set to be greater than or equal to 21! And if the minSDK version is less than 21, the following reminder will appear:


2) Introduction to common methods:


①Load sound resources :

  • load(Context context, int resId, int priority)
  • load(String path, int priority)
  • load(FileDescriptor fd, long offset, long length, int priority)
  • load (AssetFileDescriptor afd, int priority) The above methods will return a sound ID, and we can use this ID to play the specified sound later

Parameter introduction :

  • context: context
  • resId: resource id
  • priority: A parameter that is useless, it is recommended to set it to 1 to maintain compatibility with the future
  • path: file path
  • FileDescriptor: It seems to be a stream, I don’t know about this
  • AssetFileDescriptor: read a resource file from the asset directory, usage:  AssetFileDescriptor descriptor = assetManager.openFd("biaobiao.mp3");

②Playback control :

play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

The parameters are, in order:

  • soundID: the sound ID number returned by Load()
  • leftVolume: left channel volume setting
  • rightVolume: right channel volume setting
  • priority: Specifies the priority of playing the sound, the higher the value, the higher the priority.
  • loop: Specifies whether to loop: -1 means infinite loop, 0 means no loop, other values ​​indicate the number of times to repeat playback
  • rate: Specify the playback rate: a playback rate of 1.0 can make the sound play at its original frequency, and a playback rate of 2.0 can make the sound play at twice its original frequency. With a playback rate of 0.5, the playback rate is half of the original frequency. The value range of the playback rate is 0.5 to 2.0.

③Resource release :

The release() method can be called to release the memory and resources occupied by all SoundPool objects, and of course it can also be released according to the sound ID!


3. Use the code example:

When you click the button, it will say "Duang". Here are two load methods, raw and assests!

key code :

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_play1;
    private Button btn_play2;
    private Button btn_play3;
    private Button btn_play4;
    private Button btn_play5;
    private Button btn_release;
    private AssetManager aManager;
    private SoundPool mSoundPool = null;
    private HashMap<Integer, Integer> soundID = new HashMap<Integer, Integer>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        aManager = getAssets();
        try {
            initSP();
        } catch (Exception e) {
            e.printStackTrace();
        }
        bindViews();
    }

    private void bindViews() {
        btn_play1 = (Button) findViewById(R.id.btn_play1);
        btn_play2 = (Button) findViewById(R.id.btn_play2);
        btn_play3 = (Button) findViewById(R.id.btn_play3);
        btn_play4 = (Button) findViewById(R.id.btn_play4);
        btn_play5 = (Button) findViewById(R.id.btn_play5);
        btn_release = (Button) findViewById(R.id.btn_release);

        btn_play1.setOnClickListener(this);
        btn_play2.setOnClickListener(this);
        btn_play3.setOnClickListener(this);
        btn_play4.setOnClickListener(this);
        btn_play5.setOnClickListener(this);
        btn_release.setOnClickListener(this);

    }

    private void initSP() throws Exception{
        //Set up to accommodate 5 audio streams, the audio quality is 5
        mSoundPool = new SoundPool(5, AudioManager.STREAM_SYSTEM, 5);
        soundID.put(1, mSoundPool.load(this, R.raw.duang, 1));
        soundID.put(2 , mSoundPool.load(getAssets().openFd("biaobiao.mp3") , 1)); // need to catch IO exception
        soundID.put(3, mSoundPool.load(this, R.raw.duang, 1));
        soundID.put(4, mSoundPool.load(this, R.raw.duang, 1));
        soundID.put(5, mSoundPool.load(this, R.raw.duang, 1));
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_play1:
                mSoundPool.play(soundID.get(1), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play2:
                mSoundPool.play(soundID.get(2), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play3:
                mSoundPool.play(soundID.get(3), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play4:
                mSoundPool.play(soundID.get(4), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play5:
                mSoundPool.play(soundID.get(5), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_release:
                mSoundPool.release(); //Recycle SoundPool resources
                break;
        }
    }
}

The code is very simple, and if you click the last button, the SoundPool will be released, and then the other buttons will not be Duang~


4. OnLoadCompleteListener monitors whether the sound file is loaded

Well, this is a temporary thought. I suddenly remembered it when I was writing another article. The usage is also very simple. We can add the OnLoadCompleteListener to the above code, then rewrite the onLoadComplete() method, and finally create a SoundPool object Just set this up!

mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
    @Override
    public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
        Toast.makeText(MainActivity.this,"Add special effects ready~",Toast.LENGTH_SHORT).show();
    }
});

Guess you like

Origin blog.csdn.net/leyang0910/article/details/131873484