英文:
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<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();
}
}
答案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 < 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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论