SoundPool加载速度慢,并且在MotionEvent方面表现奇怪。

huangapple go评论63阅读模式
英文:

SoundPool loads slowly and is weird with MotionEvent

问题

public class MainActivityPiano extends AppCompatActivity {

    //所有声音ID
    public static final int SOUND_1 = 1;
    public static final int SOUND_2 = 2;

    SoundPool mSoundPool;
    HashMap<Integer, Integer> mSoundMap;

    static int streamID;

    @Override
    protected void onStart() {
        super.onStart();
        
        mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
        mSoundMap = new HashMap<Integer, Integer>();

        if(mSoundPool != null){
            mSoundMap.put(SOUND_1, mSoundPool.load(this, R.raw.piano_tone1, 1));
            mSoundMap.put(SOUND_2, mSoundPool.load(this, R.raw.piano_tone2, 1));
            //至少要加载十二个不同的声音文件...
        }

        //播放按钮和/或钢琴键
        Button pianoKey1 = this.findViewById(R.id.piano_key1);
        Button pianoKey2 = this.findViewById(R.id.piano_key2);
        //...

        //播放按钮和/或钢琴键
        pianoKey1.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return playSound(SOUND_1, motionEvent, view);
            }
        });
        pianoKey2.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return playSound(SOUND_2, motionEvent, view);
            }
        });
        //...
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_piano);
    }

    public boolean playSound(int sound, MotionEvent m, View v) {

        switch (m.getAction()) {
            case MotionEvent.ACTION_DOWN:
                streamID = mSoundPool.play(sound, 1, 1, 1, 0, 1.0f);
                break;

            case MotionEvent.ACTION_CANCEL:;
                mSoundPool.stop(streamID);
                break;
                
            case MotionEvent.ACTION_UP:
                mSoundPool.stop(streamID);
                break;

            case MotionEvent.ACTION_MOVE:
        }
        return true;
    }

    @Override
    protected void onPause() {
        mSoundPool.autoPause();
        super.onPause();
    }

}
英文:

Hi!
I'm fairly new to programming and I've run into some issues with SoundPool.
I'm trying to build a simple piano application and haven't found a solution yet. The audio files I'm using are midi (.mid)

Current issues with my code:

  • Audio files load very slow, I have to wait a couple of seconds for SOUND_12 to get ready.
  • It works fine if I only use one finger, but when I add another finger the first finger/sound gets stuck.

My current code:


public class MainActivityPiano extends AppCompatActivity {
//all soundIDs
public static final int SOUND_1 = 1;
public static final int SOUND_2 = 2;
SoundPool mSoundPool;
HashMap&lt;Integer, Integer&gt; mSoundMap;
static int streamID;
@Override
protected void onStart() {
super.onStart();
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
mSoundMap = new HashMap&lt;Integer, Integer&gt;();
if(mSoundPool != null){
mSoundMap.put(SOUND_1, mSoundPool.load(this, R.raw.piano_tone1, 1));
mSoundMap.put(SOUND_2, mSoundPool.load(this, R.raw.piano_tone2, 1));
//at least twelve different sound files have to be loaded...
}
//play buttons and/or piano keys
Button pianoKey1 = this.findViewById(R.id.piano_key1);
Button pianoKey2 = this.findViewById(R.id.piano_key2);
//...
//play buttons and/or pianokeys
pianoKey1.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent motionEvent) {
return playSound(SOUND_1, motionEvent, view);
}
});
pianoKey2.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent motionEvent) {
return playSound(SOUND_2, motionEvent, view);
}
});
//...
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_piano);
}
public boolean playSound(int sound, MotionEvent m, View v) {
switch (m.getAction()) {
case MotionEvent.ACTION_DOWN:
streamID = mSoundPool.play(sound, 1, 1, 1, 0, 1.0f);
break;
case MotionEvent.ACTION_CANCEL:;
mSoundPool.stop(streamID);
break;
case MotionEvent.ACTION_UP:
mSoundPool.stop(streamID);
break;
case MotionEvent.ACTION_MOVE:
}
return true;
}
@Override
protected void onPause() {
mSoundPool.autoPause();
super.onPause();
}
}

答案1

得分: 2

你可能想要预先加载你的声音,然后通过引用它们的ID来播放。

short[] 数组将包含你传递给 getSound()fileNames 中对应文件的ID。

创建一个单独的类 Sound.java
在你的主活动中,你可以创建一个 Sound 对象,并在 onCreate() 中加载声音,然后通过它们的ID播放。

public class Sound {
	private static SoundPool soundPool;
	
	public short[] getSound(Activity activity, String...fileNames) {
		soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
		short[] ids = new short[fileNames.length];
		activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
		try {
			AssetManager assetManager = activity.getAssets();
			for(int i = 0; i < fileNames.length; i++) {
				AssetFileDescriptor descriptor = assetManager.openFd(fileNames[i]);
				ids[i] = (short) soundPool.load(descriptor, 1);
			}
		} catch(IOException e) {
			//
		}
		return ids;
	}
	
	public void playSound(short id, float rV, float lV) {
		if(id != -1) {
			soundPool.play(id, rV, lV, 0, 0, 1);
		}
	}
	
	public void pauseSound() {
		soundPool.autoPause();
	}	
	
	public void releaseSound() {
		soundPool.release();
	}
}
英文:

You probably want to pre-load your sounds and then play them by referencing their ids.

The short[] array will contain ids for the corresponding file in the fileNames that you pass to getSound()

Create a separate class Sound.java:
In your Main Activity you can create a Sound object and load the sounds once in onCreate() and play them with their ids.

public class Sound {
private static SoundPool soundPool;
public short[] getSound(Activity activity, String...fileNames) {
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
short[] ids = new short[fileNames.length];
activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
try {
AssetManager assetManager = activity.getAssets();
for(int i = 0; i &lt; fileNames.length; i++) {
AssetFileDescriptor descriptor = assetManager.openFd(fileNames[i]);
ids[i] = (short) soundPool.load(descriptor, 1);
}
} catch(IOException e) {
//
}
return ids;
}
public void playSound(short id, float rV, float lV) {
if(id != -1) {
soundPool.play(id, rV, lV, 0, 0, 1);
}
}
public void pauseSound() {
soundPool.autoPause();
}	
public void releaseSound() {
soundPool.release();
}
}

huangapple
  • 本文由 发表于 2020年9月14日 02:39:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/63874298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定