2012-06-19 4 views
3

Я пытаюсь использовать waveOutSetVolume из coredll.dll, чтобы постепенно увеличивать громкость звука от бесшумного (или почти бесшумного) до максимального.Постепенное увеличение объема системы на Windows Mobile/Windows CE 6.0

Большинство примеров кода я находящих показать некоторые предопределенные уставки для 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 

В своих попытках, я пытался воскрешая объем постепенно от 0, используя 1200 в качестве увеличения. Это только увеличивает громкость на правом канале. Где-то около 66000 все звуки возвращаются к молчанию и снова начинают увеличиваться, но только на правом канале.

Указанные выше константы влияют на оба канала, как я надеялся или ожидал. Но мне непонятно, как постепенно перейти от 0 до 858993459, а затем снова от 858993459 до 1717986918 и т. Д.

Я подозреваю, что есть что-то принципиально Я не понимаю, как это работает.

Я использую VB.Net с .Net Compact Framework 3.5 в Visual Studio 2008. Если у вас есть решение на C#, я в порядке с этим.

Edit:
Из того, что я прочитал сейчас, значение перечислений, перечисленное выше, основаны на Hex, где 00000000 самый низкий возможным объем и FFFFFFFF это максимально возможный объем. Это все еще не помогает мне, потому что я не уверен, как постепенно увеличивать hex в VB.Net и преобразовывать его в Integer одновременно. Мне также непонятно, может ли увеличение Hex увеличить громкость на всех/обоих каналах одновременно, или если у меня все еще будет проблема с стереосистемой.

Я использую этот класс:

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 указывает уровень громкости, и слово высокого порядка игнорируется.

ответ

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

Это "раскол" в к WORD (16-бит) канала - левый и правый - концептуально, как это:

0xFFFF 0xFFFF

Очевидно, что левые каналы имеют более высокие значения «места», поэтому для их объединения это действительно выглядит так:

0xFFFF0000 [left] & &[право] == 0xffffffff

Если у вас низкий, ненулевое значение в одно изменение, скажем, 0x0099, то значение Stero будет выглядеть следующим образом:

0x00990099

Так постоянно поднять оба канала на ту же сумму, вы бы петлю от нуля до ushort.MaxValue (0xFFFF), установив оба слова (16 бит) ushorts в DWORD (32-битный UINT) к тому же значению:

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 
+0

что-то делать с перемещением не кажется, работает для меня. Можете ли вы сдвинуть i влево на 16 бит, когда переменная «left» определяется как 16 бит для начала? Кроме того, использование оператора «И», похоже, не объединяет мои значения в «обе» переменную, как я ожидал. – HK1

+0

ОК, некоторые из моих проблем ушли, когда я объявил свой параметр тома как UInt32 в своем API-вызове, вместо того, чтобы использовать Integer, как я. 'waveOutSetVolume (ByVal device As IntPtr, ByVal volume As UInt32) Как Integer' – HK1

Смежные вопросы