@@ -176,9 +176,9 @@ CClient::CClient ( const quint16 iPortNumber,
176176 PreciseTime.start ();
177177
178178 // set gain delay timer to single-shot and connect handler function
179- TimerGain .setSingleShot ( true );
179+ TimerGainOrPan .setSingleShot ( true );
180180
181- QObject::connect ( &TimerGain , &QTimer::timeout, this , &CClient::OnTimerRemoteChanGain );
181+ QObject::connect ( &TimerGainOrPan , &QTimer::timeout, this , &CClient::OnTimerRemoteChanGainOrPan );
182182
183183 // start the socket (it is important to start the socket after all
184184 // initializations and connections)
@@ -431,27 +431,28 @@ void CClient::SetDoAutoSockBufSize ( const bool bValue )
431431 CreateServerJitterBufferMessage ();
432432}
433433
434- // In order not to flood the server with gain change messages, particularly when using
434+ // In order not to flood the server with gain or pan change messages, particularly when using
435435// a MIDI controller, a timer is used to limit the rate at which such messages are generated.
436436// This avoids a potential long backlog of messages, since each must be ACKed before the next
437437// can be sent, and this ACK is subject to the latency of the server connection.
438438//
439- // When the first gain change message is requested after an idle period (i.e. the timer is not
440- // running), it will be sent immediately, and a 300ms timer started.
439+ // When the first gain or pan change message is requested after an idle period (i.e. the timer is not
440+ // running), it will be sent immediately, and a timer started. The timer period is dependent on
441+ // the current ping time to the remote server.
441442//
442- // If a gain change message is requested while the timer is still running, the new gain is not sent,
443- // but just stored in clientChannels[iId].newGain , and the minGainId and maxGainId updated to note
444- // the range of IDs that must be checked when the time expires (this will usually be a single channel
445- // unless channel grouping is being used). This avoids having to check all possible channels.
443+ // If a gain or pan change message is requested while the timer is still running, the new value is not sent,
444+ // but just stored in newGain or newPan within clientChannels[iId], and the minGainOrPanId and maxGainOrPanId
445+ // updated to note the range of IDs that must be checked when the time expires (this will usually be a single
446+ // channel unless channel grouping is being used). This avoids having to check all possible channels.
446447//
447- // When the timer fires, the channels minGainId <= iId < maxGainId are checked by comparing the last sent value
448- // in clientChannels[iId]. oldGain with any pending value in clientChannels[iId]. newGain, and if they differ,
449- // the new value is sent, updating clientChannels[iId]. oldGain with the sent value. If any new values are
450- // sent, the timer is restarted so that further immediate updates will be pended.
448+ // When the timer fires, the channels minGainOrPanId <= iId < maxGainOrPanId are checked by comparing the
449+ // last sent values in oldGain or oldPan with any pending values in newGain or newPan , and if they differ,
450+ // the new value is sent, updating oldGain or oldPan with the sent value. If any new values are sent,
451+ // the timer is restarted so that further immediate updates will be pended.
451452
452453void CClient::SetRemoteChanGain ( const int iId, const float fGain , const bool bIsMyOwnFader )
453454{
454- QMutexLocker locker ( &MutexGain );
455+ QMutexLocker locker ( &MutexGainOrPan );
455456
456457 CClientChannel* clientChan = &clientChannels[iId];
457458
@@ -461,17 +462,17 @@ void CClient::SetRemoteChanGain ( const int iId, const float fGain, const bool b
461462 fMuteOutStreamGain = fGain ;
462463 }
463464
464- if ( TimerGain .isActive () )
465+ if ( TimerGainOrPan .isActive () )
465466 {
466467 // just update the new value for sending later;
467468 // will compare with oldGain when the timer fires
468469 clientChan->newGain = fGain ;
469470
470471 // update range of channel IDs to check in the timer
471- if ( iId < minGainId )
472- minGainId = iId; // first value to check
473- if ( iId >= maxGainId )
474- maxGainId = iId + 1 ; // first value NOT to check
472+ if ( iId < minGainOrPanId )
473+ minGainOrPanId = iId; // first value to check
474+ if ( iId >= maxGainOrPanId )
475+ maxGainOrPanId = iId + 1 ; // first value NOT to check
475476
476477 return ;
477478 }
@@ -481,15 +482,15 @@ void CClient::SetRemoteChanGain ( const int iId, const float fGain, const bool b
481482 clientChan->oldGain = clientChan->newGain = fGain ;
482483 Channel.SetRemoteChanGain ( clientChan->iServerChannelID , fGain ); // translate client channel to server channel ID
483484
484- StartDelayTimer ();
485+ StartTimerGainOrPan ();
485486}
486487
487- void CClient::OnTimerRemoteChanGain ()
488+ void CClient::OnTimerRemoteChanGainOrPan ()
488489{
489- QMutexLocker locker ( &MutexGain );
490+ QMutexLocker locker ( &MutexGainOrPan );
490491 bool bSent = false ;
491492
492- for ( int iId = minGainId ; iId < maxGainId ; iId++ )
493+ for ( int iId = minGainOrPanId ; iId < maxGainOrPanId ; iId++ )
493494 {
494495 CClientChannel* clientChan = &clientChannels[iId];
495496
@@ -500,37 +501,69 @@ void CClient::OnTimerRemoteChanGain()
500501 Channel.SetRemoteChanGain ( clientChan->iServerChannelID , fGain ); // translate client channel to server channel ID
501502 bSent = true ;
502503 }
504+
505+ if ( clientChan->newPan != clientChan->oldPan )
506+ {
507+ // send new pan and record as old pan
508+ float fPan = clientChan->oldPan = clientChan->newPan ;
509+ Channel.SetRemoteChanPan ( clientChan->iServerChannelID , fPan ); // translate client channel to server channel ID
510+ bSent = true ;
511+ }
503512 }
504513
505- // if a new gain has been sent, reset the range of channel IDs to empty and start timer
514+ // if a new gain or pan has been sent, reset the range of channel IDs to empty and start timer
506515 if ( bSent )
507516 {
508- StartDelayTimer ();
517+ StartTimerGainOrPan ();
509518 }
510519}
511520
512521// reset the range of channel IDs to check and start the delay timer
513- void CClient::StartDelayTimer ()
522+ void CClient::StartTimerGainOrPan ()
514523{
515- maxGainId = 0 ;
516- minGainId = MAX_NUM_CHANNELS;
524+ maxGainOrPanId = 0 ;
525+ minGainOrPanId = MAX_NUM_CHANNELS;
517526
518527 // start timer to delay sending further updates
519528 // use longer delay when connected to server with higher ping time,
520529 // double the ping time in order to allow a bit of overhead for other messages
521530 if ( iCurPingTime < DEFAULT_GAIN_DELAY_PERIOD_MS / 2 )
522531 {
523- TimerGain .start ( DEFAULT_GAIN_DELAY_PERIOD_MS );
532+ TimerGainOrPan .start ( DEFAULT_GAIN_DELAY_PERIOD_MS );
524533 }
525534 else
526535 {
527- TimerGain .start ( iCurPingTime * 2 );
536+ TimerGainOrPan .start ( iCurPingTime * 2 );
528537 }
529538}
530539
531540void CClient::SetRemoteChanPan ( const int iId, const float fPan )
532541{
533- Channel.SetRemoteChanPan ( clientChannels[iId].iServerChannelID , fPan ); // translate client channel to server channel ID
542+ QMutexLocker locker ( &MutexGainOrPan );
543+
544+ CClientChannel* clientChan = &clientChannels[iId];
545+
546+ if ( TimerGainOrPan.isActive () )
547+ {
548+ // just update the new value for sending later;
549+ // will compare with oldPan when the timer fires
550+ clientChan->newPan = fPan ;
551+
552+ // update range of channel IDs to check in the timer
553+ if ( iId < minGainOrPanId )
554+ minGainOrPanId = iId; // first value to check
555+ if ( iId >= maxGainOrPanId )
556+ maxGainOrPanId = iId + 1 ; // first value NOT to check
557+
558+ return ;
559+ }
560+
561+ // here the timer was not active:
562+ // send the actual gain and reset the range of channel IDs to empty
563+ clientChan->oldPan = clientChan->newPan = fPan ;
564+ Channel.SetRemoteChanPan ( clientChan->iServerChannelID , fPan ); // translate client channel to server channel ID
565+
566+ StartTimerGainOrPan ();
534567}
535568
536569bool CClient::SetServerAddr ( QString strNAddr )
@@ -1541,6 +1574,7 @@ int CClient::FindClientChannel ( const int iServerChannelID, const bool bCreateI
15411574 clientChan->iJoinSequence = ++iJoinSequence;
15421575
15431576 clientChan->oldGain = clientChan->newGain = 1 .0f ;
1577+ clientChan->oldPan = clientChan->newPan = 0 .5f ;
15441578
15451579 clientChan->level = 0 ;
15461580
0 commit comments