void ControlDoublePrivate::initialize(double defaultValue) { double value = defaultValue; if (m_bPersistInConfiguration) { UserSettingsPointer pConfig = ControlDoublePrivate::s_pUserConfig; if (pConfig != nullptr) { value = pConfig->getValue(m_key, defaultValue); } } m_defaultValue.setValue(defaultValue); m_value.setValue(value); //qDebug() << "Creating:" << m_trackKey << "at" << &m_value << sizeof(m_value); if (m_bTrack) { // TODO(rryan): Make configurable. m_trackKey = "control " + m_key.group + "," + m_key.item; Stat::track(m_trackKey, static_cast<Stat::StatType>(m_trackType), static_cast<Stat::ComputeFlags>(m_trackFlags), m_value.getValue()); } }
Library::Library( QObject* parent, UserSettingsPointer pConfig, mixxx::DbConnectionPoolPtr pDbConnectionPool, PlayerManagerInterface* pPlayerManager, RecordingManager* pRecordingManager) : m_pConfig(pConfig), m_pDbConnectionPool(pDbConnectionPool), m_pSidebarModel(new SidebarModel(parent)), m_pTrackCollection(new TrackCollection(pConfig)), m_pLibraryControl(new LibraryControl(this)), m_pMixxxLibraryFeature(nullptr), m_pPlaylistFeature(nullptr), m_pCrateFeature(nullptr), m_pAnalysisFeature(nullptr), m_scanner(pDbConnectionPool, m_pTrackCollection, pConfig) { QSqlDatabase dbConnection = mixxx::DbConnectionPooled(m_pDbConnectionPool); // TODO(XXX): Add a checkbox in the library preferences for checking // and repairing the database on the next restart of the application. if (pConfig->getValue(kConfigKeyRepairDatabaseOnNextRestart, false)) { kLogger.info() << "Checking and repairing database (if necessary)"; m_pTrackCollection->repairDatabase(dbConnection); // Reset config value pConfig->setValue(kConfigKeyRepairDatabaseOnNextRestart, false); } kLogger.info() << "Connecting database"; m_pTrackCollection->connectDatabase(dbConnection); qRegisterMetaType<Library::RemovalType>("Library::RemovalType"); m_pKeyNotation.reset(new ControlObject(ConfigKey(kConfigGroup, "key_notation"))); connect(&m_scanner, SIGNAL(scanStarted()), this, SIGNAL(scanStarted())); connect(&m_scanner, SIGNAL(scanFinished()), this, SIGNAL(scanFinished())); // Refresh the library models when the library (re)scan is finished. connect(&m_scanner, SIGNAL(scanFinished()), this, SLOT(slotRefreshLibraryModels())); // TODO(rryan) -- turn this construction / adding of features into a static // method or something -- CreateDefaultLibrary m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); addFeature(m_pMixxxLibraryFeature); addFeature(new AutoDJFeature(this, pConfig, pPlayerManager, m_pTrackCollection)); m_pPlaylistFeature = new PlaylistFeature(this, m_pTrackCollection, m_pConfig); addFeature(m_pPlaylistFeature); m_pCrateFeature = new CrateFeature(this, m_pTrackCollection, m_pConfig); addFeature(m_pCrateFeature); BrowseFeature* browseFeature = new BrowseFeature( this, pConfig, m_pTrackCollection, pRecordingManager); connect(browseFeature, SIGNAL(scanLibrary()), &m_scanner, SLOT(scan())); connect(&m_scanner, SIGNAL(scanStarted()), browseFeature, SLOT(slotLibraryScanStarted())); connect(&m_scanner, SIGNAL(scanFinished()), browseFeature, SLOT(slotLibraryScanFinished())); addFeature(browseFeature); addFeature(new RecordingFeature(this, pConfig, m_pTrackCollection, pRecordingManager)); addFeature(new SetlogFeature(this, pConfig, m_pTrackCollection)); m_pAnalysisFeature = new AnalysisFeature(this, pConfig, m_pTrackCollection); connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList<TrackId>)), m_pAnalysisFeature, SLOT(analyzeTracks(QList<TrackId>))); connect(m_pCrateFeature, SIGNAL(analyzeTracks(QList<TrackId>)), m_pAnalysisFeature, SLOT(analyzeTracks(QList<TrackId>))); addFeature(m_pAnalysisFeature); //iTunes and Rhythmbox should be last until we no longer have an obnoxious //messagebox popup when you select them. (This forces you to reach for your //mouse or keyboard if you're using MIDI control and you scroll through them...) if (RhythmboxFeature::isSupported() && pConfig->getValue(ConfigKey(kConfigGroup,"ShowRhythmboxLibrary"), true)) { addFeature(new RhythmboxFeature(this, m_pTrackCollection)); } if (pConfig->getValue(ConfigKey(kConfigGroup,"ShowBansheeLibrary"), true)) { BansheeFeature::prepareDbPath(pConfig); if (BansheeFeature::isSupported()) { addFeature(new BansheeFeature(this, m_pTrackCollection, pConfig)); } } if (ITunesFeature::isSupported() && pConfig->getValue(ConfigKey(kConfigGroup,"ShowITunesLibrary"), true)) { addFeature(new ITunesFeature(this, m_pTrackCollection)); } if (TraktorFeature::isSupported() && pConfig->getValue(ConfigKey(kConfigGroup,"ShowTraktorLibrary"), true)) { addFeature(new TraktorFeature(this, m_pTrackCollection)); } // On startup we need to check if all of the user's library folders are // accessible to us. If the user is using a database from <1.12.0 with // sandboxing then we will need them to give us permission. QStringList directories = m_pTrackCollection->getDirectoryDAO().getDirs(); qDebug() << "Checking for access to user's library directories:"; foreach (QString directoryPath, directories) { QFileInfo directory(directoryPath); bool hasAccess = Sandbox::askForAccess(directory.canonicalFilePath()); qDebug() << "Checking for access to" << directoryPath << ":" << hasAccess; }
EngineMaster::EngineMaster(UserSettingsPointer pConfig, const char* group, EffectsManager* pEffectsManager, bool bEnableSidechain, bool bRampingGain) : m_pEngineEffectsManager(pEffectsManager ? pEffectsManager->getEngineEffectsManager() : NULL), m_bRampingGain(bRampingGain), m_masterGainOld(0.0), m_boothGainOld(0.0), m_headphoneMasterGainOld(0.0), m_headphoneGainOld(1.0), m_masterHandle(registerChannelGroup("[Master]")), m_headphoneHandle(registerChannelGroup("[Headphone]")), m_busLeftHandle(registerChannelGroup("[BusLeft]")), m_busCenterHandle(registerChannelGroup("[BusCenter]")), m_busRightHandle(registerChannelGroup("[BusRight]")) { m_bBusOutputConnected[EngineChannel::LEFT] = false; m_bBusOutputConnected[EngineChannel::CENTER] = false; m_bBusOutputConnected[EngineChannel::RIGHT] = false; m_bExternalRecordBroadcastInputConnected = false; m_pWorkerScheduler = new EngineWorkerScheduler(this); m_pWorkerScheduler->start(QThread::HighPriority); if (pEffectsManager) { pEffectsManager->registerChannel(m_masterHandle); pEffectsManager->registerChannel(m_headphoneHandle); pEffectsManager->registerChannel(m_busLeftHandle); pEffectsManager->registerChannel(m_busCenterHandle); pEffectsManager->registerChannel(m_busRightHandle); } // Master sample rate m_pMasterSampleRate = new ControlObject(ConfigKey(group, "samplerate"), true, true); m_pMasterSampleRate->set(44100.); // Latency control m_pMasterLatency = new ControlObject(ConfigKey(group, "latency"), true, true); m_pMasterAudioBufferSize = new ControlObject(ConfigKey(group, "audio_buffer_size")); m_pAudioLatencyOverloadCount = new ControlObject(ConfigKey(group, "audio_latency_overload_count"), true, true); m_pAudioLatencyUsage = new ControlPotmeter(ConfigKey(group, "audio_latency_usage"), 0.0, 0.25); m_pAudioLatencyOverload = new ControlPotmeter(ConfigKey(group, "audio_latency_overload"), 0.0, 1.0); // Master sync controller m_pMasterSync = new EngineSync(pConfig); // The last-used bpm value is saved in the destructor of EngineSync. double default_bpm = pConfig->getValue( ConfigKey("[InternalClock]", "bpm"), 124.0); ControlObject::getControl(ConfigKey("[InternalClock]","bpm"))->set(default_bpm); // Crossfader m_pCrossfader = new ControlPotmeter(ConfigKey(group, "crossfader"), -1., 1.); // Balance m_pBalance = new ControlPotmeter(ConfigKey(group, "balance"), -1., 1.); // Master gain m_pMasterGain = new ControlAudioTaperPot(ConfigKey(group, "gain"), -14, 14, 0.5); // Booth gain m_pBoothGain = new ControlAudioTaperPot(ConfigKey(group, "booth_gain"), -14, 14, 0.5); // Legacy: the master "gain" control used to be named "volume" in Mixxx // 1.11.0 and earlier. See Bug #1306253. ControlDoublePrivate::insertAlias(ConfigKey(group, "volume"), ConfigKey(group, "gain")); // VU meter: m_pVumeter = new EngineVuMeter(group); m_pMasterDelay = new EngineDelay(group, ConfigKey(group, "delay")); m_pHeadDelay = new EngineDelay(group, ConfigKey(group, "headDelay")); m_pBoothDelay = new EngineDelay(group, ConfigKey(group, "boothDelay")); m_pLatencyCompensationDelay = new EngineDelay(group, ConfigKey(group, "microphoneLatencyCompensation")); m_pNumMicsConfigured = new ControlObject(ConfigKey(group, "num_mics_configured")); // Headphone volume m_pHeadGain = new ControlAudioTaperPot(ConfigKey(group, "headGain"), -14, 14, 0.5); // Legacy: the headphone "headGain" control used to be named "headVolume" in // Mixxx 1.11.0 and earlier. See Bug #1306253. ControlDoublePrivate::insertAlias(ConfigKey(group, "headVolume"), ConfigKey(group, "headGain")); // Headphone mix (left/right) m_pHeadMix = new ControlPotmeter(ConfigKey(group, "headMix"),-1.,1.); m_pHeadMix->setDefaultValue(-1.); m_pHeadMix->set(-1.); // Master / Headphone split-out mode (for devices with only one output). m_pHeadSplitEnabled = new ControlPushButton(ConfigKey(group, "headSplit")); m_pHeadSplitEnabled->setButtonMode(ControlPushButton::TOGGLE); m_pHeadSplitEnabled->set(0.0); m_pTalkoverDucking = new EngineTalkoverDucking(pConfig, group); // Allocate buffers m_pHead = SampleUtil::alloc(MAX_BUFFER_LEN); m_pMaster = SampleUtil::alloc(MAX_BUFFER_LEN); m_pBooth = SampleUtil::alloc(MAX_BUFFER_LEN); m_pTalkover = SampleUtil::alloc(MAX_BUFFER_LEN); m_pTalkoverHeadphones = SampleUtil::alloc(MAX_BUFFER_LEN); m_pSidechainMix = SampleUtil::alloc(MAX_BUFFER_LEN); SampleUtil::clear(m_pHead, MAX_BUFFER_LEN); SampleUtil::clear(m_pMaster, MAX_BUFFER_LEN); SampleUtil::clear(m_pBooth, MAX_BUFFER_LEN); SampleUtil::clear(m_pTalkover, MAX_BUFFER_LEN); SampleUtil::clear(m_pTalkoverHeadphones, MAX_BUFFER_LEN); SampleUtil::clear(m_pSidechainMix, MAX_BUFFER_LEN); // Setup the output buses for (int o = EngineChannel::LEFT; o <= EngineChannel::RIGHT; ++o) { m_pOutputBusBuffers[o] = SampleUtil::alloc(MAX_BUFFER_LEN); SampleUtil::clear(m_pOutputBusBuffers[o], MAX_BUFFER_LEN); } m_ppSidechainOutput = &m_pMaster; // Starts a thread for recording and broadcast m_pEngineSideChain = bEnableSidechain ? new EngineSideChain(pConfig) : NULL; // X-Fader Setup m_pXFaderMode = new ControlPushButton( ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderMode")); m_pXFaderMode->setButtonMode(ControlPushButton::TOGGLE); m_pXFaderCurve = new ControlPotmeter( ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderCurve"), EngineXfader::kTransformMin, EngineXfader::kTransformMax); m_pXFaderCalibration = new ControlPotmeter( ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderCalibration"), 0.3, 1., true); m_pXFaderReverse = new ControlPushButton( ConfigKey(EngineXfader::kXfaderConfigKey, "xFaderReverse")); m_pXFaderReverse->setButtonMode(ControlPushButton::TOGGLE); m_pKeylockEngine = new ControlObject(ConfigKey(group, "keylock_engine"), true, false, true); m_pKeylockEngine->set(pConfig->getValueString( ConfigKey(group, "keylock_engine")).toDouble()); // TODO: Make this read only and make EngineMaster decide whether // processing the master mix is necessary. m_pMasterEnabled = new ControlObject(ConfigKey(group, "enabled"), true, false, true); // persist = true m_pBoothEnabled = new ControlObject(ConfigKey(group, "booth_enabled")); m_pBoothEnabled->setReadOnly(); m_pMasterMonoMixdown = new ControlObject(ConfigKey(group, "mono_mixdown"), true, false, true); // persist = true m_pMicMonitorMode = new ControlObject(ConfigKey(group, "talkover_mix"), true, false, true); // persist = true m_pHeadphoneEnabled = new ControlObject(ConfigKey(group, "headEnabled")); m_pHeadphoneEnabled->setReadOnly(); // Note: the EQ Rack is set in EffectsManager::setupDefaults(); }