add a function to dynamically select which i/o channels we're interested in at each callback
Sometimes when using a multichannel stream we only need to input or output to a subset of channels. This subset may change over the life of the stream, so current host api -specific mechanisms that select the channel subset when the stream is opened are insufficient for this use case.
The current way to do handle this in PortAudio is to ignore input channels we don't care about, and to write zeros to output channels at every callback. For multi-channel streams this can be very inefficient since PA currently needs to convert the sample formats for all i/o channels, even if only a few are being used and the rest are silence.
A solution would be to two functions:
Pa_SetStreamInputChannelMask( int *mask, int channelCount );
Pa_SetStreamOutputChannelMask( int *mask, int channelCount );
mask is an array of ints. where 0 means that PA will ignore/zero user buffer values for the corresponding channel and 1 means use current behavior (pass audio through). These functions could be called once after the stream is opened, or inside all or some callbacks for cases where the subset of active channels may change dynamically.
This would allow the buffer processor to ignore some channels. Masked host channels could be zeroed (using memset or some efficient function) rather than performing the full sample conversion path.
A further optimisation with some host APIs where the buffers are persistent (eg MME, DSound, ASIO, ...?) is to only zero the buffers once. Once the host API knows that all buffer space for a masked channel is zero, it no longer has to zero that space again.
The current way to do handle this in PortAudio is to ignore input channels we don't care about, and to write zeros to output channels at every callback. For multi-channel streams this can be very inefficient since PA currently needs to convert the sample formats for all i/o channels, even if only a few are being used and the rest are silence.
A solution would be to two functions:
Pa_SetStreamInputChannelMask( int *mask, int channelCount );
Pa_SetStreamOutputChannelMask( int *mask, int channelCount );
mask is an array of ints. where 0 means that PA will ignore/zero user buffer values for the corresponding channel and 1 means use current behavior (pass audio through). These functions could be called once after the stream is opened, or inside all or some callbacks for cases where the subset of active channels may change dynamically.
This would allow the buffer processor to ignore some channels. Masked host channels could be zeroed (using memset or some efficient function) rather than performing the full sample conversion path.
A further optimisation with some host APIs where the buffers are persistent (eg MME, DSound, ASIO, ...?) is to only zero the buffers once. Once the host API knows that all buffer space for a masked channel is zero, it no longer has to zero that space again.
Leave a comment