android - 使用 Android AudioRecorder 录制 .Wav

标签 android audiorecord

我已经阅读了很多关于 Android 的 AudioRecorder 的页面。您可以在问题下方看到它们的列表。

我正在尝试使用 AudioRecorder 录制音频,但效果不佳。

public class MainActivity extends Activity {

AudioRecord ar = null;
int buffsize = 0;

int blockSize = 256;
boolean isRecording = false;
private Thread recordingThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


}

public void baslat(View v)
{
            // when click to START 
    buffsize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
    ar = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, buffsize);

    ar.startRecording();

    isRecording = true;
    recordingThread = new Thread(new Runnable() {
        public void run() {
            writeAudioDataToFile();
        }
    }, "AudioRecorder Thread");
    recordingThread.start();
}
public void durdur(View v)
{
            // When click to STOP
    ar.stop();
    isRecording = false;
}

private void writeAudioDataToFile() {
    // Write the output audio in byte

    String filePath = "/sdcard/voice8K16bitmono.wav";
    short sData[] = new short[buffsize/2];

    FileOutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    while (isRecording) {
        // gets the voice output from microphone to byte format

        ar.read(sData, 0, buffsize/2);
        Log.d("eray","Short wirting to file" + sData.toString());
        try {
            // // writes the data to file from buffer
            // // stores the voice buffer
            byte bData[] = short2byte(sData);
            os.write(bData, 0, buffsize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    try {
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private byte[] short2byte(short[] sData) {
    int shortArrsize = sData.length;
    byte[] bytes = new byte[shortArrsize * 2];
    for (int i = 0; i < shortArrsize; i++) {
        bytes[i * 2] = (byte) (sData[i] & 0x00FF);
        bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
        sData[i] = 0;
    }
    return bytes;

}

它正在创建一个 .wav 文件,但是当我尝试收听它时,它没有打开。我收到“不支持的文件”错误。我试过使用很多媒体播放器应用程序播放该文件。

注意:我必须使用 AudioRecorder 而不是 MediaRecorder,因为我的应用程序将在录制时执行另一个进程(显示均衡器)。

以下是我阅读过的有关该主题的页面列表:

  1. http://developer.android.com/reference/android/media/AudioRecord.html#read(short[],%20int,%20int)
  2. Android AudioRecord example
  3. http://audiorecordandroid.blogspot.in
  4. AudioRecord object not initializing
  5. Recording a wav file from the mic in Android - problems
  6. http://i-liger.com/article/android-wav-audio-recording
  7. Creating a WAV file from raw PCM data using the Android SDK
  8. Capturing Sound for Analysis and Visualizing Frequencies in Android

有很多不同的方法可以解决这个问题。我已经尝试了很多,但对我没有任何用处。我已经在这个问题上工作了大约 6 个小时,所以我希望得到明确的答案,最好是一些示例代码。

最佳答案

我昨天写了一个简单的(你应该阅读它,而不是专业标准)类来做到这一点,并且它有效。

private class Wave {
    private final int LONGINT = 4;
    private final int SMALLINT = 2;
    private final int INTEGER = 4;
    private final int ID_STRING_SIZE = 4;
    private final int WAV_RIFF_SIZE = LONGINT + ID_STRING_SIZE;
    private final int WAV_FMT_SIZE = (4 * SMALLINT) + (INTEGER * 2) + LONGINT + ID_STRING_SIZE;
    private final int WAV_DATA_SIZE = ID_STRING_SIZE + LONGINT;
    private final int WAV_HDR_SIZE = WAV_RIFF_SIZE + ID_STRING_SIZE + WAV_FMT_SIZE + WAV_DATA_SIZE;
    private final short PCM = 1;
    private final int SAMPLE_SIZE = 2;
    int cursor, nSamples;
    byte[] output;

    public Wave(int sampleRate, short nChannels, short[] data, int start, int end) {
        nSamples = end - start + 1;
        cursor = 0;
        output = new byte[nSamples * SMALLINT + WAV_HDR_SIZE];
        buildHeader(sampleRate, nChannels);
        writeData(data, start, end);
    }

    // ------------------------------------------------------------
    private void buildHeader(int sampleRate, short nChannels) {
        write("RIFF");
        write(output.length);
        write("WAVE");
        writeFormat(sampleRate, nChannels);
    }

    // ------------------------------------------------------------
    public void writeFormat(int sampleRate, short nChannels) {
        write("fmt ");
        write(WAV_FMT_SIZE - WAV_DATA_SIZE);
        write(PCM);
        write(nChannels);
        write(sampleRate);
        write(nChannels * sampleRate * SAMPLE_SIZE);
        write((short) (nChannels * SAMPLE_SIZE));
        write((short) 16);
    }

    // ------------------------------------------------------------
    public void writeData(short[] data, int start, int end) {
        write("data");
        write(nSamples * SMALLINT);
        for (int i = start; i <= end; write(data[i++])) ;
    }

    // ------------------------------------------------------------
    private void write(byte b) {
        output[cursor++] = b;
    }

    // ------------------------------------------------------------
    private void write(String id) {
        if (id.length() != ID_STRING_SIZE)
            Utils.logError("String " + id + " must have four characters.");
        else {
            for (int i = 0; i < ID_STRING_SIZE; ++i) write((byte) id.charAt(i));
        }
    }

    // ------------------------------------------------------------
    private void write(int i) {
        write((byte) (i & 0xFF));
        i >>= 8;
        write((byte) (i & 0xFF));
        i >>= 8;
        write((byte) (i & 0xFF));
        i >>= 8;
        write((byte) (i & 0xFF));
    }

    // ------------------------------------------------------------
    private void write(short i) {
        write((byte) (i & 0xFF));
        i >>= 8;
        write((byte) (i & 0xFF));
    }

    // ------------------------------------------------------------
    public boolean wroteToFile(String filename) {
        boolean ok = false;

        try {
            File path = new File(getFilesDir(), filename);
            FileOutputStream outFile = new FileOutputStream(path);
            outFile.write(output);
            outFile.close();
            ok = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            ok = false;
        } catch (IOException e) {
            ok = false;
            e.printStackTrace();
        }
        return ok;
    }
}

希望对你有帮助

关于android - 使用 Android AudioRecorder 录制 .Wav,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17192256/

相关文章:

java - 安卓工作室 : E/AndroidLogcatService Error on only one device

Android audiorecord 实例失败

android - 如何使用 setMaxDuration 将 AudioRecord 限制为 MediaRecorder 的记录时间

android - Android 中的其他 lint 规则

安卓蓝牙 : "Scan failed, reason app registration failed for UUID"

安卓语音指令自定义

java - 如何缓冲字节几秒钟然后发送它们

java - 音轨在 Android 中不工作

android - AudioRecord 在 Android L Developer Preview 中记录断断续续的声音

用于录制音频的 Android AudioRecord 与 MediaRecorder