This patch (not to be confused with my Diff Sensitivity patch) implements a MIDI track selection knob.
On my controller, I have a track selection knob which reports a signed, relative number which should be interpreted as a number of clicks in a clockwise or counter-clockwise direction. (Depending on the sign.)
In order to implement a slot which behaves properly, I had to add a MIDI_OPT_SELECTKNOB which should be useful in any situation where a relative control's current position shouldn't be remembered from event to event.
My track selection knob also generates a button event if it is pressed down. Since this button does not specify a particular channel, I added a slotLoadSelectedIntoFirstStopped, which allows a MIDI button to behave like double-clicking a track in the library.
Since this patch only adds features to the codebase (instead of altering older features) I don't expect it to affect anything else. It _should_ be safe to commit.
Once Mixxx HEAD has all the code necessary to write a working MIDI mapping for the Numark Total Control, I'll be contributing a complete MIDI mapping which can be included in the next release. :)
ttyl -- Alex (Malex) Markley 740.927.3588 - http://MalexMedia.Net/ - http://SermonMP3s.com/
Index: src/configobject.h
===================================================================
--- src/configobject.h (revision 1900)
+++ src/configobject.h (working copy)
@@ -44,7 +44,8 @@
MIDI_OPT_BUTTON = 6, // Button Down (!=00) and Button Up (00) events happen together
MIDI_OPT_SWITCH = 7, // Button Down (!=00) and Button Up (00) events happen seperately
MIDI_OPT_HERC_JOG = 8, // Generic hercules wierd range correction
- MIDI_OPT_SPREAD64 = 9 // Accelerated difference from 64
+ MIDI_OPT_SPREAD64 = 9, // Accelerated difference from 64
+ MIDI_OPT_SELECTKNOB = 10,// Relative knob which can be turned forever and outputs a signed value.
} MidiOption;
typedef QMap<char,char> MidiValueMap;
Index: src/configobject.cpp
===================================================================
--- src/configobject.cpp (revision 1900)
+++ src/configobject.cpp (working copy)
@@ -179,6 +179,8 @@
midioption = MIDI_OPT_HERC_JOG;
else if (optname == "spread64")
midioption = MIDI_OPT_SPREAD64;
+ else if (optname == "selectknob")
+ midioption = MIDI_OPT_SELECTKNOB;
else {
qWarning() << "Unknown option:" << optname;
midioption = MIDI_OPT_NORMAL;
@@ -240,6 +242,8 @@
midioption = MIDI_OPT_HERC_JOG;
else if (option.contains("Spread64", false))
midioption = MIDI_OPT_SPREAD64;
+ else if (option.contains("SelectKnob", false))
+ midioption = MIDI_OPT_SELECTKNOB;
else
midioption = MIDI_OPT_NORMAL;
// Store string with corrected config value
@@ -293,6 +297,8 @@
value.append(" Diff");
else if (midioption == MIDI_OPT_SPREAD64)
value.append(" Spread64");
+ else if (midioption == MIDI_OPT_SELECTKNOB)
+ value.append(" SelectKnob");
qDebug() << "Config value:" << value;
//qDebug() << "--1, midino: " << midino << ", midimask: " << midimask << ", midichannel: " << midichannel;
@@ -361,6 +367,17 @@
_newmidivalue = _prevmidivalue + _newmidivalue;
}
}
+ else if (midioption == MIDI_OPT_SELECTKNOB)
+ {
+ //Interpret 7-bit signed value using two's compliment.
+ if (_newmidivalue >= 64.)
+ _newmidivalue = _newmidivalue - 128.;
+ //Apply sensitivity to signed value.
+ if(sensitivity > 0)
+ _newmidivalue = _newmidivalue * ((double)sensitivity / 50.);
+ //Since this is a selection knob, we do not want to inherit previous values.
+ return _newmidivalue;
+ }
else if (midioption == MIDI_OPT_BUTTON)
{
if (_newmidivalue != 0.) {
Index: src/track.h
===================================================================
--- src/track.h (revision 1900)
+++ src/track.h (working copy)
@@ -121,9 +121,11 @@
/** Slots for loading the selected track into players */
void slotLoadSelectedTrackCh1(double);
void slotLoadSelectedTrackCh2(double);
+ void slotLoadSelectedIntoFirstStopped(double);
/** Slots for moving the selection cursor in the track list */
void slotSelectNextTrack(double);
void slotSelectPrevTrack(double);
+ void slotSelectTrackKnob(double);
/** Returns pointer to active playlist */
TrackPlaylist *getActivePlaylist();
@@ -206,7 +208,7 @@
/** Pointer to ControlObject for next/prev buttons */
ControlObjectThreadMain *m_pNextTrackCh1, *m_pNextTrackCh2, *m_pPrevTrackCh1, *m_pPrevTrackCh2;
/** Pointer to ControlObject for playlist navigation/loading into Players */
- ControlObjectThreadMain *m_pLoadSelectedTrackCh1, *m_pLoadSelectedTrackCh2, *m_pSelectNextTrack, *m_pSelectPrevTrack;
+ ControlObjectThreadMain *m_pLoadSelectedTrackCh1, *m_pLoadSelectedTrackCh2, *m_pLoadSelectedIntoFirstStopped, *m_pSelectNextTrack, *m_pSelectPrevTrack, *m_pSelectTrackKnob;
/** Pointer to ControlObject for play position */
ControlObjectThreadMain *m_pPlayPositionCh1, *m_pPlayPositionCh2;
/** Pointer to waveform summary generator */
Index: src/track.cpp
===================================================================
--- src/track.cpp (revision 1900)
+++ src/track.cpp (working copy)
@@ -214,12 +214,16 @@
// Make controls for tracklist navigation and current track loading
m_pLoadSelectedTrackCh1 = new ControlObjectThreadMain(new ControlObject(ConfigKey("[Channel1]","LoadSelectedTrack")));
m_pLoadSelectedTrackCh2 = new ControlObjectThreadMain(new ControlObject(ConfigKey("[Channel2]","LoadSelectedTrack")));
+ m_pLoadSelectedIntoFirstStopped = new ControlObjectThreadMain(new ControlObject(ConfigKey("[Playlist]","LoadSelectedIntoFirstStopped")));
m_pSelectNextTrack = new ControlObjectThreadMain(new ControlObject(ConfigKey("[Playlist]","SelectNextTrack")));
m_pSelectPrevTrack = new ControlObjectThreadMain(new ControlObject(ConfigKey("[Playlist]","SelectPrevTrack")));
+ m_pSelectTrackKnob = new ControlObjectThreadMain(new ControlObject(ConfigKey("[Playlist]","SelectTrackKnob")));
connect(m_pLoadSelectedTrackCh1, SIGNAL(valueChanged(double)), this, SLOT(slotLoadSelectedTrackCh1(double)));
connect(m_pLoadSelectedTrackCh2, SIGNAL(valueChanged(double)), this, SLOT(slotLoadSelectedTrackCh2(double)));
+ connect(m_pLoadSelectedIntoFirstStopped, SIGNAL(valueChanged(double)), this, SLOT(slotLoadSelectedIntoFirstStopped(double)));
connect(m_pSelectNextTrack, SIGNAL(valueChanged(double)), this, SLOT(slotSelectNextTrack(double)));
connect(m_pSelectPrevTrack, SIGNAL(valueChanged(double)), this, SLOT(slotSelectPrevTrack(double)));
+ connect(m_pSelectTrackKnob, SIGNAL(valueChanged(double)), this, SLOT(slotSelectTrackKnob(double)));
TrackPlaylist::setTrack(this);
@@ -1147,11 +1151,22 @@
// Fetch the currently selected track
index = m_pView->m_pTrackTableView->m_pSearchFilter->mapToSource(m_pView->m_pTrackTableView->currentIndex());
pTrack = m_pView->m_pTrackTableView->m_pTable->m_pTrackPlaylist->getTrackAt(index.row());
- // If there is one, load it
+ // If there is one, load it
if (pTrack) slotLoadPlayer2(pTrack);
}
}
+void Track::slotLoadSelectedIntoFirstStopped(double v)
+{
+ if (v)
+ {
+ if (ControlObject::getControl(ConfigKey("[Channel1]","play"))->get()!=1.)
+ this->slotLoadSelectedTrackCh1(v);
+ else if (ControlObject::getControl(ConfigKey("[Channel2]","play"))->get()!=1.)
+ this->slotLoadSelectedTrackCh2(v);
+ }
+}
+
void Track::slotSelectNextTrack(double v)
{
// Only move on key presses
@@ -1164,6 +1179,24 @@
if (v) m_pView->m_pTrackTableView->selectPrevious();
}
+void Track::slotSelectTrackKnob(double v)
+{
+ int i = (int)v;
+ while(i != 0)
+ {
+ if(i > 0)
+ {
+ m_pView->m_pTrackTableView->selectNext();
+ i--;
+ }
+ else
+ {
+ m_pView->m_pTrackTableView->selectPrevious();
+ i++;
+ }
+ }
+}
+
void Track::slotNextTrackPlayer1(double v)
{
if (v && m_pTrackPlayer1)
patch_selectknob.patch.asc
Description: application/pgp-encrypted
------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________ Mixxx-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mixxx-devel
