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 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 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(); } }
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); }
/// <summary> /// Constructs a new instance of a <see cref="SoundIoAudioOut"/> /// </summary> public SoundIoAudioOut() { _audioContext = new SoundIO(); _audioContext.Connect(); _audioContext.FlushEvents(); _audioDevice = FindNonRawDefaultAudioDevice(_audioContext, true); _trackPool = new SoundIoAudioTrackPool(_audioContext, _audioDevice, MaximumTracks); }
/// <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 SoundIoHardwareDeviceDriver() { _audioContext = new SoundIO(); _updateRequiredEvent = new ManualResetEvent(false); _sessions = new List <SoundIoHardwareDeviceSession>(); _audioContext.Connect(); _audioContext.FlushEvents(); _audioDevice = FindNonRawDefaultAudioDevice(_audioContext, true); }
public AudioPlayer(IAudioSource source) { Source = source; api.Connect(); api.FlushEvents(); for (int i = 0; api.OutputDeviceCount > i; i++) { Devices.Add(api.GetOutputDevice(i)); } }
public SoundIoHardwareDeviceDriver() { _audioContext = new SoundIO(); _updateRequiredEvent = new ManualResetEvent(false); _pauseEvent = new ManualResetEvent(true); _sessions = new ConcurrentDictionary <SoundIoHardwareDeviceSession, byte>(); _audioContext.Connect(); _audioContext.FlushEvents(); _audioDevice = FindNonRawDefaultAudioDevice(_audioContext, true); }
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 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 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(); } }
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 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> /// 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(); } } }
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 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); } }
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); }
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 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) { int sampleRate; string filename = null; SoundIoBackend backend = SoundIoBackend.None; string deviceId = null; bool isRaw = false; SoundIoError err; try { if (args.Length < 1) { Usage(); return(1); } for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.StartsWith("--")) { if (++i > args.Length) { return(Usage()); } 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()); } } else { if (File.Exists(args[i])) { filename = args[i]; } else { Usage(); return(1); } } } if (string.IsNullOrEmpty(filename)) { throw new Exception("Input file name can not null."); } } catch (IndexOutOfRangeException) { Usage(); return(1); } using (_soundIO = new SoundIO()) { using (_waveFile = new WaveFileReader(filename)) { _channels = _waveFile.WaveFormat.Channels; sampleRate = _waveFile.WaveFormat.SampleRate; _soundIO.Connect(); _soundIO.FlushEvents(); SoundIODevice device = null; if (deviceId != null) { foreach (var dev in _soundIO) { if (dev.Aim == SoundIoDeviceAim.Output && dev.Id.Equals(deviceId) && dev.IsRaw == isRaw) { 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("Device: {0}.", device.Name); if (device.ProbeError != SoundIoError.None) { Console.WriteLine("Cannot probe device: {0}", device.ProbeError); return(1); } Console.WriteLine("Output device: {0}", device.Name); if (device.ProbeError != SoundIoError.None) { Console.WriteLine("Cannot probe device: {0}", device.ProbeError); return(1); } var outstream = new SoundIOOutStream(device) { OnWriteCallback = WriteCallback, OnUnderflowCallback = UnderflowCallback, Name = "sio_play", SampleRate = sampleRate }; // look for maching layout for wav file... var foundLayout = false; foreach (var layout in device.Layouts) { if (layout.ChannelCount == _channels) { outstream.Layout = layout; foundLayout = true; break; } } // TODO: may need to look at endian issues and other formats... // when paired with NAudioLite, ISampleProvider the conversion to Float32 is automatic. if (device.SupportsFormat(SoundIoFormats.Float32NE)) { outstream.Format = SoundIoFormats.Float32NE; } else if (device.SupportsFormat(SoundIoFormats.Float64NE)) { outstream.Format = SoundIoFormats.Float64NE; } else if (device.SupportsFormat(SoundIoFormats.S32NE)) { outstream.Format = SoundIoFormats.S32NE; } else if (device.SupportsFormat(SoundIoFormats.S16NE)) { outstream.Format = SoundIoFormats.S16NE; } else { Console.WriteLine("No suitable device format available."); return(1); } Console.WriteLine(); Console.WriteLine("Playing file: {0}, Format: {1}", Path.GetFullPath(filename), _waveFile.WaveFormat); err = outstream.Open(); if (err != SoundIoError.None) { Console.WriteLine($"Unable to open device: {err.GetErrorMessage()}, with sample rate: {outstream.LayoutError}"); return(1); } if (outstream.LayoutError != SoundIoError.None) { Console.WriteLine($"Unable to set channel layout: {err.GetErrorMessage()}"); } // revisit layout... // if no suitable layout found if (!foundLayout) { Console.WriteLine("No native channel layout found, Device Channels: {0}, Wav File Channels: {1}, requires sampler...", outstream.Layout.ChannelCount, _channels); } // get sample provider that matches outstream.Layout if (outstream.Layout.ChannelCount == 1) { // mono if (_waveFile.WaveFormat.Channels == 1) { _sampleProvider = _waveFile.ToSampleProvider(); } else { _sampleProvider = _waveFile.ToSampleProvider().ToMono(); } } else if (outstream.Layout.ChannelCount == 2) { //stereo if (_waveFile.WaveFormat.Channels == 1) { _sampleProvider = _waveFile.ToSampleProvider().ToStereo(); } else { _sampleProvider = _waveFile.ToSampleProvider(); } } outstream.Start(); _soundIO.OnBackendDisconnect += SoundIo_OnBackendDisconnected; while (!_fileDone) { System.Threading.Thread.Sleep(100); _soundIO.FlushEvents(); } System.Threading.Thread.Sleep(500); if (_fileDone && outstream != null) { outstream.Dispose(); outstream = null; } Console.WriteLine("End Program"); return(0); } } }