[.NET] Changer le volume du son de Windows

Amis DJ, suite à une question sur les forums Microsoft, je viens de développer une petite classe permettant aux utilisateurs de changer le volume du son de Windows. Pour cela je fais appel aux API Windows suivantes : waveOutGetVolume et waveOutSetVolume qui permettent respectivement de récupérer et de modifier le volume du son de Windows. 

Voici donc une classe statique qui contient 3 propriétés : Volume, VolumeDroite et VolumeGauche. Ces propriétés permettent de modifier le volume du son de Windows ou alors de changer la balance en jouant sur l’enceinte de gauche ou de droite. 

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; 

namespace Tourreau.Gilles.Volume
{
    /// <summary>
    /// Permet de changer le volume de Windows
    /// </summary>
    public static class Son
    {
        /// <summary>
        /// The waveOutGetVolume function retrieves the current volume level of the specified waveform-audio output device.
        /// </summary>
        /// <param name="hwo">Handle to an open waveform-audio output device. This parameter can also be a device identifier.</param>
        /// <param name="dwVolume">Pointer to a variable to be filled with the current volume setting. The low-order word of this location contains the left-channel volume setting, and the high-order word contains the right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.</param>
        /// <returns>Returns MMSYSERR_NOERROR if successful or an error otherwise. </returns>
        [DllImport("winmm.dll")]
        private static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);
 

        /// <summary>
        /// The waveOutSetVolume function sets the volume level of the specified waveform-audio output device.
        /// </summary>
        /// <param name="hwo">Handle to an open waveform-audio output device. This parameter can also be a device identifier.</param>
        /// <param name="dwVolume">New volume setting. The low-order word contains the left-channel volume setting, and the high-order word contains the right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.</param>
        /// <returns>Returns MMSYSERR_NOERROR if successful or an error otherwise.</returns>
        [DllImport("winmm.dll")]
        private static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
 

        /// <summary>
        /// Volume maximum
        /// </summary>
        public const int VolumeMax = 0x0000FFFF;
 

        /// <summary>
        /// Changer le volume pour l'enceinte à <paramref name="gauche"/> et à <paramref name="droite"/>.
        /// </summary>
        /// <param name="gauche">Volume de l'enceinte de gauche, si null alors le volume de l'enceinte de gauche n'est pas changé.</param>
        /// <param name="droite">Volume de l'enceinte de droite, si null alors le volume de l'enceinte de droite n'est pas changé.</param>
        private static void ChangerVolume(int? gauche, int? droite)
        {
            uint volume; 

            if (gauche == null)
            {
                gauche = VolumeGauche;
            } 

            if (droite == null)
            {
                droite = VolumeDroite;
            } 

            volume = ((uint)gauche.Value & 0x0000FFFF) << 16;
            volume = volume | ((uint)droite.Value & 0x0000FFFF); 

            waveOutSetVolume(IntPtr.Zero, volume);
        }
 

        /// <summary>
        /// Récupère le volume d'une des enceinte ou les deux.
        /// </summary>
        /// <param name="récupérerVolumeGauche">true pour récupérer le volume de l'enceint de gauche, false pour celle
        /// de droite, null pour les deux.</param>
        /// <returns>Le volume de l'enceint spécifiée ou la moyenne des deux.</returns>
        private static int GetVolume(bool? récupérerVolumeGauche)
        {
            uint volume;
            int gauche;
            int droite;

            waveOutGetVolume(IntPtr.Zero, out volume);

            gauche = (int)((volume & 0xFFFF0000) >> 16);
            droite = (int)(volume & 0x0000FFFF); 

            if (récupérerVolumeGauche != null)
            {
                if (récupérerVolumeGauche.Value == true)
                {
                    return gauche;
                }
                else
                {
                    return droite;
                }
            }
            else
            {
                return (gauche + droite) / 2;
            }
        } 

        /// <summary>
        /// Obtient ou défini le volume des enceintes
        /// </summary>
        /// <exception cref="ArgumentOutOfRangeException">Si <paramref name="value"/> est null.</exception>
        public static int Volume
        {
            get
            {
                return GetVolume(null);
            } 

            set
            {
                if (value < 0 && value > VolumeMax)
                {
                    throw new ArgumentOutOfRangeException(
                        String.Format("Le volume doit être compris entre 0 et {0}", VolumeMax),
                        "value");
                } 

                ChangerVolume(value, value);
            }
        }
 

        /// <summary>
        /// Obtient ou défini le volume de l'enceinte de gauche
        /// </summary>
        /// <remarks><paramref name="value"/> doit être compris entre 0 et <see cref="VolumeDroite"/>.</remarks>
        /// <exception cref="ArgumentOutOfRangeException">Si <paramref name="value"/> n'est pas compris entre 0 et <see cref="VolumeMax"/>.</exception>
        public static int VolumeGauche
        {
            get
            {
                return GetVolume(true);
            } 

            set
            {
                if (value < 0 && value > VolumeMax)
                {
                    throw new ArgumentOutOfRangeException(
                        String.Format("Le volume doit être compris entre 0 et {0}", VolumeMax),
                        "value");
                } 

                ChangerVolume(value, null);
            }
        }
 

        /// <summary>
        /// Obtient ou défini le volume de l'enceinte de droite.
        /// </summary>
        /// <remarks><paramref name="value"/> doit être compris entre 0 et <see cref="VolumeDroite"/>.</remarks>
        /// <exception cref="ArgumentOutOfRangeException">Si <paramref name="value"/> n'est pas compris entre 0 et <see cref="VolumeDroite"/>.</exception>
        public static int VolumeDroite
        {
            get
            {
                return GetVolume(false);
            } 

            set
            {
                if (value < 0 && value > VolumeMax)
                {
                    throw new ArgumentOutOfRangeException(
                        String.Format("Le volume doit être compris entre 0 et {0}", VolumeMax),
                        "value");
                } 

                ChangerVolume(null, value);
            }
        }
    }
} 

 

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices 

Namespace Tourreau.Gilles.Volume
    ''' <summary>
    ''' Permet de changer le volume de Windows
    ''' </summary>
    Public Module Son

        ''' <summary>
        ''' The waveOutGetVolume function retrieves the current volume level of the specified waveform-audio output device.
        ''' </summary>
        ''' <param name="hwo">Handle to an open waveform-audio output device. This parameter can also be a device identifier.</param>
        ''' <param name="dwVolume">Pointer to a variable to be filled with the current volume setting. The low-order word of this location contains the left-channel volume setting, and the high-order word contains the right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.</param>
        ''' <returns>Returns MMSYSERR_NOERROR if successful or an error otherwise. </returns>
        <DllImport("winmm.dll")> _
        Private Function waveOutGetVolume(ByVal hwo As IntPtr, ByRef dwVolume As UInteger) As Integer
        End Function
       
        ''' <summary>
        ''' The waveOutSetVolume function sets the volume level of the specified waveform-audio output device.
        ''' </summary>
        ''' <param name="hwo">Handle to an open waveform-audio output device. This parameter can also be a device identifier.</param>
        ''' <param name="dwVolume">New volume setting. The low-order word contains the left-channel volume setting, and the high-order word contains the right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.</param>
        ''' <returns>Returns MMSYSERR_NOERROR if successful or an error otherwise.</returns>
        <DllImport("winmm.dll")> _
        Private Function waveOutSetVolume(ByVal hwo As IntPtr, ByVal dwVolume As UInteger) As Integer
        End Function
       
        ''' <summary>
        ''' Volume maximum
        ''' </summary>
        Public Const VolumeMax As Integer = &Hffff
       
        ''' <summary>
        ''' Changer le volume pour l'enceinte à <paramref name="gauche"/> et à <paramref name="droite"/>.
        ''' </summary>
        ''' <param name="gauche">Volume de l'enceinte de gauche, si null alors le volume de l'enceinte de gauche n'est pas changé.</param>
        ''' <param name="droite">Volume de l'enceinte de droite, si null alors le volume de l'enceinte de droite n'est pas changé.</param>
        Private Sub ChangerVolume(ByVal gauche As System.Nullable(Of Integer), ByVal droite As System.Nullable(Of Integer))
            Dim volume As UInteger
           
            If gauche Is Nothing Then
                gauche = VolumeGauche
            End If
           
            If droite Is Nothing Then
                droite = VolumeDroite
            End If
           
            volume = (CUInt(gauche.Value) And &Hffff) << 16
            volume = volume Or (CUInt(droite.Value) And &Hffff)
           
            waveOutSetVolume(IntPtr.Zero, volume)
        End Sub
       
        ''' <summary>
        ''' Récupère le volume d'une des enceinte ou les deux.
        ''' </summary>
        ''' <param name="récupérerVolumeGauche">true pour récupérer le volume de l'enceint de gauche, false pour celle
        ''' de droite, null pour les deux.</param>
        ''' <returns>Le volume de l'enceint spécifiée ou la moyenne des deux.</returns>
        Private Function GetVolume(ByVal récupérerVolumeGauche As System.Nullable(Of Boolean)) As Integer
            Dim volume As UInteger
            Dim gauche As Integer
            Dim droite As Integer
           
            waveOutGetVolume(IntPtr.Zero, volume)
           
            gauche = CInt(((volume And &Hffff0000) >> 16))
            droite = CInt((volume And &Hffff))
           
            If récupérerVolumeGauche IsNot Nothing Then
                If récupérerVolumeGauche.Value = True Then
                    Return gauche
                Else
                    Return droite
                End If
            Else
                Return (gauche + droite) / 2
            End If
        End Function
       
        ''' <summary>
        ''' Obtient ou défini le volume des enceintes
        ''' </summary>
        ''' <exception cref="ArgumentOutOfRangeException">Si <paramref name="value"/> est null.</exception>
        Public Property Volume() As Integer
            Get
                Return GetVolume(Nothing)
            End Get
           
            Set(ByVal value As Integer)
                If value < 0 AndAlso value > VolumeMax Then
                    Throw New ArgumentOutOfRangeException([String].Format("Le volume doit être compris entre 0 et {0}", VolumeMax), "value")
                End If
               
                ChangerVolume(value, value)
            End Set
        End Property
       
        ''' <summary>
        ''' Obtient ou défini le volume de l'enceinte de gauche
        ''' </summary>
        ''' <remarks><paramref name="value"/> doit être compris entre 0 et <see cref="VolumeDroite"/>.</remarks>
        ''' <exception cref="ArgumentOutOfRangeException">Si <paramref name="value"/> n'est pas compris entre 0 et <see cref="VolumeMax"/>.</exception>
        Public Property VolumeGauche() As Integer
            Get
                Return GetVolume(True)
            End Get
           
            Set(ByVal value As Integer)
                If value < 0 AndAlso value > VolumeMax Then
                    Throw New ArgumentOutOfRangeException([String].Format("Le volume doit être compris entre 0 et {0}", VolumeMax), "value")
                End If
               
                ChangerVolume(value, Nothing)
            End Set
        End Property
       
        ''' <summary>
        ''' Obtient ou défini le volume de l'enceinte de droite.
        ''' </summary>
        ''' <remarks><paramref name="value"/> doit être compris entre 0 et <see cref="VolumeDroite"/>.</remarks>
        ''' <exception cref="ArgumentOutOfRangeException">Si <paramref name="value"/> n'est pas compris entre 0 et <see cref="VolumeDroite"/>.</exception>
        Public Property VolumeDroite() As Integer
            Get
                Return GetVolume(False)
            End Get
           
            Set(ByVal value As Integer)
                If value < 0 AndAlso value > VolumeMax Then
                    Throw New ArgumentOutOfRangeException([String].Format("Le volume doit être compris entre 0 et {0}", VolumeMax), "value")
                End If
               
                ChangerVolume(Nothing, value)
            End Set
        End Property
    End Module
End Namespace 

Cette classe s’utilise très facilement, il suffit de spécifier le volume qui est tout simple un nombre compris entre 0 et Son.VolumeMax : 


// Modifier le volume
Son.Volume = 1000; 


' Modifier le volume
Son.Volume = 1000; 

J’ai réalisé un projet d’exemple qui utilise un TrackBar pour changer le son. Vous pouvez télécharger ce projet d’exemple en C# ou VB .NET (les projets ont été réalisé avec Visual Studio 2008 et utilise le .NET Framework 2.0) :

Publié dans la catégorie .NET Framework.
Tags : , , , . TrackBack URL.

Un commentaire

  1. TheMutthon dit :

    merci

Leave a comment