gpt4 book ai didi

c++ - 将 Uint8(浮点 AUDIO_F32)转换为 int16_t(16 位 PCM)

转载 作者:太空宇宙 更新时间:2023-11-04 12:57:34 24 4
gpt4 key购买 nike

我目前正在尝试录制音频并使用 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 ,但您的缓冲区是字节缓冲区。您错过了首先将字节转换为 float 的步骤。这是错误的行:

float sampleFloat = (float) sample

转换应该对 4 字节 block 进行操作,而不是对单个字节进行操作。比较:

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) 也是合理的。

您还可以将转换本身带出循环并迭代 float 组,例如

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;
}

关于c++ - 将 Uint8(浮点 AUDIO_F32)转换为 int16_t(16 位 PCM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45863872/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com