support adding channels for 4 input case, same as in Windows (code not compiled and tested yet)

This commit is contained in:
Volker Fischer 2020-05-01 15:57:14 +02:00
parent 182ebac66a
commit 7cdba88fa0
2 changed files with 85 additions and 31 deletions

View file

@ -167,6 +167,7 @@ CSound::CSound ( void (*fpNewProcessCallback) ( CVector<short>& psData
CurrentAudioInputDeviceID = 0; CurrentAudioInputDeviceID = 0;
CurrentAudioOutputDeviceID = 0; CurrentAudioOutputDeviceID = 0;
iNumInChan = 0; iNumInChan = 0;
lNumInChanPlusAddChan = 0;
iNumOutChan = 0; iNumOutChan = 0;
iSelInputLeftChannel = 0; iSelInputLeftChannel = 0;
iSelInputRightChannel = 0; iSelInputRightChannel = 0;
@ -568,6 +569,32 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )
} }
} }
// special case with 4 input channels: support adding channels
if ( iNumInChan == 4 )
{
// add four mixed channels (i.e. 4 normal, 4 mixed channels)
iNumInChanPlusAddChan = 8;
for ( int iCh = 0; iCh < iNumInChanPlusAddChan; iCh++ )
{
int iSelCH, iSelAddCH;
GetSelCHAndAddCH ( iCh, iNumInChan, iSelCH, iSelAddCH );
if ( iSelAddCH >= 0 )
{
// for mixed channels, show both audio channel names to be mixed
sChannelNamesInput[iCh] =
sChannelNamesInput[iSelCH] + " + " + sChannelNamesInput[iSelAddCH];
}
}
}
else
{
// regular case: no mixing input channels used
iNumInChanPlusAddChan = iNumInChan;
}
// everything is ok, return empty string for "no error" case // everything is ok, return empty string for "no error" case
return ""; return "";
} }
@ -575,7 +602,7 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )
void CSound::SetLeftInputChannel ( const int iNewChan ) void CSound::SetLeftInputChannel ( const int iNewChan )
{ {
// apply parameter after input parameter check // apply parameter after input parameter check
if ( ( iNewChan >= 0 ) && ( iNewChan < iNumInChan ) ) if ( ( iNewChan >= 0 ) && ( iNewChan < lNumInChanPlusAddChan ) )
{ {
iSelInputLeftChannel = iNewChan; iSelInputLeftChannel = iNewChan;
} }
@ -584,7 +611,7 @@ void CSound::SetLeftInputChannel ( const int iNewChan )
void CSound::SetRightInputChannel ( const int iNewChan ) void CSound::SetRightInputChannel ( const int iNewChan )
{ {
// apply parameter after input parameter check // apply parameter after input parameter check
if ( ( iNewChan >= 0 ) && ( iNewChan < iNumInChan ) ) if ( ( iNewChan >= 0 ) && ( iNewChan < lNumInChanPlusAddChan ) )
{ {
iSelInputRightChannel = iNewChan; iSelInputRightChannel = iNewChan;
} }
@ -834,6 +861,13 @@ OSStatus CSound::callbackIO ( AudioDeviceID inDevice,
if ( ( inDevice == pSound->CurrentAudioInputDeviceID ) && inInputData ) if ( ( inDevice == pSound->CurrentAudioInputDeviceID ) && inInputData )
{ {
int iSelCHLeft, iSelAddCHLeft;
int iSelCHRight, iSelAddCHRight;
// get selected input channels plus optional additional channel
GetSelCHAndAddCH ( iSelInputLeftChannel, iNumInChan, iSelCHLeft, iSelAddCHLeft );
GetSelCHAndAddCH ( iSelInputRightChannel, iNumInChan, iSelCHRight, iSelAddCHRight );
// check size (float32 has four bytes) // check size (float32 has four bytes)
if ( inInputData->mBuffers[0].mDataByteSize == if ( inInputData->mBuffers[0].mDataByteSize ==
static_cast<UInt32> ( iCoreAudioBufferSizeMono * iNumInChan * 4 ) ) static_cast<UInt32> ( iCoreAudioBufferSizeMono * iNumInChan * 4 ) )
@ -845,48 +879,67 @@ OSStatus CSound::callbackIO ( AudioDeviceID inDevice,
// copy input data // copy input data
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{ {
// left // copy left and right channels separately
pSound->vecsTmpAudioSndCrdStereo[2 * i] = pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pInData[iNumInChan * i + iSelCHLeft] * _MAXSHORT );
(short) ( pInData[iNumInChan * i + iSelInputLeftChannel] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( pInData[iNumInChan * i + iSelCHRight] * _MAXSHORT );
}
// right // add an additional optional channel
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = if ( iSelAddCHLeft >= 0 )
(short) ( pInData[iNumInChan * i + iSelInputRightChannel] * _MAXSHORT ); {
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
/* {
// TEST mix channel with micro to the stereo output pSound->vecsTmpAudioSndCrdStereo[2 * i] = Double2Short (
if ( iNumInChan == 4 ) pSound->vecsTmpAudioSndCrdStereo[2 * i] + pInData[iNumInChan * i + iSelAddCHLeft] * _MAXSHORT );
{ }
// add mic input on input channel 4 to both stereo channels }
pSound->vecsTmpAudioSndCrdStereo[2 * i] =
Double2Short ( (double) ( pInData[iNumInChan * i + 3] * _MAXSHORT ) +
(double) pSound->vecsTmpAudioSndCrdStereo[2 * i] );
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] =
Double2Short ( (double) ( pInData[iNumInChan * i + 3] * _MAXSHORT ) +
(double) pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] );
}
*/
if ( iSelAddCHRight >= 0 )
{
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = Double2Short (
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] + pInData[iNumInChan * i + iSelAddCHRight] * _MAXSHORT );
}
} }
} }
else if ( inInputData->mNumberBuffers == (UInt32) iNumInChan && // we should have a matching number of buffers to channels else if ( inInputData->mNumberBuffers == (UInt32) iNumInChan && // we should have a matching number of buffers to channels
inInputData->mBuffers[0].mDataByteSize == static_cast<UInt32> ( iCoreAudioBufferSizeMono * 4 ) ) inInputData->mBuffers[0].mDataByteSize == static_cast<UInt32> ( iCoreAudioBufferSizeMono * 4 ) )
{ {
// one buffer per channel mode: // one buffer per channel mode:
AudioBuffer left = inInputData->mBuffers[iSelInputLeftChannel]; Float32* pLeftData = static_cast<Float32*> ( inInputData->mBuffers[iSelCHLeft].mData );
Float32* pLeftData = static_cast<Float32*> ( left.mData ); Float32* pRightData = static_cast<Float32*> ( inInputData->mBuffers[iSelCHRight].mData );
AudioBuffer right = inInputData->mBuffers[iSelInputRightChannel];
Float32* pRightData = static_cast<Float32*> ( right.mData );
// copy input data // copy input data
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{ {
// left // copy left and right channels separately
pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pLeftData[i] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pLeftData[i] * _MAXSHORT );
// right
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( pRightData[i] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( pRightData[i] * _MAXSHORT );
} }
// add an additional optional channel
if ( iSelAddCHLeft >= 0 )
{
pLeftData = static_cast<Float32*> ( inInputData->mBuffers[iSelAddCHLeft].mData );
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{
pSound->vecsTmpAudioSndCrdStereo[2 * i] = Double2Short (
pSound->vecsTmpAudioSndCrdStereo[2 * i] + pLeftData[i] * _MAXSHORT );
}
}
if ( iSelAddCHRight >= 0 )
{
pRightData = static_cast<Float32*> ( inInputData->mBuffers[iSelAddCHRight].mData );
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = Double2Short (
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] + pRightData[i] * _MAXSHORT );
}
}
} }
else else
{ {

View file

@ -47,7 +47,7 @@ public:
virtual void Stop(); virtual void Stop();
// channel selection // channel selection
virtual int GetNumInputChannels() { return iNumInChan; } virtual int GetNumInputChannels() { return iNumInChanPlusAddChan; }
virtual QString GetInputChannelName ( const int iDiD ) { return sChannelNamesInput[iDiD]; } virtual QString GetInputChannelName ( const int iDiD ) { return sChannelNamesInput[iDiD]; }
virtual void SetLeftInputChannel ( const int iNewChan ); virtual void SetLeftInputChannel ( const int iNewChan );
virtual void SetRightInputChannel ( const int iNewChan ); virtual void SetRightInputChannel ( const int iNewChan );
@ -69,6 +69,7 @@ public:
AudioDeviceID CurrentAudioInputDeviceID; AudioDeviceID CurrentAudioInputDeviceID;
AudioDeviceID CurrentAudioOutputDeviceID; AudioDeviceID CurrentAudioOutputDeviceID;
int iNumInChan; int iNumInChan;
int iNumInChanPlusAddChan; // includes additional "added" channels
int iNumOutChan; int iNumOutChan;
int iSelInputLeftChannel; int iSelInputLeftChannel;
int iSelInputRightChannel; int iSelInputRightChannel;