2017-12-05 10 views
6

문제가 있습니다. 같은 시간에 소리를 내고 싶습니다.정확한 시간에 3 개 이상의 짧은 소리를 재생합니다. SoundPool (피아노 코드)

나는 루프 (피아노 사운드)에서 3-5 단음을 연주하고, 첫 번째 1ms, 두 번째 17ms 등 지연이 있으며, 마지막 사운드는 60-90ms까지 지연됩니다.

나는 SoundPool을 사용하고 있습니다.

누구나 이런 문제가 있거나이 문제를 해결할 수있는 라이브러리를 사용하고 있습니까 (여러 개의 짧은 소리를 동기화하여 시작하십시오)? 당신이 리스너(OnLoadCompleteListener)를 구현해야처럼

Observable.timer(150, TimeUnit.MILLISECONDS, Schedulers.single()) 
      .repeat() 
      .subscribe(aLong -> { 
       for (int soundId = 55; i < 60; i++) { 
        soundPool.play(soundId , 1f, 1f, 1, 0, 1); 
       } 
      }); 

답변

0

것 같다 :

다음은 예제 테스트 샘플 (나는 RxJava를 사용하지만 RxJava로하고없이 테스트 한)입니다. SoundPool은 문서에 명시된대로 비동기 적으로 오디오 파일을로드하므로 지연이 발생하는 이유입니다.

찾을 수 3이 동작하는 예제는 사운드가 이미로드 here

public class SoundManager { 

    public static int SOUNDPOOLSND_MENU_BTN   = 0; 
    public static int SOUNDPOOLSND_WIN    = 1; 
    public static int SOUNDPOOLSND_LOOSE   = 2; 
    public static int SOUNDPOOLSND_DRAW    = 3; 
    public static int SOUNDPOOLSND_TICK1   = 4; 
    public static int SOUNDPOOLSND_TICK2   = 5; 
    public static int SOUNDPOOLSND_OUT_OF_TIME  = 6; 
    public static int SOUNDPOOLSND_HISCORE   = 7; 
    public static int SOUNDPOOLSND_CORRECT_LETTER = 8; 

    public static boolean isSoundTurnedOff; 

    private static SoundManager mSoundManager; 

    private SoundPool mSoundPool; 
    private SparseArray <Integer> mSoundPoolMap; 
    private AudioManager mAudioManager; 

    public static final int maxSounds = 4; 

    public static SoundManager getInstance(Context context) 
    { 
     if (mSoundManager == null){ 
      mSoundManager = new SoundManager(context); 
     } 

     return mSoundManager; 
    } 

    public SoundManager(Context mContext) 
    { 
     mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); 
     mSoundPool = new SoundPool(maxSounds, AudioManager.STREAM_MUSIC, 0); 

     mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() { 
      public void onLoadComplete(SoundPool soundPool, int sampleId,int status) { 
      loaded = true; 
      } 
     }); 

     mSoundPoolMap = new SparseArray<Integer>(); 
     mSoundPoolMap.put(SOUNDPOOLSND_MENU_BTN, mSoundPool.load(mContext, R.raw.menubutton, 1)); 
     mSoundPoolMap.put(SOUNDPOOLSND_WIN, mSoundPool.load(mContext, R.raw.win, 1)); 
     mSoundPoolMap.put(SOUNDPOOLSND_LOOSE, mSoundPool.load(mContext, R.raw.lose, 1)); 
     mSoundPoolMap.put(SOUNDPOOLSND_TICK1, mSoundPool.load(mContext, R.raw.tick_0, 1)); 
     mSoundPoolMap.put(SOUNDPOOLSND_TICK2, mSoundPool.load(mContext, R.raw.tick_1, 1)); 
     mSoundPoolMap.put(SOUNDPOOLSND_OUT_OF_TIME, mSoundPool.load(mContext, R.raw.out_of_time, 1)); 
     mSoundPoolMap.put(SOUNDPOOLSND_HISCORE, mSoundPool.load(mContext, R.raw.personal_highscore, 1)); 
     mSoundPoolMap.put(SOUNDPOOLSND_CORRECT_LETTER, mSoundPool.load(mContext, R.raw.correct_letter, 1)); 

     // testing simultaneous playing 
     int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
     mSoundPool.play(mSoundPoolMap.get(0), streamVolume, streamVolume, 1, 20, 1f); 
     mSoundPool.play(mSoundPoolMap.get(1), streamVolume, streamVolume, 1, 2, 1f); 
     mSoundPool.play(mSoundPoolMap.get(2), streamVolume, streamVolume, 1, 0, 1f); 


    } 

    public void playSound(int index) { 
     if (isSoundTurnedOff) 
      return; 

     int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
     mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f); 
    } 

    public static void clear() 
    { 
     if (mSoundManager != null){ 
      mSoundManager.mSoundPool = null; 
      mSoundManager.mAudioManager = null; 
      mSoundManager.mSoundPoolMap = null; 
     } 
     mSoundManager = null; 
    } 
} 
+0

, 나는 그것이 어쩌면 – Wrobel

+0

야아을 스레딩/동기화 문제라고 생각 소리, 나는 사람들이 두 개의 스레드를 사용하려고 그물에 이러한 솔루션을 보았다 2 개의 소리를 위해 그것들을 동기화 할 수는 있지만, 바로 소리를 지을 수는 없다. – Rainmaker

+0

다른 방법은 소리를 섞어 하나의 소리로 연주하는 것이다. 일반적인 해결책이다. – Rainmaker