summaryrefslogtreecommitdiff
path: root/muse2/muse
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-12-21 17:39:57 +0000
committerFlorian Jung <flo@windfisch.org>2011-12-21 17:39:57 +0000
commit1057d7190242cdf9248671b316a398db805f5f56 (patch)
treeab50268a7db2f80cfb45a7ad6578fe735ab84ce5 /muse2/muse
parent9977c7114089b8708d310268833b83343caa0fd1 (diff)
parentc36a5508aa42e596b005425208054af9a60734b4 (diff)
merged with trunk (that is, pulled the fixes from release_2_0)
only quickly tested, seems okay on the first glance
Diffstat (limited to 'muse2/muse')
-rw-r--r--muse2/muse/app.cpp411
-rw-r--r--muse2/muse/app.h19
-rw-r--r--muse2/muse/arranger/alayout.cpp2
-rw-r--r--muse2/muse/arranger/arranger.cpp61
-rw-r--r--muse2/muse/arranger/arranger.h1
-rw-r--r--muse2/muse/arranger/arrangerview.cpp31
-rw-r--r--muse2/muse/arranger/arrangerview.h10
-rw-r--r--muse2/muse/arranger/pcanvas.cpp183
-rw-r--r--muse2/muse/arranger/pcanvas.h15
-rw-r--r--muse2/muse/arranger/tlist.cpp182
-rw-r--r--muse2/muse/audio.cpp54
-rw-r--r--muse2/muse/audio.h10
-rw-r--r--muse2/muse/audioprefetch.cpp7
-rw-r--r--muse2/muse/audiotrack.cpp44
-rw-r--r--muse2/muse/cliplist/cliplist.cpp4
-rw-r--r--muse2/muse/cliplist/cliplist.h2
-rw-r--r--muse2/muse/cobject.cpp86
-rw-r--r--muse2/muse/cobject.h28
-rw-r--r--muse2/muse/conf.cpp148
-rw-r--r--muse2/muse/confmport.cpp183
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.cpp17
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.h2
-rw-r--r--muse2/muse/ctrl/ctrlpanel.cpp3
-rw-r--r--muse2/muse/dialogs.cpp16
-rw-r--r--muse2/muse/dialogs.h1
-rw-r--r--muse2/muse/driver/alsamidi.cpp273
-rw-r--r--muse2/muse/driver/jack.cpp164
-rw-r--r--muse2/muse/driver/jackaudio.h1
-rw-r--r--muse2/muse/driver/jackmidi.cpp18
-rw-r--r--muse2/muse/dssihost.cpp294
-rw-r--r--muse2/muse/dssihost.h7
-rw-r--r--muse2/muse/exportmidi.cpp100
-rw-r--r--muse2/muse/functions.cpp115
-rw-r--r--muse2/muse/functions.h2
-rw-r--r--muse2/muse/gconfig.cpp10
-rw-r--r--muse2/muse/gconfig.h4
-rw-r--r--muse2/muse/globals.cpp196
-rw-r--r--muse2/muse/globals.h42
-rw-r--r--muse2/muse/helper.cpp703
-rw-r--r--muse2/muse/helper.h11
-rw-r--r--muse2/muse/importmidi.cpp4
-rw-r--r--muse2/muse/instruments/editinstrument.cpp50
-rw-r--r--muse2/muse/instruments/minstrument.cpp35
-rw-r--r--muse2/muse/instruments/minstrument.h8
-rw-r--r--muse2/muse/liste/editevent.cpp7
-rw-r--r--muse2/muse/liste/listedit.cpp14
-rw-r--r--muse2/muse/liste/listedit.h2
-rw-r--r--muse2/muse/main.cpp120
-rw-r--r--muse2/muse/marker/markerview.cpp5
-rw-r--r--muse2/muse/marker/markerview.h2
-rw-r--r--muse2/muse/master/lmaster.cpp9
-rw-r--r--muse2/muse/master/lmaster.h2
-rw-r--r--muse2/muse/master/master.cpp20
-rw-r--r--muse2/muse/master/masteredit.cpp11
-rw-r--r--muse2/muse/master/masteredit.h2
-rw-r--r--muse2/muse/midi.cpp3
-rw-r--r--muse2/muse/midictrl.cpp3
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp8
-rw-r--r--muse2/muse/midiedit/dcanvas.h2
-rw-r--r--muse2/muse/midiedit/drumedit.cpp14
-rw-r--r--muse2/muse/midiedit/drumedit.h2
-rw-r--r--muse2/muse/midiedit/ecanvas.cpp112
-rw-r--r--muse2/muse/midiedit/ecanvas.h2
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp12
-rw-r--r--muse2/muse/midiedit/pianoroll.h2
-rw-r--r--muse2/muse/midiedit/prcanvas.cpp15
-rw-r--r--muse2/muse/midiedit/prcanvas.h2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp210
-rw-r--r--muse2/muse/midiedit/scoreedit.h85
-rw-r--r--muse2/muse/midifile.cpp34
-rw-r--r--muse2/muse/midiport.cpp19
-rw-r--r--muse2/muse/midiseq.cpp25
-rw-r--r--muse2/muse/mixer/amixer.cpp2
-rw-r--r--muse2/muse/mixer/astrip.cpp38
-rw-r--r--muse2/muse/mixer/mstrip.cpp6
-rw-r--r--muse2/muse/mixer/strip.cpp24
-rw-r--r--muse2/muse/mixer/strip.h1
-rw-r--r--muse2/muse/mpevent.cpp2
-rw-r--r--muse2/muse/mplugins/mitplugin.cpp10
-rw-r--r--muse2/muse/mplugins/rhythm.cpp4
-rw-r--r--muse2/muse/mplugins/rhythm.h27
-rw-r--r--muse2/muse/node.cpp770
-rw-r--r--muse2/muse/osc.cpp27
-rw-r--r--muse2/muse/osc.h6
-rw-r--r--muse2/muse/part.cpp18
-rw-r--r--muse2/muse/plugin.cpp125
-rw-r--r--muse2/muse/plugin.h115
-rw-r--r--muse2/muse/remote/pyapi.cpp4
-rw-r--r--muse2/muse/route.cpp725
-rw-r--r--muse2/muse/route.h12
-rw-r--r--muse2/muse/shortcuts.cpp422
-rw-r--r--muse2/muse/sig.cpp35
-rw-r--r--muse2/muse/song.cpp725
-rw-r--r--muse2/muse/song.h5
-rw-r--r--muse2/muse/songfile.cpp58
-rw-r--r--muse2/muse/structure.cpp238
-rw-r--r--muse2/muse/structure.h7
-rw-r--r--muse2/muse/synth.cpp63
-rw-r--r--muse2/muse/synth.h8
-rw-r--r--muse2/muse/ticksynth.cpp1
-rw-r--r--muse2/muse/track.cpp219
-rw-r--r--muse2/muse/track.h69
-rw-r--r--muse2/muse/transport.cpp19
-rw-r--r--muse2/muse/undo.cpp16
-rw-r--r--muse2/muse/undo.h1
-rw-r--r--muse2/muse/vst.h1
-rw-r--r--muse2/muse/wave.cpp24
-rw-r--r--muse2/muse/wave.h6
-rw-r--r--muse2/muse/waveedit/waveedit.cpp19
-rw-r--r--muse2/muse/waveedit/waveedit.h2
-rw-r--r--muse2/muse/wavetrack.cpp8
-rw-r--r--muse2/muse/widgets/citem.h2
-rw-r--r--muse2/muse/widgets/comboQuant.cpp6
-rw-r--r--muse2/muse/widgets/configmidifilebase.ui40
-rw-r--r--muse2/muse/widgets/filedialog.cpp65
-rw-r--r--muse2/muse/widgets/filedialog.h15
-rw-r--r--muse2/muse/widgets/function_dialogs/quantbase.ui24
-rw-r--r--muse2/muse/widgets/function_dialogs/quantize.cpp22
-rw-r--r--muse2/muse/widgets/function_dialogs/quantize.h5
-rw-r--r--muse2/muse/widgets/genset.cpp56
-rw-r--r--muse2/muse/widgets/genset.h4
-rw-r--r--muse2/muse/widgets/gensetbase.ui139
-rw-r--r--muse2/muse/widgets/header.cpp6
-rw-r--r--muse2/muse/widgets/knob.cpp24
-rw-r--r--muse2/muse/widgets/knob.h1
-rw-r--r--muse2/muse/widgets/meter.cpp7
-rw-r--r--muse2/muse/widgets/metronome.cpp2
-rw-r--r--muse2/muse/widgets/midisync.ui13
-rw-r--r--muse2/muse/widgets/mtrackinfo.cpp33
-rw-r--r--muse2/muse/widgets/mtscale_flo.cpp3
-rw-r--r--muse2/muse/widgets/musewidgetsplug.cpp3
-rw-r--r--muse2/muse/widgets/popupmenu.cpp23
-rw-r--r--muse2/muse/widgets/poslabel.cpp6
-rw-r--r--muse2/muse/widgets/projectcreate.ui99
-rw-r--r--muse2/muse/widgets/projectcreateimpl.cpp191
-rw-r--r--muse2/muse/widgets/projectcreateimpl.h19
-rw-r--r--muse2/muse/widgets/routepopup.cpp60
-rw-r--r--muse2/muse/widgets/shortcutcapturedialog.cpp4
-rw-r--r--muse2/muse/widgets/shortcutconfig.cpp6
-rw-r--r--muse2/muse/widgets/shortcutconfigbase.ui115
-rw-r--r--muse2/muse/widgets/spinbox.cpp15
-rw-r--r--muse2/muse/widgets/spinbox.h3
-rw-r--r--muse2/muse/widgets/synthconfigbase.ui14
-rw-r--r--muse2/muse/widgets/tb1.cpp7
-rw-r--r--muse2/muse/widgets/tools.cpp46
-rw-r--r--muse2/muse/widgets/utils.cpp3
-rw-r--r--muse2/muse/widgets/visibletracks.cpp32
-rw-r--r--muse2/muse/widgets/visibletracks.h3
-rw-r--r--muse2/muse/xml.cpp94
149 files changed, 5493 insertions, 3880 deletions
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index 386cf226..c71e23fc 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -4,6 +4,7 @@
// $Id: app.cpp,v 1.113.2.68 2009/12/21 14:51:51 spamatica Exp $
//
// (C) Copyright 1999-2011 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -33,6 +34,8 @@
#include <QProgressDialog>
#include <QMdiArea>
#include <QMdiSubWindow>
+#include <QSocketNotifier>
+#include <QString>
#include <iostream>
@@ -55,6 +58,7 @@
#include "filedialog.h"
#include "gconfig.h"
#include "gui.h"
+#include "helper.h"
#include "icons.h"
#include "instruments/editinstrument.h"
#include "listedit.h"
@@ -84,8 +88,11 @@ extern void exitJackAudio();
extern void exitDummyAudio();
extern void exitOSC();
extern void exitMidiAlsa();
-}
+extern void initMidiSequencer();
+extern void initAudio();
+extern void initAudioPrefetch();
+}
namespace MusEGui {
@@ -93,31 +100,13 @@ namespace MusEGui {
static pthread_t watchdogThread;
//ErrorHandler *error;
-static const char* fileOpenText =
- QT_TRANSLATE_NOOP("@default", "Click this button to open a <em>new song</em>.<br>"
- "You can also select the <b>Open command</b> from the File menu.");
-static const char* fileSaveText =
- QT_TRANSLATE_NOOP("@default", "Click this button to save the song you are "
- "editing. You will be prompted for a file name.\n"
- "You can also select the Save command from the File menu.");
-static const char* fileNewText = QT_TRANSLATE_NOOP("@default", "Create New Song");
-
-static const char* infoLoopButton = QT_TRANSLATE_NOOP("@default", "loop between left mark and right mark");
-static const char* infoPunchinButton = QT_TRANSLATE_NOOP("@default", "record starts at left mark");
-static const char* infoPunchoutButton = QT_TRANSLATE_NOOP("@default", "record stops at right mark");
-static const char* infoStartButton = QT_TRANSLATE_NOOP("@default", "rewind to start position");
-static const char* infoRewindButton = QT_TRANSLATE_NOOP("@default", "rewind current position");
-static const char* infoForwardButton = QT_TRANSLATE_NOOP("@default", "move current position");
-static const char* infoStopButton = QT_TRANSLATE_NOOP("@default", "stop sequencer");
-static const char* infoPlayButton = QT_TRANSLATE_NOOP("@default", "start sequencer play");
-static const char* infoRecordButton = QT_TRANSLATE_NOOP("@default", "to record press record and then play");
-static const char* infoPanicButton = QT_TRANSLATE_NOOP("@default", "send note off to all midi channels");
#define PROJECT_LIST_LEN 6
static QString* projectList[PROJECT_LIST_LEN];
#ifdef HAVE_LASH
#include <lash/lash.h>
+#include <lo/lo_osc_types.h>
lash_client_t * lash_client = 0;
extern snd_seq_t * alsaSeq;
#endif /* HAVE_LASH */
@@ -189,14 +178,7 @@ bool MusE::seqStart()
if(MusEGlobal::realTimeScheduling)
{
{
- //pfprio = MusEGlobal::realTimePriority - 5;
- // p3.3.40
pfprio = MusEGlobal::realTimePriority + 1;
-
- //midiprio = MusEGlobal::realTimePriority - 2;
- // p3.3.37
- //midiprio = MusEGlobal::realTimePriority + 1;
- // p3.3.40
midiprio = MusEGlobal::realTimePriority + 2;
}
}
@@ -216,9 +198,6 @@ bool MusE::seqStart()
MusEGlobal::audioPrefetch->msgSeek(0, true); // force
- //MusEGlobal::midiSeqRunning = !midiSeq->start(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0);
- // Changed by Tim. p3.3.22
- //MusEGlobal::midiSeq->start(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0);
MusEGlobal::midiSeq->start(midiprio);
int counter=0;
@@ -242,7 +221,7 @@ bool MusE::seqStart()
}
return true;
}
-
+
//---------------------------------------------------------
// stop
//---------------------------------------------------------
@@ -276,6 +255,7 @@ bool MusE::seqRestart()
}
seqStop();
}
+
if(!seqStart())
return false;
@@ -317,7 +297,7 @@ void addProject(const QString& name)
//---------------------------------------------------------
//MusE::MusE(int argc, char** argv) : QMainWindow(0, "mainwindow")
-MusE::MusE(int argc, char** argv) : QMainWindow()
+MusE::MusE(int /*argc*/, char** /*argv*/) : QMainWindow()
{
// By T356. For LADSPA plugins in plugin.cpp
// QWidgetFactory::addWidgetFactory( new PluginWidgetFactory ); ddskrjo
@@ -351,6 +331,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
progress = 0;
activeTopWin = NULL;
currentMenuSharingTopwin = NULL;
+ waitingForTopwin = NULL;
appName = QString("MusE");
setWindowTitle(appName);
@@ -364,8 +345,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
MusEGlobal::heartBeatTimer = new QTimer(this);
MusEGlobal::heartBeatTimer->setObjectName("timer");
connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), MusEGlobal::song, SLOT(beat()));
-
-
connect(this, SIGNAL(activeTopWinChanged(MusEGui::TopWin*)), SLOT(activeTopWinChangedSlot(MusEGui::TopWin*)));
#ifdef ENABLE_PYTHON
@@ -411,21 +390,21 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
tr("Loop"), MusEGlobal::transportAction);
MusEGlobal::loopAction->setCheckable(true);
- MusEGlobal::loopAction->setWhatsThis(tr(infoLoopButton));
+ MusEGlobal::loopAction->setWhatsThis(tr("loop between left mark and right mark"));
connect(MusEGlobal::loopAction, SIGNAL(toggled(bool)), MusEGlobal::song, SLOT(setLoop(bool)));
MusEGlobal::punchinAction = new QAction(QIcon(*MusEGui::punchin1Icon),
tr("Punchin"), MusEGlobal::transportAction);
MusEGlobal::punchinAction->setCheckable(true);
- MusEGlobal::punchinAction->setWhatsThis(tr(infoPunchinButton));
+ MusEGlobal::punchinAction->setWhatsThis(tr("record starts at left mark"));
connect(MusEGlobal::punchinAction, SIGNAL(toggled(bool)), MusEGlobal::song, SLOT(setPunchin(bool)));
MusEGlobal::punchoutAction = new QAction(QIcon(*MusEGui::punchout1Icon),
tr("Punchout"), MusEGlobal::transportAction);
MusEGlobal::punchoutAction->setCheckable(true);
- MusEGlobal::punchoutAction->setWhatsThis(tr(infoPunchoutButton));
+ MusEGlobal::punchoutAction->setWhatsThis(tr("record stops at right mark"));
connect(MusEGlobal::punchoutAction, SIGNAL(toggled(bool)), MusEGlobal::song, SLOT(setPunchout(bool)));
QAction *tseparator = new QAction(this);
@@ -435,26 +414,26 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
MusEGlobal::startAction = new QAction(QIcon(*MusEGui::startIcon),
tr("Start"), MusEGlobal::transportAction);
- MusEGlobal::startAction->setWhatsThis(tr(infoStartButton));
+ MusEGlobal::startAction->setWhatsThis(tr("rewind to start position"));
connect(MusEGlobal::startAction, SIGNAL(activated()), MusEGlobal::song, SLOT(rewindStart()));
MusEGlobal::rewindAction = new QAction(QIcon(*MusEGui::frewindIcon),
tr("Rewind"), MusEGlobal::transportAction);
- MusEGlobal::rewindAction->setWhatsThis(tr(infoRewindButton));
+ MusEGlobal::rewindAction->setWhatsThis(tr("rewind current position"));
connect(MusEGlobal::rewindAction, SIGNAL(activated()), MusEGlobal::song, SLOT(rewind()));
MusEGlobal::forwardAction = new QAction(QIcon(*MusEGui::fforwardIcon),
tr("Forward"), MusEGlobal::transportAction);
- MusEGlobal::forwardAction->setWhatsThis(tr(infoForwardButton));
+ MusEGlobal::forwardAction->setWhatsThis(tr("move current position"));
connect(MusEGlobal::forwardAction, SIGNAL(activated()), MusEGlobal::song, SLOT(forward()));
MusEGlobal::stopAction = new QAction(QIcon(*MusEGui::stopIcon),
tr("Stop"), MusEGlobal::transportAction);
MusEGlobal::stopAction->setCheckable(true);
- MusEGlobal::stopAction->setWhatsThis(tr(infoStopButton));
+ MusEGlobal::stopAction->setWhatsThis(tr("stop sequencer"));
MusEGlobal::stopAction->setChecked(true);
connect(MusEGlobal::stopAction, SIGNAL(toggled(bool)), MusEGlobal::song, SLOT(setStop(bool)));
@@ -462,23 +441,23 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
tr("Play"), MusEGlobal::transportAction);
MusEGlobal::playAction->setCheckable(true);
- MusEGlobal::playAction->setWhatsThis(tr(infoPlayButton));
+ MusEGlobal::playAction->setWhatsThis(tr("start sequencer play"));
MusEGlobal::playAction->setChecked(false);
connect(MusEGlobal::playAction, SIGNAL(toggled(bool)), MusEGlobal::song, SLOT(setPlay(bool)));
MusEGlobal::recordAction = new QAction(QIcon(*MusEGui::recordIcon),
tr("Record"), MusEGlobal::transportAction);
MusEGlobal::recordAction->setCheckable(true);
- MusEGlobal::recordAction->setWhatsThis(tr(infoRecordButton));
+ MusEGlobal::recordAction->setWhatsThis(tr("to record press record and then play"));
connect(MusEGlobal::recordAction, SIGNAL(toggled(bool)), MusEGlobal::song, SLOT(setRecord(bool)));
MusEGlobal::panicAction = new QAction(QIcon(*MusEGui::panicIcon),
tr("Panic"), this);
- MusEGlobal::panicAction->setWhatsThis(tr(infoPanicButton));
+ MusEGlobal::panicAction->setWhatsThis(tr("send note off to all midi channels"));
connect(MusEGlobal::panicAction, SIGNAL(activated()), MusEGlobal::song, SLOT(panic()));
- MusECore::initMidiInstruments();
+ MusECore::initMidiInstruments();
MusECore::initMidiPorts();
MusECore::initMidiDevices();
@@ -486,20 +465,26 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
//-------- File Actions
fileNewAction = new QAction(QIcon(*MusEGui::filenewIcon), tr("&New"), this);
- fileNewAction->setToolTip(tr(fileNewText));
- fileNewAction->setWhatsThis(tr(fileNewText));
+ fileNewAction->setToolTip(tr("Create New Song"));
+ fileNewAction->setWhatsThis(tr("Create New Song"));
fileOpenAction = new QAction(QIcon(*MusEGui::openIcon), tr("&Open"), this);
- fileOpenAction->setToolTip(tr(fileOpenText));
- fileOpenAction->setWhatsThis(tr(fileOpenText));
+ fileOpenAction->setToolTip(tr("Click this button to open a <em>new song</em>.<br>"
+ "You can also select the <b>Open command</b> from the File menu."));
+ fileOpenAction->setWhatsThis(tr("Click this button to open a <em>new song</em>.<br>"
+ "You can also select the <b>Open command</b> from the File menu."));
openRecent = new QMenu(tr("Open &Recent"), this);
fileSaveAction = new QAction(QIcon(*MusEGui::saveIcon), tr("&Save"), this);
- fileSaveAction->setToolTip(tr(fileSaveText));
- fileSaveAction->setWhatsThis(tr(fileSaveText));
+ fileSaveAction->setToolTip(tr("Click this button to save the song you are "
+ "editing. You will be prompted for a file name.\n"
+ "You can also select the Save command from the File menu."));
+ fileSaveAction->setWhatsThis(tr("Click this button to save the song you are "
+ "editing. You will be prompted for a file name.\n"
+ "You can also select the Save command from the File menu."));
fileSaveAsAction = new QAction(tr("Save &As"), this);
@@ -718,7 +703,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
//rlimit lim;
//getrlimit(RLIMIT_RTPRIO, &lim);
//printf("RLIMIT_RTPRIO soft:%d hard:%d\n", lim.rlim_cur, lim.rlim_max); // Reported 80, 80 even with non-RT kernel.
-
+
if (MusEGlobal::realTimePriority < sched_get_priority_min(SCHED_FIFO))
MusEGlobal::realTimePriority = sched_get_priority_min(SCHED_FIFO);
else if (MusEGlobal::realTimePriority > sched_get_priority_max(SCHED_FIFO))
@@ -733,18 +718,19 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
MusEGlobal::midiRTPrioOverride = sched_get_priority_max(SCHED_FIFO);
}
- // Changed by Tim. p3.3.17
- //MusEGlobal::midiSeq = new MusECore::MidiSeq(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0, "Midi");
- MusEGlobal::midiSeq = new MusECore::MidiSeq("Midi");
- MusEGlobal::audio = new MusECore::Audio();
- //MusEGlobal::audioPrefetch = new MusECore::AudioPrefetch(0, "Disc");
- MusEGlobal::audioPrefetch = new MusECore::AudioPrefetch("Prefetch");
-
+ MusECore::initMidiSequencer();
+ MusECore::initAudio();
+
+ // Moved here from Audio::Audio
+ QSocketNotifier* ss = new QSocketNotifier(MusEGlobal::audio->getFromThreadFdr(), QSocketNotifier::Read, this);
+ connect(ss, SIGNAL(activated(int)), MusEGlobal::song, SLOT(seqSignal(int)));
+
+ MusECore::initAudioPrefetch();
+
//---------------------------------------------------
// Popups
//---------------------------------------------------
-
// when adding a menu to the main window, remember adding it to
// either the leadingMenus or trailingMenus list!
// also do NOT use menuBar()->addMenu(QString&), but ALWAYS
@@ -973,6 +959,11 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
transport = new MusEGui::Transport(this, "transport");
bigtime = 0;
+ MusEGlobal::song->blockSignals(false);
+
+ // Load start song moved to main.cpp p4.0.41 REMOVE Tim.
+ /*
+
//---------------------------------------------------
// load project
// if no songname entered on command line:
@@ -987,7 +978,8 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
name = argv[0];
else if (MusEGlobal::config.startMode == 0) {
if (argc < 2)
- name = projectList[0] ? *projectList[0] : QString("untitled");
+ //name = projectList[0] ? *projectList[0] : QString("untitled");
+ name = projectList[0] ? *projectList[0] : MusEGui::getUniqueUntitledName(); // p4.0.40
else
name = argv[0];
printf("starting with selected song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
@@ -1001,19 +993,47 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
printf("starting with pre configured song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
name = MusEGlobal::config.startSong;
}
- MusEGlobal::song->blockSignals(false);
- loadProjectFile(name, useTemplate, true);
-
+
+ // loadProjectFile(name, useTemplate, true); //commented out by flo: see below (*)
+ */
+
changeConfig(false);
QSettings settings("MusE", "MusE-qt");
restoreGeometry(settings.value("MusE/geometry").toByteArray());
//restoreState(settings.value("MusE/windowState").toByteArray());
- MusEGlobal::song->update();
-
- updateWindowMenu();
+ MusEGlobal::song->update(); // commented out by flo: will be done by the below (*)
+ updateWindowMenu(); // same here
+
+ // Load start song moved to main.cpp p4.0.41 REMOVE Tim.
+ /*
+
+ // this is (*).
+ // this is a really hackish workaround for the loading-on-startup problem.
+ // i have absolutely no idea WHY it breaks when using loadProjectFile()
+ // above, but it does on my machine (it doesn't on others!).
+ // the problem can be worked around by delaying loading the song file.
+ // i use hackishSongOpenTimer for this, which calls after 10ms a slot
+ // which then does the actual loadProjectFile() call.
+ // FIXME: please, if anyone finds the real problem, FIX it and
+ // remove that dirty, dirty workaround!
+ hackishSongOpenFilename=name;
+ hackishSongOpenUseTemplate=useTemplate;
+ hackishSongOpenTimer=new QTimer(this);
+ hackishSongOpenTimer->setInterval(10);
+ hackishSongOpenTimer->setSingleShot(true);
+ connect(hackishSongOpenTimer, SIGNAL(timeout()), this, SLOT(hackishSongOpenTimerTimeout()));
+ hackishSongOpenTimer->start();
+ */
}
+// Load start song moved to main.cpp p4.0.41 REMOVE Tim.
+//void MusE::hackishSongOpenTimerTimeout()
+//{
+ ///loadProjectFile(hackishSongOpenFilename, hackishSongOpenUseTemplate, true);
+ //loadProjectFile(hackishSongOpenFilename, hackishSongOpenUseTemplate, !hackishSongOpenUseTemplate);
+//}
+
MusE::~MusE()
{
}
@@ -1027,6 +1047,44 @@ void MusE::setHeartBeat()
MusEGlobal::heartBeatTimer->start(1000/MusEGlobal::config.guiRefresh);
}
+//---------------------------------------------------
+// loadDefaultSong
+// if no songname entered on command line:
+// startMode: 0 - load last song
+// 1 - load default template
+// 2 - load configured start song
+//---------------------------------------------------
+
+void MusE::loadDefaultSong(int argc, char** argv)
+{
+ QString name;
+ bool useTemplate = false;
+ if (argc >= 2)
+ name = argv[0];
+ else if (MusEGlobal::config.startMode == 0) {
+ if (argc < 2)
+ //name = projectList[0] ? *projectList[0] : QString("untitled");
+ name = projectList[0] ? *projectList[0] : MusEGui::getUniqueUntitledName(); // p4.0.40
+ else
+ name = argv[0];
+ printf("starting with selected song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
+ }
+ else if (MusEGlobal::config.startMode == 1) {
+ printf("starting with default template\n");
+ name = MusEGlobal::museGlobalShare + QString("/templates/default.med");
+ useTemplate = true;
+ }
+ else if (MusEGlobal::config.startMode == 2) {
+ printf("starting with pre configured song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
+ name = MusEGlobal::config.startSong;
+ }
+ //loadProjectFile(name, useTemplate, true);
+ loadProjectFile(name, useTemplate, !useTemplate);
+
+ //MusEGlobal::song->update();
+ //updateWindowMenu();
+}
+
//---------------------------------------------------------
// resetDevices
//---------------------------------------------------------
@@ -1168,7 +1226,8 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
QApplication::restoreOverrideCursor();
return;
}
- project.setFile("untitled");
+ //project.setFile("untitled");
+ project.setFile(MusEGui::getUniqueUntitledName()); // p4.0.40
MusEGlobal::museProject = MusEGlobal::museProjectInitPath;
}
else {
@@ -1226,7 +1285,8 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
}
if (!songTemplate) {
addProject(project.absoluteFilePath());
- setWindowTitle(QString("MusE: Song: ") + project.completeBaseName());
+ //setWindowTitle(QString("MusE: Song: ") + project.completeBaseName());
+ setWindowTitle(QString("MusE: Song: ") + MusEGui::projectTitleFromFilename(project.absoluteFilePath()));
}
MusEGlobal::song->dirty = false;
progress->setValue(30);
@@ -1248,7 +1308,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
// set the geometry if the mixer has already been created.
if(mixer1)
{
- //if(mixer1->geometry().size() != MusEGlobal::config.mixer1.geometry.size()) // p3.3.53 Moved below
+ //if(mixer1->geometry().size() != MusEGlobal::config.mixer1.geometry.size()) // Moved below
// mixer1->resize(MusEGlobal::config.mixer1.geometry.size());
if(mixer1->geometry().topLeft() != MusEGlobal::config.mixer1.geometry.topLeft())
@@ -1256,7 +1316,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
}
if(mixer2)
{
- //if(mixer2->geometry().size() != MusEGlobal::config.mixer2.geometry.size()) // p3.3.53 Moved below
+ //if(mixer2->geometry().size() != MusEGlobal::config.mixer2.geometry.size()) // Moved below
// mixer2->resize(MusEGlobal::config.mixer2.geometry.size());
if(mixer2->geometry().topLeft() != MusEGlobal::config.mixer2.geometry.topLeft())
@@ -1285,7 +1345,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
arrangerView->scoreNamingChanged(); // inform the score menus about the new scores and their names
progress->setValue(50);
- // p3.3.53 Try this AFTER the song update above which does a mixer update... Tested OK - mixers resize properly now.
+ // Try this AFTER the song update above which does a mixer update... Tested OK - mixers resize properly now.
if (loadAll)
{
if(mixer1)
@@ -1348,10 +1408,13 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
void MusE::setUntitledProject()
{
setConfigDefaults();
- QString name("untitled");
+ //QString name("untitled");
+ QString name(MusEGui::getUniqueUntitledName()); // p4.0.40
+
MusEGlobal::museProject = "./"; //QFileInfo(name).absolutePath();
project.setFile(name);
- setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(name)));
}
//---------------------------------------------------------
@@ -1403,14 +1466,14 @@ void MusE::loadTemplate()
if (!fn.isEmpty()) {
// MusEGlobal::museProject = QFileInfo(fn).absolutePath();
- loadProjectFile(fn, true, true);
+ //loadProjectFile(fn, true, true);
// With templates, don't clear midi ports.
// Any named ports in the template file are useless since they likely
// would not be found on other users' machines.
// So keep whatever the user currently has set up for ports.
// Note that this will also keep the current window configurations etc.
// but actually that's also probably a good thing. p4.0.17 Tim. TESTING: Maybe some problems...
- //loadProjectFile(fn, true, false);
+ loadProjectFile(fn, true, false);
setUntitledProject();
}
@@ -1422,7 +1485,11 @@ void MusE::loadTemplate()
bool MusE::save()
{
- if (project.completeBaseName() == "untitled")
+ //if (project.completeBaseName() == "untitled") // p4.0.40 Must catch "untitled 1" "untitled 2" etc
+ //if (MusEGui::projectTitleFromFilename(project.absoluteFilePath()) == "untitled")
+ //if (MusEGui::projectTitleFromFilename(project.absoluteFilePath()) == MusEGui::getUniqueUntitledName())
+ ///if (project.absoluteFilePath() == MusEGui::getUniqueUntitledName())
+ if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath )
return saveAs();
else
return save(project.filePath(), false);
@@ -1554,7 +1621,7 @@ void MusE::closeEvent(QCloseEvent* event)
MusECore::exitMetronome();
// Make sure to delete the menu. ~routingPopupMenu() will NOT be called automatically.
- // Even though it is a child of MusE, it just passes MusE onto the underlying PopupMenus. p4.0.26
+ // Even though it is a child of MusE, it just passes MusE onto the underlying PopupMenus.
if(routingPopupMenu)
delete routingPopupMenu;
#if 0
@@ -1584,7 +1651,7 @@ void MusE::closeEvent(QCloseEvent* event)
}
#ifdef HAVE_LASH
- // Disconnect gracefully from LASH. Tim. p3.3.14
+ // Disconnect gracefully from LASH.
if(lash_client)
{
if(MusEGlobal::debugMsg)
@@ -1602,7 +1669,6 @@ void MusE::closeEvent(QCloseEvent* event)
printf("MusE: Exiting OSC\n");
MusECore::exitOSC();
- // p3.3.47
delete MusEGlobal::audioPrefetch;
delete MusEGlobal::audio;
delete MusEGlobal::midiSeq;
@@ -1631,8 +1697,8 @@ void MusE::showMarker(bool flag)
markerView = new MusEGui::MarkerView(this);
connect(markerView, SIGNAL(closed()), SLOT(markerClosed()));
- toplevels.push_back(markerView);
markerView->show();
+ toplevels.push_back(markerView);
}
markerView->setVisible(flag);
viewMarkerAction->setChecked(flag);
@@ -1654,6 +1720,20 @@ void MusE::markerClosed()
setCurrentMenuSharingTopwin(NULL);
updateWindowMenu();
+
+ // focus the last activated topwin which is not the marker view
+ QList<QMdiSubWindow*> l = mdiArea->subWindowList(QMdiArea::StackingOrder);
+ for (QList<QMdiSubWindow*>::iterator lit=l.begin(); lit!=l.end(); lit++)
+ if ((*lit)->isVisible() && (*lit)->widget() != markerView)
+ {
+ if (MusEGlobal::debugMsg)
+ printf("bringing '%s' to front instead of closed arranger window\n",(*lit)->widget()->windowTitle().toAscii().data());
+
+ bringToFront((*lit)->widget());
+
+ break;
+ }
+
}
//---------------------------------------------------------
@@ -1687,6 +1767,20 @@ void MusE::arrangerClosed()
{
viewArrangerAction->setChecked(false);
updateWindowMenu();
+
+ // focus the last activated topwin which is not the arranger view
+ QList<QMdiSubWindow*> l = mdiArea->subWindowList(QMdiArea::StackingOrder);
+ for (QList<QMdiSubWindow*>::iterator lit=l.begin(); lit!=l.end(); lit++)
+ if ((*lit)->isVisible() && (*lit)->widget() != arrangerView)
+ {
+ if (MusEGlobal::debugMsg)
+ printf("bringing '%s' to front instead of closed arranger window\n",(*lit)->widget()->windowTitle().toAscii().data());
+
+ bringToFront((*lit)->widget());
+
+ break;
+ }
+
}
//---------------------------------------------------------
@@ -1728,7 +1822,7 @@ MusEGui::RoutePopupMenu* MusE::getRoutingPopupMenu()
bool MusE::saveAs()
{
QString name;
- if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) {
+ //if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) // Use project dialog always now.
if (MusEGlobal::config.useProjectSaveDialog) {
MusEGui::ProjectCreateImpl pci(MusEGlobal::muse);
if (pci.exec() == QDialog::Rejected) {
@@ -1749,10 +1843,11 @@ bool MusE::saveAs()
QMessageBox::warning(this,"Path error","Can't create project path", QMessageBox::Ok);
return false;
}
- }
- else {
- name = MusEGui::getSaveFileName(QString(""), MusEGlobal::med_file_save_pattern, this, tr("MusE: Save As"));
- }
+ //}
+ //else {
+ // name = MusEGui::getSaveFileName(QString(""), MusEGlobal::med_file_save_pattern, this, tr("MusE: Save As"));
+ //}
+
bool ok = false;
if (!name.isEmpty()) {
QString tempOldProj = MusEGlobal::museProject;
@@ -1760,7 +1855,8 @@ bool MusE::saveAs()
ok = save(name, true);
if (ok) {
project.setFile(name);
- setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(name)));
addProject(name);
}
else
@@ -1843,9 +1939,9 @@ void MusE::openInScoreEdit(MusEGui::ScoreEdit* destination, MusECore::PartList*
if (destination==NULL) // if no destination given, create a new one
{
destination = new MusEGui::ScoreEdit(this, 0, _arranger->cursorValue());
- destination->show();
toplevels.push_back(destination);
- connect(destination, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ destination->show();
+ connect(destination, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(destination, SIGNAL(name_changed()), arrangerView, SLOT(scoreNamingChanged()));
//connect(muse, SIGNAL(configChanged()), destination, SLOT(config_changed()));
//commented out by flo, because the ScoreEditor connects to all
@@ -1879,11 +1975,11 @@ void MusE::startPianoroll(MusECore::PartList* pl, bool showDefaultCtrls)
{
MusEGui::PianoRoll* pianoroll = new MusEGui::PianoRoll(pl, this, 0, _arranger->cursorValue());
- if(showDefaultCtrls) // p4.0.12
+ if(showDefaultCtrls)
pianoroll->addCtrl();
- pianoroll->show();
toplevels.push_back(pianoroll);
- connect(pianoroll, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ pianoroll->show();
+ connect(pianoroll, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), pianoroll, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1903,9 +1999,9 @@ void MusE::startListEditor()
void MusE::startListEditor(MusECore::PartList* pl)
{
MusEGui::ListEdit* listEditor = new MusEGui::ListEdit(pl);
- listEditor->show();
toplevels.push_back(listEditor);
- connect(listEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ listEditor->show();
+ connect(listEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse,SIGNAL(configChanged()), listEditor, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1917,9 +2013,9 @@ void MusE::startListEditor(MusECore::PartList* pl)
void MusE::startMasterEditor()
{
MusEGui::MasterEdit* masterEditor = new MusEGui::MasterEdit();
- masterEditor->show();
toplevels.push_back(masterEditor);
- connect(masterEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ masterEditor->show();
+ connect(masterEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
updateWindowMenu();
}
@@ -1930,9 +2026,9 @@ void MusE::startMasterEditor()
void MusE::startLMasterEditor()
{
MusEGui::LMaster* lmaster = new MusEGui::LMaster();
- lmaster->show();
toplevels.push_back(lmaster);
- connect(lmaster, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ lmaster->show();
+ connect(lmaster, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), lmaster, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1952,11 +2048,11 @@ void MusE::startDrumEditor()
void MusE::startDrumEditor(MusECore::PartList* pl, bool showDefaultCtrls)
{
MusEGui::DrumEdit* drumEditor = new MusEGui::DrumEdit(pl, this, 0, _arranger->cursorValue());
- if(showDefaultCtrls) // p4.0.12
+ if(showDefaultCtrls)
drumEditor->addCtrl();
- drumEditor->show();
toplevels.push_back(drumEditor);
- connect(drumEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ drumEditor->show();
+ connect(drumEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), drumEditor, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1979,9 +2075,9 @@ void MusE::startWaveEditor(MusECore::PartList* pl)
{
MusEGui::WaveEdit* waveEditor = new MusEGui::WaveEdit(pl);
waveEditor->show();
- connect(MusEGlobal::muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged()));
toplevels.push_back(waveEditor);
- connect(waveEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(MusEGlobal::muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged()));
+ connect(waveEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
updateWindowMenu();
}
@@ -2039,7 +2135,7 @@ void MusE::startClipList(bool checked)
//clipListEdit = new ClipListEdit();
clipListEdit = new MusEGui::ClipListEdit(this);
toplevels.push_back(clipListEdit);
- connect(clipListEdit, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(clipListEdit, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
}
clipListEdit->show();
viewCliplistAction->setChecked(checked);
@@ -2077,7 +2173,11 @@ void MusE::selectProject(QAction* act)
if (!act)
return;
int id = act->data().toInt();
- assert(id < PROJECT_LIST_LEN);
+ if (!(id < PROJECT_LIST_LEN))
+ {
+ printf("THIS SHOULD NEVER HAPPEN: id(%i) < PROJECT_LIST_LEN(%i) in MusE::selectProject!\n",id, PROJECT_LIST_LEN);
+ return;
+ }
QString* name = projectList[id];
if (name == 0)
return;
@@ -2085,10 +2185,10 @@ void MusE::selectProject(QAction* act)
}
//---------------------------------------------------------
-// toplevelDeleted
+// toplevelDeleting
//---------------------------------------------------------
-void MusE::toplevelDeleted(MusEGui::TopWin* tl)
+void MusE::toplevelDeleting(MusEGui::TopWin* tl)
{
for (MusEGui::iToplevel i = toplevels.begin(); i != toplevels.end(); ++i) {
if (*i == tl) {
@@ -2097,6 +2197,19 @@ void MusE::toplevelDeleted(MusEGui::TopWin* tl)
{
activeTopWin=NULL;
emit activeTopWinChanged(NULL);
+
+ // focus the last activated topwin which is not the deleting one
+ QList<QMdiSubWindow*> l = mdiArea->subWindowList(QMdiArea::StackingOrder);
+ for (QList<QMdiSubWindow*>::iterator lit=l.begin(); lit!=l.end(); lit++)
+ if ((*lit)->isVisible() && (*lit)->widget() != tl)
+ {
+ if (MusEGlobal::debugMsg)
+ printf("bringing '%s' to front instead of closed window\n",(*lit)->widget()->windowTitle().toAscii().data());
+
+ bringToFront((*lit)->widget());
+
+ break;
+ }
}
if (tl == currentMenuSharingTopwin)
@@ -2133,19 +2246,16 @@ void MusE::toplevelDeleted(MusEGui::TopWin* tl)
case MusEGui::TopWin::TOPLEVELTYPE_LAST_ENTRY: //to avoid a warning
break;
}
- toplevels.erase(i);
+ toplevels.erase(i);
if (mustUpdateScoreMenus)
arrangerView->updateScoreMenus();
updateWindowMenu();
return;
}
}
- printf("topLevelDeleted: top level %p not found\n", tl);
- //assert(false);
+ printf("topLevelDeleting: top level %p not found\n", tl);
}
-
-
//---------------------------------------------------------
// kbAccel
//---------------------------------------------------------
@@ -2180,7 +2290,7 @@ void MusE::kbAccel(int key)
MusEGlobal::song->setPlay(true);
}
- // p4.0.10 Tim. Normally each editor window handles these, to inc by the editor's raster snap value.
+ // Normally each editor window handles these, to inc by the editor's raster snap value.
// But users were asking for a global version - "they don't work when I'm in mixer or transport".
// Since no editor claimed the key event, we don't know a specific editor's snap setting,
// so adopt a policy where the arranger is the 'main' raster reference, I guess...
@@ -2661,7 +2771,8 @@ MusE::lash_idle_cb ()
int ok = save (ss.toAscii(), false);
if (ok) {
project.setFile(ss.toAscii());
- setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(project.absoluteFilePath())));
addProject(ss.toAscii());
MusEGlobal::museProject = QFileInfo(ss.toAscii()).absolutePath();
}
@@ -2751,16 +2862,22 @@ again:
case MusEGui::TopWin::MASTER:
case MusEGui::TopWin::WAVE:
case MusEGui::TopWin::LMASTER:
- tl->close();
- goto again;
-
+ {
+ if(tl->isVisible()) // Don't keep trying to close, only if visible.
+ {
+ if(!tl->close())
+ printf("MusE::clearSong TopWin did not close!\n");
+ goto again;
+ }
+ }
case MusEGui::TopWin::TOPLEVELTYPE_LAST_ENTRY: //to avoid a warning
break;
}
}
- microSleep(100000);
+ microSleep(100000);
+ _arranger->songIsClearing();
MusEGlobal::song->clear(true, clear_all);
- microSleep(100000);
+ microSleep(100000);
return false;
}
@@ -3077,21 +3194,32 @@ void MusE::focusChanged(QWidget*, QWidget* now)
if (currentMenuSharingTopwin && (currentMenuSharingTopwin!=activeTopWin))
currentMenuSharingTopwin->storeInitialState();
-
+ // if the activated widget is a QMdiSubWindow containing some TopWin
+ if ( (dynamic_cast<QMdiSubWindow*>(ptr)!=0) &&
+ (dynamic_cast<MusEGui::TopWin*>( ((QMdiSubWindow*)ptr)->widget() )!=0) )
+ {
+ waitingForTopwin=(MusEGui::TopWin*) ((QMdiSubWindow*)ptr)->widget();
+ return;
+ }
while (ptr)
{
+ if (MusEGlobal::heavyDebugMsg)
+ printf("focusChanged: at widget %p with type %s\n",ptr, typeid(*ptr).name());
+
if ( (dynamic_cast<MusEGui::TopWin*>(ptr)!=0) || // *ptr is a TopWin or a derived class
(ptr==this) ) // the main window is selected
break;
ptr=dynamic_cast<QWidget*>(ptr->parent()); //in the unlikely case that ptr is a QObject, this returns NULL, which stops the loop
}
+ MusEGui::TopWin* win=dynamic_cast<MusEGui::TopWin*>(ptr);
// ptr is either NULL, this or the pointer to a TopWin
- if (ptr!=this) // if the main win is selected, don't treat that as "none", but also don't handle it
+
+ // if the main win or some deleting topwin is selected,
+ // don't treat that as "none", but also don't handle it
+ if (ptr!=this && (!win || !win->deleting()) )
{
- MusEGui::TopWin* win=dynamic_cast<MusEGui::TopWin*>(ptr);
-
// now 'win' is either NULL or the pointer to the active TopWin
if (win!=activeTopWin)
{
@@ -3239,6 +3367,26 @@ void MusE::shareMenuAndToolbarChanged(MusEGui::TopWin* win, bool val)
}
}
+void MusE::topwinMenuInited(MusEGui::TopWin* topwin)
+{
+ if (topwin==NULL)
+ return;
+
+ if (topwin == waitingForTopwin)
+ {
+ if (waitingForTopwin->deleting())
+ {
+ waitingForTopwin=NULL;
+ }
+ else
+ {
+ activeTopWin=waitingForTopwin;
+ waitingForTopwin=NULL;
+ emit activeTopWinChanged(activeTopWin);
+ }
+ }
+}
+
void MusE::updateWindowMenu()
{
bool sep;
@@ -3292,6 +3440,8 @@ void MusE::updateWindowMenu()
void MusE::bringToFront(QWidget* widget)
{
MusEGui::TopWin* win=dynamic_cast<MusEGui::TopWin*>(widget);
+ if (!win) return;
+
if (win->isMdiWin())
{
win->show();
@@ -3455,4 +3605,19 @@ void MusE::tileSubWindows()
}
}
+QString MusE::projectTitle() const
+{
+ return MusEGui::projectTitleFromFilename(project.fileName());
+}
+
+QString MusE::projectPath() const
+{
+ return MusEGui::projectPathFromFilename(project.absoluteFilePath());
+}
+
+QString MusE::projectExtension() const
+{
+ return MusEGui::projectExtensionFromFilename(project.fileName());
+}
+
} //namespace MusEGui
diff --git a/muse2/muse/app.h b/muse2/muse/app.h
index 46e9f99b..184581dc 100644
--- a/muse2/muse/app.h
+++ b/muse2/muse/app.h
@@ -43,6 +43,7 @@ class QToolBar;
class QToolButton;
class QProgressDialog;
class QMdiArea;
+class QTimer;
namespace MusECore {
class AudioOutput;
@@ -91,7 +92,7 @@ class TopWin;
class Transport;
class VisibleTracks;
-#define MENU_ADD_SYNTH_ID_BASE 0x1000
+#define MENU_ADD_SYNTH_ID_BASE 0x8000
//---------------------------------------------------------
@@ -128,6 +129,7 @@ class MusE : public QMainWindow
TopWin* activeTopWin;
TopWin* currentMenuSharingTopwin;
+ TopWin* waitingForTopwin;
std::list<QToolBar*> requiredToolbars; //always displayed
std::list<QToolBar*> optionalToolbars; //only displayed when no toolbar-sharing window is active
@@ -213,6 +215,10 @@ class MusE : public QMainWindow
MidiTransformerDialog* midiTransformerDialog;
QMenu* openRecent;
+ //QTimer* hackishSongOpenTimer;
+ //QString hackishSongOpenFilename;
+ //bool hackishSongOpenUseTemplate;
+
bool readMidi(FILE*);
void read(MusECore::Xml& xml, bool skipConfig, bool isTemplate);
void processTrack(MusECore::MidiTrack* track);
@@ -327,13 +333,15 @@ class MusE : public QMainWindow
void arrangeSubWindowsColumns();
void tileSubWindows();
+ //void hackishSongOpenTimerTimeout();
+
public slots:
bool saveAs();
void bounceToFile(MusECore::AudioOutput* ao = 0);
void closeEvent(QCloseEvent*e);
void loadProjectFile(const QString&);
void loadProjectFile(const QString&, bool songTemplate, bool loadAll);
- void toplevelDeleted(MusEGui::TopWin* tl);
+ void toplevelDeleting(MusEGui::TopWin* tl);
void loadTheme(const QString&);
void loadStyleSheetFile(const QString&);
bool seqRestart();
@@ -371,12 +379,14 @@ class MusE : public QMainWindow
void addMdiSubWindow(QMdiSubWindow*);
void shareMenuAndToolbarChanged(MusEGui::TopWin*, bool);
+ void topwinMenuInited(MusEGui::TopWin*);
void updateWindowMenu();
public:
MusE(int argc, char** argv);
~MusE();
+ void loadDefaultSong(int argc, char** argv);
Arranger* arranger() const { return _arranger; }
QRect configGeometryMain;
QProgressDialog *progress;
@@ -384,10 +394,13 @@ class MusE : public QMainWindow
void kbAccel(int);
void changeConfig(bool writeFlag);
void seqStop();
- bool seqStart();
+ bool seqStart();
void setHeartBeat();
void importController(int, MusECore::MidiPort*, int);
QString projectName() { return project.fileName(); }
+ QString projectTitle() const;
+ QString projectPath() const;
+ QString projectExtension() const;
QWidget* mixer1Window();
QWidget* mixer2Window();
QWidget* transportWindow();
diff --git a/muse2/muse/arranger/alayout.cpp b/muse2/muse/arranger/alayout.cpp
index a892356c..119da498 100644
--- a/muse2/muse/arranger/alayout.cpp
+++ b/muse2/muse/arranger/alayout.cpp
@@ -117,7 +117,7 @@ void TLLayout::setGeometry(const QRect &rect)
QSize s1 = li[1]->sizeHint();
QSize s2 = li[2]->sizeHint();
- QSize s3 = li[3]->sizeHint();
+ //QSize s3 = li[3]->sizeHint();
QSize s4 = li[4]->sizeHint();
QSize s5 = li[5]->sizeHint();
diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp
index 89245d64..cb024070 100644
--- a/muse2/muse/arranger/arranger.cpp
+++ b/muse2/muse/arranger/arranger.cpp
@@ -152,7 +152,7 @@ Arranger::Arranger(ArrangerView* parent, const char* name)
toolbar->addWidget(cursorPos);
const char* rastval[] = {
- QT_TRANSLATE_NOOP("@default", "Off"), QT_TRANSLATE_NOOP("@default", "Bar"), "1/2", "1/4", "1/8", "1/16"
+ QT_TRANSLATE_NOOP("MusEGui::Arranger", "Off"), QT_TRANSLATE_NOOP("MusEGui::Arranger", "Bar"), "1/2", "1/4", "1/8", "1/16"
};
label = new QLabel(tr("Snap"));
label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
@@ -569,27 +569,40 @@ void Arranger::songChanged(int type)
// Is it simply a midi controller value adjustment? Forget it.
if(type != SC_MIDI_CONTROLLER)
{
- unsigned endTick = MusEGlobal::song->len();
- int offset = AL::sigmap.ticksMeasure(endTick);
- hscroll->setRange(-offset, endTick + offset); //DEBUG
- canvas->setOrigin(-offset, 0);
- time->setOrigin(-offset, 0);
-
- int bar, beat;
- unsigned tick;
- AL::sigmap.tickValues(endTick, &bar, &beat, &tick);
- if (tick || beat)
- ++bar;
- lenEntry->blockSignals(true);
- lenEntry->setValue(bar);
- lenEntry->blockSignals(false);
-
- if(type & SC_SONG_TYPE) // p4.0.7 Tim.
+ // TEST p4.0.36 Try these, may need more/less.
+ if(type & ( SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED |
+ SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED))
+ {
+ unsigned endTick = MusEGlobal::song->len();
+ int offset = AL::sigmap.ticksMeasure(endTick);
+ hscroll->setRange(-offset, endTick + offset); //DEBUG
+ canvas->setOrigin(-offset, 0);
+ time->setOrigin(-offset, 0);
+
+ int bar, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(endTick, &bar, &beat, &tick);
+ if (tick || beat)
+ ++bar;
+ lenEntry->blockSignals(true);
+ lenEntry->setValue(bar);
+ lenEntry->blockSignals(false);
+ }
+
+ if(type & SC_SONG_TYPE)
setMode(MusEGlobal::song->mtype());
- trackSelectionChanged();
- canvas->partsChanged();
- typeBox->setCurrentIndex(int(MusEGlobal::song->mtype()));
+ if(type & SC_SELECTION) // TEST p4.0.36 Try this alone, may need more.
+ trackSelectionChanged();
+
+ // Keep this light, partsChanged is a heavy move! TEST p4.0.36 Try these, may need more.
+ if(type & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED |
+ SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED |
+ SC_SIG | SC_TEMPO)) // Maybe sig. Requires tempo.
+ canvas->partsChanged();
+
+ //typeBox->setCurrentIndex(int(MusEGlobal::song->mtype())); // REMOVE Tim. Redundant.
+
if (type & SC_SIG)
time->redraw();
if (type & SC_TEMPO)
@@ -616,6 +629,14 @@ void Arranger::songChanged(int type)
}
}
}
+
+ // TEST p4.0.36 Try this
+ if(type & ( //SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED |
+ SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED |
+ SC_EVENT_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED)) //|
+ //SC_SIG | SC_TEMPO)) // Maybe sig. and tempo. No, moved above.
+ canvas->redraw();
+
}
updateTrackInfo(type);
diff --git a/muse2/muse/arranger/arranger.h b/muse2/muse/arranger/arranger.h
index d4193c01..35a3fe36 100644
--- a/muse2/muse/arranger/arranger.h
+++ b/muse2/muse/arranger/arranger.h
@@ -187,6 +187,7 @@ class Arranger : public QWidget {
int selectionSize() { return canvas->selectionSize(); }
void setGlobalTempo(int);
void clear();
+ void songIsClearing() { canvas->songIsClearing(); }
unsigned cursorValue() { return cursVal; }
diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp
index 51fc3bb0..1bb45863 100644
--- a/muse2/muse/arranger/arrangerview.cpp
+++ b/muse2/muse/arranger/arrangerview.cpp
@@ -37,7 +37,7 @@
#include <QMessageBox>
#include <QMimeData>
#include <QPushButton>
-#include <QResizeEvent>
+//#include <QResizeEvent>
#include <QScrollArea>
#include <QScrollBar>
#include <QSettings>
@@ -129,6 +129,7 @@ ArrangerView::ArrangerView(QWidget* parent)
connect(muse, SIGNAL(configChanged()), arranger, SLOT(configChanged()));
connect(arranger, SIGNAL(setUsedTool(int)), editTools, SLOT(set(int)));
connect(arranger, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+ connect(MusEGlobal::song, SIGNAL(songChanged(int)), visTracks, SLOT(updateVisibleTracksButtons()));
@@ -167,8 +168,8 @@ ArrangerView::ArrangerView(QWidget* parent)
scoreSubmenu = new QMenu(tr("Score"), this);
scoreSubmenu->setIcon(QIcon(*scoreIconSet));
- scoreAllInOneSubsubmenu = new QMenu(tr("all parts in one staff"), this);
- scoreOneStaffPerTrackSubsubmenu = new QMenu(tr("one staff per part"), this);
+ scoreAllInOneSubsubmenu = new QMenu(tr("all tracks in one staff"), this);
+ scoreOneStaffPerTrackSubsubmenu = new QMenu(tr("one staff per track"), this);
scoreSubmenu->addMenu(scoreAllInOneSubsubmenu);
scoreSubmenu->addMenu(scoreOneStaffPerTrackSubsubmenu);
@@ -193,6 +194,10 @@ ArrangerView::ArrangerView(QWidget* parent)
strGlobalInsertAction = new QAction(tr("Global Insert"), this);
strGlobalSplitAction = new QAction(tr("Global Split"), this);
+ strGlobalCutSelAction = new QAction(tr("Global Cut - selected tracks"), this);
+ strGlobalInsertSelAction = new QAction(tr("Global Insert - selected tracks"), this);
+ strGlobalSplitSelAction = new QAction(tr("Global Split - selected tracks"), this);
+
//-------------------------------------------------------------
@@ -246,7 +251,11 @@ ArrangerView::ArrangerView(QWidget* parent)
menuStructure->addAction(strGlobalCutAction);
menuStructure->addAction(strGlobalInsertAction);
menuStructure->addAction(strGlobalSplitAction);
-
+ menuStructure->addSeparator();
+ menuStructure->addAction(strGlobalCutSelAction);
+ menuStructure->addAction(strGlobalInsertSelAction);
+ menuStructure->addAction(strGlobalSplitSelAction);
+
QMenu* functions_menu = menuBar()->addMenu(tr("Functions"));
@@ -341,6 +350,9 @@ ArrangerView::ArrangerView(QWidget* parent)
connect(strGlobalCutAction, SIGNAL(activated()), SLOT(globalCut()));
connect(strGlobalInsertAction, SIGNAL(activated()), SLOT(globalInsert()));
connect(strGlobalSplitAction, SIGNAL(activated()), SLOT(globalSplit()));
+ connect(strGlobalCutSelAction, SIGNAL(activated()), SLOT(globalCutSel()));
+ connect(strGlobalInsertSelAction, SIGNAL(activated()), SLOT(globalInsertSel()));
+ connect(strGlobalSplitSelAction, SIGNAL(activated()), SLOT(globalSplitSel()));
@@ -351,7 +363,7 @@ ArrangerView::ArrangerView(QWidget* parent)
connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged()));
connect(cb, SIGNAL(selectionChanged()), SLOT(clipboardChanged()));
-
+ MusEGlobal::muse->topwinMenuInited(this);
// work around for probable QT/WM interaction bug.
// for certain window managers, e.g xfce, this window is
@@ -368,7 +380,7 @@ ArrangerView::~ArrangerView()
void ArrangerView::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
emit closed();
e->accept();
}
@@ -629,7 +641,7 @@ void ArrangerView::clearScoreMenuMappers()
void ArrangerView::populateAddTrack()
{
- QActionGroup *grp = MusEGui::populateAddTrack(addTrack);
+ QActionGroup *grp = MusEGui::populateAddTrack(addTrack, true);
connect(addTrack, SIGNAL(triggered(QAction *)), SLOT(addNewTrack(QAction *)));
trackMidiAction = grp->actions()[0];
@@ -731,4 +743,9 @@ void ArrangerView::globalCut() { MusECore::globalCut(); }
void ArrangerView::globalInsert() { MusECore::globalInsert(); }
void ArrangerView::globalSplit() { MusECore::globalSplit(); }
+// variants only applicable for selected tracks
+void ArrangerView::globalCutSel() { MusECore::globalCut(true); }
+void ArrangerView::globalInsertSel() { MusECore::globalInsert(true); }
+void ArrangerView::globalSplitSel() { MusECore::globalSplit(true); }
+
} // namespace MusEGui
diff --git a/muse2/muse/arranger/arrangerview.h b/muse2/muse/arranger/arrangerview.h
index d52c5cc4..0dac67e4 100644
--- a/muse2/muse/arranger/arrangerview.h
+++ b/muse2/muse/arranger/arrangerview.h
@@ -89,7 +89,8 @@ class ArrangerView : public TopWin
QMenu* master;
QAction *strGlobalCutAction, *strGlobalInsertAction, *strGlobalSplitAction;
- QAction *trackMidiAction, *trackDrumAction, *trackNewStyleDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction;
+ QAction *strGlobalCutSelAction, *strGlobalInsertSelAction, *strGlobalSplitSelAction;
+ QAction *trackMidiAction, *trackDrumAction, *trackNewStyleDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction;
QAction *trackAInputAction, *trackAAuxAction;
QAction *editCutAction, *editCopyAction, *editCopyRangeAction;
QAction *editPasteAction, *editPasteCloneAction, *editPasteDialogAction, *editPasteCloneDialogAction;
@@ -119,11 +120,14 @@ class ArrangerView : public TopWin
void globalCut();
void globalInsert();
void globalSplit();
- void cmd(int);
+ void globalCutSel();
+ void globalInsertSel();
+ void globalSplitSel();
+ void cmd(int);
void addNewTrack(QAction* action);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
void closed();
public slots:
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index 987a7e9a..3889928f 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -3,7 +3,7 @@
// Linux Music Editor
// $Id: pcanvas.cpp,v 1.48.2.26 2009/11/22 11:08:33 spamatica Exp $
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
-// (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -54,6 +54,7 @@
#include "shortcuts.h"
#include "gconfig.h"
#include "app.h"
+#include "functions.h"
#include "filedialog.h"
#include "marker/marker.h"
#include "mpevent.h"
@@ -68,6 +69,8 @@
//#define ABS(x) (x>=0?x:-x)
#define ABS(x) (abs(x))
+#define EDITING_FINISHED_TIMEOUT 50 /* in milliseconds */
+
using std::set;
namespace MusEGui {
@@ -181,6 +184,8 @@ void PartCanvas::returnPressed()
MusEGlobal::audio->msgChangePart(oldPart, newPart, true, true, false);
editMode = false;
+
+ editingFinishedTime.start();
}
}
@@ -298,12 +303,9 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
QPoint newpos = raster(QPoint(nx, ny));
selectItem(ci, true);
- MusECore::UndoOp operation=moveItem(ci, newpos, dtype);
- if (operation.type != MusECore::UndoOp::DoNothing)
- {
+ bool result=moveItem(operations, ci, newpos, dtype);
+ if (result)
ci->move(newpos);
- operations.push_back(operation);
- }
if(moving.size() == 1) {
itemReleased(curItem, newpos);
@@ -322,37 +324,41 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
//---------------------------------------------------------
// Changed by T356.
-MusECore::UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t)
+bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& newpos, DragType t)
{
- MusECore::UndoOp result;
NPart* npart = (NPart*) item;
MusECore::Part* spart = npart->part();
MusECore::Track* track = npart->track();
+ MusECore::Track* dtrack=NULL;
unsigned dtick = newpos.x();
unsigned ntrack = y2pitch(item->mp().y());
MusECore::Track::TrackType type = track->type();
if (tracks->index(track) == ntrack && (dtick == spart->tick())) {
- return MusECore::UndoOp(MusECore::UndoOp::DoNothing);
+ return false;
}
if (ntrack >= tracks->size()) {
ntrack = tracks->size();
if (MusEGlobal::debugMsg)
printf("PartCanvas::moveItem - add new track\n");
- MusECore::Track* newTrack = MusEGlobal::song->addTrack(type); // Add at end of list.
+ dtrack = MusEGlobal::song->addTrack(operations, type); // Add at end of list.
+
if (type == MusECore::Track::WAVE) {
MusECore::WaveTrack* st = (MusECore::WaveTrack*) track;
- MusECore::WaveTrack* dt = (MusECore::WaveTrack*) newTrack;
+ MusECore::WaveTrack* dt = (MusECore::WaveTrack*) dtrack;
dt->setChannels(st->channels());
}
emit tracklistChanged();
}
- MusECore::Track* dtrack = tracks->index(ntrack);
- if (dtrack->type() != type) {
- QMessageBox::critical(this, QString("MusE"),
- tr("Cannot copy/move/clone to different Track-Type"));
- return MusECore::UndoOp(MusECore::UndoOp::DoNothing);
+ else
+ {
+ dtrack = tracks->index(ntrack);
+ if (dtrack->type() != type) {
+ QMessageBox::critical(this, QString("MusE"),
+ tr("Cannot copy/move/clone to different Track-Type"));
+ return false;
+ }
}
-
+
MusECore::Part* dpart;
bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->events()->arefCount() > 1));
@@ -392,23 +398,25 @@ MusECore::UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragTyp
if (t == MOVE_COPY || t == MOVE_CLONE) {
// These will not increment ref count, and will not chain clones...
- // TODO: is comment this still correct (by flo93)? i doubt it!
- result=MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart);
+ // TODO: is this comment still correct (by flo93)? i doubt it!
+ operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart));
}
else if (t == MOVE_MOVE) {
dpart->setSelected(spart->selected());
// These will increment ref count if not a clone, and will chain clones...
// TODO: is this comment still correct (by flo93)? i doubt it!
- result=MusECore::UndoOp(MusECore::UndoOp::ModifyPart,spart, dpart, true, false);
+ operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyPart,spart, dpart, true, false));
spart->setSelected(false);
}
- // else // will never happen -> result will always be defined
+ // else // will never happen -> operations will never be empty
if (MusEGlobal::song->len() < (dpart->lenTick() + dpart->tick()))
- MusEGlobal::song->setLen(dpart->lenTick() + dpart->tick());
-
- return result;
+ operations.push_back( MusECore::UndoOp(MusECore::UndoOp::ModifySongLen,
+ dpart->lenTick() + dpart->tick(),
+ MusEGlobal::song->len() ) );
+
+ return true;
}
//---------------------------------------------------------
@@ -427,6 +435,13 @@ QPoint PartCanvas::raster(const QPoint& p) const
return QPoint(x, y);
}
+
+void PartCanvas::songIsClearing()
+{
+ curItem=NULL;
+ items.clearDelete();
+}
+
//---------------------------------------------------------
// partsChanged
//---------------------------------------------------------
@@ -434,6 +449,10 @@ QPoint PartCanvas::raster(const QPoint& p) const
void PartCanvas::partsChanged()
{
//items.clear();
+ int sn = -1;
+ if (curItem) sn=curItem->part()->sn();
+ curItem=NULL;
+
items.clearDelete();
for (MusECore::iTrack t = tracks->begin(); t != tracks->end(); ++t) {
MusECore::PartList* pl = (*t)->parts();
@@ -441,6 +460,10 @@ void PartCanvas::partsChanged()
MusECore::Part* part = i->second;
NPart* np = new NPart(part);
items.add(np);
+
+ if (np->part()->sn() == sn)
+ curItem=np;
+
if (i->second->selected()) {
selectItem(np, true);
}
@@ -647,6 +670,8 @@ QMenu* PartCanvas::genItemPopup(CItem* item)
act_split->setData(2);
QAction *act_glue = partPopup->addAction(QIcon(*glueIcon), tr("glue"));
act_glue->setData(3);
+ QAction *act_superglue = partPopup->addAction(QIcon(*glueIcon), tr("super glue (merge selection)"));
+ act_superglue->setData(6);
QAction *act_declone = partPopup->addAction(tr("de-clone"));
act_declone->setData(15);
@@ -736,6 +761,9 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt)
case 5:
copy(pl);
break;
+ case 6:
+ MusECore::merge_selected_parts();
+ break;
case 14: // wave edit
emit startEditor(pl, 4);
@@ -756,7 +784,7 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt)
// Indicate undo, and do port controller values but not clone parts.
// changed by flo93: removed start and endUndo, instead changed first bool to true
MusEGlobal::audio->msgChangePart(spart, dpart, true, true, false);
- break; // Has to be break here, right?
+ break;
}
case 16: // Export to file
{
@@ -784,7 +812,7 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt)
for (MusECore::iEvent e = el->begin(); e != el->end(); ++e)
{
MusECore::Event event = e->second;
- MusECore::SndFileR f = event.sndFile();
+ MusECore::SndFileR f = event.sndFile();
if (f.isNull())
continue;
str.append(QString("\n@") + QString().setNum(event.tick()) + QString(" len:") +
@@ -858,8 +886,8 @@ void PartCanvas::mousePress(QMouseEvent* event)
default:
if (item)
emit trackChanged(item->part()->track());
- else
- emit trackChanged(NULL);
+ //else -- don't see the point of removing track selection, commenting out (rj)
+ // emit trackChanged(NULL);
break;
case CutTool:
if (item) splitItem(item, pt);
@@ -952,11 +980,14 @@ void PartCanvas::keyPress(QKeyEvent* event)
// }
if (editMode)
{
+ // this will probably never happen, as edit mode has been set
+ // to "false" some usec ago by returnPressed, called by editingFinished.
if ( key == Qt::Key_Return || key == Qt::Key_Enter )
{
//returnPressed(); commented out by flo
return;
}
+ // the below CAN indeed happen.
else if ( key == Qt::Key_Escape )
{
lineEditor->hide();
@@ -964,6 +995,11 @@ void PartCanvas::keyPress(QKeyEvent* event)
return;
}
}
+ // if returnPressed, called by editingFinished, was executed
+ // a short time ago, ignore this keypress if it was enter or return
+ if (editingFinishedTime.elapsed() < EDITING_FINISHED_TIMEOUT &&
+ (key == Qt::Key_Return || key == Qt::Key_Enter) )
+ return;
if (event->modifiers() & Qt::ShiftModifier)
key += Qt::SHIFT;
@@ -1160,7 +1196,7 @@ void PartCanvas::keyPress(QKeyEvent* event)
//If we're at topmost, leave
if (!track) {
- printf("no track above!\n");
+ //printf("no track above!\n");
return;
}
int middle = curItem->x() + curItem->part()->lenTick()/2;
@@ -1295,17 +1331,25 @@ void PartCanvas::keyPress(QKeyEvent* event)
curItem = newItem;
selectItem(newItem, true);
- //Check if we've hit the upper or lower boundaries of the window. If so, set a new position
+ //Check if we've hit the left, right, upper or lower boundaries of the window. If so, scroll to new position.
if (newItem->x() < mapxDev(0)) {
- int curpos = pos[0];
- setPos(0,newItem->x(),true);
- setPos(0,curpos,false); //Dummy to put the current position back once we've scrolled
+ emit horizontalScroll(rmapx(newItem->x() - xorg) - 10); // Leave some room.
+ }
+ else if (newItem->x() + newItem->width() > mapxDev(width())) {
+ int mx = rmapx(newItem->x());
+ int newx = mx + rmapx(newItem->width()) - width();
+ emit horizontalScroll( (newx > mx ? mx - 10 : newx + 10) - rmapx(xorg) );
+ }
+
+ if (newItem->y() < mapyDev(0)) {
+ int my = rmapy(newItem->y());
+ int newy = my + rmapy(newItem->height()) - height();
+ emit verticalScroll( (newy < my ? my - 10 : newy + 10) - rmapy(yorg) );
}
- else if (newItem->x() > mapxDev(width())) {
- int curpos = pos[0];
- setPos(0,newItem->x(),true);
- setPos(0,curpos,false); //Dummy to put the current position back once we've scrolled
+ else if (newItem->y() + newItem->height() > mapyDev(height())) {
+ emit verticalScroll( rmapy(newItem->y() + newItem->height() - yorg) - height() + 10);
}
+
redraw();
}
}
@@ -2267,9 +2311,9 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, MusECore::EventList* ev
//else
// color_brightness=64; // otherwise use dark color
if (brightness >= 12000 && !pt->selected())
- color_brightness=64; // 96; // too bright: use dark color
+ color_brightness=54; // 96; // too bright: use dark color
else
- color_brightness=190; //160; // too dark: use lighter color
+ color_brightness=200; //160; // too dark: use lighter color
}
else
color_brightness=80;
@@ -3175,9 +3219,13 @@ void PartCanvas::viewDropEvent(QDropEvent* event)
if (!track) { // we need to create a track for this drop
if (text.endsWith(".mpt", Qt::CaseInsensitive)) {
- track = MusEGlobal::song->addTrack(MusECore::Track::MIDI); // Add at end of list.
+ MusECore::Undo operations;
+ track = MusEGlobal::song->addTrack(operations, MusECore::Track::MIDI); // Add at end of list.
+ MusEGlobal::song->applyOperationGroup(operations);
} else {
- track = MusEGlobal::song->addTrack(MusECore::Track::WAVE); // Add at end of list.
+ MusECore::Undo operations;
+ track = MusEGlobal::song->addTrack(operations, MusECore::Track::WAVE); // Add at end of list.
+ MusEGlobal::song->applyOperationGroup(operations);
}
}
if (track->type() == MusECore::Track::WAVE &&
@@ -3602,7 +3650,8 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, MusECore::AudioTra
{
double y;
if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume
- y = dbToVal(cl->curVal()); // represent volume between 0 and 1
+ //printf("log conversion val=%f min=%f max=%f\n", cl->curVal(), min, max);
+ y = logToVal(cl->curVal(), min, max); // represent volume between 0 and 1
if (y < 0) y = 0.0;
}
else
@@ -3615,7 +3664,8 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, MusECore::AudioTra
{
double y = ic->second.val;
if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume
- y = dbToVal(y); // represent volume between 0 and 1
+ //printf("log conversion val=%f min=%f max=%f\n", cl->curVal(), min, max);
+ y = logToVal(y, min, max); // represent volume between 0 and 1
if (y < 0) y = 0.0;
}
else
@@ -3714,7 +3764,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo
{
double y;
if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume
- y = dbToVal(cl->curVal()); // represent volume between 0 and 1
+ y = logToVal(cl->curVal(), min, max); // represent volume between 0 and 1
if (y < 0) y = 0.0;
}
else
@@ -3727,7 +3777,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo
{
double y = ic->second.val;
if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume
- y = dbToVal(y); // represent volume between 0 and 1
+ y = logToVal(y, min, max); // represent volume between 0 and 1
if (y < 0) y = 0;
}
else
@@ -3919,7 +3969,8 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint)
automation.currentCtrlList->range(&min,&max);
double cvval;
if (automation.currentCtrlList->valueType() == MusECore::VAL_LOG ) { // use db scale for volume
- cvval = valToDb(yfraction);
+ printf("log conversion val=%f min=%f max=%f\n", yfraction, min, max);
+ cvval = valToLog(yfraction, min, max);
//printf("calc yfraction = %f v=%f ",yfraction,cvval);
if (cvval< min) cvval=min;
if (cvval>max) cvval=max;
@@ -3952,13 +4003,45 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint)
}
-double PartCanvas::dbToVal(double inDb)
+//---------------------------------------------------------
+//
+// logToVal
+// - represent logarithmic value on linear scale from 0 to 1
+//
+//---------------------------------------------------------
+double PartCanvas::logToVal(double inLog, double min, double max)
{
- return (20.0*MusECore::fast_log10(inDb)+60.0) / 70.0;
+ //printf("logToVal inLog %f :", inLog);
+ if (inLog < min) inLog = min;
+ if (inLog > max) inLog = max;
+ double linMin = 20.0*MusECore::fast_log10(min);
+ double linMax = 20.0*MusECore::fast_log10(max);
+ double linVal = 20.0*MusECore::fast_log10(inLog);
+
+ double outVal = (linVal-linMin) / (linMax - linMin);
+ // printf("inLog %f outVal %f linVal %f min %f max %f dbMin %f dbMax %f\n", inLog, outVal, linVal, min, max, linMin, linMax);
+
+ return outVal;
}
-double PartCanvas::valToDb(double inV)
+
+//---------------------------------------------------------
+//
+// valToLog
+// - represent value from 0 to 1 as logarithmic value between min and max
+//
+//---------------------------------------------------------
+double PartCanvas::valToLog(double inV, double min, double max)
{
- return exp10((inV*70.0-60.0)/20.0);
+ double linMin = 20.0*MusECore::fast_log10(min);
+ double linMax = 20.0*MusECore::fast_log10(max);
+
+ double linVal = (inV * (linMax - linMin)) + linMin;
+ double outVal = exp10((linVal)/20.0);
+
+ //printf("::valToLog inV %f outVal %f linVal %f min %f max %f\n", inV, outVal, linVal, min, max);
+ if (outVal > max) outVal = max;
+ if (outVal < min) outVal = min;
+ return outVal;
}
//---------------------------------------------------------
diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h
index 8a108055..34395688 100644
--- a/muse2/muse/arranger/pcanvas.h
+++ b/muse2/muse/arranger/pcanvas.h
@@ -26,6 +26,7 @@
#include <QVector>
#include <set>
+#include <QTime>
#include "song.h"
#include "canvas.h"
@@ -93,6 +94,8 @@ class PartCanvas : public Canvas {
NPart* editPart;
int curColorIndex;
bool editMode;
+
+ QTime editingFinishedTime;
AutomationObject automation;
@@ -116,7 +119,7 @@ class PartCanvas : public Canvas {
virtual void newItem(CItem*,bool);
virtual bool deleteItem(CItem*);
virtual void moveCanvasItems(CItemList&, int, int, DragType);
- virtual MusECore::UndoOp moveItem(CItem*, const QPoint&, DragType);
+ virtual bool moveItem(MusECore::Undo& operations, CItem*, const QPoint&, DragType);
virtual void updateSong(DragType, int);
virtual void startDrag(CItem*, DragType);
@@ -145,8 +148,8 @@ class PartCanvas : public Canvas {
void checkAutomation(MusECore::Track * t, const QPoint& pointer, bool addNewCtrl);
void processAutomationMovements(QPoint pos, bool addPoint);
- double dbToVal(double inDb);
- double valToDb(double inV);
+ double logToVal(double inLog, double min, double max);
+ double valToLog(double inV, double min, double max);
protected:
virtual void drawCanvas(QPainter&, const QRect&);
@@ -177,9 +180,11 @@ class PartCanvas : public Canvas {
virtual ~PartCanvas();
void partsChanged();
void cmd(int);
+ void songIsClearing();
+
public slots:
- void redirKeypress(QKeyEvent* e) { keyPress(e); }
- void controllerChanged(MusECore::Track *t);
+ void redirKeypress(QKeyEvent* e) { keyPress(e); }
+ void controllerChanged(MusECore::Track *t);
};
} // namespace MusEGui
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index c209ba9c..f5edc8cf 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -63,6 +63,7 @@
#include "config.h"
#include "popupmenu.h"
#include "filedialog.h"
+#include "menutitleitem.h"
#ifdef DSSI_SUPPORT
#include "dssihost.h"
@@ -397,7 +398,7 @@ void TList::paint(const QRect& r)
countVisible++;
}
//int count = ((MusECore::AudioTrack*)track)->controller()->size(); //commented out by flo: gives a "unused variable" warning
- s.sprintf(" %d(%d) visible",countVisible, countAll);
+ s.sprintf(" %d(%d) %s",countVisible, countAll, tr("visible").toAscii().data());
}
@@ -584,19 +585,23 @@ void TList::mouseDoubleClickEvent(QMouseEvent* ev)
//---------------------------------------------------------
// portsPopupMenu
//---------------------------------------------------------
-
void TList::portsPopupMenu(MusECore::Track* t, int x, int y)
{
switch(t->type()) {
case MusECore::Track::MIDI:
case MusECore::Track::DRUM:
case MusECore::Track::NEW_DRUM:
+ // FINDMICHJETZT: this is a notice for flo's experimental
+ // branch! don't forget NEW_DRUM here!
+ // please don't remove this. i'll do it when
+ // the time is there.
case MusECore::Track::AUDIO_SOFTSYNTH:
{
MusECore::MidiTrack* track = (MusECore::MidiTrack*)t;
//QPopupMenu* p = MusECore::midiPortsPopup(0);
MusECore::MidiDevice* md = 0;
+ int potential_new_port_no=-1;
int port = -1;
if(t->type() == MusECore::Track::AUDIO_SOFTSYNTH)
{
@@ -609,25 +614,158 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y)
port = track->outPort();
QMenu* p = MusECore::midiPortsPopup(this, port); // 0, port);
+
+ if (t->type()==MusECore::Track::MIDI || t->type()==MusECore::Track::DRUM) //FINDMICHJETZT
+ {
+ // extend that menu a bit
+
+
+ // find first free port number
+ // do not permit numbers already used in other tracks!
+ // except if it's only used in this track.
+ int no;
+ for (no=0;no<MIDI_PORTS;no++)
+ if (MusEGlobal::midiPorts[no].device()==NULL)
+ {
+ MusECore::ciTrack it;
+ for (it=MusEGlobal::song->tracks()->begin(); it!=MusEGlobal::song->tracks()->end(); it++)
+ {
+ MusECore::MidiTrack* mt=dynamic_cast<MusECore::MidiTrack*>(*it);
+ if (mt && mt!=t && mt->outPort()==no)
+ break;
+ }
+ if (it == MusEGlobal::song->tracks()->end())
+ break;
+ }
+
+ if (no==MIDI_PORTS)
+ {
+ delete p;
+ printf("THIS IS VERY UNLIKELY TO HAPPEN: no free midi ports! you have used all %i!\n",MIDI_PORTS);
+ break;
+ }
+
+
+ potential_new_port_no=no;
+ typedef std::map<std::string, int > asmap;
+ typedef std::map<std::string, int >::iterator imap;
+
+ asmap mapALSA;
+ asmap mapJACK;
+
+ int aix = 0x10000000;
+ int jix = 0x20000000;
+ for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i)
+ {
+ if((*i)->deviceType() == MusECore::MidiDevice::ALSA_MIDI)
+ {
+ // don't add devices which are used somewhere
+ int j;
+ for (j=0;j<MIDI_PORTS;j++)
+ if (MusEGlobal::midiPorts[j].device() == *i)
+ break;
+
+ if (j==MIDI_PORTS) mapALSA.insert( std::pair<std::string, int> (std::string((*i)->name().toLatin1().constData()), aix) );
+
+ ++aix;
+ }
+ else if((*i)->deviceType() == MusECore::MidiDevice::JACK_MIDI)
+ {
+ // don't add devices which are used somewhere
+ int j;
+ for (j=0;j<MIDI_PORTS;j++)
+ if (MusEGlobal::midiPorts[j].device() == *i)
+ break;
+
+ if (j==MIDI_PORTS) mapJACK.insert( std::pair<std::string, int> (std::string((*i)->name().toLatin1().constData()), jix) );
+ ++jix;
+ }
+ }
+
+ if (!mapALSA.empty() || !mapJACK.empty())
+ {
+ QMenu* pup = p->addMenu(tr("Unused Devices"));
+ QAction* act;
+
+
+ if (!mapALSA.empty())
+ {
+ pup->addAction(new MusEGui::MenuTitleItem("ALSA:", pup));
+
+ for(imap i = mapALSA.begin(); i != mapALSA.end(); ++i)
+ {
+ int idx = i->second;
+ QString s(i->first.c_str());
+ MusECore::MidiDevice* md = MusEGlobal::midiDevices.find(s, MusECore::MidiDevice::ALSA_MIDI);
+ if(md)
+ {
+ if(md->deviceType() != MusECore::MidiDevice::ALSA_MIDI)
+ continue;
+
+ act = pup->addAction(md->name());
+ act->setData(idx);
+ }
+ }
+ }
+
+ if (!mapALSA.empty() && !mapJACK.empty())
+ pup->addSeparator();
+
+ if (!mapJACK.empty())
+ {
+ pup->addAction(new MusEGui::MenuTitleItem("JACK:", pup));
+
+ for(imap i = mapJACK.begin(); i != mapJACK.end(); ++i)
+ {
+ int idx = i->second;
+ QString s(i->first.c_str());
+ MusECore::MidiDevice* md = MusEGlobal::midiDevices.find(s, MusECore::MidiDevice::JACK_MIDI);
+ if(md)
+ {
+ if(md->deviceType() != MusECore::MidiDevice::JACK_MIDI)
+ continue;
+
+ act = pup->addAction(md->name());
+ act->setData(idx);
+ }
+ }
+ }
+ }
+ }
+
+
QAction* act = p->exec(mapToGlobal(QPoint(x, y)), 0);
if(!act)
{
delete p;
break;
}
-
+
+ QString acttext=act->text();
int n = act->data().toInt();
delete p;
if(n < 0) // Invalid item.
break;
- if(n >= MIDI_PORTS) // Show port config dialog.
+ if(n == MIDI_PORTS) // Show port config dialog.
{
MusEGlobal::muse->configMidiPorts();
break;
}
+ else if (n & 0x30000000)
+ {
+ int typ;
+ if (n & 0x10000000)
+ typ = MusECore::MidiDevice::ALSA_MIDI;
+ else
+ typ = MusECore::MidiDevice::JACK_MIDI;
+
+ MusECore::MidiDevice* sdev = MusEGlobal::midiDevices.find(acttext, typ);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[potential_new_port_no], sdev);
+ n=potential_new_port_no;
+ }
// Changed by T356.
//track->setOutPort(n);
//MusEGlobal::audio->msgSetTrackOutPort(track, n);
@@ -892,16 +1030,24 @@ void TList::moveSelection(int n)
if (t == tracks->end()) {
--t;
break;
- }
}
- }
+ // skip over hidden tracks
+ if (!(*t)->isVisible()) {
+ n++;
+ }
+ }
+ }
else {
while (n++ != 0) {
if (t == tracks->begin())
break;
--t;
+ // skip over hidden tracks
+ if (!(*t)->isVisible()) {
+ n--;
}
}
+ }
(*s)->setSelected(false);
(*t)->setSelected(true);
@@ -1048,7 +1194,7 @@ void TList::mousePressEvent(QMouseEvent* ev)
if(act)
{
t = MusEGlobal::song->addNewTrack(act); // Add at end of list.
- if(t)
+ if(t && t->isVisible())
{
MusEGlobal::song->deselectTracks();
t->setSelected(true);
@@ -1063,13 +1209,13 @@ void TList::mousePressEvent(QMouseEvent* ev)
//delete synp;
delete p;
}
- else if (button == Qt::LeftButton) {
+ /*else if (button == Qt::LeftButton) {
if (!ctrl)
{
MusEGlobal::song->deselectTracks();
emit selectionChanged(0);
}
- }
+ }*/
return;
}
@@ -1107,7 +1253,8 @@ void TList::mousePressEvent(QMouseEvent* ev)
return;
}
- mode = START_DRAG;
+
+ mode = NORMAL;
switch (col) {
case COL_CLEF:
@@ -1136,8 +1283,8 @@ void TList::mousePressEvent(QMouseEvent* ev)
}
delete p;
}
-
break;
+
case COL_AUTOMATION:
{
if (!t->isMidiTrack()) {
@@ -1173,6 +1320,8 @@ void TList::mousePressEvent(QMouseEvent* ev)
case COL_RECORD:
{
+ mode = START_DRAG;
+
bool val = !(t->recordFlag());
if (button == Qt::LeftButton) {
if (!t->isMidiTrack()) {
@@ -1211,6 +1360,7 @@ void TList::mousePressEvent(QMouseEvent* ev)
}
break;
case COL_NONE:
+ mode = START_DRAG;
break;
case COL_CLASS:
if (t->isMidiTrack())
@@ -1231,9 +1381,10 @@ void TList::mousePressEvent(QMouseEvent* ev)
//MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
//MusEGlobal::song->update(SC_ROUTE); //
-
break;
+
case COL_MUTE:
+ mode = START_DRAG;
// p3.3.29
if ((button == Qt::RightButton) || (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier))
t->setOff(!t->off());
@@ -1247,11 +1398,13 @@ void TList::mousePressEvent(QMouseEvent* ev)
MusEGlobal::song->update(SC_MUTE);
break;
case COL_SOLO:
+ mode = START_DRAG;
MusEGlobal::audio->msgSetSolo(t, !t->solo());
MusEGlobal::song->update(SC_SOLO);
break;
case COL_NAME:
+ mode = START_DRAG;
if (button == Qt::LeftButton) {
if (!ctrl) {
MusEGlobal::song->deselectTracks();
@@ -1367,11 +1520,13 @@ void TList::mousePressEvent(QMouseEvent* ev)
break;
case COL_TIMELOCK:
+ mode = START_DRAG;
t->setLocked(!t->locked());
break;
case COL_OCHANNEL:
{
+ mode = START_DRAG; // or not? (flo)
int delta = 0;
if (button == Qt::RightButton)
delta = 1;
@@ -1437,6 +1592,9 @@ void TList::mousePressEvent(QMouseEvent* ev)
}
}
break;
+
+ default:
+ mode = START_DRAG;
}
redraw();
}
diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp
index fd90c2c2..0b1574cc 100644
--- a/muse2/muse/audio.cpp
+++ b/muse2/muse/audio.cpp
@@ -25,8 +25,6 @@
#include <cmath>
#include <errno.h>
-#include <QSocketNotifier>
-
#include "app.h"
#include "song.h"
#include "node.h"
@@ -51,10 +49,18 @@
namespace MusEGlobal {
MusECore::Audio* audio;
MusECore::AudioDevice* audioDevice; // current audio device in use
-extern unsigned int volatile midiExtSyncTicks; // p3.3.25
+extern unsigned int volatile midiExtSyncTicks;
}
namespace MusECore {
+
+
+void initAudio()
+{
+ MusEGlobal::audio = new Audio();
+}
+
+
extern double curTime();
//static const unsigned char mmcDeferredPlayMsg[] = { 0x7f, 0x7f, 0x06, 0x03 };
@@ -166,8 +172,11 @@ Audio::Audio()
exit(-1);
}
sigFd = filedes[1];
- QSocketNotifier* ss = new QSocketNotifier(filedes[0], QSocketNotifier::Read);
- MusEGlobal::song->connect(ss, SIGNAL(activated(int)), MusEGlobal::song, SLOT(seqSignal(int)));
+ sigFdr = filedes[0];
+
+ // Moved to MusE::MusE
+ //QSocketNotifier* ss = new QSocketNotifier(filedes[0], QSocketNotifier::Read);
+ //MusEGlobal::song->connect(ss, SIGNAL(activated(int)), MusEGlobal::song, SLOT(seqSignal(int)));
}
//---------------------------------------------------------
@@ -182,7 +191,9 @@ bool Audio::start()
//process(MusEGlobal::segmentSize); // warm up caches
state = STOP;
_loopCount = 0;
- MusEGlobal::muse->setHeartBeat();
+
+ MusEGlobal::muse->setHeartBeat();
+
if (MusEGlobal::audioDevice) {
//_running = true;
//MusEGlobal::audioDevice->start();
@@ -221,9 +232,11 @@ bool Audio::start()
// shall we really stop JACK transport and locate to
// saved position?
- MusEGlobal::audioDevice->stopTransport();
+ MusEGlobal::audioDevice->stopTransport();
+
//MusEGlobal::audioDevice->seekTransport(MusEGlobal::song->cPos().frame());
- MusEGlobal::audioDevice->seekTransport(MusEGlobal::song->cPos());
+ MusEGlobal::audioDevice->seekTransport(MusEGlobal::song->cPos());
+
return true;
}
@@ -531,6 +544,26 @@ void Audio::process1(unsigned samplePos, unsigned offset, unsigned frames)
// Pre-process the metronome.
((AudioTrack*)metronome)->preProcessAlways();
+ // Process Aux tracks first.
+ for(ciTrack it = tl->begin(); it != tl->end(); ++it)
+ {
+ if((*it)->isMidiTrack())
+ continue;
+ track = (AudioTrack*)(*it);
+ if(!track->processed() && track->type() == Track::AUDIO_AUX)
+ {
+ //printf("Audio::process1 Do aux: track:%s\n", track->name().toLatin1().constData());
+ channels = track->channels();
+ // Just a dummy buffer.
+ float* buffer[channels];
+ float data[frames * channels];
+ for (int i = 0; i < channels; ++i)
+ buffer[i] = data + i * frames;
+ //printf("Audio::process1 calling track->copyData for track:%s\n", track->name().toLatin1());
+ track->copyData(samplePos, channels, -1, -1, frames, buffer);
+ }
+ }
+
OutputList* ol = MusEGlobal::song->outputs();
for (ciAudioOutput i = ol->begin(); i != ol->end(); ++i)
(*i)->process(samplePos, offset, frames);
@@ -548,8 +581,11 @@ void Audio::process1(unsigned samplePos, unsigned offset, unsigned frames)
track = (AudioTrack*)(*it);
// Ignore unprocessed tracks which have an output route, because they will be processed by
// whatever track(s) they are routed to.
- if(!track->processed() && track->noOutRoute() && (track->type() != Track::AUDIO_OUTPUT))
+ //if(!track->processed() && track->noOutRoute() && (track->type() != Track::AUDIO_OUTPUT))
+ // No, do all.
+ if(!track->processed() && (track->type() != Track::AUDIO_OUTPUT))
{
+ //printf("Audio::process1 track:%s\n", track->name().toLatin1().constData());
channels = track->channels();
// Just a dummy buffer.
float* buffer[channels];
diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h
index 8d89be78..3c4eb17d 100644
--- a/muse2/muse/audio.h
+++ b/muse2/muse/audio.h
@@ -166,7 +166,9 @@ class Audio {
int fromThreadFdw, fromThreadFdr; // message pipe
int sigFd; // pipe fd for messages to gui
-
+ //QSocketNotifier* _socketNotifier;
+ int sigFdr;
+
// record values:
Pos startRecordPos;
Pos endRecordPos;
@@ -189,8 +191,12 @@ class Audio {
public:
Audio();
- virtual ~Audio() {}
+ virtual ~Audio() { }
+ // Access to message pipe (like from gui namespace), otherwise audio would need to depend on gui.
+ int getFromThreadFdw() { return sigFd; }
+ int getFromThreadFdr() { return sigFdr; }
+
void process(unsigned frames);
bool sync(int state, unsigned frame);
void shutdown();
diff --git a/muse2/muse/audioprefetch.cpp b/muse2/muse/audioprefetch.cpp
index 9406911f..1fcb7cef 100644
--- a/muse2/muse/audioprefetch.cpp
+++ b/muse2/muse/audioprefetch.cpp
@@ -39,7 +39,11 @@ MusECore::AudioPrefetch* audioPrefetch;
namespace MusECore {
-// Added by Tim. p3.3.20
+void initAudioPrefetch()
+{
+ MusEGlobal::audioPrefetch = new AudioPrefetch("Prefetch");
+}
+
//#define AUDIOPREFETCH_DEBUG
enum { PREFETCH_TICK, PREFETCH_SEEK
@@ -140,6 +144,7 @@ void AudioPrefetch::msgTick()
{
PrefetchMsg msg;
msg.id = PREFETCH_TICK;
+ msg.pos = 0; // seems to be unused, was uninitalized.
while (sendMsg1(&msg, sizeof(msg))) {
printf("AudioPrefetch::msgTick(): send failed!\n");
}
diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp
index 7de92434..aceacc75 100644
--- a/muse2/muse/audiotrack.cpp
+++ b/muse2/muse/audiotrack.cpp
@@ -42,10 +42,10 @@
namespace MusECore {
-bool AudioAux::_isVisible=true;
-bool AudioInput::_isVisible=true;
-bool AudioOutput::_isVisible=true;
-bool AudioGroup::_isVisible = true;
+bool AudioAux::_isVisible=false;
+bool AudioInput::_isVisible=false;
+bool AudioOutput::_isVisible=false;
+bool AudioGroup::_isVisible =false;
bool WaveTrack::_isVisible=true;
// By T356. For caching jack in/out routing names BEFORE file save.
@@ -107,7 +107,7 @@ AudioTrack::AudioTrack(TrackType t)
_automationType = AUTO_OFF;
//setChannels(1);
setChannels(2);
- addController(new CtrlList(AC_VOLUME,"Volume",0.0,3.16 /* roughly 10 db */, VAL_LOG));
+ addController(new CtrlList(AC_VOLUME,"Volume",0.001,3.163 /* roughly 10 db */, VAL_LOG));
addController(new CtrlList(AC_PAN, "Pan", -1.0, 1.0, VAL_LINEAR));
addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0, VAL_LINEAR, true /*dont show in arranger */));
@@ -1610,8 +1610,40 @@ void AudioAux::read(Xml& xml)
// getData
//---------------------------------------------------------
-bool AudioAux::getData(unsigned /*pos*/, int ch, unsigned /*samples*/, float** data)
+bool AudioAux::getData(unsigned pos, int ch, unsigned samples, float** data)
{
+ // Make sure all the aux-supporting tracks are processed first so aux data is gathered. p4.0.37
+ TrackList* tl = MusEGlobal::song->tracks();
+ AudioTrack* track;
+ for(ciTrack it = tl->begin(); it != tl->end(); ++it)
+ {
+ if((*it)->isMidiTrack())
+ continue;
+ track = (AudioTrack*)(*it);
+ // If there are any Aux route paths to the track, defer processing until the second main track processing pass.
+ if(!track->processed() && track->hasAuxSend() && !track->auxRefCount())
+ {
+ int chans = track->channels();
+ // Just a dummy buffer.
+ float* buff[chans];
+ float buff_data[samples * chans];
+ for (int i = 0; i < chans; ++i)
+ buff[i] = buff_data + i * samples;
+
+ //printf("AudioAux::getData name:%s\n calling copyData on:%s auxRefCount:%d\n",
+ // name().toLatin1().constData(), track->name().toLatin1().constData(), track->auxRefCount());
+
+ track->copyData(pos, chans, -1, -1, samples, buff);
+
+ /* float* buff[ch];
+ float buff_data[samples * ch];
+ for (int i = 0; i < ch; ++i)
+ buff[i] = buff_data + i * samples;
+ //printf("Audio::process1 calling track->copyData for track:%s\n", track->name().toLatin1());
+ track->copyData(pos, ch, -1, -1, samples, buff); */
+ }
+ }
+
for (int i = 0; i < ch; ++i)
data[i] = buffer[i % channels()];
return true;
diff --git a/muse2/muse/cliplist/cliplist.cpp b/muse2/muse/cliplist/cliplist.cpp
index a4702137..60041dae 100644
--- a/muse2/muse/cliplist/cliplist.cpp
+++ b/muse2/muse/cliplist/cliplist.cpp
@@ -32,6 +32,7 @@
#include "wave.h"
#include "xml.h"
#include "ui_cliplisteditorbase.h"
+#include "app.h"
namespace MusEGui {
@@ -168,6 +169,7 @@ ClipListEdit::ClipListEdit(QWidget* parent)
connect(editor->len, SIGNAL(valueChanged(const MusECore::Pos&)), SLOT(lenChanged(const MusECore::Pos&)));
updateList();
+ MusEGlobal::muse->topwinMenuInited(this);
}
ClipListEdit::~ClipListEdit()
@@ -194,7 +196,7 @@ void ClipListEdit::updateList()
void ClipListEdit::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
diff --git a/muse2/muse/cliplist/cliplist.h b/muse2/muse/cliplist/cliplist.h
index b490663c..0972df97 100644
--- a/muse2/muse/cliplist/cliplist.h
+++ b/muse2/muse/cliplist/cliplist.h
@@ -73,7 +73,7 @@ class ClipListEdit : public TopWin {
void clicked(QTreeWidgetItem*, int);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
ClipListEdit(QWidget* parent);
diff --git a/muse2/muse/cobject.cpp b/muse2/muse/cobject.cpp
index 59a9463e..50586d45 100644
--- a/muse2/muse/cobject.cpp
+++ b/muse2/muse/cobject.cpp
@@ -50,6 +50,7 @@ bool TopWin::initInited=false;
TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlags f)
: QMainWindow(parent, f)
{
+ _isDeleting = false;
if (initInited==false)
initConfiguration();
@@ -77,7 +78,10 @@ TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlag
mdisubwin=NULL;
_sharesToolsAndMenu=_defaultSubwin[_type] ? _sharesWhenSubwin[_type] : _sharesWhenFree[_type];
if (_defaultSubwin[_type])
+ {
setIsMdiWin(true);
+ _savedToolbarState=_toolbarNonsharedInit[_type];
+ }
if (_sharesToolsAndMenu)
menuBar()->hide();
@@ -85,8 +89,11 @@ TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlag
subwinAction->setChecked(isMdiWin());
shareAction->setChecked(_sharesToolsAndMenu);
fullscreenAction->setEnabled(!isMdiWin());
-
- resize(_widthInit[_type], _heightInit[_type]);
+
+ if (mdisubwin)
+ mdisubwin->resize(_widthInit[_type], _heightInit[_type]);
+ else
+ resize(_widthInit[_type], _heightInit[_type]);
}
@@ -96,6 +103,8 @@ TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlag
void TopWin::readStatus(MusECore::Xml& xml)
{
+ int x=0, y=0, width=800, height=600;
+
for (;;)
{
MusECore::Xml::Token token = xml.parse();
@@ -106,17 +115,24 @@ void TopWin::readStatus(MusECore::Xml& xml)
switch (token)
{
case MusECore::Xml::TagStart:
- if (tag == "geometry_state")
- {
- if (!restoreGeometry(QByteArray::fromHex(xml.parse1().toAscii())))
- fprintf(stderr,"ERROR: couldn't restore geometry. however, this is probably not really a problem.\n");
- }
+ if (tag == "x")
+ x=xml.parseInt();
+ else if (tag == "y")
+ y=xml.parseInt();
+ else if (tag == "width")
+ width=xml.parseInt();
+ else if (tag == "height")
+ height=xml.parseInt();
else if (tag == "toolbars")
{
if (!sharesToolsAndMenu())
{
if (!restoreState(QByteArray::fromHex(xml.parse1().toAscii())))
- fprintf(stderr,"ERROR: couldn't restore toolbars. however, this is not really a problem.\n");
+ {
+ fprintf(stderr,"ERROR: couldn't restore toolbars. trying default configuration...\n");
+ if (!restoreState(_toolbarNonsharedInit[_type]))
+ fprintf(stderr,"ERROR: couldn't restore default toolbars. this is not really a problem.\n");
+ }
}
else
{
@@ -139,7 +155,20 @@ void TopWin::readStatus(MusECore::Xml& xml)
case MusECore::Xml::TagEnd:
if (tag == "topwin")
+ {
+ if (mdisubwin)
+ {
+ mdisubwin->move(x, y);
+ mdisubwin->resize(width, height);
+ }
+ else
+ {
+ move(x,y);
+ resize(width,height);
+ }
+
return;
+ }
default:
break;
@@ -159,7 +188,22 @@ void TopWin::writeStatus(int level, MusECore::Xml& xml) const
// changing it won't break muse, but it may break proper
// restoring of the positions
xml.intTag(level, "is_subwin", isMdiWin());
- xml.strTag(level, "geometry_state", saveGeometry().toHex().data());
+
+ if (mdisubwin)
+ {
+ xml.intTag(level, "x", mdisubwin->x());
+ xml.intTag(level, "y", mdisubwin->y());
+ xml.intTag(level, "width", mdisubwin->width());
+ xml.intTag(level, "height", mdisubwin->height());
+ }
+ else
+ {
+ xml.intTag(level, "x", x());
+ xml.intTag(level, "y", y());
+ xml.intTag(level, "width", width());
+ xml.intTag(level, "height", height());
+ }
+
xml.intTag(level, "shares_menu", sharesToolsAndMenu());
if (!sharesToolsAndMenu())
@@ -359,8 +403,17 @@ void TopWin::shareToolsAndMenu(bool val)
void TopWin::storeInitialState() const
{
- _widthInit[_type] = width();
- _heightInit[_type] = height();
+ if (mdisubwin)
+ {
+ _widthInit[_type] = mdisubwin->width();
+ _heightInit[_type] = mdisubwin->height();
+ }
+ else
+ {
+ _widthInit[_type] = width();
+ _heightInit[_type] = height();
+ }
+
if (sharesToolsAndMenu())
{
if (muse->getCurrentMenuSharingTopwin() == this)
@@ -519,4 +572,15 @@ void TopWin::resize(const QSize& s)
resize(s.width(), s.height());
}
+TopWin* ToplevelList::findType(TopWin::ToplevelType type) const
+{
+ for (ciToplevel i = begin(); i != end(); ++i)
+ {
+ if((*i)->type() == type)
+ return (*i);
+ }
+ return 0;
+}
+
+
} // namespace MusEGui
diff --git a/muse2/muse/cobject.h b/muse2/muse/cobject.h
index c1c45039..f6ea2ce1 100644
--- a/muse2/muse/cobject.h
+++ b/muse2/muse/cobject.h
@@ -62,7 +62,8 @@ class TopWin : public QMainWindow
ToplevelType type() const { return _type; }
static QString typeName(ToplevelType t);
-
+ bool deleting() const { return _isDeleting; }
+
virtual void readStatus(MusECore::Xml&);
virtual void writeStatus(int, MusECore::Xml&) const;
@@ -118,6 +119,11 @@ class TopWin : public QMainWindow
QByteArray _savedToolbarState;
+ // Set if close has been called on a TopWin having the WA_DeleteOnClose attribute.
+ // The TopWins and any children should ignore any signals such as songChanged
+ // which may cause a crash while deleting.
+ bool _isDeleting;
+
void initTopwinState();
private slots:
@@ -131,13 +137,25 @@ class TopWin : public QMainWindow
void shareToolsAndMenu(bool);
void restoreMainwinState();
void storeInitialState() const;
-
+
};
-typedef std::list <TopWin*> ToplevelList;
-typedef ToplevelList::iterator iToplevel;
-typedef ToplevelList::const_iterator ciToplevel;
+//---------------------------------------------------------
+// ToplevelList
+//---------------------------------------------------------
+
+//typedef std::list <TopWin*> ToplevelList;
+//typedef ToplevelList::iterator iToplevel;
+//typedef ToplevelList::const_iterator ciToplevel;
+
+typedef std::list<TopWin*>::iterator iToplevel;
+typedef std::list<TopWin*>::const_iterator ciToplevel;
+
+class ToplevelList : public std::list<TopWin* > {
+ public:
+ TopWin* findType(TopWin::ToplevelType) const;
+ };
} // namespace MusEGui
diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp
index 26f96bf1..5376734c 100644
--- a/muse2/muse/conf.cpp
+++ b/muse2/muse/conf.cpp
@@ -220,7 +220,7 @@ static void readPortChannel(Xml& xml, int midiPort)
// readConfigMidiPort
//---------------------------------------------------------
-static void readConfigMidiPort(Xml& xml)
+static void readConfigMidiPort(Xml& xml, bool skipConfig)
{
int idx = 0;
QString device;
@@ -234,11 +234,9 @@ static void readConfigMidiPort(Xml& xml)
// FIXME: TODO: Make this user-configurable!
QString instrument("GM");
+ int rwFlags = 3;
int openFlags = 1;
- bool thruFlag = false;
- //int dic = 0;
- //int doc = 0;
- int dic = -1; // p4.0.17
+ int dic = -1;
int doc = -1;
MidiSyncInfo tmpSi;
@@ -251,6 +249,19 @@ static void readConfigMidiPort(Xml& xml)
QString tag = xml.s1();
switch (token) {
case Xml::TagStart:
+
+ // skipConfig added so it doesn't overwrite midi ports. p4.0.41 Tim.
+ // Try to keep the controller information. But, this may need to be moved below.
+ // Also may want to try to keep sync info, but that's a bit risky, so let's not for now.
+ if (tag == "channel") {
+ readPortChannel(xml, idx);
+ break;
+ }
+ else if (skipConfig){
+ xml.skip(tag);
+ break;
+ }
+
if (tag == "name")
device = xml.parse1();
else if (tag == "type")
@@ -262,6 +273,8 @@ static void readConfigMidiPort(Xml& xml)
}
else if (tag == "openFlags")
openFlags = xml.parseInt();
+ else if (tag == "rwFlags") // Jack midi devs need this. p4.0.41
+ rwFlags = xml.parseInt();
else if (tag == "defaultInChans")
dic = xml.parseInt();
else if (tag == "defaultOutChans")
@@ -270,16 +283,15 @@ static void readConfigMidiPort(Xml& xml)
tmpSi.read(xml);
else if (tag == "instrument") {
instrument = xml.parse1();
- // Moved by Tim.
- //MusEGlobal::midiPorts[idx].setInstrument(
+ //MusEGlobal::midiPorts[idx].setInstrument( // Moved below
// registerMidiInstrument(instrument)
// );
}
else if (tag == "midithru")
- thruFlag = xml.parseInt(); // obsolete
- else if (tag == "channel") {
- readPortChannel(xml, idx);
- }
+ xml.parseInt(); // obsolete
+ //else if (tag == "channel") {
+ // readPortChannel(xml, idx); // Moved above
+ // }
else
xml.unknown("MidiDevice");
break;
@@ -290,6 +302,10 @@ static void readConfigMidiPort(Xml& xml)
break;
case Xml::TagEnd:
if (tag == "midiport") {
+
+ if(skipConfig) // p4.0.41
+ return;
+
//if (idx > MIDI_PORTS) {
if (idx < 0 || idx >= MIDI_PORTS) {
fprintf(stderr, "bad midi port %d (>%d)\n",
@@ -305,9 +321,8 @@ static void readConfigMidiPort(Xml& xml)
if(!dev && type == MidiDevice::JACK_MIDI)
{
if(MusEGlobal::debugMsg)
- fprintf(stderr, "readConfigMidiPort: creating jack midi device %s\n", device.toLatin1().constData());
- //dev = MidiJackDevice::createJackMidiDevice(device, openFlags);
- dev = MidiJackDevice::createJackMidiDevice(device); // p3.3.55
+ fprintf(stderr, "readConfigMidiPort: creating jack midi device %s with rwFlags:%d\n", device.toLatin1().constData(), rwFlags);
+ dev = MidiJackDevice::createJackMidiDevice(device, rwFlags);
}
if(MusEGlobal::debugMsg && !dev)
@@ -315,7 +330,7 @@ static void readConfigMidiPort(Xml& xml)
MidiPort* mp = &MusEGlobal::midiPorts[idx];
- mp->setInstrument(registerMidiInstrument(instrument)); // By Tim.
+ mp->setInstrument(registerMidiInstrument(instrument));
if(dic != -1) // p4.0.17 Leave them alone unless set by song.
mp->setDefaultInChannels(dic);
if(doc != -1)
@@ -480,7 +495,7 @@ static void loadConfigMetronom(Xml& xml)
// readSeqConfiguration
//---------------------------------------------------------
-static void readSeqConfiguration(Xml& xml)
+static void readSeqConfiguration(Xml& xml, bool skipConfig)
{
for (;;) {
Xml::Token token = xml.parse();
@@ -492,7 +507,7 @@ static void readSeqConfiguration(Xml& xml)
if (tag == "metronom")
loadConfigMetronom(xml);
else if (tag == "midiport")
- readConfigMidiPort(xml);
+ readConfigMidiPort(xml, skipConfig);
else if (tag == "rcStop")
MusEGlobal::rcStopNote = xml.parseInt();
else if (tag == "rcEnable")
@@ -542,7 +557,7 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig
midiport configuration and VOLUME.
*/
if (tag == "sequencer") {
- readSeqConfiguration(xml);
+ readSeqConfiguration(xml, readOnlySequencer);
break;
}
else if (readOnlySequencer) {
@@ -580,8 +595,10 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig
MidiTrack::setVisible((bool)xml.parseInt());
else if (tag == "inputTracksVisible")
AudioInput::setVisible((bool)xml.parseInt());
- else if (tag == "outputTracksVisible")
+ else if (tag == "outputTracksVisible") {
+ printf("output track set from config!\n");
AudioOutput::setVisible((bool)xml.parseInt());
+ }
else if (tag == "synthTracksVisible")
SynthI::setVisible((bool)xml.parseInt());
else if (tag == "bigtimeVisible")
@@ -624,7 +641,18 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig
MusEGlobal::config.geometryTransport = readGeometry(xml, tag);
else if (tag == "geometryBigTime")
MusEGlobal::config.geometryBigTime = readGeometry(xml, tag);
-
+ else if (tag == "Mixer") {
+ if(mixers == 0)
+ MusEGlobal::config.mixer1.read(xml);
+ else
+ MusEGlobal::config.mixer2.read(xml);
+ ++mixers;
+ }
+ else if (tag == "geometryMain")
+ MusEGlobal::config.geometryMain = readGeometry(xml, tag);
+
+ // don't insert else if(...) clauses between
+ // this line and "Global config stuff begins here".
else if (!doReadGlobalConfig) {
xml.skip(tag);
break;
@@ -636,9 +664,6 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig
// ---- Global config stuff begins here ----
- else if (tag == "geometryMain")
- MusEGlobal::config.geometryMain = readGeometry(xml, tag);
-
else if (tag == "theme")
MusEGlobal::config.style = xml.parse1();
else if (tag == "styleSheetFile")
@@ -851,20 +876,6 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig
MusEGlobal::config.canvasBgPixmap = xml.parse1();
else if (tag == "canvasCustomBgList")
MusEGlobal::config.canvasCustomBgList = xml.parse1().split(";", QString::SkipEmptyParts);
-
- //else if (tag == "mixer1")
- // MusEGlobal::config.mixer1.read(xml);
- //else if (tag == "mixer2")
- // MusEGlobal::config.mixer2.read(xml);
- else if (tag == "Mixer")
- {
- if(mixers == 0)
- MusEGlobal::config.mixer1.read(xml);
- else
- MusEGlobal::config.mixer2.read(xml);
- ++mixers;
- }
-
else if (tag == "bigtimeForegroundcolor")
MusEGlobal::config.bigTimeForegroundColor = readColor(xml);
else if (tag == "bigtimeBackgroundcolor")
@@ -936,8 +947,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig
MusEGlobal::config.minControlProcessPeriod = xml.parseUInt();
else if (tag == "guiRefresh")
MusEGlobal::config.guiRefresh = xml.parseInt();
- else if (tag == "userInstrumentsDir")
- MusEGlobal::config.userInstrumentsDir = xml.parse1();
+ else if (tag == "userInstrumentsDir") // Obsolete
+ MusEGlobal::config.userInstrumentsDir = xml.parse1(); // Keep for compatibility
else if (tag == "startMode")
MusEGlobal::config.startMode = xml.parseInt();
else if (tag == "startSong")
@@ -956,6 +967,10 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig
MusEGlobal::config.leftMouseButtonCanDecrease = xml.parseInt();
else if (tag == "rangeMarkerWithoutMMB")
MusEGlobal::config.rangeMarkerWithoutMMB = xml.parseInt();
+ else if (tag == "addHiddenTracks")
+ MusEGlobal::config.addHiddenTracks = xml.parseInt();
+ else if (tag == "unhideTracks")
+ MusEGlobal::config.unhideTracks = xml.parseInt();
// ---- the following only skips obsolete entries ----
else if ((tag == "arranger") || (tag == "geometryPianoroll") || (tag == "geometryDrumedit"))
@@ -1179,7 +1194,6 @@ static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo)
if (dev) {
xml.strTag(level, "name", dev->name());
- // p3.3.38
//if(dynamic_cast<MidiJackDevice*>(dev))
if(dev->deviceType() != MidiDevice::ALSA_MIDI)
//xml.intTag(level, "type", MidiDevice::JACK_MIDI);
@@ -1189,6 +1203,9 @@ static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo)
// openFlags was read before, but never written here.
//xml.intTag(level, "record", dev->rwFlags() & 0x2 ? 1 : 0);
xml.intTag(level, "openFlags", dev->openFlags());
+
+ if(dev->deviceType() == MidiDevice::JACK_MIDI)
+ xml.intTag(level, "rwFlags", dev->rwFlags()); // Need this. Jack midi devs are created by app. p4.0.41
}
mport->syncInfo().write(level, xml);
// write out registered controller for all channels
@@ -1255,9 +1272,8 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "dummyAudioBufSize", MusEGlobal::config.dummyAudioBufSize);
xml.intTag(level, "dummyAudioSampleRate", MusEGlobal::config.dummyAudioSampleRate);
xml.uintTag(level, "minControlProcessPeriod", MusEGlobal::config.minControlProcessPeriod);
-
xml.intTag(level, "guiRefresh", MusEGlobal::config.guiRefresh);
- xml.strTag(level, "userInstrumentsDir", MusEGlobal::config.userInstrumentsDir);
+
// Removed by Orcan. 20101220
//xml.strTag(level, "helpBrowser", config.helpBrowser);
xml.intTag(level, "extendedMidi", MusEGlobal::config.extendedMidi);
@@ -1294,6 +1310,17 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "leftMouseButtonCanDecrease", MusEGlobal::config.leftMouseButtonCanDecrease);
xml.intTag(level, "rangeMarkerWithoutMMB", MusEGlobal::config.rangeMarkerWithoutMMB);
+ xml.intTag(level, "unhideTracks", MusEGlobal::config.unhideTracks);
+ xml.intTag(level, "addHiddenTracks", MusEGlobal::config.addHiddenTracks);
+
+ xml.intTag(level, "waveTracksVisible", MusECore::WaveTrack::visible());
+ xml.intTag(level, "auxTracksVisible", MusECore::AudioAux::visible());
+ xml.intTag(level, "groupTracksVisible", MusECore::AudioGroup::visible());
+ xml.intTag(level, "midiTracksVisible", MusECore::MidiTrack::visible());
+ xml.intTag(level, "inputTracksVisible", MusECore::AudioInput::visible());
+ xml.intTag(level, "outputTracksVisible", MusECore::AudioOutput::visible());
+ xml.intTag(level, "synthTracksVisible", MusECore::SynthI::visible());
+
//for (int i = 0; i < 6; ++i) {
for (int i = 0; i < NUM_FONTS; ++i) {
char buffer[32];
@@ -1348,7 +1375,6 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.colorTag(level, "auxTrackBg", MusEGlobal::config.auxTrackBg);
xml.colorTag(level, "synthTrackBg", MusEGlobal::config.synthTrackBg);
- // Removed by Tim. p3.3.6
//xml.intTag(level, "txSyncPort", txSyncPort);
//xml.intTag(level, "rxSyncPort", rxSyncPort);
xml.intTag(level, "mtctype", MusEGlobal::mtcType);
@@ -1375,11 +1401,8 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "bigtimeVisible", MusEGlobal::config.bigTimeVisible);
xml.intTag(level, "transportVisible", MusEGlobal::config.transportVisible);
- //xml.intTag(level, "mixerVisible", MusEGlobal::config.mixerVisible); // Obsolete
xml.intTag(level, "mixer1Visible", MusEGlobal::config.mixer1Visible);
xml.intTag(level, "mixer2Visible", MusEGlobal::config.mixer2Visible);
- //MusEGlobal::config.mixer1.write(level, xml, "mixer1");
- //MusEGlobal::config.mixer2.write(level, xml, "mixer2");
MusEGlobal::config.mixer1.write(level, xml);
MusEGlobal::config.mixer2.write(level, xml);
@@ -1432,20 +1455,9 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "midiFilterCtrl3", MusEGlobal::midiFilterCtrl3);
xml.intTag(level, "midiFilterCtrl4", MusEGlobal::midiFilterCtrl4);
- xml.intTag(level, "waveTracksVisible", MusECore::WaveTrack::visible());
- xml.intTag(level, "auxTracksVisible", MusECore::AudioAux::visible());
- xml.intTag(level, "groupTracksVisible", MusECore::AudioGroup::visible());
- xml.intTag(level, "midiTracksVisible", MusECore::MidiTrack::visible());
- xml.intTag(level, "inputTracksVisible", MusECore::AudioInput::visible());
- xml.intTag(level, "outputTracksVisible", MusECore::AudioOutput::visible());
- xml.intTag(level, "synthTracksVisible", MusECore::SynthI::visible());
- // Removed by Tim. p3.3.6
-
//xml.intTag(level, "txDeviceId", txDeviceId);
//xml.intTag(level, "rxDeviceId", rxDeviceId);
- // Changed by Tim. p3.3.6
-
//xml.intTag(level, "txSyncPort", txSyncPort);
/*
// To keep old muse versions happy...
@@ -1467,8 +1479,6 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const
}
*/
- // Added by Tim. p3.3.6
-
//xml.tag(level++, "midiSyncInfo");
//for(iMusECore::MidiDevice id = MusECore::MusEGlobal::midiDevices.begin(); id != MusECore::MusEGlobal::midiDevices.end(); ++id)
//{
@@ -1496,8 +1506,6 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "bigtimeVisible", viewBigtimeAction->isChecked());
xml.intTag(level, "transportVisible", viewTransportAction->isChecked());
- //xml.intTag(level, "markerVisible", viewMarkerAction->isChecked()); // Obsolete (done by song's toplevel list)
- //xml.intTag(level, "mixerVisible", menuView->isItemChecked(aid1)); // Obsolete
xml.geometryTag(level, "geometryMain", this); // FINDME: maybe remove this? do we want
// the main win to jump around when loading?
@@ -1506,18 +1514,13 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const
if (bigtime)
xml.geometryTag(level, "geometryBigTime", bigtime);
- //if (audioMixer)
- // xml.geometryTag(level, "geometryMixer", audioMixer); // Obsolete
xml.intTag(level, "mixer1Visible", viewMixerAAction->isChecked());
xml.intTag(level, "mixer2Visible", viewMixerBAction->isChecked());
if (mixer1)
- //mixer1->write(level, xml, "mixer1");
mixer1->write(level, xml);
if (mixer2)
- //mixer2->write(level, xml, "mixer2");
mixer2->write(level, xml);
- //_arranger->writeStatus(level, xml); // Obsolete. done by song's toplevel list. arrangerview also handles arranger.
writeSeqConfiguration(level, xml, true);
MusEGui::write_function_dialog_config(level, xml);
@@ -1658,18 +1661,12 @@ namespace MusEGlobal {
// write
//---------------------------------------------------------
-//void MixerConfig::write(MusECore::Xml& xml, const char* name)
void MixerConfig::write(int level, MusECore::Xml& xml)
-//void MixerConfig::write(int level, MusECore::Xml& xml, const char* name)
{
- //xml.stag(QString(name));
- //xml.tag(level++, name.toLatin1().constData());
xml.tag(level++, "Mixer");
- //xml.tag(level++, name);
-
+
xml.strTag(level, "name", name);
- //xml.tag("geometry", geometry);
xml.qrectTag(level, "geometry", geometry);
xml.intTag(level, "showMidiTracks", showMidiTracks);
@@ -1682,19 +1679,14 @@ void MixerConfig::write(int level, MusECore::Xml& xml)
xml.intTag(level, "showAuxTracks", showAuxTracks);
xml.intTag(level, "showSyntiTracks", showSyntiTracks);
- //xml.etag(name);
- //xml.etag(level, name.toLatin1().constData());
xml.etag(level, "Mixer");
- //xml.etag(level, name);
}
//---------------------------------------------------------
// read
//---------------------------------------------------------
-//void MixerConfig::read(QDomNode node)
void MixerConfig::read(MusECore::Xml& xml)
-//void MixerConfig::read(MusECore::Xml& xml, const QString& name)
{
for (;;) {
MusECore::Xml::Token token(xml.parse());
diff --git a/muse2/muse/confmport.cpp b/muse2/muse/confmport.cpp
index 315e686e..d45dd370 100644
--- a/muse2/muse/confmport.cpp
+++ b/muse2/muse/confmport.cpp
@@ -183,22 +183,25 @@ void MPConfig::changeDefOutputRoutes(QAction* act)
MusEGlobal::audio->msgUpdateSoloStates();
MusEGlobal::song->update(SC_ROUTE);
#else
- int ch = 0;
- for( ; ch < MIDI_CHANNELS; ++ch)
- if(defch & (1 << ch)) break;
-
- MusEGlobal::audio->msgIdle(true);
- for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
- {
- // Leave drum track channel at current setting.
- if((*it)->type() == MusECore::Track::DRUM)
- (*it)->setOutPortAndUpdate(no);
- else
- (*it)->setOutPortAndChannelAndUpdate(no, ch);
- }
- MusEGlobal::audio->msgIdle(false);
- MusEGlobal::audio->msgUpdateSoloStates();
- MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ if(defch & (1 << ch))
+ {
+ MusEGlobal::audio->msgIdle(true);
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ {
+ // Leave drum track channel at current setting.
+ if((*it)->type() == MusECore::Track::DRUM)
+ (*it)->setOutPortAndUpdate(no);
+ else
+ (*it)->setOutPortAndChannelAndUpdate(no, ch);
+ }
+ MusEGlobal::audio->msgIdle(false);
+ MusEGlobal::audio->msgUpdateSoloStates();
+ MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
+
+ // Stop at the first output channel found.
+ break;
+ }
#endif
}
}
@@ -730,7 +733,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
//act = pup->addAction(tr("Create") + QT_TRANSLATE_NOOP("@default", " Jack") + tr(" output"));
//act = pup->addAction(tr("Create") + QT_TRANSLATE_NOOP("@default", " Jack") + tr(" combo"));
// ... or keep it simple and let the user click on the green lights instead.
- act = pup->addAction(tr("Create") + QT_TRANSLATE_NOOP("@default", " Jack") + tr(" device"));
+ act = pup->addAction(tr("Create Jack device"));
act->setData(0);
typedef std::map<std::string, int > asmap;
@@ -776,7 +779,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
//if(!mapALSA.empty())
{
pup->addSeparator();
- pup->addAction(new MusEGui::MenuTitleItem(QT_TRANSLATE_NOOP("@default", "ALSA:"), pup));
+ pup->addAction(new MusEGui::MenuTitleItem("ALSA:", pup));
for(imap i = mapALSA.begin(); i != mapALSA.end(); ++i)
{
@@ -791,7 +794,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
if(md->deviceType() != MusECore::MidiDevice::ALSA_MIDI)
continue;
- act = pup->addAction(QT_TRANSLATE_NOOP("@default", md->name()));
+ act = pup->addAction(md->name());
act->setData(idx);
act->setCheckable(true);
act->setChecked(md == dev);
@@ -802,7 +805,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
if(!mapSYNTH.empty())
{
pup->addSeparator();
- pup->addAction(new MusEGui::MenuTitleItem(QT_TRANSLATE_NOOP("@default", "SYNTH:"), pup));
+ pup->addAction(new MusEGui::MenuTitleItem("SYNTH:", pup));
for(imap i = mapSYNTH.begin(); i != mapSYNTH.end(); ++i)
{
@@ -817,7 +820,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
if(md->deviceType() != MusECore::MidiDevice::SYNTH_MIDI)
continue;
- act = pup->addAction(QT_TRANSLATE_NOOP("@default", md->name()));
+ act = pup->addAction(md->name());
act->setData(idx);
act->setCheckable(true);
act->setChecked(md == dev);
@@ -828,7 +831,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
//if(!mapJACK.empty())
{
pup->addSeparator();
- pup->addAction(new MusEGui::MenuTitleItem(QT_TRANSLATE_NOOP("@default", "JACK:"), pup));
+ pup->addAction(new MusEGui::MenuTitleItem("JACK:", pup));
for(imap i = mapJACK.begin(); i != mapJACK.end(); ++i)
{
@@ -843,7 +846,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
if(md->deviceType() != MusECore::MidiDevice::JACK_MIDI)
continue;
- act = pup->addAction(QT_TRANSLATE_NOOP("@default", md->name()));
+ act = pup->addAction(md->name());
act->setData(idx);
act->setCheckable(true);
act->setChecked(md == dev);
@@ -902,8 +905,105 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
sdev = 0;
}
+ int allch = (1 << MIDI_CHANNELS) - 1;
+ MusECore::MidiTrackList* mtl = MusEGlobal::song->midis();
+
+ // Remove track routes to/from an existing port already using the selected device...
+ if(sdev)
+ {
+ for(int i = 0; i < MIDI_PORTS; ++i)
+ {
+ if(MusEGlobal::midiPorts[i].device() == sdev)
+ {
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ MusEGlobal::audio->msgRemoveRoute(MusECore::Route(i, allch), MusECore::Route(*it, allch));
+
+ // Turn on if and when multiple output routes are supported.
+ #if 0
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch));
+
+ //MusEGlobal::audio->msgUpdateSoloStates();
+ //MusEGlobal::song->update(SC_ROUTE);
+ #endif
+
+ break;
+ }
+ }
+ }
+
+ // Remove all track routes to/from this port...
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ // Remove all routes from this port to the tracks.
+ MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch));
+ // Turn on if and when multiple output routes are supported.
+ #if 0
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch));
+
+ //MusEGlobal::audio->msgUpdateSoloStates();
+ //MusEGlobal::song->update(SC_ROUTE);
+ #endif
+
MusEGlobal::midiSeq->msgSetMidiDevice(port, sdev);
MusEGlobal::muse->changeConfig(true); // save configuration file
+
+ // Add all track routes to/from this port...
+ if(sdev)
+ {
+ int chbits = MusEGlobal::midiPorts[no].defaultInChannels();
+ // Do not add input routes to synths.
+ if(!sdev->isSynti())
+ {
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ {
+ // Remove all routes from this port to the tracks first.
+ //MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch));
+ // Now connect all the specified routes.
+ if(chbits)
+ MusEGlobal::audio->msgAddRoute(MusECore::Route(no, chbits), MusECore::Route(*it, chbits));
+ }
+ }
+ chbits = MusEGlobal::midiPorts[no].defaultOutChannels();
+ // Turn on if and when multiple output routes are supported.
+ #if 0
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ {
+ // Remove all routes from this port to the tracks first.
+ //MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch));
+ // Now connect all the specified routes.
+ if(chbits)
+ MusEGlobal::audio->msgAddRoute(MusECore::Route(no, chbits), MusECore::Route(*it, chbits));
+ }
+ //MusEGlobal::audio->msgUpdateSoloStates();
+ //MusEGlobal::song->update(SC_ROUTE);
+ #else
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ if(chbits & (1 << ch))
+ {
+ MusEGlobal::audio->msgIdle(true);
+ for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
+ {
+ // Leave drum track channel at current setting.
+ if((*it)->type() == MusECore::Track::DRUM)
+ (*it)->setOutPortAndUpdate(no);
+ else
+ (*it)->setOutPortAndChannelAndUpdate(no, ch);
+ }
+ MusEGlobal::audio->msgIdle(false);
+ //MusEGlobal::audio->msgUpdateSoloStates();
+ //MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
+
+ // Stop at the first output channel found.
+ break;
+ }
+ #endif
+ }
+
+ //MusEGlobal::audio->msgUpdateSoloStates();
+ ////MusEGlobal::song->update(SC_ROUTE);
+
+ MusEGlobal::audio->msgUpdateSoloStates();
MusEGlobal::song->update();
}
}
@@ -1061,7 +1161,8 @@ MPConfig::MPConfig(QWidget* parent)
//popup = 0;
instrPopup = 0;
defpup = 0;
- _showAliases = -1; // 0: Show first aliases, if available. Nah, stick with -1: none at first.
+ //_showAliases = -1; // 0: Show first aliases, if available. Nah, stick with -1: none at first.
+ _showAliases = 0; // 0: Show first aliases, if available.
QStringList columnnames;
columnnames << tr("Port")
@@ -1125,8 +1226,7 @@ void MPConfig::songChanged(int flags)
// Is it simply a midi controller value adjustment? Forget it.
//if(flags == SC_MIDI_CONTROLLER)
// return;
- // No need for anything but this, yet.
- if(!(flags & SC_CONFIG))
+ if(!(flags & (SC_CONFIG | SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED)))
return;
// Get currently selected index...
@@ -1299,32 +1399,29 @@ void MPConfig::songChanged(int flags)
synthList->clear();
for (std::vector<MusECore::Synth*>::iterator i = MusEGlobal::synthis.begin();
i != MusEGlobal::synthis.end(); ++i) {
- //s = (*i)->baseName();
- //s = (*i)->name();
-
QTreeWidgetItem* item = new QTreeWidgetItem(synthList);
- //item->setText(0, s);
item->setText(0, QString((*i)->baseName()));
+ item->setText(1, MusECore::synthType2String((*i)->synthType()));
s.setNum((*i)->instances());
- item->setText(1, s);
- item->setTextAlignment(1, Qt::AlignHCenter);
- //item->setText(2, QString((*i)->baseName()));
- item->setText(2, QString((*i)->name()));
+ item->setText(2, s);
+ //item->setTextAlignment(2, Qt::AlignHCenter);
+ item->setText(3, QString((*i)->name()));
- item->setText(3, QString((*i)->version()));
- item->setText(4, QString((*i)->description()));
+ item->setText(4, QString((*i)->version()));
+ item->setText(5, QString((*i)->description()));
}
instanceList->clear();
MusECore::SynthIList* sl = MusEGlobal::song->syntis();
for (MusECore::iSynthI si = sl->begin(); si != sl->end(); ++si) {
QTreeWidgetItem* iitem = new QTreeWidgetItem(instanceList);
iitem->setText(0, (*si)->name());
+ iitem->setText(1, MusECore::synthType2String((*si)->synth()->synthType()));
if ((*si)->midiPort() == -1)
s = tr("<none>");
else
s.setNum((*si)->midiPort() + 1);
- iitem->setText(1, s);
- iitem->setTextAlignment(1, Qt::AlignHCenter);
+ iitem->setText(2, s);
+ //iitem->setTextAlignment(2, Qt::AlignHCenter);
}
synthList->resizeColumnToContents(1);
mdevView->resizeColumnsToContents();
@@ -1345,7 +1442,10 @@ void MPConfig::addInstanceClicked()
QTreeWidgetItem* item = synthList->currentItem();
if (item == 0)
return;
- MusECore::SynthI *si = MusEGlobal::song->createSynthI(item->text(0), item->text(2)); // Add at end of list.
+ // Add at end of list.
+ MusECore::SynthI *si = MusEGlobal::song->createSynthI(item->text(0),
+ item->text(3),
+ MusECore::string2SynthType(item->text(1)));
if(!si)
return;
@@ -1374,8 +1474,9 @@ void MPConfig::removeInstanceClicked()
MusECore::SynthIList* sl = MusEGlobal::song->syntis();
MusECore::iSynthI ii;
for (ii = sl->begin(); ii != sl->end(); ++ii) {
- if ((*ii)->iname() == item->text(0))
- break;
+ if( (*ii)->iname() == item->text(0) &&
+ MusECore::synthType2String((*ii)->synth()->synthType()) == item->text(1) )
+ break;
}
if (ii == sl->end()) {
printf("synthesizerConfig::removeInstanceClicked(): synthi not found\n");
diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp
index f592d4d3..9896de9a 100644
--- a/muse2/muse/ctrl/ctrlcanvas.cpp
+++ b/muse2/muse/ctrl/ctrlcanvas.cpp
@@ -227,13 +227,11 @@ CtrlCanvas::CtrlCanvas(MidiEditor* e, QWidget* parent, int xmag,
connect(MusEGlobal::song, SIGNAL(posChanged(int, unsigned, bool)), this, SLOT(setPos(int, unsigned, bool)));
setMouseTracking(true);
- if (editor->parts()->empty()) {
- curPart = 0;
- curTrack = 0;
- }
- else {
+ curPart = 0;
+ curTrack = 0;
+ if (!editor->parts()->empty())
setCurTrackAndPart();
- }
+
connect(MusEGlobal::song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), SLOT(configChanged()));
@@ -474,6 +472,9 @@ void CtrlCanvas::configChanged()
void CtrlCanvas::songChanged(int type)
{
+ if(editor->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
//printf("CtrlCanvas::songChanged type:%x\n", type);
// Is it simply a midi controller value adjustment? Forget it.
if(type == SC_MIDI_CONTROLLER)
@@ -1947,7 +1948,7 @@ void CtrlCanvas::drawOverlay(QPainter& p)
//p.setFont(MusEGlobal::config.fonts[3]);
//p.setPen(Qt::black);
//p.drawText(width()/2-100,height()/2-10, "Use shift + pencil or line tool to draw new events");
- p.drawText(2 , y * 2, tr("Use pencil or line tool to draw new events"));
+ p.drawText(2 , y * 2, tr("Drawing hint: Hold Ctrl to affect only existing events"));
}
}
@@ -1998,7 +1999,7 @@ void CtrlCanvas::draw(QPainter& p, const QRect& rect)
// draw line tool
//---------------------------------------------------
- if (drawLineMode && (tool == MusEGui::DrawTool)) {
+ if ((tool == MusEGui::DrawTool) && drawLineMode) {
p.setPen(Qt::black);
p.drawLine(line1x, line1y, line2x, line2y);
}
diff --git a/muse2/muse/ctrl/ctrlcanvas.h b/muse2/muse/ctrl/ctrlcanvas.h
index 79910b94..1fcaf1d8 100644
--- a/muse2/muse/ctrl/ctrlcanvas.h
+++ b/muse2/muse/ctrl/ctrlcanvas.h
@@ -177,6 +177,8 @@ class CtrlCanvas : public MusEGui::View {
void updateItems();
void updateSelections();
+ //virtual void closeEvent(QCloseEvent*);
+
private slots:
void songChanged(int type);
void configChanged();
diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp
index ed83bab8..e46f949c 100644
--- a/muse2/muse/ctrl/ctrlpanel.cpp
+++ b/muse2/muse/ctrl/ctrlpanel.cpp
@@ -162,6 +162,9 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
void CtrlPanel::heartBeat()
{
+ if(editor->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
inHeartBeat = true;
if(_track && _ctrl && _dnum != -1)
diff --git a/muse2/muse/dialogs.cpp b/muse2/muse/dialogs.cpp
index d88977ff..54a080bf 100644
--- a/muse2/muse/dialogs.cpp
+++ b/muse2/muse/dialogs.cpp
@@ -71,6 +71,22 @@ void init_function_dialogs(QWidget* parent)
paste_events_dialog = new PasteEventsDialog(parent);
}
+void retranslate_function_dialogs()
+{
+ gatetime_dialog->retranslateUi(gatetime_dialog);
+ velocity_dialog->retranslateUi(velocity_dialog);
+ quantize_dialog->retranslateUi(quantize_dialog);
+ erase_dialog->retranslateUi(erase_dialog);
+ del_overlaps_dialog->retranslateUi(del_overlaps_dialog);
+ set_notelen_dialog->retranslateUi(set_notelen_dialog);
+ move_notes_dialog->retranslateUi(move_notes_dialog);
+ transpose_dialog->retranslateUi(transpose_dialog);
+ crescendo_dialog->retranslateUi(crescendo_dialog);
+ legato_dialog->retranslateUi(legato_dialog);
+ paste_dialog->retranslateUi(paste_dialog);
+ paste_events_dialog->retranslateUi(paste_events_dialog);
+}
+
void read_function_dialog_config(MusECore::Xml& xml)
{
if (erase_dialog==NULL)
diff --git a/muse2/muse/dialogs.h b/muse2/muse/dialogs.h
index 08830fe0..f2d28f8c 100644
--- a/muse2/muse/dialogs.h
+++ b/muse2/muse/dialogs.h
@@ -59,6 +59,7 @@ extern PasteDialog* paste_dialog;
extern PasteEventsDialog* paste_events_dialog;
void init_function_dialogs(QWidget* parent);
+void retranslate_function_dialogs();
void read_function_dialog_config(MusECore::Xml& xml);
void write_function_dialog_config(int level, MusECore::Xml& xml);
diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp
index eae695db..4687f17f 100644
--- a/muse2/muse/driver/alsamidi.cpp
+++ b/muse2/muse/driver/alsamidi.cpp
@@ -39,6 +39,8 @@
#include "part.h"
#include "gconfig.h"
+#include <QApplication>
+
namespace MusECore {
static int alsaSeqFdi = -1;
@@ -46,6 +48,7 @@ static int alsaSeqFdo = -1;
snd_seq_t* alsaSeq = 0;
static snd_seq_addr_t musePort;
+static snd_seq_addr_t announce_adr;
//---------------------------------------------------------
// MidiAlsaDevice
@@ -83,42 +86,55 @@ QString MidiAlsaDevice::open()
QString estr;
int wer = 0;
int rer = 0;
+
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ //snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_addr(pinfo, &adr);
+
+ int cap = snd_seq_port_info_get_capability(pinfo);
// subscribe for writing
if (_openFlags & 1)
{
- snd_seq_port_subscribe_set_sender(subs, &musePort);
- snd_seq_port_subscribe_set_dest(subs, &adr);
- // Not already subscribed (or error)? Then try subscribing.
- if(snd_seq_get_port_subscription(alsaSeq, subs) < 0)
- {
- //int error = snd_seq_subscribe_port(alsaSeq, subs);
- wer = snd_seq_subscribe_port(alsaSeq, subs);
- //if (error < 0)
- if(wer < 0)
- //return QString("Play: ")+QString(snd_strerror(error));
- estr += (QString("Play: ") + QString(snd_strerror(wer)) + QString(" "));
- }
- if(!wer)
+ if(cap & SND_SEQ_PORT_CAP_SUBS_WRITE)
+ {
+ snd_seq_port_subscribe_set_sender(subs, &musePort);
+ snd_seq_port_subscribe_set_dest(subs, &adr);
+ // Not already subscribed (or error)? Then try subscribing.
+ if(snd_seq_get_port_subscription(alsaSeq, subs) < 0)
+ {
+ //int error = snd_seq_subscribe_port(alsaSeq, subs);
+ wer = snd_seq_subscribe_port(alsaSeq, subs);
+ //if (error < 0)
+ if(wer < 0)
+ //return QString("Play: ")+QString(snd_strerror(error));
+ estr += (QString("Play: ") + QString(snd_strerror(wer)) + QString(" "));
+ }
+ }
+ if(!wer && (cap & SND_SEQ_PORT_CAP_WRITE))
_writeEnable = true;
}
// subscribe for reading
if (_openFlags & 2)
{
- snd_seq_port_subscribe_set_dest(subs, &musePort);
- snd_seq_port_subscribe_set_sender(subs, &adr);
- // Not already subscribed (or error)? Then try subscribing.
- if(snd_seq_get_port_subscription(alsaSeq, subs) < 0)
- {
- //int error = snd_seq_subscribe_port(alsaSeq, subs);
- rer = snd_seq_subscribe_port(alsaSeq, subs);
- //if (error < 0)
- if(rer < 0)
- //return QString("Rec: ") + QString(snd_strerror(error));
- estr += (QString("Rec: ") + QString(snd_strerror(rer)));
- }
- if(!rer)
+ if(cap & SND_SEQ_PORT_CAP_SUBS_READ)
+ {
+ snd_seq_port_subscribe_set_dest(subs, &musePort);
+ snd_seq_port_subscribe_set_sender(subs, &adr);
+ // Not already subscribed (or error)? Then try subscribing.
+ if(snd_seq_get_port_subscription(alsaSeq, subs) < 0)
+ {
+ //int error = snd_seq_subscribe_port(alsaSeq, subs);
+ rer = snd_seq_subscribe_port(alsaSeq, subs);
+ //if (error < 0)
+ if(rer < 0)
+ //return QString("Rec: ") + QString(snd_strerror(error));
+ estr += (QString("Rec: ") + QString(snd_strerror(rer)));
+ }
+ }
+ if(!rer && (cap & SND_SEQ_PORT_CAP_READ))
_readEnable = true;
}
@@ -139,6 +155,16 @@ void MidiAlsaDevice::close()
// Allocated on stack, no need to call snd_seq_port_subscribe_free() later.
snd_seq_port_subscribe_alloca(&subs);
+ int wer = 0;
+ int rer = 0;
+
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ //snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_addr(pinfo, &adr);
+
+ int cap = snd_seq_port_info_get_capability(pinfo);
+
// This function appears to be called only by MidiPort::setMidiDevice(),
// which closes then opens the device.
// Because the open flags are set BEFORE setMidiDevice() is called, we must ignore the flags.
@@ -158,37 +184,49 @@ void MidiAlsaDevice::close()
//if (_openFlags & 1) {
//if (!(_openFlags & 1))
{
- snd_seq_port_subscribe_set_sender(subs, &musePort);
- snd_seq_port_subscribe_set_dest(subs, &adr);
-
- // Already subscribed? Then unsubscribe.
- if(!snd_seq_get_port_subscription(alsaSeq, subs))
- {
- if(!snd_seq_unsubscribe_port(alsaSeq, subs))
- _writeEnable = false;
- else
- printf("MidiAlsaDevice::close Error unsubscribing alsa midi port for writing\n");
+ if(cap & SND_SEQ_PORT_CAP_SUBS_WRITE)
+ {
+ snd_seq_port_subscribe_set_sender(subs, &musePort);
+ snd_seq_port_subscribe_set_dest(subs, &adr);
+
+ // Already subscribed? Then unsubscribe.
+ if(!snd_seq_get_port_subscription(alsaSeq, subs))
+ {
+ wer = snd_seq_unsubscribe_port(alsaSeq, subs);
+ //if(!wer)
+ // _writeEnable = false;
+ //else
+ if(wer < 0)
+ printf("MidiAlsaDevice::close Error unsubscribing alsa midi port %d:%d for writing: %s\n", adr.client, adr.port, snd_strerror(wer));
+ }
+ //else
+ //_writeEnable = false;
}
- else
- _writeEnable = false;
+ _writeEnable = false;
}
//if (_openFlags & 2) {
//if (!(_openFlags & 2))
{
- snd_seq_port_subscribe_set_dest(subs, &musePort);
- snd_seq_port_subscribe_set_sender(subs, &adr);
-
- // Already subscribed? Then unsubscribe.
- if(!snd_seq_get_port_subscription(alsaSeq, subs))
- {
- if(!snd_seq_unsubscribe_port(alsaSeq, subs))
- _readEnable = false;
- else
- printf("MidiAlsaDevice::close Error unsubscribing alsa midi port for reading\n");
- }
- else
- _readEnable = false;
+ if(cap & SND_SEQ_PORT_CAP_SUBS_READ)
+ {
+ snd_seq_port_subscribe_set_dest(subs, &musePort);
+ snd_seq_port_subscribe_set_sender(subs, &adr);
+
+ // Already subscribed? Then unsubscribe.
+ if(!snd_seq_get_port_subscription(alsaSeq, subs))
+ {
+ rer = snd_seq_unsubscribe_port(alsaSeq, subs);
+ //if(!rer)
+ // _readEnable = false;
+ //else
+ if(rer < 0)
+ printf("MidiAlsaDevice::close Error unsubscribing alsa midi port %d:%d for reading: %s\n", adr.client, adr.port, snd_strerror(rer));
+ }
+ //else
+ // _readEnable = false;
+ }
+ _readEnable = false;
}
}
@@ -208,18 +246,18 @@ void MidiAlsaDevice::writeRouting(int level, Xml& xml) const
{
if(!r->name().isEmpty())
{
- s = QT_TRANSLATE_NOOP("@default", "Route");
+ s = "Route";
if(r->channel != -1)
- s += QString(QT_TRANSLATE_NOOP("@default", " channel=\"%1\"")).arg(r->channel);
+ s += QString(" channel=\"%1\"").arg(r->channel);
xml.tag(level++, s.toLatin1().constData());
xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::ALSA_MIDI, Xml::xmlString(name()).toLatin1().constData());
- s = QT_TRANSLATE_NOOP("@default", "dest");
+ s = "dest";
if(r->type == Route::MIDI_DEVICE_ROUTE)
- s += QString(QT_TRANSLATE_NOOP("@default", " devtype=\"%1\"")).arg(r->device->deviceType());
+ s += QString(" devtype=\"%1\"").arg(r->device->deviceType());
else
if(r->type != Route::TRACK_ROUTE)
- s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
- s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
+ s += QString(" type=\"%1\"").arg(r->type);
+ s += QString(" name=\"%1\"/").arg(Xml::xmlString(r->name()));
xml.tag(level, s.toLatin1().constData());
xml.etag(level--, "Route");
@@ -696,6 +734,13 @@ bool initMidiAlsa()
snd_seq_client_info_set_client(cinfo, -1);
while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) {
+ const char* cname = snd_seq_client_info_get_name(cinfo);
+ //printf( "ALSA client name: %s\n", cname);
+
+ // Put Midi Through and user clients after others. Insert other unwanted clients here: // p4.0.41
+ if(snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT || strcmp("Midi Through", cname) == 0)
+ continue;
+
snd_seq_port_info_t *pinfo;
snd_seq_port_info_alloca(&pinfo);
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
@@ -703,6 +748,8 @@ bool initMidiAlsa()
while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
unsigned int capability = snd_seq_port_info_get_capability(pinfo);
+ if (capability & SND_SEQ_PORT_CAP_NO_EXPORT) // Ignore ports like "qjackctl" or "port". p4.0.41
+ continue;
if ((capability & outCap) == 0) {
const char *name = snd_seq_port_info_get_name(pinfo);
if (strcmp("Timer", name) == 0 ||
@@ -724,29 +771,52 @@ bool initMidiAlsa()
adr.client, adr.port,
flags, capability);
MusEGlobal::midiDevices.add(dev);
-
- /*
- // Experimental... Need to list 'sensible' devices first and ignore unwanted ones...
- // Add instance last in midi device list.
- for(int i = 0; i < MIDI_PORTS; ++i)
- {
- MidiPort* mp = &MusEGlobal::midiPorts[i];
- if(mp->device() == 0)
- {
- // midiSeq might not be initialzed yet!
- //MusEGlobal::midiSeq->msgSetMidiDevice(mp, dev);
- mp->setMidiDevice(dev);
-
- //muse->changeConfig(true); // save configuration file
- //update();
- break;
- }
}
- */
-
+ }
+
+ snd_seq_client_info_set_client(cinfo, -1); // Reset
+ while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) {
+ const char* cname = snd_seq_client_info_get_name(cinfo);
+ //printf( "ALSA client name: %s\n", cname);
+
+ // Put Midi Through and user clients after others. Insert other unwanted clients here: // p4.0.41
+ if( !(snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT || strcmp("Midi Through", cname) == 0) )
+ continue;
+
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_port(pinfo, -1);
+
+ while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
+ unsigned int capability = snd_seq_port_info_get_capability(pinfo);
+ if (capability & SND_SEQ_PORT_CAP_NO_EXPORT) // Ignore ports like "qjackctl" or "port". p4.0.41
+ continue;
+ if ((capability & outCap) == 0) {
+ const char *name = snd_seq_port_info_get_name(pinfo);
+ if (strcmp("Timer", name) == 0 ||
+ strcmp("Announce", name) == 0 ||
+ strcmp("Receiver", name) == 0)
+ continue;
+ }
+ snd_seq_addr_t adr = *snd_seq_port_info_get_addr(pinfo);
+ MidiAlsaDevice* dev = new MidiAlsaDevice(adr, QString(snd_seq_port_info_get_name(pinfo)));
+ int flags = 0;
+ if (capability & outCap)
+ flags |= 1;
+ if (capability & inCap)
+ flags |= 2;
+ dev->setrwFlags(flags);
+ if (MusEGlobal::debugMsg)
+ printf("ALSA port add: <%s>, %d:%d flags %d 0x%0x\n",
+ snd_seq_port_info_get_name(pinfo),
+ adr.client, adr.port,
+ flags, capability);
+ MusEGlobal::midiDevices.add(dev);
}
}
-
+
+
//snd_seq_set_client_name(alsaSeq, "MusE Sequencer");
snd_seq_set_client_name(alsaSeq, MusEGlobal::audioDevice->clientName());
@@ -781,14 +851,14 @@ bool initMidiAlsa()
// alsa port changes
//-----------------------------------------
- snd_seq_addr_t aadr;
- aadr.client = SND_SEQ_CLIENT_SYSTEM;
- aadr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
+ //snd_seq_addr_t aadr;
+ announce_adr.client = SND_SEQ_CLIENT_SYSTEM;
+ announce_adr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
snd_seq_port_subscribe_t* subs;
snd_seq_port_subscribe_alloca(&subs);
snd_seq_port_subscribe_set_dest(subs, &musePort);
- snd_seq_port_subscribe_set_sender(subs, &aadr);
+ snd_seq_port_subscribe_set_sender(subs, &announce_adr);
error = snd_seq_subscribe_port(alsaSeq, subs);
if (error < 0) {
printf("Alsa: Subscribe System failed: %s", snd_strerror(error));
@@ -805,12 +875,35 @@ bool initMidiAlsa()
void exitMidiAlsa()
{
if(alsaSeq)
- {
- int error = snd_seq_close(alsaSeq); // FIXME Hm, this did not get rid of a buch of valgrind leaks.
- if(error < 0)
+ {
+ int error = 0;
+ snd_seq_port_subscribe_t* subs;
+ // Allocated on stack, no need to call snd_seq_port_subscribe_free() later.
+ snd_seq_port_subscribe_alloca(&subs);
+
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_info_alloca(&pinfo);
+ //snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
+ snd_seq_port_info_set_addr(pinfo, &announce_adr);
+
+ snd_seq_port_subscribe_set_dest(subs, &musePort);
+ snd_seq_port_subscribe_set_sender(subs, &announce_adr);
+
+ // Already subscribed? Then unsubscribe.
+ if(!snd_seq_get_port_subscription(alsaSeq, subs))
{
- fprintf(stderr, "Could not close ALSA sequencer: %s\n", snd_strerror(error));
- }
+ error = snd_seq_unsubscribe_port(alsaSeq, subs);
+ if(error < 0)
+ printf("MusE: exitMidiAlsa: Error unsubscribing alsa midi Announce port %d:%d for reading: %s\n", announce_adr.client, announce_adr.port, snd_strerror(error));
+ }
+
+ error = snd_seq_delete_simple_port(alsaSeq, musePort.port);
+ if(error < 0)
+ fprintf(stderr, "MusE: Could not delete ALSA simple port: %s\n", snd_strerror(error));
+
+ error = snd_seq_close(alsaSeq);
+ if(error < 0)
+ fprintf(stderr, "MusE: Could not close ALSA sequencer: %s\n", snd_strerror(error));
}
}
@@ -850,7 +943,9 @@ void alsaScanMidiPorts()
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
snd_seq_port_info_set_port(pinfo, -1);
while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
- unsigned int capability = snd_seq_port_info_get_capability(pinfo);
+ unsigned int capability = snd_seq_port_info_get_capability(pinfo);
+ if (capability & SND_SEQ_PORT_CAP_NO_EXPORT) // Ignore ports like "qjackctl" or "port". p4.0.41
+ continue;
if (((capability & outCap) == 0)
&& ((capability & inCap) == 0))
continue;
@@ -900,6 +995,8 @@ void alsaScanMidiPorts()
//
// check for devices to add
//
+ // TODO: Possibly auto-add them to available midi ports. p4.0.41
+ //
for (std::list<AlsaPort>::iterator k = portList.begin(); k != portList.end(); ++k) {
iMidiDevice i = MusEGlobal::midiDevices.begin();
// printf("ALSA port: <%s>\n", k->name);
@@ -920,6 +1017,8 @@ void alsaScanMidiPorts()
// printf("add device\n");
}
}
+
+
}
//---------------------------------------------------------
diff --git a/muse2/muse/driver/jack.cpp b/muse2/muse/driver/jack.cpp
index 733353d8..421152a7 100644
--- a/muse2/muse/driver/jack.cpp
+++ b/muse2/muse/driver/jack.cpp
@@ -735,7 +735,11 @@ void JackAudioDevice::connectJackMidiPorts()
{
RouteList* rl = md->outRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
+ {
+ if(r->type != Route::JACK_ROUTE)
+ continue;
connect(port, r->jackPort);
+ }
}
}
@@ -748,7 +752,11 @@ void JackAudioDevice::connectJackMidiPorts()
{
RouteList* rl = md->inRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
+ {
+ if(r->type != Route::JACK_ROUTE)
+ continue;
connect(r->jackPort, port);
+ }
}
}
}
@@ -939,6 +947,8 @@ void JackAudioDevice::graphChanged()
for (int i = 0;i < 20;i++) {
erased = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -977,6 +987,8 @@ void JackAudioDevice::graphChanged()
while (*pn) {
bool found = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -1027,6 +1039,8 @@ void JackAudioDevice::graphChanged()
for (int i = 0; i < 20 ; i++) {
erased = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -1064,6 +1078,8 @@ void JackAudioDevice::graphChanged()
while (*pn) {
bool found = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -1139,6 +1155,8 @@ void JackAudioDevice::graphChanged()
{
erased = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1181,6 +1199,8 @@ void JackAudioDevice::graphChanged()
while (*pn) {
bool found = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1239,6 +1259,8 @@ void JackAudioDevice::graphChanged()
{
erased = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1280,6 +1302,8 @@ void JackAudioDevice::graphChanged()
while (*pn) {
bool found = false;
for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ if(irl->type != Route::JACK_ROUTE)
+ continue;
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1482,6 +1506,8 @@ void JackAudioDevice::start(int /*priority*/)
RouteList* rl = ai->inRoutes();
void* port = ai->jackPort(ch);
for (ciRoute ir = rl->begin(); ir != rl->end(); ++ir) {
+ if(ir->type != Route::JACK_ROUTE)
+ continue;
if (ir->channel == ch)
connect(ir->jackPort, port);
}
@@ -1495,6 +1521,8 @@ void JackAudioDevice::start(int /*priority*/)
RouteList* rl = ai->outRoutes();
void* port = ai->jackPort(ch);
for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
+ if(r->type != Route::JACK_ROUTE)
+ continue;
if (r->channel == ch) {
connect(port, r->jackPort);
}
@@ -1603,6 +1631,107 @@ int JackAudioDevice::frameDelay() const
#endif
//---------------------------------------------------------
+// getJackPorts
+//---------------------------------------------------------
+
+void JackAudioDevice::getJackPorts(const char** ports, std::list<QString>& name_list, bool midi, bool physical, int aliases)
+ {
+ if (JACK_DEBUG)
+ printf("JackAudioDevice::getJackPorts()\n");
+ //std::list<QString> clientList;
+ //if(!checkJackClient(_client)) return clientList;
+ //if(!checkJackClient(_client)) return;
+ QString qname;
+ //const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
+ //const char** ports = jack_get_ports(_client, 0, type, JackPortIsInput);
+ //const char** ports = jack_get_ports(_client, 0, type, jflags);
+
+ QString cname(jack_get_client_name(_client));
+
+ for (const char** p = ports; p && *p; ++p) {
+ jack_port_t* port = jack_port_by_name(_client, *p);
+ //int flags = jack_port_flags(port);
+ //if (!(flags & JackPortIsInput))
+ // continue;
+ //char buffer[128];
+
+ int port_flags = jack_port_flags(port);
+ //printf("JackAudioDevice::getJackPorts port: %s flags: %d\n", *p, port_flags);
+
+ // Ignore our own client ports.
+ if(jack_port_is_mine(_client, port))
+ {
+ if(MusEGlobal::debugMsg)
+ printf("JackAudioDevice::getJackPorts ignoring own port: %s\n", *p);
+ continue;
+ }
+
+ int nsz = jack_port_name_size();
+ char buffer[nsz];
+
+ bool mthrough = false;
+
+ if(midi)
+ {
+ strncpy(buffer, *p, nsz);
+ char a2[nsz];
+ char* al[2];
+ al[0] = buffer;
+ al[1] = a2;
+ int na = jack_port_get_aliases(port, al);
+ if(na >= 1)
+ {
+ qname = QString(al[0]);
+ //printf("Checking port name for: %s\n", (QString("alsa_pcm:") + cname + QString("/")).toLatin1().constData());
+ // Ignore our own ALSA client!
+ if(qname.startsWith(QString("alsa_pcm:") + cname + QString("/")))
+ continue;
+ // Put Midi Through after all others.
+ mthrough = qname.startsWith(QString("alsa_pcm:Midi-Through/"));
+ //if((physical && mthrough) || (!physical && !mthrough))
+ //if(physical && mthrough)
+ // continue;
+ }
+ }
+ // Put physical/terminal ports before others.
+ bool is_phys = (port_flags & (JackPortIsTerminal | JackPortIsPhysical)) && !mthrough;
+ if((physical && !is_phys) || (!physical && is_phys))
+ continue;
+
+
+ strncpy(buffer, *p, nsz);
+ if((aliases == 0) || (aliases == 1))
+ {
+ char a2[nsz];
+ char* al[2];
+ al[0] = buffer;
+ al[1] = a2;
+ int na = jack_port_get_aliases(port, al);
+ int a = aliases;
+ if(a >= na)
+ {
+ a = na;
+ if(a > 0)
+ a--;
+ }
+ qname = QString(al[a]);
+ }
+ else
+ qname = QString(buffer);
+
+ //clientList.push_back(QString(buffer));
+ name_list.push_back(qname);
+ }
+
+ // p3.3.37
+ //if(ports)
+ //free(ports);
+ // jack_free(ports); // p4.0.29
+
+ //return clientList;
+ }
+
+//---------------------------------------------------------
// outputPorts
//---------------------------------------------------------
@@ -1612,9 +1741,11 @@ std::list<QString> JackAudioDevice::outputPorts(bool midi, int aliases)
printf("JackAudioDevice::outputPorts()\n");
std::list<QString> clientList;
if(!checkJackClient(_client)) return clientList;
- QString qname;
const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
const char** ports = jack_get_ports(_client, 0, type, JackPortIsOutput);
+
+ /*
+ QString qname;
for (const char** p = ports; p && *p; ++p) {
jack_port_t* port = jack_port_by_name(_client, *p);
//int flags = jack_port_flags(port);
@@ -1666,12 +1797,15 @@ std::list<QString> JackAudioDevice::outputPorts(bool midi, int aliases)
//clientList.push_back(QString(buffer));
clientList.push_back(qname);
}
-
- // p3.3.37
- if(ports)
- //free(ports);
- jack_free(ports); // p4.0.29
+ */
+ if(ports)
+ {
+ getJackPorts(ports, clientList, midi, true, aliases); // Get physical ports first.
+ getJackPorts(ports, clientList, midi, false, aliases); // Get non-physical ports last.
+ jack_free(ports);
+ }
+
return clientList;
}
@@ -1683,11 +1817,14 @@ std::list<QString> JackAudioDevice::inputPorts(bool midi, int aliases)
{
if (JACK_DEBUG)
printf("JackAudioDevice::inputPorts()\n");
+
std::list<QString> clientList;
if(!checkJackClient(_client)) return clientList;
- QString qname;
const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
const char** ports = jack_get_ports(_client, 0, type, JackPortIsInput);
+
+ /*
+ QString qname;
for (const char** p = ports; p && *p; ++p) {
jack_port_t* port = jack_port_by_name(_client, *p);
//int flags = jack_port_flags(port);
@@ -1739,12 +1876,15 @@ std::list<QString> JackAudioDevice::inputPorts(bool midi, int aliases)
//clientList.push_back(QString(buffer));
clientList.push_back(qname);
}
-
- // p3.3.37
- if(ports)
- //free(ports);
- jack_free(ports); // p4.0.29
+ */
+ if(ports)
+ {
+ getJackPorts(ports, clientList, midi, true, aliases); // Get physical ports first.
+ getJackPorts(ports, clientList, midi, false, aliases); // Get non-physical ports last.
+ jack_free(ports);
+ }
+
return clientList;
}
diff --git a/muse2/muse/driver/jackaudio.h b/muse2/muse/driver/jackaudio.h
index bd78d481..c4d37db9 100644
--- a/muse2/muse/driver/jackaudio.h
+++ b/muse2/muse/driver/jackaudio.h
@@ -50,6 +50,7 @@ class JackAudioDevice : public AudioDevice {
// Free-running frame counter incremented always in process.
jack_nframes_t _frameCounter;
+ void getJackPorts(const char** ports, std::list<QString>& name_list, bool midi, bool physical, int aliases);
static int processAudio(jack_nframes_t frames, void*);
public:
diff --git a/muse2/muse/driver/jackmidi.cpp b/muse2/muse/driver/jackmidi.cpp
index fa23d336..7a12b92d 100644
--- a/muse2/muse/driver/jackmidi.cpp
+++ b/muse2/muse/driver/jackmidi.cpp
@@ -276,10 +276,10 @@ void MidiJackDevice::writeRouting(int level, Xml& xml) const
if(!r->name().isEmpty())
{
xml.tag(level++, "Route");
- s = QT_TRANSLATE_NOOP("@default", "source");
+ s = "source";
if(r->type != Route::TRACK_ROUTE)
- s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
- s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
+ s += QString(" type=\"%1\"").arg(r->type);
+ s += QString(" name=\"%1\"/").arg(Xml::xmlString(r->name()));
xml.tag(level, s.toLatin1().constData());
xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, Xml::xmlString(name()).toLatin1().constData());
xml.etag(level--, "Route");
@@ -291,18 +291,18 @@ void MidiJackDevice::writeRouting(int level, Xml& xml) const
{
if(!r->name().isEmpty())
{
- s = QT_TRANSLATE_NOOP("@default", "Route");
+ s = "Route";
if(r->channel != -1)
- s += QString(QT_TRANSLATE_NOOP("@default", " channel=\"%1\"")).arg(r->channel);
+ s += QString(" channel=\"%1\"").arg(r->channel);
xml.tag(level++, s.toLatin1().constData());
xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, Xml::xmlString(name()).toLatin1().constData());
- s = QT_TRANSLATE_NOOP("@default", "dest");
+ s = "dest";
if(r->type == Route::MIDI_DEVICE_ROUTE)
- s += QString(QT_TRANSLATE_NOOP("@default", " devtype=\"%1\"")).arg(r->device->deviceType());
+ s += QString(" devtype=\"%1\"").arg(r->device->deviceType());
else
if(r->type != Route::TRACK_ROUTE)
- s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
- s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
+ s += QString(" type=\"%1\"").arg(r->type);
+ s += QString(" name=\"%1\"/").arg(Xml::xmlString(r->name()));
xml.tag(level, s.toLatin1().constData());
diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp
index 92120dbb..2e4e6d35 100644
--- a/muse2/muse/dssihost.cpp
+++ b/muse2/muse/dssihost.cpp
@@ -99,6 +99,7 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument
// That way we cover all bases - effect plugins and synths.
// Non-synths will show up in the ladspa effect dialog, while synths will show up here...
// There should be nothing left out...
+ // TIP: Until we add programs to plugins, comment these four checks to load dssi effects as synths, in order to have programs.
if(descr->run_synth ||
descr->run_synth_adding ||
descr->run_multiple_synths ||
@@ -498,6 +499,9 @@ bool DssiSynthIF::init(DssiSynth* s)
int inports = synth->_inports;
if(inports != 0)
{
+ posix_memalign((void**)&audioInSilenceBuf, 16, sizeof(float) * MusEGlobal::segmentSize);
+ memset(audioInSilenceBuf, 0, sizeof(float) * MusEGlobal::segmentSize);
+
audioInBuffers = new float*[inports];
for(int k = 0; k < inports; ++k)
{
@@ -723,6 +727,7 @@ DssiSynthIF::DssiSynthIF(SynthI* s)
controls = 0;
controlsOut = 0;
audioInBuffers = 0;
+ audioInSilenceBuf = 0;
audioOutBuffers = 0;
}
@@ -785,6 +790,9 @@ DssiSynthIF::~DssiSynthIF()
delete[] audioInBuffers;
}
+ if(audioInSilenceBuf)
+ free(audioInSilenceBuf);
+
if(audioOutBuffers)
{
for(unsigned long i = 0; i < synth->_outports; ++i)
@@ -1420,7 +1428,7 @@ bool DssiSynthIF::processEvent(const MusECore::MidiPlayEvent& e, snd_seq_event_t
// getData
//---------------------------------------------------------
-MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MPEventList* el, MusECore::iMPEvent i, unsigned pos, int ports, unsigned n, float** buffer)
+MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MPEventList* el, MusECore::iMPEvent start_event, unsigned pos, int ports, unsigned nframes, float** buffer)
{
//#ifdef DSSI_DEBUG
// fprintf(stderr, "DssiSynthIF::getData elsize:%d pos:%d ports:%d samples:%d processed already?:%d\n", el->size(), pos, ports, n, synti->processed());
@@ -1440,19 +1448,11 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
// All ports must be connected to something!
unsigned long nop, k;
- // First, copy the given input buffers to our local input buffers.
- //np = portsin > synth->_inports ? synth->_inports : portsin;
- //for(k = 0; k < np; ++k)
- // memcpy(audioInBuffers[k], inbuffer[k], sizeof(float) * n);
- //for(; k < portsin; ++k)
- // memset(audioInBuffers[k], 0, sizeof(float) * n);
// Watch our limits.
//willyfoobar-2011-02-13
//old code//np = ports > synth->_outports ? synth->_outports : ports;
nop = ((unsigned long) ports) > synth->_outports ? synth->_outports : ((unsigned long) ports);
- // TODO Number of inports requested?
- //nip = ((unsigned long) iports) > synth->_inports ? synth->_inports : ((unsigned long) iports);
const DSSI_Descriptor* dssi = synth->dssi;
const LADSPA_Descriptor* descr = dssi->LADSPA_Plugin;
@@ -1484,18 +1484,109 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
// Note for dssi-vst this MUST equal MusEGlobal::audio period. It doesn't like broken-up runs (it stutters),
// even with fixed sizes. Could be a Wine + Jack thing, wanting a full Jack buffer's length.
//unsigned long fixedsize = 2048;
- unsigned long fixedsize = n;
+ unsigned long fixedsize = nframes;
// For now, the fixed size is clamped to the MusEGlobal::audio buffer size.
// TODO: We could later add slower processing over several cycles -
// so that users can select a small MusEGlobal::audio period but a larger control period.
- if(fixedsize > n)
- fixedsize = n;
+ if(fixedsize > nframes)
+ fixedsize = nframes;
unsigned long min_per = MusEGlobal::config.minControlProcessPeriod;
- if(min_per > n)
- min_per = n;
+ if(min_per > nframes)
+ min_per = nframes;
+
+ //
+ // p4.0.38 Handle inputs...
+ //
+ if(!((MusECore::AudioTrack*)synti)->noInRoute())
+ {
+ RouteList* irl = ((MusECore::AudioTrack*)synti)->inRoutes();
+ iRoute i = irl->begin();
+ if(i->track->isMidiTrack())
+ {
+ //if(MusEGlobal::debugMsg)
+ //printf("DssiSynthIF::getData: Error: First route is a midi track route!\n");
+ }
+ else
+ {
+ int ch = i->channel == -1 ? 0 : i->channel;
+ int remch = i->remoteChannel == -1 ? 0 : i->remoteChannel;
+ int chs = i->channels == -1 ? 0 : i->channels;
+
+ if((unsigned)ch < synth->_inports && (unsigned)(ch + chs) <= synth->_inports)
+ {
+ //printf("DssiSynthIF::getData calling copyData on %s ch:%d remch:%d chs:%d\n", i->track->name().toLatin1().constData(), ch, remch, chs);
+
+ int h = remch + chs;
+ for(int j = remch; j < h; ++j)
+ {
+ //printf(" setting used idx:%d\n", j);
+ synth->iUsedIdx[j] = true;
+ }
+
+ ((MusECore::AudioTrack*)i->track)->copyData(pos, chs, ch, -1, nframes, &audioInBuffers[remch]);
+ }
+ }
+
+ ++i;
+ for(; i != irl->end(); ++i)
+ {
+ if(i->track->isMidiTrack())
+ {
+ //if(MusEGlobal::debugMsg)
+ // printf("DssiSynthIF::getData: Error: Route is a midi track route!\n");
+ continue;
+ }
+
+ int ch = i->channel == -1 ? 0 : i->channel;
+ int remch = i->remoteChannel == -1 ? 0 : i->remoteChannel;
+ int chs = i->channels == -1 ? 0 : i->channels;
+ if((unsigned)ch < synth->_inports && (unsigned)(ch + chs) <= synth->_inports)
+ {
+ //printf("DssiSynthIF::getData calling addData on %s ch:%d remch:%d chs:%d\n", i->track->name().toLatin1().constData(), ch, remch, chs);
+
+ bool u1 = synth->iUsedIdx[remch];
+ if(chs >= 2)
+ {
+ bool u2 = synth->iUsedIdx[remch + 1];
+ if(u1 && u2)
+ ((MusECore::AudioTrack*)i->track)->addData(pos, chs, ch, -1, nframes, &audioInBuffers[remch]);
+ else
+ if(!u1 && !u2)
+ ((MusECore::AudioTrack*)i->track)->copyData(pos, chs, ch, -1, nframes, &audioInBuffers[remch]);
+ else
+ {
+ if(u1)
+ ((MusECore::AudioTrack*)i->track)->addData(pos, 1, ch, 1, nframes, &audioInBuffers[remch]);
+ else
+ ((MusECore::AudioTrack*)i->track)->copyData(pos, 1, ch, 1, nframes, &audioInBuffers[remch]);
+
+ if(u2)
+ ((MusECore::AudioTrack*)i->track)->addData(pos, 1, ch + 1, 1, nframes, &audioInBuffers[remch + 1]);
+ else
+ ((MusECore::AudioTrack*)i->track)->copyData(pos, 1, ch + 1, 1, nframes, &audioInBuffers[remch + 1]);
+ }
+ }
+ else
+ {
+ if(u1)
+ ((MusECore::AudioTrack*)i->track)->addData(pos, 1, ch, -1, nframes, &audioInBuffers[remch]);
+ else
+ ((MusECore::AudioTrack*)i->track)->copyData(pos, 1, ch, -1, nframes, &audioInBuffers[remch]);
+ }
+
+ int h = remch + chs;
+ for(int j = remch; j < h; ++j)
+ {
+ //printf(" setting used idx:%d\n", j);
+ synth->iUsedIdx[j] = true;
+ }
+ }
+ }
+ }
+
// Process automation control values now.
// TODO: This needs to be respect frame resolution. Put this inside the sample loop below.
if(MusEGlobal::automation && synti && synti->automationType() != AUTO_OFF && id() != -1)
@@ -1507,11 +1598,11 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
}
}
- while(sample < n)
+ while(sample < nframes)
{
//unsigned long nsamp = n;
//unsigned long nsamp = n - sample;
- unsigned long nsamp = usefixedrate ? fixedsize : n - sample;
+ unsigned long nsamp = usefixedrate ? fixedsize : nframes - sample;
bool found = false;
unsigned long frame = 0;
unsigned long index = 0;
@@ -1525,7 +1616,7 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
// The events happened in the last period or even before that. Shift into this period with + n. This will sync with MusEGlobal::audio.
// If the events happened even before current frame - n, make sure they are counted immediately as zero-frame.
//evframe = (pos + frameOffset > v.frame + n) ? 0 : v.frame - pos - frameOffset + n;
- evframe = (syncFrame > v.frame + n) ? 0 : v.frame - syncFrame + n;
+ evframe = (syncFrame > v.frame + nframes) ? 0 : v.frame - syncFrame + nframes;
// Protection. Observed this condition. Why? Supposed to be linear timestamps.
if(found && evframe < frame)
{
@@ -1545,7 +1636,7 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
//if(v.frame < startPos || v.frame >= (endPos + frameOffset)
//if(evframe < sample || evframe >= n
//if(evframe < sample || evframe >= (n + frameOffset)
- if(evframe >= n
+ if(evframe >= nframes
//|| (found && v.frame != frame)
//|| (!usefixedrate && found && !v.unique && v.frame != frame)
//|| (found && !v.unique && evframe != frame)
@@ -1567,6 +1658,31 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
index = v.idx;
// Set the ladspa control port value.
controls[v.idx].val = v.value;
+
+ // Need to update the automation value, otherwise it overwrites later with the last MusEGlobal::automation value.
+ if(id() != -1)
+ {
+ // Since we are now in the audio thread context, there's no need to send a message,
+ // just modify directly.
+ //MusEGlobal::audio->msgSetPluginCtrlVal(_track, genACnum(_id, k), controls[k].val);
+ synti->setPluginCtrlVal(genACnum(id(), v.idx), v.value);
+
+ // Record automation.
+ // NO! Take care of this immediately in the OSC control handler, because we don't want
+ // any delay.
+ // OTOH Since this is the actual place and time where the control ports values
+ // are set, best to reflect what happens here to automation.
+ // However for dssi-vst it might be best to handle it that way.
+
+ //AutomationType at = _track->automationType();
+ // TODO: Taken from our native gui control handlers.
+ // This may need modification or may cause problems -
+ // we don't have the luxury of access to the dssi gui controls !
+ //if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH))
+ // enableController(k, false);
+ //_track->recordAutomation(id, v.value);
+ }
+
}
// Process automation control values now.
@@ -1583,8 +1699,8 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
if(found && !usefixedrate)
//nsamp = frame - sample + 1;
nsamp = frame - sample;
- if(sample + nsamp >= n) // Safety check.
- nsamp = n - sample;
+ if(sample + nsamp >= nframes) // Safety check.
+ nsamp = nframes - sample;
//printf("DssiSynthIF::getData n:%d frame:%lu sample:%lu nsamp:%lu pos:%d fOffset:%d syncFrame:%lu loopcount:%d\n",
// n, frame, sample, nsamp, pos, frameOffset, syncFrame, loopcount); // REMOVE Tim.
@@ -1596,10 +1712,10 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
nevents = 0;
// Process event list events...
- for(; i != el->end(); ++i)
+ for(; start_event != el->end(); ++start_event)
{
//if(i->time() >= (endPos + frameOffset)) // NOTE: frameOffset? Tested, examined printouts of times: Seems OK for playback.
- if(i->time() >= (pos + sample + nsamp + frameOffset)) // frameOffset? Test again...
+ if(start_event->time() >= (pos + sample + nsamp + frameOffset)) // frameOffset? Test again...
break;
#ifdef DSSI_DEBUG
@@ -1611,40 +1727,40 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
if(synti->midiPort() != -1)
{
MusECore::MidiPort* mp = &MusEGlobal::midiPorts[synti->midiPort()];
- if(i->type() == MusECore::ME_CONTROLLER)
+ if(start_event->type() == MusECore::ME_CONTROLLER)
{
- int da = i->dataA();
- int db = i->dataB();
+ int da = start_event->dataA();
+ int db = start_event->dataB();
db = mp->limitValToInstrCtlRange(da, db);
- if(!mp->setHwCtrlState(i->channel(), da, db))
+ if(!mp->setHwCtrlState(start_event->channel(), da, db))
continue;
}
else
- if(i->type() == MusECore::ME_PITCHBEND)
+ if(start_event->type() == MusECore::ME_PITCHBEND)
{
- int da = mp->limitValToInstrCtlRange(MusECore::CTRL_PITCH, i->dataA());
- if(!mp->setHwCtrlState(i->channel(), MusECore::CTRL_PITCH, da))
+ int da = mp->limitValToInstrCtlRange(MusECore::CTRL_PITCH, start_event->dataA());
+ if(!mp->setHwCtrlState(start_event->channel(), MusECore::CTRL_PITCH, da))
continue;
}
else
- if(i->type() == MusECore::ME_PROGRAM)
+ if(start_event->type() == MusECore::ME_PROGRAM)
{
- if(!mp->setHwCtrlState(i->channel(), MusECore::CTRL_PROGRAM, i->dataA()))
+ if(!mp->setHwCtrlState(start_event->channel(), MusECore::CTRL_PROGRAM, start_event->dataA()))
continue;
}
}
// Returns false if the event was not filled. It was handled, but some other way.
- if(processEvent(*i, &events[nevents]))
+ if(processEvent(*start_event, &events[nevents]))
{
// Time-stamp the event. p4.0.15 Tim.
- int ft = i->time() - frameOffset - pos;
+ int ft = start_event->time() - frameOffset - pos;
if(ft < 0)
ft = 0;
//if (ft >= (int)MusEGlobal::segmentSize)
if (ft >= int(sample + nsamp))
{
- printf("DssiSynthIF::getData: eventlist event time:%d out of range. pos:%d offset:%d ft:%d sample:%lu nsamp:%lu\n", i->time(), pos, frameOffset, ft, sample, nsamp);
+ printf("DssiSynthIF::getData: eventlist event time:%d out of range. pos:%d offset:%d ft:%d sample:%lu nsamp:%lu\n", start_event->time(), pos, frameOffset, ft, sample, nsamp);
///if (ft > (int)MusEGlobal::segmentSize)
//ft = MusEGlobal::segmentSize - 1;
ft = sample + nsamp - 1;
@@ -1696,61 +1812,6 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
}
}
- /*
- //
- // p3.3.39 Handle inputs...
- //
- //if((MusEGlobal::song->bounceTrack != this) && !noInRoute())
- if(!((MusECore::AudioTrack*)synti)->noInRoute())
- {
- RouteList* irl = ((MusECore::AudioTrack*)synti)->inRoutes();
- iRoute i = irl->begin();
- if(!i->track->isMidiTrack())
- {
- //if(MusEGlobal::debugMsg)
- printf("DssiSynthIF::getData: Error: First route is a midi track route!\n");
- }
- else
- {
- int ch = i->channel == -1 ? 0 : i->channel;
- int remch = i->remoteChannel == -1 ? 0 : i->remoteChannel;
- int chs = i->channels == -1 ? 0 : i->channels;
-
- // TODO:
- //if(ch >= synth->_inports)
- //iUsedIdx[ch] = true;
- //if(chs == 2)
- // iUsedIdx[ch + 1] = true;
-
- //((MusECore::AudioTrack*)i->track)->copyData(framePos, channels, nframe, bp);
- ((MusECore::AudioTrack*)i->track)->copyData(pos, ports,
- //(i->track->type() == Track::AUDIO_SOFTSYNTH && i->channel != -1) ? i->channel : 0,
- i->channel,
- i->channels,
- n, bp);
- }
-
- //unsigned pos, int ports, unsigned n, float** buffer
-
- ++i;
- for(; i != irl->end(); ++i)
- {
- if(i->track->isMidiTrack())
- {
- //if(MusEGlobal::debugMsg)
- printf("DssiSynthIF::getData: Error: Route is a midi track route!\n");
- continue;
- }
- //((MusECore::AudioTrack*)i->track)->addData(framePos, channels, nframe, bp);
- ((MusECore::AudioTrack*)i->track)->addData(framePos, channels,
- //(i->track->type() == Track::AUDIO_SOFTSYNTH && i->channel != -1) ? i->channel : 0,
- i->channel,
- i->channels,
- nframe, bp);
- }
- }
- */
-
k = 0;
// Connect the given buffers directly to the ports, up to a max of synth ports.
for(; k < nop; ++k)
@@ -1758,9 +1819,21 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
// Connect the remaining ports to some local buffers (not used yet).
for(; k < synth->_outports; ++k)
descr->connect_port(handle, synth->oIdx[k], audioOutBuffers[k] + sample);
- // Just connect all inputs to some local buffers (not used yet). TODO: Support inputs.
+ // Connect all inputs either to some local buffers, or a silence buffer.
for(k = 0; k < synth->_inports; ++k)
- descr->connect_port(handle, synth->iIdx[k], audioInBuffers[k] + sample);
+ {
+ //printf(" k:%d synth->iIdx[k]:%d\n", k, synth->iIdx[k]);
+ if(synth->iUsedIdx[k])
+ {
+ synth->iUsedIdx[k] = false; // Reset
+ descr->connect_port(handle, synth->iIdx[k], audioInBuffers[k] + sample);
+ }
+ else
+ {
+ //printf(" input used size:%ld idx:%ld = %d silencing...\n", synth->iUsedIdx.size(), k, synth->iUsedIdx[k]);
+ descr->connect_port(handle, synth->iIdx[k], audioInSilenceBuf + sample);
+ }
+ }
// Run the synth for a period of time. This processes events and gets/fills our local buffers...
if(synth->dssi->run_synth)
@@ -1772,10 +1845,10 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
snd_seq_event_t* ev = events;
synth->dssi->run_multiple_synths(1, &handle, nsamp, &ev, &nevents);
}
+ // TIP: Until we add programs to plugins, uncomment these four checks to load dssi effects as synths, in order to have programs.
//else
//if(synth->dssi->LADSPA_Plugin->run)
//{
- // // Just a test, worked OK.
// synth->dssi->LADSPA_Plugin->run(handle, nsamp);
//}
@@ -1783,14 +1856,13 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
loopcount++; // REMOVE Tim.
}
- return i;
+ return start_event;
}
//---------------------------------------------------------
// putEvent
//---------------------------------------------------------
-//bool DssiSynthIF::putEvent(const MidiEvent& ev)
bool DssiSynthIF::putEvent(const MusECore::MidiPlayEvent& ev)
{
#ifdef DSSI_DEBUG
@@ -2033,16 +2105,37 @@ int DssiSynthIF::oscControl(unsigned long port, float value)
fprintf(stderr, "DssiSynthIF::oscControl: fifo overflow: in control number:%lu\n", cport);
}
- MusECore::ciMidiCtl2LadspaPort ip = synth->port2MidiCtlMap.find(cport);
- if(ip != synth->port2MidiCtlMap.end())
+ // Record automation:
+ // Take care of this immediately, because we don't want the silly delay associated with
+ // processing the fifo one-at-a-time in the apply().
+ // NOTE: With some vsts we don't receive control events until the user RELEASES a control.
+ // So the events all arrive at once when the user releases a control.
+ // That makes this pretty useless... But what the heck...
+ if(id() != -1)
{
+ //int id = genACnum(_id, cport);
+ unsigned long pid = genACnum(id(), cport);
+ AutomationType at = synti->automationType();
+
+ // TODO: Taken from our native gui control handlers.
+ // This may need modification or may cause problems -
+ // we don't have the luxury of access to the dssi gui controls !
+ if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH))
+ enableController(cport, false);
+
+ synti->recordAutomation(pid, value);
+ }
+
+ //MusECore::ciMidiCtl2LadspaPort ip = synth->port2MidiCtlMap.find(cport);
+ //if(ip != synth->port2MidiCtlMap.end())
+ //{
// TODO: TODO: Update midi MusE's midi controller knobs, sliders, boxes etc with a call to the midi port's setHwCtrlState() etc.
// But first we need a ladspa2MidiValue() function! ...
//
//
//float val = ladspa2MidiValue(ld, i, ?, ?);
- }
+ //}
return 0;
}
@@ -2064,8 +2157,8 @@ int DssiSynthIF::oscMidi(int a, int b, int c)
{
MusECore::MidiPlayEvent event(0, port, channel, a, b, c);
- #ifdef DSSI_DEBUG
- printf(stderr, "DssiSynthIF::oscMidi midi event chn:%d a:%d b:%d\n", event.channel(), event.dataA(), event.dataB());
+ #ifdef DSSI_DEBUG
+ printf("DssiSynthIF::oscMidi midi event chn:%d a:%d b:%d\n", event.channel(), event.dataA(), event.dataB());
#endif
MusEGlobal::midiPorts[port].sendEvent(event);
@@ -2329,7 +2422,8 @@ QString DssiSynthIF::name() const { return synti->nam
QString DssiSynthIF::lib() const { return synth ? synth->completeBaseName() : QString(); }
QString DssiSynthIF::dirPath() const { return synth ? synth->absolutePath() : QString(); }
QString DssiSynthIF::fileName() const { return synth ? synth->fileName() : QString(); }
-MusECore::AudioTrack* DssiSynthIF::track() { return (MusECore::AudioTrack*)synti; }
+QString DssiSynthIF::titlePrefix() const { return QString(); }
+MusECore::AudioTrack* DssiSynthIF::track() { return (MusECore::AudioTrack*)synti; }
void DssiSynthIF::enableController(unsigned long i, bool v) { controls[i].enCtrl = v; }
bool DssiSynthIF::controllerEnabled(unsigned long i) const { return controls[i].enCtrl; }
bool DssiSynthIF::controllerEnabled2(unsigned long i) const { return controls[i].en2Ctrl; }
diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h
index 9b00b642..2836d72e 100644
--- a/muse2/muse/dssihost.h
+++ b/muse2/muse/dssihost.h
@@ -76,7 +76,8 @@ class DssiSynth : public Synth {
unsigned long _portCount, _inports, _outports, _controlInPorts, _controlOutPorts;
std::vector<unsigned long> iIdx; // Audio input index to port number.
std::vector<unsigned long> oIdx; // Audio output index to port number.
- std::vector<bool> iUsedIdx; // During process, tells whether an audio input port was used by any input routes.
+ //std::vector<bool> iUsedIdx; // During process, tells whether an audio input port was used by any input routes.
+ std::vector<int> iUsedIdx; // During process, tells whether an audio input port was used by any input routes.
std::vector<unsigned long> rpIdx; // Port number to control input index. Item is -1 if it's not a control input.
MusECore::MidiCtl2LadspaPortMap midiCtl2PortMap; // Maps midi controller numbers to DSSI port numbers.
MusECore::MidiCtl2LadspaPortMap port2MidiCtlMap; // Maps DSSI port numbers to midi controller numbers.
@@ -88,6 +89,8 @@ class DssiSynth : public Synth {
public:
DssiSynth(QFileInfo&, const DSSI_Descriptor*); // removed const for QFileInfo
virtual ~DssiSynth();
+ virtual Type synthType() const { return DSSI_SYNTH; }
+
virtual void incInstances(int);
virtual SynthIF* createSIF(SynthI*);
@@ -122,6 +125,7 @@ class DssiSynthIF : public SynthIF, public PluginIBase
float** audioInBuffers;
float** audioOutBuffers;
+ float* audioInSilenceBuf; // Just all zeros all the time, so we don't have to clear for silence.
public:
DssiSynthIF(SynthI* s);
@@ -195,6 +199,7 @@ class DssiSynthIF : public SynthIF, public PluginIBase
QString lib() const;
QString dirPath() const;
QString fileName() const;
+ QString titlePrefix() const;
MusECore::AudioTrack* track();
void enableController(unsigned long /*i*/, bool v = true);
bool controllerEnabled(unsigned long /*i*/) const;
diff --git a/muse2/muse/exportmidi.cpp b/muse2/muse/exportmidi.cpp
index b892e808..4a9c1f6d 100644
--- a/muse2/muse/exportmidi.cpp
+++ b/muse2/muse/exportmidi.cpp
@@ -149,15 +149,28 @@ void MusE::exportMidi()
return;
MusECore::MidiFile mf(fp);
- MusECore::MidiTrackList* tl = MusEGlobal::song->midis();
- int ntracks = tl->size();
+ //MusECore::MidiTrackList* tl = MusEGlobal::song->midis();
+ MusECore::TrackList* tl = MusEGlobal::song->tracks(); // Changed to full track list so user can rearrange tracks.
+ //int ntracks = tl->size();
MusECore::MidiFileTrackList* mtl = new MusECore::MidiFileTrackList;
int i = 0;
- for (MusECore::iMidiTrack im = tl->begin(); im != tl->end(); ++im, ++i) {
- MusECore::MidiTrack* track = *im;
- MusECore::MidiFileTrack* mft = new MusECore::MidiFileTrack;
- mtl->push_back(mft);
+ MusECore::MidiFileTrack* mft = 0;
+ //for (MusECore::iMidiTrack im = tl->begin(); im != tl->end(); ++im, ++i) {
+ for (MusECore::ciTrack im = tl->begin(); im != tl->end(); ++im) {
+
+ if(!(*im)->isMidiTrack())
+ continue;
+
+ MusECore::MidiTrack* track = (MusECore::MidiTrack*)(*im);
+
+ //MusECore::MidiFileTrack* mft = new MusECore::MidiFileTrack;
+ if (i == 0 || (i != 0 && MusEGlobal::config.smfFormat != 0)) // Changed to single track. Tim
+ {
+ mft = new MusECore::MidiFileTrack;
+ mtl->push_back(mft);
+ }
+
MusECore::MPEventList* l = &(mft->events);
int port = track->outPort();
int channel = track->outChannel();
@@ -200,14 +213,17 @@ void MusE::exportMidi()
//---------------------------------------------------
// Write Coment
//
- QString comment = track->comment();
- if (!comment.isEmpty()) {
- int len = comment.length();
- MusECore::MidiPlayEvent ev(0, port, MusECore::ME_META, (const unsigned char*)(comment.toLatin1().constData()), len);
- ev.setA(0x1);
- l->add(ev);
- }
-
+ //if (MusEGlobal::config.smfFormat == 0) // Only for smf 0 added by Tim. FIXME: Is this correct? See below.
+ {
+ QString comment = track->comment();
+ if (!comment.isEmpty()) {
+ int len = comment.length();
+ MusECore::MidiPlayEvent ev(0, port, MusECore::ME_META, (const unsigned char*)(comment.toLatin1().constData()), len);
+ ev.setA(0x1);
+ l->add(ev);
+ }
+ }
+
//---------------------------------------------------
// Write Songtype SYSEX: GM/GS/XG
//
@@ -287,27 +303,38 @@ void MusE::exportMidi()
// track name
//-----------------------------------
- if (!track->name().isEmpty()) {
- QByteArray ba = track->name().toLatin1();
- const char* name = ba.constData();
- int len = strlen(name);
- MusECore::MidiPlayEvent ev(0, port, MusECore::ME_META, (unsigned char*)name, len+1);
- ev.setA(0x3); // Meta Sequence/Track Name
- l->add(ev);
- }
-
+ if (i == 0 || (i != 0 && MusEGlobal::config.smfFormat != 0))
+ {
+ if (!track->name().isEmpty()) {
+ QByteArray ba = track->name().toLatin1();
+ const char* name = ba.constData();
+ int len = strlen(name);
+ MusECore::MidiPlayEvent ev(0, port, MusECore::ME_META, (unsigned char*)name, len+1);
+ ev.setA(0x3); // Meta Sequence/Track Name
+ l->add(ev);
+ }
+ }
+
//-----------------------------------
// track comment
//-----------------------------------
- if (!track->comment().isEmpty()) {
- QByteArray ba = track->comment().toLatin1();
- const char* comment = ba.constData();
- int len = strlen(comment);
- MusECore::MidiPlayEvent ev(0, port, MusECore::ME_META, (unsigned char*)comment, len+1);
- ev.setA(0xf); // Meta Text
- l->add(ev);
- }
+ // FIXME: What are these 0x0F? All I found was that they are unspecified part of the sixteen text meta events.
+ // So why not use 0x01? And do we include it for all tracks, or only above 1? Tim.
+ //if (i == 0 || (i != 0 && MusEGlobal::config.smfFormat != 0))
+ //if (i != 0 && MusEGlobal::config.smfFormat != 0)
+ if (MusEGlobal::config.smfFormat != 0)
+ {
+ if (!track->comment().isEmpty()) {
+ QByteArray ba = track->comment().toLatin1();
+ const char* comment = ba.constData();
+ int len = strlen(comment);
+ MusECore::MidiPlayEvent ev(0, port, MusECore::ME_META, (unsigned char*)comment, len+1);
+ ev.setA(0xf); // Meta Text
+ l->add(ev);
+ }
+ }
+
MusECore::PartList* parts = track->parts();
for (MusECore::iPart p = parts->begin(); p != parts->end(); ++p) {
MusECore::MidiPart* part = (MusECore::MidiPart*) (p->second);
@@ -315,7 +342,6 @@ void MusE::exportMidi()
for (MusECore::iEvent i = evlist->begin(); i != evlist->end(); ++i) {
MusECore::Event ev = i->second;
int tick = ev.tick() + part->tick();
-
switch (ev.type()) {
case MusECore::Note:
{
@@ -400,11 +426,19 @@ void MusE::exportMidi()
}
}
}
+ ++i;
+
}
mf.setDivision(MusEGlobal::config.midiDivision);
mf.setMType(MusEGlobal::song->mtype());
- mf.setTrackList(mtl, ntracks);
+ //mf.setTrackList(mtl, ntracks);
+ mf.setTrackList(mtl, i);
mf.write();
+
+ // TESTING: Cleanup. I did not valgrind this feature in last memleak fixes, but I suspect it leaked.
+ //for(MusECore::iMidiFileTrack imft = mtl->begin(); imft != mtl->end(); ++imft)
+ // delete *imft;
+ //delete mtl;
}
} // namespace MusEGui
diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp
index e0f9690c..77825f52 100644
--- a/muse2/muse/functions.cpp
+++ b/muse2/muse/functions.cpp
@@ -55,7 +55,7 @@
#include <QDrag>
#include <QMessageBox>
#include <QClipboard>
-
+#include <QSet>
using namespace std;
@@ -177,8 +177,9 @@ bool quantize_notes(const set<Part*>& parts)
{
if (!MusEGui::quantize_dialog->exec())
return false;
-
- quantize_notes(parts, MusEGui::quantize_dialog->range, (MusEGlobal::config.division*4)/(1<<MusEGui::quantize_dialog->raster_power2),
+// (1<<MusEGui::quantize_dialog->raster_power2)
+ int raster = MusEGui::rasterVals[MusEGui::quantize_dialog->raster_index];
+ quantize_notes(parts, MusEGui::quantize_dialog->range, (MusEGlobal::config.division*4)/raster,
MusEGui::quantize_dialog->quant_len, MusEGui::quantize_dialog->strength, MusEGui::quantize_dialog->swing,
MusEGui::quantize_dialog->threshold);
@@ -306,8 +307,9 @@ bool quantize_notes()
parts=get_all_selected_parts();
else
parts=get_all_parts();
-
- quantize_notes(parts, MusEGui::quantize_dialog->range & FUNCTION_RANGE_ONLY_BETWEEN_MARKERS, (config.division*4)/(1<<MusEGui::quantize_dialog->raster_power2),
+
+ int raster = MusEGui::rasterVals[MusEGui::quantize_dialog->raster_index];
+ quantize_notes(parts, MusEGui::quantize_dialog->range & FUNCTION_RANGE_ONLY_BETWEEN_MARKERS, (config.division*4)/raster,
MusEGui::quantize_dialog->quant_len, MusEGui::quantize_dialog->strength, MusEGui::quantize_dialog->swing,
MusEGui::quantize_dialog->threshold);
@@ -1276,34 +1278,22 @@ void shrink_parts(int raster)
MusEGlobal::song->applyOperationGroup(operations);
}
-void internal_schedule_expand_part(Part* part, int raster, Undo& operations)
-{
- EventList* events=part->events();
- unsigned len=part->lenTick();
-
- for (iEvent ev=events->begin(); ev!=events->end(); ev++)
- if (ev->second.endTick() > len)
- len=ev->second.endTick();
-
- if (raster) len=ceil((float)len/raster)*raster;
-
- if (len > part->lenTick())
- {
- MidiPart* new_part = new MidiPart(*(MidiPart*)part);
- new_part->setLenTick(len);
- operations.push_back(UndoOp(UndoOp::ModifyPart, part, new_part, true, false));
- }
-}
void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo& operations)
{
+ QSet<const Part*> already_done;
+
+ for (Undo::iterator op_it=operations.begin(); op_it!=operations.end();op_it++)
+ if (op_it->type==UndoOp::ModifyPart || op_it->type==UndoOp::DeletePart)
+ already_done.insert(op_it->nPart);
+
unsigned old_len=part->lenTick();
if (old_len!=new_len)
{
Part* part_it=part;
do
{
- if (part_it->lenTick()==old_len)
+ if (part_it->lenTick()==old_len && !already_done.contains(part_it))
{
MidiPart* new_part = new MidiPart(*(MidiPart*)part_it);
new_part->setLenTick(new_len);
@@ -1393,4 +1383,81 @@ void clean_parts()
MusEGlobal::song->applyOperationGroup(operations);
}
+bool merge_selected_parts()
+{
+ set<Part*> temp = get_all_selected_parts();
+ return merge_parts(temp);
+}
+
+bool merge_parts(const set<Part*>& parts)
+{
+ set<Track*> tracks;
+ for (set<Part*>::iterator it=parts.begin(); it!=parts.end(); it++)
+ tracks.insert( (*it)->track() );
+
+ Undo operations;
+
+ // process tracks separately
+ for (set<Track*>::iterator t_it=tracks.begin(); t_it!=tracks.end(); t_it++)
+ {
+ Track* track=*t_it;
+
+ unsigned begin=MAXINT, end=0;
+ Part* first_part=NULL;
+
+ // find begin of the first and end of the last part
+ for (set<Part*>::iterator it=parts.begin(); it!=parts.end(); it++)
+ if ((*it)->track()==track)
+ {
+ Part* p=*it;
+ if (p->tick() < begin)
+ {
+ begin=p->tick();
+ first_part=p;
+ }
+
+ if (p->endTick() > end)
+ end=p->endTick();
+ }
+
+ if (begin==MAXINT || end==0)
+ {
+ printf("THIS SHOULD NEVER HAPPEN: begin==MAXINT || end==0 in merge_parts()\n");
+ continue; // skip the actual work, as we cannot work under errornous conditions.
+ }
+
+ // create and prepare the new part
+ Part* new_part = track->newPart(first_part);
+ new_part->setTick(begin);
+ new_part->setLenTick(end-begin);
+
+ EventList* new_el = new_part->events();
+ new_el->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it
+ // so we must decrement it first :/
+ new_el->clear();
+
+ // copy all events from the source parts into the new part
+ for (set<Part*>::iterator p_it=parts.begin(); p_it!=parts.end(); p_it++)
+ if ((*p_it)->track()==track)
+ {
+ EventList* old_el= (*p_it)->events();
+ for (iEvent ev_it=old_el->begin(); ev_it!=old_el->end(); ev_it++)
+ {
+ Event new_event=ev_it->second;
+ new_event.setTick( new_event.tick() + (*p_it)->tick() - new_part->tick() );
+ new_el->add(new_event);
+ }
+ }
+
+ // delete all the source parts
+ for (set<Part*>::iterator it=parts.begin(); it!=parts.end(); it++)
+ if ((*it)->track()==track)
+ operations.push_back( UndoOp(UndoOp::DeletePart, *it) );
+ // and add the new one
+ operations.push_back( UndoOp(UndoOp::AddPart, new_part) );
+ }
+
+ return MusEGlobal::song->applyOperationGroup(operations);
+}
+
} // namespace MusECore
diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h
index 2cf9c245..c81dd2bc 100644
--- a/muse2/muse/functions.h
+++ b/muse2/muse/functions.h
@@ -102,6 +102,8 @@ void shrink_parts(int raster=-1); //negative values mean "config.division"
void expand_parts(int raster=-1);
void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo& operations);
void clean_parts();
+bool merge_selected_parts();
+bool merge_parts(const std::set<Part*>& parts);
} // namespace MusECore
diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp
index a19d9ed8..a6abbb93 100644
--- a/muse2/muse/gconfig.cpp
+++ b/muse2/muse/gconfig.cpp
@@ -131,8 +131,8 @@ GlobalConfigValues config = {
-60.0, // double minSlider;
false, // use Jack freewheel
20, // int guiRefresh;
- QString(""), // userInstrumentsDir
- //QString(""), // helpBrowser; // Obsolete
+ QString(""), // userInstrumentsDir // Obsolete. Must keep for compatibility.
+ //QString(""), // helpBrowser; // Obsolete
true, // extendedMidi
384, // division for smf export
QString(""), // copyright string for smf export
@@ -191,7 +191,11 @@ GlobalConfigValues config = {
false, // popupsDefaultStayOpen
false, // leftMouseButtonCanDecrease
false, // rangeMarkerWithoutMMB
- MusECore::DONT_REC_MUTED_OR_HIDDEN
+ MusECore::DONT_REC_MUTED_OR_HIDDEN,
+ true, // addHiddenTracks
+ true // unhideTracks
};
+//GlobalConfigValues globalConfig = config;
+
} // namespace MusEGlobal
diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h
index 24fd787a..f611687f 100644
--- a/muse2/muse/gconfig.h
+++ b/muse2/muse/gconfig.h
@@ -121,7 +121,7 @@ struct GlobalConfigValues {
double minSlider;
bool freewheelMode;
int guiRefresh;
- QString userInstrumentsDir;
+ QString userInstrumentsDir; // Obsolete. Must keep for compatibility.
bool extendedMidi; // extended smf format
int midiDivision; // division for smf export
@@ -178,6 +178,8 @@ struct GlobalConfigValues {
bool leftMouseButtonCanDecrease;
bool rangeMarkerWithoutMMB;
MusECore::newDrumRecordCondition_t newDrumRecordCondition;
+ bool addHiddenTracks;
+ bool unhideTracks;
};
diff --git a/muse2/muse/globals.cpp b/muse2/muse/globals.cpp
index fad6472e..d50ea1eb 100644
--- a/muse2/muse/globals.cpp
+++ b/muse2/muse/globals.cpp
@@ -116,21 +116,13 @@ bool loadDSSI = true;
bool usePythonBridge = false;
bool useLASH = true;
-/*
const char* midi_file_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "Midi/Kar (*.mid *.MID *.kar *.KAR *.mid.gz *.mid.bz2)"),
- QT_TRANSLATE_NOOP("@default", "Midi (*.mid *.MID *.mid.gz *.mid.bz2)"),
- QT_TRANSLATE_NOOP("@default", "Karaoke (*.kar *.KAR *.kar.gz *.kar.bz2)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Midi/Kar (*.mid *.MID *.kar *.KAR *.mid.gz *.mid.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Midi (*.mid *.MID *.mid.gz *.mid.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Karaoke (*.kar *.KAR *.kar.gz *.kar.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
-*/
-const QStringList midi_file_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Midi/Kar (*.mid *.MID *.kar *.KAR *.mid.gz *.mid.bz2);;") +
- QString("Midi (*.mid *.MID *.mid.gz *.mid.bz2);;") +
- QString("Karaoke (*.kar *.KAR *.kar.gz *.kar.bz2);;") +
- QString("All Files (*)")).split(";;");
//FIXME: By T356 01/19/2010
// If saving as a compressed file (gz or bz2),
@@ -148,80 +140,46 @@ const char* midi_file_save_pattern[] = {
"All Files (*)",
0
};
-QStringList midi_file_save_pattern =
- QStringList::split(";;", QT_TRANSLATE_NOOP("@default",
- QString("Midi (*.mid);;") +
- QString("gzip compressed Midi (*.mid.gz);;") +
- QString("bzip2 compressed Midi (*.mid.bz2);;") +
- QString("Karaoke (*.kar);;") +
- QString("gzip compressed karaoke (*.kar.gz);;") +
- QString("bzip2 compressed karaoke (*.kar.bz2);;") +
- QString("All Files (*)")) );
*/
-/*
const char* midi_file_save_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "Midi (*.mid)"),
- QT_TRANSLATE_NOOP("@default", "Karaoke (*.kar)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Midi (*.mid)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Karaoke (*.kar)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
-*/
-const QStringList midi_file_save_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Midi (*.mid);;") +
- QString("Karaoke (*.kar);;") +
- QString("All Files (*)")).split(";;");
-/*
const char* med_file_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "med Files (*.med *.med.gz *.med.bz2)"),
- QT_TRANSLATE_NOOP("@default", "Uncompressed med Files (*.med)"),
- QT_TRANSLATE_NOOP("@default", "gzip compressed med Files (*.med.gz)"),
- QT_TRANSLATE_NOOP("@default", "bzip2 compressed med Files (*.med.bz2)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "all known files (*.med *.med.gz *.med.bz2 *.mid *.midi *.kar)"),
+ QT_TRANSLATE_NOOP("file_patterns", "med Files (*.med *.med.gz *.med.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Uncompressed med Files (*.med)"),
+ QT_TRANSLATE_NOOP("file_patterns", "gzip compressed med Files (*.med.gz)"),
+ QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed med Files (*.med.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "mid Files (*.mid *.midi *.kar *.MID *.MIDI *.KAR)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
const char* med_file_save_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "Uncompressed med Files (*.med)"),
- QT_TRANSLATE_NOOP("@default", "gzip compressed med Files (*.med.gz)"),
- QT_TRANSLATE_NOOP("@default", "bzip2 compressed med Files (*.med.bz2)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Uncompressed med Files (*.med)"),
+ QT_TRANSLATE_NOOP("file_patterns", "gzip compressed med Files (*.med.gz)"),
+ QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed med Files (*.med.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
+ 0
+ };
+const char* project_create_file_save_pattern[] = {
+ QT_TRANSLATE_NOOP("file_patterns", "Uncompressed med Files (*.med)"),
+ QT_TRANSLATE_NOOP("file_patterns", "gzip compressed med Files (*.med.gz)"),
+ QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed med Files (*.med.bz2)"),
0
};
-*/
-const QStringList med_file_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("all known files (*.med *.med.gz *.med.bz2 *.mid *.midi *.kar);;") +
- QString("med Files (*.med *.med.gz *.med.bz2);;") +
- QString("Uncompressed med Files (*.med);;") +
- QString("gzip compressed med Files (*.med.gz);;") +
- QString("bzip2 compressed med Files (*.med.bz2);;") +
- QString("mid Files (*.mid *.midi *.kar);;") +
- QString("All Files (*)")).split(";;");
-const QStringList med_file_save_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Uncompressed med Files (*.med);;") +
- QString("gzip compressed med Files (*.med.gz);;") +
- QString("bzip2 compressed med Files (*.med.bz2);;") +
- QString("All Files (*)")).split(";;");
-/*
const char* image_file_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "(*.jpg *.gif *.png)"),
- QT_TRANSLATE_NOOP("@default", "(*.jpg)"),
- QT_TRANSLATE_NOOP("@default", "(*.gif)"),
- QT_TRANSLATE_NOOP("@default", "(*.png)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "(*.jpg *.gif *.png)"),
+ QT_TRANSLATE_NOOP("file_patterns", "(*.jpg)"),
+ QT_TRANSLATE_NOOP("file_patterns", "(*.gif)"),
+ QT_TRANSLATE_NOOP("file_patterns", "(*.png)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
-*/
-const QStringList image_file_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("(*.jpg *.gif *.png);;") +
- QString("(*.jpg);;") +
- QString("(*.gif);;") +
- QString("(*.png);;") +
- QString("All Files (*)")).split(";;");
// Not used.
/*
@@ -232,84 +190,62 @@ const char* ctrl_file_pattern[] = {
};
*/
-/*
const char* part_file_pattern[] = {
- //QT_TRANSLATE_NOOP("@default", "part Files (*.mpt)"),
- QT_TRANSLATE_NOOP("@default", "part Files (*.mpt *.mpt.gz *.mpt.bz2)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "part Files (*.mpt *.mpt.gz *.mpt.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
const char* part_file_save_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "part Files (*.mpt)"),
- QT_TRANSLATE_NOOP("@default", "gzip compressed part Files (*.mpt.gz)"),
- QT_TRANSLATE_NOOP("@default", "bzip2 compressed part Files (*.mpt.bz2)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "part Files (*.mpt)"),
+ QT_TRANSLATE_NOOP("file_patterns", "gzip compressed part Files (*.mpt.gz)"),
+ QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed part Files (*.mpt.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
-*/
-const QStringList part_file_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("part Files (*.mpt *.mpt.gz *.mpt.bz2);;") +
- QString("All Files (*)")).split(";;");
-
-const QStringList part_file_save_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("part Files (*.mpt);;") +
- QString("gzip compressed part Files (*.mpt.gz);;") +
- QString("bzip2 compressed part Files (*.mpt.bz2);;") +
- QString("All Files (*)")).split(";;");
/*
const char* plug_file_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "part Files (*.pre)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "part Files (*.pre)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
*/
-/*
+
const char* preset_file_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "Presets (*.pre *.pre.gz *.pre.bz2)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Presets (*.pre *.pre.gz *.pre.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
const char* preset_file_save_pattern[] = {
- QT_TRANSLATE_NOOP("@default", "Presets (*.pre)"),
- QT_TRANSLATE_NOOP("@default", "gzip compressed presets (*.pre.gz)"),
- QT_TRANSLATE_NOOP("@default", "bzip2 compressed presets (*.pre.bz2)"),
- QT_TRANSLATE_NOOP("@default", "All Files (*)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Presets (*.pre)"),
+ QT_TRANSLATE_NOOP("file_patterns", "gzip compressed presets (*.pre.gz)"),
+ QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed presets (*.pre.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
0
};
-*/
-const QStringList preset_file_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Presets (*.pre *.pre.gz *.pre.bz2);;") +
- QString("All Files (*)")).split(";;");
-
-const QStringList preset_file_save_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Presets (*.pre);;") +
- QString("gzip compressed presets (*.pre.gz);;") +
- QString("bzip2 compressed presets (*.pre.bz2);;") +
- QString("All Files (*)")).split(";;");
-
-const QStringList drum_map_file_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Presets (*.map *.map.gz *.map.bz2);;") +
- QString("All Files (*)")).split(";;");
-const QStringList drum_map_file_save_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Presets (*.map);;") +
- QString("gzip compressed presets (*.map.gz);;") +
- QString("bzip2 compressed presets (*.map.bz2);;") +
- QString("All Files (*)")).split(";;");
-
-const QStringList audio_file_pattern =
- QT_TRANSLATE_NOOP("@default",
- QString("Wave/Binary (*.wav *.ogg *.bin);;") +
- QString("Wave (*.wav *.ogg);;") +
- QString("Binary (*.bin);;") +
- QString("All Files (*)")).split(";;");
+
+const char* drum_map_file_pattern[] = {
+ QT_TRANSLATE_NOOP("file_patterns", "Presets (*.map *.map.gz *.map.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
+ 0
+};
+
+const char* drum_map_file_save_pattern[] = {
+ QT_TRANSLATE_NOOP("file_patterns", "Presets (*.map)"),
+ QT_TRANSLATE_NOOP("file_patterns", "gzip compressed presets (*.map.gz)"),
+ QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed presets (*.map.bz2)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
+ 0
+};
+
+const char* audio_file_pattern[] = {
+ QT_TRANSLATE_NOOP("file_patterns", "Wave/Binary (*.wav *.ogg *.bin)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Wave (*.wav *.ogg)"),
+ QT_TRANSLATE_NOOP("file_patterns", "Binary (*.bin)"),
+ QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"),
+ 0
+};
///Qt::ButtonState globalKeyState;
Qt::KeyboardModifiers globalKeyState;
diff --git a/muse2/muse/globals.h b/muse2/muse/globals.h
index c0a3395a..7563c171 100644
--- a/muse2/muse/globals.h
+++ b/muse2/muse/globals.h
@@ -34,7 +34,6 @@
class QString;
class QAction;
class QActionGroup;
-class QStringList;
class QTimer;
namespace MusEGui {
@@ -91,33 +90,20 @@ extern bool realTimeScheduling;
extern int realTimePriority;
extern int midiRTPrioOverride;
-/*
-extern const char* midi_file_pattern[]; //!< File name pattern for midi files
-extern const char* midi_file_save_pattern[]; //!< File name pattern for saving midi files
-extern const char* med_file_pattern[]; //!< File name pattern for muse project files
-extern const char* med_file_save_pattern[]; //!< File name pattern for saving muse project files
-extern const char* image_file_pattern[]; //!< File name pattern for image files (gfx)
-//extern const char* ctrl_file_pattern[]; //!< File name pattern for controller-files
-extern const char* part_file_pattern[]; //!< File name pattern for part files
-extern const char* part_file_save_pattern[]; //!< File name pattern for saving part files
-//extern const char* plug_file_pattern[]; //!< File name pattern for plugin files
-extern const char* preset_file_pattern[]; //!< File name pattern for plugin files
-extern const char* preset_file_save_pattern[]; //!< File name pattern for saving plugin files
-*/
-
-extern const QStringList midi_file_pattern;
-extern const QStringList midi_file_save_pattern;
-extern const QStringList med_file_pattern;
-extern const QStringList med_file_save_pattern;
-extern const QStringList image_file_pattern;
-//extern const QStringList ctrl_file_pattern;
-extern const QStringList part_file_pattern;
-extern const QStringList part_file_save_pattern;
-extern const QStringList preset_file_pattern;
-extern const QStringList preset_file_save_pattern;
-extern const QStringList drum_map_file_pattern;
-extern const QStringList drum_map_file_save_pattern;
-extern const QStringList audio_file_pattern;
+extern const char* midi_file_pattern[];
+extern const char* midi_file_save_pattern[];
+extern const char* med_file_pattern[];
+extern const char* med_file_save_pattern[];
+extern const char* project_create_file_save_pattern[];
+extern const char* image_file_pattern[];
+//extern const char* ctrl_file_pattern[];
+extern const char* part_file_pattern[];
+extern const char* part_file_save_pattern[];
+extern const char* preset_file_pattern[];
+extern const char* preset_file_save_pattern[];
+extern const char* drum_map_file_pattern[];
+extern const char* drum_map_file_save_pattern[];
+extern const char* audio_file_pattern[];
///extern Qt::ButtonState globalKeyState;
extern Qt::KeyboardModifiers globalKeyState;
diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp
index 1298b2d2..144d876d 100644
--- a/muse2/muse/helper.cpp
+++ b/muse2/muse/helper.cpp
@@ -20,6 +20,8 @@
//
//=========================================================
+#include <list>
+
#include "helper.h"
#include "part.h"
#include "track.h"
@@ -28,6 +30,22 @@
#include "icons.h"
#include "synth.h"
#include "functions.h"
+#include "gconfig.h"
+
+#include "driver/jackmidi.h"
+#include "route.h"
+#include "mididev.h"
+#include "globaldefs.h"
+#include "audio.h"
+#include "audiodev.h"
+#include "midiseq.h"
+
+#include <QApplication>
+#include <QDir>
+#include <QFileInfo>
+#include <QFileDialog>
+#include <QString>
+//#include <QTemporaryFile>
#ifdef DSSI_SUPPORT
#include "dssihost.h"
@@ -165,237 +183,544 @@ QMenu* populateAddSynth(QWidget* parent)
//typedef std::multimap<std::string, int, addSynth_cmp_str >::iterator imap;
typedef std::multimap<std::string, int >::iterator imap;
- MusECore::MessSynth* synMESS = 0;
- QMenu* synpMESS = 0;
- asmap mapMESS;
-
- #ifdef DSSI_SUPPORT
- MusECore::DssiSynth* synDSSI = 0;
- QMenu* synpDSSI = 0;
- asmap mapDSSI;
- #endif
- #ifdef VST_SUPPORT
- MusECore::VstSynth* synVST = 0;
- QMenu* synpVST = 0;
- asmap mapVST;
- #endif
+ int ntypes = MusECore::Synth::SYNTH_TYPE_END;
+ asmap smaps[ntypes];
+ QMenu* mmaps[ntypes];
+ for(int itype = 0; itype < ntypes; ++itype)
+ mmaps[itype] = 0;
- // Not necessary, but what the heck.
- QMenu* synpOther = 0;
- asmap mapOther;
+ MusECore::Synth* synth;
+ MusECore::Synth::Type type;
- //const int synth_base_id = 0x1000;
int ii = 0;
for(std::vector<MusECore::Synth*>::iterator i = MusEGlobal::synthis.begin(); i != MusEGlobal::synthis.end(); ++i)
{
- synMESS = dynamic_cast<MusECore::MessSynth*>(*i);
- if(synMESS)
- {
- mapMESS.insert( std::pair<std::string, int> (std::string(synMESS->description().toLower().toLatin1().constData()), ii) );
- }
- else
- {
-
- #ifdef DSSI_SUPPORT
- synDSSI = dynamic_cast<MusECore::DssiSynth*>(*i);
- if(synDSSI)
- {
- mapDSSI.insert( std::pair<std::string, int> (std::string(synDSSI->description().toLower().toLatin1().constData()), ii) );
- }
- else
- #endif
-
- {
- #ifdef VST_SUPPORT
- synVST = dynamic_cast<MusECore::VstSynth*>(*i);
- if(synVST)
- {
- mapVST.insert( std::pair<std::string, int> (std::string(synVST->description().toLower().toLatin1().constData()), ii) );
- }
- else
- #endif
-
- {
- mapOther.insert( std::pair<std::string, int> (std::string((*i)->description().toLower().toLatin1().constData()), ii) );
- }
- }
- }
+ synth = *i;
+ type = synth->synthType();
+ if(type >= ntypes)
+ continue;
+ smaps[type].insert( std::pair<std::string, int> (std::string(synth->description().toLower().toLatin1().constData()), ii) );
++ii;
}
int sz = MusEGlobal::synthis.size();
- for(imap i = mapMESS.begin(); i != mapMESS.end(); ++i)
- {
- int idx = i->second;
- if(idx > sz) // Sanity check
- continue;
- MusECore::Synth* s = MusEGlobal::synthis[idx];
- if(s)
+ for(int itype = 0; itype < ntypes; ++itype)
+ {
+ for(imap i = smaps[itype].begin(); i != smaps[itype].end(); ++i)
{
- // No MESS sub-menu yet? Create it now.
- if(!synpMESS)
- synpMESS = new QMenu(parent);
- QAction* sM = synpMESS->addAction(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">");
- sM->setData(MENU_ADD_SYNTH_ID_BASE + idx);
- }
- }
-
- #ifdef DSSI_SUPPORT
- for(imap i = mapDSSI.begin(); i != mapDSSI.end(); ++i)
- {
- int idx = i->second;
- if(idx > sz)
- continue;
- MusECore::Synth* s = MusEGlobal::synthis[idx];
- if(s)
- {
- // No DSSI sub-menu yet? Create it now.
- if(!synpDSSI)
- synpDSSI = new QMenu(parent);
- //synpDSSI->insertItem(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">", MENU_ADD_SYNTH_ID_BASE + idx);
- QAction* sD = synpDSSI->addAction(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">");
- sD->setData(MENU_ADD_SYNTH_ID_BASE + idx);
- }
- }
- #endif
-
- #ifdef VST_SUPPORT
- for(imap i = mapVST.begin(); i != mapVST.end(); ++i)
- {
- int idx = i->second;
- if(idx > sz)
- continue;
- Synth* s = MusEGlobal::synthis[idx];
- if(s)
- {
- // No VST sub-menu yet? Create it now.
- if(!synpVST)
- synpVST = new QMenu(parent);
- QAction* sV = synpVST->addAction(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">");
- sV->setData(MENU_ADD_SYNTH_ID_BASE + idx);
- }
- }
- #endif
-
- for(imap i = mapOther.begin(); i != mapOther.end(); ++i)
- {
- int idx = i->second;
- if(idx > sz)
- continue;
- MusECore::Synth* s = MusEGlobal::synthis[idx];
- // No Other sub-menu yet? Create it now.
- if(!synpOther)
- synpOther = new QMenu(parent);
- //synpOther->insertItem(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">", MENU_ADD_SYNTH_ID_BASE + idx);
- QAction* sO = synpOther->addAction(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">");
- sO->setData(MENU_ADD_SYNTH_ID_BASE + idx);
- }
-
- if(synpMESS)
- {
- synpMESS->setIcon(*synthIcon);
- synpMESS->setTitle(QT_TRANSLATE_NOOP("@default", "MESS"));
- synp->addMenu(synpMESS);
- }
-
- #ifdef DSSI_SUPPORT
- if(synpDSSI)
- {
- synpDSSI->setIcon(*synthIcon);
- synpDSSI->setTitle(QT_TRANSLATE_NOOP("@default", "DSSI"));
- synp->addMenu(synpDSSI);
- }
- #endif
-
- #ifdef VST_SUPPORT
- if(synpVST)
- {
- synpVST->setIcon(*synthIcon);
- synpVST->setTitle(QT_TRANSLATE_NOOP("@default", "FST"));
- synp->addMenu(synpVST);
- }
- #endif
-
- if(synpOther)
- {
- synpOther->setIcon(*synthIcon);
- synpOther->setTitle(QObject::tr("Other"));
- synp->addMenu(synpOther);
+ int idx = i->second;
+ if(idx > sz) // Sanity check
+ continue;
+ synth = MusEGlobal::synthis[idx];
+ if(synth)
+ {
+ // No sub-menu yet? Create it now.
+ if(!mmaps[itype])
+ {
+ mmaps[itype] = new QMenu(parent);
+ mmaps[itype]->setIcon(*synthIcon);
+ mmaps[itype]->setTitle(MusECore::synthType2String((MusECore::Synth::Type)itype));
+ synp->addMenu(mmaps[itype]);
+ }
+ QAction* act = mmaps[itype]->addAction(synth->description() + " <" + synth->name() + ">");
+ act->setData( MENU_ADD_SYNTH_ID_BASE * (itype + 1) + idx );
+ }
+ }
}
-
+
return synp;
}
-
//---------------------------------------------------------
// populateAddTrack
// this is also used in "mixer"
//---------------------------------------------------------
-QActionGroup* populateAddTrack(QMenu* addTrack)
+QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll)
{
QActionGroup* grp = new QActionGroup(addTrack);
+ if (MusEGlobal::config.addHiddenTracks)
+ populateAll=true;
+
+ if (populateAll || MusECore::MidiTrack::visible()) {
+ QAction* midi = addTrack->addAction(QIcon(*addtrack_addmiditrackIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Midi Track")));
+ midi->setData(MusECore::Track::MIDI);
+ grp->addAction(midi);
+ }
+ if (populateAll || MusECore::MidiTrack::visible()) {
+ QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Drum Track")));
+ drum->setData(MusECore::Track::DRUM);
+ grp->addAction(drum);
+ }
+ if (populateAll || MusECore::MidiTrack::visible()) {
+ QAction* newdrum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add New Style Drum Track")));
+ newdrum->setData(MusECore::Track::NEW_DRUM);
+ grp->addAction(newdrum);
+ }
+ if (populateAll || MusECore::WaveTrack::visible()) {
+ QAction* wave = addTrack->addAction(QIcon(*addtrack_wavetrackIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Wave Track")));
+ wave->setData(MusECore::Track::WAVE);
+ grp->addAction(wave);
+ }
- QAction* midi = addTrack->addAction(QIcon(*addtrack_addmiditrackIcon),
- QT_TRANSLATE_NOOP("@default", "Add Midi Track"));
- midi->setData(MusECore::Track::MIDI);
- grp->addAction(midi);
+ if (populateAll || MusECore::AudioOutput::visible()) {
+ QAction* aoutput = addTrack->addAction(QIcon(*addtrack_audiooutputIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Audio Output")));
+ aoutput->setData(MusECore::Track::AUDIO_OUTPUT);
+ grp->addAction(aoutput);
+ }
+ if (populateAll || MusECore::AudioGroup::visible()) {
+ QAction* agroup = addTrack->addAction(QIcon(*addtrack_audiogroupIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Audio Group")));
+ agroup->setData(MusECore::Track::AUDIO_GROUP);
+ grp->addAction(agroup);
+ }
- QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon),
- QT_TRANSLATE_NOOP("@default", "Add Drum Track"));
- drum->setData(MusECore::Track::DRUM);
- grp->addAction(drum);
+ if (populateAll || MusECore::AudioInput::visible()) {
+ QAction* ainput = addTrack->addAction(QIcon(*addtrack_audioinputIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Audio Input")));
+ ainput->setData(MusECore::Track::AUDIO_INPUT);
+ grp->addAction(ainput);
+ }
+ if (populateAll || MusECore::AudioAux::visible()) {
+ QAction* aaux = addTrack->addAction(QIcon(*addtrack_auxsendIcon),
+ qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Aux Send")));
+ aaux->setData(MusECore::Track::AUDIO_AUX);
+ grp->addAction(aaux);
+ }
- QAction* newdrum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon),
- QT_TRANSLATE_NOOP("@default", "Add New Style Drum Track"));
- newdrum->setData(MusECore::Track::NEW_DRUM);
- grp->addAction(newdrum);
+ if (populateAll || MusECore::SynthI::visible()) {
+ // Create a sub-menu and fill it with found synth types. Make addTrack the owner.
+ QMenu* synp = populateAddSynth(addTrack);
+ synp->setIcon(*synthIcon);
+ synp->setTitle(qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Synth")));
+ // Add the sub-menu to the given menu.
+ addTrack->addMenu(synp);
+ }
- QAction* wave = addTrack->addAction(QIcon(*addtrack_wavetrackIcon),
- QT_TRANSLATE_NOOP("@default", "Add Wave Track"));
- wave->setData(MusECore::Track::WAVE);
- grp->addAction(wave);
+ //QObject::connect(addTrack, SIGNAL(triggered(QAction *)), MusEGlobal::song, SLOT(addNewTrack(QAction *)));
+ return grp;
+ }
+
+//---------------------------------------------------------
+// getFilterExtension
+//---------------------------------------------------------
- QAction* aoutput = addTrack->addAction(QIcon(*addtrack_audiooutputIcon),
- QT_TRANSLATE_NOOP("@default", "Add Audio Output"));
- aoutput->setData(MusECore::Track::AUDIO_OUTPUT);
- grp->addAction(aoutput);
+QString getFilterExtension(const QString &filter)
+{
+ //
+ // Return the first extension found. Must contain at least one * character.
+ //
+
+ int pos = filter.indexOf('*');
+ if(pos == -1)
+ return QString();
+
+ QString filt;
+ int len = filter.length();
+ ++pos;
+ for( ; pos < len; ++pos)
+ {
+ QChar c = filter[pos];
+ if((c == ')') || (c == ';') || (c == ',') || (c == ' '))
+ break;
+ filt += filter[pos];
+ }
+ return filt;
+}
+QStringList localizedStringListFromCharArray(const char** array, const char* context)
+{
+ QStringList temp;
+ for (int i=0;array[i];i++)
+ temp << qApp->translate(context, array[i]);
+
+ return temp;
+}
- QAction* agroup = addTrack->addAction(QIcon(*addtrack_audiogroupIcon),
- QT_TRANSLATE_NOOP("@default", "Add Audio Group"));
- agroup->setData(MusECore::Track::AUDIO_GROUP);
- grp->addAction(agroup);
+QString browseProjectFolder(QWidget* parent)
+{
+ QString path;
+ if(!MusEGlobal::config.projectBaseFolder.isEmpty())
+ {
+ QDir d(MusEGlobal::config.projectBaseFolder);
+ path = d.absolutePath();
+ }
+
+ QString dir = QFileDialog::getExistingDirectory(parent, qApp->tr("Select project directory"), path);
+ if(dir.isEmpty())
+ dir = MusEGlobal::config.projectBaseFolder;
+ // projDirLineEdit->setText(dir);
+ //return QFileDialog::getExistingDirectory(this, qApp.tr("Select project directory"), path);
+ return dir;
+}
+QString projectTitleFromFilename(QString filename)
+{
+ int idx;
+ idx = filename.lastIndexOf(".med.bz2", -1, Qt::CaseInsensitive);
+ if(idx == -1)
+ idx = filename.lastIndexOf(".med.gz", -1, Qt::CaseInsensitive);
+ if(idx == -1)
+ idx = filename.lastIndexOf(".med", -1, Qt::CaseInsensitive);
+
+ if(idx != -1)
+ filename.truncate(idx);
+
+ QFileInfo fi(filename);
- QAction* ainput = addTrack->addAction(QIcon(*addtrack_audioinputIcon),
- QT_TRANSLATE_NOOP("@default", "Add Audio Input"));
- ainput->setData(MusECore::Track::AUDIO_INPUT);
- grp->addAction(ainput);
+ //return fi.baseName();
+ return fi.fileName();
+}
+
+QString projectPathFromFilename(QString filename)
+{
+ QFileInfo fi(filename);
+ return QDir::cleanPath(fi.absolutePath());
+}
+
+QString projectExtensionFromFilename(QString filename)
+{
+ int idx;
+ idx = filename.lastIndexOf(".med.bz2", -1, Qt::CaseInsensitive);
+ if(idx == -1)
+ idx = filename.lastIndexOf(".med.gz", -1, Qt::CaseInsensitive);
+ if(idx == -1)
+ idx = filename.lastIndexOf(".med", -1, Qt::CaseInsensitive);
+ if(idx == -1)
+ idx = filename.lastIndexOf(".bz2", -1, Qt::CaseInsensitive);
+ if(idx == -1)
+ idx = filename.lastIndexOf(".gz", -1, Qt::CaseInsensitive);
+
+ return (idx == -1) ? QString() : filename.right(filename.size() - idx);
+}
+
+QString getUniqueUntitledName()
+{
+ QString filename("untitled");
+ //QTemporaryFile tf(MusEGlobal::config.projectBaseFolder +"/" + s + "XXXXXX.med");
+ //if(tf.open())
+ // s = MusEGui::projectTitleFromFilename(tf.fileName());
+
+ QString fbase(MusEGlobal::config.projectBaseFolder);
+
+ QString nfb = fbase;
+ if(MusEGlobal::config.projectStoreInFolder)
+ nfb += "/" + filename;
+ QFileInfo fi(nfb + "/" + filename + ".med"); // TODO p4.0.40 Check other extensions.
+ if(!fi.exists())
+ //return filename;
+ return fi.filePath();
+
+ // Find a new filename
+ QString nfn = filename;
+ int idx;
+ for (idx=2; idx<10000; idx++) {
+ QString num = QString::number(idx);
+ nfn = filename + "_" + num;
+ nfb = fbase;
+ if(MusEGlobal::config.projectStoreInFolder)
+ nfb += "/" + nfn;
+ QFileInfo fi(nfb + "/" + nfn + ".med");
+ if(!fi.exists())
+ //break;
+ return fi.filePath();
+ }
+
+ //if(idx >= 10000)
+ printf("MusE error: Could not make untitled project name (10000 or more untitled projects in project dir - clean up!\n");
+
+ //return nfn;
+
+ nfb = fbase;
+ if(MusEGlobal::config.projectStoreInFolder)
+ nfb += "/" + filename;
+ return nfb + "/" + filename + ".med";
+}
- QAction* aaux = addTrack->addAction(QIcon(*addtrack_auxsendIcon),
- QT_TRANSLATE_NOOP("@default", "Add Aux Send"));
- aaux->setData(MusECore::Track::AUDIO_AUX);
- grp->addAction(aaux);
+#if 1
- // Create a sub-menu and fill it with found synth types. Make addTrack the owner.
- QMenu* synp = populateAddSynth(addTrack);
- synp->setIcon(*synthIcon);
- synp->setTitle(QT_TRANSLATE_NOOP("@default", "Add Synth"));
+// -------------------------------------------------------------------------------------------------------
+// populateMidiPorts()
+// This version creats separate devices for input and output ports.
+// It does not attempt to pair them together.
+// -------------------------------------------------------------------------------------------------------
+void populateMidiPorts()
+{
+ if(!MusEGlobal::checkAudioDevice())
+ return;
- // Add the sub-menu to the given menu.
- addTrack->addMenu(synp);
+ MusECore::MidiDevice* dev = 0;
+
+ int port_num = 0;
+
+ // If Jack is running, prefer Jack midi devices over ALSA.
+ if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::JACK_AUDIO)
+ {
+ std::list<QString> sl;
+ sl = MusEGlobal::audioDevice->inputPorts(true, 1); // Ask for second aliases.
+ for(std::list<QString>::iterator i = sl.begin(); i != sl.end(); ++i)
+ {
+ dev = MusECore::MidiJackDevice::createJackMidiDevice(*i, 1);
+ if(dev)
+ {
+ //printf("populateMidiPorts Created jack writeable device: %s\n", dev->name().toLatin1().constData());
+ //dev->setOpenFlags(1);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev);
+ MusECore::Route srcRoute(dev, -1);
+ MusECore::Route dstRoute(*i, true, -1, MusECore::Route::JACK_ROUTE);
+ MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute);
+ if(++port_num == MIDI_PORTS)
+ return;
+ }
+ }
+
+ sl = MusEGlobal::audioDevice->outputPorts(true, 1); // Ask for second aliases.
+ for(std::list<QString>::iterator i = sl.begin(); i != sl.end(); ++i)
+ {
+ dev = MusECore::MidiJackDevice::createJackMidiDevice(*i, 2);
+ if(dev)
+ {
+ //printf("populateMidiPorts Created jack readable device: %s\n", dev->name().toLatin1().constData());
+ //dev->setOpenFlags(2);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev);
+ MusECore::Route srcRoute(*i, false, -1, MusECore::Route::JACK_ROUTE);
+ MusECore::Route dstRoute(dev, -1);
+ MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute);
+ if(++port_num == MIDI_PORTS)
+ return;
+ }
+ }
+ }
+ else
+ // If Jack is not running, use ALSA devices.
+ if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::DUMMY_AUDIO)
+ {
+ for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i)
+ {
+ if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI)
+ continue;
+ dev = *i;
+ // Select only sensible devices first - not thru etc.
+ //if( ... )
+ // continue;
- //QObject::connect(addTrack, SIGNAL(triggered(QAction *)), MusEGlobal::song, SLOT(addNewTrack(QAction *)));
+ //dev->setOpenFlags(1);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev);
+
+ if(++port_num == MIDI_PORTS)
+ return;
+ }
- return grp;
+ //for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i)
+ //{
+ // if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI)
+ // continue;
+ // // Select the ones ignored in the first pass.
+ // if(! ... )
+ // continue;
+ //
+ // dev->setOpenFlags(1);
+ // MusEGlobal::midiSeq->msgSetMidiDevice(port_num, dev);
+ //
+ // if(++port_num == MIDI_PORTS)
+ // return;
+ //}
+ }
+
+ //MusEGlobal::muse->changeConfig(true); // save configuration file
+ //MusEGlobal::song->update();
+
+}
+
+#else // this code is disabled
+
+DISABLED AND MAYBE OUT-OF-DATE CODE!
+the code below is disabled for a longer period of time,
+there were certain changes and merges. dunno if that code
+works at all. before activating it again, intensively
+verify whether its still okay!
+
+// -------------------------------------------------------------------------------------------------------
+// populateMidiPorts()
+// This version worked somewhat well with system devices.
+// But no, it is virtually impossible to tell from the names whether ports should be paired.
+// There is too much room for error - what markers to look for ("capture_"/"playback_") etc.
+// It works kind of OK with 'seq' Jack Midi ALSA devices, but not for 'raw' which have a different
+// naming structure ("in-hw-0-0-0"/"out-hw-0-0-0").
+// It also fails to combine if the ports were named by a client app, for example another instance of MusE.
+// -------------------------------------------------------------------------------------------------------
+
+void populateMidiPorts()
+{
+ if(!MusEGlobal::checkAudioDevice())
+ return;
+
+ MusECore::MidiDevice* dev = 0;
+
+ int port_num = 0;
+
+ // If Jack is running, prefer Jack midi devices over ALSA.
+ if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::JACK_AUDIO)
+ {
+ std::list<QString> wsl;
+ std::list<QString> rsl;
+ //wsl = MusEGlobal::audioDevice->inputPorts(true, 1); // Ask for second aliases.
+ wsl = MusEGlobal::audioDevice->inputPorts(true, 0); // Ask for first aliases.
+ //rsl = MusEGlobal::audioDevice->outputPorts(true, 1); // Ask for second aliases.
+ rsl = MusEGlobal::audioDevice->outputPorts(true, 0); // Ask for first aliases.
+
+ for(std::list<QString>::iterator wi = wsl.begin(); wi != wsl.end(); ++wi)
+ {
+ QString ws = *wi;
+ int y = ws.lastIndexOf("_");
+ if(y >= 1)
+ {
+ int x = ws.lastIndexOf("_", y-1);
+ if(x >= 0)
+ ws.remove(x, y - x);
+ }
+
+
+ bool match_found = false;
+ for(std::list<QString>::iterator ri = rsl.begin(); ri != rsl.end(); ++ri)
+ {
+ QString rs = *ri;
+ int y = rs.lastIndexOf("_");
+ if(y >= 1)
+ {
+ int x = rs.lastIndexOf("_", y-1);
+ if(x >= 0)
+ rs.remove(x, y - x);
+ }
+
+ // Do we have a matching pair?
+ if(rs == ws)
+ {
+ // Would like to remove the client name, but no, we need it as a distinguishing identifier.
+ //int z = ws.indexOf(":");
+ //if(z >= 0)
+ // ws.remove(0, z + 1);
+
+ dev = MusECore::MidiJackDevice::createJackMidiDevice(ws, 3);
+ if(dev)
+ {
+ //printf("populateMidiPorts Created jack writeable/readable device: %s\n", dev->name().toLatin1().constData());
+ //dev->setOpenFlags(1);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev);
+ MusECore::Route devRoute(dev, -1);
+ MusECore::Route wdstRoute(*wi, true, -1, MusECore::Route::JACK_ROUTE);
+ MusECore::Route rsrcRoute(*ri, false, -1, MusECore::Route::JACK_ROUTE);
+ MusEGlobal::audio->msgAddRoute(devRoute, wdstRoute);
+ MusEGlobal::audio->msgAddRoute(rsrcRoute, devRoute);
+ if(++port_num == MIDI_PORTS)
+ return;
+ }
+
+ rsl.erase(ri); // Done with this read port. Remove.
+ match_found = true;
+ break;
+ }
+ }
+
+ if(!match_found)
+ {
+ // No match was found. Create a single writeable device.
+ QString s = *wi;
+ // Would like to remove the client name, but no, we need it as a distinguishing identifier.
+ //int z = s.indexOf(":");
+ //if(z >= 0)
+ // s.remove(0, z + 1);
+ dev = MusECore::MidiJackDevice::createJackMidiDevice(s, 1);
+ if(dev)
+ {
+ //printf("populateMidiPorts Created jack writeable device: %s\n", dev->name().toLatin1().constData());
+ //dev->setOpenFlags(1);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev);
+ MusECore::Route srcRoute(dev, -1);
+ MusECore::Route dstRoute(*wi, true, -1, MusECore::Route::JACK_ROUTE);
+ MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute);
+ if(++port_num == MIDI_PORTS)
+ return;
+ }
}
+ }
+
+ // Create the remaining readable ports as single readable devices.
+ for(std::list<QString>::iterator ri = rsl.begin(); ri != rsl.end(); ++ri)
+ {
+ QString s = *ri;
+ // Would like to remove the client name, but no, we need it as a distinguishing identifier.
+ //int z = s.indexOf(":");
+ //if(z >= 0)
+ // s.remove(0, z + 1);
+ dev = MusECore::MidiJackDevice::createJackMidiDevice(s, 2);
+ if(dev)
+ {
+ //printf("populateMidiPorts Created jack readable device: %s\n", dev->name().toLatin1().constData());
+ //dev->setOpenFlags(2);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev);
+ MusECore::Route srcRoute(*ri, false, -1, MusECore::Route::JACK_ROUTE);
+ MusECore::Route dstRoute(dev, -1);
+ MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute);
+ if(++port_num == MIDI_PORTS)
+ return;
+ }
+ }
+ }
+ else
+ // If Jack is not running, use ALSA devices.
+ if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::DUMMY_AUDIO)
+ {
+ for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i)
+ {
+ if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI)
+ continue;
+ dev = *i;
+ // Select only sensible devices first - not thru etc.
+ //if( ... )
+ // continue;
+
+ //dev->setOpenFlags(1);
+ MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev);
+
+ if(++port_num == MIDI_PORTS)
+ return;
+ }
+
+ //for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i)
+ //{
+ // if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI)
+ // continue;
+ // // Select the ones ignored in the first pass.
+ // if(! ... )
+ // continue;
+ //
+ // dev->setOpenFlags(1);
+ // MusEGlobal::midiSeq->msgSetMidiDevice(port_num, dev);
+ //
+ // if(++port_num == MIDI_PORTS)
+ // return;
+ //}
+ }
+
+ //MusEGlobal::muse->changeConfig(true); // save configuration file
+ //MusEGlobal::song->update();
+
+}
+#endif // populateMidiPorts
+
} // namespace MusEGui
+
diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h
index a051cd15..ad531fae 100644
--- a/muse2/muse/helper.h
+++ b/muse2/muse/helper.h
@@ -25,6 +25,7 @@
#include <set>
#include <QSet>
+#include <QStringList>
#include "drummap.h"
@@ -52,7 +53,15 @@ QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks);
namespace MusEGui {
QMenu* populateAddSynth(QWidget* parent);
-QActionGroup* populateAddTrack(QMenu* addTrack);
+QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll=false);
+QStringList localizedStringListFromCharArray(const char** array, const char* context);
+QString getFilterExtension(const QString &filter);
+QString browseProjectFolder(QWidget* parent = 0);
+QString projectTitleFromFilename(QString filename);
+QString projectPathFromFilename(QString filename);
+QString projectExtensionFromFilename(QString filename);
+QString getUniqueUntitledName();
+void populateMidiPorts();
}
#endif
diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp
index 86738fe4..bd3c8a9f 100644
--- a/muse2/muse/importmidi.cpp
+++ b/muse2/muse/importmidi.cpp
@@ -21,7 +21,6 @@
//
//=========================================================
-#include <assert.h>
#include <errno.h>
#include <values.h>
@@ -418,7 +417,8 @@ void MusE::processTrack(MusECore::MidiTrack* track)
i->second.dump();
}
// all events should be processed:
- assert(tevents->empty());
+ if (!tevents->empty())
+ printf("THIS SHOULD NEVER HAPPEN: not all events processed at the end of MusE::processTrack()!\n");
}
//---------------------------------------------------------
diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp
index 742e0626..b90b872e 100644
--- a/muse2/muse/instruments/editinstrument.cpp
+++ b/muse2/muse/instruments/editinstrument.cpp
@@ -407,27 +407,10 @@ void EditInstrument::saveAs()
if(!QDir(MusEGlobal::museUserInstruments).exists())
{
- if(QMessageBox::question(this,
- tr("MusE:"),
- tr("The user instrument directory\n%1\ndoes not exist yet. Create it now?\n").arg(MusEGlobal::museUserInstruments) +
- tr("(You can change the user instruments directory at Settings->Global Settings->Midi)"),
- QMessageBox::Ok | QMessageBox::Default,
- QMessageBox::Cancel | QMessageBox::Escape,
- Qt::NoButton) == QMessageBox::Ok)
- {
- if(QDir().mkdir(MusEGlobal::museUserInstruments))
- printf("Created user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData());
- else
- {
- printf("Unable to create user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData());
- QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory '%1'").arg(MusEGlobal::museUserInstruments));
- //return;
- path = MusEGlobal::museUser;
- }
- }
- else
- // return;
- path = MusEGlobal::museUser;
+ printf("MusE Error! User instrument directory: %s does not exist. Should be created at startup!\n", MusEGlobal::museUserInstruments.toLatin1().constData());
+
+ //path = MusEGlobal::museUser;
+ //path = MusEGlobal::configPath;
}
//if (instrument->filePath().isEmpty())
@@ -699,27 +682,10 @@ void EditInstrument::fileSaveAs()
if(!QDir(MusEGlobal::museUserInstruments).exists())
{
- if(QMessageBox::question(this,
- tr("MusE:"),
- tr("The user instrument directory\n%1\ndoes not exist yet. Create it now?\n").arg(MusEGlobal::museUserInstruments) +
- tr("(You can change the user instruments directory at Settings->Global Settings->Midi)"),
- QMessageBox::Ok | QMessageBox::Default,
- QMessageBox::Cancel | QMessageBox::Escape,
- Qt::NoButton) == QMessageBox::Ok)
- {
- if(QDir().mkdir(MusEGlobal::museUserInstruments))
- printf("Created user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData());
- else
- {
- printf("Unable to create user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData());
- QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory '%1'").arg(MusEGlobal::museUserInstruments));
- //return;
- path = MusEGlobal::museUser;
- }
- }
- else
- // return;
- path = MusEGlobal::museUser;
+ printf("MusE Error! User instrument directory: %s does not exist. Should be created at startup!\n", MusEGlobal::museUserInstruments.toLatin1().constData());
+
+ //path = MusEGlobal::museUser;
+ //path = MusEGlobal::configPath;
}
path += QString("/%1.idf").arg(so);
diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp
index c479ebc6..a01903ae 100644
--- a/muse2/muse/instruments/minstrument.cpp
+++ b/muse2/muse/instruments/minstrument.cpp
@@ -932,15 +932,11 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru
return "<unknown>";
}
-} // namespace MusECore
-
-namespace MusEGui {
-
//---------------------------------------------------------
// populatePatchPopup
//---------------------------------------------------------
-void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* menu, int chan, MType songType, bool drum)
+void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MType songType, bool drum)
{
menu->clear();
int mask = 0;
@@ -952,7 +948,7 @@ void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* men
if(drumchan)
{
int id = (0xff << 16) + (0xff << 8) + 0x00; // First patch
- QAction* act = menu->addAction(MusECore::gmdrumname);
+ QAction* act = menu->addAction(gmdrumname);
//act->setCheckable(true);
act->setData(id);
return;
@@ -961,16 +957,16 @@ void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* men
break;
case MT_UNKNOWN: mask = 7; break;
}
- if (midiInstrument->groups()->size() > 1) {
- for (MusECore::ciPatchGroup i = midiInstrument->groups()->begin(); i != midiInstrument->groups()->end(); ++i) {
- MusECore::PatchGroup* pgp = *i;
+ if (pg.size() > 1) {
+ for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) {
+ PatchGroup* pgp = *i;
//QMenu* pm = menu->addMenu(pgp->name);
- PopupMenu* pm = new PopupMenu(pgp->name, menu, menu->stayOpen()); // Use the parent stayOpen here.
+ MusEGui::PopupMenu* pm = new MusEGui::PopupMenu(pgp->name, menu, menu->stayOpen()); // Use the parent stayOpen here.
menu->addMenu(pm);
pm->setFont(MusEGlobal::config.fonts[0]);
- const MusECore::PatchList& pl = pgp->patches;
- for (MusECore::ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
- const MusECore::Patch* mp = *ipl;
+ const PatchList& pl = pgp->patches;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
if ((mp->typ & mask) &&
((drum && songType != MT_GM) ||
(mp->drum == drumchan)) )
@@ -985,11 +981,11 @@ void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* men
}
}
}
- else if (midiInstrument->groups()->size() == 1 ){
+ else if (pg.size() == 1 ){
// no groups
- const MusECore::PatchList& pl = midiInstrument->groups()->front()->patches;
- for (MusECore::ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
- const MusECore::Patch* mp = *ipl;
+ const PatchList& pl = pg.front()->patches;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
if (mp->typ & mask) {
int id = ((mp->hbank & 0xff) << 16)
+ ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff);
@@ -999,6 +995,7 @@ void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* men
}
}
}
- }
-} // namespace MusEGui
+ }
+
+} // namespace MusECore
diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h
index 3a645d7f..385e67b4 100644
--- a/muse2/muse/instruments/minstrument.h
+++ b/muse2/muse/instruments/minstrument.h
@@ -143,7 +143,7 @@ class MidiInstrument {
virtual void reset(int, MType);
virtual QString getPatchName(int,int,MType,bool);
//virtual void populatePatchPopup(QMenu*, int, MType, bool);
- //virtual void populatePatchPopup(MusEGui::PopupMenu*, int, MType, bool);
+ virtual void populatePatchPopup(MusEGui::PopupMenu*, int, MType, bool);
void read(Xml&);
void write(int level, Xml&);
@@ -171,8 +171,8 @@ extern void removeMidiInstrument(const MidiInstrument* instr);
} // namespace MusECore
-namespace MusEGui {
-extern void populatePatchPopup(MusECore::MidiInstrument*, PopupMenu*, int, MType, bool);
-}
+//namespace MusEGui {
+//extern void populatePatchPopup(MusECore::MidiInstrument*, PopupMenu*, int, MType, bool);
+//}
#endif
diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/liste/editevent.cpp
index 32a328a8..cc52d26e 100644
--- a/muse2/muse/liste/editevent.cpp
+++ b/muse2/muse/liste/editevent.cpp
@@ -871,20 +871,17 @@ void EditCtrlDialog::instrPopup()
int port = track->outPort();
MusECore::MidiInstrument* instr = MusEGlobal::midiPorts[port].instrument();
- ///instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM);
//QMenu* pup = new QMenu(this);
MusEGui::PopupMenu* pup = new MusEGui::PopupMenu(this);
- populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack());
+ //populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack());
+ instr->populatePatchPopup(pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack());
- ///if(pop->actions().count() == 0)
- /// return;
if(pup->actions().count() == 0)
{
delete pup;
return;
}
- ///QAction* rv = pop->exec(patchName->mapToGlobal(QPoint(10,5)));
QAction* rv = pup->exec(patchName->mapToGlobal(QPoint(10,5)));
if (rv) {
val = rv->data().toInt();
diff --git a/muse2/muse/liste/listedit.cpp b/muse2/muse/liste/listedit.cpp
index eadfa68c..6795cedb 100644
--- a/muse2/muse/liste/listedit.cpp
+++ b/muse2/muse/liste/listedit.cpp
@@ -45,6 +45,7 @@
#include "event.h"
#include "midiport.h"
#include "midictrl.h"
+#include "app.h"
namespace MusEGui {
@@ -183,7 +184,8 @@ static QString midiMetaComment(const MusECore::Event& ev)
void ListEdit::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -193,6 +195,9 @@ void ListEdit::closeEvent(QCloseEvent* e)
void ListEdit::songChanged(int type)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (type == 0)
return;
if (type & (SC_PART_REMOVED | SC_PART_MODIFIED
@@ -465,6 +470,8 @@ QString EventListItem::text(int col) const
ListEdit::ListEdit(MusECore::PartList* pl)
: MidiEditor(TopWin::LISTE, 0, pl)
{
+ selectedTick=0;
+
insertItems = new QActionGroup(this);
insertItems->setExclusive(false);
insertNote = new QAction(QIcon(*note1Icon), tr("insert Note"), insertItems);
@@ -587,7 +594,6 @@ ListEdit::ListEdit(MusECore::PartList* pl)
mainGrid->setColumnStretch(0, 100);
mainGrid->addWidget(liste, 1, 0, 2, 1);
connect(MusEGlobal::song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
- songChanged(-1);
if(pl->empty())
{
@@ -605,10 +611,14 @@ ListEdit::ListEdit(MusECore::PartList* pl)
curPartId = -1;
}
}
+
+ songChanged(-1);
initShortcuts();
setWindowTitle("MusE: List Editor");
+
+ MusEGlobal::muse->topwinMenuInited(this);
}
//---------------------------------------------------------
diff --git a/muse2/muse/liste/listedit.h b/muse2/muse/liste/listedit.h
index 7548fc86..1c0c1bd9 100644
--- a/muse2/muse/liste/listedit.h
+++ b/muse2/muse/liste/listedit.h
@@ -86,7 +86,7 @@ class ListEdit : public MidiEditor {
void songChanged(int);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
ListEdit(MusECore::PartList*);
diff --git a/muse2/muse/main.cpp b/muse2/muse/main.cpp
index 27a8926e..d946bf00 100644
--- a/muse2/muse/main.cpp
+++ b/muse2/muse/main.cpp
@@ -24,6 +24,8 @@
#include <QApplication>
#include <QDir>
#include <QFile>
+#include <QFileInfo>
+#include <QFileInfoList>
#include <QKeyEvent>
#include <QMessageBox>
#include <QLocale>
@@ -31,6 +33,8 @@
#include <QTimer>
#include <QTranslator>
#include <QIcon>
+#include <QString>
+#include <QStringList>
#include <sys/mman.h>
#include <alsa/asoundlib.h>
@@ -41,6 +45,7 @@
#include "audiodev.h"
#include "gconfig.h"
#include "globals.h"
+#include "helper.h"
#include "icons.h"
#include "sync.h"
#include "functions.h"
@@ -267,9 +272,38 @@ int main(int argc, char* argv[])
if (! cPath.exists())
cPath.mkpath(".");
+ // Create user templates dir if it doesn't exist
+ QDir utemplDir = QDir(MusEGlobal::configPath + QString("/templates"));
+ if(!utemplDir.exists())
+ {
+ utemplDir.mkpath(".");
+ // Support old versions: Copy existing templates over.
+ QDir old_utemplDir = QDir(QString(getenv("HOME")) + QString("/templates"));
+ // printf(" old templates dir:%s\n", (QString(getenv("HOME")) + QString("/templates")).toLatin1().constData());
+ if(old_utemplDir.exists())
+ {
+ //printf(" found old templates dir\n");
+ // We really just want these, even though it's possible other filenames were saved.
+ // Another application might have used that directory.
+ QStringList flt; flt << "*.med" << "*.med.gz" << "*.med.bz2" << "*.mid" << "*.midi" << "*.kar";
+ old_utemplDir.setNameFilters(flt);
+
+ QFileInfoList fil = old_utemplDir.entryInfoList();
+ QFileInfo fi;
+ foreach(fi, fil)
+ {
+ QString fn = fi.fileName();
+ QFile f(fi.absoluteFilePath());
+ f.copy(utemplDir.absolutePath() + "/" + fn);
+ //printf(" copy old template to:%s result:%d\n", QString(utemplPath.absolutePath() + "/" + fn).toLatin1().constData(), rv);
+ }
+ }
+ }
+
QFile cConf (MusEGlobal::configName);
QFile cConfTempl (MusEGlobal::museGlobalShare + QString("/templates/MusE.cfg"));
- if (! cConf.exists())
+ bool cConfExists = cConf.exists();
+ if (!cConfExists)
{
printf ("creating new config...\n");
if (cConfTempl.copy(MusEGlobal::configName))
@@ -303,10 +337,51 @@ int main(int argc, char* argv[])
MusEGui::init_function_dialogs(MusEGlobal::muse);
MusEGui::initShortCuts();
+
MusECore::readConfiguration();
- MusEGlobal::museUserInstruments = MusEGlobal::config.userInstrumentsDir;
+ // Need to put a sane default here because we can't use ~ in the file name string.
+ if(!cConfExists)
+ MusEGlobal::config.projectBaseFolder = MusEGlobal::museUser + QString("/MusE");
+ //MusEGlobal::museUserInstruments = MusEGlobal::config.userInstrumentsDir;
+
+ // Create user instruments dir if it doesn't exist
+ {
+ QString uinstrPath = MusEGlobal::configPath + QString("/instruments");
+ QDir uinstrDir = QDir(uinstrPath);
+ if(!uinstrDir.exists())
+ uinstrDir.mkpath(".");
+
+ if(!MusEGlobal::config.userInstrumentsDir.isEmpty() && MusEGlobal::config.userInstrumentsDir != uinstrPath) // Only if it is different.
+ {
+ // Support old versions: Copy existing instruments over.
+ QDir old_uinstrDir(MusEGlobal::config.userInstrumentsDir);
+ //printf(" old instruments dir:%s\n", MusEGlobal::config.userInstrumentsDir.toLatin1().constData());
+ if(old_uinstrDir.exists())
+ {
+ //printf(" found old instruments dir\n");
+ QStringList flt; flt << "*.idf";
+ old_uinstrDir.setNameFilters(flt);
+
+ QFileInfoList fil = old_uinstrDir.entryInfoList();
+ QFileInfo fi;
+ foreach(fi, fil)
+ {
+ QString fn = fi.fileName();
+ QFile f(fi.absoluteFilePath());
+ QFile newf(uinstrDir.absolutePath() + "/" + fn);
+ if(!newf.exists())
+ {
+ f.copy(newf.fileName());
+ //printf(" copy old instrument to:%s result:%d\n", newf.fileName().toLatin1().constData(), rv);
+ }
+ }
+ }
+ }
+ MusEGlobal::museUserInstruments = uinstrPath;
+ }
+
if (MusEGlobal::config.useDenormalBias)
printf("Denormal protection enabled.\n");
// SHOW MUSE SPLASH SCREEN
@@ -324,7 +399,7 @@ int main(int argc, char* argv[])
stimer->start(6000);
}
}
-
+
int i;
QString optstr("ahvdDmMsP:Y:l:py");
@@ -393,6 +468,7 @@ int main(int argc, char* argv[])
}
*/
+
AL::initDsp();
if (MusEGlobal::debugMsg)
@@ -438,8 +514,7 @@ int main(int argc, char* argv[])
else
MusEGlobal::realTimeScheduling = MusEGlobal::audioDevice->isRealtime();
-
- // What unreliable nonsense. With Jack2 this reports true even if it is not running realtime.
+ // ??? With Jack2 this reports true even if it is not running realtime.
// Jack says: "Cannot use real-time scheduling (RR/10)(1: Operation not permitted)". The kernel is non-RT.
// I cannot seem to find a reliable answer to the question, even with dummy audio and system calls.
//if (MusEGlobal::debugMsg)
@@ -448,11 +523,7 @@ int main(int argc, char* argv[])
MusEGlobal::useJackTransport.setValue(true);
// setup the prefetch fifo length now that the segmentSize is known
- // Changed by Tim. p3.3.17
- // Changed to 4 *, JUST FOR TEST!!!
MusEGlobal::fifoLength = 131072 / MusEGlobal::segmentSize;
- //MusEGlobal::fifoLength = (131072 / MusEGlobal::segmentSize) * 4;
-
argc -= optind;
++argc;
@@ -486,7 +557,9 @@ int main(int argc, char* argv[])
printf("locale de\n");
MusEGlobal::hIsB = false;
}
-
+
+ MusEGui::retranslate_function_dialogs();
+
if (MusEGlobal::loadPlugins)
MusECore::initPlugins();
@@ -496,7 +569,6 @@ int main(int argc, char* argv[])
if(MusEGlobal::loadDSSI)
MusECore::initDSSI();
- // p3.3.39
MusECore::initOSC();
MusEGui::initIcons();
@@ -515,21 +587,19 @@ int main(int argc, char* argv[])
++it;
}
}
-
+
MusEGlobal::muse = new MusEGui::MusE(argc, &argv[optind]);
app.setMuse(MusEGlobal::muse);
MusEGlobal::muse->setWindowIcon(*MusEGui::museIcon);
-
- // Added by Tim. p3.3.22
if (!MusEGlobal::debugMode) {
if (mlockall(MCL_CURRENT | MCL_FUTURE))
perror("WARNING: Cannot lock memory:");
}
MusEGlobal::muse->show();
- MusEGlobal::muse->seqStart();
-
+ MusEGlobal::muse->seqStart();
+
#ifdef HAVE_LASH
{
MusEGui::lash_client = 0;
@@ -540,14 +610,28 @@ int main(int argc, char* argv[])
MusEGui::lash_client = lash_init (lash_args, muse_name, lash_flags, LASH_PROTOCOL(2,0));
lash_alsa_client_id (MusEGui::lash_client, snd_seq_client_id (MusECore::alsaSeq));
if (!noAudio) {
- // p3.3.38
- //char *jack_name = ((JackAudioDevice*)MusEGlobal::audioDevice)->getJackName();
const char *jack_name = MusEGlobal::audioDevice->clientName();
lash_jack_client_name (MusEGui::lash_client, jack_name);
}
}
}
#endif /* HAVE_LASH */
+
+ //--------------------------------------------------
+ // Auto-fill the midi ports, if appropriate. p4.0.41
+ //--------------------------------------------------
+ if(argc < 2 && MusEGlobal::config.startMode == 1)
+ {
+ MusEGui::populateMidiPorts();
+ //MusEGlobal::muse->changeConfig(true); // save configuration file
+ //MusEGlobal::song->update();
+ }
+
+ //--------------------------------------------------
+ // Load the default song.
+ //--------------------------------------------------
+ MusEGlobal::muse->loadDefaultSong(argc, &argv[optind]); // p4.0.41
+
QTimer::singleShot(100, MusEGlobal::muse, SLOT(showDidYouKnowDialog()));
int rv = app.exec();
diff --git a/muse2/muse/marker/markerview.cpp b/muse2/muse/marker/markerview.cpp
index bc9e48b9..39ce4fc0 100644
--- a/muse2/muse/marker/markerview.cpp
+++ b/muse2/muse/marker/markerview.cpp
@@ -26,6 +26,7 @@
#include "markerview.h"
#include "xml.h"
#include "globals.h"
+#include "app.h"
#include "sync.h"
#include "icons.h"
#include "song.h"
@@ -157,7 +158,7 @@ void MarkerItem::setTick(unsigned v)
void MarkerView::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
emit closed();
e->accept();
}
@@ -296,6 +297,8 @@ MarkerView::MarkerView(QWidget* parent)
updateList();
+ MusEGlobal::muse->topwinMenuInited(this);
+
// work around for probable QT/WM interaction bug.
// for certain window managers, e.g xfce, this window is
// is displayed although not specifically set to show();
diff --git a/muse2/muse/marker/markerview.h b/muse2/muse/marker/markerview.h
index b50ab7a4..06e22daf 100644
--- a/muse2/muse/marker/markerview.h
+++ b/muse2/muse/marker/markerview.h
@@ -96,7 +96,7 @@ class MarkerView : public TopWin {
void songChanged(int);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
void closed();
public:
diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp
index bf31cc91..f461e1d3 100644
--- a/muse2/muse/master/lmaster.cpp
+++ b/muse2/muse/master/lmaster.cpp
@@ -27,6 +27,7 @@
#include "xml.h"
#include "song.h"
#include "globals.h"
+#include "app.h"
#include "audio.h"
//#include "posedit.h"
//#include "sigedit.h"
@@ -122,7 +123,9 @@ namespace MusEGui {
void LMaster::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -132,6 +135,9 @@ void LMaster::closeEvent(QCloseEvent* e)
void LMaster::songChanged(int type)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (type & (SC_SIG | SC_TEMPO | SC_KEY ))
updateList();
}
@@ -281,6 +287,7 @@ LMaster::LMaster()
connect(keyButton, SIGNAL(clicked()), SLOT(insertKey()));
initShortcuts();
+ MusEGlobal::muse->topwinMenuInited(this);
}
//---------------------------------------------------------
diff --git a/muse2/muse/master/lmaster.h b/muse2/muse/master/lmaster.h
index 6bc90019..33b40f30 100644
--- a/muse2/muse/master/lmaster.h
+++ b/muse2/muse/master/lmaster.h
@@ -173,7 +173,7 @@ class LMaster : public MidiEditor {
void configChanged();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
void seekTo(int tick);
public:
diff --git a/muse2/muse/master/master.cpp b/muse2/muse/master/master.cpp
index 50c3f518..02bef8a1 100644
--- a/muse2/muse/master/master.cpp
+++ b/muse2/muse/master/master.cpp
@@ -27,6 +27,8 @@
#include <QEvent>
#include <QMouseEvent>
#include <QPainter>
+#include <QList>
+#include <QPair>
#include "globals.h"
#include "master.h"
@@ -52,6 +54,8 @@ Master::Master(MidiEditor* e, QWidget* parent, int xmag, int ymag)
pos[0] = 0;
pos[1] = 0;
pos[2] = 0;
+ drag = DRAG_OFF;
+ tool = MusEGui::PointerTool; // should be overridden soon anyway, but to be sure...
setFocusPolicy(Qt::StrongFocus); // Tim.
setMouseTracking(true);
connect(MusEGlobal::song, SIGNAL(posChanged(int, unsigned, bool)), this, SLOT(setPos(int, unsigned, bool)));
@@ -288,8 +292,8 @@ void Master::viewMouseReleaseEvent(QMouseEvent*)
bool Master::deleteVal1(unsigned int x1, unsigned int x2)
{
- bool songChanged = false;
-
+ QList< QPair<int,int> > stuff_to_do;
+
MusECore::TempoList* tl = &MusEGlobal::tempomap;
for (MusECore::iTEvent i = tl->begin(); i != tl->end(); ++i) {
if (i->first < x1)
@@ -300,11 +304,17 @@ bool Master::deleteVal1(unsigned int x1, unsigned int x2)
++ii;
if (ii != tl->end()) {
int tempo = ii->second->tempo;
- MusEGlobal::audio->msgDeleteTempo(i->first, tempo, false);
- songChanged = true;
+ // changed by flo: postpone the actual delete operation
+ // to avoid race conditions and invalidating the iterator
+ //MusEGlobal::audio->msgDeleteTempo(i->first, tempo, false);
+ stuff_to_do.append(QPair<int,int>(i->first, tempo));
}
}
- return songChanged;
+
+ for (QList< QPair<int,int> >::iterator it=stuff_to_do.begin(); it!=stuff_to_do.end(); it++)
+ MusEGlobal::audio->msgDeleteTempo(it->first, it->second, false);
+
+ return !stuff_to_do.empty();
}
void Master::deleteVal(int x1, int x2)
diff --git a/muse2/muse/master/masteredit.cpp b/muse2/muse/master/masteredit.cpp
index e9d669e1..f6169766 100644
--- a/muse2/muse/master/masteredit.cpp
+++ b/muse2/muse/master/masteredit.cpp
@@ -37,6 +37,7 @@
#include "doublelabel.h"
///#include "sigedit.h"
#include "globals.h"
+#include "app.h"
#include <values.h>
@@ -59,7 +60,9 @@ int MasterEdit::_rasterInit = 0;
void MasterEdit::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -69,6 +72,9 @@ void MasterEdit::closeEvent(QCloseEvent* e)
void MasterEdit::songChanged(int type)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (type & SC_TEMPO) {
int tempo = MusEGlobal::tempomap.tempo(MusEGlobal::song->cpos());
curTempo->blockSignals(true);
@@ -154,7 +160,7 @@ MasterEdit::MasterEdit()
info->addWidget(tempo);
const char* rastval[] = {
- QT_TRANSLATE_NOOP("@default", "Off"), "Bar", "1/2", "1/4", "1/8", "1/16"
+ QT_TRANSLATE_NOOP("MusEGui::MasterEdit", "Off"), QT_TRANSLATE_NOOP("MusEGui::MasterEdit", "Bar"), "1/2", "1/4", "1/8", "1/16"
};
rasterLabel = new MusEGui::LabelCombo(tr("Snap"), 0);
rasterLabel->setFocusPolicy(Qt::NoFocus);
@@ -264,6 +270,7 @@ MasterEdit::MasterEdit()
connect(canvas, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned)));
initTopwinState();
+ MusEGlobal::muse->topwinMenuInited(this);
}
//---------------------------------------------------------
diff --git a/muse2/muse/master/masteredit.h b/muse2/muse/master/masteredit.h
index fdf8dd71..835ca879 100644
--- a/muse2/muse/master/masteredit.h
+++ b/muse2/muse/master/masteredit.h
@@ -91,7 +91,7 @@ class MasterEdit : public MidiEditor {
// void tempoChanged(double);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
MasterEdit();
diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp
index d5ed119d..85a47ead 100644
--- a/muse2/muse/midi.cpp
+++ b/muse2/muse/midi.cpp
@@ -25,7 +25,6 @@
#include <cmath>
#include <errno.h>
#include <values.h>
-#include <assert.h>
#include "song.h"
#include "midi.h"
@@ -1055,7 +1054,7 @@ void Audio::processMidi()
{
int pitch = ctl & 0x7f; // pitch is now the incoming pitch
pitch = track->map_drum_in(pitch); // pitch is now the mapped (recorded) pitch
- event.setA(ctl & ~0xff | pitch); // map the drum ctrl's value accordingly
+ event.setA((ctl & ~0xff) | pitch); // map the drum ctrl's value accordingly
if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_HIDDEN &&
track->drummap_hidden()[pitch] )
diff --git a/muse2/muse/midictrl.cpp b/muse2/muse/midictrl.cpp
index 11849ce7..c477297e 100644
--- a/muse2/muse/midictrl.cpp
+++ b/muse2/muse/midictrl.cpp
@@ -21,7 +21,6 @@
//
//=========================================================
-#include <assert.h>
#include <stdio.h>
#include "midictrl.h"
@@ -241,7 +240,7 @@ QString midiCtrlName(int ctrl, bool fullyQualified)
//---------------------------------------------------------
MidiController::MidiController()
- : _name(QString(QT_TRANSLATE_NOOP("@default", "Velocity")))
+ : _name(QString("Velocity"))
{
_num = CTRL_VELOCITY;
_minVal = 0;
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp
index d024422c..bc8bbdb0 100644
--- a/muse2/muse/midiedit/dcanvas.cpp
+++ b/muse2/muse/midiedit/dcanvas.cpp
@@ -78,18 +78,18 @@ DEvent::DEvent(MusECore::Event e, MusECore::Part* p, int instr)
// addItem
//---------------------------------------------------------
-void DrumCanvas::addItem(MusECore::Part* part, MusECore::Event& event)
+CItem* DrumCanvas::addItem(MusECore::Part* part, MusECore::Event& event)
{
if (signed(event.tick())<0) {
printf("ERROR: trying to add event before current part!\n");
- return;
+ return NULL;
}
int instr=pitch_and_track_to_instrument(event.pitch(), part->track());
if (instr<0)
{
if (heavyDebugMsg) printf("trying to add event which is hidden or not in any part known to me\n");
- return;
+ return NULL;
}
DEvent* ev = new DEvent(event, part, instr);
@@ -104,6 +104,8 @@ void DrumCanvas::addItem(MusECore::Part* part, MusECore::Event& event)
//part = newPart;
part->setLenTick(part->lenTick()+diff);
}
+
+ return ev;
}
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h
index 9053b3bf..0fd4c9e0 100644
--- a/muse2/muse/midiedit/dcanvas.h
+++ b/muse2/muse/midiedit/dcanvas.h
@@ -124,7 +124,7 @@ class DrumCanvas : public EventCanvas {
void dragEnterEvent(QDragEnterEvent* event);
void dragMoveEvent(QDragMoveEvent*);
void dragLeaveEvent(QDragLeaveEvent*);
- virtual void addItem(MusECore::Part*, MusECore::Event&);
+ virtual CItem* addItem(MusECore::Part*, MusECore::Event&);
virtual void resizeEvent(QResizeEvent*);
virtual void curPartChanged();
int getNextStep(unsigned int pos, int basicStep, int stepSize=1);
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 58875b4d..7adab525 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -53,6 +53,7 @@
#include "vscale.h"
#include "swidget.h"
#include "globals.h"
+#include "app.h"
#include "icons.h"
#include "filedialog.h"
#include "drummap.h"
@@ -139,6 +140,8 @@ void DrumEdit::setHeaderToolTips()
void DrumEdit::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("Drumedit/geometry", saveGeometry());
settings.setValue("Drumedit/windowState", saveState());
@@ -149,7 +152,7 @@ void DrumEdit::closeEvent(QCloseEvent* e)
_dlistWidthInit = *it; //There are only 2 values stored in the sizelist, size of dlist widget and dcanvas widget
it++;
_dcanvasWidthInit = *it;
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -590,6 +593,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
initTopwinState();
+ MusEGlobal::muse->topwinMenuInited(this);
}
//---------------------------------------------------------
@@ -598,6 +602,9 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
void DrumEdit::songChanged1(int bits)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (bits & SC_SOLO)
{
toolbar->setSolo(canvas->track()->solo());
@@ -1007,12 +1014,15 @@ void DrumEdit::cmd(int cmd)
case DrumCanvas::CMD_MODIFY_VELOCITY: modify_velocity(partlist_to_set(parts())); break;
case DrumCanvas::CMD_CRESCENDO: crescendo(partlist_to_set(parts())); break;
case DrumCanvas::CMD_QUANTIZE:
+ {
+ int raster = MusEGui::rasterVals[MusEGui::quantize_dialog->raster_index];
if (quantize_dialog->exec())
quantize_notes(partlist_to_set(parts()), quantize_dialog->range,
- (MusEGlobal::config.division*4)/(1<<quantize_dialog->raster_power2),
+ (MusEGlobal::config.division*4)/raster,
/* quant_len= */false, quantize_dialog->strength,
quantize_dialog->swing, quantize_dialog->threshold);
break;
+ }
case DrumCanvas::CMD_ERASE_EVENT: erase_notes(partlist_to_set(parts())); break;
case DrumCanvas::CMD_DEL: erase_notes(partlist_to_set(parts()),1); break; //delete selected events
case DrumCanvas::CMD_DELETE_OVERLAPS: delete_overlaps(partlist_to_set(parts())); break;
diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h
index 08f485e7..59590d34 100644
--- a/muse2/muse/midiedit/drumedit.h
+++ b/muse2/muse/midiedit/drumedit.h
@@ -170,7 +170,7 @@ class DrumEdit : public MidiEditor {
virtual void updateHScrollRange();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
DrumEdit(MusECore::PartList*, QWidget* parent = 0, const char* name = 0, unsigned initPos = MAXINT);
diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp
index 9941f7e5..3eeb4f84 100644
--- a/muse2/muse/midiedit/ecanvas.cpp
+++ b/muse2/muse/midiedit/ecanvas.cpp
@@ -3,6 +3,7 @@
// Linux Music Editor
// $Id: ecanvas.cpp,v 1.8.2.6 2009/05/03 04:14:00 terminator356 Exp $
// (C) Copyright 2001 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -151,6 +152,17 @@ void EventCanvas::songChanged(int flags)
if (flags & ~SC_SELECTION) {
//items.clear();
+ bool curItemNeedsRestore=false;
+ MusECore::Event storedEvent;
+ int partSn;
+ if (curItem)
+ {
+ curItemNeedsRestore=true;
+ storedEvent=curItem->event();
+ partSn=curItem->part()->sn();
+ }
+ curItem=NULL;
+
items.clearDelete();
start_tick = MAXINT;
end_tick = 0;
@@ -177,7 +189,15 @@ void EventCanvas::songChanged(int flags)
break;
if (e.isNote()) {
- addItem(part, e);
+ CItem* temp = addItem(part, e);
+
+ if (temp && curItemNeedsRestore && e==storedEvent && part->sn()==partSn)
+ {
+ if (curItem!=NULL)
+ printf("THIS SHOULD NEVER HAPPEN: curItemNeedsRestore=true, event fits, but there was already a fitting event!?\n");
+
+ curItem=temp;
+ }
}
}
}
@@ -308,54 +328,54 @@ void EventCanvas::keyPress(QKeyEvent* event)
}
// Select items by key (PianoRoll & DrumEditor)
else if (key == shortcuts[SHRT_SEL_RIGHT].key || key == shortcuts[SHRT_SEL_RIGHT_ADD].key) {
- iCItem i, iRightmost;
- CItem* rightmost = NULL;
- //Get the rightmost selected note (if any)
- for (i = items.begin(); i != items.end(); ++i) {
- if (i->second->isSelected()) {
- iRightmost = i; rightmost = i->second;
- }
- }
- if (rightmost) {
- iCItem temp = iRightmost; temp++;
- //If so, deselect current note and select the one to the right
- if (temp != items.end()) {
- if (key != shortcuts[SHRT_SEL_RIGHT_ADD].key)
- deselectAll();
-
- iRightmost++;
- iRightmost->second->setSelected(true);
- updateSelection();
- }
- }
- //if (rightmost && mapx(rightmost->event().tick()) > width()) for some reason this doesn't this doesnt move the event in view
- // emit followEvent(rightmost->x());
-
+ rciCItem i;
+ for (i = items.rbegin(); i != items.rend(); ++i)
+ if (i->second->isSelected())
+ break;
+
+ if(i == items.rend())
+ i = items.rbegin();
+
+ if(i != items.rbegin())
+ --i;
+ if(i->second)
+ {
+ if (key != shortcuts[SHRT_SEL_RIGHT_ADD].key)
+ deselectAll();
+ CItem* sel = i->second;
+ sel->setSelected(true);
+ updateSelection();
+ if (sel->x() + sel->width() > mapxDev(width()))
+ {
+ int mx = rmapx(sel->x());
+ int newx = mx + rmapx(sel->width()) - width();
+ // Leave a bit of room for the specially-drawn drum notes. But good for piano too.
+ emit horizontalScroll( (newx > mx ? mx - 10: newx + 10) - rmapx(xorg) );
+ }
+ }
}
//Select items by key: (PianoRoll & DrumEditor)
else if (key == shortcuts[SHRT_SEL_LEFT].key || key == shortcuts[SHRT_SEL_LEFT_ADD].key) {
- iCItem i, iLeftmost;
- CItem* leftmost = NULL;
- if (items.size() > 0 ) {
- for (i = items.end(), i--; i != items.begin(); i--) {
- if (i->second->isSelected()) {
- iLeftmost = i; leftmost = i->second;
- }
- }
- if (leftmost) {
- if (iLeftmost != items.begin()) {
- //Add item
- if (key != shortcuts[SHRT_SEL_LEFT_ADD].key)
- deselectAll();
-
- iLeftmost--;
- iLeftmost->second->setSelected(true);
- updateSelection();
- }
- }
- //if (leftmost && mapx(leftmost->event().tick())< 0 ) for some reason this doesn't this doesnt move the event in view
- // emit followEvent(leftmost->x());
- }
+ ciCItem i;
+ for (i = items.begin(); i != items.end(); ++i)
+ if (i->second->isSelected())
+ break;
+
+ if(i == items.end())
+ i = items.begin();
+
+ if(i != items.begin())
+ --i;
+ if(i->second)
+ {
+ if (key != shortcuts[SHRT_SEL_LEFT_ADD].key)
+ deselectAll();
+ CItem* sel = i->second;
+ sel->setSelected(true);
+ updateSelection();
+ if (sel->x() <= mapxDev(0))
+ emit horizontalScroll(rmapx(sel->x() - xorg) - 10); // Leave a bit of room.
+ }
}
else if (key == shortcuts[SHRT_INC_PITCH].key) {
modifySelected(NoteInfo::VAL_PITCH, 1);
diff --git a/muse2/muse/midiedit/ecanvas.h b/muse2/muse/midiedit/ecanvas.h
index 2c783332..ad19480e 100644
--- a/muse2/muse/midiedit/ecanvas.h
+++ b/muse2/muse/midiedit/ecanvas.h
@@ -72,7 +72,7 @@ class EventCanvas : public Canvas {
bool _setCurPartIfOnlyOneEventIsSelected;
void updateSelection();
- virtual void addItem(MusECore::Part*, MusECore::Event&) = 0;
+ virtual CItem* addItem(MusECore::Part*, MusECore::Event&) = 0;
// Added by T356.
virtual QPoint raster(const QPoint&) const;
virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType) = 0;
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index 82a75f7f..8c2a7a87 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -56,6 +56,7 @@
#include "tb1.h"
#include "utils.h"
#include "globals.h"
+#include "app.h"
#include "gconfig.h"
#include "icons.h"
#include "audio.h"
@@ -118,7 +119,7 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
mapper->setMapping(editPasteAction, PianoCanvas::CMD_PASTE);
connect(editPasteAction, SIGNAL(triggered()), mapper, SLOT(map()));
- editPasteDialogAction = menuEdit->addAction(QIcon(*editpasteIconSet), tr("&Paste (with dialog)"));
+ editPasteDialogAction = menuEdit->addAction(QIcon(*editpasteIconSet), tr("Paste (with dialog)"));
mapper->setMapping(editPasteDialogAction, PianoCanvas::CMD_PASTE_DIALOG);
connect(editPasteDialogAction, SIGNAL(triggered()), mapper, SLOT(map()));
@@ -532,6 +533,7 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
}
initTopwinState();
+ MusEGlobal::muse->topwinMenuInited(this);
}
//---------------------------------------------------------
@@ -540,6 +542,8 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
void PianoRoll::songChanged1(int bits)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
if (bits & SC_SOLO)
{
@@ -815,15 +819,19 @@ void PianoRoll::removeCtrl(CtrlEdit* ctrl)
//---------------------------------------------------------
// closeEvent
+// Save state.
+// Disconnect signals which may cause crash due to Qt deferred deletion on close.
//---------------------------------------------------------
void PianoRoll::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("Pianoroll/geometry", saveGeometry());
settings.setValue("Pianoroll/windowState", saveState());
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h
index 0b90b1e6..9b73fc1b 100644
--- a/muse2/muse/midiedit/pianoroll.h
+++ b/muse2/muse/midiedit/pianoroll.h
@@ -176,7 +176,7 @@ class PianoRoll : public MidiEditor {
void updateTrackInfo();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public slots:
virtual void updateHScrollRange();
diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp
index e2a05bda..2c32a1cf 100644
--- a/muse2/muse/midiedit/prcanvas.cpp
+++ b/muse2/muse/midiedit/prcanvas.cpp
@@ -29,6 +29,8 @@
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMouseEvent>
+#include <QList>
+#include <QPair>
#include <set>
@@ -74,11 +76,11 @@ NEvent::NEvent(MusECore::Event& e, MusECore::Part* p, int y) : MusEGui::CItem(e,
// addItem
//---------------------------------------------------------
-void PianoCanvas::addItem(MusECore::Part* part, MusECore::Event& event)
+CItem* PianoCanvas::addItem(MusECore::Part* part, MusECore::Event& event)
{
if (signed(event.tick())<0) {
printf("ERROR: trying to add event before current part!\n");
- return;
+ return NULL;
}
NEvent* ev = new NEvent(event, part, pitch2y(event.pitch()));
@@ -93,6 +95,8 @@ void PianoCanvas::addItem(MusECore::Part* part, MusECore::Event& event)
//part = newPart;
part->setLenTick(part->lenTick()+diff);
}
+
+ return ev;
}
//---------------------------------------------------------
@@ -1086,6 +1090,7 @@ void PianoCanvas::curPartChanged()
void PianoCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int delta)
{
+ QList< QPair<MusECore::EventList*,MusECore::Event> > already_done;
MusEGlobal::audio->msgIdle(true);
MusEGlobal::song->startUndo();
for (MusEGui::iCItem i = items.begin(); i != items.end(); ++i) {
@@ -1097,6 +1102,10 @@ void PianoCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int delta)
continue;
MusECore::MidiPart* part = (MusECore::MidiPart*)(e->part());
+
+ if (already_done.contains(QPair<MusECore::EventList*,MusECore::Event>(part->events(), event)))
+ continue;
+
MusECore::Event newEvent = event.clone();
switch (type) {
@@ -1151,6 +1160,8 @@ void PianoCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int delta)
// Indicate do not do port controller values and clone parts.
//MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part));
MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false));
+
+ already_done.append(QPair<MusECore::EventList*,MusECore::Event>(part->events(), event));
}
MusEGlobal::song->endUndo(SC_EVENT_MODIFIED);
MusEGlobal::audio->msgIdle(false);
diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h
index e9bd654d..35e4975f 100644
--- a/muse2/muse/midiedit/prcanvas.h
+++ b/muse2/muse/midiedit/prcanvas.h
@@ -82,7 +82,7 @@ class PianoCanvas : public EventCanvas {
virtual void dragEnterEvent(QDragEnterEvent* event);
virtual void dragMoveEvent(QDragMoveEvent*);
virtual void dragLeaveEvent(QDragLeaveEvent*);
- virtual void addItem(MusECore::Part*, MusECore::Event&);
+ virtual CItem* addItem(MusECore::Part*, MusECore::Event&);
int y2pitch(int) const;
int pitch2y(int) const;
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 2d24fa54..ff1893ce 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -88,10 +88,6 @@ QString IntToQStr(int i);
-#define APPLY_TO_SELECTED_STRING tr("Apply to selected notes:")
-#define APPLY_TO_NEW_STRING tr("Apply to new notes:")
-
-
//PIXELS_PER_NOTEPOS must be greater or equal to 3*NOTE_XLEN + 2*NOTE_SHIFT
//because if tick 0 is at x=0: the notes can be shifted by NOTE_SHIFT.
//additionally, they can be moved by NOTE_XLEN (collision avoiding)
@@ -170,6 +166,15 @@ QColor* mycolors; // array [NUM_MYCOLORS]
set<QString> ScoreEdit::names;
+int ScoreCanvas::_quant_power2_init=3;
+int ScoreCanvas::_pixels_per_whole_init=300;
+int ScoreCanvas::note_velo_init=64;
+int ScoreCanvas::note_velo_off_init=64;
+int ScoreCanvas::new_len_init=0;
+ScoreCanvas::coloring_mode_t ScoreCanvas::coloring_mode_init=COLOR_MODE_BLACK;
+bool ScoreCanvas::preamble_contains_timesig_init=true;
+bool ScoreCanvas::preamble_contains_keysig_init=true;
+
//---------------------------------------------------------
// ScoreEdit
@@ -223,6 +228,8 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
xscroll->setMinimum(0);
yscroll->setMinimum(0);
+ xscroll->setValue(0);
+ yscroll->setValue(0);
menu_mapper=new QSignalMapper(this);
connect(menu_mapper, SIGNAL(mapped(int)), SLOT(menu_command(int)));
@@ -295,14 +302,28 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
len_actions->addAction(n32_action);
len_actions->addAction(nlast_action);
- nlast_action->setChecked(true);
- menu_command(CMD_NOTELEN_LAST);
+ switch (ScoreCanvas::new_len_init)
+ {
+ case 0: nlast_action->setChecked(true); menu_command(CMD_NOTELEN_LAST); break;
+ case 1: n1_action->setChecked(true); menu_command(CMD_NOTELEN_1); break;
+ case 2: n2_action->setChecked(true); menu_command(CMD_NOTELEN_2); break;
+ case 4: n4_action->setChecked(true); menu_command(CMD_NOTELEN_4); break;
+ case 8: n8_action->setChecked(true); menu_command(CMD_NOTELEN_8); break;
+ case 16: n16_action->setChecked(true); menu_command(CMD_NOTELEN_16); break;
+ case 32: n32_action->setChecked(true); menu_command(CMD_NOTELEN_32); break;
+ default:
+ cerr << "ERROR: THIS SHOULD NEVER HAPPEN. newLen is invalid in ScoreEdit::ScoreEdit.\n" <<
+ " (newLen="<<ScoreCanvas::new_len_init<<"; the only valid values are 0,1,2,4,8,16 and 32)\n" <<
+ " however, don't worry, this is no major problem, using 0 instead" << endl;
+ nlast_action->setChecked(true);
+ menu_command(CMD_NOTELEN_LAST);
+ }
note_settings_toolbar->addSeparator();
- apply_velo_to_label = new QLabel(APPLY_TO_NEW_STRING, note_settings_toolbar);
- int w1 = apply_velo_to_label->fontMetrics().width(APPLY_TO_NEW_STRING);
- int w2 = apply_velo_to_label->fontMetrics().width(APPLY_TO_SELECTED_STRING);
+ apply_velo_to_label = new QLabel(tr("Apply to new notes:"), note_settings_toolbar);
+ int w1 = apply_velo_to_label->fontMetrics().width(tr("Apply to new notes:"));
+ int w2 = apply_velo_to_label->fontMetrics().width(tr("Apply to selected notes:"));
if (w1>w2)
apply_velo_to_label->setFixedWidth(w1+5);
else
@@ -318,7 +339,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
connect(velo_spinbox, SIGNAL(editingFinished()), SLOT(velo_box_changed()));
connect(this,SIGNAL(velo_changed(int)), score_canvas, SLOT(set_velo(int)));
note_settings_toolbar->addWidget(velo_spinbox);
- velo_spinbox->setValue(64);
+ velo_spinbox->setValue(ScoreCanvas::note_velo_init);
note_settings_toolbar->addWidget(new QLabel(tr("Off-Velocity:"), note_settings_toolbar));
velo_off_spinbox = new QSpinBox(this);
@@ -329,7 +350,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
connect(velo_off_spinbox, SIGNAL(editingFinished()), SLOT(velo_off_box_changed()));
connect(this,SIGNAL(velo_off_changed(int)), score_canvas, SLOT(set_velo_off(int)));
note_settings_toolbar->addWidget(velo_off_spinbox);
- velo_off_spinbox->setValue(64);
+ velo_off_spinbox->setValue(ScoreCanvas::note_velo_off_init);
@@ -338,13 +359,16 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
quant_toolbar->addWidget(new QLabel(tr("Quantisation:"), quant_toolbar));
quant_combobox = new QComboBox(this);
quant_combobox->addItem("2"); // if you add or remove items from
- quant_combobox->addItem("4"); // here, also change quant_mapper[]
- quant_combobox->addItem("8"); // in ScoreCanvas::set_quant()!
+ quant_combobox->addItem("4"); // here, also change all code regarding
+ quant_combobox->addItem("8"); // _quant_power2 and _quant_power2_init
quant_combobox->addItem("16"); // and MAX_QUANT_POWER (must be log2(largest_value))
quant_combobox->addItem("32");
+ quant_combobox->setCurrentIndex(score_canvas->quant_power2()-1);
+ // the above is intendedly executed BEFORE connecting. otherwise this would
+ // destroy pixels_per_whole_init!
connect(quant_combobox, SIGNAL(currentIndexChanged(int)), score_canvas, SLOT(set_quant(int)));
quant_toolbar->addWidget(quant_combobox);
- quant_combobox->setCurrentIndex(2);
+
quant_toolbar->addSeparator();
@@ -355,7 +379,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
connect(px_per_whole_spinbox, SIGNAL(valueChanged(int)), score_canvas, SLOT(set_pixels_per_whole(int)));
connect(score_canvas, SIGNAL(pixels_per_whole_changed(int)), px_per_whole_spinbox, SLOT(setValue(int)));
quant_toolbar->addWidget(px_per_whole_spinbox);
- px_per_whole_spinbox->setValue(300);
+ px_per_whole_spinbox->setValue(ScoreCanvas::_pixels_per_whole_init);
QMenu* edit_menu = menuBar()->addMenu(tr("&Edit"));
@@ -456,8 +480,18 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
menu_mapper->setMapping(color_velo_action, CMD_COLOR_VELO);
menu_mapper->setMapping(color_part_action, CMD_COLOR_PART);
- color_black_action->setChecked(true);
- menu_command(CMD_COLOR_BLACK);
+ switch (ScoreCanvas::coloring_mode_init)
+ {
+ case 0: color_black_action->setChecked(true); menu_command(CMD_COLOR_BLACK); break;
+ case 1: color_velo_action->setChecked(true); menu_command(CMD_COLOR_VELO); break;
+ case 2: color_part_action->setChecked(true); menu_command(CMD_COLOR_PART); break;
+ default:
+ cerr << "ERROR: THIS SHOULD NEVER HAPPEN. noteColor is invalid in ScoreEdit::ScoreEdit.\n" <<
+ " (noteColor="<<ScoreCanvas::coloring_mode_init<<"; the only valid values are 0,1 and 2)\n" <<
+ " however, don't worry, this is no major problem, using 0 instead" << endl;
+ color_black_action->setChecked(true);
+ menu_command(CMD_COLOR_BLACK);
+ }
QMenu* preamble_menu = settings_menu->addMenu(tr("Set up &preamble"));
preamble_keysig_action = preamble_menu->addAction(tr("Display &key signature"));
@@ -468,8 +502,8 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
preamble_keysig_action->setCheckable(true);
preamble_timesig_action->setCheckable(true);
- preamble_keysig_action->setChecked(true);
- preamble_timesig_action->setChecked(true);
+ preamble_keysig_action->setChecked(ScoreCanvas::preamble_contains_keysig_init);
+ preamble_timesig_action->setChecked(ScoreCanvas::preamble_contains_timesig_init);
QAction* set_name_action = settings_menu->addAction(tr("Set Score &name"), menu_mapper, SLOT(map()));
menu_mapper->setMapping(set_name_action, CMD_SET_NAME);
@@ -505,6 +539,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
apply_velo=true;
initTopwinState();
+ MusEGlobal::muse->topwinMenuInited(this);
}
void ScoreEdit::init_shortcuts()
@@ -589,7 +624,7 @@ bool ScoreEdit::set_name(QString newname, bool emit_signal, bool emergency_name)
ScoreEdit::~ScoreEdit()
{
-
+ names.erase(name);
}
void ScoreEdit::velo_box_changed()
@@ -604,16 +639,19 @@ void ScoreEdit::velo_off_box_changed()
void ScoreEdit::song_changed(int flags)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (flags & (SC_SELECTION | SC_EVENT_MODIFIED | SC_EVENT_REMOVED))
{
map<MusECore::Event*, MusECore::Part*> selection=get_events(score_canvas->get_all_parts(),1);
if (selection.empty())
{
- apply_velo_to_label->setText(APPLY_TO_NEW_STRING);
+ apply_velo_to_label->setText(tr("Apply to new notes:"));
}
else
{
- apply_velo_to_label->setText(APPLY_TO_SELECTED_STRING);
+ apply_velo_to_label->setText(tr("Apply to selected notes:"));
int velo=-1;
int velo_off=-1;
@@ -659,6 +697,7 @@ void ScoreEdit::canvas_height_changed(int height)
void ScoreEdit::viewport_height_changed(int height)
{
int val=score_canvas->canvas_height() - height;
+ // FINDMICHJETZT canvas_height() is uninitalized!
if (val<0) val=0;
yscroll->setPageStep(height * PAGESTEP);
yscroll->setMaximum(val);
@@ -671,11 +710,14 @@ void ScoreEdit::viewport_height_changed(int height)
void ScoreEdit::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+ names.erase(name);
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("ScoreEdit/geometry", saveGeometry());
settings.setValue("ScoreEdit/windowState", saveState());
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -688,8 +730,8 @@ void ScoreEdit::menu_command(int cmd)
{
bool ok;
QString newname = QInputDialog::getText(this, tr("Enter the new score title"),
- tr("Enter the new score title"), QLineEdit::Normal,
- name, &ok);
+ tr("Enter the new score title"), QLineEdit::Normal,
+ name, &ok);
if (ok)
{
if (!set_name(newname))
@@ -1055,7 +1097,23 @@ void ScoreEdit::read_configuration(MusECore::Xml& xml)
switch (token)
{
case MusECore::Xml::TagStart:
- if (tag == "topwin")
+ if (tag=="quantPowerInit")
+ ScoreCanvas::_quant_power2_init=xml.parseInt();
+ else if (tag=="pxPerWholeInit")
+ ScoreCanvas::_pixels_per_whole_init=xml.parseInt();
+ else if (tag=="newNoteVeloInit")
+ ScoreCanvas::note_velo_init=xml.parseInt();
+ else if (tag=="newNoteVeloOffInit")
+ ScoreCanvas::note_velo_off_init=xml.parseInt();
+ else if (tag=="newLenInit")
+ ScoreCanvas::new_len_init=xml.parseInt();
+ else if (tag=="noteColorInit")
+ ScoreCanvas::coloring_mode_init=(ScoreCanvas::coloring_mode_t)xml.parseInt();
+ else if (tag=="preambleContainsKeysig")
+ ScoreCanvas::preamble_contains_keysig_init=xml.parseInt();
+ else if (tag=="preambleContainsTimesig")
+ ScoreCanvas::preamble_contains_timesig_init=xml.parseInt();
+ else if (tag == "topwin")
TopWin::readConfiguration(SCORE, xml);
else
xml.unknown("ScoreEdit");
@@ -1075,7 +1133,18 @@ void ScoreEdit::read_configuration(MusECore::Xml& xml)
void ScoreEdit::write_configuration(int level, MusECore::Xml& xml)
{
xml.tag(level++, "scoreedit");
+
+ xml.intTag(level, "quantPowerInit", ScoreCanvas::_quant_power2_init);
+ xml.intTag(level, "pxPerWholeInit", ScoreCanvas::_pixels_per_whole_init);
+ xml.intTag(level, "newNoteVeloInit", ScoreCanvas::note_velo_init);
+ xml.intTag(level, "newNoteVeloOffInit", ScoreCanvas::note_velo_off_init);
+ xml.intTag(level, "newLenInit", ScoreCanvas::new_len_init);
+ xml.intTag(level, "noteColorInit", ScoreCanvas::coloring_mode_init);
+ xml.intTag(level, "preambleContainsKeysig", ScoreCanvas::preamble_contains_keysig_init);
+ xml.intTag(level, "preambleContainsTimesig", ScoreCanvas::preamble_contains_timesig_init);
+
TopWin::writeConfiguration(SCORE, level, xml);
+
xml.etag(level, "scoreedit");
}
@@ -1212,22 +1281,20 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget) : View(parent_wi
dragged_event_part=NULL;
last_len=384;
- new_len=-1;
+ new_len=-1; // will be initalized with new_len_init by ScoreEdit::ScoreEdit();
- set_quant(2); //this is actually unneccessary, as while
- //initalizing the quant_combobox, this gets
- //called again. but for safety...
- set_pixels_per_whole(300); //same as above. but safety rocks
+ _quant_power2=_quant_power2_init; // ScoreEdit relies on this to be done!
+ _pixels_per_whole_init = _pixels_per_whole_init;
- set_velo(64);
- set_velo_off(64);
+ note_velo=note_velo_init;
+ note_velo_off_init=note_velo_off_init;
dragging_staff=false;
- coloring_mode=COLOR_MODE_BLACK;
- preamble_contains_keysig=true;
- preamble_contains_timesig=true;
+ coloring_mode=coloring_mode_init;
+ preamble_contains_keysig=preamble_contains_keysig_init;
+ preamble_contains_timesig=preamble_contains_timesig_init;
x_scroll_speed=0;
@@ -1454,6 +1521,9 @@ void ScoreCanvas::fully_recalculate()
void ScoreCanvas::song_changed(int flags)
{
+ if(parent && parent->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
if (flags & (SC_PART_MODIFIED | SC_PART_REMOVED | SC_PART_INSERTED | SC_TRACK_REMOVED))
{
update_parts();
@@ -1503,7 +1573,7 @@ int ScoreCanvas::canvas_width()
int ScoreCanvas::canvas_height()
{
- return staves.rbegin()->y_bottom;
+ return staves.empty() ? 0 : staves.rbegin()->y_bottom;
}
int ScoreCanvas::viewport_width()
@@ -1532,7 +1602,7 @@ void color_image(QImage& img, const QColor& color)
{
uchar* ptr=img.bits();
//int bytes=img.byteCount();
- int bytes=img.bytesPerLine() * img.height(); // By Tim. For older Qt versions. Tested OK on Qt4.5.
+ int bytes=img.bytesPerLine() * img.height(); // By Tim. For older Qt versions. Tested OK on Qt4.5.
int r,g,b;
color.getRgb(&r,&g,&b);
@@ -2793,6 +2863,7 @@ void ScoreCanvas::draw_note_lines(QPainter& p, int y, bool reserve_akkolade_spac
{
int xbegin = reserve_akkolade_space ? AKKOLADE_LEFTMARGIN+AKKOLADE_WIDTH+AKKOLADE_RIGHTMARGIN : 0;
int xend=width();
+ // FINDMICHJETZT y is uninitalized!
p.setPen(Qt::black);
@@ -4183,7 +4254,7 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
{
switch (MusEGlobal::song->follow())
{
- case MusECore::Song::NO: break;
+ case MusECore::Song::NO: break;
case MusECore::Song::JUMP: goto_tick(tick,false); break;
case MusECore::Song::CONTINUOUS: goto_tick(tick,true); break;
}
@@ -4277,16 +4348,16 @@ void ScoreCanvas::menu_command(int cmd)
{
switch (cmd)
{
- case CMD_COLOR_BLACK: coloring_mode=COLOR_MODE_BLACK; redraw(); break;
- case CMD_COLOR_PART: coloring_mode=COLOR_MODE_PART; redraw(); break;
- case CMD_COLOR_VELO: coloring_mode=COLOR_MODE_VELO; redraw(); break;
- case CMD_NOTELEN_1: new_len=TICKS_PER_WHOLE/ 1; break;
- case CMD_NOTELEN_2: new_len=TICKS_PER_WHOLE/ 2; break;
- case CMD_NOTELEN_4: new_len=TICKS_PER_WHOLE/ 4; break;
- case CMD_NOTELEN_8: new_len=TICKS_PER_WHOLE/ 8; break;
- case CMD_NOTELEN_16: new_len=TICKS_PER_WHOLE/16; break;
- case CMD_NOTELEN_32: new_len=TICKS_PER_WHOLE/32; break;
- case CMD_NOTELEN_LAST: new_len=-1; break;
+ case CMD_COLOR_BLACK: coloring_mode_init=coloring_mode=COLOR_MODE_BLACK; redraw(); break;
+ case CMD_COLOR_PART: coloring_mode_init=coloring_mode=COLOR_MODE_PART; redraw(); break;
+ case CMD_COLOR_VELO: coloring_mode_init=coloring_mode=COLOR_MODE_VELO; redraw(); break;
+ case CMD_NOTELEN_1: new_len_init= 1; new_len=TICKS_PER_WHOLE/ 1; break;
+ case CMD_NOTELEN_2: new_len_init= 2; new_len=TICKS_PER_WHOLE/ 2; break;
+ case CMD_NOTELEN_4: new_len_init= 4; new_len=TICKS_PER_WHOLE/ 4; break;
+ case CMD_NOTELEN_8: new_len_init= 8; new_len=TICKS_PER_WHOLE/ 8; break;
+ case CMD_NOTELEN_16: new_len_init=16; new_len=TICKS_PER_WHOLE/16; break;
+ case CMD_NOTELEN_32: new_len_init=32; new_len=TICKS_PER_WHOLE/32; break;
+ case CMD_NOTELEN_LAST: new_len_init= 0; new_len=-1; break;
default:
cerr << "ERROR: ILLEGAL FUNCTION CALL: ScoreCanvas::menu_command called with unknown command ("<<cmd<<")"<<endl;
@@ -4296,23 +4367,24 @@ void ScoreCanvas::menu_command(int cmd)
void ScoreCanvas::preamble_keysig_slot(bool state)
{
preamble_contains_keysig=state;
+ preamble_contains_keysig_init=state;
redraw();
}
void ScoreCanvas::preamble_timesig_slot(bool state)
{
preamble_contains_timesig=state;
+ preamble_contains_timesig_init=state;
redraw();
}
void ScoreCanvas::set_quant(int val)
{
- int quant_mapper[]={1,2,3,4,5};
-
- if ((val>=0) && (val<signed(sizeof(quant_mapper)/sizeof(*quant_mapper))))
+ if ((val>=0) && (val<5))
{
int old_len=quant_len();
- _quant_power2=quant_mapper[val];
+ _quant_power2=val+1;
+ _quant_power2_init=_quant_power2;
set_pixels_per_whole(pixels_per_whole() * quant_len() / old_len );
@@ -4339,6 +4411,7 @@ void ScoreCanvas::set_pixels_per_whole(int val)
// zero!)
_pixels_per_whole=val;
+ _pixels_per_whole_init=val;
for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++)
it->calc_item_pos();
@@ -4380,6 +4453,7 @@ void ScoreCanvas::maybe_close_if_empty()
void ScoreCanvas::set_velo(int velo)
{
note_velo=velo;
+ note_velo_init=velo;
if (parent->get_apply_velo())
modify_velocity(get_all_parts(),1, 0,velo);
@@ -4388,6 +4462,7 @@ void ScoreCanvas::set_velo(int velo)
void ScoreCanvas::set_velo_off(int velo)
{
note_velo_off=velo;
+ note_velo_off_init=velo;
if (parent->get_apply_velo())
modify_off_velocity(get_all_parts(),1, 0,velo);
@@ -4583,13 +4658,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
/* BUGS and potential bugs
* o tied notes don't work properly when there's a key-change in
* between, for example, when a cis is tied to a des
- * o schedule_all_same_len_parts: if there are two clones A and B,
- * and both A and B get scheduled to be expanded (because we
- * have one event from A and one event from B), this causes a bug,
- * because after A (and B) got resized, the B-resize is invalid!
- * o when changing toolbarstate when sharing and immediately after that
+ * > o when changing toolbarstate when sharing and immediately after that
* changing "share" status, the changed state isn't stored
- * o arranger state and mixer state aren't stored (says tim)
+ * (could be solved by storing the current window when quitting/saving whatever)
* ? pasting in editors sometimes fails oO? ( ERROR: reading eventlist
* from clipboard failed. ignoring this one... ) [ not reproducible ]
*
@@ -4597,9 +4668,16 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
* o drum controllers
* update ctrlcanvas/panel
* test!
+ * o drum editor is buggy. propagate_drum_map may operate on old values
+ * ("BUGGY! problem is: while changing entries, ourDrumMap
+ may be reallocated which causes abort()s and/or bugs.")
* o don't mix DRUM and NEW_DRUM in drumeditor!
+ * o quantize must round UP, not down when at 0.5
* o my record flag handling
* o option for disabling old-style / new-style drum tracks?
+ * ! o using super glue while a score editor displaying the glued parts
+ * is open lets muse segfault. this may or may not be fixed in
+ * the release branch :/
*
* > o drum editor: channel-stuff
* o clearly state in the changelog: when having multiple drumeditors open,
@@ -4611,6 +4689,11 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
* ask the user if he wants to proceed, and then set maintained_automatically to false
* o offer some way to set maintained_automatically to true again
* o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions
+ * > o fix valgrind problems (the two "FINDMICHJETZT" lines in scoreedit.cpp)
+ * > o add a songposition scrollbar-toolbar (in different sizes)
+ * this might be equivalent to "redo transport menu" (below).
+ * > o add toolbar(s) for tempo- etc spinboxes from the transport window
+ *
*
* o find and fix FINDMICHJETZT
* o fix all segfaults and non-working stuff!
@@ -4626,9 +4709,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
* o all places where i added doubleclick-edits: only react on left-click double clicks!
* o support "new style" reordering with old style drum tracks as well
* (not swapping but inserting!)
+ * o support edge-scrolling when opening a lasso
* o add "dotted quarter" quantize option (for 6/8 beat)
* o ticks-to-quarter spinboxes
- * o newly created windows have to be focussed!
* o mirror most menus to an additional right-click context menu to avoid the long mouse pointer
* journey to the menu bar. try to find a way which does not involve duplicate code!
* o implement borland-style maximize: free windows do not cover the main menu, even when maximized
@@ -4651,6 +4734,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
* o thin out: remove unneeded ctrl messages
*
* less important stuff
+ * o allow "fixating" toolbars?
* o quantize-templates (everything is forced into a specified
* rhythm)
* o part-templates (you specify some notes and a control-chord;
@@ -4662,8 +4746,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
* calc_pos_add_list must be called before calc_item_pos then,
* and calc_item_pos must respect the pos_add_list instead of
* keeping its own pos_add variable (which is only an optimisation)
- * o support edge-scrolling when opening a lasso
- * o save more configuration stuff (quant, color)
*
* really unimportant nice-to-haves
* o support in-song clef-changes
@@ -4676,10 +4758,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
*
*
* stuff for the other muse developers
- * o update translations
- * o remove ambiguous translation: "offset"="zeitversatz"
- * this is ambigous in mod. note len and WRONG in mod. velo dialogs
- *
* o process accurate timesignatures from muse's list (has to be implemented first in muse)
* ( (2+2+3)/4 or (3+2+2)/4 instead of 7/4 )
*/
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 0d1432b8..7a16d19f 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -184,7 +184,7 @@ class ScoreEdit : public TopWin
void clipboard_changed();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
void name_changed();
void velo_changed(int);
void velo_off_changed(int);
@@ -275,6 +275,9 @@ class FloEvent
tick=ti;
source_event=event;
source_part=part;
+
+ num=denom=0xdeadbeef; //unused, but valgrind complains if uninited
+ key=MusECore::KEY_C;
}
FloEvent(unsigned ti, typeEnum t, int num_, int denom_)
{
@@ -284,6 +287,9 @@ class FloEvent
tick=ti;
source_event=NULL;
source_part=NULL;
+
+ len=vel=pitch=0xdeadbeef; //unused, but valgrind complains if uninited
+ key=MusECore::KEY_C;
}
FloEvent(unsigned ti, typeEnum t, MusECore::key_enum k)
{
@@ -292,6 +298,8 @@ class FloEvent
tick=ti;
source_event=NULL;
source_part=NULL;
+
+ pitch=vel=len=num=denom=0xdeadbeef; //unused, but valgrind complains if uninited
}
};
class FloItem
@@ -345,6 +353,7 @@ class FloItem
begin_tick=beg;
source_event=event;
source_part=part;
+ is_active=false;
}
FloItem(typeEnum t, int num_, int denom_)
@@ -659,8 +668,20 @@ class ScoreCanvas : public MusEGui::View
void move_staff_below(list<staff_t>::iterator dest, list<staff_t>::iterator src);
void cleanup_staves();
void maybe_close_if_empty();
-
+
+// defaults ----------------------------------------------------------
+ public:
+ enum coloring_mode_t {COLOR_MODE_BLACK, COLOR_MODE_PART, COLOR_MODE_VELO};
+ static int _quant_power2_init;
+ static int _pixels_per_whole_init;
+ static int note_velo_init, note_velo_off_init;
+ static int new_len_init;
+ static coloring_mode_t coloring_mode_init;
+ static bool preamble_contains_timesig_init;
+ static bool preamble_contains_keysig_init;
+
// member variables ---------------------------------------------------
+ private:
int _quant_power2;
int _pixels_per_whole;
@@ -737,7 +758,7 @@ class ScoreCanvas : public MusEGui::View
bool srec;
bool held_notes[128];
- enum {COLOR_MODE_BLACK, COLOR_MODE_PART, COLOR_MODE_VELO} coloring_mode;
+ coloring_mode_t coloring_mode;
bool preamble_contains_keysig;
bool preamble_contains_timesig;
@@ -767,38 +788,38 @@ class ScoreCanvas : public MusEGui::View
void add_new_parts(const std::map< MusECore::Part*, std::set<MusECore::Part*> >&);
- public slots:
- void x_scroll_event(int);
- void y_scroll_event(int);
- void song_changed(int);
- void fully_recalculate();
- void goto_tick(int,bool);
- void pos_changed(int i, unsigned u, bool b);
- void heartbeat_timer_event();
-
- void set_tool(int);
- void set_quant(int);
- void menu_command(int);
- void preamble_keysig_slot(bool);
- void preamble_timesig_slot(bool);
- void set_pixels_per_whole(int);
+ public slots:
+ void x_scroll_event(int);
+ void y_scroll_event(int);
+ void song_changed(int);
+ void fully_recalculate();
+ void goto_tick(int,bool);
+ void pos_changed(int i, unsigned u, bool b);
+ void heartbeat_timer_event();
- void set_velo(int);
- void set_velo_off(int);
+ void set_tool(int);
+ void set_quant(int);
+ void menu_command(int);
+ void preamble_keysig_slot(bool);
+ void preamble_timesig_slot(bool);
+ void set_pixels_per_whole(int);
- void set_steprec(bool);
-
- void update_parts(); //re-populates the set<MusECore::Part*>s from the set<int>s
+ void set_velo(int);
+ void set_velo_off(int);
+
+ void set_steprec(bool);
+
+ void update_parts(); //re-populates the set<MusECore::Part*>s from the set<int>s
signals:
- void xscroll_changed(int);
- void yscroll_changed(int);
- void viewport_width_changed(int);
- void canvas_width_changed(int);
- void preamble_width_changed(int);
- void viewport_height_changed(int);
- void canvas_height_changed(int);
- void pixels_per_whole_changed(int);
- void pos_add_changed();
+ void xscroll_changed(int);
+ void yscroll_changed(int);
+ void viewport_width_changed(int);
+ void canvas_width_changed(int);
+ void preamble_width_changed(int);
+ void viewport_height_changed(int);
+ void canvas_height_changed(int);
+ void pixels_per_whole_changed(int);
+ void pos_add_changed();
protected:
virtual void draw(QPainter& p, const QRect& rect);
diff --git a/muse2/muse/midifile.cpp b/muse2/muse/midifile.cpp
index a94644ff..1fc7e114 100644
--- a/muse2/muse/midifile.cpp
+++ b/muse2/muse/midifile.cpp
@@ -23,7 +23,6 @@
#include <errno.h>
#include <values.h>
-#include <assert.h>
#include "song.h"
#include "midi.h"
@@ -568,9 +567,9 @@ void MidiFile::writeEvent(const MidiPlayEvent* event)
int nstat = event->type();
// we dont save meta data into smf type 0 files:
-
- if (MusEGlobal::config.smfFormat == 0 && nstat == ME_META)
- return;
+ // Oct 16, 2011: Apparently it is legal to do that. Part of fix for bug tracker 3293339.
+ //if (MusEGlobal::config.smfFormat == 0 && nstat == ME_META)
+ // return;
nstat |= c;
//
@@ -621,24 +620,45 @@ bool MidiFile::write()
writeLong(6); // header len
writeShort(MusEGlobal::config.smfFormat);
if (MusEGlobal::config.smfFormat == 0) {
- writeShort(1);
+ /*
+ //writeShort(1); // Removed. Bug tracker 3293339
MidiFileTrack dst;
for (iMidiFileTrack i = _tracks->begin(); i != _tracks->end(); ++i) {
MPEventList* sl = &((*i)->events);
for (iMPEvent ie = sl->begin(); ie != sl->end(); ++ie)
+ {
+ // ALERT: Observed a problem here, apparently some of the events are being added too fast.
+ // The dump below tells me some of the events (sysex/meta) are missing from the list!
+ // Apparently it's a timing problem. Very puzzling.
+ // Attempting wild-guess fix now to eliminate multiple MidiFileTracks in MusE::exportMidi()...
+ // Nope. Didn't help. Now that it's a single MidiFileTrack, try skipping this section altogether...
+ // Yes that appears to have fixed it. Weird. What's the difference - the local 'dst' variable ?
+ // Or are there still lurking problems, or something more fundamentally wrong with Event or MPEvent?
+ printf("MidiFile::write adding event to dst:\n"); // REMOVE Tim.
+ ie->dump(); // REMOVE Tim.
dst.events.add(*ie);
+ }
}
writeShort(1);
writeShort(_division);
writeTrack(&dst);
+ */
+
+ writeShort(1);
+ //writeShort(_division);
+ //if(!_tracks->empty())
+ // writeTrack(*(_tracks->begin()));
+
}
else {
+
+
writeShort(ntracks);
-
+ }
writeShort(_division);
for (ciMidiFileTrack i = _tracks->begin(); i != _tracks->end(); ++i)
writeTrack(*i);
- }
+/// }
return (ferror(fp) != 0);
}
diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp
index 71a90fe7..b7d1d7b7 100644
--- a/muse2/muse/midiport.cpp
+++ b/muse2/muse/midiport.cpp
@@ -24,6 +24,7 @@
//#include "config.h"
#include <QMenu>
+#include <QApplication>
#include "mididev.h"
#include "midiport.h"
@@ -331,18 +332,18 @@ QMenu* midiPortsPopup(QWidget* parent, int checkPort)
{
MusECore::MidiDevice* md = MusEGlobal::midiPorts[pi].device();
//if(md && !md->isSynti() && (md->rwFlags() & 1))
- //if(md && (md->rwFlags() & 1))
- if(md && (md->rwFlags() & 1 || md->isSynti()) )
+ if(md && (md->rwFlags() & 1))
+ //if(md && (md->rwFlags() & 1 || md->isSynti()) ) // Revert. Hm, why synths? Only writeable ports. p4.0.41
break;
}
if(pi == MIDI_PORTS)
{
- act = p->addAction(p->tr("Warning: No output devices!"));
+ act = p->addAction(qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Warning: No output devices!")));
act->setCheckable(false);
act->setData(-1);
p->addSeparator();
}
- act = p->addAction(QIcon(*MusEGui::settings_midiport_softsynthsIcon), p->tr("Open midi config..."));
+ act = p->addAction(QIcon(*MusEGui::settings_midiport_softsynthsIcon), qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Open midi config...")));
act->setCheckable(false);
act->setData(MIDI_PORTS);
p->addSeparator();
@@ -351,8 +352,12 @@ QMenu* midiPortsPopup(QWidget* parent, int checkPort)
for (int i = 0; i < MIDI_PORTS; ++i) {
MidiPort* port = &MusEGlobal::midiPorts[i];
+ MusECore::MidiDevice* md = port->device();
+ //if(md && !(md->rwFlags() & 1 || md->isSynti()) && (i != checkPort))
+ if(md && !(md->rwFlags() & 1) && (i != checkPort)) // Only writeable ports, or current one.
+ continue;
name.sprintf("%d:%s", port->portno()+1, port->portname().toLatin1().constData());
- if(port->device() || (i == checkPort))
+ if(md || (i == checkPort))
{
act = p->addAction(name);
act->setData(i);
@@ -360,12 +365,12 @@ QMenu* midiPortsPopup(QWidget* parent, int checkPort)
act->setChecked(i == checkPort);
}
- if(!port->device())
+ if(!md)
{
if(!subp) // No submenu yet? Create it now.
{
subp = new QMenu(p);
- subp->setTitle(subp->tr("Empty ports"));
+ subp->setTitle(qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Empty ports")));
//subp->addAction(new MusEGui::MenuTitleItem("Empty Ports", subp));
}
//act = subp->addAction(name); // No need for all those "<None>" names.
diff --git a/muse2/muse/midiseq.cpp b/muse2/muse/midiseq.cpp
index e31db7c7..1e46db11 100644
--- a/muse2/muse/midiseq.cpp
+++ b/muse2/muse/midiseq.cpp
@@ -44,6 +44,7 @@
#include "synth.h"
#include "song.h"
#include "gconfig.h"
+#include <lo/lo_osc_types.h>
namespace MusEGlobal {
MusECore::MidiSeq* midiSeq;
@@ -54,6 +55,12 @@ namespace MusECore {
int MidiSeq::ticker = 0;
+void initMidiSequencer()
+{
+ //MusEGlobal::midiSeq = new MidiSeq(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0, "Midi");
+ MusEGlobal::midiSeq = new MidiSeq("Midi");
+}
+
//---------------------------------------------------------
// readMsg
//---------------------------------------------------------
@@ -819,16 +826,16 @@ void MidiSeq::msgMsg(int id)
void MidiSeq::msgSetMidiDevice(MidiPort* port, MidiDevice* device)
{
- MusECore::AudioMsg msg;
- msg.id = MusECore::SEQM_IDLE;
- msg.a = true;
- Thread::sendMsg(&msg);
-
- port->setMidiDevice(device);
+ MusECore::AudioMsg msg;
+ msg.id = MusECore::SEQM_IDLE;
+ msg.a = true;
+ Thread::sendMsg(&msg);
+
+ port->setMidiDevice(device);
- msg.id = MusECore::SEQM_IDLE;
- msg.a = false;
- Thread::sendMsg(&msg);
+ msg.id = MusECore::SEQM_IDLE;
+ msg.a = false;
+ Thread::sendMsg(&msg);
}
// This does not appear to be used anymore. Was called in Audio::process1, now Audio::processMidi is called directly. p4.0.15 Tim.
diff --git a/muse2/muse/mixer/amixer.cpp b/muse2/muse/mixer/amixer.cpp
index f9ede36c..34c8190b 100644
--- a/muse2/muse/mixer/amixer.cpp
+++ b/muse2/muse/mixer/amixer.cpp
@@ -169,7 +169,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MusEGlobal::MixerConfig* c)
setWindowIcon(*museIcon);
QMenu* menuConfig = menuBar()->addMenu(tr("&Create"));
- MusEGui::populateAddTrack(menuConfig);
+ MusEGui::populateAddTrack(menuConfig,true);
connect(menuConfig, SIGNAL(triggered(QAction *)), MusEGlobal::song, SLOT(addNewTrack(QAction *)));
QMenu* menuView = menuBar()->addMenu(tr("&View"));
diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp
index 10f281fb..9c393a1a 100644
--- a/muse2/muse/mixer/astrip.cpp
+++ b/muse2/muse/mixer/astrip.cpp
@@ -147,6 +147,7 @@ void AudioStrip::songChanged(int val)
// Set the strip label's font.
//label->setFont(MusEGlobal::config.fonts[1]);
setLabelFont();
+ setLabelText();
// Adjust minimum volume slider and label values.
slider->setRange(MusEGlobal::config.minSlider-0.1, 10.0);
@@ -203,7 +204,17 @@ void AudioStrip::songChanged(int val)
pre->setChecked(src->prefader());
pre->blockSignals(false);
}
- }
+
+ // Are there any Aux Track routing paths to this track? Then we cannot process aux for this track!
+ // Hate to do this, but as a quick visual reminder, seems most logical to disable Aux knobs and labels.
+ int rc = track->auxRefCount();
+ int n = auxKnob.size();
+ for (int idx = 0; idx < n; ++idx)
+ {
+ auxKnob[idx]->setEnabled( rc == 0 );
+ auxLabel[idx]->setEnabled( rc == 0 );
+ }
+ }
if (val & SC_AUX) {
int n = auxKnob.size();
for (int idx = 0; idx < n; ++idx) {
@@ -333,11 +344,14 @@ void AudioStrip::updateOffState()
stereo->setEnabled(val);
label->setEnabled(val);
+ // Are there any Aux Track routing paths to this track? Then we cannot process aux for this track!
+ // Hate to do this, but as a quick visual reminder, seems most logical to disable Aux knobs and labels.
+ bool ae = track->auxRefCount() == 0 && val;
int n = auxKnob.size();
for (int i = 0; i < n; ++i)
{
- auxKnob[i]->setEnabled(val);
- auxLabel[i]->setEnabled(val);
+ auxKnob[i]->setEnabled(ae);
+ auxLabel[i]->setEnabled(ae);
}
if (pre)
@@ -348,12 +362,12 @@ void AudioStrip::updateOffState()
solo->setEnabled(val);
if (mute)
mute->setEnabled(val);
- if (autoType)
- autoType->setEnabled(val);
- if (iR)
- iR->setEnabled(val);
- if (oR)
- oR->setEnabled(val);
+ //if (autoType)
+ // autoType->setEnabled(val);
+ //if (iR)
+ // iR->setEnabled(val);
+ //if (oR)
+ // oR->setEnabled(val);
if (off) {
off->blockSignals(true);
off->setChecked(track->off());
@@ -799,6 +813,12 @@ AudioStrip::AudioStrip(QWidget* parent, MusECore::AudioTrack* at)
double val = MusECore::fast_log10(t->auxSend(idx))*20.0;
ak->setValue(val);
al->setValue(val);
+
+ // Are there any Aux Track routing paths to this track? Then we cannot process aux for this track!
+ // Hate to do this, but as a quick visual reminder, seems most logical to disable Aux knobs and labels.
+ int rc = track->auxRefCount();
+ ak->setEnabled( rc == 0 );
+ al->setEnabled( rc == 0 );
}
}
else {
diff --git a/muse2/muse/mixer/mstrip.cpp b/muse2/muse/mixer/mstrip.cpp
index 2e51feb9..dc495aa6 100644
--- a/muse2/muse/mixer/mstrip.cpp
+++ b/muse2/muse/mixer/mstrip.cpp
@@ -448,9 +448,8 @@ void MidiStrip::updateOffState()
// TODO: Disabled for now.
//if (autoType)
// autoType->setEnabled(val);
- if (iR)
- iR->setEnabled(val);
- // TODO: Disabled for now.
+ //if (iR)
+ // iR->setEnabled(val);
//if (oR)
// oR->setEnabled(val);
if (off) {
@@ -504,6 +503,7 @@ void MidiStrip::songChanged(int val)
// Set the strip label's font.
//label->setFont(MusEGlobal::config.fonts[1]);
setLabelFont();
+ setLabelText();
}
}
diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp
index 5f5e5e39..146d981c 100644
--- a/muse2/muse/mixer/strip.cpp
+++ b/muse2/muse/mixer/strip.cpp
@@ -29,6 +29,8 @@
#include <QColor>
#include <QVBoxLayout>
#include <QFrame>
+#include <QMouseEvent>
+#include <QMenu>
#include "globals.h"
#include "gconfig.h"
@@ -165,7 +167,8 @@ void Strip::setLabelText()
//gradient.setColorAt(0, c.darker());
//gradient.setColorAt(0, c);
//gradient.setColorAt(1, c.darker());
- gradient.setColorAt(0, c.lighter());
+ gradient.setColorAt(0, c);
+ gradient.setColorAt(0.5, c.lighter());
gradient.setColorAt(1, c);
//palette.setBrush(QPalette::Button, gradient);
//palette.setBrush(QPalette::Window, gradient);
@@ -307,6 +310,23 @@ void Strip::resizeEvent(QResizeEvent* ev)
setLabelText();
setLabelFont();
}
-
+
+void Strip::mousePressEvent(QMouseEvent* ev)
+{
+ if (ev->button() == Qt::RightButton) {
+ QMenu* menu = new QMenu;
+ menu->addAction(tr("Remove track?"));
+ QPoint pt = QCursor::pos();
+ QAction* act = menu->exec(pt, 0);
+ if (!act)
+ {
+ delete menu;
+ return;
+ }
+ MusEGlobal::song->removeTrack0(track);
+ MusEGlobal::audio->msgUpdateSoloStates();
+ }
+}
+
} // namespace MusEGui
diff --git a/muse2/muse/mixer/strip.h b/muse2/muse/mixer/strip.h
index 5b3b541b..d0cde1a6 100644
--- a/muse2/muse/mixer/strip.h
+++ b/muse2/muse/mixer/strip.h
@@ -73,6 +73,7 @@ class Strip : public QFrame {
MusEGui::ComboBox* autoType;
void setLabelText();
virtual void resizeEvent(QResizeEvent*);
+ virtual void mousePressEvent(QMouseEvent *);
private slots:
void recordToggled(bool);
diff --git a/muse2/muse/mpevent.cpp b/muse2/muse/mpevent.cpp
index f72af528..8b65bce1 100644
--- a/muse2/muse/mpevent.cpp
+++ b/muse2/muse/mpevent.cpp
@@ -18,7 +18,6 @@
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
//=========================================================
#include "mpevent.h"
@@ -42,6 +41,7 @@ MEvent::MEvent(unsigned t, int port, int tpe, const unsigned char* data, int len
edata.setData(data, len);
_type = tpe;
_loopNum = 0;
+ setChannel(0);
}
MEvent::MEvent(unsigned tick, int port, int channel, const Event& e)
diff --git a/muse2/muse/mplugins/mitplugin.cpp b/muse2/muse/mplugins/mitplugin.cpp
index 48e30bb6..d4d7dd70 100644
--- a/muse2/muse/mplugins/mitplugin.cpp
+++ b/muse2/muse/mplugins/mitplugin.cpp
@@ -48,7 +48,7 @@ void MusE::startMidiInputPlugin(int id)
QAction* act;
if (id == 0) {
if (!MusEGlobal::mitPluginTranspose) {
- MusEGlobal::mitPluginTranspose = new MusEGui::MITPluginTranspose();
+ MusEGlobal::mitPluginTranspose = new MITPluginTranspose();
MusECore::mitPlugins.push_back(MusEGlobal::mitPluginTranspose);
connect(MusEGlobal::mitPluginTranspose, SIGNAL(hideWindow()),
SLOT(hideMitPluginTranspose()));
@@ -58,7 +58,7 @@ void MusE::startMidiInputPlugin(int id)
}
else if (id == 1) {
if (!midiInputTransform) {
- midiInputTransform = new MusEGui::MidiInputTransformDialog();
+ midiInputTransform = new MidiInputTransformDialog();
connect(midiInputTransform, SIGNAL(hideWindow()),
SLOT(hideMidiInputTransform()));
}
@@ -67,7 +67,7 @@ void MusE::startMidiInputPlugin(int id)
}
else if (id == 2) {
if (!midiFilterConfig) {
- midiFilterConfig = new MusEGui::MidiFilterConfig();
+ midiFilterConfig = new MidiFilterConfig();
connect(midiFilterConfig, SIGNAL(hideWindow()),
SLOT(hideMidiFilterConfig()));
}
@@ -76,7 +76,7 @@ void MusE::startMidiInputPlugin(int id)
}
else if (id == 3) {
if (!midiRemoteConfig) {
- midiRemoteConfig = new MusEGui::MRConfig();
+ midiRemoteConfig = new MRConfig();
connect(midiRemoteConfig, SIGNAL(hideWindow()),
SLOT(hideMidiRemoteConfig()));
}
@@ -134,7 +134,7 @@ void MusE::hideMidiRhythmGenerator()
void MusE::startMidiTransformer()
{
if (midiTransformerDialog == 0)
- midiTransformerDialog = new MusEGui::MidiTransformerDialog;
+ midiTransformerDialog = new MidiTransformerDialog;
midiTransformerDialog->show();
}
diff --git a/muse2/muse/mplugins/rhythm.cpp b/muse2/muse/mplugins/rhythm.cpp
index 78dfeee5..7c51227c 100644
--- a/muse2/muse/mplugins/rhythm.cpp
+++ b/muse2/muse/mplugins/rhythm.cpp
@@ -29,6 +29,8 @@
#include "rhythm.h"
+namespace MusEGui {
+
//---------------------------------------------------------
// RhythmGen
//---------------------------------------------------------
@@ -525,5 +527,7 @@ RhythmGenerator::~RhythmGenerator()
{
// no need to delete child widgets, Qt does it all for us
}
+
#endif
+} // namespace MusEGui
diff --git a/muse2/muse/mplugins/rhythm.h b/muse2/muse/mplugins/rhythm.h
index d60e7993..de6c178b 100644
--- a/muse2/muse/mplugins/rhythm.h
+++ b/muse2/muse/mplugins/rhythm.h
@@ -34,17 +34,22 @@
#include <QMainWindow>
+#define MAX_GROUPS 5
+#define MAX_KEYS 20
+
class QCloseEvent;
+namespace MusECore {
+class Xml;
+}
+
+namespace MusEGui {
+
class tTrack;
class tEventWin;
class tSong;
class tBarInfo;
-#define MAX_GROUPS 5
-#define MAX_KEYS 20
-
-class Xml;
#if 0
//---------------------------------------------------------
@@ -59,8 +64,8 @@ struct tRhyGroup {
listen = 0;
contrib = 0;
}
-// void write(int, Xml&);
-// void read(Xml&);
+// void write(int, MusECore::Xml&);
+// void read(MusECore::Xml&);
};
//---------------------------------------------------------
@@ -71,8 +76,8 @@ struct tRhyGroups {
tRhyGroup g[MAX_GROUPS];
tRhyGroup& operator [] (int i) { return g[i]; }
-// void write(int, Xml&);
-// void read(Xml&);
+// void write(int, MusECore::Xml&);
+// void read(MusECore::Xml&);
};
//---------------------------------------------------------
@@ -123,8 +128,8 @@ class tRhythm
void GenInit(long start_clock);
void GenerateEvent(tTrack *track, long clock, short vel, short len);
- void write(int, Xml&);
- void read(Xml&);
+ void write(int, MusECore::Xml&);
+ void read(MusECore::Xml&);
};
#endif
@@ -209,5 +214,7 @@ class RhythmGen : public QMainWindow, public Ui::RhythmBase
// bool OnClose();
};
+} // namespace MusEGui
+
#endif
diff --git a/muse2/muse/node.cpp b/muse2/muse/node.cpp
index db11b7bd..cb77f939 100644
--- a/muse2/muse/node.cpp
+++ b/muse2/muse/node.cpp
@@ -4,6 +4,7 @@
// $Id: node.cpp,v 1.36.2.25 2009/12/20 05:00:35 terminator356 Exp $
//
// (C) Copyright 2000-2004 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -22,10 +23,11 @@
//=========================================================
#include <cmath>
-#include <assert.h>
#include <sndfile.h>
#include <stdlib.h>
+#include <QString>
+
#include "node.h"
#include "globals.h"
#include "gconfig.h"
@@ -45,7 +47,6 @@
//#define NODE_DEBUG
//#define FIFO_DEBUG
-// Added by Tim. p3.3.18
//#define METRONOME_DEBUG
namespace MusECore {
@@ -163,10 +164,19 @@ void Track::updateInternalSoloStates()
void MidiTrack::updateInternalSoloStates()
{
- if(this == _tmpSoloChainTrack)
- return;
-
- Track::updateInternalSoloStates();
+ if(_nodeTraversed) // Anti circular mechanism.
+ {
+ fprintf(stderr, "MidiTrack::updateInternalSoloStates %s :\n MusE Warning: Please check your routes: Circular path found!\n", name().toLatin1().constData());
+ return;
+ }
+ //if(this == _tmpSoloChainTrack)
+ // return;
+
+ _nodeTraversed = true;
+
+ Track::updateInternalSoloStates();
+
+ _nodeTraversed = false; // Reset.
}
@@ -176,40 +186,61 @@ void MidiTrack::updateInternalSoloStates()
void AudioTrack::updateInternalSoloStates()
{
- if(this == _tmpSoloChainTrack)
- return;
-
- Track::updateInternalSoloStates();
-
- if(_tmpSoloChainDoIns)
+ if(_nodeTraversed) // Anti circular mechanism.
+ {
+ fprintf(stderr, "AudioTrack::updateInternalSoloStates %s :\n MusE Warning: Please check your routes: Circular path found!\n", name().toLatin1().constData());
+ return;
+ }
+ //if(this == _tmpSoloChainTrack)
+ // return;
+
+ _nodeTraversed = true;
+
+ Track::updateInternalSoloStates();
+
+ if(_tmpSoloChainDoIns)
+ {
+ if(type() == AUDIO_SOFTSYNTH)
+ {
+ const MusECore::MidiTrackList* ml = MusEGlobal::song->midis();
+ for(MusECore::ciMidiTrack im = ml->begin(); im != ml->end(); ++im)
{
- if(type() == AUDIO_SOFTSYNTH)
- {
- const MusECore::MidiTrackList* ml = MusEGlobal::song->midis();
- for(MusECore::ciMidiTrack im = ml->begin(); im != ml->end(); ++im)
- {
- MusECore::MidiTrack* mt = *im;
- if(mt->outPort() >= 0 && mt->outPort() == ((SynthI*)this)->midiPort())
- mt->updateInternalSoloStates();
- }
- }
-
- const RouteList* rl = inRoutes();
- for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
- {
- if(ir->type == Route::TRACK_ROUTE)
- ir->track->updateInternalSoloStates();
- }
+ MusECore::MidiTrack* mt = *im;
+ if(mt->outPort() >= 0 && mt->outPort() == ((SynthI*)this)->midiPort())
+ mt->updateInternalSoloStates();
}
- else
- {
- const RouteList* rl = outRoutes();
- for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ }
+
+ const RouteList* rl = inRoutes();
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE)
+ ir->track->updateInternalSoloStates();
+ else
+ // Support Midi Port -> Audio Input solo chains. p4.0.37 Tim.
+ if(ir->type == Route::MIDI_PORT_ROUTE)
+ {
+ const MidiTrackList* ml = MusEGlobal::song->midis();
+ for(ciMidiTrack im = ml->begin(); im != ml->end(); ++im)
{
- if(ir->type == Route::TRACK_ROUTE)
- ir->track->updateInternalSoloStates();
+ MidiTrack* mt = *im;
+ if(mt->outPort() == ir->midiPort && ((1 << mt->outChannel()) & ir->channel) )
+ mt->updateInternalSoloStates();
}
- }
+ }
+ }
+ }
+ else
+ {
+ const RouteList* rl = outRoutes();
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE)
+ ir->track->updateInternalSoloStates();
+ }
+ }
+
+ _nodeTraversed = false; // Reset.
}
@@ -222,6 +253,8 @@ void MidiTrack::updateSoloStates(bool noDec)
if(noDec && !_solo)
return;
+ _nodeTraversed = true; // Anti circular mechanism.
+
_tmpSoloChainTrack = this;
_tmpSoloChainDoIns = false;
_tmpSoloChainNoDec = noDec;
@@ -245,6 +278,8 @@ void MidiTrack::updateSoloStates(bool noDec)
}
}
}
+
+ _nodeTraversed = false; // Reset.
}
@@ -257,6 +292,8 @@ void AudioTrack::updateSoloStates(bool noDec)
if(noDec && !_solo)
return;
+ _nodeTraversed = true; // Anti circular mechanism.
+
_tmpSoloChainTrack = this;
_tmpSoloChainNoDec = noDec;
updateSoloState();
@@ -302,6 +339,8 @@ void AudioTrack::updateSoloStates(bool noDec)
ir->track->updateInternalSoloStates();
}
}
+
+ _nodeTraversed = false; // Reset.
}
@@ -328,7 +367,6 @@ void Track::setOff(bool val)
// copyData
//---------------------------------------------------------
-//void AudioTrack::copyData(unsigned pos, int dstChannels, unsigned nframes, float** dstBuffer)
void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int srcChannels, unsigned nframes, float** dstBuffer)
{
//Changed by T356. 12/12/09.
@@ -337,60 +375,51 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
// Make better use of AudioTrack::outBuffers as a post-effect pre-volume cache system for multiple calls here during processing.
// Previously only WaveTrack used them. (Changed WaveTrack as well).
+ #ifdef NODE_DEBUG
+ printf("MusE: AudioTrack::copyData name:%s processed:%d\n", name().toLatin1().constData(), processed());
+ #endif
+
if(srcStartChan == -1)
srcStartChan = 0;
- int srcChans = (srcChannels == -1) ? channels() : srcChannels;
+ int trackChans = channels();
+ int srcChans = (srcChannels == -1) ? trackChans : srcChannels;
int srcTotalOutChans = totalOutChannels();
if(channels() == 1)
srcTotalOutChans = 1;
- #ifdef NODE_DEBUG
- printf("MusE: AudioTrack::copyData name:%s processed:%d\n", name().toLatin1().constData(), processed());
- #endif
-
// Special consideration for metronome: It is not part of the track list,
// and it has no in or out routes, yet multiple output tracks may call addData on it !
// We can't tell how many output tracks call it, so we can only assume there might be more than one.
// Not strictly necessary here because only addData is ever called, but just to be consistent...
- //bool usedirectbuf = (outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT);
- bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome);
+ //bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome);
int i;
- // p3.3.38
- //float* buffer[srcChannels];
float* buffer[srcTotalOutChans];
+ float data[nframes * srcTotalOutChans];
-
- //float data[nframes * srcChannels];
- //for(i = 0; i < srcChannels; ++i)
- // buffer[i] = data + i * nframes;
-
// precalculate stereo volume
double vol[2];
double _volume = volume();
double _pan = pan();
vol[0] = _volume * (1.0 - _pan);
vol[1] = _volume * (1.0 + _pan);
- float meter[srcChans];
+ float meter[trackChans];
// Have we been here already during this process cycle?
if(processed())
{
// If there is only one (or no) output routes, it's an error - we've been called more than once per process cycle!
+ // No, this is no longer an error, it's deliberate. Processing no longer done in 'chains', now done randomly. p4.0.37
#ifdef NODE_DEBUG
- if(usedirectbuf)
- printf("MusE: AudioTrack::copyData Error! One or no out routes, but already processed! Copying local buffers anyway...\n");
+ printf("MusE: AudioTrack::copyData name:%s already processed _haveData:%d\n", name().toLatin1().constData(), _haveData);
#endif
// Is there already some data gathered from a previous call during this process cycle?
if(_haveData)
{
// Point the input buffers at our local cached 'pre-volume' buffers. They need processing, so continue on after.
- //for(i = 0; i < srcChannels; ++i)
- // buffer[i] = outBuffers[i];
- // p3.3.38
for(i = 0; i < srcTotalOutChans; ++i)
buffer[i] = outBuffers[i];
}
@@ -414,29 +443,16 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
{
// First time here during this process cycle.
- // Point the input buffers at a temporary stack buffer.
- //float data[nframes * srcChannels];
- //for(i = 0; i < srcChannels; ++i)
- // buffer[i] = data + i * nframes;
- // p3.3.38
- float data[nframes * srcTotalOutChans];
- for(i = 0; i < srcTotalOutChans; ++i)
- buffer[i] = data + i * nframes;
-
- // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc.
- // For ex. if this is an audio input, Jack will set the pointers for us in AudioInput::getData!
- // p3.3.29 1/27/10 Don't do any processing at all if off. Whereas, mute needs to be ready for action at all times,
- // so still call getData before it. Off is NOT meant to be toggled rapidly, but mute is !
- //if(!getData(pos, srcChannels, nframes, buffer) || off() || (isMute() && !_prefader))
- //if(off() || !getData(pos, srcChannels, nframes, buffer) || (isMute() && !_prefader))
- // p3.3.38
- if(off() || !getData(pos, srcTotalOutChans, nframes, buffer) || (isMute() && !_prefader))
- {
+ _haveData = false; // Reset.
+ _processed = true; // Set this now.
+
+ if(off())
+ {
#ifdef NODE_DEBUG
- printf("MusE: AudioTrack::copyData name:%s dstChannels:%d zeroing buffers\n", name().toLatin1().constData(), dstChannels);
+ printf("MusE: AudioTrack::copyData name:%s dstChannels:%d Off, zeroing buffers\n", name().toLatin1().constData(), dstChannels);
#endif
- // No data was available. Zero the supplied buffers.
+ // Track is off. Zero the supplied buffers.
unsigned int q;
for(i = 0; i < dstChannels; ++i)
{
@@ -449,13 +465,12 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
memset(dstBuffer[i], 0, sizeof(float) * nframes);
}
- for(i = 0; i < srcChans; ++i)
+ _efxPipe->apply(0, nframes, 0); // Just process controls only, not audio (do not 'run').
+
+ for(i = 0; i < trackChans; ++i)
{
- //_meter[i] = 0;
_meter[i] = 0.0;
-
- /*
- if(!usedirectbuf)
+ /*if(!usedirectbuf)
{
if(MusEGlobal::config.useDenormalBias)
{
@@ -464,22 +479,49 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
}
else
memset(outBuffers[i], 0, sizeof(float) * nframes);
- }
- */
+ } */
}
- _haveData = false;
- _processed = true;
+ //_haveData = false;
+ //_processed = true;
+ //_isProcessing = false; // Unblock.
return;
}
+
+ // Point the input buffers at a temporary stack buffer.
+ for(i = 0; i < srcTotalOutChans; ++i)
+ buffer[i] = data + i * nframes;
+
+ // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc.
+ // For ex. if this is an audio input, Jack will set the pointers for us in AudioInput::getData!
+ // Don't do any processing at all if off. Whereas, mute needs to be ready for action at all times,
+ // so still call getData before it. Off is NOT meant to be toggled rapidly, but mute is !
+ if(!getData(pos, srcTotalOutChans, nframes, buffer) || (isMute() && !_prefader))
+ {
+ #ifdef NODE_DEBUG
+ printf("MusE: AudioTrack::copyData name:%s srcTotalOutChans:%d zeroing buffers\n", name().toLatin1().constData(), srcTotalOutChans);
+ #endif
+
+ // No data was available. Track is not off. Zero the working buffers and continue on.
+ unsigned int q;
+ for(i = 0; i < srcTotalOutChans; ++i)
+ {
+ if(MusEGlobal::config.useDenormalBias)
+ {
+ for(q = 0; q < nframes; ++q)
+ buffer[i][q] = MusEGlobal::denormalBias;
+ }
+ else
+ memset(buffer[i], 0, sizeof(float) * nframes);
+ }
+ }
//---------------------------------------------------
// apply plugin chain
//---------------------------------------------------
- // p3.3.41
//fprintf(stderr, "AudioTrack::copyData %s efx apply srcChans:%d\n", name().toLatin1().constData(), srcChans);
- _efxPipe->apply(srcChans, nframes, buffer);
+ _efxPipe->apply(trackChans, nframes, buffer);
//---------------------------------------------------
// aux sends
@@ -526,18 +568,16 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
if(_prefader)
{
- for(i = 0; i < srcChans; ++i)
+ for(i = 0; i < trackChans; ++i)
{
float* p = buffer[i];
meter[i] = 0.0;
for(unsigned k = 0; k < nframes; ++k)
{
- double f = fabs(*p);
+ double f = fabs(*p++);
if(f > meter[i])
meter[i] = f;
- ++p;
}
- //_meter[i] = lrint(meter[i] * 32767.0);
_meter[i] = meter[i];
if(_meter[i] > _peak[i])
_peak[i] = _meter[i];
@@ -571,20 +611,19 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
else
memset(outBuffers[i], 0, sizeof(float) * nframes);
}
- }
- */
+ } */
+
- _haveData = false;
- _processed = true;
+ if(!_prefader)
+ for(i = 0; i < trackChans; ++i) // Must process ALL channels, even if unconnected. Only max 2 channels.
+ _meter[i] = 0.0;
+
return;
}
// If we're using local cached 'pre-volume' buffers, copy the input buffers (as they are right now: post-effect pre-volume) back to them.
- if(!usedirectbuf)
+ //if(!usedirectbuf)
{
- //for(i = 0; i < srcChannels; ++i)
- // AL::dsp->cpy(outBuffers[i], buffer[i], nframes);
- // p3.3.38
for(i = 0; i < srcTotalOutChans; ++i)
AL::dsp->cpy(outBuffers[i], buffer[i], nframes);
}
@@ -607,9 +646,9 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
else
memset(dstBuffer[i], 0, sizeof(float) * nframes);
}
- _processed = true;
return;
}
+
// Force a source range to fit actual available total out channels.
if((srcStartChan + srcChans) > srcTotalOutChans)
srcChans = srcTotalOutChans - srcStartChan;
@@ -619,132 +658,94 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
// postfader metering
//---------------------------------------------------
-
- if(srcChans == dstChannels)
+ #ifdef NODE_DEBUG
+ printf("MusE: AudioTrack::copyData trackChans:%d srcTotalOutChans:%d srcStartChan:%d srcChans:%d dstChannels:%d\n", trackChans, srcTotalOutChans, srcStartChan, srcChans, dstChannels);
+ #endif
+
+ if(!_prefader)
{
- if(_prefader)
+ for(int c = 0; c < trackChans; ++c)
{
- for(int c = 0; c < dstChannels; ++c)
+ meter[c] = 0.0;
+ double v = (trackChans == 1 ? _volume : vol[c]);
+ float* sp = buffer[c];
+ for(unsigned k = 0; k < nframes; ++k)
{
- // p3.3.38
- //float* sp = buffer[c];
- float* sp = buffer[c + srcStartChan];
-
- float* dp = dstBuffer[c];
- for(unsigned k = 0; k < nframes; ++k)
- *dp++ = (*sp++ * vol[c]);
+ float val = *sp++ * v; // If the track is mono pan has no effect on meters.
+ double f = fabs(val);
+ if(f > meter[c])
+ meter[c] = f;
}
- }
- else
+ _meter[c] = meter[c];
+ if(_meter[c] > _peak[c])
+ _peak[c] = _meter[c];
+ }
+ }
+
+ if(srcChans == dstChannels)
+ {
+ for(int c = 0; c < dstChannels; ++c)
{
- for(int c = 0; c < dstChannels; ++c)
- {
- meter[c] = 0.0;
-
- // p3.3.38
- //float* sp = buffer[c];
- float* sp = buffer[c + srcStartChan];
-
- float* dp = dstBuffer[c];
- //printf("2 dstBuffer[c]=%d\n",long(dstBuffer[c]));
- for(unsigned k = 0; k < nframes; ++k)
- {
- float val = *sp++ * vol[c];
- *dp++ = val;
- double f = fabs(val);
- if(f > meter[c])
- meter[c] = f;
- }
- //_meter[c] = lrint(meter[c] * 32767.0);
- _meter[c] = meter[c];
- if(_meter[c] > _peak[c])
- _peak[c] = _meter[c];
- }
+ double v;
+ if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2.
+ //v = _volume;
+ v = 1.0;
+ else
+ if(srcChans >= 2) // If 2 channels apply pan normally.
+ v = vol[c];
+ else
+ if(trackChans < 2) // If 1 channel and track is 1 channel, don't apply pan.
+ v = _volume;
+ else
+ v = vol[srcStartChan]; // Otherwise 1 channel but track is 2 channels. Apply the channel volume.
+
+ float* sp = buffer[c + srcStartChan];
+ float* dp = dstBuffer[c];
+ for(unsigned k = 0; k < nframes; ++k)
+ //*dp++ = (*sp++ * vol[c]);
+ *dp++ = (*sp++ * v);
}
}
else if(srcChans == 1 && dstChannels == 2)
{
- // p3.3.38
- //float* sp = buffer[0];
- float* sp = buffer[srcStartChan];
-
- if(_prefader)
+ for(int c = 0; c < dstChannels; ++c)
{
- for(int c = 0; c < dstChannels; ++c)
- {
- float* dp = dstBuffer[c];
- for(unsigned k = 0; k < nframes; ++k)
- *dp++ = (*sp++ * vol[c]);
- }
- }
- else
- {
- meter[0] = 0.0;
- for(unsigned k = 0; k < nframes; ++k)
- {
- float val = *sp++;
- double f = fabs(val) * _volume;
- if(f > meter[0])
- meter[0] = f;
- *(dstBuffer[0] + k) = val * vol[0];
- *(dstBuffer[1] + k) = val * vol[1];
- }
- //_meter[0] = lrint(meter[0] * 32767.0);
- _meter[0] = meter[0];
- if(_meter[0] > _peak[0])
- _peak[0] = _meter[0];
+ double v;
+ if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2.
+ //v = _volume;
+ v = 1.0;
+ else
+ if(trackChans <= 1) // If track is mono apply pan.
+ v = vol[c];
+ else
+ v = vol[srcStartChan]; // Otherwise track is stereo, apply the same channel volume to both.
+
+ float* sp = buffer[srcStartChan];
+ float* dp = dstBuffer[c];
+ for(unsigned k = 0; k < nframes; ++k)
+ //*dp++ = (*sp++ * vol[c]);
+ *dp++ = (*sp++ * v);
}
}
else if(srcChans == 2 && dstChannels == 1)
{
- // p3.3.38
- //float* sp1 = buffer[0];
- //float* sp2 = buffer[1];
+ //double v1 = (srcStartChan > 2 ? _volume : vol[srcStartChan]); // Don't apply pan to extra channels above 2.
+ //double v2 = (srcStartChan > 2 ? _volume : vol[srcStartChan + 1]); //
+ double v1 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan]); // Don't apply pan or volume to extra channels above 2.
+ double v2 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan + 1]); //
+ float* dp = dstBuffer[0];
float* sp1 = buffer[srcStartChan];
float* sp2 = buffer[srcStartChan + 1];
-
- if(_prefader)
- {
- float* dp = dstBuffer[0];
- for(unsigned k = 0; k < nframes; ++k)
- *dp++ = (*sp1++ * vol[0] + *sp2++ * vol[1]);
- }
- else
- {
- float* dp = dstBuffer[0];
- meter[0] = 0.0;
- meter[1] = 0.0;
- for(unsigned k = 0; k < nframes; ++k)
- {
- float val1 = *sp1++ * vol[0];
- float val2 = *sp2++ * vol[1];
- double f1 = fabs(val1);
- if(f1 > meter[0])
- meter[0] = f1;
- double f2 = fabs(val2);
- if(f2 > meter[1])
- meter[1] = f2;
- *dp++ = (val1 + val2);
- }
- //_meter[0] = lrint(meter[0] * 32767.0);
- _meter[0] = meter[0];
- if(_meter[0] > _peak[0])
- _peak[0] = _meter[0];
- //_meter[1] = lrint(meter[1] * 32767.0);
- _meter[1] = meter[1];
- if(_meter[1] > _peak[1])
- _peak[1] = _meter[1];
- }
+ for(unsigned k = 0; k < nframes; ++k)
+ //*dp++ = (*sp1++ * vol[0] + *sp2++ * vol[1]);
+ *dp++ = (*sp1++ * v1 + *sp2++ * v2);
}
-
- _processed = true;
}
//---------------------------------------------------------
// addData
//---------------------------------------------------------
-//void AudioTrack::addData(unsigned pos, int dstChannels, unsigned nframes, float** dstBuffer)
void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int srcChannels, unsigned nframes, float** dstBuffer)
{
//Changed by T356. 12/12/09.
@@ -753,21 +754,21 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
// Make better use of AudioTrack::outBuffers as a post-effect pre-volume cache system for multiple calls here during processing.
// Previously only WaveTrack used them. (Changed WaveTrack as well).
- //Added by Tim. p3.3.16
#ifdef NODE_DEBUG
printf("MusE: AudioTrack::addData name:%s processed:%d\n", name().toLatin1().constData(), processed());
#endif
- if (off())
- {
- _processed = true;
- return;
- }
+ //if (off())
+ //{
+ // _processed = true;
+ // return;
+ //}
if(srcStartChan == -1)
srcStartChan = 0;
- int srcChans = (srcChannels == -1) ? channels() : srcChannels;
+ int trackChans = channels();
+ int srcChans = (srcChannels == -1) ? trackChans : srcChannels;
int srcTotalOutChans = totalOutChannels();
if(channels() == 1)
srcTotalOutChans = 1;
@@ -775,18 +776,12 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
// Special consideration for metronome: It is not part of the track list,
// and it has no in or out routes, yet multiple output tracks may call addData on it !
// We can't tell how many output tracks call it, so we can only assume there might be more than one.
- //bool usedirectbuf = (outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT);
- bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome);
+ //bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome);
int i;
- // p3.3.38
- //float* buffer[srcChannels];
float* buffer[srcTotalOutChans];
-
- //float data[nframes * srcChannels];
- //for (i = 0; i < srcChannels; ++i)
- // buffer[i] = data + i * nframes;
+ float data[nframes * srcTotalOutChans];
// precalculate stereo volume
double vol[2];
@@ -794,105 +789,96 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
double _pan = pan();
vol[0] = _volume * (1.0 - _pan);
vol[1] = _volume * (1.0 + _pan);
- float meter[srcChans];
+ //float meter[srcChans];
+ float meter[trackChans];
// Have we been here already during this process cycle?
if(processed())
{
// If there is only one (or no) output routes, it's an error - we've been called more than once per process cycle!
+ // No, this is no longer an error, it's deliberate. Processing no longer done in 'chains', now done randomly. p4.0.37
#ifdef NODE_DEBUG
- if(usedirectbuf)
- printf("MusE: AudioTrack::addData Error! One or no out routes, but already processed! Copying local buffers anyway...\n");
+ printf("MusE: AudioTrack::addData name:%s already processed _haveData:%d\n", name().toLatin1().constData(), _haveData);
#endif
// Is there already some data gathered from a previous call during this process cycle?
if(_haveData)
{
// Point the input buffers at our local cached 'pre-volume' buffers. They need processing, so continue on after.
- //for(i = 0; i < srcChannels; ++i)
- // buffer[i] = outBuffers[i];
- // p3.3.38
for(i = 0; i < srcTotalOutChans; ++i)
buffer[i] = outBuffers[i];
}
else
+ {
// No data was available from a previous call during this process cycle. Nothing to add, just return.
return;
+ }
}
else
{
// First time here during this process cycle.
- // Point the input buffers at a temporary stack buffer.
- //float data[nframes * srcChannels];
- //for(i = 0; i < srcChannels; ++i)
- // buffer[i] = data + i * nframes;
- // p3.3.38
- float data[nframes * srcTotalOutChans];
- for(i = 0; i < srcTotalOutChans; ++i)
- buffer[i] = data + i * nframes;
-
+ _haveData = false; // Reset.
+ _processed = true; // Set this now.
- // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc.
- // For ex. if this is an audio input, Jack will set the pointers for us.
- //if(!getData(pos, srcChannels, nframes, buffer))
- // p3.3.38
- if(!getData(pos, srcTotalOutChans, nframes, buffer))
- {
- // No data was available. Nothing to add, but zero our local buffers and the meters.
- for(i = 0; i < srcChans; ++i)
+ if(off())
+ {
+ #ifdef NODE_DEBUG
+ printf("MusE: AudioTrack::addData name:%s dstChannels:%d Track is Off \n", name().toLatin1().constData(), dstChannels);
+ #endif
+
+ // Nothing to zero or add...
+
+ _efxPipe->apply(0, nframes, 0); // Track is off. Just process controls only, not audio (do not 'run').
+
+ for(i = 0; i < trackChans; ++i)
{
- // If we're using local buffers, we must zero them so that the next thing requiring them
- // during this process cycle will see zeros.
- /*
- if(!usedirectbuf)
+ _meter[i] = 0.0;
+ /*if(!usedirectbuf)
{
if(MusEGlobal::config.useDenormalBias)
{
- for(unsigned int q = 0; q < nframes; ++q)
+ for(q = 0; q < nframes; ++q)
outBuffers[i][q] = MusEGlobal::denormalBias;
- }
- else
+ }
+ else
memset(outBuffers[i], 0, sizeof(float) * nframes);
- }
- */
-
- //_meter[i] = 0;
- _meter[i] = 0.0;
- }
-
- _haveData = false;
- _processed = true;
+ } */
+ }
return;
}
-
- /*
- // p3.3.41 Added.
- unsigned int q;
- for(i = 0; i < srcChans; ++i)
+
+ // Point the input buffers at a temporary stack buffer.
+ for(i = 0; i < srcTotalOutChans; ++i)
+ buffer[i] = data + i * nframes;
+
+ // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc.
+ // For ex. if this is an audio input, Jack will set the pointers for us.
+ if(!getData(pos, srcTotalOutChans, nframes, buffer))
{
- if(MusEGlobal::config.useDenormalBias)
- {
- for(q = 0; q < nframes; ++q)
+ // No data was available. Track is not off. Zero the working buffers and continue on.
+ unsigned int q;
+ for(i = 0; i < srcTotalOutChans; ++i)
+ {
+ if(MusEGlobal::config.useDenormalBias)
{
- if(q & 1)
- buffer[i][q] -= MusEGlobal::denormalBias;
- else
- buffer[i][q] += MusEGlobal::denormalBias;
- }
- }
- }
- */
-
+ for(q = 0; q < nframes; ++q)
+ buffer[i][q] = MusEGlobal::denormalBias;
+ }
+ else
+ memset(buffer[i], 0, sizeof(float) * nframes);
+ }
+ }
+
//---------------------------------------------------
// apply plugin chain
//---------------------------------------------------
- // p3.3.41
//fprintf(stderr, "AudioTrack::addData %s efx apply srcChans:%d nframes:%ld %e %e %e %e\n",
// name().toLatin1().constData(), srcChans, nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]);
- _efxPipe->apply(srcChans, nframes, buffer);
- // p3.3.41
+
+ _efxPipe->apply(trackChans, nframes, buffer);
+
//fprintf(stderr, "AudioTrack::addData after efx: %e %e %e %e\n",
// buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]);
@@ -941,18 +927,16 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
if(_prefader)
{
- for(i = 0; i < srcChans; ++i)
+ for(i = 0; i < trackChans; ++i)
{
float* p = buffer[i];
meter[i] = 0.0;
for(unsigned k = 0; k < nframes; ++k)
{
- double f = fabs(*p);
+ double f = fabs(*p++);
if(f > meter[i])
meter[i] = f;
- ++p;
}
- //_meter[i] = lrint(meter[i] * 32767.0);
_meter[i] = meter[i];
if(_meter[i] > _peak[i])
_peak[i] = _meter[i];
@@ -962,8 +946,7 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
if(isMute())
{
// If we're using local buffers, we must zero them.
- /*
- if(!usedirectbuf)
+ /* if(!usedirectbuf)
{
for(i = 0; i < srcChannels; ++i)
{
@@ -975,20 +958,19 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
else
memset(outBuffers[i], 0, sizeof(float) * nframes);
}
- }
- */
+ } */
- _haveData = false;
- _processed = true;
+ if(!_prefader)
+ //for(i = 0; i < srcChans; ++i)
+ for(i = 0; i < trackChans; ++i)
+ _meter[i] = 0.0;
+
return;
}
// If we're using local cached 'pre-volume' buffers, copy the input buffers (as they are right now: post-effect pre-volume) back to them.
- if(!usedirectbuf)
+ //if(!usedirectbuf)
{
- //for(i = 0; i < srcChannels; ++i)
- // AL::dsp->cpy(outBuffers[i], buffer[i], nframes);
- // p3.3.38
for(i = 0; i < srcTotalOutChans; ++i)
AL::dsp->cpy(outBuffers[i], buffer[i], nframes);
}
@@ -1011,9 +993,9 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
else
memset(dstBuffer[i], 0, sizeof(float) * nframes);
}
- _processed = true;
return;
}
+
// Force a source range to fit actual available total out channels.
if((srcStartChan + srcChans) > srcTotalOutChans)
srcChans = srcTotalOutChans - srcStartChan;
@@ -1023,123 +1005,88 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
// postfader metering
//---------------------------------------------------
- if(srcChans == dstChannels)
+ #ifdef NODE_DEBUG
+ printf("MusE: AudioTrack::addData trackChans:%d srcTotalOutChans:%d srcChans:%d dstChannels:%d\n", trackChans, srcTotalOutChans, srcChans, dstChannels);
+ #endif
+
+ if(!_prefader)
{
- if(_prefader)
+ for(int c = 0; c < trackChans; ++c)
{
- for(int c = 0; c < dstChannels; ++c)
+ meter[c] = 0.0;
+ double v = (trackChans == 1 ? _volume : vol[c]);
+ float* sp = buffer[c];
+ for(unsigned k = 0; k < nframes; ++k)
{
- // p3.3.38
- //float* sp = buffer[c];
- float* sp = buffer[c + srcStartChan];
-
- float* dp = dstBuffer[c];
- for(unsigned k = 0; k < nframes; ++k)
- *dp++ += (*sp++ * vol[c]);
+ float val = *sp++ * v; // If the track is mono pan has no effect on meters.
+ double f = fabs(val);
+ if(f > meter[c])
+ meter[c] = f;
}
- }
- else
+ _meter[c] = meter[c];
+ if(_meter[c] > _peak[c])
+ _peak[c] = _meter[c];
+ }
+ }
+
+ if(srcChans == dstChannels)
+ {
+ for(int c = 0; c < dstChannels; ++c)
{
- for(int c = 0; c < dstChannels; ++c)
- {
- meter[c] = 0.0;
- // p3.3.38
- //float* sp = buffer[c];
- float* sp = buffer[c + srcStartChan];
-
- float* dp = dstBuffer[c];
- for(unsigned k = 0; k < nframes; ++k)
- {
- float val = *sp++ * vol[c];
- *dp++ += val;
- double f = fabs(val);
- if (f > meter[c])
- meter[c] = f;
- }
- //_meter[c] = lrint(meter[c] * 32767.0);
- _meter[c] = meter[c];
- if(_meter[c] > _peak[c])
- _peak[c] = _meter[c];
- }
+ double v;
+ if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2.
+ //v = _volume;
+ v = 1.0;
+ else
+ if(srcChans >= 2) // If 2 channels apply pan normally.
+ v = vol[c];
+ else
+ if(trackChans < 2) // If 1 channel and track is 1 channel, don't apply pan.
+ v = _volume;
+ else
+ v = vol[srcStartChan]; // Otherwise 1 channel but track is 2 channels. Apply the channel volume.
+
+ float* sp = buffer[c + srcStartChan];
+ float* dp = dstBuffer[c];
+ for(unsigned k = 0; k < nframes; ++k)
+ //*dp++ += (*sp++ * vol[c]);
+ *dp++ += (*sp++ * v);
}
}
else if(srcChans == 1 && dstChannels == 2)
{
- // p3.3.38
- float* sp = buffer[srcStartChan];
-
- if(_prefader)
+ for(int c = 0; c < dstChannels; ++c)
{
- for(int c = 0; c < dstChannels; ++c)
- {
- float* dp = dstBuffer[c];
- //float* sp = buffer[0];
- for(unsigned k = 0; k < nframes; ++k)
- *dp++ += (*sp++ * vol[c]);
- }
- }
- else
- {
- //float* sp = buffer[0];
- meter[0] = 0.0;
- for(unsigned k = 0; k < nframes; ++k)
- {
- float val = *sp++;
- double f = fabs(val) * _volume;
- if(f > meter[0])
- meter[0] = f;
- *(dstBuffer[0] + k) += val * vol[0];
- *(dstBuffer[1] + k) += val * vol[1];
- }
- //_meter[0] = lrint(meter[0] * 32767.0);
- _meter[0] = meter[0];
- if(_meter[0] > _peak[0])
- _peak[0] = _meter[0];
+ double v;
+ if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2.
+ //v = _volume;
+ v = 1.0;
+ else
+ if(trackChans <= 1) // If track is mono apply pan.
+ v = vol[c];
+ else
+ v = vol[srcStartChan]; // Otherwise track is stereo, apply the same channel volume to both.
+
+ float* sp = buffer[srcStartChan];
+ float* dp = dstBuffer[c];
+ for(unsigned k = 0; k < nframes; ++k)
+ //*dp++ += (*sp++ * vol[c]);
+ *dp++ += (*sp++ * v);
}
}
else if(srcChans == 2 && dstChannels == 1)
{
- // p3.3.38
- //float* sp1 = buffer[0];
- //float* sp2 = buffer[1];
+ //double v1 = (srcStartChan > 2 ? _volume : vol[srcStartChan]); // Don't apply pan to extra channels above 2.
+ //double v2 = (srcStartChan > 2 ? _volume : vol[srcStartChan + 1]); //
+ double v1 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan]); // Don't apply pan or volume to extra channels above 2.
+ double v2 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan + 1]); //
float* sp1 = buffer[srcStartChan];
float* sp2 = buffer[srcStartChan + 1];
-
- if(_prefader)
- {
- float* dp = dstBuffer[0];
- for(unsigned k = 0; k < nframes; ++k)
- *dp++ += (*sp1++ * vol[0] + *sp2++ * vol[1]);
- }
- else
- {
- float* dp = dstBuffer[0];
- meter[0] = 0.0;
- meter[1] = 0.0;
- for(unsigned k = 0; k < nframes; ++k)
- {
- float val1 = *sp1++ * vol[0];
- float val2 = *sp2++ * vol[1];
- double f1 = fabs(val1);
- if(f1 > meter[0])
- meter[0] = f1;
- double f2 = fabs(val2);
- if(f2 > meter[1])
- meter[1] = f2;
- *dp++ += (val1 + val2);
- }
- //_meter[0] = lrint(meter[0] * 32767.0);
- _meter[0] = meter[0];
- if(_meter[0] > _peak[0])
- _peak[0] = _meter[0];
- //_meter[1] = lrint(meter[1] * 32767.0);
- _meter[1] = meter[1];
- if(_meter[1] > _peak[1])
- _peak[1] = _meter[1];
- }
+ float* dp = dstBuffer[0];
+ for(unsigned k = 0; k < nframes; ++k)
+ //*dp++ += (*sp1++ * vol[0] + *sp2++ * vol[1]);
+ *dp++ += (*sp1++ * v1 + *sp2++ * v2);
}
-
- _processed = true;
}
//---------------------------------------------------------
@@ -1301,15 +1248,12 @@ bool AudioTrack::getData(unsigned pos, int channels, unsigned nframes, float** b
printf(" calling copyData on %s...\n", ir->track->name().toLatin1().constData());
#endif
- // p3.3.38
- //((AudioTrack*)ir->track)->copyData(pos, channels, nframes, buffer);
((AudioTrack*)ir->track)->copyData(pos, channels,
//(ir->track->type() == Track::AUDIO_SOFTSYNTH && ir->channel != -1) ? ir->channel : 0,
ir->channel,
ir->channels,
nframes, buffer);
- // p3.3.41
//fprintf(stderr, "AudioTrack::getData %s data: nframes:%ld %e %e %e %e\n", name().toLatin1().constData(), nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]);
++ir;
@@ -1321,8 +1265,6 @@ bool AudioTrack::getData(unsigned pos, int channels, unsigned nframes, float** b
if(ir->track->isMidiTrack())
continue;
- // p3.3.38
- //((AudioTrack*)ir->track)->addData(pos, channels, nframes, buffer);
((AudioTrack*)ir->track)->addData(pos, channels,
//(ir->track->type() == Track::AUDIO_SOFTSYNTH && ir->channel != -1) ? ir->channel : 0,
ir->channel,
@@ -1345,12 +1287,11 @@ bool AudioInput::getData(unsigned, int channels, unsigned nframes, float** buffe
void* jackPort = jackPorts[ch];
//float* jackbuf = 0;
- //if (jackPort) {
- // p3.3.41 Do not get buffers of unconnected client ports. Causes repeating leftover data, can be loud, or DC !
+ // Do not get buffers of unconnected client ports. Causes repeating leftover data, can be loud, or DC !
if (jackPort && MusEGlobal::audioDevice->connections(jackPort))
{
//buffer[ch] = MusEGlobal::audioDevice->getBuffer(jackPort, nframes);
- // p3.3.41 If the client port buffer is also used by another channel (connected to the same jack port),
+ // If the client port buffer is also used by another channel (connected to the same jack port),
// don't directly set pointer, copy the data instead.
// Otherwise the next channel will interfere - it will overwrite the buffer !
// Verified symptoms: Can't use a splitter. Mono noise source on a stereo track sounds in mono. Etc...
@@ -1367,8 +1308,6 @@ bool AudioInput::getData(unsigned, int channels, unsigned nframes, float** buffe
{
for (unsigned int i=0; i < nframes; i++)
buffer[ch][i] += MusEGlobal::denormalBias;
-
- // p3.3.41
//fprintf(stderr, "AudioInput::getData %s Jack port %p efx apply channels:%d nframes:%ld %e %e %e %e\n",
// name().toLatin1().constData(), jackPort, channels, nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]);
}
@@ -1385,8 +1324,6 @@ bool AudioInput::getData(unsigned, int channels, unsigned nframes, float** buffe
memset(buffer[ch], 0, nframes * sizeof(float));
}
- // p3.3.41
- //fprintf(stderr, "AudioInput::getData %s No Jack port efx apply channels:%d nframes:%ld %e %e %e %e\n",
// name().toLatin1().constData(), channels, nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]);
}
}
@@ -1525,7 +1462,7 @@ void AudioTrack::record()
return;
}
if (_recFile) {
- // Line removed by Tim. p3.3.8 Oct 28, 2009
+ // Line removed by Tim. Oct 28, 2009
//_recFile->seek(pos, 0);
//
// Fix for recorded waves being shifted ahead by an amount
@@ -1571,7 +1508,6 @@ void AudioTrack::record()
if( (pos >= fr) && (!MusEGlobal::song->punchout() || (!MusEGlobal::song->loop() && pos < MusEGlobal::song->rPos().frame())) )
{
pos -= fr;
- // Added by Tim. p3.3.8
//int position = _recFile->seek(0, SEEK_CUR);
//printf("AudioTrack::record loopcnt:%d lframe:%d newpos:%d curpos:%d start:%d end:%d\n", MusEGlobal::audio->loopCount(), MusEGlobal::audio->loopFrame(), pos, position, MusEGlobal::audio->getStartRecordPos().frame(), MusEGlobal::audio->getEndRecordPos().frame());
@@ -1615,7 +1551,6 @@ void AudioOutput::processInit(unsigned nframes)
void AudioOutput::process(unsigned pos, unsigned offset, unsigned n)
{
- //Added by Tim. p3.3.16
#ifdef NODE_DEBUG
printf("MusE: AudioOutput::process name:%s processed:%d\n", name().toLatin1().constData(), processed());
#endif
@@ -1623,9 +1558,6 @@ void AudioOutput::process(unsigned pos, unsigned offset, unsigned n)
for (int i = 0; i < _channels; ++i) {
buffer1[i] = buffer[i] + offset;
}
-
- // p3.3.38
- //copyData(pos, _channels, n, buffer1);
copyData(pos, _channels, -1, -1, n, buffer1);
}
@@ -1667,17 +1599,13 @@ void AudioOutput::processWrite()
putFifo(_channels, _nframes, buffer);
}
}
- // Changed by Tim. p3.3.18
+ // Changed by Tim.
//if (MusEGlobal::audioClickFlag && MusEGlobal::song->click()) {
if (sendMetronome() && MusEGlobal::audioClickFlag && MusEGlobal::song->click()) {
- // Added by Tim. p3.3.18
#ifdef METRONOME_DEBUG
printf("MusE: AudioOutput::processWrite Calling metronome->addData frame:%u channels:%d frames:%lu\n", MusEGlobal::audio->pos().frame(), _channels, _nframes);
#endif
-
- // p3.3.38
- //metronome->addData(MusEGlobal::audio->pos().frame(), _channels, _nframes, buffer);
metronome->addData(MusEGlobal::audio->pos().frame(), _channels, -1, -1, _nframes, buffer);
}
}
@@ -1722,7 +1650,6 @@ Fifo::~Fifo()
{
for (int i = 0; i < nbuffer; ++i)
{
- // p3.3.45
if(buffer[i]->buffer)
{
//printf("Fifo::~Fifo freeing buffer\n");
@@ -1743,7 +1670,6 @@ Fifo::~Fifo()
bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos)
{
- // Added by Tim. p3.3.17
#ifdef FIFO_DEBUG
printf("FIFO::put segs:%d samples:%lu pos:%u\n", segs, samples, pos);
#endif
@@ -1766,7 +1692,6 @@ bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos)
// Changed by Tim. p3.3.15
//b->buffer = new float[n];
posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n);
- // p3.3.45
if(!b->buffer)
{
printf("Fifo::put could not allocate buffer segs:%d samples:%lu pos:%u\n", segs, samples, pos);
@@ -1775,7 +1700,6 @@ bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos)
b->maxSize = n;
}
- // p3.3.45
if(!b->buffer)
{
printf("Fifo::put no buffer! segs:%d samples:%lu pos:%u\n", segs, samples, pos);
@@ -1799,7 +1723,6 @@ bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos)
bool Fifo::get(int segs, unsigned long samples, float** dst, unsigned* pos)
{
- // Added by Tim. p3.3.17
#ifdef FIFO_DEBUG
printf("FIFO::get segs:%d samples:%lu\n", segs, samples);
#endif
@@ -1809,7 +1732,6 @@ bool Fifo::get(int segs, unsigned long samples, float** dst, unsigned* pos)
return true;
}
FifoBuffer* b = buffer[ridx];
- // p3.3.45
if(!b->buffer)
{
printf("Fifo::get no buffer! segs:%d samples:%lu b->pos:%u\n", segs, samples, b->pos);
@@ -1845,7 +1767,6 @@ void Fifo::remove()
bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned pos)
{
- // Added by Tim. p3.3.17
#ifdef FIFO_DEBUG
printf("Fifo::getWriteBuffer segs:%d samples:%lu pos:%u\n", segs, samples, pos);
#endif
@@ -1867,7 +1788,6 @@ bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned
// Changed by Tim. p3.3.15
//b->buffer = new float[n];
posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n);
- // p3.3.45
if(!b->buffer)
{
printf("Fifo::getWriteBuffer could not allocate buffer segs:%d samples:%lu pos:%u\n", segs, samples, pos);
@@ -1876,8 +1796,6 @@ bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned
b->maxSize = n;
}
-
- // p3.3.45
if(!b->buffer)
{
printf("Fifo::getWriteBuffer no buffer! segs:%d samples:%lu pos:%u\n", segs, samples, pos);
diff --git a/muse2/muse/osc.cpp b/muse2/muse/osc.cpp
index bc64575a..7daeb9ff 100644
--- a/muse2/muse/osc.cpp
+++ b/muse2/muse/osc.cpp
@@ -824,7 +824,7 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin
}
QString oscUrl;
- oscUrl = QString("%1%2/%3/%4").arg(QString(QT_TRANSLATE_NOOP("@default", url))).arg(typ).arg(baseName).arg(label);
+ oscUrl = QString("%1%2/%3/%4").arg(QString( url)).arg(typ).arg(baseName).arg(label);
#ifdef _USE_QPROCESS_FOR_GUI_
@@ -841,7 +841,8 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin
arguments << oscUrl
<< filePath
<< name
- << QString("channel-1");
+ //<< QString("channel-1");
+ << (titlePrefix() + label);
#ifdef OSC_DEBUG
fprintf(stderr, "OscIF::oscInitGui starting QProcess\n");
@@ -885,7 +886,8 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin
oscUrl.toLatin1().constData(),
filePath.toLatin1().constData(),
name.toLatin1().constData(),
- "channel 1", (void*)0);
+ //"channel 1", (void*)0);
+ label.toLatin1().constData(), (void*)0);
// Should not return after execlp. If so it's an error.
fprintf(stderr, "exec %s %s %s %s %s failed: %s\n",
@@ -941,13 +943,13 @@ void OscIF::oscShowGui(bool v)
}
//for (int i = 0; i < 5; ++i) {
- for (int i = 0; i < 10; ++i) { // Give it a wee bit more time?
+ for (int i = 0; i < 20; ++i) { // Give it a wee bit more time?
if (_uiOscPath)
break;
sleep(1);
}
if (_uiOscPath == 0) {
- printf("OscIF::oscShowGui(): no _uiOscPath. Error: Timeout - synth gui did not start within 10 seconds.\n");
+ printf("OscIF::oscShowGui(): no _uiOscPath. Error: Timeout - synth gui did not start within 20 seconds.\n");
return;
}
@@ -1087,14 +1089,18 @@ bool OscDssiIF::oscInitGui()
if(!_oscSynthIF)
return false;
- return OscIF::oscInitGui(QT_TRANSLATE_NOOP("@default", "dssi_synth"), _oscSynthIF->dssiSynth()->baseName(),
+ return OscIF::oscInitGui("dssi_synth", _oscSynthIF->dssiSynth()->baseName(),
_oscSynthIF->dssiSynth()->name(), _oscSynthIF->dssiSynthI()->name(),
_oscSynthIF->dssiSynth()->fileName(), _oscSynthIF->dssi_ui_filename());
}
+
+QString OscDssiIF::titlePrefix() const
+{
+ return _oscSynthIF ? _oscSynthIF->titlePrefix() : QString();
+}
#endif // DSSI_SUPPORT
-
//---------------------------------------------------------
// OscEffectIF::
// oscSetPluginI
@@ -1160,11 +1166,16 @@ bool OscEffectIF::oscInitGui()
if(!_oscPluginI)
return false;
- return OscIF::oscInitGui(QT_TRANSLATE_NOOP("@default", "ladspa_efx"), _oscPluginI->plugin()->lib(false),
+ return OscIF::oscInitGui("ladspa_efx", _oscPluginI->plugin()->lib(false),
_oscPluginI->plugin()->label(), _oscPluginI->label(),
_oscPluginI->plugin()->fileName(), _oscPluginI->dssi_ui_filename());
}
+QString OscEffectIF::titlePrefix() const
+{
+ return _oscPluginI ? _oscPluginI->titlePrefix() : QString();
+}
+
#else //OSC_SUPPORT
void initOSC() {}
diff --git a/muse2/muse/osc.h b/muse2/muse/osc.h
index 30df03cb..e3f1a26d 100644
--- a/muse2/muse/osc.h
+++ b/muse2/muse/osc.h
@@ -74,6 +74,8 @@ class OscIF
virtual bool oscInitGui() { return false; }
virtual void oscShowGui(bool);
virtual bool oscGuiVisible() const;
+
+ virtual QString titlePrefix() const { return QString(); }
};
class OscEffectIF : public OscIF
@@ -95,6 +97,8 @@ class OscEffectIF : public OscIF
virtual int oscConfigure(lo_arg**);
virtual bool oscInitGui();
+
+ virtual QString titlePrefix() const;
};
#ifdef DSSI_SUPPORT
@@ -117,6 +121,8 @@ class OscDssiIF : public OscIF
virtual int oscConfigure(lo_arg**);
virtual bool oscInitGui();
+
+ virtual QString titlePrefix() const;
};
#endif // DSSI_SUPPORT
diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp
index 6407dadc..33519e11 100644
--- a/muse2/muse/part.cpp
+++ b/muse2/muse/part.cpp
@@ -23,7 +23,6 @@
//=========================================================
#include <stdio.h>
-#include <assert.h>
#include <cmath>
#include "song.h"
@@ -39,7 +38,7 @@
namespace MusECore {
-int Part::snGen;
+int Part::snGen=0;
//---------------------------------------------------------
// unchainClone
@@ -751,6 +750,18 @@ WavePart::WavePart(const WavePart& p) : Part(p)
Part::~Part()
{
+ if (_prevClone!=this || _nextClone!=this)
+ {
+ printf("THIS MIGHT BE A HINT FOR BUGS: Part isn't unchained in ~Part()! i'll do that now. this is\n"
+ "not an actual bug, actually that manual unchain should be unneccessary if this was coded\n"
+ "properly. but as it wasn't, and the unchain was always done manually, this might be an\n"
+ "indicator that it have been forgotten. either your computer will explode in 3..2..1..now,\n"
+ "or you can ignore this message.\n"
+ "\n");
+
+ unchainClone(this);
+ }
+
_events->incRef(-1);
if (_events->refCount() <= 0)
delete _events;
@@ -805,7 +816,8 @@ void PartList::remove(Part* part)
break;
}
}
- assert(i != end());
+ if (i == end())
+ printf("THIS SHOULD NEVER HAPPEN: could not find the part in PartList::remove()!\n");
}
//---------------------------------------------------------
diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp
index 63e65f2e..227a9daf 100644
--- a/muse2/muse/plugin.cpp
+++ b/muse2/muse/plugin.cpp
@@ -1573,65 +1573,60 @@ bool Pipeline::nativeGuiVisible(int idx)
//---------------------------------------------------------
// apply
+// If ports is 0, just process controllers only, not audio (do not 'run').
//---------------------------------------------------------
-//void Pipeline::apply(int ports, unsigned long nframes, float** buffer1)
void Pipeline::apply(unsigned long ports, unsigned long nframes, float** buffer1)
{
// prepare a second set of buffers in case a plugin is not
// capable of inPlace processing
-
- // Removed by Tim. p3.3.15
//float* buffer2[ports];
//float data[nframes * ports];
//for (int i = 0; i < ports; ++i)
// buffer2[i] = data + i * nframes;
- // p3.3.41
- //fprintf(stderr, "Pipeline::apply data: nframes:%lu %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]);
+ //fprintf(stderr, "Pipeline::apply data: nframes:%lu %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]);
bool swap = false;
for (iPluginI ip = begin(); ip != end(); ++ip) {
PluginI* p = *ip;
- if (p && p->on()) {
- if (p->inPlaceCapable())
- {
- if (swap)
- //p->connect(ports, buffer2, buffer2);
- //p->connect(ports, buffer, buffer);
- p->apply(nframes, ports, buffer, buffer); // p4.0.21
- else
- //p->connect(ports, buffer1, buffer1);
- p->apply(nframes, ports, buffer1, buffer1); //
- }
- else
- {
- if (swap)
- //p->connect(ports, buffer2, buffer1);
- //p->connect(ports, buffer, buffer1);
- p->apply(nframes, ports, buffer, buffer1); //
- else
- //p->connect(ports, buffer1, buffer2);
- //p->connect(ports, buffer1, buffer);
- p->apply(nframes, ports, buffer1, buffer); //
- swap = !swap;
- }
- //p->apply(nframes); // Rem. p4.0.21
- }
+
+ if(p)
+ {
+ //if (p && p->on()) {
+ if (p->on())
+ {
+ //fprintf(stderr, "Pipeline::apply PluginI:%p on:%d\n", p, p->on());
+ if (p->inPlaceCapable())
+ {
+ if (swap)
+ p->apply(nframes, ports, buffer, buffer);
+ else
+ p->apply(nframes, ports, buffer1, buffer1);
+ }
+ else
+ {
+ if (swap)
+ p->apply(nframes, ports, buffer, buffer1);
+ else
+ p->apply(nframes, ports, buffer1, buffer);
+ swap = !swap;
+ }
+ }
+ else
+ {
+ p->apply(nframes, 0, 0, 0); // Do not process (run) audio, process controllers only.
+ }
}
- if (swap)
+ }
+ if (ports != 0 && swap)
{
- //for (int i = 0; i < ports; ++i)
- for (unsigned long i = 0; i < ports; ++i) // p4.0.21
+ for (unsigned long i = 0; i < ports; ++i)
//memcpy(buffer1[i], buffer2[i], sizeof(float) * nframes);
//memcpy(buffer1[i], buffer[i], sizeof(float) * nframes);
AL::dsp->cpy(buffer1[i], buffer[i], nframes);
}
-
- // p3.3.41
- //fprintf(stderr, "Pipeline::apply after data: nframes:%lu %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]);
-
}
//---------------------------------------------------------
@@ -2439,6 +2434,7 @@ void PluginI::showGui()
if (_plugin) {
if (_gui == 0)
makeGui();
+ _gui->setWindowTitle(titlePrefix() + name());
if (_gui->isVisible())
_gui->hide();
else
@@ -2558,7 +2554,17 @@ void PluginI::enable2AllControllers(bool v)
}
//---------------------------------------------------------
+// titlePrefix
+//---------------------------------------------------------
+
+QString PluginI::titlePrefix() const
+{
+ return _track->name() + QString(": ");
+}
+
+//---------------------------------------------------------
// apply
+// If ports is 0, just process controllers only, not audio (do not 'run').
//---------------------------------------------------------
/*
@@ -2653,7 +2659,6 @@ void PluginI::apply(unsigned long n)
*/
#if 1
-// p4.0.21
void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** bufOut)
{
// Process control value changes.
@@ -2769,7 +2774,6 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float**
//controls[v.idx].val = v.value;
controls[v.idx].tmpVal = v.value;
- /*
// Need to update the automation value, otherwise it overwrites later with the last MusEGlobal::automation value.
if(_track && _id != -1)
{
@@ -2795,7 +2799,6 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float**
// enableController(k, false);
//_track->recordAutomation(id, v.value);
}
- */
}
// Now update the actual values from the temporary values...
@@ -2813,20 +2816,23 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float**
nsamp = n - sample;
//printf("PluginI::apply ports:%lu n:%lu frame:%lu sample:%lu nsamp:%lu syncFrame:%lu loopcount:%d\n",
- // ports, n, frame, sample, nsamp, syncFrame, loopcount); // REMOVE Tim.
+ // ports, n, frame, sample, nsamp, syncFrame, loopcount);
// Don't allow zero-length runs. This could/should be checked in the control loop instead.
// Note this means it is still possible to get stuck in the top loop (at least for a while).
if(nsamp == 0)
continue;
- connect(ports, sample, bufIn, bufOut);
+ if(ports != 0)
+ {
+ connect(ports, sample, bufIn, bufOut);
- for(int i = 0; i < instances; ++i)
- {
- //fprintf(stderr, "PluginI::apply handle %d\n", i);
- _plugin->apply(handle[i], nsamp);
- }
+ for(int i = 0; i < instances; ++i)
+ {
+ //fprintf(stderr, "PluginI::apply handle %d\n", i);
+ _plugin->apply(handle[i], nsamp);
+ }
+ }
sample += nsamp;
loopcount++; // REMOVE Tim.
@@ -3444,7 +3450,8 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
params = 0;
paramsOut = 0;
plugin = p;
- setWindowTitle(plugin->name());
+ //setWindowTitle(plugin->name());
+ setWindowTitle(plugin->titlePrefix() + plugin->name());
QToolBar* tools = addToolBar(tr("File Buttons"));
@@ -3546,7 +3553,7 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
gw[nobj].param = parameter;
gw[nobj].type = -1;
- if (strcmp(obj->metaObject()->className(), "Slider") == 0) {
+ if (strcmp(obj->metaObject()->className(), "MusEGui::Slider") == 0) {
gw[nobj].type = GuiWidgets::SLIDER;
((Slider*)obj)->setId(nobj);
((Slider*)obj)->setCursorHoming(true);
@@ -3561,7 +3568,7 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
connect(obj, SIGNAL(sliderReleased(int)), SLOT(guiSliderReleased(int)));
connect(obj, SIGNAL(sliderRightClicked(const QPoint &, int)), SLOT(guiSliderRightClicked(const QPoint &, int)));
}
- else if (strcmp(obj->metaObject()->className(), "DoubleLabel") == 0) {
+ else if (strcmp(obj->metaObject()->className(), "MusEGui::DoubleLabel") == 0) {
gw[nobj].type = GuiWidgets::DOUBLE_LABEL;
((DoubleLabel*)obj)->setId(nobj);
//for(int i = 0; i < nobj; i++)
@@ -4106,16 +4113,18 @@ void PluginGui::save()
void PluginGui::bypassToggled(bool val)
{
+ setWindowTitle(plugin->titlePrefix() + plugin->name());
plugin->setOn(val);
MusEGlobal::song->update(SC_ROUTE);
}
//---------------------------------------------------------
-// songChanged
+// setOn
//---------------------------------------------------------
void PluginGui::setOn(bool val)
{
+ setWindowTitle(plugin->titlePrefix() + plugin->name());
onOff->blockSignals(true);
onOff->setChecked(val);
onOff->blockSignals(false);
@@ -4208,11 +4217,11 @@ void PluginGui::updateControls()
}
- if(!MusEGlobal::automation)
- return;
- AutomationType at = plugin->track()->automationType();
- if(at == AUTO_OFF)
- return;
+ //if(!MusEGlobal::automation)
+ // return;
+ //AutomationType at = plugin->track()->automationType();
+ //if(at == AUTO_OFF)
+ // return;
if (params) {
//for (int i = 0; i < plugin->parameters(); ++i) {
for (unsigned long i = 0; i < plugin->parameters(); ++i) { // p4.0.21
@@ -4611,9 +4620,9 @@ void PluginGui::guiSliderRightClicked(const QPoint &p, int idx)
//---------------------------------------------------------
QWidget* PluginLoader::createWidget(const QString & className, QWidget * parent, const QString & name)
{
- if(className == QString("DoubleLabel"))
+ if(className == QString("MusEGui::DoubleLabel"))
return new DoubleLabel(parent, name.toLatin1().constData());
- if(className == QString("Slider"))
+ if(className == QString("MusEGui::Slider"))
return new Slider(parent, name.toLatin1().constData(), Qt::Horizontal);
return QUiLoader::createWidget(className, parent, name);
diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h
index 717f98b6..044fd863 100644
--- a/muse2/muse/plugin.h
+++ b/muse2/muse/plugin.h
@@ -72,18 +72,6 @@ class Xml;
class MidiController;
-/*
-//---------------------------------------------------------
-// PluginBase
-//---------------------------------------------------------
-
-class PluginBase
-{
- protected:
- void range(unsigned long i, float*, float*) const;
-};
-*/
-
//---------------------------------------------------------
// Plugin
//---------------------------------------------------------
@@ -155,13 +143,11 @@ class Plugin {
if (plugin && plugin->cleanup)
plugin->cleanup(handle);
}
- //void connectPort(LADSPA_Handle handle, int port, float* value) {
- void connectPort(LADSPA_Handle handle, unsigned long port, float* value) { // p4.0.21
+ void connectPort(LADSPA_Handle handle, unsigned long port, float* value) {
if(plugin)
plugin->connect_port(handle, port, value);
}
- //void apply(LADSPA_Handle handle, int n) {
- void apply(LADSPA_Handle handle, unsigned long n) { // p4.0.21
+ void apply(LADSPA_Handle handle, unsigned long n) {
if(plugin)
plugin->run(handle, n);
}
@@ -170,12 +156,10 @@ class Plugin {
int oscConfigure(LADSPA_Handle /*handle*/, const char* /*key*/, const char* /*value*/);
#endif
- //int ports() { return plugin ? plugin->PortCount : 0; }
unsigned long ports() { return _portCount; }
LADSPA_PortDescriptor portd(unsigned long k) const {
return plugin ? plugin->PortDescriptors[k] : 0;
- //return _portDescriptors[k];
}
LADSPA_PortRangeHint range(unsigned long i) {
@@ -184,8 +168,7 @@ class Plugin {
return plugin->PortRangeHints[i];
}
- //double defaultValue(unsigned long port) const;
- float defaultValue(unsigned long port) const; // p4.0.21
+ float defaultValue(unsigned long port) const;
void range(unsigned long i, float*, float*) const;
CtrlValueType ctrlValueType(unsigned long /*i*/) const;
CtrlList::Mode ctrlMode(unsigned long /*i*/) const;
@@ -202,20 +185,6 @@ class Plugin {
unsigned long controlInPorts() const { return _controlInPorts; }
unsigned long controlOutPorts() const { return _controlOutPorts; }
bool inPlaceCapable() const { return _inPlaceCapable; }
-
- /*
- bool isLog(int k) const {
- LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]];
- return LADSPA_IS_HINT_LOGARITHMIC(r.HintDescriptor);
- }
- bool isBool(int k) const {
- return LADSPA_IS_HINT_TOGGLED(plugin->PortRangeHints[pIdx[k]].HintDescriptor);
- }
- bool isInt(int k) const {
- LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]];
- return LADSPA_IS_HINT_INTEGER(r.HintDescriptor);
- }
- */
};
typedef std::list<Plugin>::iterator iPlugin;
@@ -266,21 +235,18 @@ class PluginIBase
~PluginIBase();
virtual bool on() const = 0;
virtual void setOn(bool /*val*/) = 0;
- //virtual int pluginID() = 0;
- virtual unsigned long pluginID() = 0; // p4.0.21
+ virtual unsigned long pluginID() = 0;
virtual int id() = 0;
virtual QString pluginLabel() const = 0;
virtual QString name() const = 0;
virtual QString lib() const = 0;
virtual QString dirPath() const = 0;
virtual QString fileName() const = 0;
+ virtual QString titlePrefix() const = 0;
virtual AudioTrack* track() = 0;
- //virtual void enableController(int /*i*/, bool /*v*/ = true) = 0;
- //virtual bool controllerEnabled(int /*i*/) const = 0;
- //virtual bool controllerEnabled2(int /*i*/) const = 0;
- virtual void enableController(unsigned long /*i*/, bool /*v*/ = true) = 0; // p4.0.21
+ virtual void enableController(unsigned long /*i*/, bool /*v*/ = true) = 0;
virtual bool controllerEnabled(unsigned long /*i*/) const = 0;
virtual bool controllerEnabled2(unsigned long /*i*/) const = 0;
virtual void updateControllers() = 0;
@@ -288,12 +254,7 @@ class PluginIBase
virtual void writeConfiguration(int /*level*/, Xml& /*xml*/) = 0;
virtual bool readConfiguration(Xml& /*xml*/, bool /*readPreset*/=false) = 0;
- //virtual int parameters() const = 0;
- //virtual void setParam(int /*i*/, double /*val*/) = 0;
- //virtual double param(int /*i*/) const = 0;
- //virtual const char* paramName(int /*i*/) = 0;
- //virtual LADSPA_PortRangeHint range(int /*i*/) = 0;
- virtual unsigned long parameters() const = 0; // p4.0.21
+ virtual unsigned long parameters() const = 0;
virtual unsigned long parametersOut() const = 0;
virtual void setParam(unsigned long /*i*/, float /*val*/) = 0;
virtual float param(unsigned long /*i*/) const = 0;
@@ -307,8 +268,6 @@ class PluginIBase
virtual CtrlList::Mode ctrlMode(unsigned long /*i*/) const = 0;
QString dssi_ui_filename() const;
- //virtual void showGui(bool) = 0; // p4.0.20
- //virtual void showNativeGui(bool) = 0; //
MusEGui::PluginGui* gui() const { return _gui; }
void deleteGui();
};
@@ -353,7 +312,6 @@ class PluginBase
#define AUDIO_IN (LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT)
#define AUDIO_OUT (LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT)
-//class PluginI {
class PluginI : public PluginIBase {
Plugin* _plugin;
int channel;
@@ -365,10 +323,8 @@ class PluginI : public PluginIBase {
Port* controls;
Port* controlsOut;
- //int controlPorts;
- //int controlOutPorts;
- unsigned long controlPorts; // p4.0.21
- unsigned long controlOutPorts; //
+ unsigned long controlPorts;
+ unsigned long controlOutPorts;
///PluginGui* _gui;
bool _on;
@@ -400,26 +356,17 @@ class PluginI : public PluginIBase {
void setTrack(AudioTrack* t) { _track = t; }
AudioTrack* track() { return _track; }
- //int pluginID() { return _plugin->id(); }
- unsigned long pluginID() { return _plugin->id(); } // p4.0.21
+ unsigned long pluginID() { return _plugin->id(); }
void setID(int i);
int id() { return _id; }
void updateControllers();
bool initPluginInstance(Plugin*, int channels);
void setChannels(int);
- //void connect(int ports, float** src, float** dst);
- //void apply(int n);
- //void connect(unsigned ports, float** src, float** dst);
- //void apply(unsigned n);
- void connect(unsigned long ports, unsigned long offset, float** src, float** dst); // p4.0.21
- void apply(unsigned long n, unsigned long ports, float** bufIn, float** bufOut); //
-
- //void enableController(int i, bool v = true) { controls[i].enCtrl = v; }
- //bool controllerEnabled(int i) const { return controls[i].enCtrl; }
- //void enable2Controller(int i, bool v = true) { controls[i].en2Ctrl = v; }
- //bool controllerEnabled2(int i) const { return controls[i].en2Ctrl; }
- void enableController(unsigned long i, bool v = true) { controls[i].enCtrl = v; } // p4.0.21
+ void connect(unsigned long ports, unsigned long offset, float** src, float** dst);
+ void apply(unsigned long n, unsigned long ports, float** bufIn, float** bufOut);
+
+ void enableController(unsigned long i, bool v = true) { controls[i].enCtrl = v; }
bool controllerEnabled(unsigned long i) const { return controls[i].enCtrl; }
void enable2Controller(unsigned long i, bool v = true) { controls[i].en2Ctrl = v; }
bool controllerEnabled2(unsigned long i) const { return controls[i].en2Ctrl; }
@@ -434,6 +381,7 @@ class PluginI : public PluginIBase {
QString lib() const { return _plugin->lib(); }
QString dirPath() const { return _plugin->dirPath(); }
QString fileName() const { return _plugin->fileName(); }
+ QString titlePrefix() const;
#ifdef OSC_SUPPORT
OscEffectIF& oscIF() { return _oscif; }
@@ -453,8 +401,7 @@ class PluginI : public PluginIBase {
void writeConfiguration(int level, Xml& xml);
bool readConfiguration(Xml& xml, bool readPreset=false);
bool loadControl(Xml& xml);
- //bool setControl(const QString& s, double val);
- bool setControl(const QString& s, float val); // p4.0.21
+ bool setControl(const QString& s, float val);
void showGui();
void showGui(bool);
bool isDssiPlugin() const { return _plugin->isDssiPlugin(); }
@@ -464,20 +411,8 @@ class PluginI : public PluginIBase {
bool guiVisible();
bool nativeGuiVisible();
- //int parameters() const { return controlPorts; }
- //void setParam(int i, double val) { controls[i].tmpVal = val; }
- //double param(int i) const { return controls[i].val; }
- //double defaultValue(unsigned int param) const;
- //const char* paramName(int i) { return _plugin->portName(controls[i].idx); }
- //LADSPA_PortDescriptor portd(int i) const { return _plugin->portd(controls[i].idx); }
- //void range(int i, float* min, float* max) const { _plugin->range(controls[i].idx, min, max); }
- //bool isAudioIn(int k) { return (_plugin->portd(k) & AUDIO_IN) == AUDIO_IN; }
- //bool isAudioOut(int k) { return (_plugin->portd(k) & AUDIO_OUT) == AUDIO_OUT; }
- //LADSPA_PortRangeHint range(int i) { return _plugin->range(controls[i].idx); }
- // p4.0.21
unsigned long parameters() const { return controlPorts; }
unsigned long parametersOut() const { return controlOutPorts; }
- //void setParam(unsigned i, float val) { controls[i].tmpVal = val; }
void setParam(unsigned long i, float val);
float param(unsigned long i) const { return controls[i].val; }
float paramOut(unsigned long i) const { return controlsOut[i].val; }
@@ -500,8 +435,6 @@ class PluginI : public PluginIBase {
// chain of connected efx inserts
//---------------------------------------------------------
-//const int PipelineDepth = 4; // Moved to globaldefs.h
-
class Pipeline : public std::vector<PluginI*> {
float* buffer[MAX_CHANNELS];
@@ -525,8 +458,7 @@ class Pipeline : public std::vector<PluginI*> {
void deleteAllGuis();
bool guiVisible(int);
bool nativeGuiVisible(int);
- //void apply(int ports, unsigned long nframes, float** buffer);
- void apply(unsigned long ports, unsigned long nframes, float** buffer); // p4.0.21
+ void apply(unsigned long ports, unsigned long nframes, float** buffer);
void move(int idx, bool up);
bool empty(int idx) const;
void setChannels(int);
@@ -537,11 +469,6 @@ typedef Pipeline::const_iterator ciPluginI;
extern void initPlugins();
-//extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val);
-//extern void ladspaControlRange(const LADSPA_Descriptor* plugin, int i, float* min, float* max);
-//extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctlnum, int* min, int* max, int* def);
-//extern float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, int val);
-// p4.0.21
extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, unsigned long port, float* val);
extern void ladspaControlRange(const LADSPA_Descriptor* plugin, unsigned long port, float* min, float* max);
extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long port, int ctlnum, int* min, int* max, int* def);
@@ -593,8 +520,7 @@ struct GuiWidgets {
};
QWidget* widget;
int type;
- //int param;
- unsigned long param; // p4.0.21
+ unsigned long param;
};
//---------------------------------------------------------
@@ -604,13 +530,11 @@ struct GuiWidgets {
class PluginGui : public QMainWindow {
Q_OBJECT
- //PluginI* plugin; // plugin instance
MusECore::PluginIBase* plugin; // plugin instance
GuiParam* params;
GuiParam* paramsOut;
- //int nobj;
- unsigned long nobj; // number of widgets in gw // p4.0.21
+ unsigned long nobj; // number of widgets in gw
GuiWidgets* gw;
QAction* onOff;
@@ -640,7 +564,6 @@ class PluginGui : public QMainWindow {
void heartBeat();
public:
- //PluginGui(MusECore::PluginI*);
PluginGui(MusECore::PluginIBase*);
~PluginGui();
diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp
index 57b956ca..90818a44 100644
--- a/muse2/muse/remote/pyapi.cpp
+++ b/muse2/muse/remote/pyapi.cpp
@@ -1131,7 +1131,9 @@ bool Song::event(QEvent* _e)
break;
}
case QPybridgeEvent::SONG_ADD_TRACK:
- MusEGlobal::song->addTrack((Track::TrackType)e->getP1()); // Add at end of list.
+ MusECore::Undo operations;
+ MusEGlobal::song->addTrack(operations, (Track::TrackType)e->getP1()); // Add at end of list.
+ MusEGlobal::song->applyOperationGroup(operations);
break;
case QPybridgeEvent::SONG_CHANGE_TRACKNAME: {
Track* t = this->findTrack(e->getS1());
diff --git a/muse2/muse/route.cpp b/muse2/muse/route.cpp
index f00c6d6c..1d494fb0 100644
--- a/muse2/muse/route.cpp
+++ b/muse2/muse/route.cpp
@@ -4,6 +4,7 @@
// $Id: route.cpp,v 1.18.2.3 2008/05/21 00:28:52 terminator356 Exp $
//
// (C) Copyright 2003-2004 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -37,8 +38,6 @@
//#define ROUTE_DEBUG
-//#define ROUTE_MIDIPORT_NAME_PREFIX "MusE MidiPort "
-
namespace MusECore {
const QString ROUTE_MIDIPORT_NAME_PREFIX = "MusE MidiPort ";
@@ -57,9 +56,7 @@ Route::Route(void* t, int ch)
type = JACK_ROUTE;
}
-//Route::Route(AudioTrack* t, int ch)
Route::Route(Track* t, int ch, int chans)
-//Route::Route(Track* t, int ch)
{
track = t;
midiPort = -1;
@@ -69,7 +66,6 @@ Route::Route(Track* t, int ch, int chans)
type = TRACK_ROUTE;
}
-//Route::Route(MidiJackDevice* d)
Route::Route(MidiDevice* d, int ch)
{
device = d;
@@ -77,19 +73,10 @@ Route::Route(MidiDevice* d, int ch)
channel = ch;
channels = -1;
remoteChannel = -1;
- /*
- //if(dynamic_cast<MidiJackDevice*>(d))
- if(d->deviceType() == MidiDevice::JACK_MIDI)
- type = JACK_MIDI_ROUTE;
- else
- //if(dynamic_cast<MidiAlsaDevice*>(d))
- if(d->deviceType() == MidiDevice::ALSA_MIDI)
- type = ALSA_MIDI_ROUTE;
- */
type = MIDI_DEVICE_ROUTE;
}
-Route::Route(int port, int ch) // p3.3.49
+Route::Route(int port, int ch)
{
track = 0;
midiPort = port;
@@ -99,16 +86,12 @@ Route::Route(int port, int ch) // p3.3.49
type = MIDI_PORT_ROUTE;
}
-//Route::Route(const QString& s, bool dst, int ch)
Route::Route(const QString& s, bool dst, int ch, int rtype)
{
- //Route node(name2route(s, dst));
Route node(name2route(s, dst, rtype));
channel = node.channel;
if(channel == -1)
channel = ch;
- //if(channels == -1)
- // channels = chans;
channels = node.channels;
remoteChannel = node.remoteChannel;
type = node.type;
@@ -123,14 +106,6 @@ Route::Route(const QString& s, bool dst, int ch, int rtype)
jackPort = node.jackPort;
midiPort = -1;
}
- /*
- else
- if (type == JACK_MIDI_ROUTE)
- device = node.device;
- else
- if (type == ALSA_MIDI_ROUTE)
- device = node.device;
- */
else
if(type == MIDI_DEVICE_ROUTE)
{
@@ -138,10 +113,10 @@ Route::Route(const QString& s, bool dst, int ch, int rtype)
midiPort = -1;
}
else
- if(type == MIDI_PORT_ROUTE) // p3.3.49
+ if(type == MIDI_PORT_ROUTE)
{
track = 0;
- midiPort = node.midiPort; //
+ midiPort = node.midiPort;
}
}
@@ -179,31 +154,20 @@ void addRoute(Route src, Route dst)
// dst.type, dst.channel, dst.name().toLatin1().constData());
if (src.type == Route::JACK_ROUTE)
{
- //if (dst.type != TRACK_ROUTE)
- //{
- // fprintf(stderr, "addRoute: bad route 1\n");
- // exit(-1);
- // return;
- //}
-
if (dst.type == Route::TRACK_ROUTE)
{
if (dst.track->type() != Track::AUDIO_INPUT)
{
fprintf(stderr, "addRoute: source is jack, dest:%s is track but not audio input\n", dst.track->name().toLatin1().constData());
- //exit(-1);
return;
}
if (dst.channel < 0)
{
fprintf(stderr, "addRoute: source is jack, dest:%s is track but invalid channel:%d\n", dst.track->name().toLatin1().constData(), dst.channel);
- //exit(-1);
return;
}
- //src.channel = src.dstChannel = dst.channel;
src.channel = dst.channel;
- //src.channels = dst.channels = 1;
RouteList* inRoutes = dst.track->inRoutes();
for (ciRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
{
@@ -221,28 +185,11 @@ void addRoute(Route src, Route dst)
inRoutes->push_back(src);
}
else
- //if (dst.type == Route::JACK_MIDI_ROUTE)
if (dst.type == Route::MIDI_DEVICE_ROUTE)
- //if (dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49
{
- //MidiDevice *md = MusEGlobal::midiPorts[dst.midiPort].device();
- //if(dst.device->deviceType() == MidiDevice::JACK_MIDI)
- //if(!md)
- //{
- // fprintf(stderr, "addRoute: source is Jack, but no destination port device\n");
- // return;
- //}
-
if(dst.device->deviceType() == MidiDevice::JACK_MIDI)
- //if(md->deviceType() == MidiDevice::JACK_MIDI)
{
src.channel = dst.channel;
- //src.channel = -1;
- //src.channel = 0;
- //src.channel = src.dstChannel = dst.channel;
- //src.channels = dst.channels = 1;
- //dst.channel = -1;
-
RouteList* routes = dst.device->inRoutes();
for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
@@ -262,45 +209,32 @@ void addRoute(Route src, Route dst)
else
{
fprintf(stderr, "addRoute: source is Jack, but destination is not jack midi - type:%d\n", dst.device->deviceType());
- // exit(-1);
return;
}
}
else
{
fprintf(stderr, "addRoute: source is Jack, but destination is not track or midi - type:%d \n", dst.type);
- // exit(-1);
return;
}
}
else if (dst.type == Route::JACK_ROUTE)
{
- //if (src.type != TRACK_ROUTE)
- //{
- // fprintf(stderr, "addRoute: bad route 3\n");
- // exit(-1);
- // return;
- //}
-
if (src.type == Route::TRACK_ROUTE)
{
if (src.track->type() != Track::AUDIO_OUTPUT)
{
fprintf(stderr, "addRoute: destination is jack, source is track but not audio output\n");
- // exit(-1);
return;
}
if (src.channel < 0)
{
fprintf(stderr, "addRoute: destination is jack, source:%s is track but invalid channel:%d\n", src.track->name().toLatin1().constData(), src.channel);
- // exit(-1);
return;
}
RouteList* outRoutes = src.track->outRoutes();
- //dst.channel = dst.dstChannel = src.channel;
dst.channel = src.channel;
- //dst.channels = src.channels = 1;
for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
@@ -318,17 +252,11 @@ void addRoute(Route src, Route dst)
outRoutes->push_back(dst);
}
else
- //if (src.type == Route::JACK_MIDI_ROUTE)
if (src.type == Route::MIDI_DEVICE_ROUTE)
{
if(src.device->deviceType() == MidiDevice::JACK_MIDI)
{
dst.channel = src.channel;
- //dst.channel = -1;
- //src.channel = -1;
- //dst.channel = dst.dstChannel = src.channel;
- //dst.channels = src.channels = 1;
-
RouteList* routes = src.device->outRoutes();
for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
@@ -348,18 +276,16 @@ void addRoute(Route src, Route dst)
else
{
fprintf(stderr, "addRoute: destination is Jack, but source is not jack midi - type:%d\n", src.device->deviceType());
- // exit(-1);
return;
}
}
else
{
fprintf(stderr, "addRoute: destination is Jack, but source is not track or midi - type:%d \n", src.type);
- // exit(-1);
return;
}
}
- else if(src.type == Route::MIDI_PORT_ROUTE) // p3.3.49
+ else if(src.type == Route::MIDI_PORT_ROUTE)
{
if(dst.type != Route::TRACK_ROUTE)
{
@@ -367,66 +293,18 @@ void addRoute(Route src, Route dst)
return;
}
- // p4.0.14
- /*
- if(dst.track->type() == Track::AUDIO_INPUT)
- {
- if(src.channel < 1 || src.channel >= (1 << MIDI_CHANNELS))
- {
- fprintf(stderr, "addRoute: source is midi port:%d, but channel mask:%d out of range\n", src.midiPort, src.channel);
- return;
- }
-
- MidiPort *mp = &MusEGlobal::midiPorts[src.midiPort];
- //src.channel = dst.channel = -1;
- RouteList* outRoutes = mp->outRoutes();
- iRoute ir = outRoutes->begin();
- for ( ; ir != outRoutes->end(); ++ir)
- {
- //if (*i == dst) // route already there
- ir->dump();
- if (ir->type == Route::TRACK_ROUTE && ir->track == dst.track) // Does a route to the track exist?
- {
- //#ifdef ROUTE_DEBUG
- fprintf(stderr, "addRoute: src midi port:%d dst audio in track:%s out route already exists. ir->channel:%d |= dst.channel:%d\n",
- src.midiPort, dst.track->name().toLatin1().constData(), ir->channel, dst.channel);
- //#endif
- ir->channel |= dst.channel; // Bitwise OR the desired channel bit with the existing bit mask.
- break;
- //return;
- }
- }
- if(ir == outRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
- outRoutes->push_back(dst);
-
- RouteList* inRoutes = dst.track->inRoutes();
-
- ir = inRoutes->begin();
- for ( ; ir != inRoutes->end(); ++ir)
- {
- if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == src.midiPort) // Does a route to the midi port exist?
- {
- fprintf(stderr, "addRoute: src midi port:%d dst audio in track:%s in route already exists. ir->channel:%d |= src.channel:%d\n",
- src.midiPort, dst.track->name().toLatin1().constData(), ir->channel, src.channel);
- ir->channel |= src.channel; // Bitwise OR the desired channel bit with the existing bit mask.
- break;
- }
- }
- if(ir == inRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
- inRoutes->push_back(src);
-
- return;
- }
- */
-
MidiPort *mp = &MusEGlobal::midiPorts[src.midiPort];
- // p4.0.17 Do not allow ports with synth midi devices to connect to audio ins!
- if(dst.track->type() == Track::AUDIO_INPUT && mp->device() && mp->device()->isSynti())
- {
- fprintf(stderr, "addRoute: destination is audio in, but source midi port:%d is synth device\n", src.midiPort);
+ // Do not allow ports with synth midi devices to connect to audio ins! p4.0.17
+ //if(dst.track->type() == Track::AUDIO_INPUT && mp->device() && mp->device()->isSynti())
+ //{
+ // fprintf(stderr, "addRoute: destination is audio in, but source midi port:%d is synth device\n", src.midiPort);
+ // return;
+ //}
+ // Actually, do not allow synth ports to connect to any track. It may be useful in some cases,
+ // may be desired later, but for now it's just a routing hassle. p4.0.35
+ if(mp->device() && mp->device()->isSynti())
return;
- }
if(dst.channel < 1 || dst.channel >= (1 << MIDI_CHANNELS))
{
@@ -443,46 +321,39 @@ void addRoute(Route src, Route dst)
src.channel = dst.channel;
RouteList* outRoutes = mp->outRoutes();
- //for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
- iRoute ir = outRoutes->begin(); // p3.3.50
+ iRoute ir = outRoutes->begin();
for ( ; ir != outRoutes->end(); ++ir)
{
- //if (*i == dst) // route already there
- if (ir->type == Route::TRACK_ROUTE && ir->track == dst.track) // p3.3.50 Does a route to the track exist?
+ if (ir->type == Route::TRACK_ROUTE && ir->track == dst.track) // Does a route to the track exist?
{
- //#ifdef ROUTE_DEBUG
- //fprintf(stderr, "addRoute: src midi port:%d dst track:%s route already exists.\n", src.midiPort, dst.track->name().toLatin1().constData());
- //#endif
- ir->channel |= dst.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask.
+ ir->channel |= dst.channel; // Bitwise OR the desired channel bit with the existing bit mask.
break;
-
- //return;
}
}
#ifdef ROUTE_DEBUG
fprintf(stderr, "addRoute: src midi port:%d dst track name:%s pushing dst and src routes\n", src.midiPort, dst.track->name().toLatin1().constData());
#endif
- if(ir == outRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with.
+ if(ir == outRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
outRoutes->push_back(dst);
RouteList* inRoutes = dst.track->inRoutes();
- // p3.3.50 Make sure only one single route, with a channel mask, can ever exist.
+ // Make sure only one single route, with a channel mask, can ever exist.
ir = inRoutes->begin();
for ( ; ir != inRoutes->end(); ++ir)
{
- if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == src.midiPort) // p3.3.50 Does a route to the midi port exist?
+ if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == src.midiPort) // Does a route to the midi port exist?
{
- ir->channel |= src.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask.
+ ir->channel |= src.channel; // Bitwise OR the desired channel bit with the existing bit mask.
break;
}
}
- if(ir == inRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with.
+ if(ir == inRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
inRoutes->push_back(src);
}
- else if(dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49
+ else if(dst.type == Route::MIDI_PORT_ROUTE)
{
if(src.type != Route::TRACK_ROUTE)
{
@@ -495,7 +366,6 @@ void addRoute(Route src, Route dst)
return;
}
-
//MidiDevice *md = MusEGlobal::midiPorts[dst.midiPort].device();
//if(!md)
//{
@@ -506,24 +376,17 @@ void addRoute(Route src, Route dst)
dst.channel = src.channel;
RouteList* outRoutes = src.track->outRoutes();
- //for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
- iRoute ir = outRoutes->begin(); // p3.3.50
+ iRoute ir = outRoutes->begin();
for ( ; ir != outRoutes->end(); ++ir)
{
- //if (*i == dst) // route already there
- if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == dst.midiPort) // p3.3.50 Does a route to the midi port exist?
+ if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == dst.midiPort) // Does a route to the midi port exist?
{
- //#ifdef ROUTE_DEBUG
- //fprintf(stderr, "addRoute: dst midi port:%d src track:%s route already exists.\n", dst.midiPort, src.track->name().toLatin1().constData());
- //#endif
- //return;
-
- ir->channel |= dst.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask.
+ ir->channel |= dst.channel; // Bitwise OR the desired channel bit with the existing bit mask.
break;
}
}
- if(ir == outRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with.
+ if(ir == outRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
outRoutes->push_back(dst);
MidiPort *mp = &MusEGlobal::midiPorts[dst.midiPort];
@@ -533,167 +396,97 @@ void addRoute(Route src, Route dst)
#endif
RouteList* inRoutes = mp->inRoutes();
- // p3.3.50 Make sure only one single route, with a channel mask, can ever exist.
+ // Make sure only one single route, with a channel mask, can ever exist.
ir = inRoutes->begin();
for ( ; ir != inRoutes->end(); ++ir)
{
- if (ir->type == Route::TRACK_ROUTE && ir->track == src.track) // p3.3.50 Does a route to the track exist?
+ if (ir->type == Route::TRACK_ROUTE && ir->track == src.track) // Does a route to the track exist?
{
- ir->channel |= src.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask.
+ ir->channel |= src.channel; // Bitwise OR the desired channel bit with the existing bit mask.
break;
}
}
- if(ir == inRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with.
+ if(ir == inRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with.
inRoutes->push_back(src);
- //inRoutes->insert(inRoutes->begin(), src);
}
else
{
- if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE) // p3.3.49
+ if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE)
{
fprintf(stderr, "addRoute: source or destination are not track routes\n");
return;
}
- // Removed p3.3.49
- /*
- //if ((src.type == Route::JACK_MIDI_ROUTE) || (src.type == Route::ALSA_MIDI_ROUTE))
- if(src.type == Route::MIDI_DEVICE_ROUTE)
- {
- //src.channel = src.dstChannel = dst.dstChannel = dst.channel;
- src.channel = dst.channel;
- //src.channels = dst.channels = 1;
- RouteList* outRoutes = src.device->outRoutes();
- #ifdef ROUTE_DEBUG
- fprintf(stderr, "addRoute: src name: %s looking for existing dest in out routes...\n", src.device->name().toLatin1().constData());
- #endif
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
- {
- if (*i == dst) // route already there
- {
- //#ifdef ROUTE_DEBUG
- fprintf(stderr, "addRoute: src Jack or ALSA midi route already exists.\n");
- //#endif
- return;
- }
- }
- #ifdef ROUTE_DEBUG
- fprintf(stderr, "addRoute: src midi dst name: %s pushing destination and source routes\n", dst.track->name().toLatin1().constData());
- #endif
-
- outRoutes->push_back(dst);
- RouteList* inRoutes = dst.track->inRoutes();
- inRoutes->push_back(src);
- }
- else
- */
+ RouteList* outRoutes = src.track->outRoutes();
- {
- ///if(dst.type == Route::MIDI_DEVICE_ROUTE) // Removed p3.3.49
- //{
- /// dst.channel = src.channel;
- //src.channel = src.dstChannel = dst.dstChannel = dst.channel;
- //src.channels = dst.channels = 1;
- //}
- //else
- //{
- //src.channel = src.dstChannel = dst.dstChannel = dst.channel;
- //src.channels = dst.channels = 1;
- //}
-
- RouteList* outRoutes = src.track->outRoutes();
-
- //
- // Must enforce to ensure channel and channels are valid if defaults of -1 passed.
- //
- if(src.track->type() == Track::AUDIO_SOFTSYNTH)
- {
- if(src.channel == -1)
- src.channel = 0;
- if(src.channels == -1)
- src.channels = src.track->channels();
- //if(dst.type == Route::TRACK_ROUTE) // p3.3.49 Removed
- //{
- //if(dst.channel == -1)
- // dst.channel = 0;
- //if(dst.channels == -1)
- // Yes, that's correct: dst channels = src track channels.
- // dst.channels = src.track->channels();
- dst.channel = src.channel;
- dst.channels = src.channels;
- dst.remoteChannel = src.remoteChannel;
- //}
- }
- //if(dst.type == Route::TRACK_ROUTE && dst.track->type() == Track::AUDIO_SOFTSYNTH)
- //{
- // if(dst.channel == -1)
- // dst.channel = 0;
- // if(dst.channels == -1)
- // Yes, that's correct: dst channels = src track channels.
- // dst.channels = src.track->channels();
- //}
-
- for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
- {
- if (*i == dst) // route already there
- // TODO:
- //if (i->type == dst.type && i->channel == dst.channel)
+ //
+ // Must enforce to ensure channel and channels are valid if defaults of -1 passed.
+ //
+ if(src.track->type() == Track::AUDIO_SOFTSYNTH)
+ {
+ if(src.channel == -1)
+ src.channel = 0;
+ if(src.channels == -1)
+ src.channels = src.track->channels();
+ dst.channel = src.channel;
+ dst.channels = src.channels;
+ dst.remoteChannel = src.remoteChannel;
+ }
+
+ for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
+ {
+ if (*i == dst) // route already there
+ // TODO:
+ //if (i->type == dst.type && i->channel == dst.channel)
+ {
+ //if(i->type == Route::TRACK_ROUTE)
+ {
+ //if(i->track == dst.track)
{
- //if(i->type == Route::TRACK_ROUTE)
+ //if(i->channels == dst.channels)
{
- //if(i->track == dst.track)
- {
- //if(i->channels == dst.channels)
- {
- //#ifdef ROUTE_DEBUG
- fprintf(stderr, "addRoute: src track route already exists.\n");
- //#endif
- return;
- }
- //else
- //{
-
- //}
- }
+ //#ifdef ROUTE_DEBUG
+ fprintf(stderr, "addRoute: src track route already exists.\n");
+ //#endif
+ return;
}
- }
- }
- outRoutes->push_back(dst);
- RouteList* inRoutes;
-
- // Removed p3.3.49
- /*
- //if ((dst.type == Route::JACK_MIDI_ROUTE) || (dst.type == Route::ALSA_MIDI_ROUTE))
- if(dst.type == Route::MIDI_DEVICE_ROUTE)
- {
- #ifdef ROUTE_DEBUG
- fprintf(stderr, "addRoute: src track dst midi name: %s pushing destination and source routes\n", dst.device->name().toLatin1().constData());
- #endif
- inRoutes = dst.device->inRoutes();
- }
- else
- */
-
- {
- #ifdef ROUTE_DEBUG
- //fprintf(stderr, "addRoute: src track ch:%d chs:%d dst track ch:%d chs:%d name: %s pushing destination and source routes\n", src.channel, src.channels, dst.channel, dst.channels, dst.track->name().toLatin1().constData());
- fprintf(stderr, "addRoute: src track ch:%d chs:%d remch:%d dst track ch:%d chs:%d remch:%d name: %s pushing dest and source routes\n",
- src.channel, src.channels, src.remoteChannel, dst.channel, dst.channels, dst.remoteChannel, dst.track->name().toLatin1().constData());
- //fprintf(stderr, "addRoute: src track ch:%d dst track ch:%d name: %s pushing destination and source routes\n", src.channel, dst.channel, dst.track->name().toLatin1().constData());
- #endif
- inRoutes = dst.track->inRoutes();
- }
-
-
- //
- // make sure AUDIO_AUX is processed last
- //
- if (src.track->type() == Track::AUDIO_AUX)
- inRoutes->push_back(src);
- else
- inRoutes->insert(inRoutes->begin(), src);
- }
+ //else
+ //{
+
+ //}
+ }
+ }
+ }
+ }
+ outRoutes->push_back(dst);
+ RouteList* inRoutes;
+
+ #ifdef ROUTE_DEBUG
+ //fprintf(stderr, "addRoute: src track ch:%d chs:%d dst track ch:%d chs:%d name: %s pushing destination and source routes\n", src.channel, src.channels, dst.channel, dst.channels, dst.track->name().toLatin1().constData());
+ fprintf(stderr, "addRoute: src track ch:%d chs:%d remch:%d dst track ch:%d chs:%d remch:%d name: %s pushing dest and source routes\n",
+ src.channel, src.channels, src.remoteChannel, dst.channel, dst.channels, dst.remoteChannel, dst.track->name().toLatin1().constData());
+ //fprintf(stderr, "addRoute: src track ch:%d dst track ch:%d name: %s pushing destination and source routes\n", src.channel, dst.channel, dst.track->name().toLatin1().constData());
+ #endif
+ inRoutes = dst.track->inRoutes();
+
+ //
+ // make sure AUDIO_AUX is processed last
+ //
+ if (src.track->type() == Track::AUDIO_AUX) // REMOVE Tim. This special aux code may not be useful or needed now.
+ inRoutes->push_back(src); //
+ else
+ inRoutes->insert(inRoutes->begin(), src);
+
+ // Is the source an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the destination track's aux ref count, and all tracks it is routed to.
+ if(src.track->auxRefCount())
+ //dst.track->updateAuxStates( src.track->auxRefCount() );
+ src.track->updateAuxRoute( src.track->auxRefCount(), dst.track );
+ else
+ if(src.track->type() == Track::AUDIO_AUX)
+ //dst.track->updateAuxStates( 1 );
+ src.track->updateAuxRoute( 1, dst.track );
}
}
@@ -709,12 +502,6 @@ void removeRoute(Route src, Route dst)
if (src.type == Route::JACK_ROUTE)
{
- //if (dst.type != TRACK_ROUTE)
- //{
- // fprintf(stderr, "removeRoute: bad route 1\n");
- // exit(-1);
- // return;
- //}
if(!dst.isValid())
{
printf("removeRoute: source is jack, invalid destination\n");
@@ -726,7 +513,6 @@ void removeRoute(Route src, Route dst)
if (dst.track->type() != Track::AUDIO_INPUT)
{
fprintf(stderr, "removeRoute: source is jack, destination is track but not audio input\n");
- // exit(-1);
return;
}
RouteList* inRoutes = dst.track->inRoutes();
@@ -741,7 +527,6 @@ void removeRoute(Route src, Route dst)
}
}
else
- //if (dst.type == Route::JACK_MIDI_ROUTE)
if (dst.type == Route::MIDI_DEVICE_ROUTE)
{
RouteList* routes = dst.device->inRoutes();
@@ -758,18 +543,11 @@ void removeRoute(Route src, Route dst)
else
{
fprintf(stderr, "removeRoute: source is jack, destination unknown\n");
- // exit(-1);
return;
}
}
else if (dst.type == Route::JACK_ROUTE)
{
- //if (src.type != TRACK_ROUTE)
- //{
- // fprintf(stderr, "removeRoute: bad route 3\n");
- // exit(-1);
- // return;
- //}
if(!src.isValid())
{
printf("removeRoute: destination is jack, invalid source\n");
@@ -781,7 +559,6 @@ void removeRoute(Route src, Route dst)
if (src.track->type() != Track::AUDIO_OUTPUT)
{
fprintf(stderr, "removeRoute: destination is jack, source is track but not audio output\n");
- // exit(-1);
return;
}
RouteList* outRoutes = src.track->outRoutes();
@@ -795,7 +572,6 @@ void removeRoute(Route src, Route dst)
}
}
else
- //if (src.type == Route::JACK_MIDI_ROUTE)
if (src.type == Route::MIDI_DEVICE_ROUTE)
{
RouteList* routes = src.device->outRoutes();
@@ -811,11 +587,10 @@ void removeRoute(Route src, Route dst)
else
{
fprintf(stderr, "removeRoute: destination is jack, source unknown\n");
- // exit(-1);
return;
}
}
- else if(src.type == Route::MIDI_PORT_ROUTE) // p3.3.49
+ else if(src.type == Route::MIDI_PORT_ROUTE)
{
if(dst.type != Route::TRACK_ROUTE)
{
@@ -829,19 +604,18 @@ void removeRoute(Route src, Route dst)
RouteList* outRoutes = mp->outRoutes();
for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
- //if (*i == dst)
- if(i->type == Route::TRACK_ROUTE && i->track == dst.track) // p3.3.50 Is there a route to the track?
+ if(i->type == Route::TRACK_ROUTE && i->track == dst.track) // Is there a route to the track?
{
//printf("i->channel:%x dst.channel:%x\n", i->channel, dst.channel);
- i->channel &= ~dst.channel; // p3.3.50 Unset the desired channel bits.
+ i->channel &= ~dst.channel; // Unset the desired channel bits.
if(i->channel == 0) // Only if there are no channel bits set, erase the route.
{
//printf("erasing out route from midi port:%d\n", src.midiPort);
outRoutes->erase(i);
}
- break; // For safety, keep looking and remove any more found.
- // No, must break, else crash. There should only be one route anyway...
+ break; // For safety, keep looking and remove any more found.
+ // No, must break, else crash. There should only be one route anyway...
}
}
}
@@ -853,22 +627,21 @@ void removeRoute(Route src, Route dst)
RouteList* inRoutes = dst.track->inRoutes();
for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
{
- //if (*i == src)
- if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == src.midiPort) // p3.3.50 Is there a route to the midi port?
+ if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == src.midiPort) // Is there a route to the midi port?
{
- i->channel &= ~src.channel; // p3.3.50 Unset the desired channel bits.
+ i->channel &= ~src.channel; // Unset the desired channel bits.
if(i->channel == 0) // Only if there are no channel bits set, erase the route.
inRoutes->erase(i);
- break; // For safety, keep looking and remove any more found.
- // No, must break, else crash. There should only be one route anyway...
+ break; // For safety, keep looking and remove any more found.
+ // No, must break, else crash. There should only be one route anyway...
}
}
}
else
printf("removeRoute: source is midi port:%d but destination track invalid\n", src.midiPort);
}
- else if(dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49
+ else if(dst.type == Route::MIDI_PORT_ROUTE)
{
if(src.type != Route::TRACK_ROUTE)
{
@@ -881,15 +654,14 @@ void removeRoute(Route src, Route dst)
RouteList* outRoutes = src.track->outRoutes();
for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
- //if (*i == dst)
- if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == dst.midiPort) // p3.3.50 Is there a route to the midi port?
+ if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == dst.midiPort) // Is there a route to the midi port?
{
- i->channel &= ~dst.channel; // p3.3.50 Unset the desired channel bits.
+ i->channel &= ~dst.channel; // Unset the desired channel bits.
if(i->channel == 0) // Only if there are no channel bits set, erase the route.
outRoutes->erase(i);
- break; // For safety, keep looking and remove any more found.
- // No, must break, else crash. There should only be one route anyway...
+ break; // For safety, keep looking and remove any more found.
+ // No, must break, else crash. There should only be one route anyway...
}
}
}
@@ -902,15 +674,14 @@ void removeRoute(Route src, Route dst)
RouteList* inRoutes = mp->inRoutes();
for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
{
- //if (*i == src)
- if (i->type == Route::TRACK_ROUTE && i->track == src.track) // p3.3.50 Is there a route to the track?
+ if (i->type == Route::TRACK_ROUTE && i->track == src.track) // Is there a route to the track?
{
- i->channel &= ~src.channel; // p3.3.50 Unset the desired channel bits.
+ i->channel &= ~src.channel; // Unset the desired channel bits.
if(i->channel == 0) // Only if there are no channel bits set, erase the route.
inRoutes->erase(i);
- break; // For safety, keep looking and remove any more found.
- // No, must break, else crash. There should only be one route anyway...
+ break; // For safety, keep looking and remove any more found.
+ // No, must break, else crash. There should only be one route anyway...
}
}
}
@@ -919,87 +690,54 @@ void removeRoute(Route src, Route dst)
}
else
{
- if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE) // p3.3.49
+ if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE)
{
fprintf(stderr, "removeRoute: source and destination are not tracks\n");
return;
}
- // Removed p3.3.49
- /*
- //if((src.type == Route::JACK_MIDI_ROUTE) || (src.type == Route::ALSA_MIDI_ROUTE))
- if(src.type == Route::MIDI_DEVICE_ROUTE)
+ // Is the source an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the destination track's aux ref count, and all tracks it is routed to.
+ if(src.isValid() && dst.isValid())
{
- if(src.isValid())
- {
- RouteList* outRoutes = src.device->outRoutes();
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
- {
- if (*i == dst) {
- outRoutes->erase(i);
- break;
- }
- }
- }
+ if(src.track->auxRefCount())
+ //dst.track->updateAuxStates( -src.track->auxRefCount() );
+ src.track->updateAuxRoute( -src.track->auxRefCount(), dst.track );
else
- printf("removeRoute: source is midi but invalid\n");
-
- if(dst.isValid())
+ if(src.track->type() == Track::AUDIO_AUX)
+ //dst.track->updateAuxStates( -1 );
+ src.track->updateAuxRoute( -1, dst.track );
+ }
+
+ if(src.isValid())
+ {
+ RouteList* outRoutes = src.track->outRoutes();
+ for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
- RouteList* inRoutes = dst.track->inRoutes();
- for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
- {
- if (*i == src) {
- inRoutes->erase(i);
- break;
- }
- }
+ if (*i == dst) {
+ outRoutes->erase(i);
+ break;
+ }
}
- else
- printf("removeRoute: source is midi but destination invalid\n");
- }
+ }
else
- */
+ printf("removeRoute: source is track but invalid\n");
+ if(dst.isValid())
{
- if(src.isValid())
- {
- RouteList* outRoutes = src.track->outRoutes();
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
- {
- if (*i == dst) {
- outRoutes->erase(i);
- break;
- }
- }
- }
- else
- printf("removeRoute: source is track but invalid\n");
+ RouteList* inRoutes;
- if(dst.isValid())
+ inRoutes = dst.track->inRoutes();
+ for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
{
- RouteList* inRoutes;
-
- //if ((dst.type == Route::JACK_MIDI_ROUTE) || (dst.type == Route::ALSA_MIDI_ROUTE))
- // Removed p3.3.49
- /*
- if (dst.type == Route::MIDI_DEVICE_ROUTE)
- inRoutes = dst.device->inRoutes();
- else
- */
-
- inRoutes = dst.track->inRoutes();
- for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
- {
- if (*i == src) {
- inRoutes->erase(i);
- break;
- }
- }
- }
- else
- printf("removeRoute: source is track but destination invalid\n");
- }
+ if (*i == src) {
+ inRoutes->erase(i);
+ break;
+ }
+ }
+ }
+ else
+ printf("removeRoute: source is track but destination invalid\n");
}
}
@@ -1013,9 +751,19 @@ void removeRoute(Route src, Route dst)
// So far it only works with MidiDevice <-> Jack.
//---------------------------------------------------------
-// p3.3.55
void removeAllRoutes(Route src, Route dst)
{
+ // TODO: Is the source an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the destination track's aux ref count, and all tracks it is routed to.
+ /* if(src.isValid() && dst.isValid())
+ {
+ if(src.track->auxRefCount())
+ dst.track->updateAuxStates( -src.track->auxRefCount() );
+ else
+ if(src.track->type() == Track::TrackType::AUDIO_AUX))
+ dst.track->updateAuxStates( -1 );
+ } */
+
if(src.isValid())
{
if(src.type == Route::MIDI_DEVICE_ROUTE)
@@ -1052,22 +800,11 @@ static QString track2name(const Track* n)
QString Route::name() const
{
- // p3.3.38 Removed
- /*
- QString s;
- if ((type == TRACK_ROUTE) && (channel != -1)) {
-// if (channel != -1) {
- QString c;
- c.setNum(channel+1);
- s = c + ":";
- }
- */
-
if(type == MIDI_DEVICE_ROUTE)
{
if(device)
{
- // p3.3.55 Removed for unified jack in/out devices, the actual port names are now different from device name.
+ // For unified jack in/out devices, the actual port names are now different from device name.
// Like this: device: "MyJackDevice1" -> inport: "MyJackDevice1_in" outport: "MyJackDevice1_out"
/*
if(device->deviceType() == MidiDevice::JACK_MIDI)
@@ -1075,8 +812,7 @@ QString Route::name() const
else
*/
- //if(device->deviceType() == MidiDevice::ALSA_MIDI)
- return device->name();
+ return device->name();
}
return QWidget::tr("None");
}
@@ -1084,16 +820,14 @@ QString Route::name() const
if(type == JACK_ROUTE)
{
if (!MusEGlobal::checkAudioDevice()) return "";
- //return s + MusEGlobal::audioDevice->portName(jackPort);
return MusEGlobal::audioDevice->portName(jackPort);
}
else
- if(type == MIDI_PORT_ROUTE) // p3.3.49
+ if(type == MIDI_PORT_ROUTE)
{
return ROUTE_MIDIPORT_NAME_PREFIX + QString().setNum(midiPort);
}
else
- //return s + track2name(track);
return track2name(track);
}
@@ -1106,7 +840,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
{
// printf("name2route %s\n", rn.toLatin1().constData());
int channel = -1;
- //int channel = 0;
QString s(rn);
// Support old route style in med files. Obsolete.
if (rn[0].isNumber() && rn[1]==':')
@@ -1117,8 +850,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
if(rtype == -1)
{
- //if(dst)
- //{
if(MusEGlobal::checkAudioDevice())
{
void* p = MusEGlobal::audioDevice->findPort(s.toLatin1().constData());
@@ -1149,7 +880,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
return Route(*i, channel);
}
- // p3.3.49
if(s.left(ROUTE_MIDIPORT_NAME_PREFIX.length()) == ROUTE_MIDIPORT_NAME_PREFIX)
{
bool ok = false;
@@ -1160,8 +890,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
}
else
{
- //if(dst)
- //{
if(rtype == Route::TRACK_ROUTE)
{
TrackList* tl = MusEGlobal::song->tracks();
@@ -1178,8 +906,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
AudioTrack* track = (AudioTrack*)*i;
if(track->name() == s)
return Route(track, channel);
- //return Route(track, channel, 1);
- //return Route(track, channel, track->channels());
}
}
}
@@ -1191,7 +917,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
for(iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i)
{
if((*i)->name() == s)
- //if (jmd->name() == rn)
return Route(*i, channel);
/*
@@ -1224,7 +949,7 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
}
}
else
- if(rtype == Route::MIDI_PORT_ROUTE) // p3.3.49
+ if(rtype == Route::MIDI_PORT_ROUTE)
{
if(s.left(ROUTE_MIDIPORT_NAME_PREFIX.length()) == ROUTE_MIDIPORT_NAME_PREFIX)
{
@@ -1238,7 +963,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype)
printf(" name2route: <%s> not found\n", rn.toLatin1().constData());
return Route((Track*) 0, channel);
- //return Route((Track*) 0, channel, 1);
}
//---------------------------------------------------------
@@ -1255,10 +979,6 @@ bool checkRoute(const QString& s, const QString& d)
return false;
if (src.type == Route::JACK_ROUTE)
{
- //if (dst.type != TRACK_ROUTE) {
- // return false;
- // }
-
if (dst.type == Route::TRACK_ROUTE)
{
if (dst.track->type() != Track::AUDIO_INPUT) {
@@ -1274,12 +994,9 @@ bool checkRoute(const QString& s, const QString& d)
}
}
else
- //if (dst.type == Route::JACK_MIDI_ROUTE)
if (dst.type == Route::MIDI_DEVICE_ROUTE)
{
- //src.channel = dst.channel;
src.channel = -1;
- //dst.channel = -1;
RouteList* routes = dst.device->inRoutes();
for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
@@ -1293,10 +1010,6 @@ bool checkRoute(const QString& s, const QString& d)
}
else if (dst.type == Route::JACK_ROUTE)
{
- //if (src.type != TRACK_ROUTE) {
- // return false;
- // }
-
if (src.type == Route::TRACK_ROUTE)
{
if (src.track->type() != Track::AUDIO_OUTPUT) {
@@ -1312,13 +1025,10 @@ bool checkRoute(const QString& s, const QString& d)
}
}
else
- //if (src.type == Route::JACK_MIDI_ROUTE)
if (src.type == Route::MIDI_DEVICE_ROUTE)
{
RouteList* routes = src.device->outRoutes();
- //dst.channel = src.channel;
dst.channel = -1;
- //src.channel = -1;
for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
if (*i == dst) { // route already there
@@ -1329,7 +1039,7 @@ bool checkRoute(const QString& s, const QString& d)
else
return false;
}
- else if (src.type == Route::MIDI_PORT_ROUTE) // p3.3.49
+ else if (src.type == Route::MIDI_PORT_ROUTE)
{
RouteList* outRoutes = MusEGlobal::midiPorts[src.midiPort].outRoutes();
for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
@@ -1339,13 +1049,11 @@ bool checkRoute(const QString& s, const QString& d)
}
}
}
- //else if (dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49
+ //else if (dst.type == Route::MIDI_PORT_ROUTE)
//{
//}
else
{
- //RouteList* outRoutes = ((src.type == Route::JACK_MIDI_ROUTE) || (src.type == Route::ALSA_MIDI_ROUTE)) ?
- // src.device->outRoutes() : src.track->outRoutes();
RouteList* outRoutes = (src.type == Route::MIDI_DEVICE_ROUTE) ? src.device->outRoutes() : src.track->outRoutes();
for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
@@ -1366,7 +1074,7 @@ void Route::read(Xml& xml)
{
QString s;
int dtype = MidiDevice::ALSA_MIDI;
- int port = -1; // p3.3.49
+ int port = -1;
unsigned char rtype = Route::TRACK_ROUTE;
for (;;)
@@ -1397,7 +1105,7 @@ void Route::read(Xml& xml)
if(tag == "name")
s = xml.s2();
else
- if(tag == "mport") // p3.3.49
+ if(tag == "mport")
{
port = xml.s2().toInt();
rtype = Route::MIDI_PORT_ROUTE;
@@ -1409,7 +1117,7 @@ void Route::read(Xml& xml)
#ifdef ROUTE_DEBUG
printf("Route::read(): tag end type:%d channel:%d name:%s\n", rtype, channel, s.toLatin1().constData());
#endif
- if(rtype == MIDI_PORT_ROUTE) // p3.3.49
+ if(rtype == MIDI_PORT_ROUTE)
{
if(port >= 0 && port < MIDI_PORTS)
{
@@ -1462,7 +1170,6 @@ void Route::read(Xml& xml)
MidiDevice* md = *imd;
if(md->name() == s && md->deviceType() == dtype)
{
- // p3.3.45
// We found a device, but if it is not in use by the song (port is -1), ignore it.
// This prevents loading and propagation of bogus routes in the med file.
if(md->midiPort() == -1)
@@ -1509,7 +1216,7 @@ void Song::readRoute(Xml& xml)
case Xml::End:
return;
case Xml::TagStart:
- // p3.3.38 2010/02/03 Support old routes in med files. Now obsolete!
+ // 2010/02/03 Support old routes in med files. Now obsolete!
if (tag == "srcNode")
src = xml.parse1();
else if (tag == "dstNode")
@@ -1545,7 +1252,7 @@ void Song::readRoute(Xml& xml)
if(tag == "remch")
remch = xml.s2().toInt();
else
- if(tag == "channelMask") // p3.3.50 New channel mask for midi port-track routes.
+ if(tag == "channelMask") // New channel mask for midi port-track routes.
ch = xml.s2().toInt();
else
printf("Song::readRoute(): unknown attribute:%s\n", tag.toLatin1().constData());
@@ -1564,17 +1271,17 @@ void Song::readRoute(Xml& xml)
// Support new routes.
if(sroute.isValid() && droute.isValid())
{
- // p3.3.49 Support pre- 1.1-RC2 midi-device-to-track routes. Obsolete. Replaced with midi port routes.
+ // Support pre- 1.1-RC2 midi-device-to-track routes. Obsolete. Replaced with midi port routes.
if(sroute.type == Route::MIDI_DEVICE_ROUTE && droute.type == Route::TRACK_ROUTE)
{
if(sroute.device->midiPort() >= 0 && sroute.device->midiPort() < MIDI_PORTS
- && ch >= 0 && ch < MIDI_CHANNELS) // p3.3.50
+ && ch >= 0 && ch < MIDI_CHANNELS)
{
sroute.midiPort = sroute.device->midiPort();
sroute.device = 0;
sroute.type = Route::MIDI_PORT_ROUTE;
- sroute.channel = 1 << ch; // p3.3.50 Convert to new bit-wise channel mask.
+ sroute.channel = 1 << ch; // Convert to new bit-wise channel mask.
droute.channel = sroute.channel;
addRoute(sroute, droute);
@@ -1586,13 +1293,13 @@ void Song::readRoute(Xml& xml)
else if(sroute.type == Route::TRACK_ROUTE && droute.type == Route::MIDI_DEVICE_ROUTE)
{
if(droute.device->midiPort() >= 0 && droute.device->midiPort() < MIDI_PORTS
- && ch >= 0 && ch < MIDI_CHANNELS) // p3.3.50
+ && ch >= 0 && ch < MIDI_CHANNELS)
{
droute.midiPort = droute.device->midiPort();
droute.device = 0;
droute.type = Route::MIDI_PORT_ROUTE;
- droute.channel = 1 << ch; // p3.3.50 Convert to new bit-wise channel mask.
+ droute.channel = 1 << ch; // Convert to new bit-wise channel mask.
sroute.channel = droute.channel;
addRoute(sroute, droute);
@@ -1659,7 +1366,7 @@ void Route::dump() const
printf("Route dump: jack audio port <%s> channel %d\n", MusEGlobal::audioDevice->portName(jackPort).toLatin1().constData(), channel);
}
else
- if (type == MIDI_PORT_ROUTE) // p3.3.49
+ if (type == MIDI_PORT_ROUTE)
{
printf("Route dump: midi port <%d> channel mask %d\n", midiPort, channel);
}
@@ -1672,8 +1379,6 @@ void Route::dump() const
if(device->deviceType() == MidiDevice::JACK_MIDI)
{
if(MusEGlobal::checkAudioDevice())
- //printf("jack midi port device <%s> ", MusEGlobal::audioDevice->portName(device->clientPort()).toLatin1().constData());
- // p3.3.55
{
printf("jack midi device <%s> ", device->name().toLatin1().constData());
if(device->inClientPort())
@@ -1730,36 +1435,16 @@ bool Route::operator==(const Route& a) const
{
//if (!MusEGlobal::checkAudioDevice()) return false;
//return MusEGlobal::audioDevice->portName(jackPort) == MusEGlobal::audioDevice->portName(a.jackPort);
- // p3.3.55 Simplified.
- return jackPort == a.jackPort;
+ return jackPort == a.jackPort; // Simplified.
}
else
- if (type == MIDI_PORT_ROUTE) // p3.3.49
+ if (type == MIDI_PORT_ROUTE)
{
return midiPort == a.midiPort;
}
else
if (type == MIDI_DEVICE_ROUTE)
{
- // p3.3.55 Changed for unified jack in/out devices, the actual port names are now different from device name.
- // Like this: device: "MyJackDevice1" -> inport: "MyJackDevice1_in" outport: "MyJackDevice1_out"
- /*
- if(device && a.device && device->deviceType() == a.device->deviceType())
- {
- if(device->deviceType() == MidiDevice::JACK_MIDI)
- {
- if (!MusEGlobal::checkAudioDevice()) return false;
- return MusEGlobal::audioDevice->portName(device->clientPort()) == MusEGlobal::audioDevice->portName(a.device->clientPort());
- }
- else
- if(device->deviceType() == MidiDevice::ALSA_MIDI)
- // TODO: OK ??
- return device->clientPort() == a.device->clientPort() && (channel == a.channel);
- else
- if(device->deviceType() == MidiDevice::SYNTH_MIDI)
- return device->name() == a.device->name();
- }
- */
return device == a.device;
}
}
@@ -1767,4 +1452,56 @@ bool Route::operator==(const Route& a) const
return false;
}
+/*
+//---------------------------------------------------------
+// isCircularRoute
+// Recursive.
+// If dst is valid, start traversal from there, not from src.
+// Returns true if circular.
+//---------------------------------------------------------
+
+bool isCircularRoutePath(Track* src, Track* dst)
+{
+ //if(isMidiTrack() || _type == AUDIO_AUX)
+ //if(isMidiTrack())
+ // return;
+
+ bool rv = false;
+
+ if(dst)
+ {
+ src->setNodeTraversed(true);
+ rv = isCircularRoutePath(dst, NULL);
+ src->setNodeTraversed(false);
+ //if(rv)
+ // fprintf(stderr, " Circular route %s -> %s\n", src->name().toLatin1().constData(), dst->name().toLatin1().constData());
+ return rv;
+ }
+
+ if(src->nodeTraversed())
+ return true;
+
+ src->setNodeTraversed(true);
+
+ //printf("isCircularRoute %s\n", src->name().toLatin1().constData());
+
+ RouteList* orl = src->outRoutes();
+ for (iRoute i = orl->begin(); i != orl->end(); ++i)
+ {
+ if( !(*i).isValid() || (*i).type != Route::TRACK_ROUTE )
+ continue;
+ Track* t = (*i).track;
+ //if(t->isMidiTrack())
+ // continue;
+ rv = isCircularRoutePath(src, NULL);
+ if(rv)
+ break;
+ }
+
+ src->setNodeTraversed(false);
+ return rv;
+}
+*/
+
+
} // namespace MusECore
diff --git a/muse2/muse/route.h b/muse2/muse/route.h
index 36b00d47..587369bc 100644
--- a/muse2/muse/route.h
+++ b/muse2/muse/route.h
@@ -4,6 +4,7 @@
// $Id: route.h,v 1.5.2.1 2008/05/21 00:28:52 terminator356 Exp $
//
// (C) Copyright 2001 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -43,17 +44,15 @@ class Xml;
//---------------------------------------------------------
struct Route {
- enum { TRACK_ROUTE=0, JACK_ROUTE=1, MIDI_DEVICE_ROUTE=2, MIDI_PORT_ROUTE=3 }; // p3.3.49
+ enum { TRACK_ROUTE=0, JACK_ROUTE=1, MIDI_DEVICE_ROUTE=2, MIDI_PORT_ROUTE=3 };
union {
- //AudioTrack* track;
Track* track;
- //MidiJackDevice* device;
MidiDevice* device;
void* jackPort;
};
- int midiPort; // p3.3.49 Midi port number. Best not to put this in the union to avoid problems?
+ int midiPort; // Midi port number. Best not to put this in the union to avoid problems?
//snd_seq_addr_t alsaAdr;
@@ -75,7 +74,7 @@ struct Route {
Route(void* t, int ch=-1);
Route(Track* t, int ch = -1, int chans = -1);
Route(MidiDevice* d, int ch);
- Route(int port, int ch); // p3.3.49
+ Route(int port, int ch);
Route(const QString&, bool dst, int ch, int rtype = -1);
Route();
@@ -84,7 +83,7 @@ struct Route {
bool isValid() const {
return ((type == TRACK_ROUTE) && (track != 0)) || ((type == JACK_ROUTE) && (jackPort != 0)) ||
((type == MIDI_DEVICE_ROUTE) && (device != 0)) ||
- ((type == MIDI_PORT_ROUTE) && (midiPort >= 0) && (midiPort < MIDI_PORTS)); // p3.3.49
+ ((type == MIDI_PORT_ROUTE) && (midiPort >= 0) && (midiPort < MIDI_PORTS));
}
void read(Xml& xml);
void dump() const;
@@ -106,6 +105,7 @@ extern void removeRoute(Route, Route);
extern void removeAllRoutes(Route, Route); // p3.3.55
extern Route name2route(const QString&, bool dst, int rtype = -1);
extern bool checkRoute(const QString&, const QString&);
+//extern bool isCircularRoutePath(Track* src, Track* dst); // Recursive.
//---------------------------------------------------------
// RouteMenuMap
diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp
index 7563fd93..95df7292 100644
--- a/muse2/muse/shortcuts.cpp
+++ b/muse2/muse/shortcuts.cpp
@@ -42,7 +42,7 @@ ShortCut shortcuts[SHRT_NUM_OF_ELEMENTS];
void defShrt(int shrt, int key, const char* descr, int type, const char* xml)
{
shortcuts[shrt].key = key;
- shortcuts[shrt].descr = QT_TRANSLATE_NOOP("@default", descr);
+ shortcuts[shrt].descr = descr;
shortcuts[shrt].type = type;
shortcuts[shrt].xml = xml;
}
@@ -51,279 +51,279 @@ void defShrt(int shrt, int key, const char* descr, int type, const char* xml)
void initShortCuts()
{
//Global:
- defShrt(SHRT_PLAY_SONG, Qt::Key_Enter, "Transport: Start playback from current location", GLOBAL_SHRT, "play");
- defShrt(SHRT_TOGGLE_METRO, Qt::Key_C, "Transport: Toggle metronome", GLOBAL_SHRT,"toggle_metro");
- defShrt(SHRT_STOP, Qt::Key_Insert,"Transport: Stop Playback", GLOBAL_SHRT, "stop");
- defShrt(SHRT_GOTO_START, Qt::Key_W, "Transport: Goto Start", GLOBAL_SHRT, "goto_start");
- defShrt(SHRT_PLAY_TOGGLE, Qt::Key_Space, "Transport: Play, Stop, Rewind", GLOBAL_SHRT, "play_toggle");
- defShrt(SHRT_GOTO_LEFT, Qt::Key_End, "Transport: Goto left marker" , GLOBAL_SHRT, "goto_left");
- defShrt(SHRT_GOTO_RIGHT, Qt::Key_PageDown, "Transport: Goto right marker" , GLOBAL_SHRT, "goto_right");
- defShrt(SHRT_TOGGLE_LOOP, Qt::Key_Slash, "Transport: Toggle Loop section", GLOBAL_SHRT, "toggle_loop");
- defShrt(SHRT_START_REC, Qt::Key_Asterisk, "Transport: Toggle Record", GLOBAL_SHRT, "toggle_rec");
- defShrt(SHRT_REC_CLEAR, Qt::Key_Backspace, "Transport: Clear all rec enabled tracks", GLOBAL_SHRT, "rec_clear");
- defShrt(SHRT_FULLSCREEN, Qt::CTRL + Qt::Key_F, "Toggle fullscreen", GLOBAL_SHRT, "fullscreen");
-
- defShrt(SHRT_COPY, Qt::CTRL + Qt::Key_C, "Edit: Copy", INVIS_SHRT, "copy");
- defShrt(SHRT_COPY_RANGE, Qt::CTRL + Qt::SHIFT + Qt::Key_C, "Edit: Copy in range", GLOBAL_SHRT, "copy_range");
- defShrt(SHRT_UNDO, Qt::CTRL + Qt::Key_Z, "Edit: Undo", INVIS_SHRT, "undo");
- defShrt(SHRT_REDO, Qt::CTRL + Qt::Key_Y, "Edit: Redo", INVIS_SHRT, "redo");
- defShrt(SHRT_CUT, Qt::CTRL + Qt::Key_X, "Edit: Cut", INVIS_SHRT, "cut");
- defShrt(SHRT_PASTE, Qt::CTRL + Qt::Key_V, "Edit: Paste", INVIS_SHRT, "paste");
- defShrt(SHRT_PASTE_DIALOG, Qt::CTRL + Qt::SHIFT + Qt::Key_V, "Edit: Paste (with dialog)", GLOBAL_SHRT, "paste_dialog");
- defShrt(SHRT_DELETE, Qt::Key_Delete, "Edit: Delete", INVIS_SHRT, "delete");
+ defShrt(SHRT_PLAY_SONG, Qt::Key_Enter, QT_TRANSLATE_NOOP("shortcuts", "Transport: Start playback from current location"), GLOBAL_SHRT, "play");
+ defShrt(SHRT_TOGGLE_METRO, Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Transport: Toggle metronome"), GLOBAL_SHRT,"toggle_metro");
+ defShrt(SHRT_STOP, Qt::Key_Insert,QT_TRANSLATE_NOOP("shortcuts", "Transport: Stop Playback"), GLOBAL_SHRT, "stop");
+ defShrt(SHRT_GOTO_START, Qt::Key_W, QT_TRANSLATE_NOOP("shortcuts", "Transport: Goto Start"), GLOBAL_SHRT, "goto_start");
+ defShrt(SHRT_PLAY_TOGGLE, Qt::Key_Space, QT_TRANSLATE_NOOP("shortcuts", "Transport: Play, Stop, Rewind"), GLOBAL_SHRT, "play_toggle");
+ defShrt(SHRT_GOTO_LEFT, Qt::Key_End, QT_TRANSLATE_NOOP("shortcuts", "Transport: Goto left marker") , GLOBAL_SHRT, "goto_left");
+ defShrt(SHRT_GOTO_RIGHT, Qt::Key_PageDown, QT_TRANSLATE_NOOP("shortcuts", "Transport: Goto right marker") , GLOBAL_SHRT, "goto_right");
+ defShrt(SHRT_TOGGLE_LOOP, Qt::Key_Slash, QT_TRANSLATE_NOOP("shortcuts", "Transport: Toggle Loop section"), GLOBAL_SHRT, "toggle_loop");
+ defShrt(SHRT_START_REC, Qt::Key_Asterisk, QT_TRANSLATE_NOOP("shortcuts", "Transport: Toggle Record"), GLOBAL_SHRT, "toggle_rec");
+ defShrt(SHRT_REC_CLEAR, Qt::Key_Backspace, QT_TRANSLATE_NOOP("shortcuts", "Transport: Clear all rec enabled tracks"), GLOBAL_SHRT, "rec_clear");
+ defShrt(SHRT_FULLSCREEN, Qt::CTRL + Qt::Key_F, QT_TRANSLATE_NOOP("shortcuts", "Toggle fullscreen"), GLOBAL_SHRT, "fullscreen");
+
+ defShrt(SHRT_COPY, Qt::CTRL + Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy"), INVIS_SHRT, "copy");
+ defShrt(SHRT_COPY_RANGE, Qt::CTRL + Qt::SHIFT + Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy in range"), GLOBAL_SHRT, "copy_range");
+ defShrt(SHRT_UNDO, Qt::CTRL + Qt::Key_Z, QT_TRANSLATE_NOOP("shortcuts", "Edit: Undo"), INVIS_SHRT, "undo");
+ defShrt(SHRT_REDO, Qt::CTRL + Qt::SHIFT + Qt::Key_Z, QT_TRANSLATE_NOOP("shortcuts", "Edit: Redo"), INVIS_SHRT, "redo");
+ defShrt(SHRT_CUT, Qt::CTRL + Qt::Key_X, QT_TRANSLATE_NOOP("shortcuts", "Edit: Cut"), INVIS_SHRT, "cut");
+ defShrt(SHRT_PASTE, Qt::CTRL + Qt::Key_V, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste"), INVIS_SHRT, "paste");
+ defShrt(SHRT_PASTE_DIALOG, Qt::CTRL + Qt::SHIFT + Qt::Key_V, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste (with dialog)"), GLOBAL_SHRT, "paste_dialog");
+ defShrt(SHRT_DELETE, Qt::Key_Delete, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete"), INVIS_SHRT, "delete");
//-----------------------------------------------------------
// Arranger:
- defShrt(SHRT_NEW, Qt::CTRL + Qt::Key_N, "File: New project", ARRANG_SHRT + DEDIT_SHRT, "new_project");
- defShrt(SHRT_OPEN, Qt::CTRL + Qt::Key_O, "File: Open from disk", ARRANG_SHRT + DEDIT_SHRT, "open_project");
- defShrt(SHRT_SAVE, Qt::CTRL + Qt::Key_S, "File: Save project", ARRANG_SHRT + DEDIT_SHRT, "save_project");
+ defShrt(SHRT_NEW, Qt::CTRL + Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "File: New project"), ARRANG_SHRT + DEDIT_SHRT, "new_project");
+ defShrt(SHRT_OPEN, Qt::CTRL + Qt::Key_O, QT_TRANSLATE_NOOP("shortcuts", "File: Open from disk"), ARRANG_SHRT + DEDIT_SHRT, "open_project");
+ defShrt(SHRT_SAVE, Qt::CTRL + Qt::Key_S, QT_TRANSLATE_NOOP("shortcuts", "File: Save project"), ARRANG_SHRT + DEDIT_SHRT, "save_project");
//-----------------------------------------------------------
- defShrt(SHRT_OPEN_RECENT, Qt::CTRL + Qt::Key_1, "File: Open recent file", ARRANG_SHRT, "open_recent");
- defShrt(SHRT_SAVE_AS, 0 , "File: Save as", ARRANG_SHRT, "save_project_as");
- defShrt(SHRT_LOAD_TEMPLATE, 0 , "File: Load template", ARRANG_SHRT, "load_template");
-// defShrt(SHRT_CONFIG_PRINTER, Qt::CTRL + Qt::Key_P, "Configure printer", ARRANG_SHRT, "config_printer");
- defShrt(SHRT_IMPORT_MIDI, 0 , "File: Import midi file", ARRANG_SHRT, "import_midi");
- defShrt(SHRT_EXPORT_MIDI, 0 , "File: Export midi file", ARRANG_SHRT, "export_midi");
- defShrt(SHRT_IMPORT_PART, 0 , "File: Import midi part", ARRANG_SHRT, "import_part");
- defShrt(SHRT_IMPORT_AUDIO, 0 , "File: Import audio file", ARRANG_SHRT, "import_audio");
- defShrt(SHRT_QUIT, Qt::CTRL + Qt::Key_Q, "File: Quit MusE", ARRANG_SHRT, "quit");
-// defShrt(SHRT_DESEL_PARTS, Qt::CTRL + Qt::Key_B, "Deselect all parts", ARRANG_SHRT, "deselect_parts");
- defShrt(SHRT_SELECT_PRTSTRACK, Qt::CTRL+ Qt::ALT + Qt::Key_P, "Edit: Select parts on track", ARRANG_SHRT, "select_parts_on_track");
- defShrt(SHRT_OPEN_PIANO, Qt::CTRL + Qt::Key_E, "Open pianoroll", ARRANG_SHRT, "open_pianoroll");
- defShrt(SHRT_OPEN_DRUMS, Qt::CTRL + Qt::Key_D, "Open drumeditor", ARRANG_SHRT, "open_drumedit");
- defShrt(SHRT_OPEN_LIST, Qt::CTRL + Qt::Key_L, "Open listeditor", ARRANG_SHRT, "open_listedit");
- defShrt(SHRT_OPEN_WAVE, Qt::CTRL + Qt::Key_W, "Open waveeditor", ARRANG_SHRT, "open_waveedit");
- defShrt(SHRT_OPEN_GRAPHIC_MASTER, Qt::CTRL + Qt::Key_M, "Open graphical mastertrack editor", ARRANG_SHRT, "open_graph_master");
- defShrt(SHRT_OPEN_LIST_MASTER, Qt::CTRL + Qt::SHIFT + Qt::Key_M, "Open list mastertrack editor", ARRANG_SHRT, "open_list_master");
- defShrt(SHRT_OPEN_MIDI_TRANSFORM, Qt::CTRL + Qt::Key_T, "Open midi transformer", ARRANG_SHRT, "open_midi_transform");
- defShrt(SHRT_ADD_MIDI_TRACK, Qt::CTRL + Qt::Key_J, "Add midi track", ARRANG_SHRT, "add_midi_track");
- defShrt(SHRT_ADD_DRUM_TRACK, 0, "Add drum track", ARRANG_SHRT, "add_drum_track");
- defShrt(SHRT_ADD_NEW_STYLE_DRUM_TRACK, 0, "Add new style drum track", ARRANG_SHRT, "add_new_style_drum_track");
- defShrt(SHRT_ADD_WAVE_TRACK, 0, "Add wave track", ARRANG_SHRT, "add_wave_track");
- defShrt(SHRT_ADD_AUDIO_OUTPUT, 0, "Add audio output", ARRANG_SHRT, "add_audio_output");
- defShrt(SHRT_ADD_AUDIO_GROUP, 0, "Add audio group", ARRANG_SHRT, "add_audio_group");
- defShrt(SHRT_ADD_AUDIO_INPUT, 0, "Add audio input", ARRANG_SHRT, "add_audio_input");
- defShrt(SHRT_ADD_AUDIO_AUX , 0, "Add audio aux", ARRANG_SHRT, "add_audio_aux");
- defShrt(SHRT_GLOBAL_CUT, 0, "Structure: Global cut", ARRANG_SHRT, "global_cut");
- defShrt(SHRT_GLOBAL_INSERT, 0, "Structure: Global insert", ARRANG_SHRT, "global_insert");
- defShrt(SHRT_GLOBAL_SPLIT, 0, "Structure: Global split", ARRANG_SHRT, "global_split");
- defShrt(SHRT_CUT_EVENTS, 0, "Structure: Cut events", ARRANG_SHRT, "cut_events");
- //defShrt(SHRT_OPEN_MIXER, Qt::Key_F10, "View: Open mixer window", ARRANG_SHRT, "toggle_mixer");
- defShrt(SHRT_OPEN_MIXER, Qt::Key_F10, "View: Open mixer #1 window", ARRANG_SHRT, "toggle_mixer");
- defShrt(SHRT_OPEN_MIXER2, Qt::CTRL + Qt::Key_F10, "View: Open mixer #2 window", ARRANG_SHRT, "toggle_mixer2");
- defShrt(SHRT_OPEN_TRANSPORT, Qt::Key_F11, "View: Toggle transport window", ARRANG_SHRT, "toggle_transport");
- defShrt(SHRT_OPEN_BIGTIME, Qt::Key_F12, "View: Toggle bigtime window", ARRANG_SHRT, "toggle_bigtime");
- defShrt(SHRT_OPEN_MARKER, Qt::Key_F9, "View: Open marker window", ARRANG_SHRT, "marker_window");
-
- defShrt(SHRT_FOLLOW_JUMP, 0, "Settings: Follow song by page", ARRANG_SHRT, "follow_jump");
- defShrt(SHRT_FOLLOW_NO, 0, "Settings: Follow song off", ARRANG_SHRT, "follow_no");
- defShrt(SHRT_FOLLOW_CONTINUOUS, 0, "Settings: Follow song continuous", ARRANG_SHRT, "follow_continuous");
-
- defShrt(SHRT_GLOBAL_CONFIG, 0, "Settings: Global configuration", ARRANG_SHRT, "configure_global");
- defShrt(SHRT_CONFIG_SHORTCUTS, 0, "Settings: Configure shortcuts", ARRANG_SHRT, "configure_shortcuts");
- defShrt(SHRT_CONFIG_METRONOME, 0, "Settings: Configure metronome", ARRANG_SHRT, "configure_metronome");
- defShrt(SHRT_CONFIG_MIDISYNC, 0, "Settings: Midi sync configuration", ARRANG_SHRT, "configure_midi_sync");
- defShrt(SHRT_MIDI_FILE_CONFIG, 0, "Settings: Midi file import/export configuration", ARRANG_SHRT, "configure_midi_file");
- defShrt(SHRT_APPEARANCE_SETTINGS, 0, "Settings: Appearance settings", ARRANG_SHRT, "configure_appearance_settings");
- defShrt(SHRT_CONFIG_MIDI_PORTS, 0, "Settings: Midi ports / Soft Synth", ARRANG_SHRT, "configure_midi_ports");
- defShrt(SHRT_CONFIG_AUDIO_PORTS, 0, "Settings: Audio subsystem configuration", ARRANG_SHRT, "configure_audio_ports");
- //defShrt(SHRT_SAVE_GLOBAL_CONFIG, 0, "Save global configuration", ARRANG_SHRT, "configure_save_global");
-
- defShrt(SHRT_MIDI_EDIT_INSTRUMENTS, 0, "Midi: Edit midi instruments", ARRANG_SHRT, "midi_edit_instruments");
- defShrt(SHRT_MIDI_INPUT_TRANSFORM, 0, "Midi: Open midi input transform", ARRANG_SHRT, "midi_open_input_transform");
- defShrt(SHRT_MIDI_INPUT_FILTER, 0, "Midi: Open midi input filter", ARRANG_SHRT, "midi_open_input_filter");
- defShrt(SHRT_MIDI_INPUT_TRANSPOSE, 0, "Midi: Midi input transpose", ARRANG_SHRT, "midi_open_input_transpose");
- defShrt(SHRT_MIDI_REMOTE_CONTROL, 0, "Midi: Midi remote control", ARRANG_SHRT, "midi_remote_control");
+ defShrt(SHRT_OPEN_RECENT, Qt::CTRL + Qt::Key_1, QT_TRANSLATE_NOOP("shortcuts", "File: Open recent file"), ARRANG_SHRT, "open_recent");
+ defShrt(SHRT_SAVE_AS, 0 , QT_TRANSLATE_NOOP("shortcuts", "File: Save as"), ARRANG_SHRT, "save_project_as");
+ defShrt(SHRT_LOAD_TEMPLATE, 0 , QT_TRANSLATE_NOOP("shortcuts", "File: Load template"), ARRANG_SHRT, "load_template");
+// defShrt(SHRT_CONFIG_PRINTER, Qt::CTRL + Qt::Key_P, QT_TRANSLATE_NOOP("shortcuts", "Configure printer"), ARRANG_SHRT, "config_printer");
+ defShrt(SHRT_IMPORT_MIDI, 0 , QT_TRANSLATE_NOOP("shortcuts", "File: Import midi file"), ARRANG_SHRT, "import_midi");
+ defShrt(SHRT_EXPORT_MIDI, 0 , QT_TRANSLATE_NOOP("shortcuts", "File: Export midi file"), ARRANG_SHRT, "export_midi");
+ defShrt(SHRT_IMPORT_PART, 0 , QT_TRANSLATE_NOOP("shortcuts", "File: Import midi part"), ARRANG_SHRT, "import_part");
+ defShrt(SHRT_IMPORT_AUDIO, 0 , QT_TRANSLATE_NOOP("shortcuts", "File: Import audio file"), ARRANG_SHRT, "import_audio");
+ defShrt(SHRT_QUIT, Qt::CTRL + Qt::Key_Q, QT_TRANSLATE_NOOP("shortcuts", "File: Quit MusE"), ARRANG_SHRT, "quit");
+// defShrt(SHRT_DESEL_PARTS, Qt::CTRL + Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Deselect all parts"), ARRANG_SHRT, "deselect_parts");
+ defShrt(SHRT_SELECT_PRTSTRACK, Qt::CTRL+ Qt::ALT + Qt::Key_P, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select parts on track"), ARRANG_SHRT, "select_parts_on_track");
+ defShrt(SHRT_OPEN_PIANO, Qt::CTRL + Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Open pianoroll"), ARRANG_SHRT, "open_pianoroll");
+ defShrt(SHRT_OPEN_DRUMS, Qt::CTRL + Qt::Key_D, QT_TRANSLATE_NOOP("shortcuts", "Open drumeditor"), ARRANG_SHRT, "open_drumedit");
+ defShrt(SHRT_OPEN_LIST, Qt::CTRL + Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "Open listeditor"), ARRANG_SHRT, "open_listedit");
+ defShrt(SHRT_OPEN_WAVE, Qt::CTRL + Qt::Key_W, QT_TRANSLATE_NOOP("shortcuts", "Open waveeditor"), ARRANG_SHRT, "open_waveedit");
+ defShrt(SHRT_OPEN_GRAPHIC_MASTER, Qt::CTRL + Qt::Key_M, QT_TRANSLATE_NOOP("shortcuts", "Open graphical mastertrack editor"), ARRANG_SHRT, "open_graph_master");
+ defShrt(SHRT_OPEN_LIST_MASTER, Qt::CTRL + Qt::SHIFT + Qt::Key_M, QT_TRANSLATE_NOOP("shortcuts", "Open list mastertrack editor"), ARRANG_SHRT, "open_list_master");
+ defShrt(SHRT_OPEN_MIDI_TRANSFORM, Qt::CTRL + Qt::Key_T, QT_TRANSLATE_NOOP("shortcuts", "Open midi transformer"), ARRANG_SHRT, "open_midi_transform");
+ defShrt(SHRT_ADD_MIDI_TRACK, Qt::CTRL + Qt::Key_J, QT_TRANSLATE_NOOP("shortcuts", "Add midi track"), ARRANG_SHRT, "add_midi_track");
+ defShrt(SHRT_ADD_DRUM_TRACK, 0, QT_TRANSLATE_NOOP("shortcuts", "Add drum track"), ARRANG_SHRT, "add_drum_track");
+ defShrt(SHRT_ADD_NEW_STYLE_DRUM_TRACK, 0, QT_TRANSLATE_NOOP("shortcuts", "Add new style drum track"), ARRANG_SHRT, "add_new_style_drum_track");
+ defShrt(SHRT_ADD_WAVE_TRACK, 0, QT_TRANSLATE_NOOP("shortcuts", "Add wave track"), ARRANG_SHRT, "add_wave_track");
+ defShrt(SHRT_ADD_AUDIO_OUTPUT, 0, QT_TRANSLATE_NOOP("shortcuts", "Add audio output"), ARRANG_SHRT, "add_audio_output");
+ defShrt(SHRT_ADD_AUDIO_GROUP, 0, QT_TRANSLATE_NOOP("shortcuts", "Add audio group"), ARRANG_SHRT, "add_audio_group");
+ defShrt(SHRT_ADD_AUDIO_INPUT, 0, QT_TRANSLATE_NOOP("shortcuts", "Add audio input"), ARRANG_SHRT, "add_audio_input");
+ defShrt(SHRT_ADD_AUDIO_AUX , 0, QT_TRANSLATE_NOOP("shortcuts", "Add audio aux"), ARRANG_SHRT, "add_audio_aux");
+ defShrt(SHRT_GLOBAL_CUT, 0, QT_TRANSLATE_NOOP("shortcuts", "Structure: Global cut"), ARRANG_SHRT, "global_cut");
+ defShrt(SHRT_GLOBAL_INSERT, 0, QT_TRANSLATE_NOOP("shortcuts", "Structure: Global insert"), ARRANG_SHRT, "global_insert");
+ defShrt(SHRT_GLOBAL_SPLIT, 0, QT_TRANSLATE_NOOP("shortcuts", "Structure: Global split"), ARRANG_SHRT, "global_split");
+ defShrt(SHRT_CUT_EVENTS, 0, QT_TRANSLATE_NOOP("shortcuts", "Structure: Cut events"), ARRANG_SHRT, "cut_events");
+ //defShrt(SHRT_OPEN_MIXER, Qt::Key_F10, QT_TRANSLATE_NOOP("shortcuts", "View: Open mixer window"), ARRANG_SHRT, "toggle_mixer");
+ defShrt(SHRT_OPEN_MIXER, Qt::Key_F10, QT_TRANSLATE_NOOP("shortcuts", "View: Open mixer #1 window"), ARRANG_SHRT, "toggle_mixer");
+ defShrt(SHRT_OPEN_MIXER2, Qt::CTRL + Qt::Key_F10, QT_TRANSLATE_NOOP("shortcuts", "View: Open mixer #2 window"), ARRANG_SHRT, "toggle_mixer2");
+ defShrt(SHRT_OPEN_TRANSPORT, Qt::Key_F11, QT_TRANSLATE_NOOP("shortcuts", "View: Toggle transport window"), ARRANG_SHRT, "toggle_transport");
+ defShrt(SHRT_OPEN_BIGTIME, Qt::Key_F12, QT_TRANSLATE_NOOP("shortcuts", "View: Toggle bigtime window"), ARRANG_SHRT, "toggle_bigtime");
+ defShrt(SHRT_OPEN_MARKER, Qt::Key_F9, QT_TRANSLATE_NOOP("shortcuts", "View: Open marker window"), ARRANG_SHRT, "marker_window");
+
+ defShrt(SHRT_FOLLOW_JUMP, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Follow song by page"), ARRANG_SHRT, "follow_jump");
+ defShrt(SHRT_FOLLOW_NO, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Follow song off"), ARRANG_SHRT, "follow_no");
+ defShrt(SHRT_FOLLOW_CONTINUOUS, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Follow song continuous"), ARRANG_SHRT, "follow_continuous");
+
+ defShrt(SHRT_GLOBAL_CONFIG, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Global configuration"), ARRANG_SHRT, "configure_global");
+ defShrt(SHRT_CONFIG_SHORTCUTS, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Configure shortcuts"), ARRANG_SHRT, "configure_shortcuts");
+ defShrt(SHRT_CONFIG_METRONOME, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Configure metronome"), ARRANG_SHRT, "configure_metronome");
+ defShrt(SHRT_CONFIG_MIDISYNC, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Midi sync configuration"), ARRANG_SHRT, "configure_midi_sync");
+ defShrt(SHRT_MIDI_FILE_CONFIG, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Midi file import/export configuration"), ARRANG_SHRT, "configure_midi_file");
+ defShrt(SHRT_APPEARANCE_SETTINGS, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Appearance settings"), ARRANG_SHRT, "configure_appearance_settings");
+ defShrt(SHRT_CONFIG_MIDI_PORTS, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Midi ports / Soft Synth"), ARRANG_SHRT, "configure_midi_ports");
+ defShrt(SHRT_CONFIG_AUDIO_PORTS, 0, QT_TRANSLATE_NOOP("shortcuts", "Settings: Audio subsystem configuration"), ARRANG_SHRT, "configure_audio_ports");
+ //defShrt(SHRT_SAVE_GLOBAL_CONFIG, 0, QT_TRANSLATE_NOOP("shortcuts", "Save global configuration"), ARRANG_SHRT, "configure_save_global");
+
+ defShrt(SHRT_MIDI_EDIT_INSTRUMENTS, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Edit midi instruments"), ARRANG_SHRT, "midi_edit_instruments");
+ defShrt(SHRT_MIDI_INPUT_TRANSFORM, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Open midi input transform"), ARRANG_SHRT, "midi_open_input_transform");
+ defShrt(SHRT_MIDI_INPUT_FILTER, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Open midi input filter"), ARRANG_SHRT, "midi_open_input_filter");
+ defShrt(SHRT_MIDI_INPUT_TRANSPOSE, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Midi input transpose"), ARRANG_SHRT, "midi_open_input_transpose");
+ defShrt(SHRT_MIDI_REMOTE_CONTROL, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Midi remote control"), ARRANG_SHRT, "midi_remote_control");
#ifdef BUILD_EXPERIMENTAL
- defShrt(SHRT_RANDOM_RHYTHM_GENERATOR,0,"Midi: Random rhythm generator", ARRANG_SHRT, "midi_random_rhythm_generator");
+ defShrt(SHRT_RANDOM_RHYTHM_GENERATOR,0,QT_TRANSLATE_NOOP("shortcuts", "Midi: Random rhythm generator"), ARRANG_SHRT, "midi_random_rhythm_generator");
#endif
- defShrt(SHRT_MIDI_RESET, 0, "Midi: Reset midi", ARRANG_SHRT, "midi_reset");
- defShrt(SHRT_MIDI_INIT, 0, "Midi: Init midi", ARRANG_SHRT, "midi_init");
- defShrt(SHRT_MIDI_LOCAL_OFF, 0, "Midi: Midi local off", ARRANG_SHRT, "midi_local_off");
+ defShrt(SHRT_MIDI_RESET, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Reset midi"), ARRANG_SHRT, "midi_reset");
+ defShrt(SHRT_MIDI_INIT, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Init midi"), ARRANG_SHRT, "midi_init");
+ defShrt(SHRT_MIDI_LOCAL_OFF, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Midi local off"), ARRANG_SHRT, "midi_local_off");
- defShrt(SHRT_AUDIO_BOUNCE_TO_TRACK, 0, "Audio: Bounce audio to track", ARRANG_SHRT, "audio_bounce_to_track");
- defShrt(SHRT_AUDIO_BOUNCE_TO_FILE, 0, "Audio: Bounce audio to file", ARRANG_SHRT, "audio_bounce_to_file");
- defShrt(SHRT_AUDIO_RESTART, 0, "Audio: Restart audio", ARRANG_SHRT, "audio_restart");
+ defShrt(SHRT_AUDIO_BOUNCE_TO_TRACK, 0, QT_TRANSLATE_NOOP("shortcuts", "Audio: Bounce audio to track"), ARRANG_SHRT, "audio_bounce_to_track");
+ defShrt(SHRT_AUDIO_BOUNCE_TO_FILE, 0, QT_TRANSLATE_NOOP("shortcuts", "Audio: Bounce audio to file"), ARRANG_SHRT, "audio_bounce_to_file");
+ defShrt(SHRT_AUDIO_RESTART, 0, QT_TRANSLATE_NOOP("shortcuts", "Audio: Restart audio"), ARRANG_SHRT, "audio_restart");
- defShrt(SHRT_MIXER_AUTOMATION, 0, "Automation: Mixer automation", ARRANG_SHRT, "mixer_automation");
- defShrt(SHRT_MIXER_SNAPSHOT, 0, "Automation: Take mixer snapshot", ARRANG_SHRT, "mixer_snapshot");
- defShrt(SHRT_MIXER_AUTOMATION_CLEAR,0, "Automation: Clear mixer automation", ARRANG_SHRT, "mixer_automation_clear");
+ defShrt(SHRT_MIXER_AUTOMATION, 0, QT_TRANSLATE_NOOP("shortcuts", "Automation: Mixer automation"), ARRANG_SHRT, "mixer_automation");
+ defShrt(SHRT_MIXER_SNAPSHOT, 0, QT_TRANSLATE_NOOP("shortcuts", "Automation: Take mixer snapshot"), ARRANG_SHRT, "mixer_snapshot");
+ defShrt(SHRT_MIXER_AUTOMATION_CLEAR,0, QT_TRANSLATE_NOOP("shortcuts", "Automation: Clear mixer automation"), ARRANG_SHRT, "mixer_automation_clear");
-// defShrt(SHRT_OPEN_CLIPS, 0, "View audio clips", ARRANG_SHRT, "view_audio_clips");
- defShrt(SHRT_OPEN_HELP, Qt::Key_F1, "Help: Open Manual", ARRANG_SHRT, "open_help");
- defShrt(SHRT_START_WHATSTHIS, Qt::SHIFT + Qt::Key_F1, "Help: Toggle whatsthis mode", ARRANG_SHRT, "toggle_whatsthis");
+// defShrt(SHRT_OPEN_CLIPS, 0, QT_TRANSLATE_NOOP("shortcuts", "View audio clips"), ARRANG_SHRT, "view_audio_clips");
+ defShrt(SHRT_OPEN_HELP, Qt::Key_F1, QT_TRANSLATE_NOOP("shortcuts", "Help: Open Manual"), ARRANG_SHRT, "open_help");
+ defShrt(SHRT_START_WHATSTHIS, Qt::SHIFT + Qt::Key_F1, QT_TRANSLATE_NOOP("shortcuts", "Help: Toggle whatsthis mode"), ARRANG_SHRT, "toggle_whatsthis");
- defShrt(SHRT_EDIT_PART, Qt::Key_Return, "Edit: Edit selected part", ARRANG_SHRT, "edit_selected_part");
- defShrt(SHRT_SEL_ABOVE, Qt::Key_Up, "Edit: Select nearest part on track above", ARRANG_SHRT, "sel_part_above");
- defShrt(SHRT_SEL_ABOVE_ADD, Qt::SHIFT + Qt::Key_Up, "Edit: Add nearest part on track above", ARRANG_SHRT, "sel_part_above_add");
- defShrt(SHRT_SEL_BELOW, Qt::Key_Down, "Edit: Select nearest part on track below", ARRANG_SHRT, "sel_part_below");
- defShrt(SHRT_SEL_BELOW_ADD, Qt::SHIFT + Qt::Key_Down, "Edit: Add nearest part on track below", ARRANG_SHRT, "sel_part_below_add");
+ defShrt(SHRT_EDIT_PART, Qt::Key_Return, QT_TRANSLATE_NOOP("shortcuts", "Edit: Edit selected part"), ARRANG_SHRT, "edit_selected_part");
+ defShrt(SHRT_SEL_ABOVE, Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part on track above"), ARRANG_SHRT, "sel_part_above");
+ defShrt(SHRT_SEL_ABOVE_ADD, Qt::SHIFT + Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part on track above"), ARRANG_SHRT, "sel_part_above_add");
+ defShrt(SHRT_SEL_BELOW, Qt::Key_Down, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part on track below"), ARRANG_SHRT, "sel_part_below");
+ defShrt(SHRT_SEL_BELOW_ADD, Qt::SHIFT + Qt::Key_Down, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part on track below"), ARRANG_SHRT, "sel_part_below_add");
- defShrt(SHRT_INSERTMEAS, Qt::CTRL+Qt::SHIFT+ Qt::Key_O, "Edit: Insert empty measure", ARRANG_SHRT, "insert_measure");
+ defShrt(SHRT_INSERTMEAS, Qt::CTRL+Qt::SHIFT+ Qt::Key_O, QT_TRANSLATE_NOOP("shortcuts", "Edit: Insert empty measure"), ARRANG_SHRT, "insert_measure");
- defShrt(SHRT_PASTE_CLONE, Qt::CTRL+Qt::Key_B, "Edit: Paste as clones", ARRANG_SHRT, "paste_as_clone"); // i changed "paste_clone" to "paste_as_clone" intendedly. otherwise muse would keep its old, conflicting definition (ctrl+shift+v instead of ctrl+b) (flo)
- defShrt(SHRT_PASTE_CLONE_DIALOG, Qt::CTRL+Qt::SHIFT+Qt::Key_B, "Edit: Paste as clones (with dialog)", ARRANG_SHRT, "paste_as_clone_dialog");
+ defShrt(SHRT_PASTE_CLONE, Qt::CTRL+Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste as clones"), ARRANG_SHRT, "paste_as_clone"); // i changed "paste_clone" to "paste_as_clone" intendedly. otherwise muse would keep its old, conflicting definition (ctrl+shift+v instead of ctrl+b) (flo)
+ defShrt(SHRT_PASTE_CLONE_DIALOG, Qt::CTRL+Qt::SHIFT+Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste as clones (with dialog)"), ARRANG_SHRT, "paste_as_clone_dialog");
- defShrt(SHRT_SEL_TRACK_ABOVE, Qt::CTRL + Qt::Key_Up, "Select track above", ARRANG_SHRT, "sel_track_above");
- defShrt(SHRT_SEL_TRACK_BELOW, Qt::CTRL + Qt::Key_Down, "Select track below", ARRANG_SHRT, "sel_track_below");
+ defShrt(SHRT_SEL_TRACK_ABOVE, Qt::CTRL + Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Select track above"), ARRANG_SHRT, "sel_track_above");
+ defShrt(SHRT_SEL_TRACK_BELOW, Qt::CTRL + Qt::Key_Down, QT_TRANSLATE_NOOP("shortcuts", "Select track below"), ARRANG_SHRT, "sel_track_below");
//-----------------------------------------------------------
- defShrt(SHRT_TRANSPOSE, 0, "Midi: Transpose", ARRANG_SHRT + PROLL_SHRT, "midi_transpose");
+ defShrt(SHRT_TRANSPOSE, 0, QT_TRANSLATE_NOOP("shortcuts", "Midi: Transpose"), ARRANG_SHRT + PROLL_SHRT, "midi_transpose");
//-----------------------------------------------------------
- defShrt(SHRT_SELECT_ALL, Qt::CTRL + Qt::Key_A, "Edit: Select all", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_all");
- defShrt(SHRT_SELECT_NONE, Qt::CTRL + Qt::SHIFT + Qt::Key_A, "Edit: Select none", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_none");
- defShrt(SHRT_SELECT_INVERT, Qt::CTRL + Qt::Key_I, "Edit: Invert Selection", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_inv");
- defShrt(SHRT_SELECT_ILOOP, 0, "Edit: Select events/parts inside locators", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_ins_loc");
- defShrt(SHRT_SELECT_OLOOP, 0, "Edit: Select events/parts outside locators", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_out_loc");
- defShrt(SHRT_SELECT_PREV_PART, Qt::ALT + Qt::Key_Left, "Edit: Select previous part", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_prv_prt");
- defShrt(SHRT_SELECT_NEXT_PART, Qt::ALT + Qt::Key_Right, "Edit: Select next part", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_nxt_prt");
- defShrt(SHRT_SEL_LEFT, Qt::Key_Left, "Edit: Select nearest part/event to the left or move cursor", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_left");
- defShrt(SHRT_SEL_LEFT_ADD, Qt::Key_Left + Qt::SHIFT, "Edit: Add nearest part/event to the left to selection", PROLL_SHRT + DEDIT_SHRT, "sel_left_add");
- defShrt(SHRT_SEL_RIGHT, Qt::Key_Right, "Edit: Select nearest part/event to the right or move cursor", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,"sel_right");
- defShrt(SHRT_SEL_RIGHT_ADD, Qt::Key_Right + Qt::SHIFT, "Edit: Add nearest part/event to the right to selection", PROLL_SHRT + DEDIT_SHRT,"sel_right_add");
- defShrt(SHRT_LOCATORS_TO_SELECTION, Qt::ALT + Qt::Key_P, "Edit: Set locators to selection", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "loc_to_sel");
- defShrt(SHRT_INC_PITCH, Qt::CTRL + Qt::Key_Up, "Edit: Increase pitch", PROLL_SHRT + DEDIT_SHRT, "sel_inc_pitch");
- defShrt(SHRT_DEC_PITCH, Qt::CTRL + Qt::Key_Down, "Edit: Decrease pitch", PROLL_SHRT + DEDIT_SHRT, "sel_dec_pitch");
- defShrt(SHRT_INC_POS, Qt::CTRL + Qt::Key_Right, "Edit: Increase event position", PROLL_SHRT + DEDIT_SHRT, "sel_inc_pos");
- defShrt(SHRT_DEC_POS, Qt::CTRL + Qt::Key_Left, "Edit: Decrease event position", PROLL_SHRT + DEDIT_SHRT, "sel_dec_pos");
- defShrt(SHRT_ZOOM_IN, Qt::CTRL + Qt::Key_PageUp, "View: Zoom in", PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "zoom_in");
- defShrt(SHRT_ZOOM_OUT, Qt::CTRL + Qt::Key_PageDown, "View: Zoom out", PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "zoom_out");
- defShrt(SHRT_GOTO_CPOS, Qt::Key_C, "View: Goto Current Position", PROLL_SHRT + DEDIT_SHRT, "goto_cpos");
- defShrt(SHRT_SCROLL_LEFT, Qt::Key_H, "View: Scroll left", PROLL_SHRT + DEDIT_SHRT, "scroll_left");
- defShrt(SHRT_SCROLL_RIGHT, Qt::Key_L, "View: Scroll left", PROLL_SHRT + DEDIT_SHRT, "scroll_right");
+ defShrt(SHRT_SELECT_ALL, Qt::CTRL + Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select all"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_all");
+ defShrt(SHRT_SELECT_NONE, Qt::CTRL + Qt::SHIFT + Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select none"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_none");
+ defShrt(SHRT_SELECT_INVERT, Qt::CTRL + Qt::Key_I, QT_TRANSLATE_NOOP("shortcuts", "Edit: Invert Selection"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_inv");
+ defShrt(SHRT_SELECT_ILOOP, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select events/parts inside locators"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_ins_loc");
+ defShrt(SHRT_SELECT_OLOOP, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select events/parts outside locators"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_out_loc");
+ defShrt(SHRT_SELECT_PREV_PART, Qt::ALT + Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select previous part"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_prv_prt");
+ defShrt(SHRT_SELECT_NEXT_PART, Qt::ALT + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select next part"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_nxt_prt");
+ defShrt(SHRT_SEL_LEFT, Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part/event to the left or move cursor"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "sel_left");
+ defShrt(SHRT_SEL_LEFT_ADD, Qt::Key_Left + Qt::SHIFT, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part/event to the left to selection"), PROLL_SHRT + DEDIT_SHRT, "sel_left_add");
+ defShrt(SHRT_SEL_RIGHT, Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Select nearest part/event to the right or move cursor"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,"sel_right");
+ defShrt(SHRT_SEL_RIGHT_ADD, Qt::Key_Right + Qt::SHIFT, QT_TRANSLATE_NOOP("shortcuts", "Edit: Add nearest part/event to the right to selection"), PROLL_SHRT + DEDIT_SHRT,"sel_right_add");
+ defShrt(SHRT_LOCATORS_TO_SELECTION, Qt::ALT + Qt::Key_P, QT_TRANSLATE_NOOP("shortcuts", "Edit: Set locators to selection"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "loc_to_sel");
+ defShrt(SHRT_INC_PITCH, Qt::CTRL + Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Edit: Increase pitch"), PROLL_SHRT + DEDIT_SHRT, "sel_inc_pitch");
+ defShrt(SHRT_DEC_PITCH, Qt::CTRL + Qt::Key_Down, QT_TRANSLATE_NOOP("shortcuts", "Edit: Decrease pitch"), PROLL_SHRT + DEDIT_SHRT, "sel_dec_pitch");
+ defShrt(SHRT_INC_POS, Qt::CTRL + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Increase event position"), PROLL_SHRT + DEDIT_SHRT, "sel_inc_pos");
+ defShrt(SHRT_DEC_POS, Qt::CTRL + Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Decrease event position"), PROLL_SHRT + DEDIT_SHRT, "sel_dec_pos");
+ defShrt(SHRT_ZOOM_IN, Qt::CTRL + Qt::Key_PageUp, QT_TRANSLATE_NOOP("shortcuts", "View: Zoom in"), PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "zoom_in");
+ defShrt(SHRT_ZOOM_OUT, Qt::CTRL + Qt::Key_PageDown, QT_TRANSLATE_NOOP("shortcuts", "View: Zoom out"), PROLL_SHRT + DEDIT_SHRT + ARRANG_SHRT, "zoom_out");
+ defShrt(SHRT_GOTO_CPOS, Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "View: Goto Current Position"), PROLL_SHRT + DEDIT_SHRT, "goto_cpos");
+ defShrt(SHRT_SCROLL_LEFT, Qt::Key_H, QT_TRANSLATE_NOOP("shortcuts", "View: Scroll left"), PROLL_SHRT + DEDIT_SHRT, "scroll_left");
+ defShrt(SHRT_SCROLL_RIGHT, Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "View: Scroll left"), PROLL_SHRT + DEDIT_SHRT, "scroll_right");
//-----------------------------------------------------------
//Drum:
//-----------------------------------------------------------
- defShrt(SHRT_FIXED_LEN, Qt::ALT + Qt::Key_L, "Edit: Set Fixed Length on Midi Events", PROLL_SHRT + DEDIT_SHRT, "midi_fixed_len");
+ defShrt(SHRT_FIXED_LEN, Qt::ALT + Qt::Key_L, QT_TRANSLATE_NOOP("shortcuts", "Edit: Set Fixed Length on Midi Events"), PROLL_SHRT + DEDIT_SHRT, "midi_fixed_len");
//-----------------------------------------------------------
//Pianoroll:
//-----------------------------------------------------------
- defShrt(SHRT_QUANTIZE, 0, "Quantize", PROLL_SHRT, "midi_quant");
- defShrt(SHRT_MODIFY_GATE_TIME, 0, "Modify Note Length", PROLL_SHRT, "midi_mod_gate_time");
- defShrt(SHRT_MODIFY_VELOCITY, 0, "Modify Velocity", PROLL_SHRT, "midi_mod_velo");
- defShrt(SHRT_CRESCENDO, 0, "Edit: Crescendo", PROLL_SHRT, "midi_crescendo");
- defShrt(SHRT_THIN_OUT, 0, "Edit: Thin Out", PROLL_SHRT, "midi_thin_out");
- defShrt(SHRT_ERASE_EVENT, 0, "Edit: Erase Event", PROLL_SHRT, "midi_erase_event");
- defShrt(SHRT_DELETE_OVERLAPS, 0, "Edit: Delete Overlaps", PROLL_SHRT, "midi_delete_overlaps");
- defShrt(SHRT_NOTE_SHIFT, 0, "Edit: Note Shift", PROLL_SHRT, "midi_note_shift");
- defShrt(SHRT_MOVE_CLOCK, 0, "Edit: Move Clock", PROLL_SHRT, "midi_move_clock");
- defShrt(SHRT_COPY_MEASURE, 0, "Edit: Copy Measure", PROLL_SHRT, "midi_copy_measure");
- defShrt(SHRT_ERASE_MEASURE, 0, "Edit: Erase Measure", PROLL_SHRT,"midi_erase_measure");
- defShrt(SHRT_DELETE_MEASURE, 0, "Edit: Delete Measure", PROLL_SHRT, "midi_delete_measure");
- defShrt(SHRT_CREATE_MEASURE, 0, "Edit: Create Measure", PROLL_SHRT, "midi_create_measure");
- defShrt(SHRT_EVENT_COLOR, Qt::Key_E, "Edit: Change Event Color", PROLL_SHRT, "change_event_color");
+ defShrt(SHRT_QUANTIZE, 0, QT_TRANSLATE_NOOP("shortcuts", "Quantize"), PROLL_SHRT, "midi_quant");
+ defShrt(SHRT_MODIFY_GATE_TIME, 0, QT_TRANSLATE_NOOP("shortcuts", "Modify Note Length"), PROLL_SHRT, "midi_mod_gate_time");
+ defShrt(SHRT_MODIFY_VELOCITY, 0, QT_TRANSLATE_NOOP("shortcuts", "Modify Velocity"), PROLL_SHRT, "midi_mod_velo");
+ defShrt(SHRT_CRESCENDO, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Crescendo"), PROLL_SHRT, "midi_crescendo");
+ defShrt(SHRT_THIN_OUT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Thin Out"), PROLL_SHRT, "midi_thin_out");
+ defShrt(SHRT_ERASE_EVENT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Erase Event"), PROLL_SHRT, "midi_erase_event");
+ defShrt(SHRT_DELETE_OVERLAPS, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete Overlaps"), PROLL_SHRT, "midi_delete_overlaps");
+ defShrt(SHRT_NOTE_SHIFT, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Note Shift"), PROLL_SHRT, "midi_note_shift");
+ defShrt(SHRT_MOVE_CLOCK, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Move Clock"), PROLL_SHRT, "midi_move_clock");
+ defShrt(SHRT_COPY_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy Measure"), PROLL_SHRT, "midi_copy_measure");
+ defShrt(SHRT_ERASE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Erase Measure"), PROLL_SHRT,"midi_erase_measure");
+ defShrt(SHRT_DELETE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Delete Measure"), PROLL_SHRT, "midi_delete_measure");
+ defShrt(SHRT_CREATE_MEASURE, 0, QT_TRANSLATE_NOOP("shortcuts", "Edit: Create Measure"), PROLL_SHRT, "midi_create_measure");
+ defShrt(SHRT_EVENT_COLOR, Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Edit: Change Event Color"), PROLL_SHRT, "change_event_color");
// Shortcuts for tools
// global
- defShrt(SHRT_TOOL_POINTER, Qt::Key_A, "Tool: Pointer", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "pointer_tool");
- defShrt(SHRT_TOOL_PENCIL, Qt::Key_D, "Tool: Pencil", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "pencil_tool");
- defShrt(SHRT_TOOL_RUBBER, Qt::Key_R, "Tool: Eraser", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "eraser_tool");
+ defShrt(SHRT_TOOL_POINTER, Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Tool: Pointer"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "pointer_tool");
+ defShrt(SHRT_TOOL_PENCIL, Qt::Key_D, QT_TRANSLATE_NOOP("shortcuts", "Tool: Pencil"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "pencil_tool");
+ defShrt(SHRT_TOOL_RUBBER, Qt::Key_R, QT_TRANSLATE_NOOP("shortcuts", "Tool: Eraser"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "eraser_tool");
// piano roll & drum editor
- defShrt(SHRT_TOOL_LINEDRAW, Qt::Key_F, "Tool: Line Draw", ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "line_draw_tool");
+ defShrt(SHRT_TOOL_LINEDRAW, Qt::Key_F, QT_TRANSLATE_NOOP("shortcuts", "Tool: Line Draw"), ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT, "line_draw_tool");
// drum editor
- defShrt(SHRT_TOOL_CURSOR, Qt::Key_U, "Tool: Cursor", DEDIT_SHRT, "cursor_tool");
- defShrt(SHRT_ADDNOTE_1, Qt::Key_V, "Add note velocity 1", DEDIT_SHRT, "add_note_velocity_1");
- defShrt(SHRT_ADDNOTE_2, Qt::Key_B, "Add note velocity 2", DEDIT_SHRT, "add_note_velocity_2");
- defShrt(SHRT_ADDNOTE_3, Qt::Key_N, "Add note velocity 3", DEDIT_SHRT, "add_note_velocity_3");
- defShrt(SHRT_ADDNOTE_4, Qt::Key_M, "Add note velocity 4", DEDIT_SHRT, "add_note_velocity_4");
+ defShrt(SHRT_TOOL_CURSOR, Qt::Key_U, QT_TRANSLATE_NOOP("shortcuts", "Tool: Cursor"), DEDIT_SHRT, "cursor_tool");
+ defShrt(SHRT_ADDNOTE_1, Qt::Key_V, QT_TRANSLATE_NOOP("shortcuts", "Add note velocity 1"), DEDIT_SHRT, "add_note_velocity_1");
+ defShrt(SHRT_ADDNOTE_2, Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Add note velocity 2"), DEDIT_SHRT, "add_note_velocity_2");
+ defShrt(SHRT_ADDNOTE_3, Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "Add note velocity 3"), DEDIT_SHRT, "add_note_velocity_3");
+ defShrt(SHRT_ADDNOTE_4, Qt::Key_M, QT_TRANSLATE_NOOP("shortcuts", "Add note velocity 4"), DEDIT_SHRT, "add_note_velocity_4");
- defShrt(SHRT_CURSOR_STEP_UP, Qt::Key_0, "Cursor step size: larger", DEDIT_SHRT, "cursor_step_up");
- defShrt(SHRT_CURSOR_STEP_DOWN, Qt::Key_9, "Cursor step size: smaller", DEDIT_SHRT, "cursor_step_down");
- defShrt(SHRT_INSTRUMENT_STEP_UP, Qt::Key_Up, "Instrument/Cursor up", DEDIT_SHRT, "instrument_up");
- defShrt(SHRT_INSTRUMENT_STEP_DOWN, Qt::Key_Down, "Instrument/Cursor down", DEDIT_SHRT, "instrument_down");
+ defShrt(SHRT_CURSOR_STEP_UP, Qt::Key_0, QT_TRANSLATE_NOOP("shortcuts", "Cursor step size: larger"), DEDIT_SHRT, "cursor_step_up");
+ defShrt(SHRT_CURSOR_STEP_DOWN, Qt::Key_9, QT_TRANSLATE_NOOP("shortcuts", "Cursor step size: smaller"), DEDIT_SHRT, "cursor_step_down");
+ defShrt(SHRT_INSTRUMENT_STEP_UP, Qt::Key_Up, QT_TRANSLATE_NOOP("shortcuts", "Instrument/Cursor up"), DEDIT_SHRT, "instrument_up");
+ defShrt(SHRT_INSTRUMENT_STEP_DOWN, Qt::Key_Down, QT_TRANSLATE_NOOP("shortcuts", "Instrument/Cursor down"), DEDIT_SHRT, "instrument_down");
// arranger
- defShrt(SHRT_TOOL_SCISSORS, Qt::Key_S, "Tool: Scissor", ARRANG_SHRT, "scissor_tool");
- defShrt(SHRT_TOOL_GLUE, Qt::Key_G, "Tool: Glue", ARRANG_SHRT, "glue_tool");
- defShrt(SHRT_TOOL_MUTE, 0, "Tool: Mute", ARRANG_SHRT, "mute_tool");
+ defShrt(SHRT_TOOL_SCISSORS, Qt::Key_S, QT_TRANSLATE_NOOP("shortcuts", "Tool: Scissor"), ARRANG_SHRT, "scissor_tool");
+ defShrt(SHRT_TOOL_GLUE, Qt::Key_G, QT_TRANSLATE_NOOP("shortcuts", "Tool: Glue"), ARRANG_SHRT, "glue_tool");
+ defShrt(SHRT_TOOL_MUTE, 0, QT_TRANSLATE_NOOP("shortcuts", "Tool: Mute"), ARRANG_SHRT, "mute_tool");
//Increase/decrease current position, is going to be in arranger & drumeditor as well
// p4.0.10 Editors and arranger handle these by themselves, otherwise global handler will now use them, too.
- defShrt(SHRT_POS_INC, Qt::Key_Plus, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase");
- defShrt(SHRT_POS_DEC, Qt::Key_Minus, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease");
+ defShrt(SHRT_POS_INC, Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase");
+ defShrt(SHRT_POS_DEC, Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease");
- defShrt(SHRT_POS_INC_NOSNAP, Qt::SHIFT + Qt::Key_Plus, "Transport: Increase current position, no snap", GLOBAL_SHRT, "curpos_increase_nosnap");
- defShrt(SHRT_POS_DEC_NOSNAP, Qt::SHIFT + Qt::Key_Minus, "Transport: Decrease current position, no snap", GLOBAL_SHRT, "curpos_decrease_nosnap");
+ defShrt(SHRT_POS_INC_NOSNAP, Qt::SHIFT + Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position, no snap"), GLOBAL_SHRT, "curpos_increase_nosnap");
+ defShrt(SHRT_POS_DEC_NOSNAP, Qt::SHIFT + Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position, no snap"), GLOBAL_SHRT, "curpos_decrease_nosnap");
/*
- defShrt(SHRT_POS_INC_BAR, Qt::CTRL + Qt::ALT + Qt::Key_Plus, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_bar");
- defShrt(SHRT_POS_DEC_BAR, Qt::CTRL + Qt::ALT + Qt::Key_Minus, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_bar");
- defShrt(SHRT_POS_INC_BAR_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::ALT + Qt::Key_Plus, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_bar_nosnap");
- defShrt(SHRT_POS_DEC_BAR_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::ALT + Qt::Key_Minus, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_bar_nosnap");
+ defShrt(SHRT_POS_INC_BAR, Qt::CTRL + Qt::ALT + Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_bar");
+ defShrt(SHRT_POS_DEC_BAR, Qt::CTRL + Qt::ALT + Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_bar");
+ defShrt(SHRT_POS_INC_BAR_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::ALT + Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_bar_nosnap");
+ defShrt(SHRT_POS_DEC_BAR_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::ALT + Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_bar_nosnap");
- defShrt(SHRT_POS_INC_BEAT, Qt::ALT + Qt::Key_Plus, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_beat");
- defShrt(SHRT_POS_DEC_BEAT, Qt::ALT + Qt::Key_Minus, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_beat");
- defShrt(SHRT_POS_INC_BEAT_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_Plus, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_beat_nosnap");
- defShrt(SHRT_POS_DEC_BEAT_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_Minus, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_beat_nosnap");
+ defShrt(SHRT_POS_INC_BEAT, Qt::ALT + Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_beat");
+ defShrt(SHRT_POS_DEC_BEAT, Qt::ALT + Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_beat");
+ defShrt(SHRT_POS_INC_BEAT_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_beat_nosnap");
+ defShrt(SHRT_POS_DEC_BEAT_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_beat_nosnap");
- defShrt(SHRT_POS_INC_TICK, Qt::CTRL + Qt::Key_Plus, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_tick");
- defShrt(SHRT_POS_DEC_TICK, Qt::CTRL + Qt::Key_Minus, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_tick");
- defShrt(SHRT_POS_INC_TICK_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_Plus, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_tick");
- defShrt(SHRT_POS_DEC_TICK_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_Minus, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_tick");
+ defShrt(SHRT_POS_INC_TICK, Qt::CTRL + Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_tick");
+ defShrt(SHRT_POS_DEC_TICK, Qt::CTRL + Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_tick");
+ defShrt(SHRT_POS_INC_TICK_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_Plus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_tick");
+ defShrt(SHRT_POS_DEC_TICK_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_Minus, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_tick");
- defShrt(SHRT_POS_INC_FRAME, Qt::Key_N, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_frame");
- defShrt(SHRT_POS_DEC_FRAME, Qt::Key_B, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_frame");
+ defShrt(SHRT_POS_INC_FRAME, Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_frame");
+ defShrt(SHRT_POS_DEC_FRAME, Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_frame");
- defShrt(SHRT_POS_INC_SECOND, Qt::CTRL + Qt::Key_N, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_second");
- defShrt(SHRT_POS_DEC_SECOND, Qt::CTRL + Qt::Key_B, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_second");
- defShrt(SHRT_POS_INC_SECOND_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_N, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_second_nosnap");
- defShrt(SHRT_POS_DEC_SECOND_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_B, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_second_nosnap");
+ defShrt(SHRT_POS_INC_SECOND, Qt::CTRL + Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_second");
+ defShrt(SHRT_POS_DEC_SECOND, Qt::CTRL + Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_second");
+ defShrt(SHRT_POS_INC_SECOND_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_second_nosnap");
+ defShrt(SHRT_POS_DEC_SECOND_NOSNAP, Qt::SHIFT + Qt::CTRL + Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_second_nosnap");
- defShrt(SHRT_POS_INC_MINUTE, Qt::ALT + Qt::Key_N, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_minute");
- defShrt(SHRT_POS_DEC_MINUTE, Qt::ALT + Qt::Key_B, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_minute");
- defShrt(SHRT_POS_INC_MINUTE_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_N, "Transport: Increase current position", GLOBAL_SHRT, "curpos_increase_minute_nosnap");
- defShrt(SHRT_POS_DEC_MINUTE_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_B, "Transport: Decrease current position", GLOBAL_SHRT, "curpos_decrease_minute_nosnap");
+ defShrt(SHRT_POS_INC_MINUTE, Qt::ALT + Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_minute");
+ defShrt(SHRT_POS_DEC_MINUTE, Qt::ALT + Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_minute");
+ defShrt(SHRT_POS_INC_MINUTE_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "Transport: Increase current position"), GLOBAL_SHRT, "curpos_increase_minute_nosnap");
+ defShrt(SHRT_POS_DEC_MINUTE_NOSNAP, Qt::SHIFT + Qt::ALT + Qt::Key_B, QT_TRANSLATE_NOOP("shortcuts", "Transport: Decrease current position"), GLOBAL_SHRT, "curpos_decrease_minute_nosnap");
*/
- defShrt(SHRT_SET_QUANT_1, Qt::Key_1, "Quantize: Set quantize to 1/1 note", PROLL_SHRT, "midi_quant_1");
- defShrt(SHRT_SET_QUANT_2, Qt::Key_2, "Quantize: Set quantize to 1/2 note", PROLL_SHRT, "midi_quant_2");
- defShrt(SHRT_SET_QUANT_3, Qt::Key_3, "Quantize: Set quantize to 1/4 note", PROLL_SHRT, "midi_quant_3");
- defShrt(SHRT_SET_QUANT_4, Qt::Key_4, "Quantize: Set quantize to 1/8 note", PROLL_SHRT, "midi_quant_4");
- defShrt(SHRT_SET_QUANT_5, Qt::Key_5, "Quantize: Set quantize to 1/16 note", PROLL_SHRT, "midi_quant_5");
- defShrt(SHRT_SET_QUANT_6, Qt::Key_6, "Quantize: Set quantize to 1/32 note", PROLL_SHRT, "midi_quant_6");
- defShrt(SHRT_SET_QUANT_7, Qt::Key_7, "Quantize: Set quantize to 1/64 note", PROLL_SHRT, "midi_quant_7");
-
- defShrt(SHRT_TOGGLE_TRIOL, Qt::Key_T, "Quantize: Toggle triol quantization", PROLL_SHRT, "midi_quant_triol");
- defShrt(SHRT_TOGGLE_PUNCT, Qt::Key_Period, "Quantize: Toggle punctuation quantization", PROLL_SHRT, "midi_quant_punct");
- defShrt(SHRT_TOGGLE_PUNCT2, Qt::Key_Comma, "Quantize: Toggle punctuation quantization (2)", PROLL_SHRT, "midi_quant_punct2");
- defShrt(SHRT_INSERT_AT_LOCATION, Qt::SHIFT + Qt::Key_Right, "Edit: Insert at location", PROLL_SHRT, "midi_insert_at_loc");
-
- defShrt(SHRT_INCREASE_LEN, Qt::CTRL + Qt::SHIFT + Qt::Key_Right, "Edit: Increase length", PROLL_SHRT, "increase_len");
- defShrt(SHRT_DECREASE_LEN, Qt::CTRL + Qt::SHIFT + Qt::Key_Left, "Edit: Decrease length", PROLL_SHRT, "decrease_len");
+ defShrt(SHRT_SET_QUANT_1, Qt::Key_1, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/1 note"), PROLL_SHRT, "midi_quant_1");
+ defShrt(SHRT_SET_QUANT_2, Qt::Key_2, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/2 note"), PROLL_SHRT, "midi_quant_2");
+ defShrt(SHRT_SET_QUANT_3, Qt::Key_3, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/4 note"), PROLL_SHRT, "midi_quant_3");
+ defShrt(SHRT_SET_QUANT_4, Qt::Key_4, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/8 note"), PROLL_SHRT, "midi_quant_4");
+ defShrt(SHRT_SET_QUANT_5, Qt::Key_5, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/16 note"), PROLL_SHRT, "midi_quant_5");
+ defShrt(SHRT_SET_QUANT_6, Qt::Key_6, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/32 note"), PROLL_SHRT, "midi_quant_6");
+ defShrt(SHRT_SET_QUANT_7, Qt::Key_7, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Set quantize to 1/64 note"), PROLL_SHRT, "midi_quant_7");
+
+ defShrt(SHRT_TOGGLE_TRIOL, Qt::Key_T, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle triol quantization"), PROLL_SHRT, "midi_quant_triol");
+ defShrt(SHRT_TOGGLE_PUNCT, Qt::Key_Period, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle punctuation quantization"), PROLL_SHRT, "midi_quant_punct");
+ defShrt(SHRT_TOGGLE_PUNCT2, Qt::Key_Comma, QT_TRANSLATE_NOOP("shortcuts", "Quantize: Toggle punctuation quantization (2)"), PROLL_SHRT, "midi_quant_punct2");
+ defShrt(SHRT_INSERT_AT_LOCATION, Qt::SHIFT + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Insert at location"), PROLL_SHRT, "midi_insert_at_loc");
+
+ defShrt(SHRT_INCREASE_LEN, Qt::CTRL + Qt::SHIFT + Qt::Key_Right, QT_TRANSLATE_NOOP("shortcuts", "Edit: Increase length"), PROLL_SHRT, "increase_len");
+ defShrt(SHRT_DECREASE_LEN, Qt::CTRL + Qt::SHIFT + Qt::Key_Left, QT_TRANSLATE_NOOP("shortcuts", "Edit: Decrease length"), PROLL_SHRT, "decrease_len");
//-----------------------------------------------------------
// List edit:
//-----------------------------------------------------------
- defShrt(SHRT_LE_INS_NOTES, Qt::CTRL + Qt::Key_N, "Insert Note", LEDIT_SHRT, "le_ins_note");
- defShrt(SHRT_LE_INS_SYSEX, Qt::CTRL + Qt::Key_S, "Insert SysEx", LEDIT_SHRT, "le_ins_sysex");
- defShrt(SHRT_LE_INS_CTRL, Qt::CTRL + Qt::Key_T, "Insert Ctrl", LEDIT_SHRT, "le_ins_ctrl");
- defShrt(SHRT_LE_INS_META, 0, "Insert Meta", LEDIT_SHRT, "le_ins_meta");
- defShrt(SHRT_LE_INS_CHAN_AFTERTOUCH, Qt::CTRL + Qt::Key_A, "Insert Channel Aftertouch", LEDIT_SHRT, "le_ins_afttouch");
- defShrt(SHRT_LE_INS_POLY_AFTERTOUCH, Qt::CTRL + Qt::Key_P, "Insert Key Aftertouch", LEDIT_SHRT, "le_ins_poly");
+ defShrt(SHRT_LE_INS_NOTES, Qt::CTRL + Qt::Key_N, QT_TRANSLATE_NOOP("shortcuts", "Insert Note"), LEDIT_SHRT, "le_ins_note");
+ defShrt(SHRT_LE_INS_SYSEX, Qt::CTRL + Qt::Key_S, QT_TRANSLATE_NOOP("shortcuts", "Insert SysEx"), LEDIT_SHRT, "le_ins_sysex");
+ defShrt(SHRT_LE_INS_CTRL, Qt::CTRL + Qt::Key_T, QT_TRANSLATE_NOOP("shortcuts", "Insert Ctrl"), LEDIT_SHRT, "le_ins_ctrl");
+ defShrt(SHRT_LE_INS_META, 0, QT_TRANSLATE_NOOP("shortcuts", "Insert Meta"), LEDIT_SHRT, "le_ins_meta");
+ defShrt(SHRT_LE_INS_CHAN_AFTERTOUCH, Qt::CTRL + Qt::Key_A, QT_TRANSLATE_NOOP("shortcuts", "Insert Channel Aftertouch"), LEDIT_SHRT, "le_ins_afttouch");
+ defShrt(SHRT_LE_INS_POLY_AFTERTOUCH, Qt::CTRL + Qt::Key_P, QT_TRANSLATE_NOOP("shortcuts", "Insert Key Aftertouch"), LEDIT_SHRT, "le_ins_poly");
//-----------------------------------------------------------
// List masteredit:
//-----------------------------------------------------------
- defShrt(SHRT_LM_INS_TEMPO, Qt::CTRL + Qt::Key_T, "Insert Tempo", LMEDIT_SHRT, "lm_ins_tempo");
- defShrt(SHRT_LM_INS_SIG , Qt::CTRL + Qt::Key_R, "Insert Signature", LMEDIT_SHRT, "lm_ins_sig");
- defShrt(SHRT_LM_EDIT_BEAT, Qt::CTRL + Qt::SHIFT+ Qt::Key_E, "Change Event Position", LMEDIT_SHRT, "lm_edit_beat");
- defShrt(SHRT_LM_EDIT_VALUE, Qt::CTRL + Qt::Key_E, "Edit Event Value", LMEDIT_SHRT, "lm_edit_val");
- defShrt(SHRT_LM_INS_KEY, Qt::CTRL + Qt::Key_K, "Insert Key", LMEDIT_SHRT, "lm_ins_key");
-
- defShrt(SHRT_NEXT_MARKER, Qt::Key_F6, "Goto Next Marker", ARRANG_SHRT, "me_sel_next");
- defShrt(SHRT_PREV_MARKER, Qt::Key_F5, "Goto Prev Marker", ARRANG_SHRT, "me_sel_prev");
+ defShrt(SHRT_LM_INS_TEMPO, Qt::CTRL + Qt::Key_T, QT_TRANSLATE_NOOP("shortcuts", "Insert Tempo"), LMEDIT_SHRT, "lm_ins_tempo");
+ defShrt(SHRT_LM_INS_SIG , Qt::CTRL + Qt::Key_R, QT_TRANSLATE_NOOP("shortcuts", "Insert Signature"), LMEDIT_SHRT, "lm_ins_sig");
+ defShrt(SHRT_LM_EDIT_BEAT, Qt::CTRL + Qt::SHIFT+ Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Change Event Position"), LMEDIT_SHRT, "lm_edit_beat");
+ defShrt(SHRT_LM_EDIT_VALUE, Qt::CTRL + Qt::Key_E, QT_TRANSLATE_NOOP("shortcuts", "Edit Event Value"), LMEDIT_SHRT, "lm_edit_val");
+ defShrt(SHRT_LM_INS_KEY, Qt::CTRL + Qt::Key_K, QT_TRANSLATE_NOOP("shortcuts", "Insert Key"), LMEDIT_SHRT, "lm_ins_key");
+
+ defShrt(SHRT_NEXT_MARKER, Qt::Key_F6, QT_TRANSLATE_NOOP("shortcuts", "Goto Next Marker"), ARRANG_SHRT, "me_sel_next");
+ defShrt(SHRT_PREV_MARKER, Qt::Key_F5, QT_TRANSLATE_NOOP("shortcuts", "Goto Prev Marker"), ARRANG_SHRT, "me_sel_prev");
}
diff --git a/muse2/muse/sig.cpp b/muse2/muse/sig.cpp
index 0b62848c..b11aa622 100644
--- a/muse2/muse/sig.cpp
+++ b/muse2/muse/sig.cpp
@@ -22,7 +22,6 @@
//=========================================================
#include <stdio.h>
-#include <assert.h>
#include "sig.h"
#include "gconfig.h"
#include "xml.h"
@@ -51,14 +50,18 @@ SigList::SigList()
void SigList::add(unsigned tick, int z, int n)
{
if (z == 0 || n == 0) {
- printf("SigList::add illegal signature %d/%d\n", z, n);
+ printf("THIS SHOULD NEVER HAPPEN: SigList::add() illegal signature %d/%d\n", z, n);
// Added p3.3.43
return;
}
tick = raster1(tick, 0);
iSigEvent e = upper_bound(tick);
- assert(e != end());
+ if (e == end())
+ {
+ printf("THIS SHOULD NEVER HAPPEN: could not find upper_bound(%i) in SigList::add()!\n", tick);
+ return;
+ }
if (tick == e->second->tick) {
e->second->z = z;
@@ -185,7 +188,11 @@ int SigList::ticksMeasure(unsigned tick) const
int SigList::ticksBeat(unsigned tick) const
{
ciSigEvent i = upper_bound(tick);
- assert(i != end());
+ if (i == end())
+ {
+ printf("THIS SHOULD NEVER HAPPEN: couldn't find sig event for tick=%i in SigList::ticksBeat()!\n",tick);
+ return 0;
+ }
return ticks_beat(i->second->n);
}
@@ -202,7 +209,7 @@ int SigList::ticks_beat(int n) const
case 32: m >>= 3; break; // 48
case 64: m >>= 4; break; // 24
case 128: m >>= 5; break; // 12
- default: assert(false); break;
+ default: printf("THIS SHOULD NEVER HAPPEN: invalid function call in SigList::ticks_beat(): n=%i\n",n); break;
}
return m;
}
@@ -308,7 +315,11 @@ unsigned SigList::raster1(unsigned t, int raster) const
if (raster == 1)
return t;
ciSigEvent e = upper_bound(t);
- assert(e != end());
+ if (e == end())
+ {
+ printf("THIS SHOULD NEVER HAPPEN: couldn't find sig event for tick=%i in SigList::raster1()!\n", t);
+ return 0;
+ }
int delta = t - e->second->tick;
int ticksM = ticks_beat(e->second->n) * e->second->z;
@@ -329,7 +340,11 @@ unsigned SigList::raster2(unsigned t, int raster) const
if (raster == 1)
return t;
ciSigEvent e = upper_bound(t);
- assert(e != end());
+ if (e == end())
+ {
+ printf("THIS SHOULD NEVER HAPPEN: couldn't find sig event for tick=%i in SigList::raster2()!\n", t);
+ return 0;
+ }
int delta = t - e->second->tick;
int ticksM = ticks_beat(e->second->n) * e->second->z;
@@ -348,7 +363,11 @@ int SigList::rasterStep(unsigned t, int raster) const
{
if (raster == 0) {
ciSigEvent e = upper_bound(t);
- assert(e != end());
+ if (e == end())
+ {
+ printf("THIS SHOULD NEVER HAPPEN: couldn't find sig event for tick=%i in SigList::rasterStep()!\n", t);
+ return 0;
+ }
return ticks_beat(e->second->n) * e->second->z;
}
return raster;
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index b48f134b..484e2d42 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -72,26 +72,6 @@ namespace MusECore {
extern void clearMidiTransforms();
extern void clearMidiInputTransforms();
-/*
-//---------------------------------------------------------
-// RoutingMenuItem
-//---------------------------------------------------------
-
-class RoutingMenuItem : public QCustomMenuItem
-{
- Route route;
- //virtual QSize sizeHint() { return QSize(80, h); }
- virtual void paint(QPainter* p, const QColorGroup&, bool, bool, int x, int y, int w, int h)
- {
- p->fillRect(x, y, w, h, QBrush(lightGray));
- p->drawText(x, y, w, h, AlignCenter, route.name());
- }
-
- public:
- RoutingMenuItem(const Route& r) : route(r) { }
-};
-*/
-
//---------------------------------------------------------
// Song
//---------------------------------------------------------
@@ -108,6 +88,8 @@ Song::Song(const char* name)
redoList = new UndoList;
_markerList = new MarkerList;
_globalPitchShift = 0;
+ bounceTrack = NULL;
+ bounceOutput = NULL;
showSongInfo=true;
clear(false);
}
@@ -174,6 +156,7 @@ void Song::setSig(const AL::TimeSignature& sig)
Track* Song::addNewTrack(QAction* action, Track* insertAt)
{
+printf("Song::addNewTrack\n");
int n = action->data().toInt();
// Ignore negative numbers since this slot could be called by a menu or list etc. passing -1.
if(n < 0)
@@ -183,13 +166,20 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt)
if(n >= MENU_ADD_SYNTH_ID_BASE)
{
n -= MENU_ADD_SYNTH_ID_BASE;
+ int ntype = n / MENU_ADD_SYNTH_ID_BASE;
+ if(ntype >= Synth::SYNTH_TYPE_END)
+ return 0;
+
+ n %= MENU_ADD_SYNTH_ID_BASE;
if(n >= (int)MusEGlobal::synthis.size())
return 0;
- SynthI* si = createSynthI(MusEGlobal::synthis[n]->baseName(), MusEGlobal::synthis[n]->name(), insertAt);
+ //printf("Song::addNewTrack synth: type:%d idx:%d class:%s label:%s\n", ntype, n, MusEGlobal::synthis[n]->baseName().toLatin1().constData(), MusEGlobal::synthis[n]->name().toLatin1().constData());
+ SynthI* si = createSynthI(MusEGlobal::synthis[n]->baseName(), MusEGlobal::synthis[n]->name(), (Synth::Type)ntype, insertAt);
if(!si)
return 0;
-
+ if (MusEGlobal::config.unhideTracks) SynthI::setVisible(true);
+
// Add instance last in midi device list.
for (int i = 0; i < MIDI_PORTS; ++i)
{
@@ -199,15 +189,19 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt)
{
MusEGlobal::midiSeq->msgSetMidiDevice(port, si);
MusEGlobal::muse->changeConfig(true); // save configuration file
- deselectTracks();
- si->setSelected(true);
- update();
+ if (SynthI::visible()) {
+ deselectTracks();
+ si->setSelected(true);
+ update();
+ }
return si;
}
}
- deselectTracks();
- si->setSelected(true);
- update(SC_SELECTION);
+ if (SynthI::visible()) {
+ deselectTracks();
+ si->setSelected(true);
+ update(SC_SELECTION);
+ }
return si;
}
// Normal track.
@@ -218,10 +212,14 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt)
if((Track::TrackType)n >= Track::AUDIO_SOFTSYNTH)
return 0;
- Track* t = addTrack((Track::TrackType)n, insertAt);
- deselectTracks();
- t->setSelected(true);
- update(SC_SELECTION);
+ Undo operations;
+ Track* t = addTrack(operations, (Track::TrackType)n, insertAt);
+ applyOperationGroup(operations);
+ if (t->isVisible()) {
+ deselectTracks();
+ t->setSelected(true);
+ update(SC_SELECTION);
+ }
return t;
}
}
@@ -234,14 +232,16 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt)
// If insertAt is valid, inserts before insertAt. Else at the end after all tracks.
//---------------------------------------------------------
-Track* Song::addTrack(Track::TrackType type, Track* insertAt)
+Track* Song::addTrack(Undo& operations, Track::TrackType type, Track* insertAt)
{
+ printf("Song::addTrack\n");
Track* track = 0;
int lastAuxIdx = _auxs.size();
switch(type) {
case Track::MIDI:
track = new MidiTrack();
track->setType(Track::MIDI);
+ if (MusEGlobal::config.unhideTracks) MidiTrack::setVisible(true);
break;
case Track::NEW_DRUM:
track = new MidiTrack();
@@ -252,40 +252,48 @@ Track* Song::addTrack(Track::TrackType type, Track* insertAt)
track = new MidiTrack();
track->setType(Track::DRUM);
((MidiTrack*)track)->setOutChannel(9);
+ if (MusEGlobal::config.unhideTracks) MidiTrack::setVisible(true);
break;
case Track::WAVE:
track = new MusECore::WaveTrack();
((AudioTrack*)track)->addAuxSend(lastAuxIdx);
+ if (MusEGlobal::config.unhideTracks) WaveTrack::setVisible(true);
break;
case Track::AUDIO_OUTPUT:
track = new AudioOutput();
+ if (MusEGlobal::config.unhideTracks) AudioOutput::setVisible(true);
break;
case Track::AUDIO_GROUP:
track = new AudioGroup();
((AudioTrack*)track)->addAuxSend(lastAuxIdx);
+ if (MusEGlobal::config.unhideTracks) AudioGroup::setVisible(true);
break;
case Track::AUDIO_AUX:
track = new AudioAux();
+ if (MusEGlobal::config.unhideTracks) AudioAux::setVisible(true);
break;
case Track::AUDIO_INPUT:
track = new AudioInput();
((AudioTrack*)track)->addAuxSend(lastAuxIdx);
+ if (MusEGlobal::config.unhideTracks) AudioInput::setVisible(true);
break;
case Track::AUDIO_SOFTSYNTH:
printf("not implemented: Song::addTrack(SOFTSYNTH)\n");
// ((AudioTrack*)track)->addAuxSend(lastAuxIdx);
break;
default:
- printf("Song::addTrack() illegal type %d\n", type);
- abort();
+ printf("THIS SHOULD NEVER HAPPEN: Song::addTrack() illegal type %d. returning NULL.\n"
+ "save your work if you can and expect soon crashes!\n", type);
+ return NULL;
}
track->setDefaultName();
int idx = insertAt ? _tracks.index(insertAt) : -1;
- insertTrack1(track, idx);
- msgInsertTrack(track, idx, true);
- insertTrack3(track, idx);
+ // insertTrack1(track, idx); // this and the below are replaced
+ // msgInsertTrack(track, idx, true); // by the UndoOp-operation
+ // insertTrack3(track, idx); // does nothing
+ operations.push_back(UndoOp(UndoOp::AddTrack, idx, track));
// Add default track <-> midiport routes.
if(track->isMidiTrack())
@@ -436,45 +444,6 @@ void Song::changeTrack(Track* oldTrack, Track* newTrack)
bool Song::addEvent(Event& event, Part* part)
{
- /*
- if (event.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int ch = track->outChannel();
- int tick = event.tick() + part->tick();
- int cntrl = event.dataA();
- int val = event.dataB();
- MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];
-
- // Is it a drum controller event, according to the track port's instrument?
- if(track->type() == Track::DRUM)
- {
- MidiController* mc = mp->drumController(cntrl);
- if(mc)
- {
- int note = cntrl & 0x7f;
- cntrl &= ~0xff;
- ch = MusEGlobal::drumMap[note].channel;
- mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[note].port];
- cntrl |= MusEGlobal::drumMap[note].anote;
- }
- }
-
- // Changed by T356.
- //if (!mp->setCtrl(ch, tick, cntrl, val)) {
- // mp->addManagedController(ch, cntrl);
- // if (!mp->setCtrl(ch, tick, cntrl, val))
- // return false;
- // }
- // Changed again. Don't depend on return value of this - search for the event, below.
- //if(!mp->setControllerVal(ch, tick, cntrl, val, part))
- // return false;
- if(mp->setControllerVal(ch, tick, cntrl, val, part))
- updateFlags |= SC_MIDI_CONTROLLER;
- }
- */
-
- //addPortCtrlEvents(event, part);
-
// Return false if the event is already found.
// (But allow a port controller value, above, in case it is not already stored.)
if(part->events()->find(event) != part->events()->end())
@@ -501,7 +470,6 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part)
// This can be normal for some (redundant) operations.
if(MusEGlobal::debugMsg)
printf("Song::changeEvent event not found in part:%s size:%zd\n", part->name().toLatin1().constData(), part->events()->size());
- // abort();
// Removed by T356. Allow it to add the new event.
// (And remove the old one from the midi port controller!)
//return;
@@ -510,59 +478,6 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part)
part->events()->erase(i);
part->events()->add(newEvent);
-
- /*
- if (oldEvent.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int ch = track->outChannel();
- int tick = oldEvent.tick() + part->tick();
- int cntrl = oldEvent.dataA();
- MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];
- // Is it a drum controller event, according to the track port's instrument?
- if(track->type() == Track::DRUM)
- {
- MidiController* mc = mp->drumController(cntrl);
- if(mc)
- {
- int note = cntrl & 0x7f;
- cntrl &= ~0xff;
- ch = MusEGlobal::drumMap[note].channel;
- mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[note].port];
- cntrl |= MusEGlobal::drumMap[note].anote;
- }
- }
-
- mp->deleteController(ch, tick, cntrl, part);
- }
- */
- //removePortCtrlEvents(oldEvent, part);
-
- /*
- if (newEvent.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int ch = track->outChannel();
- int tick = newEvent.tick() + part->tick();
- int cntrl = newEvent.dataA();
- int val = newEvent.dataB();
- MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];
- // Is it a drum controller event, according to the track port's instrument?
- if(track->type() == Track::DRUM)
- {
- MidiController* mc = mp->drumController(cntrl);
- if(mc)
- {
- int note = cntrl & 0x7f;
- cntrl &= ~0xff;
- ch = MusEGlobal::drumMap[note].channel;
- mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[note].port];
- cntrl |= MusEGlobal::drumMap[note].anote;
- }
- }
-
- mp->setControllerVal(ch, tick, cntrl, val, part);
- }
- */
- //addPortCtrlEvents(newEvent, part);
}
//---------------------------------------------------------
@@ -571,33 +486,6 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part)
void Song::deleteEvent(Event& event, Part* part)
{
- /*
- if (event.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int ch = track->outChannel();
- int tick = event.tick() + part->tick();
- int cntrl = event.dataA();
-
- MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()];
- // Is it a drum controller event, according to the track port's instrument?
- if(track->type() == Track::DRUM)
- {
- MidiController* mc = mp->drumController(cntrl);
- if(mc)
- {
- int note = cntrl & 0x7f;
- cntrl &= ~0xff;
- ch = MusEGlobal::drumMap[note].channel;
- mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[note].port];
- cntrl |= MusEGlobal::drumMap[note].anote;
- }
- }
-
- mp->deleteController(ch, tick, cntrl, part);
- }
- */
- //removePortCtrlEvents(event, part);
-
iEvent ev = part->events()->find(event);
if (ev == part->events()->end()) {
// This can be normal for some (redundant) operations.
@@ -944,88 +832,6 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start
// Add the event to the new part's port controller values, and do all clone parts.
addPortCtrlEvents(event, newPart, true);
}
-
-
- /*
- if (_recMode == REC_REPLACE)
- {
- iEvent si = part->events()->lower_bound(startTick - part->tick());
- iEvent ei = part->events()->lower_bound(part->endTick() - part->tick());
-
- for (iEvent i = si; i != ei; ++i)
- {
- Event event = i->second;
- // Create an undo op. Indicate do port controller values and clone parts.
- //addUndo(UndoOp(UndoOp::DeleteEvent, event, part));
- addUndo(UndoOp(UndoOp::DeleteEvent, event, part, true, true));
-
- //if (event.type() == Controller) {
- // MidiTrack* track = (MidiTrack*)part->track();
- // int ch = track->outChannel();
- // int tick = event.tick() + part->tick();
- // int cntrl = event.dataA();
- // MusEGlobal::midiPorts[track->outPort()].deleteController(ch, tick, cntrl, part);
- // }
-
- // Remove the event from the part's port controller values, and do all clone parts.
- //removePortCtrlEvents(event, part, true);
- }
- part->events()->erase(si, ei);
- }
-
- // Remove all of the part's port controller values, and do all clone parts.
- removePortCtrlEvents(part, true);
-
- // Clone the part. This doesn't increment aref count, and doesn't chain clones.
- // It also gives the new part a new serial number, but it is
- // overwritten with the old one by Song::changePart(), below.
- Part* newPart = part->clone();
-
- endTick = 0;
- for (iEvent i = s; i != e; ++i) {
- Event event = i->second;
- unsigned tick = event.tick() - partTick;
- event.setTick(tick);
- Event e;
- // Create an undo op. Indicate do port controller values and clone parts.
- //addUndo(UndoOp(UndoOp::AddEvent, e, event, newPart));
- addUndo(UndoOp(UndoOp::AddEvent, e, event, newPart, true, true));
-
- // addEvent also adds port controller values. So does msgChangePart, below. Let msgChangePart handle them.
- //addEvent(event, (MidiPart*)newPart);
- if(newPart->events()->find(event) == newPart->events()->end())
- newPart->events()->add(event);
-
- if (endTick < event.tick() + event.lenTick())
- endTick = event.tick() + event.lenTick();
- }
- newPart->setLenTick(endTick); // endTick - part->tick()
-
- //printf("Song::cmdAddRecordedEvents before changePart part:%p events:%p refs:%d Arefs:%d newPart:%p events:%p refs:%d Arefs:%d\n", part, part->events(), part->events()->refCount(), part->events()->arefCount(), newPart, newPart->events(), newPart->events()->refCount(), newPart->events()->arefCount());
-
- // Change the part.
- changePart(part, newPart);
- // Manually adjust reference counts.
- part->events()->incARef(-1);
- newPart->events()->incARef(1);
- // Replace the part in the clone chain with the new part.
- replaceClone(part, newPart);
- // Now add all of the new part's port controller values, and do all clone parts.
- addPortCtrlEvents(newPart, true);
-
- //printf("Song::cmdAddRecordedEvents after changePart part:%p events:%p refs:%d Arefs:%d newPart:%p events:%p refs:%d Arefs:%d\n", part, part->events(), part->events()->refCount(), part->events()->arefCount(), newPart, newPart->events(), newPart->events()->refCount(), newPart->events()->arefCount());
-
- //addUndo(UndoOp(UndoOp::ModifyPart, part, newPart));
- // Create an undo op. Indicate do not do port controller values and clone parts.
- addUndo(UndoOp(UndoOp::ModifyPart, part, newPart, false, false));
-
- // Removed by T356.
- //part->events()->incARef(-1);
-
- updateFlags |= SC_PART_MODIFIED;
- //printf("Song::cmdAddRecordedEvents final part:%p events:%p refs:%d Arefs:%d newPart:%p events:%p refs:%d Arefs:%d\n", part, part->events(), part->events()->refCount(), part->events()->arefCount(), newPart, newPart->events(), newPart->events()->refCount(), newPart->events()->arefCount());
- */
-
}
else {
if (_recMode == REC_REPLACE) {
@@ -1037,15 +843,6 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start
// Create an undo op. Indicate that controller values and clone parts were handled.
//addUndo(UndoOp(UndoOp::DeleteEvent, event, part));
addUndo(UndoOp(UndoOp::DeleteEvent, event, part, true, true));
- /*
- if (event.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int ch = track->outChannel();
- int tick = event.tick() + part->tick();
- int cntrl = event.dataA();
- MusEGlobal::midiPorts[track->outPort()].deleteController(ch, tick, cntrl, part);
- }
- */
// Remove the event from the part's port controller values, and do all clone parts.
removePortCtrlEvents(event, part, true);
}
@@ -1719,6 +1516,7 @@ void Song::setMType(MType t)
void Song::beat()
{
#if 0
+ // Just a rate test...
static double _heartbeatRateTimer = 0.0;
double t = MusEUtil::curTime();
if(t - _heartbeatRateTimer > 0.0)
@@ -2040,14 +1838,12 @@ void Song::processMsg(AudioMsg* msg)
break;
case SEQM_ADD_TEMPO:
- //printf("processMsg (SEQM_ADD_TEMPO) UndoOp::AddTempo. adding tempo at: %d with tempo=%d\n", msg->a, msg->b);
addUndo(UndoOp(UndoOp::AddTempo, msg->a, msg->b));
MusEGlobal::tempomap.addTempo(msg->a, msg->b);
updateFlags = SC_TEMPO;
break;
case SEQM_SET_TEMPO:
- //printf("processMsg (SEQM_SET_TEMPO) UndoOp::AddTempo. adding tempo at: %d with tempo=%d\n", msg->a, msg->b);
addUndo(UndoOp(UndoOp::AddTempo, msg->a, msg->b));
MusEGlobal::tempomap.setTempo(msg->a, msg->b);
updateFlags = SC_TEMPO;
@@ -2058,7 +1854,6 @@ void Song::processMsg(AudioMsg* msg)
break;
case SEQM_REMOVE_TEMPO:
- //printf("processMsg (SEQM_REMOVE_TEMPO) UndoOp::DeleteTempo. adding tempo at: %d with tempo=%d\n", msg->a, msg->b);
addUndo(UndoOp(UndoOp::DeleteTempo, msg->a, msg->b));
MusEGlobal::tempomap.delTempo(msg->a);
updateFlags = SC_TEMPO;
@@ -2123,7 +1918,6 @@ void Song::cmdRemovePart(Part* part)
// cmdChangePart
//---------------------------------------------------------
-//void Song::cmdChangePart(Part* oldPart, Part* newPart)
void Song::cmdChangePart(Part* oldPart, Part* newPart, bool doCtrls, bool doClones)
{
//printf("Song::cmdChangePart before changePart oldPart:%p events:%p refs:%d Arefs:%d sn:%d newPart:%p events:%p refs:%d Arefs:%d sn:%d\n", oldPart, oldPart->events(), oldPart->events()->refCount(), oldPart->events()->arefCount(), oldPart->sn(), newPart, newPart->events(), newPart->events()->refCount(), newPart->events()->arefCount(), newPart->sn());
@@ -2172,13 +1966,13 @@ void Song::panic()
// If clear_all is false, it will not touch things like midi ports.
//---------------------------------------------------------
-void Song::clear(bool signal, bool /*clear_all*/)
+void Song::clear(bool signal, bool clear_all)
{
if(MusEGlobal::debugMsg)
printf("Song::clear\n");
bounceTrack = 0;
-
+
_tracks.clear();
_midis.clearDelete();
_waves.clearDelete();
@@ -2197,7 +1991,7 @@ void Song::clear(bool signal, bool /*clear_all*/)
// p3.3.50 Reset this.
MusEGlobal::midiPorts[i].setFoundInSongFile(false);
- //if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems...
+ if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems...
// This will also close the device.
MusEGlobal::midiPorts[i].setMidiDevice(0);
}
@@ -2216,7 +2010,7 @@ void Song::clear(bool signal, bool /*clear_all*/)
//if((*imd)->deviceType() == MidiDevice::JACK_MIDI)
if(dynamic_cast< MidiJackDevice* >(*imd))
{
- //if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems...
+ if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems...
{
// Remove the device from the list.
MusEGlobal::midiDevices.erase(imd);
@@ -2475,7 +2269,6 @@ void Song::seqSignal(int fd)
if(MusEGlobal::debugMsg)
printf("Song: seqSignal: case f: setFreewheel start\n");
- // Enabled by Tim. p3.3.6
if(MusEGlobal::config.freewheelMode)
MusEGlobal::audioDevice->setFreewheel(true);
@@ -2485,7 +2278,6 @@ void Song::seqSignal(int fd)
if(MusEGlobal::debugMsg)
printf("Song: seqSignal: case F: setFreewheel stop\n");
- // Enabled by Tim. p3.3.6
if(MusEGlobal::config.freewheelMode)
MusEGlobal::audioDevice->setFreewheel(false);
@@ -2502,7 +2294,6 @@ void Song::seqSignal(int fd)
MusEGlobal::audioDevice->graphChanged();
break;
- // p3.3.37
case 'R': // Registration changed
if (MusEGlobal::audioDevice)
MusEGlobal::audioDevice->registrationChanged();
@@ -2593,8 +2384,7 @@ void Song::recordEvent(MidiTrack* mt, Event& event)
int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int acid)
{
- //enum { HEADER, SEP1, PREV_EVENT, NEXT_EVENT, SEP2, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
- enum { HEADER, PREV_EVENT, NEXT_EVENT, SEP2, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
+ enum { PREV_EVENT, NEXT_EVENT, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
QMenu* menu = new QMenu;
int count = 0;
@@ -2639,14 +2429,8 @@ int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int a
}
}
- //menu->insertItem(tr("Automation:"), HEADER, HEADER);
- //menu->setItemEnabled(HEADER, false);
- //MenuTitleItem* title = new MenuTitleItem(tr("Automation:")); ddskrjo
- //menu->insertItem(title, HEADER, HEADER); ddskrjo
menu->addAction(new MusEGui::MenuTitleItem(tr("Automation:"), menu));
- //menu->insertSeparator(SEP1);
-
QAction* prevEvent = menu->addAction(tr("previous event"));
prevEvent->setData(PREV_EVENT);
prevEvent->setEnabled(canSeekPrev);
@@ -2655,7 +2439,6 @@ int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int a
nextEvent->setData(NEXT_EVENT);
nextEvent->setEnabled(canSeekNext);
- //menu->insertSeparator(SEP2);
menu->addSeparator();
QAction* addEvent = new QAction(menu);
@@ -2738,8 +2521,8 @@ int Song::execMidiAutomationCtlPopup(MidiTrack* track, MidiPart* part, const QPo
if(!track && !part)
return -1;
- //enum { HEADER, SEP1, PREV_EVENT, NEXT_EVENT, SEP2, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
- enum { HEADER, ADD_EVENT, CLEAR_EVENT };
+ //enum { PREV_EVENT, NEXT_EVENT, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
+ enum { ADD_EVENT, CLEAR_EVENT };
QMenu* menu = new QMenu;
//int count = 0;
@@ -2825,22 +2608,8 @@ int Song::execMidiAutomationCtlPopup(MidiTrack* track, MidiPart* part, const QPo
}
}
-
- //menu->insertItem(tr("Automation:"), HEADER, HEADER);
- //menu->setItemEnabled(HEADER, false);
- //MenuTitleItem* title = new MenuTitleItem(tr("Automation:")); ddskrjo
- ///menu->insertItem(title, HEADER, HEADER); ddskrjo
-
- //menu->insertSeparator(SEP1);
+ menu->addAction(new MusEGui::MenuTitleItem(tr("Automation:"), menu));
-// menu->insertItem(tr("previous event"), PREV_EVENT, PREV_EVENT);
-// menu->setItemEnabled(PREV_EVENT, canSeekPrev);
-
-// menu->insertItem(tr("next event"), NEXT_EVENT, NEXT_EVENT);
-// menu->setItemEnabled(NEXT_EVENT, canSeekNext);
-
-// menu->insertSeparator(SEP2);
-
QAction* addEvent = new QAction(menu);
menu->addAction(addEvent);
if(isEvent)
@@ -3101,220 +2870,6 @@ void Song::connectJackRoutes(AudioTrack* track, bool disconnect)
}
}
-/*
-//---------------------------------------------------------
-// chooseMidiRoutes
-//---------------------------------------------------------
-
-void Song::chooseMidiRoutes(QButton* parent, MidiTrack* track, bool dst)
-{
- if(!track)
- return;
-
- //if(!track->isMidiTrack())
- // return;
-
- QPoint ppt = QCursor::pos();
- //QPoint ppt = parent->rect().bottomLeft();
-
- //if(dst)
- //{
- // TODO
-
- //}
- //else
- //{
- RouteList* rl = dst ? track->outRoutes() : track->inRoutes();
- //Route dst(track, -1);
-
- QPopupMenu* pup = new QPopupMenu(parent);
- pup->setCheckable(true);
-
- int gid = 0;
- int n;
-
- // FIXME:
- // Routes can't be re-read until the message sent from msgAddRoute1()
- // has had time to be sent and actually affected the routes.
- ///_redisplay:
-
- pup->clear();
- gid = 0;
-
- //MidiInPortList* tl = MusEGlobal::song->midiInPorts();
- //for(iMidiInPort i = tl->begin();i != tl->end(); ++i)
- for(int i = 0; i < MIDI_PORTS; ++i)
- {
- //MidiInPort* track = *i;
- // NOTE: Could possibly list all devices, bypassing ports, but no, let's stick wth ports.
- MidiPort* mp = &MusEGlobal::midiPorts[i];
- MidiDevice* md = mp->device();
- if(!md)
- continue;
-
- if(!(md->rwFlags() & (dst ? 1 : 2)))
- continue;
-
- //printf("MidiStrip::iRoutePressed adding submenu portnum:%d\n", i);
-
- //QMenu* m = menu->addMenu(track->name());
- QPopupMenu* subp = new QPopupMenu(parent);
-
- for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
- {
- //QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
- //subp->insertItem(QT_TRANSLATE_NOOP("@default", QString("Channel %1").arg(ch+1)), i * MIDI_CHANNELS + ch);
- gid = i * MIDI_CHANNELS + ch;
-
- //printf("MidiStrip::iRoutePressed inserting gid:%d\n", gid);
-
- subp->insertItem(QString("Channel %1").arg(ch+1), gid);
- //a->setCheckable(true);
- //Route src(track, ch, RouteNode::TRACK);
- //Route src(md, ch);
- //Route r = Route(src, dst);
- //a->setData(QVariant::fromValue(r));
- //a->setChecked(rl->indexOf(r) != -1);
- Route srcRoute(md, ch);
- for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
- {
- //if(*ir == dst)
- if(*ir == srcRoute)
- {
- subp->setItemChecked(gid, true);
- break;
- }
- }
- }
- pup->insertItem(QT_TRANSLATE_NOOP("@default", md->name()), subp);
- }
-
-// QPopupMenu* pup = new QPopupMenu(iR);
-// pup->setCheckable(true);
- //MidiTrack* t = (MidiTrack*)track;
-// RouteList* irl = track->inRoutes();
-
-// MidiTrack* t = (MidiTrack*)track;
-// int gid = 0;
-// for (int i = 0; i < channel; ++i)
-// {
-// char buffer[128];
-// snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), i+1);
-// MenuTitleItem* titel = new MenuTitleItem(QString(buffer));
-// pup->insertItem(titel);
-
-// if (!MusEGlobal::checkAudioDevice()) return;
-// std::list<QString> ol = MusEGlobal::audioDevice->outputPorts();
-// for (std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip) {
-// int id = pup->insertItem(*ip, (gid * 16) + i);
-// Route dst(*ip, true, i);
-// ++gid;
-// for (iRoute ir = irl->begin(); ir != irl->end(); ++ir) {
-// if (*ir == dst) {
-// pup->setItemChecked(id, true);
-// break;
-// }
-// }
-// }
-// if (i+1 != channel)
-// pup->insertSeparator();
-// }
-
- if(pup->count() == 0)
- {
- delete pup;
- return;
- }
-
- //n = pup->exec(QCursor::pos());
- n = pup->exec(ppt);
- ///delete pup;
- if (n != -1)
- {
- int mdidx = n / MIDI_CHANNELS;
- int ch = n % MIDI_CHANNELS;
-
- //if(MusEGlobal::debugMsg)
- //printf("Song::chooseMidiRoutes mdidx:%d ch:%d\n", mdidx, ch);
-
- MidiPort* mp = &MusEGlobal::midiPorts[mdidx];
- MidiDevice* md = mp->device();
- if(!md)
- {
- delete pup;
- return;
- }
-
- //if(!(md->rwFlags() & 2))
- if(!(md->rwFlags() & (dst ? 1 : 2)))
- {
- delete pup;
- return;
- }
-
- //QString s(pup->text(n));
- //QT_TRANSLATE_NOOP("@default", md->name())
-
- //Route srcRoute(s, false, -1);
- Route aRoute(md, ch);
- //Route srcRoute(md, -1);
- //Route dstRoute(track, -1);
- Route bRoute(track, ch);
-
- //if (track->type() == Track::AUDIO_INPUT)
- // srcRoute.channel = dstRoute.channel = n & 0xf;
- iRoute iir = rl->begin();
- for (; iir != rl->end(); ++iir)
- {
- //if(*iir == (dst ? bRoute : aRoute))
- if(*iir == aRoute)
- break;
- }
- if (iir != rl->end())
- {
- // disconnect
- if(dst)
- {
- //printf("Song::chooseMidiRoutes removing route src track name: %s dst device name: %s\n", track->name().toLatin1().constData(), md->name().toLatin1().constData());
- MusEGlobal::audio->msgRemoveRoute(bRoute, aRoute);
- }
- else
- {
- //printf("Song::chooseMidiRoutes removing route src device name: %s dst track name: %s\n", md->name().toLatin1().constData(), track->name().toLatin1().constData());
- MusEGlobal::audio->msgRemoveRoute(aRoute, bRoute);
- }
- }
- else
- {
- // connect
- if(dst)
- {
- //printf("Song::chooseMidiRoutes adding route src track name: %s dst device name: %s\n", track->name().toLatin1().constData(), md->name().toLatin1().constData());
- MusEGlobal::audio->msgAddRoute(bRoute, aRoute);
- }
- else
- {
- //printf("Song::chooseMidiRoutes adding route src device name: %s dst track name: %s\n", md->name().toLatin1().constData(), track->name().toLatin1().constData());
- MusEGlobal::audio->msgAddRoute(aRoute, bRoute);
- }
- }
-
- //printf("Song::chooseMidiRoutes calling msgUpdateSoloStates\n");
- MusEGlobal::audio->msgUpdateSoloStates();
- //printf("Song::chooseMidiRoutes calling MusEGlobal::song->update\n");
- MusEGlobal::song->update(SC_ROUTE);
-
- // p3.3.46
- ///goto _redisplay;
- }
- delete pup;
- parent->setDown(false); // pup->exec() catches mouse release event
- //printf("Song::chooseMidiRoutes end\n");
-
- //}
-}
-*/
-
//---------------------------------------------------------
// insertTrack0
//---------------------------------------------------------
@@ -3403,7 +2958,6 @@ void Song::insertTrack2(Track* track, int idx)
break;
default:
fprintf(stderr, "unknown track type %d\n", track->type());
- // abort();
return;
}
@@ -3420,43 +2974,12 @@ void Song::insertTrack2(Track* track, int idx)
for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i) {
if ((*i)->isMidiTrack())
continue;
- MusECore::WaveTrack* wt = (MusECore::WaveTrack*)*i;
+ MusECore::AudioTrack* wt = (MusECore::AudioTrack*)*i;
if (wt->hasAuxSend()) {
wt->addAuxSend(n);
}
}
- /*
- //
- // add routes
- //
-
- if (track->isMidiTrack())
- return;
- AudioTrack* at = (AudioTrack*)track;
- Route src(at, -1);
- if (at->type() == Track::AUDIO_OUTPUT) {
- const RouteList* rl = at->inRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->outRoutes()->push_back(src);
- }
- else if (at->type() == Track::AUDIO_INPUT) {
- const RouteList* rl = at->outRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->inRoutes()->push_back(src);
- }
- else {
- const RouteList* rl = at->inRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->outRoutes()->push_back(src);
- rl = at->outRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->inRoutes()->push_back(src);
- }
- */
-
- // p3.3.38
-
//
// add routes
//
@@ -3472,6 +2995,13 @@ void Song::insertTrack2(Track* track, int idx)
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->outRoutes()->push_back(src);
+ // Is the source an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the Audio Output track's aux ref count. p4.0.37
+ if(r->track->auxRefCount())
+ track->updateAuxRoute( r->track->auxRefCount(), NULL );
+ else
+ if(r->track->type() == Track::AUDIO_AUX)
+ track->updateAuxRoute( 1, NULL );
}
}
else if (track->type() == Track::AUDIO_INPUT)
@@ -3485,6 +3015,13 @@ void Song::insertTrack2(Track* track, int idx)
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->inRoutes()->push_back(src);
+ // Is this track an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the other track's aux ref count and all tracks it is connected to. p4.0.37
+ if(track->auxRefCount())
+ r->track->updateAuxRoute( track->auxRefCount(), NULL );
+ else
+ if(track->type() == Track::AUDIO_AUX)
+ r->track->updateAuxRoute( 1, NULL );
}
}
else if (track->isMidiTrack()) // p3.3.50
@@ -3492,14 +3029,14 @@ void Song::insertTrack2(Track* track, int idx)
const RouteList* rl = track->inRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
{
- //printf("Song::insertTrack2 %s in route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
+ //printf("Song::insertTrack2 %s in route port:%d\n", track->name().toLatin1().constData(), r->midiPort);
Route src(track, r->channel);
MusEGlobal::midiPorts[r->midiPort].outRoutes()->push_back(src);
}
rl = track->outRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
{
- //printf("Song::insertTrack2 %s out route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
+ //printf("Song::insertTrack2 %s out route port:%d\n", track->name().toLatin1().constData(), r->midiPort);
Route src(track, r->channel);
MusEGlobal::midiPorts[r->midiPort].inRoutes()->push_back(src);
}
@@ -3515,6 +3052,13 @@ void Song::insertTrack2(Track* track, int idx)
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->outRoutes()->push_back(src);
+ // Is the source an Aux Track or else does it have Aux Tracks routed to it?
+ // Update this track's aux ref count. p4.0.37
+ if(r->track->auxRefCount())
+ track->updateAuxRoute( r->track->auxRefCount(), NULL );
+ else
+ if(r->track->type() == Track::AUDIO_AUX)
+ track->updateAuxRoute( 1, NULL );
}
rl = track->outRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
@@ -3525,6 +3069,13 @@ void Song::insertTrack2(Track* track, int idx)
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->inRoutes()->push_back(src);
+ // Is this track an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the other track's aux ref count and all tracks it is connected to. p4.0.37
+ if(track->auxRefCount())
+ r->track->updateAuxRoute( track->auxRefCount(), NULL );
+ else
+ if(track->type() == Track::AUDIO_AUX)
+ r->track->updateAuxRoute( 1, NULL );
}
}
@@ -3537,18 +3088,9 @@ void Song::insertTrack2(Track* track, int idx)
// non realtime part of insertTrack
//---------------------------------------------------------
+// empty. gets executed after the realtime part
void Song::insertTrack3(Track* /*track*/, int /*idx*/)//prevent compiler warning: unused parameter
{
- //printf("Song::insertTrack3\n");
-
- /*
- switch(track->type()) {
- case Track::AUDIO_SOFTSYNTH:
- break;
- default:
- break;
- }
- */
}
//---------------------------------------------------------
@@ -3596,7 +3138,7 @@ void Song::removeTrack1(Track* track)
SynthI* si = (SynthI*)track;
if(si->hasGui())
si->showGui(false);
- if(si->hasNativeGui()) // p4.0.20
+ if(si->hasNativeGui())
si->showNativeGui(false);
}
break;
@@ -3612,7 +3154,7 @@ void Song::removeTrack1(Track* track)
void Song::removeTrack2(Track* track)
{
- //printf("Song::removeTrack2 track:%s\n", track->name().toLatin1().constData()); // p3.3.50
+ //printf("Song::removeTrack2 track:%s\n", track->name().toLatin1().constData());
switch(track->type()) {
case Track::MIDI:
@@ -3653,38 +3195,6 @@ void Song::removeTrack2(Track* track)
}
_tracks.erase(track);
-
- /*
- if (track->isMidiTrack())
- return;
- //
- // remove routes
- //
-
- AudioTrack* at = (AudioTrack*)track;
- Route src(at, -1);
- if (at->type() == Track::AUDIO_OUTPUT) {
- const RouteList* rl = at->inRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->outRoutes()->removeRoute(src);
- }
- else if (at->type() == Track::AUDIO_INPUT) {
- const RouteList* rl = at->outRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->inRoutes()->removeRoute(src);
- }
- else {
- const RouteList* rl = at->inRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->outRoutes()->removeRoute(src);
- rl = at->outRoutes();
- for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- r->track->inRoutes()->removeRoute(src);
- }
- */
-
- // p3.3.38
-
//
// remove routes
//
@@ -3696,11 +3206,18 @@ void Song::removeTrack2(Track* track)
{
//if(r->track == track)
// r->track->outRoutes()->removeRoute(*r);
- //printf("Song::removeTrack2 %s audio out track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData()); // p3.3.50
+ //printf("Song::removeTrack2 %s audio out track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData());
// p3.3.50
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->outRoutes()->removeRoute(src);
+ // Is the source an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the Audio Output track's aux ref count. p4.0.37
+ if(r->track->auxRefCount())
+ track->updateAuxRoute( -r->track->auxRefCount(), NULL );
+ else
+ if(r->track->type() == Track::AUDIO_AUX)
+ track->updateAuxRoute( -1, NULL );
}
}
else if (track->type() == Track::AUDIO_INPUT)
@@ -3710,11 +3227,18 @@ void Song::removeTrack2(Track* track)
{
//if(r->track == track)
// r->track->inRoutes()->removeRoute(*r);
- //printf("Song::removeTrack2 %s audio in track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData()); // p3.3.50
+ //printf("Song::removeTrack2 %s audio in track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData());
// p3.3.50
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->inRoutes()->removeRoute(src);
+ // Is this track an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the other track's aux ref count and all tracks it is connected to. p4.0.37
+ if(track->auxRefCount())
+ r->track->updateAuxRoute( -track->auxRefCount(), NULL );
+ else
+ if(track->type() == Track::AUDIO_AUX)
+ r->track->updateAuxRoute( -1, NULL );
}
}
else if (track->isMidiTrack()) // p3.3.50
@@ -3722,14 +3246,14 @@ void Song::removeTrack2(Track* track)
const RouteList* rl = track->inRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
{
- //printf("Song::removeTrack2 %s in route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
+ //printf("Song::removeTrack2 %s in route port:%d\n", track->name().toLatin1().constData(), r->midiPort);
Route src(track, r->channel);
MusEGlobal::midiPorts[r->midiPort].outRoutes()->removeRoute(src);
}
rl = track->outRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
{
- //printf("Song::removeTrack2 %s out route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
+ //printf("Song::removeTrack2 %s out route port:%d\n", track->name().toLatin1().constData(), r->midiPort);
Route src(track, r->channel);
MusEGlobal::midiPorts[r->midiPort].inRoutes()->removeRoute(src);
}
@@ -3741,22 +3265,36 @@ void Song::removeTrack2(Track* track)
{
//if(r->track == track)
// r->track->outRoutes()->removeRoute(*r);
- //printf("Song::removeTrack2 %s in route track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData()); // p3.3.50
+ //printf("Song::removeTrack2 %s in route track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData());
// p3.3.50
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->outRoutes()->removeRoute(src);
+ // Is the source an Aux Track or else does it have Aux Tracks routed to it?
+ // Update this track's aux ref count. p4.0.37
+ if(r->track->auxRefCount())
+ track->updateAuxRoute( -r->track->auxRefCount(), NULL );
+ else
+ if(r->track->type() == Track::AUDIO_AUX)
+ track->updateAuxRoute( -1, NULL );
}
rl = track->outRoutes();
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
{
//if(r->track == track)
// r->track->inRoutes()->removeRoute(*r);
- //printf("Song::removeTrack2 %s out route track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData()); // p3.3.50
+ //printf("Song::removeTrack2 %s out route track:%s\n", track->name().toLatin1().constData(), r->track->name().toLatin1().constData());
// p3.3.50
Route src(track, r->channel, r->channels);
src.remoteChannel = r->remoteChannel;
r->track->inRoutes()->removeRoute(src);
+ // Is this track an Aux Track or else does it have Aux Tracks routed to it?
+ // Update the other track's aux ref count and all tracks it is connected to. p4.0.37
+ if(track->auxRefCount())
+ r->track->updateAuxRoute( -track->auxRefCount(), NULL );
+ else
+ if(track->type() == Track::AUDIO_AUX)
+ r->track->updateAuxRoute( -1, NULL );
}
}
@@ -3767,21 +3305,10 @@ void Song::removeTrack2(Track* track)
// non realtime part of removeTrack
//---------------------------------------------------------
+//empty. gets executed after the realtime part
void Song::removeTrack3(Track* /*track*/)//prevent of compiler warning: unused parameter
- {
- /*
- switch(track->type()) {
- case Track::AUDIO_SOFTSYNTH:
- {
- SynthI* s = (SynthI*) track;
- s->deactivate3();
- }
- break;
- default:
- break;
- }
- */
- }
+{
+}
//---------------------------------------------------------
// executeScript
diff --git a/muse2/muse/song.h b/muse2/muse/song.h
index d6d3628c..047dbac3 100644
--- a/muse2/muse/song.h
+++ b/muse2/muse/song.h
@@ -37,6 +37,7 @@
#include "al/sig.h"
#include "undo.h"
#include "track.h"
+#include "synth.h"
class QAction;
class QFont;
@@ -362,7 +363,7 @@ class Song : public QObject {
// Configuration
//-----------------------------------------
- SynthI* createSynthI(const QString& sclass, const QString& label = QString(), Track* insertAt = 0);
+ SynthI* createSynthI(const QString& sclass, const QString& label = QString(), Synth::Type type = Synth::SYNTH_TYPE_END, Track* insertAt = 0);
void rescanAlsaPorts();
@@ -412,7 +413,7 @@ class Song : public QObject {
void setQuantize(bool val);
void panic();
void seqSignal(int fd);
- Track* addTrack(Track::TrackType type, Track* insertAt = 0);
+ Track* addTrack(Undo& operations, Track::TrackType type, Track* insertAt = 0);
Track* addNewTrack(QAction* action, Track* insertAt = 0);
QString getScriptPath(int id, bool delivered);
void populateScriptMenu(QMenu* menuPlugins, QObject* receiver);
diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp
index b5c3382d..5726345e 100644
--- a/muse2/muse/songfile.cpp
+++ b/muse2/muse/songfile.cpp
@@ -21,7 +21,6 @@
//
//=========================================================
-#include <assert.h>
#include <uuid/uuid.h>
#include <QProgressDialog>
#include <QMessageBox>
@@ -29,6 +28,7 @@
#include "app.h"
#include "song.h"
#include "arranger.h"
+#include "arrangerview.h"
//#include "arranger/arranger.h" // p4.0.2
#include "cobject.h"
#include "drumedit.h"
@@ -1302,10 +1302,10 @@ void MusE::readToplevels(MusECore::Xml& xml)
}
else if (tag == "scoreedit") {
MusEGui::ScoreEdit* score = new MusEGui::ScoreEdit(this, 0, _arranger->cursorValue());
- score->show();
toplevels.push_back(score);
- connect(score, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
- connect(score, SIGNAL(name_changed()), SLOT(scoreNamingChanged()));
+ connect(score, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
+ connect(score, SIGNAL(name_changed()), arrangerView, SLOT(scoreNamingChanged()));
+ score->show();
score->readStatus(xml);
}
else if (tag == "drumedit") {
@@ -1334,13 +1334,19 @@ void MusE::readToplevels(MusECore::Xml& xml)
}
else if (tag == "marker") {
showMarker(true);
- if (toplevels.back()->type()==MusEGui::TopWin::MARKER)
- toplevels.back()->readStatus(xml);
+ TopWin* tw = toplevels.findType(TopWin::MARKER);
+ if(!tw)
+ xml.skip("marker");
+ else
+ tw->readStatus(xml);
}
else if (tag == "arrangerview") {
showArranger(true);
- if (toplevels.back()->type()==MusEGui::TopWin::ARRANGER)
- toplevels.back()->readStatus(xml);
+ TopWin* tw = toplevels.findType(TopWin::ARRANGER);
+ if(!tw)
+ xml.skip("arrangerview");
+ else
+ tw->readStatus(xml);
}
else if (tag == "waveedit") {
if(!pl->empty())
@@ -1352,8 +1358,11 @@ void MusE::readToplevels(MusECore::Xml& xml)
}
else if (tag == "cliplist") {
startClipList(true);
- if (toplevels.back()->type()==MusEGui::TopWin::CLIPLIST)
- toplevels.back()->readStatus(xml);
+ TopWin* tw = toplevels.findType(TopWin::CLIPLIST);
+ if(!tw)
+ xml.skip("cliplist");
+ else
+ tw->readStatus(xml);
}
else
xml.unknown("MusE");
@@ -1515,9 +1524,34 @@ void MusE::read(MusECore::Xml& xml, bool skipConfig, bool isTemplate)
else if (tag == "configuration")
if (skipConfig)
//xml.skip(tag);
- readConfiguration(xml,true /* only read sequencer settings */, false /* do NOT read global settings */);
+ readConfiguration(xml,true /* only read sequencer settings */, false /* do NOT read global settings, see below */);
+ // see even more below!
else
- readConfiguration(xml, false, false /* do NOT read global settings */);
+ readConfiguration(xml, false, false /* do NOT read global settings, see below */);
+ /* Explanation for why "do NOT read global settings":
+ * if you would use true here, then muse would overwrite certain global config stuff
+ * by the settings stored in the song. but you don't want this. imagine that you
+ * send a friend a .med file. your friend opens it and baaam, his configuration is
+ * garbled. why? well, because these readConfigurations here would have overwritten
+ * parts (but not all) of his global config (like MDI/SDI, toolbar states etc.)
+ * with the data stored in the song. (it IS stored there. dunny why, i find it pretty
+ * senseless.)
+ *
+ * If you've a problem which seems to be solved by replacing "false" with "true", i've
+ * a better solution for you: go into conf.cpp, in void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig)
+ * (around line 525), look for a comment like this:
+ * "Global and/or per-song config stuff ends here" (alternatively just search for
+ * "----"). Your problem is probably that some non-global setting should be loaded but
+ * is not. Fix it by either placing the else if (foo)... clause responsible for that
+ * setting to be loaded into the first part, that is, before "else if (!doReadGlobalConfig)"
+ * or (if the settings actually IS global and not per-song), ensure that the routine
+ * which writes the global (and not the song-)configuration really writes that setting.
+ * (it might happen that it formerly worked because it was written to the song instead
+ * of the global config by mistake, and now isn't loaded anymore. write it to the
+ * correct location.)
+ *
+ * -- flo93
+ */
else if (tag == "song")
{
MusEGlobal::song->read(xml, isTemplate);
diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp
index 90d02908..70b19540 100644
--- a/muse2/muse/structure.cpp
+++ b/muse2/muse/structure.cpp
@@ -137,7 +137,7 @@ void adjustGlobalLists(Undo& operations, int startPos, int diff)
// - cut master track
//---------------------------------------------------------
-void globalCut()
+void globalCut(bool onlySelectedTracks)
{
int lpos = MusEGlobal::song->lpos();
int rpos = MusEGlobal::song->rpos();
@@ -146,17 +146,11 @@ void globalCut()
Undo operations;
TrackList* tracks = MusEGlobal::song->tracks();
- bool at_least_one_selected=false;
-
- for (iTrack it = tracks->begin(); it != tracks->end(); ++it)
- if ( (*it)->selected() ) {
- at_least_one_selected=true;
- break;
- }
for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
- MidiTrack* track = dynamic_cast<MidiTrack*>(*it);
- if (track == 0 || (at_least_one_selected && !track->selected()))
+ //MidiTrack* track = dynamic_cast<MidiTrack*>(*it);
+ Track* track = *it;
+ if (track == 0 || (onlySelectedTracks && !track->selected()))
continue;
PartList* pl = track->parts();
for (iPart p = pl->begin(); p != pl->end(); ++p) {
@@ -169,63 +163,61 @@ void globalCut()
operations.push_back(UndoOp(UndoOp::DeletePart,part));
}
else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) {
- // remove part tail
- int len = lpos - t;
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- nPart->setLenTick(len);
- //
- // cut Events in nPart
- EventList* el = nPart->events();
- for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie)
- operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, nPart, false, false));
-
- operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true));
- }
+ // remove part tail
+ int len = lpos - t;
+ Part *nPart;
+ if (track->isMidiTrack())
+ nPart = new MidiPart(*(MidiPart*)part);
+ else
+ nPart = new WavePart(*(WavePart*)part);
+
+ nPart->setLenTick(len);
+ //
+ // cut Events in nPart
+ EventList* el = nPart->events();
+ for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie)
+ operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, nPart, false, false));
+
+ operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true));
+ }
else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) {
//----------------------
// remove part middle
//----------------------
+ Part* p1;
+ Part* p2;
+ Part* p3;
+ track->splitPart(part, lpos, p1, p2);
+ delete p2;
+ track->splitPart(part, rpos, p2, p3);
+ delete p2;
+ p3->setTick(lpos);
+ p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/
+ p3->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- EventList* el = nPart->events();
- iEvent is = el->lower_bound(lpos-t);
- iEvent ie = el->lower_bound(rpos-t); //lower bound, because we do NOT want to erase the events at rpos-t
- for (iEvent i = is; i != ie; ++i)
- operations.push_back(UndoOp(UndoOp::DeleteEvent,i->second, nPart, false, false));
-
- for (iEvent i = el->lower_bound(rpos-t); i != el->end(); ++i) {
- Event event = i->second;
- Event nEvent = event.clone();
- nEvent.setTick(nEvent.tick() - (rpos-lpos));
- // Indicate no undo, and do not do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyEvent,nEvent, event, nPart, false, false));
- }
- nPart->setLenTick(l - (rpos-lpos));
// Indicate no undo, and do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true));
+ operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, true));
+ operations.push_back(UndoOp(UndoOp::AddPart,p3));
}
else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) {
// remove part head
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- EventList* el = nPart->events();
- iEvent i_end = el->lower_bound(rpos-t); //lower bound, because we do NOT want to erase the events at rpos-t
- for (iEvent it = el->begin(); it!=i_end; it++)
- operations.push_back(UndoOp(UndoOp::DeleteEvent,it->second, nPart, false, false));
-
- for (iEvent it = el->lower_bound(rpos-t); it!=el->end(); it++) {
- Event event = it->second;
- Event nEvent = event.clone();
- nEvent.setTick(nEvent.tick() - (rpos-t));
- // Indicate no undo, and do not do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyEvent,nEvent, event, nPart, false, false));
- }
-
- nPart->setLenTick(l - (rpos-t));
- operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true));
+ Part* p1;
+ Part* p2;
+ track->splitPart(part, rpos, p1, p2);
+ delete p1;
+ p2->setTick(lpos);
+ p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/
+ operations.push_back(UndoOp(UndoOp::ModifyPart,part, p2, true, true));
}
else if (t >= rpos) {
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
+ // move part to the left
+ Part *nPart;
+ if (track->isMidiTrack())
+ nPart = new MidiPart(*(MidiPart*)part);
+ else
+ nPart = new WavePart(*(WavePart*)part);
+ //MidiPart* nPart = new MidiPart(*(MidiPart*)part);
int nt = part->tick();
nPart->setTick(nt - (rpos -lpos));
// Indicate no undo, and do port controller values but not clone parts.
@@ -246,33 +238,24 @@ void globalCut()
// - insert in master track
//---------------------------------------------------------
-void globalInsert()
- {
- Undo operations=movePartsTotheRight(MusEGlobal::song->lpos(), MusEGlobal::song->rpos()-MusEGlobal::song->lpos(), true);
+void globalInsert(bool onlySelectedTracks)
+{
+ Undo operations=movePartsTotheRight(MusEGlobal::song->lpos(), MusEGlobal::song->rpos()-MusEGlobal::song->lpos(), onlySelectedTracks);
MusEGlobal::song->applyOperationGroup(operations);
- }
-
+}
Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selected, set<Track*>* tracklist)
- {
+{
if (moveTicks<=0)
return Undo();
Undo operations;
TrackList* tracks = MusEGlobal::song->tracks();
- bool at_least_one_selected=false;
-
- for (iTrack it = tracks->begin(); it != tracks->end(); ++it)
- if ( (*it)->selected() ) {
- at_least_one_selected=true;
- break;
- }
-
for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
- MidiTrack* track = dynamic_cast<MidiTrack*>(*it);
+ Track* track = *it;
if ( (track == 0) ||
- (only_selected && at_least_one_selected && !track->selected()) ||
+ (only_selected && !track->selected()) ||
(tracklist && tracklist->find(track)==tracklist->end()) )
continue;
PartList* pl = track->parts();
@@ -283,23 +266,23 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec
if (t + l <= startTicks)
continue;
if (startTicks > t && startTicks < (t+l)) {
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- nPart->setLenTick(l + moveTicks);
- EventList* el = nPart->events();
-
- for (riEvent i = el->rbegin(); i!=el->rend(); ++i)
- {
- if (i->first < startTicks-t)
- break;
- Event event = i->second;
- Event nEvent = i->second.clone();
- nEvent.setTick(nEvent.tick() + moveTicks);
- operations.push_back(UndoOp(UndoOp::ModifyEvent, nEvent, event, nPart, false, false));
- }
- operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, true));
+ // split part to insert new space
+ Part* p1;
+ Part* p2;
+ track->splitPart(part, startTicks, p1, p2);
+ p2->setTick(startTicks+moveTicks);
+ p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/
+ p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/
+
+ operations.push_back(UndoOp(UndoOp::ModifyPart, part, p1, true, true));
+ operations.push_back(UndoOp(UndoOp::AddPart, p2));
}
else if (t >= startTicks) {
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
+ Part *nPart;
+ if (track->isMidiTrack())
+ nPart = new MidiPart(*(MidiPart*)part);
+ else
+ nPart = new WavePart(*(WavePart*)part);
nPart->setTick(t + moveTicks);
operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, false));
}
@@ -317,47 +300,50 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec
// - split all parts at the song position pointer
//---------------------------------------------------------
-void globalSplit()
- {
- int pos = MusEGlobal::song->cpos();
- Undo operations;
- TrackList* tracks = MusEGlobal::song->tracks();
- bool at_least_one_selected=false;
-
- for (iTrack it = tracks->begin(); it != tracks->end(); ++it)
- if ( (*it)->selected() ) {
- at_least_one_selected=true;
- break;
- }
-
-
- for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
- Track* track = *it;
- if (track == 0 || (at_least_one_selected && !track->selected()))
- continue;
-
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p) {
- Part* part = p->second;
- int p1 = part->tick();
- int l0 = part->lenTick();
- if (pos > p1 && pos < (p1+l0)) {
- Part* p1;
- Part* p2;
- track->splitPart(part, pos, p1, p2);
+void globalSplit(bool onlySelectedTracks)
+{
+ Undo operations=partSplitter(MusEGlobal::song->cpos(), onlySelectedTracks);
+ MusEGlobal::song->applyOperationGroup(operations);
+}
- p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it
- p2->events()->incARef(-1); // so we must decrement it first :/
+Undo partSplitter(unsigned int pos, bool onlySelectedTracks)
+{
+ Undo operations;
+ TrackList* tracks = MusEGlobal::song->tracks();
+
+ for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
+ Track* track = *it;
+ if (track == 0 || (onlySelectedTracks && !track->selected()))
+ continue;
+
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part* part = p->second;
+ unsigned int p1 = part->tick();
+ unsigned int l0 = part->lenTick();
+ if (pos > p1 && pos < (p1+l0)) {
+ Part* p1;
+ Part* p2;
+ track->splitPart(part, pos, p1, p2);
+
+ p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it
+ p2->events()->incARef(-1); // so we must decrement it first :/
+
+ //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ModifyPart
+ MusEGlobal::song->informAboutNewParts(part, p2);
+ operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, false));
+ operations.push_back(UndoOp(UndoOp::AddPart,p2));
+ if (MusEGlobal::debugMsg)
+ {
+ printf("in partSplitter: part1 %d\n",p1->events()->refCount());
+ printf("in partSplitter: part2 %d\n",p2->events()->refCount());
+ }
+ break;
+ }
+ }
+ }
+ return operations;
+}
- //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ModifyPart
- MusEGlobal::song->informAboutNewParts(part, p2);
- operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, false));
- operations.push_back(UndoOp(UndoOp::AddPart,p2));
- break;
- }
- }
- }
- MusEGlobal::song->applyOperationGroup(operations);
- }
} // namespace MusECore
diff --git a/muse2/muse/structure.h b/muse2/muse/structure.h
index b92c4e14..3a359dc0 100644
--- a/muse2/muse/structure.h
+++ b/muse2/muse/structure.h
@@ -28,10 +28,11 @@
namespace MusECore {
Undo movePartsTotheRight(unsigned int startTick, int moveTick, bool only_selected=false, std::set<Track*>* tracklist=NULL);
+Undo partSplitter(unsigned int tick, bool onlySelectedTracks=false);
void adjustGlobalLists(Undo& operations, int startPos, int diff);
-void globalCut();
-void globalInsert();
-void globalSplit();
+void globalCut(bool onlySelectedTracks=false);
+void globalInsert(bool onlySelectedTracks=false);
+void globalSplit(bool onlySelectedTracks=false);
}
#endif
diff --git a/muse2/muse/synth.cpp b/muse2/muse/synth.cpp
index fd526931..7ab18bda 100644
--- a/muse2/muse/synth.cpp
+++ b/muse2/muse/synth.cpp
@@ -32,6 +32,7 @@
#include <dlfcn.h>
#include <QDir>
+#include <QString>
//#include <QMenu>
#include "app.h"
@@ -60,7 +61,20 @@ std::vector<MusECore::Synth*> synthis; // array of available MusEGlobal::synthi
namespace MusECore {
extern void connectNodes(AudioTrack*, AudioTrack*);
-bool SynthI::_isVisible=true;
+bool SynthI::_isVisible=false;
+
+const char* synthTypes[] = { "METRONOME", "MESS", "DSSI", "VST", "UNKNOWN" };
+QString synthType2String(Synth::Type type) { return QString(synthTypes[type]); }
+
+Synth::Type string2SynthType(const QString& type)
+{
+ for(int i = 0; i < Synth::SYNTH_TYPE_END; ++i)
+ {
+ if(synthType2String((Synth::Type)i) == type)
+ return (Synth::Type)i;
+ }
+ return Synth::SYNTH_TYPE_END;
+}
/*
//---------------------------------------------------------
@@ -145,19 +159,17 @@ void MessSynthIF::setNativeGeometry(int x, int y, int w, int h)
// search for synthesizer base class
//---------------------------------------------------------
-//static Synth* findSynth(const QString& sclass)
-static Synth* findSynth(const QString& sclass, const QString& label)
+static Synth* findSynth(const QString& sclass, const QString& label, Synth::Type type = Synth::SYNTH_TYPE_END)
{
for (std::vector<Synth*>::iterator i = MusEGlobal::synthis.begin();
i != MusEGlobal::synthis.end(); ++i)
{
- //if ((*i)->baseName() == sclass)
- //if ((*i)->name() == sclass)
- if ( ((*i)->baseName() == sclass) && (label.isEmpty() || ((*i)->name() == label)) )
-
- return *i;
+ if( ((*i)->baseName() == sclass) &&
+ (label.isEmpty() || ((*i)->name() == label)) &&
+ (type == Synth::SYNTH_TYPE_END || type == (*i)->synthType()) )
+ return *i;
}
- printf("synthi class:%s label:%s not found\n", sclass.toLatin1().constData(), label.toLatin1().constData());
+ printf("synthi type:%d class:%s label:%s not found\n", type, sclass.toLatin1().constData(), label.toLatin1().constData());
return 0;
}
@@ -166,10 +178,9 @@ static Synth* findSynth(const QString& sclass, const QString& label)
// create a synthesizer instance of class "label"
//---------------------------------------------------------
-static SynthI* createSynthInstance(const QString& sclass, const QString& label)
+static SynthI* createSynthInstance(const QString& sclass, const QString& label, Synth::Type type = Synth::SYNTH_TYPE_END)
{
- //Synth* s = findSynth(sclass);
- Synth* s = findSynth(sclass, label);
+ Synth* s = findSynth(sclass, label, type);
SynthI* si = 0;
if (s) {
si = new SynthI();
@@ -652,13 +663,11 @@ void initMidiSynth()
// If insertAt is valid, inserts before insertAt. Else at the end after all tracks.
//---------------------------------------------------------
-SynthI* Song::createSynthI(const QString& sclass, const QString& label, Track* insertAt)
+SynthI* Song::createSynthI(const QString& sclass, const QString& label, Synth::Type type, Track* insertAt)
{
//printf("Song::createSynthI calling ::createSynthI class:%s\n", sclass.toLatin1().constData());
- //SynthI* si = ::createSynthI(sclass);
- //SynthI* si = ::createSynthI(sclass, label);
- SynthI* si = createSynthInstance(sclass, label);
+ SynthI* si = createSynthInstance(sclass, label, type);
if(!si)
return 0;
//printf("Song::createSynthI created SynthI. Before insertTrack1...\n");
@@ -705,6 +714,9 @@ void SynthI::write(int level, Xml& xml) const
{
xml.tag(level++, "SynthI");
AudioTrack::writeProperties(level, xml);
+ //xml.intTag(level, "synthType", synth()->synthType());
+ xml.strTag(level, "synthType", synthType2String(synth()->synthType()));
+
xml.strTag(level, "class", synth()->baseName());
// To support plugins like dssi-vst where all the baseNames are the same 'dssi-vst' and the label is the name of the dll file.
@@ -823,7 +835,8 @@ void SynthI::read(Xml& xml)
{
QString sclass;
QString label;
-
+ Synth::Type type = Synth::SYNTH_TYPE_END;
+
int port = -1;
bool startgui = false;
bool startngui = false;
@@ -837,7 +850,10 @@ void SynthI::read(Xml& xml)
case Xml::End:
return;
case Xml::TagStart:
- if (tag == "class")
+ if (tag == "synthType")
+ //type = xml.parseInt();
+ type = string2SynthType(xml.parse1());
+ else if (tag == "class")
sclass = xml.parse1();
else if (tag == "label")
label = xml.parse1();
@@ -866,8 +882,15 @@ void SynthI::read(Xml& xml)
break;
case Xml::TagEnd:
if (tag == "SynthI") {
- //Synth* s = findSynth(sclass);
- Synth* s = findSynth(sclass, label);
+
+ // NOTICE: This is a hack to quietly change songs to use the new 'fluid_synth' name instead of 'fluidsynth'.
+ // Recent linker changes required the name change in fluidsynth's cmakelists. Nov 8, 2011 By Tim.
+ if(sclass == QString("fluidsynth") &&
+ (type == Synth::SYNTH_TYPE_END || type == Synth::MESS_SYNTH) &&
+ (label.isEmpty() || label == QString("FluidSynth")) )
+ sclass = QString("fluid_synth");
+
+ Synth* s = findSynth(sclass, label, type);
if (s == 0)
return;
if (initInstance(s, name()))
diff --git a/muse2/muse/synth.h b/muse2/muse/synth.h
index c5b63424..497395c0 100644
--- a/muse2/muse/synth.h
+++ b/muse2/muse/synth.h
@@ -72,6 +72,8 @@ class Synth {
QString _version;
public:
+ enum Type { METRO_SYNTH=0, MESS_SYNTH, DSSI_SYNTH, VST_SYNTH, SYNTH_TYPE_END };
+
//Synth(const QFileInfo& fi);
//Synth(const QFileInfo& fi, QString label);
Synth(const QFileInfo& fi, QString label, QString descr, QString maker, QString ver);
@@ -80,6 +82,7 @@ class Synth {
//virtual const char* description() const { return ""; }
//virtual const char* version() const { return ""; }
+ virtual Type synthType() const = 0;
int instances() const { return _instances; }
virtual void incInstances(int val) { _instances += val; }
QString completeBaseName() /*const*/ { return info.completeBaseName(); } // ddskrjo
@@ -117,6 +120,8 @@ class MessSynth : public Synth {
//virtual const char* description() const;
//virtual const char* version() const;
+ virtual Type synthType() const { return MESS_SYNTH; }
+
//virtual void* instantiate();
virtual void* instantiate(const QString&);
@@ -363,6 +368,9 @@ class MessSynthIF : public SynthIF {
virtual int getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max, int* initval);
};
+extern QString synthType2String(Synth::Type);
+extern Synth::Type string2SynthType(const QString&);
+
} // namespace MusECore
namespace MusEGlobal {
diff --git a/muse2/muse/ticksynth.cpp b/muse2/muse/ticksynth.cpp
index 1edc0b12..6d3721ea 100644
--- a/muse2/muse/ticksynth.cpp
+++ b/muse2/muse/ticksynth.cpp
@@ -49,6 +49,7 @@ class MetronomeSynth : public Synth {
//MetronomeSynth(const QFileInfo& fi) : Synth(fi, QString("Metronome")) {}
MetronomeSynth(const QFileInfo& fi) : Synth(fi, QString("Metronome"), QString("Metronome"), QString(), QString()) {}
virtual ~MetronomeSynth() {}
+ virtual Type synthType() const { return METRO_SYNTH; }
virtual void incInstances(int) {}
virtual void* instantiate();
diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp
index 4140732d..07a2dff0 100644
--- a/muse2/muse/track.cpp
+++ b/muse2/muse/track.cpp
@@ -4,6 +4,7 @@
// $Id: track.cpp,v 1.34.2.11 2009/11/30 05:05:49 terminator356 Exp $
//
// (C) Copyright 2000-2004 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -37,10 +38,12 @@
namespace MusECore {
//bool Track::_isVisible=true;
-unsigned int Track::_soloRefCnt = 0;
+unsigned int Track::_soloRefCnt = 0;
Track* Track::_tmpSoloChainTrack = 0;
bool Track::_tmpSoloChainDoIns = false;
bool Track::_tmpSoloChainNoDec = false;
+//bool Track::_tmpIsAuxProcessing = false;
+//int Track::_tmpIsAuxProcRefCount = 0;
const char* Track::_cname[] = {
"Midi", "Drum", "NewStyleDrum", "Wave",
@@ -145,6 +148,34 @@ void removePortCtrlEvents(MidiTrack* t)
}
}
+//---------------------------------------------------------
+// isVisible
+//---------------------------------------------------------
+bool Track::isVisible()
+{
+ switch (type())
+ {
+ case Track::AUDIO_AUX:
+ return AudioAux::visible();
+ break;
+ case Track::AUDIO_GROUP:
+ return AudioGroup::visible();
+ case Track::AUDIO_INPUT:
+ return AudioInput::visible();
+ case Track::AUDIO_OUTPUT:
+ return AudioOutput::visible();
+ case Track::WAVE:
+ return WaveTrack::visible();
+ case Track::MIDI:
+ return MidiTrack::visible();
+ case Track::AUDIO_SOFTSYNTH:
+ return AudioAux::visible();
+ default:
+ break;
+ }
+
+ return false;
+}
//---------------------------------------------------------
@@ -172,6 +203,8 @@ int Track::y() const
void Track::init()
{
+ _auxRouteCount = 0;
+ _nodeTraversed = false;
_activity = 0;
_lastActivity = 0;
_recordFlag = false;
@@ -206,6 +239,8 @@ Track::Track(Track::TrackType t)
//Track::Track(const Track& t)
Track::Track(const Track& t, bool cloneParts)
{
+ _auxRouteCount = t._auxRouteCount;
+ _nodeTraversed = t._nodeTraversed;
_activity = t._activity;
_lastActivity = t._lastActivity;
_recordFlag = t._recordFlag;
@@ -271,6 +306,8 @@ Track::~Track()
Track& Track::operator=(const Track& t)
{
+ _auxRouteCount = t._auxRouteCount;
+ _nodeTraversed = t._nodeTraversed;
_activity = t._activity;
_lastActivity = t._lastActivity;
_recordFlag = t._recordFlag;
@@ -388,6 +425,107 @@ void Track::dump() const
_name.toLatin1().constData(), _type, _parts.size(), _selected);
}
+//---------------------------------------------------------
+// updateAuxRoute
+// Internal use. Update all the Aux ref counts of tracks dst is connected to.
+// If dst is valid, start traversal from there, not from this track.
+//---------------------------------------------------------
+
+void Track::updateAuxRoute(int refInc, Track* dst)
+{
+ //if(isMidiTrack() || _type == AUDIO_AUX)
+ if(isMidiTrack())
+ return;
+
+ //printf("Track::updateAuxRoute %s _auxRouteCount:%d refInc:%d\n", name().toLatin1().constData(), _auxRouteCount, refInc);
+
+ if(dst)
+ {
+ _nodeTraversed = true;
+ dst->updateAuxRoute(refInc, NULL);
+ _nodeTraversed = false;
+ return;
+ }
+
+ if(_type == AUDIO_AUX)
+ return;
+
+ if(_nodeTraversed)
+ {
+ fprintf(stderr, "Track::updateAuxRoute %s _auxRouteCount:%d refInc:%d :\n", name().toLatin1().constData(), _auxRouteCount, refInc);
+ if(refInc >= 0)
+ fprintf(stderr, " MusE Warning: Please check your routes: Circular path found!\n");
+ else
+ fprintf(stderr, " MusE: Circular path removed.\n");
+ return;
+ }
+
+ _nodeTraversed = true;
+
+ _auxRouteCount += refInc;
+ if(_auxRouteCount < 0)
+ {
+ fprintf(stderr, "Track::updateAuxRoute Ref underflow! %s _auxRouteCount:%d refInc:%d\n", name().toLatin1().constData(), _auxRouteCount, refInc);
+ //_auxRouteCount = 0;
+ }
+
+ for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i)
+ {
+ if( !(*i).isValid() || (*i).type != Route::TRACK_ROUTE )
+ continue;
+ Track* t = (*i).track;
+ //if(t->isMidiTrack())
+ // continue;
+ t->updateAuxRoute(refInc, NULL);
+ }
+
+ _nodeTraversed = false;
+}
+
+//---------------------------------------------------------
+// isCircularRoute
+// If dst is valid, start traversal from there, not from this track.
+// Returns true if circular.
+//---------------------------------------------------------
+
+bool Track::isCircularRoute(Track* dst)
+{
+ //if(isMidiTrack() || _type == AUDIO_AUX)
+ //if(isMidiTrack())
+ // return;
+
+ bool rv = false;
+
+ if(dst)
+ {
+ _nodeTraversed = true;
+ rv = dst->isCircularRoute(NULL);
+ _nodeTraversed = false;
+ //if(rv)
+ // fprintf(stderr, " Circular route %s -> %s\n", name().toLatin1().constData(), dst->name().toLatin1().constData());
+ return rv;
+ }
+
+ if(_nodeTraversed)
+ return true;
+
+ _nodeTraversed = true;
+
+ for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i)
+ {
+ if( !(*i).isValid() || (*i).type != Route::TRACK_ROUTE )
+ continue;
+ Track* t = (*i).track;
+ //if(t->isMidiTrack())
+ // continue;
+ rv = t->isCircularRoute(NULL);
+ if(rv)
+ break;
+ }
+
+ _nodeTraversed = false;
+ return rv;
+}
//---------------------------------------------------------
// MidiTrack
@@ -468,7 +606,6 @@ void MidiTrack::init()
{
_outPort = 0;
_outChannel = (type()==NEW_DRUM) ? 9 : 0;
- // Changed by Tim. p3.3.8
//_inPortMask = 0xffff;
///_inPortMask = 0xffffffff;
@@ -569,7 +706,7 @@ void MidiTrack::setOutPortAndChannelAndUpdate(int port, int ch)
//---------------------------------------------------------
// setInPortAndChannelMask
// For old song files with port mask (max 32 ports) and channel mask (16 channels),
-// before midi routing was added (the iR button). p3.3.48
+// before midi routing was added (the iR button).
//---------------------------------------------------------
void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask)
@@ -582,7 +719,7 @@ void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask)
for(int port = 0; port < 32; ++port) // 32 is the old maximum number of ports.
{
- // p3.3.50 If the port was not used in the song file to begin with, just ignore it.
+ // If the port was not used in the song file to begin with, just ignore it.
// This saves from having all of the first 32 ports' channels connected.
if(!MusEGlobal::midiPorts[port].foundInSongFile())
continue;
@@ -590,34 +727,18 @@ void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask)
//if(!(portmask & (1 << port)))
// continue;
- // p3.3.50 Removed. Allow to connect to port with no device so user can change device later.
+ // Removed. Allow to connect to port with no device so user can change device later.
//MidiPort* mp = &MusEGlobal::midiPorts[port];
//MidiDevice* md = mp->device();
//if(!md)
// continue;
- //for(int ch = 0; ch < MIDI_CHANNELS; ++ch) // p3.3.50 Removed.
- //{
- //if(!(chanmask & (1 << ch)))
- // continue;
-
- //Route aRoute(md, ch);
- //Route bRoute(this, ch);
- Route aRoute(port, chanmask); // p3.3.50
+ Route aRoute(port, chanmask);
Route bRoute(this, chanmask);
- // p3.3.50 Removed.
- //iRoute iir = rl->begin();
- //for(; iir != rl->end(); ++iir)
- //{
- //if(*iir == aRoute)
- // if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == port) // p3.3.50
- // break;
- //}
-
// Route wanted?
//if((portmask & (1 << port)) && (chanmask & (1 << ch)))
- if(portmask & (1 << port)) // p3.3.50
+ if(portmask & (1 << port))
{
// Route already exists?
//if(iir != rl->end())
@@ -923,11 +1044,11 @@ void MidiTrack::read(Xml& xml)
//setInPortMask(xml.parseInt());
///setInPortMask(xml.parseUInt());
//xml.skip(tag); // Obsolete.
- portmask = xml.parseUInt(); // p3.3.48: Support old files.
+ portmask = xml.parseUInt(); // Support old files.
else if (tag == "inchannelMap")
///setInChannelMask(xml.parseInt());
//xml.skip(tag); // Obsolete.
- chanmask = xml.parseInt(); // p3.3.48: Support old files.
+ chanmask = xml.parseInt(); // Support old files.
else if (tag == "locked")
_locked = xml.parseInt();
else if (tag == "echo")
@@ -950,7 +1071,7 @@ void MidiTrack::read(Xml& xml)
case Xml::TagEnd:
if (tag == "miditrack" || tag == "drumtrack" || tag == "newdrumtrack")
{
- setInPortAndChannelMask(portmask, chanmask); // p3.3.48: Support old files.
+ setInPortAndChannelMask(portmask, chanmask); // Support old files.
return;
}
default:
@@ -1184,15 +1305,15 @@ void Track::writeRouting(int level, Xml& xml) const
// Support Midi Port to Audio Input track routes. p4.0.14 Tim.
if(r->type == Route::MIDI_PORT_ROUTE)
{
- s = QT_TRANSLATE_NOOP("@default", "Route");
+ s = "Route";
if(r->channel != -1 && r->channel != 0)
- s += QString(QT_TRANSLATE_NOOP("@default", " channelMask=\"%1\"")).arg(r->channel); // Use new channel mask.
+ s += QString(" channelMask=\"%1\"").arg(r->channel); // Use new channel mask.
xml.tag(level++, s.toLatin1().constData());
xml.tag(level, "source mport=\"%d\"/", r->midiPort);
- s = QT_TRANSLATE_NOOP("@default", "dest");
- s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(name()));
+ s = "dest";
+ s += QString(" name=\"%1\"/").arg(Xml::xmlString(name()));
xml.tag(level, s.toLatin1().constData());
xml.etag(level--, "Route");
@@ -1200,17 +1321,17 @@ void Track::writeRouting(int level, Xml& xml) const
else
if(!r->name().isEmpty())
{
- s = QT_TRANSLATE_NOOP("@default", "Route");
+ s = "Route";
if(r->channel != -1)
- s += QString(QT_TRANSLATE_NOOP("@default", " channel=\"%1\"")).arg(r->channel);
+ s += QString(" channel=\"%1\"").arg(r->channel);
xml.tag(level++, s.toAscii().constData());
- // p3.3.38 New routing scheme.
- s = QT_TRANSLATE_NOOP("@default", "source");
+ // New routing scheme.
+ s = "source";
if(r->type != Route::TRACK_ROUTE)
- s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
- s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
+ s += QString(" type=\"%1\"").arg(r->type);
+ s += QString(" name=\"%1\"/").arg(Xml::xmlString(r->name()));
xml.tag(level, s.toAscii().constData());
xml.tag(level, "dest name=\"%s\"/", Xml::xmlString(name()).toLatin1().constData());
@@ -1228,42 +1349,42 @@ void Track::writeRouting(int level, Xml& xml) const
if(r->type == Route::TRACK_ROUTE && r->track && r->track->type() == Track::AUDIO_INPUT)
continue;
- if(r->midiPort != -1 || !r->name().isEmpty()) // p3.3.49
+ if(r->midiPort != -1 || !r->name().isEmpty())
{
- s = QT_TRANSLATE_NOOP("@default", "Route");
- if(r->type == Route::MIDI_PORT_ROUTE) // p3.3.50
+ s = "Route";
+ if(r->type == Route::MIDI_PORT_ROUTE)
{
if(r->channel != -1 && r->channel != 0)
- s += QString(QT_TRANSLATE_NOOP("@default", " channelMask=\"%1\"")).arg(r->channel); // Use new channel mask.
+ s += QString(" channelMask=\"%1\"").arg(r->channel); // Use new channel mask.
}
else
{
if(r->channel != -1)
- s += QString(QT_TRANSLATE_NOOP("@default", " channel=\"%1\"")).arg(r->channel);
+ s += QString(" channel=\"%1\"").arg(r->channel);
}
if(r->channels != -1)
- s += QString(QT_TRANSLATE_NOOP("@default", " channels=\"%1\"")).arg(r->channels);
+ s += QString(" channels=\"%1\"").arg(r->channels);
if(r->remoteChannel != -1)
- s += QString(QT_TRANSLATE_NOOP("@default", " remch=\"%1\"")).arg(r->remoteChannel);
+ s += QString(" remch=\"%1\"").arg(r->remoteChannel);
xml.tag(level++, s.toAscii().constData());
// Allow for a regular mono or stereo track to feed a multi-channel synti.
xml.tag(level, "source name=\"%s\"/", Xml::xmlString(name()).toLatin1().constData());
- s = QT_TRANSLATE_NOOP("@default", "dest");
+ s = "dest";
- //if(r->type == Route::MIDI_DEVICE_ROUTE) // p3.3.49 Obsolete since 1.1-RC2
+ //if(r->type == Route::MIDI_DEVICE_ROUTE) // Obsolete since 1.1-RC2
// s += QString(QT_TRANSLATE_NOOP("@default", " devtype=\"%1\"")).arg(r->device->deviceType()); //
//if(r->type != Route::TRACK_ROUTE) //
if(r->type != Route::TRACK_ROUTE && r->type != Route::MIDI_PORT_ROUTE)
- s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
+ s += QString(" type=\"%1\"").arg(r->type);
//s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(r->name());
- if(r->type == Route::MIDI_PORT_ROUTE) // p3.3.49
- s += QString(QT_TRANSLATE_NOOP("@default", " mport=\"%1\"/")).arg(r->midiPort);
+ if(r->type == Route::MIDI_PORT_ROUTE)
+ s += QString(" mport=\"%1\"/").arg(r->midiPort);
else
- s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
+ s += QString(" name=\"%1\"/").arg(Xml::xmlString(r->name()));
xml.tag(level, s.toAscii().constData());
diff --git a/muse2/muse/track.h b/muse2/muse/track.h
index bbda67e4..f2e12e3a 100644
--- a/muse2/muse/track.h
+++ b/muse2/muse/track.h
@@ -4,6 +4,7 @@
// $Id: track.h,v 1.39.2.17 2009/12/20 05:00:35 terminator356 Exp $
//
// (C) Copyright 1999-2004 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -71,9 +72,10 @@ class Track {
static bool _tmpSoloChainDoIns;
static bool _tmpSoloChainNoDec;
- // p3.3.38
RouteList _inRoutes;
RouteList _outRoutes;
+ bool _nodeTraversed; // Internal anti circular route traversal flag.
+ int _auxRouteCount; // Number of aux paths feeding this track.
QString _name;
bool _recordFlag;
@@ -90,8 +92,6 @@ class Track {
int _activity;
int _lastActivity;
- //int _meter[MAX_CHANNELS];
- //int _peak[MAX_CHANNELS];
double _meter[MAX_CHANNELS];
double _peak[MAX_CHANNELS];
@@ -148,7 +148,10 @@ class Track {
bool noInRoute() const { return _inRoutes.empty(); }
bool noOutRoute() const { return _outRoutes.empty(); }
void writeRouting(int, Xml&) const;
-
+ bool isCircularRoute(Track* dst);
+ int auxRefCount() const { return _auxRouteCount; } // Number of Aux Tracks with routing paths to this track.
+ void updateAuxRoute(int refInc, Track* dst); // Internal use.
+
PartList* parts() { return &_parts; }
const PartList* cparts() const { return &_parts; }
Part* findPart(unsigned tick);
@@ -169,20 +172,21 @@ class Track {
virtual void setMute(bool val);
virtual void setOff(bool val);
- virtual void updateSoloStates(bool noDec) = 0;
- virtual void updateInternalSoloStates();
- void updateSoloState();
void setInternalSolo(unsigned int val);
- static void clearSoloRefCounts();
virtual void setSolo(bool val) = 0;
virtual bool isMute() const = 0;
-
unsigned int internalSolo() const { return _internalSolo; }
bool soloMode() const { return _soloRefCnt; }
bool solo() const { return _solo; }
bool mute() const { return _mute; }
bool off() const { return _off; }
bool recordFlag() const { return _recordFlag; }
+ //
+ // Internal use...
+ static void clearSoloRefCounts();
+ void updateSoloState();
+ virtual void updateSoloStates(bool noDec) = 0;
+ virtual void updateInternalSoloStates();
int activity() { return _activity; }
void setActivity(int v) { _activity = v; }
@@ -191,8 +195,6 @@ class Track {
void addActivity(int v) { _activity += v; }
void resetPeaks();
static void resetAllMeter();
- //int meter(int ch) const { return _meter[ch]; }
- //int peak(int ch) const { return _peak[ch]; }
double meter(int ch) const { return _meter[ch]; }
double peak(int ch) const { return _peak[ch]; }
void resetMeter();
@@ -207,6 +209,7 @@ class Track {
virtual AutomationType automationType() const = 0;
virtual void setAutomationType(AutomationType t) = 0;
static void setVisible(bool) { }
+ bool isVisible();
};
@@ -221,9 +224,9 @@ class MidiTrack : public Track {
int _outPort;
int _outChannel;
//int _inPortMask;
- ///unsigned int _inPortMask; // bitmask of accepted record ports
- ///int _inChannelMask; // bitmask of accepted record channels
- bool _recEcho; // For midi (and audio). Whether to echo incoming record events to output device.
+ //unsigned int _inPortMask; // bitmask of accepted record ports
+ //int _inChannelMask; // bitmask of accepted record channels
+ bool _recEcho; // For midi (and audio). Whether to echo incoming record events to output device.
EventList* _events; // tmp Events during midi import
MPEventList* _mpevents; // tmp Events druring recording
@@ -284,17 +287,17 @@ class MidiTrack : public Track {
void setOutPortAndChannelAndUpdate(int /*port*/, int /*chan*/);
//void setInPortMask(int i) { _inPortMask = i; }
- ///void setInPortMask(unsigned int i) { _inPortMask = i; } // Obsolete
- ///void setInChannelMask(int i) { _inChannelMask = i; } //
+ //void setInPortMask(unsigned int i) { _inPortMask = i; } // Obsolete
+ //void setInChannelMask(int i) { _inChannelMask = i; } //
// Backward compatibility: For reading old songs.
void setInPortAndChannelMask(unsigned int /*portmask*/, int /*chanmask*/);
void setRecEcho(bool b) { _recEcho = b; }
int outPort() const { return _outPort; }
//int inPortMask() const { return _inPortMask; }
- ///unsigned int inPortMask() const { return _inPortMask; }
+ //unsigned int inPortMask() const { return _inPortMask; }
int outChannel() const { return _outChannel; }
- ///int inChannelMask() const { return _inChannelMask; }
+ //int inChannelMask() const { return _inChannelMask; }
bool recEcho() const { return _recEcho; }
virtual bool isMute() const;
@@ -324,14 +327,10 @@ class MidiTrack : public Track {
void readOurDrumMap(Xml& xml, bool dont_init=false);
};
-} // namespace MusECore
-
-namespace MusECore {
-
//---------------------------------------------------------
// AudioTrack
// this track can hold audio automation data and can
-// hold tracktypes AUDIO, AUDIO_MASTER, AUDIO_GROUP,
+// hold tracktypes WAVE, AUDIO_GROUP, AUDIO_OUTPUT,
// AUDIO_INPUT, AUDIO_SOFTSYNTH, AUDIO_AUX
//---------------------------------------------------------
@@ -339,25 +338,19 @@ class AudioTrack : public Track {
//friend class MidiTrack;
//static unsigned int _soloRefCnt;
- bool _haveData;
+ bool _haveData; // Whether we have data from a previous process call during current cycle.
CtrlListList _controller;
CtrlRecList _recEvents; // recorded automation events
bool _prefader; // prefader metering
std::vector<double> _auxSend;
- Pipeline* _efxPipe;
-
- AutomationType _automationType;
-
- //RouteList _inRoutes;
- //RouteList _outRoutes;
-
- bool _sendMetronome;
-
//void readRecfile(Xml& xml);
void readAuxSend(Xml& xml);
-
+
+ bool _sendMetronome;
+ AutomationType _automationType;
+ Pipeline* _efxPipe;
protected:
float** outBuffers;
@@ -370,7 +363,7 @@ class AudioTrack : public Track {
SndFile* _recFile;
Fifo fifo; // fifo -> _recFile
bool _processed;
-
+
public:
AudioTrack(TrackType t);
//AudioTrack(TrackType t, int num_out_bufs = MAX_CHANNELS);
@@ -450,12 +443,6 @@ class AudioTrack : public Track {
void readVolume(Xml& xml);
//void writeRouting(int, Xml&) const;
- // routing
- //RouteList* inRoutes() { return &_inRoutes; }
- //RouteList* outRoutes() { return &_outRoutes; }
- //bool noInRoute() const { return _inRoutes.empty(); }
- //bool noOutRoute() const { return _outRoutes.empty(); }
-
virtual void preProcessAlways() { _processed = false; }
virtual void addData(unsigned /*samplePos*/, int /*channels*/, int /*srcStartChan*/, int /*srcChannels*/, unsigned /*frames*/, float** /*buffer*/);
virtual void copyData(unsigned /*samplePos*/, int /*channels*/, int /*srcStartChan*/, int /*srcChannels*/, unsigned /*frames*/, float** /*buffer*/);
diff --git a/muse2/muse/transport.cpp b/muse2/muse/transport.cpp
index 60494bc4..e978cb2e 100644
--- a/muse2/muse/transport.cpp
+++ b/muse2/muse/transport.cpp
@@ -45,13 +45,6 @@
namespace MusEGui {
-static const char* recordTransportText = QT_TRANSLATE_NOOP("@default", "Click this button to enable recording");
-static const char* stopTransportText = QT_TRANSLATE_NOOP("@default", "Click this button to stop playback");
-static const char* playTransportText = QT_TRANSLATE_NOOP("@default", "Click this button to start playback");
-static const char* startTransportText = QT_TRANSLATE_NOOP("@default", "Click this button to rewind to start position");
-static const char* frewindTransportText = QT_TRANSLATE_NOOP("@default", "Click this button to rewind");
-static const char* fforwardTransportText = QT_TRANSLATE_NOOP("@default", "Click this button to forward current play position");
-
//---------------------------------------------------------
// toolButton
//---------------------------------------------------------
@@ -401,25 +394,25 @@ Transport::Transport(QWidget* parent, const char* name)
tb->setSpacing(0);
buttons[0] = newButton(startIcon, tr("rewind to start"));
- buttons[0]->setWhatsThis(tr(startTransportText));
+ buttons[0]->setWhatsThis(tr("Click this button to rewind to start position"));
buttons[1] = newButton(frewindIcon, tr("rewind"));
buttons[1]->setAutoRepeat(true);
- buttons[1]->setWhatsThis(tr(frewindTransportText));
+ buttons[1]->setWhatsThis(tr("Click this button to rewind"));
buttons[2] = newButton(fforwardIcon, tr("forward"));
buttons[2]->setAutoRepeat(true);
- buttons[2]->setWhatsThis(tr(fforwardTransportText));
+ buttons[2]->setWhatsThis(tr("Click this button to forward current play position"));
buttons[3] = newButton(stopIcon, tr("stop"), true);
buttons[3]->setChecked(true); // set STOP
- buttons[3]->setWhatsThis(tr(stopTransportText));
+ buttons[3]->setWhatsThis(tr("Click this button to stop playback"));
buttons[4] = newButton(playIcon, tr("play"), true);
- buttons[4]->setWhatsThis(tr(playTransportText));
+ buttons[4]->setWhatsThis(tr("Click this button to start playback"));
buttons[5] = newButton(record_on_Icon, tr("record"), true);
- buttons[5]->setWhatsThis(tr(recordTransportText));
+ buttons[5]->setWhatsThis(tr("Click this button to enable recording"));
for (int i = 0; i < 6; ++i)
{
diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp
index 5bbcfcd8..06c190a2 100644
--- a/muse2/muse/undo.cpp
+++ b/muse2/muse/undo.cpp
@@ -50,8 +50,11 @@ const char* UndoOp::typeName()
"AddTrack", "DeleteTrack", "ModifyTrack",
"AddPart", "DeletePart", "ModifyPart",
"AddEvent", "DeleteEvent", "ModifyEvent",
- "AddTempo", "DeleteTempo", "AddSig", "DeleteSig",
- "SwapTrack", "ModifyClip"
+ "AddTempo", "DeleteTempo",
+ "AddSig", "DeleteSig",
+ "AddKey", "DeleteKey",
+ "SwapTrack", "ModifyClip", "ModifyMarker",
+ "ModifySongLen", "DoNothing"
};
return name[type];
}
@@ -95,6 +98,7 @@ void UndoOp::dump()
case ModifyMarker:
case AddKey:
case DeleteKey:
+ case ModifySongLen:
case DoNothing:
break;
}
@@ -530,6 +534,10 @@ void Song::doUndo2()
MusEGlobal::keymap.addKey(i->a, (key_enum)i->b);
updateFlags |= SC_KEY;
break;
+ case UndoOp::ModifySongLen:
+ _len=i->b;
+ updateFlags = -1; // set all flags
+ break;
case UndoOp::ModifyClip:
case UndoOp::ModifyMarker:
case UndoOp::DoNothing:
@@ -767,6 +775,10 @@ void Song::doRedo2()
MusEGlobal::keymap.delKey(i->a);
updateFlags |= SC_KEY;
break;
+ case UndoOp::ModifySongLen:
+ _len=i->a;
+ updateFlags = -1; // set all flags
+ break;
case UndoOp::ModifyClip:
case UndoOp::ModifyMarker:
case UndoOp::DoNothing:
diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h
index 42a80763..dffa1f55 100644
--- a/muse2/muse/undo.h
+++ b/muse2/muse/undo.h
@@ -54,6 +54,7 @@ struct UndoOp {
SwapTrack,
ModifyClip,
ModifyMarker,
+ ModifySongLen, // a = new len, b = old len
DoNothing
};
UndoType type;
diff --git a/muse2/muse/vst.h b/muse2/muse/vst.h
index b57b598d..b41e7137 100644
--- a/muse2/muse/vst.h
+++ b/muse2/muse/vst.h
@@ -50,6 +50,7 @@ class VstSynth : public Synth {
}
virtual ~VstSynth() {}
+ virtual Type synthType() const { return VST_SYNTH; }
virtual void incInstances(int val);
virtual void* instantiate();
//virtual SynthIF* createSIF() const;
diff --git a/muse2/muse/wave.cpp b/muse2/muse/wave.cpp
index 06759441..f22f6f97 100644
--- a/muse2/muse/wave.cpp
+++ b/muse2/muse/wave.cpp
@@ -105,7 +105,7 @@ SndFile::~SndFile()
bool SndFile::openRead()
{
if (openFlag) {
- printf("SndFile:: alread open\n");
+ printf("SndFile:: already open\n");
return false;
}
QString p = path();
@@ -468,7 +468,7 @@ size_t SndFile::readWithHeap(int srcChannels, float** dst, size_t n, bool overwr
{
float *buffer = new float[n * sfinfo.channels];
int rn = readInternal(srcChannels,dst,n,overwrite, buffer);
- delete buffer;
+ delete[] buffer;
return rn;
}
@@ -588,11 +588,11 @@ size_t SndFile::write(int srcChannels, float** src, size_t n)
else {
printf("SndFile:write channel mismatch %d -> %d\n",
srcChannels, dstChannels);
- delete buffer;
+ delete[] buffer;
return 0;
}
int nbr = sf_writef_float(sf, buffer, n) ;
- delete buffer;
+ delete[] buffer;
return nbr;
}
@@ -1120,6 +1120,22 @@ SndFileR::~SndFileR()
}
}
+void SndFileList::clearDelete()
+{
+ // ~SndFile searches itself on the list (and will find for
+ // sure) and deletes the entry on its own.
+ while (!empty())
+ delete *begin();
+
+ /* this is wrong, because ~SndFile deletes itself from the
+ * list, causing the iterator to be invalidated -> fail.
+ for (SndFileList::iterator i = begin(); i != end(); ++i)
+ delete *i;
+ clear();
+ */
+}
+
+
} // namespace MusECore
namespace MusEGui {
diff --git a/muse2/muse/wave.h b/muse2/muse/wave.h
index 58e0ab87..535df939 100644
--- a/muse2/muse/wave.h
+++ b/muse2/muse/wave.h
@@ -182,11 +182,7 @@ class SndFileR {
class SndFileList : public std::list<SndFile*> {
public:
SndFile* search(const QString& name);
- void clearDelete() {
- for (SndFileList::iterator i = begin(); i != end(); ++i)
- delete *i;
- clear();
- }
+ void clearDelete();
};
typedef SndFileList::iterator iSndFile;
diff --git a/muse2/muse/waveedit/waveedit.cpp b/muse2/muse/waveedit/waveedit.cpp
index 424f0688..1c1115b1 100644
--- a/muse2/muse/waveedit/waveedit.cpp
+++ b/muse2/muse/waveedit/waveedit.cpp
@@ -64,10 +64,12 @@ namespace MusEGui {
void WaveEdit::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("Waveedit/geometry", saveGeometry());
settings.setValue("Waveedit/windowState", saveState());
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -92,23 +94,23 @@ WaveEdit::WaveEdit(MusECore::PartList* pl)
menuGain = menuFunctions->addMenu(tr("&Gain"));
- act = menuGain->addAction(tr("200%"));
+ act = menuGain->addAction("200%");
mapper->setMapping(act, CMD_GAIN_200);
connect(act, SIGNAL(triggered()), mapper, SLOT(map()));
- act = menuGain->addAction(tr("150%"));
+ act = menuGain->addAction("150%");
mapper->setMapping(act, CMD_GAIN_150);
connect(act, SIGNAL(triggered()), mapper, SLOT(map()));
- act = menuGain->addAction(tr("75%"));
+ act = menuGain->addAction("75%");
mapper->setMapping(act, CMD_GAIN_75);
connect(act, SIGNAL(triggered()), mapper, SLOT(map()));
- act = menuGain->addAction(tr("50%"));
+ act = menuGain->addAction("50%");
mapper->setMapping(act, CMD_GAIN_50);
connect(act, SIGNAL(triggered()), mapper, SLOT(map()));
- act = menuGain->addAction(tr("25%"));
+ act = menuGain->addAction("25%");
mapper->setMapping(act, CMD_GAIN_25);
connect(act, SIGNAL(triggered()), mapper, SLOT(map()));
@@ -287,6 +289,7 @@ WaveEdit::WaveEdit(MusECore::PartList* pl)
}
initTopwinState();
+ MusEGlobal::muse->topwinMenuInited(this);
}
void WaveEdit::initShortcuts()
@@ -458,7 +461,9 @@ void WaveEdit::readStatus(MusECore::Xml& xml)
void WaveEdit::songChanged1(int bits)
{
-
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (bits & SC_SOLO)
{
MusECore::WavePart* part = (MusECore::WavePart*)(parts()->begin()->second);
diff --git a/muse2/muse/waveedit/waveedit.h b/muse2/muse/waveedit/waveedit.h
index b40aa93a..85e71a60 100644
--- a/muse2/muse/waveedit/waveedit.h
+++ b/muse2/muse/waveedit/waveedit.h
@@ -94,7 +94,7 @@ class WaveEdit : public MidiEditor {
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
WaveEdit(MusECore::PartList*);
diff --git a/muse2/muse/wavetrack.cpp b/muse2/muse/wavetrack.cpp
index 9edeffb6..0d699cbe 100644
--- a/muse2/muse/wavetrack.cpp
+++ b/muse2/muse/wavetrack.cpp
@@ -229,8 +229,8 @@ bool WaveTrack::getData(unsigned framePos, int channels, unsigned nframe, float*
ciRoute i = irl->begin();
if(i->track->isMidiTrack())
{
- if(MusEGlobal::debugMsg)
- printf("WaveTrack::getData: Error: First route is a midi track route!\n");
+ //if(MusEGlobal::debugMsg)
+ // printf("WaveTrack::getData: Error: First route is a midi track route!\n");
return false;
}
// p3.3.38
@@ -246,8 +246,8 @@ bool WaveTrack::getData(unsigned framePos, int channels, unsigned nframe, float*
{
if(i->track->isMidiTrack())
{
- if(MusEGlobal::debugMsg)
- printf("WaveTrack::getData: Error: Route is a midi track route!\n");
+ //if(MusEGlobal::debugMsg)
+ // printf("WaveTrack::getData: Error: Route is a midi track route!\n");
//return false;
continue;
}
diff --git a/muse2/muse/widgets/citem.h b/muse2/muse/widgets/citem.h
index 1777eb23..199d18b0 100644
--- a/muse2/muse/widgets/citem.h
+++ b/muse2/muse/widgets/citem.h
@@ -90,7 +90,7 @@ class CItem {
};
typedef std::multimap<int, CItem*, std::less<int> >::iterator iCItem;
-//typedef std::multimap<int, CItem*, std::less<int> >::const_iterator ciCItem;
+typedef std::multimap<int, CItem*, std::less<int> >::const_iterator ciCItem;
typedef std::multimap<int, CItem*, std::less<int> >::const_reverse_iterator rciCItem;
//---------------------------------------------------------
diff --git a/muse2/muse/widgets/comboQuant.cpp b/muse2/muse/widgets/comboQuant.cpp
index aee7ad5c..6d8dc30c 100644
--- a/muse2/muse/widgets/comboQuant.cpp
+++ b/muse2/muse/widgets/comboQuant.cpp
@@ -37,9 +37,9 @@ static int quantTable[] = {
};
static const char* quantStrings[] = {
- QT_TRANSLATE_NOOP("@default", "Off"), "64T", "32T", "16T", "8T", "4T", "2T", "1T",
- QT_TRANSLATE_NOOP("@default", "Off"), "64", "32", "16", "8", "4", "2", "1",
- QT_TRANSLATE_NOOP("@default", "Off"), "64.", "32.", "16.", "8.", "4.", "2.", "1."
+ QT_TRANSLATE_NOOP("MusEGui::ComboQuant", "Off"), "64T", "32T", "16T", "8T", "4T", "2T", "1T",
+ QT_TRANSLATE_NOOP("MusEGui::ComboQuant", "Off"), "64", "32", "16", "8", "4", "2", "1",
+ QT_TRANSLATE_NOOP("MusEGui::ComboQuant", "Off"), "64.", "32.", "16.", "8.", "4.", "2.", "1."
};
//---------------------------------------------------------
diff --git a/muse2/muse/widgets/configmidifilebase.ui b/muse2/muse/widgets/configmidifilebase.ui
index c050450c..3eb7063e 100644
--- a/muse2/muse/widgets/configmidifilebase.ui
+++ b/muse2/muse/widgets/configmidifilebase.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>548</width>
- <height>346</height>
+ <width>546</width>
+ <height>367</height>
</rect>
</property>
<property name="windowTitle">
@@ -28,8 +28,8 @@
<property name="title">
<string>Import:</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
<widget class="QCheckBox" name="splitPartsCheckBox">
<property name="toolTip">
<string>Split tracks into parts, or one single part</string>
@@ -42,7 +42,7 @@
</property>
</widget>
</item>
- <item>
+ <item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QRadioButton" name="newDrumsCheckbox">
@@ -78,10 +78,10 @@
<string>Export:</string>
</property>
<layout class="QGridLayout">
- <item row="2" column="1">
+ <item row="3" column="1">
<widget class="QLineEdit" name="copyrightEdit"/>
</item>
- <item row="1" column="1">
+ <item row="2" column="1">
<widget class="QComboBox" name="divisionCombo">
<item>
<property name="text">
@@ -100,7 +100,7 @@
</item>
</widget>
</item>
- <item row="3" column="0" colspan="2">
+ <item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="extendedFormat">
<property name="enabled">
<bool>true</bool>
@@ -110,7 +110,7 @@
</property>
</widget>
</item>
- <item row="4" column="0" colspan="2">
+ <item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="twoByteTimeSigs">
<property name="text">
<string>Use &amp;2-byte time signatures instead of standard 4</string>
@@ -120,7 +120,7 @@
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="3" column="0">
<widget class="QLabel" name="textLabel2">
<property name="text">
<string>Copyright:</string>
@@ -140,7 +140,23 @@
</property>
</widget>
</item>
- <item row="1" column="0">
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="textLabel4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Note: Format 0 uses the FIRST midi track's name/comment in the arranger</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
<widget class="QLabel" name="textLabel1">
<property name="text">
<string>Division:</string>
@@ -150,7 +166,7 @@
</property>
</widget>
</item>
- <item row="5" column="0" colspan="2">
+ <item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="optNoteOffs">
<property name="text">
<string>Save space by replacing note-offs with &amp;zero velocity note-ons</string>
diff --git a/muse2/muse/widgets/filedialog.cpp b/muse2/muse/widgets/filedialog.cpp
index df391b45..7f2c1681 100644
--- a/muse2/muse/widgets/filedialog.cpp
+++ b/muse2/muse/widgets/filedialog.cpp
@@ -33,6 +33,7 @@
#include "filedialog.h"
#include "../globals.h"
#include "gconfig.h"
+#include "helper.h"
namespace MusEGui {
@@ -122,11 +123,13 @@ void MFileDialog::userToggled(bool flag)
if (lastUserDir.isEmpty()) {
- lastUserDir = MusEGlobal::museUser + QString("/") + baseDir; // Initialize if first time
+ //lastUserDir = MusEGlobal::museUser + QString("/") + baseDir; // Initialize if first time
+ lastUserDir = MusEGlobal::configPath + QString("/") + baseDir; // Initialize if first time // p4.0.39
}
if (testDirCreate(this, lastUserDir))
- setDirectory(MusEGlobal::museUser);
+ //setDirectory(MusEGlobal::museUser);
+ setDirectory(MusEGlobal::configPath); // p4.0.39
else
setDirectory(lastUserDir);
@@ -269,40 +272,14 @@ void MFileDialog::directoryChanged(const QString&)
}
}
-
-//---------------------------------------------------------
-// getFilterExtension
-//---------------------------------------------------------
-
-QString getFilterExtension(const QString &filter)
-{
- //
- // Return the first extension found. Must contain at least one * character.
- //
-
- int pos = filter.indexOf('*');
- if(pos == -1)
- return QString();
-
- QString filt;
- int len = filter.length();
- ++pos;
- for( ; pos < len; ++pos)
- {
- QChar c = filter[pos];
- if((c == ')') || (c == ';') || (c == ',') || (c == ' '))
- break;
- filt += filter[pos];
- }
- return filt;
-}
-
//---------------------------------------------------------
// getOpenFileName
//---------------------------------------------------------
-QString getOpenFileName(const QString &startWith,
- const QStringList& filters, QWidget* parent, const QString& name, bool* all, MFileDialog::ViewType viewType)
+QString getOpenFileName(const QString &startWith, const char** filters_chararray,
+ QWidget* parent, const QString& name, bool* all, MFileDialog::ViewType viewType)
{
+ QStringList filters = localizedStringListFromCharArray(filters_chararray, "file_patterns");
+
QString initialSelection; // FIXME Tim.
MFileDialog *dlg = new MFileDialog(startWith, QString::null, parent, false);
dlg->setNameFilters(filters);
@@ -339,9 +316,10 @@ QString getOpenFileName(const QString &startWith,
//---------------------------------------------------------
QString getSaveFileName(const QString &startWith,
- //const char** filters, QWidget* parent, const QString& name)
- const QStringList& filters, QWidget* parent, const QString& name)
+ const char** filters_chararray, QWidget* parent, const QString& name)
{
+ QStringList filters = localizedStringListFromCharArray(filters_chararray, "file_patterns");
+
MFileDialog *dlg = new MFileDialog(startWith, QString::null, parent, true);
dlg->setNameFilters(filters);
dlg->setWindowTitle(name);
@@ -404,9 +382,9 @@ QString getSaveFileName(const QString &startWith,
//---------------------------------------------------------
QString getImageFileName(const QString& startWith,
- //const char** filters, QWidget* parent, const QString& name)
- const QStringList& filters, QWidget* parent, const QString& name)
+ const char** filters_chararray, QWidget* parent, const QString& name)
{
+ QStringList filters = localizedStringListFromCharArray(filters_chararray, "file_patterns");
QString initialSelection;
QString* workingDirectory = new QString(QDir::currentPath());
if (!startWith.isEmpty() ) {
@@ -505,10 +483,12 @@ FILE* fileOpen(QWidget* parent, QString name, const QString& ext,
FILE* fp = 0;
if (popenFlag) {
if (strcmp(mode, "r") == 0)
- zip += QString(" -d < ");
+ //zip += QString(" -d < ");
+ zip += QString(" -d < \""); // p4.0.40
else
- zip += QString(" > ");
- zip += name;
+ zip += QString(" > \"");
+ //zip += name;
+ zip = zip + name + QString("\""); // p4.0.40
fp = popen(zip.toAscii().data(), mode);
}
else {
@@ -547,15 +527,14 @@ MFile::~MFile()
// open
//---------------------------------------------------------
-//FILE* MFile::open(const char* mode, const char** pattern,
-FILE* MFile::open(const char* mode, const QStringList& pattern,
+FILE* MFile::open(const char* mode, const char** patterns_chararray,
QWidget* parent, bool noError, bool warnIfOverwrite, const QString& caption)
{
QString name;
if (strcmp(mode, "r") == 0)
- name = getOpenFileName(path, pattern, parent, caption, 0);
+ name = getOpenFileName(path, patterns_chararray, parent, caption, 0);
else
- name = getSaveFileName(path, pattern, parent, caption);
+ name = getSaveFileName(path, patterns_chararray, parent, caption);
if (name.isEmpty())
return 0;
f = fileOpen(parent, name, ext, mode, isPopen, noError,
diff --git a/muse2/muse/widgets/filedialog.h b/muse2/muse/widgets/filedialog.h
index e5687494..b4e21e2c 100644
--- a/muse2/muse/widgets/filedialog.h
+++ b/muse2/muse/widgets/filedialog.h
@@ -3,6 +3,7 @@
// Linux Music Editor
// $Id: filedialog.h,v 1.2.2.2 2008/01/19 13:33:46 wschweer Exp $
// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -24,8 +25,6 @@
#include "ui_fdialogbuttons.h"
-class QStringList;
-
namespace MusEGui {
//---------------------------------------------------------
@@ -91,14 +90,11 @@ class ContentsPreview : public QWidget, public Q3FilePreview {
};
*/
-//QString getSaveFileName(const QString& startWidth, const char** filter,
-QString getSaveFileName(const QString& startWidth, const QStringList& filters,
+QString getSaveFileName(const QString& startWidth, const char** filters,
QWidget* parent, const QString& name);
-//QString getOpenFileName(const QString& startWidth, const char** filter,
-QString getOpenFileName(const QString& startWidth, const QStringList& filters,
+QString getOpenFileName(const QString& startWidth, const char** filters,
QWidget* parent, const QString& name, bool* openAll, MFileDialog::ViewType viewType = MFileDialog::PROJECT_VIEW);
-//QString getImageFileName(const QString& startWith, const char** filters,
-QString getImageFileName(const QString& startWith, const QStringList& filters,
+QString getImageFileName(const QString& startWith, const char** filters,
QWidget* parent, const QString& name);
FILE* fileOpen(QWidget*, QString, const QString&,
@@ -119,8 +115,7 @@ class MFile {
public:
MFile(const QString& path, const QString& ext);
~MFile();
- //FILE* open(const char* mode, const char** pattern,
- FILE* open(const char* mode, const QStringList& pattern,
+ FILE* open(const char* mode, const char** patterns,
QWidget* parent, bool noError,
bool warnIfOverwrite, const QString& caption);
};
diff --git a/muse2/muse/widgets/function_dialogs/quantbase.ui b/muse2/muse/widgets/function_dialogs/quantbase.ui
index 973be7b8..31173e46 100644
--- a/muse2/muse/widgets/function_dialogs/quantbase.ui
+++ b/muse2/muse/widgets/function_dialogs/quantbase.ui
@@ -157,7 +157,7 @@
<bool>false</bool>
</property>
<property name="currentIndex">
- <number>3</number>
+ <number>0</number>
</property>
<property name="frame">
<bool>true</bool>
@@ -174,7 +174,12 @@
</item>
<item>
<property name="text">
- <string>Quarter</string>
+ <string>4th</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>4th Triplet</string>
</property>
</item>
<item>
@@ -184,14 +189,29 @@
</item>
<item>
<property name="text">
+ <string>8th Triplet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
<string>16th</string>
</property>
</item>
<item>
<property name="text">
+ <string>16th Triplet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
<string>32th</string>
</property>
</item>
+ <item>
+ <property name="text">
+ <string>32th Triplet</string>
+ </property>
+ </item>
</widget>
</item>
<item row="3" column="0">
diff --git a/muse2/muse/widgets/function_dialogs/quantize.cpp b/muse2/muse/widgets/function_dialogs/quantize.cpp
index df7c0298..7233c2b8 100644
--- a/muse2/muse/widgets/function_dialogs/quantize.cpp
+++ b/muse2/muse/widgets/function_dialogs/quantize.cpp
@@ -26,6 +26,20 @@
namespace MusEGui {
+int rasterVals[] = {
+ 1, // Whole note divisor
+ 2, // Half note divisor
+ 4, // 4th note divisor
+ 6, // 4thT divisor
+ 8, // 8th divisor
+ 12,//8thT divisor
+ 16,// ...
+ 24,
+ 32,
+ 48,
+ 64
+};
+
Quantize::Quantize(QWidget* parent)
: QDialog(parent)
{
@@ -44,7 +58,7 @@ void Quantize::pull_values()
range = range_group->checkedId();
strength = strength_spinbox->value();
threshold = threshold_spinbox->value();
- raster_power2 = raster_combobox->currentIndex();
+ raster_index = raster_combobox->currentIndex();
quant_len = len_checkbox->isChecked();
swing = swing_spinbox->value();
}
@@ -62,7 +76,7 @@ int Quantize::exec()
range_group->button(range)->setChecked(true);
strength_spinbox->setValue(strength);
threshold_spinbox->setValue(threshold);
- raster_combobox->setCurrentIndex(raster_power2);
+ raster_combobox->setCurrentIndex(raster_index);
len_checkbox->setChecked(quant_len);
swing_spinbox->setValue(swing);
@@ -88,7 +102,7 @@ void Quantize::read_configuration(MusECore::Xml& xml)
else if (tag == "threshold")
threshold=xml.parseInt();
else if (tag == "raster")
- raster_power2=xml.parseInt();
+ raster_index=xml.parseInt();
else if (tag == "swing")
swing=xml.parseInt();
else if (tag == "quant_len")
@@ -113,7 +127,7 @@ void Quantize::write_configuration(int level, MusECore::Xml& xml)
xml.intTag(level, "range", range);
xml.intTag(level, "strength", strength);
xml.intTag(level, "threshold", threshold);
- xml.intTag(level, "raster", raster_power2);
+ xml.intTag(level, "raster", raster_index);
xml.intTag(level, "swing", swing);
xml.intTag(level, "quant_len", quant_len);
xml.tag(level, "/quantize");
diff --git a/muse2/muse/widgets/function_dialogs/quantize.h b/muse2/muse/widgets/function_dialogs/quantize.h
index 6ce74215..b5229f9e 100644
--- a/muse2/muse/widgets/function_dialogs/quantize.h
+++ b/muse2/muse/widgets/function_dialogs/quantize.h
@@ -33,6 +33,7 @@ class Xml;
namespace MusEGui {
+
class Quantize : public QDialog, public Ui::QuantBase
{
Q_OBJECT
@@ -50,18 +51,18 @@ class Quantize : public QDialog, public Ui::QuantBase
int range;
int strength;
int threshold;
- int raster_power2;
+ int raster_index;
int swing;
bool quant_len;
void read_configuration(MusECore::Xml& xml);
void write_configuration(int level, MusECore::Xml& xml);
-
public slots:
int exec();
};
+extern int rasterVals[];
} // namespace MusEGui
#endif
diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp
index dd91e9ec..df7dea78 100644
--- a/muse2/muse/widgets/genset.cpp
+++ b/muse2/muse/widgets/genset.cpp
@@ -4,6 +4,7 @@
// $Id: genset.cpp,v 1.7.2.8 2009/12/01 03:52:40 terminator356 Exp $
//
// (C) Copyright 2001-2004 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -24,8 +25,10 @@
#include <stdio.h>
#include <QFileDialog>
+#include <QFileInfo>
#include <QRect>
#include <QShowEvent>
+#include <QString>
#include "genset.h"
#include "app.h"
@@ -33,6 +36,7 @@
#include "midiseq.h"
#include "globals.h"
#include "icons.h"
+#include "helper.h"
namespace MusEGui {
@@ -100,12 +104,6 @@ GlobalSettingsConfig::GlobalSettingsConfig(QWidget* parent)
}
}
- userInstrumentsPath->setText(MusEGlobal::config.userInstrumentsDir);
- selectInstrumentsDirButton->setIcon(*openIcon);
- defaultInstrumentsDirButton->setIcon(*undoIcon);
- connect(selectInstrumentsDirButton, SIGNAL(clicked()), SLOT(selectInstrumentsPath()));
- connect(defaultInstrumentsDirButton, SIGNAL(clicked()), SLOT(defaultInstrumentsPath()));
-
guiRefreshSelect->setValue(MusEGlobal::config.guiRefresh);
minSliderSelect->setValue(int(MusEGlobal::config.minSlider));
minMeterSelect->setValue(MusEGlobal::config.minMeter);
@@ -126,6 +124,9 @@ GlobalSettingsConfig::GlobalSettingsConfig(QWidget* parent)
Period affects midi playback resolution.
Shorter periods are desirable.</string>
</property> */
+
+ projDirEntry->setText(MusEGlobal::config.projectBaseFolder);
+ projDirOpenToolButton->setIcon(*openIcon);
startSongEntry->setText(MusEGlobal::config.startSong);
startSongGroup->button(MusEGlobal::config.startMode)->setChecked(true);
@@ -180,9 +181,14 @@ Shorter periods are desirable.</string>
popsDefStayOpenCheckBox->setChecked(MusEGlobal::config.popupsDefaultStayOpen);
lmbDecreasesCheckBox->setChecked(MusEGlobal::config.leftMouseButtonCanDecrease);
rangeMarkerWithoutMMBCheckBox->setChecked(MusEGlobal::config.rangeMarkerWithoutMMB);
-
+
+ addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks);
+ unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks);
+
//updateSettings(); // TESTING
+ connect(projDirOpenToolButton, SIGNAL(clicked()), SLOT(browseProjDir()));
+
connect(applyButton, SIGNAL(clicked()), SLOT(apply()));
connect(okButton, SIGNAL(clicked()), SLOT(ok()));
connect(cancelButton, SIGNAL(clicked()), SLOT(cancel()));
@@ -267,6 +273,8 @@ void GlobalSettingsConfig::updateSettings()
//dummyAudioRealRate->setText(dad ? QString().setNum(sampleRate) : "---");
//dummyAudioRealRate->setText(QString().setNum(sampleRate)); // Not used any more. p4.0.20
+ projDirEntry->setText(MusEGlobal::config.projectBaseFolder);
+
startSongEntry->setText(MusEGlobal::config.startSong);
startSongGroup->button(MusEGlobal::config.startMode)->setChecked(true);
@@ -321,6 +329,9 @@ void GlobalSettingsConfig::updateSettings()
lmbDecreasesCheckBox->setChecked(MusEGlobal::config.leftMouseButtonCanDecrease);
rangeMarkerWithoutMMBCheckBox->setChecked(MusEGlobal::config.rangeMarkerWithoutMMB);
+ addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks);
+ unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks);
+
updateMdiSettings();
}
@@ -361,7 +372,9 @@ void GlobalSettingsConfig::apply()
MusEGlobal::config.useOutputLimiter = outputLimiterCheckBox->isChecked();
MusEGlobal::config.vstInPlace = vstInPlaceCheckBox->isChecked();
MusEGlobal::config.rtcTicks = rtcResolutions[rtcticks];
- MusEGlobal::config.userInstrumentsDir = userInstrumentsPath->text();
+
+ MusEGlobal::config.projectBaseFolder = projDirEntry->text();
+
MusEGlobal::config.startSong = startSongEntry->text();
MusEGlobal::config.startMode = startSongGroup->checkedId();
MusEGlobal::config.newDrumRecordCondition = MusECore::newDrumRecordCondition_t(recDrumGroup->checkedId());
@@ -421,6 +434,9 @@ void GlobalSettingsConfig::apply()
MusEGlobal::config.leftMouseButtonCanDecrease = lmbDecreasesCheckBox->isChecked();
MusEGlobal::config.rangeMarkerWithoutMMB = rangeMarkerWithoutMMBCheckBox->isChecked();
+ MusEGlobal::config.addHiddenTracks = addHiddenCheckBox->isChecked();
+ MusEGlobal::config.unhideTracks = unhideTracksCheckBox->isChecked();
+
//MusEGlobal::muse->showMixer(MusEGlobal::config.mixerVisible);
MusEGlobal::muse->showMixer1(MusEGlobal::config.mixer1Visible);
MusEGlobal::muse->showMixer2(MusEGlobal::config.mixer2Visible);
@@ -455,8 +471,6 @@ void GlobalSettingsConfig::apply()
MusEGlobal::muse->resize(MusEGlobal::config.geometryMain.size());
MusEGlobal::muse->move(MusEGlobal::config.geometryMain.topLeft());
- MusEGlobal::museUserInstruments = MusEGlobal::config.userInstrumentsDir;
-
MusEGlobal::muse->setHeartBeat(); // set guiRefresh
MusEGlobal::midiSeq->msgSetRtc(); // set midi tick rate
@@ -559,21 +573,6 @@ void GlobalSettingsConfig::transportCurrent()
transportY->setValue(r.y());
}
-void GlobalSettingsConfig::selectInstrumentsPath()
- {
- QString dir = QFileDialog::getExistingDirectory(this,
- tr("Selects instruments directory"),
- MusEGlobal::config.userInstrumentsDir);
- userInstrumentsPath->setText(dir);
- }
-
-void GlobalSettingsConfig::defaultInstrumentsPath()
- {
- QString dir = MusEGlobal::configPath + "/instruments";
- userInstrumentsPath->setText(dir);
- }
-
-
void GlobalSettingsConfig::traditionalPreset()
{
for (std::list<MdiSettings*>::iterator it = mdisettings.begin(); it!=mdisettings.end(); it++)
@@ -611,5 +610,12 @@ void GlobalSettingsConfig::borlandPreset()
updateMdiSettings();
}
+void GlobalSettingsConfig::browseProjDir()
+{
+ QString dir = MusEGui::browseProjectFolder(this);
+ if(!dir.isEmpty())
+ projDirEntry->setText(dir);
+}
+
} // namespace MusEGui
diff --git a/muse2/muse/widgets/genset.h b/muse2/muse/widgets/genset.h
index 92da61e3..53f5c2c1 100644
--- a/muse2/muse/widgets/genset.h
+++ b/muse2/muse/widgets/genset.h
@@ -4,6 +4,7 @@
// $Id: genset.h,v 1.3 2004/01/25 09:55:17 wschweer Exp $
//
// (C) Copyright 2001 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -53,8 +54,7 @@ class GlobalSettingsConfig : public QDialog, public Ui::GlobalSettingsDialogBase
void bigtimeCurrent();
void mainCurrent();
void transportCurrent();
- void selectInstrumentsPath();
- void defaultInstrumentsPath();
+ void browseProjDir();
void traditionalPreset();
void mdiPreset();
void borlandPreset();
diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui
index 39dcd4c3..1abc3cd1 100644
--- a/muse2/muse/widgets/gensetbase.ui
+++ b/muse2/muse/widgets/gensetbase.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>556</width>
- <height>527</height>
+ <height>552</height>
</rect>
</property>
<property name="windowTitle">
@@ -23,14 +23,43 @@
</sizepolicy>
</property>
<property name="currentIndex">
- <number>2</number>
+ <number>0</number>
</property>
<widget class="QWidget" name="TabPage">
<attribute name="title">
<string>Application</string>
</attribute>
<layout class="QGridLayout">
- <item row="1" column="0">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="projDirGroupBox">
+ <property name="title">
+ <string>Project directory</string>
+ </property>
+ <layout class="QHBoxLayout" name="qhboxProjDir">
+ <item>
+ <widget class="QLabel" name="textLabel_ProjDir">
+ <property name="text">
+ <string>Projects:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="projDirEntry"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="projDirOpenToolButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
<widget class="QGroupBox" name="groupBox4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -413,14 +442,14 @@
</layout>
</widget>
</item>
- <item row="0" column="0">
+ <item row="1" column="0">
<widget class="QGroupBox" name="groupBox3">
<property name="title">
<string>Start Muse</string>
</property>
<layout class="QGridLayout">
<item row="0" column="0">
- <layout class="QGridLayout">
+ <layout class="QGridLayout" name="gridLayout11">
<item row="1" column="0">
<spacer name="spacer7_2">
<property name="orientation">
@@ -438,7 +467,7 @@
</spacer>
</item>
<item row="2" column="0" colspan="2">
- <layout class="QHBoxLayout">
+ <layout class="QHBoxLayout" name="qhboxStartSong">
<item>
<widget class="QLabel" name="textLabel1_2">
<property name="text">
@@ -811,9 +840,9 @@ Adjusts responsiveness of audio controls and
<number>2</number>
</property>
<item row="0" column="0">
- <layout class="QGridLayout">
+ <layout class="QGridLayout" name="gridLayoutwaveEditor">
<item row="0" column="0">
- <layout class="QHBoxLayout">
+ <layout class="QHBoxLayout" name="qhboxLayoutWaveEditor">
<item>
<widget class="QLabel" name="textLabel2_2">
<property name="sizePolicy">
@@ -995,13 +1024,7 @@ Adjusts responsiveness of audio controls and
<attribute name="title">
<string>Midi</string>
</attribute>
- <layout class="QVBoxLayout">
- <property name="spacing">
- <number>6</number>
- </property>
- <property name="margin">
- <number>11</number>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QGroupBox" name="GroupBox2">
<property name="title">
@@ -1179,30 +1202,6 @@ Adjusts responsiveness of audio controls and
</item>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="TextLabel3_4">
- <property name="text">
- <string>Instruments Directory</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="userInstrumentsPath"/>
- </item>
- <item row="3" column="2">
- <widget class="QPushButton" name="selectInstrumentsDirButton">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="3" column="3">
- <widget class="QPushButton" name="defaultInstrumentsDirButton">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
@@ -1244,14 +1243,14 @@ Adjusts responsiveness of audio controls and
</widget>
</item>
<item>
- <spacer name="verticalSpacer_2">
+ <spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
- <height>40</height>
+ <width>191</width>
+ <height>166</height>
</size>
</property>
</spacer>
@@ -1260,7 +1259,7 @@ Adjusts responsiveness of audio controls and
</widget>
<widget class="QWidget" name="tab3">
<attribute name="title">
- <string>GUI</string>
+ <string>GUI Behaviour</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
@@ -1443,10 +1442,58 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
+ <item row="9" column="0">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="7" column="1">
+ <widget class="QCheckBox" name="addHiddenCheckBox">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Allow adding hidden tracks in track list menu</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Unhide tracks when adding hidden tracks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QCheckBox" name="unhideTracksCheckBox">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
- <item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>GUI Style</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayoutTab2">
+ <item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>MDI-subwindowness and sharing menus</string>
@@ -1497,8 +1544,8 @@ left button behave like the middle button in such areas.</string>
<rect>
<x>0</x>
<y>0</y>
- <width>482</width>
- <height>143</height>
+ <width>96</width>
+ <height>26</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
diff --git a/muse2/muse/widgets/header.cpp b/muse2/muse/widgets/header.cpp
index 2c1057c3..968e7f73 100644
--- a/muse2/muse/widgets/header.cpp
+++ b/muse2/muse/widgets/header.cpp
@@ -51,7 +51,7 @@ void Header::readStatus(MusECore::Xml& xml)
for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
int logialIdx=abs((*it).toInt());
bool isHidden = (*it).toInt() < 0 ? true:false;
- int section = visualIndex(logialIdx);
+ int section = visualIndex(logialIdx - (isHidden? 1:0));
moveSection(section, index);
if (isHidden)
hideSection(logialIdx-1);
@@ -65,7 +65,7 @@ void Header::readStatus(MusECore::Xml& xml)
bool foundIt=false;
for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
int id=((*it).toInt());
- if ( id == i || i ==1-id )
+ if ( id == i || i == -1 - id )
foundIt=true;
}
if (foundIt == false) {
@@ -97,7 +97,7 @@ void Header::writeStatus(int level, MusECore::Xml& xml) const
//xml.nput(level, "<%s> ", name());
xml.nput(level, "<%s> ", MusECore::Xml::xmlString(objectName()).toLatin1().constData());
int n = count();
- for (int i = n; i >= 0; --i) {
+ for (int i = n-1; i >= 0; --i) {
if (isSectionHidden(logicalIndex(i)))
xml.nput("%d ", -logicalIndex(i)-1); // hidden is stored as negative value starting from -1
else
diff --git a/muse2/muse/widgets/knob.cpp b/muse2/muse/widgets/knob.cpp
index 920d2028..269f65cf 100644
--- a/muse2/muse/widgets/knob.cpp
+++ b/muse2/muse/widgets/knob.cpp
@@ -323,6 +323,30 @@ void Knob::rangeChange()
repaint();
}
+void Knob::mousePressEvent(QMouseEvent *e)
+{
+ if (e->button() == Qt::MidButton || e->modifiers() & Qt::ControlModifier) {
+ int xpos = e->x() - width() /2;
+ double v = float(e->y()) / height() * 1.2;
+
+ double halfRange = (maxValue() - minValue())/2;
+ double midValue = minValue() + halfRange;
+ // apply to range
+ if (xpos < 0) { // left values
+ v = -v;
+ }
+ setValue(v * halfRange + midValue);
+ SliderBase::valueChange();
+
+ // fake a left-click to make the knob still "stick" to
+ // the mouse.
+ QMouseEvent temp(e->type(), e->pos(), Qt::LeftButton, e->buttons(), e->modifiers());
+ SliderBase::mousePressEvent(&temp);
+ return;
+ }
+ SliderBase::mousePressEvent(e);
+}
+
//---------------------------------------------------------
// resizeEvent
//---------------------------------------------------------
diff --git a/muse2/muse/widgets/knob.h b/muse2/muse/widgets/knob.h
index 483fafa6..bd8621a1 100644
--- a/muse2/muse/widgets/knob.h
+++ b/muse2/muse/widgets/knob.h
@@ -80,6 +80,7 @@ class Knob : public SliderBase, public ScaleIf
virtual void paintEvent(QPaintEvent *);
virtual void resizeEvent(QResizeEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
double getValue(const QPoint &p);
void getScrollMode( QPoint &p, const Qt::MouseButton &button, int &scrollMode, int &direction );
void scaleChange() { repaint(); }
diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp
index 5c79ffb2..d9ca8e20 100644
--- a/muse2/muse/widgets/meter.cpp
+++ b/muse2/muse/widgets/meter.cpp
@@ -229,6 +229,8 @@ void Meter::setRange(double min, double max)
void Meter::paintEvent(QPaintEvent* ev)
{
+ // For some reason upon resizing we get double calls here and in resizeEvent.
+
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
@@ -534,8 +536,11 @@ void Meter::drawVU(QPainter& p, const QRect& rect, const QPainterPath& drawPath,
void Meter::resizeEvent(QResizeEvent* ev)
{
- QFrame::resizeEvent(ev);
+ // For some reason upon resizing we get double calls here and in paintEvent.
+ //printf("Meter::resizeEvent w:%d h:%d\n", ev->size().width(), ev->size().height());
cur_yv = -1; // Force re-initialization.
+ QFrame::resizeEvent(ev);
+ update();
}
//---------------------------------------------------------
diff --git a/muse2/muse/widgets/metronome.cpp b/muse2/muse/widgets/metronome.cpp
index e6b7bd91..416e9e47 100644
--- a/muse2/muse/widgets/metronome.cpp
+++ b/muse2/muse/widgets/metronome.cpp
@@ -85,7 +85,7 @@ void MetronomeConfig::audioBeepRoutesClicked()
int nn = 0;
for(MusECore::iAudioOutput iao = ol->begin(); iao != ol->end(); ++iao)
{
- QAction* action = pup->addAction(QT_TRANSLATE_NOOP("@default", (*iao)->name()));
+ QAction* action = pup->addAction((*iao)->name());
action->setCheckable(true);
action->setData(nn);
if((*iao)->sendMetronome())
diff --git a/muse2/muse/widgets/midisync.ui b/muse2/muse/widgets/midisync.ui
index 8fc6248a..81d7451e 100644
--- a/muse2/muse/widgets/midisync.ui
+++ b/muse2/muse/widgets/midisync.ui
@@ -388,6 +388,19 @@ Enabled inputs in the list will
</column>
</widget>
</item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="toBeDoneLabel">
+ <property name="text">
+ <string>Note: Sync delay and MTC sync currently not fully implemeted</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp
index d0c0e070..7952308e 100644
--- a/muse2/muse/widgets/mtrackinfo.cpp
+++ b/muse2/muse/widgets/mtrackinfo.cpp
@@ -579,7 +579,8 @@ void MidiTrackInfo::setLabelText()
//gradient.setColorAt(0, c.darker());
//gradient.setColorAt(0, c);
//gradient.setColorAt(1, c.darker());
- gradient.setColorAt(0, c.lighter());
+ gradient.setColorAt(0, c);
+ gradient.setColorAt(0.5, c.lighter());
gradient.setColorAt(1, c);
//palette.setBrush(QPalette::Button, gradient);
//palette.setBrush(QPalette::Window, gradient);
@@ -640,14 +641,17 @@ void MidiTrackInfo::iOutputPortChanged(int index)
{
if(!selected)
return;
+ int port_num = iOutput->itemData(index).toInt();
+ if(port_num < 0 || port_num >= MIDI_PORTS)
+ return;
MusECore::MidiTrack* track = (MusECore::MidiTrack*)selected;
- if (index == track->outPort())
+ if (port_num == track->outPort())
return;
// Changed by T356.
- //track->setOutPort(index);
+ //track->setOutPort(port_num);
MusEGlobal::audio->msgIdle(true);
- //audio->msgSetTrackOutPort(track, index);
- track->setOutPortAndUpdate(index);
+ //audio->msgSetTrackOutPort(track, port_num);
+ track->setOutPortAndUpdate(port_num);
MusEGlobal::audio->msgIdle(false);
//MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
@@ -1086,11 +1090,9 @@ void MidiTrackInfo::instrPopup()
//QMenu* pup = new QMenu;
PopupMenu* pup = new PopupMenu(true);
- //instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->isDrumTrack());
- populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack());
+ instr->populatePatchPopup(pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack());
+ //populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack());
- //if(pop->actions().count() == 0)
- // return;
if(pup->actions().count() == 0)
{
delete pup;
@@ -1100,7 +1102,6 @@ void MidiTrackInfo::instrPopup()
connect(pup, SIGNAL(triggered(QAction*)), SLOT(instrPopupActivated(QAction*)));
//connect(pup, SIGNAL(hovered(QAction*)), SLOT(instrPopupActivated(QAction*)));
- //QAction *act = pop->exec(iPatch->mapToGlobal(QPoint(10,5)));
QAction *act = pup->exec(iPatch->mapToGlobal(QPoint(10,5)));
if(act)
{
@@ -1351,12 +1352,20 @@ void MidiTrackInfo::updateTrackInfo(int flags)
//iInput->clear();
iOutput->clear();
+ int item_idx = 0;
for (int i = 0; i < MIDI_PORTS; ++i) {
+ MusECore::MidiDevice* md = MusEGlobal::midiPorts[i].device();
+ if(!md) // In the case of this combo box, don't bother listing empty ports. p4.0.41
+ continue;
+ //if(!(md->rwFlags() & 1 || md->isSynti()) && (i != outPort))
+ if(!(md->rwFlags() & 1) && (i != outPort)) // Only writeable ports, or current one. p4.0.41
+ continue;
QString name;
name.sprintf("%d:%s", i+1, MusEGlobal::midiPorts[i].portname().toLatin1().constData());
- iOutput->insertItem(i, name);
+ iOutput->insertItem(item_idx, name, i);
if (i == outPort)
- iOutput->setCurrentIndex(i);
+ iOutput->setCurrentIndex(item_idx);
+ item_idx++;
}
iOutput->blockSignals(false);
diff --git a/muse2/muse/widgets/mtscale_flo.cpp b/muse2/muse/widgets/mtscale_flo.cpp
index df077102..c54ef1ad 100644
--- a/muse2/muse/widgets/mtscale_flo.cpp
+++ b/muse2/muse/widgets/mtscale_flo.cpp
@@ -45,6 +45,9 @@ MTScaleFlo::MTScaleFlo(ScoreCanvas* parent_editor, QWidget* parent_widget)
pos[0] = MusEGlobal::song->cpos();
pos[1] = MusEGlobal::song->lpos();
pos[2] = MusEGlobal::song->rpos();
+ xpos=0;
+ xoffset=0;
+
button = Qt::NoButton;
setMouseTracking(true);
connect(MusEGlobal::song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(setPos(int, unsigned, bool)));
diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp
index 27e6d523..32a886fa 100644
--- a/muse2/muse/widgets/musewidgetsplug.cpp
+++ b/muse2/muse/widgets/musewidgetsplug.cpp
@@ -159,7 +159,8 @@ MusEGlobal::GlobalConfigValues config = {
-60.0, // double minSlider;
false, // use Jack freewheel
20, // int guiRefresh;
- QString(""), // helpBrowser
+ QString(""), // userInstrumentsDir // Obsolete. Must keep for compatibility.
+ //QString(""), // helpBrowser // Obsolete
true, // extendedMidi
384, // division for smf export
QString(""), // copyright string for smf export
diff --git a/muse2/muse/widgets/popupmenu.cpp b/muse2/muse/widgets/popupmenu.cpp
index af546ec3..af870975 100644
--- a/muse2/muse/widgets/popupmenu.cpp
+++ b/muse2/muse/widgets/popupmenu.cpp
@@ -341,21 +341,38 @@ void PopupMenu::popHovered(QAction* action)
void PopupMenu::mouseReleaseEvent(QMouseEvent *e)
{
- #ifdef POPUP_MENU_DISABLE_STAY_OPEN
+ QAction* action = actionAt(e->pos());
+ if (!(action && action == activeAction() && !action->isSeparator() && action->isEnabled()))
+ action=NULL;
+
+ #ifdef POPUP_MENU_DISABLE_STAY_OPEN
+ if (action && action->menu() != NULL && action->isCheckable())
+ action->activate(QAction::Trigger);
+
QMenu::mouseReleaseEvent(e);
+
+ if (action && action->menu() != NULL && action->isCheckable())
+ close();
+
return;
#else
// Check for Ctrl to stay open.
if(!_stayOpen || (!MusEGlobal::config.popupsDefaultStayOpen && (e->modifiers() & Qt::ControlModifier) == 0))
{
+ if (action && action->menu() != NULL && action->isCheckable())
+ action->activate(QAction::Trigger);
+
QMenu::mouseReleaseEvent(e);
+
+ if (action && action->menu() != NULL && action->isCheckable())
+ close();
+
return;
}
//printf("PopupMenu::mouseReleaseEvent\n");
- QAction *action = actionAt(e->pos());
- if (action && action == activeAction() && !action->isSeparator() && action->isEnabled())
+ if (action)
action->activate(QAction::Trigger);
else
QMenu::mouseReleaseEvent(e);
diff --git a/muse2/muse/widgets/poslabel.cpp b/muse2/muse/widgets/poslabel.cpp
index 6cdcb27e..b893c58d 100644
--- a/muse2/muse/widgets/poslabel.cpp
+++ b/muse2/muse/widgets/poslabel.cpp
@@ -138,7 +138,11 @@ void PosLabel::setTickValue(unsigned val)
if (val == _tickValue)
return;
if (val >= MAX_TICK)
- abort();
+ {
+ printf("THIS SHOULD NEVER HAPPEN: val=%u > MAX_TICK=%u in PosLabel::setTickValue()!\n",val, MAX_TICK);
+ val=MAX_TICK-1;
+ }
+
_tickValue = val;
updateValue();
}
diff --git a/muse2/muse/widgets/projectcreate.ui b/muse2/muse/widgets/projectcreate.ui
index 406c83d6..d03f093c 100644
--- a/muse2/muse/widgets/projectcreate.ui
+++ b/muse2/muse/widgets/projectcreate.ui
@@ -17,28 +17,94 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Project Name:</string>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Projects folder:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="projDirLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="projDirToolButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Project Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QLineEdit" name="projectNameEdit"/>
</item>
<item>
+ <widget class="QCheckBox" name="templateCheckBox">
+ <property name="text">
+ <string>Project is a Template</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Project song file type:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="projectFileTypeCB"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>75</width>
+ <width>40</width>
<height>20</height>
</size>
</property>
@@ -87,9 +153,16 @@
</widget>
</item>
<item>
- <widget class="QPushButton" name="browseDirButton">
+ <widget class="QToolButton" name="browseDirButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="restorePathButton">
<property name="text">
- <string>Browse</string>
+ <string>...</string>
</property>
</widget>
</item>
@@ -123,6 +196,18 @@
</item>
</layout>
</widget>
+ <tabstops>
+ <tabstop>projectNameEdit</tabstop>
+ <tabstop>templateCheckBox</tabstop>
+ <tabstop>projectFileTypeCB</tabstop>
+ <tabstop>createFolderCheckbox</tabstop>
+ <tabstop>storageDirEdit</tabstop>
+ <tabstop>browseDirButton</tabstop>
+ <tabstop>commentEdit</tabstop>
+ <tabstop>buttonBox</tabstop>
+ <tabstop>projDirLineEdit</tabstop>
+ <tabstop>projDirToolButton</tabstop>
+ </tabstops>
<resources/>
<connections>
<connection>
diff --git a/muse2/muse/widgets/projectcreateimpl.cpp b/muse2/muse/widgets/projectcreateimpl.cpp
index 31973101..665d725e 100644
--- a/muse2/muse/widgets/projectcreateimpl.cpp
+++ b/muse2/muse/widgets/projectcreateimpl.cpp
@@ -4,6 +4,7 @@
// $Id: ./muse/widgets/projectcreateimpl.cpp $
//
// Copyright (C) 1999-2011 by Werner Schweer and others
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -21,12 +22,16 @@
//
//=========================================================
#include <stdio.h>
-#include <qfiledialog.h>
-#include <qdir.h>
+#include <QFileDialog>
+#include <QDir>
+#include <QStringList>
+
#include "projectcreateimpl.h"
#include "gconfig.h"
#include "globals.h"
#include "app.h"
+#include "helper.h"
+#include "icons.h"
namespace MusEGui {
@@ -35,10 +40,51 @@ ProjectCreateImpl::ProjectCreateImpl(QWidget *parent) :
{
setupUi(this);
- createFolderCheckbox->setChecked(MusEGlobal::config.projectStoreInFolder);
+ //bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath);
+ directoryPath = MusEGlobal::config.projectBaseFolder;
+
+ QStringList filters = localizedStringListFromCharArray(MusEGlobal::project_create_file_save_pattern, "file_patterns");
+ projectFileTypeCB->addItems(filters);
+
+ QString proj_title = MusEGlobal::muse->projectTitle();
+ QString proj_path = MusEGlobal::muse->projectPath();
+ QString proj_ext = MusEGlobal::muse->projectExtension();
+
+ projectNameEdit->setText(proj_title);
+
+ bool is_template = proj_path.startsWith(MusEGlobal::configPath + "/templates");
+
+ templateCheckBox->setChecked(is_template);
+
+ projDirPath = proj_path;
+
+ int type_idx = 0;
+ if(!proj_ext.isEmpty())
+ {
+ // FIXME Imperfect. Trying to avoid adding yet another series of character strings. p4.0.40
+ type_idx = projectFileTypeCB->findText(proj_ext, Qt::MatchContains | Qt::MatchCaseSensitive);
+ if(type_idx == -1)
+ type_idx = 0;
+ }
+ projectFileTypeCB->setCurrentIndex(type_idx);
+
+ projDirToolButton->setIcon(*openIcon);
+ browseDirButton->setIcon(*openIcon);
+ restorePathButton->setIcon(*undoIcon);
+
+ restorePathButton->setEnabled(false); // Disabled at first.
+
+ //createFolderCheckbox->setChecked(MusEGlobal::config.projectStoreInFolder && is_new); // Suggest no folder if not new.
+
+ connect(templateCheckBox,SIGNAL(clicked()), this, SLOT(templateButtonChanged()));
+ //connect(templateCheckBox,SIGNAL(clicked()), this, SLOT(updateDirectoryPath()));
+ connect(projDirToolButton,SIGNAL(clicked()), this, SLOT(browseProjDir()));
+ connect(restorePathButton,SIGNAL(clicked()), this, SLOT(restorePath()));
connect(browseDirButton,SIGNAL(clicked()), this, SLOT(selectDirectory()));
- connect(projectNameEdit,SIGNAL(textChanged(QString)), this, SLOT(updateDirectoryPath()));
- connect(createFolderCheckbox,SIGNAL(clicked()), this, SLOT(updateDirectoryPath()));
+ //connect(projectNameEdit,SIGNAL(textChanged(QString)), this, SLOT(updateDirectoryPath()));
+ connect(projectNameEdit,SIGNAL(textChanged(QString)), this, SLOT(updateProjectName()));
+ connect(createFolderCheckbox,SIGNAL(clicked()), this, SLOT(createProjFolderChanged()));
+ connect(projectFileTypeCB,SIGNAL(currentIndexChanged(int)), this, SLOT(updateDirectoryPath()));
connect(buttonBox, SIGNAL(accepted()), this, SLOT(ok()));
#if QT_VERSION >= 0x040700
projectNameEdit->setPlaceholderText("<Project Name>");
@@ -46,52 +92,155 @@ ProjectCreateImpl::ProjectCreateImpl(QWidget *parent) :
// as of Qt-4.7.1
//commentEdit->setPlaceholderText("<Add information about project here>");
#endif
- directoryPath = MusEGlobal::config.projectBaseFolder;
updateDirectoryPath();
show();
}
void ProjectCreateImpl::selectDirectory()
{
- QFileDialog qfd;
- qfd.selectFile(directoryPath);
- qfd.setFileMode(QFileDialog::DirectoryOnly);
- if (qfd.exec() == QDialog::Rejected) {
- return;
- }
- directoryPath=qfd.selectedFiles().first();
+ QString dpath = templateCheckBox->isChecked() ?
+ (overrideTemplDirPath.isEmpty() ? (MusEGlobal::configPath + QString("/templates")) : overrideTemplDirPath) :
+ (overrideDirPath.isEmpty() ? directoryPath : overrideDirPath);
+
+ QString dir = QFileDialog::getExistingDirectory(this, tr("Select directory"), dpath);
+ if(dir.isEmpty())
+ return;
+
+ (templateCheckBox->isChecked() ? overrideTemplDirPath : overrideDirPath) = dir;
+ restorePathButton->setEnabled(true);
updateDirectoryPath();
}
-void ProjectCreateImpl::updateDirectoryPath()
+void ProjectCreateImpl::updateProjectName()
{
+ QString curExt = projectFileTypeCB->currentText();
+ if(curExt.isEmpty())
+ curExt = ".med";
+ else
+ {
+ curExt = MusEGui::getFilterExtension(curExt);
+ // Do we have a valid extension?
+ if(curExt.isEmpty())
+ curExt = ".med";
+ }
+
QString name = "";
if (createFolderCheckbox->isChecked()) {
if (!projectNameEdit->text().isEmpty())
- name = projectNameEdit->text() + "/" + projectNameEdit->text() + ".med";
+ //name = projectNameEdit->text() + "/" + projectNameEdit->text() + ".med";
+ name = projectNameEdit->text() + "/" + projectNameEdit->text() + curExt;
//storageDirEdit->setText(directoryPath + name );
} else {
if (!projectNameEdit->text().isEmpty())
- name = projectNameEdit->text() + ".med";
+ //name = projectNameEdit->text() + ".med";
+ name = projectNameEdit->text() + curExt;
//storageDirEdit->setText(directoryPath +"/" + name);
}
- storageDirEdit->setText(directoryPath +"/" + name ); // Tim
+
+ bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath);
+
+ QString dpath = templateCheckBox->isChecked() ?
+ (overrideTemplDirPath.isEmpty() ? (MusEGlobal::configPath + QString("/templates")) : overrideTemplDirPath) :
+ (overrideDirPath.isEmpty() ? (is_new ? directoryPath : projDirPath) : overrideDirPath);
+
+ QDir proj_dir(dpath);
+ //if(is_project && MusEGlobal::config.projectStoreInFolder)
+ bool is_project = dpath.startsWith(MusEGlobal::config.projectBaseFolder);
+ //bool is_template = dpath.startsWith(MusEGlobal::configPath + "/templates") && templateCheckBox->isChecked();
+ //bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath) && MusEGlobal::config.projectStoreInFolder;
+ //bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath) &&
+ MusEGlobal::config.projectStoreInFolder &&
+ (templateCheckBox->isChecked() ? overrideTemplDirPath.isEmpty() : overrideDirPath.isEmpty());
+ //bool is_template = is_new && dpath.startsWith(MusEGlobal::configPath + "/templates") && templateCheckBox->isChecked();
+ if(!is_new && createFolderCheckbox->isChecked() && !templateCheckBox->isChecked() &&
+ (templateCheckBox->isChecked() ? overrideTemplDirPath.isEmpty() : overrideDirPath.isEmpty()))
+ proj_dir.cdUp();
+ dpath = proj_dir.absolutePath();
+
+ //if(!initProjPath.isEmpty())
+ //{
+ // initProjPath.clear();
+ //}
+
+ storageDirEdit->blockSignals(true);
+ storageDirEdit->setText(dpath + "/" + name );
+ storageDirEdit->blockSignals(false);
+
+ projDirLineEdit->setEnabled(!templateCheckBox->isChecked() && is_project);
+}
+
+void ProjectCreateImpl::updateDirectoryPath()
+{
+ updateProjectName();
+
+ projDirLineEdit->blockSignals(true);
+ projDirLineEdit->setText(MusEGlobal::config.projectBaseFolder);
+ projDirLineEdit->blockSignals(false);
}
-QString ProjectCreateImpl::getProjectPath()
+QString ProjectCreateImpl::getProjectPath() const
{
return storageDirEdit->text();
}
-QString ProjectCreateImpl::getSongInfo()
+
+QString ProjectCreateImpl::getSongInfo() const
{
return commentEdit->toPlainText();
}
+
void ProjectCreateImpl::ok()
{
MusEGlobal::config.projectStoreInFolder = createFolderCheckbox->isChecked();
- MusEGlobal::config.projectBaseFolder = directoryPath;
- MusEGlobal::muse->changeConfig(true);
+ //MusEGlobal::config.projectBaseFolder = directoryPath;
+ //MusEGlobal::muse->changeConfig(true);
emit accept();
}
+void ProjectCreateImpl::createProjFolderChanged()
+{
+ //MusEGlobal::config.projectStoreInFolder = createFolderCheckbox->isChecked();
+ //MusEGlobal::muse->changeConfig(true); // Save to config file.
+ updateDirectoryPath();
+}
+
+void ProjectCreateImpl::browseProjDir()
+{
+ QString dir = MusEGui::browseProjectFolder(this);
+ if(!dir.isEmpty())
+ {
+ directoryPath = dir;
+ MusEGlobal::config.projectBaseFolder = dir;
+ MusEGlobal::muse->changeConfig(true); // Save to config file.
+ updateDirectoryPath();
+ }
+}
+
+void ProjectCreateImpl::templateButtonChanged()
+{
+ restorePathButton->setEnabled(templateCheckBox->isChecked() ? !overrideTemplDirPath.isEmpty() : !overrideDirPath.isEmpty());
+ updateDirectoryPath();
+}
+
+void ProjectCreateImpl::restorePath()
+{
+ if(templateCheckBox->isChecked())
+ overrideTemplDirPath.clear();
+ else
+ overrideDirPath.clear();
+ restorePathButton->setEnabled(templateCheckBox->isChecked() ? !overrideTemplDirPath.isEmpty() : !overrideDirPath.isEmpty());
+ updateDirectoryPath();
+}
+
+/*
+bool ProjectCreateImpl::getProjectIsTemplate() const
+{
+ return templateCheckBox->isChecked();
+}
+
+QString ProjectCreateImpl::getTemplatePath() const
+{
+ return templDirPath;
+}
+*/
+
} //namespace MusEGui
diff --git a/muse2/muse/widgets/projectcreateimpl.h b/muse2/muse/widgets/projectcreateimpl.h
index 258b0921..f08cb1bc 100644
--- a/muse2/muse/widgets/projectcreateimpl.h
+++ b/muse2/muse/widgets/projectcreateimpl.h
@@ -4,6 +4,7 @@
// $Id: ./muse/widgets/projectcreateimpl.h $
//
// Copyright (C) 1999-2011 by Werner Schweer and others
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -33,18 +34,28 @@ class ProjectCreateImpl : public QDialog, Ui::ProjectCreate
Q_OBJECT
QString directoryPath;
+ QString overrideDirPath;
+ QString overrideTemplDirPath;
+ QString projDirPath;
+
public:
explicit ProjectCreateImpl(QWidget *parent = 0);
- QString getProjectPath();
- QString getSongInfo();
+ QString getProjectPath() const;
+ QString getSongInfo() const;
+ //bool getProjectIsTemplate() const;
+ //QString getTemplatePath() const;
signals:
-public slots:
+protected slots:
+ void updateProjectName();
void updateDirectoryPath();
void selectDirectory();
void ok();
-
+ void createProjFolderChanged();
+ void browseProjDir();
+ void templateButtonChanged();
+ void restorePath();
};
} // namespace MusEGui
diff --git a/muse2/muse/widgets/routepopup.cpp b/muse2/muse/widgets/routepopup.cpp
index 73d29c25..0f1f8264 100644
--- a/muse2/muse/widgets/routepopup.cpp
+++ b/muse2/muse/widgets/routepopup.cpp
@@ -43,10 +43,10 @@ namespace MusEGui {
int RoutePopupMenu::addMenuItem(MusECore::AudioTrack* track, MusECore::Track* route_track, PopupMenu* lb, int id, int channel, int channels, bool isOutput)
{
// totalInChannels is only used by syntis.
- int toch = ((MusECore::AudioTrack*)track)->totalOutChannels();
+ //int toch = ((MusECore::AudioTrack*)track)->totalOutChannels();
// If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
- if(track->channels() == 1)
- toch = 1;
+ //if(track->channels() == 1)
+ // toch = 1;
// Don't add the last stray mono route if the track is stereo.
//if(route_track->channels() > 1 && (channel+1 == chans))
@@ -95,6 +95,13 @@ int RoutePopupMenu::addMenuItem(MusECore::AudioTrack* track, MusECore::Track* ro
}
}
}
+
+ if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden.
+ {
+ if( (isOutput ? track : route_track)->isCircularRoute(isOutput ? route_track : track) )
+ act->setEnabled(false);
+ }
+
return ++id;
}
@@ -220,9 +227,9 @@ int RoutePopupMenu::addSyntiPorts(MusECore::AudioTrack* t, PopupMenu* lb, int id
{
char buffer[128];
if(tchans == 2)
- snprintf(buffer, 128, "%s %d,%d", chpup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
+ snprintf(buffer, 128, "%s %d,%d", tr("Channel").toLatin1().constData(), ch+1, ch+2);
else
- snprintf(buffer, 128, "%s %d", chpup->tr("Channel").toLatin1().constData(), ch+1);
+ snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), ch+1);
act = chpup->addAction(QString(buffer));
act->setCheckable(true);
@@ -259,6 +266,13 @@ int RoutePopupMenu::addSyntiPorts(MusECore::AudioTrack* t, PopupMenu* lb, int id
}
}
}
+
+ if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden.
+ {
+ if( (isOutput ? t : track)->isCircularRoute(isOutput ? track : t) )
+ act->setEnabled(false);
+ }
+
++id;
}
@@ -347,7 +361,7 @@ int RoutePopupMenu::addMultiChannelPorts(MusECore::AudioTrack* t, PopupMenu* pup
if(chans > 1)
{
char buffer[128];
- snprintf(buffer, 128, "%s %d", pup->tr("Channel").toLatin1().constData(), ch+1);
+ snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), ch+1);
chpup->setTitle(QString(buffer));
pup->addMenu(chpup);
}
@@ -425,7 +439,7 @@ int RoutePopupMenu::addMultiChannelPorts(MusECore::AudioTrack* t, PopupMenu* pup
if(chans > 2)
{
char buffer[128];
- snprintf(buffer, 128, "%s %d,%d", pup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
+ snprintf(buffer, 128, "%s %d,%d", tr("Channel").toLatin1().constData(), ch+1, ch+2);
chpup->setTitle(QString(buffer));
pup->addMenu(chpup);
}
@@ -482,7 +496,7 @@ int RoutePopupMenu::nonSyntiTrackAddSyntis(MusECore::AudioTrack* t, PopupMenu* l
for(int ch = 0; ch < chans; ++ch)
{
char buffer[128];
- snprintf(buffer, 128, "%s %d", chpup->tr("Channel").toLatin1().constData(), ch+1);
+ snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), ch+1);
act = chpup->addAction(QString(buffer));
act->setCheckable(true);
@@ -520,6 +534,13 @@ int RoutePopupMenu::nonSyntiTrackAddSyntis(MusECore::AudioTrack* t, PopupMenu* l
}
}
}
+
+ if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden.
+ {
+ if( (isOutput ? t : track)->isCircularRoute(isOutput ? track : t) )
+ act->setEnabled(false);
+ }
+
++id;
}
@@ -535,7 +556,7 @@ int RoutePopupMenu::nonSyntiTrackAddSyntis(MusECore::AudioTrack* t, PopupMenu* l
for(int ch = 0; ch < chans; ++ch)
{
char buffer[128];
- snprintf(buffer, 128, "%s %d,%d", chpup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
+ snprintf(buffer, 128, "%s %d,%d", tr("Channel").toLatin1().constData(), ch+1, ch+2);
act = chpup->addAction(QString(buffer));
act->setCheckable(true);
@@ -573,6 +594,13 @@ int RoutePopupMenu::nonSyntiTrackAddSyntis(MusECore::AudioTrack* t, PopupMenu* l
}
}
}
+
+ if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden.
+ {
+ if( (isOutput ? t : track)->isCircularRoute(isOutput ? track : t) )
+ act->setEnabled(false);
+ }
+
++id;
}
}
@@ -1062,9 +1090,8 @@ void RoutePopupMenu::prepare()
for( ; pi < MIDI_PORTS; ++pi)
{
MusECore::MidiDevice* md = MusEGlobal::midiPorts[pi].device();
- //if(md && !md->isSynti() && (md->rwFlags() & 2))
- //if(md && (md->rwFlags() & 2)) // p4.0.27
- if(md && (md->rwFlags() & 2 || md->isSynti()) ) // p4.0.27
+ if(md && !md->isSynti() && (md->rwFlags() & 2))
+ //if(md && (md->rwFlags() & 2 || md->isSynti()) ) // p4.0.27 Reverted p4.0.35
break;
}
if(pi == MIDI_PORTS)
@@ -1091,12 +1118,9 @@ void RoutePopupMenu::prepare()
// continue;
// Do not list synth devices!
- ///if(md && md->isSynti())
- /// continue;
- ///if(md && !(md->rwFlags() & 2))
- /// continue;
- // p4.0.27 Go ahead. Synths esp MESS send out stuff.
- if( md && !(md->rwFlags() & 2) && !md->isSynti() )
+ if( md && (!(md->rwFlags() & 2) || md->isSynti()) )
+ // p4.0.27 Go ahead. Synths esp MESS send out stuff. Reverted p4.0.35
+ //if( md && !(md->rwFlags() & 2) && !md->isSynti() )
continue;
//printf("MusE::prepareRoutingPopupMenu adding submenu portnum:%d\n", i);
diff --git a/muse2/muse/widgets/shortcutcapturedialog.cpp b/muse2/muse/widgets/shortcutcapturedialog.cpp
index 46a3e75d..ad78a2ad 100644
--- a/muse2/muse/widgets/shortcutcapturedialog.cpp
+++ b/muse2/muse/widgets/shortcutcapturedialog.cpp
@@ -30,7 +30,6 @@
//
// Description:
// Dialog window for capturing keyboard shortcuts
-//
#include "shortcutcapturedialog.h"
#include "shortcuts.h"
@@ -39,6 +38,7 @@
#include <QKeySequence>
#include <QInputEvent>
#include <QChar>
+#include <QApplication>
namespace MusEGui {
@@ -105,7 +105,7 @@ void ShortcutCaptureDialog::keyPressEvent(QKeyEvent* e)
(( shortcuts[i].type & (shortcuts[shortcutindex].type | INVIS_SHRT)) ||
shortcuts[i].type & GLOBAL_SHRT ||
shortcuts[shortcutindex].type & GLOBAL_SHRT)) { // affect the same scope
- msgString = tr("Shortcut conflicts with %1").arg(shortcuts[i].descr);
+ msgString = tr("Shortcut conflicts with %1").arg(qApp->translate("shortcuts",shortcuts[i].descr));
conflict = true;
break;
}
diff --git a/muse2/muse/widgets/shortcutconfig.cpp b/muse2/muse/widgets/shortcutconfig.cpp
index fc08e7ce..609564cc 100644
--- a/muse2/muse/widgets/shortcutconfig.cpp
+++ b/muse2/muse/widgets/shortcutconfig.cpp
@@ -30,12 +30,12 @@
//
// Description:
// Dialog for configuring keyboard shortcuts
-//
#include <QCloseEvent>
#include <QKeySequence>
#include <QString>
#include <QSettings>
+#include <QApplication>
#include "shortcutconfig.h"
#include "shortcutcapturedialog.h"
@@ -86,12 +86,12 @@ void ShortcutConfig::updateSCListView(int category)
for (int i=0; i < SHRT_NUM_OF_ELEMENTS; i++) {
if (shortcuts[i].type & category) {
newItem = new SCListViewItem(scListView, i);
- newItem->setText(SHRT_DESCR_COL, tr(shortcuts[i].descr));
+ newItem->setText(SHRT_DESCR_COL, qApp->translate("shortcuts", shortcuts[i].descr));
//if(category == ALL_SHRT)
// catpre = QString(shortcut_category[shortcuts[i].type].name) + QString(": ");
//else
// catpre.clear();
- //newItem->setText(SHRT_DESCR_COL, catpre + tr(shortcuts[i].descr)); // Tim
+ //newItem->setText(SHRT_DESCR_COL, catpre + tr(qApp->translate("shortcuts", shortcuts[i].descr)); // Tim
QKeySequence key = QKeySequence(shortcuts[i].key);
newItem->setText(SHRT_SHRTCUT_COL, key);
}
diff --git a/muse2/muse/widgets/shortcutconfigbase.ui b/muse2/muse/widgets/shortcutconfigbase.ui
index 119a7007..6dd5d5b7 100644
--- a/muse2/muse/widgets/shortcutconfigbase.ui
+++ b/muse2/muse/widgets/shortcutconfigbase.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>466</width>
- <height>403</height>
+ <width>512</width>
+ <height>452</height>
</rect>
</property>
<property name="windowTitle">
@@ -16,67 +16,64 @@
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
- <layout class="QVBoxLayout">
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QGroupBox" name="groupBox3">
- <property name="title">
- <string/>
+ <widget class="QSplitter" name="splitter">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <layout class="QHBoxLayout">
- <property name="spacing">
- <number>3</number>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="childrenCollapsible">
+ <bool>false</bool>
+ </property>
+ <widget class="QTreeWidget" name="cgListView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>105</width>
+ <height>200</height>
+ </size>
+ </property>
+ <column>
+ <property name="text">
+ <string>Shortcut Category</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QTreeWidget" name="scListView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>2</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="margin">
- <number>0</number>
+ <property name="minimumSize">
+ <size>
+ <width>170</width>
+ <height>230</height>
+ </size>
</property>
- <item>
- <widget class="QTreeWidget" name="cgListView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
- <horstretch>1</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>105</width>
- <height>200</height>
- </size>
- </property>
- <column>
- <property name="text">
- <string>Shortcut Category</string>
- </property>
- </column>
- </widget>
- </item>
- <item>
- <widget class="QTreeWidget" name="scListView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
- <horstretch>2</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>170</width>
- <height>230</height>
- </size>
- </property>
- <column>
- <property name="text">
- <string>Shortcut</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Description</string>
- </property>
- </column>
- </widget>
- </item>
- </layout>
+ <column>
+ <property name="text">
+ <string>Shortcut</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ </column>
+ </widget>
</widget>
</item>
<item>
diff --git a/muse2/muse/widgets/spinbox.cpp b/muse2/muse/widgets/spinbox.cpp
index f7afcf2a..a763eea1 100644
--- a/muse2/muse/widgets/spinbox.cpp
+++ b/muse2/muse/widgets/spinbox.cpp
@@ -99,4 +99,19 @@ void SpinBox::stepDown()
_clearFocus = true;
}
+void SpinBox::keyPressEvent(QKeyEvent* ev)
+{
+ switch (ev->key()) {
+ case Qt::Key_Return:
+ clearFocus();
+ //emit returnPressed();
+ // return;
+ break;
+ default:
+ break;
+ }
+ QSpinBox::keyPressEvent(ev);
+}
+
} // namespace MusEGui
+
diff --git a/muse2/muse/widgets/spinbox.h b/muse2/muse/widgets/spinbox.h
index cee112d4..cd37fb32 100644
--- a/muse2/muse/widgets/spinbox.h
+++ b/muse2/muse/widgets/spinbox.h
@@ -43,7 +43,8 @@ class SpinBox : public QSpinBox {
protected:
bool eventFilter(QObject* obj, QEvent* ev);
-
+ virtual void keyPressEvent(QKeyEvent*);
+
public slots:
virtual void stepUp();
virtual void stepDown();
diff --git a/muse2/muse/widgets/synthconfigbase.ui b/muse2/muse/widgets/synthconfigbase.ui
index 97f0beaa..500241a8 100644
--- a/muse2/muse/widgets/synthconfigbase.ui
+++ b/muse2/muse/widgets/synthconfigbase.ui
@@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
- <width>630</width>
+ <width>810</width>
<height>492</height>
</rect>
</property>
<property name="windowTitle">
- <string>MusE: Synth Configuration</string>
+ <string>Midi Port and Soft Synth Configuration</string>
</property>
<layout class="QGridLayout">
<item row="1" column="1">
@@ -32,6 +32,11 @@
</column>
<column>
<property name="text">
+ <string>Type</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
<string>Midi Port</string>
</property>
</column>
@@ -137,6 +142,11 @@
</column>
<column>
<property name="text">
+ <string>Type</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
<string>Inst</string>
</property>
</column>
diff --git a/muse2/muse/widgets/tb1.cpp b/muse2/muse/widgets/tb1.cpp
index 3174260f..589726a9 100644
--- a/muse2/muse/widgets/tb1.cpp
+++ b/muse2/muse/widgets/tb1.cpp
@@ -20,7 +20,6 @@
//
//=========================================================
-//#include <assert.h>
#include <stdio.h>
#include <values.h>
@@ -45,9 +44,9 @@ static int rasterTable[] = {
};
static const char* rasterStrings[] = {
- QT_TRANSLATE_NOOP("@default", "Off"), "2pp", "5pp", "64T", "32T", "16T", "8T", "4T", "2T", "1T",
- QT_TRANSLATE_NOOP("@default", "Off"), "3pp", "6pp", "64", "32", "16", "8", "4", "2", "1",
- QT_TRANSLATE_NOOP("@default", "Off"), "4pp", "7pp", "64.", "32.", "16.", "8.", "4.", "2.", "1."
+ QT_TRANSLATE_NOOP("MusEGui::Toolbar1", "Off"), "2pp", "5pp", "64T", "32T", "16T", "8T", "4T", "2T", "1T",
+ QT_TRANSLATE_NOOP("MusEGui::Toolbar1", "Off"), "3pp", "6pp", "64", "32", "16", "8", "4", "2", "1",
+ QT_TRANSLATE_NOOP("MusEGui::Toolbar1", "Off"), "4pp", "7pp", "64.", "32.", "16.", "8.", "4.", "2.", "1."
};
diff --git a/muse2/muse/widgets/tools.cpp b/muse2/muse/widgets/tools.cpp
index 162d2b97..d46126a9 100644
--- a/muse2/muse/widgets/tools.cpp
+++ b/muse2/muse/widgets/tools.cpp
@@ -30,42 +30,42 @@
namespace MusEGui {
-const char* infoPointer = QT_TRANSLATE_NOOP("@default", "select Pointer Tool:\n"
+const char* infoPointer = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Pointer Tool:\n"
"with the pointer tool you can:\n"
" select parts\n"
" move parts\n"
" copy parts");
-const char* infoPencil = QT_TRANSLATE_NOOP("@default", "select Pencil Tool:\n"
+const char* infoPencil = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Pencil Tool:\n"
"with the pencil tool you can:\n"
" create new parts\n"
" modify length of parts");
-const char* infoDel = QT_TRANSLATE_NOOP("@default", "select Delete Tool:\n"
+const char* infoDel = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Delete Tool:\n"
"with the delete tool you can delete parts");
-const char* infoCut = QT_TRANSLATE_NOOP("@default", "select Cut Tool:\n"
+const char* infoCut = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Cut Tool:\n"
"with the cut tool you can split a part");
-const char* infoGlue = QT_TRANSLATE_NOOP("@default", "select Glue Tool:\n"
+const char* infoGlue = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Glue Tool:\n"
"with the glue tool you can glue two parts");
-const char* infoScore = QT_TRANSLATE_NOOP("@default", "select Score Tool:\n");
-const char* infoQuant = QT_TRANSLATE_NOOP("@default", "select Quantize Tool:\n"
+const char* infoScore = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Score Tool:\n");
+const char* infoQuant = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Quantize Tool:\n"
"insert display quantize event");
-const char* infoDraw = QT_TRANSLATE_NOOP("@default", "select Drawing Tool");
-const char* infoMute = QT_TRANSLATE_NOOP("@default", "select Muting Tool:\n"
+const char* infoDraw = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Drawing Tool");
+const char* infoMute = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "select Muting Tool:\n"
"click on part to mute/unmute");
-const char* infoAutomation = QT_TRANSLATE_NOOP("@default", "Manipulate automation");
-const char* infoCursor = QT_TRANSLATE_NOOP("@default", "Cursor tool");
+const char* infoAutomation = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "Manipulate automation");
+const char* infoCursor = QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "Cursor tool");
ToolB toolList[] = {
- {&pointerIcon, QT_TRANSLATE_NOOP("@default", "pointer"), infoPointer },
- {&pencilIcon, QT_TRANSLATE_NOOP("@default", "pencil"), infoPencil },
- {&deleteIcon, QT_TRANSLATE_NOOP("@default", "eraser"), infoDel },
- {&cutIcon, QT_TRANSLATE_NOOP("@default", "cutter"), infoCut },
- {&note1Icon, QT_TRANSLATE_NOOP("@default", "score"), infoScore },
- {&glueIcon, QT_TRANSLATE_NOOP("@default", "glue"), infoGlue },
- {&quantIcon, QT_TRANSLATE_NOOP("@default", "quantize"), infoQuant },
- {&drawIcon, QT_TRANSLATE_NOOP("@default", "draw"), infoDraw },
- {&editmuteIcon, QT_TRANSLATE_NOOP("@default", "mute parts"), infoMute },
- {&drawIcon, QT_TRANSLATE_NOOP("@default", "edit automation"),infoAutomation},
- {&cursorIcon, QT_TRANSLATE_NOOP("@default", "cursor"), infoCursor},
+ {&pointerIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "pointer"), infoPointer },
+ {&pencilIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "pencil"), infoPencil },
+ {&deleteIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "eraser"), infoDel },
+ {&cutIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "cutter"), infoCut },
+ {&note1Icon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "score"), infoScore },
+ {&glueIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "glue"), infoGlue },
+ {&quantIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "quantize"), infoQuant },
+ {&drawIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "draw"), infoDraw },
+ {&editmuteIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "mute parts"), infoMute },
+ {&drawIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "edit automation"),infoAutomation},
+ {&cursorIcon, QT_TRANSLATE_NOOP("MusEGui::EditToolBar", "cursor"), infoCursor},
};
//---------------------------------------------------------
@@ -94,7 +94,7 @@ EditToolBar::EditToolBar(QWidget* parent, int tools, const char*)
continue;
ToolB* t = &toolList[i];
- Action* a = new Action(action, 1<<i, t->tip, true);
+ Action* a = new Action(action, 1<<i, tr(t->tip).toAscii().data(), true);
actions[n] = a;
//a->setIconSet(QIcon(**(t->icon)));
a->setIcon(QIcon(**(t->icon)));
diff --git a/muse2/muse/widgets/utils.cpp b/muse2/muse/widgets/utils.cpp
index 708bef07..1641b267 100644
--- a/muse2/muse/widgets/utils.cpp
+++ b/muse2/muse/widgets/utils.cpp
@@ -528,7 +528,8 @@ int get_paste_len()
if (p->endTick() > end_tick)
end_tick=p->endTick();
-
+
+ unchainClone(p);
delete p;
}
}
diff --git a/muse2/muse/widgets/visibletracks.cpp b/muse2/muse/widgets/visibletracks.cpp
index 84e7dd42..4976ecf9 100644
--- a/muse2/muse/widgets/visibletracks.cpp
+++ b/muse2/muse/widgets/visibletracks.cpp
@@ -29,25 +29,26 @@
#include "action.h"
#include "track.h"
#include "synth.h"
+#include "app.h"
namespace MusEGui {
-const char* waveTrack = QT_TRANSLATE_NOOP("@default", "Show wave tracks");
-const char* groupTrack = QT_TRANSLATE_NOOP("@default", "Show group tracks");
-const char* auxTrack = QT_TRANSLATE_NOOP("@default", "Show aux tracks");
-const char* inputTrack = QT_TRANSLATE_NOOP("@default", "Show input tracks");
-const char* outputTrack = QT_TRANSLATE_NOOP("@default", "Show output tracks");
-const char* midiTrack = QT_TRANSLATE_NOOP("@default", "Show midi tracks");
-const char* synthTrack = QT_TRANSLATE_NOOP("@default", "Show synth tracks");
+const char* waveTrack = QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show wave tracks");
+const char* groupTrack = QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show group tracks");
+const char* auxTrack = QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show aux tracks");
+const char* inputTrack = QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show input tracks");
+const char* outputTrack = QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show output tracks");
+const char* midiTrack = QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show midi tracks");
+const char* synthTrack = QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show synth tracks");
VisibleToolB visTrackList[] = {
- {&addtrack_wavetrackIcon, QT_TRANSLATE_NOOP("@default", "Show wave tracks"), waveTrack },
- {&addtrack_audiogroupIcon, QT_TRANSLATE_NOOP("@default", "Show group tracks"), groupTrack },
- {&addtrack_auxsendIcon, QT_TRANSLATE_NOOP("@default", "Show aux tracks"), auxTrack },
- {&addtrack_audioinputIcon, QT_TRANSLATE_NOOP("@default", "Show input tracks"), inputTrack },
- {&addtrack_audiooutputIcon, QT_TRANSLATE_NOOP("@default", "Show output tracks"), outputTrack },
- {&addtrack_addmiditrackIcon,QT_TRANSLATE_NOOP("@default", "Show midi tracks"), midiTrack },
- {&synthIcon, QT_TRANSLATE_NOOP("@default", "Show synth tracks"), midiTrack },
+ {&addtrack_wavetrackIcon, QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show wave tracks"), waveTrack },
+ {&addtrack_audiogroupIcon, QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show group tracks"), groupTrack },
+ {&addtrack_auxsendIcon, QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show aux tracks"), auxTrack },
+ {&addtrack_audioinputIcon, QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show input tracks"), inputTrack },
+ {&addtrack_audiooutputIcon, QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show output tracks"), outputTrack },
+ {&addtrack_addmiditrackIcon,QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show midi tracks"), midiTrack },
+ {&synthIcon, QT_TRANSLATE_NOOP("MusEGui::VisibleTracks", "Show synth tracks"), midiTrack },
};
//---------------------------------------------------------
@@ -67,7 +68,7 @@ VisibleTracks::VisibleTracks(QWidget* parent, const char*)
for (unsigned i = 0; i < sizeof(visTrackList)/sizeof(*visTrackList); ++i) {
VisibleToolB* t = &visTrackList[i];
- Action* a = new Action(action, i, t->tip, true);
+ Action* a = new Action(action, i, tr(t->tip).toAscii().data(), true);
actions[n] = a;
//a->setIconSet(QIcon(**(t->icon)));
a->setIcon(QIcon(**(t->icon)));
@@ -130,6 +131,7 @@ void VisibleTracks::visibilityChanged(QAction* action)
default:
break;
}
+ MusEGlobal::muse->changeConfig(true); // save settings
emit visibilityChanged();
}
diff --git a/muse2/muse/widgets/visibletracks.h b/muse2/muse/widgets/visibletracks.h
index d56c9ce7..bf49c068 100644
--- a/muse2/muse/widgets/visibletracks.h
+++ b/muse2/muse/widgets/visibletracks.h
@@ -52,13 +52,14 @@ class VisibleTracks : public QToolBar {
private slots:
void visibilityChanged(QAction* action);
+ public slots:
+ void updateVisibleTracksButtons();
signals:
void visibilityChanged();
public:
VisibleTracks(QWidget* /*parent*/, const char* name = 0); // Needs a parent !
- void updateVisibleTracksButtons();
~VisibleTracks();
};
diff --git a/muse2/muse/xml.cpp b/muse2/muse/xml.cpp
index 139437c1..45bed368 100644
--- a/muse2/muse/xml.cpp
+++ b/muse2/muse/xml.cpp
@@ -4,6 +4,7 @@
// $Id: xml.cpp,v 1.17.2.6 2009/12/07 20:48:45 spamatica Exp $
//
// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -24,6 +25,7 @@
#include <stdio.h>
#include <stdarg.h>
+#include <QByteArray>
#include <QString>
#include <QColor>
#include <QWidget>
@@ -112,9 +114,12 @@ void Xml::nextc()
void Xml::token(int cc)
{
- char buffer[512];
+ //char buffer[512];
+ QByteArray buffer;
+
int i = 0;
- for (; i < 511;) {
+ //for (; i < 511;) {
+ for (; i < 9999999;) { // Stop at a reasonably large amount 10 million.
if (c == ' ' || c == '\t' || c == cc || c == '\n' || c == EOF)
break;
buffer[i++] = c;
@@ -131,12 +136,16 @@ void Xml::token(int cc)
void Xml::stoken()
{
- char buffer[1024*4];
+ //char buffer[1024*4];
+ QByteArray buffer;
+
int i = 0;
buffer[i] = c;
++i;
next();
- for (;i < 1024*4-1;) {
+
+ //for (;i < 1024*4-1;) {
+ for (;i < 10000000*4-1;) { // Stop at a reasonably large amount 10 million.
if (c == '"') {
buffer[i++] = c;
next();
@@ -207,8 +216,10 @@ QString Xml::strip(const QString& s)
Xml::Token Xml::parse()
{
- char buffer[1024*1024]; // increase buffer -rj
- char* p;
+ //char buffer[1024*1024]; // increase buffer -rj
+ //char* p;
+ QByteArray buffer;
+ int idx = 0;
again:
bool endFlag = false;
@@ -262,15 +273,23 @@ Xml::Token Xml::parse()
}
if (c == '?') {
next();
- p = buffer;
+ //p = buffer;
+ //p = buffer.data();
+ idx = 0;
for (;;) {
if (c == '?' || c == EOF || c == '>')
break;
- *p++ = c;
+
+ //*p++ = c;
+ buffer[idx++] = c;
+
// TODO: check overflow
next();
}
- *p = 0;
+
+ //*p = 0;
+ buffer[idx] = 0;
+
_s1 = QString(buffer);
if (c == EOF) {
fprintf(stderr, "XML: unexpected EOF\n");
@@ -298,15 +317,23 @@ Xml::Token Xml::parse()
}
goto again;
}
- p = buffer;
+ //p = buffer;
+ //p = buffer.data();
+ idx = 0;
for (;;) {
if (c == '/' || c == ' ' || c == '\t' || c == '>' || c == '\n' || c == EOF)
break;
// TODO: check overflow
- *p++ = c;
+
+ //*p++ = c;
+ buffer[idx++] = c;
+
next();
}
- *p = 0;
+
+ //*p = 0;
+ buffer[idx] = 0;
+
_s1 = QString(buffer);
// skip white space:
while (c == ' ' || c == '\t' || c == '\n')
@@ -355,26 +382,43 @@ Xml::Token Xml::parse()
fprintf(stderr, "XML: level = 0\n");
goto error;
}
- p = buffer;
+ //p = buffer;
+ //p = buffer.data();
+ idx = 0;
for (;;) {
if (c == EOF || c == '<')
break;
if (c == '&') {
next();
if (c == '<') { // be tolerant with old muse files
- *p++ = '&';
+
+ //*p++ = '&';
+ buffer[idx++] = '&';
+
continue;
}
- char name[32];
- char* dp = name;
- *dp++ = c;
- for (; dp-name < 31;) {
+
+ //char name[32];
+ //char* dp = name;
+ QByteArray name;
+ int name_idx = 0;
+
+ //*dp++ = c;
+ name[name_idx++] = c;
+
+ //for (; dp-name < 31;) {
+ for (; name_idx < 9999999;) { // Stop at a reasonably large amount 10 million.
next();
if (c == ';')
break;
- *dp++ = c;
+
+ //*dp++ = c;
+ name[name_idx++] = c;
}
- *dp = 0;
+
+ //*dp = 0;
+ name[name_idx] = 0;
+
if (strcmp(name, "lt") == 0)
c = '<';
else if (strcmp(name, "gt") == 0)
@@ -388,10 +432,16 @@ Xml::Token Xml::parse()
else
c = '?';
}
- *p++ = c;
+
+ //*p++ = c;
+ buffer[idx++] = c;
+
next();
}
- *p = 0;
+
+ //*p = 0;
+ buffer[idx] = 0;
+
_s1 = QString(buffer);
if (c == '<')