It seemed that the above code actually was working but for some reason, not in the NAudioWin8Demo that I tried it in. When I created new test project, it started working. And in NAudioWin8Demo it started working if I set AudioStreamCategory to Communications.
Here is how the code looks after cleaning, in case you want to implement it too. Feel free to make changes if these changes fight against the architectural ideology behind NAudio:
(All changes are just into Win8 project, nothing was added to NAudio core project)
Add the following enums and struct to CoreAudioApi folder
I haven't tested the changes much yet and all testing I have done is with Windows 8.1. And AudioClientProperties.Options is only supported in Windows 8.1 as the comments state so I'm not sure what happens when trying to set it in Windows 8.0.
Regards,
Janne
Here is how the code looks after cleaning, in case you want to implement it too. Feel free to make changes if these changes fight against the architectural ideology behind NAudio:
(All changes are just into Win8 project, nothing was added to NAudio core project)
Add the following enums and struct to CoreAudioApi folder
namespace NAudio.CoreAudioApi
{
/// <summary>
/// Specifies the category of an audio stream.
/// </summary>
public enum AudioStreamCategory
{
/// <summary>
/// Other audio stream.
/// </summary>
Other = 0,
/// <summary>
/// Media that will only stream when the app is in the foreground.
/// </summary>
ForegroundOnlyMedia,
/// <summary>
/// Media that can be streamed when the app is in the background.
/// </summary>
BackgroundCapableMedia,
/// <summary>
/// Real-time communications, such as VOIP or chat.
/// </summary>
Communications,
/// <summary>
/// Alert sounds.
/// </summary>
Alerts,
/// <summary>
/// Sound effects.
/// </summary>
SoundEffects,
/// <summary>
/// Game sound effects.
/// </summary>
GameEffects,
/// <summary>
/// Background audio for games.
/// </summary>
GameMedia,
}
}
namespace NAudio.CoreAudioApi
{
/// <summary>
/// Defines values that describe the characteristics of an audio stream.
/// </summary>
public enum AudioClientStreamOptions
{
/// <summary>
/// No stream options.
/// </summary>
None = 0,
/// <summary>
/// The audio stream is a 'raw' stream that bypasses all signal processing except for endpoint specific, always-on processing in the APO, driver, and hardware.
/// </summary>
Raw = 0x1
}
}
namespace NAudio.CoreAudioApi
{
/// <summary>
/// The AudioClientProperties structure is used to set the parameters that describe the properties of the client's audio stream.
/// </summary>
/// <remarks>http://msdn.microsoft.com/en-us/library/windows/desktop/hh968105(v=vs.85).aspx</remarks>
[StructLayout(LayoutKind.Sequential)]
public struct AudioClientProperties
{
/// <summary>
/// The size of the buffer for the audio stream.
/// </summary>
public UInt32 cbSize;
/// <summary>
/// Boolean value to indicate whether or not the audio stream is hardware-offloaded
/// </summary>
public int bIsOffload;
/// <summary>
/// An enumeration that is used to specify the category of the audio stream.
/// </summary>
public AudioStreamCategory eCategory;
/// <summary>
/// A bit-field describing the characteristics of the stream. Supported in Windows 8.1 and later.
/// </summary>
public AudioClientStreamOptions Options;
}
}
Add this to WaveOutputs/IWavePlayer
/// <summary>
/// Sets the parameters that describe the properties of the client's audio stream.
/// </summary>
/// <param name="useHardwareOffload">Boolean value to indicate whether or not the audio stream is hardware-offloaded.</param>
/// <param name="category">An enumeration that is used to specify the category of the audio stream.</param>
/// <param name="options">A bit-field describing the characteristics of the stream. Supported in Windows 8.1 and later.</param>
void SetClientProperties(bool useHardwareOffload, AudioStreamCategory category, AudioClientStreamOptions options);
Changes to WasapiOutRT: /// <summary>
/// Properties of the client's audio stream.
/// </summary>
private AudioClientProperties? audioClientProperties = null;
/// <summary>
/// Sets the parameters that describe the properties of the client's audio stream.
/// </summary>
/// <param name="useHardwareOffload">Boolean value to indicate whether or not the audio stream is hardware-offloaded.</param>
/// <param name="category">An enumeration that is used to specify the category of the audio stream.</param>
/// <param name="options">A bit-field describing the characteristics of the stream. Supported in Windows 8.1 and later.</param>
public void SetClientProperties(bool useHardwareOffload, AudioStreamCategory category, AudioClientStreamOptions options)
{
var audioClientProperties = new AudioClientProperties();
audioClientProperties.cbSize = (uint)Marshal.SizeOf<AudioClientProperties>();
audioClientProperties.bIsOffload = Convert.ToInt32(useHardwareOffload);
audioClientProperties.eCategory = category;
audioClientProperties.Options = options;
this.audioClientProperties = audioClientProperties;
}
private async Task Activate()
{
var icbh = new ActivateAudioInterfaceCompletionHandler(
ac2 =>
{
if (this.audioClientProperties != null)
{
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(this.audioClientProperties.Value));
Marshal.StructureToPtr(this.audioClientProperties.Value, p, false);
ac2.SetClientProperties(p);
}
/*var wfx = new WaveFormat(44100, 16, 2);
int hr = ac2.Initialize(AudioClientShareMode.Shared,
AudioClientStreamFlags.EventCallback | AudioClientStreamFlags.NoPersist,
10000000, 0, wfx, IntPtr.Zero);*/
});
var IID_IAudioClient2 = new Guid("726778CD-F60A-4eda-82DE-E47610CD78AA");
IActivateAudioInterfaceAsyncOperation activationOperation;
NativeMethods.ActivateAudioInterfaceAsync(device, IID_IAudioClient2, IntPtr.Zero, icbh, out activationOperation);
var audioClient2 = await icbh;
this.audioClient = new AudioClient((IAudioClient)audioClient2);
}
When testing, call SetClientProperties before Init(). Remember to set background capability in appxmanifest.I haven't tested the changes much yet and all testing I have done is with Windows 8.1. And AudioClientProperties.Options is only supported in Windows 8.1 as the comments state so I'm not sure what happens when trying to set it in Windows 8.0.
Regards,
Janne