我正在尝试调整正弦波中每个单独通道的音量以实现立体声输出。
我只是使用 WASAPI 以 32 位 IEEE-float 立体声格式输出这个。
我有一个 32 位 IEEE-Float 格式的正弦波,我尝试通过乘以 0f 和 1f 之间的值来设置左右声道音量。
每个浮点数有 4 个字节,所以我将缓冲区中的字节总数除以 4。
浮动之间的交替应该是左右通道,还是我弄错了?
例如:
|-------------Frame-------------|
(Left Channel) (Right Channel)
[0] [0] [0] [0] | [0] [0] [0] [0]
|----Sample----| |----Sample----|
每个样本都应该是一个浮点值,对吧?
我使用 DBOUT 打印了两个样本的值进行测试,以确保一切都有意义。 nChannels 为 2,nSamplesPerSec 为 48000。
static inline float sin01(float alpha) {
return 0.5 * sin(alpha) + 0.5;
}
static inline float sin_minmax_Hz(float min, float max, float freq_Hz, float t) {
return (max - min) / 2.0 * sin01(t * freq_Hz * TWO_PI);
}
Invoke() {
BYTE* pData;
hr = audioclient->GetCurrentPadding(&pad);
int bytes_per_frame = wave_format.nChannels * 32 / 8;
actual_size = (buffer_framecount - pad);
count = actual_size * bytes_per_frame;
hr = renderclient->GetBuffer(actual_size, &pData);
float dt = 1.0 / (float)wave_format.nSamplesPerSec;
float freq = (float)wave_format.nSamplesPerSec / ((float)count / 4);
float* float_buffer = new float[count / 4];
for (int i = 0; i < count / 4; i++) {
static_assert(sizeof(float) == 4, "float size is expected to be 4 bytes");
float t = (float)i * dt;
float_buffer[i++] = sin_minmax_Hz(-1, 1, freq, t) * 0.5f; // should be half volume L channel
float_buffer[i] = sin_minmax_Hz(-1, 1, freq, t) * 0.25f; // should be quarter volume R channel
}
if (SUCCEEDED(hr)) {
std::memcpy(pData, float_buffer, count);
//DBOUT(float_buffer[20] << " < float : byte > " << pData[80] << " " << pData[81] << " " << pData[82] << " " << pData[83] << "\n");
//DBOUT(float_buffer[21] << " < float : byte > " << pData[84] << " " << pData[85] << " " << pData[86] << " " << pData[87] << "\n");
hr = renderclient->ReleaseBuffer(actual_size, 0);
EXIT_ON_ERROR(hr);
}
}
无论我怎么尝试,左右声道输出都是一样的
如果我同时降低两个乘数,音量将被调整,但我无法让左右声道音量有任何不同。
有人知道我哪里错了吗?
DBOUT 结果是针对随机帧的,这对我来说很有意义:
alternating between *0.5 and *0.25
0.282632 < float : byte > 21 181 144 62
0.141316 < float : byte > 21 181 16 62
Converted to hex for comparison:
hex: 15 B5 90 3E // 0x3E90B515 = 0.282632
hex: 15 B5 10 3E // 0x3E10B515 = 0.141316
我也试过这个方法:
float freq = (float)wave_format.nSamplesPerSec / (float)actual_size;
float* float_buffer = new float[count / 4];
for (int i = 0; i < count / 8; ++i) {
float t = (float)i * dt;
float_buffer[2 * i] = sin_minmax_Hz(-1, 1, freq, t) * 0.5f;
float_buffer[2 * i + 1] = sin_minmax_Hz(-1, 1, freq, t) * 0.25f;
}