3

coredll.dll の waveOutSetVolume を使用して、音声ボリュームを無音 (または無音に近い) から最大まで徐々に上げようとしています。

私が見つけたコード例のほとんどは、次のように、オフ、低、標準、中、高、および非常に高のいくつかの事前定義された設定値を示しています。

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 で .Net Compact Framework 3.5 と共に VB.Net を使用しています。C# で解決策があれば、それで問題ありません。

編集:
私が今読んだことから、上記の列挙値は16進数に基づいており、00000000が可能な限り低いボリュームで、FFFFFFFFが可能な限り高いボリュームです。VB.Netで16進数を徐々に増やし、同時に整数に変換する方法がわからないため、それでもあまり役に立ちません。また、ここで 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

OK、ここにいくつかの API ドキュメントがありますが、この特定のコンテキストではあまり意味がありません。下位語と上位語とは何ですか? また、どのようにして両方が単一の値に存在することができますか?

· dwVolume
新しいボリューム設定。下位ワードには左チャンネルの音量設定が含まれ、上位ワードには右チャンネルの設定が含まれます。値 0xFFFF はフル ボリュームを表し、値 0x0000 は無音です。デバイスが左右両方のボリューム コントロールをサポートしていない場合、dwVolume の下位ワードはボリューム レベルを指定し、上位ワードは無視されます。

4

1 に答える 1

5

最初に、C# で回答することを少しお詫びさせてください。早すぎるし、コーヒーも飲んでいないので、VB の頭の中での翻訳機はまだ起動していません。

列挙型の値は、16 進数の方が見栄えがよく、理解しやすいです。

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[左] | 0x0000FFFF[右] == 0xffffffff

1 回の変更で 0x0099 などのゼロ以外の低い値があった場合、ステレオ値は次のようになります。

0x00990099

したがって、両方のチャネルを同じ量だけ継続的に上げるには、ゼロから ushort.MaxValue (0xffff) までループし、DWORD (32 ビット uint) 内の両方の WORD (16 ビット ushort) を同じ値に設定します。

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な効果を得るために増加するステップを調整する必要があります。また、直線的な進行ではないことが多いため、単純に i をインクリメントするだけでも、より複雑にする必要があるかもしれませんが、おわかりいただけたと思います。

編集1

私はコーヒーを飲んだので:

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 | right
    waveOutSetVolume(both)
    Thread.Sleep(10)
Next
于 2012-06-19T13:38:41.940 に答える