LMMS / lmms

Cross-platform music production software
https://lmms.io
GNU General Public License v2.0
7.98k stars 995 forks source link

Ability to assign opened instruments and samples to mixer track #7455

Closed bratpeki closed 1 month ago

bratpeki commented 1 month ago

Enhancement Summary

This idea comes from the fact that LMMS doesn't have the ability to send multiple instrument/sample tracks to one mixer track, and it gets tedious do either scroll the mixer track LCD each time, or right-click-assign.

The idea relies on opening all the instruments and samples you want routed to a mixer track, right-clicking on the desired track, and using an option with a name like "Route all open instruments and samples to mixer track".

Here is a video demonstration, using some instrument tracks:

https://github.com/user-attachments/assets/a329ffd3-dd5a-4d3e-9670-1ebcbc0dd932

Implementation Details / Mockup

I've already done some bit of the implementation, and require a bit of help with the rest. I was hoping @michaelgregorius would be kind enough to look at this.

My implementation has currently taken the following steps:

The current diff looks like this:

diff --git a/include/InstrumentTrackView.h b/include/InstrumentTrackView.h
index c7d524b36..d661868ce 100644
--- a/include/InstrumentTrackView.h
+++ b/include/InstrumentTrackView.h
@@ -88,11 +88,13 @@ private slots:
    void midiOutSelected();
    void midiConfigChanged();

-   void assignMixerLine( int channelIndex );
    void createMixerLine();

    void handleConfigChange(QString cls, QString attr, QString value);

+public slots:
+   void assignMixerLine( int channelIndex );
+
 private:
    static QPixmap determinePixmap(InstrumentTrack* instrumentTrack);

diff --git a/include/MixerChannelView.h b/include/MixerChannelView.h
index 7ccb8a24f..bd1562664 100644
--- a/include/MixerChannelView.h
+++ b/include/MixerChannelView.h
@@ -103,6 +103,7 @@ namespace lmms::gui
     private slots:
         void renameFinished();
         void removeChannel();
+        void assignActiveTracks();
         void removeUnusedChannels();
         void moveChannelLeft();
         void moveChannelRight();
diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp
index 2a1fe0928..0d40c2d73 100644
--- a/src/gui/MixerChannelView.cpp
+++ b/src/gui/MixerChannelView.cpp
@@ -22,6 +22,7 @@
  *
  */

+#include "SongEditor.h"
 #include "CaptionMenu.h"
 #include "ColorChooser.h"
 #include "GuiApplication.h"
@@ -31,6 +32,7 @@
 #include "PeakIndicator.h"
 #include "Song.h"
 #include "ConfigManager.h"
+#include "InstrumentTrackView.h"

 #include "gui_templates.h"
 #include "lmms_math.h"
@@ -162,6 +164,9 @@ namespace lmms::gui
             contextMenu->addSeparator();
         }

+        contextMenu->addAction("Assign active instrument and sample tracks here", this, &MixerChannelView::assignActiveTracks);
+        contextMenu->addSeparator();
+
         contextMenu->addAction(embed::getIconPixmap("cancel"), tr("Remove &unused channels"), this, &MixerChannelView::removeUnusedChannels);
         contextMenu->addSeparator();

@@ -454,6 +459,29 @@ namespace lmms::gui
        return answer == QMessageBox::Ok;
    }

+        void MixerChannelView::assignActiveTracks()
+    {
+        printf("Channel index: %d\n", channelIndex());
+
+        QList<TrackView*> trackViewsList = getGUI()->songEditor()->m_editor->trackViews();
+
+        for (auto i = 0; i < trackViewsList.size(); i++) {
+
+            // TODO: Make this a switch statement
+
+            if (trackViewsList.at(i)->getTrack()->type() == lmms::Track::Type::Instrument ) {
+                InstrumentTrackView* itv = dynamic_cast<InstrumentTrackView*>(trackViewsList.at(i));
+                itv->assignMixerLine(channelIndex());
+            }
+
+            if (trackViewsList.at(i)->getTrack()->type() == lmms::Track::Type::Sample ) {
+                // Needs work
+            }
+
+        }
+
+    }
+
     void MixerChannelView::removeChannel()
     {
        if (!confirmRemoval(m_channelIndex)) { return; }
@@ -492,4 +520,4 @@ namespace lmms::gui
         return Engine::mixer()->mixerChannel(m_channelIndex);
     }

-} // namespace lmms::gui
\ No newline at end of file
+} // namespace lmms::gui

This currently assigns all instruments to the given track. So, I have not yet started work on routing the sample tracks. For starters, I have the following question:

How does one check if an instrument window is opened?

After I finish up the instrument tracks, I'll move on to sample tracks.

Thank you in advance!

Please search the issue tracker for existing feature requests before submitting your own.

bratpeki commented 1 month ago

Just to note, I will be opening a PR if such a feature is accepted and properly implemented! :)

bratpeki commented 1 month ago

Some people in the server stated they wouldn't like such an addition, as it doesn't have large benefits, so I might abstain from making it a PR.

bratpeki commented 1 month ago

Lost mentioned that you can copy and repeatedly paste the mixer line LCD, so I guess there's no need for this!