static int Main(string[] args) { string exe = "SoundIOListDevices"; bool watch = false; SoundIoBackend backend = SoundIoBackend.None; SoundIoError err; for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.CompareTo("--watch") == 0) { watch = true; } else if (arg.CompareTo("--short") == 0) { shortOutput = true; } else if (arg.StartsWith("--")) { i++; if (i >= args.Length) { return(Usage(exe)); } else if (arg.CompareTo("--backend") == 0) { backend = (SoundIoBackend)Enum.Parse(typeof(SoundIoBackend), args[i]); } else { return(Usage(exe)); } } else { return(Usage(exe)); } } SoundIO soundIo = new SoundIO(); err = (backend == SoundIoBackend.None) ? soundIo.Connect() : soundIo.ConnectBackend(backend); if (err != SoundIoError.None) { Console.Error.WriteLine("{0}.", err.GetErrorMessage()); return(1); } if (watch) { soundIo.OnDevicesChange = OnDevicesChange; while (true) { soundIo.WaitEvents(); } } else { soundIo.FlushEvents(); err = (SoundIoError)ListDevices(soundIo); soundIo.Dispose(); Console.ReadKey(); return((int)err); } }
public static int Main(string [] args) { string in_device_id = null, out_device_id = null; string backend_name = null; bool in_raw = false, out_raw = false; double microphone_latency = 0.2; // seconds foreach (var arg in args) { switch (arg) { case "--in_raw": in_raw = true; continue; case "--out_raw": out_raw = true; continue; default: if (arg.StartsWith("--backend:")) { backend_name = arg.Substring(arg.IndexOf(':') + 1); } else if (arg.StartsWith("--in-device:")) { in_device_id = arg.Substring(arg.IndexOf(':') + 1); } else if (arg.StartsWith("--out-device:")) { out_device_id = arg.Substring(arg.IndexOf(':') + 1); } else if (arg.StartsWith("--latency:")) { microphone_latency = double.Parse(arg.Substring(arg.IndexOf(':') + 1)); } continue; } } var api = new SoundIO(); var backend = backend_name == null ? SoundIOBackend.None : (SoundIOBackend)Enum.Parse(typeof(SoundIOBackend), backend_name); if (backend == SoundIOBackend.None) { api.Connect(); } else { api.ConnectBackend(backend); } Console.WriteLine("backend: " + api.CurrentBackend); api.FlushEvents(); var in_device = in_device_id == null?api.GetInputDevice(api.DefaultInputDeviceIndex) : Enumerable.Range(0, api.InputDeviceCount) .Select(i => api.GetInputDevice(i)) .FirstOrDefault(d => d.Id == in_device_id && d.IsRaw == in_raw); if (in_device == null) { Console.Error.WriteLine("Input device " + in_device_id + " not found."); return(1); } Console.WriteLine("input device: " + in_device.Name); if (in_device.ProbeError != 0) { Console.Error.WriteLine("Cannot probe input device " + in_device_id + "."); return(1); } var out_device = out_device_id == null?api.GetOutputDevice(api.DefaultOutputDeviceIndex) : Enumerable.Range(0, api.OutputDeviceCount) .Select(i => api.GetOutputDevice(i)) .FirstOrDefault(d => d.Id == out_device_id && d.IsRaw == out_raw); if (out_device == null) { Console.Error.WriteLine("Output device " + out_device_id + " not found."); return(1); } Console.WriteLine("output device: " + out_device.Name); if (out_device.ProbeError != 0) { Console.Error.WriteLine("Cannot probe output device " + out_device_id + "."); return(1); } out_device.SortDeviceChannelLayouts(); var layout = SoundIODevice.BestMatchingChannelLayout(out_device, in_device); if (layout.IsNull) { throw new InvalidOperationException("channel layouts not compatible"); // panic() } var sample_rate = prioritized_sample_rates.FirstOrDefault(sr => in_device.SupportsSampleRate(sr) && out_device.SupportsSampleRate(sr)); if (sample_rate == default(int)) { throw new InvalidOperationException("incompatible sample rates"); // panic() } var fmt = prioritized_formats.FirstOrDefault(f => in_device.SupportsFormat(f) && out_device.SupportsFormat(f)); if (fmt == default(SoundIOFormat)) { throw new InvalidOperationException("incompatible sample formats"); // panic() } var instream = in_device.CreateInStream(); instream.Format = fmt; instream.SampleRate = sample_rate; instream.Layout = layout; instream.SoftwareLatency = microphone_latency; instream.ReadCallback = (fmin, fmax) => read_callback(instream, fmin, fmax); instream.Open(); var outstream = out_device.CreateOutStream(); outstream.Format = fmt; outstream.SampleRate = sample_rate; outstream.Layout = layout; outstream.SoftwareLatency = microphone_latency; outstream.WriteCallback = (fmin, fmax) => write_callback(outstream, fmin, fmax); outstream.UnderflowCallback = () => underflow_callback(outstream); outstream.Open(); int capacity = (int)(microphone_latency * 2 * instream.SampleRate * instream.BytesPerFrame); ring_buffer = api.CreateRingBuffer(capacity); var buf = ring_buffer.WritePointer; int fill_count = (int)(microphone_latency * outstream.SampleRate * outstream.BytesPerFrame); // FIXME: there should be more efficient way for memset() for (int i = 0; i < fill_count; i++) { Marshal.WriteByte(buf, i, 0); } ring_buffer.AdvanceWritePointer(fill_count); instream.Start(); outstream.Start(); for (;;) { api.WaitEvents(); } outstream.Dispose(); instream.Dispose(); in_device.RemoveReference(); out_device.RemoveReference(); api.Dispose(); return(0); }