在android中使用AudioRecord录制音频

发布于 2024-11-24 19:27:06 字数 7639 浏览 1 评论 0原文

从下面的代码我可以创建 test.pcm 文件,但我无法在手机或电脑上播放它。

我也厌倦了 test.mp3、test.wav 和 test.raw。我得知播放器不支持这种类型的文件。

有谁知道我如何播放我使用 AudioRecord 录制的文件?

使用下面的代码我从麦克风获取短路数组并将其写入 SdCard。

这是代码:

package com.anroid.AudioProcess;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;


public class AudioProcess extends Activity {
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Record 20 seconds of audio.
        Recorder recorderInstance = new Recorder();
        Thread th = new Thread(recorderInstance);
        recorderInstance.setFileName(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.pcm"));
        th.start();
        recorderInstance.setRecording(true);
        synchronized (this) {
        try {
            this.wait(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        }
        recorderInstance.setRecording(false);
        try {
            th.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
}





 class Recorder implements Runnable {
    private int frequency;
    private int channelConfiguration;
    private volatile boolean isPaused;
    private File fileName;
    private volatile boolean isRecording;
    private final Object mutex = new Object();

    // Changing the sample resolution changes sample type. byte vs. short.
    private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

    /**
     * 
     */
    public Recorder() {
        super();
        this.setFrequency(11025);
        this.setChannelConfiguration(AudioFormat.CHANNEL_CONFIGURATION_MONO);
        this.setPaused(false);
    }

    public void run() {
        // Wait until we're recording...
        synchronized (mutex) {
            while (!this.isRecording) {
                try {
                    mutex.wait();
                } catch (InterruptedException e) {
                    throw new IllegalStateException("Wait() interrupted!", e);
                }
            }
        }

        // Open output stream...
        if (this.fileName == null) {
            throw new IllegalStateException("fileName is null");
        }
        BufferedOutputStream bufferedStreamInstance = null;
        if (fileName.exists()) {
            fileName.delete();
        }
        try {
            fileName.createNewFile();
        } catch (IOException e) {
            throw new IllegalStateException("Cannot create file: " + fileName.toString());
        }
        try {
            bufferedStreamInstance = new BufferedOutputStream(
                    new FileOutputStream(this.fileName));
        } catch (FileNotFoundException e) {
            throw new IllegalStateException("Cannot Open File", e);
        }
        DataOutputStream dataOutputStreamInstance = 
            new DataOutputStream(bufferedStreamInstance);

        // We're important...
        android.os.Process
                .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

        // Allocate Recorder and Start Recording...
        int bufferRead = 0;
        int bufferSize = AudioRecord.getMinBufferSize(this.getFrequency(),
                this.getChannelConfiguration(), this.getAudioEncoding());
        AudioRecord recordInstance = new AudioRecord(
                MediaRecorder.AudioSource.MIC, this.getFrequency(), this
                        .getChannelConfiguration(), this.getAudioEncoding(),
                bufferSize);
        short[] tempBuffer = new short[bufferSize];
        recordInstance.startRecording();
        while (this.isRecording) {
            // Are we paused?
            synchronized (mutex) {
                if (this.isPaused) {
                    try {
                        mutex.wait(250);
                    } catch (InterruptedException e) {
                        throw new IllegalStateException("Wait() interrupted!",
                                e);
                    }
                    continue;
                }
            }

            bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
            if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
                throw new IllegalStateException(
                        "read() returned AudioRecord.ERROR_INVALID_OPERATION");
            } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) {
                throw new IllegalStateException(
                        "read() returned AudioRecord.ERROR_BAD_VALUE");
            } else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
                throw new IllegalStateException(
                        "read() returned AudioRecord.ERROR_INVALID_OPERATION");
            }
            try {
                for (int idxBuffer = 0; idxBuffer < bufferRead; ++idxBuffer) {
                    dataOutputStreamInstance.writeShort(tempBuffer[idxBuffer]);
                }
            } catch (IOException e) {
                throw new IllegalStateException(
                    "dataOutputStreamInstance.writeShort(curVal)");
            }

        }

        // Close resources...
        recordInstance.stop();
        try {
            bufferedStreamInstance.close();
        } catch (IOException e) {
            throw new IllegalStateException("Cannot close buffered writer.");
        }
    }

    public void setFileName(File fileName) {
        this.fileName = fileName;
    }

    public File getFileName() {
        return fileName;
    }

    /**
     * @param isRecording
     *            the isRecording to set
     */
    public void setRecording(boolean isRecording) {
        synchronized (mutex) {
            this.isRecording = isRecording;
            if (this.isRecording) {
                mutex.notify();
            }
        }
    }

    /**
     * @return the isRecording
     */
    public boolean isRecording() {
        synchronized (mutex) {
            return isRecording;
        }
    }

    /**
     * @param frequency
     *            the frequency to set
     */
    public void setFrequency(int frequency) {
        this.frequency = frequency;
    }

    /**
     * @return the frequency
     */
    public int getFrequency() {
        return frequency;
    }

    /**
     * @param channelConfiguration
     *            the channelConfiguration to set
     */
    public void setChannelConfiguration(int channelConfiguration) {
        this.channelConfiguration = channelConfiguration;
    }

    /**
     * @return the channelConfiguration
     */
    public int getChannelConfiguration() {
        return channelConfiguration;
    }

    /**
     * @return the audioEncoding
     */
    public int getAudioEncoding() {
        return audioEncoding;
    }

    /**
     * @param isPaused
     *            the isPaused to set
     */
    public void setPaused(boolean isPaused) {
        synchronized (mutex) {
            this.isPaused = isPaused;
        }
    }

    /**
     * @return the isPaused
     */
    public boolean isPaused() {
        synchronized (mutex) {
            return isPaused;
        }
    }

}

From the below code I can create test.pcm file but I couldn't play it in mobile or pc.

I have also tired with test.mp3, test.wav and test.raw. I got toast that player doesn't support this type of file.

does any one has idea that how can i play file which is i have recorded using AudioRecord?

Using below code I get array of short from mic and write it into SdCard.

Here is the Code:

package com.anroid.AudioProcess;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;


public class AudioProcess extends Activity {
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Record 20 seconds of audio.
        Recorder recorderInstance = new Recorder();
        Thread th = new Thread(recorderInstance);
        recorderInstance.setFileName(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.pcm"));
        th.start();
        recorderInstance.setRecording(true);
        synchronized (this) {
        try {
            this.wait(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        }
        recorderInstance.setRecording(false);
        try {
            th.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
}





 class Recorder implements Runnable {
    private int frequency;
    private int channelConfiguration;
    private volatile boolean isPaused;
    private File fileName;
    private volatile boolean isRecording;
    private final Object mutex = new Object();

    // Changing the sample resolution changes sample type. byte vs. short.
    private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

    /**
     * 
     */
    public Recorder() {
        super();
        this.setFrequency(11025);
        this.setChannelConfiguration(AudioFormat.CHANNEL_CONFIGURATION_MONO);
        this.setPaused(false);
    }

    public void run() {
        // Wait until we're recording...
        synchronized (mutex) {
            while (!this.isRecording) {
                try {
                    mutex.wait();
                } catch (InterruptedException e) {
                    throw new IllegalStateException("Wait() interrupted!", e);
                }
            }
        }

        // Open output stream...
        if (this.fileName == null) {
            throw new IllegalStateException("fileName is null");
        }
        BufferedOutputStream bufferedStreamInstance = null;
        if (fileName.exists()) {
            fileName.delete();
        }
        try {
            fileName.createNewFile();
        } catch (IOException e) {
            throw new IllegalStateException("Cannot create file: " + fileName.toString());
        }
        try {
            bufferedStreamInstance = new BufferedOutputStream(
                    new FileOutputStream(this.fileName));
        } catch (FileNotFoundException e) {
            throw new IllegalStateException("Cannot Open File", e);
        }
        DataOutputStream dataOutputStreamInstance = 
            new DataOutputStream(bufferedStreamInstance);

        // We're important...
        android.os.Process
                .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

        // Allocate Recorder and Start Recording...
        int bufferRead = 0;
        int bufferSize = AudioRecord.getMinBufferSize(this.getFrequency(),
                this.getChannelConfiguration(), this.getAudioEncoding());
        AudioRecord recordInstance = new AudioRecord(
                MediaRecorder.AudioSource.MIC, this.getFrequency(), this
                        .getChannelConfiguration(), this.getAudioEncoding(),
                bufferSize);
        short[] tempBuffer = new short[bufferSize];
        recordInstance.startRecording();
        while (this.isRecording) {
            // Are we paused?
            synchronized (mutex) {
                if (this.isPaused) {
                    try {
                        mutex.wait(250);
                    } catch (InterruptedException e) {
                        throw new IllegalStateException("Wait() interrupted!",
                                e);
                    }
                    continue;
                }
            }

            bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
            if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
                throw new IllegalStateException(
                        "read() returned AudioRecord.ERROR_INVALID_OPERATION");
            } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) {
                throw new IllegalStateException(
                        "read() returned AudioRecord.ERROR_BAD_VALUE");
            } else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
                throw new IllegalStateException(
                        "read() returned AudioRecord.ERROR_INVALID_OPERATION");
            }
            try {
                for (int idxBuffer = 0; idxBuffer < bufferRead; ++idxBuffer) {
                    dataOutputStreamInstance.writeShort(tempBuffer[idxBuffer]);
                }
            } catch (IOException e) {
                throw new IllegalStateException(
                    "dataOutputStreamInstance.writeShort(curVal)");
            }

        }

        // Close resources...
        recordInstance.stop();
        try {
            bufferedStreamInstance.close();
        } catch (IOException e) {
            throw new IllegalStateException("Cannot close buffered writer.");
        }
    }

    public void setFileName(File fileName) {
        this.fileName = fileName;
    }

    public File getFileName() {
        return fileName;
    }

    /**
     * @param isRecording
     *            the isRecording to set
     */
    public void setRecording(boolean isRecording) {
        synchronized (mutex) {
            this.isRecording = isRecording;
            if (this.isRecording) {
                mutex.notify();
            }
        }
    }

    /**
     * @return the isRecording
     */
    public boolean isRecording() {
        synchronized (mutex) {
            return isRecording;
        }
    }

    /**
     * @param frequency
     *            the frequency to set
     */
    public void setFrequency(int frequency) {
        this.frequency = frequency;
    }

    /**
     * @return the frequency
     */
    public int getFrequency() {
        return frequency;
    }

    /**
     * @param channelConfiguration
     *            the channelConfiguration to set
     */
    public void setChannelConfiguration(int channelConfiguration) {
        this.channelConfiguration = channelConfiguration;
    }

    /**
     * @return the channelConfiguration
     */
    public int getChannelConfiguration() {
        return channelConfiguration;
    }

    /**
     * @return the audioEncoding
     */
    public int getAudioEncoding() {
        return audioEncoding;
    }

    /**
     * @param isPaused
     *            the isPaused to set
     */
    public void setPaused(boolean isPaused) {
        synchronized (mutex) {
            this.isPaused = isPaused;
        }
    }

    /**
     * @return the isPaused
     */
    public boolean isPaused() {
        synchronized (mutex) {
            return isPaused;
        }
    }

}

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

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

发布评论

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

评论(3

歌枕肩 2024-12-01 19:27:06

MediaRecorder 是您的需要。如果您不打算摆弄原始音频数据,请使用 MediaRecorder 对象进行录制。将输出格式设置为 THREE_GPP,它应该适合您。

MediaRecorder is your need here. If you do not plan to fiddle around with raw audio data, use a MediaRecorder object to do the recording. Set the output format to THREE_GPP and it should work for you.

与君绝 2024-12-01 19:27:06

更改文件扩展名不会更改文件格式,因此,例如,输入 .mp3 不会自动创建 MP3 文件。 AudioRecord 生成原始 PCM 数据。

您必须告诉媒体播放器播放原始文件,以及期望什么样的数据(采样率、编码等),就像您在录制时所做的那样,因为这些信息不是由文件本身给出的。

您可以在此处阅读 Audacity 中执行此操作的说明:http://delog.wordpress.com/2011/03/25/playing-raw-pcm-audio-using-audacity/

Changing the file extension does not change the file format, so putting .mp3, for example, does not automatically create an MP3 file. AudioRecord produces raw PCM data.

You will have to tell the media player to play a raw file, and what kind of data to expect (sample rate, encoding etc) just as you did when making the recording, since this information is not given by the file itself.

You can read instructions for doing this in Audacity here: http://delog.wordpress.com/2011/03/25/playing-raw-pcm-audio-using-audacity/

混吃等死 2024-12-01 19:27:06

认为您应该使用另一个类然后 AudioRecord。
AudioRecord 是当前声音端口上内容的原始数字印象。
你在那里“借用”的代码只是一系列数字。

尝试使用 AudioManager,认为这更适合您的风格。

Think you should use another class then AudioRecord.
AudioRecord is raw digital impressions of what is on your soundport right now.
And what you have "borrowed" up there for an code, is just a series of numbers.

Try AudioManager instead, think thats more your style.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文