2014-11-14 87 views
0

我是編程的新手,我嘗試做一個播放音頻樣本的音頻應用程序,但我想同步所有這些音頻應用程序。就像一個計數爲0,1,2,3的驗證循環一樣。當用戶點擊「播放/停止」時,如果循環爲「0」,則音頻僅啓動/停止。 這是我的課程之一,我設置了遊戲和停止方法。聲音同步?

public class Sample { 

private static final int SAMPLE_RATE = 44100; 

private String name; 
private AudioTrack audioTrack; 
private int loopPoint; 
int soundId; 
private Uri uri; 
private Context context; 
private MediaPlayer currentPlayer; 
private boolean isImported; 

private boolean isLooping = false; 

public Sample(String name, byte[] soundBytes) { 
    this.name = name; 
    loopPoint = soundBytes.length/2; 
    isImported = false; 

    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, 
      AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 
      soundBytes.length, AudioTrack.MODE_STATIC); 

    audioTrack.write(soundBytes, 0, soundBytes.length); 
} 

public Sample(String name, File file, Context context) { 
    this.name = name; 
    this.context = context; 
    isImported = true; 

    uri = Uri.parse(file.getAbsolutePath()); 
} 

public String getName() { 
    return name; 
} 

public void updateSample(byte[] soundBytes) { 
    if (!isImported) { 
     audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, 
       AudioFormat.CHANNEL_OUT_MONO, 
       AudioFormat.ENCODING_PCM_16BIT, soundBytes.length, 
       AudioTrack.MODE_STATIC); 

     audioTrack.write(soundBytes, 0, soundBytes.length); 
    } 
} 

public void play(boolean isLooped) { 



     isLooping = isLooped; 
     audioTrack.setPlaybackRate(88200); 

     if (isImported) { 
      if (currentPlayer != null) { 
       currentPlayer.seekTo(0); 
      } else { 
       currentPlayer = MediaPlayer.create(context, uri); 

      } 

      currentPlayer.setLooping(isLooped); 
      currentPlayer.start(); 
     } else { 
      audioTrack.stop(); 
      audioTrack.reloadStaticData(); 

      if (isLooped) { 
       audioTrack.setLoopPoints(0, loopPoint, -1); 
      } else { 
       audioTrack.setLoopPoints(0, 0, 0); 
      } 

      audioTrack.play(); 
     } 

} 

public void stop() { 
    try { 
     if (isImported && currentPlayer != null) { 
      currentPlayer.stop(); 
      currentPlayer.release(); 
      currentPlayer = null; 
     } else if (!isImported && audioTrack != null) { 
      audioTrack.stop(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    isLooping = false; 
} 

public boolean isImported() { 
    return isImported; 
} 

public boolean isLooping() { 
    return isLooping; 
} 

} 
+0

目前尚不清楚你的問題是什麼。請更詳細地解釋你正在嘗試做什麼,最重要的是你從這裏列出的代碼中得到的意外/不期望的結果是什麼? – 2014-11-14 22:48:36

+0

@SoundConception,代碼正在工作,它爲每個樣本設置播放和暫停。我的問題是,我如何同步所有樣本。就像,所有樣品必須在酒吧的第一拍中停下來或停頓,你知道嗎?例如,iOS的Novation啓動板。 – FabioDu 2014-11-15 00:12:15

回答

0

您可以使用currentPlayer.getCurrentPosition()以毫秒爲單位獲取樣本播放的當前位置。

說你的節奏是120 bpm。這是每拍半秒。
現在說我們在4/4時間,那麼我們在一個酒吧有4個節拍,所以每個酒吧總共2秒長。 因此,只有在條的開始處停止播放,當CurrentPosition爲2000毫秒的倍數時,您將需要停止播放。

你可以做的MediaPlayer停止在正確的時間用類似下面的邏輯:

onUserPressedStop() { 

    // Check if the remainder is 0 when you divide by bar length 
    if ((currentPlayer.getCurrentPosition() % barLengthMillis) == 0) { 
     // We are at the start of a bar so stop and release the MediaPlayer 
     stopMyMediaPlayer();} 

    // Else were not at the start of a bar, so find out how much longer we need to wait 
    else { 
     int waitTime = currentPlayer.getCurrentPosition() % barLengthMillis; 

     // Stop and release the MediaPlayer once the necessary time has elapsed 
     final Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       stopMyMediaPlayer(); 
      } 
     }, waitTime); 
    } 
}