[8 to Android game development] add audio in the game-details the advantages and disadvantages of MediaPlayer and SoundPool and

Source: Internet
Author: User
Tags drawtext

 

In game development, I learned from materials and books that two formats of playing audio can be used in our game development: MediaPlayer and SoundPool!

PS: Of course, there is another JetPlayer, but the format of the file to be played is quite troublesome, so I will not explain it here. If you are interested, you can study it on your own;

 

Run:

 

 

MediaPlayer and: SoundPool class! What are their advantages and disadvantages? Or, which one is better for game development?

The answer is: both are required !!! After analyzing the pros and cons and their respective purposes, I will give you a detailed explanation when you are familiar with each playing mode!

 

The following is the code first: (first look at the code and then I will explain the pros and cons of the two playback forms, their respective uses, and several notes in the Code !)

 

 

··· · 50 ······· · 90 ····· · 140 · 150

Package com. himi;

Import java. util. HashMap;

Import android. content. Context;

Import android. graphics. Canvas;

Import android. graphics. Color;

Import android. graphics. Paint;

Import android. media. AudioManager;

Import android. media. MediaPlayer;

Import android. media. SoundPool;

Import android. view. KeyEvent;

Import android. view. MotionEvent;

Import android. view. SurfaceHolder;

Import android. view. SurfaceView;

Import android. view. SurfaceHolder. Callback;

Public class MySurfaceView extends SurfaceView implements Callback, Runnable {

Private Thread th;

Private SurfaceHolder sfh;

Private Canvas canvas;

Private MediaPlayer player;

Private Paint paint;

Private boolean ON = true;

Private int currentVol, maxVol;

Private AudioManager am;

Private HashMap <Integer, Integer> soundPoolMap; // Note 1

Private int loadId;

Private SoundPool soundPool;

Public MySurfaceView (Context context ){

Super (context );

// Obtain the audio service and convert it into an audio manager, which can be used to control the volume.

Am = (AudioManager) MainActivity. instance

. GetSystemService (Context. AUDIO_SERVICE );

MaxVol = am. getStreamMaxVolume (AudioManager. STREAM_MUSIC );

// Obtain the maximum volume (15 Max! . Not 100 !)

Sfh = this. getHolder ();

Sfh. addCallback (this );

Th = new Thread (this );

This. setKeepScreenOn (true );

SetFocusable (true );

Paint = new Paint ();

Paint. setAntiAlias (true );

// Initialize MediaPlayer

Player = MediaPlayer. create (context, R. raw. himi );

Player. setLooping (true); // sets loop playback.

// SoundPool Initialization

SoundPool = new SoundPool (4, AudioManager. STREAM_MUSIC, 100 );

SoundPoolMap = new HashMap <Integer, Integer> ();

SoundPoolMap. put (1, soundPool. load (MainActivity. content,

R. raw. himi_ogg, 1 ));

LoadId = soundPool. load (context, R. raw. himi_ogg, 1 );

// The last parameter of the load () method identifies the priority sound. Currently, there is no effect. It is only a value for future compatibility.

}

Public void surfaceCreated (SurfaceHolder holder ){

/*

* In Android OS, if you press the volume adjustment button on your mobile phone, there will be two situations,

* One is to adjust the ringtone volume of the mobile phone, and the other is to adjust the volume of the game, software, and music.

* When we are in the game, we always want to adjust the game volume instead of the phone volume,

* The annoying problem comes again. I found during development that only when there is sound in the game playing

* You can adjust the game volume. Otherwise, it is the volume of the mobile phone. Is there a way to make the mobile phone as long as it is

* When the game is running, only the game volume is adjusted? Try the following code!

*/

MainActivity. instance. setVolumeControlStream (AudioManager. STREAM_MUSIC );

// Set the volume to the media volume. When the playback is paused, the volume will not be adjusted by default.

Player. start ();

Th. start ();

}

Public void draw (){

Canvas = sfh. lockCanvas ();

Canvas. drawColor (Color. WHITE );

Paint. setColor (Color. RED );

Canvas. drawText ("current volume:" + currentVol, 100, 40, paint );

Canvas. drawText ("Current playback time" + player. getCurrentPosition () + "millisecond", 100,

70, paint );

Canvas. drawText ("Pause/start switch between the arrow keys", 100,100, paint );

Canvas. drawText (" ← (5 seconds), 100,130, paint );

Canvas. drawText ("direction key → key fast forward for 5 seconds", 100,160, paint );

Canvas. drawText (" ↑ ", 100,190, paint );

Canvas. drawText (" ↓ ", 100,220, paint );

Sfh. unlockCanvasAndPost (canvas );

}

Private void logic (){

CurrentVol = am. getStreamVolume (AudioManager. STREAM_MUSIC); // get the current volume continuously

}

@ Override

Public boolean onKeyDown (int key, KeyEvent event ){

If (key = KeyEvent. KEYCODE_DPAD_CENTER ){

ON =! ON;

If (ON = false)

Player. pause ();

Else

Player. start ();

} Else if (key = KeyEvent. KEYCODE_DPAD_UP) {// press the key here. It should be RIGHT, but because it is in Landscape mode, the following is the same

Player. seekTo (player. getCurrentPosition () + 5000 );

} Else if (key = KeyEvent. KEYCODE_DPAD_DOWN ){

If (player. getCurrentPosition () <5000 ){

Player. seekTo (0 );

} Else {

Player. seekTo (player. getCurrentPosition ()-5000 );

}

} Else if (key = KeyEvent. KEYCODE_DPAD_LEFT ){

CurrentVol + = 1;

If (currentVol> maxVol ){

CurrentVol = 100;

}

Am. setStreamVolume (AudioManager. STREAM_MUSIC, currentVol, // Note 2

AudioManager. FLAG_PLAY_SOUND );

} Else if (key = KeyEvent. KEYCODE_DPAD_RIGHT ){

CurrentVol-= 1;

If (currentVol <= 0 ){

CurrentVol = 0;

}

Am. setStreamVolume (AudioManager. STREAM_MUSIC, currentVol,

AudioManager. FLAG_PLAY_SOUND );

}

SoundPool. play (loadId, currentVol, currentVol, 1, 0, 1f); // Note 3

// SoundPool. play (soundPoolMap. get (1), currentVol, currentVol, 1, 0, 1f); // Note 4

// SoundPool. pause (1); // pause the SoundPool sound

Return super. onKeyDown (key, event );

}

@ Override

Public boolean onTouchEvent (MotionEvent event ){

Return true;

}

Public void run (){

// TODO Auto-generated method stub

While (true ){

Draw ();

Logic ();

Try {

Thread. sleep (100 );

} Catch (Exception ex ){

}

}

}

Public void surfaceChanged (SurfaceHolder holder, int format, int width,

Int height ){

}

Public void surfaceDestroyed (SurfaceHolder holder ){

}

}

 

 

 

1. Steps for playing audio using MediaPlayer:

1. Call MediaPlayer. create (context, R. raw. himi). Call the create method using the MediaPlayer class and pass in the resource audio file indexed by id to obtain the instance;

2. The obtained instance can call MediaPlayer. star ();

Simple. In fact, there are several constructor methods for MediaPlayer. If you are interested, you can try and implement them. Here we will introduce you to the basics in a simple and practical way!

 

Ii. Steps for playing audio in SoundPlayer:

1. new generates an instance; new SoundPool (4, AudioManager. STREAM_MUSIC, 100); the first parameter is the number of sound streams that can be played simultaneously. The second parameter is the sound type, and the third parameter is the sound quality;

2. loadId = soundPool. load (context, R. raw. himi_ogg, 1 );

3. Use an instance to call the play method to input the corresponding audio file id!

 

The following describes the advantages and disadvantages of two Playback modes:

 

Using MediaPlayer to play audio files has some shortcomings:

For example, high resource usage, long latency, and simultaneous playback of multiple audios are not supported.

These disadvantages determine that MediaPlayer is not ideal in some scenarios, for example, in game development with relatively high time precision.

At first, I used a common MediaPlayer method, but this method is not suitable for game development because it is common to play multiple sound effects simultaneously in the game, anyone who has used MediaPlayer should know that it does not support real-time playback of multiple sounds, and there may be more or less latency, which is intolerable, especially when the sound (such as the continuous click button) is played in a fast and continuous manner, it will be very obvious, and 3 ~ Latency of 5 seconds: [Use MediaPlayer. seekTo () to solve this problem ];

 

Some problems with using SoundPool:

1. soundPool can only apply for a maximum of 1 MB of memory space, which means we can only use some very short sound fragments, instead of playing songs or game background music (you can use JetPlayer to play background music ).

2. SoundPool provides pause and stop methods, but it is recommended that you do not use these methods easily, because sometimes they may cause your program to terminate inexplicably. Some friends report that they do not stop the playing sound immediately. Instead, they stop playing the data in the buffer zone. They may play for another second.

3. We recommend that you use OGG for audio format. Audio files in WAV format are used to store game sound effects. After repeated tests, when the playback interval of a sound effect is short, an exception will occur (SoundPool currently only supports 16-bit WAV files ). The problem was solved by converting the file to the OGG format.

4. When playing audio using SoundPool, if you call the playing function during initialization to play music, there is no sound at all, not because it is not executed, but SoundPool requires a preparation time! . Of course, this preparation time is also very short, it will not affect the use, but the program will play without sound when it is run, so I wrote the SoundPool play in the key processed, note 4

 

After reading the pros and cons, let's take a look at my code remarks:

Note 1:

Here I have defined a HashMap. This is a hash table. If you are not familiar with this class, we recommend that you use it frequently with Hashtable, the main differences between them are: HashMap is not synchronized, empty key values, high efficiency; Hashtable synchronization, non-empty key values, low efficiency; but HashMap is not supported in j2s, because me does not support null key values, you can only use hashtable, Keke, and verbose in me. Here I use hashmap to store multiple audio IDs, multiple audios can be played simultaneously during playback.

As mentioned above, SoundPool supports simultaneous playing of multiple audios, and SoundPool calls this method during Playing (note 3. play (loadId, currentVol, currentVol, 1, 0, 1f); the first parameter is the previous loadId! Obtained Through soundPool. load (context, R. raw. himi_ogg, 1,

Note that hashmap must be defined as HashMap <Integer, Integer> hm = new Hash <Integer, Integer>, declare that this hash table is a hash table where both the key and volue values are Integer! Why do you want to do this, because if you simply define it as HashMap hm = new HashMap (), then when you are playing, that is, note 4. The first id parameter here uses Hashmap. the get () method always prompts an error!

 

SoundPool can only apply for a maximum of 1 MB of memory space, which means we can only use some very short sound clips. Why can only use some very short sound?

Let's take a look at the first parameter of Method 4. The input Id type is required to be an int value, so this int actually corresponds to the audio id returned by the load () method, in addition, this id will become smaller because of the audio file size. Once our audio file exceeds the maximum int value, a memory error will be reported. That's why SoundPool can only play some brief audio. Of course, I cannot verify and explain why such a definition is defined in the OS.

 

Note 4: Interpretation of parameters in this method

The first parameter is through SoundPool. the id of the audio returned by the load () method. The second and third parameters indicate the size of the left and right channels, the fourth parameter indicates the priority, and the fifth parameter indicates the number of loops, the last one is the playback speed (1.0 = normal playback, range: 0.5 to 2.0)

 

NOTE 2:

The Media Service obtains an audio manager to adjust the volume. It should be emphasized that the adjustment of the audio is to use the audio manager to call setStreamVolume (), instead of MediaPlayer. setVolue (int LeftVolume, int RightVolume); the two parameters of this method are to adjust the Left and Right audio channels rather than adjust the sound size.

 

Well, we have analyzed what needs to be used in game development. The conclusion is that SoundPool is suitable for special effects. In fact, it is better to play background music with MediaPlayer. Of course, let's take a look at everyone's preferences and choices! The following is a project attached: (Project 10 + MB includes res audio files)

 

If someone asks how to know that a song has been played, let's talk about it here:

 

PlaybackCompleted status: this status is displayed when the file is normally played and loop playback is not set. The OnCompletionListener onCompletion () method is triggered. In this case, you can call the start () method to play the file from scratch again, stop () to stop the MediaPlayer, or seekTo () to locate the playback position again.

Note: 1. Do not forget the binding operation! Mp. setOnCompletionListener (this );

2. If you have set Loop Playing mp. setLooping (true);, it will never be monitored until the playback is complete !!!! Be sure to pay attention here!

 

 

Source code: http://download.csdn.net/source/2943074 (there is a ringtone to my cell phone)

 

Himi original, you are welcome to reprint, please note clearly! Thank you.

Address: http://blog.csdn.net/xiaominghimi/archive/2010/12/28/6101737.aspx

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.