2009-09-03 19:01:11 +00:00
|
|
|
#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;
|
|
|
|
using OpenTK.Audio.OpenAL;
|
|
|
|
|
|
|
|
namespace Examples
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// A text-based diagnosis program for OpenAL.
|
|
|
|
/// The constructors will call the OpenAL commands, the Print() methods just show the information.
|
|
|
|
/// </summary>
|
|
|
|
[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;
|
|
|
|
}
|
|
|
|
|
2009-10-24 10:07:43 +00:00
|
|
|
// Trace.WriteLine("All done. Press Enter to exit.");
|
|
|
|
// Console.ReadLine();
|
2009-09-03 19:01:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class DeviceDiagnostic
|
|
|
|
{
|
|
|
|
#region Fields
|
|
|
|
public readonly IList<string> AllPlaybackDevices;
|
|
|
|
public readonly IList<string> 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<string, bool> Extensions = new Dictionary<string, bool>();
|
|
|
|
#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<string, bool> 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<string, bool> Extensions = new Dictionary<string, bool>();
|
|
|
|
|
|
|
|
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.CurrentDevice;
|
|
|
|
|
|
|
|
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<string, bool> 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<string, bool> Effects = new Dictionary<string, bool>();
|
|
|
|
public readonly Dictionary<string, bool> Filters = new Dictionary<string, bool>();
|
|
|
|
|
|
|
|
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<string, bool> pair in Effects)
|
|
|
|
Trace.WriteLine(pair.Key + ": " + pair.Value);
|
|
|
|
}
|
|
|
|
Trace.Unindent();
|
|
|
|
|
|
|
|
Trace.WriteLine("Efx Filters supported:");
|
|
|
|
Trace.Indent();
|
|
|
|
{
|
|
|
|
foreach (KeyValuePair<string, bool> 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<string, bool> BufferModes = new Dictionary<string, bool>();
|
|
|
|
#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<string, bool> 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<string, AlcError> Errorlist = new Dictionary<string, AlcError>();
|
|
|
|
|
|
|
|
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.CurrentDevice;
|
|
|
|
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<string, AlcError> 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();
|
|
|
|
}
|
|
|
|
}
|
2009-07-17 09:58:47 +00:00
|
|
|
}
|