在 Android 中将语音缓冲区从麦克风路由到扬声器

发布于 2024-10-21 00:55:22 字数 185 浏览 1 评论 0原文

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

有什么想法吗?
谢谢。

I need to increase voice, recorder from microphone on Android device.
I try to read buffer from AudioRecord and then write it to AudioTrack... It works, but with delay, because min buffer size, returned bu method AudioRecord.getMinBufferSize with frequency like 44100 is 4480 bytes.

Any ideas?
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独难免 2024-10-28 00:55:22

我有这段代码

AudioRecord 和 AudioTrack 延迟

但碰巧有 20ms 的延迟,并且我需要解决它
上面的代码似乎播放了一些东西,但没有麦克风输入,它有效吗?

谢谢!

I have this code

AudioRecord and AudioTrack latency

But it happens to that there is a 20ms delay, and I need to solve it,
The code above seems that plays something but there is no mic input, does it work?

Thanks!

月下凄凉 2024-10-28 00:55:22

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

I noticed there is no threading code. I would recommend trying to thread the recording and playback aspects and see if that better avoids the latency. Fill the buffer in from the mic one thread, and read it out to the speaker in the other. Avoid buffer overflows and underruns by handling those situations with some action (e.g. clearing the buffer for overflows). In theory, one should keep up with the other.

深巷少女 2024-10-28 00:55:22
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();
        }   
    }
}
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();
        }   
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文