簡體   English   中英

有符號的16位PCM轉換不起作用。 為什么?

[英]Signed 16 bit PCM transformations aren't working. Why?

在過去的兩天里,我一直試圖在Android上操縱16位PCM數據,但收效甚微。 我目前正在使用WAV錄音機來捕捉音頻。 onPeriodicNotification(AudioRecord recorder)法在緩沖之前與寫入randomAccessWriter我緩沖器發送到一個自定義類,來操縱的樣品中,並保存該樣品回到緩沖器中。 我的自定義類中的方法如下:

由於緩沖區是一個字節數組,我首先將它們轉換為短路,現在一個短路代表一個幀(只有一個通道)。 我將實現FFT算法,一旦我越過這個障礙,需要輸入為浮點數組 - 所以我將每個短路轉換為浮點數。 現在,將數據寫入WAV文件的randomAccessWriter接受一個字節數組,並期望每個幀為2個字節。 因此,我將每個float轉換回short並使用ByteBuffer重建一個字節數組,然后返回該數組。 當我運行我的錄音機應用程序時,通過上面的代碼發送緩沖區,一切都很好。

我嘗試使用簡單的語音調制算法來測試錄音是否被修改,算法放在TODO評論的位置:

現在如果我在我的iPhone上使用上面的代碼,音頻樣本將被轉換,盡管數據本身是32位浮點數。 但是,在我重新運行錄音機應用程序的Android上,插入上面的代碼后,產生的所有內容都是白噪聲。 在我用上面的代碼成功修改樣本之前,我無法繼續使用我的FFT算法。

為什么會這樣? 如果有關於該主題的知識的人能夠闡明這一主題,我將不勝感激。

解決 - 由Bjorn Roche

基本原因:錄制正在Little Endian提供數據,而Java短片則在Big Endian; 當使用兩種不同形式應用函數時,會產生白噪聲。 下面的代碼顯示了如何接收Little Endian字節數組,轉換為Big Endian浮點數組並返回Little Endian字節數組。 雖然浮動你可以隨心所欲,我現在將使用我的FFT算法:

public byte[] manipulateSamples(byte[] data,
                                int samplingRate,
                                int numFrames,
                                short numChannels) {

    // Convert byte[] to short[] (16 bit) to float[] (32 bit) (End result: Big Endian)
    ShortBuffer sbuf = ByteBuffer.wrap(data).asShortBuffer();
    short[] audioShorts = new short[sbuf.capacity()];
    sbuf.get(audioShorts);

    float[] audioFloats = new float[audioShorts.length];

    for (int i = 0; i < audioShorts.length; i++) {
        audioFloats[i] = ((float)Short.reverseBytes(audioShorts[i])/0x8000);
    }

    // Do your tasks here.

    // Convert float[] to short[] to byte[] (End result: Little Endian)
    audioShorts = new short[audioFloats.length];
    for (int i = 0; i < audioFloats.length; i++) {
        audioShorts[i] = Short.reverseBytes((short) ((audioFloats[i])*0x8000));
    }

    byte byteArray[] = new byte[audioShorts.length * 2];
    ByteBuffer buffer = ByteBuffer.wrap(byteArray);
    sbuf = buffer.asShortBuffer();
    sbuf.put(audioShorts);
    data = buffer.array();

    return data;

}

你的問題是java中的short是bigendian,但如果從WAV文件中獲取數據,那么數據就是小端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM