示例#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();
        }
示例#2
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);
            }
        }
示例#3
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();
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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);
        }
示例#6
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);
        }
示例#7
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 SoundIoHardwareDeviceDriver()
        {
            _audioContext        = new SoundIO();
            _updateRequiredEvent = new ManualResetEvent(false);
            _sessions            = new List <SoundIoHardwareDeviceSession>();

            _audioContext.Connect();
            _audioContext.FlushEvents();

            _audioDevice = FindNonRawDefaultAudioDevice(_audioContext, true);
        }
示例#9
0
        public AudioPlayer(IAudioSource source)
        {
            Source = source;
            api.Connect();
            api.FlushEvents();

            for (int i = 0; api.OutputDeviceCount > i; i++)
            {
                Devices.Add(api.GetOutputDevice(i));
            }
        }
示例#10
0
        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);
        }
示例#11
0
        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();
        }
示例#12
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();
            }
        }
        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();
            }
        }
示例#16
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();
            }
        }
示例#17
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();
            }
        }
示例#18
0
        public static int Main(string[] args)
        {
            string         exe        = "SoundIOSine";
            SoundIoBackend backend    = SoundIoBackend.None;
            string         deviceId   = null;
            bool           raw        = false;
            string         streamName = null;
            double         latency    = 0.0;
            int            sampleRate = 0;
            SoundIoError   err;
            SoundIODevice  device = null;

            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i];
                if (arg.StartsWith("--"))
                {
                    if (arg.CompareTo("--raw") == 0)
                    {
                        raw = true;
                    }
                    else
                    {
                        i++;
                        if (i >= args.Length)
                        {
                            return(Usage(exe));
                        }
                        else if (arg.CompareTo("--backend") == 0)
                        {
                            backend = (SoundIoBackend)Enum.Parse(typeof(SoundIoBackend), args[i]);
                        }
                        else if (arg.CompareTo("--device") == 0)
                        {
                            deviceId = args[i];
                        }
                        else if (arg.CompareTo("--name") == 0)
                        {
                            streamName = args[i];
                        }
                        else if (arg.CompareTo("--latency") == 0)
                        {
                            latency = double.Parse(args[i]);
                        }
                        else if (arg.CompareTo("--sample-rate") == 0)
                        {
                            sampleRate = int.Parse(args[i]);
                        }
                        else
                        {
                            return(Usage(exe));
                        }
                    }
                }
                else
                {
                    return(Usage(exe));
                }
            }

            SoundIO soundIo = new SoundIO();

            err = (backend == SoundIoBackend.None) ?
                  soundIo.Connect() : soundIo.ConnectBackend(backend);

            if (err != SoundIoError.None)
            {
                Console.Error.WriteLine("Unable to connect to backend: {0}.", err.GetErrorMessage());
                return(1);
            }

            Console.WriteLine("Backend: {0}.", soundIo.CurrentBackend);

            soundIo.FlushEvents();

            if (deviceId != null)
            {
                foreach (var dev in soundIo)
                {
                    if (dev.Aim == SoundIoDeviceAim.Output && dev.Id.Equals(deviceId) && dev.IsRaw == raw)
                    {
                        device = dev;
                        break;
                    }
                }

                if (device == null)
                {
                    Console.Error.WriteLine("Output device not found.");
                    return(1);
                }

                device.AddRef(); // Enumerator cleans up itself on dispose
            }
            else
            {
                device = soundIo.GetDefaultOutputDevice();
            }

            Console.WriteLine("Output device: {0}.", device.Name);

            if (device.ProbeError != SoundIoError.None)
            {
                Console.Error.WriteLine("Cannot probe device: {0}.", device.ProbeError.GetErrorMessage());
                return(1);
            }

            SoundIOOutStream outstream = new SoundIOOutStream(device);

            outstream.OnWriteCallback     = WriteCallback;
            outstream.OnUnderflowCallback = UnderflowCallback;
            if (streamName != null)
            {
                outstream.Name = streamName;
            }
            outstream.SoftwareLatency = latency;
            if (sampleRate != 0)
            {
                outstream.SampleRate = sampleRate;
            }

            if (device.SupportsFormat(SoundIoFormats.Float32NE))
            {
                outstream.Format = SoundIoFormats.Float32NE;
                writeSample      = WriteSampleFloat32NE;
            }
            else if (device.SupportsFormat(SoundIoFormats.Float64NE))
            {
                outstream.Format = SoundIoFormats.Float64NE;
                writeSample      = WriteSampleFloat64NE;
            }
            else if (device.SupportsFormat(SoundIoFormats.S32NE))
            {
                outstream.Format = SoundIoFormats.S32NE;
                writeSample      = WriteSampleS32NE;
            }
            else if (device.SupportsFormat(SoundIoFormats.S16NE))
            {
                outstream.Format = SoundIoFormats.S16NE;
                writeSample      = WriteSampleS16NE;
            }
            else
            {
                Console.Error.WriteLine("No suitable format available.");
                return(1);
            }

            err = outstream.Open();
            if (err != SoundIoError.None)
            {
                Console.Error.WriteLine("Unable to open device: {0}.", err.GetErrorMessage());
                return(1);
            }

            Console.WriteLine("Software latency: {0:N6}.", outstream.SoftwareLatency);
            Console.WriteLine(
                "\t'p' - pause\n" +
                "\t'u' - unpause\n" +
                "\t'P' - pause from within callback\n" +
                "\t'c' - clear buffer\n" +
                "\t'q' - quit\n");

            if (outstream.LayoutError != SoundIoError.None)
            {
                Console.Error.WriteLine("Unable to set channel layout: {0}.", outstream.LayoutError.GetErrorMessage());
            }

            err = outstream.Start();
            if (err != SoundIoError.None)
            {
                Console.Error.WriteLine("Unable to start device {0}.", err.GetErrorMessage());
                return(1);
            }

            while (true)
            {
                soundIo.FlushEvents();

                int c = Console.Read();
                if (c == 'p')
                {
                    err = outstream.Pause(true);
                    Console.Error.WriteLine("Pausing result: {0}.", err.GetErrorMessage());
                }
                else if (c == 'P')
                {
                    wantPause = true;
                }
                else if (c == 'u')
                {
                    wantPause = false;
                    err       = outstream.Pause(false);
                    Console.Error.WriteLine("Unpausing result: {0}.", err.GetErrorMessage());
                }
                else if (c == 'c')
                {
                    err = outstream.ClearBuffer();
                    Console.Error.WriteLine("Clear buffer result: {0}.", err.GetErrorMessage());
                }
                else if (c == 'q')
                {
                    break;
                }
                else if (c == '\r' || c == '\n')
                {
                    // ignore
                }
                else
                {
                    Console.Error.WriteLine("Unrecognized command: {0}.", (char)c);
                }
            }

            outstream.Dispose();
            device.Release();
            soundIo.Dispose();
            return(0);
        }
示例#19
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();
                }
            }
        }
示例#20
0
        static int Main(string[] args)
        {
            string         exe     = "SoundIOListDevices";
            bool           watch   = false;
            SoundIoBackend backend = SoundIoBackend.None;
            SoundIoError   err;

            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i];
                if (arg.CompareTo("--watch") == 0)
                {
                    watch = true;
                }
                else if (arg.CompareTo("--short") == 0)
                {
                    shortOutput = true;
                }
                else if (arg.StartsWith("--"))
                {
                    i++;
                    if (i >= args.Length)
                    {
                        return(Usage(exe));
                    }
                    else if (arg.CompareTo("--backend") == 0)
                    {
                        backend = (SoundIoBackend)Enum.Parse(typeof(SoundIoBackend), args[i]);
                    }
                    else
                    {
                        return(Usage(exe));
                    }
                }
                else
                {
                    return(Usage(exe));
                }
            }

            SoundIO soundIo = new SoundIO();

            err = (backend == SoundIoBackend.None) ?
                  soundIo.Connect() : soundIo.ConnectBackend(backend);

            if (err != SoundIoError.None)
            {
                Console.Error.WriteLine("{0}.", err.GetErrorMessage());
                return(1);
            }

            if (watch)
            {
                soundIo.OnDevicesChange = OnDevicesChange;
                while (true)
                {
                    soundIo.WaitEvents();
                }
            }
            else
            {
                soundIo.FlushEvents();
                err = (SoundIoError)ListDevices(soundIo);
                soundIo.Dispose();
                Console.ReadKey();
                return((int)err);
            }
        }
示例#21
0
        public static int Main(string[] args)
        {
            string         exe      = "SoundIORecord";
            SoundIoBackend backend  = SoundIoBackend.None;
            string         deviceId = null;
            bool           isRaw    = true;
            string         outfile  = "1.pcm";
            SoundIoError   err;

            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i];
                if (arg.StartsWith("--"))
                {
                    if (arg.CompareTo("--raw") == 0)
                    {
                        isRaw = true;
                    }
                    else if (++i > args.Length)
                    {
                        return(Usage(exe));
                    }
                    else if (arg.CompareTo("--backend") == 0)
                    {
                        backend = (SoundIoBackend)Enum.Parse(typeof(SoundIoBackend), args[i]);
                    }
                    else if (arg.CompareTo("--device") == 0)
                    {
                        deviceId = args[i];
                    }
                    else
                    {
                        return(Usage(exe));
                    }
                }
                else if (outfile == null)
                {
                    outfile = arg;
                }
                else
                {
                    return(Usage(exe));
                }
            }

            if (outfile == null)
            {
                return(Usage(exe));
            }

            using (SoundIO soundIo = new SoundIO())
            {
                err = (backend == SoundIoBackend.None) ? soundIo.Connect() : soundIo.ConnectBackend(backend);
                if (err != SoundIoError.None)
                {
                    Console.Error.WriteLine("Error connecting: {0}.", err.GetErrorMessage());
                    return(1);
                }
                soundIo.FlushEvents();
                SoundIODevice selectedDevice = null;
                if (deviceId != null)
                {
                    foreach (var dev in soundIo)
                    {
                        if (dev.Aim == SoundIoDeviceAim.Input && dev.Id.Equals(deviceId) && dev.IsRaw == isRaw)
                        {
                            selectedDevice = dev;
                            break;
                        }
                    }

                    if (selectedDevice == null)
                    {
                        Console.Error.WriteLine("Invalid device id: {0}.", deviceId);
                        return(1);
                    }

                    selectedDevice.AddRef(); // Enumerator cleans up itself on dispose
                }
                else
                {
                    selectedDevice = soundIo.GetDefaultInputDevice();
                    if (selectedDevice == null)
                    {
                        Console.Error.WriteLine("No input devices available.");
                        return(1);
                    }
                }

                Console.WriteLine("Device: {0}.", selectedDevice.Name);

                if (selectedDevice.ProbeError != 0)
                {
                    Console.Error.WriteLine("Unable to probe device: {0}.", selectedDevice.ProbeError.GetErrorMessage());
                    return(1);
                }

                selectedDevice.SortChannelLayouts();

                int sampleRate = prioritizedSampleRates.FirstOrDefault(sr => selectedDevice.SupportsSampleRate(sr));
                if (sampleRate == 0)
                {
                    sampleRate = selectedDevice.SampleRates[0].Max;
                }

                SoundIoFormat fmt = prioritizedFormats.FirstOrDefault(f => selectedDevice.SupportsFormat(f));
                if (fmt == SoundIoFormat.Invalid)
                {
                    fmt = selectedDevice.Formats[0];
                }

                using (SoundIOInStream instream = new SoundIOInStream(selectedDevice))
                {
                    instream.Format             = fmt;
                    instream.SampleRate         = sampleRate;
                    instream.OnReadCallback     = ReadCallback;
                    instream.OnOverflowCallback = OverflowCallback;

                    err = instream.Open();
                    if (err != SoundIoError.None)
                    {
                        Console.Error.WriteLine("Unable to open input stream: {0}.", err.GetErrorMessage());
                        return(1);
                    }

                    Console.WriteLine("{0} {1}Hz {2} interleaved", instream.Layout.Name, sampleRate, fmt.GetFormatString());

                    const int         ringBufferDurationSeconds = 30;
                    int               capacity   = ringBufferDurationSeconds * instream.SampleRate * instream.BytesPerFrame;
                    SoundIORingBuffer ringBuffer = new SoundIORingBuffer(soundIo, capacity);
                    instream.UserData = ringBuffer.Handle;
                    ringBuffers.Add(ringBuffer.Handle, ringBuffer);

                    err = instream.Start();
                    if (err != SoundIoError.None)
                    {
                        Console.Error.WriteLine("Unable to start input device: {0}.", err.GetErrorMessage());
                        return(1);
                    }

                    Console.WriteLine("Recording data for 10 seconds.");
                    int timeout = 100;
                    using (var fs = File.OpenWrite(outfile))
                    {
                        byte[] buffer = new byte[capacity];
                        while (true) // No memory allocations allowed
                        {
                            soundIo.FlushEvents();
                            Thread.Sleep(100);
                            int    fillBytes = ringBuffer.FillCount;
                            IntPtr readBuf   = ringBuffer.ReadPointer;
                            Marshal.Copy(readBuf, buffer, 0, fillBytes);
                            fs.Write(buffer, 0, fillBytes);

                            ringBuffer.AdvanceReadPointer(fillBytes);

                            if (--timeout <= 0)
                            {
                                break;
                            }
                        }
                    }
                }
                selectedDevice.Release();
                return(0);
            }
        }
示例#22
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);
        }
示例#23
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);
        }
示例#24
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();
        }
示例#25
0
        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);
        }
示例#26
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);
                }
            }
        }