[PreserveSig] public int 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, that's 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. // AUDIO_VOLUME_NOTIFICATION_DATA data = (AUDIO_VOLUME_NOTIFICATION_DATA)Marshal.PtrToStructure(NotifyData, typeof(AUDIO_VOLUME_NOTIFICATION_DATA)); //Determine offset in structure of the first float IntPtr Offset = Marshal.OffsetOf(typeof(AUDIO_VOLUME_NOTIFICATION_DATA), "ChannelVolume"); //Determine offset in memory of the first float IntPtr FirstFloatPtr = (IntPtr)((long)NotifyData + (long)Offset); float[] voldata = new float[data.nChannels]; //Read all floats from memory. for (int i = 0; i < data.nChannels; i++) { voldata[i] = (float)Marshal.PtrToStructure(FirstFloatPtr, typeof(float)); } //Create combined structure and Fire Event in parent class. AudioVolumeNotificationData NotificationData = new AudioVolumeNotificationData(data.guidEventContext, data.bMuted, data.fMasterVolume, voldata); _Parent.FireNotification(NotificationData); return(0); //S_OK }
public int OnNotify(IntPtr notifyData) { //https://github.com/naudio/NAudio/blob/master/NAudio/CoreAudioApi/AudioEndpointVolumeCallback.cs //"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." //get only static data: AUDIO_VOLUME_NOTIFICATION_DATA data = Marshal.PtrToStructure <AUDIO_VOLUME_NOTIFICATION_DATA>(notifyData); //don't fire event if callback was called because of changes of volume inside the app if (data.guidEventContext.Equals(GuidValue.Internal.VolumeGUID)) { return(0); } int newVolumeValue = Convert.ToInt32(data.masterVolume * 100); //prevent invoking event if new volume value is not the same as the actual device volume value this.endpointVolume.GetMasterVolumeLevelScalar(out float volumeLevel); var actualVolumeValue = Convert.ToInt32(volumeLevel * 100); if (newVolumeValue != actualVolumeValue) { return(0); } this.VolumeChanged?.Invoke(new VolumeChangedEventArgs(newVolumeValue, data.isMuted)); Marshal.DestroyStructure <AUDIO_VOLUME_NOTIFICATION_DATA>(notifyData); return(0); }
public void SetExpected(string type, AUDIO_VOLUME_NOTIFICATION_DATA expected) { _type = type; _expected = expected; _tested = false; _passed = false; }
public int OnNotify(IntPtr dataPtr) { if (String.IsNullOrEmpty(_type)) { return(0); } var localType = _type; _type = null; _tested = true; AUDIO_VOLUME_NOTIFICATION_DATA notificationData = (AUDIO_VOLUME_NOTIFICATION_DATA)System.Runtime.InteropServices.Marshal.PtrToStructure(dataPtr, typeof(AUDIO_VOLUME_NOTIFICATION_DATA)); Assert.AreEqual(_expected.EventContext, notificationData.EventContext); switch (localType) { case "MuteState": Assert.AreEqual(_expected.IsMuted, notificationData.IsMuted); break; case "MasterVolume": Assert.AreEqual(_expected.MasterVolume, notificationData.MasterVolume); break; } _passed = true; return(0); }
void IAudioEndpointVolumeCallback.OnNotify(ref AUDIO_VOLUME_NOTIFICATION_DATA pNotify) { _volume = pNotify.fMasterVolume; _isMuted = pNotify.bMuted != 0; _dispatcher.BeginInvoke((Action)(() => { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Volume))); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsMuted))); })); }
public void OnNotify(IntPtr pNotify, AUDIO_VOLUME_NOTIFICATION_DATA data) { var channelVolumesValues = new float[data.nChannels]; Marshal.Copy(IntPtr.Add(pNotify, _afChannelVolumesOffset), channelVolumesValues, 0, (int)data.nChannels); for (var i = 0; i < data.nChannels; i++) { Channels[i].OnNotify(channelVolumesValues[i]); } }
public int OnNotify(IntPtr NotifyData) { AUDIO_VOLUME_NOTIFICATION_DATA audio_volume_notification_data = (AUDIO_VOLUME_NOTIFICATION_DATA)Marshal.PtrToStructure(NotifyData, typeof(AUDIO_VOLUME_NOTIFICATION_DATA)); IntPtr ptr = Marshal.OffsetOf(typeof(AUDIO_VOLUME_NOTIFICATION_DATA), "ChannelVolume"); IntPtr ptr2 = (IntPtr)(((long)NotifyData) + ((long)ptr)); float[] channelVolume = new float[audio_volume_notification_data.nChannels]; for (int i = 0; i < audio_volume_notification_data.nChannels; i++) { channelVolume[i] = (float)Marshal.PtrToStructure(ptr2, typeof(float)); } AudioVolumeNotificationData notificationData = new AudioVolumeNotificationData(audio_volume_notification_data.guidEventContext, audio_volume_notification_data.bMuted, audio_volume_notification_data.fMasterVolume, channelVolume); this._Parent.FireNotification(notificationData); return(0); }