backup checkin, WIP

This commit is contained in:
Volker Fischer 2020-05-02 17:15:18 +02:00
parent 02dfb101f1
commit 70a78fa426
2 changed files with 177 additions and 83 deletions

View file

@ -264,40 +264,49 @@ int CSound::CountChannels ( AudioDeviceID devID,
UInt32 propSize; UInt32 propSize;
int result = 0; int result = 0;
// check for the case the we have interleaved format, in that case we assume if ( isInput )
// that only the very first buffer contains all our channels
if ( iNumChanPerFrame > 1 )
{ {
result = iNumChanPerFrame; vecNumInBufChan.Init ( 0 );
} }
else else
{ {
// it seems we have multiple buffers where each buffer has only one channel, vecNumOutBufChan.Init ( 0 );
// in that case we assume that each input channel has its own buffer }
AudioObjectPropertyScope theScope = isInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyStreamConfiguration, // it seems we have multiple buffers where each buffer has only one channel,
theScope, // in that case we assume that each input channel has its own buffer
0 }; AudioObjectPropertyScope theScope = isInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
AudioObjectGetPropertyDataSize ( devID, &theAddress, 0, NULL, &propSize ); AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyStreamConfiguration,
theScope,
0 };
AudioBufferList *buflist = (AudioBufferList*) malloc ( propSize ); AudioObjectGetPropertyDataSize ( devID, &theAddress, 0, NULL, &propSize );
err = AudioObjectGetPropertyData ( devID, &theAddress, 0, NULL, &propSize, buflist ); AudioBufferList *buflist = (AudioBufferList*) malloc ( propSize );
if ( !err ) err = AudioObjectGetPropertyData ( devID, &theAddress, 0, NULL, &propSize, buflist );
if ( !err )
{
for ( UInt32 i = 0; i < buflist->mNumberBuffers; ++i )
{ {
for ( UInt32 i = 0; i < buflist->mNumberBuffers; ++i ) // The correct value mNumberChannels for an AudioBuffer can be derived from the mChannelsPerFrame
// and the interleaved flag. For non interleaved formats, mNumberChannels is always 1.
// For interleaved formats, mNumberChannels is equal to mChannelsPerFrame.
result += buflist->mBuffers[i].mNumberChannels;
if ( isInput )
{ {
// The correct value mNumberChannels for an AudioBuffer can be derived from the mChannelsPerFrame vecNumInBufChan.Add ( buflist->mBuffers[i].mNumberChannels );
// and the interleaved flag. For non interleaved formats, mNumberChannels is always 1. }
// For interleaved formats, mNumberChannels is equal to mChannelsPerFrame. else
result += buflist->mBuffers[i].mNumberChannels; {
vecNumOutBufChan.Add ( buflist->mBuffers[i].mNumberChannels );
} }
} }
free ( buflist );
} }
free ( buflist );
return result; return result;
} }
@ -317,10 +326,10 @@ QString CSound::LoadAndInitializeDriver ( int iDriverIdx, bool )
// the device has changed, per definition we reset the channel // the device has changed, per definition we reset the channel
// mapping to the defaults (first two available channels) // mapping to the defaults (first two available channels)
iSelInputLeftChannel = 0; SetLeftInputChannel ( 0 );
iSelInputRightChannel = min ( iNumInChan - 1, 1 ); SetRightInputChannel ( 1 );
iSelOutputLeftChannel = 0; SetLeftOutputChannel ( 0 );
iSelOutputRightChannel = min ( iNumOutChan - 1, 1 ); SetRightOutputChannel ( 1 );
} }
return strStat; return strStat;
@ -599,12 +608,85 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )
return ""; return "";
} }
void CSound::UpdateChSelection()
{
// calculate the selected input/output buffer and the selected interleaved
// channel index in the buffer, note that each buffer can have a different
// number of interleaved channels
int iChCnt;
int iSelCHLeft, iSelAddCHLeft;
int iSelCHRight, iSelAddCHRight;
iSelAddInBufferLeft = -1; // initialize with invalid value
iSelAddInInterlChLeft = -1; // initialize with invalid value
iSelAddInBufferRight = -1; // initialize with invalid value
iSelAddInInterlChRight = -1; // initialize with invalid value
// input
GetSelCHAndAddCH ( iSelInputLeftChannel, iNumInChan, iSelCHLeft, iSelAddCHLeft );
GetSelCHAndAddCH ( iSelInputRightChannel, iNumInChan, iSelCHRight, iSelAddCHRight );
iChCnt = 0;
for ( int iBuf = 0; iBuf < vecNumInBufChan.Size(); iBuf++ )
{
iChCnt += vecNumInBufChan[iBuf];
if ( iChCnt > iSelCHLeft )
{
iSelInBufferLeft = iBuf;
iSelInInterlChLeft = iSelCHLeft - iChCnt + vecNumInBufChan[iBuf];
}
if ( iChCnt > iSelCHRight )
{
iSelInBufferRight = iBuf;
iSelInInterlChRight = iSelCHRight - iChCnt + vecNumInBufChan[iBuf];
}
if ( ( iSelAddCHLeft >= 0 ) && ( iChCnt > iSelAddCHLeft ) )
{
iSelAddInBufferLeft = iBuf;
iSelAddInInterlChLeft = iSelAddCHLeft - iChCnt + vecNumInBufChan[iBuf];
}
if ( ( iSelAddCHRight >= 0 ) && ( iChCnt > iSelAddCHRight ) )
{
iSelAddInBufferRight = iBuf;
iSelAddInInterlChRight = iSelAddCHRight - iChCnt + vecNumInBufChan[iBuf];
}
}
// output
GetSelCHAndAddCH ( iSelOutputLeftChannel, iNumOutChan, iSelCHLeft, iSelAddCHLeft );
GetSelCHAndAddCH ( iSelOutputRightChannel, iNumOutChan, iSelCHRight, iSelAddCHRight );
iChCnt = 0;
for ( int iBuf = 0; iBuf < vecNumOutBufChan.Size(); iBuf++ )
{
iChCnt += vecNumOutBufChan[iBuf];
if ( iChCnt > iSelCHLeft )
{
iSelOutBufferLeft = iBuf;
iSelOutInterlChLeft = iSelCHLeft - iChCnt + vecNumOutBufChan[iBuf];
}
if ( iChCnt > iSelCHRight )
{
iSelOutBufferRight = iBuf;
iSelOutInterlChRight = iSelCHRight - iChCnt + vecNumOutBufChan[iBuf];
}
}
}
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 < iNumInChanPlusAddChan ) ) if ( ( iNewChan >= 0 ) && ( iNewChan < iNumInChanPlusAddChan ) )
{ {
iSelInputLeftChannel = iNewChan; iSelInputLeftChannel = iNewChan;
UpdateChSelection();
} }
} }
@ -614,6 +696,7 @@ void CSound::SetRightInputChannel ( const int iNewChan )
if ( ( iNewChan >= 0 ) && ( iNewChan < iNumInChanPlusAddChan ) ) if ( ( iNewChan >= 0 ) && ( iNewChan < iNumInChanPlusAddChan ) )
{ {
iSelInputRightChannel = iNewChan; iSelInputRightChannel = iNewChan;
UpdateChSelection();
} }
} }
@ -623,6 +706,7 @@ void CSound::SetLeftOutputChannel ( const int iNewChan )
if ( ( iNewChan >= 0 ) && ( iNewChan < iNumOutChan ) ) if ( ( iNewChan >= 0 ) && ( iNewChan < iNumOutChan ) )
{ {
iSelOutputLeftChannel = iNewChan; iSelOutputLeftChannel = iNewChan;
UpdateChSelection();
} }
} }
@ -632,6 +716,7 @@ void CSound::SetRightOutputChannel ( const int iNewChan )
if ( ( iNewChan >= 0 ) && ( iNewChan < iNumOutChan ) ) if ( ( iNewChan >= 0 ) && ( iNewChan < iNumOutChan ) )
{ {
iSelOutputRightChannel = iNewChan; iSelOutputRightChannel = iNewChan;
UpdateChSelection();
} }
} }
@ -854,90 +939,62 @@ OSStatus CSound::callbackIO ( AudioDeviceID inDevice,
const int iCoreAudioBufferSizeMono = pSound->iCoreAudioBufferSizeMono; const int iCoreAudioBufferSizeMono = pSound->iCoreAudioBufferSizeMono;
const int iNumInChan = pSound->iNumInChan; const int iNumInChan = pSound->iNumInChan;
const int iNumOutChan = pSound->iNumOutChan; const int iNumOutChan = pSound->iNumOutChan;
const int iSelInputLeftChannel = pSound->iSelInputLeftChannel; const int iSelInBufferLeft = pSound->iSelInBufferLeft;
const int iSelInputRightChannel = pSound->iSelInputRightChannel; const int iSelInBufferRight = pSound->iSelInBufferRight;
const int iSelOutputLeftChannel = pSound->iSelOutputLeftChannel; const int iSelInInterlChLeft = pSound->iSelInInterlChLeft;
const int iSelOutputRightChannel = pSound->iSelOutputRightChannel; const int iSelInInterlChRight = pSound->iSelInInterlChRight;
const int iSelAddInBufferLeft = pSound->iSelAddInBufferLeft;
const int iSelAddInBufferRight = pSound->iSelAddInBufferRight;
const int iSelAddInInterlChLeft = pSound->iSelAddInInterlChLeft;
const int iSelAddInInterlChRight = pSound->iSelAddInInterlChRight;
const int iSelOutBufferLeft = pSound->iSelOutBufferLeft;
const int iSelOutBufferRight = pSound->iSelOutBufferRight;
const int iSelOutInterlChLeft = pSound->iSelOutInterlChLeft;
const int iSelOutInterlChRight = pSound->iSelOutInterlChRight;
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 == // TODO check...
static_cast<UInt32> ( iCoreAudioBufferSizeMono * iNumInChan * 4 ) ) if ( inInputData->mBuffers[iSelInBufferLeft].mDataByteSize == ...
inInputData->mBuffers[0].mDataByteSize * inInputData->mNumberBuffers ==
(UInt32) iNumInChan * static_cast<UInt32> ( iCoreAudioBufferSizeMono * 4 ) )
{ {
// one buffer with all the channels in interleaved format: Float32* pLeftData = static_cast<Float32*> ( inInputData->mBuffers[iSelInBufferLeft].mData );
// get a pointer to the input data of the correct type Float32* pRightData = static_cast<Float32*> ( inInputData->mBuffers[iSelInBufferRight].mData );
Float32* pInData = static_cast<Float32*> ( inInputData->mBuffers[0].mData ); int iNumChanPerFrameLeft = pSound->vecNumInBufChan[iSelInBufferLeft];
int iNumChanPerFrameRight = pSound->vecNumInBufChan[iSelInBufferRight];
// copy input data // copy input data
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{ {
// copy left and right channels separately // copy left and right channels separately
pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pInData[iNumInChan * i + iSelCHLeft] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pLeftData[iNumChanPerFrameLeft * i + iSelInInterlChLeft] * _MAXSHORT );
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( pInData[iNumInChan * i + iSelCHRight] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( pRightData[iNumChanPerFrameRight * i + iSelInInterlChRight] * _MAXSHORT );
} }
// add an additional optional channel // add an additional optional channel
if ( iSelAddCHLeft >= 0 ) if ( iSelAddInBufferLeft >= 0 )
{ {
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) pLeftData = static_cast<Float32*> ( inInputData->mBuffers[iSelAddInBufferLeft].mData );
{ iNumChanPerFrameLeft = pSound->vecNumInBufChan[iSelAddInBufferLeft];
pSound->vecsTmpAudioSndCrdStereo[2 * i] = Double2Short (
pSound->vecsTmpAudioSndCrdStereo[2 * i] + pInData[iNumInChan * i + iSelAddCHLeft] * _MAXSHORT );
}
}
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
inInputData->mBuffers[0].mDataByteSize == static_cast<UInt32> ( iCoreAudioBufferSizeMono * 4 ) )
{
// one buffer per channel mode:
Float32* pLeftData = static_cast<Float32*> ( inInputData->mBuffers[iSelCHLeft].mData );
Float32* pRightData = static_cast<Float32*> ( inInputData->mBuffers[iSelCHRight].mData );
// copy input data
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{
// copy left and right channels separately
pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pLeftData[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++ ) for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{ {
pSound->vecsTmpAudioSndCrdStereo[2 * i] = Double2Short ( pSound->vecsTmpAudioSndCrdStereo[2 * i] = Double2Short (
pSound->vecsTmpAudioSndCrdStereo[2 * i] + pLeftData[i] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i] + pLeftData[iNumChanPerFrameLeft * i + iSelAddInInterlChLeft] * _MAXSHORT );
} }
} }
if ( iSelAddCHRight >= 0 ) if ( iSelAddInBufferRight >= 0 )
{ {
pRightData = static_cast<Float32*> ( inInputData->mBuffers[iSelAddCHRight].mData ); pRightData = static_cast<Float32*> ( inInputData->mBuffers[iSelAddInBufferRight].mData );
iNumChanPerFrameRight = pSound->vecNumInBufChan[iSelAddInBufferRight];
for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
{ {
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = Double2Short ( pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = Double2Short (
pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] + pRightData[i] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] + pRightData[iNumChanPerFrameRight * i + iSelAddInInterlChRight] * _MAXSHORT );
} }
} }
} }
@ -954,6 +1011,27 @@ OSStatus CSound::callbackIO ( AudioDeviceID inDevice,
if ( ( inDevice == pSound->CurrentAudioOutputDeviceID ) && outOutputData ) if ( ( inDevice == pSound->CurrentAudioOutputDeviceID ) && outOutputData )
{ {
// check size (float32 has four bytes) // check size (float32 has four bytes)
// if ( outOutputData->mBuffers[0].mDataByteSize * outOutputData->mNumberBuffers ==
// (UInt32) iNumOutChan * static_cast<UInt32> ( iCoreAudioBufferSizeMono * 4 ) )
// {
// const int iNumChanPerFrame = iNumOutChan / outOutputData->mNumberBuffers;
// const int iSelBufferLeft = iSelOutputLeftChannel / iNumChanPerFrame;
// const int iSelBufferRight = iSelOutputRightChannel / iNumChanPerFrame;
// const int iSelInterlChLeft = iSelOutputLeftChannel % iNumChanPerFrame;
// const int iSelInterlChRight = iSelOutputRightChannel % iNumChanPerFrame;
//
// Float32* pLeftData = static_cast<Float32*> ( outOutputData->mBuffers[iSelBufferLeft].mData );
// Float32* pRightData = static_cast<Float32*> ( outOutputData->mBuffers[iSelBufferRight].mData );
//
// // copy output data
// for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ )
// {
// // copy left and right channels separately
// pLeftData[iNumChanPerFrame * i + iSelInterlChLeft] = (Float32) pSound->vecsTmpAudioSndCrdStereo[2 * i] / _MAXSHORT;
// pRightData[iNumChanPerFrame * i + iSelInterlChRight] = (Float32) pSound->vecsTmpAudioSndCrdStereo[2 * i] / _MAXSHORT;
// }
// }
// else
if ( outOutputData->mBuffers[0].mDataByteSize == if ( outOutputData->mBuffers[0].mDataByteSize ==
static_cast<UInt32> ( iCoreAudioBufferSizeMono * iNumOutChan * 4 ) ) static_cast<UInt32> ( iCoreAudioBufferSizeMono * iNumOutChan * 4 ) )
{ {

View file

@ -75,11 +75,27 @@ public:
int iSelInputRightChannel; int iSelInputRightChannel;
int iSelOutputLeftChannel; int iSelOutputLeftChannel;
int iSelOutputRightChannel; int iSelOutputRightChannel;
int iSelInBufferLeft;
int iSelInBufferRight;
int iSelInInterlChLeft;
int iSelInInterlChRight;
int iSelAddInBufferLeft;
int iSelAddInBufferRight;
int iSelAddInInterlChLeft;
int iSelAddInInterlChRight;
int iSelOutBufferLeft;
int iSelOutBufferRight;
int iSelOutInterlChLeft;
int iSelOutInterlChRight;
CVector<int> vecNumInBufChan;
CVector<int> vecNumOutBufChan;
protected: protected:
virtual QString LoadAndInitializeDriver ( int iIdx, bool ); virtual QString LoadAndInitializeDriver ( int iIdx, bool );
QString CheckDeviceCapabilities ( const int iDriverIdx ); QString CheckDeviceCapabilities ( const int iDriverIdx );
void UpdateChSelection();
int CountChannels ( AudioDeviceID devID, int CountChannels ( AudioDeviceID devID,
const int iNumChanPerFrame, const int iNumChanPerFrame,
bool isInput ); bool isInput );