【问题标题】:Recording a wav file from the mic in Android - problems在 Android 中从麦克风录制 wav 文件 - 问题
【发布时间】:2014-02-17 06:55:26
【问题描述】:

我需要能够在 Android 中使用麦克风创建 WAV 文件。目前,我遇到了很多麻烦。到目前为止,这是我的情况。我正在使用部分 micDroid 项目代码来记录:

//read thread


int sampleRate = 44100;
int bufferSize = AudioRecord.getMinBufferSize(sampleRate,android.media.AudioFormat.CHANNEL_CONFIGURATION_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);
AudioRecord ar = new AudioRecord(AudioSource.MIC,sampleRate,android.media.AudioFormat.CHANNEL_CONFIGURATION_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT,bufferSize);
short[] buffer = new short[bufferSize];

ar.startRecording();
while(isRunning){
    try{
        int numSamples = ar.read(buffer, 0, buffer.length);
        queue.put(new Sample(buffer, numSamples));
    } catch (InterruptedException e){
        e.printStackTrace();
    }
}


//write thread


int sampleRate = 44100;
WaveWriter writer = new WaveWriter("/sdcard","recOut.wav",sampleRate,android.media.AudioFormat.CHANNEL_CONFIGURATION_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);
try {
    writer.createWaveFile();
} catch (IOException e) {
    e.printStackTrace();
}
while(isRunning){
    try {
        Sample sample = queue.take();
        writer.write(sample.buffer, sample.bufferSize);
    } catch (IOException e) {
        //snip
    }
}

这似乎工作正常,但最终结果可以识别包含我所说的任何内容,但它被严重扭曲了。这是一个大胆的屏幕截图(WMP 拒绝播放文件)。

任何帮助将不胜感激,如果您需要更多代码/信息,请告诉我。

更新

根据 markus 的建议,这是我更新的代码:

int sampleRate = 16000;

writer = new WaveWriter("/sdcard","recOut.wav",sampleRate,android.media.AudioFormat.CHANNEL_IN_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);

int bufferSize = AudioRecord.getMinBufferSize(sampleRate,android.media.AudioFormat.CHANNEL_IN_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT);
AudioRecord ar = new AudioRecord(AudioSource.MIC,sampleRate,android.media.AudioFormat.CHANNEL_IN_MONO,android.media.AudioFormat.ENCODING_PCM_16BIT,bufferSize);

byte[] buffer = new byte[bufferSize]; //all references changed from short to byte type

...和另一个大胆的屏幕截图:

【问题讨论】:

  • 您使用的是哪个 Wave Writer 库?

标签: java android wav audio-recording


【解决方案1】:

据我所知,CHANNEL_CONFIGURATION_MONO 已被弃用,请使用 CHANNEL_IN_MONO。考虑查看rehearsalassistant 项目,他们也使用 AudioRecord 类。应选择采样率以适应标准采样率,如wikipedia article 中所述。

【讨论】:

  • 您建议的采样率是多少?质量不是真正的问题。
  • 不知道,试试看。我的代码在 16 khz 下工作得很好。我没有尝试 16 khz - 22 khz 之间的任何东西,因为 16 khz 对我来说已经足够了。
【解决方案2】:

您可以使用以下命令将缓冲区设置为小端:

buffer.order(ByteOrder.LITTLE_ENDIAN);

【讨论】:

    【解决方案3】:

    我有很多理论:

    1. 如果您的信号被噪声饱和并且您无法理解任何内容或您可以理解某些内容。可能是大端和小端有问题。当您录制 16 位(2 字节)时,可以像 AB 或 BA 一样存储(其中 A 和 B 是一个字节)。在java中所有都是大端(http://mindprod.com/jgloss/endian.html)所以你在大端存储一个16位的样本,然后你尝试构造一个wav,但是一个wav需要将数据存储在小端(https://ccrma.stanford.edu/courses/422/projects/WaveFormat/) .那么结果很清楚,你有一个截图。解决方案是始终使用 byte,您已经完成了,现在可能一切正常

    如果不检查 queue.put 和 queue.take 我认为您不需要它们,因为您将音频存储在数组中就足够了。首先,我将 queue.put 替换为一个函数,以将缓冲区存储在一个包含所有字节的巨大字节数组中。然后就可以放上wav的header了。

    记住 wav 有音频的标题和字节,也许你忘记了标题,而你正在使用的程序正在发明一个标题来播放它。

    另一个选项是:您在 44 字节的 wav 标头上有问题。检查您的 WaveWriter 功能。如果你在上面写了糟糕的代码,你会听到很多不同的声音。

    注意:我在android的源代码上看到过WaveWriter或类似的功能,但三个月前还没有准备好使用。关于波头的一些新内容?

    【讨论】:

      【解决方案4】:

      很明显,Audacity 认为您的文件是浮点数。 要么 WAV 标头搞砸了,要么就是你打开它的方式。

      录制。 在 Audacity 中,使用 Project / Import Raw Data 打开它 设置您认为如何记录它的参数。 我敢打赌它可以播放。

      【讨论】:

        猜你喜欢
        • 2012-01-25
        • 1970-01-01
        • 2018-03-26
        • 2011-06-15
        • 2022-11-10
        • 2012-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多