windows对音频音量滑块使用什么对数函数? 我目前正在努力实现我的C++音量滑块在C++应用程序中的应用。

windows对音频音量滑块使用什么对数函数? 我目前正在努力实现我的C++音量滑块在C++应用程序中的应用。,c++,windows,audio,volume,C++,Windows,Audio,Volume,该应用程序能够控制windows混音器音量,滑块的范围为0.0f到1.0f 我面临的问题是,我的DB值不等于windows使用的DB值 以下是我使用音量滑块设置的一些值,以及生成的DB值和windows正在使用的值 下面是我用来计算音频分贝级的函数。我做错了什么 提前谢谢你 if (this->m_useAudioEndpointVolume) { const float slider_min = 0.0f; const float sli

该应用程序能够控制windows混音器音量,滑块的范围为0.0f到1.0f

我面临的问题是,我的DB值不等于windows使用的DB值

以下是我使用音量滑块设置的一些值,以及生成的DB值和windows正在使用的值

下面是我用来计算音频分贝级的函数。我做错了什么

提前谢谢你

    if (this->m_useAudioEndpointVolume)
    {
        const float slider_min = 0.0f;
        const float slider_max = 1.0f;
        const float logBase = 10;

        m_ignoreAudioValue = TRUE;

        if (volume >= 1.0f) {
            volume = 1.0f;
        }

        if (volume <= 0.0f) {
            volume = 0.0f;
        }

        float pfLevelMinDB = 0;
        float pfLevelMaxDB = 0;
        float pfVolumeIncrementDB = 0;
        m_pEndpointVolume->GetVolumeRange(&pfLevelMinDB, &pfLevelMaxDB, &pfVolumeIncrementDB);

        // Logarithmic formula for audio volume
        // Volume = log(((Slider.Value-Slider.Min)*(B-1))/(Slider.Max-Slider.Min) + 1)/log(B) * (Volume.Max - Volume.Min) + Volume.Min
        float calcVolume = log(((volume - slider_min)*(logBase - 1)) / (slider_max - slider_min) + 1) / log(logBase) * (pfLevelMaxDB - pfLevelMinDB) + pfLevelMinDB;

        if (volume == 0.0f) {
            m_pEndpointVolume->SetMute(TRUE, NULL);
        }
        else
        {
            m_pEndpointVolume->SetMute(FALSE, NULL);
        }

        float currentValue = 0.0f;

        m_pEndpointVolume->GetMasterVolumeLevel(&currentValue);

        // Todo: The calculation has to be logarithmic
        m_pEndpointVolume->SetMasterVolumeLevel(calcVolume, NULL);
    }
if(此->m_useAudioEndpointVolume)
{
常量浮动滑块_min=0.0f;
常量浮动滑块_max=1.0f;
常量浮点对数基=10;
m_ignoreAudioValue=真;
如果(音量>=1.0f){
体积=1.0f;
}
if(卷获取卷数(&pfLevelMinDB,&pfLevelMaxDB,&pfVolumeIncrementDB);
//音频音量的对数公式
//Volume=log(((Slider.Value Slider.Min)*(B-1))/(Slider.Max Slider.Min)+1)/log(B)*(Volume.Max-Volume.Min)+Volume.Min
float calcVolume=log((卷-滑块最小值)*(logBase-1))/(滑块最大值-滑块最小值)+1)/log(logBase)*(pfLevelMaxDB-pfLevelMinDB)+pfLevelMinDB;
如果(体积=0.0f){
m_pEndpointVolume->SetMute(真,空);
}
其他的
{
m_pEndpointVolume->SetMute(FALSE,NULL);
}
浮动电流值=0.0f;
m_pEndpointVolume->GetMasterVolumeLevel(¤tValue);
//Todo:计算必须是对数的
m_pEndpointVolume->SetMasterVolumeLevel(calcVolume,NULL);
}
假设如下:

volumeMaxDB =  +5
volumeMinDB = -10
incrementDB = 5
对我来说,这意味着一个类似于下面ascii艺术的滑块。我还展示了我假定的与滑块UI比例的映射

        dB        Slider
     |  +5   <=>   1.0
     |   0
     -  -5
     |  -10  <=>   0.0
其次,将当前滑块位置dB值0缩放为dBRange * 0.0 -> 0 * 1.0 -> 15 *0.5->7.5

dB = dBRange * slider;
第三,上下移动范围,使+15变为+5,0变为-10

dB = dB - (dbRange - volumeMaxDB);
最后,您可能希望舍入到最接近的dB增量

额外积分:如果你可以控制滑块的范围,你可以通过将最小值和最大值设置为与minDB和maxDB相同的值来简化你的生活方式。我找到了解决方案

IAudioEndpointVolume具有函数SetMasterVolumeLevelScalar。该函数在MSDN文档中使用的范围为0.0到1.0,因此您无需自己实现对数函数。 好像我忽略了这个

这是我正在使用的当前代码示例,以防将来有人需要它

float pLevel = 0.0f;
m_pEndpointVolume->GetMasterVolumeLevelScalar(&pLevel);

// We have to set this first to TRUE to an avoid unnecessary callback
m_ignoreAudioValue = TRUE;
// Set the scalar value
// https://msdn.microsoft.com/de-de/library/windows/desktop/dd368062(v=vs.85).aspx
m_pEndpointVolume->SetMasterVolumeLevelScalar(sliderValue, NULL);

// We have to set this again to TRUE to avoid an unnecessary callback
// because the SetMasterVolumeLevelScalar triggers the OnNotify event
// and this causes the m_ignoreAudioValue to be FALSE again.
m_ignoreAudioValue = TRUE;
// If the value is higher the 0.0 unmute the master volume.
m_pEndpointVolume->SetMute(sliderValue > 0.0f ? FALSE : TRUE, NULL);

m_pEndpointVolume->GetMasterVolumeLevelScalar(&pLevel);
编辑:

Windows似乎在使用线性音量滑块。这就是为什么Windows中2%的音量仍然感觉太大,而高于50%的音量不再增加的原因

这里有一篇关于为什么你应该避免它的非常好的文章


谢谢您的回答。我一试用就会给您反馈并接受答案。再次您好。我试用了。不幸的是,这不是我需要的解决方案。这是一个线性体积滑块,而不是对数滑块。我很高兴您找到了答案。我想指出,您的问题是关于日志滑块的:“我面临的问题是,我的DB值不等于windows使用的DB值。”没错,但如果我是对的,你的答案是线性函数。
float pLevel = 0.0f;
m_pEndpointVolume->GetMasterVolumeLevelScalar(&pLevel);

// We have to set this first to TRUE to an avoid unnecessary callback
m_ignoreAudioValue = TRUE;
// Set the scalar value
// https://msdn.microsoft.com/de-de/library/windows/desktop/dd368062(v=vs.85).aspx
m_pEndpointVolume->SetMasterVolumeLevelScalar(sliderValue, NULL);

// We have to set this again to TRUE to avoid an unnecessary callback
// because the SetMasterVolumeLevelScalar triggers the OnNotify event
// and this causes the m_ignoreAudioValue to be FALSE again.
m_ignoreAudioValue = TRUE;
// If the value is higher the 0.0 unmute the master volume.
m_pEndpointVolume->SetMute(sliderValue > 0.0f ? FALSE : TRUE, NULL);

m_pEndpointVolume->GetMasterVolumeLevelScalar(&pLevel);