如何分别调整正弦波的左声道或右声道的音量?

问题描述 投票:0回答:0

我正在尝试调整正弦波中每个单独通道的音量以实现立体声输出。

我只是使用 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;
}
c++ audio ieee-754 wasapi sine-wave
© www.soinside.com 2019 - 2024. All rights reserved.