提问人:Jake A 提问时间:11/1/2023 更新时间:11/1/2023 访问量:25
如何在 SDL 中将 16 位样本拆分为 2 个字节的音频?
How do I split a 16bit sample into 2 bytes for audio in SDL?
问:
以下函数填充在回调中读取的音频缓冲区。当没有声音时,它很好,但是当播放样本时,它有明显的失真。如果我尝试使用AUDIO_S8格式并删除 val 的位移,它可以正常工作,但将 8 个通道混合到一个 8 位输出听起来很糟糕,您可以想象。
// global
struct AudioBuffer{
Uint8 *data;
Uint32 len;
Uint32 pos;
bool update; // if true audio_works() fills buffer
bool stop;
} buffer;
#define AMP_LEV 252
#define BYTES_IN_SAMPLE 2
#define CHANNELS 8
注意:隔离到通道 0 进行测试。目标是将 8 个 8 位通道混合到 1 个 16 位输出。
void AudioW::audio_works(AudioBuffer *b)
{
int actual_pos;
int16_t val;
if (b->stop)
{
for (int c = 0; c < CHANNELS; c++)
{
t->channel[c].play = false;
}
b->stop = false;
}
for (int p = 0; p < b->len; p += BYTES_IN_SAMPLE)
{
val = 0;
for (int c = 0; c < 1; c++) // only use channel 0
{
if (t->channel[c].play && t->mute[c] == false)
{
actual_pos = (int)t->channel[c].pos;
if (t->sample[t->channel[c].sample].len != 0 && actual_pos < t->sample[t->channel[c].sample].len)
{
val = (t->sample[t->channel[c].sample].data[actual_pos] * AMP_LEV) * t->channel[c].amplifier;
t->channel[c].pos += t->channel[c].pos_adv;
t->channel[c].pos_adv *= t->channel[c].pitch_mod;
} else{
t->channel[c].play = false; // stop channel playback if sample reaches end or sample is empty
}
}
}
val = val; // with other channels: val / CHANNELS
b->data[p] = val;
b->data[p+1] = val >> 8;
}
}
我想我已经将其缩小到将“val”拆分为 2 个字节的问题。 有谁知道是什么原因导致了失真?
答: 暂无答案
评论
float
±1
b->data[p+1] = val << 8;
(int16_t)(*b->data+p)