I am trying to stream all 8 input channels from my Audio interface using PortAudio.
I have discovered the available hosts/devices, and every host reports 1 input device for my audio interface, and that device is reported to have 8 channels.
However, the device name is always "Analogue 1 + 2" which sounds like it's only 2 of the 8 channels, and when I open the 8 channel input stream, only the first 2 channels are populated, and specifically populated by the interface's analog channels 1 & 2, matching the device name.
Here is a list of input devices reported by PortAudio:
INPUT DEVICES:
- Host API: MME
--- Total device count: 9
----- Input device: Microsoft Sound Mapper - Input ... num channels: 2
----- Input device: Headset Microphone (Wireless Co ... num channels: 1
----- Input device: Microphone (BRIO 4K Stream Edit ... num channels: 2
----- Input device: Analogue 1 + 2 (Focusrite USB A ... num channels: 8
- Host API: Windows DirectSound
--- Total device count: 9
----- Input device: Primary Sound Capture Driver ... num channels: 2
----- Input device: Headset Microphone (Wireless Controller) ... num channels: 1
----- Input device: Microphone (BRIO 4K Stream Edition) ... num channels: 2
----- Input device: Analogue 1 + 2 (Focusrite USB Audio) ... num channels: 8
- Host API: Windows WASAPI
--- Total device count: 7
----- Input device: Microphone (BRIO 4K Stream Edition) ... num channels: 2
----- Input device: Headset Microphone (Wireless Controller) ... num channels: 1
----- Input device: Analogue 1 + 2 (Focusrite USB Audio) ... num channels: 2
- Host API: Windows WDM-KS
--- Total device count: 19
----- Input device: Microphone (BRIO 4K Stream Edition) ... num channels: 2
----- Input device: Analogue 1 + 2 (wc4800_8214) ... num channels: 8
----- Input device: Line (Realtek USB2.0 Audio) ... num channels: 2
----- Input device: Headset Microphone (Realtek USB2.0 Audio) ... num channels: 2
----- Input device: Desktop Microphone (Realtek USB2.0 Audio) ... num channels: 2
Here is the code I'm using to initialise the streams:
void AudioInterface::_init_audio_stream()
{
_stream_input_parameters = std::make_shared<PaStreamParameters>();
_stream_output_parameters = std::make_shared<PaStreamParameters>();
_stream_input_parameters->device = _current_input_device_index;
_stream_output_parameters->device = _current_output_device_index;
_stream_input_parameters->channelCount = _current_input_device_info.maxInputChannels;
_stream_output_parameters->channelCount = 2;
_stream_input_parameters->sampleFormat = paFloat32;
_stream_output_parameters->sampleFormat = paFloat32;
_stream_input_parameters->suggestedLatency = 0.0333;
_stream_output_parameters->suggestedLatency = 0.0333;
auto error = Pa_OpenStream(
&_stream,
_stream_input_parameters.get(),
_stream_output_parameters.get(),
SAMPLE_RATE,
IN_OUT_BUFFER_SIZE,
paNoFlag,paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags`
_audio_out_callback_wrapper,
&_callback_data );
}
EDIT: I've also just added the following check, to which success is reported:
Pa_GetErrorText(Pa_IsFormatSupported(_stream_input_parameters.get(), _stream_output_parameters.get(), SAMPLE_RATE))
I'm setting up the stream interleaved right now (going to change that once I have things working), and as such here is the code grabbing the input from the callback:
int AudioInterface::_audio_out_callback_wrapper(const void* input_buffer, void* output_buffer, unsigned long frames_per_buffer,
const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags status_flags,
void* user_data_from_previous_frame)
{
return _singleton->_audio_out_callback(static_cast<const float*>(input_buffer),
static_cast<SampleFrameStereo*>(output_buffer),
frames_per_buffer,
timeInfo,
status_flags,
static_cast<PersistentStreamCallbackData*>(user_data_from_previous_frame));
}
int AudioInterface::_audio_out_callback(const float* input_buffer, SampleFrameStereo* output_buffer, unsigned long frames_per_buffer,
const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags status_flags,
PersistentStreamCallbackData* persistent_stream_callback_data)
{
_handle_input_sample_frames_buffer(input_buffer, output_buffer, frames_per_buffer);
_handle_output_sample_frames_buffer(output_buffer, frames_per_buffer);
_clear_output_sample_frames_buffer();
return 0;
}
void AudioInterface::_handle_input_sample_frames_buffer(const float* input_buffer,
SampleFrameStereo* output_buffer,
unsigned long frames_per_buffer)
{
const int num_input_channels = _current_input_device_info.maxInputChannels;
for (int chan_i = 0; chan_i < num_input_channels; chan_i++)
{
for (int frame_i = 0; frame_i < frames_per_buffer; frame_i++)
{
const size_t input_buffer_index = frame_i * num_input_channels + chan_i;
const float input_sample = input_buffer[input_buffer_index];
_state->input_channel_buffers[chan_i][frame_i] = input_sample;
}
}
}
I'm not really sure what to try from here. I've compared the general device list to the individual host API device lists, and as you'd expect they match up. I can see all 8 channels in both Focusrite Control app and coming through in FL Studio, but I definitely only get channels 1 and 2 (Analogue 1 + 2 as the device even calls it) coming through to my code.