![]() |
Mixxx
|
00001 // QuantizeControl.cpp 00002 // Created on Sat 5, 2011 00003 // Author: pwhelan 00004 00005 #include <QtDebug> 00006 #include <QObject> 00007 00008 #include "controlobject.h" 00009 #include "configobject.h" 00010 #include "controlpushbutton.h" 00011 #include "cachingreader.h" 00012 #include "engine/quantizecontrol.h" 00013 #include "engine/enginecontrol.h" 00014 #include "mathstuff.h" 00015 00016 QuantizeControl::QuantizeControl(const char* pGroup, 00017 ConfigObject<ConfigValue>* pConfig) 00018 : EngineControl(pGroup, pConfig) { 00019 // Turn quantize OFF by default. See Bug #898213 00020 m_pCOQuantizeEnabled = new ControlPushButton(ConfigKey(pGroup, "quantize")); 00021 m_pCOQuantizeEnabled->setToggleButton(true); 00022 m_pCONextBeat = new ControlObject(ConfigKey(pGroup, "beat_next")); 00023 m_pCONextBeat->set(-1); 00024 m_pCOPrevBeat = new ControlObject(ConfigKey(pGroup, "beat_prev")); 00025 m_pCOPrevBeat->set(-1); 00026 m_pCOClosestBeat = new ControlObject(ConfigKey(pGroup, "beat_closest")); 00027 m_pCOClosestBeat->set(-1); 00028 } 00029 00030 QuantizeControl::~QuantizeControl() { 00031 delete m_pCOQuantizeEnabled; 00032 delete m_pCONextBeat; 00033 delete m_pCOPrevBeat; 00034 delete m_pCOClosestBeat; 00035 } 00036 00037 void QuantizeControl::trackLoaded(TrackPointer pTrack) { 00038 if (m_pTrack) { 00039 trackUnloaded(m_pTrack); 00040 } 00041 00042 if (pTrack) { 00043 m_pTrack = pTrack; 00044 m_pBeats = m_pTrack->getBeats(); 00045 connect(m_pTrack.data(), SIGNAL(beatsUpdated()), 00046 this, SLOT(slotBeatsUpdated())); 00047 } 00048 } 00049 00050 void QuantizeControl::trackUnloaded(TrackPointer pTrack) { 00051 if (m_pTrack) { 00052 disconnect(m_pTrack.data(), SIGNAL(beatsUpdated()), 00053 this, SLOT(slotBeatsUpdated())); 00054 } 00055 m_pTrack.clear(); 00056 m_pBeats.clear(); 00057 m_pCOPrevBeat->set(-1); 00058 m_pCONextBeat->set(-1); 00059 m_pCOClosestBeat->set(-1); 00060 } 00061 00062 void QuantizeControl::slotBeatsUpdated() { 00063 if (m_pTrack) { 00064 m_pBeats = m_pTrack->getBeats(); 00065 } 00066 } 00067 00068 double QuantizeControl::process(const double dRate, 00069 const double currentSample, 00070 const double totalSamples, 00071 const int iBufferSize) { 00072 int iCurrentSample = currentSample; 00073 if (!even(iCurrentSample)) { 00074 iCurrentSample--; 00075 } 00076 00077 if (!m_pBeats) { 00078 return kNoTrigger; 00079 } 00080 00081 double prevBeat = m_pCOPrevBeat->get(); 00082 double nextBeat = m_pCONextBeat->get(); 00083 double closestBeat = m_pCOClosestBeat->get(); 00084 double currentClosestBeat = 00085 floorf(m_pBeats->findClosestBeat(iCurrentSample)); 00086 00087 if (closestBeat != currentClosestBeat) { 00088 if (!even(currentClosestBeat)) { 00089 currentClosestBeat--; 00090 } 00091 m_pCOClosestBeat->set(currentClosestBeat); 00092 } 00093 00094 if (prevBeat == -1 || nextBeat == -1 || 00095 currentSample >= nextBeat || currentSample <= prevBeat) { 00096 // TODO(XXX) are the floor and even checks necessary? 00097 nextBeat = floorf(m_pBeats->findNextBeat(iCurrentSample)); 00098 prevBeat = floorf(m_pBeats->findPrevBeat(iCurrentSample)); 00099 00100 if (!even(nextBeat)) 00101 nextBeat--; 00102 if (!even(prevBeat)) 00103 prevBeat--; 00104 00105 m_pCONextBeat->set(nextBeat); 00106 m_pCOPrevBeat->set(prevBeat); 00107 } 00108 00109 return kNoTrigger; 00110 }