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

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

SoundPool loads slowly and is weird with MotionEvent

问题

  1. public class MainActivityPiano extends AppCompatActivity {
  2. //所有声音ID
  3. public static final int SOUND_1 = 1;
  4. public static final int SOUND_2 = 2;
  5. SoundPool mSoundPool;
  6. HashMap<Integer, Integer> mSoundMap;
  7. static int streamID;
  8. @Override
  9. protected void onStart() {
  10. super.onStart();
  11. mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
  12. mSoundMap = new HashMap<Integer, Integer>();
  13. if(mSoundPool != null){
  14. mSoundMap.put(SOUND_1, mSoundPool.load(this, R.raw.piano_tone1, 1));
  15. mSoundMap.put(SOUND_2, mSoundPool.load(this, R.raw.piano_tone2, 1));
  16. //至少要加载十二个不同的声音文件...
  17. }
  18. //播放按钮和/或钢琴键
  19. Button pianoKey1 = this.findViewById(R.id.piano_key1);
  20. Button pianoKey2 = this.findViewById(R.id.piano_key2);
  21. //...
  22. //播放按钮和/或钢琴键
  23. pianoKey1.setOnTouchListener(new View.OnTouchListener() {
  24. public boolean onTouch(View view, MotionEvent motionEvent) {
  25. return playSound(SOUND_1, motionEvent, view);
  26. }
  27. });
  28. pianoKey2.setOnTouchListener(new View.OnTouchListener() {
  29. public boolean onTouch(View view, MotionEvent motionEvent) {
  30. return playSound(SOUND_2, motionEvent, view);
  31. }
  32. });
  33. //...
  34. }
  35. @Override
  36. protected void onCreate(Bundle savedInstanceState) {
  37. super.onCreate(savedInstanceState);
  38. setContentView(R.layout.layout_piano);
  39. }
  40. public boolean playSound(int sound, MotionEvent m, View v) {
  41. switch (m.getAction()) {
  42. case MotionEvent.ACTION_DOWN:
  43. streamID = mSoundPool.play(sound, 1, 1, 1, 0, 1.0f);
  44. break;
  45. case MotionEvent.ACTION_CANCEL:;
  46. mSoundPool.stop(streamID);
  47. break;
  48. case MotionEvent.ACTION_UP:
  49. mSoundPool.stop(streamID);
  50. break;
  51. case MotionEvent.ACTION_MOVE:
  52. }
  53. return true;
  54. }
  55. @Override
  56. protected void onPause() {
  57. mSoundPool.autoPause();
  58. super.onPause();
  59. }
  60. }
英文:

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:

  1. public class MainActivityPiano extends AppCompatActivity {
  2. //all soundIDs
  3. public static final int SOUND_1 = 1;
  4. public static final int SOUND_2 = 2;
  5. SoundPool mSoundPool;
  6. HashMap&lt;Integer, Integer&gt; mSoundMap;
  7. static int streamID;
  8. @Override
  9. protected void onStart() {
  10. super.onStart();
  11. mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
  12. mSoundMap = new HashMap&lt;Integer, Integer&gt;();
  13. if(mSoundPool != null){
  14. mSoundMap.put(SOUND_1, mSoundPool.load(this, R.raw.piano_tone1, 1));
  15. mSoundMap.put(SOUND_2, mSoundPool.load(this, R.raw.piano_tone2, 1));
  16. //at least twelve different sound files have to be loaded...
  17. }
  18. //play buttons and/or piano keys
  19. Button pianoKey1 = this.findViewById(R.id.piano_key1);
  20. Button pianoKey2 = this.findViewById(R.id.piano_key2);
  21. //...
  22. //play buttons and/or pianokeys
  23. pianoKey1.setOnTouchListener(new View.OnTouchListener() {
  24. public boolean onTouch(View view, MotionEvent motionEvent) {
  25. return playSound(SOUND_1, motionEvent, view);
  26. }
  27. });
  28. pianoKey2.setOnTouchListener(new View.OnTouchListener() {
  29. public boolean onTouch(View view, MotionEvent motionEvent) {
  30. return playSound(SOUND_2, motionEvent, view);
  31. }
  32. });
  33. //...
  34. }
  35. @Override
  36. protected void onCreate(Bundle savedInstanceState) {
  37. super.onCreate(savedInstanceState);
  38. setContentView(R.layout.layout_piano);
  39. }
  40. public boolean playSound(int sound, MotionEvent m, View v) {
  41. switch (m.getAction()) {
  42. case MotionEvent.ACTION_DOWN:
  43. streamID = mSoundPool.play(sound, 1, 1, 1, 0, 1.0f);
  44. break;
  45. case MotionEvent.ACTION_CANCEL:;
  46. mSoundPool.stop(streamID);
  47. break;
  48. case MotionEvent.ACTION_UP:
  49. mSoundPool.stop(streamID);
  50. break;
  51. case MotionEvent.ACTION_MOVE:
  52. }
  53. return true;
  54. }
  55. @Override
  56. protected void onPause() {
  57. mSoundPool.autoPause();
  58. super.onPause();
  59. }
  60. }

答案1

得分: 2

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

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

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

  1. public class Sound {
  2. private static SoundPool soundPool;
  3. public short[] getSound(Activity activity, String...fileNames) {
  4. soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
  5. short[] ids = new short[fileNames.length];
  6. activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
  7. try {
  8. AssetManager assetManager = activity.getAssets();
  9. for(int i = 0; i < fileNames.length; i++) {
  10. AssetFileDescriptor descriptor = assetManager.openFd(fileNames[i]);
  11. ids[i] = (short) soundPool.load(descriptor, 1);
  12. }
  13. } catch(IOException e) {
  14. //
  15. }
  16. return ids;
  17. }
  18. public void playSound(short id, float rV, float lV) {
  19. if(id != -1) {
  20. soundPool.play(id, rV, lV, 0, 0, 1);
  21. }
  22. }
  23. public void pauseSound() {
  24. soundPool.autoPause();
  25. }
  26. public void releaseSound() {
  27. soundPool.release();
  28. }
  29. }
英文:

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.

  1. public class Sound {
  2. private static SoundPool soundPool;
  3. public short[] getSound(Activity activity, String...fileNames) {
  4. soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
  5. short[] ids = new short[fileNames.length];
  6. activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
  7. try {
  8. AssetManager assetManager = activity.getAssets();
  9. for(int i = 0; i &lt; fileNames.length; i++) {
  10. AssetFileDescriptor descriptor = assetManager.openFd(fileNames[i]);
  11. ids[i] = (short) soundPool.load(descriptor, 1);
  12. }
  13. } catch(IOException e) {
  14. //
  15. }
  16. return ids;
  17. }
  18. public void playSound(short id, float rV, float lV) {
  19. if(id != -1) {
  20. soundPool.play(id, rV, lV, 0, 0, 1);
  21. }
  22. }
  23. public void pauseSound() {
  24. soundPool.autoPause();
  25. }
  26. public void releaseSound() {
  27. soundPool.release();
  28. }
  29. }

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:

确定