private static long GetDuration(IMFSourceReader reader) { var variantPtr = Marshal.AllocHGlobal(MarshalHelpers.SizeOf <PropVariant>()); try { int hResult = reader.GetPresentationAttribute(MediaFoundationInterop.MF_SOURCE_READER_MEDIASOURCE, MediaFoundationAttributes.MF_PD_DURATION, variantPtr); if (hResult == MediaFoundationErrors.MF_E_ATTRIBUTENOTFOUND) { return(0); } if (hResult != 0) { Marshal.ThrowExceptionForHR(hResult); } var variant = MarshalHelpers.PtrToStructure <PropVariant> (variantPtr); return((long)variant.Value); } finally { PropVariant.Clear(variantPtr); Marshal.FreeHGlobal(variantPtr); } }
private long GetLength(IMFSourceReader reader) { var variantPtr = Marshal.AllocHGlobal(MarshalHelpers.SizeOf <PropVariant>()); try { // http://msdn.microsoft.com/en-gb/library/windows/desktop/dd389281%28v=vs.85%29.aspx#getting_file_duration int hResult = reader.GetPresentationAttribute(MediaFoundationInterop.MF_SOURCE_READER_MEDIASOURCE, MediaFoundationAttributes.MF_PD_DURATION, variantPtr); if (hResult == MediaFoundationErrors.MF_E_ATTRIBUTENOTFOUND) { // this doesn't support telling us its duration (might be streaming) return(0); } if (hResult != 0) { Marshal.ThrowExceptionForHR(hResult); } var variant = MarshalHelpers.PtrToStructure <PropVariant>(variantPtr); var lengthInBytes = (((long)variant.Value) * waveFormat.AverageBytesPerSecond) / 10000000L; return(lengthInBytes); } finally { PropVariant.Clear(variantPtr); Marshal.FreeHGlobal(variantPtr); } }
public void OnNotify(IntPtr notifyData) { //Since AUDIO_VOLUME_NOTIFICATION_DATA is dynamic in length based on the //number of audio channels available we cannot just call PtrToStructure //to get all data, thats why it is split up into two steps, first the static //data is marshalled into the data structure, then with some IntPtr math the //remaining floats are read from memory. // var data = MarshalHelpers.PtrToStructure <AudioVolumeNotificationDataStruct>(notifyData); //Determine offset in structure of the first float var offset = MarshalHelpers.OffsetOf <AudioVolumeNotificationDataStruct>("ChannelVolume"); //Determine offset in memory of the first float var firstFloatPtr = (IntPtr)((long)notifyData + (long)offset); var voldata = new float[data.nChannels]; //Read all floats from memory. for (int i = 0; i < data.nChannels; i++) { voldata[i] = MarshalHelpers.PtrToStructure <float>(firstFloatPtr); } //Create combined structure and Fire Event in parent class. var notificationData = new AudioVolumeNotificationData(data.guidEventContext, data.bMuted, data.fMasterVolume, voldata, data.guidEventContext); parent.FireNotification(notificationData); }
/// <summary> /// Determines if the specified output format is supported in shared mode /// </summary> /// <param name="shareMode">Share Mode</param> /// <param name="desiredFormat">Desired Format</param> /// <param name="closestMatchFormat">Output The closest match format.</param> /// <returns>True if the format is supported</returns> public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { IntPtr pointerToPtr = GetPointerToPointer(); // IntPtr.Zero; // Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormatExtensible>()); closestMatchFormat = null; int hresult = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, pointerToPtr); var closestMatchPtr = MarshalHelpers.PtrToStructure <IntPtr>(pointerToPtr); if (closestMatchPtr != IntPtr.Zero) { closestMatchFormat = MarshalHelpers.PtrToStructure <WaveFormatExtensible>(closestMatchPtr); Marshal.FreeCoTaskMem(closestMatchPtr); } Marshal.FreeHGlobal(pointerToPtr); // S_OK is 0, S_FALSE = 1 if (hresult == 0) { // directly supported return(true); } if (hresult == 1) { return(false); } if (hresult == (int)AudioClientErrors.UnsupportedFormat) { // Succeeded but the specified format is not supported in exclusive mode. return(shareMode != AudioClientShareMode.Exclusive); } Marshal.ThrowExceptionForHR(hresult); // shouldn't get here throw new NotSupportedException("Unknown hresult " + hresult); }
/// <summary> /// Helper function to retrieve a WaveFormat structure from a pointer /// </summary> /// <param name="pointer">WaveFormat structure</param> /// <returns></returns> public static WaveFormat MarshalFromPtr(IntPtr pointer) { var waveFormat = MarshalHelpers.PtrToStructure <WaveFormat>(pointer); switch (waveFormat.Encoding) { case WaveFormatEncoding.Pcm: // can't rely on extra size even being there for PCM so blank it to avoid reading // corrupt data waveFormat.extraSize = 0; break; case WaveFormatEncoding.Extensible: waveFormat = MarshalHelpers.PtrToStructure <WaveFormatExtensible>(pointer); break; case WaveFormatEncoding.Adpcm: // waveFormat = MarshalHelpers.PtrToStructure<AdpcmWaveFormat>(pointer); break; case WaveFormatEncoding.Gsm610: // waveFormat = MarshalHelpers.PtrToStructure<Gsm610WaveFormat>(pointer); break; default: if (waveFormat.ExtraSize > 0) { waveFormat = MarshalHelpers.PtrToStructure <WaveFormatExtraData>(pointer); } break; } return(waveFormat); }
public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { IntPtr pointerToPointer = this.GetPointerToPointer(); closestMatchFormat = null; int num = this.audioClientInterface.IsFormatSupported(shareMode, desiredFormat, pointerToPointer); IntPtr intPtr = MarshalHelpers.PtrToStructure <IntPtr>(pointerToPointer); if (intPtr != IntPtr.Zero) { closestMatchFormat = MarshalHelpers.PtrToStructure <WaveFormatExtensible>(intPtr); Marshal.FreeCoTaskMem(intPtr); } Marshal.FreeHGlobal(pointerToPointer); if (num == 0) { return(true); } if (num == 1) { return(false); } if (num == -2004287480) { return(shareMode != AudioClientShareMode.Exclusive); } Marshal.ThrowExceptionForHR(num); throw new NotSupportedException("Unknown hresult " + num); }
private long GetLength(IMFSourceReader reader) { IntPtr intPtr = Marshal.AllocHGlobal(MarshalHelpers.SizeOf <PropVariant>()); long result; try { int presentationAttribute = reader.GetPresentationAttribute(-1, MediaFoundationAttributes.MF_PD_DURATION, intPtr); if (presentationAttribute == -1072875802) { result = 0L; } else { if (presentationAttribute != 0) { Marshal.ThrowExceptionForHR(presentationAttribute); } result = (long)MarshalHelpers.PtrToStructure <PropVariant>(intPtr).Value *(long)this.waveFormat.AverageBytesPerSecond / 10000000L; } } finally { PropVariant.Clear(intPtr); Marshal.FreeHGlobal(intPtr); } return(result); }
/// <summary> /// Gets the details for this control /// </summary> protected override void GetDetails(IntPtr pDetails) { unsignedDetails = new MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[nChannels]; for (int channel = 0; channel < nChannels; channel++) { unsignedDetails[channel] = MarshalHelpers.PtrToStructure <MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>(mixerControlDetails.paDetails); } }
/// <summary> /// Gets a specified Mixer Control /// </summary> /// <param name="mixerHandle">Mixer Handle</param> /// <param name="nLineId">Line ID</param> /// <param name="controlId">Control ID</param> /// <param name="nChannels">Number of Channels</param> /// <param name="mixerFlags">Flags to use (indicates the meaning of mixerHandle)</param> /// <returns></returns> public static MixerControl GetMixerControl(IntPtr mixerHandle, int nLineId, int controlId, int nChannels, MixerFlags mixerFlags) { var mlc = new MixerInterop.MIXERLINECONTROLS(); var mc = new MixerInterop.MIXERCONTROL(); // set up the pointer to a structure IntPtr pMixerControl = Marshal.AllocCoTaskMem(Marshal.SizeOf(mc)); //Marshal.StructureToPtr(mc, pMixerControl, false); mlc.cbStruct = Marshal.SizeOf(mlc); mlc.cControls = 1; mlc.dwControlID = controlId; mlc.cbmxctrl = Marshal.SizeOf(mc); mlc.pamxctrl = pMixerControl; mlc.dwLineID = nLineId; MmResult err = MixerInterop.mixerGetLineControls(mixerHandle, ref mlc, MixerFlags.OneById | mixerFlags); if (err != MmResult.NoError) { Marshal.FreeCoTaskMem(pMixerControl); throw new MmException(err, "mixerGetLineControls"); } // retrieve the structure from the pointer mc = MarshalHelpers.PtrToStructure <MixerInterop.MIXERCONTROL>(mlc.pamxctrl); Marshal.FreeCoTaskMem(pMixerControl); if (IsControlBoolean(mc.dwControlType)) { return(new BooleanMixerControl(mc, mixerHandle, mixerFlags, nChannels)); } if (IsControlSigned(mc.dwControlType)) { return(new SignedMixerControl(mc, mixerHandle, mixerFlags, nChannels)); } if (IsControlUnsigned(mc.dwControlType)) { return(new UnsignedMixerControl(mc, mixerHandle, mixerFlags, nChannels)); } if (IsControlListText(mc.dwControlType)) { return(new ListTextMixerControl(mc, mixerHandle, mixerFlags, nChannels)); } if (IsControlCustom(mc.dwControlType)) { return(new CustomMixerControl(mc, mixerHandle, mixerFlags, nChannels)); } throw new InvalidOperationException($"Unknown mixer control type {mc.dwControlType}"); }
private static void AddAttribute(IMFActivate mft, int index, StringBuilder sb) { var variantPtr = Marshal.AllocHGlobal(MarshalHelpers.SizeOf <PropVariant>()); try { Guid key; mft.GetItemByIndex(index, out key, variantPtr); var value = MarshalHelpers.PtrToStructure <PropVariant>(variantPtr); string propertyName = FieldDescriptionHelper.Describe(typeof(MediaFoundationAttributes), key); if (key == MediaFoundationAttributes.MFT_INPUT_TYPES_Attributes || key == MediaFoundationAttributes.MFT_OUTPUT_TYPES_Attributes) { var types = value.GetBlobAsArrayOf <MFT_REGISTER_TYPE_INFO>(); sb.AppendFormat("{0}: {1} items:", propertyName, types.Length); sb.AppendLine(); foreach (var t in types) { sb.AppendFormat(" {0}-{1}", FieldDescriptionHelper.Describe(typeof(MediaTypes), t.guidMajorType), FieldDescriptionHelper.Describe(typeof(AudioSubtypes), t.guidSubtype)); sb.AppendLine(); } } else if (key == MediaFoundationAttributes.MF_TRANSFORM_CATEGORY_Attribute) { sb.AppendFormat("{0}: {1}", propertyName, FieldDescriptionHelper.Describe(typeof(MediaFoundationTransformCategories), (Guid)value.Value)); sb.AppendLine(); } else if (value.DataType == (VarEnum.VT_VECTOR | VarEnum.VT_UI1)) { var b = (byte[])value.Value; sb.AppendFormat("{0}: Blob of {1} bytes", propertyName, b.Length); sb.AppendLine(); } else { sb.AppendFormat("{0}: {1}", propertyName, value.Value); sb.AppendLine(); } } finally { PropVariant.Clear(variantPtr); Marshal.FreeHGlobal(variantPtr); } }
private static void DescribeAttribute(IMFMediaType mediaType, int n, StringBuilder sb) { var variantPtr = Marshal.AllocHGlobal(MarshalHelpers.SizeOf <PropVariant>()); try { Guid key; mediaType.GetItemByIndex(n, out key, variantPtr); var val = MarshalHelpers.PtrToStructure <PropVariant>(variantPtr); string propertyName = FieldDescriptionHelper.Describe(typeof(MediaFoundationAttributes), key); sb.AppendFormat("{0}={1}\r\n", propertyName, val.Value); } finally { PropVariant.Clear(variantPtr); Marshal.FreeHGlobal(variantPtr); } }
public void OnNotify(IntPtr notifyData) { AudioVolumeNotificationDataStruct audioVolumeNotificationDataStruct = MarshalHelpers.PtrToStructure <AudioVolumeNotificationDataStruct>(notifyData); IntPtr value = MarshalHelpers.OffsetOf <AudioVolumeNotificationDataStruct>("ChannelVolume"); IntPtr pointer = (IntPtr)((long)notifyData + (long)value); float[] array = new float[audioVolumeNotificationDataStruct.nChannels]; int num = 0; while ((long)num < (long)((ulong)audioVolumeNotificationDataStruct.nChannels)) { array[num] = MarshalHelpers.PtrToStructure <float>(pointer); num++; } AudioVolumeNotificationData notificationData = new AudioVolumeNotificationData(audioVolumeNotificationDataStruct.guidEventContext, audioVolumeNotificationDataStruct.bMuted, audioVolumeNotificationDataStruct.fMasterVolume, array, audioVolumeNotificationDataStruct.guidEventContext); this.parent.FireNotification(notificationData); }
/// <summary> /// Gets all the mixer controls /// </summary> /// <param name="mixerHandle">Mixer Handle</param> /// <param name="mixerLine">Mixer Line</param> /// <param name="mixerHandleType">Mixer Handle Type</param> /// <returns></returns> public static IList <MixerControl> GetMixerControls(IntPtr mixerHandle, MixerLine mixerLine, MixerFlags mixerHandleType) { var controls = new List <MixerControl>(); if (mixerLine.ControlsCount > 0) { int mixerControlSize = MarshalHelpers.SizeOf <MixerInterop.MIXERCONTROL>(); var mlc = new MixerInterop.MIXERLINECONTROLS(); IntPtr pmc = Marshal.AllocHGlobal(mixerControlSize * mixerLine.ControlsCount); mlc.cbStruct = Marshal.SizeOf(mlc); mlc.dwLineID = mixerLine.LineId; mlc.cControls = mixerLine.ControlsCount; mlc.pamxctrl = pmc; mlc.cbmxctrl = MarshalHelpers.SizeOf <MixerInterop.MIXERCONTROL>(); try { MmResult err = MixerInterop.mixerGetLineControls(mixerHandle, ref mlc, MixerFlags.All | mixerHandleType); if (err != MmResult.NoError) { throw new MmException(err, "mixerGetLineControls"); } for (int i = 0; i < mlc.cControls; i++) { Int64 address = pmc.ToInt64() + mixerControlSize * i; var mc = MarshalHelpers.PtrToStructure <MixerInterop.MIXERCONTROL>((IntPtr)address); var mixerControl = GetMixerControl(mixerHandle, mixerLine.LineId, mc.dwControlID, mixerLine.Channels, mixerHandleType); controls.Add(mixerControl); } } finally { Marshal.FreeHGlobal(pmc); } } return(controls); }
public static WaveFormat MarshalFromPtr(IntPtr pointer) { WaveFormat waveFormat = MarshalHelpers.PtrToStructure <WaveFormat>(pointer); WaveFormatEncoding encoding = waveFormat.Encoding; if (encoding <= WaveFormatEncoding.Adpcm) { if (encoding == WaveFormatEncoding.Pcm) { waveFormat.extraSize = 0; return(waveFormat); } if (encoding == WaveFormatEncoding.Adpcm) { waveFormat = MarshalHelpers.PtrToStructure <AdpcmWaveFormat>(pointer); return(waveFormat); } } else { if (encoding == WaveFormatEncoding.Gsm610) { waveFormat = MarshalHelpers.PtrToStructure <Gsm610WaveFormat>(pointer); return(waveFormat); } if (encoding == WaveFormatEncoding.Extensible) { waveFormat = MarshalHelpers.PtrToStructure <WaveFormatExtensible>(pointer); return(waveFormat); } } if (waveFormat.ExtraSize > 0) { waveFormat = MarshalHelpers.PtrToStructure <WaveFormatExtraData>(pointer); } return(waveFormat); }
/// <summary> /// Determines if the specified output format is supported in shared mode /// </summary> /// <param name="shareMode">Share Mode</param> /// <param name="desiredFormat">Desired Format</param> /// <param name="closestMatchFormat">Output The closest match format.</param> /// <returns>True if the format is supported</returns> public bool IsFormatSupported(AudioClientShareMode shareMode, WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat) { IntPtr pointerToPtr = GetPointerToPointer(); // IntPtr.Zero; // Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormatExtensible>()); closestMatchFormat = null; int hresult = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, pointerToPtr); var closestMatchPtr = MarshalHelpers.PtrToStructure <IntPtr>(pointerToPtr); if (closestMatchPtr != IntPtr.Zero) { closestMatchFormat = MarshalHelpers.PtrToStructure <WaveFormatExtensible>(closestMatchPtr); Marshal.FreeCoTaskMem(closestMatchPtr); } Marshal.FreeHGlobal(pointerToPtr); // S_OK is 0, S_FALSE = 1 if (hresult == 0) { // directly supported return(true); } if (hresult == 1) { return(false); } if (hresult == (int)AudioClientErrors.UnsupportedFormat) { // documentation is confusing as to what this flag means // https://docs.microsoft.com/en-us/windows/desktop/api/audioclient/nf-audioclient-iaudioclient-isformatsupported // "Succeeded but the specified format is not supported in exclusive mode." return(false); // shareMode != AudioClientShareMode.Exclusive; } Marshal.ThrowExceptionForHR(hresult); // shouldn't get here throw new NotSupportedException("Unknown hresult " + hresult); }
/// <summary> /// Gets details for this contrl /// </summary> protected override void GetDetails(IntPtr pDetails) { signedDetails = MarshalHelpers.PtrToStructure <MixerInterop.MIXERCONTROLDETAILS_SIGNED>(mixerControlDetails.paDetails); }
/// <summary> /// Gets the details for this control /// </summary> /// <param name="pDetails">memory pointer</param> protected override void GetDetails(IntPtr pDetails) { boolDetails = MarshalHelpers.PtrToStructure <MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>(pDetails); }