有没有在Android初始化AudioTrack任何显著延误? [英] Is there any significant delay in initializing AudioTrack on Android?

查看:108
本文介绍了有没有在Android初始化AudioTrack任何显著延误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过在MIC使用AudioRecord和AudioTrack扬声器获得的音频采样。这里是code:

I am trying to pass through the audio samples obtained at the MIC to the speaker using AudioRecord and AudioTrack. Here is the code:

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");
    }
    // */
}  

该计划应该开始通过执行一通线程。线程开始在应用程序的onResume(),因此应立即启动。但总是在开始一1.5〜2秒的延迟。我认为这可能是因为的onCreate()和其他初始化发生的线程在onResume()开始前的,但如果我打印出来的数组的内容到文件,它总是在指示延迟可能不是由于TOT初始化需要他刚开始的时候写的0一长排。那么,什么是这个延迟在这里看到?是否track.play()需要一个显著的时间开始播放?

The program is supposed to start a Thread that performs a pass through. The Thread starts at the app's onResume() so should start immediately. But there is always a 1.5~2 sec delay at the beginning. I assumed that it might be because of onCreate() and other initialization happening before the Thread starts in onResume(), but if I print out the contents of the lin array to file, it always writes a long line of 0's at the beginning which indicates the delay is probably not due tot he time required for initializing. So what is this delay seen here? Does track.play() need a significant time to start playing?

推荐答案

我调试了类似的延迟,虽然我没有完整的答案,看来这AudioManager推出了setMode呼叫延迟( am.setMode(AudioManager.MODE_IN_COMMUNICATION))。

I am debugging a similar delay, and while I don't have the complete answer yet, it appears that the AudioManager is introducing the delay in the setMode call (am.setMode(AudioManager.MODE_IN_COMMUNICATION)).

这篇关于有没有在Android初始化AudioTrack任何显著延误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆