首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Uint8 (浮点AUDIO_F32)转换为int16_t (16位PCM)

将Uint8 (浮点AUDIO_F32)转换为int16_t (16位PCM)
EN

Stack Overflow用户
提问于 2017-08-24 22:10:02
回答 1查看 1.5K关注 0票数 1

我目前正在尝试录制音频并使用SDL进行处理,但我在获取处理步骤所需的16位PCM音频时遇到了一些问题。我运行的设备只支持AUDIO_F32格式。所以我的AudioSpec如下所示;

代码语言:javascript
复制
SDL_AudioSpec wanted;
SDL_zero(wanted);

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

现在我必须跟随包含录制的音频的缓冲区;

代码语言:javascript
复制
std::vector<Uint8> buffered;

如何将Uint8转换为16位PCM格式?如果我没记错,Uint8应该是定义为unsigned char的32位浮点音频。我已经尝试了下面的代码,但它似乎没有给出正确的结果;

代码语言:javascript
复制
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);
}

我有一种感觉,我完全误解了我在做什么,所以我希望有人能给我指出正确的方向。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-24 22:40:21

F32格式是4字节浮点数,但是您的缓冲区是字节的缓冲区。您错过了首先将字节转换为浮点数的步骤。这是错误的一行:

代码语言:javascript
复制
float sampleFloat = (float) sample

转换应该在4字节块上操作,而不是在单字节上操作。比较:

代码语言:javascript
复制
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)也是合理的。

您还可以将强制转换本身放在循环之外,并迭代浮点数组,例如

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45863872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档