我正在尝试使用coredll.dll中的waveOutSetVolume逐渐将音频音量从静音(或接近静音)增加到最大值。
我发现的大多数代码示例都显示了Off,Low,Normal,Medium,High和Very High的预定义设置点,如下所示:
Public Enum Volumes As Integer
OFF = 0
LOW = 858993459
NORMAL = 1717986918
MEDIUM = -1717986919
HIGH = -858993460
VERY_HIGH = -1
End Enum
在我的尝试中,我尝试使用1200作为增加器从0逐步增加音量。这只会增加右声道的音量。在大约66000的某个地方,所有音频都会恢复静音并再次开始增加,但只能在正确的频道上播出。
上面列出的常数确实会影响我希望或预期的两个频道。但是我不清楚如何逐渐从0转换到858993459,然后再从858993459转换到1717986918等等。
我怀疑从根本上说,我不了解这是如何运作的。
我在Visual Studio 2008中使用VB.Net和.Net Compact Framework 3.5。如果你在C#中有一个解决方案我就可以了。
修改
从我现在读到的,上面列出的枚举值基于Hex,其中00000000是可能的最低音量,FFFFFFFF是可能的最高音量。这仍然没有帮助我很多,因为我不知道如何逐步增加VB.Net中的十六进制并同时将其转换为整数。我还不清楚,如果仅仅增加十六进制会导致音量在所有/两个声道上同时增加,或者我仍然遇到立体声问题。
我正在使用这个课程:
Public Class VolumeControl
<DllImport("coredll.dll", SetLastError:=True)> _
Friend Shared Function waveOutSetVolume(ByVal device As IntPtr, ByVal volume As Integer) As Integer
End Function
<DllImport("coredll.dll", SetLastError:=True)> _
Friend Shared Function waveOutGetVolume(ByVal device As IntPtr, ByRef volume As Integer) As Integer
End Function
Public Shared Property Volume() As Integer
Get
Dim v As Integer = CInt(0)
waveOutGetVolume(IntPtr.Zero, v)
Return v
End Get
Set(ByVal value As Integer)
waveOutSetVolume(IntPtr.Zero, value)
End Set
End Property
End Class
好的,这里有一些API文档,在这个特定的上下文中对我没有多大意义。什么是低阶词和高阶词?它们如何都存在于单个值中?
·dwVolume
新音量设置。低位字包含左声道音量设置,高位字包含右声道设置。值0xFFFF表示完整卷,值0x0000表示静默。
如果设备不支持左右音量控制,则dwVolume的低位字指定音量级别,忽略高位字。
答案 0 :(得分:4)
首先,让我稍微道歉,我将在C#中回答。现在太早了,而且我没有咖啡,所以我的VB精神翻译器还没有被解雇。
枚举值看起来更好,更容易理解为十六进制。
Public Enum Volumes As Integer
OFF = &H00000000
LOW = &H33333333
NORMAL = &H66666666
MEDIUM = &H99999999
HIGH = &HCCCCCCCC
VERY_HIGH = &HFFFFFFFF
End Enum
所以音量是一个DWORD,它映射到一个32位整数。所以这里有完整的数据:
0xFFFFFFFF
这是&#34;分裂&#34;进入WORD(16位)频道 - 左和右 - 概念上是这样的:
0xFFFF 0xFFFF
显然,左边的频道有更高的地方值&#34;所以要合并它们,它看起来真的像这样:
0xFFFF0000
[left]&amp;&amp; 0x0000FFFF
[右] == 0xffffffff
如果您在单个更改中具有低的非零值,例如0x0099,则stero值将如下所示:
0x00990099
因此,为了不断地将两个通道提高相同的数量,您将从零循环到ushort.MaxValue(0xffff),将DWORD(32位uint)中的WORDS(16位ushorts)设置为相同的价值:
UInt16 left;
UInt16 right;
UInt32 both;
for(int i = 0 ; i < ushort.MaxValue ; i++)
{
left = i << 16; // left shift it to the upper 16 bits
right = i;
both = left & right;
waveOutSetVolue(both);
Thread.Sleep(10);
}
显然,你想要调整睡眠暂停,也许是i
增加的步骤,以获得你想要的效果。它通常也不是一个线性的进展,所以简单地增加我可能需要更复杂,但你明白了。
<强> EDIT1 强>
现在我喝咖啡了:
Dim left As UInt16
Dim right As UInt16
Dim both As UInt32
For i As Integer = 0 To UShort.MaxValue - 1
' left shift it to the upper 16 bits
left = i << 16
right = i
both = left And right
waveOutSetVolue(both)
Thread.Sleep(10)
Next