public void ApplicationName() { var api = new SoundIO(); Assert.AreEqual("SoundIo", api.ApplicationName, "default app name unexpected"); api.ApplicationName = "MyApp"; Assert.AreEqual("MyApp", api.ApplicationName, "app_name not assigned"); api.Dispose(); }
public void Dispose() { _instream?.Dispose(); _instream = null; Device?.RemoveReference(); Device = null; _api?.Disconnect(); _api?.Dispose(); }
public void Dispose() { Stop(); foreach (var device in Devices) { device.RemoveReference(); } api.Disconnect(); api.Dispose(); }
public void EnumerateBackends() { var obj = new SoundIO(); Assert.AreNotEqual(0, obj.BackendCount, "no backend?"); var nameList = new List <string> (); for (int i = 0; i < obj.BackendCount; i++) { nameList.Add(SoundIO.GetBackendName(obj.GetBackend(i))); } string names = string.Join(", ", nameList); Assert.AreNotEqual(string.Empty, names, "no backend names?"); obj.Dispose(); }
public void OnBackendDisconnect() { var api = new SoundIO(); string msg = null; int err = -1; api.OnBackendDisconnect = e => { msg = "disconnected"; err = e; }; api.Connect(); api.FlushEvents(); api.Disconnect(); Assert.AreEqual("disconnected", msg, "msg not set"); Assert.AreEqual(0, err, "either error occured or event not fired"); api.Dispose(); }
public void Properties() { var api = new SoundIO(); api.Connect(); try { api.FlushEvents(); var dev = api.GetOutputDevice(api.DefaultOutputDeviceIndex); foreach (var p in typeof(SoundIODevice).GetProperties()) { try { p.GetValue(dev); } catch (Exception ex) { Assert.Fail("Failed to get property " + p + " : " + ex); } } } finally { api.Disconnect(); api.Dispose(); } }
public void Properties() { var api = new SoundIO(); api.Connect(); try { api.FlushEvents(); var dev = api.GetInputDevice(api.DefaultInputDeviceIndex); using (var stream = dev.CreateInStream()) { foreach (var p in typeof(SoundIOInStream).GetProperties()) { try { p.GetValue(stream); } catch (Exception ex) { Assert.Fail("Failed to get property " + p + " : " + ex); } } } } finally { api.Disconnect(); api.Dispose(); } }
public void Properties() { var api = new SoundIO(); api.Connect(); try { api.FlushEvents(); var dev = api.GetOutputDevice(api.DefaultOutputDeviceIndex); using (var stream = dev.CreateOutStream()) { foreach (var p in typeof(SoundIOOutStream).GetProperties()) { try { switch (p.Name) { case "Layout": var cl = stream.Layout; foreach (var pcl in typeof(SoundIOChannelLayout).GetProperties()) { Console.Error.WriteLine(pcl + " : " + pcl.GetValue(cl)); } break; default: p.GetValue(stream); break; } } catch (Exception ex) { Assert.Fail("Failed to get property " + p + " : " + ex.InnerException); } } } } finally { api.Disconnect(); api.Dispose(); } }
/// <summary> /// Determines if SoundIO can connect to a supported backend /// </summary> /// <returns></returns> private static bool IsSupportedInternal() { SoundIO context = null; SoundIODevice device = null; SoundIOOutStream stream = null; bool backendDisconnected = false; try { context = new SoundIO(); context.OnBackendDisconnect = (i) => { backendDisconnected = true; }; context.Connect(); context.FlushEvents(); if (backendDisconnected) { return(false); } if (context.OutputDeviceCount == 0) { return(false); } device = FindNonRawDefaultAudioDevice(context); if (device == null || backendDisconnected) { return(false); } stream = device.CreateOutStream(); if (stream == null || backendDisconnected) { return(false); } return(true); } catch { return(false); } finally { if (stream != null) { stream.Dispose(); } if (context != null) { context.Dispose(); } } }
/// <summary> /// Releases the unmanaged resources used by the <see cref="SoundIoAudioOut" /> /// </summary> public void Dispose() { _trackPool.Dispose(); _audioContext.Disconnect(); _audioContext.Dispose(); }
void Run(string [] args) { ring_buffer = new RingBuffer(); synth = new SynthUnit(ring_buffer); synth.Init(44100); soundio = new SoundIO(); soundio.Connect(); soundio.FlushEvents(); Console.WriteLine("SoundIO backend: " + soundio.CurrentBackend); // MIDI sender var midi_wait = new ManualResetEvent(false); Task.Run(() => { midi_wait.WaitOne(); if (args.Length > 0) { var sysex = File.ReadAllBytes(args [0]); int remaining = sysex.Length; while (remaining > 0) { int len = Math.Min(remaining, ring_buffer.WriteBytesAvailable()); ring_buffer.Write(sysex, 0, len); Task.Delay(50); remaining -= len; } } for (int i = 0; i < 10; i++) { byte [] bytes = { 0x90, (byte)(0x30 + i), 0x60 }; ring_buffer.Write(bytes, 0, 3); System.Threading.Thread.Sleep(1000); byte [] bytes2 = { 0x80, (byte)(0x30 + i), 0 }; ring_buffer.Write(bytes2, 0, 3); } }); // Audio outputter var wait = new ManualResetEvent(false); Task.Run(() => { var device = soundio.GetOutputDevice(soundio.DefaultOutputDeviceIndex); if (device.ProbeError != 0) { Console.Error.WriteLine($"Cannot probe device {device.Name}."); return; } Console.WriteLine($"Output device: {device.Name}"); var outStream = device.CreateOutStream(); if (!device.SupportsFormat(SoundIOFormat.S16LE)) { throw new NotSupportedException(); } outStream.Format = SoundIOFormat.S16LE; outStream.WriteCallback = (min, max) => WriteCallback(outStream, min, max); outStream.UnderflowCallback = () => { Console.WriteLine("underflow"); }; outStream.ErrorCallback = () => { Console.WriteLine($"ERROR at libsoundio: {outStream.LayoutErrorMessage}"); }; outStream.Open(); play_audio = true; midi_wait.Set(); Task.Delay(50); outStream.Start(); soundio.FlushEvents(); wait.WaitOne(); outStream.Dispose(); device.RemoveReference(); }); Console.Read(); play_audio = false; wait.Set(); Console.WriteLine("Finishing up"); soundio.Dispose(); }
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); }
/// <summary> /// Releases the unmanaged resources used by the <see cref="SoundIoAudioOut" /> /// </summary> public void Dispose() { m_TrackPool.Dispose(); m_AudioContext.Disconnect(); m_AudioContext.Dispose(); }
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 void Dispose() { outstream?.Dispose(); OutputDevice?.RemoveReference(); api.Dispose(); }
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); }