2014-11-14 88 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); 
    } 
}