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)); }
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); } }
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; }
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); } }
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); } }