![]() |
Mixxx
|
00001 /*************************************************************************** 00002 dlgmidilearning.cpp - description 00003 ------------------- 00004 begin : Mon March 2 2009 00005 copyright : (C) 2009 by Albert Santoni 00006 email : alberts at mixxx dot org 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 "dlgmidilearning.h" 00019 #include "mixxxcontrol.h" 00020 #include "midi/midimessage.h" 00021 #include "midi/midimapping.h" 00022 00023 DlgMidiLearning::DlgMidiLearning(QWidget * parent, MidiMapping* mapping) : QDialog(parent), Ui::DlgMidiLearning() 00024 { 00025 setupUi(this); 00026 m_pMidiMapping = mapping; 00027 labelMappedTo->setText(""); 00028 iCurrentControl = 0; 00029 stackedWidget->setCurrentIndex(0); //Ensure the first page is always shown regardless 00030 //of the last page shown when the .ui file was saved. 00031 00032 //Delete this dialog when its closed. We don't want any persistence. 00033 QWidget::setAttribute(Qt::WA_DeleteOnClose); 00034 00035 m_pSkipShortcut = new QShortcut(QKeySequence(Qt::Key_Space), this); 00036 connect(m_pSkipShortcut, SIGNAL(triggered()), pushButtonSkip, SLOT(click())); 00037 //pushButtonSkip->setShortcut(QKeySequence(Qt::Key_Space)); 00038 00039 connect(pushButtonBegin, SIGNAL(clicked()), this, SLOT(begin())); 00040 connect(pushButtonSkip, SIGNAL(clicked()), this, SLOT(next())); 00041 connect(pushButtonPrevious, SIGNAL(clicked()), this, SLOT(prev())); 00042 connect(m_pMidiMapping, SIGNAL(midiLearningFinished(MidiMessage)), this, SLOT(controlMapped(MidiMessage))); 00043 connect(pushButtonFinish, SIGNAL(clicked()), this, SLOT(close())); 00044 00045 00046 // Master Controls 00047 setupControl("[Master]", "crossfader", tr("Crossfader")); 00048 setupControl("[Master]", "volume", tr("Master volume")); 00049 setupControl("[Master]", "balance", tr("Master balance")); 00050 setupControl("[Master]", "headVolume", tr("Headphones volume")); 00051 setupControl("[Master]", "headMix", tr("Headphones mix (pre/main)")); 00052 00053 // Deck Controls 00054 setupDeckControl("cue_default", tr("Cue button for Player %1")); 00055 setupDeckControl("play", tr("Play button for Player %1")); 00056 setupDeckControl("back", tr("Fast rewind button for Player %1")); 00057 setupDeckControl("fwd", tr("Fast forward button for Player %1")); 00058 setupDeckControl("reverse", tr("Play reverse button for Player %1")); 00059 setupDeckControl("pfl", tr("Headphone listen button for Player %1")); 00060 setupDeckControl("beatsync", tr("Beat sync button for Player %1")); 00061 setupDeckControl("bpm", tr("BPM tap button for Player %1")); 00062 setupDeckControl("keylock", tr("Keylock button for Player %1")); 00063 setupDeckControl("rate", tr("Pitch control slider for Player %1")); 00064 setupDeckControl("flanger", tr("Flanger effect button for Player %1")); 00065 setupDeckControl("volume", tr("Channel %1 volume fader")); 00066 setupDeckControl("pregain", tr("Gain knob for Channel %1")); 00067 setupDeckControl("filterHigh", tr("High EQ knob for Channel %1")); 00068 setupDeckControl("filterMid", tr("Mid EQ knob for Channel %1")); 00069 setupDeckControl("filterLow", tr("Low EQ knob for Channel %1")); 00070 setupDeckControl("loop_in", tr("Loop In button for Player %1")); 00071 setupDeckControl("loop_out", tr("Loop Out button for Player %1")); 00072 setupDeckControl("reloop_exit", tr("Reloop / Exit button for Player %1")); 00073 setupDeckControl("beatloop_4", tr("Setup a loop over 4 beats for Player %1")); 00074 setupDeckControl("loop_halve", tr("Halves the current loop's length for Player %1")); 00075 setupDeckControl("loop_double", tr("Doubles the current loop's length for Player %1")); 00076 setupDeckControl("hotcue_1_activate", tr("Hotcue 1 button for Player %1")); 00077 setupDeckControl("hotcue_2_activate", tr("Hotcue 2 button for Player %1")); 00078 setupDeckControl("hotcue_3_activate", tr("Hotcue 3 button for Player %1")); 00079 setupDeckControl("hotcue_4_activate", tr("Hotcue 4 button for Player %1")); 00080 setupDeckControl("hotcue_1_clear", tr("Hotcue 1 delete button for Player %1")); 00081 setupDeckControl("hotcue_2_clear", tr("Hotcue 2 delete button for Player %1")); 00082 setupDeckControl("hotcue_3_clear", tr("Hotcue 3 delete button for Player %1")); 00083 setupDeckControl("hotcue_4_clear", tr("Hotcue 4 delete button for Player %1")); 00084 00085 setupSamplerControl("play", tr("Play button for Sampler %1")); 00086 setupSamplerControl("pregain", tr("Gain knob for Sampler %1")); 00087 setupSamplerControl("pfl", tr("Headphone listen button for Sampler %1")); 00088 setupSamplerControl("bpm", tr("BPM tap button for Sampler %1")); 00089 setupSamplerControl("keylock", tr("Keylock button for Sampler %1")); 00090 setupSamplerControl("rate", tr("Pitch control slider for Sampler %1")); 00091 setupSamplerControl("hotcue_1_activate", tr("Hotcue 1 button for Sampler %1")); 00092 setupSamplerControl("hotcue_2_activate", tr("Hotcue 2 button for Sampler %1")); 00093 setupSamplerControl("hotcue_3_activate", tr("Hotcue 3 button for Sampler %1")); 00094 setupSamplerControl("hotcue_4_activate", tr("Hotcue 4 button for Sampler %1")); 00095 setupSamplerControl("hotcue_1_clear", tr("Hotcue 1 delete button for Sampler %1")); 00096 setupSamplerControl("hotcue_2_clear", tr("Hotcue 2 delete button for Sampler %1")); 00097 setupSamplerControl("hotcue_3_clear", tr("Hotcue 3 delete button for Sampler %1")); 00098 setupSamplerControl("hotcue_4_clear", tr("Hotcue 4 delete button for Sampler %1")); 00099 00100 // Library Controls 00101 setupControl("[Playlist]", "SelectNextPlaylist", tr("Switch to the next view (library, playlist..)")); 00102 setupControl("[Playlist]", "SelectPrevPlaylist", tr("Switch to the previous view (library, playlist..)")); 00103 setupControl("[Playlist]", "SelectNextTrack", tr("Scroll to next track in library/playlist")); 00104 setupControl("[Playlist]", "SelectPrevTrack", tr("Scroll to previous track in library/playlist")); 00105 setupControl("[Playlist]", "LoadSelectedIntoFirstStopped", tr("Load selected track into first stopped player")); 00106 setupDeckControl("LoadSelectedTrack", tr("Load selected track into Player %1")); 00107 00108 // Flanger Controls 00109 setupControl("[Flanger]", "lfoPeriod", tr("Adjusts the wavelength of the flange effect")); 00110 setupControl("[Flanger]", "lfoDepth", tr("Adjusts the intensity of the flange effect")); 00111 setupControl("[Flanger]", "lfoDelay", tr("Adjusts the phase delay of the flange effect")); 00112 00113 // Microphone Controls 00114 setupControl("[Microphone]", "talkover", tr("Microphone on/off")); 00115 setupControl("[Microphone]", "volume", tr("Microphone volume")); 00116 } 00117 00118 void DlgMidiLearning::setupControl(QString group, QString control, QString description) { 00119 m_controlsToBind.append(qMakePair(MixxxControl(group, control), description)); 00120 } 00121 00122 void DlgMidiLearning::setupDeckControl(QString control, QString description) { 00123 // TODO(rryan) get this from the PlayerManager 00124 const int iNumDecks = 2; 00125 for (int i = 1; i <= iNumDecks; ++i) { 00126 QString group = QString("[Channel%1]").arg(i); 00127 m_controlsToBind.append(qMakePair(MixxxControl(group, control), description.arg(i))); 00128 } 00129 } 00130 00131 void DlgMidiLearning::setupSamplerControl(QString control, QString description) { 00132 // TODO(rryan) get this from the PlayerManager 00133 const int iNumSamplers = 4; 00134 for (int i = 1; i <= iNumSamplers; ++i) { 00135 QString group = QString("[Sampler%1]").arg(i); 00136 m_controlsToBind.append(qMakePair(MixxxControl(group, control), description.arg(i))); 00137 } 00138 } 00139 00140 DlgMidiLearning::~DlgMidiLearning() 00141 { 00142 //If there was any ongoing learning, cancel it (benign if there wasn't). 00143 m_pMidiMapping->cancelMidiLearn(); 00144 00145 delete m_pSkipShortcut; 00146 } 00147 00148 void DlgMidiLearning::begin() 00149 { 00150 //Switch pages in the stacked widget so that we show the mapping stuff. 00151 stackedWidget->setCurrentIndex(1); 00152 00153 //Tell the MIDI mapping to start learning the first control. 00154 iCurrentControl = 0; 00155 QPair<MixxxControl, QString>& control = m_controlsToBind[iCurrentControl]; 00156 m_pMidiMapping->beginMidiLearn(control.first); 00157 labelMixxxControl->setText(control.second); 00158 } 00159 00160 void DlgMidiLearning::next() 00161 { 00162 iCurrentControl++; 00163 if (iCurrentControl < m_controlsToBind.size()) 00164 { 00165 00166 QPair<MixxxControl, QString>& control = m_controlsToBind[iCurrentControl]; 00167 m_pMidiMapping->beginMidiLearn(control.first); 00168 labelMixxxControl->setText(control.second); 00169 pushButtonSkip->setText(tr("Skip")); 00170 00171 labelMappedTo->setText(""); 00172 pushButtonPrevious->setEnabled(true); 00173 } 00174 else 00175 { 00176 //We've hit the end, show the congrats pane 00177 stackedWidget->setCurrentIndex(2); 00178 } 00179 } 00180 00181 void DlgMidiLearning::prev() 00182 { 00183 iCurrentControl--; 00184 if (iCurrentControl >= 0) 00185 { 00186 QPair<MixxxControl, QString>& control = m_controlsToBind[iCurrentControl]; 00187 m_pMidiMapping->beginMidiLearn(control.first); 00188 labelMixxxControl->setText(control.second); 00189 pushButtonSkip->setText(tr("Skip")); 00190 labelMappedTo->setText(""); 00191 00192 //We've hit the start, don't let the user go back anymore. 00193 if (iCurrentControl == 0) 00194 pushButtonPrevious->setEnabled(false); 00195 } 00196 00197 } 00198 00200 void DlgMidiLearning::controlMapped(MidiMessage message) 00201 { 00202 //QThread::sleep(1); 00203 00204 labelMappedTo->setText(tr("Successfully mapped to: ") + message.toString()); 00205 00206 //Set the label on the "Skip" button to "Next" because we're proceeding 00207 //instead of "skipping" now. Makes more sense, I think... 00208 pushButtonSkip->setText(tr("Next")); 00209 //next(); 00210 }