Esempio n. 1
0
        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();
        }
Esempio n. 2
0
        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();
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
        public AudioPlayer(IAudioSource source)
        {
            Source = source;
            api.Connect();
            api.FlushEvents();

            for (int i = 0; api.OutputDeviceCount > i; i++)
            {
                Devices.Add(api.GetOutputDevice(i));
            }
        }
Esempio n. 6
0
        /// <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);
        }
Esempio n. 7
0
 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));
     }
 }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 9
0
        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();
            }
        }
Esempio n. 12
0
        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);
            }
        }
Esempio n. 13
0
        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();
            }
        }
Esempio n. 14
0
        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();
            }
        }
Esempio n. 15
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);
        }
Esempio n. 16
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();
        }
Esempio n. 17
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);
        }