Search code examples
c#windowsnaudio

Setting MMDevice WaveFormat


enter image description here

I am trying to set the WaveFormat for recording audio device "MMDevice" using this code I am using NAudio:

// Getting The WaveFormat for the device
    var value = selectedRecordingDevices.Properties[PropertyKeys.PKEY_AudioEngine_DeviceFormat].Value as byte[];
                IntPtr unmanagedPointer = Marshal.AllocHGlobal(value.Length);
                Marshal.Copy(value, 0, unmanagedPointer, value.Length);
                Marshal.FreeHGlobal(unmanagedPointer);
                var waveFormat = WaveFormat.MarshalFromPtr(unmanagedPointer);


// Setting The WaveFormat for the device
                WaveFormat w = new WaveFormat(44100, 16, 2);
                PropVariant p = new PropVariant();
                p.pointerValue = WaveFormatToPointer(w);
                selectedRecordingDevices.Properties.SetValue(PropertyKeys.PKEY_AudioEngine_DeviceFormat, p);



    public static IntPtr WaveFormatToPointer(WaveFormat format)
        {
            IntPtr formatPointer = Marshal.AllocHGlobal(Marshal.SizeOf(format));
            Marshal.StructureToPtr(format, formatPointer, false);
            return formatPointer;
        }

and I am getting this exception :

System.UnauthorizedAccessException
  HResult=0x80070005
  Message=Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
  Source=NAudio
  StackTrace:
   at NAudio.CoreAudioApi.Interfaces.IPropertyStore.SetValue(PropertyKey& key, PropVariant& value)
   at NAudio.CoreAudioApi.PropertyStore.SetValue(PropertyKey key, PropVariant value)

Solution

  • 1- Before Setting the value you need to set the StorageAccessMode:

    selectedRecordingDevice.GetPropertyInformation(StorageAccessMode.ReadWrite);
    

    so it will look like this:

          // Setting The WaveFormat for the device
                            WaveFormat w = new WaveFormat(44100, 16, 2);
                            PropVariant p = new PropVariant();
                            p.pointerValue = WaveFormatToPointer(w);
    
    
        selectedRecordingDevice.GetPropertyInformation(StorageAccessMode.ReadWrite);
    
    
    
    
      selectedRecordingDevices.Properties.SetValue(PropertyKeys.PKEY_AudioEngine_DeviceFormat, p);
    

    2- It has to run as Admin