在Windows Mobile / Windows CE 6.0上逐渐增加系统卷

时间:2012-06-19 04:32:11

标签: c# vb.net compact-framework windows-ce

我正在尝试使用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的低位字指定音量级别,忽略高位字。

1 个答案:

答案 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