簡體   English   中英

將Uint8(浮點AUDIO_F32)轉換為int16_t(16bit PCM)

[英]Convert Uint8 (floating-point AUDIO_F32) to int16_t (16bit PCM)

我目前正在嘗試記錄音頻並使用SDL處理它,但遇到一些麻煩,無法獲得處理步驟所需的16位PCM音頻。 我正在運行的設備僅支持AUDIO_F32格式。 所以我的AudioSpec如下:

SDL_AudioSpec wanted;
SDL_zero(wanted);

wanted.freq = 48000;
wanted.format = AUDIO_F32SYS;
wanted.channels = 1;
wanted.samples = 4096;
wanted.callback = NULL;

現在,我要跟蹤包含已錄制音頻的緩沖區;

std::vector<Uint8> buffered;

如何將Uint8轉換為16位PCM格式? 如果我正確的話, Uint8應該是定義為unsigned char 32位浮點音頻。 我已經嘗試了下面的代碼,但似乎無法給出正確的結果;

std::vector<int16_t> pcm_buffer;
for( const Uint8& sample : buffered )
{
   float sampleFloat = (float) sample;
   sampleFloat *= 32767;

   int16_t sampleInt = (int16_t) sampleFloat;
   pcm_buffer.push_back(sampleInt);
}

我感覺自己完全誤解了我在做什么,所以我希望有人能指出我正確的方向。

F32格式為4字節浮點數,但是您將緩沖區作為字節緩沖區。 您錯過了先將字節轉換為浮點的步驟。 這是錯誤的行:

float sampleFloat = (float) sample

轉換應在4字節塊上進行,而不是在單字節上進行。 相比:

std::vector<Uint8> buffered = ...;
std::vector<int16_t> pcm_buffer;
assert(buffered.size() % 4 == 0);
for(for size_t i = 0; i < buffered.size(); i += 4)
{
     float sampleFloat = *(float*)(buffered.data() + i);
     sampleFloat *= 32767;

     int16_t sampleInt = (int16_t) sampleFloat;
     pcm_buffer.push_back(sampleInt);
}

由於對齊和別名規則,我認為assert(buffered.data() % 4 == 0)也很合理。

您還可以將強制類型轉換本身置於循環之外,並迭代浮點數組,例如

std::vector<Uint8> buffered = ...;
const float* p = (const float*)buffered.data();
const float* pe = p + buffered.size() / 4;
for (; p < pe; ++p) {
    int16_t sampleInt = *p * 32767;
}

暫無
暫無

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

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