1 #include "engine/enginemaster.h"
2 
3 #include <QList>
4 #include <QPair>
5 #include <QtDebug>
6 
7 #include "control/controlaudiotaperpot.h"
8 #include "control/controlpotmeter.h"
9 #include "control/controlpushbutton.h"
10 #include "effects/effectsmanager.h"
11 #include "engine/channelmixer.h"
12 #include "engine/channels/enginechannel.h"
13 #include "engine/channels/enginedeck.h"
14 #include "engine/effects/engineeffectsmanager.h"
15 #include "engine/enginebuffer.h"
16 #include "engine/enginedelay.h"
17 #include "engine/enginetalkoverducking.h"
18 #include "engine/enginevumeter.h"
19 #include "engine/engineworkerscheduler.h"
20 #include "engine/enginexfader.h"
21 #include "engine/sidechain/enginesidechain.h"
22 #include "engine/sync/enginesync.h"
23 #include "mixer/playermanager.h"
24 #include "moc_enginemaster.cpp"
25 #include "preferences/usersettings.h"
26 #include "util/defs.h"
27 #include "util/sample.h"
28 #include "util/timer.h"
29 #include "util/trace.h"
30 
EngineMaster(UserSettingsPointer pConfig,const QString & group,EffectsManager * pEffectsManager,ChannelHandleFactoryPointer pChannelHandleFactory,bool bEnableSidechain)31 EngineMaster::EngineMaster(
32         UserSettingsPointer pConfig,
33         const QString& group,
34         EffectsManager* pEffectsManager,
35         ChannelHandleFactoryPointer pChannelHandleFactory,
36         bool bEnableSidechain)
37         : m_pChannelHandleFactory(pChannelHandleFactory),
38           m_pEngineEffectsManager(pEffectsManager->getEngineEffectsManager()),
39           m_masterGainOld(0.0),
40           m_boothGainOld(0.0),
41           m_headphoneMasterGainOld(0.0),
42           m_headphoneGainOld(1.0),
43           m_balleftOld(1.0),
44           m_balrightOld(1.0),
45           m_masterHandle(registerChannelGroup(group)),
46           m_headphoneHandle(registerChannelGroup("[Headphone]")),
47           m_masterOutputHandle(registerChannelGroup("[MasterOutput]")),
48           m_busTalkoverHandle(registerChannelGroup("[BusTalkover]")),
49           m_busCrossfaderLeftHandle(registerChannelGroup("[BusLeft]")),
50           m_busCrossfaderCenterHandle(registerChannelGroup("[BusCenter]")),
51           m_busCrossfaderRightHandle(registerChannelGroup("[BusRight]")) {
52     pEffectsManager->registerInputChannel(m_masterHandle);
53     pEffectsManager->registerInputChannel(m_headphoneHandle);
54     pEffectsManager->registerOutputChannel(m_masterHandle);
55     pEffectsManager->registerOutputChannel(m_headphoneHandle);
56 
57     pEffectsManager->registerInputChannel(m_masterOutputHandle);
58     pEffectsManager->registerInputChannel(m_busTalkoverHandle);
59     pEffectsManager->registerInputChannel(m_busCrossfaderLeftHandle);
60     pEffectsManager->registerInputChannel(m_busCrossfaderCenterHandle);
61     pEffectsManager->registerInputChannel(m_busCrossfaderRightHandle);
62     m_bBusOutputConnected[EngineChannel::LEFT] = false;
63     m_bBusOutputConnected[EngineChannel::CENTER] = false;
64     m_bBusOutputConnected[EngineChannel::RIGHT] = false;
65     m_bExternalRecordBroadcastInputConnected = false;
66     m_pWorkerScheduler = new EngineWorkerScheduler(this);
67     m_pWorkerScheduler->start(QThread::HighPriority);
68 
69     // Master sample rate
70     m_pMasterSampleRate = new ControlObject(ConfigKey(group, "samplerate"), true, true);
71     m_pMasterSampleRate->set(44100.);
72 
73     // Latency control
74     m_pMasterLatency = new ControlObject(ConfigKey(group, "latency"), true, true);
75     m_pMasterAudioBufferSize = new ControlObject(ConfigKey(group, "audio_buffer_size"));
76     m_pAudioLatencyOverloadCount = new ControlObject(ConfigKey(group, "audio_latency_overload_count"), true, true);
77     m_pAudioLatencyUsage = new ControlPotmeter(ConfigKey(group, "audio_latency_usage"), 0.0, 0.25);
78     m_pAudioLatencyOverload  = new ControlPotmeter(ConfigKey(group, "audio_latency_overload"), 0.0, 1.0);
79 
80     // Master sync controller
81     m_pMasterSync = new EngineSync(pConfig);
82 
83     // The last-used bpm value is saved in the destructor of EngineSync.
84     double default_bpm = pConfig->getValue(
85             ConfigKey("[InternalClock]", "bpm"), 124.0);
86     ControlObject::getControl(ConfigKey("[InternalClock]","bpm"))->set(default_bpm);
87 
88     // Crossfader
89     m_pCrossfader = new ControlPotmeter(ConfigKey(group, "crossfader"), -1., 1.);
90 
91     // Balance
92     m_pBalance = new ControlPotmeter(ConfigKey(group, "balance"), -1., 1.);
93 
94     // Master gain
95     m_pMasterGain = new ControlAudioTaperPot(ConfigKey(group, "gain"), -14, 14, 0.5);
96 
97     // Booth gain
98     m_pBoothGain = new ControlAudioTaperPot(ConfigKey(group, "booth_gain"), -14, 14, 0.5);
99 
100     // Legacy: the master "gain" control used to be named "volume" in Mixxx
101     // 1.11.0 and earlier. See Bug #1306253.
102     ControlDoublePrivate::insertAlias(ConfigKey(group, "volume"),
103                                       ConfigKey(group, "gain"));
104 
105     // VU meter:
106     m_pVumeter = new EngineVuMeter(group);
107 
108     m_pMasterDelay = new EngineDelay(group, ConfigKey(group, "delay"));
109     m_pHeadDelay = new EngineDelay(group, ConfigKey(group, "headDelay"));
110     m_pBoothDelay = new EngineDelay(group, ConfigKey(group, "boothDelay"));
111     m_pLatencyCompensationDelay = new EngineDelay(group,
112         ConfigKey(group, "microphoneLatencyCompensation"));
113     m_pNumMicsConfigured = new ControlObject(ConfigKey(group, "num_mics_configured"));
114 
115     // Headphone volume
116     m_pHeadGain = new ControlAudioTaperPot(ConfigKey(group, "headGain"), -14, 14, 0.5);
117 
118     // Legacy: the headphone "headGain" control used to be named "headVolume" in
119     // Mixxx 1.11.0 and earlier. See Bug #1306253.
120     ControlDoublePrivate::insertAlias(ConfigKey(group, "headVolume"),
121                                       ConfigKey(group, "headGain"));
122 
123     // Headphone mix (left/right)
124     m_pHeadMix = new ControlPotmeter(ConfigKey(group, "headMix"),-1.,1.);
125     m_pHeadMix->setDefaultValue(-1.);
126     m_pHeadMix->set(-1.);
127 
128     // Master / Headphone split-out mode (for devices with only one output).
129     m_pHeadSplitEnabled = new ControlPushButton(ConfigKey(group, "headSplit"));
130     m_pHeadSplitEnabled->setButtonMode(ControlPushButton::TOGGLE);
131     m_pHeadSplitEnabled->set(0.0);
132 
133     m_pTalkoverDucking = new EngineTalkoverDucking(pConfig, group);
134 
135     // Allocate buffers
136     m_pHead = SampleUtil::alloc(MAX_BUFFER_LEN);
137     m_pMaster = SampleUtil::alloc(MAX_BUFFER_LEN);
138     m_pBooth = SampleUtil::alloc(MAX_BUFFER_LEN);
139     m_pTalkover = SampleUtil::alloc(MAX_BUFFER_LEN);
140     m_pTalkoverHeadphones = SampleUtil::alloc(MAX_BUFFER_LEN);
141     m_pSidechainMix = SampleUtil::alloc(MAX_BUFFER_LEN);
142     SampleUtil::clear(m_pHead, MAX_BUFFER_LEN);
143     SampleUtil::clear(m_pMaster, MAX_BUFFER_LEN);
144     SampleUtil::clear(m_pBooth, MAX_BUFFER_LEN);
145     SampleUtil::clear(m_pTalkover, MAX_BUFFER_LEN);
146     SampleUtil::clear(m_pTalkoverHeadphones, MAX_BUFFER_LEN);
147     SampleUtil::clear(m_pSidechainMix, MAX_BUFFER_LEN);
148 
149     // Setup the output buses
150     for (int o = EngineChannel::LEFT; o <= EngineChannel::RIGHT; ++o) {
151         m_pOutputBusBuffers[o] = SampleUtil::alloc(MAX_BUFFER_LEN);
152         SampleUtil::clear(m_pOutputBusBuffers[o], MAX_BUFFER_LEN);
153     }
154 
155     // Starts a thread for recording and broadcast
156     m_pEngineSideChain =
157             bEnableSidechain ?
158                     new EngineSideChain(pConfig, m_pSidechainMix) : nullptr;
159 
160     // X-Fader Setup
161     m_pXFaderMode = new ControlPushButton(
162             ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderMode"));
163     m_pXFaderMode->setButtonMode(ControlPushButton::TOGGLE);
164 
165     m_pXFaderCurve = new ControlPotmeter(
166             ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderCurve"),
167             EngineXfader::kTransformMin, EngineXfader::kTransformMax);
168     m_pXFaderCalibration = new ControlPotmeter(
169             ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderCalibration"),
170             0.3, 1., true);
171     m_pXFaderReverse = new ControlPushButton(
172             ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderReverse"));
173     m_pXFaderReverse->setButtonMode(ControlPushButton::TOGGLE);
174 
175     m_pKeylockEngine = new ControlObject(ConfigKey(group, "keylock_engine"),
176                                          true, false, true);
177     m_pKeylockEngine->set(pConfig->getValueString(
178             ConfigKey(group, "keylock_engine")).toDouble());
179 
180     // TODO: Make this read only and make EngineMaster decide whether
181     // processing the master mix is necessary.
182     m_pMasterEnabled = new ControlObject(ConfigKey(group, "enabled"),
183             true, false, true);  // persist = true
184     m_pBoothEnabled = new ControlObject(ConfigKey(group, "booth_enabled"));
185     m_pBoothEnabled->setReadOnly();
186     m_pMasterMonoMixdown = new ControlObject(ConfigKey(group, "mono_mixdown"),
187             true, false, true);  // persist = true
188     m_pMicMonitorMode = new ControlObject(ConfigKey(group, "talkover_mix"),
189             true, false, true);  // persist = true
190     m_pHeadphoneEnabled = new ControlObject(ConfigKey(group, "headEnabled"));
191     m_pHeadphoneEnabled->setReadOnly();
192 
193     // Note: the EQ Rack is set in EffectsManager::setupDefaults();
194 }
195 
~EngineMaster()196 EngineMaster::~EngineMaster() {
197     //qDebug() << "in ~EngineMaster()";
198     delete m_pKeylockEngine;
199     delete m_pCrossfader;
200     delete m_pBalance;
201     delete m_pHeadMix;
202     delete m_pHeadSplitEnabled;
203     delete m_pMasterGain;
204     delete m_pBoothGain;
205     delete m_pHeadGain;
206     delete m_pTalkoverDucking;
207     delete m_pVumeter;
208     delete m_pEngineSideChain;
209     delete m_pMasterDelay;
210     delete m_pHeadDelay;
211     delete m_pBoothDelay;
212     delete m_pLatencyCompensationDelay;
213     delete m_pNumMicsConfigured;
214 
215     delete m_pXFaderReverse;
216     delete m_pXFaderCalibration;
217     delete m_pXFaderCurve;
218     delete m_pXFaderMode;
219 
220     delete m_pMasterSync;
221     delete m_pMasterSampleRate;
222     delete m_pMasterLatency;
223     delete m_pMasterAudioBufferSize;
224     delete m_pAudioLatencyOverloadCount;
225     delete m_pAudioLatencyUsage;
226     delete m_pAudioLatencyOverload;
227 
228     delete m_pMasterEnabled;
229     delete m_pBoothEnabled;
230     delete m_pMasterMonoMixdown;
231     delete m_pMicMonitorMode;
232     delete m_pHeadphoneEnabled;
233 
234     SampleUtil::free(m_pHead);
235     SampleUtil::free(m_pMaster);
236     SampleUtil::free(m_pBooth);
237     SampleUtil::free(m_pTalkover);
238     SampleUtil::free(m_pTalkoverHeadphones);
239     SampleUtil::free(m_pSidechainMix);
240     for (int o = EngineChannel::LEFT; o <= EngineChannel::RIGHT; o++) {
241         SampleUtil::free(m_pOutputBusBuffers[o]);
242     }
243 
244     delete m_pWorkerScheduler;
245 
246     for (int i = 0; i < m_channels.size(); ++i) {
247         ChannelInfo* pChannelInfo = m_channels[i];
248         SampleUtil::free(pChannelInfo->m_pBuffer);
249         delete pChannelInfo->m_pChannel;
250         delete pChannelInfo->m_pVolumeControl;
251         delete pChannelInfo->m_pMuteControl;
252         delete pChannelInfo;
253     }
254 }
255 
getMasterBuffer() const256 const CSAMPLE* EngineMaster::getMasterBuffer() const {
257     return m_pMaster;
258 }
259 
getBoothBuffer() const260 const CSAMPLE* EngineMaster::getBoothBuffer() const {
261     return m_pBooth;
262 }
263 
getHeadphoneBuffer() const264 const CSAMPLE* EngineMaster::getHeadphoneBuffer() const {
265     return m_pHead;
266 }
267 
getSidechainBuffer() const268 const CSAMPLE* EngineMaster::getSidechainBuffer() const {
269     return m_pSidechainMix;
270 }
271 
processChannels(int iBufferSize)272 void EngineMaster::processChannels(int iBufferSize) {
273     // Update internal master sync rate.
274     m_pMasterSync->onCallbackStart(m_iSampleRate, m_iBufferSize);
275 
276     m_activeBusChannels[EngineChannel::LEFT].clear();
277     m_activeBusChannels[EngineChannel::CENTER].clear();
278     m_activeBusChannels[EngineChannel::RIGHT].clear();
279     m_activeHeadphoneChannels.clear();
280     m_activeTalkoverChannels.clear();
281     m_activeChannels.clear();
282 
283     //ScopedTimer timer("EngineMaster::processChannels");
284     EngineChannel* pMasterChannel = m_pMasterSync->getMaster();
285     // Reserve the first place for the master channel which
286     // should be processed first
287     m_activeChannels.append(NULL);
288     int activeChannelsStartIndex = 1; // Nothing at 0 yet
289     for (int i = 0; i < m_channels.size(); ++i) {
290         ChannelInfo* pChannelInfo = m_channels[i];
291         EngineChannel* pChannel = pChannelInfo->m_pChannel;
292 
293         // Skip inactive channels.
294         if (!pChannel || !pChannel->isActive()) {
295             continue;
296         }
297 
298         if (pChannel->isTalkoverEnabled() &&
299                 !pChannelInfo->m_pMuteControl->toBool()) {
300             // talkover is an exclusive channel
301             // once talkover is enabled it is not used in
302             // xFader-Mix
303             m_activeTalkoverChannels.append(pChannelInfo);
304 
305             // Check if we need to fade out the master channel
306             GainCache& gainCache = m_channelMasterGainCache[i];
307             if (gainCache.m_gain != 0) {
308                 gainCache.m_fadeout = true;
309                 m_activeBusChannels[pChannel->getOrientation()].append(pChannelInfo);
310             }
311         } else {
312             // Check if we need to fade out the channel
313             GainCache& gainCache = m_channelTalkoverGainCache[i];
314             if (gainCache.m_gain != 0) {
315                 gainCache.m_fadeout = true;
316                 m_activeTalkoverChannels.append(pChannelInfo);
317             }
318             if (pChannel->isMasterEnabled() &&
319                     !pChannelInfo->m_pMuteControl->toBool()) {
320                 // the xFader-Mix
321                 m_activeBusChannels[pChannel->getOrientation()].append(pChannelInfo);
322             } else {
323                 // Check if we need to fade out the channel
324                 GainCache& gainCache = m_channelMasterGainCache[i];
325                 if (gainCache.m_gain != 0) {
326                     gainCache.m_fadeout = true;
327                     m_activeBusChannels[pChannel->getOrientation()].append(pChannelInfo);
328                 }
329             }
330         }
331 
332         // If the channel is enabled for previewing in headphones, copy it
333         // over to the headphone buffer
334         if (pChannel->isPflEnabled()) {
335             m_activeHeadphoneChannels.append(pChannelInfo);
336         } else {
337             // Check if we need to fade out the channel
338             GainCache& gainCache = m_channelHeadphoneGainCache[i];
339             if (gainCache.m_gain != 0) {
340                 m_channelHeadphoneGainCache[i].m_fadeout = true;
341                 m_activeHeadphoneChannels.append(pChannelInfo);
342             }
343         }
344 
345         // If necessary, add the channel to the list of buffers to process.
346         if (pChannel == pMasterChannel) {
347             // If this is the sync master, it should be processed first.
348             m_activeChannels.replace(0, pChannelInfo);
349             activeChannelsStartIndex = 0;
350         } else {
351             m_activeChannels.append(pChannelInfo);
352         }
353     }
354 
355     // Now that the list is built and ordered, do the processing.
356     for (int i = activeChannelsStartIndex;
357              i < m_activeChannels.size(); ++i) {
358         ChannelInfo* pChannelInfo = m_activeChannels[i];
359         EngineChannel* pChannel = pChannelInfo->m_pChannel;
360         pChannel->process(pChannelInfo->m_pBuffer, iBufferSize);
361 
362         // Collect metadata for effects
363         if (m_pEngineEffectsManager) {
364             GroupFeatureState features;
365             pChannel->collectFeatures(&features);
366             pChannelInfo->m_features = features;
367         }
368     }
369 
370     // Do internal master sync post-processing before the other
371     // channels.
372     m_pMasterSync->onCallbackEnd(m_iSampleRate, m_iBufferSize);
373 
374     // After all the engines have been processed, trigger post-processing
375     // which ensures that all channels are updating certain values at the
376     // same point in time.  This prevents sync from failing depending on
377     // if the sync target was processed before or after the sync origin.
378     for (int i = activeChannelsStartIndex;
379             i < m_activeChannels.size(); ++i) {
380         m_activeChannels[i]->m_pChannel->postProcess(iBufferSize);
381     }
382 }
383 
process(const int iBufferSize)384 void EngineMaster::process(const int iBufferSize) {
385     static bool haveSetName = false;
386     if (!haveSetName) {
387         QThread::currentThread()->setObjectName("Engine");
388         haveSetName = true;
389     }
390     //Trace t("EngineMaster::process");
391 
392     bool masterEnabled = m_pMasterEnabled->toBool();
393     bool boothEnabled = m_pBoothEnabled->toBool();
394     bool headphoneEnabled = m_pHeadphoneEnabled->toBool();
395 
396     m_iSampleRate = static_cast<int>(m_pMasterSampleRate->get());
397     m_iBufferSize = iBufferSize;
398     // TODO: remove assumption of stereo buffer
399     const unsigned int kChannels = 2;
400     const unsigned int iFrames = iBufferSize / kChannels;
401 
402     if (m_pEngineEffectsManager) {
403         m_pEngineEffectsManager->onCallbackStart();
404     }
405 
406     // Prepare all channels for output
407     processChannels(m_iBufferSize);
408 
409     // Compute headphone mix
410     // Head phone left/right mix
411     CSAMPLE pflMixGainInHeadphones = 1;
412     CSAMPLE masterMixGainInHeadphones = 0;
413     if (masterEnabled) {
414         const auto cf_val = static_cast<CSAMPLE_GAIN>(m_pHeadMix->get());
415         pflMixGainInHeadphones = 0.5f * (-cf_val + 1.0f);
416         masterMixGainInHeadphones = 0.5f * (cf_val + 1.0f);
417         // qDebug() << "head val " << cf_val << ", head " << chead_gain
418         //          << ", master " << cmaster_gain;
419     }
420 
421     // Mix all the PFL enabled channels together.
422     m_headphoneGain.setGain(pflMixGainInHeadphones);
423 
424     if (headphoneEnabled) {
425         // Process effects and mix PFL channels together for the headphones.
426         // Effects will be reprocessed post-fader for the crossfader busses
427         // and master mix, so the channel input buffers cannot be modified here.
428         ChannelMixer::applyEffectsAndMixChannels(
429             m_headphoneGain, &m_activeHeadphoneChannels,
430             &m_channelHeadphoneGainCache,
431             m_pHead, m_headphoneHandle.handle(),
432             m_iBufferSize, m_iSampleRate,
433             m_pEngineEffectsManager);
434 
435         // Process headphone channel effects
436         if (m_pEngineEffectsManager) {
437             GroupFeatureState headphoneFeatures;
438             // If there is only one channel in the headphone mix, use its features
439             // for effects processing. This allows for previewing how an effect will
440             // sound on a playing deck before turning up the dry/wet knob to make it
441             // audible on the master mix. Without this, the effect would sound different
442             // in headphones than how it would sound if it was enabled on the deck,
443             // for example with tempo synced effects.
444             if (m_activeHeadphoneChannels.size() == 1) {
445                 headphoneFeatures = m_activeHeadphoneChannels.at(0)->m_features;
446             }
447             m_pEngineEffectsManager->processPostFaderInPlace(
448                 m_headphoneHandle.handle(),
449                 m_headphoneHandle.handle(),
450                 m_pHead,
451                 m_iBufferSize, m_iSampleRate,
452                 headphoneFeatures);
453         }
454     }
455 
456     // Mix all the talkover enabled channels together.
457     // Effects processing is done in place to avoid unnecessary buffer copying.
458     ChannelMixer::applyEffectsInPlaceAndMixChannels(
459             m_talkoverGain, &m_activeTalkoverChannels,
460             &m_channelTalkoverGainCache,
461             m_pTalkover, m_masterHandle.handle(),
462             m_iBufferSize, m_iSampleRate, m_pEngineEffectsManager);
463 
464     // Process effects on all microphones mixed together
465     // We have no metadata for mixed effect buses, so use an empty GroupFeatureState.
466     GroupFeatureState busFeatures;
467     if (m_pEngineEffectsManager) {
468         m_pEngineEffectsManager->processPostFaderInPlace(
469                 m_busTalkoverHandle.handle(),
470                 m_masterHandle.handle(),
471                 m_pTalkover,
472                 m_iBufferSize,
473                 m_iSampleRate,
474                 busFeatures);
475     }
476 
477     switch (m_pTalkoverDucking->getMode()) {
478     case EngineTalkoverDucking::OFF:
479         m_pTalkoverDucking->setAboveThreshold(false);
480         break;
481     case EngineTalkoverDucking::AUTO:
482         m_pTalkoverDucking->processKey(m_pTalkover, m_iBufferSize);
483         break;
484     case EngineTalkoverDucking::MANUAL:
485         m_pTalkoverDucking->setAboveThreshold(m_activeTalkoverChannels.size());
486         break;
487     default:
488         DEBUG_ASSERT("!Unknown Ducking mode");
489         m_pTalkoverDucking->setAboveThreshold(false);
490         break;
491     }
492 
493     // Calculate the crossfader gains for left and right side of the crossfader
494     CSAMPLE_GAIN crossfaderLeftGain, crossfaderRightGain;
495     EngineXfader::getXfadeGains(m_pCrossfader->get(), m_pXFaderCurve->get(),
496                                 m_pXFaderCalibration->get(),
497                                 m_pXFaderMode->get(),
498                                 m_pXFaderReverse->toBool(),
499                                 &crossfaderLeftGain, &crossfaderRightGain);
500 
501     // Make the mix for each crossfader orientation output bus.
502     // m_masterGain takes care of applying the attenuation from
503     // channel volume faders, crossfader, and talkover ducking.
504     // Talkover is mixed in later according to the configured MicMonitorMode
505     m_masterGain.setGains(crossfaderLeftGain,
506             1.0f,
507             crossfaderRightGain,
508             m_pTalkoverDucking->getGain(m_iBufferSize / 2));
509 
510     for (int o = EngineChannel::LEFT; o <= EngineChannel::RIGHT; o++) {
511         ChannelMixer::applyEffectsInPlaceAndMixChannels(
512             m_masterGain,
513             &m_activeBusChannels[o],
514             &m_channelMasterGainCache, // no [o] because the old gain follows an orientation switch
515             m_pOutputBusBuffers[o], m_masterHandle.handle(),
516             m_iBufferSize, m_iSampleRate, m_pEngineEffectsManager);
517     }
518 
519     // Process crossfader orientation bus channel effects
520     if (m_pEngineEffectsManager) {
521         m_pEngineEffectsManager->processPostFaderInPlace(
522             m_busCrossfaderLeftHandle.handle(),
523             m_masterHandle.handle(),
524             m_pOutputBusBuffers[EngineChannel::LEFT],
525             m_iBufferSize, m_iSampleRate, busFeatures);
526         m_pEngineEffectsManager->processPostFaderInPlace(
527             m_busCrossfaderCenterHandle.handle(),
528             m_masterHandle.handle(),
529             m_pOutputBusBuffers[EngineChannel::CENTER],
530             m_iBufferSize, m_iSampleRate, busFeatures);
531         m_pEngineEffectsManager->processPostFaderInPlace(
532             m_busCrossfaderRightHandle.handle(),
533             m_masterHandle.handle(),
534             m_pOutputBusBuffers[EngineChannel::RIGHT],
535             m_iBufferSize, m_iSampleRate, busFeatures);
536     }
537 
538     if (masterEnabled) {
539         // Mix the crossfader orientation buffers together into the master mix
540         SampleUtil::copy3WithGain(m_pMaster,
541             m_pOutputBusBuffers[EngineChannel::LEFT], 1.0,
542             m_pOutputBusBuffers[EngineChannel::CENTER], 1.0,
543             m_pOutputBusBuffers[EngineChannel::RIGHT], 1.0,
544             m_iBufferSize);
545 
546         MicMonitorMode configuredMicMonitorMode = static_cast<MicMonitorMode>(
547             static_cast<int>(m_pMicMonitorMode->get()));
548 
549         // Process master, booth, and record/broadcast buffers according to the
550         // MicMonitorMode configured in DlgPrefSound
551         // TODO(Be): make SampleUtil ramping functions update the old gain variable
552         if (configuredMicMonitorMode == MicMonitorMode::MASTER) {
553             // Process master channel effects
554             // TODO(Be): Move this after mixing in talkover. To apply master effects
555             // to both the master and booth in that case will require refactoring
556             // the effects system to be able to process the same effects on multiple
557             // buffers within the same callback.
558             applyMasterEffects();
559 
560             if (headphoneEnabled) {
561                 processHeadphones(masterMixGainInHeadphones);
562             }
563 
564             // Copy master mix to booth output with booth gain before mixing
565             // talkover with master mix
566             if (boothEnabled) {
567                 CSAMPLE_GAIN boothGain = static_cast<CSAMPLE_GAIN>(m_pBoothGain->get());
568                 SampleUtil::copyWithRampingGain(m_pBooth, m_pMaster,
569                                                 m_boothGainOld, boothGain,
570                                                 m_iBufferSize);
571                 m_boothGainOld = boothGain;
572             }
573 
574             // Mix talkover into master mix
575             if (m_pNumMicsConfigured->get() > 0) {
576                 SampleUtil::add(m_pMaster, m_pTalkover, m_iBufferSize);
577             }
578 
579             // Apply master gain
580             CSAMPLE_GAIN master_gain = static_cast<CSAMPLE_GAIN>(m_pMasterGain->get());
581             SampleUtil::applyRampingGain(m_pMaster, m_masterGainOld,
582                                          master_gain, m_iBufferSize);
583             m_masterGainOld = master_gain;
584 
585             // Record/broadcast signal is the same as the master output
586             if (sidechainMixRequired()) {
587                 SampleUtil::copy(m_pSidechainMix, m_pMaster, m_iBufferSize);
588             }
589         } else if (configuredMicMonitorMode == MicMonitorMode::MASTER_AND_BOOTH) {
590             // Process master channel effects
591             // TODO(Be): Move this after mixing in talkover. For the MASTER only
592             // MicMonitorMode above, that will require refactoring the effects system
593             // to be able to process the same effects on different buffers
594             // within the same callback. For consistency between the MicMonitorModes,
595             // process master effects here before mixing in talkover.
596             applyMasterEffects();
597 
598             if (headphoneEnabled) {
599                 processHeadphones(masterMixGainInHeadphones);
600             }
601 
602             // Mix talkover with master
603             if (m_pNumMicsConfigured->get() > 0) {
604                 SampleUtil::add(m_pMaster, m_pTalkover, m_iBufferSize);
605             }
606 
607             // Copy master mix (with talkover mixed in) to booth output with booth gain
608             if (boothEnabled) {
609                 CSAMPLE_GAIN boothGain = static_cast<CSAMPLE_GAIN>(m_pBoothGain->get());
610                 SampleUtil::copyWithRampingGain(m_pBooth, m_pMaster,
611                                                 m_boothGainOld, boothGain,
612                                                 m_iBufferSize);
613                 m_boothGainOld = boothGain;
614             }
615 
616             // Apply master gain
617             CSAMPLE_GAIN master_gain = static_cast<CSAMPLE_GAIN>(m_pMasterGain->get());
618             SampleUtil::applyRampingGain(m_pMaster, m_masterGainOld,
619                                          master_gain, m_iBufferSize);
620             m_masterGainOld = master_gain;
621 
622             // Record/broadcast signal is the same as the master output
623             if (sidechainMixRequired()) {
624                 SampleUtil::copy(m_pSidechainMix, m_pMaster, m_iBufferSize);
625             }
626         } else if (configuredMicMonitorMode == MicMonitorMode::DIRECT_MONITOR) {
627             // Skip mixing talkover with the master and booth outputs
628             // if using direct monitoring because it is being mixed in hardware
629             // without the latency of sending the signal into Mixxx for processing.
630             // However, include the talkover mix in the record/broadcast signal.
631 
632             // Copy master mix to booth output with booth gain
633             if (boothEnabled) {
634                 CSAMPLE_GAIN boothGain = static_cast<CSAMPLE_GAIN>(m_pBoothGain->get());
635                 SampleUtil::copyWithRampingGain(m_pBooth, m_pMaster,
636                                                 m_boothGainOld, boothGain,
637                                                 m_iBufferSize);
638                 m_boothGainOld = boothGain;
639             }
640 
641             // Process master channel effects
642             // NOTE(Be): This should occur before mixing in talkover for the
643             // record/broadcast signal so the record/broadcast signal is the same
644             // as what is heard on the master & booth outputs.
645             applyMasterEffects();
646 
647             if (headphoneEnabled) {
648                 processHeadphones(masterMixGainInHeadphones);
649             }
650 
651             // Apply master gain
652             CSAMPLE_GAIN master_gain = static_cast<CSAMPLE_GAIN>(m_pMasterGain->get());
653             SampleUtil::applyRampingGain(m_pMaster, m_masterGainOld,
654                                          master_gain, m_iBufferSize);
655             m_masterGainOld = master_gain;
656             if (sidechainMixRequired()) {
657                 SampleUtil::copy(m_pSidechainMix, m_pMaster, m_iBufferSize);
658 
659                 if (m_pNumMicsConfigured->get() > 0) {
660                     // The talkover signal Mixxx receives is delayed by the round trip latency.
661                     // There is an output latency between the time Mixxx processes the audio
662                     // and the user hears it. So if the microphone user plays on beat with
663                     // what they hear, they will be playing out of sync with the engine's
664                     // processing by the output latency. Additionally, Mixxx gets input signals
665                     // delayed by the input latency. By the time Mixxx receives the input signal,
666                     // a full round trip through the signal chain has elapsed since Mixxx
667                     // processed the output signal.
668                     // Although Mixxx receives the input signal delayed, the user hears it mixed
669                     // in hardware with the master & booth outputs without that
670                     // latency, so to record/broadcast the same signal that is heard
671                     // on the master & booth outputs, the master mix must be delayed before
672                     // mixing the talkover signal for the record/broadcast mix.
673                     // If not using microphone inputs or recording/broadcasting from
674                     // a sound card input, skip unnecessary processing here.
675 
676                     // Copy the master mix to a separate buffer before delaying it
677                     // to avoid delaying the master output.
678                     m_pLatencyCompensationDelay->process(m_pSidechainMix, m_iBufferSize);
679                     SampleUtil::add(m_pSidechainMix, m_pTalkover, m_iBufferSize);
680                 }
681             }
682         }
683 
684         // Submit buffer to the side chain to do CPU intensive non-realtime
685         // tasks like recording. The SoundDeviceNetwork, responsible for
686         // passing samples to the network reads directly from m_pSidechainMix,
687         // registering it with SoundDevice::addOutput().
688         // Note: In case the broadcast/recording input is configured,
689         // EngineSideChain::receiveBuffer has copied the input buffer to m_pSidechainMix
690         // via before (called by SoundManager::pushInputBuffers())
691         if (m_pEngineSideChain) {
692             m_pEngineSideChain->writeSamples(m_pSidechainMix, iFrames);
693         }
694 
695         // Process effects that apply to master hardware output only but not
696         // record/broadcast signal
697         if (m_pEngineEffectsManager) {
698             GroupFeatureState masterFeatures;
699             masterFeatures.has_gain = true;
700             masterFeatures.gain = m_pMasterGain->get();
701             m_pEngineEffectsManager->processPostFaderInPlace(
702                     m_masterOutputHandle.handle(),
703                     m_masterHandle.handle(),
704                     m_pMaster,
705                     m_iBufferSize, m_iSampleRate,
706                     masterFeatures);
707         }
708 
709         // Balance values
710         CSAMPLE balright = 1.;
711         CSAMPLE balleft = 1.;
712         const auto bal = static_cast<CSAMPLE_GAIN>(m_pBalance->get());
713         if (bal > 0.) {
714             balleft -= bal;
715         } else if (bal < 0.) {
716             balright += bal;
717         }
718 
719         // Perform balancing on main out
720         SampleUtil::applyRampingAlternatingGain(m_pMaster, balleft, balright,
721                 m_balleftOld, m_balrightOld, iBufferSize);
722 
723         m_balleftOld = balleft;
724         m_balrightOld = balright;
725 
726         // Update VU meter (it does not return anything). Needs to be here so that
727         // master balance and talkover is reflected in the VU meter.
728         if (m_pVumeter != nullptr) {
729             m_pVumeter->process(m_pMaster, m_iBufferSize);
730         }
731     }
732 
733     if (m_pMasterMonoMixdown->toBool()) {
734         SampleUtil::mixStereoToMono(m_pMaster, m_iBufferSize);
735     }
736 
737     if (masterEnabled) {
738         m_pMasterDelay->process(m_pMaster, m_iBufferSize);
739     } else {
740         SampleUtil::clear(m_pMaster, m_iBufferSize);
741     }
742     if (headphoneEnabled) {
743         m_pHeadDelay->process(m_pHead, m_iBufferSize);
744     }
745     if (boothEnabled) {
746         m_pBoothDelay->process(m_pBooth, m_iBufferSize);
747     }
748 
749     // We're close to the end of the callback. Wake up the engine worker
750     // scheduler so that it runs the workers.
751     m_pWorkerScheduler->runWorkers();
752 }
753 
applyMasterEffects()754 void EngineMaster::applyMasterEffects() {
755     // Apply master effects
756     if (m_pEngineEffectsManager) {
757         GroupFeatureState masterFeatures;
758         masterFeatures.has_gain = true;
759         masterFeatures.gain = m_pMasterGain->get();
760         m_pEngineEffectsManager->processPostFaderInPlace(m_masterHandle.handle(),
761                                                          m_masterHandle.handle(),
762                                                          m_pMaster,
763                                                          m_iBufferSize, m_iSampleRate,
764                                                          masterFeatures);
765     }
766 }
767 
processHeadphones(const CSAMPLE_GAIN masterMixGainInHeadphones)768 void EngineMaster::processHeadphones(const CSAMPLE_GAIN masterMixGainInHeadphones) {
769     // Add master mix to headphones
770     SampleUtil::addWithRampingGain(m_pHead, m_pMaster,
771                                    m_headphoneMasterGainOld,
772                                    masterMixGainInHeadphones, m_iBufferSize);
773     m_headphoneMasterGainOld = masterMixGainInHeadphones;
774 
775     // If Head Split is enabled, replace the left channel of the pfl buffer
776     // with a mono mix of the headphone buffer, and the right channel of the pfl
777     // buffer with a mono mix of the master output buffer.
778     if (m_pHeadSplitEnabled->toBool()) {
779         // note: NOT VECTORIZED because of in place copy
780         for (unsigned int i = 0; i + 1 < m_iBufferSize; i += 2) {
781             m_pHead[i] = (m_pHead[i] + m_pHead[i + 1]) / 2;
782             m_pHead[i + 1] = (m_pMaster[i] + m_pMaster[i + 1]) / 2;
783         }
784     }
785 
786     // Apply headphone gain
787     CSAMPLE_GAIN headphoneGain = static_cast<CSAMPLE_GAIN>(m_pHeadGain->get());
788     SampleUtil::applyRampingGain(m_pHead, m_headphoneGainOld,
789                                  headphoneGain, m_iBufferSize);
790     m_headphoneGainOld = headphoneGain;
791 }
792 
addChannel(EngineChannel * pChannel)793 void EngineMaster::addChannel(EngineChannel* pChannel) {
794     ChannelInfo* pChannelInfo = new ChannelInfo(m_channels.size());
795     pChannel->setChannelIndex(pChannelInfo->m_index);
796     pChannelInfo->m_pChannel = pChannel;
797     const QString& group = pChannel->getGroup();
798     pChannelInfo->m_handle = m_pChannelHandleFactory->getOrCreateHandle(group);
799     pChannelInfo->m_pVolumeControl = new ControlAudioTaperPot(
800             ConfigKey(group, "volume"), -20, 0, 1);
801     pChannelInfo->m_pVolumeControl->setDefaultValue(1.0);
802     pChannelInfo->m_pVolumeControl->set(1.0);
803     pChannelInfo->m_pMuteControl = new ControlPushButton(
804             ConfigKey(group, "mute"));
805     pChannelInfo->m_pMuteControl->setButtonMode(ControlPushButton::POWERWINDOW);
806     pChannelInfo->m_pBuffer = SampleUtil::alloc(MAX_BUFFER_LEN);
807     SampleUtil::clear(pChannelInfo->m_pBuffer, MAX_BUFFER_LEN);
808     m_channels.append(pChannelInfo);
809     const GainCache gainCacheDefault = {0, false};
810     m_channelHeadphoneGainCache.append(gainCacheDefault);
811     m_channelTalkoverGainCache.append(gainCacheDefault);
812     m_channelMasterGainCache.append(gainCacheDefault);
813 
814     // Pre-allocate scratch buffers to avoid memory allocation in the
815     // callback. QVarLengthArray does nothing if reserve is called with a size
816     // smaller than its pre-allocation.
817     m_activeChannels.reserve(m_channels.size());
818     m_activeBusChannels[EngineChannel::LEFT].reserve(m_channels.size());
819     m_activeBusChannels[EngineChannel::CENTER].reserve(m_channels.size());
820     m_activeBusChannels[EngineChannel::RIGHT].reserve(m_channels.size());
821     m_activeHeadphoneChannels.reserve(m_channels.size());
822     m_activeTalkoverChannels.reserve(m_channels.size());
823 
824     EngineBuffer* pBuffer = pChannelInfo->m_pChannel->getEngineBuffer();
825     if (pBuffer != nullptr) {
826         pBuffer->bindWorkers(m_pWorkerScheduler);
827     }
828 }
829 
getChannel(const QString & group)830 EngineChannel* EngineMaster::getChannel(const QString& group) {
831     for (int i = 0; i < m_channels.size(); ++i) {
832         ChannelInfo* pChannelInfo = m_channels[i];
833         if (pChannelInfo->m_pChannel->getGroup() == group) {
834             return pChannelInfo->m_pChannel;
835         }
836     }
837     return nullptr;
838 }
839 
getMasterGain(int channelIndex) const840 CSAMPLE_GAIN EngineMaster::getMasterGain(int channelIndex) const {
841     if (channelIndex >= 0 && channelIndex < m_channelMasterGainCache.size()) {
842         return m_channelMasterGainCache[channelIndex].m_gain;
843     }
844     return CSAMPLE_GAIN_ZERO;
845 }
846 
getDeckBuffer(unsigned int i) const847 const CSAMPLE* EngineMaster::getDeckBuffer(unsigned int i) const {
848     return getChannelBuffer(PlayerManager::groupForDeck(i));
849 }
850 
getOutputBusBuffer(unsigned int i) const851 const CSAMPLE* EngineMaster::getOutputBusBuffer(unsigned int i) const {
852     if (i <= EngineChannel::RIGHT) {
853         return m_pOutputBusBuffers[i];
854     }
855     return nullptr;
856 }
857 
getChannelBuffer(const QString & group) const858 const CSAMPLE* EngineMaster::getChannelBuffer(const QString& group) const {
859     for (int i = 0; i < m_channels.size(); ++i) {
860         const ChannelInfo* pChannelInfo = m_channels[i];
861         if (pChannelInfo->m_pChannel->getGroup() == group) {
862             return pChannelInfo->m_pBuffer;
863         }
864     }
865     return nullptr;
866 }
867 
buffer(const AudioOutput & output) const868 const CSAMPLE* EngineMaster::buffer(const AudioOutput& output) const {
869     switch (output.getType()) {
870     case AudioOutput::MASTER:
871         return getMasterBuffer();
872         break;
873     case AudioOutput::BOOTH:
874         return getBoothBuffer();
875         break;
876     case AudioOutput::HEADPHONES:
877         return getHeadphoneBuffer();
878         break;
879     case AudioOutput::BUS:
880         return getOutputBusBuffer(output.getIndex());
881         break;
882     case AudioOutput::DECK:
883         return getDeckBuffer(output.getIndex());
884         break;
885     case AudioOutput::RECORD_BROADCAST:
886         return getSidechainBuffer();
887         break;
888     default:
889         return nullptr;
890     }
891 }
892 
onOutputConnected(const AudioOutput & output)893 void EngineMaster::onOutputConnected(const AudioOutput& output) {
894     switch (output.getType()) {
895         case AudioOutput::MASTER:
896             // overwrite config option if a master output is configured
897             m_pMasterEnabled->forceSet(1.0);
898             break;
899         case AudioOutput::HEADPHONES:
900             m_pMasterEnabled->forceSet(1.0);
901             m_pHeadphoneEnabled->forceSet(1.0);
902             break;
903         case AudioOutput::BOOTH:
904             m_pMasterEnabled->forceSet(1.0);
905             m_pBoothEnabled->forceSet(1.0);
906             break;
907         case AudioOutput::BUS:
908             m_bBusOutputConnected[output.getIndex()] = true;
909             break;
910         case AudioOutput::DECK:
911             // We don't track enabled decks.
912             break;
913         case AudioOutput::RECORD_BROADCAST:
914             // We don't track enabled sidechain.
915             break;
916         default:
917             break;
918     }
919 }
920 
onOutputDisconnected(const AudioOutput & output)921 void EngineMaster::onOutputDisconnected(const AudioOutput& output) {
922     switch (output.getType()) {
923         case AudioOutput::MASTER:
924             // not used, because we need the master buffer for headphone mix
925             // and recording/broadcasting as well
926             break;
927         case AudioOutput::BOOTH:
928             m_pBoothEnabled->forceSet(0.0);
929             break;
930         case AudioOutput::HEADPHONES:
931             m_pHeadphoneEnabled->forceSet(0.0);
932             break;
933         case AudioOutput::BUS:
934             m_bBusOutputConnected[output.getIndex()] = false;
935             break;
936         case AudioOutput::DECK:
937             // We don't track enabled decks.
938             break;
939         case AudioOutput::RECORD_BROADCAST:
940             // We don't track enabled sidechain.
941             break;
942         default:
943             break;
944     }
945 }
946 
onInputConnected(const AudioInput & input)947 void EngineMaster::onInputConnected(const AudioInput& input) {
948     switch (input.getType()) {
949       case AudioInput::MICROPHONE:
950           m_pNumMicsConfigured->set(m_pNumMicsConfigured->get() + 1);
951           break;
952       case AudioInput::AUXILIARY:
953           // We don't track enabled auxiliary inputs.
954           break;
955       case AudioInput::VINYLCONTROL:
956           // We don't track enabled vinyl control inputs.
957           break;
958       case AudioInput::RECORD_BROADCAST:
959           m_bExternalRecordBroadcastInputConnected = true;
960           break;
961       default:
962           break;
963     }
964 }
965 
onInputDisconnected(const AudioInput & input)966 void EngineMaster::onInputDisconnected(const AudioInput& input) {
967     switch (input.getType()) {
968       case AudioInput::MICROPHONE:
969           m_pNumMicsConfigured->set(m_pNumMicsConfigured->get() - 1);
970           break;
971       case AudioInput::AUXILIARY:
972           // We don't track enabled auxiliary inputs.
973           break;
974       case AudioInput::VINYLCONTROL:
975           // We don't track enabled vinyl control inputs.
976           break;
977       case AudioInput::RECORD_BROADCAST:
978           m_bExternalRecordBroadcastInputConnected = false;
979           break;
980       default:
981           break;
982     }
983 }
984 
registerNonEngineChannelSoundIO(SoundManager * pSoundManager)985 void EngineMaster::registerNonEngineChannelSoundIO(SoundManager* pSoundManager) {
986     pSoundManager->registerInput(AudioInput(AudioPath::RECORD_BROADCAST, 0, 2),
987                                  m_pEngineSideChain);
988 
989     pSoundManager->registerOutput(AudioOutput(AudioOutput::MASTER, 0, 2), this);
990     pSoundManager->registerOutput(AudioOutput(AudioOutput::HEADPHONES, 0, 2), this);
991     pSoundManager->registerOutput(AudioOutput(AudioOutput::BOOTH, 0, 2), this);
992     for (int o = EngineChannel::LEFT; o <= EngineChannel::RIGHT; o++) {
993         pSoundManager->registerOutput(AudioOutput(AudioOutput::BUS, 0, 2, o), this);
994     }
995     pSoundManager->registerOutput(AudioOutput(AudioOutput::RECORD_BROADCAST, 0, 2), this);
996 }
997 
sidechainMixRequired() const998 bool EngineMaster::sidechainMixRequired() const {
999     return m_pEngineSideChain && !m_bExternalRecordBroadcastInputConnected;
1000 }
1001