Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/engine/vinylcontrolcontrol.cpp

Go to the documentation of this file.
00001 #include "engine/vinylcontrolcontrol.h"
00002 #include "mathstuff.h"
00003 #include "vinylcontrol/vinylcontrol.h"
00004 #include "library/dao/cue.h"
00005 
00006 VinylControlControl::VinylControlControl(const char* pGroup, ConfigObject<ConfigValue>* pConfig)
00007         : EngineControl(pGroup, pConfig) {
00008     m_pControlVinylStatus = new ControlObject(ConfigKey(pGroup, "vinylcontrol_status"));
00009     m_pControlVinylSpeedType = new ControlObject(ConfigKey(pGroup, "vinylcontrol_speed_type"));
00010 
00011     //Convert the ConfigKey's value into a double for the CO (for fast reads).
00012     QString strVinylSpeedType = pConfig->getValueString(ConfigKey(pGroup,
00013                                                       "vinylcontrol_speed_type"));
00014     if (strVinylSpeedType == MIXXX_VINYL_SPEED_33) {
00015         m_pControlVinylSpeedType->set(MIXXX_VINYL_SPEED_33_NUM);
00016     } else if (strVinylSpeedType == MIXXX_VINYL_SPEED_45) {
00017         m_pControlVinylSpeedType->set(MIXXX_VINYL_SPEED_45_NUM);
00018     } else {
00019         m_pControlVinylSpeedType->set(MIXXX_VINYL_SPEED_33_NUM);
00020     }
00021 
00022     m_pControlVinylSeek = new ControlObject(ConfigKey(pGroup, "vinylcontrol_seek"));
00023     connect(m_pControlVinylSeek, SIGNAL(valueChanged(double)),
00024             this, SLOT(slotControlVinylSeek(double)),
00025             Qt::DirectConnection);
00026 
00027     m_pControlVinylEnabled = new ControlPushButton(ConfigKey(pGroup, "vinylcontrol_enabled"));
00028     m_pControlVinylEnabled->set(0);
00029     m_pControlVinylEnabled->setToggleButton(true);
00030     m_pControlVinylWantEnabled = new ControlPushButton(ConfigKey(pGroup, "vinylcontrol_wantenabled"));
00031     m_pControlVinylWantEnabled->set(0);
00032     m_pControlVinylWantEnabled->setToggleButton(true);
00033     m_pControlVinylMode = new ControlPushButton(ConfigKey(pGroup, "vinylcontrol_mode"));
00034     m_pControlVinylMode->setStates(3);
00035     m_pControlVinylMode->setToggleButton(true);
00036     m_pControlVinylCueing = new ControlPushButton(ConfigKey(pGroup, "vinylcontrol_cueing"));
00037     m_pControlVinylCueing->setStates(3);
00038     m_pControlVinylCueing->setToggleButton(true);
00039     m_pControlVinylSignalEnabled = new ControlPushButton(ConfigKey(pGroup, "vinylcontrol_signal_enabled"));
00040     m_pControlVinylSignalEnabled->set(1);
00041     m_pControlVinylSignalEnabled->setToggleButton(true);
00042 }
00043 
00044 VinylControlControl::~VinylControlControl() {
00045     delete m_pControlVinylSeek;
00046     delete m_pControlVinylStatus;
00047     delete m_pControlVinylSpeedType;
00048     delete m_pControlVinylEnabled;
00049     delete m_pControlVinylMode;
00050     delete m_pControlVinylCueing;
00051 }
00052 
00053 void VinylControlControl::trackLoaded(TrackPointer pTrack) {
00054     m_pCurrentTrack = pTrack;
00055 }
00056 
00057 void VinylControlControl::trackUnloaded(TrackPointer pTrack) {
00058     m_pCurrentTrack.clear();
00059 }
00060 
00061 void VinylControlControl::slotControlVinylSeek(double change) {
00062     if(isnan(change) || change > 1.14 || change < -1.14) {
00063         // This seek is ridiculous.
00064         return;
00065     }
00066 
00067     double total_samples = getTotalSamples();
00068     double new_playpos = round(change*total_samples);
00069 
00070     // Do nothing if no track is loaded.
00071     if (!m_pCurrentTrack) {
00072         return;
00073     }
00074 
00075     if (m_pControlVinylEnabled->get() > 0.0 && m_pControlVinylMode->get() == MIXXX_VCMODE_RELATIVE) {
00076         int cuemode = (int)m_pControlVinylCueing->get();
00077 
00078         //if in preroll, always seek
00079         if (new_playpos < 0) {
00080             emit(seek(change));
00081             return;
00082         } else if (cuemode == MIXXX_RELATIVE_CUE_OFF) {
00083             return;  //if off, do nothing
00084         } else if (cuemode == MIXXX_RELATIVE_CUE_ONECUE) {
00085             //if onecue, just seek to the regular cue
00086             emit(seekAbs(m_pCurrentTrack->getCuePoint()));
00087             return;
00088         }
00089 
00090         double distance = 0;
00091         int nearest_playpos = -1;
00092 
00093         QList<Cue*> cuePoints = m_pCurrentTrack->getCuePoints();
00094         QListIterator<Cue*> it(cuePoints);
00095         while (it.hasNext()) {
00096             Cue* pCue = it.next();
00097             if (pCue->getType() != Cue::CUE || pCue->getHotCue() == -1) {
00098                 continue;
00099             }
00100 
00101             int cue_position = pCue->getPosition();
00102             //pick cues closest to new_playpos
00103             if ((nearest_playpos == -1) ||
00104                 (fabs(new_playpos - cue_position) < distance)) {
00105                 nearest_playpos = cue_position;
00106                 distance = fabs(new_playpos - cue_position);
00107             }
00108         }
00109 
00110         if (nearest_playpos == -1) {
00111             if (new_playpos >= 0) {
00112                 //never found an appropriate cue, so don't seek?
00113                 return;
00114             }
00115             //if negative, allow a seek by falling down to the bottom
00116         } else {
00117             emit(seekAbs(nearest_playpos));
00118             return;
00119         }
00120     }
00121 
00122     // just seek where it wanted to originally
00123     emit(seek(change));
00124 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines