這裏是切割至少顯著位的方法:
byte[] data = ...
var skipBytes = 0;
byte[] data16bit;
int samples;
if(/* data was 32 bit */) {
skipBytes = 2;
samples = data.Length/4;
} else if(/* data was 24 bit */) {
skipBytes = 1;
samples = data.Length/3;
}
data16bit = new byte[samples * 2];
int writeIndex = 0;
int readIndex = 0;
for(var i = 0; i < samples; ++i) {
readIndex += skipBytes; //skip the least significant bytes
//read the two most significant bytes
data16bit[writeIndex++] = data[readIndex++];
data16bit[writeIndex++] = data[readIndex++];
}
這假定一個小端字節順序(至少顯著字節是第一個字節,通常爲WAV RIFF)。如果你有大的字節序,你必須在兩條讀取行之後加上readIndex += ...
。
您可以實現這個任務你自己的轉換迭代器,像這樣:
IEnumerable<byte> ConvertTo16Bit(byte[] data, int skipBytes)
{
int bytesToRead = 0;
int bytesToSkip = skipBytes;
int readIndex = 0;
while (readIndex < data.Length)
{
if (bytesToSkip > 0)
{
readIndex += bytesToSkip;
bytesToSkip = 0;
bytesToRead = 2;
continue;
}
if (bytesToRead == 0)
{
bytesToSkip = skipBytes;
continue;
}
yield return data[readIndex++];
bytesToRead--;
}
}
這樣,您就不必創建一個新的數組,如果沒有必要的。你可以在數據陣列簡單地轉換到一個新的16位陣列與IEnumerable<T>
擴展方法:
var data16bit = ConvertTo16Bit(data, 1).ToArray();
或者,如果你不需要的數組,你可以遍歷數據跳過至少顯著字節:
foreach (var b in ConvertTo16Bit(data, 1))
{
Console.WriteLine(b);
}
這是因爲您將數組對象轉換爲一個'short',然後將其轉換爲'int'。如果樣本太大以至'int16'無法保存數據,您希望如何轉換?你想切斷最不重要的位?然後你只需要在輸入數據中拋出這些字節。無需「轉換」。 –
謝謝你的參加。我沒有經驗的位和字節...我讀過你並在互聯網上搜索如何刪除LSB,但沒有太多關於它...而你說,你告訴我,我的Convert.toInt16是不需要的這裏?但是,如何將32b轉換爲16呢? – snakelecaps
如果要將32位轉換爲16位,則必須進行折衷。對於聲音數據來說,放寬一些精度可能是合理的。精度存儲在最低有效位中。所以我們可以拋棄它們(假設其他位中還有一些數據,並且沒有其他編碼,如差分等)。因此,要將32位轉換爲16位,需要2個字節,跳過2個字節,直到您位於數組的末尾。對於24到16位需要2個字節,跳過1個字節。用這個過程構造一個新的數組,或者使用一個列表來移除元素(更方便,但效率更低)。 –