public void Start() { if (State != SynthesizerState.Initial) { return; } soundio = new SoundIO(); soundio.Connect(); soundio.FlushEvents(); var device = soundio.GetOutputDevice(soundio.DefaultOutputDeviceIndex); if (device.ProbeError != 0) { throw new DX7SynthesizerException($"Cannot probe device {device.Name}."); } out_stream = device.CreateOutStream(); if (!device.SupportsFormat(SoundIOFormat.S16LE)) { throw new NotSupportedException(); } out_stream.Format = SoundIOFormat.S16LE; out_stream.WriteCallback = (min, max) => WriteCallback(min, max); out_stream.UnderflowCallback = () => { Debug.WriteLine("underflow"); }; out_stream.ErrorCallback = () => { throw new DX7SynthesizerException($"ERROR at libsoundio: {out_stream.LayoutErrorMessage}"); }; out_stream.Open(); State = SynthesizerState.Started; out_stream.Start(); soundio.FlushEvents(); }
public void WithDefaultOutputDevice() { var api = new SoundIO(); api.Connect(); try { api.FlushEvents(); var dev = api.GetOutputDevice(api.DefaultOutputDeviceIndex); Assert.AreNotEqual(0, dev.GetNearestSampleRate(1), "nearest sample rate is 0...?"); var wait = new ManualResetEvent(false); using (var stream = dev.CreateOutStream()) { stream.Open(); stream.WriteCallback = (min, max) => { int frameCount = max; var results = stream.BeginWrite(ref frameCount); for (int channel = 0; channel < stream.Layout.ChannelCount; channel += 1) { var area = results.GetArea(channel); // FIXME: do write samples area.Pointer += area.Step; } stream.EndWrite(); wait.Set(); }; stream.Start(); stream.Pause(true); wait.WaitOne(); } } finally { api.Disconnect(); } }
static int ListDevices(SoundIO soundIo) { int outputCount = soundIo.GetOutputDeviceCount(); int inputCount = soundIo.GetInputDeviceCount(); int defaultOutput = soundIo.GetDefaultOutputDeviceIndex(); int defaultInput = soundIo.GetDefaultInputDeviceIndex(); Console.WriteLine("--------Input Devices--------"); for (int i = 0; i < inputCount; i++) { SoundIODevice device = soundIo.GetInputDevice(i); PrintDevice(device, defaultInput == i); device.Release(); } Console.WriteLine("\n--------Output Devices--------\n"); for (int i = 0; i < outputCount; i++) { SoundIODevice device = soundIo.GetOutputDevice(i); PrintDevice(device, defaultOutput == i); device.Release(); } Console.WriteLine("\n{0} devices found.", inputCount + outputCount); return(0); }
/// <summary> /// Constructs a new instance of a <see cref="SoundIoAudioOut"/> /// </summary> public SoundIoAudioOut() { m_AudioContext = new SoundIO(); m_AudioContext.Connect(); m_AudioContext.FlushEvents(); m_AudioDevice = m_AudioContext.GetOutputDevice(m_AudioContext.DefaultOutputDeviceIndex); m_TrackPool = new SoundIoAudioTrackPool(m_AudioContext, m_AudioDevice, MaximumTracks); }
public AudioPlayer(IAudioSource source) { Source = source; api.Connect(); api.FlushEvents(); for (int i = 0; api.OutputDeviceCount > i; i++) { Devices.Add(api.GetOutputDevice(i)); } }
/// <summary> /// Searches for a shared version of the default audio device /// </summary> /// <param name="audioContext">The <see cref="SoundIO"/> audio context</param> /// <param name="fallback">Whether to fallback to the raw default audio device if a non-raw device cannot be found</param> private static SoundIODevice FindNonRawDefaultAudioDevice(SoundIO audioContext, bool fallback = false) { SoundIODevice defaultAudioDevice = audioContext.GetOutputDevice(audioContext.DefaultOutputDeviceIndex); if (!defaultAudioDevice.IsRaw) { return(defaultAudioDevice); } for (int i = 0; i < audioContext.BackendCount; i++) { SoundIODevice audioDevice = audioContext.GetOutputDevice(i); if (audioDevice.Id == defaultAudioDevice.Id && !audioDevice.IsRaw) { return(audioDevice); } } return(fallback ? defaultAudioDevice : null); }
static void DoListDevices(SoundIO api) { Console.WriteLine("Inputs"); for (int i = 0; i < api.InputDeviceCount; i++) { PrintDevice(api.GetInputDevice(i)); } Console.WriteLine("Outputs"); for (int i = 0; i < api.OutputDeviceCount; i++) { PrintDevice(api.GetOutputDevice(i)); } }
public SoundioOutput() { api.Connect(); api.FlushEvents(); for (int i = 0; api.OutputDeviceCount > i; i++) { var device = api.GetOutputDevice(i); if (i == api.DefaultOutputDeviceIndex) { DefaultDevice = device; } Devices.Add(device); } }
public void SoftwareLatencyOffset() { var api = new SoundIO(); api.Connect(); try { api.FlushEvents(); var dev = api.GetOutputDevice(api.DefaultOutputDeviceIndex); Assert.AreNotEqual(0, dev.GetNearestSampleRate(1), "nearest sample rate is 0...?"); using (var stream = dev.CreateOutStream()) { Assert.AreEqual(0, stream.SoftwareLatency, "existing non-zero latency...?"); stream.SoftwareLatency = 0.5; Assert.AreEqual(0.5, stream.SoftwareLatency, "wrong software latency"); } } finally { api.Disconnect(); } }
public void Devices() { var api = new SoundIO(); api.Connect(); try { api.FlushEvents(); Assert.IsTrue(api.DefaultInputDeviceIndex >= -1, "default input device index"); Assert.IsTrue(api.DefaultOutputDeviceIndex >= -1, "default output device index"); for (int i = 0; i < api.OutputDeviceCount; i++) { var dev = api.GetOutputDevice(i); } for (int i = 0; i < api.InputDeviceCount; i++) { var dev = api.GetInputDevice(i); } } finally { api.Disconnect(); } }
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 SoundioOutput(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.OutputDeviceCount > i; i++) { var device = _api.GetOutputDevice(i); if (i == _api.DefaultOutputDeviceIndex) { DefaultDevice = device; } Devices.Add(device); } }
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(); } }
public void WithDefaultOutputDevice() { var api = new SoundIO(); api.Connect(); try { api.FlushEvents(); var dev = api.GetOutputDevice(api.DefaultOutputDeviceIndex); Assert.AreNotEqual(0, dev.GetNearestSampleRate(1), "nearest sample rate is 0...?"); using (var stream = dev.CreateOutStream()) { stream.Open(); stream.WriteCallback = (min, max) => { int frameCount = max; stream.BeginWrite(ref frameCount); }; stream.Start(); stream.Pause(true); Thread.Sleep(50); stream.EndWrite(); } } finally { api.Disconnect(); } }
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); }
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 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); }