summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse/ChangeLog2
-rw-r--r--muse/doc/dimpl/dimpl.tex69
-rw-r--r--muse/muse/CMakeLists.txt3
-rw-r--r--muse/muse/arranger/canvas.cpp6
-rw-r--r--muse/muse/audio.cpp21
-rw-r--r--muse/muse/audio.h4
-rw-r--r--muse/muse/importmidi.cpp2
-rw-r--r--muse/muse/liste/ctrllistedit.cpp141
-rw-r--r--muse/muse/liste/ctrllistedit.h3
-rw-r--r--muse/muse/liste/listedit.cpp21
-rw-r--r--muse/muse/liste/listedit.h3
-rw-r--r--muse/muse/midi.cpp2
-rw-r--r--muse/muse/midiedit/drumedit.cpp4
-rw-r--r--muse/muse/midiinport.h2
-rw-r--r--muse/muse/midiout.cpp3
-rw-r--r--muse/muse/midiout.h3
-rw-r--r--muse/muse/midioutport.h2
-rw-r--r--muse/muse/midisynti.h2
-rw-r--r--muse/muse/miditrack.cpp6
-rw-r--r--muse/muse/miditrack.h2
-rw-r--r--muse/muse/miditrackbase.cpp139
-rw-r--r--muse/muse/miditrackbase.h53
-rw-r--r--muse/muse/muse.cpp36
-rw-r--r--muse/muse/part.cpp156
-rw-r--r--muse/muse/seqmsg.cpp51
-rw-r--r--muse/muse/song.cpp306
-rw-r--r--muse/muse/song.h19
-rw-r--r--muse/muse/songpart.cpp366
-rw-r--r--muse/muse/track.cpp204
-rw-r--r--muse/muse/track.h28
-rw-r--r--muse/muse/wave.cpp2
-rw-r--r--muse/muse/wavetrack.cpp4
32 files changed, 940 insertions, 725 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog
index c2c1f075..a4688528 100644
--- a/muse/ChangeLog
+++ b/muse/ChangeLog
@@ -1,3 +1,5 @@
+16.11 (ws)
+ - implemented controller editor part of new list editor
12.11 (ws)
- the internationalization files (*.qm) are now part of the
MusE image via the qt resource system. Installing them is not
diff --git a/muse/doc/dimpl/dimpl.tex b/muse/doc/dimpl/dimpl.tex
index 31b28470..d8c91743 100644
--- a/muse/doc/dimpl/dimpl.tex
+++ b/muse/doc/dimpl/dimpl.tex
@@ -174,6 +174,75 @@
%%=======================================================================
%%
+\chapter{Process Structure}
+
+\chapter{Song}
+ \section{Multithreading}
+
+ \section{Editing}
+ \subsection{Realtime Editing}
+ \M\ allows for realtime editing. That means that you can edit
+ a song while the sequencer is running.
+ Two threads want to access data in the main {\tt Song()} class:
+ the GUI thread and the realtime sequencer thread.
+
+ This are the rules how \M\ handles {\tt Song()} data accesses:
+
+ \startitemize[packed,broad]
+ \item the GUI thread can only read {\tt Song()} data
+ \item the GUI thread can request the sequencer thread to
+ modify Song data
+ \item the sequencer thread can modify {\tt Song()} data, but only
+ on request of the GUI thread
+ \stopitemize
+
+ Interprocess communication is done via message passing.
+ Communication from the gui thread to the sequencer thread is
+ done in the following steps:
+
+ \startitemize[packed,broad]
+ \item the GUI sends a Message to the sequencer thread
+ and waits for an answer
+ \item once the sequencer thread is running (the JACK
+ client {\tt process()} call) it processes the message and
+ sends back an answer to the GUI process.
+ \item the GUI process reads the answer and continues
+ \stopitemize
+
+ This scheme stops the GUI process in a defined state while the
+ realtime process can safely manipulate the {\tt Song()} data.
+
+ \subsection{User Transaction}
+
+ A user transaction is a sequence of actions manipulating the
+ main {\Song()} structure. Each action involves sending a
+ message to the realtime thread. This means that every action
+ stops the GUI thread for at most one JACK cycle.
+
+ If a transaction consists of lot of actions then this scheme
+ would be too slow. For such cases the sequencer thread is switched
+ to "idle" mode, which ensures it is not touching the {\tt Song()}
+ data anymore. Then safe manipulation of the data is possible.
+
+ \subsection{Naming Conventions}
+
+ There are several methods involved in an edit transaction;
+ example for adding a part:
+
+ \startitemize[packed,broad]
+ \item {\tt cmdAddPart()}
+ This implements a complete undoable user transaction
+ and is called from the gui thread
+ \item {\tt addPart()}
+ This method is also called from the gui thread. It
+ implements part of a user transaction. It is not
+ surrounded by {\tt startUndo() endUndo()}.
+ \item the realtime part (actually removing the {\tt Part} from the
+ PartList) is done inline during processing of
+ messages in the sequencer thread.
+ \stopitemize
+
+
\chapter{File Formats}
\section{Instrument Definition Files}
diff --git a/muse/muse/CMakeLists.txt b/muse/muse/CMakeLists.txt
index 8de90026..e61c4a8f 100644
--- a/muse/muse/CMakeLists.txt
+++ b/muse/muse/CMakeLists.txt
@@ -64,6 +64,7 @@ QT4_WRAP_CPP ( muse_moc_headers
cobject.h
transpose.h
track.h
+ miditrackbase.h
midisynti.h
miditrack.h
wavetrack.h
@@ -138,12 +139,14 @@ add_executable ( muse
midiplugin.cpp
muse.cpp
song.cpp
+ songpart.cpp
transport.cpp
conf.cpp
editor.cpp
cobject.cpp
transpose.cpp
track.cpp
+ miditrackbase.cpp
midisynti.cpp
miditrack.cpp
wavetrack.cpp
diff --git a/muse/muse/arranger/canvas.cpp b/muse/muse/arranger/canvas.cpp
index 85e2305e..4ee07a65 100644
--- a/muse/muse/arranger/canvas.cpp
+++ b/muse/muse/arranger/canvas.cpp
@@ -471,7 +471,7 @@ void PartCanvas::contextMenu(const QPoint& pos)
renamePart(part);
break;
case 1:
- audio->msgRemovePart(part, true);
+ song->cmdRemovePart(part);
track->partListChanged();
break;
case 2:
@@ -610,7 +610,7 @@ void PartCanvas::mousePress(QMouseEvent* me)
break;
case RubberTool:
if (part)
- audio->msgRemovePart(part);
+ song->cmdRemovePart(part);
break;
case GlueTool:
if (part)
@@ -811,7 +811,7 @@ void PartCanvas::mouseRelease(QMouseEvent* me)
Pos p2 = pix2pos(drag.x() + drag.width()).snaped(raster());
part->setPos(p1);
part->setLenTick(p2.tick() - p1.tick());
- song->addPart(part);
+ song->cmdAddPart(part);
}
else
widget()->update();
diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp
index aa58b30d..543dcdf4 100644
--- a/muse/muse/audio.cpp
+++ b/muse/muse/audio.cpp
@@ -588,27 +588,6 @@ void Audio::processMsg()
midiSeq->initRealtimeTimer();
break;
- case SEQM_ADD_TRACK:
- song->insertTrack2(msg->track);
- midiSeq->updatePollFd();
- break;
-
- case SEQM_REMOVE_TRACK:
- song->removeTrack2(msg->track);
- midiSeq->updatePollFd();
- break;
- case SEQM_ADD_PART:
- song->cmdAddPart((Part*)msg->p1);
- break;
- case SEQM_REMOVE_PART:
- song->cmdRemovePart((Part*)msg->p1);
- break;
- case SEQM_CHANGE_PART:
- song->cmdChangePart((Part*)msg->p1, (Part*)msg->p2);
- break;
- case SEQM_MOVE_TRACK:
- song->moveTrack((Track*)(msg->p1), (Track*)(msg->p2));
- break;
case AUDIO_ADDMIDIPLUGIN:
((MidiTrackBase*)msg->track)->addPlugin(msg->mplugin, msg->ival);
break;
diff --git a/muse/muse/audio.h b/muse/muse/audio.h
index 11f30d5e..050757fd 100644
--- a/muse/muse/audio.h
+++ b/muse/muse/audio.h
@@ -215,8 +215,8 @@ class Audio {
void msgRemoveTrack(Track*);
void msgRemoveTracks();
void msgMoveTrack(Track*, Track*);
- void msgAddPart(Part*, bool u = true);
- void msgRemovePart(Part*, bool u = true);
+// void msgAddPart(Part*, bool u = true);
+// void msgRemovePart(Part*, bool u = true);
void msgChangePart(Part* oldPart, Part* newPart, bool u = true);
void msgAddEvent(const Event&, Part*, bool u = true);
void msgDeleteEvent(const Event&, Part*, bool u = true);
diff --git a/muse/muse/importmidi.cpp b/muse/muse/importmidi.cpp
index 83cae602..41a8dfd2 100644
--- a/muse/muse/importmidi.cpp
+++ b/muse/muse/importmidi.cpp
@@ -315,7 +315,7 @@ void MusE::addMidiFile(const QString name)
int division = mf.division();
MidiOutPort* outPort = 0;
- MidiInPort* inPort = 0;
+// MidiInPort* inPort = 0;
if (song->midiOutPorts()->empty()) {
outPort = new MidiOutPort();
diff --git a/muse/muse/liste/ctrllistedit.cpp b/muse/muse/liste/ctrllistedit.cpp
index 472e02f4..9c4a05eb 100644
--- a/muse/muse/liste/ctrllistedit.cpp
+++ b/muse/muse/liste/ctrllistedit.cpp
@@ -46,13 +46,17 @@ CtrlListEditor::CtrlListEditor(ListEdit* e, QWidget* parent)
le.maxValue->setSingleStep(1.0);
le.defaultValue->setSingleStep(1.0);
- le.ctrlList->setColumnWidth(TICK_COL, 60);
- le.ctrlList->setColumnWidth(TIME_COL, 120);
+ QFontMetrics fm(le.ctrlList->font());
+ int zW = fm.width("0");
+ le.ctrlList->setColumnWidth(TICK_COL, zW * 8);
+ le.ctrlList->setColumnWidth(TIME_COL, zW * 14);
MidiTimeDelegate* midiTimeDelegate = new MidiTimeDelegate(this);
le.ctrlList->setItemDelegate(midiTimeDelegate);
track = 0;
connect(le.ctrlList, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
+ SLOT(itemActivated(QTreeWidgetItem*,int)));
+ connect(le.ctrlList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
SLOT(itemDoubleClicked(QTreeWidgetItem*,int)));
connect(le.ctrlList, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
SLOT(itemChanged(QTreeWidgetItem*, int)));
@@ -136,8 +140,7 @@ void CtrlListEditor::updateList()
QTreeWidgetItem* item = new QTreeWidgetItem;
item->setData(TICK_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter));
item->setData(TIME_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter));
- item->setData(VAL_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter));
-// item->setItemDelegate(TIME_COL, midiTimeDelegate);
+ item->setData(VAL_COL, Qt::TextAlignmentRole, int(Qt::AlignHCenter | Qt::AlignVCenter));
item->setData(TICK_COL, Qt::DisplayRole, i.key());
item->setData(TIME_COL, Qt::DisplayRole, i.key());
@@ -165,10 +168,10 @@ void CtrlListEditor::controllerChanged(int id)
}
//---------------------------------------------------------
-// itemDoubleClicked
+// itemActivated
//---------------------------------------------------------
-void CtrlListEditor::itemDoubleClicked(QTreeWidgetItem* item, int column)
+void CtrlListEditor::itemActivated(QTreeWidgetItem* item, int column)
{
le.ctrlList->openPersistentEditor(item, column);
}
@@ -179,11 +182,6 @@ void CtrlListEditor::itemDoubleClicked(QTreeWidgetItem* item, int column)
void CtrlListEditor::itemChanged(QTreeWidgetItem* item, int column)
{
- if (column != VAL_COL) {
- printf("time change not implemented\n");
- return;
- }
-
CVal val;
if (c->type() & Ctrl::INT) {
val.i = item->data(VAL_COL, Qt::DisplayRole).toInt();
@@ -217,7 +215,29 @@ void CtrlListEditor::itemChanged(QTreeWidgetItem* item, int column)
le.ctrlList->closePersistentEditor(item, TIME_COL);
le.ctrlList->closePersistentEditor(item, VAL_COL);
updateListDisabled = true;
- song->addControllerVal(track, c, listEdit->pos(), val);
+ switch(column) {
+ case TICK_COL:
+ {
+ int otick = item->data(TIME_COL, Qt::DisplayRole).toInt();
+ int tick = item->data(TICK_COL, Qt::DisplayRole).toInt();
+ item->setData(TIME_COL, Qt::DisplayRole, tick);
+ song->removeControllerVal(track, c->id(), otick);
+ song->addControllerVal(track, c, tick, val);
+ }
+ break;
+ case TIME_COL:
+ {
+ int otick = item->data(TICK_COL, Qt::DisplayRole).toInt();
+ int tick = item->data(TIME_COL, Qt::DisplayRole).toInt();
+ item->setData(TICK_COL, Qt::DisplayRole, tick);
+ song->removeControllerVal(track, c->id(), otick);
+ song->addControllerVal(track, c, tick, val);
+ }
+ break;
+ case VAL_COL:
+ song->addControllerVal(track, c, listEdit->pos(), val);
+ break;
+ }
updateListDisabled = false;
}
@@ -350,14 +370,31 @@ MidiTimeDelegate::MidiTimeDelegate(QObject* parent)
// createEditor
//---------------------------------------------------------
-QWidget* MidiTimeDelegate::createEditor(QWidget* parent,
+QWidget* MidiTimeDelegate::createEditor(QWidget* pw,
const QStyleOptionViewItem& option, const QModelIndex& index) const
{
- if (index.column() != CtrlListEditor::TIME_COL)
- return QItemDelegate::createEditor(parent, option, index);
-
- Awl::PosEdit* pe = new Awl::PosEdit(parent);
- return pe;
+ switch(index.column()) {
+ case CtrlListEditor::TICK_COL:
+ break;
+ case CtrlListEditor::TIME_COL:
+ return new Awl::PosEdit(pw);
+ case CtrlListEditor::VAL_COL:
+ {
+ CtrlListEditor* ce = static_cast<CtrlListEditor*>(parent());
+ Ctrl* c = ce->ctrl();
+ if (c->type() & Ctrl::INT) {
+ QSpinBox* w = new QSpinBox(pw);
+ w->setRange(c->minVal().i, c->maxVal().i);
+ w->installEventFilter(const_cast<MidiTimeDelegate*>(this));
+ return w;
+ }
+ QDoubleSpinBox* w = new QDoubleSpinBox(pw);
+ w->setRange(c->minVal().f, c->maxVal().f);
+ w->installEventFilter(const_cast<MidiTimeDelegate*>(this));
+ return w;
+ }
+ }
+ return QItemDelegate::createEditor(pw, option, index);
}
//---------------------------------------------------------
@@ -367,12 +404,31 @@ QWidget* MidiTimeDelegate::createEditor(QWidget* parent,
void MidiTimeDelegate::setEditorData(QWidget* editor,
const QModelIndex& index) const
{
- if (index.column() != CtrlListEditor::TIME_COL) {
- QItemDelegate::setEditorData(editor, index);
- return;
+ switch(index.column()) {
+ case CtrlListEditor::TICK_COL:
+ break;
+ case CtrlListEditor::TIME_COL:
+ {
+ Awl::PosEdit* pe = static_cast<Awl::PosEdit*>(editor);
+ pe->setValue(AL::Pos(index.data().toInt()));
+ }
+ return;
+ case CtrlListEditor::VAL_COL:
+ {
+ CtrlListEditor* ce = static_cast<CtrlListEditor*>(parent());
+ Ctrl* c = ce->ctrl();
+ if (c->type() & Ctrl::INT) {
+ QSpinBox* w = static_cast<QSpinBox*>(editor);
+ w->setValue(index.data().toInt());
+ }
+ else {
+ QDoubleSpinBox* w = static_cast<QDoubleSpinBox*>(editor);
+ w->setValue(index.data().toDouble());
+ }
+ }
+ return;
}
- Awl::PosEdit* pe = (Awl::PosEdit*)editor;
- pe->setValue(AL::Pos(index.data().toInt()));
+ QItemDelegate::setEditorData(editor, index);
}
//---------------------------------------------------------
@@ -382,12 +438,31 @@ void MidiTimeDelegate::setEditorData(QWidget* editor,
void MidiTimeDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const
{
- if (index.column() != CtrlListEditor::TIME_COL) {
- QItemDelegate::setModelData(editor, model, index);
- return;
+ switch(index.column()) {
+ case CtrlListEditor::TICK_COL:
+ break;
+ case CtrlListEditor::TIME_COL:
+ {
+ Awl::PosEdit* pe = static_cast<Awl::PosEdit*>(editor);
+ model->setData(index, pe->pos().tick(), Qt::DisplayRole);
+ }
+ return;
+ case CtrlListEditor::VAL_COL:
+ {
+ CtrlListEditor* ce = static_cast<CtrlListEditor*>(parent());
+ Ctrl* c = ce->ctrl();
+ if (c->type() & Ctrl::INT) {
+ QSpinBox* w = static_cast<QSpinBox*>(editor);
+ model->setData(index, w->value(), Qt::DisplayRole);
+ }
+ else {
+ QDoubleSpinBox* w = static_cast<QDoubleSpinBox*>(editor);
+ model->setData(index, w->value(), Qt::DisplayRole);
+ }
+ }
+ break;
}
- Awl::PosEdit* pe = (Awl::PosEdit*)editor;
- model->setData(index, pe->pos().tick(), Qt::DisplayRole);
+ QItemDelegate::setModelData(editor, model, index);
}
//---------------------------------------------------------
@@ -431,3 +506,13 @@ void MidiTimeDelegate::paint(QPainter* painter,
painter->restore();
}
+//---------------------------------------------------------
+// itemDoubleClicked
+//---------------------------------------------------------
+
+void CtrlListEditor::itemDoubleClicked(QTreeWidgetItem* item, int column)
+ {
+ printf("double clicked\n");
+ }
+
+
diff --git a/muse/muse/liste/ctrllistedit.h b/muse/muse/liste/ctrllistedit.h
index 842ba7eb..a6384321 100644
--- a/muse/muse/liste/ctrllistedit.h
+++ b/muse/muse/liste/ctrllistedit.h
@@ -30,6 +30,7 @@
//---------------------------------------------------------
class MidiTimeDelegate : public QItemDelegate {
+ Q_OBJECT
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&,
const QModelIndex& index) const;
@@ -73,6 +74,7 @@ class CtrlListEditor : public ListWidget {
private slots:
void controllerChanged(int id);
+ void itemActivated(QTreeWidgetItem*,int);
void itemDoubleClicked(QTreeWidgetItem*,int);
void itemChanged(QTreeWidgetItem*,int);
void currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
@@ -87,6 +89,7 @@ class CtrlListEditor : public ListWidget {
CtrlListEditor(ListEdit*, QWidget* parent = 0);
virtual void setup(const ListType&);
void sendEscape();
+ Ctrl* ctrl() const { return c; }
enum { TICK_COL, TIME_COL, VAL_COL };
};
diff --git a/muse/muse/liste/listedit.cpp b/muse/muse/liste/listedit.cpp
index 09e2ed86..df78dfe7 100644
--- a/muse/muse/liste/listedit.cpp
+++ b/muse/muse/liste/listedit.cpp
@@ -67,8 +67,9 @@ ListEdit::ListEdit(QWidget*)
SLOT(itemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
connect(list, SIGNAL(itemExpanded(QTreeWidgetItem*)), SLOT(itemExpanded(QTreeWidgetItem*)));
connect(list, SIGNAL(itemCollapsed(QTreeWidgetItem*)), SLOT(itemExpanded(QTreeWidgetItem*)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
list->resizeColumnToContents(0);
- resize(900, 300);
+ resize(900, 400);
}
//---------------------------------------------------------
@@ -153,6 +154,19 @@ void ListEdit::buildList()
}
//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void ListEdit::songChanged(int flags)
+ {
+ if (flags & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_PART_INSERTED
+ | SC_PART_REMOVED)) {
+ buildList();
+ selectItem();
+ }
+ }
+
+//---------------------------------------------------------
// findItem
//---------------------------------------------------------
@@ -189,12 +203,11 @@ void ListEdit::selectItem(const AL::Pos& p, Track* track, Part* part, Ctrl* ctrl
lt.track = track;
lt.part = part;
lt.ctrl = ctrl;
- selectItem(lt);
+ selectItem();
}
-void ListEdit::selectItem(const ListType& l)
+void ListEdit::selectItem()
{
- lt = l;
stack->setCurrentWidget(ctrlPanel);
buildList();
for (int i = 0;; ++i) {
diff --git a/muse/muse/liste/listedit.h b/muse/muse/liste/listedit.h
index 2c33cdab..66179cd0 100644
--- a/muse/muse/liste/listedit.h
+++ b/muse/muse/liste/listedit.h
@@ -75,11 +75,12 @@ class ListEdit : public TopWin {
void buildList();
QTreeWidgetItem* findItem(const ListType& lt, QTreeWidgetItem* item);
- void selectItem(const ListType& lt);
+ void selectItem();
private slots:
void itemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
void itemExpanded(QTreeWidgetItem*);
+ void songChanged(int);
public:
ListEdit(QWidget* parent = 0);
diff --git a/muse/muse/midi.cpp b/muse/muse/midi.cpp
index 79eff684..37b5e5b4 100644
--- a/muse/muse/midi.cpp
+++ b/muse/muse/midi.cpp
@@ -568,7 +568,7 @@ void buildMidiEventList(EventList* del, const MidiEventList* el, MidiTrack* trac
CVal val;
val.i = ev.dataB();
- bool found = false;
+// bool found = false;
Ctrl* c = track->getController(id);
if (c)
c->add(tick, val);
diff --git a/muse/muse/midiedit/drumedit.cpp b/muse/muse/midiedit/drumedit.cpp
index 61537069..7d783245 100644
--- a/muse/muse/midiedit/drumedit.cpp
+++ b/muse/muse/midiedit/drumedit.cpp
@@ -123,7 +123,7 @@ DrumEdit::DrumEdit(PartList* pl, bool init)
QToolBar* transport = addToolBar(tr("Transport"));
muse->setupTransportToolbar(transport);
- // dont´how pitch value in toolbar
+ // dont´ow pitch value in toolbar
addToolBarBreak();
toolbar = new Toolbar1(initRaster, initQuant, false);
addToolBar(toolbar);
@@ -341,12 +341,14 @@ void DrumEdit::configChanged()
initShortcuts();
}
+#if 0
static int rasterTable[] = {
//-9----8- 7 6 5 4 3(1/4) 2 1
4, 8, 16, 32, 64, 128, 256, 512, 1024, // triple
6, 12, 24, 48, 96, 192, 384, 768, 1536,
9, 18, 36, 72, 144, 288, 576, 1152, 2304 // dot
};
+#endif
//---------------------------------------------------------
// keyPressEvent
diff --git a/muse/muse/midiinport.h b/muse/muse/midiinport.h
index 4a7b8bf1..8589cf41 100644
--- a/muse/muse/midiinport.h
+++ b/muse/muse/midiinport.h
@@ -21,7 +21,7 @@
#ifndef __MIDIINPORT_H__
#define __MIDIINPORT_H__
-#include "track.h"
+#include "miditrackbase.h"
#include "midievent.h"
static const int RECORD_FIFO_SIZE = 512;
diff --git a/muse/muse/midiout.cpp b/muse/muse/midiout.cpp
index 6ab98da7..31ed904d 100644
--- a/muse/muse/midiout.cpp
+++ b/muse/muse/midiout.cpp
@@ -20,7 +20,8 @@
#include "midiout.h"
#include "midictrl.h"
-#include "track.h"
+#include "miditrackbase.h"
+#include "al/al.h"
#include "al/tempo.h"
#include "event.h"
#include "sync.h"
diff --git a/muse/muse/midiout.h b/muse/muse/midiout.h
index 9df88569..75e9cbd6 100644
--- a/muse/muse/midiout.h
+++ b/muse/muse/midiout.h
@@ -21,9 +21,6 @@
#ifndef __MIDIOUT_H__
#define __MIDIOUT_H__
-#include "al/al.h"
-#include "globaldefs.h"
-#include "midievent.h"
#include "midififo.h"
class Track;
diff --git a/muse/muse/midioutport.h b/muse/muse/midioutport.h
index aa056db5..e77af2e5 100644
--- a/muse/muse/midioutport.h
+++ b/muse/muse/midioutport.h
@@ -21,7 +21,7 @@
#ifndef __MIDIOUTPORT_H__
#define __MIDIOUTPORT_H__
-#include "track.h"
+#include "miditrackbase.h"
#include "midiout.h"
//---------------------------------------------------------
diff --git a/muse/muse/midisynti.h b/muse/muse/midisynti.h
index c74a0eb7..89c77764 100644
--- a/muse/muse/midisynti.h
+++ b/muse/muse/midisynti.h
@@ -21,7 +21,7 @@
#ifndef __MIDISYNTH_H__
#define __MIDISYNTH_H__
-#include "track.h"
+#include "miditrackbase.h"
//---------------------------------------------------------
// MidiSynti
diff --git a/muse/muse/miditrack.cpp b/muse/muse/miditrack.cpp
index b7e3a53d..3f380ba4 100644
--- a/muse/muse/miditrack.cpp
+++ b/muse/muse/miditrack.cpp
@@ -98,7 +98,7 @@ void MidiTrack::write(Xml& xml) const
xml.intTag("compression", _compression);
xml.intTag("useDrumMap", _useDrumMap);
- const PartList* pl = cparts();
+ const PartList* pl = parts();
for (ciPart p = pl->begin(); p != pl->end(); ++p)
p->second->write(xml);
xml.etag("miditrack");
@@ -195,7 +195,7 @@ void MidiTrack::startRecording()
recordPart->setTick(startTick);
recordPart->setLenTick(endTick - startTick);
recordPart->setName(name());
- audio->msgAddPart(recordPart, false);
+ song->addPart(recordPart);
partCreated = true;
}
}
@@ -604,7 +604,7 @@ void MidiTrack::processMidi(unsigned from, unsigned to, unsigned, unsigned)
// from/to - midi ticks
//---------------------------------------------------------
-void MidiTrack::getEvents(unsigned from, unsigned to, int, MidiEventList* dst)
+void MidiTrack::getEvents(unsigned /*from*/, unsigned /*to*/, int, MidiEventList* dst)
{
for (iMidiEvent i = schedEvents.begin(); i != schedEvents.end(); ++i) {
dst->insert(*i);
diff --git a/muse/muse/miditrack.h b/muse/muse/miditrack.h
index d8b0d231..6424c1d8 100644
--- a/muse/muse/miditrack.h
+++ b/muse/muse/miditrack.h
@@ -21,7 +21,7 @@
#ifndef __MIDITRACK_H__
#define __MIDITRACK_H__
-#include "track.h"
+#include "miditrackbase.h"
#include "midififo.h"
class Part;
diff --git a/muse/muse/miditrackbase.cpp b/muse/muse/miditrackbase.cpp
new file mode 100644
index 00000000..faf0ed4d
--- /dev/null
+++ b/muse/muse/miditrackbase.cpp
@@ -0,0 +1,139 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "miditrackbase.h"
+#include "midiplugin.h"
+
+//---------------------------------------------------------
+// MidiTrackBase
+//---------------------------------------------------------
+
+MidiTrackBase::MidiTrackBase()
+ : Track()
+ {
+ _pipeline = new MidiPipeline();
+ }
+
+//---------------------------------------------------------
+// MidiTrackBase
+//---------------------------------------------------------
+
+MidiTrackBase::~MidiTrackBase()
+ {
+ foreach(MidiPluginI* plugin, *_pipeline)
+ delete plugin;
+ delete _pipeline;
+ }
+
+//---------------------------------------------------------
+// MidiTrackBase::writeProperties
+//---------------------------------------------------------
+
+void MidiTrackBase::writeProperties(Xml& xml) const
+ {
+ Track::writeProperties(xml);
+ for (ciMidiPluginI ip = _pipeline->begin(); ip != _pipeline->end(); ++ip) {
+ if (*ip)
+ (*ip)->writeConfiguration(xml);
+ }
+ }
+
+//---------------------------------------------------------
+// MidiTrackBase::readProperties
+//---------------------------------------------------------
+
+bool MidiTrackBase::readProperties(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "midiPlugin") {
+ MidiPluginI* pi = new MidiPluginI(this);
+ if (pi->readConfiguration(node))
+ delete pi;
+ else
+ addPlugin(pi, -1);
+ }
+ else
+ return Track::readProperties(node);
+ return false;
+ }
+
+//---------------------------------------------------------
+// plugin
+//---------------------------------------------------------
+
+MidiPluginI* MidiTrackBase::plugin(int idx) const
+ {
+ return _pipeline->value(idx);
+ }
+
+//---------------------------------------------------------
+// addPlugin
+// idx = -1 append
+// plugin = 0 remove slot
+//---------------------------------------------------------
+
+void MidiTrackBase::addPlugin(MidiPluginI* plugin, int idx)
+ {
+ if (plugin == 0) {
+#if 0
+ MidiPluginI* oldPlugin = (*_pipeline)[idx];
+ if (oldPlugin) {
+ int controller = oldPlugin->plugin()->parameter();
+ for (int i = 0; i < controller; ++i) {
+ int id = (idx + 1) * 0x1000 + i;
+ removeController(id);
+ }
+ }
+#endif
+ }
+ if (idx == -1)
+ idx = _pipeline->size();
+
+ if (plugin) {
+ _pipeline->insert(idx, plugin);
+#if 0
+ int ncontroller = plugin->plugin()->parameter();
+ for (int i = 0; i < ncontroller; ++i) {
+ int id = (idx + 1) * 0x1000 + i;
+ QString name(plugin->getParameterName(i));
+ double min, max;
+ plugin->range(i, &min, &max);
+ Ctrl* cl = getController(id);
+ if (cl == 0) {
+ cl = new Ctrl(id, name);
+ cl->setRange(min, max);
+ double defaultValue = plugin->defaultValue(i);
+ cl->setDefault(defaultValue);
+ cl->setCurVal(defaultValue);
+ addController(cl);
+ }
+ plugin->setParam(i, cl->schedVal().f);
+ plugin->setControllerList(cl);
+ }
+#endif
+ }
+ else {
+ _pipeline->removeAt(idx);
+ }
+ }
+
+
+
diff --git a/muse/muse/miditrackbase.h b/muse/muse/miditrackbase.h
new file mode 100644
index 00000000..d10b2bb3
--- /dev/null
+++ b/muse/muse/miditrackbase.h
@@ -0,0 +1,53 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDITRACKBASE_H__
+#define __MIDITRACKBASE_H__
+
+#include "track.h"
+
+//---------------------------------------------------------
+// MidiTrackBase
+//---------------------------------------------------------
+
+class MidiTrackBase : public Track {
+ Q_OBJECT
+
+ MidiPipeline* _pipeline;
+
+ public:
+ MidiTrackBase();
+ virtual ~MidiTrackBase();
+
+ bool readProperties(QDomNode);
+ void writeProperties(Xml&) const;
+
+ MidiPipeline* pipeline() { return _pipeline; }
+ void addPlugin(MidiPluginI* plugin, int idx);
+ MidiPluginI* plugin(int idx) const;
+
+ virtual void processMidi(unsigned, unsigned, unsigned, unsigned) {}
+ virtual void getEvents(unsigned /*from*/, unsigned /*to*/, int /*channel*/, MidiEventList* /*dst*/) {}
+ };
+
+#endif
+
+
+
diff --git a/muse/muse/muse.cpp b/muse/muse/muse.cpp
index 31fcdc5b..f22e654b 100644
--- a/muse/muse/muse.cpp
+++ b/muse/muse/muse.cpp
@@ -82,7 +82,7 @@ static const char* fileSaveText =
static const char* infoLoopButton = QT_TR_NOOP("loop between left mark and right mark");
static const char* infoPunchinButton = QT_TR_NOOP("record starts at left mark");
static const char* infoPunchoutButton = QT_TR_NOOP("record stops at right mark");
-static const char* infoStartButton = QT_TR_NOOP("rewind to start position");
+// static const char* infoStartButton = QT_TR_NOOP("rewind to start position");
static const char* infoRewindButton = QT_TR_NOOP("rewind current position");
static const char* infoForwardButton = QT_TR_NOOP("move current position");
static const char* infoStopButton = QT_TR_NOOP("stop sequencer");
@@ -1690,7 +1690,7 @@ void MusE::selectProject(QAction* a)
// kbAccel
//---------------------------------------------------------
-void MusE::kbAccel(int key)
+void MusE::kbAccel(int /*key*/)
{
#if 0 //TODOB
if (key == shortcuts[SHRT_TOGGLE_METRO].key) {
@@ -1863,23 +1863,27 @@ void MusE::cmd(QAction* a)
//TODO1 arranger->cmd(Arranger::CMD_PASTE_PART);
break;
case CMD_DELETE:
- song->startUndo();
- if (song->msgRemoveParts()) {
- song->endUndo(SC_PART_REMOVED);
- break;
+ {
+ TrackList* tl = song->tracks();
+ bool partsMarked = false;
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ PartList* pl2 = (*it)->parts();
+ for (iPart ip = pl2->begin(); ip != pl2->end(); ++ip) {
+ if (ip->second->selected()) {
+ partsMarked = true;
+ break;
+ }
+ }
}
- else {
- // if there are no selected parts, delete
- // selected tracks
- //
+ if (partsMarked)
+ song->cmdRemoveParts();
+ else
audio->msgRemoveTracks();
- }
- song->endUndo(SC_TRACK_REMOVED);
+ }
break;
+
case CMD_DELETE_TRACK:
- song->startUndo();
audio->msgRemoveTracks();
- song->endUndo(SC_TRACK_REMOVED);
break;
case CMD_SELECT_ALL:
@@ -2193,7 +2197,7 @@ void MusE::globalCut()
if (t + l <= lpos)
continue;
if ((t >= lpos) && ((t+l) <= rpos)) {
- audio->msgRemovePart(part, false);
+ song->removePart(part);
}
else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) {
// remove part tail
@@ -2337,7 +2341,7 @@ void MusE::globalSplit()
Part* p2;
track->splitPart(part, pos, p1, p2);
audio->msgChangePart(part, p1, false);
- audio->msgAddPart(p2, false);
+ song->addPart(p2);
break;
}
}
diff --git a/muse/muse/part.cpp b/muse/muse/part.cpp
index b4a6bc86..ea8ca457 100644
--- a/muse/muse/part.cpp
+++ b/muse/muse/part.cpp
@@ -223,162 +223,6 @@ printf("remove part: not found\n");
}
//---------------------------------------------------------
-// splitPart
-// split part "part" at "tick" position
-// create two new parts p1 and p2
-//---------------------------------------------------------
-
-void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)
- {
- int l1 = 0; // len of first new part (ticks or samples)
- int l2 = 0; // len of second new part
-
- int samplepos = AL::tempomap.tick2frame(tickpos);
-
- switch (type()) {
- case WAVE:
- l1 = samplepos - part->frame();
- l2 = part->lenFrame() - l1;
- break;
- case MIDI:
- l1 = tickpos - part->tick();
- l2 = part->lenTick() - l1;
- break;
- default:
- return;
- }
-
- if (l1 <= 0 || l2 <= 0)
- return;
-
- p1 = newPart(part); // new left part
- p2 = newPart(part); // new right part
-
- switch (type()) {
- case WAVE:
- p1->setLenFrame(l1);
- p2->setFrame(samplepos);
- p2->setLenFrame(l2);
- break;
- case MIDI:
- p1->setLenTick(l1);
- p2->setTick(tickpos);
- p2->setLenTick(l2);
- break;
- default:
- break;
- }
-
- EventList* se = part->events();
- EventList* de1 = p1->events();
- EventList* de2 = p2->events();
-
- if (type() == WAVE) {
- int ps = part->frame();
- int d1p1 = p1->frame();
- int d2p1 = p1->endFrame();
- int d1p2 = p2->frame();
- int d2p2 = p2->endFrame();
- for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
- Event event = ie->second;
- int s1 = event.frame() + ps;
- int s2 = event.endFrame() + ps;
-
- if ((s2 > d1p1) && (s1 < d2p1)) {
- Event si = event.mid(d1p1 - ps, d2p1 - ps);
- de1->add(si);
- }
- if ((s2 > d1p2) && (s1 < d2p2)) {
- Event si = event.mid(d1p2 - ps, d2p2 - ps);
- si.setFrame(si.frame() - l1); //??
- si.setFrame(0); //??
- de2->add(si);
- }
- }
- }
- else {
- for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
- Event event = ie->second.clone();
- int t = event.tick();
- if (t >= l1) {
- event.move(-l1);
- de2->add(event);
- }
- else
- de1->add(event);
- }
- }
- }
-
-//---------------------------------------------------------
-// cmdSplitPart
-//---------------------------------------------------------
-
-void Song::cmdSplitPart(Part* part, const Pos& pos)
- {
- int tick = pos.tick();
- int l1 = tick - part->tick();
- int l2 = part->lenTick() - l1;
- if (l1 <= 0 || l2 <= 0)
- return;
- Part* p1;
- Part* p2;
- part->track()->splitPart(part, tick, p1, p2);
-
- startUndo();
- audio->msgChangePart(part, p1, false);
- audio->msgAddPart(p2, false);
- endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED);
- part->track()->partListChanged();
- }
-
-//---------------------------------------------------------
-// cmdGluePart
-//---------------------------------------------------------
-
-void Song::cmdGluePart(Part* oPart)
- {
- Track* track = oPart->track();
- PartList* pl = track->parts();
- Part* nextPart = 0;
-
- for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
- if (ip->second == oPart) {
- ++ip;
- if (ip == pl->end())
- return;
- nextPart = ip->second;
- break;
- }
- }
-
- Part* nPart = track->newPart(oPart);
- nPart->setLenTick(nextPart->tick() + nextPart->lenTick() - oPart->tick());
-
- // populate nPart with Events from oPart and nextPart
-
- EventList* sl1 = oPart->events();
- EventList* dl = nPart->events();
-
- for (iEvent ie = sl1->begin(); ie != sl1->end(); ++ie)
- dl->add(ie->second);
-
- EventList* sl2 = nextPart->events();
- int tickOffset = nextPart->tick() - oPart->tick();
-
- for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) {
- Event event = ie->second.clone();
- event.move(tickOffset);
- dl->add(event);
- }
- startUndo();
- audio->msgRemovePart(nextPart, false);
- audio->msgChangePart(oPart, nPart, false);
- endUndo(SC_PART_MODIFIED | SC_PART_REMOVED);
- track->partListChanged();
- }
-
-//---------------------------------------------------------
// dump
//---------------------------------------------------------
diff --git a/muse/muse/seqmsg.cpp b/muse/muse/seqmsg.cpp
index 1033381a..28dfe043 100644
--- a/muse/muse/seqmsg.cpp
+++ b/muse/muse/seqmsg.cpp
@@ -336,7 +336,7 @@ void Audio::msgRemoveTrack(Track* track)
AudioMsg msg;
msg.id = SEQM_REMOVE_TRACK;
msg.track = track;
- sendMessage(&msg, false);
+ sendMessage(&msg, true);
}
//---------------------------------------------------------
@@ -376,55 +376,6 @@ void Audio::msgMoveTrack(Track* src, Track* dst)
}
//---------------------------------------------------------
-// msgAddPart
-//---------------------------------------------------------
-
-void Audio::msgAddPart(Part* part, bool doUndoFlag)
- {
- AudioMsg msg;
- msg.id = SEQM_ADD_PART;
- msg.p1 = part;
- sendMessage(&msg, doUndoFlag);
- }
-
-//---------------------------------------------------------
-// msgRemovePart
-//---------------------------------------------------------
-
-void Audio::msgRemovePart(Part* part, bool doUndoFlag)
- {
- AudioMsg msg;
- msg.id = SEQM_REMOVE_PART;
- msg.p1 = part;
- sendMessage(&msg, doUndoFlag);
- part->track()->partListChanged(); // emit signal
- }
-
-//---------------------------------------------------------
-// msgRemoveParts
-// remove selected parts; return true if any part was
-// removed
-//---------------------------------------------------------
-
-bool Song::msgRemoveParts()
- {
- TrackList* tl = song->tracks();
- PartList pl;
-
- for (iTrack it = tl->begin(); it != tl->end(); ++it) {
- PartList* pl2 = (*it)->parts();
- for (iPart ip = pl2->begin(); ip != pl2->end(); ++ip) {
- if (ip->second->selected())
- pl.add(ip->second);
- }
- }
- for (iPart ip = pl.begin(); ip != pl.end(); ++ip)
- audio->msgRemovePart(ip->second, false);
-
- return !pl.empty();
- }
-
-//---------------------------------------------------------
// msgChangePart
//---------------------------------------------------------
diff --git a/muse/muse/song.cpp b/muse/muse/song.cpp
index a051d978..244b3a72 100644
--- a/muse/muse/song.cpp
+++ b/muse/muse/song.cpp
@@ -923,19 +923,7 @@ void Song::processMsg(AudioMsg* msg)
case SEQM_REDO:
doRedo2();
break;
- case SEQM_MOVE_TRACK:
- if (msg->a > msg->b) {
- for (int i = msg->a; i > msg->b; --i) {
- swapTracks(i, i-1);
- }
- }
- else {
- for (int i = msg->a; i < msg->b; ++i) {
- swapTracks(i, i+1);
- }
- }
- updateFlags = SC_TRACK_MODIFIED;
- break;
+
case SEQM_ADD_EVENT:
updateFlags = SC_EVENT_INSERTED;
if (addEvent(msg->ev1, (Part*)(msg->p2))) {
@@ -1004,63 +992,41 @@ void Song::processMsg(AudioMsg* msg)
msg->track->removeControllerVal(msg->a, msg->time);
break;
- default:
- printf("unknown seq message %d\n", msg->id);
+ case SEQM_ADD_TRACK:
+ insertTrack2(msg->track);
break;
- }
- }
-//---------------------------------------------------------
-// cmdAddPart
-// realtime context
-//---------------------------------------------------------
-
-void Song::cmdAddPart(Part* part)
- {
- part->track()->addPart(part);
- undoOp(UndoOp::AddPart, part);
- updateFlags = SC_PART_INSERTED;
- if (len() < part->endTick())
- setLen(part->endTick());
- }
-
-//---------------------------------------------------------
-// cmdRemovePart
-//---------------------------------------------------------
-
-void Song::cmdRemovePart(Part* part)
- {
- Track* track = part->track();
- track->parts()->remove(part);
+ case SEQM_REMOVE_TRACK:
+ removeTrack2(msg->track);
+ break;
-//TD esettingsList->removeSettings(part->sn());
- undoOp(UndoOp::DeletePart, part);
- part->events()->incARef(-1);
- updateFlags = SC_PART_MODIFIED;
- }
+ case SEQM_ADD_PART:
+ {
+ Part* part = (Part*)(msg->p1);
+ part->track()->addPart(part);
+ }
+ break;
-//---------------------------------------------------------
-// changePart
-//---------------------------------------------------------
+ case SEQM_REMOVE_PART:
+ {
+ Part* part = (Part*)(msg->p1);
+ Track* track = part->track();
+ track->parts()->remove(part);
+ }
+ break;
-void Song::changePart(Part* oldPart, Part* newPart)
- {
- Part part = *newPart;
- *newPart = *oldPart;
- *oldPart = part;
- }
+ case SEQM_CHANGE_PART:
+ cmdChangePart((Part*)msg->p1, (Part*)msg->p2);
+ break;
-//---------------------------------------------------------
-// cmdChangePart
-// realtime context
-//---------------------------------------------------------
+ case SEQM_MOVE_TRACK:
+ moveTrack((Track*)(msg->p1), (Track*)(msg->p2));
+ break;
-void Song::cmdChangePart(Part* oldPart, Part* newPart)
- {
- changePart(oldPart, newPart);
- undoOp(UndoOp::ModifyPart, oldPart, newPart);
- oldPart->events()->incARef(-1);
- updateFlags = SC_PART_MODIFIED;
+ default:
+ printf("unknown seq message %d\n", msg->id);
+ break;
+ }
}
//---------------------------------------------------------
@@ -1228,52 +1194,6 @@ void Song::seqSignal(int fd)
}
}
-#if 0
-//---------------------------------------------------------
-// recordEvent
-//---------------------------------------------------------
-
-void Song::recordEvent(MidiTrack* mt, Event& event)
- {
- //---------------------------------------------------
- // if tick points into a part,
- // record to that part
- // else
- // create new part
- //---------------------------------------------------
-
- unsigned tick = event.tick();
- PartList* pl = mt->parts();
- Part* part = 0;
- iPart ip;
- for (ip = pl->begin(); ip != pl->end(); ++ip) {
- part = ip->second;
- unsigned partStart = part->tick();
- unsigned partEnd = partStart + part->lenTick();
- if (tick >= partStart && tick < partEnd)
- break;
- }
- updateFlags |= SC_EVENT_INSERTED;
- if (ip == pl->end()) {
- // create new part
- part = new Part(mt);
- int startTick = roundDownBar(tick);
- int endTick = roundUpBar(tick);
- part->setTick(startTick);
- part->setLenTick(endTick - startTick);
- part->setName(mt->name());
- event.move(-startTick);
- part->events()->add(event);
- audio->msgAddPart(part);
- return;
- }
- part = ip->second;
- tick -= part->tick();
- event.setTick(tick);
- audio->msgAddEvent(event, part);
- }
-#endif
-
//---------------------------------------------------------
// stopRolling
//---------------------------------------------------------
@@ -1823,174 +1743,6 @@ std::vector<QString>* Song::synthesizer() const
}
//---------------------------------------------------------
-// changePart
-// extend/shrink part in front or at end
-//---------------------------------------------------------
-
-void Song::changePart(Part* oPart, unsigned pos, unsigned len)
- {
- startUndo();
- //
- // move events so they stay at same position in song
- //
- int delta = oPart->tick() - pos;
- EventList* d = new EventList();
- EventList* s = oPart->events();
- for (iEvent ie = s->begin(); ie != s->end(); ++ie) {
- int tick = ie->first + delta;
- if (tick >= 0 && tick < int(len)) {
- Event ev = ie->second.clone();
- ev.move(delta);
- d->add(ev, unsigned(tick));
- }
- }
- if (oPart->fillLen() > 0 && len < (unsigned)oPart->fillLen())
- oPart->setFillLen(len);
- if (oPart->lenTick() < len && oPart->fillLen() > 0) {
- unsigned loop = oPart->fillLen();
- unsigned fillLen = len - oPart->lenTick();
- for (unsigned i = 0; i < fillLen / loop; ++i) {
- int start = oPart->lenTick() + loop * i;
- for (iEvent ie = s->begin(); ie != s->end(); ++ie) {
- if (ie->first >= loop)
- break;
- Event ev = ie->second.clone();
- ev.move(start);
- d->add(ev, ie->first + start);
- }
- }
- }
- Part* nPart = new Part(*oPart, d);
- nPart->setLenTick(len);
- nPart->setTick(pos);
- audio->msgChangePart(oPart, nPart, false);
- endUndo(SC_PART_MODIFIED);
- oPart->track()->partListChanged();
- if (unsigned(_len) < oPart->endTick()) // update song len
- setLen(oPart->endTick());
- }
-
-//---------------------------------------------------------
-// movePart
-//---------------------------------------------------------
-
-void Song::movePart(Part* oPart, unsigned pos, Track* track)
- {
- Track* oTrack = oPart->track();
- Part* nPart = new Part(*oPart);
- nPart->setTrack(track);
- nPart->setTick(pos);
- startUndo();
- if (oPart->track() != track) {
- audio->msgRemovePart(oPart, false);
- audio->msgAddPart(nPart, false);
- }
- else {
- audio->msgChangePart(oPart, nPart, false);
- }
- endUndo(0);
- oTrack->partListChanged();
- if (len() < nPart->endTick())
- setLen(nPart->endTick());
- }
-
-//---------------------------------------------------------
-// linkPart
-//---------------------------------------------------------
-
-void Song::linkPart(Part* sPart, unsigned pos, Track* track)
- {
- Part* dPart = track->newPart(sPart, true);
- dPart->setTick(pos);
- audio->msgAddPart(dPart);
- sPart->track()->partListChanged();
- dPart->track()->partListChanged();
- }
-
-//---------------------------------------------------------
-// copyPart
-//---------------------------------------------------------
-
-void Song::copyPart(Part* sPart, unsigned pos, Track* track)
- {
- bool clone = sPart->events()->arefCount() > 1;
- Part* dPart = track->newPart(sPart, clone);
- dPart->setTick(pos);
- if (!clone) {
- //
- // Copy Events
- //
- EventList* se = sPart->events();
- EventList* de = dPart->events();
- for (iEvent i = se->begin(); i != se->end(); ++i) {
- Event oldEvent = i->second;
- Event ev = oldEvent.clone();
- de->add(ev);
- }
- }
- audio->msgAddPart(dPart);
- sPart->track()->partListChanged();
- dPart->track()->partListChanged();
- }
-
-//---------------------------------------------------------
-// createLRPart
-//---------------------------------------------------------
-
-void Song::createLRPart(Track* track)
- {
- Part* part = track->newPart();
- if (part) {
- part->setTick(pos[1].tick());
- part->setLenTick(pos[2].tick()-pos[1].tick());
- part->setSelected(true);
- addPart(part);
- }
- }
-
-//---------------------------------------------------------
-// addPart
-//---------------------------------------------------------
-
-void Song::addPart(Part* part)
- {
- audio->msgAddPart(part);
- // adjust song len:
- unsigned epos = part->tick() + part->lenTick();
-
- if (epos > len())
- setLen(epos);
- part->track()->partListChanged();
- }
-
-//---------------------------------------------------------
-// selectPart
-//---------------------------------------------------------
-
-void Song::selectPart(Part* part, bool add)
- {
- if (add) {
- part->setSelected(!part->selected());
- part->track()->partListChanged();
- return;
- }
- for (iTrack it = _tracks.begin(); it != _tracks.end(); ++it) {
- PartList* pl = (*it)->parts();
- bool changed = false;
- for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
- bool f = part == ip->second;
- if (ip->second->selected() != f) {
- ip->second->setSelected(f);
- changed = true;
- }
- }
- if (changed)
- (*it)->partListChanged();
- }
- }
-
-
-//---------------------------------------------------------
// setRecordFlag
//---------------------------------------------------------
diff --git a/muse/muse/song.h b/muse/muse/song.h
index 610b0eec..8e011fb9 100644
--- a/muse/muse/song.h
+++ b/muse/muse/song.h
@@ -235,8 +235,6 @@ class Song : public QObject {
const Pos& lPos() const { return pos[1]; }
const Pos& rPos() const { return pos[2]; }
unsigned cpos() const { return pos[0].tick(); }
-// unsigned vcpos() const { return _vcpos.tick(); }
-// const Pos& vcPos() const { return _vcpos; }
unsigned lpos() const { return pos[1].tick(); }
unsigned rpos() const { return pos[2].tick(); }
@@ -276,18 +274,22 @@ class Song : public QObject {
// part manipulations
//-----------------------------------------
+ void cmdAddPart(Part* part);
+ void addPart(Part* part);
+
+ void cmdRemoveParts();
+ void cmdRemovePart(Part* part);
+ void removePart(Part* part);
+
+ void cmdChangePart(Part* oldPart, Part* newPart);
+ void changePart(Part*, Part*);
+
void cmdSplitPart(Part* p, const Pos&);
void cmdGluePart(Part* p);
- void changePart(Part*, Part*);
- void addPart(Part* part);
PartList* getSelectedMidiParts() const;
PartList* getSelectedWaveParts() const;
- bool msgRemoveParts();
- void cmdChangePart(Part* oldPart, Part* newPart);
- void cmdRemovePart(Part* part);
- void cmdAddPart(Part* part);
void movePart(Part*, unsigned, Track*);
void linkPart(Part*, unsigned, Track*);
void copyPart(Part*, unsigned, Track*);
@@ -324,7 +326,6 @@ class Song : public QObject {
void insertTrack1(Track*, int idx);
void insertTrack2(Track*);
void readRoute(QDomNode);
-// void recordEvent(MidiTrack*, Event&);
std::vector<QString>* synthesizer() const;
void deselectTracks();
diff --git a/muse/muse/songpart.cpp b/muse/muse/songpart.cpp
new file mode 100644
index 00000000..7b49cdfa
--- /dev/null
+++ b/muse/muse/songpart.cpp
@@ -0,0 +1,366 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "part.h"
+#include "audio.h"
+
+//---------------------------------------------------------
+// cmdAddPart
+// GUI context + startUndo/endUndo
+//---------------------------------------------------------
+
+void Song::cmdAddPart(Part* part)
+ {
+ Track* track = part->track();
+ //
+ // create default name:
+ //
+ for (int i = 1;;++i) {
+ PartList* pl = track->parts();
+ bool found = false;
+ QString name = QString("Part-%1").arg(i);
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ if (name == ip->second->name()) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ part->setName(name);
+ break;
+ }
+ }
+ startUndo();
+ addPart(part);
+ endUndo(0);
+ track->partListChanged();
+ }
+
+//---------------------------------------------------------
+// addPart
+// GUI context
+//---------------------------------------------------------
+
+void Song::addPart(Part* part)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_ADD_PART;
+ msg.p1 = part;
+ audio->sendMessage(&msg, false);
+ undoOp(UndoOp::AddPart, part);
+ updateFlags |= SC_PART_INSERTED;
+ if (len() < part->endTick())
+ setLen(part->endTick());
+ }
+
+//---------------------------------------------------------
+// cmdRemovePart
+//---------------------------------------------------------
+
+void Song::cmdRemovePart(Part* part)
+ {
+ startUndo();
+ removePart(part);
+ endUndo(0);
+ part->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// removePart
+//---------------------------------------------------------
+
+void Song::removePart(Part* part)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_PART;
+ msg.p1 = part;
+ audio->sendMessage(&msg, false);
+ undoOp(UndoOp::DeletePart, part);
+ part->events()->incARef(-1);
+ updateFlags |= SC_PART_REMOVED;
+ }
+
+//---------------------------------------------------------
+// cmdRemoveParts
+// remove selected parts
+//---------------------------------------------------------
+
+void Song::cmdRemoveParts()
+ {
+ TrackList* tl = song->tracks();
+ PartList pl;
+
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ PartList* pl2 = (*it)->parts();
+ for (iPart ip = pl2->begin(); ip != pl2->end(); ++ip) {
+ if (ip->second->selected())
+ pl.add(ip->second);
+ }
+ }
+ for (iPart ip = pl.begin(); ip != pl.end(); ++ip)
+ removePart(ip->second);
+ }
+
+//---------------------------------------------------------
+// cmdChangePart
+// realtime context
+//---------------------------------------------------------
+
+void Song::cmdChangePart(Part* oldPart, Part* newPart)
+ {
+ changePart(oldPart, newPart);
+ undoOp(UndoOp::ModifyPart, oldPart, newPart);
+ oldPart->events()->incARef(-1);
+ updateFlags = SC_PART_MODIFIED;
+ }
+
+//---------------------------------------------------------
+// changePart
+//---------------------------------------------------------
+
+void Song::changePart(Part* oldPart, Part* newPart)
+ {
+ Part part = *newPart;
+ *newPart = *oldPart;
+ *oldPart = part;
+ }
+
+//---------------------------------------------------------
+// changePart
+// extend/shrink part in front or at end
+//---------------------------------------------------------
+
+void Song::changePart(Part* oPart, unsigned pos, unsigned len)
+ {
+ startUndo();
+ //
+ // move events so they stay at same position in song
+ //
+ int delta = oPart->tick() - pos;
+ EventList* d = new EventList();
+ EventList* s = oPart->events();
+ for (iEvent ie = s->begin(); ie != s->end(); ++ie) {
+ int tick = ie->first + delta;
+ if (tick >= 0 && tick < int(len)) {
+ Event ev = ie->second.clone();
+ ev.move(delta);
+ d->add(ev, unsigned(tick));
+ }
+ }
+ if (oPart->fillLen() > 0 && len < (unsigned)oPart->fillLen())
+ oPart->setFillLen(len);
+ if (oPart->lenTick() < len && oPart->fillLen() > 0) {
+ unsigned loop = oPart->fillLen();
+ unsigned fillLen = len - oPart->lenTick();
+ for (unsigned i = 0; i < fillLen / loop; ++i) {
+ int start = oPart->lenTick() + loop * i;
+ for (iEvent ie = s->begin(); ie != s->end(); ++ie) {
+ if (ie->first >= loop)
+ break;
+ Event ev = ie->second.clone();
+ ev.move(start);
+ d->add(ev, ie->first + start);
+ }
+ }
+ }
+ Part* nPart = new Part(*oPart, d);
+ nPart->setLenTick(len);
+ nPart->setTick(pos);
+ audio->msgChangePart(oPart, nPart, false);
+ endUndo(SC_PART_MODIFIED);
+ oPart->track()->partListChanged();
+ if (unsigned(_len) < oPart->endTick()) // update song len
+ setLen(oPart->endTick());
+ }
+
+//---------------------------------------------------------
+// movePart
+//---------------------------------------------------------
+
+void Song::movePart(Part* oPart, unsigned pos, Track* track)
+ {
+ Track* oTrack = oPart->track();
+ Part* nPart = new Part(*oPart);
+ nPart->setTrack(track);
+ nPart->setTick(pos);
+ startUndo();
+ if (oPart->track() != track) {
+ removePart(oPart);
+ addPart(nPart);
+ }
+ else {
+ audio->msgChangePart(oPart, nPart, false);
+ }
+ endUndo(0);
+ oTrack->partListChanged();
+ if (len() < nPart->endTick())
+ setLen(nPart->endTick());
+ }
+
+//---------------------------------------------------------
+// linkPart
+//---------------------------------------------------------
+
+void Song::linkPart(Part* sPart, unsigned pos, Track* track)
+ {
+ Part* dPart = track->newPart(sPart, true);
+ dPart->setTick(pos);
+ cmdAddPart(dPart);
+ sPart->track()->partListChanged();
+ dPart->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// copyPart
+//---------------------------------------------------------
+
+void Song::copyPart(Part* sPart, unsigned pos, Track* track)
+ {
+ bool clone = sPart->events()->arefCount() > 1;
+ Part* dPart = track->newPart(sPart, clone);
+ dPart->setTick(pos);
+ if (!clone) {
+ //
+ // Copy Events
+ //
+ EventList* se = sPart->events();
+ EventList* de = dPart->events();
+ for (iEvent i = se->begin(); i != se->end(); ++i) {
+ Event oldEvent = i->second;
+ Event ev = oldEvent.clone();
+ de->add(ev);
+ }
+ }
+ cmdAddPart(dPart);
+ sPart->track()->partListChanged();
+ dPart->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// createLRPart
+//---------------------------------------------------------
+
+void Song::createLRPart(Track* track)
+ {
+ Part* part = track->newPart();
+ if (part) {
+ part->setTick(pos[1].tick());
+ part->setLenTick(pos[2].tick()-pos[1].tick());
+ part->setSelected(true);
+ cmdAddPart(part);
+ }
+ }
+
+//---------------------------------------------------------
+// selectPart
+//---------------------------------------------------------
+
+void Song::selectPart(Part* part, bool add)
+ {
+ if (add) {
+ part->setSelected(!part->selected());
+ part->track()->partListChanged();
+ return;
+ }
+ for (iTrack it = _tracks.begin(); it != _tracks.end(); ++it) {
+ PartList* pl = (*it)->parts();
+ bool changed = false;
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ bool f = part == ip->second;
+ if (ip->second->selected() != f) {
+ ip->second->setSelected(f);
+ changed = true;
+ }
+ }
+ if (changed)
+ (*it)->partListChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// cmdSplitPart
+//---------------------------------------------------------
+
+void Song::cmdSplitPart(Part* part, const Pos& pos)
+ {
+ int tick = pos.tick();
+ int l1 = tick - part->tick();
+ int l2 = part->lenTick() - l1;
+ if (l1 <= 0 || l2 <= 0)
+ return;
+ Part* p1;
+ Part* p2;
+ part->track()->splitPart(part, tick, p1, p2);
+
+ startUndo();
+ audio->msgChangePart(part, p1, false);
+ addPart(p2);
+ endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED);
+ part->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// cmdGluePart
+//---------------------------------------------------------
+
+void Song::cmdGluePart(Part* oPart)
+ {
+ Track* track = oPart->track();
+ PartList* pl = track->parts();
+ Part* nextPart = 0;
+
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ if (ip->second == oPart) {
+ ++ip;
+ if (ip == pl->end())
+ return;
+ nextPart = ip->second;
+ break;
+ }
+ }
+
+ Part* nPart = track->newPart(oPart);
+ nPart->setLenTick(nextPart->tick() + nextPart->lenTick() - oPart->tick());
+
+ // populate nPart with Events from oPart and nextPart
+
+ EventList* sl1 = oPart->events();
+ EventList* dl = nPart->events();
+
+ for (iEvent ie = sl1->begin(); ie != sl1->end(); ++ie)
+ dl->add(ie->second);
+
+ EventList* sl2 = nextPart->events();
+ int tickOffset = nextPart->tick() - oPart->tick();
+
+ for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) {
+ Event event = ie->second.clone();
+ event.move(tickOffset);
+ dl->add(event);
+ }
+ startUndo();
+ removePart(nextPart);
+ audio->msgChangePart(oPart, nPart, false);
+ endUndo(SC_PART_MODIFIED | SC_PART_REMOVED);
+ track->partListChanged();
+ }
+
+
diff --git a/muse/muse/track.cpp b/muse/muse/track.cpp
index 14189c61..ca457ad6 100644
--- a/muse/muse/track.cpp
+++ b/muse/muse/track.cpp
@@ -21,6 +21,7 @@
#include "track.h"
#include "midiplugin.h"
#include "song.h"
+#include "al/tempo.h"
#include "al/xml.h"
#include "icons.h"
#include "muse.h"
@@ -682,121 +683,6 @@ void Track::writeRouting(Xml& xml) const
}
//---------------------------------------------------------
-// MidiTrackBase
-//---------------------------------------------------------
-
-MidiTrackBase::MidiTrackBase()
- : Track()
- {
- _pipeline = new MidiPipeline();
- }
-
-//---------------------------------------------------------
-// MidiTrackBase
-//---------------------------------------------------------
-
-MidiTrackBase::~MidiTrackBase()
- {
- foreach(MidiPluginI* plugin, *_pipeline)
- delete plugin;
- delete _pipeline;
- }
-
-//---------------------------------------------------------
-// MidiTrackBase::writeProperties
-//---------------------------------------------------------
-
-void MidiTrackBase::writeProperties(Xml& xml) const
- {
- Track::writeProperties(xml);
- for (ciMidiPluginI ip = _pipeline->begin(); ip != _pipeline->end(); ++ip) {
- if (*ip)
- (*ip)->writeConfiguration(xml);
- }
- }
-
-//---------------------------------------------------------
-// MidiTrackBase::readProperties
-//---------------------------------------------------------
-
-bool MidiTrackBase::readProperties(QDomNode node)
- {
- QDomElement e = node.toElement();
- QString tag(e.tagName());
- if (tag == "midiPlugin") {
- MidiPluginI* pi = new MidiPluginI(this);
- if (pi->readConfiguration(node))
- delete pi;
- else
- addPlugin(pi, -1);
- }
- else
- return Track::readProperties(node);
- return false;
- }
-
-//---------------------------------------------------------
-// plugin
-//---------------------------------------------------------
-
-MidiPluginI* MidiTrackBase::plugin(int idx) const
- {
- return _pipeline->value(idx);
- }
-
-//---------------------------------------------------------
-// addPlugin
-// idx = -1 append
-// plugin = 0 remove slot
-//---------------------------------------------------------
-
-void MidiTrackBase::addPlugin(MidiPluginI* plugin, int idx)
- {
- if (plugin == 0) {
-#if 0
- MidiPluginI* oldPlugin = (*_pipeline)[idx];
- if (oldPlugin) {
- int controller = oldPlugin->plugin()->parameter();
- for (int i = 0; i < controller; ++i) {
- int id = (idx + 1) * 0x1000 + i;
- removeController(id);
- }
- }
-#endif
- }
- if (idx == -1)
- idx = _pipeline->size();
-
- if (plugin) {
- _pipeline->insert(idx, plugin);
-#if 0
- int ncontroller = plugin->plugin()->parameter();
- for (int i = 0; i < ncontroller; ++i) {
- int id = (idx + 1) * 0x1000 + i;
- QString name(plugin->getParameterName(i));
- double min, max;
- plugin->range(i, &min, &max);
- Ctrl* cl = getController(id);
- if (cl == 0) {
- cl = new Ctrl(id, name);
- cl->setRange(min, max);
- double defaultValue = plugin->defaultValue(i);
- cl->setDefault(defaultValue);
- cl->setCurVal(defaultValue);
- addController(cl);
- }
- plugin->setParam(i, cl->schedVal().f);
- plugin->setControllerList(cl);
- }
-#endif
- }
- else {
- _pipeline->removeAt(idx);
- }
- }
-
-
-//---------------------------------------------------------
// hwCtrlState
//---------------------------------------------------------
@@ -1072,4 +958,92 @@ void Track::setSendSync(bool val)
emit sendSyncChanged(val);
}
+//---------------------------------------------------------
+// splitPart
+// split part "part" at "tick" position
+// create two new parts p1 and p2
+//---------------------------------------------------------
+
+void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)
+ {
+ int l1 = 0; // len of first new part (ticks or samples)
+ int l2 = 0; // len of second new part
+
+ int samplepos = AL::tempomap.tick2frame(tickpos);
+
+ switch (type()) {
+ case WAVE:
+ l1 = samplepos - part->frame();
+ l2 = part->lenFrame() - l1;
+ break;
+ case MIDI:
+ l1 = tickpos - part->tick();
+ l2 = part->lenTick() - l1;
+ break;
+ default:
+ return;
+ }
+
+ if (l1 <= 0 || l2 <= 0)
+ return;
+
+ p1 = newPart(part); // new left part
+ p2 = newPart(part); // new right part
+
+ switch (type()) {
+ case WAVE:
+ p1->setLenFrame(l1);
+ p2->setFrame(samplepos);
+ p2->setLenFrame(l2);
+ break;
+ case MIDI:
+ p1->setLenTick(l1);
+ p2->setTick(tickpos);
+ p2->setLenTick(l2);
+ break;
+ default:
+ break;
+ }
+
+ EventList* se = part->events();
+ EventList* de1 = p1->events();
+ EventList* de2 = p2->events();
+
+ if (type() == WAVE) {
+ int ps = part->frame();
+ int d1p1 = p1->frame();
+ int d2p1 = p1->endFrame();
+ int d1p2 = p2->frame();
+ int d2p2 = p2->endFrame();
+ for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
+ Event event = ie->second;
+ int s1 = event.frame() + ps;
+ int s2 = event.endFrame() + ps;
+
+ if ((s2 > d1p1) && (s1 < d2p1)) {
+ Event si = event.mid(d1p1 - ps, d2p1 - ps);
+ de1->add(si);
+ }
+ if ((s2 > d1p2) && (s1 < d2p2)) {
+ Event si = event.mid(d1p2 - ps, d2p2 - ps);
+ si.setFrame(si.frame() - l1); //??
+ si.setFrame(0); //??
+ de2->add(si);
+ }
+ }
+ }
+ else {
+ for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
+ Event event = ie->second.clone();
+ int t = event.tick();
+ if (t >= l1) {
+ event.move(-l1);
+ de2->add(event);
+ }
+ else
+ de1->add(event);
+ }
+ }
+ }
+
diff --git a/muse/muse/track.h b/muse/muse/track.h
index 7ffb76a6..c7a68d8e 100644
--- a/muse/muse/track.h
+++ b/muse/muse/track.h
@@ -233,8 +233,8 @@ class Track : public QObject {
virtual TrackType type() const = 0;
- PartList* parts() { return _parts; }
- const PartList* cparts() const { return _parts; }
+ PartList* parts() const { return _parts; }
+
Part* findPart(unsigned tick);
void addPart(Part* p);
@@ -332,30 +332,6 @@ class Track : public QObject {
Q_DECLARE_METATYPE(class Track*);
-//---------------------------------------------------------
-// MidiTrackBase
-//---------------------------------------------------------
-
-class MidiTrackBase : public Track {
- Q_OBJECT
-
- MidiPipeline* _pipeline;
-
- public:
- MidiTrackBase();
- virtual ~MidiTrackBase();
-
- bool readProperties(QDomNode);
- void writeProperties(Xml&) const;
-
- MidiPipeline* pipeline() { return _pipeline; }
- void addPlugin(MidiPluginI* plugin, int idx);
- MidiPluginI* plugin(int idx) const;
-
- virtual void processMidi(unsigned, unsigned, unsigned, unsigned) {}
- virtual void getEvents(unsigned /*from*/, unsigned /*to*/, int /*channel*/, MidiEventList* /*dst*/) {}
- };
-
typedef QList<Track*> TrackList;
typedef TrackList::iterator iTrack;
typedef TrackList::const_iterator ciTrack;
diff --git a/muse/muse/wave.cpp b/muse/muse/wave.cpp
index 7ef0a665..934b8b9d 100644
--- a/muse/muse/wave.cpp
+++ b/muse/muse/wave.cpp
@@ -910,7 +910,7 @@ bool MusE::importWaveToTrack(const QString& wave, Track* track, const Pos& pos)
part->addEvent(event);
part->setName(srcInfo.baseName());
- audio->msgAddPart(part);
+ song->cmdAddPart(part);
unsigned endTick = part->tick() + part->lenTick();
if (song->len() < endTick)
song->setLen(endTick);
diff --git a/muse/muse/wavetrack.cpp b/muse/muse/wavetrack.cpp
index 8504d35c..c022c3c1 100644
--- a/muse/muse/wavetrack.cpp
+++ b/muse/muse/wavetrack.cpp
@@ -140,7 +140,7 @@ void WaveTrack::write(Xml& xml) const
{
xml.tag("wavetrack");
AudioTrack::writeProperties(xml);
- const PartList* pl = cparts();
+ const PartList* pl = parts();
for (ciPart p = pl->begin(); p != pl->end(); ++p)
p->second->write(xml);
xml.etag("wavetrack");
@@ -232,7 +232,7 @@ void WaveTrack::startRecording()
recordPart->setPos(spos);
recordPart->setLenTick(epos.tick() - spos.tick());
recordPart->setName(name());
- audio->msgAddPart(recordPart, false);
+ song->addPart(recordPart);
partCreated = true;
emit partsChanged();
}