![]() |
Mixxx
|
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 }