sig*_*eta 1 audio multithreading android loops
我正在尝试编写一个Android应用程序,其中包括一个节拍器.这需要能够定期以准确的时间播放各种声音,但是现在我正在努力让一个人工作.训练有素的听众很容易检测到超过2-3ms的误差.这是我的播放主题:
protected void onCreate(Bundle savedInstanceState) {
// stuff
int minBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
}
public void startThread(View view){
mThread = new Thread (new Runnable() {
public void run(){
Log.d(TAG, "Starting met at tempo: " + mTempo + " Interval: " + (60000 / mTempo) );
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
InputStream in = getResources().openRawResource(R.raw.chirp);
byte [] output = getBytesFromStream(in);
Log.d(TAG, "Output length: " + output.length);
mAudioTrack.play();
while (mRunning) {
mAudioTrack.write(output, 0, output.length);
try {
Thread.sleep(60000 / mTempo);
} catch (InterruptedException e) {
}
}
mAudioTrack.release();
}
});
mThread.start();
}
Run Code Online (Sandbox Code Playgroud)
R.raw.chirp是Audacity中生成的正弦波.1000hz在44100hz采样100ms,因此它应该是大约4410个样本.在Nexus 4上进行测试,速度设置为200bpm(即啁啾应该每300ms播放一次),声音似乎很好,但是为了好的测量,我通过线路输入将输出录制到Audacity中.我注意到两个奇怪的事情:
1)唧唧声似乎是在298-299毫秒之间播放.这在很大程度上是一致的,但是1-2ms将节奏改为201bpm,这足以使它与参考节拍器不同步.
2)第二个怪异并不是一直可重复的,但是在看似随机数量的唧唧声后,会有一个啁啾延迟整整20ms.
我可以想象的第二个问题可以解释; 也许是一个线程/优先问题?但是,第一个问题令我感到困惑.我想如果有什么唧唧声应该迟到,而不是早点.我相信这些问题是相关的,我也开始认为我没有正确理解正在发生的事情并且正在做一些非常基本的错误(这是我第一次使用任何类型的音频代码.)
任何帮助将非常感激.
除了目前使用较差的定时源之外,还有一个更大的问题,即Android在请求播放和实际发生时间之间仅提供相对宽松且基本上可变的耦合.
要解决这个问题,请继续播放声音 - 主要是静音 - 并在所需的时间混合您想要的点击.不使用任何普通的软件可访问系统时钟来确定时间,而是使用先前写入的采样计数,以便您的时序与数模转换器采样时钟具有固定的关系.
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |