@@ -50,7 +50,9 @@ CSound::CSound( void (*fpNewProcessCallback) ( CVector<short>& psData,
5050 const QString& ) :
5151 CSoundBase ( " portaudio" , fpNewProcessCallback, arg, strMIDISetup ),
5252 deviceIndex (-1 ),
53- deviceStream (NULL )
53+ deviceStream (NULL ),
54+ vSelectedInputChannels ( NUM_IN_OUT_CHANNELS ),
55+ vSelectedOutputChannels ( NUM_IN_OUT_CHANNELS )
5456{
5557 pThisSound = this ;
5658
@@ -136,7 +138,7 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
136138 iPrefMonoBufferSize = iNewPrefMonoBufferSize;
137139 }
138140
139- vecsAudioData.Init ( iPrefMonoBufferSize * 2 );
141+ vecsAudioData.Init ( iPrefMonoBufferSize * NUM_IN_OUT_CHANNELS );
140142 if ( deviceStream && deviceIndex >= 0 )
141143 {
142144 ReinitializeDriver ( deviceIndex );
@@ -165,6 +167,82 @@ PaDeviceIndex CSound::DeviceIndexFromName (const QString& strDriverName )
165167 return -1 ;
166168}
167169
170+ int CSound::GetNumInputChannels ()
171+ {
172+ if (deviceIndex >= 0 )
173+ {
174+ const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo ( deviceIndex );
175+ return deviceInfo->maxInputChannels ;
176+ }
177+ return CSoundBase::GetNumInputChannels ();
178+ }
179+ int CSound::GetNumOutputChannels ()
180+ {
181+ if (deviceIndex >= 0 )
182+ {
183+ const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo ( deviceIndex );
184+ return deviceInfo->maxOutputChannels ;
185+ }
186+ return CSoundBase::GetNumOutputChannels ();
187+ }
188+
189+ QString CSound::GetInputChannelName ( const int channel )
190+ {
191+ if (deviceIndex >= 0 )
192+ {
193+ const char * channelName;
194+ PaError err = PaAsio_GetInputChannelName ( deviceIndex, channel, &channelName );
195+ if ( err == paNoError )
196+ {
197+ return QString ( channelName );
198+ }
199+ }
200+ return CSoundBase::GetInputChannelName ( channel );
201+ }
202+ QString CSound::GetOutputChannelName ( const int channel )
203+ {
204+ if (deviceIndex >= 0 )
205+ {
206+ const char * channelName;
207+ PaError err = PaAsio_GetOutputChannelName ( deviceIndex, channel, &channelName );
208+ if ( err == paNoError )
209+ {
210+ return QString ( channelName );
211+ }
212+ }
213+ return CSoundBase::GetOutputChannelName ( channel );
214+ }
215+
216+ void CSound::SetLeftInputChannel ( const int channel )
217+ {
218+ if ( channel < GetNumInputChannels () )
219+ {
220+ vSelectedInputChannels[0 ] = channel;
221+ }
222+ }
223+ void CSound::SetRightInputChannel ( const int channel )
224+ {
225+ if ( channel < GetNumInputChannels () )
226+ {
227+ vSelectedInputChannels[1 ] = channel;
228+ }
229+ }
230+
231+ void CSound::SetLeftOutputChannel ( const int channel )
232+ {
233+ if ( channel < GetNumOutputChannels () )
234+ {
235+ vSelectedOutputChannels[0 ] = channel;
236+ }
237+ }
238+ void CSound::SetRightOutputChannel ( const int channel )
239+ {
240+ if ( channel < GetNumOutputChannels () )
241+ {
242+ vSelectedOutputChannels[1 ] = channel;
243+ }
244+ }
245+
168246QString CSound::LoadAndInitializeDriver ( QString strDriverName, bool bOpenDriverSetup )
169247{
170248 (void ) bOpenDriverSetup; // FIXME: respect this
@@ -181,10 +259,11 @@ QString CSound::ReinitializeDriver ( int devIndex )
181259{
182260 const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo ( devIndex );
183261
184- if ( deviceInfo->maxInputChannels < 2 || deviceInfo->maxOutputChannels < 2 )
262+ if ( deviceInfo->maxInputChannels < NUM_IN_OUT_CHANNELS ||
263+ deviceInfo->maxOutputChannels < NUM_IN_OUT_CHANNELS )
185264 {
186265 // FIXME: handle mono devices.
187- return tr ( " Less than 2 channels supported" );
266+ return tr ( " Less than 2 channels not supported" );
188267 }
189268
190269 if ( deviceStream != NULL )
@@ -195,18 +274,30 @@ QString CSound::ReinitializeDriver ( int devIndex )
195274 }
196275
197276 PaStreamParameters paInputParams;
277+ PaAsioStreamInfo asioInputInfo;
198278 paInputParams.device = devIndex;
199- paInputParams.channelCount = std::min (2 , deviceInfo->maxInputChannels );
279+ paInputParams.channelCount = std::min (NUM_IN_OUT_CHANNELS , deviceInfo->maxInputChannels );
200280 paInputParams.sampleFormat = paInt16;
201281 paInputParams.suggestedLatency = deviceInfo->defaultLowInputLatency ;
202- paInputParams.hostApiSpecificStreamInfo = NULL ;
282+ paInputParams.hostApiSpecificStreamInfo = &asioInputInfo;
283+ asioInputInfo.size = sizeof asioInputInfo;
284+ asioInputInfo.hostApiType = paASIO;
285+ asioInputInfo.version = 1 ;
286+ asioInputInfo.flags = paAsioUseChannelSelectors;
287+ asioInputInfo.channelSelectors = &vSelectedInputChannels[0 ];
203288
204289 PaStreamParameters paOutputParams;
290+ PaAsioStreamInfo asioOutputInfo;
205291 paOutputParams.device = devIndex;
206- paOutputParams.channelCount = std::min (2 , deviceInfo->maxOutputChannels );
292+ paOutputParams.channelCount = std::min (NUM_IN_OUT_CHANNELS , deviceInfo->maxOutputChannels );
207293 paOutputParams.sampleFormat = paInt16;
208294 paOutputParams.suggestedLatency = deviceInfo->defaultLowOutputLatency ;
209- paOutputParams.hostApiSpecificStreamInfo = NULL ;
295+ paOutputParams.hostApiSpecificStreamInfo = &asioOutputInfo;
296+ asioOutputInfo.size = sizeof asioOutputInfo;
297+ asioOutputInfo.hostApiType = paASIO;
298+ asioOutputInfo.version = 1 ;
299+ asioOutputInfo.flags = paAsioUseChannelSelectors;
300+ asioOutputInfo.channelSelectors = &vSelectedOutputChannels[0 ];
210301
211302 PaError err = Pa_OpenStream ( &deviceStream,
212303 &paInputParams,
@@ -224,6 +315,8 @@ QString CSound::ReinitializeDriver ( int devIndex )
224315 ( Pa_GetLastHostErrorInfo () ->errorText );
225316 }
226317
318+ strCurDevName = deviceInfo->name ;
319+
227320 deviceIndex = devIndex;
228321 return " " ;
229322}
@@ -249,12 +342,12 @@ int CSound::paStreamCallback(const void *input, void *output, unsigned long fram
249342 CVector<int16_t >& vecsAudioData = pSound->vecsAudioData ;
250343
251344 // CAPTURE ---------------------------------
252- memcpy (&vecsAudioData[0 ], input, sizeof (int16_t ) * frameCount * 2 );
345+ memcpy (&vecsAudioData[0 ], input, sizeof (int16_t ) * frameCount * NUM_IN_OUT_CHANNELS );
253346
254347 pSound->ProcessCallback ( vecsAudioData );
255348
256349 // PLAYBACK ------------------------------------------------------------
257- memcpy (output, &vecsAudioData[0 ], sizeof (int16_t ) * frameCount * 2 );
350+ memcpy (output, &vecsAudioData[0 ], sizeof (int16_t ) * frameCount * NUM_IN_OUT_CHANNELS );
258351
259352 return paContinue;
260353}
0 commit comments