Skip to content

Commit

Permalink
Automatically assign a midi input device to the selected track (#5499)
Browse files Browse the repository at this point in the history
  • Loading branch information
LNooteboom authored Jun 21, 2020
1 parent 82f4135 commit 5d7e672
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/InstrumentTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor
return m_previewMode;
}

void autoAssignMidiDevice( bool );

signals:
void instrumentChanged();
void midiNoteOn( const Note& );
Expand Down Expand Up @@ -260,6 +262,9 @@ protected slots:

bool m_previewMode;

bool m_hasAutoMidiDev;
static InstrumentTrack *s_autoAssignedTrack;

IntModel m_baseNoteModel;

NotePlayHandleList m_processHandles;
Expand Down
1 change: 1 addition & 0 deletions include/PianoRoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ class PianoRoll : public QWidget
void resizeEvent( QResizeEvent * re ) override;
void wheelEvent( QWheelEvent * we ) override;
void focusOutEvent( QFocusEvent * ) override;
void focusInEvent( QFocusEvent * ) override;

int getKey( int y ) const;
void drawNoteRect( QPainter & p, int x, int y,
Expand Down
1 change: 1 addition & 0 deletions include/PianoView.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class PianoView : public QWidget, public ModelView
void mouseReleaseEvent( QMouseEvent * me ) override;
void mouseMoveEvent( QMouseEvent * me ) override;
void focusOutEvent( QFocusEvent * _fe ) override;
void focusInEvent( QFocusEvent * fe ) override;
void resizeEvent( QResizeEvent * _event ) override;


Expand Down
1 change: 1 addition & 0 deletions include/SetupDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ private slots:
QComboBox * m_midiInterfaces;
MswMap m_midiIfaceSetupWidgets;
trMap m_midiIfaceNames;
QComboBox * m_assignableMidiDevices;

// Paths settings widgets.
QString m_workingDir;
Expand Down
7 changes: 7 additions & 0 deletions src/gui/PianoView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,17 @@ void PianoView::focusOutEvent( QFocusEvent * )
m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOff, -1, i, 0 ) );
m_piano->setKeyState( i, false );
}


update();
}


void PianoView::focusInEvent( QFocusEvent * )
{
m_piano->instrumentTrack()->autoAssignMidiDevice(true);
}



/*! \brief update scrollbar range after resize
Expand Down
25 changes: 25 additions & 0 deletions src/gui/SetupDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,9 +677,32 @@ SetupDialog::SetupDialog(ConfigTabs tab_to_open) :
this, SLOT(midiInterfaceChanged(const QString &)));


// MIDI autoassign tab.
TabWidget * midiAutoAssign_tw = new TabWidget(
tr("Automatically assign MIDI controller to selected track"), midi_w);
midiAutoAssign_tw->setFixedHeight(56);

m_assignableMidiDevices = new QComboBox(midiAutoAssign_tw);
m_assignableMidiDevices->setGeometry(10, 20, 240, 28);
m_assignableMidiDevices->addItem("none");
if ( !Engine::mixer()->midiClient()->isRaw() )
{
m_assignableMidiDevices->addItems(Engine::mixer()->midiClient()->readablePorts());
}
else
{
m_assignableMidiDevices->addItem("all");
}
int current = m_assignableMidiDevices->findText(ConfigManager::inst()->value("midi", "midiautoassign"));
if (current >= 0)
{
m_assignableMidiDevices->setCurrentIndex(current);
}

// MIDI layout ordering.
midi_layout->addWidget(midiiface_tw);
midi_layout->addWidget(ms_w);
midi_layout->addWidget(midiAutoAssign_tw);
midi_layout->addStretch();


Expand Down Expand Up @@ -917,6 +940,8 @@ void SetupDialog::accept()
QString::number(m_bufferSize));
ConfigManager::inst()->setValue("mixer", "mididev",
m_midiIfaceNames[m_midiInterfaces->currentText()]);
ConfigManager::inst()->setValue("midi", "midiautoassign",
m_assignableMidiDevices->currentText());


ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir));
Expand Down
8 changes: 8 additions & 0 deletions src/gui/editors/PianoRoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3600,6 +3600,14 @@ void PianoRoll::focusOutEvent( QFocusEvent * )
update();
}

void PianoRoll::focusInEvent( QFocusEvent * )
{
if ( hasValidPattern() )
{
// Assign midi device
m_pattern->instrumentTrack()->autoAssignMidiDevice(true);
}
}



Expand Down
46 changes: 46 additions & 0 deletions src/tracks/InstrumentTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) :
m_sustainPedalPressed( false ),
m_silentBuffersProcessed( false ),
m_previewMode( false ),
m_hasAutoMidiDev( false ),
m_baseNoteModel( 0, 0, KeysPerOctave * NumOctaves - 1, this,
tr( "Base note" ) ),
m_volumeModel( DefaultVolume, MinVolume, MaxVolume, 0.1f, this, tr( "Volume" ) ),
Expand Down Expand Up @@ -149,6 +150,13 @@ int InstrumentTrack::baseNote() const

InstrumentTrack::~InstrumentTrack()
{
// De-assign midi device
if (m_hasAutoMidiDev)
{
autoAssignMidiDevice(false);
s_autoAssignedTrack = NULL;
}

// kill all running notes and the iph
silenceAllNotes( true );

Expand Down Expand Up @@ -766,7 +774,13 @@ void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement
if (Engine::getSong()->isSavingProject()
&& !Engine::getSong()->getSaveOptions().discardMIDIConnections.value())
{
// Don't save auto assigned midi device connection
bool hasAuto = m_hasAutoMidiDev;
autoAssignMidiDevice(false);

m_midiPort.saveState( doc, thisElement );

autoAssignMidiDevice(hasAuto);
}

m_audioPort.effects()->saveState( doc, thisElement );
Expand Down Expand Up @@ -914,6 +928,38 @@ Instrument * InstrumentTrack::loadInstrument(const QString & _plugin_name,



InstrumentTrack *InstrumentTrack::s_autoAssignedTrack = NULL;

/*! \brief Automatically assign a midi controller to this track, based on the midiautoassign setting
*
* \param assign set to true to connect the midi device, set to false to disconnect
*/
void InstrumentTrack::autoAssignMidiDevice(bool assign)
{
if (assign)
{
if (s_autoAssignedTrack)
{
s_autoAssignedTrack->autoAssignMidiDevice(false);
}
s_autoAssignedTrack = this;
}

const QString &device = ConfigManager::inst()->value("midi", "midiautoassign");
if ( Engine::mixer()->midiClient()->isRaw() && device != "none" )
{
m_midiPort.setReadable( assign );
return;
}

// Check if the device exists
if ( Engine::mixer()->midiClient()->readablePorts().indexOf(device) >= 0 )
{
m_midiPort.subscribeReadablePort(device, assign);
m_hasAutoMidiDev = assign;
}
}



// #### ITV:
Expand Down

0 comments on commit 5d7e672

Please sign in to comment.