/// <summary> /// The GetPeakValue method gets the peak sample value for the channels in the audio stream. /// </summary> /// <returns>HRESULT</returns> public unsafe int GetPeakValueNative(out float peak) { fixed(void *ptr = &peak) { return(InteropCalls.CallI(_basePtr, ptr, ((void **)(*(void **)_basePtr))[3])); } }
/// <summary> /// The <see cref="GetDevicePositionNative" /> method gets the current device position, in frames, directly from the /// hardware. /// </summary> /// <param name="devicePosition"> /// Receives the device position, in frames. The received position is an unprocessed value /// that the method obtains directly from the hardware. For more information, see /// <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd370883(v=vs.85).aspx" />. /// </param> /// <param name="qpcPosition"> /// Receives the value of the performance counter at the time that the audio endpoint device read /// the device position retrieved in the <paramref name="devicePosition" /> parameter in response to the /// <see cref="GetDevicePositionNative" /> call. /// <see cref="GetDevicePositionNative" /> converts the counter value to 100-nanosecond time units before writing it to /// QPCPosition. /// </param> /// <returns>HRESULT</returns> public unsafe int GetDevicePositionNative(out long devicePosition, out long qpcPosition) { fixed(void *p0 = &devicePosition, p1 = &qpcPosition) { return(InteropCalls.CallI(UnsafeBasePtr, p0, p1, ((void **)(*(void **)UnsafeBasePtr))[3])); } }
/// <summary> /// Retrieves the grouping parameter of the audio session. /// <seealso cref="GroupingParam"/> /// </summary> /// <param name="groupingParam">A variable into which the method writes the grouping parameter.</param> /// <returns>HRESULT</returns> /// <remarks>For some more information about grouping parameters, see <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd370848(v=vs.85).aspx"/>.</remarks> public unsafe int GetGroupingParamNative(out Guid groupingParam) { fixed(void *p = &groupingParam) { return(InteropCalls.CallI(UnsafeBasePtr, p, ((void **)(*(void **)UnsafeBasePtr))[8])); } }
/// <summary> /// Indicates whether the audio endpoint device /// supports a particular stream format. /// </summary> /// <param name="shareMode"> /// The sharing mode for the stream format. Through this parameter, the client indicates whether it /// wants to use the specified format in exclusive mode or shared mode. /// </param> /// <param name="waveFormat">The stream format to test whether it is supported by the <see cref="AudioClient" /> or not.</param> /// <param name="closestMatch"> /// Retrieves the supported format that is closest to the format that the client specified /// through the <paramref name="waveFormat" /> parameter. If <paramref name="shareMode" /> is /// <see cref="AudioClientShareMode.Shared" />, the <paramref name="closestMatch" /> will be always null. /// </param> /// <returns> /// HRESULT code. If the method returns 0 (= <see cref="HResult.S_OK" />), the endpoint device supports the specified /// <paramref name="waveFormat" />. If the method returns /// 1 (= <see cref="HResult.S_FALSE" />), the method succeeded with a <paramref name="closestMatch" /> to the specified /// <paramref name="waveFormat" />. If the method returns /// 0x88890008 (= <see cref="HResult.AUDCLNT_E_UNSUPPORTED_FORMAT" />), the method succeeded but the specified format /// is not supported in exclusive mode. If the method returns anything else, the method failed. /// </returns> /// <remarks> /// For more information, see /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd370876(v=vs.85).aspx" />. /// </remarks> public unsafe int IsFormatSupportedNative(AudioClientShareMode shareMode, WaveFormat waveFormat, out WaveFormat closestMatch) { closestMatch = null; IntPtr pclosestMatch = IntPtr.Zero; GCHandle hWaveFormat = GCHandle.Alloc(waveFormat, GCHandleType.Pinned); int result; try { result = InteropCalls.CallI(UnsafeBasePtr, shareMode, hWaveFormat.AddrOfPinnedObject().ToPointer(), shareMode == AudioClientShareMode.Shared ? &pclosestMatch : IntPtr.Zero.ToPointer(), ((void **)(*(void **)UnsafeBasePtr))[7]); if (pclosestMatch != IntPtr.Zero) { closestMatch = (WaveFormat)Marshal.PtrToStructure(pclosestMatch, typeof(WaveFormat)); if (closestMatch.ExtraSize == WaveFormatExtensible.WaveFormatExtensibleExtraSize) { closestMatch = (WaveFormatExtensible)Marshal.PtrToStructure(pclosestMatch, typeof(WaveFormatExtensible)); } } } finally { hWaveFormat.Free(); if (pclosestMatch != IntPtr.Zero) { Marshal.FreeCoTaskMem(pclosestMatch); } } return(result); }
/// <summary> /// Retrieves the length of the periodic interval separating /// successive processing passes by the audio engine on the data in the endpoint buffer. /// </summary> /// <param name="hnsDefaultDevicePeriod"> /// Retrieves a time value specifying the default interval between periodic processing /// passes by the audio engine. The time is expressed in 100-nanosecond units. /// </param> /// <param name="hnsMinimumDevicePeriod"> /// Retrieves a time value specifying the minimum interval between periodic processing /// passes by the audio endpoint device. The time is expressed in 100-nanosecond units. /// </param> /// <remarks> /// Use the <paramref name="hnsDefaultDevicePeriod" /> and the <paramref name="hnsMinimumDevicePeriod" /> properties instead of /// the <see cref="GetDevicePeriodNative" /> method. /// For more information, see /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd370871(v=vs.85).aspx" />. /// </remarks> /// <returns>HRESULT</returns> public unsafe int GetDevicePeriodNative(out long hnsDefaultDevicePeriod, out long hnsMinimumDevicePeriod) { fixed(void *ddp = &hnsDefaultDevicePeriod, mdp = &hnsMinimumDevicePeriod) { return(InteropCalls.CallI(UnsafeBasePtr, ddp, mdp, ((void **)(*(void **)UnsafeBasePtr))[9])); } }
/// <summary> /// Gets the total number of audio sessions that are open on the audio device. /// <seealso cref="Count"/> /// </summary> /// <param name="count">Receives the total number of audio sessions.</param> /// <returns>HRESULT</returns> public unsafe int GetCountNative(out int count) { fixed(void *p = &count) { return(InteropCalls.CallI(UnsafeBasePtr, p, ((void **)(*(void **)UnsafeBasePtr))[3])); } }
/// <summary> /// Retrieves the maximum latency for the current stream and can /// be called any time after the stream has been initialized. /// </summary> /// <param name="hnsLatency">Retrieves a value representing the latency. The time is expressed in 100-nanosecond units.</param> /// <remarks> /// Rendering clients can use this latency value to compute the minimum amount of data that /// they can write during any single processing pass. To write less than this minimum is to /// risk introducing glitches into the audio stream. For more information, see /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd370874(v=vs.85).aspx" />. /// </remarks> /// <returns>HRESULT</returns> public unsafe int GetStreamLatencyNative(out long hnsLatency) { fixed(void *pl = &hnsLatency) { return(InteropCalls.CallI(UnsafeBasePtr, pl, ((void **)(*(void **)UnsafeBasePtr))[5])); } }
/// <summary> /// The GetVolumeStepInfo method gets information about the current step in the volume /// range. /// </summary> /// <param name="currentStep">Current stepindex. This value is a value in the range from 0 /// to stepCount.</param> /// <param name="stepCount">Number of steps in the volume range.</param> /// <returns>HRESULT</returns> public unsafe int GetVolumeStepInfoNative(out uint currentStep, out uint stepCount) { fixed(void *ptr1 = ¤tStep, ptr2 = &stepCount) { return(InteropCalls.CallI(_basePtr, ptr1, ptr2, ((void **)(*(void **)_basePtr))[16])); } }
/// <summary> /// The QueryHardwareSupport method queries the audio endpoint device for its /// hardware-supported functions. /// </summary> /// <returns>HRESULT</returns> public unsafe int QueryHardwareSupportNative(out EndpointHardwareSupport hardwareSupportMask) { fixed(void *ptr = &hardwareSupportMask) { return(InteropCalls.CallI(_basePtr, ptr, ((void **)(*(void **)_basePtr))[19])); } }
/// <summary> /// The GetChannelVolumeLevelScalar method gets the normalized, audio-tapered volume level /// of the specified channel of the audio stream that enters or leaves the audio endpoint /// device. /// </summary> /// <param name="level">Pointer to a float variable into which the method writes the volume /// level. The level is expressed as a normalized value in the range from 0.0 to /// 1.0.</param> /// <returns>HRESULT</returns> public unsafe int GetChannelVolumeLevelScalarNative(uint channel, out float level) { fixed(void *ptr = &level) { return(InteropCalls.CallI(_basePtr, channel, ptr, ((void **)(*(void **)_basePtr))[13])); } }
/// <summary> /// The GetMute method gets the muting state of the audio stream that enters or leaves the /// audio endpoint device. /// </summary> /// <param name="mute">True = Stream is muted. False = Stream is not muted.</param> /// <returns>HRESULT</returns> public unsafe int GetMuteNative(out NativeBool mute) { fixed(void *ptr = &mute) { return(InteropCalls.CallI(_basePtr, ptr, ((void **)(*(void **)_basePtr))[15])); } }
/// <summary> /// The GetMasterVolumeLevelScalar method gets the master volume level of the audio stream /// that enters or leaves the audio endpoint device. The volume level is expressed as a /// normalized, audio-tapered value in the range from 0.0 to 1.0. /// </summary> /// <param name="level">Pointer to the master volume level. This parameter points to a float /// variable into which the method writes the volume level. The level is expressed as a /// normalized value in the range from 0.0 to 1.0.</param> /// <returns>HRESULT</returns> public unsafe int GetMasterVolumeLevelScalarNative(out float level) { fixed(void *ptr = &level) { return(InteropCalls.CallI(_basePtr, ptr, ((void **)(*(void **)_basePtr))[9])); } }
/// <summary> /// The GetChannelCount method gets a count of the channels in the audio stream that enters /// or leaves the audio endpoint device. /// </summary> /// <returns>HRESULT</returns> public unsafe int GetChannelCountNative(out uint channelCount) { fixed(void *ptr = &channelCount) { return(InteropCalls.CallI(_basePtr, ptr, ((void **)(*(void **)_basePtr))[5])); } }
/// <summary> /// Indicates whether the endpoint is associated with a rendering device or a capture device. /// </summary> /// <param name="dataFlow">A variable into which the method writes the data-flow direction of the endpoint device.</param> /// <returns>HRESULT</returns> /// <remarks>Use the <see cref="DataFlow"/> property instead.</remarks> public unsafe int GetDataFlowNative(out DataFlow dataFlow) { fixed(void *p = &dataFlow) { return(InteropCalls.CallI(UnsafeBasePtr, p, ((void **)*(void **)UnsafeBasePtr)[3])); } }
/// <summary> /// The GetCharacteristics method is reserved for future use. /// </summary> /// <param name="characteristics">Value that indicates the characteristics of the audio clock.</param> /// <returns>HREUSLT</returns> public unsafe int GetCharacteristicsNative(out int characteristics) { fixed(void *p = &characteristics) { return(InteropCalls.CallI(UnsafeBasePtr, p, ((void **)(*(void **)UnsafeBasePtr))[5])); } }
/// <summary> /// The GetVolumeRange method gets the volume range, in decibels, of the audio stream that /// enters or leaves the audio endpoint device. /// </summary> /// <param name="volumeMinDB">Minimum volume level in decibels. This value remains constant /// for the lifetime of the IAudioEndpointVolume interface instance.</param> /// <param name="volumeMaxDB">Maximum volume level in decibels. This value remains constant /// for the lifetime of the IAudioEndpointVolume interface instance.</param> /// <param name="volumeIncrementDB">Volume increment in decibels. This increment remains /// constant for the lifetime of the IAudioEndpointVolume interface instance.</param> /// <returns>HREUSLT</returns> public unsafe int GetVolumeRangeNative(out float volumeMinDB, out float volumeMaxDB, out float volumeIncrementDB) { fixed(void *ptr1 = &volumeMinDB, ptr2 = &volumeMaxDB, ptr3 = &volumeIncrementDB) { return(InteropCalls.CallI(_basePtr, ptr1, ptr2, ptr3, ((void **)(*(void **)_basePtr))[20])); } }
/// <summary> /// The GetFrequency method gets the device frequency. /// </summary> /// <param name="pu64Frequency"> /// The device frequency. For more information, see /// <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd370889(v=vs.85).aspx" />. /// </param> /// <returns>HRESULT</returns> public unsafe int GetFrequencyNative(out long pu64Frequency) { fixed(void *p = &pu64Frequency) { return(InteropCalls.CallI(UnsafeBasePtr, p, ((void **)(*(void **)UnsafeBasePtr))[3])); } }
/// <summary> /// The GetNextPacketSize method retrieves the number of frames in the next data packet in /// the capture endpoint buffer. /// http: //msdn.microsoft.com/en-us/library/dd370860(v=vs.85).aspx /// </summary> /// <returns>HRESULT</returns> public unsafe int GetNextPacketSizeNative(out UInt32 numFramesInNextPacket) { fixed(void *p = &numFramesInNextPacket) { return(InteropCalls.CallI(_basePtr, p, ((void **)(*(void **)_basePtr))[5])); } }
/// <summary> /// Retrieves the size (maximum capacity) of the endpoint buffer. /// </summary> /// <param name="bufferFramesCount">Retrieves the number of audio frames that the buffer can hold.</param> /// <remarks> /// The size of one frame = <c>(number of bits per sample)/8 * (number of channels)</c> /// </remarks> /// <returns>HRESULT</returns> public unsafe int GetBufferSizeNative(out Int32 bufferFramesCount) { fixed(void *pbfc = &bufferFramesCount) { return(InteropCalls.CallI(UnsafeBasePtr, pbfc, ((void **)(*(void **)UnsafeBasePtr))[4])); } }
//-- /// <summary> /// Registers the application to receive ducking notifications. /// <seealso cref="RegisterDuckNotification"/> /// </summary> /// <param name="sessionId">A string that contains a session instance identifier. Applications that are playing a media stream and want to provide custom stream attenuation or ducking behavior, pass their own session instance identifier. /// Other applications that do not want to alter their streams but want to get all the ducking notifications must pass NULL.</param> /// <param name="sessionNotification">Instance of any object which implements the <see cref="IAudioVolumeDuckNotification"/> and which should receive duck notifications.</param> /// <returns>HRESULT</returns> public unsafe int RegisterDuckNotificationNative(string sessionId, IAudioVolumeDuckNotification sessionNotification) { int result = 0; if (!_volumeDuckNotifications.Contains(sessionNotification)) { IntPtr ptr = sessionNotification != null ? Marshal.GetComInterfaceForObject(sessionNotification, typeof(IAudioVolumeDuckNotification)) : IntPtr.Zero; IntPtr ptr0 = sessionId != null?Marshal.StringToHGlobalUni(sessionId) : IntPtr.Zero; try { result = InteropCalls.CallI(UnsafeBasePtr, (void *)ptr0, (void *)ptr, ((void **)(*(void **)UnsafeBasePtr))[8]); } finally { if (ptr != IntPtr.Zero) { Marshal.Release(ptr); } if (ptr0 != IntPtr.Zero) { Marshal.FreeHGlobal(ptr0); } } _volumeDuckNotifications.Add(sessionNotification); } return(result); }
/// <summary> /// Retrieves the number of frames of padding in the endpoint buffer. /// </summary> /// <param name="numPaddingFrames">Retrieves the frame count (the number of audio frames of padding in the buffer).</param> /// <returns>HRESULT</returns> /// <remarks> /// The size of one frame = <c>(number of bits per sample)/8 * (number of channels)</c> /// </remarks> public unsafe int GetCurrentPaddingNative(out Int32 numPaddingFrames) { fixed(void *pndf = &numPaddingFrames) { return(InteropCalls.CallI(UnsafeBasePtr, pndf, ((void **)(*(void **)UnsafeBasePtr))[6])); } }
/// <summary> /// Deletes the registration to receive ducking notifications. /// <seealso cref="UnregisterDuckNotification"/> /// </summary> /// <param name="sessionNotification"> /// The <see cref="IAudioVolumeDuckNotification"/> interface that is implemented by the application. Pass the same interface pointer that was specified to the session manager in a previous call to the <see cref="RegisterDuckNotification"/> method. /// </param> /// <returns>HRESULT</returns> public unsafe int UnregisterDuckNotificationNative(IAudioVolumeDuckNotification sessionNotification) { int result = 0; if (_volumeDuckNotifications.Contains(sessionNotification)) { IntPtr ptr = sessionNotification != null ? Marshal.GetComInterfaceForObject(sessionNotification, typeof(IAudioVolumeDuckNotification)) : IntPtr.Zero; try { result = InteropCalls.CallI(UnsafeBasePtr, (void *)ptr, ((void **)(*(void **)UnsafeBasePtr))[9]); } finally { if (ptr != IntPtr.Zero) { Marshal.Release(ptr); } } _volumeDuckNotifications.Remove(sessionNotification); } return(result); }
/// <summary> /// Retrieves the stream format that the audio engine uses for its /// internal processing of shared-mode streams. /// </summary> /// <param name="deviceFormat"> /// Retrieves the mix format that the audio engine uses for its internal processing of /// shared-mode streams. /// </param> /// <remarks> /// For more information, see /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd370872(v=vs.85).aspx" />. /// </remarks> /// <returns>HRESULT</returns> public unsafe int GetMixFormatNative(out WaveFormat deviceFormat) { IntPtr pdeviceFormat = IntPtr.Zero; int result; if ((result = InteropCalls.CallI(UnsafeBasePtr, &pdeviceFormat, ((void **)(*(void **)UnsafeBasePtr))[8])) == 0 && pdeviceFormat != IntPtr.Zero) { try { //deviceFormat = Marshal.PtrToStructure(pdeviceFormat, typeof (WaveFormat)) as WaveFormat; //if (deviceFormat != null && deviceFormat.WaveFormatTag == AudioEncoding.Extensible) //{ // deviceFormat = // Marshal.PtrToStructure(pdeviceFormat, typeof (WaveFormatExtensible)) as WaveFormatExtensible; //} deviceFormat = WaveFormatMarshaler.PointerToWaveFormat(pdeviceFormat); } finally { Marshal.FreeCoTaskMem(pdeviceFormat); } return(result); } deviceFormat = null; return(result); }
/// <summary> /// Registers the application to receive a notification when a session is created. /// <seealso cref="RegisterSessionNotificationNative"/> /// </summary> /// <param name="sessionNotification">The application's implementation of the <see cref="IAudioSessionNotification"/> interface.</param> /// <returns>HRESULT</returns> /// <remarks> /// Use the <see cref="AudioSessionNotification"/> class as the default implementation for the <paramref name="sessionNotification"/> parameter. /// /// <c>Note:</c> Make sure to call the <see cref="RegisterSessionNotificationNative"/> from an MTA-Thread. Also make sure to enumerate all sessions after calling this method. /// </remarks> public unsafe int RegisterSessionNotificationNative(IAudioSessionNotification sessionNotification) { int result = 0; if (!_sessionNotifications.Contains(sessionNotification)) { IntPtr ptr = sessionNotification != null ? Marshal.GetComInterfaceForObject(sessionNotification, typeof(IAudioSessionNotification)) : IntPtr.Zero; try { result = InteropCalls.CallI( UnsafeBasePtr, ptr, ((void **)(*(void **)UnsafeBasePtr))[6]); } finally { if (ptr != IntPtr.Zero) { Marshal.Release(ptr); } } _sessionNotifications.Add(sessionNotification); } return(result); }
/// <summary> /// Accesses additional services from the audio client object. /// </summary> /// <param name="riid"> /// The interface ID for the requested service. For a list of all available values, see /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd370873(v=vs.85).aspx" />. /// </param> /// <param name="ppv"> /// A pointer variable into which the method writes the address of an instance of the /// requested interface. Through this method, the caller obtains a counted reference to the interface. The caller is /// responsible for releasing the interface, when it is no longer needed, by calling the interface's Release method. If /// the GetService call fails, *ppv is <see cref="IntPtr.Zero" />. /// </param> /// <returns>HRESULT</returns> /// <remarks> /// For more information, see /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd370873(v=vs.85).aspx" />. /// </remarks> public unsafe int GetServiceNative(Guid riid, out IntPtr ppv) { fixed(void *pppv = &ppv) { return(InteropCalls.CallI(UnsafeBasePtr, &riid, pppv, ((void **)(*(void **)UnsafeBasePtr))[14])); } }
/// <summary> /// Retrieves the current device state. /// </summary> /// <param name="state">The variable which will receive the <see cref="CoreAudioAPI.DeviceState"/> of the device.</param> /// <returns>HRESULT</returns> public unsafe int GetStateNative(out DeviceState state) { fixed(void *pstate = &state) { return(InteropCalls.CallI(UnsafeBasePtr, unchecked (pstate), ((void **)(*(void **)UnsafeBasePtr))[6])); } }
/// <summary> /// Retrieves the current state of the audio session. /// <seealso cref="SessionState"/> /// </summary> /// <param name="state">A variable into which the method writes the current session state.</param> /// <returns>HRESULT</returns> public unsafe int GetStateNative(out AudioSessionState state) { fixed(void *p = &state) { return(InteropCalls.CallI(UnsafeBasePtr, p, ((void **)(*(void **)UnsafeBasePtr))[3])); } }
/// <summary> /// The GetPosition method gets the current device position. /// </summary> /// <param name="pu64Position"> /// The device position is the offset from the start of the stream to the current position in the stream. However, the /// units in which this offset is expressed are undefined—the device position value has meaning only in relation to the /// <see cref="Pu64Frequency" />. For more information, see /// <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd370889(v=vs.85).aspx" />. /// </param> /// <param name="pu64QPCPosition"> /// The value of the performance counter at the time that the audio endpoint device read the device position /// (<paramref name="pu64Position" />) in response to the <see cref="GetPositionNative" /> call. The method converts /// the counter value to 100-nanosecond time /// units before writing it to <paramref name="pu64QPCPosition" />. /// </param> /// <returns>HRESULT</returns> // ReSharper disable once InconsistentNaming public unsafe int GetPositionNative(out long pu64Position, out long pu64QPCPosition) { fixed(void *p0 = &pu64Position, p1 = &pu64QPCPosition) { return(InteropCalls.CallI(UnsafeBasePtr, p0, p1, ((void **)(*(void **)UnsafeBasePtr))[4])); } }
/// <summary> /// Deletes a previous registration by the client to receive notifications. /// </summary> /// <param name="notifications">The instance of the <see cref="IAudioSessionEvents"/> object which got registered previously by the <see cref="RegisterAudioSessionNotification"/> method.</param> /// <returns>HRESULT</returns> public unsafe int UnregisterAudioSessionNotificationNative(IAudioSessionEvents notifications) { int result = 0; if (_sessionEventHandler.Contains(notifications)) { IntPtr ptr = notifications != null ? Marshal.GetComInterfaceForObject(notifications, typeof(IAudioSessionEvents)) : IntPtr.Zero; try { result = InteropCalls.CallI(UnsafeBasePtr, ptr.ToPointer(), ((void **)(*(void **)UnsafeBasePtr))[11]); } finally { if (ptr != IntPtr.Zero) { Marshal.Release(ptr); } } _sessionEventHandler.Remove(notifications); } return(result); }
/// <summary> /// Gets the process identifier of the audio session. /// <seealso cref="ProcessID"/> /// </summary> /// <param name="processId">A variable which receives the process id of the audio session.</param> /// <returns>HRESULT</returns> public unsafe int GetProcessIdNative(out int processId) { fixed(void *p = &processId) { return(InteropCalls.CallI(UnsafeBasePtr, p, ((void **)(*(void **)UnsafeBasePtr))[14])); } }