locked
midiOutSetVolume failes even if MIDICAPS_VOLUME set RRS feed

  • Question

  • I have an issue with midiOutSetVolume function from winmm library. I use it from C#. The problem is it fails even if midiOutGetDevCaps returns struct where dwSupport has MIDICAPS_VOLUME flag set. As example of device with this behavior you can try built-in Microsoft GS Wavetable Synth.

    Exact error message is: This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports. But I use midiOutGetDevCaps to get capabilities and the device supports volume control :)

    Can someone explain why function fails in case where it mustn't?

    Monday, February 17, 2020 5:49 PM

Answers

  • Hi,

    Thanks for posting here.

    The following sample work for me with "Microsoft MIDI Mapper":

    using System;
    using System.Runtime.InteropServices;
    namespace ConsoleApp
    {
        class Program
        {
            #region Nested Types
    
            [StructLayout(LayoutKind.Sequential)]
            struct MIDIOUTCAPS
            {
                public UInt16 wMid;
                public UInt16 wPid;
                public UInt32 vDriverVersion;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
                public string szPname;
                public UInt16 wTechnology;
                public UInt16 wVoices;
                public UInt16 wNotes;
                public UInt16 wChannelMask;
                public UInt32 dwSupport;
            }
    
            #endregion Nested Types
    
            [DllImport("Winmm.dll")]
            private static extern uint midiOutGetNumDevs();
            [DllImport("Winmm.dll")]
            private static extern uint midiOutOpen(ref IntPtr phmo,uint uDeviceID, IntPtr dwCallback, IntPtr dwInstance, uint fdwOpen);
            [DllImport("Winmm.dll", CharSet = CharSet.Ansi, SetLastError = true)]
            private static extern uint midiOutGetDevCaps(uint uDeviceID, ref MIDIOUTCAPS pmoc, uint cbmoc);
            [DllImport("Winmm.dll")]
            private static extern uint midiOutGetVolume(IntPtr hmo, ref ulong dwVolume);
            [DllImport("Winmm.dll")]
            private static extern uint midiOutSetVolume(IntPtr hmo,ulong dwVolume);
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
                MIDIOUTCAPS midi = new MIDIOUTCAPS();
                uint MIDI_MAPPER = 0xffffffff; //(UINT)-1
                uint ret  = midiOutGetDevCaps(MIDI_MAPPER,ref midi, (UInt32)Marshal.SizeOf(midi));
                IntPtr phmo = new IntPtr();
                ret = midiOutOpen(ref phmo, MIDI_MAPPER, IntPtr.Zero, IntPtr.Zero, 0);
                ulong dw_oldVolume = 0;
                ret = midiOutGetVolume(phmo, ref dw_oldVolume);
                ulong dwVolume = 0;
                ret = midiOutSetVolume(phmo, dwVolume);
                ret = midiOutGetVolume(phmo, ref dwVolume);
                ret = midiOutSetVolume(phmo, dw_oldVolume);
            }
        }
    }
    

    Check if this sample work for you? Or could you provide a minimal sample that can reproduce this issue.

    Best Regards,

    Drake


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, February 18, 2020 3:48 AM

All replies

  • Hi,

    Thanks for posting here.

    The following sample work for me with "Microsoft MIDI Mapper":

    using System;
    using System.Runtime.InteropServices;
    namespace ConsoleApp
    {
        class Program
        {
            #region Nested Types
    
            [StructLayout(LayoutKind.Sequential)]
            struct MIDIOUTCAPS
            {
                public UInt16 wMid;
                public UInt16 wPid;
                public UInt32 vDriverVersion;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
                public string szPname;
                public UInt16 wTechnology;
                public UInt16 wVoices;
                public UInt16 wNotes;
                public UInt16 wChannelMask;
                public UInt32 dwSupport;
            }
    
            #endregion Nested Types
    
            [DllImport("Winmm.dll")]
            private static extern uint midiOutGetNumDevs();
            [DllImport("Winmm.dll")]
            private static extern uint midiOutOpen(ref IntPtr phmo,uint uDeviceID, IntPtr dwCallback, IntPtr dwInstance, uint fdwOpen);
            [DllImport("Winmm.dll", CharSet = CharSet.Ansi, SetLastError = true)]
            private static extern uint midiOutGetDevCaps(uint uDeviceID, ref MIDIOUTCAPS pmoc, uint cbmoc);
            [DllImport("Winmm.dll")]
            private static extern uint midiOutGetVolume(IntPtr hmo, ref ulong dwVolume);
            [DllImport("Winmm.dll")]
            private static extern uint midiOutSetVolume(IntPtr hmo,ulong dwVolume);
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
                MIDIOUTCAPS midi = new MIDIOUTCAPS();
                uint MIDI_MAPPER = 0xffffffff; //(UINT)-1
                uint ret  = midiOutGetDevCaps(MIDI_MAPPER,ref midi, (UInt32)Marshal.SizeOf(midi));
                IntPtr phmo = new IntPtr();
                ret = midiOutOpen(ref phmo, MIDI_MAPPER, IntPtr.Zero, IntPtr.Zero, 0);
                ulong dw_oldVolume = 0;
                ret = midiOutGetVolume(phmo, ref dw_oldVolume);
                ulong dwVolume = 0;
                ret = midiOutSetVolume(phmo, dwVolume);
                ret = midiOutGetVolume(phmo, ref dwVolume);
                ret = midiOutSetVolume(phmo, dw_oldVolume);
            }
        }
    }
    

    Check if this sample work for you? Or could you provide a minimal sample that can reproduce this issue.

    Best Regards,

    Drake


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, February 18, 2020 3:48 AM
  • Hi Drake,

    Can you test your sample with Microsoft GS Wavetable Synth?

    Tuesday, February 18, 2020 8:46 AM
  • Hmm, I've tested with Microsoft GS Wavetable Synth and volume set without errors. Maybe I'm doing something wrong. Thanks!
    Tuesday, February 18, 2020 10:39 AM
  • The Microsoft GS Wavetable Synth also works for me.

    Best Regard,

    Drake


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 19, 2020 1:24 AM
  • Drake,

    I forgot to call midiOutOpen. Thank you!

    Wednesday, February 19, 2020 12:31 PM