java - SoundPool 加载缓慢并且在 MotionEvent 中很奇怪
问题描述
你好! 我对编程很陌生,我遇到了一些关于 SoundPool 的问题。我正在尝试构建一个简单的钢琴应用程序,但尚未找到解决方案。我使用的音频文件是 midi (.mid)
我的代码当前存在的问题:
- 音频文件加载速度很慢,我必须等待几秒钟才能让 SOUND_12 准备好。
- 如果我只用一根手指,它工作得很好,但是当我添加另一根手指时,第一根手指/声音会卡住。
我当前的代码:
public class MainActivityPiano extends AppCompatActivity {
//all soundIDs
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));
//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();
}
}
解决方案
您可能想要预加载您的声音,然后通过引用它们的 id 来播放它们。
该short[]
数组将包含fileNames
您传递给的相应文件的 IDgetSound()
创建一个单独的类Sound.java
:在您的 Main Activity 中,您可以创建一个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();
}
}
推荐阅读
- python - python过滤元字符,同时保持单词的完整性
- python - 用python查询bloomberg api;行情不返回任何东西
- c - major() 和 minor() 给出与 ls 不同的数字
- dart - 隐藏 TextField 选择句柄
- dart - Future.wait() 用于多个期货
- php - 无法在项目 simpleSpringRestWeb 上执行目标 org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war):组装 WAR 时出错:webxml
- postgresql - 有没有办法通过其配置文件为 PostgreSQL 进程设置 CPU 亲和性?
- php - 是否可以使用 php 和表单创建数据库、用户、密码(只有 cpanel,没有 WHM)
- javascript - 有人可以解释 setInterval 计数器是如何工作的吗?
- javascript - 从模板应用程序进行 API 调用的最佳策略?