![]() |
Mixxx
|
00001 /*************************************************************************** 00002 enginemaster.cpp - description 00003 ------------------- 00004 begin : Sun Apr 28 2002 00005 copyright : (C) 2002 by 00006 email : 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include <QDebug> 00019 #include <QList> 00020 #include <QPair> 00021 00022 #include "controlpushbutton.h" 00023 #include "configobject.h" 00024 #include "controllogpotmeter.h" 00025 #include "controlpotmeter.h" 00026 #include "enginebuffer.h" 00027 #include "enginemaster.h" 00028 #include "engine/engineworkerscheduler.h" 00029 #include "enginebuffer.h" 00030 #include "enginechannel.h" 00031 #include "engineclipping.h" 00032 #include "enginevumeter.h" 00033 #include "enginexfader.h" 00034 #include "enginesidechain.h" 00035 #include "engine/syncworker.h" 00036 #include "sampleutil.h" 00037 00038 #ifdef __LADSPA__ 00039 #include "engineladspa.h" 00040 #endif 00041 00042 00043 EngineMaster::EngineMaster(ConfigObject<ConfigValue> * _config, 00044 const char * group) { 00045 00046 m_pWorkerScheduler = new EngineWorkerScheduler(this); 00047 m_pWorkerScheduler->start(); 00048 m_pSyncWorker = new SyncWorker(m_pWorkerScheduler); 00049 00050 // Master sample rate 00051 m_pMasterSampleRate = new ControlObject(ConfigKey(group, "samplerate")); 00052 m_pMasterSampleRate->set(44100.); 00053 00054 // Latency control 00055 m_pMasterLatency = new ControlObject(ConfigKey(group, "latency")); 00056 00057 // Master rate 00058 m_pMasterRate = new ControlPotmeter(ConfigKey(group, "rate"), -1.0, 1.0); 00059 00060 #ifdef __LADSPA__ 00061 // LADSPA 00062 ladspa = new EngineLADSPA(); 00063 #endif 00064 00065 // Crossfader 00066 crossfader = new ControlPotmeter(ConfigKey(group, "crossfader"),-1.,1.); 00067 00068 // Balance 00069 m_pBalance = new ControlPotmeter(ConfigKey(group, "balance"), -1., 1.); 00070 00071 // Master volume 00072 m_pMasterVolume = new ControlLogpotmeter(ConfigKey(group, "volume"), 5.); 00073 00074 // Clipping 00075 clipping = new EngineClipping(group); 00076 00077 // VU meter: 00078 vumeter = new EngineVuMeter(group); 00079 00080 // Headphone volume 00081 m_pHeadVolume = new ControlLogpotmeter(ConfigKey(group, "headVolume"), 5.); 00082 00083 // Headphone mix (left/right) 00084 head_mix = new ControlPotmeter(ConfigKey(group, "headMix"),-1.,1.); 00085 head_mix->set(-1.); 00086 00087 // Headphone Clipping 00088 head_clipping = new EngineClipping(""); 00089 00090 // Allocate buffers 00091 m_pHead = SampleUtil::alloc(MAX_BUFFER_LEN); 00092 m_pMaster = SampleUtil::alloc(MAX_BUFFER_LEN); 00093 memset(m_pHead, 0, sizeof(CSAMPLE) * MAX_BUFFER_LEN); 00094 memset(m_pMaster, 0, sizeof(CSAMPLE) * MAX_BUFFER_LEN); 00095 00096 //Starts a thread for recording and shoutcast 00097 sidechain = new EngineSideChain(_config); 00098 connect(sidechain, SIGNAL(isRecording(bool)), 00099 this, SIGNAL(isRecording(bool))); 00100 connect(sidechain, SIGNAL(bytesRecorded(int)), 00101 this, SIGNAL(bytesRecorded(int))); 00102 00103 //X-Fader Setup 00104 xFaderCurve = new ControlPotmeter( 00105 ConfigKey("[Mixer Profile]", "xFaderCurve"), 0., 2.); 00106 xFaderCalibration = new ControlPotmeter( 00107 ConfigKey("[Mixer Profile]", "xFaderCalibration"), -2., 2.); 00108 } 00109 00110 EngineMaster::~EngineMaster() 00111 { 00112 qDebug() << "in ~EngineMaster()"; 00113 delete crossfader; 00114 delete m_pBalance; 00115 delete head_mix; 00116 delete m_pMasterVolume; 00117 delete m_pHeadVolume; 00118 delete clipping; 00119 delete vumeter; 00120 delete head_clipping; 00121 delete sidechain; 00122 00123 delete xFaderCalibration; 00124 delete xFaderCurve; 00125 00126 delete m_pMasterSampleRate; 00127 delete m_pMasterLatency; 00128 delete m_pMasterRate; 00129 00130 SampleUtil::free(m_pHead); 00131 SampleUtil::free(m_pMaster); 00132 00133 QMutableListIterator<ChannelInfo*> channel_it(m_channels); 00134 while (channel_it.hasNext()) { 00135 ChannelInfo* pChannelInfo = channel_it.next(); 00136 channel_it.remove(); 00137 SampleUtil::free(pChannelInfo->m_pBuffer); 00138 delete pChannelInfo->m_pChannel; 00139 delete pChannelInfo->m_pVolumeControl; 00140 delete pChannelInfo; 00141 } 00142 00143 delete m_pWorkerScheduler; 00144 delete m_pSyncWorker; 00145 } 00146 00147 const CSAMPLE* EngineMaster::getMasterBuffer() const 00148 { 00149 return m_pMaster; 00150 } 00151 00152 const CSAMPLE* EngineMaster::getHeadphoneBuffer() const 00153 { 00154 return m_pHead; 00155 } 00156 00157 void EngineMaster::mixChannels(unsigned int channelBitvector, unsigned int maxChannels, 00158 CSAMPLE* pOutput, unsigned int iBufferSize, 00159 GainCalculator* pGainCalculator) { 00160 // Common case: 2 decks, 4 samplers, 1 mic 00161 ChannelInfo* pChannel1 = NULL; 00162 ChannelInfo* pChannel2 = NULL; 00163 ChannelInfo* pChannel3 = NULL; 00164 ChannelInfo* pChannel4 = NULL; 00165 ChannelInfo* pChannel5 = NULL; 00166 ChannelInfo* pChannel6 = NULL; 00167 ChannelInfo* pChannel7 = NULL; 00168 00169 unsigned int totalActive = 0; 00170 for (unsigned int i = 0; i < maxChannels; ++i) { 00171 if ((channelBitvector & (1 << i)) == 0) { 00172 continue; 00173 } 00174 00175 ++totalActive; 00176 00177 if (pChannel1 == NULL) { 00178 pChannel1 = m_channels[i]; 00179 } else if (pChannel2 == NULL) { 00180 pChannel2 = m_channels[i]; 00181 } else if (pChannel3 == NULL) { 00182 pChannel3 = m_channels[i]; 00183 } else if (pChannel4 == NULL) { 00184 pChannel4 = m_channels[i]; 00185 } else if (pChannel5 == NULL) { 00186 pChannel5 = m_channels[i]; 00187 } else if (pChannel6 == NULL) { 00188 pChannel6 = m_channels[i]; 00189 } else if (pChannel7 == NULL) { 00190 pChannel7 = m_channels[i]; 00191 } 00192 } 00193 00194 if (totalActive == 0) { 00195 SampleUtil::applyGain(pOutput, 0.0f, iBufferSize); 00196 } else if (totalActive == 1) { 00197 CSAMPLE* pBuffer1 = pChannel1->m_pBuffer; 00198 double gain1 = pGainCalculator->getGain(pChannel1); 00199 SampleUtil::copyWithGain(pOutput, 00200 pBuffer1, gain1, 00201 iBufferSize); 00202 } else if (totalActive == 2) { 00203 CSAMPLE* pBuffer1 = pChannel1->m_pBuffer; 00204 double gain1 = pGainCalculator->getGain(pChannel1); 00205 CSAMPLE* pBuffer2 = pChannel2->m_pBuffer; 00206 double gain2 = pGainCalculator->getGain(pChannel2); 00207 SampleUtil::copy2WithGain(pOutput, 00208 pBuffer1, gain1, 00209 pBuffer2, gain2, 00210 iBufferSize); 00211 } else if (totalActive == 3) { 00212 CSAMPLE* pBuffer1 = pChannel1->m_pBuffer; 00213 double gain1 = pGainCalculator->getGain(pChannel1); 00214 CSAMPLE* pBuffer2 = pChannel2->m_pBuffer; 00215 double gain2 = pGainCalculator->getGain(pChannel2); 00216 CSAMPLE* pBuffer3 = pChannel3->m_pBuffer; 00217 double gain3 = pGainCalculator->getGain(pChannel3); 00218 00219 SampleUtil::copy3WithGain(pOutput, 00220 pBuffer1, gain1, 00221 pBuffer2, gain2, 00222 pBuffer3, gain3, 00223 iBufferSize); 00224 } else if (totalActive == 4) { 00225 CSAMPLE* pBuffer1 = pChannel1->m_pBuffer; 00226 double gain1 = pGainCalculator->getGain(pChannel1); 00227 CSAMPLE* pBuffer2 = pChannel2->m_pBuffer; 00228 double gain2 = pGainCalculator->getGain(pChannel2); 00229 CSAMPLE* pBuffer3 = pChannel3->m_pBuffer; 00230 double gain3 = pGainCalculator->getGain(pChannel3); 00231 CSAMPLE* pBuffer4 = pChannel4->m_pBuffer; 00232 double gain4 = pGainCalculator->getGain(pChannel4); 00233 SampleUtil::copy4WithGain(pOutput, 00234 pBuffer1, gain1, 00235 pBuffer2, gain2, 00236 pBuffer3, gain3, 00237 pBuffer4, gain4, 00238 iBufferSize); 00239 } else if (totalActive == 5) { 00240 CSAMPLE* pBuffer1 = pChannel1->m_pBuffer; 00241 double gain1 = pGainCalculator->getGain(pChannel1); 00242 CSAMPLE* pBuffer2 = pChannel2->m_pBuffer; 00243 double gain2 = pGainCalculator->getGain(pChannel2); 00244 CSAMPLE* pBuffer3 = pChannel3->m_pBuffer; 00245 double gain3 = pGainCalculator->getGain(pChannel3); 00246 CSAMPLE* pBuffer4 = pChannel4->m_pBuffer; 00247 double gain4 = pGainCalculator->getGain(pChannel4); 00248 CSAMPLE* pBuffer5 = pChannel5->m_pBuffer; 00249 double gain5 = pGainCalculator->getGain(pChannel5); 00250 00251 SampleUtil::copy5WithGain(pOutput, 00252 pBuffer1, gain1, 00253 pBuffer2, gain2, 00254 pBuffer3, gain3, 00255 pBuffer4, gain4, 00256 pBuffer5, gain5, 00257 iBufferSize); 00258 } else if (totalActive == 6) { 00259 CSAMPLE* pBuffer1 = pChannel1->m_pBuffer; 00260 double gain1 = pGainCalculator->getGain(pChannel1); 00261 CSAMPLE* pBuffer2 = pChannel2->m_pBuffer; 00262 double gain2 = pGainCalculator->getGain(pChannel2); 00263 CSAMPLE* pBuffer3 = pChannel3->m_pBuffer; 00264 double gain3 = pGainCalculator->getGain(pChannel3); 00265 CSAMPLE* pBuffer4 = pChannel4->m_pBuffer; 00266 double gain4 = pGainCalculator->getGain(pChannel4); 00267 CSAMPLE* pBuffer5 = pChannel5->m_pBuffer; 00268 double gain5 = pGainCalculator->getGain(pChannel5); 00269 CSAMPLE* pBuffer6 = pChannel6->m_pBuffer; 00270 double gain6 = pGainCalculator->getGain(pChannel6); 00271 SampleUtil::copy6WithGain(pOutput, 00272 pBuffer1, gain1, 00273 pBuffer2, gain2, 00274 pBuffer3, gain3, 00275 pBuffer4, gain4, 00276 pBuffer5, gain5, 00277 pBuffer6, gain6, 00278 iBufferSize); 00279 } else if (totalActive == 7) { 00280 CSAMPLE* pBuffer1 = pChannel1->m_pBuffer; 00281 double gain1 = pGainCalculator->getGain(pChannel1); 00282 CSAMPLE* pBuffer2 = pChannel2->m_pBuffer; 00283 double gain2 = pGainCalculator->getGain(pChannel2); 00284 CSAMPLE* pBuffer3 = pChannel3->m_pBuffer; 00285 double gain3 = pGainCalculator->getGain(pChannel3); 00286 CSAMPLE* pBuffer4 = pChannel4->m_pBuffer; 00287 double gain4 = pGainCalculator->getGain(pChannel4); 00288 CSAMPLE* pBuffer5 = pChannel5->m_pBuffer; 00289 double gain5 = pGainCalculator->getGain(pChannel5); 00290 CSAMPLE* pBuffer6 = pChannel6->m_pBuffer; 00291 double gain6 = pGainCalculator->getGain(pChannel6); 00292 CSAMPLE* pBuffer7 = pChannel7->m_pBuffer; 00293 double gain7 = pGainCalculator->getGain(pChannel7); 00294 SampleUtil::copy7WithGain(pOutput, 00295 pBuffer1, gain1, 00296 pBuffer2, gain2, 00297 pBuffer3, gain3, 00298 pBuffer4, gain4, 00299 pBuffer5, gain5, 00300 pBuffer6, gain6, 00301 pBuffer7, gain7, 00302 iBufferSize); 00303 } else { 00304 // Set pOutput to all 0s 00305 SampleUtil::applyGain(pOutput, 0.0f, iBufferSize); 00306 00307 for (unsigned int i = 0; i < maxChannels; ++i) { 00308 if (channelBitvector & (1 << i)) { 00309 ChannelInfo* pChannelInfo = m_channels[i]; 00310 CSAMPLE* pBuffer = pChannelInfo->m_pBuffer; 00311 double gain = pGainCalculator->getGain(pChannelInfo); 00312 SampleUtil::addWithGain(pOutput, pBuffer, gain, iBufferSize); 00313 } 00314 } 00315 } 00316 } 00317 00318 void EngineMaster::process(const CSAMPLE *, const CSAMPLE *pOut, const int iBufferSize) 00319 { 00320 CSAMPLE **pOutput = (CSAMPLE**)pOut; 00321 Q_UNUSED(pOutput); 00322 00323 // Prepare each channel for output 00324 00325 // Bitvector of enabled channels 00326 const unsigned int maxChannels = 32; 00327 unsigned int masterOutput = 0; 00328 unsigned int headphoneOutput = 0; 00329 00330 // Compute headphone mix 00331 // Head phone left/right mix 00332 float cf_val = head_mix->get(); 00333 float chead_gain = 0.5*(-cf_val+1.); 00334 float cmaster_gain = 0.5*(cf_val+1.); 00335 // qDebug() << "head val " << cf_val << ", head " << chead_gain 00336 // << ", master " << cmaster_gain; 00337 00338 QList<ChannelInfo*>::iterator it = m_channels.begin(); 00339 for (unsigned int channel_number = 0; 00340 it != m_channels.end(); ++it, ++channel_number) { 00341 ChannelInfo* pChannelInfo = *it; 00342 EngineChannel* pChannel = pChannelInfo->m_pChannel; 00343 00344 if (!pChannel->isActive()) { 00345 continue; 00346 } 00347 00348 bool needsProcessing = false; 00349 if (pChannel->isMaster()) { 00350 masterOutput |= (1 << channel_number); 00351 needsProcessing = true; 00352 } 00353 00354 // If the channel is enabled for previewing in headphones, copy it 00355 // over to the headphone buffer 00356 if (pChannel->isPFL()) { 00357 headphoneOutput |= (1 << channel_number); 00358 needsProcessing = true; 00359 } 00360 00361 // Process the buffer if necessary 00362 if (needsProcessing) { 00363 pChannel->process(NULL, pChannelInfo->m_pBuffer, iBufferSize); 00364 } 00365 } 00366 00367 // Mix all the enabled headphone channels together. 00368 m_headphoneGain.setGain(chead_gain); 00369 mixChannels(headphoneOutput, maxChannels, m_pHead, iBufferSize, &m_headphoneGain); 00370 00371 // Calculate the crossfader gains for left and right side of the crossfader 00372 float c1_gain, c2_gain; 00373 EngineXfader::getXfadeGains(c1_gain, c2_gain, 00374 crossfader->get(), xFaderCurve->get(), 00375 xFaderCalibration->get()); 00376 00377 // Now set the gains for overall volume and the left, center, right gains. 00378 m_masterGain.setGains(m_pMasterVolume->get(), c1_gain, 1.0, c2_gain); 00379 00380 // Perform the master mix 00381 mixChannels(masterOutput, maxChannels, m_pMaster, iBufferSize, &m_masterGain); 00382 00383 #ifdef __LADSPA__ 00384 // LADPSA master effects 00385 ladspa->process(m_pMaster, m_pMaster, iBufferSize); 00386 #endif 00387 00388 // Clipping 00389 clipping->process(m_pMaster, m_pMaster, iBufferSize); 00390 00391 // Balance values 00392 float balright = 1.; 00393 float balleft = 1.; 00394 float bal = m_pBalance->get(); 00395 if (bal>0.) 00396 balleft -= bal; 00397 else if (bal<0.) 00398 balright += bal; 00399 00400 // Perform balancing on main out 00401 SampleUtil::applyAlternatingGain(m_pMaster, balleft, balright, iBufferSize); 00402 00403 // Update VU meter (it does not return anything). Needs to be here so that 00404 // master balance is reflected in the VU meter. 00405 if (vumeter != NULL) 00406 vumeter->process(m_pMaster, m_pMaster, iBufferSize); 00407 00408 //Submit master samples to the side chain to do shoutcasting, recording, 00409 //etc. (cpu intensive non-realtime tasks) 00410 sidechain->submitSamples(m_pMaster, iBufferSize); 00411 00412 // Add master to headphone with appropriate gain 00413 SampleUtil::addWithGain(m_pHead, m_pMaster, cmaster_gain, iBufferSize); 00414 00415 // Head volume and clipping 00416 SampleUtil::applyGain(m_pHead, m_pHeadVolume->get(), iBufferSize); 00417 head_clipping->process(m_pHead, m_pHead, iBufferSize); 00418 00419 //Master/headphones interleaving is now done in 00420 //SoundManager::requestBuffer() - Albert Nov 18/07 00421 00422 // Schedule a ControlObject sync 00423 m_pSyncWorker->schedule(); 00424 00425 // We're close to the end of the callback. Wake up the engine worker 00426 // scheduler so that it runs the workers. 00427 m_pWorkerScheduler->runWorkers(); 00428 } 00429 00430 void EngineMaster::addChannel(EngineChannel* pChannel) { 00431 ChannelInfo* pChannelInfo = new ChannelInfo(); 00432 pChannelInfo->m_pChannel = pChannel; 00433 pChannelInfo->m_pVolumeControl = new ControlLogpotmeter( 00434 ConfigKey(pChannel->getGroup(), "volume"), 1.0); 00435 pChannelInfo->m_pBuffer = SampleUtil::alloc(MAX_BUFFER_LEN); 00436 SampleUtil::applyGain(pChannelInfo->m_pBuffer, 0, MAX_BUFFER_LEN); 00437 m_channels.push_back(pChannelInfo); 00438 00439 EngineBuffer* pBuffer = pChannelInfo->m_pChannel->getEngineBuffer(); 00440 if (pBuffer != NULL) { 00441 pBuffer->bindWorkers(m_pWorkerScheduler); 00442 } 00443 00444 // TODO(XXX) WARNING HUGE HACK ALERT In the case of 2-decks, this code hooks 00445 // the two EngineBuffers together so they can beat-sync off of each other. 00446 // rryan 6/2010 00447 bool isDeck1 = pChannel->getGroup() == "[Channel1]"; 00448 bool isDeck2 = pChannel->getGroup() == "[Channel2]"; 00449 if (isDeck1 || isDeck2) { 00450 QString otherGroup = isDeck1 ? "[Channel2]" : "[Channel1]"; 00451 for (QList<ChannelInfo*>::const_iterator i = m_channels.constBegin(); 00452 i != m_channels.constEnd(); ++i) { 00453 const ChannelInfo* pChannelInfo = *i; 00454 if (pChannelInfo->m_pChannel->getGroup() == otherGroup) { 00455 EngineBuffer *pBuffer1 = pChannel->getEngineBuffer(); 00456 EngineBuffer *pBuffer2 = pChannelInfo->m_pChannel->getEngineBuffer(); 00457 if (pBuffer1 != NULL && pBuffer2 != NULL) { 00458 pBuffer1->setOtherEngineBuffer(pBuffer2); 00459 pBuffer2->setOtherEngineBuffer(pBuffer1); 00460 } 00461 } 00462 } 00463 } 00464 } 00465 00466 const CSAMPLE* EngineMaster::getDeckBuffer(unsigned int i) const { 00467 return getChannelBuffer(QString("[Channel%1]").arg(i+1)); 00468 } 00469 00470 const CSAMPLE* EngineMaster::getChannelBuffer(QString group) const { 00471 for (QList<ChannelInfo*>::const_iterator i = m_channels.constBegin(); 00472 i != m_channels.constEnd(); ++i) { 00473 const ChannelInfo* pChannelInfo = *i; 00474 if (pChannelInfo->m_pChannel->getGroup() == group) { 00475 return pChannelInfo->m_pBuffer; 00476 } 00477 } 00478 return NULL; 00479 } 00480 00481 const CSAMPLE* EngineMaster::buffer(AudioOutput output) const { 00482 switch (output.getType()) { 00483 case AudioOutput::MASTER: 00484 return getMasterBuffer(); 00485 break; 00486 case AudioOutput::HEADPHONES: 00487 return getHeadphoneBuffer(); 00488 break; 00489 case AudioOutput::DECK: 00490 return getDeckBuffer(output.getIndex()); 00491 break; 00492 default: 00493 return NULL; 00494 } 00495 }