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,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,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.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的{​​{1}}中相应文件的ID。

创建一个单独的类getSound(): 在您的主要活动中,您可以创建一个Sound.java对象,并在Sound中加载一次声音,然后使用其ID播放它们。

onCreate()