2014-02-10 72 views
0

我有以下的方法,收集來自IMediaSample PCM數據轉換成float型的FFT:如何閱讀IMediaSample 24位PCM數據

public int PCMDataCB(IntPtr Buffer, int Length, ref TDSStream Stream, out float[] singleChannel) 
    { 
     int numSamples = Length/(Stream.Bits/8); 
     int samplesPerChannel = numSamples/Stream.Channels; 

     float[] samples = new float[numSamples]; 

     if (Stream.Bits == 32 && Stream.Float) { 
      // this seems to work for 32 bit floating point 
      byte[] buffer32f = new byte[numSamples * 4]; 
      Marshal.Copy(Buffer, buffer32f, 0, numSamples); 

      for (int j = 0; j < buffer32f.Length; j+=4) 
      { 
       samples[j/4] = System.BitConverter.ToSingle(new byte[] { buffer32f[j + 0], buffer32f[j + 1], buffer32f[j + 2], buffer32f[j + 3]}, 0); 
      } 
     } 
     else if (Stream.Bits == 24) 
     { 
      // I need this code 
     } 

     // compress result into one mono channel 
     float[] result = new float[samplesPerChannel]; 

     for (int i = 0; i < numSamples; i += Stream.Channels) 
     { 
      float tmp = 0; 

      for (int j = 0; j < Stream.Channels; j++) 
       tmp += samples[i + j]/Stream.Channels; 

      result[i/Stream.Channels] = tmp; 
     } 

     // mono output to be used for visualizations 
     singleChannel = result; 

     return 0; 
    } 

似乎爲32B浮動工作,因爲我得到的敏感數據頻譜分析儀(雖然它看起來太偏移(或壓縮?)到較低的頻率)。

我似乎也設法使其工作於8,16和32個非浮動,但我只能讀取垃圾時位是24

我怎樣才能適應這個24位PCM來上班進入緩衝區?

緩衝區來自IMediaSample。

我想知道的另一件事情是,如果我使用的總結和信道的數量除以所有的頻道添加到一個方法是確定...

回答

0

你試過

byte[] buffer24f = new byte[numSamples * 3]; 
Marshal.Copy(Buffer, buffer24f, 0, numSamples); 

for (int j = 0; j < buffer24f.Length; j+=3) 
{ 
    samples[j/3] = System.BitConverter.ToSingle(
      new byte[] { 
       0, 
       buffer24f[j + 0], 
       buffer24f[j + 1], 
       buffer24f[j + 2] 
      }, 0); 
} 
+0

24位不是浮點數。它是整數音頻。如果需要做的事情是弄清楚如何從字節緩衝區組成一個整數,然後將其轉換爲浮點數以放入樣本數組。 –

1

我計算出來:

byte[] buffer24 = new byte[numSamples * 3]; 
Marshal.Copy(Buffer, buffer24, 0, numSamples * 3); 
var window = (float)(255 << 16 | 255 << 8 | 255); 

for (int j = 0; j < buffer24.Length; j+=3) 
{ 
    samples[j/3] = (buffer24[j] << 16 | buffer24[j + 1] << 8 | buffer24[j + 2])/window; 
} 

創建從三個字節一個整數,然後通過用三個字節的最大值除以縮放爲範圍1/-1。