2010-12-15 82 views
3

我需要能夠在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

回答

5

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

2

我有很多的理論:

  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一些新的?

1

這很清楚,Audacity認爲你的文件是浮點數。 無論WAV標頭是搞砸了,還是你打開它的方式。

進行錄製。 在Audacity中,使用Project/Import Raw Data打開它 設置您認爲您錄製它的參數。 我敢打賭它回放OK。

3

您可以設置一個緩衝區是小端通過使用下列內容:

buffer.order(ByteOrder.LITTLE_ENDIAN);