Can not play whole .mp3 file


#1

I am using following method and pre-loading .mp3 file as below:

CocosDenshion::SimpleAudioEngine::sharedEngine->preloadEffect;

and playing that file with following code :
CocosDenshion::SimpleAudioEngine::sharedEngine->playEffect;

But the problem is files are not played fully i.e. suppose a file is 20 seconds long and it is played only for 15-16 seconds. What can be the problem?


[Android] playEffect() from CocosDenshion doesn't play full length
#2

That is because SoundPool only have 1MB allocated size in memory, and playEffect() is considered to be used to play short Sound Effect only. to play large files, you should use playBackgroundMusic();


#3

Hi, thanks for your reply. The file I am playing is of size 267 KB and its duration is 17 seconds but the file is only played for 12-13 seconds. I have already loaded this file using preloadEffect* method. I am playing this file usingplayEffect()* method, I am using this method because I am already playing background music using playBackgroundMusic* method. What can be the problem?
Is it possible to play multiple files using
playBackgroundMusic()* method? If it is possible I would be able to play the file that is not playing fully using *playEffect()* method.


#4

Nope, you cannot play multiple files using playBackgroundMusic(). That is where I hated simple audio Engine because it is too simple to handle all of our requirements.

If you do not have a strict requirements on latency, you can try below:

What I did is I create an Array of MediaPlayer in the Java Class, and when I need to play something, I use one of them and release after using.

I call these Java method using JNI, which is exactly same as what playBackgroundMusic() is doing.

private MediaPlayer[] mVoiceEffect = new MediaPlayer[10];
private static native void nativeOnVoiceFinished();

private void initData(){
for(int i = 0; i < 10; +i){
mVoiceEffect[i] = null;
}
}
private MediaPlayer createMediaplayerFromAssets{
MediaPlayer mediaPlayer = null;
try{
AssetFileDescriptor assetFileDescritor = mContext.getAssets.openFd;
mediaPlayer = new MediaPlayer;
mediaPlayer.setDataSource,
assetFileDescritor.getStartOffset, assetFileDescritor.getLength);
mediaPlayer.prepare;
mediaPlayer.setVolume;
}catch {
mediaPlayer = null;
Log.e, e);
}
return mediaPlayer;
}
public boolean playVoiceSequence{
if){
mVoiceEffect[0] = this.createMediaplayerFromAssets;
try {
mVoiceEffect[0].setOnCompletionListener;
mVoiceEffect[0].stop;
mVoiceEffect[0].prepare;
mVoiceEffect[0].seekTo;
mVoiceEffect[0].start;
currentIndex = 0;
} catch {
Log.e, e);
}
return true;
}
return false;
}
boolean isPlayingSequence{
for{
if
return true;
}
return false;
}
public void stopVoice{
for{
if {
try {
mVoiceEffect[i].stop;
mVoiceEffect[i].release;
mVoiceEffect[i] = null;
}catch {
Log.e);
}
}
}
}
@Override
public void onCompletion {
mp.release;
mVoiceEffect[currentIndex] = null;
if {
try {
mVoiceEffect[currentIndex+1].stop;
mVoiceEffect[currentIndex+1].prepare;
mVoiceEffect[currentIndex+1].seekTo;
mVoiceEffect[currentIndex+1].start;
currentIndex
= 1;
} catch (Exception e){
Log.e(TAG, “playVoiceVallBack: error state”);
}
}
else{
this.stopVoice();
currentIndex = 0;
this.nativeOnVoiceFinished();
}
}

public void addVoice(String path){
for(int i = 1; i < 9; i++){
if (mVoiceEffect[i] == null) {
mVoiceEffect[i] = this.createMediaplayerFromAssets(path);
try {
mVoiceEffect[i].setOnCompletionListener(this);
}
catch (Exception e){
Log.e(TAG, “error:” + e.getMessage(), e);
}
break;
}
}
}


#5

Thanks. Sorry for my late reply but I can not figure out how to use this code.

Would this code allow me to play multiple files at the same time? I guess it would not because it is using MediaPlayer.


#6

Actually it CAN. By modifying this code, you are able to find an empty MediaPlayer and use it to play sound.


#7

Thanks. Where do I modify my code and write your code?


#8

You can create a new Java class, say Cocos2dxDroid.java, put the above code in, create a new method call playSound, which takes a filename as input argument. Then in this method, loop all MediaPlayers to check if there is one not in use. you can then use the perticular MediaPlayer to play sound. At last you use jni in your code to call these methods. Check How Cocos2dxMusic.java and your implementation should be similar.