Exemple #1
0
        private static Tuple <int, int> GetSelectedDevices(string apiName, int inDeviceId, int outDeviceId, string inputDeviceName, string outputDeviceName)
        {
            var devices = Enumerable.Range(0, PortAudio.Pa_GetDeviceCount())
                          .ToDictionary(x => x, x => PortAudio.Pa_GetDeviceInfo(x))
                          .Where(x => PortAudio.Pa_GetHostApiInfo(x.Value.hostApi).name == apiName)
                          .ToDictionary(x => x.Key, x => x.Value);

            int realInputDeviceId;
            int realOutputDeviceId;

            var matchedInputArr = devices.Where(x => x.Key == inDeviceId && x.Value.name == inputDeviceName).ToArray();

            if (matchedInputArr.Length == 1)
            {
                realInputDeviceId = matchedInputArr[0].Key;
            }
            else
            {
                realInputDeviceId = devices.Where(x => x.Value.name == inputDeviceName).First().Key;
            }

            var matchedOutputArr = devices.Where(x => x.Key == outDeviceId && x.Value.name == outputDeviceName).ToArray();

            if (matchedOutputArr.Length == 1)
            {
                realOutputDeviceId = matchedOutputArr[0].Key;
            }
            else
            {
                realOutputDeviceId = devices.Where(x => x.Value.name == outputDeviceName).First().Key;
            }

            return(Tuple.Create(realInputDeviceId, realOutputDeviceId));
        }
Exemple #2
0
        private RealtimeHost()
        {
            if (!PortAudio.Pa_IsInitialized)
            {
                PortAudio.Pa_Initialize();
            }

            StreamState = StreamState.Closed;
        }
Exemple #3
0
        public static RealtimeHostConfig Deserialize(string serializedString)
        {
            try
            {
                var dict = serializedString
                           .Split('\n')
                           .Where(x => x.Contains('='))
                           .Select(x => x.Trim())
                           .ToDictionary(x => x.Split('=')[0].Trim(), x => x.Split('=')[1].Trim());

                var apiName          = dict["APIName"];
                var inDeviceId       = Convert.ToInt32(dict["InputDeviceID"]);
                var outDeviceId      = Convert.ToInt32(dict["OutputDeviceID"]);
                var inputDeviceName  = dict["InputDeviceName"];
                var outputDeviceName = dict["OutputDeviceName"];
                var numInputs        = Convert.ToInt32(dict["NumberOfInputs"]);
                var numOutputs       = Convert.ToInt32(dict["NumberOfOutputs"]);

                // fuzzy matching of devices as the deviceIds can change
                // prefers a device that matches on apiName, deviceId and deviceName, but falls back to match only apiName and deviceName if not found

                var devices            = GetSelectedDevices(apiName, inDeviceId, outDeviceId, inputDeviceName, outputDeviceName);
                var realInputDeviceId  = devices.Item1;
                var realOutputDeviceId = devices.Item2;

                var inDevice  = PortAudio.Pa_GetDeviceInfo(realInputDeviceId);
                var outDevice = PortAudio.Pa_GetDeviceInfo(realOutputDeviceId);

                if (inDevice.maxInputChannels < numInputs)
                {
                    numInputs = inDevice.maxInputChannels;
                }

                if (outDevice.maxOutputChannels < numOutputs)
                {
                    numOutputs = outDevice.maxOutputChannels;
                }

                var conf = new RealtimeHostConfig();
                conf.InputDeviceID   = realInputDeviceId;
                conf.OutputDeviceID  = realOutputDeviceId;
                conf.NumberOfInputs  = numInputs;
                conf.NumberOfOutputs = numOutputs;
                conf.Samplerate      = Convert.ToInt32(dict["Samplerate"]);
                conf.BufferSize      = Convert.ToUInt32(dict["BufferSize"]);
                return(conf);
            }
            catch
            {
                return(null);
            }
        }
Exemple #4
0
        public void StartStream()
        {
            if (StreamState != StreamState.Open)
            {
                throw new Exception("Trying to Start a stream that does not have State: Open. State is " + StreamState.ToString());
            }

            var err = PortAudio.Pa_StartStream(Config.Stream);

            if (err != PortAudio.PaError.paNoError)
            {
                throw new Exception(PortAudio.Pa_GetErrorText(err));
            }

            StreamState = StreamState.Started;
        }
Exemple #5
0
        public RealtimeHostConfig()
        {
            int defaultInput = PortAudio.Pa_GetDefaultInputDevice();
            var inputInfo    = PortAudio.Pa_GetDeviceInfo(defaultInput);

            inputParameters                           = new PortAudio.PaStreamParameters();
            inputParameters.device                    = defaultInput;
            inputParameters.sampleFormat              = PortAudio.PaSampleFormat.paFloat32 | PortAudio.PaSampleFormat.paNonInterleaved; /* 32 bit floating point output */
            inputParameters.suggestedLatency          = inputInfo.defaultLowInputLatency;
            inputParameters.hostApiSpecificStreamInfo = (IntPtr)0;

            int defaultOutput = PortAudio.Pa_GetDefaultOutputDevice();
            var outputInfo    = PortAudio.Pa_GetDeviceInfo(defaultInput);

            outputParameters                           = new PortAudio.PaStreamParameters();
            outputParameters.device                    = defaultOutput;
            outputParameters.sampleFormat              = PortAudio.PaSampleFormat.paFloat32 | PortAudio.PaSampleFormat.paNonInterleaved; /* 32 bit floating point output */
            outputParameters.suggestedLatency          = outputInfo.defaultLowOutputLatency;
            outputParameters.hostApiSpecificStreamInfo = (IntPtr)0;
        }
Exemple #6
0
        public void populateHostAPIs()
        {
            int hostCount = PortAudio.Pa_GetHostApiCount();

            for (int i = 0; i < hostCount; i++)
            {
                hostInfos.Add(PortAudio.Pa_GetHostApiInfo(i));
            }

            int deviceCount = PortAudio.Pa_GetDeviceCount();

            for (int i = 0; i < deviceCount; i++)
            {
                deviceInfos.Add(PortAudio.Pa_GetDeviceInfo(i));
            }

            foreach (var info in hostInfos)
            {
                comboBoxHost.Items.Add(info.name);
            }
        }
Exemple #7
0
        public void CloseStream()
        {
            if (StreamState != StreamState.Stopped)
            {
                throw new Exception("Trying to Close a stream that does not have State: Stopped. State is " + StreamState.ToString());
            }

            if (Config == null)
            {
                return;
            }

            var err = PortAudio.Pa_CloseStream(Config.Stream);

            if (err != PortAudio.PaError.paNoError)
            {
                throw new Exception(PortAudio.Pa_GetErrorText(err));
            }

            StreamState = StreamState.Closed;
        }
Exemple #8
0
        public void OpenStream()
        {
            if (Config == null)
            {
                throw new Exception("Configuration settings have not been applied. You must first configure the host");
            }

            if (StreamState != StreamState.Closed)
            {
                throw new Exception("Trying to Open a stream that does not have State: Closed. State is " + StreamState.ToString());
            }

            callbackDelegate       = RealtimeCallback;
            streamFinishedDelegate = StreamFinished;

            var err = PortAudio.Pa_OpenStream(
                out Config.Stream,
                ref Config.inputParameters,
                ref Config.outputParameters,
                Samplerate,
                BufferSize,
                (PortAudio.PaStreamFlags.paClipOff | PortAudio.PaStreamFlags.paDitherOff),
                callbackDelegate,
                new IntPtr(0)
                );

            if (err != PortAudio.PaError.paNoError)
            {
                throw new Exception(PortAudio.Pa_GetErrorText(err));
            }

            err = PortAudio.Pa_SetStreamFinishedCallback(Config.Stream, streamFinishedDelegate);

            if (err != PortAudio.PaError.paNoError)
            {
                throw new Exception(PortAudio.Pa_GetErrorText(err));
            }

            StreamState = StreamState.Open;
        }
 public HostInfo(PortAudio.PaHostApiInfo val)
 {
     value = val;
 }
 public DeviceInfo(PortAudio.PaDeviceInfo val)
 {
     value = val;
 }
Exemple #11
0
 private void labelASIO_Click(object sender, EventArgs e)
 {
     PortAudio.PaAsio_ShowControlPanel(InputDeviceID, this.Handle);
 }
Exemple #12
0
        PortAudio.PaStreamCallbackResult RealtimeCallback(IntPtr inputBuffer, IntPtr outputBuffer, uint framesPerBuffer, ref PortAudio.PaStreamCallbackTimeInfo timeInfo, PortAudio.PaStreamCallbackFlags statusFlags, IntPtr userData)
        {
            if(UseDirectProcessing)
            {
                var ins = (float**)inputBuffer;
                var outs = (float**)outputBuffer;
                ProcessDirect(ins, outs, (int)framesPerBuffer);
                return PortAudio.PaStreamCallbackResult.paContinue;
            }

            float[][] Inputs = new float[NumberOfInputs][];
            float[][] Outputs = new float[NumberOfOutputs][];

            // create input channels and copy data into them
            for (int i = 0; i < NumberOfInputs; i++)
            {
                float* inChannel = (float*)((float**)inputBuffer)[i];
                float[] inArr = new float[framesPerBuffer];
                Marshal.Copy((IntPtr)inChannel, inArr, 0, (int)framesPerBuffer);

                Inputs[i] = inArr;
            }

            // create empty output array
            for (int i = 0; i < NumberOfOutputs; i++)
            {
                float[] outArr = new float[framesPerBuffer];
                Outputs[i] = outArr;
            }

            // Call the process function
            Process(Inputs, Outputs);

            // Copy data back from managed array into native array
            for (int i = 0; i < NumberOfOutputs; i++)
            {
                float* outChannel = (float*)((float**)outputBuffer)[i];
                float[] outArr = Outputs[i];
                Marshal.Copy(outArr, 0, (IntPtr)outChannel, (int)framesPerBuffer);
            }

            return PortAudio.PaStreamCallbackResult.paContinue;
        }
Exemple #13
0
        public static RealtimeHostConfig CreateConfig(RealtimeHostConfig config = null)
        {
            if (!PortAudio.Pa_IsInitialized)
            {
                PortAudio.Pa_Initialize();
            }

            Application.EnableVisualStyles();
            var editor = new RealtimeHostConfigEditor();

            if (config != null)
            {
                var apiName = config.APIName;

                var devices            = GetSelectedDevices(apiName, config.InputDeviceID, config.OutputDeviceID, config.InputDeviceName, config.OutputDeviceName);
                var realInputDeviceId  = devices.Item1;
                var realOutputDeviceId = devices.Item2;

                var inDevice  = PortAudio.Pa_GetDeviceInfo(realInputDeviceId);
                var outDevice = PortAudio.Pa_GetDeviceInfo(realOutputDeviceId);

                var numInputs = (config.NumberOfInputs < inDevice.maxInputChannels)
                                        ? config.NumberOfInputs
                                        : inDevice.maxInputChannels;

                var numOutputs = (config.NumberOfOutputs < inDevice.maxOutputChannels)
                                        ? config.NumberOfOutputs
                                        : outDevice.maxOutputChannels;

                editor.InputDeviceID  = realInputDeviceId;
                editor.OutputDeviceID = realOutputDeviceId;
                editor.Samplerate     = config.Samplerate;
                editor.Latency        = (int)(config.InputLatencyMs * config.Samplerate);
                editor.InputChannels  = numInputs;
                editor.OutputChannels = numOutputs;
            }

            editor.ShowDialog();

            if (editor.OK == false)
            {
                return(null);
            }
            else
            {
                var conf = new RealtimeHostConfig();
                conf.InputDeviceID   = editor.InputDeviceID;
                conf.OutputDeviceID  = editor.OutputDeviceID;
                conf.NumberOfInputs  = editor.InputChannels;
                conf.NumberOfOutputs = editor.OutputChannels;
                conf.Samplerate      = editor.Samplerate;
                conf.InputLatencyMs  = editor.Latency / (double)editor.Samplerate;
                conf.OutputLatencyMs = editor.Latency / (double)editor.Samplerate;

                var supported = PortAudio.Pa_IsFormatSupported(ref conf.inputParameters, ref conf.outputParameters, conf.Samplerate);
                if (supported == PortAudio.PaError.paInvalidSampleRate)
                {
                    throw new InvalidFormatException("The samplerate you have selected is not supported by the device");
                }
                if (supported == PortAudio.PaError.paInvalidChannelCount)
                {
                    throw new InvalidFormatException("The number of inputs or outputs you have selected is not supported by the device");
                }
                if (supported != PortAudio.PaError.paNoError)
                {
                    throw new InvalidFormatException("The configuration you have selected is not supported by the device");
                }

                return(conf);
            }
        }
Exemple #14
0
 private void Dispose(bool isDisposing)
 {
     PortAudio.Pa_Terminate();
 }