在Android上初始化AudioTrack是否有明显延迟?
我正试图通过录音和音轨将从麦克风获得的音频样本传递给扬声器。代码如下:在Android上初始化AudioTrack是否有明显延迟?,android,audio,Android,Audio,我正试图通过录音和音轨将从麦克风获得的音频样本传递给扬声器。代码如下: public class MainActivity extends Activity { AudioManager am = null; AudioRecord record =null; AudioTrack track =null; final int SAMPLE_FREQUENCY = 44100; final int SIZE_OF_RECORD_ARRAY = 1024;
public class MainActivity extends Activity {
AudioManager am = null;
AudioRecord record =null;
AudioTrack track =null;
final int SAMPLE_FREQUENCY = 44100;
final int SIZE_OF_RECORD_ARRAY = 1024; // 1024 ORIGINAL
final int WAV_SAMPLE_MULTIPLICATION_FACTOR = 1;
int i= 0;
boolean isPlaying = true;
class MyThread extends Thread{
private volatile boolean passThroughMode = true;
// /*
MyThread(){
super();
}
MyThread(boolean newPTV){
this.passThroughMode = newPTV;
}
// */
// /*
@Override
public void run(){
short[] lin = new short[SIZE_OF_RECORD_ARRAY];
int num = 0;
// am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); // -> MOVED THESE TO init()
// am.setMode(AudioManager.MODE_IN_COMMUNICATION);
record.startRecording();
track.play();
while (passThroughMode) {
// while (!isInterrupted()) {
num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
for(i=0;i<lin.length;i++)
lin[i] *= WAV_SAMPLE_MULTIPLICATION_FACTOR;
track.write(lin, 0, num);
}
// /*
record.stop();
track.stop();
record.release();
track.release();
// */
}
// */
// /*
public void stopThread(){
passThroughMode = false;
}
// */
}
MyThread newThread;
private void init() {
int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_IN_COMMUNICATION);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
// init(); // -> Moved this to onResume();
Log.d("MYLOG", "onCreate() called");
}
@Override
protected void onResume(){
super.onResume();
// newThread.stopThread();
Log.d("MYLOG", "onResume() called");
init();
newThread = new MyThread(true);
newThread.start();
}
@Override
protected void onPause(){
super.onPause();
Log.d("MYLOG", "onPause() called");
newThread.stopThread();
// android.os.Process.killProcess(android.os.Process.myPid());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void passStop(View view){
Button playBtn = (Button) findViewById(R.id.playBtn);
// /*
if(!isPlaying){
record.startRecording();
track.play();
isPlaying = true;
playBtn.setText("Pause");
}
else{
record.stop();
track.pause();
isPlaying=false;
playBtn.setText("Pass through");
}
// */
}
// /*
@Override
protected void onDestroy() {
super.onDestroy();
newThread.stopThread();
// android.os.Process.killProcess(android.os.Process.myPid());
// killProcess(android.os.Process.myPid());
// newThread.interrupt();
Log.d("MYLOG", "onDestroy() called");
}
// */
}
公共类MainActivity扩展活动{
AudioManager am=null;
录音记录=空;
AudioTrack track=null;
最终int样本_频率=44100;
记录数组的最终整数大小=1024;//1024原始
最终整数波形样本乘法因子=1;
int i=0;
布尔值isplay=true;
类MyThread扩展线程{
私有易失性布尔passThroughMode=true;
// /*
神话读物(){
超级();
}
MyThread(布尔newPTV){
this.passThroughMode=newPTV;
}
// */
// /*
@凌驾
公开募捐{
short[]lin=新的short[记录数组的大小];
int num=0;
//am=(AudioManager)this.getSystemService(Context.AUDIO_SERVICE);//->将它们移动到init()中
//am.setMode(AudioManager.MODE_IN_通信);
record.startRecording();
track.play();
while(passThroughMode){
//而(!isInterrupted()){
num=record.read(lin,0,记录数组的大小);
对于(i=0;我将其移动到onResume();
d(“MYLOG”,“onCreate()被调用”);
}
@凌驾
受保护的void onResume(){
super.onResume();
//newThread.stopThread();
d(“MYLOG”,“onResume()被调用”);
init();
newThread=newmythread(true);
newThread.start();
}
@凌驾
受保护的void onPause(){
super.onPause();
d(“MYLOG”,“onPause()调用”);
newThread.stopThread();
//android.os.Process.killProcess(android.os.Process.myPid());
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.main,menu);
返回true;
}
公共无效通行证(视图){
按钮playBtn=(按钮)findviewbyd(R.id.playBtn);
// /*
如果(!显示){
record.startRecording();
track.play();
isplay=true;
playBtn.setText(“暂停”);
}
否则{
record.stop();
track.pause();
isplay=false;
playBtn.setText(“传递”);
}
// */
}
// /*
@凌驾
受保护的空onDestroy(){
super.ondestory();
newThread.stopThread();
//android.os.Process.killProcess(android.os.Process.myPid());
//killProcess(android.os.Process.myPid());
//newThread.interrupt();
d(“MYLOG”,“onDestroy()被调用”);
}
// */
}
程序应该启动一个执行传递的线程。该线程从应用程序的onResume()开始,因此应该立即启动。但在开始时总是有1.5~2秒的延迟。我认为这可能是因为onCreate()和其他初始化在onResume()中线程开始之前发生,但如果我将
lin
数组的内容打印到文件中,它总是在开始处写入一个长的0行,这表明延迟可能不是由于初始化所需的时间造成的。那么这里看到的延迟是什么?跟踪.play()吗需要很长的时间才能开始播放?我正在调试一个类似的延迟,虽然我还没有完整的答案,但AudioManager似乎在设置模式调用(am.setMode(AudioManager.MODE\u in_COMMUNICATION))中引入了延迟。user13267,您发现过这个问题的答案吗?