From 3222b976b34ae7c31a46af1c3d1f302b8c9f9b31 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Fri, 17 Jul 2009 23:00:50 +0000 Subject: [PATCH] Updated to use latest Audio api. --- .../Examples/OpenAL/Test/OpenALDiagnostics.cs | 1265 ++++++++--------- 1 file changed, 631 insertions(+), 634 deletions(-) diff --git a/Source/Examples/OpenAL/Test/OpenALDiagnostics.cs b/Source/Examples/OpenAL/Test/OpenALDiagnostics.cs index ccce4533..4d7e2844 100644 --- a/Source/Examples/OpenAL/Test/OpenALDiagnostics.cs +++ b/Source/Examples/OpenAL/Test/OpenALDiagnostics.cs @@ -1,635 +1,632 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2009 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -#endregion - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using System.Runtime.InteropServices; - -using OpenTK; -using OpenTK.Audio; - -namespace Examples -{ - - /// - /// A text-based diagnosis program for OpenAL. - /// The constructors will call the OpenAL commands, the Print() methods just show the information. - /// - [Example("OpenAL diagnostics", ExampleCategory.OpenAL, "Test", 0, true)] - class OpenALDiagnostics - { - public static void checkForErrors() - { - { - IntPtr device = Alc.GetContextsDevice(Alc.GetCurrentContext()); - AlcError error = Alc.GetError(device); - - if (error != AlcError.NoError) - Trace.WriteLine("ALC ERROR: (" + error + ") " + Alc.GetString(device, (AlcGetString)error)); - } - { - ALError error = AL.GetError(); - if (error != ALError.NoError) - Trace.WriteLine("AL ERROR: (" + error + ") " + AL.GetErrorString(error)); - } - } - - [STAThread] - static void Main() - { - Trace.Listeners.RemoveAt(0); - Trace.Listeners.Add(new ConsoleTraceListener()); - - Trace.WriteLine("This application is currently running as " + (IntPtr.Size == 4 ? "x86" : "x64")); - - DeviceDiagnostic DevDiag = new DeviceDiagnostic(); - DevDiag.Print(); - DevDiag = null; - - using (AudioContext A = new AudioContext()) - { - AlcDiagnostic AlcDiag = new AlcDiagnostic(Alc.GetContextsDevice(Alc.GetCurrentContext())); - checkForErrors(); - AlcDiag.Print(); - AlcDiag = null; - - ALDiagnostic ALdiag = new ALDiagnostic(A); - checkForErrors(); - ALdiag.Print(); - ALdiag = null; - - EfxDiagnostic EfxDiag = new EfxDiagnostic(); - checkForErrors(); - EfxDiag.Print(); - EfxDiag = null; - - XRamDiagnostic XRamDiag = new XRamDiagnostic(); - checkForErrors(); - XRamDiag.Print(); - XRamDiag = null; - - RecorderDiagnostic rec = new RecorderDiagnostic(); - rec.Print(); - rec = null; - } - - Trace.WriteLine("All done. Press Enter to exit."); - Console.ReadLine(); - } - } - - class DeviceDiagnostic - { - #region Fields - public readonly IList AllPlaybackDevices; - public readonly IList AllRecordingDevices; - - public readonly string DefaultPlaybackDevice; - public readonly string DefaultRecordingDevice; - #endregion Fields - - public DeviceDiagnostic() - { - Trace.WriteLine("--- Device related errors ---"); - - AllPlaybackDevices = AudioContext.AvailableDevices; - AllRecordingDevices = AudioCapture.AvailableDevices; - - DefaultPlaybackDevice = AudioContext.Default; - DefaultRecordingDevice = AudioCapture.Default; - } - - public void Print() - { - Trace.WriteLine("--- Device related analysis ---"); - Trace.Indent(); - { - Trace.WriteLine("Default playback device: " + DefaultPlaybackDevice); - Trace.WriteLine("All known playback devices:"); - Trace.Indent(); - { - foreach (string s in AllPlaybackDevices) - Trace.WriteLine(s); - } - Trace.Unindent(); - - Trace.WriteLine("Default recording device: " + DefaultRecordingDevice); - Trace.WriteLine("All known recording devices:"); - Trace.Indent(); - { - foreach (string s in AllRecordingDevices) - Trace.WriteLine(s); - } - Trace.Unindent(); - } - Trace.Unindent(); - } - } - - class AlcDiagnostic - { - #region Fields - private string[] Alc_Extension_C_Names = new string[] - { - "ALC_ENUMERATE_ALL_EXT", - "ALC_ENUMERATION_EXT", - "ALC_EXT_ASA", - "ALC_EXT_ASA_DISTORTION", - "ALC_EXT_ASA_ROGER_BEEP", - "ALC_EXT_BRS_GAME_LICENSE_REQUIRED", - "ALC_EXT_capture", - "ALC_EXT_DEDICATED", - "ALC_EXT_EFX", - }; - - public readonly int MajorVersion; - public readonly int MinorVersion; - public readonly int EfxMajorVersion; - public readonly int EfxMinorVersion; - public readonly int EfxMaxAuxiliarySends; - public readonly string ExtensionString; - public readonly Dictionary Extensions = new Dictionary(); - #endregion Fields - - public AlcDiagnostic(IntPtr dev) - { - Trace.WriteLine("--- Alc related errors ---"); - - Alc.GetInteger(dev, AlcGetInteger.MajorVersion, 1, out MajorVersion); - Alc.GetInteger(dev, AlcGetInteger.MinorVersion, 1, out MinorVersion); - Alc.GetInteger(dev, AlcGetInteger.EfxMajorVersion, 1, out EfxMajorVersion); - Alc.GetInteger(dev, AlcGetInteger.EfxMinorVersion, 1, out EfxMinorVersion); - Alc.GetInteger(dev, AlcGetInteger.EfxMaxAuxiliarySends, 1, out EfxMaxAuxiliarySends); - - ExtensionString = Alc.GetString(dev, AlcGetString.Extensions); - - foreach (string s in Alc_Extension_C_Names) - Extensions.Add(s, Alc.IsExtensionPresent(dev, s)); - } - - public void Print() - { - Trace.WriteLine("--- Alc related analysis ---"); - Trace.Indent(); - { - Trace.WriteLine("Alc Version: " + MajorVersion + "." + MinorVersion); - Trace.WriteLine("Efx Version: " + EfxMajorVersion + "." + EfxMinorVersion); - Trace.WriteLine("Efx max. Auxiliary sends: " + EfxMaxAuxiliarySends); - Trace.WriteLine("Alc Extension string: " + ExtensionString); - - Trace.WriteLine("Confirmed Alc Extensions:"); - Trace.Indent(); - { - foreach (KeyValuePair pair in Extensions) - Trace.WriteLine(pair.Key + ": " + pair.Value); - } - Trace.Unindent(); - } - Trace.Unindent(); - } - } - - class ALDiagnostic - { - #region Fields - private string[] AL_Extension_Names = new string[] - { - "AL_EXT_ALAW", - "AL_EXT_BFORMAT", - "AL_EXT_double", - "AL_EXT_EXPONENT_DISTANCE", - "AL_EXT_float32", - "AL_EXT_FOLDBACK", - "AL_EXT_IMA4", - "AL_EXT_LINEAR_DISTANCE", - "AL_EXT_MCFORMATS", - "AL_EXT_mp3", - "AL_EXT_MULAW", - "AL_EXT_OFFSET", - "AL_EXT_vorbis", - "AL_LOKI_quadriphonic", - "EAX-RAM", - "EAX", - "EAX1.0", - "EAX2.0", - "EAX3.0", - "EAX3.0EMULATED", - "EAX4.0", - "EAX4.0EMULATED", - "EAX5.0" - }; - - public readonly Dictionary Extensions = new Dictionary(); - - public readonly string DeviceName; - public readonly float SpeedOfSound; - public readonly string ExtensionString; - public readonly string Renderer; - public readonly string Vendor; - public readonly string Version; - public readonly ALDistanceModel DistanceModel; - - const uint MaxSourcesLimit = 128; - public readonly uint MaxSources; - #endregion Fields - - public ALDiagnostic(AudioContext ac) - { - Trace.WriteLine("--- AL related errors ---"); - - DeviceName = ac.CurrentDeviceName; - - ExtensionString = AL.Get(ALGetString.Extensions); - Renderer = AL.Get(ALGetString.Renderer); - Vendor = AL.Get(ALGetString.Vendor); - Version = AL.Get(ALGetString.Version); - - SpeedOfSound = AL.Get(ALGetFloat.SpeedOfSound); - DistanceModel = AL.GetDistanceModel(); - - foreach (string s in AL_Extension_Names) - Extensions.Add(s, AL.IsExtensionPresent(s)); - - AL.GetError(); // clear it, need this for the source counting to work properly - uint[] dummy_sources = new uint[MaxSourcesLimit]; - for (MaxSources = 0; MaxSources < MaxSourcesLimit; MaxSources++) - { - AL.GenSource(out dummy_sources[MaxSources]); - if (AL.GetError() != ALError.NoError) - break; - } - - for (int i = 0; i < MaxSources; i++) - AL.DeleteSource(ref dummy_sources[i]); - } - - public void Print() - { - Trace.WriteLine("--- AL related analysis ---"); - Trace.Indent(); - { - Trace.WriteLine("Used Device: "+DeviceName); - Trace.WriteLine("AL Renderer: " + Renderer); - Trace.WriteLine("AL Vendor: " + Vendor); - Trace.WriteLine("AL Version: " + Version); - - Trace.WriteLine("AL Speed of sound: " + SpeedOfSound); - Trace.WriteLine("AL Distance Model: " + DistanceModel.ToString()); - Trace.WriteLine("AL Maximum simultanous Sources: " + MaxSources); - - Trace.WriteLine("AL Extension string: " + ExtensionString); - Trace.WriteLine("Confirmed AL Extensions:"); - Trace.Indent(); - { - foreach (KeyValuePair pair in Extensions) - Trace.WriteLine(pair.Key + ": " + pair.Value); - } - Trace.Unindent(); - } - Trace.Unindent(); - } - } - - class EfxDiagnostic - { - #region Fields - private EfxEffectType[] EffectNames = new EfxEffectType[] - { - EfxEffectType.Autowah, - EfxEffectType.Chorus, - EfxEffectType.Compressor, - EfxEffectType.Distortion, - EfxEffectType.EaxReverb, - EfxEffectType.Echo, - EfxEffectType.Equalizer, - EfxEffectType.Flanger, - EfxEffectType.FrequencyShifter, - EfxEffectType.PitchShifter, - EfxEffectType.Reverb, - EfxEffectType.RingModulator, - EfxEffectType.VocalMorpher, - }; - - private EfxFilterType[] FilterNames = new EfxFilterType[] - { - EfxFilterType.Bandpass, - EfxFilterType.Highpass, - EfxFilterType.Lowpass, - }; - - public readonly Dictionary Effects = new Dictionary(); - public readonly Dictionary Filters = new Dictionary(); - - const uint MaxAuxiliaryEffectSlotsLimit = 4; - public readonly uint MaxAuxiliaryEffectSlots; - #endregion Fields - - public EfxDiagnostic() - { - Trace.WriteLine("--- Efx related errors ---"); - - EffectsExtension Efx = new EffectsExtension(); - Trace.Assert(Efx.IsInitialized); - - #region Test for available Effects - uint effect; - Efx.GenEffect(out effect); - AL.GetError(); - foreach (EfxEffectType e in EffectNames) - { - Efx.BindEffect(effect, e); - Effects.Add(e.ToString(), AL.GetError() == ALError.NoError); - } - Efx.DeleteEffect(ref effect); - #endregion Test for available Effects - - #region Test for available Filters - uint filter; - Efx.GenFilter(out filter); - AL.GetError(); - foreach (EfxFilterType f in FilterNames) - { - Efx.Filter(filter, EfxFilteri.FilterType, (int)f); - Filters.Add(f.ToString(), AL.GetError() == ALError.NoError); - } - Efx.DeleteFilter(ref filter); - #endregion Test for available Filters - - AL.GetError(); - uint[] dummy_slots = new uint[MaxAuxiliaryEffectSlotsLimit]; - for (MaxAuxiliaryEffectSlots = 0; MaxAuxiliaryEffectSlots < MaxAuxiliaryEffectSlotsLimit; MaxAuxiliaryEffectSlots++) - { - Efx.GenAuxiliaryEffectSlot(out dummy_slots[MaxAuxiliaryEffectSlots]); - if (AL.GetError() != ALError.NoError) - break; - } - for (uint i = 0; i < MaxAuxiliaryEffectSlots; i++) - Efx.DeleteAuxiliaryEffectSlot(ref dummy_slots[i]); - } - - public void Print() - { - Trace.WriteLine("--- Efx related analysis ---"); - Trace.Indent(); - { - Trace.WriteLine("Efx Effects supported:"); - Trace.Indent(); - { - foreach (KeyValuePair pair in Effects) - Trace.WriteLine(pair.Key + ": " + pair.Value); - } - Trace.Unindent(); - - Trace.WriteLine("Efx Filters supported:"); - Trace.Indent(); - { - foreach (KeyValuePair pair in Filters) - Trace.WriteLine(pair.Key + ": " + pair.Value); - } - Trace.Unindent(); - - Trace.WriteLine("Efx max. Auxiliary Effect Slots: " + MaxAuxiliaryEffectSlots); - } - Trace.Unindent(); - } - } - - class XRamDiagnostic - { - #region Fields - private XRamExtension.XRamStorage[] storagemodes = new XRamExtension.XRamStorage[] - { - XRamExtension.XRamStorage.Hardware, - XRamExtension.XRamStorage.Accessible, - XRamExtension.XRamStorage.Automatic, - }; - - public readonly bool XRamFound; - public readonly int RamTotal; - public readonly int RamFree; - public readonly Dictionary BufferModes = new Dictionary(); - #endregion Fields - - public XRamDiagnostic() - { - Trace.WriteLine("--- X-RAM related errors ---"); - - XRamExtension XRam = new XRamExtension(); - if (XRam.IsInitialized) - { - XRamFound = true; - - RamTotal = XRam.GetRamSize; - RamFree = XRam.GetRamFree; - - uint buffer; - AL.GenBuffer(out buffer); - - foreach (XRamExtension.XRamStorage m in storagemodes) - { - bool result = XRam.SetBufferMode(1, ref buffer, m); - BufferModes.Add(m.ToString(), m == XRam.GetBufferMode(ref buffer)); - } - - AL.DeleteBuffer(ref buffer); - } - else - XRamFound = false; - } - - public void Print() - { - Trace.WriteLine("--- X-RAM related analysis ---"); - - if (XRamFound) - { - Trace.Indent(); // * - Trace.WriteLine("X-RAM extension found."); - } - else - { - Trace.Indent(); - { - Trace.WriteLine("X-RAM extension is not available, skipping test."); - } - Trace.Unindent(); - return; - } - - Trace.WriteLine("Ram status (free/total) in bytes: " + RamFree + "/" + RamTotal); - - Trace.WriteLine("Available buffer modes:"); - Trace.Indent(); - { - foreach (KeyValuePair pair in BufferModes) - Trace.WriteLine(pair.Key + ": " + pair.Value); - } - Trace.Unindent(); - - Trace.Unindent(); // * - } - } - - class RecorderDiagnostic - { - #region Fields - bool IsDeviceAvailable; - bool BufferContentsAllZero; - short MaxSample = short.MinValue; - short MinSample = short.MaxValue; - - private AudioCapture r; - Dictionary Errorlist = new Dictionary(); - - string DeviceName; - - #endregion Fields - - private void CheckRecorderError(string location) - { - AlcError err = r.CurrentAlcError; - if (err != AlcError.NoError) - Errorlist.Add(location, err); - } - - public RecorderDiagnostic() - { - Trace.WriteLine("--- AudioCapture related errors ---"); - IsDeviceAvailable = false; - - try - { - r = new AudioCapture(AudioCapture.Default, (uint)16000, ALFormat.Mono16, 4096); - } - catch (AudioDeviceException ade) - { - Trace.WriteLine("AudioCapture Exception caught: " + ade.Message); - return; - } - IsDeviceAvailable = true; - DeviceName = r.CurrentDeviceName; - CheckRecorderError("Alc.CaptureOpenDevice"); - - r.Start(); - CheckRecorderError("Alc.CaptureStart"); - Thread.Sleep(100); - r.Stop(); - CheckRecorderError("Alc.CaptureStop"); - - byte[] Buffer = new byte[8192]; - GCHandle BufferHandle = GCHandle.Alloc(Buffer, GCHandleType.Pinned); - IntPtr BufferPtr = BufferHandle.AddrOfPinnedObject(); - - int SamplesBefore = r.AvailableSamples; - CheckRecorderError("Alc.GetInteger(...CaptureSamples...)"); - r.GetSamples(BufferPtr, (SamplesBefore > 4096 ? 4096 : SamplesBefore)); - CheckRecorderError("Alc.CaptureSamples"); - Thread.Sleep(50); // getsamples doesn't block - - int SamplesCaptured = SamplesBefore - r.AvailableSamples; - - uint ZeroCounter = 0; - for (int i = 0; i < SamplesCaptured * 2; i++) - { - if (Buffer[i] == 0) - ZeroCounter++; - } - - for (int i = 0; i < SamplesCaptured; i++) - { - short sample = BitConverter.ToInt16(Buffer, i * 2); - if (sample > MaxSample) - MaxSample = sample; - if (sample < MinSample) - MinSample = sample; - } - - if (ZeroCounter < SamplesCaptured * 2 && SamplesCaptured > 0) - BufferContentsAllZero = false; - else - BufferContentsAllZero = true; - - r.Dispose(); - CheckRecorderError("Alc.CaptureCloseDevice"); - - // no playback test needed due to Parrot test app. - /* - uint buf; - AL.GenBuffer(out buf); - AL.BufferData(buf, ALFormat.Mono16, BufferPtr, SamplesCaptured * 2, 16000); - uint src; - AL.GenSource(out src); - AL.BindBufferToSource(src, buf); - AL.Listener(ALListenerf.Gain, 16.0f); - AL.SourcePlay(src); - while (AL.GetSourceState(src) == ALSourceState.Playing) - { - Thread.Sleep(0); - } - AL.SourceStop(src); - - AL.DeleteSource(ref src); - AL.DeleteBuffer(ref buf); - */ - - BufferHandle.Free(); - } - - public void Print() - { - Trace.WriteLine("--- AudioCapture related analysis ---"); - - if (!IsDeviceAvailable) - { - Trace.WriteLine("Capture Device could not be initlialized (no microphone plugged into the jack?). Skipping test."); - return; - } - - Trace.Indent(); - { - Trace.WriteLine("Using capture device: " + DeviceName); - if (Errorlist.Count > 0) - { - Trace.WriteLine("Found Alc Errors:"); - Trace.Indent(); - { - foreach (KeyValuePair pair in Errorlist) - Trace.WriteLine(pair.Key + ": " + pair.Value); - } - Trace.Unindent(); - - - } - Trace.WriteLine("Buffer contents after capture was all 0's: " + BufferContentsAllZero); - Trace.WriteLine("Sample min/max in recorded data: " + MinSample + " / " + MaxSample); - } - Trace.Unindent(); - } - } +#region License +// +// The Open Toolkit Library License +// +// Copyright (c) 2006 - 2009 the Open Toolkit library. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +#endregion + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using System.Runtime.InteropServices; + +using OpenTK; +using OpenTK.Audio; + +namespace Examples +{ + + /// + /// A text-based diagnosis program for OpenAL. + /// The constructors will call the OpenAL commands, the Print() methods just show the information. + /// + [Example("OpenAL diagnostics", ExampleCategory.OpenAL, "Test", 0, true)] + class OpenALDiagnostics + { + public static void checkForErrors() + { + { + IntPtr device = Alc.GetContextsDevice(Alc.GetCurrentContext()); + AlcError error = Alc.GetError(device); + + if (error != AlcError.NoError) + Trace.WriteLine("ALC ERROR: (" + error + ") " + Alc.GetString(device, (AlcGetString)error)); + } + { + ALError error = AL.GetError(); + if (error != ALError.NoError) + Trace.WriteLine("AL ERROR: (" + error + ") " + AL.GetErrorString(error)); + } + } + + [STAThread] + static void Main() + { + Trace.Listeners.RemoveAt(0); + Trace.Listeners.Add(new ConsoleTraceListener()); + + Trace.WriteLine("This application is currently running as " + (IntPtr.Size == 4 ? "x86" : "x64")); + + DeviceDiagnostic DevDiag = new DeviceDiagnostic(); + DevDiag.Print(); + DevDiag = null; + + using (AudioContext A = new AudioContext()) + { + AlcDiagnostic AlcDiag = new AlcDiagnostic(Alc.GetContextsDevice(Alc.GetCurrentContext())); + checkForErrors(); + AlcDiag.Print(); + AlcDiag = null; + + ALDiagnostic ALdiag = new ALDiagnostic(A); + checkForErrors(); + ALdiag.Print(); + ALdiag = null; + + EfxDiagnostic EfxDiag = new EfxDiagnostic(); + checkForErrors(); + EfxDiag.Print(); + EfxDiag = null; + + XRamDiagnostic XRamDiag = new XRamDiagnostic(); + checkForErrors(); + XRamDiag.Print(); + XRamDiag = null; + + RecorderDiagnostic rec = new RecorderDiagnostic(); + rec.Print(); + rec = null; + } + + Trace.WriteLine("All done. Press Enter to exit."); + Console.ReadLine(); + } + } + + class DeviceDiagnostic + { + #region Fields + public readonly IList AllPlaybackDevices; + public readonly IList AllRecordingDevices; + + public readonly string DefaultPlaybackDevice; + public readonly string DefaultRecordingDevice; + #endregion Fields + + public DeviceDiagnostic() + { + Trace.WriteLine("--- Device related errors ---"); + + AllPlaybackDevices = AudioContext.AvailableDevices; + AllRecordingDevices = AudioCapture.AvailableDevices; + + DefaultPlaybackDevice = AudioContext.DefaultDevice; + DefaultRecordingDevice = AudioCapture.DefaultDevice; + } + + public void Print() + { + Trace.WriteLine("--- Device related analysis ---"); + Trace.Indent(); + { + Trace.WriteLine("Default playback device: " + DefaultPlaybackDevice); + Trace.WriteLine("All known playback devices:"); + Trace.Indent(); + { + foreach (string s in AllPlaybackDevices) + Trace.WriteLine(s); + } + Trace.Unindent(); + + Trace.WriteLine("Default recording device: " + DefaultRecordingDevice); + Trace.WriteLine("All known recording devices:"); + Trace.Indent(); + { + foreach (string s in AllRecordingDevices) + Trace.WriteLine(s); + } + Trace.Unindent(); + } + Trace.Unindent(); + } + } + + class AlcDiagnostic + { + #region Fields + private string[] Alc_Extension_C_Names = new string[] + { + "ALC_ENUMERATE_ALL_EXT", + "ALC_ENUMERATION_EXT", + "ALC_EXT_ASA", + "ALC_EXT_ASA_DISTORTION", + "ALC_EXT_ASA_ROGER_BEEP", + "ALC_EXT_BRS_GAME_LICENSE_REQUIRED", + "ALC_EXT_capture", + "ALC_EXT_DEDICATED", + "ALC_EXT_EFX", + }; + + public readonly int MajorVersion; + public readonly int MinorVersion; + public readonly int EfxMajorVersion; + public readonly int EfxMinorVersion; + public readonly int EfxMaxAuxiliarySends; + public readonly string ExtensionString; + public readonly Dictionary Extensions = new Dictionary(); + #endregion Fields + + public AlcDiagnostic(IntPtr dev) + { + Trace.WriteLine("--- Alc related errors ---"); + + Alc.GetInteger(dev, AlcGetInteger.MajorVersion, 1, out MajorVersion); + Alc.GetInteger(dev, AlcGetInteger.MinorVersion, 1, out MinorVersion); + Alc.GetInteger(dev, AlcGetInteger.EfxMajorVersion, 1, out EfxMajorVersion); + Alc.GetInteger(dev, AlcGetInteger.EfxMinorVersion, 1, out EfxMinorVersion); + Alc.GetInteger(dev, AlcGetInteger.EfxMaxAuxiliarySends, 1, out EfxMaxAuxiliarySends); + + ExtensionString = Alc.GetString(dev, AlcGetString.Extensions); + + foreach (string s in Alc_Extension_C_Names) + Extensions.Add(s, Alc.IsExtensionPresent(dev, s)); + } + + public void Print() + { + Trace.WriteLine("--- Alc related analysis ---"); + Trace.Indent(); + { + Trace.WriteLine("Alc Version: " + MajorVersion + "." + MinorVersion); + Trace.WriteLine("Efx Version: " + EfxMajorVersion + "." + EfxMinorVersion); + Trace.WriteLine("Efx max. Auxiliary sends: " + EfxMaxAuxiliarySends); + Trace.WriteLine("Alc Extension string: " + ExtensionString); + + Trace.WriteLine("Confirmed Alc Extensions:"); + Trace.Indent(); + { + foreach (KeyValuePair pair in Extensions) + Trace.WriteLine(pair.Key + ": " + pair.Value); + } + Trace.Unindent(); + } + Trace.Unindent(); + } + } + + class ALDiagnostic + { + #region Fields + private string[] AL_Extension_Names = new string[] + { + "AL_EXT_ALAW", + "AL_EXT_BFORMAT", + "AL_EXT_double", + "AL_EXT_EXPONENT_DISTANCE", + "AL_EXT_float32", + "AL_EXT_FOLDBACK", + "AL_EXT_IMA4", + "AL_EXT_LINEAR_DISTANCE", + "AL_EXT_MCFORMATS", + "AL_EXT_mp3", + "AL_EXT_MULAW", + "AL_EXT_OFFSET", + "AL_EXT_vorbis", + "AL_LOKI_quadriphonic", + "EAX-RAM", + "EAX", + "EAX1.0", + "EAX2.0", + "EAX3.0", + "EAX3.0EMULATED", + "EAX4.0", + "EAX4.0EMULATED", + "EAX5.0" + }; + + public readonly Dictionary Extensions = new Dictionary(); + + public readonly string DeviceName; + public readonly float SpeedOfSound; + public readonly string ExtensionString; + public readonly string Renderer; + public readonly string Vendor; + public readonly string Version; + public readonly ALDistanceModel DistanceModel; + + const uint MaxSourcesLimit = 128; + public readonly uint MaxSources; + #endregion Fields + + public ALDiagnostic(AudioContext ac) + { + Trace.WriteLine("--- AL related errors ---"); + + DeviceName = ac.CurrentDeviceName; + + ExtensionString = AL.Get(ALGetString.Extensions); + Renderer = AL.Get(ALGetString.Renderer); + Vendor = AL.Get(ALGetString.Vendor); + Version = AL.Get(ALGetString.Version); + + SpeedOfSound = AL.Get(ALGetFloat.SpeedOfSound); + DistanceModel = AL.GetDistanceModel(); + + foreach (string s in AL_Extension_Names) + Extensions.Add(s, AL.IsExtensionPresent(s)); + + AL.GetError(); // clear it, need this for the source counting to work properly + uint[] dummy_sources = new uint[MaxSourcesLimit]; + for (MaxSources = 0; MaxSources < MaxSourcesLimit; MaxSources++) + { + AL.GenSource(out dummy_sources[MaxSources]); + if (AL.GetError() != ALError.NoError) + break; + } + + for (int i = 0; i < MaxSources; i++) + AL.DeleteSource(ref dummy_sources[i]); + } + + public void Print() + { + Trace.WriteLine("--- AL related analysis ---"); + Trace.Indent(); + { + Trace.WriteLine("Used Device: "+DeviceName); + Trace.WriteLine("AL Renderer: " + Renderer); + Trace.WriteLine("AL Vendor: " + Vendor); + Trace.WriteLine("AL Version: " + Version); + + Trace.WriteLine("AL Speed of sound: " + SpeedOfSound); + Trace.WriteLine("AL Distance Model: " + DistanceModel.ToString()); + Trace.WriteLine("AL Maximum simultanous Sources: " + MaxSources); + + Trace.WriteLine("AL Extension string: " + ExtensionString); + Trace.WriteLine("Confirmed AL Extensions:"); + Trace.Indent(); + { + foreach (KeyValuePair pair in Extensions) + Trace.WriteLine(pair.Key + ": " + pair.Value); + } + Trace.Unindent(); + } + Trace.Unindent(); + } + } + + class EfxDiagnostic + { + #region Fields + private EfxEffectType[] EffectNames = new EfxEffectType[] + { + EfxEffectType.Autowah, + EfxEffectType.Chorus, + EfxEffectType.Compressor, + EfxEffectType.Distortion, + EfxEffectType.EaxReverb, + EfxEffectType.Echo, + EfxEffectType.Equalizer, + EfxEffectType.Flanger, + EfxEffectType.FrequencyShifter, + EfxEffectType.PitchShifter, + EfxEffectType.Reverb, + EfxEffectType.RingModulator, + EfxEffectType.VocalMorpher, + }; + + private EfxFilterType[] FilterNames = new EfxFilterType[] + { + EfxFilterType.Bandpass, + EfxFilterType.Highpass, + EfxFilterType.Lowpass, + }; + + public readonly Dictionary Effects = new Dictionary(); + public readonly Dictionary Filters = new Dictionary(); + + const uint MaxAuxiliaryEffectSlotsLimit = 4; + public readonly uint MaxAuxiliaryEffectSlots; + #endregion Fields + + public EfxDiagnostic() + { + Trace.WriteLine("--- Efx related errors ---"); + + EffectsExtension Efx = new EffectsExtension(); + Trace.Assert(Efx.IsInitialized); + + #region Test for available Effects + uint effect; + Efx.GenEffect(out effect); + AL.GetError(); + foreach (EfxEffectType e in EffectNames) + { + Efx.BindEffect(effect, e); + Effects.Add(e.ToString(), AL.GetError() == ALError.NoError); + } + Efx.DeleteEffect(ref effect); + #endregion Test for available Effects + + #region Test for available Filters + uint filter; + Efx.GenFilter(out filter); + AL.GetError(); + foreach (EfxFilterType f in FilterNames) + { + Efx.Filter(filter, EfxFilteri.FilterType, (int)f); + Filters.Add(f.ToString(), AL.GetError() == ALError.NoError); + } + Efx.DeleteFilter(ref filter); + #endregion Test for available Filters + + AL.GetError(); + uint[] dummy_slots = new uint[MaxAuxiliaryEffectSlotsLimit]; + for (MaxAuxiliaryEffectSlots = 0; MaxAuxiliaryEffectSlots < MaxAuxiliaryEffectSlotsLimit; MaxAuxiliaryEffectSlots++) + { + Efx.GenAuxiliaryEffectSlot(out dummy_slots[MaxAuxiliaryEffectSlots]); + if (AL.GetError() != ALError.NoError) + break; + } + for (uint i = 0; i < MaxAuxiliaryEffectSlots; i++) + Efx.DeleteAuxiliaryEffectSlot(ref dummy_slots[i]); + } + + public void Print() + { + Trace.WriteLine("--- Efx related analysis ---"); + Trace.Indent(); + { + Trace.WriteLine("Efx Effects supported:"); + Trace.Indent(); + { + foreach (KeyValuePair pair in Effects) + Trace.WriteLine(pair.Key + ": " + pair.Value); + } + Trace.Unindent(); + + Trace.WriteLine("Efx Filters supported:"); + Trace.Indent(); + { + foreach (KeyValuePair pair in Filters) + Trace.WriteLine(pair.Key + ": " + pair.Value); + } + Trace.Unindent(); + + Trace.WriteLine("Efx max. Auxiliary Effect Slots: " + MaxAuxiliaryEffectSlots); + } + Trace.Unindent(); + } + } + + class XRamDiagnostic + { + #region Fields + private XRamExtension.XRamStorage[] storagemodes = new XRamExtension.XRamStorage[] + { + XRamExtension.XRamStorage.Hardware, + XRamExtension.XRamStorage.Accessible, + XRamExtension.XRamStorage.Automatic, + }; + + public readonly bool XRamFound; + public readonly int RamTotal; + public readonly int RamFree; + public readonly Dictionary BufferModes = new Dictionary(); + #endregion Fields + + public XRamDiagnostic() + { + Trace.WriteLine("--- X-RAM related errors ---"); + + XRamExtension XRam = new XRamExtension(); + if (XRam.IsInitialized) + { + XRamFound = true; + + RamTotal = XRam.GetRamSize; + RamFree = XRam.GetRamFree; + + uint buffer; + AL.GenBuffer(out buffer); + + foreach (XRamExtension.XRamStorage m in storagemodes) + { + bool result = XRam.SetBufferMode(1, ref buffer, m); + BufferModes.Add(m.ToString(), m == XRam.GetBufferMode(ref buffer)); + } + + AL.DeleteBuffer(ref buffer); + } + else + XRamFound = false; + } + + public void Print() + { + Trace.WriteLine("--- X-RAM related analysis ---"); + + if (XRamFound) + { + Trace.Indent(); // * + Trace.WriteLine("X-RAM extension found."); + } + else + { + Trace.Indent(); + { + Trace.WriteLine("X-RAM extension is not available, skipping test."); + } + Trace.Unindent(); + return; + } + + Trace.WriteLine("Ram status (free/total) in bytes: " + RamFree + "/" + RamTotal); + + Trace.WriteLine("Available buffer modes:"); + Trace.Indent(); + { + foreach (KeyValuePair pair in BufferModes) + Trace.WriteLine(pair.Key + ": " + pair.Value); + } + Trace.Unindent(); + + Trace.Unindent(); // * + } + } + + class RecorderDiagnostic + { + #region Fields + bool IsDeviceAvailable; + bool BufferContentsAllZero; + short MaxSample = short.MinValue; + short MinSample = short.MaxValue; + + private AudioCapture r; + Dictionary Errorlist = new Dictionary(); + + string DeviceName; + + #endregion Fields + + private void CheckRecorderError(string location) + { + AlcError err = r.CurrentError; + if (err != AlcError.NoError) + Errorlist.Add(location, err); + } + + public RecorderDiagnostic() + { + Trace.WriteLine("--- AudioCapture related errors ---"); + IsDeviceAvailable = false; + + try + { + r = new AudioCapture(AudioCapture.DefaultDevice, 16000, ALFormat.Mono16, 4096); + } + catch (AudioDeviceException ade) + { + Trace.WriteLine("AudioCapture Exception caught: " + ade.Message); + return; + } + IsDeviceAvailable = true; + DeviceName = r.CurrentDeviceName; + CheckRecorderError("Alc.CaptureOpenDevice"); + + r.Start(); + CheckRecorderError("Alc.CaptureStart"); + Thread.Sleep(100); + r.Stop(); + CheckRecorderError("Alc.CaptureStop"); + + byte[] Buffer = new byte[8192]; + + Thread.Sleep(10); // Wait for a few samples to become available. + int SamplesBefore = r.AvailableSamples; + + CheckRecorderError("Alc.GetInteger(...CaptureSamples...)"); + r.ReadSamples(Buffer, (SamplesBefore > 4096 ? 4096 : SamplesBefore)); + CheckRecorderError("Alc.CaptureSamples"); + + int SamplesCaptured = SamplesBefore - r.AvailableSamples; + + uint ZeroCounter = 0; + for (int i = 0; i < SamplesCaptured * 2; i++) + { + if (Buffer[i] == 0) + ZeroCounter++; + } + + for (int i = 0; i < SamplesCaptured; i++) + { + short sample = BitConverter.ToInt16(Buffer, i * 2); + if (sample > MaxSample) + MaxSample = sample; + if (sample < MinSample) + MinSample = sample; + } + + if (ZeroCounter < SamplesCaptured * 2 && SamplesCaptured > 0) + BufferContentsAllZero = false; + else + BufferContentsAllZero = true; + + r.Dispose(); + CheckRecorderError("Alc.CaptureCloseDevice"); + + // no playback test needed due to Parrot test app. + /* + uint buf; + AL.GenBuffer(out buf); + AL.BufferData(buf, ALFormat.Mono16, BufferPtr, SamplesCaptured * 2, 16000); + uint src; + AL.GenSource(out src); + AL.BindBufferToSource(src, buf); + AL.Listener(ALListenerf.Gain, 16.0f); + AL.SourcePlay(src); + while (AL.GetSourceState(src) == ALSourceState.Playing) + { + Thread.Sleep(0); + } + AL.SourceStop(src); + + AL.DeleteSource(ref src); + AL.DeleteBuffer(ref buf); + */ + } + + public void Print() + { + Trace.WriteLine("--- AudioCapture related analysis ---"); + + if (!IsDeviceAvailable) + { + Trace.WriteLine("Capture Device could not be initlialized (no microphone plugged into the jack?). Skipping test."); + return; + } + + Trace.Indent(); + { + Trace.WriteLine("Using capture device: " + DeviceName); + if (Errorlist.Count > 0) + { + Trace.WriteLine("Found Alc Errors:"); + Trace.Indent(); + { + foreach (KeyValuePair pair in Errorlist) + Trace.WriteLine(pair.Key + ": " + pair.Value); + } + Trace.Unindent(); + + + } + Trace.WriteLine("Buffer contents after capture was all 0's: " + BufferContentsAllZero); + Trace.WriteLine("Sample min/max in recorded data: " + MinSample + " / " + MaxSample); + } + Trace.Unindent(); + } + } } \ No newline at end of file