在Android中录制麦克风的wav文件 - 问题

问题描述:

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

//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拒绝播放该文件)。

alt text

任何帮助将不胜感激,让我知道如果你需要更多的代码/信息。

更新

继马库斯的建议,这是我更新的代码:

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 

...和另一个大胆撷取画面:据我所知 alt text

+0

这波作家的lib您正在使用? – Eray 2013-06-19 11:03:58

CHANNEL_CONFIGURATION_MONO已被弃用,使用CHANNEL_IN_MONO。考虑看rehearsalassistant项目,afaik也使用AudioRecord类。应选择采样率以符合标准采样率,如此处所述wikipedia article

+0

作为采样率,你会建议什么?质量不是真正的问题。 – fredley 2010-12-15 17:41:13

+0

不知道,试一下。我的代码很好地处理了16 khz。我没有在16千赫兹到22千赫兹之间做任何事情,因为16赫兹对我来说已经足够了。 – mad 2010-12-15 17:43:58

+0

没有这个运气,看到更新和screencap ... – fredley 2010-12-15 18:32:04

我有很多的理论:

  1. 如果你有饱和噪声的信号,你不能什么都不懂,或者你能理解的东西。这可能是因为你有一个大端和小端的问题。当你记录16位(2字节)时可以像AB或BA一样存储(其中A和B是一个字节)。在java中,所有的都是大端(http://mindprod.com/jgloss/endian.html),所以你要存储一个16位长的样本,然后你尝试构建一个wav,但是一个wav需要在little endian上存储数据(https://ccrma.stanford.edu/courses/422/projects/WaveFormat/)。那么结果是明确的,你有一个截图。解决的办法是经常使用的字节,你做了,它可能是所有现在是确定

如果不检查queue.put和queue.take我觉得你并不需要它们,因为你保存你的音频和数组这就够了。在第一次,我会用一个函数替换queue.put来将缓冲区存储在包含所有字节的大量字节数组中。然后你可以把wav的标题。

记住一个wav的头部和音频的字节,也许你已经忘了头部,你正在使用的程序是发明头播放它。

另一种选择是:你在44字节的wav头上有问题。检查你的WaveWriter功能。如果你在上面写错误的代码,你可以听到很多不同的声音。

注意:我已经看到了功能WaveWriter或类似的Android的源代码,但它还没有准备好在三个月前使用。关于waveheader一些新的?

这很清楚,Audacity认为你的文件是浮点数。 无论WAV标头是搞砸了,还是你打开它的方式。

进行录制。 在Audacity中,使用Project/Import Raw Data打开它 设置您认为您录制它的参数。 我敢打赌它回放OK。

您可以设置一个缓冲区是小端通过使用下列内容:

buffer.order(ByteOrder.LITTLE_ENDIAN);