【问题标题】:Route voice buffer from mic to speaker in Android在Android中将语音缓冲区从麦克风路由到扬声器
【发布时间】:2011-03-09 10:35:11
【问题描述】:

我需要在 Android 设备上通过麦克风增加语音、录音机。 我尝试从AudioRecord 读取缓冲区,然后将其写入AudioTrack... 它可以工作,但有延迟,因为最小缓冲区大小,返回 bu 方法AudioRecord.getMinBufferSize,频率为 44100 为 4480 字节。

有什么想法吗?
谢谢。

【问题讨论】:

    标签: android audiorecord


    【解决方案1】:

    我有这个代码

    AudioRecord and AudioTrack latency

    但碰巧有20ms的延迟,我需要解决它, 上面的代码好像在播放什么但是没有mic输入,有没有用?

    谢谢!

    【讨论】:

      【解决方案2】:

      我注意到没有线程代码。我建议尝试对录制和播放方面进行线程化,看看是否能更好地避免延迟。从麦克风一个线程填充缓冲区,然后将其读出到另一个线程中的扬声器。通过采取一些措施(例如清除缓冲区溢出)来处理这些情况,避免缓冲区溢出和欠载。理论上,一个应该跟上另一个。

      【讨论】:

        【解决方案3】:
        package org.example.audio;
        
        import android.app.Activity;
        import android.media.MediaPlayer;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.View;
        import android.view.View.OnClickListener;
        import android.widget.Button;
        import android.widget.Toast;
        
        public class AudioDemo extends Activity implements OnClickListener {
            private static final String TAG = "AudioDemo";
            private static final String isPlaying = "Media is Playing"; 
            private static final String notPlaying = "Media has stopped Playing"; 
        
            MediaPlayer player;
            Button playerButton;
        
            public void onClick(View v) {
                Log.d(TAG, "onClick: " + v);
                if (v.getId() == R.id.play) {
                    playPause();
                }
            }
        
            /** Called when the activity is first created. */
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
        
                //player = MediaPlayer.create(this, R.raw.robotrock);
                player.setLooping(false); // Set looping
        
                // Get the button from the view
                playerButton = (Button) this.findViewById(R.id.play);
                playerButton.setText(R.string.stop_label);
                playerButton.setOnClickListener(this);
        
                // Begin playing selected media
                demoPlay();
        
                // Release media instance to system
                player.release();
            }
        
            @Override
            public void onPause() {
                super.onPause();
                player.pause();
            }
        
            // Initiate media player pause
            private void demoPause(){
                player.pause();
                playerButton.setText(R.string.play_label);
                Toast.makeText(this, notPlaying, Toast.LENGTH_LONG).show();
                Log.d(TAG, notPlaying);
            }
        
            // Initiate playing the media player
            private void demoPlay(){
                player.start();
                playerButton.setText(R.string.stop_label);
                Toast.makeText(this, isPlaying, Toast.LENGTH_LONG).show();
                Log.d(TAG, isPlaying);
            }
        
            // Toggle between the play and pause
            private void playPause() {
                if(player.isPlaying()) {
                    demoPause();
                } else {
                    demoPlay();
                }   
            }
        }
        

        【讨论】:

        • 这是什么?这是 MediaPlayer 使用的简单示例...对我没有帮助
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-06
        • 2012-02-07
        • 1970-01-01
        • 2014-08-11
        • 2014-10-31
        • 1970-01-01
        相关资源
        最近更新 更多