public SoundioInput(SoundIOBackend?backend = null, TimeSpan?bufferDuration = null) { _bufferDuration = bufferDuration ?? TimeSpan.FromSeconds(30); if (backend.HasValue) { _api.ConnectBackend(backend.Value); } else { _api.Connect(); } _api.FlushEvents(); for (int i = 0; _api.InputDeviceCount > i; i++) { var device = _api.GetInputDevice(i); if (i == _api.DefaultInputDeviceIndex) { DefaultDevice = device; } Devices.Add(device); } }
public static int Main(string [] args) { bool watch = false; string backend = null; foreach (var arg in args) { switch (arg) { case "--watch": watch = true; continue; default: if (arg.StartsWith("--backend:")) { backend = arg.Substring(arg.IndexOf(':') + 1); continue; } break; } ShowUsageToExit(); return(1); } using (var api = new SoundIO()) { SoundIOBackend be = SoundIOBackend.None; if (Enum.TryParse(backend, out be)) { ShowUsageToExit(); return(1); } if (be == SoundIOBackend.None) { api.Connect(); } else { api.ConnectBackend(be); } api.FlushEvents(); if (watch) { api.OnDevicesChange = () => OnDeviceChange(api); Console.WriteLine("Type [ENTER] to exit."); Console.ReadLine(); } else { DoListDevices(api); } } return(0); }
public static int Main(string[] args) { string exe = "SoundIOSine"; SoundIoBackend backend = SoundIoBackend.None; string deviceId = null; bool raw = false; string streamName = null; double latency = 0.0; int sampleRate = 0; SoundIoError err; SoundIODevice device = null; for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.StartsWith("--")) { if (arg.CompareTo("--raw") == 0) { raw = true; } else { i++; if (i >= args.Length) { return(Usage(exe)); } else if (arg.CompareTo("--backend") == 0) { backend = (SoundIoBackend)Enum.Parse(typeof(SoundIoBackend), args[i]); } else if (arg.CompareTo("--device") == 0) { deviceId = args[i]; } else if (arg.CompareTo("--name") == 0) { streamName = args[i]; } else if (arg.CompareTo("--latency") == 0) { latency = double.Parse(args[i]); } else if (arg.CompareTo("--sample-rate") == 0) { sampleRate = int.Parse(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("Unable to connect to backend: {0}.", err.GetErrorMessage()); return(1); } Console.WriteLine("Backend: {0}.", soundIo.CurrentBackend); soundIo.FlushEvents(); if (deviceId != null) { foreach (var dev in soundIo) { if (dev.Aim == SoundIoDeviceAim.Output && dev.Id.Equals(deviceId) && dev.IsRaw == raw) { device = dev; break; } } if (device == null) { Console.Error.WriteLine("Output device not found."); return(1); } device.AddRef(); // Enumerator cleans up itself on dispose } else { device = soundIo.GetDefaultOutputDevice(); } Console.WriteLine("Output device: {0}.", device.Name); if (device.ProbeError != SoundIoError.None) { Console.Error.WriteLine("Cannot probe device: {0}.", device.ProbeError.GetErrorMessage()); return(1); } SoundIOOutStream outstream = new SoundIOOutStream(device); outstream.OnWriteCallback = WriteCallback; outstream.OnUnderflowCallback = UnderflowCallback; if (streamName != null) { outstream.Name = streamName; } outstream.SoftwareLatency = latency; if (sampleRate != 0) { outstream.SampleRate = sampleRate; } if (device.SupportsFormat(SoundIoFormats.Float32NE)) { outstream.Format = SoundIoFormats.Float32NE; writeSample = WriteSampleFloat32NE; } else if (device.SupportsFormat(SoundIoFormats.Float64NE)) { outstream.Format = SoundIoFormats.Float64NE; writeSample = WriteSampleFloat64NE; } else if (device.SupportsFormat(SoundIoFormats.S32NE)) { outstream.Format = SoundIoFormats.S32NE; writeSample = WriteSampleS32NE; } else if (device.SupportsFormat(SoundIoFormats.S16NE)) { outstream.Format = SoundIoFormats.S16NE; writeSample = WriteSampleS16NE; } else { Console.Error.WriteLine("No suitable format available."); return(1); } err = outstream.Open(); if (err != SoundIoError.None) { Console.Error.WriteLine("Unable to open device: {0}.", err.GetErrorMessage()); return(1); } Console.WriteLine("Software latency: {0:N6}.", outstream.SoftwareLatency); Console.WriteLine( "\t'p' - pause\n" + "\t'u' - unpause\n" + "\t'P' - pause from within callback\n" + "\t'c' - clear buffer\n" + "\t'q' - quit\n"); if (outstream.LayoutError != SoundIoError.None) { Console.Error.WriteLine("Unable to set channel layout: {0}.", outstream.LayoutError.GetErrorMessage()); } err = outstream.Start(); if (err != SoundIoError.None) { Console.Error.WriteLine("Unable to start device {0}.", err.GetErrorMessage()); return(1); } while (true) { soundIo.FlushEvents(); int c = Console.Read(); if (c == 'p') { err = outstream.Pause(true); Console.Error.WriteLine("Pausing result: {0}.", err.GetErrorMessage()); } else if (c == 'P') { wantPause = true; } else if (c == 'u') { wantPause = false; err = outstream.Pause(false); Console.Error.WriteLine("Unpausing result: {0}.", err.GetErrorMessage()); } else if (c == 'c') { err = outstream.ClearBuffer(); Console.Error.WriteLine("Clear buffer result: {0}.", err.GetErrorMessage()); } else if (c == 'q') { break; } else if (c == '\r' || c == '\n') { // ignore } else { Console.Error.WriteLine("Unrecognized command: {0}.", (char)c); } } outstream.Dispose(); device.Release(); soundIo.Dispose(); return(0); }
public static int Main(string[] args) { string exe = "SoundIORecord"; SoundIoBackend backend = SoundIoBackend.None; string deviceId = null; bool isRaw = true; string outfile = "1.pcm"; SoundIoError err; for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.StartsWith("--")) { if (arg.CompareTo("--raw") == 0) { isRaw = true; } else if (++i > args.Length) { return(Usage(exe)); } else if (arg.CompareTo("--backend") == 0) { backend = (SoundIoBackend)Enum.Parse(typeof(SoundIoBackend), args[i]); } else if (arg.CompareTo("--device") == 0) { deviceId = args[i]; } else { return(Usage(exe)); } } else if (outfile == null) { outfile = arg; } else { return(Usage(exe)); } } if (outfile == null) { return(Usage(exe)); } using (SoundIO soundIo = new SoundIO()) { err = (backend == SoundIoBackend.None) ? soundIo.Connect() : soundIo.ConnectBackend(backend); if (err != SoundIoError.None) { Console.Error.WriteLine("Error connecting: {0}.", err.GetErrorMessage()); return(1); } soundIo.FlushEvents(); SoundIODevice selectedDevice = null; if (deviceId != null) { foreach (var dev in soundIo) { if (dev.Aim == SoundIoDeviceAim.Input && dev.Id.Equals(deviceId) && dev.IsRaw == isRaw) { selectedDevice = dev; break; } } if (selectedDevice == null) { Console.Error.WriteLine("Invalid device id: {0}.", deviceId); return(1); } selectedDevice.AddRef(); // Enumerator cleans up itself on dispose } else { selectedDevice = soundIo.GetDefaultInputDevice(); if (selectedDevice == null) { Console.Error.WriteLine("No input devices available."); return(1); } } Console.WriteLine("Device: {0}.", selectedDevice.Name); if (selectedDevice.ProbeError != 0) { Console.Error.WriteLine("Unable to probe device: {0}.", selectedDevice.ProbeError.GetErrorMessage()); return(1); } selectedDevice.SortChannelLayouts(); int sampleRate = prioritizedSampleRates.FirstOrDefault(sr => selectedDevice.SupportsSampleRate(sr)); if (sampleRate == 0) { sampleRate = selectedDevice.SampleRates[0].Max; } SoundIoFormat fmt = prioritizedFormats.FirstOrDefault(f => selectedDevice.SupportsFormat(f)); if (fmt == SoundIoFormat.Invalid) { fmt = selectedDevice.Formats[0]; } using (SoundIOInStream instream = new SoundIOInStream(selectedDevice)) { instream.Format = fmt; instream.SampleRate = sampleRate; instream.OnReadCallback = ReadCallback; instream.OnOverflowCallback = OverflowCallback; err = instream.Open(); if (err != SoundIoError.None) { Console.Error.WriteLine("Unable to open input stream: {0}.", err.GetErrorMessage()); return(1); } Console.WriteLine("{0} {1}Hz {2} interleaved", instream.Layout.Name, sampleRate, fmt.GetFormatString()); const int ringBufferDurationSeconds = 30; int capacity = ringBufferDurationSeconds * instream.SampleRate * instream.BytesPerFrame; SoundIORingBuffer ringBuffer = new SoundIORingBuffer(soundIo, capacity); instream.UserData = ringBuffer.Handle; ringBuffers.Add(ringBuffer.Handle, ringBuffer); err = instream.Start(); if (err != SoundIoError.None) { Console.Error.WriteLine("Unable to start input device: {0}.", err.GetErrorMessage()); return(1); } Console.WriteLine("Recording data for 10 seconds."); int timeout = 100; using (var fs = File.OpenWrite(outfile)) { byte[] buffer = new byte[capacity]; while (true) // No memory allocations allowed { soundIo.FlushEvents(); Thread.Sleep(100); int fillBytes = ringBuffer.FillCount; IntPtr readBuf = ringBuffer.ReadPointer; Marshal.Copy(readBuf, buffer, 0, fillBytes); fs.Write(buffer, 0, fillBytes); ringBuffer.AdvanceReadPointer(fillBytes); if (--timeout <= 0) { break; } } } } selectedDevice.Release(); return(0); } }
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 device_id = null; string backend_name = null; bool raw = false; string outfile = null; foreach (var arg in args) { switch (arg) { case "--raw": raw = true; continue; default: if (arg.StartsWith("--backend:")) { backend_name = arg.Substring(arg.IndexOf(':') + 1); } else if (arg.StartsWith("--device:")) { device_id = arg.Substring(arg.IndexOf(':') + 1); } else { outfile = arg; } 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 device = device_id == null?api.GetInputDevice(api.DefaultInputDeviceIndex) : Enumerable.Range(0, api.InputDeviceCount) .Select(i => api.GetInputDevice(i)) .FirstOrDefault(d => d.Id == device_id && d.IsRaw == raw); if (device == null) { Console.Error.WriteLine("device " + device_id + " not found."); return(1); } Console.WriteLine("device: " + device.Name); if (device.ProbeError != 0) { Console.Error.WriteLine("Cannot probe device " + device_id + "."); return(1); } var sample_rate = prioritized_sample_rates.First(sr => device.SupportsSampleRate(sr)); var fmt = prioritized_formats.First(f => device.SupportsFormat(f)); var instream = device.CreateInStream(); instream.Format = fmt; instream.SampleRate = sample_rate; instream.ReadCallback = (fmin, fmax) => read_callback(instream, fmin, fmax); instream.OverflowCallback = () => overflow_callback(instream); instream.Open(); const int ring_buffer_duration_seconds = 30; int capacity = (int)(ring_buffer_duration_seconds * instream.SampleRate * instream.BytesPerFrame); ring_buffer = api.CreateRingBuffer(capacity); var buf = ring_buffer.WritePointer; instream.Start(); Console.WriteLine("Type CTRL+C to quit by killing process..."); using (var fs = File.OpenWrite(outfile)) { var arr = new byte [capacity]; unsafe { fixed(void *arrptr = arr) { for (; ;) { api.FlushEvents(); Thread.Sleep(1000); int fill_bytes = ring_buffer.FillCount; var read_buf = ring_buffer.ReadPointer; Buffer.MemoryCopy((void *)read_buf, arrptr, fill_bytes, fill_bytes); fs.Write(arr, 0, fill_bytes); ring_buffer.AdvanceReadPointer(fill_bytes); } } } } instream.Dispose(); device.RemoveReference(); api.Dispose(); return(0); }
public static int Main(string [] args) { string device_id = null; string backend_name = null; bool raw = false; string stream_name = null; double latency = 0.0; int sample_rate = 0; foreach (var arg in args) { switch (arg) { case "--raw": raw = true; continue; default: if (arg.StartsWith("--backend:")) { backend_name = arg.Substring(arg.IndexOf(':') + 1); } else if (arg.StartsWith("--device:")) { device_id = arg.Substring(arg.IndexOf(':') + 1); } else if (arg.StartsWith("--name:")) { stream_name = arg.Substring(arg.IndexOf(':') + 1); } else if (arg.StartsWith("--latency:")) { latency = double.Parse(arg.Substring(arg.IndexOf(':') + 1)); } else if (arg.StartsWith("--sample_rate:")) { sample_rate = int.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 device = device_id == null?api.GetOutputDevice(api.DefaultOutputDeviceIndex) : Enumerable.Range(0, api.OutputDeviceCount) .Select(i => api.GetOutputDevice(i)) .FirstOrDefault(d => d.Id == device_id && d.IsRaw == raw); if (device == null) { Console.Error.WriteLine("Output device " + device_id + " not found."); return(1); } Console.WriteLine("output device: " + device.Name); if (device.ProbeError != 0) { Console.Error.WriteLine("Cannot probe device " + device_id + "."); return(1); } var outstream = device.CreateOutStream(); outstream.WriteCallback = (min, max) => write_callback(outstream, min, max); outstream.UnderflowCallback = () => underflow_callback(outstream); if (stream_name != null) { outstream.Name = stream_name; } outstream.SoftwareLatency = latency; if (sample_rate != 0) { outstream.SampleRate = sample_rate; } if (device.SupportsFormat(SoundIODevice.Float32NE)) { outstream.Format = SoundIODevice.Float32NE; write_sample = write_sample_float32ne; } else if (device.SupportsFormat(SoundIODevice.Float64NE)) { outstream.Format = SoundIODevice.Float64NE; write_sample = write_sample_float64ne; } else if (device.SupportsFormat(SoundIODevice.S32NE)) { outstream.Format = SoundIODevice.S32NE; write_sample = write_sample_s32ne; } else if (device.SupportsFormat(SoundIODevice.S16NE)) { outstream.Format = SoundIODevice.S16NE; write_sample = write_sample_s16ne; } else { Console.Error.WriteLine("No suitable format available."); return(1); } outstream.Open(); Console.Error.WriteLine("Software latency: " + outstream.SoftwareLatency); Console.Error.WriteLine( @" 'p\n' - pause 'u\\n' - unpause 'P\\n' - pause from within callback 'c\\n' - clear buffer 'q\\n' - quit"); if (outstream.LayoutErrorMessage != null) { Console.Error.WriteLine("Unable to set channel layout: " + outstream.LayoutErrorMessage); } outstream.Start(); for (; ;) { api.FlushEvents(); int c = Console.Read(); if (c == 'p') { outstream.Pause(true); Console.Error.WriteLine("pause"); } else if (c == 'P') { want_pause = true; } else if (c == 'u') { want_pause = false; outstream.Pause(false); Console.Error.WriteLine("resume"); } else if (c == 'c') { outstream.ClearBuffer(); Console.Error.WriteLine("clear buffer"); } else if (c == 'q') { break; } } outstream.Dispose(); device.RemoveReference(); api.Dispose(); return(0); }
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); }