'I'm Trying to open a stream in PortAudio
i'm using this api: Pa_OpenStream()
// Open line-in stream
err = Pa_OpenStream(&m_stream,
&m_inputParameters,
&m_outputParameters,
44100, // sample rate
128, // frames per buffer
0, // paClipOff
OmniLineInCallback,
NULL);
and i'm getting err = -9993, i.e. paBadIODeviceCombination.
I configured both input and output device and i want to record from the input and transmit to the output playback device.
i don't know why i'm getting this err?!
Appreciate your help, Aviel
Solution 1:[1]
Make sure you pass correct parameters to the method. For that you may to do the following.
- Initialize PortAudio via
Pa_Initialize()
Check what audio devices are actually available for you through PortAudio. Use
Pa_GetDeviceCount()
and thenPa_GetDeviceInfo()
for each available device. Look how many inputs and outputs are actually available for each device, and don't pass a quantity greater than it supports.Fill the corresponding fields of the
PaStreamParameters
struct with the correct values.
This is how I open my ASIO/CoreAudio device (I also use Qt framework, but this does not affect the meaning of the example).
How I init the library and find the device I need:
int MyClass::initSoundInterfaces()
{
int result = -1; // target ASIO/CoreAudio device index
PaError err = Pa_Initialize();
const PaDeviceInfo* deviceInfo;
int numDevices = Pa_GetDeviceCount();
for( int DevIndex=0; DevIndex<numDevices; DevIndex++ )
{
deviceInfo = Pa_GetDeviceInfo( DevIndex );
QString str = Pa_GetHostApiInfo(deviceInfo->hostApi)->name;
qDebug() << "DEV: ApiInfo: " << str;
qDebug() << "defaultSampleRate = " << deviceInfo->defaultSampleRate;
qDebug() << "maxInputChannels = " << deviceInfo->maxInputChannels;
qDebug() << "maxOutputChannels = " << deviceInfo->maxOutputChannels;
QRegExp reg_exp(".*(ASIO|Core.*Audio).*", Qt::CaseInsensitive);
if( str.contains(reg_exp) )
{
if(deviceInfo->maxInputChannels > 0
&& deviceInfo->maxOutputChannels > 1)
{
result = DevIndex;
break;
}
}
}
return result;
}
Then I pass the given device index to the following method to open and start a stream:
bool MyClass::startAudio(int DevIndex)
{
PaError err = paNoError;
PaStreamParameters in_param;
in_param.device = DevIndex;
g_ChannelCount = min(Pa_GetDeviceInfo(DevIndex)->maxInputChannels,
MAX_INPUT_COUNT);
in_param.channelCount = g_ChannelCount;
in_param.hostApiSpecificStreamInfo = NULL;
in_param.sampleFormat = paFloat32 | paNonInterleaved;
in_param.suggestedLatency = 0;
// Pa_GetDeviceInfo(DevIndex)->defaultLowInputLatency;
PaStreamParameters out_param;
out_param.device = DevIndex;
out_param.channelCount = 2; // I do not need more than 2 output channels
out_param.hostApiSpecificStreamInfo = NULL;
out_param.sampleFormat = paFloat32 | paNonInterleaved; // Not all devices support 32 bits
out_param.suggestedLatency = 0;
// Pa_GetDeviceInfo(DevIndex)->defaultLowOutputLatency;
if(err == paNoError)
{
err = Pa_OpenStream(&stream,
&in_param,
&out_param,
nSampleRate,
cBufferSize/*paFramesPerBufferUnspecified*/,
paNoFlag,
process,
0);
}
err = Pa_StartStream(stream);
...
}
Solution 2:[2]
OK, when call Pa_GetDeviceCount() i get many available devices. currently i have the onborad sound card and a usb sound card. (each of them have input and output devices) when i configure input and output of the OnBoard sound card it works fine. but when i configure input of the usb card and output of the onboard card it returns err = paInvalidDevice.
also i saw that each card has several devices that differs in hostApi (paInDevelopment=0, paDirectSound=1, paMME=2)
what is the diffeence between them? and which device should i choose? it's ok to mix between them, i.e. choose input device that have "paDirectSound" and output that have "paInDevelopment"?
another thing that i paid attention to is the sample rate and number of channels, is it ok to have input with sample rate of 44100 and output of 48000?
and one last thing: you confiugured the variables: nSampleRate nBufferSize according to what?
thanks, aviel.
Solution 3:[3]
it is because the host api type of input device and output device are not same. For example:
import sounddevice as sd
sd.query_devices()
will get the available devices:
> 1 ADAT (7+8) (RME Fireface UC), MME (2 in, 0 out)
2 SPDIF/ADAT (1+2) (RME Fireface , MME (2 in, 0 out)
3 Analog (1+2) (RME Fireface UC), MME (2 in, 0 out)
...
14 ??? (RME Fireface UC), MME (0 in, 8 out)
...
44 ASIO Fireface USB, ASIO (18 in, 18 out)
where I have delete the unconcerned devices. here we can see: device 3 is an input device with host api MME, device 14 is an output device with host api MME, device 44 is an io device with host api ASIO.
Now if you want call the sounddevice.playrec() method, you must make sure the io devices you choose has the same kind of api, for example:
import sounddevice as sd
sd.playrec(data, device=(3, 14)) # OK
sd.playrec(data, device=(44, 44)) # OK
sd.playrec(data, device=(3, 44)) # bad
sd.playrec(data, device=(44, 14)) # bad
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | aos |
Solution 3 | bactone li |