change the pan signal processing: avoid that pan=center attenuates any of the stereo channels; if no gain/pan change, do not multiply with the gains

This commit is contained in:
Volker Fischer 2020-05-19 20:38:14 +02:00
parent 546e3f96e0
commit 5705b798f8
2 changed files with 20 additions and 19 deletions

View file

@ -15,6 +15,7 @@
- support intermediate Reaper RPP file while recording, coded by pljones (Ticket #170) - support intermediate Reaper RPP file while recording, coded by pljones (Ticket #170)
TODO remove this code "TODO output mapping from stereo to multi channel"
TODO Central Server Address: "Default" results in empty server browser, "Default (North America)" works fine #156 TODO Central Server Address: "Default" results in empty server browser, "Default (North America)" works fine #156
-> made max list smaller from 200 to 150 -> check if that is sufficient to prevent UDP packet fragmentation -> made max list smaller from 200 to 150 -> check if that is sufficient to prevent UDP packet fragmentation

View file

@ -1152,17 +1152,18 @@ void CServer::ProcessData ( const CVector<CVector<int16_t> >& vecvecsData,
// Stereo target channel ----------------------------------------------- // Stereo target channel -----------------------------------------------
for ( j = 0; j < iNumClients; j++ ) for ( j = 0; j < iNumClients; j++ )
{ {
// get a reference to the audio data and gain of the current client // get a reference to the audio data and gain/pan of the current client
const CVector<int16_t>& vecsData = vecvecsData[j]; const CVector<int16_t>& vecsData = vecvecsData[j];
const double dGain = vecdGains[j]; const double dGain = vecdGains[j];
const double dPan = vecdPannings[j];
// calculate pan coefficient, see http://write.flossmanuals.net/csound/b-panning-and-spatialization/ for better formula, if needed // calculate combined gain/pan for each stereo channel where we define
const double dPan = vecdPannings[j]; // the panning that center equals full gain for both channels
const double dPanCoefL = sqrt ( 1 - dPan ); // faster: ( 1 - dPan ) const double dGainL = std::min ( 0.5, 1 - dPan ) * 2 * dGain;
const double dPanCoefR = sqrt ( dPan ); // ( dPan ) const double dGainR = std::min ( 0.5, dPan ) * 2 * dGain;
// if channel gain is 1, avoid multiplication for speed optimization // if channel gain is 1, avoid multiplication for speed optimization
if ( dGain == static_cast<double> ( 1.0 ) ) if ( ( dGainL == static_cast<double> ( 1.0 ) ) && ( dGainR == static_cast<double> ( 1.0 ) ) )
{ {
if ( vecNumAudioChannels[j] == 1 ) if ( vecNumAudioChannels[j] == 1 )
{ {
@ -1171,11 +1172,11 @@ void CServer::ProcessData ( const CVector<CVector<int16_t> >& vecvecsData,
{ {
// left channel // left channel
vecsOutData[k] = Double2Short ( vecsOutData[k] = Double2Short (
static_cast<double> ( vecsOutData[k] ) + vecsData[i] * dPanCoefL ); static_cast<double> ( vecsOutData[k] ) + vecsData[i] );
// right channel // right channel
vecsOutData[k + 1] = Double2Short ( vecsOutData[k + 1] = Double2Short (
static_cast<double> ( vecsOutData[k + 1] ) + vecsData[i] * dPanCoefR ); static_cast<double> ( vecsOutData[k + 1] ) + vecsData[i] );
} }
} }
else else
@ -1183,11 +1184,8 @@ void CServer::ProcessData ( const CVector<CVector<int16_t> >& vecvecsData,
// stereo // stereo
for ( i = 0; i < ( 2 * iServerFrameSizeSamples ); i++ ) for ( i = 0; i < ( 2 * iServerFrameSizeSamples ); i++ )
{ {
// get the correct pan value for the current channel (left or right)
const double pan = ( i % 2 == 0 ) ? dPanCoefL : dPanCoefR;
vecsOutData[i] = Double2Short ( vecsOutData[i] = Double2Short (
static_cast<double> ( vecsOutData[i] ) + vecsData[i] * pan ); static_cast<double> ( vecsOutData[i] ) + vecsData[i] );
} }
} }
} }
@ -1200,23 +1198,25 @@ void CServer::ProcessData ( const CVector<CVector<int16_t> >& vecvecsData,
{ {
// left channel // left channel
vecsOutData[k] = Double2Short ( vecsOutData[k] = Double2Short (
vecsOutData[k] + vecsData[i] * dGain * dPanCoefL ); vecsOutData[k] + vecsData[i] * dGain * dGainL );
// right channel // right channel
vecsOutData[k + 1] = Double2Short ( vecsOutData[k + 1] = Double2Short (
vecsOutData[k + 1] + vecsData[i] * dGain * dPanCoefR ); vecsOutData[k + 1] + vecsData[i] * dGain * dGainR );
} }
} }
else else
{ {
// stereo // stereo
for ( i = 0; i < ( 2 * iServerFrameSizeSamples ); i++ ) for ( i = 0; i < ( 2 * iServerFrameSizeSamples ); i += 2 )
{ {
// get the correct pan value for the current channel (left or right) // left channel
const double pan = ( i % 2 == 0 ) ? dPanCoefL : dPanCoefR;
vecsOutData[i] = Double2Short ( vecsOutData[i] = Double2Short (
vecsOutData[i] + vecsData[i] * dGain * pan ); vecsOutData[i] + vecsData[i] * dGain * dGainL );
// right channel
vecsOutData[i + 1] = Double2Short (
vecsOutData[i + 1] + vecsData[i + 1] * dGain * dGainR );
} }
} }
} }