Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android和Thread&;中的实时音频录制和播放;回调处理_Android_Audio Streaming_Audio Recording_Audiorecord - Fatal编程技术网

Android和Thread&;中的实时音频录制和播放;回调处理

Android和Thread&;中的实时音频录制和播放;回调处理,android,audio-streaming,audio-recording,audiorecord,Android,Audio Streaming,Audio Recording,Audiorecord,我想录制并播放现场音频。就用户界面而言,该应用程序只有三个按钮:一个用于开始录制和流式播放,一个用于播放预录制的文件,最后一个用于停止当前任务(录制/播放)。为此,我分别使用了录音和音轨课程进行录音和播放。我的程序看起来像 /** *@作者阿米特 * */ 正如您可能看到的,startPlaying()和stopPlaying()函数尚未实现,因此我们不必讨论它们。目前我正在尝试录制和播放。当我运行程序时,它会播放录制的音频,但音频似乎来自远方。另一个问题是应用程序的UI线程挂起,尽管我有一个

我想录制并播放现场音频。就用户界面而言,该应用程序只有三个按钮:一个用于开始录制和流式播放,一个用于播放预录制的文件,最后一个用于停止当前任务(录制/播放)。为此,我分别使用了录音音轨课程进行录音和播放。我的程序看起来像

/** *@作者阿米特 * */


正如您可能看到的,
startPlaying()
stopPlaying()
函数尚未实现,因此我们不必讨论它们。目前我正在尝试录制和播放。当我运行程序时,它会播放录制的音频,但音频似乎来自远方。另一个问题是应用程序的UI线程挂起,尽管我有一个单独的线程来读取音频。请帮助……

如果您的要求是在录制时播放(意味着循环播放音频),则在您的while循环线程中,您正在存储录制的数据(audioData bufer),您可以将其复制到while循环中的player对象(player.write(audioData,0,numShortsRead);)。你们说你们的UI线程被卡住了,这可能是因为你们给了录音线程更多的优先级

检查下面的代码,我用于上面的环回要求

boolean m_isRun=true;
public void loopback() {
        // Prepare the AudioRecord & AudioTrack
        try {
            buffersize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT);

            if (buffersize <= BUF_SIZE) {
                buffersize = BUF_SIZE;
            }
            Log.i(LOG_TAG,"Initializing Audio Record and Audio Playing objects");

            m_record = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, buffersize * 1);

            m_track = new AudioTrack(AudioManager.STREAM_ALARM,
                    SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, buffersize * 1,
                    AudioTrack.MODE_STREAM);

            m_track.setPlaybackRate(SAMPLE_RATE);
        } catch (Throwable t) {
            Log.e("Error", "Initializing Audio Record and Play objects Failed "+t.getLocalizedMessage());
        }

        m_record.startRecording();
        Log.i(LOG_TAG,"Audio Recording started");
        m_track.play();
        Log.i(LOG_TAG,"Audio Playing started");

        while (m_isRun) {
            m_record.read(buffer, 0, BUF_SIZE);
            m_track.write(buffer, 0, buffer.length);
        }

        Log.i(LOG_TAG, "loopback exit");
    }

    private void do_loopback() {
        m_thread = new Thread(new Runnable() {
            public void run() {
                loopback();
            }
        });
布尔m_isRun=true;
公共void环回(){
//准备录音带和音轨
试一试{
buffersize=AudioRecord.getMinBufferSize(采样率,
AudioFormat.CHANNEL\u配置\u单声道,
音频格式。编码(PCM(16位);

如果(buffersize我的建议是使用异步任务,另一种称为无痛线程。这是利用Android线程的最佳方式。您可以通过分割现有程序来使用后台处理、预执行和后执行方法


选择一种速率、配置和格式。然后坚持使用它,或者让您的init函数接收属性并切换。@L7ColWinters谢谢,请看编辑后的问题……您希望的功能是否能够在录制时说些什么,并且在不点击播放的情况下自动播放?这就是您当前的代码确实可以,但它确实挂起并播放非常高的音调静噪,这可能是反馈。@L7ColWinters,是的,这就是我想要的(要录制并播放它,播放按钮将用于播放尚未实现的文件),你有我的问题,为什么我的程序挂起并播放如此糟糕的音频…我需要对录音和音轨使用相同的缓冲区大小吗?plz帮助…你是否在AndroidManifiest.xml中设置了必要的权限,我已经分配了以下权限,你如何确定BUF_大小值?我还使用了positionUpdateListener()你对它的重要性有什么看法…还有一件事while循环的停止条件是什么?在这个过程中,你的主线程是否挂起?对于停止条件,我根据我的要求使用adb命令中的keyevent。在这一点上,我制作了“m_isRun”若为false,可以使用超时线程或按钮事件。我认为主线程不会停止,以前我使用的是按钮事件而不是keyevents。如果这确实是一个环回要求,我认为也不需要位置更新。在BUF_SIZE的情况下,当我仅使用getMinBufferSize()时,它给了缓冲区不足的问题。在网络链接中,有些地方提到缓冲区大小应该大于采样率。我继续这样说。但我不能说这是解决缓冲区大小问题的完美解决方案。你能解释一下这个m_isRun变量的用途吗?我还想同时录制和播放音频,我是一个ginner在这方面需要一些帮助:)+1用于回答M_isRun是一个简单的布尔变量,我用它来启动/停止唱片播放
boolean m_isRun=true;
public void loopback() {
        // Prepare the AudioRecord & AudioTrack
        try {
            buffersize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT);

            if (buffersize <= BUF_SIZE) {
                buffersize = BUF_SIZE;
            }
            Log.i(LOG_TAG,"Initializing Audio Record and Audio Playing objects");

            m_record = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, buffersize * 1);

            m_track = new AudioTrack(AudioManager.STREAM_ALARM,
                    SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, buffersize * 1,
                    AudioTrack.MODE_STREAM);

            m_track.setPlaybackRate(SAMPLE_RATE);
        } catch (Throwable t) {
            Log.e("Error", "Initializing Audio Record and Play objects Failed "+t.getLocalizedMessage());
        }

        m_record.startRecording();
        Log.i(LOG_TAG,"Audio Recording started");
        m_track.play();
        Log.i(LOG_TAG,"Audio Playing started");

        while (m_isRun) {
            m_record.read(buffer, 0, BUF_SIZE);
            m_track.write(buffer, 0, buffer.length);
        }

        Log.i(LOG_TAG, "loopback exit");
    }

    private void do_loopback() {
        m_thread = new Thread(new Runnable() {
            public void run() {
                loopback();
            }
        });