summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2012-07-01 16:42:16 +0000
committerFlorian Jung <flo@windfisch.org>2012-07-01 16:42:16 +0000
commit9c4664d162c537ba4dd4fd8220971c0fb727103a (patch)
tree37a28b7cd4e4d8984ad4934a4884cd7b4da0505c
parente87fedf1be804f7ec774071d844b1f163be30b96 (diff)
final merge
-rw-r--r--muse2/AUTHORS79
-rw-r--r--muse2/CMakeLists.txt14
-rw-r--r--muse2/ChangeLog78
-rw-r--r--muse2/README6
-rw-r--r--muse2/README.de38
-rw-r--r--muse2/doc/documentation.tex557
-rw-r--r--muse2/doc/pics/arrow_tool.pngbin0 -> 258 bytes
-rw-r--r--muse2/doc/pics/bad_timing.pngbin0 -> 34355 bytes
-rw-r--r--muse2/doc/pics/main_window.pngbin0 -> 89649 bytes
-rw-r--r--muse2/doc/pics/main_window_annotated.pngbin0 -> 82252 bytes
-rw-r--r--muse2/doc/pics/main_window_with_arrangement.pngbin0 -> 169229 bytes
-rw-r--r--muse2/doc/pics/main_window_with_midi_editor.pngbin0 -> 140617 bytes
-rw-r--r--muse2/doc/pics/main_window_with_tracks.pngbin0 -> 122625 bytes
-rw-r--r--muse2/doc/pics/mixer.pngbin0 -> 56812 bytes
-rw-r--r--muse2/doc/pics/mixer_strip.pngbin0 -> 13169 bytes
-rw-r--r--muse2/doc/pics/muse2.pngbin0 -> 97657 bytes
-rw-r--r--muse2/doc/pics/no_audio.pngbin0 -> 32195 bytes
-rw-r--r--muse2/doc/pics/organ_synth.pngbin0 -> 66145 bytes
-rw-r--r--muse2/doc/pics/output_routing.pngbin0 -> 27489 bytes
-rw-r--r--muse2/grepmidi/grepmidi.cpp3
-rw-r--r--muse2/muse/arranger/arranger.cpp8
-rw-r--r--muse2/muse/arranger/arranger.h2
-rw-r--r--muse2/muse/arranger/pcanvas.cpp88
-rw-r--r--muse2/muse/arranger/pcanvas.h2
-rw-r--r--muse2/muse/arranger/tlist.cpp186
-rw-r--r--muse2/muse/audio.cpp110
-rw-r--r--muse2/muse/audio.h22
-rw-r--r--muse2/muse/audiotrack.cpp339
-rw-r--r--muse2/muse/conf.cpp19
-rw-r--r--muse2/muse/confmport.cpp41
-rw-r--r--muse2/muse/ctrl.cpp471
-rw-r--r--muse2/muse/ctrl.h68
-rw-r--r--muse2/muse/driver/alsamidi.cpp10
-rw-r--r--muse2/muse/driver/jack.cpp182
-rw-r--r--muse2/muse/driver/jackaudio.h2
-rw-r--r--muse2/muse/driver/jackmidi.cpp38
-rw-r--r--muse2/muse/dssihost.cpp173
-rw-r--r--muse2/muse/dssihost.h4
-rw-r--r--muse2/muse/gconfig.cpp2
-rw-r--r--muse2/muse/globals.cpp6
-rw-r--r--muse2/muse/globals.h4
-rw-r--r--muse2/muse/midi.cpp199
-rw-r--r--muse2/muse/midictrl.cpp33
-rw-r--r--muse2/muse/midictrl.h1
-rw-r--r--muse2/muse/mididev.cpp15
-rw-r--r--muse2/muse/midiseq.cpp74
-rw-r--r--muse2/muse/midiseq.h19
-rw-r--r--muse2/muse/mixer/astrip.cpp53
-rw-r--r--muse2/muse/mixer/astrip.h4
-rw-r--r--muse2/muse/mixer/panknob.cpp1
-rw-r--r--muse2/muse/mpevent.cpp8
-rw-r--r--muse2/muse/mpevent.h14
-rw-r--r--muse2/muse/node.cpp16
-rw-r--r--muse2/muse/osc.cpp4
-rw-r--r--muse2/muse/part.cpp61
-rw-r--r--muse2/muse/part.h13
-rw-r--r--muse2/muse/plugin.cpp624
-rw-r--r--muse2/muse/plugin.h11
-rw-r--r--muse2/muse/seqmsg.cpp19
-rw-r--r--muse2/muse/song.cpp179
-rw-r--r--muse2/muse/song.h11
-rw-r--r--muse2/muse/sync.cpp174
-rw-r--r--muse2/muse/sync.h7
-rw-r--r--muse2/muse/tempo.cpp86
-rw-r--r--muse2/muse/tempo.h56
-rw-r--r--muse2/muse/thread.cpp53
-rw-r--r--muse2/muse/track.cpp17
-rw-r--r--muse2/muse/track.h5
-rw-r--r--muse2/muse/undo.h6
-rw-r--r--muse2/muse/wave.cpp55
-rw-r--r--muse2/muse/wavetrack.cpp12
-rw-r--r--muse2/muse/widgets/CMakeLists.txt3
-rw-r--r--muse2/muse/widgets/aboutbox.ui4
-rw-r--r--muse2/muse/widgets/bigtime.cpp5
-rw-r--r--muse2/muse/widgets/filedialog.cpp30
-rw-r--r--muse2/muse/widgets/filedialog.h3
-rw-r--r--muse2/muse/widgets/midi_audio_control.cpp340
-rw-r--r--muse2/muse/widgets/midi_audio_control.h60
-rw-r--r--muse2/muse/widgets/midi_audio_control_base.ui310
-rw-r--r--muse2/muse/widgets/midisync.ui110
-rw-r--r--muse2/muse/widgets/midisyncimpl.cpp283
-rw-r--r--muse2/muse/widgets/musewidgetsplug.cpp2
-rw-r--r--muse2/muse/widgets/scldraw.cpp5
-rw-r--r--muse2/muse/widgets/sliderbase.cpp12
-rw-r--r--muse2/muse/widgets/sliderbase.h1
-rw-r--r--muse2/share/locale/muse_cs.ts795
-rw-r--r--muse2/share/locale/muse_de.ts361
-rw-r--r--muse2/share/locale/muse_en.ts760
-rw-r--r--muse2/share/locale/muse_es.ts268
-rw-r--r--muse2/share/locale/muse_fr.ts300
-rw-r--r--muse2/share/locale/muse_pl.ts312
-rw-r--r--muse2/share/locale/muse_ru.ts147
-rw-r--r--muse2/share/locale/muse_sv_SE.ts366
-rw-r--r--muse2/share/templates/MusE.cfg2
-rw-r--r--muse2/synti/deicsonze/deicsonzegui.cpp4
-rw-r--r--muse2/synti/deicsonze/deicsonzeplugin.cpp8
-rw-r--r--muse2/synti/simpledrums2/simpledrums.cpp8
-rw-r--r--muse2/xpm/record_off.xpm216
-rw-r--r--muse2/xpm/record_on.xpm244
99 files changed, 6849 insertions, 2492 deletions
diff --git a/muse2/AUTHORS b/muse2/AUTHORS
index 3fcac758..22d70210 100644
--- a/muse2/AUTHORS
+++ b/muse2/AUTHORS
@@ -1,19 +1,80 @@
-Muse
-This software has been brought to you by:
++-------------------------------------------+
+| MusE |
+| This software has been brought to you by: |
++-------------------------------------------+
Name: user: <user> <at> users <dot> sourceforge <dot> net
--------------- ---------
-Administrator:
-Werner Schweer wschweer
-Developers:
-Nil Geisweiller a-lin
-Frank Neumann franky
-Mathias Lundgren lunar_shuttle
-Joachim Schiele qknight
+Active Developers:
+
Robert Jonsson spamatica
Tim Donnelly terminator356
Orcan Ogetbil ogetbilo
Florian Jung flo93
+
+Former Developers:
+
+Werner Schweer wschweer
+Nil Geisweiller a-lin
+Frank Neumann franky
+Mathias Lundgren lunar_shuttle
+Joachim Schiele qknight
+
Fluidsynth logo designed by Josh "Swami" Green.
+
+
+
++------------------+
+| PGP Public Keys: |
++------------------+
+
+Florian Jung:
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.10 (GNU/Linux)
+
+mQENBE/A9gcBCADKNwa/lSJRz73Vfs+IKmmltxnHqGZQvYGJ32nDQny04hdSzlOQ
+XVqyZHYDREpbXHnAPtANJTPozQVWoegxsC9ePEvydw3ezMO9P7hDjanXZvd4egHY
+VLR9ZpLvFx7WJDxTQqD1Zaa4sA7ZzSdDu9kv/Bc8Qx2Qtur5T67THV8Pr8izSFSN
+MKqR5X5fKqkN0+54hTDnj1YguIloYPKVI6+ns9RGOgvbys4rC1X1EqXdkkRXv3OT
+r98udsWNlq+FMmwR+igfzi8+B79V3OAmqUDtpNBAnGgmRW1N6mzv47jRjSX72Ev2
+3HI8GXM2rxrsUyjDuDfgGG2rA0KDnWGpwHZLABEBAAG0JEZsb3JpYW4gSnVuZyA8
+Zmxvcmlhbi5hLmp1bmdAZ214LmRlPokBPgQTAQIAKAUCT8D2BwIbIwUJCWYBgAYL
+CQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQc931Ar+c+qX3GAgAuFsDSSItndVq
+mPeMtjnQDinWAx//trezRoc3puC4mlrvr8dHD6cZ4n/1dPr58kuuGmS9+CzcDgdo
+7HGiY1+rXyZIS2K18Z/YurIfJk7ZRr2QNv0aiuvz5JUh/TunV6OrUqapBb2XBgtW
+lDIDlFMQmWQ+pUq3g4FbjWgdoAJp3BDKniO2fAGqBSrWqLFllFhBI/RChdoVWD2v
+hbYQw+msbZ/cZjx6rDceOxsYr/ltXmfIHTVNpkQ/B9W84xHT64vqW9Z1wKbJ7yOs
+vf1qQ72h6yOTP4Ru17hY6oFNdFkIkkwmJPEmRC0hn2MnvvYOhgl6HwAJc+MM4W/D
+5X2lO73StLQkRmxvcmlhbiBKdW5nIDxmbG9yaWFuLmEuanVuZ0B3ZWIuZGU+iQE+
+BBMBAgAoBQJP7gyJAhsjBQkJZgGABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
+CRBz3fUCv5z6pZPQB/sHAU2Z1LBVQ+ECw5OygLxXhLJOJzbDmoZpbEMrqkndcDLq
+80eyiTx6YfccwqA4NbNItfwMIlVBXg3uCUK9fRKWV3J4BC7geJtkDL2K+7Z/qpbF
+V65OnghJtSyLYVSpKInEsKKAmNMZATZsnkdDrdJ7u953eLw1Y5W8aEa+1n4PYG2d
+jxySbeMLbvfVDrmDwl87RSH1EpuGQCFX0hNqWpUN9OLmx8IP8/j6/jv9U9+2bqbN
+up0O2AkKLNezkGZcXVUzhC8NECd0LTsrGNmSuVo632U2Q0v/AIAAMetqlHfk1DSx
+zzB1hNoca6Yosd/+NTnz8jvDqWBiG8aTjU5fdfijtCpGbG9yaWFuIEp1bmcgPGZs
+bzkzQHVzZXJzLnNvdXJjZWZvcmdlLm5ldD6JAT4EEwECACgFAk/uEfYCGyMFCQlm
+AYAGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEHPd9QK/nPqlHcgH/23gHsd3
+JYUhxAatuVCz1RCcy+iURIBd1Do0kCxCyQVF0NA7Y98AOTLJoyFPNB2Koq0CYunG
+InKGKZN8NFCDUFCmSkNu88PkjDRfNKWCq69z/nfE2OlyvEdAdmWn0FY89VFMvhUj
+NvG9n8g7s8tZciymRny4otjQjPOEmZUZyt5qm4KPfY58R/F+H1AF0E5V0pjwkBrV
+ItI3tsw15bKrvzFddU6pwospRNbyb2dcuedRSbSttnehXGR5w5rr41Myp3slQNVt
+TVbJedjWVQWK5ImIzYj8SRmG+dCXIL75RiWE72ctiy65MN8h/gG1PX/Dt/E3f2vG
+GaBRR0EHueE9ShK5AQ0ET8D2BwEIAMZEvoloCudmQEZ2L7L6FwzfULDyV1dFojbZ
+YiPXXKe4sYrFf7TK5dUsOIsBxQUcUANPzCpFOw84Ii2A7FRDYMzUfyb+KP9vXIVE
+W84WQI6zILN3YowhIa+bSTkQEx+7nn2JORnQp74goxxWKY9HaTtN3v6LgjseljSk
+YxEh8nLo9l1W3d9AYuMNmSv3amzC+p7P66E/+iFGjmKw0Nlb6eJL9iYkFGt+wjgM
+jbm7Rvheq95xtJpYcw6/1iqN7uQdup5ZwAk+PQhDOnM0DAZtbim20OujUP+imUot
+oEJAfG1QojKQqn6hr9hz6i/2BdJNwiss4d6ywILryJUnTFzWypcAEQEAAYkBJQQY
+AQIADwUCT8D2BwIbDAUJCWYBgAAKCRBz3fUCv5z6paB3B/9UISZmdmZD5ExQan1b
+W7Mz/ZvrJe+3jun1C5/ZADvBRgKBYfTA7GbwL6x963ovUXzyWUN16GH7KQca4yaq
+oneJk55s9DBXHzcICtSwnojZVXiZEK1765lna8lFvYEBjYWNR7upR4RlwH7N1P1V
+AVJ8yNJwNNjUu86CJMZ4rVXIie/o/Y/L2PEHZYiXSDfQtxEBKapXjbN2MP1DK4iq
+LexeEJLanIxyWKe1KHFE1W2iPnzVgqfvqv6LuIcMY6vy8/lRXrlne6nEXabMu9tN
+EoTXpkh0hYQzx3WP+CIutORts95i6aBAlo5Cv/67z5xBffeWCp9dmt30rlr/JIYy
+kkXE
+=iCVh
+-----END PGP PUBLIC KEY BLOCK-----
+
diff --git a/muse2/CMakeLists.txt b/muse2/CMakeLists.txt
index 12bf4855..3d91aa7e 100644
--- a/muse2/CMakeLists.txt
+++ b/muse2/CMakeLists.txt
@@ -78,9 +78,9 @@ set(CMAKE_SKIP_RULE_DEPENDENCY TRUE)
SET(MusE_VERSION_MAJOR 2)
SET(MusE_VERSION_MINOR 0)
SET(MusE_VERSION_PATCH 0)
-SET(MusE_VERSION "2.0rc2")
-SET(MusE_VERSION_FULL "2.0rc2")
-SET(MusE_INSTALL_NAME "muse-2.0rc2")
+SET(MusE_VERSION "2.0")
+SET(MusE_VERSION_FULL "2.0")
+SET(MusE_INSTALL_NAME "muse-2.0")
SET(MusE_EXEC_NAME "muse2")
## The directory where we will install the shared components:
@@ -118,7 +118,7 @@ endif (${SVNVER} STREQUAL "SVNVER-NOTFOUND")
option ( ENABLE_LASH "enable LASH Audio Session Handler" ON)
option ( ENABLE_OSC "enable Open Sound Control (DSSI also recommended)" ON)
option ( ENABLE_DSSI "enable Disposable Soft Synth Interface (OSC also recommended)" ON)
-option ( ENABLE_VST "enable VST/win support" OFF)
+option ( ENABLE_VST "enable VST/win support (deprecated)" OFF)
option ( ENABLE_FLUID "enable fluidsynth softsynth plugins" ON)
option ( ENABLE_EXPERIMENTAL "enable building experimental features" OFF)
option ( ENABLE_PYTHON "enable Python control support" OFF)
@@ -268,10 +268,10 @@ else (ENABLE_DSSI)
endif (ENABLE_DSSI)
if (ENABLE_VST)
- message("VST support enabled")
+ message("deprecated VST support enabled")
set (VST_SUPPORT TRUE)
else (ENABLE_VST)
- message("VST support disabled")
+ #message("VST support disabled")
set (VST_SUPPORT FALSE)
endif (ENABLE_VST)
@@ -426,7 +426,7 @@ summary_add("Lash support" HAVE_LASH)
summary_add("OSC (Liblo) support" OSC_SUPPORT)
summary_add("Python support" PYTHON_SUPPORT)
summary_add("DSSI support" DSSI_SUPPORT)
-summary_add("VST support" VST_SUPPORT)
+#summary_add("VST support" VST_SUPPORT)
summary_add("Fluidsynth support" HAVE_FLUIDSYNTH)
summary_add("Experimental features" ENABLE_EXPERIMENTAL)
summary_show()
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index b13301ff..1a526f20 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,78 @@
+30.06.2012:
+ =======================================
+ * 2.0 tagged (rj)
+ =======================================
+ - Emergency crash fix: In automation popup midi control 'Clear' item. (Tim)
+ Cannot delete any actions from menu due to recent December PopupMenu fixes.
+29.06.2012:
+ - Fixed file dialog: disable 'read configuration' for midi files. (Tim)
+ - Updated swedish translation (rj)
+ - reworked the REC button somewhat (rj)
+28.06.2012:
+ - External sync fixes: Now have user-selectable of clock filtering and quantization. (Tim)
+ - Fixed clicking tempo master does not update wave parts. Allow SC_MASTER to call canvas->partsChanged. (Tim)
+ - Fixed problems with recorded wave part and event sizes, and 'past end' indicator. (Tim)
+ - Don't resize or destroy wave events upon part resize. (Tim)
+ - Init support for controlling midi engine from Jack timebase master. Completely disabled for now. (Tim)
+26.06.2012:
+ - Added updated Czech translation from Pavel Fric[pavelfric@seznam.cz] (rj)
+23.06.2012:
+ - automation graphs: deletion with middle-click, fixed automation (flo93)
+ editing.
+18.06.2012:
+ - Removed printouts about no longer supported VST implementation,
+ use DSSI implementation instead (rj)
+ - Some preparations for 2.0 (rj)
+16.06.2012:
+ - MusE as Jack Timebase master: Corrected ticks_per_beat and bar_start_tick fields. (Tim)
+ - Fixed bug by Geoff B and Flo: Changing a midi port device: We are only interested in altering
+ tracks using the port being changed in the midi port list. And don't change channel. (Tim)
+15.06.2012:
+ * Sync fix: MusE now records tempo changes from externally clocked midi. (Tim)
+ Still experimental but non-intrusive: You will be asked at the end of recording if you
+ want to transfer the recorded tempos to the master tempo graph.
+ Tested OK so far with ALSA and Jack midi. Best results ATM may be when recording from
+ position 0, not 'continuing' a recording or skipping 'fwd' or 'rew'.
+ TODO: Record Jack timebase changes! Find patch someone sent years ago, likely still useful...
+11.06.2012:
+ - Finally! Audio controller playback has smooooth frame resolution even with large audio buffers. (Tim)
+ CtrlList::value() now accepts a nextFrame*, filled with next event frame, which the
+ plugin and dssi process use to determine the run sizes.
+ Bonus! This processing is now guaranteed to be ALIGNED with user's chosen minimum control processing
+ period in Settings. Before, it was occasionally going to 1, 2, 4 frame runs etc., was not good.
+ TODO: Sorry, track audio/pan have no 'variable run length' support yet. Choppy with large buffers.
+ Tip: If a ping-pong effect is desired, try a plugin for now!
+ - Increased default minimum controller period from 64 to 256. Tests showed 256 is just fine, smooth.
+10.06.2012:
+ - Add midi-to-audio control popups to right-click automation menus. (Tim)
+ - Track list audio automation popup now can stay open, for colour and 'clear' items. (Tim)
+08.06.2012:
+ * Merge: From branch r2_0_extra. (Tim)
+ - More automation fixes. In AudioTrack::processAutomationEvents, optimize integer, bool,
+ discrete controller types to avoid multiple dots on flat straight-line graph segments. (Tim)
+ - Replaced Song::controllerChange() with a lower-level
+ CtrlList::guiUpdatePending()/clearGuiUpdatePending(). Checked and cleared in
+ Song::beat() at the nice slow heartbeat rate instead of direct calls to QWidget::update().
+ This means ALL controls should update their graphs now, and at a more reasonable rate. (Tim)
+ - ARVT_STOP automation events are also recorded now
+ - When clicking sliders in the plugin's native GUIs or the
+ mixer with SHIFT held down, straight lines are drawn (no
+ intermediate control points are recorded)
+ TODO: does not yet work for muse-native, but customized GUIs (flo)
+07.06.2012:
+ - More automation fixes. (Tim)
+06.06.2012:
+ - Another midi-to-audio mapper classes rewrite. (Tim)
+05.06.2012:
+ - Rewrote midi-to-audio control mapper classes. (Tim...)
+ - Added save and load midi-to-audio settings.
+ - Remap or remove mappers when rack items moved or removed.
+04.06.2012:
+ - Side branch r2_0_extra, copied from release_2_0:
+ * Feature: Midi control of audio paramters. (Tim)
+ - More important timing, accuracy fixes.
+03.06.2012:
+ - Merged documentation from local source to repository LaTeX document, 80% done (rj)
27.05.2012:
* Timing, resolution, accuracy, and automation fixes: (Tim)
- Ask audio driver for 'its' current system time instead of wallclock in utils.cpp:curTime().
@@ -154,7 +229,7 @@
use it instead of setValue().
17.03.2012:
- Custom columns can now either affect tick0 or song->cpos() (flo)
- - hopefully fixed a big in the custom columns dialog (flo)
+ - hopefully fixed a bug in the custom columns dialog (flo)
16.03.2012:
- Custom columns now send their controller changes to the device
automatically if appropriate (flo)
@@ -1612,7 +1687,6 @@
* Renamed: Soft synth configuration changed to Synth configuration, as per patch from Geoff King (rj)
* Fixed: Shortcuts with modifier keys wasn't working for global shortcuts, should be now (rj)
* Added: Shortcuts for changing len of events, default Ctrl+Shift+Left/Right (rj)
->>>>>>> .r459
10.08.2010
* Fixed/Changed: Grid reacts to midi resolution change (rj)
01.08.2010
diff --git a/muse2/README b/muse2/README
index 59655059..3650d817 100644
--- a/muse2/README
+++ b/muse2/README
@@ -99,7 +99,8 @@ details.
--------------
There are a few different ways to configure (notice the two dots):
- Type "cmake -i .." to run in step-by-step 'Wizard' mode.
+ Type "cmake -i .." to run in step-by-step 'Wizard' mode, this is the RECOMMENDED way to
+ setup the build environment.
Or type "cmake -L .." to see options, then compose "cmake <options>" yourself.
Some <options> are:
@@ -210,6 +211,9 @@ details.
=============================
- not so many: only some usability quirks we're working on currently
+ - automation recording displays odd things in the arranger
+ while recording; the display is corrected once recording is
+ complete.
====================================================================
Let us know whether MusE works for you !!!
diff --git a/muse2/README.de b/muse2/README.de
index 04e2c301..75aaf57f 100644
--- a/muse2/README.de
+++ b/muse2/README.de
@@ -11,7 +11,7 @@ Für Einzelheiten siehe COPYING.
,-----------------------------------------------------------------.
| HINWEIS |
|-----------------------------------------------------------------|
-| Viel Teile des Codes von MusE sind EXPERIMENTELL und können |
+| Viele Teile des Codes von MusE sind EXPERIMENTELL und können |
| zu Programmabstürzen und wer weiß was sonst noch allem |
| führen. |
| SIE BENUTZEN DIESE SOFTWARE AUF EIGENES RISIKO! |
@@ -26,27 +26,39 @@ Für Einzelheiten siehe COPYING.
- qt 4.2.0 oder neuer
ftp://ftp.trolltech.com/qt/source
- MsE kompiliert nicht mit alter versionen
+ MsE kompiliert nicht mit älteren Versionen!
+
+ - gcc >= 4.x.x oder clang >= 2.9
+ http://gcc.gnu.org/
+ http://clang.llvm.org/
- libsndfile >= 1.0.1
- http://www.mega-nerd.com/libsndfile/
+ http://www.mega-nerd.com/libsndfile/
+
+ - libsamplerate
+ http://www.mega-nerd.com/SRC/
- JACK >= 0.103
- http://jackit.sourceforge.net/
- download:
- http://jackit.sourceforge.net/download/
+ http://jackaudio.org/
+
+ - libuuid
+ e2fsprogs Paket http://e2fsprogs.sourceforge.net/
+ Einige Distros bieten das eventuell in einem anderen Paket an.
- - fluidsynth-1.0.3 (die synti früher bekannt als "iiwusynth") von
- http://savannah.nongnu.org/download/fluid
+ Optional:
- - Linux Kernel mit rtc (RealTimeClock) Treiber (device /dev/rtc)
- ("low latency patches" für minimales timing-jitter wären fein)
+ - fluidsynth >= 1.0.3 (formerly known as iiwusynth) from
+ http://sourceforge.net/apps/trac/fluidsynth/
- - ALSA von http://www.alsa-project.org/
- Version 0.9.x oder neuer
+ - liblo Lightweight OSC (Open Sound Control) http://liblo.sourceforge.net/
+ - DSSI Disposable Soft Synth Interface. http://dssi.sourceforge.net/
+ (Both recommended - DSSI alone will have no native GUIs, OSC alone does nothing, for now.)
- - gcc >= 4.x.x
+ - dssi-vst Unterstützung für DSSI vst plugins http://www.breakfastquay.com/dssi-vst/
+ - LASH Audio Session Handler http://lash.nongnu.org/
+ Seit neuerem kann LADISH es auch emulieren http://ladish.org/
+
- natürlich: eine Soundkarte und/oder irgendwelche Midi Geräte
=============================
diff --git a/muse2/doc/documentation.tex b/muse2/doc/documentation.tex
index a36fd07c..dabcf738 100644
--- a/muse2/doc/documentation.tex
+++ b/muse2/doc/documentation.tex
@@ -27,10 +27,20 @@
%% neccessary.
%%
%% Whenever referring to code symbols, constants or source/header
-%% files, please use \texttt{someClass::someSymbol} or \texttt{file.cpp}
+%% files, please use \sym{someClass::someSymbol}, \usym{UPPERCASE_THING}
+%% or \f{file.cpp}.
%% Only specify file paths or namespaces where it would be ambiguous
%% otherwise. Specify 'someClass::' until it would disturb the reader
-%% and it is obvious. (watch out to prefix _ with \)
+%% and it is obvious. you have to replace '_' by {\_} (with the {}!).
+%% These macros do automatic hyphenation on Camel-Case, under_-score
+%% and scope::-operator boundaries. If you need to insert additional
+%% hyphenation points, use {\-}.
+%% Example: \sym{someClass::someAb{\-}nor{\-}mal{\-}lyLongName} will
+%% hyphenate: some-Class::-some-Ab-nor-mal-ly-Long-Name
+%%
+%% Whenever referring to URLs, please wrap them in \url{blah}. Key
+%% combinations shall look like \key{CTRL+C}. Menu items shall look
+%% like \menu{Menu > Submenu > Menu Item}.
%%
%% Where possible, reference other parts of this documents with
%% \label and \ref. Avoid duplicate information under "Internals" by
@@ -58,18 +68,343 @@
\documentclass[a4paper]{report}
+\usepackage[a4paper, left=2.5cm, right=2.5cm, top=2.5cm, bottom=2.5cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[english]{babel}
-\author{Florian Jung}
+\usepackage{graphicx}
+\usepackage{hyphenat}
+\usepackage{wrapfig}
+\usepackage{fancyhdr}
+\pagestyle{fancy}
+ \lhead{\scriptsize{\slshape\leftmark}}
+ \chead{}
+ \rhead{\thepage}
+ \lfoot{}
+ \cfoot{}
+ \rfoot{}
+ \renewcommand{\headrulewidth}{0.4pt}
+\usepackage{ifthen}
+
+% Hyphenate symbols before each uppercase letter, after each underscore
+% (without a "-") and after each ':' (without a "-")
+% TODO for any latex crack: also do automatic hyphenation, that is,
+% instead of some-Automation-Expression, do some-Au-to-ma-tion-Ex-press-ion
+\makeatletter
+\newcommand{\camelhyph}[1]{\@fterfirst\c@amelhyph#1\relax }
+\newcommand{\underscorehyph}[1]{\@fterfirst\u@nderscorehyph#1\relax }
+\def\@fterfirst #1#2{#2#1}
+\def\c@amelhyph #1{%
+\ifthenelse{\equal{#1}\relax}{}{% Do nothing if the end has been reached
+ \ifnum`#1=95 \_\hspace{0pt}\else % Check whether #1 is "_", then print _[thin space]
+ \ifnum`#1=58 :\hspace{0pt}\else
+ \ifnum`#1>64
+ \ifnum`#1<91 \-#1\else#1\fi% Check whether #1 is an uppercase letter,
+ \else#1\fi
+ \fi
+ \fi
+ % if so, print \-#1, otherwise #1
+ \expandafter\c@amelhyph% % insert \c@amelhyph again.
+}}
+\def\u@nderscorehyph #1{%
+\ifthenelse{\equal{#1}\relax}{}{% Do nothing if the end has been reached
+ \ifnum`#1=95 \_\hspace{0pt}\else % Check whether #1 is "_", then print _\-
+ \ifnum`#1=58 :\hspace{0pt}\else#1\fi\fi
+ \expandafter\u@nderscorehyph% % insert \u@nderscorehyph again.
+}}
+\makeatother
+
+
+
+\author{Florian Jung, Robert Jonsson}
\title{MusE Documentation}
-\begin{document}
+\newcommand{\url}[1]{\texttt{#1}}
+\newcommand{\key}[1]{\textbf{#1}}
+\newcommand{\shell}[1]{\texttt{\textbf{#1}}}
+\newcommand{\menu}[1]{\textbf{#1}}
+\newcommand{\sym}[1]{\texttt{\camelhyph{#1}}}
+\newcommand{\usym}[1]{\texttt{\underscorehyph{#1}}}
+\newcommand{\file}[1]{\texttt{\camelhyph{#1}}}
+\newcommand{\screenshotwidth}[0]{0.8\textwidth}
+
+
+\begin{document}
+\label{Main/Arranger}
+\begin{figure}[htp]
+\centering
+\includegraphics[width=1.0\textwidth]{pics/muse2}
+\label{fig:MusE}
+\end{figure}
+\chapter {What is this?}
+You are, if you have printed this document, holding in your hand the
+written documentation for the audio and midi sequencer MusE version 2.\\
+\url{http://www.muse-sequencer.org} is MusE's home on the internet where
+everything MusE releated should be possible to find, software, this
+documentation, forums, mailing lists, bug reporting, FAQs. If you have
+this document but not the software head on over there to find what it's
+all about.
\chapter{User's manual}
-someone should really write this!
-\section{Basic overview}
+\section {Introduction}
+\subsection {A brief history of computer audio and MusE}
+To quickly summarize over a decades open source development: in 1999 Werner
+ Schweer released the first version of MusE, muse-0.0.1.tar.gz, in it's first
+few releases (actually not few, Werner relentlessly churned out new releases)
+MusE was only a midi sequencer. The target was to create a fully fledged
+midi sequencer for the Linux operating system. Over the years audio was
+added among with other things implemented and sometimes abandoned.
+Today MusE is a stable and feature rich music creation environment which
+strives to encompass most of the music recording process, creation, editing,
+mastering.
+
+\subsection {Definitions}
+\key{CTRL} refers to the control key on the keyboard, e.g. \key{CTRL+C}
+means to press and hold the control key while pressing the c key. Make sure
+you know where you have it so you won't accidentally lose control
+(bad jokes are the best jokes, so say we all!).\\
+\key{SHIFT} refers to the shift key on the keyboard, see above for usage\\
+\key{ALT} refers to the alt key on the keyboard, see above for usage\\
+\shell{\$>} is used as a generic definition for a terminal prompt. When the
+manual lists a command that shall be typed, the prompt is not part of the
+command.\\
+Keys are always referred to in bold uppercase, e.g. \key{A}. For instance
+\key{SHIFT+A} for the key a pressed together with the shift key.\\
+Sometimes terminal examples are written tabbed in with a fixed font to
+visualize more closely what something looks like on the screen.
+E.g.\\
+\hspace*{1cm}\shell{\$> muse2}\\
+
+\subsection {Getting up and running for impatient people}
+Install MusE from the repository of your chosen distribution.
+To get decent performance start Jack with the following command in a
+terminal:\\
+\hspace*{1cm}\shell{\$> jackd -d alsa -d hw:0 -p 256}\\
+Or, if you prefer, use the launcher utility \textbf{QJackCtl} to get some
+help starting Jack.
+After this, start MusE from the menu or fire up another terminal and type
+\shell{muse2}.\\
+If this didn't work out read on for the slighly more complete route for
+getting things started.
+
+\subsection {Getting up and running}
+\subsubsection {Installation from binaries}
+There are several ways to install MusE depending on your situation. The
+most convenient way is to install a prepackaged version from your chosen
+distribution. The drawback of this is that it may not be the most recent
+version, though often there is a more recent package from a private packager.
+\subsubsection {Installation from source}
+Building MusE from source is not hard, there are a number of prerequistes
+that must be met but the actual building should be painless (ha, famous
+last words).\\
+Please follow the README in the source package and/or read the instructions
+on the homepage: \url{http://muse-sequencer.org/index.php/Installation}
+
+\subsubsection {Hardware}
+MusE on the Linux platform supports midi through ALSA and Jack-midi and audio
+through Jack. For information on what hardware is supported there are some
+convenient places to check:
+\begin {itemize}
+\item Alsa soundcard matrix
+\item \url{http://FFADO.org} for firewire devices.
+\end {itemize}
+Also, as is often a very good approach for Linux and open source, the
+various forums available on the internet often contain good information.
+Chances are someone has already tried your configuration and/or had your
+specific problem and the solution is already written down.
+\subsubsection {Launching}
+After installation the binary muse2 is installed on the computer. If MusE
+was installed from a distribution repository the binary may have a
+different name depending on the distribution policies. Most distributions
+do however install a menu entry so MusE should be conveniently available
+from there.
+\subsubsection {Audio preconditions}
+In the standard case MusE expects to find and connect to the Jack audio
+server \url{http://jackaudio.org}. Make sure jack is installed (if MusE was
+installed with a distribution-package Jack will very likely already be
+installed) For Jack to run with best performance your system should be
+sufficiently tuned to allow it to run with realtime capabilities. The
+realtime configuration is configuration of the operating system and roughly
+consists of two parts.
+\begin {enumerate}
+\item By default on most distros only the superuser lets applications setup
+realtime capabilities. Please see the APPENDIX for setting up realtime
+\item Maximizing performance. A standard linux installation may not able
+to reach the performance required by a power user. This requires exchanging
+the linux kernel for a so called lowlatency kernel, this is also covered by
+the realtime APPENDIX.
+\end {enumerate}
+
+\subsubsection {Running MusE}
+Find MusE in the menu or open a terminal and enter muse2. A splash screen
+should pop up followed by the main application window and you are off!
+\shell{\$> muse2}\\
+If an error like the screenshot below pops up the Jack audio server is
+either not running or started as a different user than what you are trying
+to start MusE as.
+\begin{figure}[htp]
+\centering
+\includegraphics[width=\screenshotwidth]{pics/no_audio}
+\caption{Jack server missing}
+\label{fig:no_audio}
+\end{figure}
+\subsubsection {Midi only}
+MusE can be started in Midi-only mode where MusE does not have any external
+dependencies apart from ALSA midi. In this case start MusE from a terminal:
+\shell{\$> muse2 -a}
+
+\subsection {Beginners tutorial}
+To get a quick grip of what MusE can achieve please follow this beginners
+tutorial.
+\subsubsection {Setup}
+First off, fire up MusE as was described in the previous chapter, making
+sure that the jack audio server is started with sufficient configuration
+to allow for audio output without breakup. Also make sure your system can
+make sound.
+\subsubsection {Soft synth test}
+With MusE up and running right click in the Track-pane (see screenshot in
+~\ref{Main/Arranger}) and select \menu{Add Synth > MESS > Organ}. A Soft
+Synth track called Organ-0 should appear as well as a separate GUI for
+the synthesizer.
+
+Now right click once more in the Track-pane and select \menu{Add Midi
+Track}. Another track appears called Track-1, you will notice that it is
+by default bound to the synth that was just created Organ-0.
+\begin{wrapfigure}{r}{0.05\textwidth}
+\includegraphics[width=0.05\textwidth]{pics/arrow_tool}
+%\hrulefill
+\end{wrapfigure}
+Now select the drawing tool icon
+from the toolbar, alternatively press the shortcut key \key{D}.
+Move the mouse over to the arranger canvas as referenced in ~\ref{Main/Arranger}
+and point at the midi track, the mouse should have changed to a small pencil.
+Draw a Part along the midi track using the mouse. For this exercise it is
+not important where or how large the drawn Part is. When you are done double
+click on the drawn part. This will open up the Piano Roll editor. To the
+left of the Piano Roll there are piano keys in a vertical line, try clicking
+on the keys in this virtual keyboard each click should be rewarded with an
+organ sound (maybe of questionable quality, a sound nevertheless)
+\begin{figure}[htp]
+\centering
+\includegraphics[width=.5\textwidth]{pics/organ_synth}
+\caption{Organ synthesizer}
+\label{fig:organ_synth}
+\end{figure}
+
+\subsubsection {Missing sound}
+If you got sound from the previous exercise you can carry on to the next,
+or keep reading for further enlightenment in case you come upon trouble
+later on. If there are no sound we need to do some fault hunting. First
+of, click on Arranger window once more and select the Organ-0 track in the
+track-pane.
+\begin{figure}[ht]
+\centering
+\includegraphics[width=\screenshotwidth]{pics/main_window_with_midi_editor}
+\caption{Midi editor view}
+\label{fig:Midi editor}
+\end{figure}
+Now bring back Piano Roll window and align the windows so you
+can see the piano keys as well as the Meter on the Mixer Strip (see the
+5 Function by function chapter for more information on these windows).
+The result should be something like the following:
+
+When pressing one of the keys on virtual Keyboard the Meter on the Mixer
+Strip should light up in green to visualize that the Synth is making
+sound, if it is not try to trace back your steps and and see if you did
+anything differently than described.
+Now, if the Meter lights up but there is still no sound we need to to
+check the routing between the tracks. Click on the Arranger window again
+and select the Out 1 track, this is the predefined output which MusE by
+default loads at startup, at the bottom of Mixer Strip there are two
+buttons looking like tele- jacks, these bring up the inputs and outputs
+of the track, click on the right one, the output and make sure that it is
+connected to some valid outputs on your system.
+\begin{wrapfigure}{r}{0.25\textwidth}
+\includegraphics[width=0.25\textwidth]{pics/output_routing}
+%\hrulefill
+\end{wrapfigure}
+Click on the outputs to select them, if you did changes here go back and
+try clicking on the Piano Roll keyboard again, hopefully it helped. If there
+ still are problems make sure your system actually can make sound through
+Jack, this is however getting outside the scope of this manual.\\\\
+\textit{This might be the time to bring up the concept of community support.
+Open source software could never be what it is without the support given by
+individuals on forums and mailinglists, if the information given in this
+document is not enough, try googling your problem and/or get in touch with
+one of the online forums for MusE or Linux audio in general. See some pointers
+in the Support chapter.}
+
+\subsubsection {Recording} %TODO: walkthrough of recording midi
+TBD
+
+
+\section {Basic overview}
+In this section we will make a step by step walk-through of all the
+different editors, their purpose and what functions they support.
+
+\subsection{Main/Arranger}
+
+\label{Main/Arranger}
+\begin{figure}[htp]
+\centering
+\includegraphics[width=\screenshotwidth]{pics/main_window_annotated}
+\caption{MusE main window}
+\label{fig:Main Window}
+\end{figure}
+Above is the main window of MusE, the Arranger, this is what greets you
+when launching MusE. The Arranger consists of two main parts, the Track-pane
+and the Arranger canvas. The Track-pane lists all currently visible tracks
+and the Arranger canvas contains all Parts of the composition. The
+screenshot above shows an empty project. Below is MusE with a song in
+progress, turns out it wasn't a very good song, but for our purposes it
+is fine. In the below screenshot there are a lot of tracks visible in the
+Track-pane, each have an icon which indicate it's type, wave-trace, input,
+output etcetera, more about that later. In the Arranger canvas a number of
+parts are visible, the ones in yellow are in this composition wave files,
+the multicolored line are different Parts of a drum track.
+\label{Main/Arranger}
+\begin{figure}[htp]
+\centering
+\includegraphics[width=\screenshotwidth]{pics/main_window_with_arrangement}
+\caption{MusE main window with arrangement}
+\label{fig:Main Window with arrangement}
+\end{figure}
+
+\subsection{Mixer}
+Choosing \menu{View > Mixer A} or \menu{B} from the menu in the main
+window will bring up the mixer as viewed below. The mixer will with all
+options enabled show channel strips for all tracks in the current setup,
+depending on how far you have gotten this view may become very large,
+at which point it may be a good idea to limit what is viewed in the
+Mixer. From the view menu all the different kinds of tracks can be
+toggled on/off from the mixer. Some may find it a good idea to use the
+two mixers A and B setup with different setup and store this in your
+song template(s), more about this in the Song Template section. It can
+be argued that everything in MusE is a track analogous to the Unix
+idiom that everything is a file.
+The types of tracks viable in the mixer (and track-pane) are:
+\begin{wrapfigure}{r}{0.5\textwidth}
+\includegraphics[width=0.5\textwidth]{pics/mixer}
+%\hrulefill
+\end{wrapfigure}
+\begin {itemize}
+\item Audio output
+\item Audio input
+\item Group track
+\item Aux track
+\item Wave track
+\item Synth track
+\item Midi track
+\end{itemize}
+
+
+There are also a Midi Track variation called Drum Track, they are
+however not distinguishable from Midi Tracks in the Mixer. Also the
+strips for midi tracks are different in the Mixer than in the
+Track-pane view.
+
+
\subsection{Tracks}
MusE arranges your music in \emph{tracks} and \emph{parts}. The following
section shall provice you an overview of how things are done with MusE.
@@ -202,16 +537,16 @@ copied, cloned and deleted independent from other parts.
Parts are created by selecting the pencil tool and then drawing onto
the right part area in the arranger. You can move them with the arrow
-tool, delete them using the \texttt{DEL} key, and a right-click opens
+tool, delete them using the \key{DEL} key, and a right-click opens
a popup menu. This menu allows you even more stuff, such as setting
the part's color, saving the part to disk etc.. You can use
-\texttt{CTRL+C} and \texttt{CTRL+V} for copying and pasting parts.
-\texttt{CTRL+B} pastes the part as a clone. Pressing \texttt{SHIFT}
+\key{CTRL+C} and \key{CTRL+V} for copying and pasting parts.
+\key{CTRL+B} pastes the part as a clone. Pressing \key{SHIFT}
additionally provides you a dialog which allows you to paste the part
multiple times and set more stuff.
You can also copy parts with the mouse by moving the part with the mouse
-while holding down the \texttt{CTRL} key.
+while holding down the \key{CTRL} key.
@@ -253,31 +588,94 @@ For details on \emph{why} stuff is done please refer to the following
chapter.
\section{User controls and automation}
\subsection{Handling user input}
-\paragraph{Plugins and synthesizers}
+\subsubsection{Plugins and synthesizers}
+\paragraph{Overview}
When the user launches a plugin's GUI, either a MusE-window with
the relevant controls is shown, or the native GUI is launched. MusE
will communicate with this native GUI through OSC (Open Sound Control).
+The relevant classes are \sym{PluginGui}, \sym{PluginIBase}
+(in \file{plugin.h}) and \sym{OscIF} (in \sym{osc.h}).
-The relevant classes are \texttt{PluginGui}, \texttt{PluginIBase}
-(in \texttt{plugin.h}) and \texttt{OscIF} (in \texttt{osc.h}).
-
-If the user changes a slider, first the corresponding control is
+If the user changes a GUI element, first the corresponding control is
disabled, making MusE not steadily update it through automation
-while the user operates it. \texttt{PluginIBase::setParam} is called,
+while the user operates it. Then MusE will update the plugin's parameter
+value, and also record the new value. When appropriate, the controller
+is enabled again.
+
+\paragraph{Processing the input, recording}
+Upon operating a slider, \sym{PluginIBase::setParam} is called,
which usually writes the control change into the ringbuffer
-\texttt{PluginI::\_controlFifo}. (\texttt{PluginI::apply()},
-\texttt{DssiSynthIF::getData()} will read this ringbuffer and
-do the processing accordingly). Furthermore, the change is written
-into a "to be recorded"-list (done by calling \texttt{AudioTrack::recordAutomation}).
-This list is processed after recording has finished. %TODO: where and when exactly?
+\sym{PluginI::{\_}controlFifo}. (\sym{PluginI::apply()},
+\sym{DssiSynthIF::getData()} will read this ringbuffer and
+do the processing accordingly). Furthermore, \sym{AudioTrack::recordAutomation}
+is called, which either directly modifies the controller lists or writes
+the change into a "to be recorded"-list (\sym{AudioTrack::{\_}recEvents})
+(depending on whether the song is stopped or played).
+
+The \sym{AudioTrack::{\_}recEvents} list consists of \sym{CtrlRecVal}
+items (see \file{ctrl.h}), which hold the following data:
+\begin{itemize}
+\item the frame where the change occurred
+\item the value
+\item the type, which can be \usym{ARVT{\_}START}, \usym{ARVT{\_}VAL} or \usym{ARVT{\_}STOP}.
+ \usym{ARVT{\_}VAL} are written by every \usym{AudioTrack::recordAutomation}
+ call, \usym{ARVT{\_}START} and \usym{ARVT{\_}STOP} are generated by
+ \sym{AudioTrack::startAutoRecord} and \sym{stopAutoRecord},
+ respectively.
+\item and the id of the controller which is affected
+\end{itemize}
+It is processed when the song is stopped. The call path for this is:
+\sym{Song::stopRolling} calls \sym{Song::processAutomationEvents}
+calls \sym{AudioTrack::processAutomationEvents}.
+This function removes the old events from the track's controller list
+and replaces them with the new events from \sym{{\_}recEvents}. In
+\usym{AUTO{\_}WRITE} mode, just all controller events within the recorded
+range are erased; in \usym{AUTO{\_}TOUCH} mode, the \usym{ARVT{\_}START}
+and \usym{ARVT{\_}STOP} types of the \sym{CtrlRecVal} events are used
+to determine the range(s) which should be wiped.
+
+\paragraph{How it's stored}
+Automation data is kept % this is copied from
+in \sym{AudioTrack::{\_}controller}, which is a \sym{CtrlListList}, % "design decisions" -> "automation"
+that is, a list of \sym{CtrlList}s, that is, a list of lists of
+controller-objects which hold the control points of the automation graph.
+The \sym{CtrlList} also stores whether the list is meant discrete
+(a new control point results in a value-jump) or continous (a new control
+point results in the value slowly sloping to the new value).
+Furthermore, it stores a \sym{{\_}curVal} (accessed by \sym{curVal()}),
+which holds the currently active value, which can be different from the
+actually stored value because of user interaction. This value is also
+used when there is no stored automation data.
+
+\sym{AudioTrack::addController} and \sym{removeController} are used % TODO: swapControllerIDX??
+to add/remove whole controller types; the most important functions which
+access \sym{{\_}controller} are:
+\begin{itemize}
+\item \sym{processAutomationEvents}, \sym{recordAutomation},
+ \sym{startAutoRecord}, \sym{stopAutoRecord}: see above.
+\item \sym{seekPrevACEvent}, \sym{seekNextACEvent}, \sym{eraseACEvent},
+ \sym{eraseRangeACEvents}, \sym{addACEvent}, \sym{changeACEvent},
+ which do the obvious
+\item \sym{pluginCtrlVal}, \sym{setPluginCtrlVal}: the first
+ returns the current value according to the \sym{{\_}controller}
+ list, the second only sets the \sym{curVal}, but does not
+ insert any events.
+\end{itemize}
+
+Whenever a \sym{CtrlList} has been manipulated,
+\sym{MusEGlobal::song->controllerChange(Track*)} shall be called,
+which emits the \sym{MusEGlobal::song->controllerChanged(Track*)}
+signal in order to inform any parts of MusE about the change (currently,
+only the arranger's part canvas utilizes this).
+\paragraph{Enabling and disabling controllers}
Disabling the controller is both dependent from the current automation
mode and from whether the GUI is native or not.
-In \texttt{AUTO\_WRITE} mode, once a slider is touched (for MusE-GUIs) or
+In \usym{AUTO{\_}WRITE} mode, once a slider is touched (for MusE-GUIs) or
once a OSC control change is received (for native GUIs), the control
is disabled until the song is stopped or seeked.
-In \texttt{AUTO\_TOUCH} (and currently (r1492) \texttt{AUTO\_READ}, but
+In \usym{AUTO{\_}TOUCH} (and currently (r1492) \usym{AUTO{\_}READ}, but
that's to be fixed) mode, once a MusE-GUI's slider is pressed down, the
corresponding control is disabled. Once the slider is released, the
control is re-enabled again. Checkboxes remain in "disabled" mode,
@@ -289,31 +687,31 @@ and the last toggle.). For native GUIs, this is a bit tricky, because
we don't have direct access to the GUI widgets. That is, we have no
way to find out whether the user doesn't touch a control at all, or
whether he has it held down, but just doesn't operate it. The current
-behaviour for native GUIs is to behave like in \texttt{AUTO\_WRITE} mode.
-
-The responsible functions are: \texttt{PluginI::oscControl} and
-\texttt{DssiSynthIF::oscControl} for handling native GUIs,
-\texttt{PluginI::ctrlPressed} and \texttt{ctrlReleased} for MusE
-default GUIs and \texttt{PluginI::guiParamPressed},
-\texttt{guiParamReleased}, \texttt{guiSliderPressed} and
-\texttt{guiSliderReleased} for MusE GUIs read from a UI file;
-\texttt{guiSlider*} obviously handle sliders, while \texttt{guiParam*}
+behaviour for native GUIs is to behave like in \usym{AUTO{\_}WRITE} mode.
+
+The responsible functions are: \sym{PluginI::oscControl} and
+\sym{DssiSynthIF::oscControl} for handling native GUIs,
+\sym{PluginI::ctrlPressed} and \sym{ctrlReleased} for MusE
+default GUIs and \sym{PluginI::guiParamPressed},
+\sym{guiParamReleased}, \sym{guiSliderPressed} and
+\sym{guiSliderReleased} for MusE GUIs read from a UI file;
+\sym{guiSlider*} obviously handle sliders, while \sym{guiParam*}
handle everything else which is not a slider. They call
-\texttt{PluginI::enableController} to enable/disable it.
+\sym{PluginI::enableController} to enable/disable it.
-Furthermore, on every song stop or seek, \texttt{PluginI::enableAllControllers}
+Furthermore, on every song stop or seek, \sym{PluginI::enableAllControllers}
is called, which re-enables all controllers again. The call paths for
this are:
\begin{itemize}
-\item For stop: \texttt{Song::stopRolling} calls
- \texttt{Song::processAutomationEvents} calls
- \texttt{Song::clearRecAutomation} calls
- \texttt{Track::clearRecAutomation} calls
- \texttt{PluginI::enableAllControllers}
-\item For seek: \texttt{Audio::seek} sends a message ("\texttt{G}") to
- \texttt{Song::seqSignal} which calls
- \texttt{Song::clearRecAutomation} which calls
- \texttt{PluginI::enableAllControllers}
+\item For stop: \sym{Song::stopRolling} calls
+ \sym{Song::processAutomationEvents} calls
+ \sym{Song::clearRecAu{\-}to{\-}ma{\-}tion} calls
+ \sym{Track::clearRecAutomation} calls
+ \sym{PluginI::enableAllControllers}
+\item For seek: \sym{Audio::seek} sends a message ("\sym{G}") to
+ \sym{Song::seqSignal} which calls
+ \sym{Song::clearRecAutomation} which calls
+ \sym{PluginI::enableAllControllers}
\end{itemize}
@@ -323,15 +721,15 @@ this are:
\section{Automation}
As of revision 1490, automation is handled in two ways: User-generated
(live) automation data (generated by the user moving sliders while playing)
-is fed into \texttt{PluginI::\_controlFifo}. Automation data is kept
-in \texttt{AudioTrack::\_controller}, which is a \texttt{CtrlListList},
-that is, a list of \texttt{CtrlList}s, that is, a list of lists of
+is fed into \sym{PluginI::{\_}controlFifo}. Automation data is kept
+in \sym{AudioTrack::{\_}controller}, which is a \sym{CtrlListList},
+that is, a list of \sym{CtrlList}s, that is, a list of lists of
controller-objects which hold the control points of the automation graph.
-The \texttt{CtrlList} also stores whether the list is meant discrete
+The \sym{CtrlList} also stores whether the list is meant discrete
(a new control point results in a value-jump) or continous (a new control
point results in the value slowly sloping to the new value).
-While \texttt{PluginI::\_controlFifo} can be queried very quickly and
+While \sym{PluginI::{\_}controlFifo} can be queried very quickly and
thus is processed with a very high resolution (only limited by the
minimum control period setting), the automation value are expensive to
query, and are only processed once in an audio \emph{driver} period.
@@ -340,16 +738,16 @@ This might lead to noticeable jumps in value.
This could possibly be solved in two ways:
\paragraph{Maintaining a slave control list}
This approach would maintain a fully redundant slave control list,
-similar to \texttt{PluginI::\_controlFifo}. This list must be updated
+similar to \sym{PluginI::{\_}controlFifo}. This list must be updated
every time any automation-related thing is changed, and shall contain
every controller change as a tuple of controller number and value.
-This could be processed in the same loop as \texttt{PluginI::\_controlFifo},
+This could be processed in the same loop as \sym{PluginI::{\_}controlFifo},
making it comfortable to implement; furthermore, it allows to cleanly
offer automation-settings at other places in future (such as storing
automation data in parts or similar).
\paragraph{Holding iterators}
-We also could hold a list of iterators of the single \texttt{CtrlList}s.
+We also could hold a list of iterators of the single \sym{CtrlList}s.
This would also cause low CPU usage, because usually, the iterators only
need to be incremented once. However, it is pretty complex to implement,
because the iterators may become totally wrong (because of a seek in the
@@ -550,5 +948,62 @@ slots shall either also display the key change (if they're score slots)
or display a gap. Events which happen at the same time shall be at the
same x-coordinate, regardless which slot they are.
+\section{Controller master values}
+All controllers (MIDI-controllers and also automation controllers)
+shall have one set of "master values" which allow you to set a gain and
+a bias. Instead of the actual set value, $\textrm{value} * \textrm{bias}
++ textrm{bias}$ shall be sent to the MIDI device / the plugin. For
+controllers like "pan", the unbiased values shall be transformed, that
+is, a pan of 64, with $\textrm{bias}=2$ and $\textrm{gain}=0.5$, shall
+be transformed to 66 (because 64 is actually 0, while 0 is actually -64).
+These values shall be set in the arranger and whereever the actual
+controller/automation values can be edited.
+
+\section{Enabled-indicator while recording}
+The MusE-plugin-GUIs shall display a small LED displaying whether a
+controller is currently enabled or disabled. By clicking this LED, the
+enabled state shall be switched.
+
+Furthermore, there shall be a dedicated window which only lets you switch
+enabled/disabled states. This will be useful when using external GUIs
+or the MIDI-controller-to-automation feature, to re-enable a controller
+when in \usym{AUTO{\_}TOUCH} mode.
+
+
+
+\section{Linear automation editing}
+While holding some modifier key (like shift), operating the MusE-native-
+GUI sliders shall only generate control points when clicking and when
+releasing the slider. This will result in linear graphs for continous
+controllers, and in large steps for discrete controllers (which is in
+particular useful for stuff like "which low/high-pass filter type to use").
+
+Maybe make this behaviour default for discrete controllers?
+
+
\end{document}
+
+% TODO: song type etc? kill it!
+% song len box: same
+
+% TODO: unified automation and midi ctrls:
+% both shall be editable through the same editors
+% four modes: 1. discrete
+% 2. continous (plus a global and per-port setting for the max rate)
+% 3. switch (not necessarily ON/OFF; signals with color plus text annotation)
+% 4. raw (no graph, instead a box with the value sent out (for "all voices off")
+% they shall be copy-and-pastable, at least between compatible modes
+% they shall be slotted, like pianoroll
+% maybe also "overlapping", like arranger (?)
+% midi recording tries to make out straight lines (like non-ended automation streams)
+%
+
+
+% new song (in general: load as template) plus "overwrite port config"
+% should re-create the default jack devices and autoconnect them.
+
+% what's audio aux for?
+
+% bug in arranger/pcanvas/automation: if a controlpoint is directly on
+% a line of another ctrl graph, you can't click it
diff --git a/muse2/doc/pics/arrow_tool.png b/muse2/doc/pics/arrow_tool.png
new file mode 100644
index 00000000..1ae872fb
--- /dev/null
+++ b/muse2/doc/pics/arrow_tool.png
Binary files differ
diff --git a/muse2/doc/pics/bad_timing.png b/muse2/doc/pics/bad_timing.png
new file mode 100644
index 00000000..bf5c5c4f
--- /dev/null
+++ b/muse2/doc/pics/bad_timing.png
Binary files differ
diff --git a/muse2/doc/pics/main_window.png b/muse2/doc/pics/main_window.png
new file mode 100644
index 00000000..9739e0a7
--- /dev/null
+++ b/muse2/doc/pics/main_window.png
Binary files differ
diff --git a/muse2/doc/pics/main_window_annotated.png b/muse2/doc/pics/main_window_annotated.png
new file mode 100644
index 00000000..f8f7701f
--- /dev/null
+++ b/muse2/doc/pics/main_window_annotated.png
Binary files differ
diff --git a/muse2/doc/pics/main_window_with_arrangement.png b/muse2/doc/pics/main_window_with_arrangement.png
new file mode 100644
index 00000000..8d391d9f
--- /dev/null
+++ b/muse2/doc/pics/main_window_with_arrangement.png
Binary files differ
diff --git a/muse2/doc/pics/main_window_with_midi_editor.png b/muse2/doc/pics/main_window_with_midi_editor.png
new file mode 100644
index 00000000..435cc655
--- /dev/null
+++ b/muse2/doc/pics/main_window_with_midi_editor.png
Binary files differ
diff --git a/muse2/doc/pics/main_window_with_tracks.png b/muse2/doc/pics/main_window_with_tracks.png
new file mode 100644
index 00000000..d69ee427
--- /dev/null
+++ b/muse2/doc/pics/main_window_with_tracks.png
Binary files differ
diff --git a/muse2/doc/pics/mixer.png b/muse2/doc/pics/mixer.png
new file mode 100644
index 00000000..22d9f2b7
--- /dev/null
+++ b/muse2/doc/pics/mixer.png
Binary files differ
diff --git a/muse2/doc/pics/mixer_strip.png b/muse2/doc/pics/mixer_strip.png
new file mode 100644
index 00000000..5bfd757b
--- /dev/null
+++ b/muse2/doc/pics/mixer_strip.png
Binary files differ
diff --git a/muse2/doc/pics/muse2.png b/muse2/doc/pics/muse2.png
new file mode 100644
index 00000000..84a28d8a
--- /dev/null
+++ b/muse2/doc/pics/muse2.png
Binary files differ
diff --git a/muse2/doc/pics/no_audio.png b/muse2/doc/pics/no_audio.png
new file mode 100644
index 00000000..1e62245c
--- /dev/null
+++ b/muse2/doc/pics/no_audio.png
Binary files differ
diff --git a/muse2/doc/pics/organ_synth.png b/muse2/doc/pics/organ_synth.png
new file mode 100644
index 00000000..a81ff876
--- /dev/null
+++ b/muse2/doc/pics/organ_synth.png
Binary files differ
diff --git a/muse2/doc/pics/output_routing.png b/muse2/doc/pics/output_routing.png
new file mode 100644
index 00000000..08af67fa
--- /dev/null
+++ b/muse2/doc/pics/output_routing.png
Binary files differ
diff --git a/muse2/grepmidi/grepmidi.cpp b/muse2/grepmidi/grepmidi.cpp
index 6e1aabbd..4cb0632f 100644
--- a/muse2/grepmidi/grepmidi.cpp
+++ b/muse2/grepmidi/grepmidi.cpp
@@ -128,7 +128,6 @@ int grepTrack(FILE* f, int trackno)
{
// printf("TRACK %d\n", trackno);
int mtype, mlen;
- int b;
char* buffer;
char tmp[4];
@@ -156,7 +155,7 @@ int grepTrack(FILE* f, int trackno)
case 0xa0:
case 0xb0:
case 0xe0:
- b = getc(f);
+ getc(f);
++cpos;
case 0xc0:
case 0xd0:
diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp
index 29e69582..8d786311 100644
--- a/muse2/muse/arranger/arranger.cpp
+++ b/muse2/muse/arranger/arranger.cpp
@@ -531,7 +531,7 @@ Arranger::Arranger(ArrangerView* parent, const char* name)
connect(canvas, SIGNAL(dropMidiFile(const QString&)), SIGNAL(dropMidiFile(const QString&)));
connect(canvas, SIGNAL(toolChanged(int)), SIGNAL(toolChanged(int)));
- connect(MusEGlobal::song, SIGNAL(controllerChanged(MusECore::Track*)), SLOT(controllerChanged(MusECore::Track*)));
+ connect(MusEGlobal::song, SIGNAL(controllerChanged(MusECore::Track*, int)), SLOT(controllerChanged(MusECore::Track*, int)));
configChanged(); // set configuration values
if(canvas->part())
@@ -677,7 +677,7 @@ void Arranger::songChanged(int type)
// 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.
+ SC_SIG | SC_TEMPO | SC_MASTER)) // Maybe sig. Requires tempo.
canvas->partsChanged();
if (type & SC_SIG)
@@ -1110,9 +1110,9 @@ void Arranger::clear()
// emit redirectWheelEvent(ev);
// }
-void Arranger::controllerChanged(MusECore::Track *t)
+void Arranger::controllerChanged(MusECore::Track *t, int ctrlId)
{
- canvas->controllerChanged(t);
+ canvas->controllerChanged(t, ctrlId);
}
//---------------------------------------------------------
diff --git a/muse2/muse/arranger/arranger.h b/muse2/muse/arranger/arranger.h
index e51ec068..60390a8f 100644
--- a/muse2/muse/arranger/arranger.h
+++ b/muse2/muse/arranger/arranger.h
@@ -186,7 +186,7 @@ class Arranger : public QWidget {
void setTool(int);
void updateTrackInfo(int flags);
void configChanged();
- void controllerChanged(MusECore::Track *t);
+ void controllerChanged(MusECore::Track *t, int ctrlId);
void focusCanvas();
public:
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index cc23b59b..c5c3ca6d 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -904,12 +904,25 @@ bool PartCanvas::mousePress(QMouseEvent* event)
}
}
case AutomationTool:
- if (event->button() & Qt::RightButton) {
- QMenu *automationMenu = new QMenu(this);
- QAction* act;
- act = automationMenu->addAction(tr("Remove selected"));
- act = automationMenu->exec(event->globalPos());
- if (act && automation.currentTrack) {
+ if (event->button() & Qt::RightButton ||
+ event->button() & Qt::MidButton) {
+
+ bool do_delete;
+
+ if (event->button() & Qt::MidButton) // mid-click
+ do_delete=true;
+ else // right-click
+ {
+ QMenu *automationMenu = new QMenu(this);
+ QAction* act;
+ act = automationMenu->addAction(tr("Remove selected"));
+ act = automationMenu->exec(event->globalPos());
+ if (act)
+ do_delete=true;
+ else
+ do_delete=false;
+ }
+ if (do_delete && automation.currentTrack) {
foreach(int frame, automation.currentCtrlFrameList)
MusEGlobal::audio->msgEraseACEvent((MusECore::AudioTrack*)automation.currentTrack,
automation.currentCtrlList->id(), frame);
@@ -2683,6 +2696,7 @@ void PartCanvas::cmd(int cmd)
case 0: paste_mode=PASTEMODE_MIX; break;
case 1: paste_mode=PASTEMODE_MOVEALL; break;
case 2: paste_mode=PASTEMODE_MOVESOME; break;
+ default: paste_mode=PASTEMODE_MIX; // shall never be executed
}
paste(paste_dialog->clone, paste_mode, paste_dialog->all_in_one_track,
@@ -3411,7 +3425,7 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect)
yy += th;
}
- unsigned int startPos = MusEGlobal::audio->getStartRecordPos().tick();
+ unsigned int startPos = MusEGlobal::extSyncFlag.value() ? MusEGlobal::audio->getStartExternalRecTick() : MusEGlobal::audio->getStartRecordPos().tick();
if (MusEGlobal::song->punchin())
startPos=MusEGlobal::song->lpos();
int startx = mapx(startPos);
@@ -3663,19 +3677,36 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, MusECore::AudioTra
bool checkIfOnLine(double mouseX, double mouseY, double firstX, double lastX, double firstY, double lastY, int circumference)
{
- double proportion = (mouseX-firstX)/(lastX-firstX);
-
- // 10 X(15) 20
- // proportion = 0.5
- // 10
- // /
- // Y(5)
- // /
- // 1
- double calcY = (lastY-firstY)*proportion+firstY;
- if(ABS(calcY-mouseY) < circumference || (lastX == firstX && ABS(mouseX-lastX) < circumference))
- return true;
- return false;
+ if (lastX==firstX)
+ return (ABS(mouseX-lastX) < circumference);
+ else if (mouseX < firstX || mouseX > lastX+circumference) // (*)
+ return false;
+ else
+ {
+ double proportion = (mouseX-firstX)/(lastX-firstX); // a value between 0 and 1, where firstX->0 and lastX->1
+ double calcY = (lastY-firstY)*proportion+firstY; // where the drawn line's y-coord is at mouseX
+ double slope = (lastY-firstY)/(lastX-firstX);
+
+ return (ABS(calcY-mouseY) < (circumference * sqrt(1+slope*slope)));
+ // this is equivalent to circumference / cos( atan(slope) ). to
+ // verify, draw a sloped line (the graph), a 90°-line to it with
+ // length "circumference". from the (unconnected) endpoint of that
+ // line, draw a vertical line down to the sloped line.
+ // use slope=tan(alpha) <==> alpha=atan(slope) and
+ // cos(alpha) = adjacent side / hypothenuse (hypothenuse is what we
+ // want, and adjacent = circumference).
+ // to optimize: this looks similar to abs(slope)+1
+
+ //return (ABS(calcY-mouseY) < circumference);
+ }
+
+ /* without the +circumference in the above if statement (*), moving
+ * the mouse towards a control point from the right would result in
+ * the line segment from the targeted point to the next to be con-
+ * sidered, but not the segment from the previous to the targeted.
+ * however, only points for which the line segment they _end_ is
+ * under the cursor are considered, so we need to enlengthen this
+ * a bit (flo93)*/
}
//---------------------------------------------------------
@@ -3684,12 +3715,7 @@ bool checkIfOnLine(double mouseX, double mouseY, double firstX, double lastX, do
bool checkIfNearPoint(int mouseX, int mouseY, int eventX, int eventY, int circumference)
{
- int x1 = ABS(mouseX - eventX) ;
- int y1 = ABS(mouseY - eventY);
- if (x1 < circumference && y1 < circumference) {
- return true;
- }
- return false;
+ return (ABS(mouseX - eventX) < circumference && ABS(mouseY - eventY) < circumference);
}
//---------------------------------------------------------
@@ -3703,7 +3729,7 @@ bool checkIfNearPoint(int mouseX, int mouseY, int eventX, int eventY, int circum
// controller added.
//---------------------------------------------------------
-void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, bool NOTaddNewCtrl)
+void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, bool /*NOTaddNewCtrl*/)
{
if (t->isMidiTrack())
return;
@@ -3751,7 +3777,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo
}
else // we have automation, loop through it
{
- for (; ic !=cl->end(); ic++)
+ for (; ic!=cl->end(); ic++)
{
double y = ic->second.val;
if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume
@@ -3774,7 +3800,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo
eventOldX = eventX;
eventOldY = eventY;
-
+
if (onLine) {
if (!onPoint) {
QWidget::setCursor(Qt::CrossCursor);
@@ -3799,7 +3825,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo
// check if we are reasonably close to a line, we only need to check Y
// as the line is straight after the last controller
//printf("post oldX:%d oldY:%d xpixel:%d ypixel:%d currX:%d currY:%d\n", oldX, oldY, xpixel, ypixel, currX, currY);
- if(mouseX >= eventX && eventY == eventOldY && ABS(mouseY-eventY) < circumference) {
+ if(mouseX >= eventX && ABS(mouseY-eventY) < circumference) {
QWidget::setCursor(Qt::CrossCursor);
automation.controllerState = addNewController;
automation.currentCtrlList = cl;
@@ -3817,7 +3843,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo
setCursor();
}
-void PartCanvas::controllerChanged(MusECore::Track* t)
+void PartCanvas::controllerChanged(MusECore::Track* t, int)
{
redraw((QRect(0, mapy(t->y()), width(), rmapy(t->height())))); // TODO Check this - correct?
}
diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h
index ab227eb2..1b766c5d 100644
--- a/muse2/muse/arranger/pcanvas.h
+++ b/muse2/muse/arranger/pcanvas.h
@@ -184,7 +184,7 @@ class PartCanvas : public Canvas {
public slots:
void redirKeypress(QKeyEvent* e) { keyPress(e); }
- void controllerChanged(MusECore::Track *t);
+ void controllerChanged(MusECore::Track *t, int CtrlId);
};
} // namespace MusEGui
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index 3d831ba9..05e23321 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -22,6 +22,8 @@
#include <cmath>
+#include <QAction>
+#include <QActionGroup>
#include <QKeyEvent>
#include <QLineEdit>
#include <QMessageBox>
@@ -35,6 +37,7 @@
#include <QIcon>
#include <QSpinBox>
#include <QToolTip>
+#include <QList>
#include "popupmenu.h"
#include "globals.h"
@@ -64,6 +67,8 @@
#include "menutitleitem.h"
#include "arranger.h"
#include "undo.h"
+#include "midi_audio_control.h"
+#include "ctrl.h"
#ifdef DSSI_SUPPORT
#include "dssihost.h"
@@ -1409,18 +1414,21 @@ MusECore::TrackList TList::getRecEnabledTracks()
void TList::changeAutomation(QAction* act)
{
- if ( (editAutomation->type() == MusECore::Track::MIDI) || (editAutomation->type() == MusECore::Track::DRUM) || (editAutomation->type() == MusECore::Track::NEW_DRUM) ) {
- printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n");
+ if(!editAutomation || editAutomation->isMidiTrack())
+ return;
+ if(act->data().toInt() == -1)
return;
- }
int colindex = act->data().toInt() & 0xff;
- int id = (act->data().toInt() & 0x00ffffff) / 256;
+ int id = (act->data().toInt() & 0x00ffffff) >> 8;
+ // Is it the midi control action or clear action item?
+ if (colindex == 254 || colindex == 255)
+ return;
+
if (colindex < 100)
return; // this was meant for changeAutomationColor
// one of these days I'll rewrite this so it's understandable
// this is just to get it up and running...
-
MusECore::CtrlListList* cll = ((MusECore::AudioTrack*)editAutomation)->controller();
for(MusECore::CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll) {
MusECore::CtrlList *cl = icll->second;
@@ -1435,13 +1443,81 @@ void TList::changeAutomation(QAction* act)
//---------------------------------------------------------
void TList::changeAutomationColor(QAction* act)
{
- if ( (editAutomation->type() == MusECore::Track::MIDI) || (editAutomation->type() == MusECore::Track::DRUM) || (editAutomation->type() == MusECore::Track::NEW_DRUM) ) {
- printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n");
+ if(!editAutomation || editAutomation->isMidiTrack())
+ return;
+ if(act->data().toInt() == -1)
return;
- }
int colindex = act->data().toInt() & 0xff;
- int id = (act->data().toInt() & 0x00ffffff) / 256;
+ int id = (act->data().toInt() & 0x00ffffff) >> 8;
+ // Is it the clear midi control action item?
+ if(colindex == 254)
+ {
+ MusECore::AudioTrack* track = static_cast<MusECore::AudioTrack*>(editAutomation);
+ MusECore::MidiAudioCtrlMap* macp = track->controller()->midiControls();
+ MusECore::AudioMidiCtrlStructMap amcs;
+ macp->find_audio_ctrl_structs(id, &amcs);
+ if(!amcs.empty())
+ MusEGlobal::audio->msgIdle(true); // Gain access to structures, and sync with audio
+ for(MusECore::iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ macp->erase(*iamcs);
+ if(!amcs.empty())
+ MusEGlobal::audio->msgIdle(false);
+
+ // Hm, need to remove the 'clear' item, and the status lines below it. Try this:
+ QActionGroup* midi_actgrp = act->actionGroup();
+ if(midi_actgrp)
+ {
+ QList<QAction*> act_list = midi_actgrp->actions();
+ int sz = act_list.size();
+ for(int i = 0; i < sz; ++i)
+ {
+ QAction* list_act = act_list.at(i);
+ ///midi_actgrp->removeAction(list_act);
+ // list_act has no parent now.
+ ///delete list_act;
+ list_act->setVisible(false); // HACK Cannot delete any actions! Causes crash with our PopupMenu due to recent fixes.
+ }
+ }
+ return;
+ }
+
+ // Is it the midi control action item?
+ if(colindex == 255)
+ {
+ MusECore::AudioTrack* track = static_cast<MusECore::AudioTrack*>(editAutomation);
+ MusECore::MidiAudioCtrlMap* macm = track->controller()->midiControls();
+ MusECore::AudioMidiCtrlStructMap amcs;
+ macm->find_audio_ctrl_structs(id, &amcs);
+
+ int port = -1, chan = 0, ctrl = 0;
+ for(MusECore::iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ {
+ macm->hash_values((*iamcs)->first, &port, &chan, &ctrl);
+ break; // Only a single item for now, thanks!
+ }
+
+ MidiAudioControl* pup = new MidiAudioControl(port, chan, ctrl);
+
+ if(pup->exec() == QDialog::Accepted)
+ {
+ MusEGlobal::audio->msgIdle(true); // Gain access to structures, and sync with audio
+ // Erase all for now.
+ for(MusECore::iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ macm->erase(*iamcs);
+
+ port = pup->port(); chan = pup->chan(); ctrl = pup->ctrl();
+ if(port >= 0 && chan >=0 && ctrl >= 0)
+ // Add will replace if found.
+ macm->add_ctrl_struct(port, chan, ctrl, MusECore::MidiAudioCtrlStruct(id));
+
+ MusEGlobal::audio->msgIdle(false);
+ }
+
+ delete pup;
+ return;
+ }
+
if (colindex > 100)
return; // this was meant for changeAutomation
// one of these days I'll rewrite this so it's understandable
@@ -1461,7 +1537,10 @@ void TList::changeAutomationColor(QAction* act)
//---------------------------------------------------------
PopupMenu* TList::colorMenu(QColor c, int id, QWidget* parent)
{
- PopupMenu * m = new PopupMenu(parent); //, true); //TODO
+ PopupMenu * m = new PopupMenu(parent, true);
+
+ QActionGroup* col_actgrp = new QActionGroup(m);
+ col_actgrp->setExclusive(true);
for (int i = 0; i< 6; i++) {
QPixmap pix(10,10);
QPainter p(&pix);
@@ -1469,14 +1548,52 @@ PopupMenu* TList::colorMenu(QColor c, int id, QWidget* parent)
p.setPen(Qt::black);
p.drawRect(0,0,10,10);
QIcon icon(pix);
- QAction *act = m->addAction(icon,"");
+ QAction *act = col_actgrp->addAction(icon,"");
act->setCheckable(true);
if (c == collist[i])
act->setChecked(true);
- int data = id * 256; // shift 8 bits
- data += i; // color in the bottom 8 bits
- act->setData(data);
+ act->setData((id<<8) + i); // Shift 8 bits. Color in the bottom 8 bits.
}
+ m->addActions(col_actgrp->actions());
+
+ //m->addSeparator();
+ m->addAction(new MenuTitleItem(tr("Midi control"), m));
+
+ if(editAutomation && !editAutomation->isMidiTrack())
+ {
+ QAction *act = m->addAction(tr("Assign"));
+ act->setCheckable(false);
+ act->setData((id<<8) + 255); // Shift 8 bits. Make midi menu the last item at 255.
+
+ MusECore::AudioTrack* track = static_cast<MusECore::AudioTrack*>(editAutomation);
+ MusECore::MidiAudioCtrlMap* macm = track->controller()->midiControls();
+ MusECore::AudioMidiCtrlStructMap amcs;
+ macm->find_audio_ctrl_structs(id, &amcs);
+
+ // Group only the clear and status items so they can both be easily removed when clear is clicked.
+ if(!amcs.empty())
+ {
+ QActionGroup* midi_actgrp = new QActionGroup(m);
+ QAction *cact = midi_actgrp->addAction(tr("Clear"));
+ cact->setData((id<<8) + 254); // Shift 8 bits. Make clear the second-last item at 254
+ for(MusECore::iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ {
+ int port, chan, mctrl;
+ macm->hash_values((*iamcs)->first, &port, &chan, &mctrl);
+ //QString s = QString("Port:%1 Chan:%2 Ctl:%3-%4").arg(port + 1)
+ QString s = QString("Port:%1 Chan:%2 Ctl:%3").arg(port + 1)
+ .arg(chan + 1)
+ //.arg((mctrl >> 8) & 0xff)
+ //.arg(mctrl & 0xff);
+ .arg(MusECore::midiCtrlName(mctrl, true));
+ QAction *mact = midi_actgrp->addAction(s);
+ mact->setEnabled(false);
+ mact->setData(-1); // Not used
+ }
+ m->addActions(midi_actgrp->actions());
+ }
+ }
+
connect(m, SIGNAL(triggered(QAction*)), SLOT(changeAutomationColor(QAction*)));
return m;
@@ -1611,14 +1728,53 @@ void TList::mousePressEvent(QMouseEvent* ev)
p->setTitle(tr("Viewable automation"));
MusECore::CtrlListList* cll = ((MusECore::AudioTrack*)t)->controller();
QAction* act = 0;
+ int last_rackpos = -1;
+ bool internal_found = false;
+ bool synth_found = false;
for(MusECore::CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll) {
MusECore::CtrlList *cl = icll->second;
if (cl->dontShow())
continue;
+
+ int ctrl = cl->id();
+
+ if(ctrl < AC_PLUGIN_CTL_BASE)
+ {
+ if(!internal_found)
+ p->addAction(new MusEGui::MenuTitleItem(tr("Internal"), p));
+ internal_found = true;
+ }
+ else
+ {
+ if(ctrl < (int)MusECore::genACnum(MAX_PLUGINS, 0)) // The beginning of the special dssi synth controller block.
+ {
+ int rackpos = (ctrl - AC_PLUGIN_CTL_BASE) >> AC_PLUGIN_CTL_BASE_POW;
+ if(rackpos < PipelineDepth)
+ {
+ if(rackpos != last_rackpos)
+ {
+ QString s = ((MusECore::AudioTrack*)t)->efxPipe()->name(rackpos);
+ p->addAction(new MusEGui::MenuTitleItem(s, p));
+ }
+ last_rackpos = rackpos;
+ }
+ }
+ else
+ {
+ if(t->type() == MusECore::Track::AUDIO_SOFTSYNTH)
+ {
+ if(!synth_found)
+ p->addAction(new MusEGui::MenuTitleItem(tr("Synth"), p));
+ synth_found = true;
+ }
+ }
+ }
+
act = p->addAction(cl->name());
act->setCheckable(true);
act->setChecked(cl->isVisible());
- int data = cl->id() * 256; // shift 8 bits
+
+ int data = ctrl<<8; // shift 8 bits
data += 150; // illegal color > 100
act->setData(data);
PopupMenu *m = colorMenu(cl->color(), cl->id(), p);
diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp
index cbcbd922..6349971b 100644
--- a/muse2/muse/audio.cpp
+++ b/muse2/muse/audio.cpp
@@ -45,6 +45,19 @@
#include "pos.h"
#include "ticksynth.h"
+// Experimental for now - allow other Jack timebase masters to control our midi engine.
+// TODO: Be friendly to other apps and ask them to be kind to us by using jack_transport_reposition.
+// It is actually required IF we want the extra position info to show up
+// in the sync callback, otherwise we get just the frame only.
+// This information is shared on the server, it is directly passed around.
+// jack_transport_locate blanks the info from sync until the timebase callback reads
+// it again right after, from some timebase master.
+// Sadly not many of us use jack_transport_reposition. So we need to work around it !
+//#define _JACK_TIMEBASE_DRIVES_MIDI_
+
+#ifdef _JACK_TIMEBASE_DRIVES_MIDI_
+#include "jackaudio.h"
+#endif
namespace MusEGlobal {
MusECore::Audio* audio;
@@ -102,6 +115,7 @@ const char* seqMsgList[] = {
"AUDIO_ADD_AC_EVENT",
"AUDIO_CHANGE_AC_EVENT",
"AUDIO_SET_SOLO", "AUDIO_SET_SEND_METRONOME",
+ "AUDIO_START_MIDI_LEARN",
"MS_PROCESS", "MS_STOP", "MS_SET_RTC", "MS_UPDATE_POLL_FD",
"SEQM_IDLE", "SEQM_SEEK"
};
@@ -127,6 +141,10 @@ Audio::Audio()
_pos.setType(Pos::FRAMES);
_pos.setFrame(0);
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ _previousPos.setType(Pos::FRAMES);
+ _previousPos.setFrame(0);
+#endif
nextTickPos = curTickPos = 0;
midiClick = 0;
@@ -143,6 +161,8 @@ Audio::Audio()
startRecordPos.setType(Pos::FRAMES); // Tim
endRecordPos.setType(Pos::FRAMES);
+ startExternalRecTick = 0;
+ endExternalRecTick = 0;
_audioMonitor = 0;
_audioMaster = 0;
@@ -384,7 +404,10 @@ void Audio::process(unsigned frames)
(*i)->processInit(frames);
int samplePos = _pos.frame();
int offset = 0; // buffer offset in audio buffers
-
+#ifdef _JACK_TIMEBASE_DRIVES_MIDI_
+ bool use_jack_timebase = false;
+#endif
+
if (isPlaying()) {
if (!freewheel())
MusEGlobal::audioPrefetch->msgTick();
@@ -394,7 +417,22 @@ void Audio::process(unsigned frames)
write(sigFd, "F", 1);
return;
}
-
+
+#ifdef _JACK_TIMEBASE_DRIVES_MIDI_
+ unsigned curr_jt_tick, next_jt_ticks;
+ use_jack_timebase =
+ MusEGlobal::audioDevice->deviceType() == AudioDevice::JACK_AUDIO &&
+ !MusEGlobal::jackTransportMaster &&
+ !MusEGlobal::song->masterFlag() &&
+ !MusEGlobal::extSyncFlag.value() &&
+ static_cast<MusECore::JackAudioDevice*>(MusEGlobal::audioDevice)->timebaseQuery(
+ frames, NULL, NULL, NULL, &curr_jt_tick, &next_jt_ticks);
+ // NOTE: I would rather trust the reported current tick than rely solely on the stream of
+ // tempos to correctly advance to the next position (which did actually test OK anyway).
+ if(use_jack_timebase)
+ curTickPos = curr_jt_tick;
+#endif
+
//
// check for end of song
//
@@ -452,10 +490,19 @@ void Audio::process(unsigned frames)
}
else
{
-
- Pos ppp(_pos);
- ppp += frames;
- nextTickPos = ppp.tick();
+
+#ifdef _JACK_TIMEBASE_DRIVES_MIDI_
+ if(use_jack_timebase)
+ // With jack timebase this might not be accurate -
+ // we are relying on the tempo to figure out the next tick.
+ nextTickPos = curTickPos + next_jt_ticks;
+ else
+#endif
+ {
+ Pos ppp(_pos);
+ ppp += frames;
+ nextTickPos = ppp.tick();
+ }
}
}
//
@@ -468,9 +515,15 @@ void Audio::process(unsigned frames)
process1(samplePos, offset, frames);
for (iAudioOutput i = ol->begin(); i != ol->end(); ++i)
(*i)->processWrite();
+
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ _previousPos = _pos;
+#endif
if (isPlaying()) {
_pos += frames;
- curTickPos = nextTickPos;
+ // With jack timebase this might not be accurate if we
+ // set curTickPos (above) from the reported current tick.
+ curTickPos = nextTickPos;
}
}
@@ -626,6 +679,13 @@ void Audio::processMsg(AudioMsg* msg)
msg->snode->setSendMetronome((bool)msg->ival);
break;
+ case AUDIO_START_MIDI_LEARN:
+ // Reset the values. The engine will fill these from driver events.
+ MusEGlobal::midiLearnPort = -1;
+ MusEGlobal::midiLearnChan = -1;
+ MusEGlobal::midiLearnCtrl = -1;
+ break;
+
case AUDIO_SET_SEG_SIZE:
MusEGlobal::segmentSize = msg->ival;
MusEGlobal::sampleRate = msg->iival;
@@ -690,6 +750,9 @@ void Audio::processMsg(AudioMsg* msg)
MusEGlobal::song->processMsg(msg);
if (isPlaying()) {
if (!MusEGlobal::checkAudioDevice()) return;
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ _previousPos = _pos;
+#endif
_pos.setTick(curTickPos);
int samplePos = _pos.frame();
syncFrame = MusEGlobal::audioDevice->framePos();
@@ -742,10 +805,25 @@ void Audio::seek(const Pos& p)
if (MusEGlobal::heavyDebugMsg)
printf("Audio::seek frame:%d\n", p.frame());
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ _previousPos = _pos;
+#endif
_pos = p;
if (!MusEGlobal::checkAudioDevice()) return;
syncFrame = MusEGlobal::audioDevice->framePos();
frameOffset = syncFrame - _pos.frame();
+
+#ifdef _JACK_TIMEBASE_DRIVES_MIDI_
+ unsigned curr_jt_tick;
+ if(MusEGlobal::audioDevice->deviceType() == AudioDevice::JACK_AUDIO &&
+ !MusEGlobal::jackTransportMaster &&
+ !MusEGlobal::song->masterFlag() &&
+ !MusEGlobal::extSyncFlag.value() &&
+ static_cast<MusECore::JackAudioDevice*>(MusEGlobal::audioDevice)->timebaseQuery(
+ MusEGlobal::segmentSize, NULL, NULL, NULL, &curr_jt_tick, NULL))
+ curTickPos = curr_jt_tick;
+ else
+#endif
curTickPos = _pos.tick();
// ALSA support
@@ -802,6 +880,7 @@ void Audio::startRolling()
if(_loopCount == 0) {
startRecordPos = _pos;
+ startExternalRecTick = curTickPos;
}
if (MusEGlobal::song->record()) {
recording = true;
@@ -916,6 +995,7 @@ void Audio::stopRolling()
}
recording = false;
endRecordPos = _pos;
+ endExternalRecTick = curTickPos;
write(sigFd, "0", 1); // STOP
}
@@ -926,8 +1006,10 @@ void Audio::stopRolling()
void Audio::recordStop()
{
+ MusEGlobal::song->processMasterRec();
+
if (MusEGlobal::debugMsg)
- printf("recordStop - startRecordPos=%d\n", startRecordPos.tick());
+ printf("recordStop - startRecordPos=%d\n", MusEGlobal::extSyncFlag.value() ? startExternalRecTick : startRecordPos.tick());
MusEGlobal::audio->msgIdle(true); // gain access to all data structures
@@ -937,7 +1019,7 @@ void Audio::recordStop()
for (iWaveTrack it = wl->begin(); it != wl->end(); ++it) {
WaveTrack* track = *it;
if (track->recordFlag() || MusEGlobal::song->bounceTrack == track) {
- MusEGlobal::song->cmdAddRecordedWave(track, startRecordPos, endRecordPos);
+ MusEGlobal::song->cmdAddRecordedWave(track, startRecordPos, endRecordPos);
// The track's _recFile pointer may have been kept and turned
// into a SndFileR and added to a new part.
// Or _recFile may have been discarded (no new recorded part created).
@@ -960,7 +1042,8 @@ void Audio::recordStop()
// Do SysexMeta. Do loops.
buildMidiEventList(el, mpel, mt, MusEGlobal::config.division, true, true);
- MusEGlobal::song->cmdAddRecordedEvents(mt, el, startRecordPos.tick());
+ MusEGlobal::song->cmdAddRecordedEvents(mt, el,
+ MusEGlobal::extSyncFlag.value() ? startExternalRecTick : startRecordPos.tick());
el->clear();
mpel->clear();
}
@@ -981,6 +1064,7 @@ void Audio::recordStop()
msgSetRecord(ao, false);
}
}
+
MusEGlobal::audio->msgIdle(false);
MusEGlobal::song->endUndo(0);
MusEGlobal::song->setRecord(false);
@@ -993,7 +1077,11 @@ void Audio::recordStop()
unsigned Audio::framesSinceCycleStart() const
{
- return lrint((curTime() - syncTime) * MusEGlobal::sampleRate);
+ unsigned f = lrint((curTime() - syncTime) * MusEGlobal::sampleRate);
+ // Safety due to inaccuracies. It cannot be after the segment, right?
+ if(f >= MusEGlobal::segmentSize)
+ f = MusEGlobal::segmentSize - 1;
+ return f;
}
//---------------------------------------------------------
diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h
index a9d2cc82..7c3d73ce 100644
--- a/muse2/muse/audio.h
+++ b/muse2/muse/audio.h
@@ -31,6 +31,12 @@
#include "route.h"
#include "event.h"
+// An experiment to use true frames for time-stamping all recorded input.
+// (All recorded data actually arrived in the previous period.)
+// TODO: Some more work needs to be done in WaveTrack::getData() in order to
+// make everything line up and sync correctly. Cannot use this yet!
+//#define _AUDIO_USE_TRUE_FRAME_
+
namespace MusECore {
class AudioDevice;
class AudioTrack;
@@ -94,6 +100,7 @@ enum {
AUDIO_ADD_AC_EVENT,
AUDIO_CHANGE_AC_EVENT,
AUDIO_SET_SOLO, AUDIO_SET_SEND_METRONOME,
+ AUDIO_START_MIDI_LEARN,
MS_PROCESS, MS_STOP, MS_SET_RTC, MS_UPDATE_POLL_FD,
SEQM_IDLE, SEQM_SEEK,
};
@@ -147,7 +154,11 @@ class Audio {
int _loopCount; // Number of times we have looped so far
Pos _pos; // current play position
-
+
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ Pos _previousPos; // previous play position
+#endif
+
unsigned curTickPos; // pos at start of frame during play/record
unsigned nextTickPos; // pos at start of next frame during play/record
@@ -172,7 +183,8 @@ class Audio {
// record values:
Pos startRecordPos;
Pos endRecordPos;
-
+ unsigned startExternalRecTick;
+ unsigned endExternalRecTick;
AudioOutput* _audioMaster;
AudioOutput* _audioMonitor;
@@ -288,6 +300,7 @@ class Audio {
void msgRemapPortDrumCtlEvents(int, int, int, int);
void msgChangeAllPortDrumCtrlEvents(bool, bool);
void msgSetSendMetronome(AudioTrack*, bool);
+ void msgStartMidiLearn();
void msgPlayMidiEvent(const MidiPlayEvent* event);
void rescanAlsaPorts();
@@ -295,8 +308,13 @@ class Audio {
void midiPortsChanged();
const Pos& pos() const { return _pos; }
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ const Pos& previousPos() const { return _previousPos; }
+#endif
const Pos& getStartRecordPos() const { return startRecordPos; }
const Pos& getEndRecordPos() const { return endRecordPos; }
+ unsigned getStartExternalRecTick() const { return startExternalRecTick; }
+ unsigned getEndExternalRecTick() const { return endExternalRecTick; }
int loopCount() { return _loopCount; } // Number of times we have looped so far
unsigned loopFrame() { return _loopFrame; }
diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp
index b0c52a54..dac496d7 100644
--- a/muse2/muse/audiotrack.cpp
+++ b/muse2/muse/audiotrack.cpp
@@ -39,6 +39,7 @@
#include "synth.h"
#include "dssihost.h"
#include "app.h"
+#include "controlfifo.h"
namespace MusECore {
@@ -385,6 +386,10 @@ void AudioTrack::addController(CtrlList* list)
void AudioTrack::removeController(int id)
{
+ AudioMidiCtrlStructMap amcs;
+ _controller.midiControls()->find_audio_ctrl_structs(id, &amcs);
+ for(ciAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++ iamcs)
+ _controller.midiControls()->erase(*iamcs);
iCtrlList i = _controller.find(id);
if (i == _controller.end()) {
printf("AudioTrack::removeController id %d not found\n", id);
@@ -399,20 +404,14 @@ void AudioTrack::removeController(int id)
void AudioTrack::swapControllerIDX(int idx1, int idx2)
{
- // FIXME This code is ugly.
- // At best we would like to modify the keys (IDXs) in-place and
- // do some kind of deferred re-sort, but it can't be done...
-
- if(idx1 == idx2)
- return;
-
- if(idx1 < 0 || idx2 < 0 || idx1 >= PipelineDepth || idx2 >= PipelineDepth)
+ if(idx1 == idx2 || idx1 < 0 || idx2 < 0 || idx1 >= PipelineDepth || idx2 >= PipelineDepth)
return;
CtrlList *cl;
CtrlList *newcl;
int id1 = (idx1 + 1) * AC_PLUGIN_CTL_BASE;
int id2 = (idx2 + 1) * AC_PLUGIN_CTL_BASE;
+ int id_mask = ~((int)AC_PLUGIN_CTL_ID_MASK);
int i, j;
CtrlListList tmpcll;
@@ -422,7 +421,7 @@ void AudioTrack::swapControllerIDX(int idx1, int idx2)
{
cl = icl->second;
i = cl->id() & AC_PLUGIN_CTL_ID_MASK;
- j = cl->id() & ~((unsigned long)AC_PLUGIN_CTL_ID_MASK);
+ j = cl->id() & id_mask;
if(j == id1 || j == id2)
{
newcl = new CtrlList(i | (j == id1 ? id2 : id1));
@@ -460,74 +459,21 @@ void AudioTrack::swapControllerIDX(int idx1, int idx2)
_controller.insert(std::pair<const int, CtrlList*>(newcl->id(), newcl));
}
- // DELETETHIS 67
- /*
- unsigned int idmask = ~AC_PLUGIN_CTL_ID_MASK;
-
- CtrlList* cl;
- CtrlList* ctl1 = 0;
- CtrlList* ctl2 = 0;
- CtrlList* newcl1 = 0;
- CtrlList* newcl2 = 0;
- CtrlVal cv(0, 0.0);
- int id1 = (idx1 + 1) * AC_PLUGIN_CTL_BASE;
- int id2 = (idx2 + 1) * AC_PLUGIN_CTL_BASE;
- int i, j;
- double min, max;
-
- for(ciCtrlList icl = _controller.begin(); icl != _controller.end(); ++icl)
+ // Remap midi to audio controls...
+ MidiAudioCtrlMap* macm = _controller.midiControls();
+ for(iMidiAudioCtrlMap imacm = macm->begin(); imacm != macm->end(); ++imacm)
{
- cl = icl->second;
- i = cl->id() & AC_PLUGIN_CTL_ID_MASK;
- j = cl->id() & idmask;
-
- if(j == id1)
- {
- ctl1 = cl;
- newcl1 = new CtrlList( i | id2 );
- newcl1->setMode(cl->mode());
- newcl1->setValueType(cl->valueType());
- newcl1->setName(cl->name());
- cl->range(&min, &max);
- newcl1->setRange(min, max);
- newcl1->setCurVal(cl->curVal());
- newcl1->setDefault(cl->getDefault());
- for(iCtrl ic = cl->begin(); ic != cl->end(); ++ic)
- {
- cv = ic->second;
- newcl1->insert(std::pair<const int, CtrlVal>(cv.frame, cv));
- }
- }
- //else
- if(j == id2)
- {
- ctl2 = cl;
- newcl2 = new CtrlList( i | id1 );
- newcl2->setMode(cl->mode());
- newcl2->setValueType(cl->valueType());
- newcl2->setName(cl->name());
- cl->range(&min, &max);
- newcl2->setRange(min, max);
- newcl2->setCurVal(cl->curVal());
- newcl2->setDefault(cl->getDefault());
- for(iCtrl ic = cl->begin(); ic != cl->end(); ++ic)
- {
- cv = ic->second;
- newcl2->insert(std::pair<const int, CtrlVal>(cv.frame, cv));
- }
- }
- }
- if(ctl1)
- _controller.erase(ctl1->id());
- if(ctl2)
- _controller.erase(ctl2->id());
- if(newcl1)
- //_controller.add(newcl1);
- _controller.insert(std::pair<const int, CtrlList*>(newcl1->id(), newcl1));
- if(newcl2)
- _controller.insert(std::pair<const int, CtrlList*>(newcl2->id(), newcl2));
- //_controller.add(newcl2);
- */
+ int actrl = imacm->second.audioCtrlId();
+ int id = actrl & id_mask;
+ actrl &= AC_PLUGIN_CTL_ID_MASK;
+ if(id == id1)
+ actrl |= id2;
+ else if(id == id2)
+ actrl |= id1;
+ else
+ continue;
+ imacm->second.setAudioCtrlId(actrl);
+ }
}
//---------------------------------------------------------
@@ -610,11 +556,7 @@ void AudioTrack::processAutomationEvents()
if(icr->id == id && icr->type == ARVT_STOP)
{
int end = icr->frame;
- // Erase everything up to, not including, this stop event's frame.
- // Because an event was already stored directly when slider released.
- if(end > start)
- --end;
-
+
iCtrl s = cl->lower_bound(start);
iCtrl e = cl->lower_bound(end);
@@ -636,8 +578,21 @@ void AudioTrack::processAutomationEvents()
// from CtrlRecList and put into cl.
for (iCtrlRec icr = _recEvents.begin(); icr != _recEvents.end(); ++icr)
{
- if (icr->id == id && (icr->type == ARVT_VAL || icr->type == ARVT_START))
+ if (icr->id == id)
+ {
+ // Must optimize these types otherwise multiple vertices appear on flat straight lines in the graphs.
+ CtrlValueType vtype = cl->valueType();
+ if(!cl->empty() && (cl->mode() == CtrlList::DISCRETE || vtype == VAL_BOOL || vtype == VAL_INT))
+ {
+ iCtrl icl_prev = cl->lower_bound(icr->frame);
+ if(icl_prev != cl->begin())
+ --icl_prev;
+ if(icl_prev->second.val == icr->val)
+ continue;
+ }
+ // Now add the value.
cl->add(icr->frame, icr->val);
+ }
}
}
@@ -790,7 +745,7 @@ void AudioTrack::changeACEvent(int id, int frame, int newframe, double newval)
iCtrl ic = cl->find(frame);
if(ic != cl->end())
cl->erase(ic);
- cl->insert(std::pair<const int, CtrlVal> (newframe, CtrlVal(newframe, newval)));
+ cl->insert(std::pair<const int, CtrlVal> (newframe, CtrlVal(newframe, newval)));
}
//---------------------------------------------------------
@@ -825,7 +780,7 @@ void AudioTrack::setVolume(double val)
double AudioTrack::pan() const
{
return _controller.value(AC_PAN, MusEGlobal::audio->curFramePos(),
- !MusEGlobal::automation || automationType() == AUTO_OFF || !_volumeEnCtrl || !_volumeEn2Ctrl);
+ !MusEGlobal::automation || automationType() == AUTO_OFF || !_panEnCtrl || !_panEn2Ctrl);
}
//---------------------------------------------------------
@@ -848,8 +803,49 @@ void AudioTrack::setPan(double val)
double AudioTrack::pluginCtrlVal(int ctlID) const
{
+ bool en_1 = true, en_2 = true;
+ if(ctlID < AC_PLUGIN_CTL_BASE)
+ {
+ if(ctlID == AC_VOLUME)
+ {
+ en_1 = _volumeEnCtrl;
+ en_2 = _volumeEn2Ctrl;
+ }
+ else
+ if(ctlID == AC_PAN)
+ {
+ en_1 = _panEnCtrl;
+ en_2 = _panEn2Ctrl;
+ }
+ }
+ else
+ {
+ if(ctlID < (int)genACnum(MAX_PLUGINS, 0)) // The beginning of the special dssi synth controller block.
+ {
+ _efxPipe->controllersEnabled(ctlID, &en_1, &en_2);
+ }
+ else
+ {
+ if(type() == AUDIO_SOFTSYNTH)
+ {
+ const SynthI* synth = static_cast<const SynthI*>(this);
+ if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
+ {
+ SynthIF* sif = synth->sif();
+ if(sif)
+ {
+ const DssiSynthIF* dssi_sif = static_cast<const DssiSynthIF*>(sif);
+ int in_ctrl_idx = ctlID & AC_PLUGIN_CTL_ID_MASK;
+ en_1 = dssi_sif->controllerEnabled(in_ctrl_idx);
+ en_2 = dssi_sif->controllerEnabled2(in_ctrl_idx);
+ }
+ }
+ }
+ }
+ }
+
return _controller.value(ctlID, MusEGlobal::audio->curFramePos(),
- !MusEGlobal::automation || automationType() == AUTO_OFF);
+ !MusEGlobal::automation || automationType() == AUTO_OFF || !en_1 || !en_2);
}
//---------------------------------------------------------
@@ -865,6 +861,140 @@ void AudioTrack::setPluginCtrlVal(int param, double val)
cl->second->setCurVal(val);
}
+//---------------------------------------------------------
+// addScheduledControlEvent
+// returns true if event cannot be delivered
+//---------------------------------------------------------
+
+bool AudioTrack::addScheduledControlEvent(int track_ctrl_id, float val, unsigned frame)
+{
+ if(track_ctrl_id < AC_PLUGIN_CTL_BASE) // FIXME: These controllers (three so far - vol, pan, mute) have no vari-run-length support.
+ {
+ iCtrlList icl = _controller.find(track_ctrl_id);
+ if(icl == _controller.end())
+ return true;
+ icl->second->setCurVal(val);
+ return false;
+ }
+ else
+ {
+ if(track_ctrl_id < (int)genACnum(MAX_PLUGINS, 0)) // The beginning of the special dssi synth controller block.
+ return _efxPipe->addScheduledControlEvent(track_ctrl_id, val, frame);
+ else
+ {
+ if(type() == AUDIO_SOFTSYNTH)
+ {
+ const SynthI* synth = static_cast<const SynthI*>(this);
+ if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
+ {
+ SynthIF* sif = synth->sif();
+ if(sif)
+ {
+ DssiSynthIF* dssi_sif = static_cast<DssiSynthIF*>(sif);
+ int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
+ return dssi_sif->addScheduledControlEvent(in_ctrl_idx, val, frame);
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//---------------------------------------------------------
+// enableController
+// Enable or disable gui controls.
+// Used during automation recording to inhibit gui controls
+// from playback controller stream
+//---------------------------------------------------------
+
+void AudioTrack::enableController(int track_ctrl_id, bool en)
+{
+ if(track_ctrl_id < AC_PLUGIN_CTL_BASE)
+ {
+ if(track_ctrl_id == AC_VOLUME)
+ enableVolumeController(en);
+ else
+ if(track_ctrl_id == AC_PAN)
+ enablePanController(en);
+ }
+ else
+ {
+ if(track_ctrl_id < (int)genACnum(MAX_PLUGINS, 0)) // The beginning of the special dssi synth controller block.
+ _efxPipe->enableController(track_ctrl_id, en);
+ else
+ {
+ if(type() == AUDIO_SOFTSYNTH)
+ {
+ SynthI* synth = static_cast<SynthI*>(this);
+ if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
+ {
+ SynthIF* sif = synth->sif();
+ if(sif)
+ {
+ DssiSynthIF* dssi_sif = static_cast<DssiSynthIF*>(sif);
+ int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
+ dssi_sif->enableController(in_ctrl_idx, en);
+ }
+ }
+ }
+ }
+ }
+}
+
+//---------------------------------------------------------
+// controllersEnabled
+//---------------------------------------------------------
+
+void AudioTrack::controllersEnabled(int track_ctrl_id, bool* en1, bool* en2) const
+ {
+ bool en_1 = true, en_2 = true;
+ if(track_ctrl_id < AC_PLUGIN_CTL_BASE)
+ {
+ if(track_ctrl_id == AC_VOLUME)
+ {
+ en_1 = _volumeEnCtrl;
+ en_2 = _volumeEn2Ctrl;
+ }
+ else
+ if(track_ctrl_id == AC_PAN)
+ {
+ en_1 = _panEnCtrl;
+ en_2 = _panEn2Ctrl;
+ }
+ }
+ else
+ {
+ if(track_ctrl_id < (int)genACnum(MAX_PLUGINS, 0)) // The beginning of the special dssi synth controller block.
+ {
+ _efxPipe->controllersEnabled(track_ctrl_id, &en_1, &en_2);
+ }
+ else
+ {
+ if(type() == AUDIO_SOFTSYNTH)
+ {
+ const SynthI* synth = static_cast<const SynthI*>(this);
+ if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
+ {
+ SynthIF* sif = synth->sif();
+ if(sif)
+ {
+ const DssiSynthIF* dssi_sif = static_cast<const DssiSynthIF*>(sif);
+ int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
+ en_1 = dssi_sif->controllerEnabled(in_ctrl_idx);
+ en_2 = dssi_sif->controllerEnabled2(in_ctrl_idx);
+ }
+ }
+ }
+ }
+ }
+
+ if(en1)
+ *en1 = en_1;
+ if(en2)
+ *en2 = en_2;
+ }
+
void AudioTrack::recordAutomation(int n, double v)
{
if(!MusEGlobal::automation)
@@ -883,7 +1013,7 @@ void AudioTrack::recordAutomation(int n, double v)
if (cl == _controller.end())
return;
// Add will replace if found.
- cl->second->add(MusEGlobal::audio->curFramePos(), v);
+ cl->second->add(MusEGlobal::audio->curFramePos(), v);
}
}
}
@@ -895,10 +1025,10 @@ void AudioTrack::startAutoRecord(int n, double v)
if(MusEGlobal::audio->isPlaying())
{
if(automationType() == AUTO_TOUCH)
- _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v, ARVT_START));
- else
+ _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v, ARVT_START));
+ else
if(automationType() == AUTO_WRITE)
- _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));
+ _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));
}
else
{
@@ -926,7 +1056,7 @@ void AudioTrack::stopAutoRecord(int n, double v)
{
if(automationType() == AUTO_TOUCH)
{
- MusEGlobal::audio->msgAddACEvent(this, n, MusEGlobal::audio->curFramePos(), v);
+ MusEGlobal::audio->msgAddACEvent(this, n, MusEGlobal::audio->curFramePos(), v);
_recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v, ARVT_STOP));
}
}
@@ -953,26 +1083,7 @@ void AudioTrack::writeProperties(int level, Xml& xml) const
if (*ip)
(*ip)->writeConfiguration(level, xml);
}
- for (ciCtrlList icl = _controller.begin(); icl != _controller.end(); ++icl) {
- const CtrlList* cl = icl->second;
-
- QString s= QString("controller id=\"%1\" cur=\"%2\"").arg(cl->id()).arg(cl->curVal()).toAscii().constData();
- s += QString(" color=\"%1\" visible=\"%2\"").arg(cl->color().name()).arg(cl->isVisible());
- xml.tag(level++, s.toAscii().constData());
- int i = 0;
- for (ciCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
- QString s("%1 %2, ");
- xml.nput(level, s.arg(ic->second.frame).arg(ic->second.val).toAscii().constData());
- ++i;
- if (i >= 4) {
- xml.put(level, "");
- i = 0;
- }
- }
- if (i)
- xml.put(level, "");
- xml.etag(level--, "controller");
- }
+ _controller.write(level, xml);
}
//---------------------------------------------------------
@@ -1113,6 +1224,8 @@ bool AudioTrack::readProperties(Xml& xml, const QString& tag)
l->setMode(p->ctrlMode(m));
}
}
+ else if (tag == "midiMapper")
+ _controller.midiControls()->read(xml);
else
return Track::readProperties(xml, tag);
return false;
@@ -1230,20 +1343,20 @@ void AudioTrack::mapRackPluginsToControllers()
unsigned param = id & AC_PLUGIN_CTL_ID_MASK;
int idx = (id >> AC_PLUGIN_CTL_BASE_POW) - 1;
- PluginIBase* p = 0;
+ const PluginIBase* p = 0;
if(idx >= 0 && idx < PipelineDepth)
p = (*_efxPipe)[idx];
// Support a special block for dssi synth ladspa controllers.
else if(idx == MAX_PLUGINS && type() == AUDIO_SOFTSYNTH)
{
- SynthI* synti = dynamic_cast < SynthI* > (this);
+ const SynthI* synti = dynamic_cast < const SynthI* > (this);
if(synti)
{
SynthIF* sif = synti->sif();
if(sif)
{
#ifdef DSSI_SUPPORT
- DssiSynthIF* dsif = dynamic_cast < DssiSynthIF* > (sif);
+ const DssiSynthIF* dsif = dynamic_cast < const DssiSynthIF* > (sif);
if(dsif)
p = dsif;
#endif
diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp
index 6c5c93db..cca3cb94 100644
--- a/muse2/muse/conf.cpp
+++ b/muse2/muse/conf.cpp
@@ -561,6 +561,23 @@ void readConfiguration(Xml& xml, bool doReadMidiPortConfig, bool doReadGlobalCon
if(MusEGlobal::audioDevice)
MusEGlobal::audioDevice->setMaster(MusEGlobal::jackTransportMaster);
}
+ else if (tag == "syncRecFilterPreset")
+ {
+ int p = xml.parseInt();
+ if(p >= 0 && p < MidiSyncInfo::TYPE_END)
+ {
+ MusEGlobal::syncRecFilterPreset = MidiSyncInfo::SyncRecFilterPresetType(p);
+ if(MusEGlobal::midiSeq)
+ MusEGlobal::midiSeq->setSyncRecFilterPreset(MusEGlobal::syncRecFilterPreset);
+ }
+ }
+ else if (tag == "syncRecTempoValQuant")
+ {
+ double qv = xml.parseDouble();
+ MusEGlobal::syncRecTempoValQuant = qv;
+ if(MusEGlobal::midiSeq)
+ MusEGlobal::midiSeq->setRecTempoValQuant(qv);
+ }
else if (tag == "mtcoffset") {
QString qs(xml.parse1());
QByteArray ba = qs.toLatin1();
@@ -1348,6 +1365,8 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const
xml.uintTag(level, "sendClockDelay", MusEGlobal::syncSendFirstClockDelay);
xml.intTag(level, "useJackTransport", MusEGlobal::useJackTransport.value());
xml.intTag(level, "jackTransportMaster", MusEGlobal::jackTransportMaster);
+ xml.intTag(level, "syncRecFilterPreset", MusEGlobal::syncRecFilterPreset);
+ xml.doubleTag(level, "syncRecTempoValQuant", MusEGlobal::syncRecTempoValQuant);
MusEGlobal::extSyncFlag.save(level, xml);
xml.intTag(level, "bigtimeVisible", viewBigtimeAction->isChecked());
diff --git a/muse2/muse/confmport.cpp b/muse2/muse/confmport.cpp
index 637e927e..32e1dc91 100644
--- a/muse2/muse/confmport.cpp
+++ b/muse2/muse/confmport.cpp
@@ -888,7 +888,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
#endif
MusEGlobal::midiSeq->msgSetMidiDevice(port, sdev);
- MusEGlobal::muse->changeConfig(true); // save configuration file
+ MusEGlobal::muse->changeConfig(true); // save configuration file
// Add all track routes to/from this port...
if(sdev)
@@ -904,7 +904,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
MusEGlobal::audio->msgAddRoute(MusECore::Route(no, chbits), MusECore::Route(*it, chbits));
}
}
- chbits = MusEGlobal::midiPorts[no].defaultOutChannels();
+// chbits = MusEGlobal::midiPorts[no].defaultOutChannels();
// Turn on if and when multiple output routes are supported. DELETETHIS?
#if 0
for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it)
@@ -914,22 +914,27 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
MusEGlobal::audio->msgAddRoute(MusECore::Route(no, chbits), MusECore::Route(*it, chbits));
}
#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);
- // Stop at the first output channel found.
- break;
- }
+// REMOVE Tim.
+// 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)
+// {
+// // We are only interested in tracks which use this port being changed now.
+// if((*it)->outPort() != no)
+// continue;
+// // Leave drum track channel at current setting. // REMOVE Tim.
+// //if((*it)->type() == MusECore::Track::DRUM)
+// // (*it)->setOutPortAndUpdate(no);
+// //else
+// // (*it)->setOutPortAndChannelAndUpdate(no, ch);
+// (*it)->setOutPortAndUpdate(no);
+// }
+// MusEGlobal::audio->msgIdle(false);
+// // Stop at the first output channel found.
+// break;
+// }
#endif
}
diff --git a/muse2/muse/ctrl.cpp b/muse2/muse/ctrl.cpp
index 8071491e..d7d42770 100644
--- a/muse2/muse/ctrl.cpp
+++ b/muse2/muse/ctrl.cpp
@@ -6,7 +6,7 @@
// controller handling for mixer automation
//
// (C) Copyright 2003 Werner Schweer (ws@seh.de)
-// (C) Copyright 2011 Time E. Real (terminator356 on users dot sourceforge dot net)
+// (C) Copyright 2011-2012 Tim E. Real (terminator356 on users dot sourceforge dot net)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -24,15 +24,20 @@
//
//=========================================================
+// Turn on debugging messages
+//#define _CTRL_DEBUG_
#include <QLocale>
#include <QColor>
+#include <map>
+
+#include <math.h>
#include "gconfig.h"
#include "fastlog.h"
-#include "math.h"
#include "globals.h"
#include "ctrl.h"
+#include "midictrl.h"
#include "xml.h"
namespace MusECore {
@@ -48,8 +53,268 @@ void CtrlList::initColor(int i)
_visible = false;
}
+//---------------------------------------------------------
+// midi2AudioCtrlValue
+// Apply mapper if it is non-null
+//---------------------------------------------------------
+
+double midi2AudioCtrlValue(const CtrlList* audio_ctrl_list, const MidiAudioCtrlStruct* /*mapper*/, int midi_ctlnum, int midi_val)
+{
+ double fmin, fmax;
+ audio_ctrl_list->range(&fmin, &fmax);
+ double frng = fmax - fmin; // The audio control range.
+
+ MidiController::ControllerType t = midiControllerType(midi_ctlnum);
+ CtrlValueType aud_t = audio_ctrl_list->valueType();
+
+ #ifdef _CTRL_DEBUG_
+ printf("midi2AudioCtrlValue: midi_ctlnum:%d val:%d fmin:%f fmax:%f\n", midi_ctlnum, midi_val, fmin, fmax);
+ #endif
+
+ int ctlmn = 0;
+ int ctlmx = 127;
+
+ int bval = midi_val;
+ switch(t)
+ {
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ case MidiController::Controller7:
+ ctlmn = 0;
+ ctlmx = 127;
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ ctlmn = 0;
+ ctlmx = 16383;
+ break;
+ case MidiController::Program:
+ ctlmn = 0;
+ ctlmx = 0xffffff;
+ break;
+ case MidiController::Pitch:
+ ctlmn = -8192;
+ ctlmx = 8191;
+ bval += 8192;
+ break;
+ case MidiController::Velo: // cannot happen
+ default:
+ break;
+ }
+ double fictlrng = double(ctlmx - ctlmn); // Float version of the integer midi range.
+ double normval = double(bval) / fictlrng; // Float version of the normalized midi value.
+
+ // ---------- TODO: Do stuff with the mapper, if supplied.
+
+ if(aud_t == VAL_LOG)
+ {
+ // FIXME: Although this should be correct, some sliders show "---" at top end, some don't.
+ // Possibly because of use of fast_log10 in value(), and in sliders and automation IIRC.
+ fmin = 20.0*log10(fmin);
+ fmax = 20.0*log10(fmax);
+ frng = fmax - fmin;
+ double ret = exp10((normval * frng + fmin) / 20.0);
+ #ifdef _CTRL_DEBUG_
+ printf("midi2AudioCtrlValue: is VAL_LOG normval:%f frng:%f returning:%f\n", normval, frng, ret);
+ #endif
+ return ret;
+ }
+
+ if(aud_t == VAL_LINEAR)
+ {
+ double ret = normval * frng + fmin;
+ #ifdef _CTRL_DEBUG_
+ printf("midi2AudioCtrlValue: is VAL_LINEAR normval:%f frng:%f returning:%f\n", normval, frng, ret);
+ #endif
+ return ret;
+ }
+
+ if(aud_t == VAL_INT)
+ {
+ double ret = int(normval * frng + fmin);
+ #ifdef _CTRL_DEBUG_
+ printf("midi2AudioCtrlValue: is VAL_INT returning:%f\n", ret);
+ #endif
+ return ret;
+ }
+
+ if(aud_t == VAL_BOOL)
+ {
+ #ifdef _CTRL_DEBUG_
+ printf("midi2AudioCtrlValue: is VAL_BOOL\n");
+ #endif
+ //if(midi_val > ((ctlmx - ctlmn)/2 + ctlmn))
+ if((normval * frng + fmin) > (frng/2.0 + fmin))
+ return fmax;
+ else
+ return fmin;
+ }
+
+ printf("midi2AudioCtrlValue: unknown audio controller type:%d\n", aud_t);
+ return 0.0;
+}
+
+//---------------------------------------------------------
+// Midi to audio controller stuff
+//---------------------------------------------------------
+
+MidiAudioCtrlStruct::MidiAudioCtrlStruct()
+{
+ _audio_ctrl_id = 0;
+};
+
+MidiAudioCtrlStruct::MidiAudioCtrlStruct(int audio_ctrl_id) : _audio_ctrl_id(audio_ctrl_id)
+{
+};
+
+MidiAudioCtrlMap_idx_t MidiAudioCtrlMap::index_hash(int midi_port, int midi_chan, int midi_ctrl_num) const
+{
+ return ((MidiAudioCtrlMap_idx_t(midi_port) & 0xff) << 24) |
+ ((MidiAudioCtrlMap_idx_t(midi_chan) & 0xf) << 20) |
+ (MidiAudioCtrlMap_idx_t(midi_ctrl_num) & 0xfffff);
+}
+
+void MidiAudioCtrlMap::hash_values(MidiAudioCtrlMap_idx_t hash, int* midi_port, int* midi_chan, int* midi_ctrl_num) const
+{
+ if(midi_ctrl_num)
+ *midi_ctrl_num = hash & 0xfffff;
+ if(midi_chan)
+ *midi_chan = (hash >> 20) & 0xf;
+ if(midi_port)
+ *midi_port = (hash >> 24) & 0xff;
+}
+
+iMidiAudioCtrlMap MidiAudioCtrlMap::add_ctrl_struct(int midi_port, int midi_chan, int midi_ctrl_num,
+ const MidiAudioCtrlStruct& macs)
+{
+ MidiAudioCtrlMap_idx_t h = index_hash(midi_port, midi_chan, midi_ctrl_num);
+ std::pair<iMidiAudioCtrlMap, iMidiAudioCtrlMap> range = equal_range(h);
+ for(iMidiAudioCtrlMap imacp = range.first; imacp != range.second; ++imacp)
+ if(imacp->second.audioCtrlId() == macs.audioCtrlId())
+ return imacp;
+ return insert(std::pair<MidiAudioCtrlMap_idx_t, MidiAudioCtrlStruct >(h, macs));
+}
+void MidiAudioCtrlMap::erase_ctrl_struct(int midi_port, int midi_chan, int midi_ctrl_num, int audio_ctrl_id)
+{
+ MidiAudioCtrlMap_idx_t h = index_hash(midi_port, midi_chan, midi_ctrl_num);
+ std::pair<iMidiAudioCtrlMap, iMidiAudioCtrlMap> range = equal_range(h);
+ MidiAudioCtrlMap macm;
+ macm.insert(range.first, range.second);
+ for(iMidiAudioCtrlMap imacm = macm.begin(); imacm != macm.end(); ++imacm)
+ if(imacm->second.audioCtrlId() == audio_ctrl_id)
+ erase(imacm);
+}
+
+void MidiAudioCtrlMap::find_audio_ctrl_structs(int audio_ctrl_id, AudioMidiCtrlStructMap* amcs) //const
+{
+ for(iMidiAudioCtrlMap imacm = begin(); imacm != end(); ++imacm)
+ if(imacm->second.audioCtrlId() == audio_ctrl_id)
+ amcs->push_back(imacm);
+}
+
+void MidiAudioCtrlMap::write(int level, Xml& xml) const
+{
+ for(ciMidiAudioCtrlMap imacm = begin(); imacm != end(); ++imacm)
+ {
+ int port, chan, mctrl;
+ hash_values(imacm->first, &port, &chan, &mctrl);
+ int actrl = imacm->second.audioCtrlId();
+ QString s= QString("midiMapper port=\"%1\" ch=\"%2\" mctrl=\"%3\" actrl=\"%4\"")
+ .arg(port)
+ .arg(chan)
+ .arg(mctrl)
+ .arg(actrl);
+ xml.tag(level++, s.toAscii().constData());
+
+ // TODO
+ //const MidiAudioCtrlStruct& macs = imacs->second;
+ //xml.intTag(level, "macs ???", macs.);
+
+ xml.etag(level--, "midiMapper");
+ }
+}
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void MidiAudioCtrlMap::read(Xml& xml)
+ {
+ int port = -1, chan = -1, midi_ctrl = -1;
+ MidiAudioCtrlStruct macs(-1);
+
+ QLocale loc = QLocale::c();
+ bool ok;
+ int errcount = 0;
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::Attribut:
+ if (tag == "port")
+ {
+ port = loc.toInt(xml.s2(), &ok);
+ if(!ok)
+ {
+ ++errcount;
+ printf("MidiAudioCtrlPortMap::read failed reading port string: %s\n", xml.s2().toLatin1().constData());
+ }
+ }
+ else if (tag == "ch")
+ {
+ chan = loc.toInt(xml.s2(), &ok);
+ if(!ok)
+ {
+ ++errcount;
+ printf("MidiAudioCtrlPortMap::read failed reading ch string: %s\n", xml.s2().toLatin1().constData());
+ }
+ }
+ else if (tag == "mctrl")
+ {
+ midi_ctrl = loc.toInt(xml.s2(), &ok);
+ if(!ok)
+ {
+ ++errcount;
+ printf("MidiAudioCtrlPortMap::read failed reading mctrl string: %s\n", xml.s2().toLatin1().constData());
+ }
+ }
+ else if (tag == "actrl")
+ {
+ macs.setAudioCtrlId(loc.toInt(xml.s2(), &ok));
+ if(!ok)
+ {
+ ++errcount;
+ printf("MidiAudioCtrlPortMap::read failed reading actrl string: %s\n", xml.s2().toLatin1().constData());
+ }
+ }
+ else
+ printf("unknown tag %s\n", tag.toLatin1().constData());
+ break;
+ case Xml::TagStart:
+ // TODO
+ //if (tag == "???") {
+ // }
+ //else
+ xml.unknown("midiMapper");
+ break;
+ case Xml::TagEnd:
+ if (xml.s1() == "midiMapper")
+ {
+ if(errcount == 0 && port != -1 && chan != -1 && midi_ctrl != -1 && macs.audioCtrlId() != -1)
+ add_ctrl_struct(port, chan, midi_ctrl, macs);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ }
//---------------------------------------------------------
// CtrlList
//---------------------------------------------------------
@@ -62,6 +327,7 @@ CtrlList::CtrlList()
_mode = INTERPOLATE;
_dontShow = false;
_visible = false;
+ _guiUpdatePending = false;
initColor(0);
}
@@ -73,6 +339,7 @@ CtrlList::CtrlList(int id)
_mode = INTERPOLATE;
_dontShow = false;
_visible = false;
+ _guiUpdatePending = false;
initColor(id);
}
@@ -88,6 +355,7 @@ CtrlList::CtrlList(int id, QString name, double min, double max, CtrlValueType v
_valueType = v;
_dontShow = dontShow;
_visible = false;
+ _guiUpdatePending = false;
initColor(id);
}
@@ -115,39 +383,54 @@ void CtrlList::assign(const CtrlList& l, int flags)
if(flags & ASSIGN_VALUES)
{
*this = l; // Let the vector assign values.
+ _guiUpdatePending = true;
}
}
//---------------------------------------------------------
// value
+// Returns value at frame.
+// cur_val_only means read the current 'manual' value, not from the list even if it is not empty.
+// If passed a nextFrame, sets nextFrame to the next event frame, or -1 if no next frame (wide-open), or,
+// since CtrlList is a map, ZERO if should be replaced with some other frame by the caller (interpolation).
//---------------------------------------------------------
-double CtrlList::value(int frame) const
+double CtrlList::value(int frame, bool cur_val_only, int* nextFrame) const
{
- if(empty())
+ if(cur_val_only || empty())
+ {
+ if(nextFrame)
+ *nextFrame = -1;
return _curVal;
+ }
double rv;
- ciCtrl i = upper_bound(frame); // get the index after current frame
+ int nframe;
+ ciCtrl i = upper_bound(frame); // get the index after current frame
if (i == end()) { // if we are past all items just return the last value
--i;
- rv = i->second.val;
+ if(nextFrame)
+ *nextFrame = -1;
+ return i->second.val;
}
else if(_mode == DISCRETE)
{
if(i == begin())
{
+ nframe = i->second.frame;
rv = i->second.val;
}
else
{
+ nframe = i->second.frame;
--i;
rv = i->second.val;
}
}
- else {
+ else { // INTERPOLATE
if (i == begin()) {
+ nframe = i->second.frame;
rv = i->second.val;
}
else {
@@ -157,6 +440,12 @@ double CtrlList::value(int frame) const
int frame1 = i->second.frame;
double val1 = i->second.val;
+
+ if(val2 != val1)
+ nframe = 0; // Zero signifies the next frame should be determined by caller.
+ else
+ nframe = frame2;
+
if (_valueType == VAL_LOG) {
val1 = 20.0*fast_log10(val1);
if (val1 < MusEGlobal::config.minSlider)
@@ -166,10 +455,8 @@ double CtrlList::value(int frame) const
val2=MusEGlobal::config.minSlider;
}
- frame -= frame1;
val2 -= val1;
- frame2 -= frame1;
- val1 += (double(frame) * val2)/double(frame2);
+ val1 += (double(frame - frame1) * val2)/double(frame2 - frame1);
if (_valueType == VAL_LOG) {
val1 = exp10(val1/20.0);
@@ -178,6 +465,10 @@ double CtrlList::value(int frame) const
rv = val1;
}
}
+
+ if(nextFrame)
+ *nextFrame = nframe;
+
return rv;
}
@@ -196,7 +487,101 @@ double CtrlList::curVal() const
//---------------------------------------------------------
void CtrlList::setCurVal(double val)
{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::setCurVal val:%f\n", val);
+#endif
+
+ bool upd = (val != _curVal);
_curVal = val;
+ // If empty, any controller graphs etc. will be displaying this value.
+ // Otherwise they'll be displaying the list, so update is not required.
+ if(empty() && upd)
+ _guiUpdatePending = true;
+}
+
+//---------------------------------------------------------
+//
+// Catch all insert, erase, clear etc.
+//
+//---------------------------------------------------------
+
+CtrlList& CtrlList::operator=(const CtrlList& cl)
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::operator= id:%d\n", cl.id());
+#endif
+ std::map<int, CtrlVal, std::less<int> >::operator=(cl);
+ _guiUpdatePending = true;
+ return *this;
+}
+
+void CtrlList::swap(CtrlList& cl)
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::swap id:%d\n", cl.id());
+#endif
+ std::map<int, CtrlVal, std::less<int> >::swap(cl);
+ cl.setGuiUpdatePending(true);
+ _guiUpdatePending = true;
+}
+
+std::pair<iCtrl, bool> CtrlList::insert(const std::pair<int, CtrlVal>& p)
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::insert frame:%d val:%f\n", p.first, p.second.val);
+#endif
+ std::pair<iCtrl, bool> res = std::map<int, CtrlVal, std::less<int> >::insert(p);
+ _guiUpdatePending = true;
+ return res;
+}
+
+iCtrl CtrlList::insert(iCtrl ic, const std::pair<int, CtrlVal>& p)
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::insert2 frame:%d val:%f\n", p.first, p.second.val);
+#endif
+ iCtrl res = std::map<int, CtrlVal, std::less<int> >::insert(ic, p);
+ _guiUpdatePending = true;
+ return res;
+}
+
+void CtrlList::erase(iCtrl ictl)
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::erase iCtrl frame:%d val:%f\n", ictl->second.frame, ictl->second.val);
+#endif
+ std::map<int, CtrlVal, std::less<int> >::erase(ictl);
+ _guiUpdatePending = true;
+}
+
+std::map<int, CtrlVal, std::less<int> >::size_type CtrlList::erase(int frame)
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::erase frame:%d\n", frame);
+#endif
+ std::map<int, CtrlVal, std::less<int> >::size_type res = std::map<int, CtrlVal, std::less<int> >::erase(frame);
+ _guiUpdatePending = true;
+ return res;
+}
+
+void CtrlList::erase(iCtrl first, iCtrl last)
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::erase range first frame:%d val:%f second frame:%d val:%f\n",
+ first->second.frame, first->second.val,
+ last->second.frame, last->second.val);
+#endif
+ std::map<int, CtrlVal, std::less<int> >::erase(first, last);
+ _guiUpdatePending = true;
+}
+
+void CtrlList::clear()
+{
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::clear\n");
+#endif
+ std::map<int, CtrlVal, std::less<int> >::clear();
+ _guiUpdatePending = true;
}
//---------------------------------------------------------
@@ -208,7 +593,15 @@ void CtrlList::add(int frame, double val)
{
iCtrl e = find(frame);
if (e != end())
+ {
+ bool upd = (val != e->second.val);
e->second.val = val;
+#ifdef _CTRL_DEBUG_
+ printf("CtrlList::add frame:%d val:%f\n", frame, val);
+#endif
+ if(upd)
+ _guiUpdatePending = true;
+ }
else
insert(std::pair<const int, CtrlVal> (frame, CtrlVal(frame, val)));
}
@@ -234,7 +627,13 @@ void CtrlList::del(int frame)
void CtrlList::updateCurValue(int frame)
{
- _curVal = value(frame);
+ double v = value(frame);
+ bool upd = (v != _curVal);
+ _curVal = v;
+ // If empty, any controller graphs etc. will be displaying this value.
+ // Otherwise they'll be displaying the list, so update is not required.
+ if(empty() && upd)
+ _guiUpdatePending = true;
}
//---------------------------------------------------------
@@ -361,18 +760,23 @@ void CtrlListList::add(CtrlList* vl)
//---------------------------------------------------------
// value
+// Returns value at frame for controller with id ctrlId.
+// cur_val_only means read the current 'manual' value, not from the list even if it is not empty.
+// If passed a nextFrame, sets nextFrame to the next event frame, or -1 if no next frame (wide-open), or,
+// since CtrlList is a map, ZERO if should be replaced with some other frame by the caller (interpolation).
//---------------------------------------------------------
-double CtrlListList::value(int ctrlId, int frame, bool cur_val_only) const
+double CtrlListList::value(int ctrlId, int frame, bool cur_val_only, int* nextFrame) const
{
ciCtrlList cl = find(ctrlId);
if (cl == end())
- return 0.0;
-
- if(cur_val_only)
- return cl->second->curVal();
+ {
+ if(nextFrame)
+ *nextFrame = -1;
+ return 0.0;
+ }
- return cl->second->value(frame);
+ return cl->second->value(frame, cur_val_only, nextFrame);
}
//---------------------------------------------------------
@@ -391,5 +795,36 @@ void CtrlListList::updateCurValues(int frame)
for(ciCtrlList cl = begin(); cl != end(); ++cl)
cl->second->updateCurValue(frame);
}
-
+
+//---------------------------------------------------------
+// value
+//---------------------------------------------------------
+
+void CtrlListList::write(int level, Xml& xml) const
+{
+ for (ciCtrlList icl = begin(); icl != end(); ++icl) {
+ const CtrlList* cl = icl->second;
+
+ QString s= QString("controller id=\"%1\" cur=\"%2\"").arg(cl->id()).arg(cl->curVal()).toAscii().constData();
+ s += QString(" color=\"%1\" visible=\"%2\"").arg(cl->color().name()).arg(cl->isVisible());
+ xml.tag(level++, s.toAscii().constData());
+ int i = 0;
+ for (ciCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ QString s("%1 %2, ");
+ xml.nput(level, s.arg(ic->second.frame).arg(ic->second.val).toAscii().constData());
+ ++i;
+ if (i >= 4) {
+ xml.put(level, "");
+ i = 0;
+ }
+ }
+ if (i)
+ xml.put(level, "");
+ xml.etag(level--, "controller");
+ }
+
+ _midi_controls.write(level, xml);
+}
+
+
} // namespace MusECore
diff --git a/muse2/muse/ctrl.h b/muse2/muse/ctrl.h
index 687c5610..c56abe28 100644
--- a/muse2/muse/ctrl.h
+++ b/muse2/muse/ctrl.h
@@ -6,7 +6,7 @@
// controller for mixer automation
//
// (C) Copyright 2003-2004 Werner Schweer (ws@seh.de)
-// (C) Copyright 2011 Time E. Real (terminator356 on users dot sourceforge dot net)
+// (C) Copyright 2011-2012 Tim E. Real (terminator356 on users dot sourceforge dot net)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -29,7 +29,9 @@
#include <map>
#include <list>
+#include <vector>
#include <qcolor.h>
+#include <lo/lo_osc_types.h>
#define AC_PLUGIN_CTL_BASE 0x1000
#define AC_PLUGIN_CTL_BASE_POW 12
@@ -85,6 +87,47 @@ class CtrlRecList : public std::list<CtrlRecVal> {
typedef CtrlRecList::iterator iCtrlRec;
//---------------------------------------------------------
+// MidiAudioCtrlMap
+// Describes midi control of audio controllers
+//---------------------------------------------------------
+
+class MidiAudioCtrlStruct {
+ int _audio_ctrl_id;
+ public:
+ MidiAudioCtrlStruct();
+ MidiAudioCtrlStruct(int audio_ctrl_id);
+ int audioCtrlId() const { return _audio_ctrl_id; }
+ void setAudioCtrlId(int actrl) { _audio_ctrl_id = actrl; }
+ };
+
+typedef uint32_t MidiAudioCtrlMap_idx_t;
+
+typedef std::multimap<MidiAudioCtrlMap_idx_t, MidiAudioCtrlStruct, std::less<MidiAudioCtrlMap_idx_t> >::iterator iMidiAudioCtrlMap;
+typedef std::multimap<MidiAudioCtrlMap_idx_t, MidiAudioCtrlStruct, std::less<MidiAudioCtrlMap_idx_t> >::const_iterator ciMidiAudioCtrlMap;
+
+// Reverse lookup based on audio control.
+typedef std::vector<iMidiAudioCtrlMap>::iterator iAudioMidiCtrlStructMap;
+typedef std::vector<iMidiAudioCtrlMap>::const_iterator ciAudioMidiCtrlStructMap;
+class AudioMidiCtrlStructMap : public std::vector<iMidiAudioCtrlMap> {
+ public:
+
+ };
+
+// Midi to audio controller map.
+// The index is a hash of port, chan, and midi control number.
+class MidiAudioCtrlMap : public std::multimap<MidiAudioCtrlMap_idx_t, MidiAudioCtrlStruct, std::less<MidiAudioCtrlMap_idx_t> > {
+ public:
+ MidiAudioCtrlMap_idx_t index_hash(int midi_port, int midi_chan, int midi_ctrl_num) const;
+ void hash_values(MidiAudioCtrlMap_idx_t hash, int* midi_port, int* midi_chan, int* midi_ctrl_num) const;
+ iMidiAudioCtrlMap add_ctrl_struct(int midi_port, int midi_chan, int midi_ctrl_num, const MidiAudioCtrlStruct& amcs);
+ void find_audio_ctrl_structs(int audio_ctrl_id, AudioMidiCtrlStructMap* amcs); // const;
+ void erase_ctrl_struct(int midi_port, int midi_chan, int midi_ctrl_num, int audio_ctrl_id);
+ void write(int level, Xml& xml) const;
+ void read(Xml& xml);
+ };
+
+
+//---------------------------------------------------------
// CtrlList
// arrange controller events of a specific type in a
// list for easy retrieval
@@ -109,6 +152,7 @@ class CtrlList : public std::map<int, CtrlVal, std::less<int> > {
QColor _displayColor;
bool _visible;
bool _dontShow; // when this is true the control exists but is not compatible with viewing in the arranger
+ volatile bool _guiUpdatePending; // Gui heartbeat routines read this. Checked and cleared in Song::beat().
void initColor(int i);
public:
@@ -117,6 +161,15 @@ class CtrlList : public std::map<int, CtrlVal, std::less<int> > {
CtrlList(int id, QString name, double min, double max, CtrlValueType v, bool dontShow=false);
void assign(const CtrlList& l, int flags);
+ void swap(CtrlList&);
+ std::pair<iCtrl, bool> insert(const std::pair<int, CtrlVal>& p);
+ iCtrl insert(iCtrl ic, const std::pair<int, CtrlVal>& p);
+ void erase(iCtrl ictl);
+ size_type erase(int frame);
+ void erase(iCtrl first, iCtrl last);
+ void clear();
+ CtrlList& operator=(const CtrlList&);
+
Mode mode() const { return _mode; }
void setMode(Mode m) { _mode = m; }
double getDefault() const { return _default; }
@@ -138,7 +191,7 @@ class CtrlList : public std::map<int, CtrlVal, std::less<int> > {
CtrlValueType valueType() const { return _valueType; }
void setValueType(CtrlValueType t) { _valueType = t; }
- double value(int frame) const;
+ double value(int frame, bool cur_val_only = false, int* nextFrame = NULL) const;
void add(int frame, double value);
void del(int frame);
void read(Xml& xml);
@@ -148,6 +201,8 @@ class CtrlList : public std::map<int, CtrlVal, std::less<int> > {
void setVisible(bool v) { _visible = v; }
bool isVisible() const { return _visible; }
bool dontShow() const { return _dontShow; }
+ bool guiUpdatePending() const { return _guiUpdatePending; }
+ void setGuiUpdatePending(bool v) { _guiUpdatePending = v; }
};
//---------------------------------------------------------
@@ -161,6 +216,8 @@ typedef std::map<int, CtrlList*, std::less<int> >::iterator iCtrlList;
typedef std::map<int, CtrlList*, std::less<int> >::const_iterator ciCtrlList;
class CtrlListList : public std::map<int, CtrlList*, std::less<int> > {
+ private:
+ MidiAudioCtrlMap _midi_controls; // For midi control of audio controllers.
public:
void add(CtrlList* vl);
void clearDelete() {
@@ -176,14 +233,19 @@ class CtrlListList : public std::map<int, CtrlList*, std::less<int> > {
return std::map<int, CtrlList*, std::less<int> >::find(id);
}
- double value(int ctrlId, int frame, bool cur_val_only = false) const;
+ MidiAudioCtrlMap* midiControls() { return &_midi_controls; }
+
+ double value(int ctrlId, int frame, bool cur_val_only = false, int* nextFrame = NULL) const;
void updateCurValues(int frame);
void clearAllAutomation() {
for(iCtrlList i = begin(); i != end(); ++i)
i->second->clear();
}
+ void write(int level, Xml& xml) const;
};
+extern double midi2AudioCtrlValue(const CtrlList* audio_ctrl_list, const MidiAudioCtrlStruct* mapper, int midi_ctlnum, int midi_val);
+
} // namespace MusECore
#endif
diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp
index f75b9c33..e3e71365 100644
--- a/muse2/muse/driver/alsamidi.cpp
+++ b/muse2/muse/driver/alsamidi.cpp
@@ -1318,24 +1318,24 @@ void alsaProcessMidiInput()
break;
case SND_SEQ_EVENT_CLOCK:
- MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_CLOCK);
+ MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_CLOCK, curTime());
//mdev->syncInfo().trigMCSyncDetect();
break;
case SND_SEQ_EVENT_START:
- MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_START);
+ MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_START, curTime());
break;
case SND_SEQ_EVENT_CONTINUE:
- MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_CONTINUE);
+ MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_CONTINUE, curTime());
break;
case SND_SEQ_EVENT_STOP:
- MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_STOP);
+ MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_STOP, curTime());
break;
case SND_SEQ_EVENT_TICK:
- MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_TICK);
+ MusEGlobal::midiSeq->realtimeSystemInput(curPort, ME_TICK, curTime());
//mdev->syncInfo().trigTickDetect();
break;
diff --git a/muse2/muse/driver/jack.cpp b/muse2/muse/driver/jack.cpp
index 4cc8bfb8..05d47955 100644
--- a/muse2/muse/driver/jack.cpp
+++ b/muse2/muse/driver/jack.cpp
@@ -42,6 +42,7 @@
#include "tempo.h"
#include "sync.h"
#include "utils.h"
+#include "gconfig.h"
#include "midi.h"
#include "mididev.h"
@@ -50,7 +51,7 @@
#include "jackmidi.h"
-#define JACK_DEBUG 0
+#define JACK_DEBUG 0
//#include "errorhandler.h"
@@ -176,7 +177,7 @@ int JackAudioDevice::processAudio(jack_nframes_t frames, void*)
}
}
}
-
+
//if(jackAudio->getState() != Audio::START_PLAY) // Don't process while we're syncing. TODO: May need to deliver silence in process!
MusEGlobal::audio->process((unsigned long)frames);
}
@@ -196,8 +197,21 @@ int JackAudioDevice::processAudio(jack_nframes_t frames, void*)
static int processSync(jack_transport_state_t state, jack_position_t* pos, void*)
{
if (JACK_DEBUG)
- printf("processSync()\n");
+ {
+ printf("processSync frame:%u\n", pos->frame);
+ if(pos->valid & JackPositionBBT)
+ {
+ if(JACK_DEBUG)
+ {
+ printf("processSync BBT:\n bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
+ pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
+ if(pos->valid & JackBBTFrameOffset)
+ printf("processSync BBTFrameOffset: %u\n", pos->bbt_offset);
+ }
+ }
+ }
+
if(!MusEGlobal::useJackTransport.value())
return 1;
@@ -237,49 +251,54 @@ static int processSync(jack_transport_state_t state, jack_position_t* pos, void*
//---------------------------------------------------------
static void timebase_callback(jack_transport_state_t /* state */,
- jack_nframes_t /* nframes */,
+ jack_nframes_t nframes,
jack_position_t* pos,
- int /* new_pos */,
+ int new_pos,
void*)
{
- if (JACK_DEBUG)
- printf("Jack timebase_callback pos->frame:%u MusEGlobal::audio->tickPos:%d MusEGlobal::song->cpos:%d\n", pos->frame, MusEGlobal::audio->tickPos(), MusEGlobal::song->cpos());
-
- //Pos p(pos->frame, false);
+
+ if (JACK_DEBUG)
+ {
+ if(pos->valid & JackPositionBBT)
+ printf("timebase_callback BBT:\n bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
+ pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
+ if(pos->valid & JackBBTFrameOffset)
+ printf("timebase_callback BBTFrameOffset: %u\n", pos->bbt_offset);
+ if(pos->valid & JackPositionTimecode)
+ printf("timebase_callback JackPositionTimecode: frame_time:%f next_time:%f\n", pos->frame_time, pos->next_time);
+ if(pos->valid & JackAudioVideoRatio)
+ printf("timebase_callback JackAudioVideoRatio: %f\n", pos->audio_frames_per_video_frame);
+ if(pos->valid & JackVideoFrameOffset)
+ printf("timebase_callback JackVideoFrameOffset: %u\n", pos->video_offset);
+ }
+
+ //Pos p(pos->frame, false);
Pos p(MusEGlobal::extSyncFlag.value() ? MusEGlobal::audio->tickPos() : pos->frame, MusEGlobal::extSyncFlag.value() ? true : false);
// Can't use song pos - it is only updated every (slow) GUI heartbeat !
//Pos p(MusEGlobal::extSyncFlag.value() ? MusEGlobal::song->cpos() : pos->frame, MusEGlobal::extSyncFlag.value() ? true : false);
pos->valid = JackPositionBBT;
p.mbt(&pos->bar, &pos->beat, &pos->tick);
+ pos->bar_start_tick = Pos(pos->bar, 0, 0).tick();
pos->bar++;
pos->beat++;
- pos->bar_start_tick = Pos(pos->bar, 0, 0).tick();
-
- //
- // dummy:
- //
- //pos->beats_per_bar = 4;
- //pos->beat_type = 4;
- //pos->ticks_per_beat = 384;
- //
- /* // From example client transport.c :
- float time_beats_per_bar = 4.0;
- float time_beat_type = 0.25; // Huh? Inverted? From docs: "Time signature 'denominator'"
- double time_ticks_per_beat = 1920.0; // Huh? Ticks per beat should be 24 etc. not 384 or 1920 etc. Otherwise it would be called 'frames_per_beat'.
- double time_beats_per_minute = 120.0;
- */
- //
int z, n;
AL::sigmap.timesig(p.tick(), z, n);
pos->beats_per_bar = z;
pos->beat_type = n;
- //pos->ticks_per_beat = config.division;
- pos->ticks_per_beat = 24;
+ pos->ticks_per_beat = MusEGlobal::config.division;
+ //pos->ticks_per_beat = 24;
+
+ double tempo = MusEGlobal::tempomap.tempo(p.tick());
+ pos->beats_per_minute = (60000000.0 / tempo) * double(MusEGlobal::tempomap.globalTempo())/100.0;
+ if (JACK_DEBUG)
+ {
+ printf("timebase_callback is new_pos:%d nframes:%u frame:%u tickPos:%d cpos:%d\n", new_pos, nframes, pos->frame, MusEGlobal::audio->tickPos(), MusEGlobal::song->cpos());
+ printf(" new: bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
+ pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
+ }
- int tempo = MusEGlobal::tempomap.tempo(p.tick());
- pos->beats_per_minute = (60000000.0 / tempo) * MusEGlobal::tempomap.globalTempo()/100.0;
}
//---------------------------------------------------------
@@ -1226,6 +1245,69 @@ jack_transport_state_t JackAudioDevice::transportQuery(jack_position_t* pos)
}
//---------------------------------------------------------
+// timebaseQuery
+// Given the number of frames in this period, get the bar, beat, tick,
+// and current absolute tick, and number of ticks in this period.
+// Return false if information could not be obtained.
+//---------------------------------------------------------
+
+bool JackAudioDevice::timebaseQuery(unsigned frames, unsigned* bar, unsigned* beat, unsigned* tick, unsigned* curr_abs_tick, unsigned* next_ticks)
+{
+ jack_position_t jp;
+ jack_transport_query(_client, &jp);
+
+ if(JACK_DEBUG)
+ printf("timebaseQuery frame:%u\n", jp.frame);
+
+ if(jp.valid & JackPositionBBT)
+ {
+ if(JACK_DEBUG)
+ {
+ printf("timebaseQuery BBT:\n bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
+ jp.bar, jp.beat, jp.tick, jp.bar_start_tick, jp.beats_per_bar, jp.beat_type, jp.ticks_per_beat, jp.beats_per_minute);
+ if(jp.valid & JackBBTFrameOffset)
+ printf("timebaseQuery BBTFrameOffset: %u\n", jp.bbt_offset);
+ }
+
+ if(jp.ticks_per_beat > 0.0)
+ {
+ unsigned muse_tick = unsigned((double(jp.tick) / jp.ticks_per_beat) * double(MusEGlobal::config.division));
+ unsigned curr_tick = ((jp.bar - 1) * jp.beats_per_bar + (jp.beat - 1)) * double(MusEGlobal::config.division) + muse_tick;
+ // Prefer the reported frame rate over the app's rate if possible.
+ double f_rate = jp.frame_rate != 0 ? jp.frame_rate : MusEGlobal::sampleRate;
+ // beats_per_minute is "supposed" to be quantized to period size - that is, computed
+ // so that mid-period changes are averaged out to produce a single tempo which
+ // produces the same tick in the end. If we can rely on that, we should be good accuracy.
+ unsigned ticks = double(MusEGlobal::config.division) * (jp.beats_per_minute / 60.0) * double(frames) / f_rate;
+
+ if(JACK_DEBUG)
+ printf("timebaseQuery curr_tick:%u f_rate:%f ticks:%u\n", curr_tick, f_rate, ticks);
+
+ if(bar) *bar = jp.bar;
+ if(beat) *beat = jp.beat;
+ if(tick) *tick = muse_tick;
+
+ if(curr_abs_tick) *curr_abs_tick = curr_tick;
+ if(next_ticks) *next_ticks = ticks;
+
+ return true;
+ }
+ }
+
+ if(JACK_DEBUG)
+ {
+ if(jp.valid & JackPositionTimecode)
+ printf("timebaseQuery JackPositionTimecode: frame_time:%f next_time:%f\n", jp.frame_time, jp.next_time);
+ if(jp.valid & JackAudioVideoRatio)
+ printf("timebaseQuery JackAudioVideoRatio: %f\n", jp.audio_frames_per_video_frame);
+ if(jp.valid & JackVideoFrameOffset)
+ printf("timebaseQuery JackVideoFrameOffset: %u\n", jp.video_offset);
+ }
+
+ return false;
+}
+
+//---------------------------------------------------------
// systemTime
// Return system time. Depends on selected clock source.
// With Jack, may be based upon wallclock time, the
@@ -1617,7 +1699,7 @@ void JackAudioDevice::seekTransport(unsigned frame)
void JackAudioDevice::seekTransport(const Pos &p)
{
if (JACK_DEBUG)
- printf("JackAudioDevice::seekTransport() frame:%d\n", p.frame());
+ printf("JackAudioDevice::seekTransport(Pos) frame:%d\n", p.frame());
if(!MusEGlobal::useJackTransport.value())
{
@@ -1628,25 +1710,29 @@ void JackAudioDevice::seekTransport(const Pos &p)
}
if(!checkJackClient(_client)) return;
+
+// TODO: Be friendly to other apps... Sadly not many of us use jack_transport_reposition.
+// This is actually required IF we want the extra position info to show up
+// in the sync callback, otherwise we get just the frame only.
+// This information is shared on the server, it is directly passed around.
+// jack_transport_locate blanks the info from sync until the timebase callback reads
+// it again right after, from some timebase master. See process in audio.cpp
+
+// jack_position_t jp;
+// jp.frame = p.frame();
+//
+// jp.valid = JackPositionBBT;
+// p.mbt(&jp.bar, &jp.beat, &jp.tick);
+// jp.bar_start_tick = Pos(jp.bar, 0, 0).tick();
+// jp.bar++;
+// jp.beat++;
+// jp.beats_per_bar = 5; // TODO Make this correct !
+// jp.beat_type = 8; //
+// jp.ticks_per_beat = MusEGlobal::config.division;
+// int tempo = MusEGlobal::tempomap.tempo(p.tick());
+// jp.beats_per_minute = (60000000.0 / tempo) * MusEGlobal::tempomap.globalTempo()/100.0;
+// jack_transport_reposition(_client, &jp);
- /*
- jack_position_t jp;
- jp.valid = JackPositionBBT;
- p.mbt(&jp.bar, &jp.beat, &jp.tick);
- jp.bar++;
- jp.beat++;
- jp.bar_start_tick = Pos(jp.bar, 0, 0).tick();
- //
- // dummy:
- //
- jp.beats_per_bar = 4;
- jp.beat_type = 4;
- jp.ticks_per_beat = 384;
- int tempo = MusEGlobal::tempomap.tempo(p.tick());
- jp.beats_per_minute = (60000000.0 / tempo) * MusEGlobal::tempomap.globalTempo()/100.0;
-
- jack_transport_reposition(_client, &jp);
- */
jack_transport_locate(_client, p.frame());
}
diff --git a/muse2/muse/driver/jackaudio.h b/muse2/muse/driver/jackaudio.h
index 9640ca81..aab60d88 100644
--- a/muse2/muse/driver/jackaudio.h
+++ b/muse2/muse/driver/jackaudio.h
@@ -80,6 +80,7 @@ class JackAudioDevice : public AudioDevice {
virtual std::list<QString> outputPorts(bool midi = false, int aliases = -1);
virtual std::list<QString> inputPorts(bool midi = false, int aliases = -1);
+ jack_client_t* jackClient() const { return _client; }
virtual void registerClient();
virtual const char* clientName() { return jackRegisteredName; }
@@ -105,6 +106,7 @@ class JackAudioDevice : public AudioDevice {
virtual void seekTransport(const Pos &p);
virtual void setFreewheel(bool f);
jack_transport_state_t transportQuery(jack_position_t* pos);
+ bool timebaseQuery(unsigned frames, unsigned* bar, unsigned* beat, unsigned* tick, unsigned* curr_abs_tick, unsigned* next_ticks);
void graphChanged();
void registrationChanged();
void connectJackMidiPorts();
diff --git a/muse2/muse/driver/jackmidi.cpp b/muse2/muse/driver/jackmidi.cpp
index 706fa269..e3e67dfb 100644
--- a/muse2/muse/driver/jackmidi.cpp
+++ b/muse2/muse/driver/jackmidi.cpp
@@ -30,6 +30,7 @@
//#include <jack/midiport.h>
#include "jackmidi.h"
+#include "jackaudio.h"
#include "song.h"
#include "globals.h"
#include "midi.h"
@@ -50,10 +51,6 @@
// Turn on debug messages.
//#define JACK_MIDI_DEBUG
-namespace MusEGlobal {
-extern unsigned int volatile lastExtMidiSyncTick;
-}
-
namespace MusECore {
//---------------------------------------------------------
@@ -422,7 +419,7 @@ void MidiJackDevice::recordEvent(MidiRecordEvent& event)
// Split the events up into channel fifos. Special 'channel' number 17 for sysex events.
unsigned int ch = (typ == ME_SYSEX)? MIDI_CHANNELS : event.channel();
- if(_recordFifo[ch].put(MidiPlayEvent(event)))
+ if(_recordFifo[ch].put(event))
printf("MidiJackDevice::recordEvent: fifo channel %d overflow\n", ch);
}
@@ -446,10 +443,18 @@ void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
// catch process play
//
- //int frameOffset = MusEGlobal::audio->getFrameOffset();
- unsigned pos = MusEGlobal::audio->pos().frame();
-
- event.setTime(MusEGlobal::extSyncFlag.value() ? MusEGlobal::lastExtMidiSyncTick : (pos + ev->time)); // p3.3.25
+ // These Jack events arrived in the previous period, and it may not have been at the audio position before this one (after a seek).
+ // This is how our ALSA driver works, events there are timestamped asynchronous of any process, referenced to the CURRENT audio
+ // position, so that by the time of the NEXT process, THOSE events have also occured in the previous period.
+ // So, technically this is correct. What MATTERS is how we adjust the times for storage, and/or simultaneous playback in THIS period,
+ // and TEST: we'll need to make sure any non-contiguous previous period is handled correctly by process - will it work OK as is?
+ // If ALSA works OK than this should too...
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ event.setTime(MusEGlobal::audio->previousPos().frame() + ev->time);
+#else
+ event.setTime(MusEGlobal::audio->pos().frame() + ev->time);
+#endif
+ event.setTick(MusEGlobal::lastExtMidiSyncTick);
event.setChannel(*(ev->buffer) & 0xf);
int type = *(ev->buffer) & 0xf0;
@@ -509,9 +514,20 @@ void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
case ME_START:
case ME_CONTINUE:
case ME_STOP:
- if(_port != -1)
- MusEGlobal::midiSeq->realtimeSystemInput(_port, type);
+ {
+ if(MusEGlobal::audioDevice && MusEGlobal::audioDevice->deviceType() == JACK_MIDI && _port != -1)
+ {
+ MusECore::JackAudioDevice* jad = static_cast<MusECore::JackAudioDevice*>(MusEGlobal::audioDevice);
+ jack_client_t* jc = jad->jackClient();
+ if(jc)
+ {
+ jack_nframes_t abs_ft = jack_last_frame_time(jc) + ev->time;
+ double abs_ev_t = double(jack_frames_to_time(jc, abs_ft)) / 1000000.0;
+ MusEGlobal::midiSeq->realtimeSystemInput(_port, type, abs_ev_t);
+ }
+ }
return;
+ }
//case ME_SYSEX_END:
//break;
// return;
diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp
index 5000e338..01f9c0f3 100644
--- a/muse2/muse/dssihost.cpp
+++ b/muse2/muse/dssihost.cpp
@@ -680,7 +680,7 @@ bool DssiSynthIF::init(DssiSynth* s)
// Set current program.
if(dssi->select_program)
- dssi->select_program(handle, synti->_curBankL, synti->_curProgram);
+ doSelectProgram(handle, synti->_curBankL, synti->_curProgram);
//
// For stored initial control values, let SynthI::initInstance() take care of that via ::setParameter().
@@ -839,27 +839,7 @@ float DssiSynthIF::getParameterOut(unsigned long n) const
void DssiSynthIF::setParameter(unsigned long n, float v)
{
- if(n >= synth->_controlInPorts)
- {
- printf("DssiSynthIF::setParameter param number %lu out of range of ports:%lu\n", n, synth->_controlInPorts);
- return;
- }
-
- ControlEvent ce;
- ce.unique = false;
- ce.idx = n;
- ce.value = v;
- // Time-stamp the event. This does a possibly slightly slow call to gettimeofday via timestamp().
- // timestamp() is more or less an estimate of the current frame. (This is exactly how ALSA events
- // are treated when they arrive in our ALSA driver.)
- //ce.frame = MusEGlobal::audio->timestamp();
- // p4.0.23 timestamp() is circular, which is making it impossible to deal with 'modulo' events which
- // slip in 'under the wire' before processing the ring buffers. So try this linear timestamp instead:
- ce.frame = MusEGlobal::audio->curFrame();
- if(_controlFifo.put(ce))
- {
- fprintf(stderr, "DssiSynthIF::setParameter: fifo overflow: in control number:%lu\n", n);
- }
+ addScheduledControlEvent(n, v, MusEGlobal::audio->curFrame());
}
//---------------------------------------------------------
@@ -1084,7 +1064,7 @@ bool DssiSynthIF::processEvent(const MusECore::MidiPlayEvent& e, snd_seq_event_t
synti->_curProgram = prog;
if(dssi->select_program)
- dssi->select_program(handle, bank, prog);
+ doSelectProgram(handle, bank, prog);
// Event pointer not filled. Return false.
return false;
@@ -1113,7 +1093,7 @@ bool DssiSynthIF::processEvent(const MusECore::MidiPlayEvent& e, snd_seq_event_t
synti->_curProgram = prog;
if(dssi->select_program)
- dssi->select_program(handle, bank, prog);
+ doSelectProgram(handle, bank, prog);
// Event pointer not filled. Return false.
return false;
@@ -1220,6 +1200,11 @@ bool DssiSynthIF::processEvent(const MusECore::MidiPlayEvent& e, snd_seq_event_t
// Set the ladspa port value.
controls[k].val = val;
+ // Need to update the automation value, otherwise it overwrites later with the last automation value.
+ if(id() != -1)
+ // We're in the audio thread context: no need to send a message, just modify directly.
+ synti->setPluginCtrlVal(genACnum(id(), k), val);
+
// Since we absorbed the message as a ladspa control change, return false - the event is not filled.
return false;
}
@@ -1404,7 +1389,7 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
if(fixedsize > nframes)
fixedsize = nframes;
- unsigned long min_per = MusEGlobal::config.minControlProcessPeriod;
+ unsigned long min_per = MusEGlobal::config.minControlProcessPeriod; // Must be power of 2 !
if(min_per > nframes)
min_per = nframes;
@@ -1412,7 +1397,7 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
fprintf(stderr, "DssiSynthIF::getData: Handling inputs...\n");
#endif
- // p4.0.38 Handle inputs...
+ // Handle inputs...
if(!((MusECore::AudioTrack*)synti)->noInRoute())
{
RouteList* irl = ((MusECore::AudioTrack*)synti)->inRoutes();
@@ -1485,21 +1470,57 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
#ifdef DSSI_DEBUG_PROCESS
fprintf(stderr, "DssiSynthIF::getData: Processing automation control values...\n");
#endif
-
- // 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)
- {
- for(unsigned long k = 0; k < synth->_controlInPorts; ++k)
- {
- if(controls[k].enCtrl && controls[k].en2Ctrl )
- controls[k].val = (static_cast<MusECore::AudioTrack*>(synti))->controller()->value(genACnum(id(), k), pos);
- }
- }
-
+
while(sample < nframes)
{
unsigned long nsamp = usefixedrate ? fixedsize : nframes - sample;
+
+ //
+ // Process automation control values, while also determining the maximum acceptable
+ // size of this run. Further processing, from FIFOs for example, can lower the size
+ // from there, but this section determines where the next highest maximum frame
+ // absolutely needs to be for smooth playback of the controller value stream...
+ //
+ if(id() != -1)
+ {
+ unsigned long frame = pos + sample;
+ AutomationType at = AUTO_OFF;
+ at = synti->automationType();
+ bool no_auto = !MusEGlobal::automation || at == AUTO_OFF;
+ AudioTrack* track = (static_cast<AudioTrack*>(synti));
+ int nextFrame;
+ for(unsigned long k = 0; k < synth->_controlInPorts; ++k)
+ {
+ controls[k].val = track->controller()->value(genACnum(id(), k), frame,
+ no_auto || !controls[k].enCtrl || !controls[k].en2Ctrl,
+ &nextFrame);
+#ifdef DSSI_DEBUG_PROCESS
+ printf("DssiSynthIF::getData k:%lu sample:%lu frame:%lu nextFrame:%d nsamp:%lu \n", k, sample, frame, nextFrame, nsamp);
+#endif
+ if(MusEGlobal::audio->isPlaying() && !usefixedrate && nextFrame != -1)
+ {
+ // Returned value of nextFrame can be zero meaning caller replaces with some (constant) value.
+ unsigned long samps = (unsigned long)nextFrame;
+ if(samps > frame + min_per)
+ {
+ unsigned long diff = samps - frame;
+ unsigned long mask = min_per-1; // min_per must be power of 2
+ samps = diff & ~mask;
+ if((diff & mask) != 0)
+ samps += min_per;
+ }
+ else
+ samps = min_per;
+
+ if(samps < nsamp)
+ nsamp = samps;
+ }
+ }
+#ifdef DSSI_DEBUG
+ printf("DssiSynthIF::getData sample:%lu nsamp:%lu\n", sample, nsamp);
+#endif
+ }
+
bool found = false;
unsigned long frame = 0;
unsigned long index = 0;
@@ -1528,11 +1549,13 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
continue;
}
- if(evframe >= nframes
- || (found && !v.unique && (evframe - sample >= min_per))
- || (usefixedrate && found && v.unique && v.idx == index))
+ if(evframe >= nframes // Next events are for a later period.
+ || (!usefixedrate && !found && !v.unique && (evframe - sample >= nsamp)) // Next events are for a later run in this period. (Autom took prio.)
+ || (found && !v.unique && (evframe - sample >= min_per)) // Eat up events within minimum slice - they're too close.
+ || (usefixedrate && found && v.unique && v.idx == index)) // Special for dssi-vst: Fixed rate and must reply to all.
break;
_controlFifo.remove(); // Done with the ring buffer's item. Remove it.
+
if(v.idx >= synth->_controlInPorts) // Sanity check.
break;
found = true;
@@ -1543,36 +1566,16 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
// Need to update the automation value, otherwise it overwrites later with the last automation value.
if(id() != -1)
- {
- // We're in the audio thread context: no need to send a message, just modify directly.
synti->setPluginCtrlVal(genACnum(id(), v.idx), v.value);
-
- /* Record automation. DELETETHIS?
- * 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.
-
- // 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 !
- AutomationType at = _track->automationType();
- if ((at == AUTO_WRITE) ||
- (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()))
- enableController(k, false);
- _track->recordAutomation(id, v.value);
- */
- }
}
- if(found && !usefixedrate)
+ if(found && !usefixedrate) // If a control FIFO item was found, takes priority over automation controller stream.
nsamp = frame - sample;
if(sample + nsamp >= nframes) // Safety check.
nsamp = nframes - sample;
- // TODO: TESTING: Don't allow zero-length runs. This could/should be checked in the control loop instead.
+ // TODO: 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;
@@ -1586,8 +1589,13 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP
#endif
if(start_event->time() >= (pos + sample + nsamp + frameOffset)) // frameOffset? Test again...
+ {
+ #ifdef DSSI_DEBUG
+ fprintf(stderr, " event is for future:%lu, breaking loop now\n", start_event->time() - frameOffset - pos - sample);
+ #endif
break;
-
+ }
+
// Update hardware state so knobs and boxes are updated. Optimize to avoid re-setting existing values.
// Same code as in MidiPort::sendEvent()
if(synti->midiPort() != -1)
@@ -2083,6 +2091,25 @@ void DssiSynthIF::queryPrograms()
}
}
+void DssiSynthIF::doSelectProgram(LADSPA_Handle handle, int bank, int prog)
+{
+ const DSSI_Descriptor* dssi = synth->dssi;
+ dssi->select_program(handle, bank, prog);
+
+ // Need to update the automation value, otherwise it overwrites later with the last automation value.
+ // "A plugin is permitted to re-write the values of its input control ports when select_program is called.
+ // The host should re-read the input control port values and update its own records appropriately.
+ // (This is the only circumstance in which a DSSI plugin is allowed to modify its own input ports.)" From dssi.h
+ if(id() != -1)
+ {
+ for(unsigned long k = 0; k < synth->_controlInPorts; ++k)
+ {
+ // We're in the audio thread context: no need to send a message, just modify directly.
+ synti->setPluginCtrlVal(genACnum(id(), k), controls[k].val);
+ }
+ }
+}
+
//---------------------------------------------------------
// getPatchName
//---------------------------------------------------------
@@ -2235,14 +2262,30 @@ 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; }
+void DssiSynthIF::enable2Controller(unsigned long i, bool v) { controls[i].en2Ctrl = v; }
bool DssiSynthIF::controllerEnabled2(unsigned long i) const { return controls[i].en2Ctrl; }
+void DssiSynthIF::enableAllControllers(bool v)
+{
+ if(!synth)
+ return;
+ for(unsigned long i = 0; i < synth->_controlInPorts; ++i)
+ controls[i].enCtrl = v;
+}
+void DssiSynthIF::enable2AllControllers(bool v)
+{
+ if(!synth)
+ return;
+ for(unsigned long i = 0; i < synth->_controlInPorts; ++i)
+ controls[i].en2Ctrl = v;
+}
+
void DssiSynthIF::updateControllers() { }
void DssiSynthIF::writeConfiguration(int /*level*/, Xml& /*xml*/) { }
bool DssiSynthIF::readConfiguration(Xml& /*xml*/, bool /*readPreset*/) { return false; }
unsigned long DssiSynthIF::parameters() const { return synth ? synth->_controlInPorts : 0; }
unsigned long DssiSynthIF::parametersOut() const { return synth ? synth->_controlOutPorts : 0; }
-void DssiSynthIF::setParam(unsigned long i, float val) { setParameter(i, val); }
+void DssiSynthIF::setParam(unsigned long i, float val) { setParameter(i, val); }
float DssiSynthIF::param(unsigned long i) const { return getParameter(i); }
float DssiSynthIF::paramOut(unsigned long i) const { return getParameterOut(i); }
const char* DssiSynthIF::paramName(unsigned long i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortNames[controls[i].idx] : 0; }
diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h
index 238b468e..46c9a07b 100644
--- a/muse2/muse/dssihost.h
+++ b/muse2/muse/dssihost.h
@@ -128,6 +128,7 @@ class DssiSynthIF : public SynthIF, public PluginIBase
std::vector<DSSI_Program_Descriptor> programs;
void queryPrograms();
+ void doSelectProgram(LADSPA_Handle handle, int bank, int prog);
bool processEvent(const MusECore::MidiPlayEvent&, snd_seq_event_t*);
float** audioInBuffers;
@@ -209,7 +210,10 @@ class DssiSynthIF : public SynthIF, public PluginIBase
MusECore::AudioTrack* track();
void enableController(unsigned long i, bool v = true);
bool controllerEnabled(unsigned long i) const;
+ void enable2Controller(unsigned long i, bool v = true);
bool controllerEnabled2(unsigned long i) const;
+ void enableAllControllers(bool v = true);
+ void enable2AllControllers(bool v = true);
void updateControllers();
void writeConfiguration(int level, Xml& xml);
bool readConfiguration(Xml& xml, bool readPreset=false);
diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp
index 1a0426a7..302007b3 100644
--- a/muse2/muse/gconfig.cpp
+++ b/muse2/muse/gconfig.cpp
@@ -186,7 +186,7 @@ GlobalConfigValues config = {
QString("./"), // projectBaseFolder
true, // projectStoreInFolder
true, // useProjectSaveDialog
- 64, // minControlProcessPeriod
+ 256, // minControlProcessPeriod
false, // popupsDefaultStayOpen
false, // leftMouseButtonCanDecrease
false, // rangeMarkerWithoutMMB
diff --git a/muse2/muse/globals.cpp b/muse2/muse/globals.cpp
index d92e6abf..b3765074 100644
--- a/muse2/muse/globals.cpp
+++ b/muse2/muse/globals.cpp
@@ -275,6 +275,12 @@ unsigned char rcPlayNote = 29;
unsigned char rcSteprecNote = 36;
bool automation = true;
+// Midi learn params. These will be initialized to -1 by any midi learn function,
+// and then filled by the midi engine in response to the drivers.
+int midiLearnPort = -1;
+int midiLearnChan = -1;
+int midiLearnCtrl = -1;
+
uid_t euid, ruid; // effective user id, real user id
bool midiSeqRunning = false;
diff --git a/muse2/muse/globals.h b/muse2/muse/globals.h
index c64fdf89..bdf383c8 100644
--- a/muse2/muse/globals.h
+++ b/muse2/muse/globals.h
@@ -172,6 +172,10 @@ extern unsigned char rcGotoLeftMarkNote;
extern unsigned char rcPlayNote;
extern unsigned char rcSteprecNote;
+extern int midiLearnPort;
+extern int midiLearnChan;
+extern int midiLearnCtrl;
+
extern bool midiSeqRunning;
extern bool automation;
diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp
index ae348b5f..503208e6 100644
--- a/muse2/muse/midi.cpp
+++ b/muse2/muse/midi.cpp
@@ -34,6 +34,7 @@
#include "marker/marker.h"
#include "midiport.h"
#include "midictrl.h"
+#include "sync.h"
#include "audio.h"
#include "mididev.h"
#include "driver/alsamidi.h"
@@ -860,31 +861,149 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned
void Audio::processMidi()
{
MusEGlobal::midiBusy=true;
+
+ bool extsync = MusEGlobal::extSyncFlag.value();
+
//
// TODO: syntis should directly write into recordEventList
//
- for (iMidiDevice id = MusEGlobal::midiDevices.begin(); id != MusEGlobal::midiDevices.end(); ++id) {
- MidiDevice* md = *id;
-
- // klumsy hack for synti devices:
- if(md->isSynti())
+ for (iMidiDevice id = MusEGlobal::midiDevices.begin(); id != MusEGlobal::midiDevices.end(); ++id)
+ {
+ MidiDevice* md = *id;
+
+ // klumsy hack for MESS synti devices:
+ if(md->isSynti())
+ {
+ SynthI* s = (SynthI*)md;
+ while (s->eventsPending())
+ {
+ MusECore::MidiRecordEvent ev = s->receiveEvent();
+ md->recordEvent(ev);
+ }
+ }
+
+ md->collectMidiEvents();
+
+ // Take snapshots of the current sizes of the recording fifos,
+ // because they may change while here in process, asynchronously.
+ md->beforeProcess();
+
+ //
+ // --------- Handle midi events for audio tracks -----------
+ //
+
+ int port = md->midiPort(); // Port should be same as event.port() from this device. Same idea event.channel().
+ if(port < 0)
+ continue;
+
+ for(int chan = 0; chan < MIDI_CHANNELS; ++chan)
+ {
+ MusECore::MidiRecFifo& rf = md->recordEvents(chan);
+ int count = md->tmpRecordCount(chan);
+ for(int i = 0; i < count; ++i)
+ {
+ MusECore::MidiRecordEvent event(rf.peek(i));
+
+ int etype = event.type();
+ if(etype == MusECore::ME_CONTROLLER || etype == MusECore::ME_PITCHBEND || etype == MusECore::ME_PROGRAM)
{
- SynthI* s = (SynthI*)md;
- while (s->eventsPending())
+ int ctl, val;
+ if(etype == MusECore::ME_CONTROLLER)
{
- MusECore::MidiRecordEvent ev = s->receiveEvent();
- md->recordEvent(ev);
+ ctl = event.dataA();
+ val = event.dataB();
}
+ else if(etype == MusECore::ME_PITCHBEND)
+ {
+ ctl = MusECore::CTRL_PITCH;
+ val = event.dataA();
+ }
+ else if(etype == MusECore::ME_PROGRAM)
+ {
+ ctl = MusECore::CTRL_PROGRAM;
+ val = event.dataA();
+ }
+
+ // Midi learn!
+ MusEGlobal::midiLearnPort = port;
+ MusEGlobal::midiLearnChan = chan;
+ MusEGlobal::midiLearnCtrl = ctl;
+
+ // Send to audio tracks...
+ for (MusECore::iTrack t = MusEGlobal::song->tracks()->begin(); t != MusEGlobal::song->tracks()->end(); ++t)
+ {
+ if((*t)->isMidiTrack())
+ continue;
+ MusECore::AudioTrack* track = static_cast<MusECore::AudioTrack*>(*t);
+ MidiAudioCtrlMap* macm = track->controller()->midiControls();
+ int h = macm->index_hash(port, chan, ctl);
+ std::pair<ciMidiAudioCtrlMap, ciMidiAudioCtrlMap> range = macm->equal_range(h);
+ for(ciMidiAudioCtrlMap imacm = range.first; imacm != range.second; ++imacm)
+ {
+ const MidiAudioCtrlStruct* macs = &imacm->second;
+ int actrl = macs->audioCtrlId();
+
+ iCtrlList icl = track->controller()->find(actrl);
+ if(icl == track->controller()->end())
+ continue;
+ CtrlList* cl = icl->second;
+ double dval = midi2AudioCtrlValue(cl, macs, ctl, val);
+
+ // Time here needs to be frames always.
+ unsigned int ev_t = event.time();
+ unsigned int t = ev_t;
+
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ unsigned int pframe = _previousPos.frame();
+#else
+ unsigned int pframe = _pos.frame();
+#endif
+ if(pframe > t) // Technically that's an error, shouldn't happen
+ t = 0;
+ else
+ // Subtract the current audio position frame
+ t -= pframe;
+
+ // Add the current running sync frame to make the control processing happy
+ t += syncFrame;
+ track->addScheduledControlEvent(actrl, dval, t);
+
+ // Rec automation...
+
+ // For the record time, if stopped we don't want the circular running position,
+ // just the static one.
+ unsigned int rec_t = isPlaying() ? ev_t : pframe;
+
+ if(!MusEGlobal::automation)
+ continue;
+ AutomationType at = track->automationType();
+ // Unlike our built-in gui controls, there is not much choice here but to
+ // just do this:
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
+ //if(isPlaying() && (at == AUTO_WRITE || at == AUTO_TOUCH)) DELETETHIS
+ track->enableController(actrl, false);
+ if(isPlaying())
+ {
+ if(at == AUTO_WRITE || at == AUTO_TOUCH)
+ track->recEvents()->push_back(CtrlRecVal(rec_t, actrl, dval));
+ }
+ else
+ {
+ if(at == AUTO_WRITE)
+ track->recEvents()->push_back(CtrlRecVal(rec_t, actrl, dval));
+ else if(at == AUTO_TOUCH)
+ // In touch mode and not playing. Send directly to controller list.
+ // Add will replace if found.
+ cl->add(rec_t, dval);
+ }
+ }
+ }
}
-
- md->collectMidiEvents();
-
- // Take snapshots of the current sizes of the recording fifos,
- // because they may change while here in process, asynchronously.
- md->beforeProcess();
- }
+ }
+ }
+ }
- bool extsync = MusEGlobal::extSyncFlag.value();
for (MusECore::iMidiTrack t = MusEGlobal::song->midis()->begin(); t != MusEGlobal::song->midis()->end(); ++t)
{
MusECore::MidiTrack* track = *t;
@@ -934,15 +1053,30 @@ void Audio::processMidi()
for(int i = 0; i < count; ++i)
{
- MusECore::MidiPlayEvent event(rf.peek(i));
+ MusECore::MidiRecordEvent event(rf.peek(i));
event.setPort(port);
// dont't echo controller changes back to software
// synthesizer:
if(!dev->isSynti() && md && track->recEcho())
+ {
+ // All recorded events arrived in the previous period. Shift into this period for playback.
+ unsigned int et = event.time();
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ unsigned int t = et - _previousPos.frame() + _pos.frame() + frameOffset;
+#else
+ unsigned int t = et + frameOffset;
+#endif
+ event.setTime(t);
md->addScheduledEvent(event);
- // If syncing externally the event time is already in units of ticks, set above. p3.3.25
- if(!extsync)
- event.setTime(MusEGlobal::tempomap.frame2tick(event.time())); // set tick time
+ event.setTime(et); // Restore for recording.
+ }
+
+ // Make sure the event is recorded in units of ticks.
+ if(extsync)
+ event.setTime(event.tick()); // HACK: Transfer the tick to the frame time
+ else
+ event.setTime(MusEGlobal::tempomap.frame2tick(event.time()));
+
if(recording)
rl->add(event);
}
@@ -953,7 +1087,7 @@ void Audio::processMidi()
int count = dev->tmpRecordCount(channel);
for(int i = 0; i < count; ++i)
{
- MusECore::MidiPlayEvent event(rf.peek(i));
+ MusECore::MidiRecordEvent event(rf.peek(i));
int defaultPort = devport;
int drumRecPitch=0; //prevent compiler warning: variable used without initialization
MusECore::MidiController *mc = 0;
@@ -1073,7 +1207,16 @@ void Audio::processMidi()
if (!dev->isSynti())
{
- //Check if we're outputting to another port than default:
+ // All recorded events arrived in previous period. Shift into this period for playback.
+ // frameoffset needed to make process happy.
+ unsigned int et = event.time();
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ unsigned int t = et - _previousPos.frame() + _pos.frame() + frameOffset;
+#else
+ unsigned int t = et + frameOffset;
+#endif
+ event.setTime(t);
+ // Check if we're outputting to another port than default:
if (devport == defaultPort) {
event.setPort(port);
if(md && track->recEcho())
@@ -1085,14 +1228,18 @@ void Audio::processMidi()
if(mdAlt && track->recEcho())
mdAlt->addScheduledEvent(event);
}
+ event.setTime(et); // Restore for recording.
+
// Shall we activate meters even while rec echo is off? Sure, why not...
if(event.isNote() && event.dataB() > track->activity())
track->setActivity(event.dataB());
}
- // If syncing externally the event time is already in units of ticks, set above. p3.3.25
- if(!extsync)
- event.setTime(MusEGlobal::tempomap.frame2tick(event.time())); // set tick time
+ // Make sure the event is recorded in units of ticks.
+ if(extsync)
+ event.setTime(event.tick()); // HACK: Transfer the tick to the frame time
+ else
+ event.setTime(MusEGlobal::tempomap.frame2tick(event.time()));
// Special handling of events stored in rec-lists. a bit hACKish. TODO: Clean up (after 0.7)! :-/ (ml)
if (recording)
diff --git a/muse2/muse/midictrl.cpp b/muse2/muse/midictrl.cpp
index b95ccf77..63ce6fe6 100644
--- a/muse2/muse/midictrl.cpp
+++ b/muse2/muse/midictrl.cpp
@@ -306,6 +306,39 @@ MidiController::ControllerType midiControllerType(int num)
}
//---------------------------------------------------------
+// midiCtrlTerms2Number
+//---------------------------------------------------------
+
+int midiCtrlTerms2Number(int type_num, int ctrl)
+{
+ ctrl &= 0xffff;
+ switch(type_num)
+ {
+ case MidiController::Controller7:
+ return ctrl & 0xff;
+ case MidiController::Controller14:
+ return CTRL_14_OFFSET + ctrl;
+ case MidiController::RPN:
+ return CTRL_RPN_OFFSET + ctrl;
+ case MidiController::NRPN:
+ return CTRL_NRPN_OFFSET + ctrl;
+ case MidiController::Pitch:
+ return CTRL_PITCH;
+ case MidiController::Program:
+ return CTRL_PROGRAM;
+ case MidiController::Velo:
+ return CTRL_VELOCITY;
+ case MidiController::RPN14:
+ return CTRL_RPN14_OFFSET + ctrl;
+ case MidiController::NRPN14:
+ return CTRL_NRPN14_OFFSET + ctrl;
+ default:
+ printf("MusE: unknown ctrl type in midiCtrTerms2Number()\n");
+ return ctrl;
+ }
+}
+
+//---------------------------------------------------------
// updateBias
//---------------------------------------------------------
diff --git a/muse2/muse/midictrl.h b/muse2/muse/midictrl.h
index 74902bc2..4c9a4097 100644
--- a/muse2/muse/midictrl.h
+++ b/muse2/muse/midictrl.h
@@ -242,6 +242,7 @@ typedef MidiControllerList MidiControllerList;
extern MidiControllerList defaultMidiController;
extern void initMidiController();
extern MidiController::ControllerType midiControllerType(int num);
+extern int midiCtrlTerms2Number(int type_num, int ctrl);
extern const QString& int2ctrlType(int n);
diff --git a/muse2/muse/mididev.cpp b/muse2/muse/mididev.cpp
index becab6f7..5ff8bf94 100644
--- a/muse2/muse/mididev.cpp
+++ b/muse2/muse/mididev.cpp
@@ -46,7 +46,6 @@
namespace MusEGlobal {
MusECore::MidiDeviceList midiDevices;
-extern unsigned int volatile lastExtMidiSyncTick;
}
namespace MusECore {
@@ -215,10 +214,14 @@ void MidiDevice::beforeProcess()
void MidiDevice::recordEvent(MidiRecordEvent& event)
{
- // TODO: Tested, but record resolution not so good. Switch to wall clock based separate list in MidiDevice. And revert this line.
- //event.setTime(MusEGlobal::audio->timestamp());
- event.setTime(MusEGlobal::extSyncFlag.value() ? MusEGlobal::lastExtMidiSyncTick : MusEGlobal::audio->timestamp());
-
+ // TODO: Tested, but record resolution not so good. Switch to wall clock based separate list in MidiDevice.
+ unsigned frame_ts = MusEGlobal::audio->timestamp();
+#ifndef _AUDIO_USE_TRUE_FRAME_
+ if(MusEGlobal::audio->isPlaying())
+ frame_ts += MusEGlobal::segmentSize; // Shift forward into this period if playing
+#endif
+ event.setTime(frame_ts);
+ event.setTick(MusEGlobal::lastExtMidiSyncTick);
if(MusEGlobal::audio->isPlaying())
event.setLoopNum(MusEGlobal::audio->loopCount());
@@ -300,7 +303,7 @@ void MidiDevice::recordEvent(MidiRecordEvent& event)
// Split the events up into channel fifos. Special 'channel' number 17 for sysex events.
unsigned int ch = (typ == ME_SYSEX)? MIDI_CHANNELS : event.channel();
- if(_recordFifo[ch].put(MidiPlayEvent(event)))
+ if(_recordFifo[ch].put(event))
printf("MidiDevice::recordEvent: fifo channel %d overflow\n", ch);
}
diff --git a/muse2/muse/midiseq.cpp b/muse2/muse/midiseq.cpp
index 300382e9..2cfc1917 100644
--- a/muse2/muse/midiseq.cpp
+++ b/muse2/muse/midiseq.cpp
@@ -287,6 +287,18 @@ MidiSeq::MidiSeq(const char* name)
lastTempo = 0;
storedtimediffs = 0;
playStateExt = false; // not playing
+
+ _clockAveragerStages = new int[16]; // Max stages is 16!
+ setSyncRecFilterPreset(MusEGlobal::syncRecFilterPreset);
+
+ for(int i = 0; i < _clockAveragerPoles; ++i)
+ {
+ _avgClkDiffCounter[i] = 0;
+ _averagerFull[i] = false;
+ }
+ _tempoQuantizeAmount = 1.0;
+ _lastRealTempo = 0.0;
+
MusEGlobal::doSetuid();
timerFd=selectTimer();
MusEGlobal::undoSetuid();
@@ -300,6 +312,7 @@ MidiSeq::MidiSeq(const char* name)
MidiSeq::~MidiSeq()
{
delete timer;
+ delete _clockAveragerStages;
}
//---------------------------------------------------------
@@ -505,11 +518,70 @@ void MidiSeq::checkAndReportTimingResolution()
"Timing source frequency is %1hz, which is below the recommended minimum: 500hz!\n" \
"This could lead to audible timing problems for MIDI.\n" \
"Please see the FAQ on http://muse-sequencer.org for remedies.\n" \
- "Also please check console output for any further error messages\n ")).arg(freq) );
+ "Also please check console output for any further error messages.\n ")).arg(freq) );
}
}
//---------------------------------------------------------
+// setSyncRecFilterPreset
+// To be called in realtime thread only.
+//---------------------------------------------------------
+void MidiSeq::setSyncRecFilterPreset(MidiSyncInfo::SyncRecFilterPresetType type)
+{
+ _syncRecFilterPreset = type;
+ alignAllTicks();
+
+ switch(_syncRecFilterPreset)
+ {
+ // NOTE: Max _clockAveragerPoles is 16 and maximum stages is 48 per pole !
+ case MidiSyncInfo::NONE:
+ _clockAveragerPoles = 0;
+ _preDetect = false;
+ break;
+ case MidiSyncInfo::TINY:
+ _clockAveragerPoles = 2;
+ _clockAveragerStages[0] = 4;
+ _clockAveragerStages[1] = 4;
+ _preDetect = false;
+ break;
+ case MidiSyncInfo::SMALL:
+ _clockAveragerPoles = 3;
+ _clockAveragerStages[0] = 12;
+ _clockAveragerStages[1] = 8;
+ _clockAveragerStages[2] = 4;
+ _preDetect = false;
+ break;
+ case MidiSyncInfo::MEDIUM:
+ _clockAveragerPoles = 3;
+ _clockAveragerStages[0] = 28;
+ _clockAveragerStages[1] = 12;
+ _clockAveragerStages[2] = 8;
+ _preDetect = false;
+ break;
+ case MidiSyncInfo::LARGE:
+ _clockAveragerPoles = 4;
+ _clockAveragerStages[0] = 48;
+ _clockAveragerStages[1] = 48;
+ _clockAveragerStages[2] = 48;
+ _clockAveragerStages[3] = 48;
+ _preDetect = false;
+ break;
+ case MidiSyncInfo::LARGE_WITH_PRE_DETECT:
+ _clockAveragerPoles = 4;
+ _clockAveragerStages[0] = 8;
+ _clockAveragerStages[1] = 48;
+ _clockAveragerStages[2] = 48;
+ _clockAveragerStages[3] = 48;
+ _preDetect = true;
+ break;
+
+ default:
+ printf("MidiSeq::setSyncRecFilterPreset unknown preset type:%d\n", (int)type);
+ }
+}
+
+
+//---------------------------------------------------------
// processMidiClock
//---------------------------------------------------------
diff --git a/muse2/muse/midiseq.h b/muse2/muse/midiseq.h
index b5ed1099..08adcdce 100644
--- a/muse2/muse/midiseq.h
+++ b/muse2/muse/midiseq.h
@@ -28,6 +28,7 @@
#include "mpevent.h"
#include "driver/alsatimer.h"
#include "driver/rtctimer.h"
+#include "sync.h"
namespace MusECore {
@@ -55,9 +56,17 @@ class MidiSeq : public Thread {
double songtick1, songtick2;
int recTick1, recTick2;
int lastTempo;
- double timediff[24];
+ double timediff[16][48];
int storedtimediffs;
-
+ int _avgClkDiffCounter[16];
+ double _lastRealTempo;
+ bool _averagerFull[16];
+ int _clockAveragerPoles;
+ int* _clockAveragerStages;
+ bool _preDetect;
+ double _tempoQuantizeAmount;
+ MidiSyncInfo::SyncRecFilterPresetType _syncRecFilterPreset;
+
void alignAllTicks(int frameOverride = 0);
/* Testing */
@@ -87,13 +96,17 @@ class MidiSeq : public Thread {
bool externalPlayState() const { return playStateExt; }
void setExternalPlayState(bool v) { playStateExt = v; }
- void realtimeSystemInput(int, int);
+ void realtimeSystemInput(int port, int type, double time = 0.0);
void mtcInputQuarter(int, unsigned char);
void setSongPosition(int, int);
void mmcInput(int, const unsigned char*, int);
void mtcInputFull(int, const unsigned char*, int);
void nonRealtimeSystemSysex(int, const unsigned char*, int);
void checkAndReportTimingResolution();
+ MidiSyncInfo::SyncRecFilterPresetType syncRecFilterPreset() const { return _syncRecFilterPreset; }
+ void setSyncRecFilterPreset(MidiSyncInfo::SyncRecFilterPresetType type);
+ double recTempoValQuant() const { return _tempoQuantizeAmount; }
+ void setRecTempoValQuant(double q) { _tempoQuantizeAmount = q; }
void msgMsg(int id);
void msgSeek();
diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp
index 7699af41..3b0a8707 100644
--- a/muse2/muse/mixer/astrip.cpp
+++ b/muse2/muse/mixer/astrip.cpp
@@ -455,10 +455,11 @@ void AudioStrip::auxLabelChanged(double val, unsigned int idx)
// volumeChanged
//---------------------------------------------------------
-void AudioStrip::volumeChanged(double val)
+void AudioStrip::volumeChanged(double val, int, bool shift_pressed)
{
AutomationType at = ((MusECore::AudioTrack*)track)->automationType();
- if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH))
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
track->enableVolumeController(false);
double vol;
@@ -472,12 +473,7 @@ void AudioStrip::volumeChanged(double val)
//MusEGlobal::audio->msgSetVolume((MusECore::AudioTrack*)track, vol);
// p4.0.21 MusEGlobal::audio->msgXXX waits. Do we really need to?
((MusECore::AudioTrack*)track)->setVolume(vol);
- MusEGlobal::song->controllerChange(track);
-
- ((MusECore::AudioTrack*)track)->recordAutomation(MusECore::AC_VOLUME, vol);
-
- //MusEGlobal::song->update(SC_TRACK_MODIFIED); // for graphical automation update
- //MusEGlobal::song->controllerChange(track);
+ if (!shift_pressed) ((MusECore::AudioTrack*)track)->recordAutomation(MusECore::AC_VOLUME, vol);
}
//---------------------------------------------------------
@@ -487,7 +483,7 @@ void AudioStrip::volumeChanged(double val)
void AudioStrip::volumePressed()
{
AutomationType at = ((MusECore::AudioTrack*)track)->automationType();
- if(at == AUTO_WRITE || (at == AUTO_READ || at == AUTO_TOUCH))
+ if (at == AUTO_READ || at == AUTO_TOUCH || at == AUTO_WRITE)
track->enableVolumeController(false);
double val = slider->value();
@@ -502,8 +498,6 @@ void AudioStrip::volumePressed()
//MusEGlobal::audio->msgSetVolume((MusECore::AudioTrack*)track, volume);
// p4.0.21 MusEGlobal::audio->msgXXX waits. Do we really need to?
((MusECore::AudioTrack*)track)->setVolume(volume);
- MusEGlobal::song->controllerChange(track);
-
((MusECore::AudioTrack*)track)->startAutoRecord(MusECore::AC_VOLUME, volume);
}
@@ -513,7 +507,8 @@ void AudioStrip::volumePressed()
void AudioStrip::volumeReleased()
{
- if(track->automationType() != AUTO_WRITE)
+ AutomationType at = track->automationType();
+ if (at == AUTO_OFF || at == AUTO_READ || at == AUTO_TOUCH)
track->enableVolumeController(true);
((MusECore::AudioTrack*)track)->stopAutoRecord(MusECore::AC_VOLUME, volume);
@@ -534,7 +529,8 @@ void AudioStrip::volumeRightClicked(const QPoint &p)
void AudioStrip::volLabelChanged(double val)
{
AutomationType at = ((MusECore::AudioTrack*)track)->automationType();
- if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH))
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
track->enableVolumeController(false);
double vol;
@@ -549,8 +545,6 @@ void AudioStrip::volLabelChanged(double val)
//audio->msgSetVolume((MusECore::AudioTrack*)track, vol);
// p4.0.21 audio->msgXXX waits. Do we really need to?
((MusECore::AudioTrack*)track)->setVolume(vol);
- MusEGlobal::song->controllerChange(track);
-
((MusECore::AudioTrack*)track)->startAutoRecord(MusECore::AC_VOLUME, vol);
}
@@ -558,19 +552,18 @@ void AudioStrip::volLabelChanged(double val)
// panChanged
//---------------------------------------------------------
-void AudioStrip::panChanged(double val)
+void AudioStrip::panChanged(double val, int, bool shift_pressed)
{
AutomationType at = ((MusECore::AudioTrack*)track)->automationType();
- if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH))
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
track->enablePanController(false);
panVal = val;
//MusEGlobal::audio->msgSetPan(((MusECore::AudioTrack*)track), val);
// p4.0.21 MusEGlobal::audio->msgXXX waits. Do we really need to?
((MusECore::AudioTrack*)track)->setPan(val);
- MusEGlobal::song->controllerChange(track);
-
- ((MusECore::AudioTrack*)track)->recordAutomation(MusECore::AC_PAN, val);
+ if (!shift_pressed) ((MusECore::AudioTrack*)track)->recordAutomation(MusECore::AC_PAN, val);
}
//---------------------------------------------------------
@@ -580,15 +573,13 @@ void AudioStrip::panChanged(double val)
void AudioStrip::panPressed()
{
AutomationType at = ((MusECore::AudioTrack*)track)->automationType();
- if(at == AUTO_WRITE || (at == AUTO_READ || at == AUTO_TOUCH))
+ if (at == AUTO_READ || at == AUTO_TOUCH || at == AUTO_WRITE)
track->enablePanController(false);
panVal = pan->value();
//MusEGlobal::audio->msgSetPan(((MusECore::AudioTrack*)track), panVal);
// p4.0.21 MusEGlobal::audio->msgXXX waits. Do we really need to?
((MusECore::AudioTrack*)track)->setPan(panVal);
- MusEGlobal::song->controllerChange(track);
-
((MusECore::AudioTrack*)track)->startAutoRecord(MusECore::AC_PAN, panVal);
}
@@ -598,7 +589,8 @@ void AudioStrip::panPressed()
void AudioStrip::panReleased()
{
- if(track->automationType() != AUTO_WRITE)
+ AutomationType at = track->automationType();
+ if (at == AUTO_OFF || at == AUTO_READ || at == AUTO_TOUCH)
track->enablePanController(true);
((MusECore::AudioTrack*)track)->stopAutoRecord(MusECore::AC_PAN, panVal);
}
@@ -617,8 +609,9 @@ void AudioStrip::panRightClicked(const QPoint &p)
void AudioStrip::panLabelChanged(double val)
{
- AutomationType at = ((MusECore::AudioTrack*)track)->automationType();
- if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH))
+ AutomationType at = ((MusECore::AudioTrack*)track)->automationType();
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
track->enablePanController(false);
panVal = val;
@@ -626,8 +619,6 @@ void AudioStrip::panLabelChanged(double val)
//MusEGlobal::audio->msgSetPan((MusECore::AudioTrack*)track, val);
// p4.0.21 MusEGlobal::audio->msgXXX waits. Do we really need to?
((MusECore::AudioTrack*)track)->setPan(val);
- MusEGlobal::song->controllerChange(track);
-
((MusECore::AudioTrack*)track)->startAutoRecord(MusECore::AC_PAN, val);
}
@@ -727,11 +718,10 @@ MusEGui::Knob* AudioStrip::addKnob(int type, int id, MusEGui::DoubleLabel** dlab
_curGridRow += 2;
connect(knob, SIGNAL(valueChanged(double,int)), pl, SLOT(setValue(double)));
- //connect(pl, SIGNAL(valueChanged(double, int)), SLOT(panChanged(double)));
if (type == 0) {
connect(pl, SIGNAL(valueChanged(double, int)), SLOT(panLabelChanged(double)));
- connect(knob, SIGNAL(sliderMoved(double,int)), SLOT(panChanged(double)));
+ connect(knob, SIGNAL(sliderMoved(double,int,bool)), SLOT(panChanged(double,int,bool)));
connect(knob, SIGNAL(sliderPressed(int)), SLOT(panPressed()));
connect(knob, SIGNAL(sliderReleased(int)), SLOT(panReleased()));
connect(knob, SIGNAL(sliderRightClicked(const QPoint &, int)), SLOT(panRightClicked(const QPoint &)));
@@ -894,9 +884,8 @@ AudioStrip::AudioStrip(QWidget* parent, MusECore::AudioTrack* at)
sl->setValue(MusECore::fast_log10(t->volume()) * 20.0);
connect(sl, SIGNAL(valueChanged(double,int)), SLOT(volLabelChanged(double)));
- //connect(sl, SIGNAL(valueChanged(double,int)), SLOT(volumeChanged(double)));
connect(slider, SIGNAL(valueChanged(double,int)), sl, SLOT(setValue(double)));
- connect(slider, SIGNAL(sliderMoved(double,int)), SLOT(volumeChanged(double)));
+ connect(slider, SIGNAL(sliderMoved(double,int,bool)), SLOT(volumeChanged(double,int,bool)));
connect(slider, SIGNAL(sliderPressed(int)), SLOT(volumePressed()));
connect(slider, SIGNAL(sliderReleased(int)), SLOT(volumeReleased()));
connect(slider, SIGNAL(sliderRightClicked(const QPoint &, int)), SLOT(volumeRightClicked(const QPoint &)));
diff --git a/muse2/muse/mixer/astrip.h b/muse2/muse/mixer/astrip.h
index f5406652..c0df5360 100644
--- a/muse2/muse/mixer/astrip.h
+++ b/muse2/muse/mixer/astrip.h
@@ -94,10 +94,10 @@ class AudioStrip : public Strip {
void iRoutePressed();
void oRoutePressed();
void auxChanged(double, int);
- void volumeChanged(double);
+ void volumeChanged(double,int,bool);
void volumePressed();
void volumeReleased();
- void panChanged(double);
+ void panChanged(double,int,bool);
void panPressed();
void panReleased();
void volLabelChanged(double);
diff --git a/muse2/muse/mixer/panknob.cpp b/muse2/muse/mixer/panknob.cpp
index dc2564a7..c54a112f 100644
--- a/muse2/muse/mixer/panknob.cpp
+++ b/muse2/muse/mixer/panknob.cpp
@@ -48,7 +48,6 @@ void PanKnob::valueChanged(double val)
//audio->msgSetPan(src, val);
// p4.0.21 audio->msgXXX waits. Do we really need to?
src->setPan(val);
- MusEGlobal::song->controllerChange(src);
}
} // namespace MusEGui
diff --git a/muse2/muse/mpevent.cpp b/muse2/muse/mpevent.cpp
index d3709b1f..a8596224 100644
--- a/muse2/muse/mpevent.cpp
+++ b/muse2/muse/mpevent.cpp
@@ -178,7 +178,7 @@ void MidiFifo::remove()
// return true on fifo overflow
//---------------------------------------------------------
-bool MidiRecFifo::put(const MidiPlayEvent& event)
+bool MidiRecFifo::put(const MidiRecordEvent& event)
{
if (size < MIDI_REC_FIFO_SIZE) {
fifo[wIndex] = event;
@@ -193,9 +193,9 @@ bool MidiRecFifo::put(const MidiPlayEvent& event)
// get
//---------------------------------------------------------
-MidiPlayEvent MidiRecFifo::get()
+MidiRecordEvent MidiRecFifo::get()
{
- MidiPlayEvent event(fifo[rIndex]);
+ MidiRecordEvent event(fifo[rIndex]);
rIndex = (rIndex + 1) % MIDI_REC_FIFO_SIZE;
--size;
return event;
@@ -205,7 +205,7 @@ MidiPlayEvent MidiRecFifo::get()
// peek
//---------------------------------------------------------
-const MidiPlayEvent& MidiRecFifo::peek(int n)
+const MidiRecordEvent& MidiRecFifo::peek(int n)
{
int idx = (rIndex + n) % MIDI_REC_FIFO_SIZE;
return fifo[idx];
diff --git a/muse2/muse/mpevent.h b/muse2/muse/mpevent.h
index 9b64f9cd..903a8126 100644
--- a/muse2/muse/mpevent.h
+++ b/muse2/muse/mpevent.h
@@ -111,6 +111,8 @@ class MEvent {
//---------------------------------------------------------
class MidiRecordEvent : public MEvent {
+ private:
+ unsigned int _tick; // To store tick when external sync is on, required besides frame.
public:
MidiRecordEvent() : MEvent() {}
MidiRecordEvent(const MEvent& e) : MEvent(e) {}
@@ -121,6 +123,9 @@ class MidiRecordEvent : public MEvent {
MidiRecordEvent(unsigned t, int p, int type, EvData data)
: MEvent(t, p, type, data) {}
~MidiRecordEvent() {}
+
+ unsigned int tick() {return _tick;}
+ void setTick(unsigned int tick) {_tick = tick;}
};
//---------------------------------------------------------
@@ -200,20 +205,19 @@ class MidiFifo {
//---------------------------------------------------------
// MidiRecFifo
-// (Same as MidiFifo, but with a smaller size.)
//---------------------------------------------------------
class MidiRecFifo {
- MidiPlayEvent fifo[MIDI_REC_FIFO_SIZE];
+ MidiRecordEvent fifo[MIDI_REC_FIFO_SIZE];
volatile int size;
int wIndex;
int rIndex;
public:
MidiRecFifo() { clear(); }
- bool put(const MidiPlayEvent& event); // returns true on fifo overflow
- MidiPlayEvent get();
- const MidiPlayEvent& peek(int = 0);
+ bool put(const MidiRecordEvent& event); // returns true on fifo overflow
+ MidiRecordEvent get();
+ const MidiRecordEvent& peek(int = 0);
void remove();
bool isEmpty() const { return size == 0; }
void clear() { size = 0, wIndex = 0, rIndex = 0; }
diff --git a/muse2/muse/node.cpp b/muse2/muse/node.cpp
index e56949aa..02264a37 100644
--- a/muse2/muse/node.cpp
+++ b/muse2/muse/node.cpp
@@ -401,10 +401,10 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s
// precalculate stereo volume
double vol[2];
- //double _volume = volume();
- //double _pan = pan();
- double _volume = controller()->value(AC_VOLUME, pos);
- double _pan = controller()->value(AC_PAN, pos);
+ double _volume = controller()->value(AC_VOLUME, pos,
+ !MusEGlobal::automation || automationType() == AUTO_OFF || !_volumeEnCtrl || !_volumeEn2Ctrl);
+ double _pan = controller()->value(AC_PAN, pos,
+ !MusEGlobal::automation || automationType() == AUTO_OFF || !_panEnCtrl || !_panEn2Ctrl);
vol[0] = _volume * (1.0 - _pan);
vol[1] = _volume * (1.0 + _pan);
@@ -739,10 +739,10 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr
// precalculate stereo volume
double vol[2];
- //double _volume = volume();
- //double _pan = pan();
- double _volume = controller()->value(AC_VOLUME, pos);
- double _pan = controller()->value(AC_PAN, pos);
+ double _volume = controller()->value(AC_VOLUME, pos,
+ !MusEGlobal::automation || automationType() == AUTO_OFF || !_volumeEnCtrl || !_volumeEn2Ctrl);
+ double _pan = controller()->value(AC_PAN, pos,
+ !MusEGlobal::automation || automationType() == AUTO_OFF || !_panEnCtrl || !_panEn2Ctrl);
vol[0] = _volume * (1.0 - _pan);
vol[1] = _volume * (1.0 + _pan);
diff --git a/muse2/muse/osc.cpp b/muse2/muse/osc.cpp
index 0d4a1750..381e4acc 100644
--- a/muse2/muse/osc.cpp
+++ b/muse2/muse/osc.cpp
@@ -1092,7 +1092,7 @@ int OscDssiIF::oscControl(lo_arg** argv)
if(_oscSynthIF)
{
_oscSynthIF->oscControl(argv[0]->i, argv[1]->f);
- if (port<maxDssiPort)
+ if (port<(int)maxDssiPort)
old_control[control_port_mapper->at(port)]=argv[1]->f;
}
@@ -1170,7 +1170,7 @@ int OscEffectIF::oscControl(lo_arg** argv)
if(_oscPluginI)
{
_oscPluginI->oscControl(argv[0]->i, argv[1]->f);
- if (port<maxDssiPort)
+ if (port<(int)maxDssiPort)
old_control[control_port_mapper->at(port)]=argv[1]->f;
}
diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp
index a632bc9c..9950c362 100644
--- a/muse2/muse/part.cpp
+++ b/muse2/muse/part.cpp
@@ -864,17 +864,18 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo
unsigned event_endframe = event_startframe + e.lenFrame();
if (event_endframe < new_partlength)
continue;
- if (event_startframe > new_partlength) { // If event start was after the new length, remove it from part
- // Do not do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::DeleteEvent, e, nPart, false, false));
- continue;
- }
- if (event_endframe > new_partlength) { // If this event starts before new length and ends after, shrink it
- Event newEvent = e.clone();
- newEvent.setLenFrame(new_partlength - event_startframe);
- // Do not do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, e, nPart, false,false));
- }
+// REMOVE Tim.
+// if (event_startframe > new_partlength) { // If event start was after the new length, remove it from part
+// // Do not do port controller values and clone parts.
+// operations.push_back(UndoOp(UndoOp::DeleteEvent, e, nPart, false, false));
+// continue;
+// }
+// if (event_endframe > new_partlength) { // If this event starts before new length and ends after, shrink it
+// Event newEvent = e.clone();
+// newEvent.setLenFrame(new_partlength - event_startframe);
+// // Do not do port controller values and clone parts.
+// operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, e, nPart, false,false));
+// }
}
nPart->setLenFrame(new_partlength);
// Do not do port controller values and clone parts.
@@ -893,19 +894,20 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo
iEvent i = el->end();
i--;
Event last = i->second;
- unsigned last_start = last.frame();
+// REMOVE Tim. unsigned last_start = last.frame();
MusECore::SndFileR file = last.sndFile();
if (file.isNull())
return;
- unsigned clipframes = (file.samples() - last.spos());// / file.channels();
+// unsigned clipframes = (file.samples() - last.spos());// / file.channels();
Event newEvent = last.clone();
- unsigned new_eventlength = new_partlength - last_start;
- if (new_eventlength > clipframes) // Shrink event length if new partlength exceeds last clip
- new_eventlength = clipframes;
-
- newEvent.setLenFrame(new_eventlength);
+// REMOVE Tim.
+// unsigned new_eventlength = new_partlength - last_start;
+// if (new_eventlength > clipframes) // Shrink event length if new partlength exceeds last clip
+// new_eventlength = clipframes;
+//
+// newEvent.setLenFrame(new_eventlength);
// Do not do port controller values and clone parts.
operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, last, nPart, false, false));
}
@@ -1199,13 +1201,12 @@ WavePart* WavePart::clone() const
return new WavePart(*this);
}
-
//---------------------------------------------------------
// hasHiddenEvents
// Returns combination of HiddenEventsType enum.
//---------------------------------------------------------
-int Part::hasHiddenEvents()
+int MidiPart::hasHiddenEvents()
{
unsigned len = lenTick();
@@ -1222,7 +1223,27 @@ int Part::hasHiddenEvents()
return _hiddenEvents;
}
+//---------------------------------------------------------
+// hasHiddenEvents
+// Returns combination of HiddenEventsType enum.
+//---------------------------------------------------------
+int WavePart::hasHiddenEvents()
+{
+ unsigned len = lenFrame();
+
+ // TODO: For now, we don't support events before the left border, only events past the right border.
+ for(iEvent ev=events()->begin(); ev!=events()->end(); ev++)
+ {
+ if(ev->second.endFrame() > len)
+ {
+ _hiddenEvents = RightEventsHidden; // Cache the result for later.
+ return _hiddenEvents;
+ }
+ }
+ _hiddenEvents = NoEventsHidden; // Cache the result for later.
+ return _hiddenEvents;
+}
//---------------------------------------------------------
// ClonePart
diff --git a/muse2/muse/part.h b/muse2/muse/part.h
index f2bc342b..357ec1db 100644
--- a/muse2/muse/part.h
+++ b/muse2/muse/part.h
@@ -76,14 +76,13 @@ class Part : public PosLen {
bool _mute;
int _colorIndex;
- int _hiddenEvents; // Combination of HiddenEventsType.
-
protected:
Track* _track;
EventList* _events;
Part* _prevClone;
Part* _nextClone;
-
+ int _hiddenEvents; // Combination of HiddenEventsType.
+
public:
Part(Track*);
Part(Track*, EventList*);
@@ -114,7 +113,7 @@ class Part : public PosLen {
void setNextClone(Part* p) { _nextClone = p; }
// Returns combination of HiddenEventsType enum.
- int hasHiddenEvents();
+ virtual int hasHiddenEvents() = 0;
// If repeated calls to hasHiddenEvents() are desired, then to avoid re-iteration of the event list,
// call this after hasHiddenEvents().
int cachedHasHiddenEvents() const { return _hiddenEvents; }
@@ -140,7 +139,9 @@ class MidiPart : public Part {
virtual ~MidiPart() {}
virtual MidiPart* clone() const;
MidiTrack* track() const { return (MidiTrack*)Part::track(); }
-
+ // Returns combination of HiddenEventsType enum.
+ int hasHiddenEvents();
+
virtual void dump(int n = 0) const;
};
@@ -161,6 +162,8 @@ class WavePart : public Part {
virtual ~WavePart() {}
virtual WavePart* clone() const;
WaveTrack* track() const { return (WaveTrack*)Part::track(); }
+ // Returns combination of HiddenEventsType enum.
+ int hasHiddenEvents();
virtual void dump(int n = 0) const;
};
diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp
index 8bf35143..e8b0489c 100644
--- a/muse2/muse/plugin.cpp
+++ b/muse2/muse/plugin.cpp
@@ -32,6 +32,7 @@
#include <QButtonGroup>
#include <QCheckBox>
#include <QComboBox>
+#include <QCursor>
#include <QDir>
#include <QFile>
#include <QGridLayout>
@@ -78,6 +79,9 @@
// Turn on debugging messages.
//#define PLUGIN_DEBUGIN
+// Turn on constant stream of debugging messages.
+//#define PLUGIN_DEBUGIN_PROCESS
+
namespace MusEGlobal {
MusECore::PluginList plugins;
}
@@ -119,7 +123,7 @@ bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long por
*min = 0;
*max = 1;
- *def = (int)lrint(fdef);
+ *def = (int)lrintf(fdef);
return hasdef;
}
@@ -156,8 +160,8 @@ bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long por
fmax = 1.0;
frng = fmax - fmin;
- imin = lrint(fmin);
- imax = lrint(fmax);
+ imin = lrintf(fmin);
+ imax = lrintf(fmax);
int ctlmn = 0;
int ctlmx = 127;
@@ -230,7 +234,7 @@ bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long por
*min = imin;
*max = imax;
- *def = (int)lrint(fdef);
+ *def = (int)lrintf(fdef);
return hasdef;
}
@@ -244,7 +248,7 @@ bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long por
// FIXME: TODO: Incorrect... Fix this somewhat more trivial stuff later....
- *def = (int)lrint(fdef) + bias;
+ *def = (int)lrintf(fdef) + bias;
#ifdef PLUGIN_DEBUGIN
printf("ladspa2MidiControlValues: setting default:%d\n", *def);
@@ -305,7 +309,7 @@ float midi2LadspaValue(const LADSPA_Descriptor* plugin, unsigned long port, int
fmax = 1.0;
frng = fmax - fmin;
- imin = lrint(fmin);
+ imin = lrintf(fmin);
if(desc & LADSPA_HINT_TOGGLED)
{
@@ -619,40 +623,6 @@ void ladspaControlRange(const LADSPA_Descriptor* plugin, unsigned long port, flo
*max = 1.0;
}
-// DELETETHIS 35
-/*
-//---------------------------------------------------------
-// PluginBase
-//---------------------------------------------------------
-
-//---------------------------------------------------------
-// range
-//---------------------------------------------------------
-
-void PluginBase::range(unsigned long i, float* min, float* max) const
- {
- LADSPA_PortRangeHint range = plugin->PortRangeHints[i];
- LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor;
- if (desc & LADSPA_HINT_TOGGLED) {
- *min = 0.0;
- *max = 1.0;
- return;
- }
- float m = 1.0;
- if (desc & LADSPA_HINT_SAMPLE_RATE)
- m = float(MusEGlobal::sampleRate);
-
- if (desc & LADSPA_HINT_BOUNDED_BELOW)
- *min = range.LowerBound * m;
- else
- *min = 0.0;
- if (desc & LADSPA_HINT_BOUNDED_ABOVE)
- *max = range.UpperBound * m;
- else
- *max = 1.0;
- }
-*/
-
//---------------------------------------------------------
// Plugin
//---------------------------------------------------------
@@ -792,8 +762,7 @@ int Plugin::incReferences(int val)
if(dssi)
{
const DSSI_Descriptor* descr;
- //for(int i = 0;; ++i)
- for(unsigned long i = 0;; ++i) // p4.0.21
+ for(unsigned long i = 0;; ++i)
{
descr = dssi(i);
if(descr == NULL)
@@ -817,7 +786,7 @@ int Plugin::incReferences(int val)
if(ladspadf)
{
const LADSPA_Descriptor* descr;
- for(unsigned long i = 0;; ++i) // p4.0.21
+ for(unsigned long i = 0;; ++i)
{
descr = ladspadf(i);
if(descr == NULL)
@@ -913,7 +882,7 @@ int Plugin::incReferences(int val)
void Plugin::range(unsigned long i, float* min, float* max) const
{
- ladspaControlRange(plugin, i, min, max); // p4.0.20
+ ladspaControlRange(plugin, i, min, max);
}
//---------------------------------------------------------
@@ -922,59 +891,9 @@ void Plugin::range(unsigned long i, float* min, float* max) const
float Plugin::defaultValue(unsigned long port) const
{
- // p4.0.21
float val;
ladspaDefaultValue(plugin, port, &val);
return val;
-
- // DELETETHIS 50
- /*
- if(port >= plugin->PortCount)
- return 0.0;
-
- LADSPA_PortRangeHint range = plugin->PortRangeHints[port];
- LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor;
- //double val = 1.0;
- float val = 1.0;
- if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh))
- val = range.LowerBound;
- else if (LADSPA_IS_HINT_DEFAULT_LOW(rh))
- if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor))
- //val = exp(fast_log10(range.LowerBound) * .75 +
- // log(range.UpperBound) * .25);
- val = expf(fast_log10(range.LowerBound) * .75 +
- logf(range.UpperBound) * .25);
- else
- val = range.LowerBound*.75 + range.UpperBound*.25;
- else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh))
- if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor))
- //val = exp(log(range.LowerBound) * .5 +
- // log(range.UpperBound) * .5);
- val = expf(logf(range.LowerBound) * .5 +
- logf(range.UpperBound) * .5);
- else
- val = range.LowerBound*.5 + range.UpperBound*.5;
- else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh))
- if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor))
- //val = exp(log(range.LowerBound) * .25 +
- // log(range.UpperBound) * .75);
- val = expf(logf(range.LowerBound) * .25 +
- logf(range.UpperBound) * .75);
- else
- val = range.LowerBound*.25 + range.UpperBound*.75;
- else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh))
- val = range.UpperBound;
- else if (LADSPA_IS_HINT_DEFAULT_0(rh))
- val = 0.0;
- else if (LADSPA_IS_HINT_DEFAULT_1(rh))
- val = 1.0;
- else if (LADSPA_IS_HINT_DEFAULT_100(rh))
- val = 100.0;
- else if (LADSPA_IS_HINT_DEFAULT_440(rh))
- val = 440.0;
-
- return val;
- */
}
//---------------------------------------------------------
@@ -1013,7 +932,7 @@ static void loadPluginLib(QFileInfo* fi)
if(dssi)
{
const DSSI_Descriptor* descr;
- for (unsigned long i = 0;; ++i) // p4.0.21
+ for (unsigned long i = 0;; ++i)
{
descr = dssi(i);
if (descr == 0)
@@ -1060,7 +979,7 @@ static void loadPluginLib(QFileInfo* fi)
}
const LADSPA_Descriptor* descr;
- for (unsigned long i = 0;; ++i) // p4.0.21
+ for (unsigned long i = 0;; ++i)
{
descr = ladspa(i);
if (descr == NULL)
@@ -1224,6 +1143,76 @@ Pipeline::~Pipeline()
}
//---------------------------------------------------------
+// addScheduledControlEvent
+// track_ctrl_id is the fully qualified track audio controller number
+// Returns true if event cannot be delivered
+//---------------------------------------------------------
+
+bool Pipeline::addScheduledControlEvent(int track_ctrl_id, float val, unsigned frame)
+{
+ // If a track controller, or the special dssi synth controller block, just return.
+ if(track_ctrl_id < AC_PLUGIN_CTL_BASE || track_ctrl_id >= (int)genACnum(MAX_PLUGINS, 0))
+ return true;
+ int rack_idx = (track_ctrl_id - AC_PLUGIN_CTL_BASE) >> AC_PLUGIN_CTL_BASE_POW;
+ for (int i = 0; i < PipelineDepth; ++i)
+ {
+ PluginI* p = (*this)[i];
+ if(p && p->id() == rack_idx)
+ return p->addScheduledControlEvent(track_ctrl_id & AC_PLUGIN_CTL_ID_MASK, val, frame);
+ }
+ return true;
+}
+
+//---------------------------------------------------------
+// controllersEnabled
+// Returns whether automation control stream is enabled or disabled.
+// Used during automation recording to inhibit gui controls
+//---------------------------------------------------------
+
+void Pipeline::controllersEnabled(int track_ctrl_id, bool* en1, bool* en2)
+{
+ // If a track controller, or the special dssi synth controller block, just return.
+ if(track_ctrl_id < AC_PLUGIN_CTL_BASE || track_ctrl_id >= (int)genACnum(MAX_PLUGINS, 0))
+ return;
+ int rack_idx = (track_ctrl_id - AC_PLUGIN_CTL_BASE) >> AC_PLUGIN_CTL_BASE_POW;
+ for (int i = 0; i < PipelineDepth; ++i)
+ {
+ PluginI* p = (*this)[i];
+ if(p && p->id() == rack_idx)
+ {
+ if(en1)
+ *en1 = p->controllerEnabled(track_ctrl_id & AC_PLUGIN_CTL_ID_MASK);
+ if(en2)
+ *en2 = p->controllerEnabled2(track_ctrl_id & AC_PLUGIN_CTL_ID_MASK);
+ return;
+ }
+ }
+}
+
+//---------------------------------------------------------
+// enableController
+// Enable or disable gui automation control stream.
+// Used during automation recording to inhibit gui controls
+//---------------------------------------------------------
+
+void Pipeline::enableController(int track_ctrl_id, bool en)
+{
+ // If a track controller, or the special dssi synth controller block, just return.
+ if(track_ctrl_id < AC_PLUGIN_CTL_BASE || track_ctrl_id >= (int)genACnum(MAX_PLUGINS, 0))
+ return;
+ int rack_idx = (track_ctrl_id - AC_PLUGIN_CTL_BASE) >> AC_PLUGIN_CTL_BASE_POW;
+ for (int i = 0; i < PipelineDepth; ++i)
+ {
+ PluginI* p = (*this)[i];
+ if(p && p->id() == rack_idx)
+ {
+ p->enableController(track_ctrl_id & AC_PLUGIN_CTL_ID_MASK, en);
+ return;
+ }
+ }
+}
+
+//---------------------------------------------------------
// setChannels
//---------------------------------------------------------
@@ -1524,6 +1513,39 @@ PluginIBase::~PluginIBase()
delete _gui;
}
+//---------------------------------------------------------
+// addScheduledControlEvent
+// i is the specific index of the control input port
+// Returns true if event cannot be delivered
+//---------------------------------------------------------
+
+bool PluginIBase::addScheduledControlEvent(unsigned long i, float val, unsigned frame)
+{
+ if(i >= parameters())
+ {
+ printf("PluginIBase::addScheduledControlEvent param number %lu out of range of ports:%lu\n", i, parameters());
+ return true;
+ }
+ ControlEvent ce;
+ ce.unique = false;
+ ce.idx = i;
+ ce.value = val;
+ // Time-stamp the event. This does a possibly slightly slow call to gettimeofday via timestamp().
+ // timestamp() is more or less an estimate of the current frame. (This is exactly how ALSA events
+ // are treated when they arrive in our ALSA driver.)
+ //ce.frame = MusEGlobal::audio->timestamp();
+ // p4.0.23 timestamp() is circular, which is making it impossible to deal with 'modulo' events which
+ // slip in 'under the wire' before processing the ring buffers. So try this linear timestamp instead:
+ ce.frame = frame;
+
+ if(_controlFifo.put(ce))
+ {
+ fprintf(stderr, "PluginIBase::addScheduledControlEvent: fifo overflow: in control number:%lu\n", i);
+ return true;
+ }
+ return false;
+}
+
QString PluginIBase::dssi_ui_filename() const
{
QString libr(lib());
@@ -1658,8 +1680,6 @@ void PluginI::updateControllers()
for(unsigned long i = 0; i < controlPorts; ++i)
_track->setPluginCtrlVal(genACnum(_id, i), controls[i].val); // TODO A faster bulk message
-
- MusEGlobal::song->controllerChange(_track);
}
//---------------------------------------------------------
@@ -1698,7 +1718,7 @@ void PluginI::setChannels(int c)
}
}
- unsigned long curPort = 0; // p4.0.21
+ unsigned long curPort = 0;
unsigned long curOutPort = 0;
unsigned long ports = _plugin->ports();
for (unsigned long k = 0; k < ports; ++k)
@@ -1733,27 +1753,7 @@ void PluginI::setChannels(int c)
void PluginI::setParam(unsigned long i, float val)
{
- if(i >= _plugin->_controlInPorts)
- {
- printf("PluginI::setParameter param number %lu out of range of ports:%lu\n", i, _plugin->_controlInPorts);
- return;
- }
- ControlEvent ce;
- ce.unique = false;
- ce.idx = i;
- ce.value = val;
- // Time-stamp the event. This does a possibly slightly slow call to gettimeofday via timestamp().
- // timestamp() is more or less an estimate of the current frame. (This is exactly how ALSA events
- // are treated when they arrive in our ALSA driver.)
- //ce.frame = MusEGlobal::audio->timestamp();
- // p4.0.23 timestamp() is circular, which is making it impossible to deal with 'modulo' events which
- // slip in 'under the wire' before processing the ring buffers. So try this linear timestamp instead:
- ce.frame = MusEGlobal::audio->curFrame();
-
- if(_controlFifo.put(ce))
- {
- fprintf(stderr, "PluginI::setParameter: fifo overflow: in control number:%lu\n", i);
- }
+ addScheduledControlEvent(i, val, MusEGlobal::audio->curFrame());
}
//---------------------------------------------------------
@@ -1865,7 +1865,7 @@ bool PluginI::initPluginInstance(Plugin* plug, int c)
{
if(pd & LADSPA_PORT_INPUT)
{
- float val = _plugin->defaultValue(k); // p4.0.21
+ float val = _plugin->defaultValue(k);
controls[curPort].val = val;
controls[curPort].tmpVal = val;
controls[curPort].enCtrl = true;
@@ -1917,11 +1917,11 @@ bool PluginI::initPluginInstance(Plugin* plug, int c)
void PluginI::connect(unsigned long ports, unsigned long offset, float** src, float** dst)
{
- unsigned long port = 0; // p4.0.21
+ unsigned long port = 0;
for (int i = 0; i < instances; ++i) {
for (unsigned long k = 0; k < _plugin->ports(); ++k) {
if (isAudioIn(k)) {
- _plugin->connectPort(handle[i], k, src[port] + offset); // p4.0.21
+ _plugin->connectPort(handle[i], k, src[port] + offset);
port = (port + 1) % ports;
}
}
@@ -1930,7 +1930,7 @@ void PluginI::connect(unsigned long ports, unsigned long offset, float** src, fl
for (int i = 0; i < instances; ++i) {
for (unsigned long k = 0; k < _plugin->ports(); ++k) {
if (isAudioOut(k)) {
- _plugin->connectPort(handle[i], k, dst[port] + offset); // p4.0.21
+ _plugin->connectPort(handle[i], k, dst[port] + offset);
port = (port + 1) % ports; // overwrite output?
}
}
@@ -1979,7 +1979,7 @@ bool PluginI::setControl(const QString& s, float val)
{
for (unsigned long i = 0; i < controlPorts; ++i) {
if (_plugin->portName(controls[i].idx) == s) {
- setParam(i, val); // p4.0.21
+ setParam(i, val);
return false;
}
}
@@ -1997,7 +1997,7 @@ void PluginI::writeConfiguration(int level, Xml& xml)
xml.tag(level++, "plugin file=\"%s\" label=\"%s\" channel=\"%d\"",
Xml::xmlString(_plugin->lib()).toLatin1().constData(), Xml::xmlString(_plugin->label()).toLatin1().constData(), channel);
- for (unsigned long i = 0; i < controlPorts; ++i) { // p4.0.21
+ for (unsigned long i = 0; i < controlPorts; ++i) {
unsigned long idx = controls[i].idx;
QString s("control name=\"%1\" val=\"%2\" /");
xml.tag(level, s.arg(Xml::xmlString(_plugin->portName(idx)).toLatin1().constData()).arg(controls[i].tmpVal).toLatin1().constData());
@@ -2040,7 +2040,7 @@ bool PluginI::loadControl(Xml& xml)
if (tag == "name")
name = xml.s2();
else if (tag == "val")
- val = xml.s2().toFloat(); // p4.0.21
+ val = xml.s2().toFloat();
break;
case Xml::TagEnd:
if (tag == "control") {
@@ -2102,7 +2102,7 @@ bool PluginI::readConfiguration(Xml& xml, bool readPreset)
xml.parse1();
printf("Error initializing plugin instance (%s, %s)\n",
file.toLatin1().constData(), label.toLatin1().constData());
- //break; // Don't break - let it read any control tags. DELETETHIS
+ //break; // Don't break - let it read any control tags.
}
}
}
@@ -2352,28 +2352,152 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float**
if(min_per > n)
min_per = n;
- // Process automation control values now.
- // TODO: This needs to be respect frame resolution. Put this inside the sample loop below.
- if(MusEGlobal::automation && _track && _track->automationType() != AUTO_OFF && _id != -1)
+ // CtrlListList* cll = NULL; // WIP
+ AutomationType at = AUTO_OFF;
+ if(_track)
{
- for(unsigned long k = 0; k < controlPorts; ++k)
- {
- if(controls[k].enCtrl && controls[k].en2Ctrl )
- controls[k].tmpVal = _track->controller()->value(genACnum(_id, k), MusEGlobal::audio->pos().frame());
- }
+ at = _track->automationType();
+ //cll = _track->controller(); // WIP
}
-
+ bool no_auto = !MusEGlobal::automation || at == AUTO_OFF;
+
while(sample < n)
{
// nsamp is the number of samples the plugin->process() call will be supposed to do
unsigned long nsamp = usefixedrate ? fixedsize : n - sample;
+ //
+ // Process automation control values, while also determining the maximum acceptable
+ // size of this run. Further processing, from FIFOs for example, can lower the size
+ // from there, but this section determines where the next highest maximum frame
+ // absolutely needs to be for smooth playback of the controller value stream...
+ //
+ if(_track && _id != -1 && ports != 0) // Don't bother if not 'running'.
+ {
+ unsigned long frame = MusEGlobal::audio->pos().frame() + sample;
+ int nextFrame;
+ //double val; // WIP
+ for(unsigned long k = 0; k < controlPorts; ++k)
+ {
+
+
+#if 0 // WIP - Work in progress. Tim.
+
+ ciCtrlList icl = cll->find(genACnum(_id, k));
+ if(icl == cll->end())
+ continue;
+ CtrlList* cl = icl->second;
+ if(no_auto || !controls[k].enCtrl || !controls[k].en2Ctrl || cl->empty())
+ {
+ nextFrame = -1;
+ val = cl->curVal();
+ }
+ else
+ {
+ ciCtrl i = cl->upper_bound(frame); // get the index after current frame
+ if (i == cl->end()) { // if we are past all items just return the last value
+ --i;
+ nextFrame = -1;
+ val = i->second.val;
+ }
+ else if(cl->mode() == CtrlList::DISCRETE)
+ {
+ if(i == cl->begin())
+ {
+ nextFrame = i->second.frame;
+ val = i->second.val;
+ }
+ else
+ {
+ nextFrame = i->second.frame;
+ --i;
+ val = i->second.val;
+ }
+ }
+ else { // INTERPOLATE
+ if (i == cl->begin()) {
+ nextFrame = i->second.frame;
+ val = i->second.val;
+ }
+ else {
+ int frame2 = i->second.frame;
+ double val2 = i->second.val;
+ --i;
+ int frame1 = i->second.frame;
+ double val1 = i->second.val;
+
+
+ if(val2 != val1)
+ nextFrame = 0; // Zero signifies the next frame should be determined by caller.
+ else
+ nextFrame = frame2;
+
+ if (cl->valueType() == VAL_LOG) {
+ val1 = 20.0*fast_log10(val1);
+ if (val1 < MusEGlobal::config.minSlider)
+ val1=MusEGlobal::config.minSlider;
+ val2 = 20.0*fast_log10(val2);
+ if (val2 < MusEGlobal::config.minSlider)
+ val2=MusEGlobal::config.minSlider;
+ }
+
+ val2 -= val1;
+ val1 += (double(frame - frame1) * val2)/double(frame2 - frame1);
+
+ if (cl->valueType() == VAL_LOG) {
+ val1 = exp10(val1/20.0);
+ }
+
+ val = val1;
+ }
+ }
+ }
+
+ controls[k].tmpVal = val;
+
+
+#else
+ controls[k].tmpVal = _track->controller()->value(genACnum(_id, k), frame,
+ no_auto || !controls[k].enCtrl || !controls[k].en2Ctrl,
+ &nextFrame);
+#endif
+
+
+#ifdef PLUGIN_DEBUGIN_PROCESS
+ printf("PluginI::apply k:%lu sample:%lu frame:%lu nextFrame:%d nsamp:%lu \n", k, sample, frame, nextFrame, nsamp);
+#endif
+ if(MusEGlobal::audio->isPlaying() && !usefixedrate && nextFrame != -1)
+ {
+ // Returned value of nextFrame can be zero meaning caller replaces with some (constant) value.
+ unsigned long samps = (unsigned long)nextFrame;
+ if(samps > frame + min_per)
+ {
+ unsigned long diff = samps - frame;
+ unsigned long mask = min_per-1; // min_per must be power of 2
+ samps = diff & ~mask;
+ if((diff & mask) != 0)
+ samps += min_per;
+ }
+ else
+ samps = min_per;
+
+ if(samps < nsamp)
+ nsamp = samps;
+ }
+ }
+
+#ifdef PLUGIN_DEBUGIN_PROCESS
+ printf("PluginI::apply sample:%lu nsamp:%lu\n", sample, nsamp);
+#endif
+ }
+
+ //
+ // Process all control ring buffer items valid for this time period...
+ //
bool found = false;
unsigned long frame = 0;
unsigned long index = 0;
unsigned long evframe;
-
- // Get all control ring buffer items valid for this time period...
while(!_controlFifo.isEmpty())
{
ControlEvent v = _controlFifo.peek();
@@ -2398,9 +2522,10 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float**
// but stop after a control event was found (then process(),
// then loop here again), but ensure that process() must process
// at least min_per frames.
- if(evframe >= n
- || (found && !v.unique && (evframe - sample >= min_per))
- || (usefixedrate && found && v.unique && v.idx == index))
+ if(evframe >= n // Next events are for a later period.
+ || (!usefixedrate && !found && !v.unique && (evframe - sample >= nsamp)) // Next events are for a later run in this period. (Autom took prio.)
+ || (found && !v.unique && (evframe - sample >= min_per)) // Eat up events within minimum slice - they're too close.
+ || (usefixedrate && found && v.unique && v.idx == index)) // Special for dssi-vst: Fixed rate and must reply to all.
break;
_controlFifo.remove(); // Done with the ring buffer's item. Remove it.
@@ -2415,27 +2540,20 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float**
// Need to update the automation value, otherwise it overwrites later with the last automation value.
if(_track && _id != -1)
- {
- // We're in the audio thread context: no need to send a message, just modify directly.
_track->setPluginCtrlVal(genACnum(_id, v.idx), v.value);
-
- /* Recording automation is done immediately in the *
- * OSC control handler, because we don't want any delay. *
- * we might want to handle dssi-vst synthes here, however! */
- }
}
// Now update the actual values from the temporary values...
for(unsigned long k = 0; k < controlPorts; ++k)
controls[k].val = controls[k].tmpVal;
- if(found && !usefixedrate)
- nsamp = frame - sample;
+ if(found && !usefixedrate) // If a control FIFO item was found, takes priority over automation controller stream.
+ nsamp = frame - sample;
- if(sample + nsamp >= n) // Safety check.
+ if(sample + nsamp >= n) // Safety check.
nsamp = n - sample;
- // Don't allow zero-length runs. This could/should be checked in the control loop instead.
+ // TODO: 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;
@@ -2563,13 +2681,8 @@ int PluginI::oscUpdate()
usleep(300000);
// Send current control values.
- //unsigned long ports = controlPorts; DELETETHIS 2
- //for(int i = 0; i < controlPorts; ++i)
for(unsigned long i = 0; i < controlPorts; ++i)
{
- //unsigned long k = synth->pIdx(i); DELETETHIS 2
- //_oscIF.oscSendControl(k, controls[i], true /*force*/);
- //printf("PluginI::oscUpdate() sending control:%lu val:%f\n", i, controls[i].val);
_oscif.oscSendControl(controls[i].idx, controls[i].val, true /*force*/);
// Avoid overloading the GUI if there are lots and lots of ports.
if((i+1) % 50 == 0)
@@ -2638,7 +2751,6 @@ int PluginI::oscControl(unsigned long port, float value)
}
}
*/
- // p4.0.21
ControlEvent ce;
ce.unique = _plugin->_isDssiVst; // Special for messages from vst gui to host - requires processing every message.
ce.idx = cport;
@@ -2693,27 +2805,6 @@ int PluginI::oscControl(unsigned long port, float value)
}
*/
-// DELETETHIS 20
-#if 0
- int port = argv[0]->i;
- LADSPA_Data value = argv[1]->f;
-
- if (port < 0 || port > instance->plugin->descriptor->LADSPA_Plugin->PortCount) {
- fprintf(stderr, "MusE: OSC: %s port number (%d) is out of range\n",
- instance->friendly_name, port);
- return 0;
- }
- if (instance->pluginPortControlInNumbers[port] == -1) {
- fprintf(stderr, "MusE: OSC: %s port %d is not a control in\n",
- instance->friendly_name, port);
- return 0;
- }
- pluginControlIns[instance->pluginPortControlInNumbers[port]] = value;
- if (verbose) {
- printf("MusE: OSC: %s port %d = %f\n",
- instance->friendly_name, port, value);
- }
-#endif
return 0;
}
@@ -2795,7 +2886,7 @@ PluginDialog::PluginDialog(QWidget* parent)
ok_lo->addWidget(cancelB);
QGroupBox* plugSelGroup = new QGroupBox(this);
- plugSelGroup->setTitle("Show plugs:");
+ plugSelGroup->setTitle(tr("Show plugs:"));
plugSelGroup->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
QGridLayout* psl = new QGridLayout;
plugSelGroup->setLayout(psl);
@@ -2972,7 +3063,7 @@ void PluginDialog::fillPlugs()
QString type_name;
pList->clear();
for (MusECore::iPlugin i = MusEGlobal::plugins.begin(); i != MusEGlobal::plugins.end(); ++i) {
- unsigned long ai = i->inports(); // p4.0.21
+ unsigned long ai = i->inports();
unsigned long ao = i->outports();
unsigned long ci = i->controlInPorts();
unsigned long co = i->controlOutPorts();
@@ -3115,7 +3206,7 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
const char* name = ba.constData();
if (*name !='P')
continue;
- unsigned long parameter; // p4.0.21
+ unsigned long parameter;
int rv = sscanf(name, "P%lu", &parameter);
if(rv != 1)
continue;
@@ -3126,15 +3217,17 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
nobj = 0;
QSignalMapper* mapper = new QSignalMapper(this);
- // FIXME: There's no unsigned for gui params. We would need to limit nobj to MAXINT. // p4.0.21
- // FIXME: Our MusEGui::Slider class uses doubles for values, giving some problems with float conversion. // p4.0.21
+ // FIXME: There's no unsigned for gui params. We would need to limit nobj to MAXINT.
+ // FIXME: Our MusEGui::Slider class uses doubles for values, giving some problems with float conversion.
connect(mapper, SIGNAL(mapped(int)), SLOT(guiParamChanged(int)));
- QSignalMapper* mapperPressed = new QSignalMapper(this);
- QSignalMapper* mapperReleased = new QSignalMapper(this);
+ QSignalMapper* mapperPressed = new QSignalMapper(this);
+ QSignalMapper* mapperReleased = new QSignalMapper(this);
+ QSignalMapper* mapperContextMenuReq = new QSignalMapper(this);
connect(mapperPressed, SIGNAL(mapped(int)), SLOT(guiParamPressed(int)));
connect(mapperReleased, SIGNAL(mapped(int)), SLOT(guiParamReleased(int)));
+ connect(mapperContextMenuReq, SIGNAL(mapped(int)), SLOT(guiContextMenuReq(int)));
for (it = l.begin(); it != l.end(); ++it) {
obj = *it;
@@ -3142,7 +3235,7 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
const char* name = ba.constData();
if (*name !='P')
continue;
- unsigned long parameter; // p4.0.21
+ unsigned long parameter;
int rv = sscanf(name, "P%lu", &parameter);
if(rv != 1)
continue;
@@ -3150,6 +3243,7 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
mapper->setMapping(obj, nobj);
mapperPressed->setMapping(obj, nobj);
mapperReleased->setMapping(obj, nobj);
+ mapperContextMenuReq->setMapping(obj, nobj);
gw[nobj].widget = (QWidget*)obj;
gw[nobj].param = parameter;
@@ -3159,15 +3253,15 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
gw[nobj].type = GuiWidgets::SLIDER;
((Slider*)obj)->setId(nobj);
((Slider*)obj)->setCursorHoming(true);
- for(unsigned long i = 0; i < nobj; i++) // p4.0.21
+ for(unsigned long i = 0; i < nobj; i++)
{
if(gw[i].type == GuiWidgets::DOUBLE_LABEL && gw[i].param == parameter)
((DoubleLabel*)gw[i].widget)->setSlider((Slider*)obj);
}
- connect(obj, SIGNAL(sliderMoved(double,int)), mapper, SLOT(map()));
- connect(obj, SIGNAL(sliderPressed(int)), SLOT(guiSliderPressed(int)));
- connect(obj, SIGNAL(sliderReleased(int)), SLOT(guiSliderReleased(int)));
- connect(obj, SIGNAL(sliderRightClicked(const QPoint &, int)), SLOT(guiSliderRightClicked(const QPoint &, int)));
+ connect((Slider*)obj, SIGNAL(sliderMoved(double,int)), mapper, SLOT(map()));
+ connect((Slider*)obj, SIGNAL(sliderPressed(int)), SLOT(guiSliderPressed(int)));
+ connect((Slider*)obj, SIGNAL(sliderReleased(int)), SLOT(guiSliderReleased(int)));
+ connect((Slider*)obj, SIGNAL(sliderRightClicked(const QPoint &, int)), SLOT(guiSliderRightClicked(const QPoint &, int)));
}
else if (strcmp(obj->metaObject()->className(), "MusEGui::DoubleLabel") == 0) {
gw[nobj].type = GuiWidgets::DOUBLE_LABEL;
@@ -3180,17 +3274,23 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
break;
}
}
- connect(obj, SIGNAL(valueChanged(double,int)), mapper, SLOT(map()));
+ connect((DoubleLabel*)obj, SIGNAL(valueChanged(double,int)), mapper, SLOT(map()));
}
else if (strcmp(obj->metaObject()->className(), "QCheckBox") == 0) {
gw[nobj].type = GuiWidgets::QCHECKBOX;
- connect(obj, SIGNAL(toggled(bool)), mapper, SLOT(map()));
- connect(obj, SIGNAL(pressed()), mapperPressed, SLOT(map()));
- connect(obj, SIGNAL(released()), mapperReleased, SLOT(map()));
+ gw[nobj].widget->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect((QCheckBox*)obj, SIGNAL(toggled(bool)), mapper, SLOT(map()));
+ connect((QCheckBox*)obj, SIGNAL(pressed()), mapperPressed, SLOT(map()));
+ connect((QCheckBox*)obj, SIGNAL(released()), mapperReleased, SLOT(map()));
+ connect((QCheckBox*)obj, SIGNAL(customContextMenuRequested(const QPoint &)),
+ mapperContextMenuReq, SLOT(map()));
}
else if (strcmp(obj->metaObject()->className(), "QComboBox") == 0) {
gw[nobj].type = GuiWidgets::QCOMBOBOX;
- connect(obj, SIGNAL(activated(int)), mapper, SLOT(map()));
+ gw[nobj].widget->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect((QComboBox*)obj, SIGNAL(activated(int)), mapper, SLOT(map()));
+ connect((QComboBox*)obj, SIGNAL(customContextMenuRequested(const QPoint &)),
+ mapperContextMenuReq, SLOT(map()));
}
else {
printf("unknown widget class %s\n", obj->metaObject()->className());
@@ -3201,7 +3301,6 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
updateValues(); // otherwise the GUI won't have valid data
}
else {
- // p3.4.43
view = new QScrollArea;
view->setWidgetResizable(true);
setCentralWidget(view);
@@ -3212,13 +3311,13 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
mw->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
- unsigned long n = plugin->parameters(); // p4.0.21
+ unsigned long n = plugin->parameters();
params = new GuiParam[n];
QFontMetrics fm = fontMetrics();
int h = fm.height() + 4;
- for (unsigned long i = 0; i < n; ++i) { // p4.0.21
+ for (unsigned long i = 0; i < n; ++i) {
QLabel* label = 0;
LADSPA_PortRangeHint range = plugin->range(i);
double lower = 0.0; // default values
@@ -3281,7 +3380,7 @@ PluginGui::PluginGui(MusECore::PluginIBase* p)
grid->addWidget(params[i].actuator, i, 0, 1, 3);
}
if (params[i].type == GuiParam::GUI_SLIDER) {
- connect(params[i].actuator, SIGNAL(sliderMoved(double,int)), SLOT(sliderChanged(double,int)));
+ connect(params[i].actuator, SIGNAL(sliderMoved(double,int,bool)), SLOT(sliderChanged(double,int,bool)));
connect(params[i].label, SIGNAL(valueChanged(double,int)), SLOT(labelChanged(double,int)));
connect(params[i].actuator, SIGNAL(sliderPressed(int)), SLOT(ctrlPressed(int)));
connect(params[i].actuator, SIGNAL(sliderReleased(int)), SLOT(ctrlReleased(int)));
@@ -3429,21 +3528,17 @@ void PluginGui::ctrlPressed(int param)
if(track)
{
track->setPluginCtrlVal(id, val);
- MusEGlobal::song->controllerChange(track);
-
track->startAutoRecord(id, val);
}
}
else if(params[param].type == GuiParam::GUI_SWITCH)
{
- float val = (float)((CheckBox*)params[param].actuator)->isChecked(); // p4.0.21
+ float val = (float)((CheckBox*)params[param].actuator)->isChecked();
plugin->setParam(param, val);
if(track)
{
track->setPluginCtrlVal(id, val);
- MusEGlobal::song->controllerChange(track);
-
track->startAutoRecord(id, val);
}
}
@@ -3498,13 +3593,17 @@ void PluginGui::ctrlRightClicked(const QPoint &p, int param)
// sliderChanged
//---------------------------------------------------------
-void PluginGui::sliderChanged(double val, int param)
+void PluginGui::sliderChanged(double val, int param, bool shift_pressed)
{
AutomationType at = AUTO_OFF;
MusECore::AudioTrack* track = plugin->track();
if(track)
at = track->automationType();
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
+ plugin->enableController(param, false);
+
if (LADSPA_IS_HINT_LOGARITHMIC(params[param].hint))
val = pow(10.0, val/20.0);
else if (LADSPA_IS_HINT_INTEGER(params[param].hint))
@@ -3523,9 +3622,7 @@ void PluginGui::sliderChanged(double val, int param)
if(track)
{
track->setPluginCtrlVal(id, val);
- MusEGlobal::song->controllerChange(track);
-
- track->recordAutomation(id, val);
+ if (!shift_pressed) track->recordAutomation(id, val); //with shift, we get straight lines :)
}
}
@@ -3540,6 +3637,10 @@ void PluginGui::labelChanged(double val, int param)
if(track)
at = track->automationType();
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
+ plugin->enableController(param, false);
+
double dval = val;
if (LADSPA_IS_HINT_LOGARITHMIC(params[param].hint))
dval = MusECore::fast_log10(val) * 20.0;
@@ -3559,8 +3660,6 @@ void PluginGui::labelChanged(double val, int param)
if(track)
{
track->setPluginCtrlVal(id, val);
- MusEGlobal::song->controllerChange(track);
-
track->startAutoRecord(id, val);
}
}
@@ -3689,7 +3788,7 @@ void PluginGui::setOn(bool val)
void PluginGui::updateValues()
{
if (params) {
- for (unsigned long i = 0; i < plugin->parameters(); ++i) { // p4.0.21
+ for (unsigned long i = 0; i < plugin->parameters(); ++i) {
GuiParam* gp = &params[i];
if (gp->type == GuiParam::GUI_SLIDER) {
double lv = plugin->param(i);
@@ -3710,10 +3809,10 @@ void PluginGui::updateValues()
}
}
else if (gw) {
- for (unsigned long i = 0; i < nobj; ++i) { // p4.0.21
+ for (unsigned long i = 0; i < nobj; ++i) {
QWidget* widget = gw[i].widget;
int type = gw[i].type;
- unsigned long param = gw[i].param; // p4.0.21
+ unsigned long param = gw[i].param;
float val = plugin->param(param);
switch(type) {
case GuiWidgets::SLIDER:
@@ -3766,12 +3865,16 @@ void PluginGui::updateControls()
if (params) {
- for (unsigned long i = 0; i < plugin->parameters(); ++i) { // p4.0.21
+ for (unsigned long i = 0; i < plugin->parameters(); ++i) {
GuiParam* gp = &params[i];
if (gp->type == GuiParam::GUI_SLIDER) {
- if( plugin->controllerEnabled(i) && plugin->controllerEnabled2(i) )
{
- double lv = plugin->track()->pluginCtrlVal(MusECore::genACnum(plugin->id(), i));
+ double lv = plugin->track()->controller()->value(MusECore::genACnum(plugin->id(), i),
+ MusEGlobal::audio->curFramePos(),
+ !MusEGlobal::automation ||
+ plugin->track()->automationType() == AUTO_OFF ||
+ !plugin->controllerEnabled(i) ||
+ !plugin->controllerEnabled2(i));
double sv = lv;
if (LADSPA_IS_HINT_LOGARITHMIC(params[i].hint))
sv = MusECore::fast_log10(lv) * 20.0;
@@ -3791,12 +3894,15 @@ void PluginGui::updateControls()
gp->label->blockSignals(false);
}
}
-
}
else if (gp->type == GuiParam::GUI_SWITCH) {
- if( plugin->controllerEnabled(i) && plugin->controllerEnabled2(i) )
{
- bool v = (int)plugin->track()->pluginCtrlVal(MusECore::genACnum(plugin->id(), i));
+ bool v = (int)plugin->track()->controller()->value(MusECore::genACnum(plugin->id(), i),
+ MusEGlobal::audio->curFramePos(),
+ !MusEGlobal::automation ||
+ plugin->track()->automationType() == AUTO_OFF ||
+ !plugin->controllerEnabled(i) ||
+ !plugin->controllerEnabled2(i));
if(((CheckBox*)(gp->actuator))->isChecked() != v)
{
((CheckBox*)(gp->actuator))->blockSignals(true);
@@ -3808,15 +3914,19 @@ void PluginGui::updateControls()
}
}
else if (gw) {
- for (unsigned long i = 0; i < nobj; ++i) { // p4.0.21
+ for (unsigned long i = 0; i < nobj; ++i) {
QWidget* widget = gw[i].widget;
int type = gw[i].type;
- unsigned long param = gw[i].param; // p4.0.21
+ unsigned long param = gw[i].param;
switch(type) {
case GuiWidgets::SLIDER:
- if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) )
{
- double v = plugin->track()->pluginCtrlVal(MusECore::genACnum(plugin->id(), param));
+ double v = plugin->track()->controller()->value(MusECore::genACnum(plugin->id(), param),
+ MusEGlobal::audio->curFramePos(),
+ !MusEGlobal::automation ||
+ plugin->track()->automationType() == AUTO_OFF ||
+ !plugin->controllerEnabled(param) ||
+ !plugin->controllerEnabled2(param));
if(((Slider*)widget)->value() != v)
{
((Slider*)widget)->blockSignals(true);
@@ -3826,9 +3936,13 @@ void PluginGui::updateControls()
}
break;
case GuiWidgets::DOUBLE_LABEL:
- if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) )
{
- double v = plugin->track()->pluginCtrlVal(MusECore::genACnum(plugin->id(), param));
+ double v = plugin->track()->controller()->value(MusECore::genACnum(plugin->id(), param),
+ MusEGlobal::audio->curFramePos(),
+ !MusEGlobal::automation ||
+ plugin->track()->automationType() == AUTO_OFF ||
+ !plugin->controllerEnabled(param) ||
+ !plugin->controllerEnabled2(param));
if(((DoubleLabel*)widget)->value() != v)
{
((DoubleLabel*)widget)->blockSignals(true);
@@ -3838,9 +3952,13 @@ void PluginGui::updateControls()
}
break;
case GuiWidgets::QCHECKBOX:
- if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) )
{
- bool b = (bool) plugin->track()->pluginCtrlVal(MusECore::genACnum(plugin->id(), param));
+ bool b = (bool) plugin->track()->controller()->value(MusECore::genACnum(plugin->id(), param),
+ MusEGlobal::audio->curFramePos(),
+ !MusEGlobal::automation ||
+ plugin->track()->automationType() == AUTO_OFF ||
+ !plugin->controllerEnabled(param) ||
+ !plugin->controllerEnabled2(param));
if(((QCheckBox*)widget)->isChecked() != b)
{
((QCheckBox*)widget)->blockSignals(true);
@@ -3850,9 +3968,13 @@ void PluginGui::updateControls()
}
break;
case GuiWidgets::QCOMBOBOX:
- if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) )
{
- int n = (int) plugin->track()->pluginCtrlVal(MusECore::genACnum(plugin->id(), param));
+ int n = (int) plugin->track()->controller()->value(MusECore::genACnum(plugin->id(), param),
+ MusEGlobal::audio->curFramePos(),
+ !MusEGlobal::automation ||
+ plugin->track()->automationType() == AUTO_OFF ||
+ !plugin->controllerEnabled(param) ||
+ !plugin->controllerEnabled2(param));
if(((QComboBox*)widget)->currentIndex() != n)
{
((QComboBox*)widget)->blockSignals(true);
@@ -3873,7 +3995,7 @@ void PluginGui::updateControls()
void PluginGui::guiParamChanged(int idx)
{
QWidget* w = gw[idx].widget;
- unsigned long param = gw[idx].param; // p4.0.21
+ unsigned long param = gw[idx].param;
int type = gw[idx].type;
AutomationType at = AUTO_OFF;
@@ -3881,6 +4003,10 @@ void PluginGui::guiParamChanged(int idx)
if(track)
at = track->automationType();
+ if ( (at == AUTO_WRITE) ||
+ (at == AUTO_TOUCH && MusEGlobal::audio->isPlaying()) )
+ plugin->enableController(param, false);
+
double val = 0.0;
switch(type) {
case GuiWidgets::SLIDER:
@@ -3897,7 +4023,7 @@ void PluginGui::guiParamChanged(int idx)
break;
}
- for (unsigned long i = 0; i < nobj; ++i) { // p4.0.21
+ for (unsigned long i = 0; i < nobj; ++i) {
QWidget* widget = gw[i].widget;
if (widget == w || param != gw[i].param)
continue;
@@ -3922,10 +4048,7 @@ void PluginGui::guiParamChanged(int idx)
if(track && id != -1)
{
id = MusECore::genACnum(id, param);
-
track->setPluginCtrlVal(id, val);
- MusEGlobal::song->controllerChange(track);
-
switch(type)
{
case GuiWidgets::DOUBLE_LABEL:
@@ -3946,7 +4069,7 @@ void PluginGui::guiParamChanged(int idx)
void PluginGui::guiParamPressed(int idx)
{
- unsigned long param = gw[idx].param; // p4.0.21
+ unsigned long param = gw[idx].param;
AutomationType at = AUTO_OFF;
MusECore::AudioTrack* track = plugin->track();
@@ -3965,8 +4088,8 @@ void PluginGui::guiParamPressed(int idx)
// NOTE: For this to be of any use, the freeverb gui 2142.ui
// would have to be used, and changed to use CheckBox and ComboBox
// instead of QCheckBox and QComboBox, since both of those would
- // need customization (Ex. QCheckBox doesn't check on click).
- /* DELETETHIS 10 plus above
+ // need customization (Ex. QCheckBox doesn't check on click). RECHECK: Qt4 it does?
+ /*
switch(type) {
case GuiWidgets::QCHECKBOX:
double val = (double)((CheckBox*)w)->isChecked();
@@ -3986,7 +4109,7 @@ void PluginGui::guiParamPressed(int idx)
void PluginGui::guiParamReleased(int idx)
{
- unsigned long param = gw[idx].param; // p4.0.21
+ unsigned long param = gw[idx].param;
int type = gw[idx].type;
AutomationType at = AUTO_OFF;
@@ -4011,8 +4134,8 @@ void PluginGui::guiParamReleased(int idx)
// NOTE: For this to be of any use, the freeverb gui 2142.ui
// would have to be used, and changed to use CheckBox and ComboBox
// instead of QCheckBox and QComboBox, since both of those would
- // need customization (Ex. QCheckBox doesn't check on click).
- /* DELETETHIS 10 plus above
+ // need customization (Ex. QCheckBox doesn't check on click). // RECHECK Qt4 it does?
+ /*
switch(type) {
case GuiWidgets::QCHECKBOX:
double val = (double)((CheckBox*)w)->isChecked();
@@ -4032,7 +4155,7 @@ void PluginGui::guiParamReleased(int idx)
void PluginGui::guiSliderPressed(int idx)
{
- unsigned long param = gw[idx].param; // p4.0.21
+ unsigned long param = gw[idx].param;
QWidget *w = gw[idx].widget;
AutomationType at = AUTO_OFF;
@@ -4054,12 +4177,10 @@ void PluginGui::guiSliderPressed(int idx)
plugin->setParam(param, val);
track->setPluginCtrlVal(id, val);
- MusEGlobal::song->controllerChange(track);
-
track->startAutoRecord(id, val);
// Needed so that paging a slider updates a label or other buddy control.
- for (unsigned long i = 0; i < nobj; ++i) { // p4.0.21
+ for (unsigned long i = 0; i < nobj; ++i) {
QWidget* widget = gw[i].widget;
if (widget == w || param != gw[i].param)
continue;
@@ -4127,6 +4248,15 @@ void PluginGui::guiSliderRightClicked(const QPoint &p, int idx)
}
//---------------------------------------------------------
+// guiContextMenuReq
+//---------------------------------------------------------
+
+void PluginGui::guiContextMenuReq(int idx)
+{
+ guiSliderRightClicked(QCursor().pos(), idx);
+}
+
+//---------------------------------------------------------
// PluginLoader
//---------------------------------------------------------
QWidget* PluginLoader::createWidget(const QString & className, QWidget * parent, const QString & name)
diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h
index 9c671097..06e99564 100644
--- a/muse2/muse/plugin.h
+++ b/muse2/muse/plugin.h
@@ -246,12 +246,16 @@ class PluginIBase
virtual void enableController(unsigned long i, bool v = true) = 0;
virtual bool controllerEnabled(unsigned long i) const = 0;
+ virtual void enable2Controller(unsigned long i, bool v = true) = 0;
virtual bool controllerEnabled2(unsigned long i) const = 0;
+ virtual void enableAllControllers(bool v = true) = 0;
+ virtual void enable2AllControllers(bool v = true) = 0;
virtual void updateControllers() = 0;
virtual void writeConfiguration(int level, Xml& xml) = 0;
virtual bool readConfiguration(Xml& xml, bool readPreset=false) = 0;
+ virtual bool addScheduledControlEvent(unsigned long i, float val, unsigned frame); // returns true if event cannot be delivered
virtual unsigned long parameters() const = 0;
virtual unsigned long parametersOut() const = 0;
virtual void setParam(unsigned long i, float val) = 0;
@@ -412,6 +416,10 @@ class Pipeline : public std::vector<PluginI*> {
void move(int idx, bool up);
bool empty(int idx) const;
void setChannels(int);
+ bool addScheduledControlEvent(int track_ctrl_id, float val, unsigned frame); // returns true if event cannot be delivered
+ void enableController(int track_ctrl_id, bool en);
+ void enable2Controller(int track_ctrl_id, bool en);
+ void controllersEnabled(int track_ctrl_id, bool* en1, bool* en2);
};
typedef Pipeline::iterator iPluginI;
@@ -497,7 +505,7 @@ class PluginGui : public QMainWindow {
void load();
void save();
void bypassToggled(bool);
- void sliderChanged(double, int);
+ void sliderChanged(double, int, bool);
void labelChanged(double, int);
void guiParamChanged(int);
void ctrlPressed(int);
@@ -508,6 +516,7 @@ class PluginGui : public QMainWindow {
void guiSliderReleased(int);
void ctrlRightClicked(const QPoint &, int);
void guiSliderRightClicked(const QPoint &, int);
+ void guiContextMenuReq(int idx);
protected slots:
void heartBeat();
diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp
index d5257f80..f60a2d51 100644
--- a/muse2/muse/seqmsg.cpp
+++ b/muse2/muse/seqmsg.cpp
@@ -46,6 +46,7 @@ namespace MusECore {
// sendMsg
//---------------------------------------------------------
+// this function blocks until the request has been processed
void Audio::sendMsg(AudioMsg* m)
{
static int sno = 0;
@@ -522,7 +523,6 @@ void Audio::msgSwapControllerIDX(AudioTrack* node, int idx1, int idx2)
msg.a = idx1;
msg.b = idx2;
sendMsg(&msg);
- MusEGlobal::song->controllerChange(node);
}
//---------------------------------------------------------
@@ -537,7 +537,6 @@ void Audio::msgClearControllerEvents(AudioTrack* node, int acid)
msg.snode = node;
msg.ival = acid;
sendMsg(&msg);
- MusEGlobal::song->controllerChange(node);
}
//---------------------------------------------------------
@@ -581,7 +580,6 @@ void Audio::msgEraseACEvent(AudioTrack* node, int acid, int frame)
msg.ival = acid;
msg.a = frame;
sendMsg(&msg);
- MusEGlobal::song->controllerChange(node);
}
//---------------------------------------------------------
@@ -598,7 +596,6 @@ void Audio::msgEraseRangeACEvents(AudioTrack* node, int acid, int frame1, int fr
msg.a = frame1;
msg.b = frame2;
sendMsg(&msg);
- MusEGlobal::song->controllerChange(node);
}
//---------------------------------------------------------
@@ -615,7 +612,6 @@ void Audio::msgAddACEvent(AudioTrack* node, int acid, int frame, double val)
msg.a = frame;
msg.dval = val;
sendMsg(&msg);
- MusEGlobal::song->controllerChange(node);
}
//---------------------------------------------------------
@@ -633,7 +629,6 @@ void Audio::msgChangeACEvent(AudioTrack* node, int acid, int frame, int newFrame
msg.b = newFrame;
msg.dval = val;
sendMsg(&msg);
- MusEGlobal::song->controllerChange(node);
}
//---------------------------------------------------------
@@ -1297,6 +1292,18 @@ void Audio::msgSetSendMetronome(AudioTrack* track, bool b)
}
//---------------------------------------------------------
+// msgStartMidiLearn
+// Start learning midi
+//---------------------------------------------------------
+
+void Audio::msgStartMidiLearn()
+{
+ AudioMsg msg;
+ msg.id = AUDIO_START_MIDI_LEARN;
+ sendMessage(&msg, false);
+}
+
+//---------------------------------------------------------
// msgBounce
// start bounce operation
//---------------------------------------------------------
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index 0c7a0c73..020d620c 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -57,11 +57,13 @@
#include "sync.h"
#include "midictrl.h"
#include "menutitleitem.h"
+#include "midi_audio_control.h"
#include "tracks_duplicate.h"
#include "midi.h"
#include "al/sig.h"
#include "keyevent.h"
#include <sys/wait.h>
+#include "tempo.h"
namespace MusEGlobal {
MusECore::Song* song = 0;
@@ -762,18 +764,11 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly)
void Song::addACEvent(AudioTrack* t, int acid, int frame, double val)
{
MusEGlobal::audio->msgAddACEvent(t, acid, frame, val);
- emit controllerChanged(t);
}
void Song::changeACEvent(AudioTrack* t, int acid, int frame, int newFrame, double val)
{
MusEGlobal::audio->msgChangeACEvent(t, acid, frame, newFrame, val);
- emit controllerChanged(t);
-}
-
-void Song::controllerChange(Track* t)
-{
- emit controllerChanged(t);
}
//---------------------------------------------------------
@@ -883,7 +878,6 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start
if (endTick < tick)
endTick = tick;
}
- // Added by Tim. p3.3.8
// Round the end up (again) using the Arranger part snap raster value.
endTick = AL::sigmap.raster2(endTick, arrangerRaster());
@@ -1626,6 +1620,26 @@ void Song::beat()
if (MusEGlobal::audio->isPlaying())
setPos(0, MusEGlobal::audio->tickPos(), true, false, true);
+ // Process external tempo changes:
+ while(!_tempoFifo.isEmpty())
+ MusEGlobal::tempo_rec_list.addTempo(_tempoFifo.get());
+
+ // Update anything related to audio controller graphs etc.
+ for(ciTrack it = _tracks.begin(); it != _tracks.end(); ++ it)
+ {
+ if((*it)->isMidiTrack())
+ continue;
+ AudioTrack* at = static_cast<AudioTrack*>(*it);
+ CtrlListList* cll = at->controller();
+ for(ciCtrlList icl = cll->begin(); icl != cll->end(); ++icl)
+ {
+ CtrlList* cl = icl->second;
+ if(cl->isVisible() && !cl->dontShow() && cl->guiUpdatePending())
+ emit controllerChanged(at, cl->id());
+ cl->setGuiUpdatePending(false);
+ }
+ }
+
// Update synth native guis at the heartbeat rate.
for(ciSynthI is = _synthIs.begin(); is != _synthIs.end(); ++is)
(*is)->guiHeartBeat();
@@ -2078,6 +2092,7 @@ void Song::clear(bool signal, bool clear_all)
while (loop);
MusEGlobal::tempomap.clear();
+ MusEGlobal::tempo_rec_list.clear();
AL::sigmap.clear();
MusEGlobal::keymap.clear();
@@ -2419,13 +2434,14 @@ void Song::recordEvent(MidiTrack* mt, Event& event)
int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int acid)
{
- enum { PREV_EVENT, NEXT_EVENT, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
+ enum { PREV_EVENT=0, NEXT_EVENT, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS, MIDI_ASSIGN, MIDI_CLEAR };
QMenu* menu = new QMenu;
int count = 0;
bool isEvent = false, canSeekPrev = false, canSeekNext = false, canEraseRange = false;
bool canAdd = false;
double ctlval = 0.0;
+ int frame = 0;
if(track)
{
ciCtrlList icl = track->controller()->find(acid);
@@ -2434,11 +2450,17 @@ int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int a
CtrlList *cl = icl->second;
canAdd = true;
- //int frame = pos[0].frame(); DELETETHIS
- int frame = MusEGlobal::audio->pos().frame(); // Try this. p4.0.33 DELETETHIS
+ frame = MusEGlobal::audio->pos().frame();
+
+ bool en1, en2;
+ track->controllersEnabled(acid, &en1, &en2);
+
+ AutomationType at = track->automationType();
+ if(!MusEGlobal::automation || at == AUTO_OFF || !en1 || !en2)
+ ctlval = cl->curVal();
+ else
+ ctlval = cl->value(frame);
- ctlval = cl->curVal();
-
count = cl->size();
if(count)
{
@@ -2491,6 +2513,40 @@ int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int a
clearAction->setData(CLEAR_ALL_EVENTS);
clearAction->setEnabled((bool)count);
+
+ menu->addSeparator();
+ menu->addAction(new MusEGui::MenuTitleItem(tr("Midi control"), menu));
+
+ QAction *assign_act = menu->addAction(tr("Assign"));
+ assign_act->setCheckable(false);
+ assign_act->setData(MIDI_ASSIGN);
+
+ MidiAudioCtrlMap* macm = track->controller()->midiControls();
+ AudioMidiCtrlStructMap amcs;
+ macm->find_audio_ctrl_structs(acid, &amcs);
+
+ if(!amcs.empty())
+ {
+ QAction *cact = menu->addAction(tr("Clear"));
+ cact->setData(MIDI_CLEAR);
+ menu->addSeparator();
+ }
+
+ for(iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ {
+ int port, chan, mctrl;
+ macm->hash_values((*iamcs)->first, &port, &chan, &mctrl);
+ //QString s = QString("Port:%1 Chan:%2 Ctl:%3-%4").arg(port + 1)
+ QString s = QString("Port:%1 Chan:%2 Ctl:%3").arg(port + 1)
+ .arg(chan + 1)
+ //.arg((mctrl >> 8) & 0xff)
+ //.arg(mctrl & 0xff);
+ .arg(midiCtrlName(mctrl, true));
+ QAction *mact = menu->addAction(s);
+ mact->setEnabled(false);
+ mact->setData(-1); // Not used
+ }
+
QAction* act = menu->exec(menupos);
if (!act || !track)
{
@@ -2504,10 +2560,10 @@ int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int a
switch(sel)
{
case ADD_EVENT:
- MusEGlobal::audio->msgAddACEvent(track, acid, pos[0].frame(), ctlval);
+ MusEGlobal::audio->msgAddACEvent(track, acid, frame, ctlval);
break;
case CLEAR_EVENT:
- MusEGlobal::audio->msgEraseACEvent(track, acid, pos[0].frame());
+ MusEGlobal::audio->msgEraseACEvent(track, acid, frame);
break;
case CLEAR_RANGE:
@@ -2529,6 +2585,45 @@ int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int a
MusEGlobal::audio->msgSeekNextACEvent(track, acid);
break;
+ case MIDI_ASSIGN:
+ {
+ int port = -1, chan = 0, ctrl = 0;
+ for(MusECore::iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ {
+ macm->hash_values((*iamcs)->first, &port, &chan, &ctrl);
+ break; // Only a single item for now, thanks!
+ }
+
+ MusEGui::MidiAudioControl* pup = new MusEGui::MidiAudioControl(port, chan, ctrl);
+
+ if(pup->exec() == QDialog::Accepted)
+ {
+ MusEGlobal::audio->msgIdle(true); // Gain access to structures, and sync with audio
+ // Erase all for now.
+ for(MusECore::iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ macm->erase(*iamcs);
+
+ port = pup->port(); chan = pup->chan(); ctrl = pup->ctrl();
+ if(port >= 0 && chan >=0 && ctrl >= 0)
+ // Add will replace if found.
+ macm->add_ctrl_struct(port, chan, ctrl, MusECore::MidiAudioCtrlStruct(acid));
+
+ MusEGlobal::audio->msgIdle(false);
+ }
+
+ delete pup;
+ }
+ break;
+
+ case MIDI_CLEAR:
+ if(!amcs.empty())
+ MusEGlobal::audio->msgIdle(true); // Gain access to structures, and sync with audio
+ for(MusECore::iAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++iamcs)
+ macm->erase(*iamcs);
+ if(!amcs.empty())
+ MusEGlobal::audio->msgIdle(false);
+ break;
+
default:
return -1;
break;
@@ -2755,8 +2850,62 @@ void Song::processAutomationEvents()
// Process (and clear) rec events.
((AudioTrack*)(*i))->processAutomationEvents();
}
+
+ MusEGlobal::audio->msgIdle(false);
+}
+
+//---------------------------------------------------------
+// processMasterRec
+//---------------------------------------------------------
+
+void Song::processMasterRec()
+{
+ bool do_tempo = false;
+
+ // Wait a few seconds for the tempo fifo to be empty.
+ int tout = 30;
+ while(!_tempoFifo.isEmpty())
+ {
+ usleep(100000);
+ --tout;
+ if(tout == 0)
+ break;
+ }
+
+ int tempo_rec_list_sz = MusEGlobal::tempo_rec_list.size();
+ if(tempo_rec_list_sz != 0)
+ {
+ if(QMessageBox::question(MusEGlobal::muse,
+ tr("MusE: Tempo list"),
+ tr("External tempo changes were recorded.\nTransfer them to master tempo list?"),
+ QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Ok)
+ do_tempo = true;
+ }
+
+ MusEGlobal::audio->msgIdle(true); // gain access to all data structures
+
+ if(do_tempo)
+ {
+ // Erase from master tempo the (approximate) recording start/end tick range according to the recorded tempo map,
+ //MusEGlobal::tempomap.eraseRange(MusEGlobal::tempo_rec_list.frame2tick(MusEGlobal::audio->getStartRecordPos().frame()),
+ // MusEGlobal::tempo_rec_list.frame2tick(MusEGlobal::audio->getEndRecordPos().frame()));
+ // This is more accurate but lacks resolution:
+ MusEGlobal::tempomap.eraseRange(MusEGlobal::audio->getStartExternalRecTick(), MusEGlobal::audio->getEndExternalRecTick());
+
+ // Add the recorded tempos to the master tempo list:
+ for(int i = 0; i < tempo_rec_list_sz; ++i)
+ MusEGlobal::tempomap.addTempo(MusEGlobal::tempo_rec_list[i].tick,
+ MusEGlobal::tempo_rec_list[i].tempo,
+ false); // False: Defer normalize
+ MusEGlobal::tempomap.normalize();
+ }
+
+ MusEGlobal::tempo_rec_list.clear();
MusEGlobal::audio->msgIdle(false);
+
+ if(do_tempo)
+ update(SC_TEMPO);
}
//---------------------------------------------------------
diff --git a/muse2/muse/song.h b/muse2/muse/song.h
index 82b8cf18..6570ad8d 100644
--- a/muse2/muse/song.h
+++ b/muse2/muse/song.h
@@ -126,6 +126,8 @@ class Song : public QObject {
int noteFifoWindex;
int noteFifoRindex;
+ TempoFifo _tempoFifo; // External tempo changes, processed in heartbeat.
+
int updateFlags;
TrackList _tracks; // tracklist as seen by arranger
@@ -263,7 +265,7 @@ class Song : public QObject {
// event manipulations
//-----------------------------------------
- void cmdAddRecordedWave(WaveTrack* track, Pos, Pos);
+ void cmdAddRecordedWave(WaveTrack* track, Pos, Pos);
void cmdAddRecordedEvents(MidiTrack*, EventList*, unsigned);
bool addEvent(Event&, Part*);
void changeEvent(Event&, Event&, Part*);
@@ -274,8 +276,8 @@ class Song : public QObject {
void addACEvent(AudioTrack* t, int acid, int frame, double val);
void changeACEvent(AudioTrack* t, int acid, int frame, int newFrame, double val);
- void controllerChange(Track* t);
-
+ void addExternalTempo(const TempoRecEvent& e) { _tempoFifo.put(e); }
+
//-----------------------------------------
// part manipulations
//-----------------------------------------
@@ -332,6 +334,7 @@ class Song : public QObject {
void msgInsertTrack(Track* track, int idx, bool u = true);
void clearRecAutomation(bool clearList);
void processAutomationEvents();
+ void processMasterRec();
int execAutomationCtlPopup(AudioTrack*, const QPoint&, int);
int execMidiAutomationCtlPopup(MidiTrack*, MidiPart*, const QPoint&, int);
void connectJackRoutes(AudioTrack* track, bool disconnect);
@@ -428,7 +431,7 @@ class Song : public QObject {
void markerChanged(int);
void midiPortsChanged();
void midiNote(int pitch, int velo);
- void controllerChanged(MusECore::Track* t); // maybe DELETETHIS: this only triggers a redraw in pcanvas.cpp; what is this for?
+ void controllerChanged(MusECore::Track*, int);
void newPartsCreated(const std::map< MusECore::Part*, std::set<MusECore::Part*> >&);
};
diff --git a/muse2/muse/sync.cpp b/muse2/muse/sync.cpp
index 56560a5e..bf9d2613 100644
--- a/muse2/muse/sync.cpp
+++ b/muse2/muse/sync.cpp
@@ -21,6 +21,7 @@
//
//=========================================================
+#include <stdlib.h>
#include <cmath>
#include "sync.h"
#include "song.h"
@@ -59,12 +60,13 @@ static unsigned int curExtMidiSyncTick = 0;
unsigned int volatile lastExtMidiSyncTick = 0;
double volatile curExtMidiSyncTime = 0.0;
double volatile lastExtMidiSyncTime = 0.0;
+MusECore::MidiSyncInfo::SyncRecFilterPresetType syncRecFilterPreset = MusECore::MidiSyncInfo::SMALL;
+double syncRecTempoValQuant = 1.0;
// Not used yet. DELETETHIS?
// static bool mcStart = false;
// static int mcStartTick;
-// p3.3.25
// From the "Introduction to the Volatile Keyword" at Embedded dot com
/* A variable should be declared volatile whenever its value could change unexpectedly.
... <such as> global variables within a multi-threaded application
@@ -820,18 +822,25 @@ void MidiSeq::alignAllTicks(int frameOverride)
recTick2 = 0;
if (MusEGlobal::debugSync)
printf("alignAllTicks curFrame=%d recTick=%d tempo=%.3f frameOverride=%d\n",curFrame,recTick,(float)((1000000.0 * 60.0)/tempo), frameOverride);
-
+
+ lastTempo = 0;
+ for(int i = 0; i < _clockAveragerPoles; ++i)
+ {
+ _avgClkDiffCounter[i] = 0;
+ _averagerFull[i] = false;
+ }
+ _lastRealTempo = 0.0;
}
//---------------------------------------------------------
// realtimeSystemInput
// real time message received
//---------------------------------------------------------
-void MidiSeq::realtimeSystemInput(int port, int c)
+void MidiSeq::realtimeSystemInput(int port, int c, double time)
{
if (MusEGlobal::midiInputTrace)
- printf("realtimeSystemInput port:%d 0x%x\n", port+1, c);
+ printf("realtimeSystemInput port:%d 0x%x time:%f\n", port+1, c, time);
MidiPort* mp = &MusEGlobal::midiPorts[port];
@@ -873,6 +882,9 @@ void MidiSeq::realtimeSystemInput(int port, int c)
if(p != port && MusEGlobal::midiPorts[p].syncInfo().MCOut())
MusEGlobal::midiPorts[p].sendClock();
+ MusEGlobal::lastExtMidiSyncTime = MusEGlobal::curExtMidiSyncTime;
+ MusEGlobal::curExtMidiSyncTime = time;
+
if(MusEGlobal::playPendingFirstClock)
{
MusEGlobal::playPendingFirstClock = false;
@@ -887,12 +899,158 @@ void MidiSeq::realtimeSystemInput(int port, int c)
// Can't check audio state, might not be playing yet, we might miss some increments.
if(playStateExt)
{
- MusEGlobal::lastExtMidiSyncTime = MusEGlobal::curExtMidiSyncTime;
- MusEGlobal::curExtMidiSyncTime = curTime();
int div = MusEGlobal::config.division/24;
MusEGlobal::midiExtSyncTicks += div;
MusEGlobal::lastExtMidiSyncTick = MusEGlobal::curExtMidiSyncTick;
MusEGlobal::curExtMidiSyncTick += div;
+
+ if(MusEGlobal::song->record() && MusEGlobal::lastExtMidiSyncTime > 0.0)
+ {
+ double diff = MusEGlobal::curExtMidiSyncTime - MusEGlobal::lastExtMidiSyncTime;
+ if(diff != 0.0)
+ {
+ if(_clockAveragerPoles == 0)
+ {
+ double real_tempo = 60.0/(diff * 24.0);
+ if(_tempoQuantizeAmount > 0.0)
+ {
+ double f_mod = fmod(real_tempo, _tempoQuantizeAmount);
+ if(f_mod < _tempoQuantizeAmount/2.0)
+ real_tempo -= f_mod;
+ else
+ real_tempo += _tempoQuantizeAmount - f_mod;
+ }
+ int new_tempo = ((1000000.0 * 60.0) / (real_tempo));
+ if(new_tempo != lastTempo)
+ {
+ lastTempo = new_tempo;
+ // Compute tick for this tempo - it is one step back in time.
+ int add_tick = MusEGlobal::curExtMidiSyncTick - div;
+ if(MusEGlobal::debugSync)
+ printf("adding new tempo tick:%d curExtMidiSyncTick:%d avg_diff:%f real_tempo:%f new_tempo:%d = %f\n", add_tick, MusEGlobal::curExtMidiSyncTick, diff, real_tempo, new_tempo, (double)((1000000.0 * 60.0)/new_tempo));
+ MusEGlobal::song->addExternalTempo(TempoRecEvent(add_tick, new_tempo));
+ }
+ }
+ else
+ {
+ double avg_diff = diff;
+ for(int pole = 0; pole < _clockAveragerPoles; ++pole)
+ {
+ timediff[pole][_avgClkDiffCounter[pole]] = avg_diff;
+ ++_avgClkDiffCounter[pole];
+ if(_avgClkDiffCounter[pole] >= _clockAveragerStages[pole])
+ {
+ _avgClkDiffCounter[pole] = 0;
+ _averagerFull[pole] = true;
+ }
+
+ // Each averager needs to be full before we can pass the data to
+ // the next averager or use the data if all averagers are full...
+ if(!_averagerFull[pole])
+ break;
+ else
+ {
+ avg_diff = 0.0;
+ for(int i = 0; i < _clockAveragerStages[pole]; ++i)
+ avg_diff += timediff[pole][i];
+ avg_diff /= _clockAveragerStages[pole];
+
+ int fin_idx = _clockAveragerPoles - 1;
+
+ // On the first pole? Check for large differences.
+ if(_preDetect && pole == 0)
+ {
+ double real_tempo = 60.0/(avg_diff * 24.0);
+ double real_tempo_diff = abs(real_tempo - _lastRealTempo);
+
+ // If the tempo changed a large amount, reset.
+ if(real_tempo_diff >= 10.0) // TODO: User-adjustable?
+ {
+ if(_tempoQuantizeAmount > 0.0)
+ {
+ double f_mod = fmod(real_tempo, _tempoQuantizeAmount);
+ if(f_mod < _tempoQuantizeAmount/2.0)
+ real_tempo -= f_mod;
+ else
+ real_tempo += _tempoQuantizeAmount - f_mod;
+ }
+ _lastRealTempo = real_tempo;
+ int new_tempo = ((1000000.0 * 60.0) / (real_tempo));
+
+ if(new_tempo != lastTempo)
+ {
+ lastTempo = new_tempo;
+ // Compute tick for this tempo - it is way back in time.
+ int add_tick = MusEGlobal::curExtMidiSyncTick - _clockAveragerStages[0] * div;
+ if(add_tick < 0)
+ {
+ printf("FIXME sync: adding restart tempo curExtMidiSyncTick:%d: add_tick:%d < 0 !\n", MusEGlobal::curExtMidiSyncTick, add_tick);
+ add_tick = 0;
+ }
+ if(MusEGlobal::debugSync)
+ printf("adding restart tempo tick:%d curExtMidiSyncTick:%d tick_idx_sub:%d avg_diff:%f real_tempo:%f real_tempo_diff:%f new_tempo:%d = %f\n", add_tick, MusEGlobal::curExtMidiSyncTick, _clockAveragerStages[0], avg_diff, real_tempo, real_tempo_diff, new_tempo, (double)((1000000.0 * 60.0)/new_tempo));
+ MusEGlobal::song->addExternalTempo(TempoRecEvent(add_tick, new_tempo));
+ }
+
+ // Reset all the poles.
+ //for(int i = 0; i < clockAveragerPoles; ++i)
+ // We have a value for this pole, let's keep it but reset the other poles.
+ for(int i = 1; i < _clockAveragerPoles; ++i)
+ {
+ _avgClkDiffCounter[i] = 0;
+ _averagerFull[i] = false;
+ }
+ break;
+ }
+ }
+
+ // On the last pole?
+ // All averagers need to be full before we can use the data...
+ if(pole == fin_idx)
+ {
+ double real_tempo = 60.0/(avg_diff * 24.0);
+ double real_tempo_diff = abs(real_tempo - _lastRealTempo);
+
+ if(real_tempo_diff >= _tempoQuantizeAmount/2.0) // Anti-hysteresis
+ {
+ if(_tempoQuantizeAmount > 0.0)
+ {
+ double f_mod = fmod(real_tempo, _tempoQuantizeAmount);
+ if(f_mod < _tempoQuantizeAmount/2.0)
+ real_tempo -= f_mod;
+ else
+ real_tempo += _tempoQuantizeAmount - f_mod;
+ }
+ _lastRealTempo = real_tempo;
+ int new_tempo = ((1000000.0 * 60.0) / (real_tempo));
+
+ if(new_tempo != lastTempo)
+ {
+ lastTempo = new_tempo;
+ // Compute tick for this tempo - it is way back in time.
+ int tick_idx_sub = 0;
+ for(int i = 0; i <= pole; ++i)
+ tick_idx_sub += _clockAveragerStages[i];
+ // Compensate: Each pole > 0 has a delay one less than its number of stages.
+ // For example three pole {8, 8, 8} has a delay of 22 not 24.
+ tick_idx_sub -= pole;
+ int add_tick = MusEGlobal::curExtMidiSyncTick - tick_idx_sub * div;
+ if(add_tick < 0)
+ {
+ printf("FIXME sync: adding new tempo curExtMidiSyncTick:%d: add_tick:%d < 0 !\n", MusEGlobal::curExtMidiSyncTick, add_tick);
+ add_tick = 0;
+ }
+ if(MusEGlobal::debugSync)
+ printf("adding new tempo tick:%d curExtMidiSyncTick:%d tick_idx_sub:%d avg_diff:%f real_tempo:%f new_tempo:%d = %f\n", add_tick, MusEGlobal::curExtMidiSyncTick, tick_idx_sub, avg_diff, real_tempo, new_tempo, (double)((1000000.0 * 60.0)/new_tempo));
+ MusEGlobal::song->addExternalTempo(TempoRecEvent(add_tick, new_tempo));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
//BEGIN : Original code: DELETETHIS 250
@@ -1185,8 +1343,6 @@ void MidiSeq::realtimeSystemInput(int port, int c)
alignAllTicks();
storedtimediffs = 0;
- for (int i=0; i<24; i++)
- timediff[i] = 0.0;
// p3.3.26 1/23/10 DELETETHIS 6
// Changed because msgPlay calls MusEGlobal::audioDevice->seekTransport(song->cPos())
@@ -1243,7 +1399,7 @@ void MidiSeq::realtimeSystemInput(int port, int c)
if (MusEGlobal::debugSync)
printf("realtimeSystemInput stop\n");
-
+
//DELETETHIS 7
// Just in case the process still runs a cycle or two and causes the
// audio tick position to increment, reset the incrementer and force
diff --git a/muse2/muse/sync.h b/muse2/muse/sync.h
index 41ad34ad..09ea06e9 100644
--- a/muse2/muse/sync.h
+++ b/muse2/muse/sync.h
@@ -32,9 +32,11 @@ namespace MusECore {
class Xml;
-
class MidiSyncInfo
{
+ public:
+ enum SyncRecFilterPresetType { NONE=0, TINY, SMALL, MEDIUM, LARGE, LARGE_WITH_PRE_DETECT, TYPE_END };
+
private:
int _port;
@@ -151,6 +153,9 @@ extern int volatile curMidiSyncInPort;
extern MusECore::BValue useJackTransport;
extern bool volatile jackTransportMaster;
extern unsigned int syncSendFirstClockDelay; // In milliseconds.
+extern unsigned int volatile lastExtMidiSyncTick;
+extern MusECore::MidiSyncInfo::SyncRecFilterPresetType syncRecFilterPreset;
+extern double syncRecTempoValQuant;
} // namespace MusEGlobal
diff --git a/muse2/muse/tempo.cpp b/muse2/muse/tempo.cpp
index 1147fd78..d339f516 100644
--- a/muse2/muse/tempo.cpp
+++ b/muse2/muse/tempo.cpp
@@ -32,6 +32,7 @@
namespace MusEGlobal {
MusECore::TempoList tempomap;
+MusECore::TempoRecList tempo_rec_list;
}
namespace MusECore {
@@ -59,7 +60,7 @@ TempoList::~TempoList()
// add
//---------------------------------------------------------
-void TempoList::add(unsigned tick, int tempo)
+void TempoList::add(unsigned tick, int tempo, bool do_normalize)
{
if (tick > MAX_TICK)
tick = MAX_TICK;
@@ -74,7 +75,8 @@ void TempoList::add(unsigned tick, int tempo)
ne->tick = tick;
insert(std::pair<const unsigned, TEvent*> (tick, ev));
}
- normalize();
+ if(do_normalize)
+ normalize();
}
//---------------------------------------------------------
@@ -120,6 +122,33 @@ void TempoList::clear()
}
//---------------------------------------------------------
+// eraseRange
+//---------------------------------------------------------
+
+void TempoList::eraseRange(unsigned stick, unsigned etick)
+{
+ if(stick >= etick || stick > MAX_TICK)
+ return;
+ if(etick > MAX_TICK)
+ etick = MAX_TICK;
+
+ iTEvent se = MusEGlobal::tempomap.upper_bound(stick);
+ if(se == end() || (se->first == MAX_TICK+1))
+ return;
+
+ iTEvent ee = MusEGlobal::tempomap.upper_bound(etick);
+
+ ee->second->tempo = se->second->tempo;
+ ee->second->tick = se->second->tick;
+
+ for(iTEvent ite = se; ite != ee; ++ite)
+ delete ite->second;
+ erase(se, ee); // Erase range does NOT include the last element.
+ normalize();
+ ++_tempoSN;
+}
+
+//---------------------------------------------------------
// tempo
//---------------------------------------------------------
@@ -224,9 +253,9 @@ void TempoList::setGlobalTempo(int val)
// addTempo
//---------------------------------------------------------
-void TempoList::addTempo(unsigned t, int tempo)
+void TempoList::addTempo(unsigned t, int tempo, bool do_normalize)
{
- add(t, tempo);
+ add(t, tempo, do_normalize);
++_tempoSN;
}
@@ -538,5 +567,54 @@ int TEvent::read(Xml& xml)
return 0;
}
+//---------------------------------------------------------
+// put
+// return true on fifo overflow
+//---------------------------------------------------------
+
+bool TempoFifo::put(const TempoRecEvent& event)
+ {
+ if (size < TEMPO_FIFO_SIZE) {
+ fifo[wIndex] = event;
+ wIndex = (wIndex + 1) % TEMPO_FIFO_SIZE;
+ // q_atomic_increment(&size);
+ ++size;
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// get
+//---------------------------------------------------------
+
+TempoRecEvent TempoFifo::get()
+ {
+ TempoRecEvent event(fifo[rIndex]);
+ rIndex = (rIndex + 1) % TEMPO_FIFO_SIZE;
+ --size;
+ return event;
+ }
+
+//---------------------------------------------------------
+// peek
+//---------------------------------------------------------
+
+const TempoRecEvent& TempoFifo::peek(int n)
+ {
+ int idx = (rIndex + n) % TEMPO_FIFO_SIZE;
+ return fifo[idx];
+ }
+
+//---------------------------------------------------------
+// remove
+//---------------------------------------------------------
+
+void TempoFifo::remove()
+ {
+ rIndex = (rIndex + 1) % TEMPO_FIFO_SIZE;
+ --size;
+ }
+
} // namespace MusECore
diff --git a/muse2/muse/tempo.h b/muse2/muse/tempo.h
index 7a3f413b..71f1580c 100644
--- a/muse2/muse/tempo.h
+++ b/muse2/muse/tempo.h
@@ -25,11 +25,16 @@
#define __TEMPO_H__
#include <map>
+#include <vector>
#ifndef MAX_TICK
#define MAX_TICK (0x7fffffff/100)
#endif
+// Tempo ring buffer size
+#define TEMPO_FIFO_SIZE 1024
+
+
namespace MusECore {
class Xml;
@@ -70,8 +75,7 @@ class TempoList : public TEMPOLIST {
int _tempo; // tempo if not using tempo list
int _globalTempo; // %percent 50-200%
- void normalize();
- void add(unsigned tick, int tempo);
+ void add(unsigned tick, int tempo, bool do_normalize = true);
void change(unsigned tick, int newTempo);
void del(iTEvent);
void del(unsigned tick);
@@ -79,7 +83,9 @@ class TempoList : public TEMPOLIST {
public:
TempoList();
~TempoList();
+ void normalize();
void clear();
+ void eraseRange(unsigned stick, unsigned etick);
void read(Xml&);
void write(int, Xml&) const;
@@ -96,18 +102,62 @@ class TempoList : public TEMPOLIST {
int tempoSN() const { return _tempoSN; }
void setTempo(unsigned tick, int newTempo);
- void addTempo(unsigned t, int tempo);
+ void addTempo(unsigned t, int tempo, bool do_normalize = true);
void delTempo(unsigned tick);
void changeTempo(unsigned tick, int newTempo);
+ bool masterFlag() const { return useList; }
bool setMasterFlag(unsigned tick, bool val);
int globalTempo() const { return _globalTempo; }
void setGlobalTempo(int val);
};
+//---------------------------------------------------------
+// Tempo Record Event
+//---------------------------------------------------------
+
+struct TempoRecEvent {
+ int tempo;
+ unsigned tick;
+ TempoRecEvent() { }
+ TempoRecEvent(unsigned tk, unsigned t) {
+ tick = tk;
+ tempo = t;
+ }
+ };
+
+class TempoRecList : public std::vector<TempoRecEvent >
+{
+ public:
+ void addTempo(int tick, int tempo) { push_back(TempoRecEvent(tick, tempo)); }
+ void addTempo(const TempoRecEvent& e) { push_back(e); }
+};
+
+//---------------------------------------------------------
+// TempoFifo
+//---------------------------------------------------------
+
+class TempoFifo {
+ TempoRecEvent fifo[TEMPO_FIFO_SIZE];
+ volatile int size;
+ int wIndex;
+ int rIndex;
+
+ public:
+ TempoFifo() { clear(); }
+ bool put(const TempoRecEvent& event); // returns true on fifo overflow
+ TempoRecEvent get();
+ const TempoRecEvent& peek(int = 0);
+ void remove();
+ bool isEmpty() const { return size == 0; }
+ void clear() { size = 0, wIndex = 0, rIndex = 0; }
+ int getSize() const { return size; }
+ };
+
} // namespace MusECore
namespace MusEGlobal {
extern MusECore::TempoList tempomap;
+extern MusECore::TempoRecList tempo_rec_list;
}
#endif
diff --git a/muse2/muse/thread.cpp b/muse2/muse/thread.cpp
index 69238922..14f9750e 100644
--- a/muse2/muse/thread.cpp
+++ b/muse2/muse/thread.cpp
@@ -250,61 +250,11 @@ void Thread::removePollFd(int fd, int action)
void Thread::loop()
{
- // Changed by Tim. p3.3.17
-
if (!MusEGlobal::debugMode) {
if (mlockall(MCL_CURRENT | MCL_FUTURE))
perror("WARNING: Cannot lock memory:");
}
-/* DELETETHIS 46
- pthread_attr_t* attributes = 0;
- attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t));
- pthread_attr_init(attributes);
-
- if (MusEGlobal::realTimeScheduling && realTimePriority > 0) {
-
- doSetuid();
-// if (pthread_attr_setschedpolicy(attributes, SCHED_FIFO)) {
-// printf("cannot set FIFO scheduling class for RT thread\n");
-// }
-// if (pthread_attr_setscope (attributes, PTHREAD_SCOPE_SYSTEM)) {
-// printf("Cannot set scheduling scope for RT thread\n");
-// }
-// struct sched_param rt_param;
-// memset(&rt_param, 0, sizeof(rt_param));
-// rt_param.sched_priority = realTimePriority;
-// if (pthread_attr_setschedparam (attributes, &rt_param)) {
-// printf("Cannot set scheduling priority %d for RT thread (%s)\n",
-// realTimePriority, strerror(errno));
-// }
-
- // do the SCHED_FIFO stuff _after_ thread creation:
- struct sched_param *param = new struct sched_param;
- param->sched_priority = realTimePriority;
- int error = pthread_setschedparam(pthread_self(), SCHED_FIFO, param);
- if (error != 0)
- perror( "error set_schedparam 2:");
-
-// if (!MusEGlobal::debugMode) {
-// if (mlockall(MCL_CURRENT|MCL_FUTURE))
-// perror("WARNING: Cannot lock memory:");
-// }
-
- undoSetuid();
- }
-
-*/
-
-
-/*
-#define BIG_ENOUGH_STACK (1024*1024*1)
- char buf[BIG_ENOUGH_STACK];
- for (int i = 0; i < BIG_ENOUGH_STACK; i++)
- buf[i] = i;
-#undef BIG_ENOUGH_STACK
-*/
-
#ifdef __APPLE__
#define BIG_ENOUGH_STACK (1024*256*1)
#else
@@ -318,7 +268,8 @@ void Thread::loop()
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
- int policy = 0;
+ int policy = buf[0]; // Initialize using buf[0] to keep the compiler from complaining about unused buf.
+ policy = 0; // Now set the true desired inital value.
if ((policy = sched_getscheduler (0)) < 0) {
printf("Thread: Cannot get current client scheduler: %s\n", strerror(errno));
}
diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp
index 905f9030..d353b4bb 100644
--- a/muse2/muse/track.cpp
+++ b/muse2/muse/track.cpp
@@ -37,6 +37,7 @@
#include "midictrl.h"
#include "helper.h"
#include "limits.h"
+#include "dssihost.h"
namespace MusECore {
@@ -384,7 +385,21 @@ void Track::clearRecAutomation(bool clearList)
continue;
p->enableAllControllers(true);
}
-
+
+ if(type() == AUDIO_SOFTSYNTH)
+ {
+ SynthI* synth = static_cast<SynthI*>(this);
+ if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
+ {
+ SynthIF* sif = synth->sif();
+ if(sif)
+ {
+ DssiSynthIF* dssi_sif = static_cast<DssiSynthIF*>(sif);
+ dssi_sif->enableAllControllers(true);
+ }
+ }
+ }
+
if(clearList)
t->recEvents()->clear();
}
diff --git a/muse2/muse/track.h b/muse2/muse/track.h
index 93f2f673..3da34912 100644
--- a/muse2/muse/track.h
+++ b/muse2/muse/track.h
@@ -46,7 +46,7 @@ class PluginI;
class SynthI;
class Xml;
class DrumMap;
-
+class ControlEvent;
//---------------------------------------------------------
// Track
@@ -447,6 +447,9 @@ class AudioTrack : public Track {
virtual void setAutomationType(AutomationType t);
void processAutomationEvents();
CtrlRecList* recEvents() { return &_recEvents; }
+ bool addScheduledControlEvent(int track_ctrl_id, float val, unsigned frame); // return true if event cannot be delivered
+ void enableController(int track_ctrl_id, bool en);
+ void controllersEnabled(int track_ctrl_id, bool* en1, bool* en2) const;
void recordAutomation(int n, double v);
void startAutoRecord(int, double);
void stopAutoRecord(int, double);
diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h
index b88a9457..2f582d8e 100644
--- a/muse2/muse/undo.h
+++ b/muse2/muse/undo.h
@@ -125,12 +125,12 @@ struct UndoOp {
UndoOp(UndoType type, Track* track, const char* old_name, const char* new_name);
UndoOp(UndoType type, Track* track, int old_chan, int new_chan);
UndoOp(UndoType type);
- };
+};
class Undo : public std::list<UndoOp> {
public:
bool empty() const;
- };
+};
typedef Undo::iterator iUndoOp;
typedef Undo::reverse_iterator riUndoOp;
@@ -141,7 +141,7 @@ class UndoList : public std::list<Undo> {
public:
void clearDelete();
UndoList(bool _isUndo) : std::list<Undo>() { isUndo=_isUndo; }
- };
+};
typedef UndoList::iterator iUndo;
typedef UndoList::reverse_iterator riUndo;
diff --git a/muse2/muse/wave.cpp b/muse2/muse/wave.cpp
index 5e19648d..8d17a10d 100644
--- a/muse2/muse/wave.cpp
+++ b/muse2/muse/wave.cpp
@@ -964,7 +964,7 @@ int ClipList::idx(const Clip& clip) const
// cmdAddRecordedWave
//---------------------------------------------------------
-void Song::cmdAddRecordedWave(MusECore::WaveTrack* track, MusECore::Pos s, MusECore::Pos e)
+void Song::cmdAddRecordedWave(MusECore::WaveTrack* track, MusECore::Pos s, MusECore::Pos e)
{
if (MusEGlobal::debugMsg)
printf("cmdAddRecordedWave - loopCount = %d, punchin = %d", MusEGlobal::audio->loopCount(), punchin());
@@ -976,15 +976,31 @@ void Song::cmdAddRecordedWave(MusECore::WaveTrack* track, MusECore::Pos s, MusEC
return;
}
+ // If externally clocking (and therefore master was forced off),
+ // tempos may have been recorded. We really should temporarily force
+ // the master tempo map on in order to properly determine the ticks below.
+ // Else internal clocking, the user decided to record either with or without
+ // master on, so let it be.
+ // FIXME: We really should allow the master flag to be on at the same time as
+ // the external sync flag! AFAIR when external sync is on, no part of the app shall
+ // depend on the tempo map anyway, so it should not matter whether it's on or off.
+ // If we do that, then we may be able to remove this section and user simply decides
+ // whether master is on/off, because we may be able to use the flag to determine
+ // whether to record external tempos at all, because we may want a switch for it!
+ bool master_was_on = MusEGlobal::tempomap.masterFlag();
+ if(MusEGlobal::extSyncFlag.value() && !master_was_on)
+ MusEGlobal::tempomap.setMasterFlag(0, true);
+
if((MusEGlobal::audio->loopCount() > 0 && s.tick() > lPos().tick()) || (punchin() && s.tick() < lPos().tick()))
s.setTick(lPos().tick());
// If we are looping, just set the end to the right marker, since we don't know how many loops have occurred.
// (Fixed: Added Audio::loopCount)
// Otherwise if punchout is on, limit the end to the right marker.
- if((MusEGlobal::audio->loopCount() > 0) || (punchout() && e.tick() > rPos().tick()) )
+ if((MusEGlobal::audio->loopCount() > 0) || (punchout() && e.tick() > rPos().tick()) )
e.setTick(rPos().tick());
+
// No part to be created? Delete the rec sound file.
- if(s.tick() >= e.tick())
+ if(s.frame() >= e.frame())
{
QString st = f->path();
// The function which calls this function already does this immediately after. But do it here anyway.
@@ -992,19 +1008,30 @@ void Song::cmdAddRecordedWave(MusECore::WaveTrack* track, MusECore::Pos s, MusEC
// counter has dropped by 2 and _recFile will probably deleted then
remove(st.toLatin1().constData());
if(MusEGlobal::debugMsg)
- printf("Song::cmdAddRecordedWave: remove file %s - start=%d end=%d\n", st.toLatin1().constData(), s.tick(), e.tick());
+ printf("Song::cmdAddRecordedWave: remove file %s - startframe=%d endframe=%d\n", st.toLatin1().constData(), s.frame(), e.frame());
+
+ // Restore master flag.
+ if(MusEGlobal::extSyncFlag.value() && !master_was_on)
+ MusEGlobal::tempomap.setMasterFlag(0, false);
+
return;
}
// Round the start down using the Arranger part snap raster value.
- unsigned startTick = AL::sigmap.raster1(s.tick(), MusEGlobal::song->arrangerRaster());
+ int a_rast = MusEGlobal::song->arrangerRaster();
+ unsigned sframe = (a_rast == 1) ? s.frame() : Pos(AL::sigmap.raster1(s.tick(), MusEGlobal::song->arrangerRaster())).frame();
// Round the end up using the Arranger part snap raster value.
- unsigned endTick = AL::sigmap.raster2(e.tick(), MusEGlobal::song->arrangerRaster());
+ unsigned eframe = (a_rast == 1) ? e.frame() : Pos(AL::sigmap.raster2(e.tick(), MusEGlobal::song->arrangerRaster())).frame();
+ unsigned etick = Pos(eframe).tick();
+
+ // Done using master tempo map. Restore master flag.
+ if(MusEGlobal::extSyncFlag.value() && !master_was_on)
+ MusEGlobal::tempomap.setMasterFlag(0, false);
f->update();
MusECore::WavePart* part = new MusECore::WavePart(track);
- part->setTick(startTick);
- part->setLenTick(endTick - startTick);
+ part->setFrame(sframe);
+ part->setLenFrame(eframe - sframe);
part->setName(track->name());
// create Event
@@ -1015,20 +1042,18 @@ void Song::cmdAddRecordedWave(MusECore::WaveTrack* track, MusECore::Pos s, MusEC
track->setRecFile(0);
event.setSpos(0);
-
// Since the part start was snapped down, we must apply the difference so that the
// wave event tick lines up with when the user actually started recording.
- // Added by Tim. p3.3.8
- event.setTick(s.tick() - startTick);
-
-
+ event.setFrame(s.frame() - sframe);
+ // NO Can't use this. SF reports too long samples at first part recorded in sequence. See samples() - funny business with SEEK ?
+ //event.setLenFrame(f.samples());
event.setLenFrame(e.frame() - s.frame());
part->addEvent(event);
MusEGlobal::song->cmdAddPart(part);
- if (MusEGlobal::song->len() < endTick)
- MusEGlobal::song->setLen(endTick);
+ if (MusEGlobal::song->len() < etick)
+ MusEGlobal::song->setLen(etick);
}
//---------------------------------------------------------
diff --git a/muse2/muse/wavetrack.cpp b/muse2/muse/wavetrack.cpp
index dd890b42..b55a67d6 100644
--- a/muse2/muse/wavetrack.cpp
+++ b/muse2/muse/wavetrack.cpp
@@ -223,7 +223,17 @@ bool WaveTrack::getData(unsigned framePos, int channels, unsigned nframe, float*
if (MusEGlobal::audio->freewheel()) {
}
else {
- if (fifo.put(channels, nframe, bp, MusEGlobal::audio->pos().frame()))
+#ifdef _AUDIO_USE_TRUE_FRAME_
+ // TODO: Tested: This is the line that would be needed for Audio Inputs,
+ // because the data arrived in the previous period! Test OK, the waves are in sync.
+ // So we need to do Audio Inputs separately above, AND find a way to mix two overlapping
+ // periods into the file! Nothing wrong with the FIFO per se, we could stamp overlapping
+ // times. But the soundfile just writes, does not mix.
+ //if (fifo.put(channels, nframe, bp, MusEGlobal::audio->previousPos().frame()))
+ //
+ // Tested: This line is OK for track-to-track recording, the waves are in sync:
+#endif
+ if (fifo.put(channels, nframe, bp, MusEGlobal::audio->pos().frame()))
printf("WaveTrack::getData(%d, %d, %d): fifo overrun\n",
framePos, channels, nframe);
}
diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt
index fae0d614..88706339 100644
--- a/muse2/muse/widgets/CMakeLists.txt
+++ b/muse2/muse/widgets/CMakeLists.txt
@@ -57,6 +57,7 @@ QT4_WRAP_CPP (widget_mocs
menutitleitem.h
meter.h
metronome.h
+ midi_audio_control.h
midisyncimpl.h
mixdowndialog.h
mlabel.h
@@ -122,6 +123,7 @@ file (GLOB widgets_ui_files
itransformbase.ui
metronomebase.ui
midisync.ui
+ midi_audio_control_base.ui
mittransposebase.ui
mixdowndialogbase.ui
mtrackinfobase.ui
@@ -169,6 +171,7 @@ file (GLOB widgets_source_files
menutitleitem.cpp
meter.cpp
metronome.cpp
+ midi_audio_control.cpp
midisyncimpl.cpp
mixdowndialog.cpp
mlabel.cpp
diff --git a/muse2/muse/widgets/aboutbox.ui b/muse2/muse/widgets/aboutbox.ui
index 250f656f..8b4d5b37 100644
--- a/muse2/muse/widgets/aboutbox.ui
+++ b/muse2/muse/widgets/aboutbox.ui
@@ -48,7 +48,7 @@
<item>
<widget class="QLabel" name="versionLabel">
<property name="text">
- <string>Version 2 pre-alpha</string>
+ <string>Version 2</string>
</property>
<property name="wordWrap">
<bool>false</bool>
@@ -58,7 +58,7 @@
<item>
<widget class="QLabel" name="textLabel1">
<property name="text">
- <string>(C) Copyright 1999-2010 Werner Schweer and others.
+ <string>(C) Copyright 1999-2012 Werner Schweer and others.
See http://www.muse-sequencer.org for new versions and
more information.
diff --git a/muse2/muse/widgets/bigtime.cpp b/muse2/muse/widgets/bigtime.cpp
index 0b213f28..5adf4966 100644
--- a/muse2/muse/widgets/bigtime.cpp
+++ b/muse2/muse/widgets/bigtime.cpp
@@ -32,6 +32,7 @@
#include "song.h"
#include "app.h"
#include "gconfig.h"
+#include "audio.h"
namespace MusEGlobal {
extern int mtcType;
@@ -229,7 +230,9 @@ bool BigTime::setString(unsigned v)
return true;
}
- unsigned absFrame = MusEGlobal::tempomap.tick2frame(v);
+ // Quick fix: Not much to do but ignore the supplied tick: We need the exact frame here.
+ unsigned absFrame = MusEGlobal::audio->pos().frame();
+
int bar, beat;
unsigned tick;
AL::sigmap.tickValues(v, &bar, &beat, &tick);
diff --git a/muse2/muse/widgets/filedialog.cpp b/muse2/muse/widgets/filedialog.cpp
index 6e7d6882..aa8c5df1 100644
--- a/muse2/muse/widgets/filedialog.cpp
+++ b/muse2/muse/widgets/filedialog.cpp
@@ -102,6 +102,7 @@ void MFileDialog::globalToggled(bool flag)
{
if (flag) {
buttons.readMidiPortsButton->setChecked(false);
+ readMidiPortsSaved = false;
if (lastGlobalDir.isEmpty())
lastGlobalDir = MusEGlobal::museGlobalShare + QString("/") + baseDir; // Initialize if first time
setDirectory(lastGlobalDir);
@@ -117,6 +118,7 @@ void MFileDialog::userToggled(bool flag)
{
if (flag) {
buttons.readMidiPortsButton->setChecked(true);
+ readMidiPortsSaved = true;
if (lastUserDir.isEmpty()) {
//lastUserDir = MusEGlobal::museUser + QString("/") + baseDir; // Initialize if first time
lastUserDir = MusEGlobal::configPath + QString("/") + baseDir; // Initialize if first time // p4.0.39
@@ -140,6 +142,7 @@ void MFileDialog::projectToggled(bool flag)
{
if (flag) {
buttons.readMidiPortsButton->setChecked(true);
+ readMidiPortsSaved = true;
QString s;
if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) {
// if project path is uninitialized, meaning it is still set to museProjectInitPath.
@@ -158,6 +161,29 @@ void MFileDialog::projectToggled(bool flag)
}
}
+void MFileDialog::fileChanged(const QString& path)
+{
+ bool is_mid = path.endsWith(".mid", Qt::CaseInsensitive) ||
+ path.endsWith(".midi", Qt::CaseInsensitive) ||
+ path.endsWith(".kar", Qt::CaseInsensitive);
+
+ if (is_mid)
+ {
+ readMidiPortsSaved=buttons.readMidiPortsButton->isChecked();
+ buttons.readMidiPortsButton->setEnabled(false);
+ buttons.readMidiPortsButton->setChecked(false);
+ }
+ else
+ {
+ if (!buttons.readMidiPortsButton->isEnabled())
+ {
+ buttons.readMidiPortsButton->setEnabled(true);
+ buttons.readMidiPortsButton->setChecked(readMidiPortsSaved);
+ }
+ }
+
+}
+
//---------------------------------------------------------
// MFileDialog
@@ -167,6 +193,7 @@ MFileDialog::MFileDialog(const QString& dir,
const QString& filter, QWidget* parent, bool writeFlag)
: QFileDialog(parent, QString(), QString("."), filter)
{
+ readMidiPortsSaved = true;
showButtons = false;
lastUserDir = "";
lastGlobalDir = "";
@@ -201,10 +228,11 @@ MFileDialog::MFileDialog(const QString& dir,
buttons.userButton->setAutoExclusive(true);
buttons.projectButton->setAutoExclusive(true);
- connect(buttons.globalButton, SIGNAL(toggled(bool)), this, SLOT(globalToggled(bool)));
+ connect(buttons.globalButton, SIGNAL(toggled(bool)), this, SLOT(globalToggled(bool)));
connect(buttons.userButton, SIGNAL(toggled(bool)), this, SLOT(userToggled(bool)));
connect(buttons.projectButton, SIGNAL(toggled(bool)), this, SLOT(projectToggled(bool)));
connect(this, SIGNAL(directoryEntered(const QString&)), SLOT(directoryChanged(const QString&)));
+ connect(this, SIGNAL(currentChanged(const QString&)), SLOT(fileChanged(const QString&)));
if (writeFlag) {
setAcceptMode(QFileDialog::AcceptSave);
diff --git a/muse2/muse/widgets/filedialog.h b/muse2/muse/widgets/filedialog.h
index 1e2616da..582e943d 100644
--- a/muse2/muse/widgets/filedialog.h
+++ b/muse2/muse/widgets/filedialog.h
@@ -52,9 +52,12 @@ class MFileDialog : public QFileDialog {
QString lastUserDir, lastGlobalDir;
bool showButtons;
QString baseDir;
+
+ bool readMidiPortsSaved;
private slots:
void directoryChanged(const QString& directory);
+ void fileChanged(const QString&);
public slots:
void globalToggled(bool);
void userToggled(bool);
diff --git a/muse2/muse/widgets/midi_audio_control.cpp b/muse2/muse/widgets/midi_audio_control.cpp
new file mode 100644
index 00000000..78c8de3c
--- /dev/null
+++ b/muse2/muse/widgets/midi_audio_control.cpp
@@ -0,0 +1,340 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+//
+// midi_audio_control.cpp
+// Copyright (C) 2012 by Tim E. Real (terminator356 at users.sourceforge.net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+#include "midi_audio_control.h"
+
+#include "globals.h"
+#include "globaldefs.h"
+#include "mididev.h"
+#include "midiport.h"
+#include "midictrl.h"
+#include "audio.h"
+#include "app.h"
+
+#include <QTimer>
+
+namespace MusEGui {
+
+// -----------------------------------
+// MidiAudioControl
+// Set port to -1 to automatically set it to the port of
+// the first combo box item (the first readable port).
+// -----------------------------------
+
+MidiAudioControl::MidiAudioControl(int port, int chan, int ctrl, QWidget* parent)
+ : QDialog(parent)
+{
+ setupUi(this);
+
+ _port = port;
+ _chan = chan;
+ _ctrl = ctrl;
+ _is_learning = false;
+
+ update();
+
+ connect(learnPushButton, SIGNAL(clicked(bool)), SLOT(learnChanged(bool)));
+ connect(portComboBox, SIGNAL(currentIndexChanged(int)), SLOT(portChanged(int)));
+ connect(channelSpinBox, SIGNAL(valueChanged(int)), SLOT(chanChanged()));
+ connect(controlTypeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(ctrlTypeChanged(int)));
+ connect(ctrlHiSpinBox, SIGNAL(valueChanged(int)), SLOT(ctrlHChanged()));
+ connect(ctrlLoSpinBox, SIGNAL(valueChanged(int)), SLOT(ctrlLChanged()));
+ connect(MusEGlobal::muse, SIGNAL(configChanged()), SLOT(configChanged()));
+ connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), SLOT(heartbeat()));
+}
+
+void MidiAudioControl::heartbeat()
+{
+ if(_is_learning)
+ {
+ if(MusEGlobal::midiLearnPort != -1)
+ {
+ int port_item = portComboBox->findData(MusEGlobal::midiLearnPort);
+ if(port_item != -1 && port_item != portComboBox->currentIndex())
+ {
+ _port = MusEGlobal::midiLearnPort;
+ portComboBox->blockSignals(true);
+ portComboBox->setCurrentIndex(port_item);
+ portComboBox->blockSignals(false);
+ }
+ }
+
+ if(MusEGlobal::midiLearnChan != -1 && (MusEGlobal::midiLearnChan + 1) != channelSpinBox->value())
+ {
+ _chan = MusEGlobal::midiLearnChan;
+ channelSpinBox->blockSignals(true);
+ channelSpinBox->setValue(_chan + 1);
+ channelSpinBox->blockSignals(false);
+ }
+
+ if(MusEGlobal::midiLearnCtrl != -1)
+ {
+ int type = MusECore::midiControllerType(MusEGlobal::midiLearnCtrl);
+ if(type < controlTypeComboBox->count() && type != controlTypeComboBox->currentIndex())
+ {
+ controlTypeComboBox->blockSignals(true);
+ controlTypeComboBox->setCurrentIndex(type);
+ controlTypeComboBox->blockSignals(false);
+ }
+
+ int hv = (MusEGlobal::midiLearnCtrl >> 8) & 0xff;
+ int lv = MusEGlobal::midiLearnCtrl & 0xff;
+ if(type == MusECore::MidiController::Program || type == MusECore::MidiController::Pitch)
+ {
+ ctrlHiSpinBox->setEnabled(false);
+ ctrlLoSpinBox->setEnabled(false);
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlLoSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(0);
+ ctrlLoSpinBox->setValue(0);
+ ctrlHiSpinBox->blockSignals(false);
+ ctrlLoSpinBox->blockSignals(false);
+ }
+ else if(type == MusECore::MidiController::Controller7)
+ {
+ ctrlHiSpinBox->setEnabled(false);
+ ctrlLoSpinBox->setEnabled(true);
+
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(0);
+ ctrlHiSpinBox->blockSignals(false);
+
+ if(lv != ctrlLoSpinBox->value())
+ {
+ ctrlLoSpinBox->blockSignals(true);
+ ctrlLoSpinBox->setValue(lv);
+ ctrlLoSpinBox->blockSignals(false);
+ }
+ }
+ else
+ {
+ ctrlHiSpinBox->setEnabled(true);
+ ctrlLoSpinBox->setEnabled(true);
+ if(hv != ctrlHiSpinBox->value())
+ {
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(hv);
+ ctrlHiSpinBox->blockSignals(false);
+ }
+ if(lv != ctrlLoSpinBox->value())
+ {
+ ctrlLoSpinBox->blockSignals(true);
+ ctrlLoSpinBox->setValue(lv);
+ ctrlLoSpinBox->blockSignals(false);
+ }
+ }
+
+ _ctrl = MusECore::midiCtrlTerms2Number(type, (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value());
+ }
+ }
+}
+
+void MidiAudioControl::learnChanged(bool v)
+{
+ _is_learning = v;
+ if(_is_learning)
+ MusEGlobal::audio->msgStartMidiLearn(); // Resets the learn values to -1.
+}
+
+void MidiAudioControl::resetLearn()
+{
+ _is_learning = false;
+ learnPushButton->blockSignals(true);
+ learnPushButton->setChecked(false);
+ learnPushButton->blockSignals(false);
+ MusEGlobal::audio->msgStartMidiLearn(); // Resets the learn values to -1.
+}
+
+void MidiAudioControl::portChanged(int idx)
+{
+ if(idx == -1)
+ return;
+ int port_num = portComboBox->itemData(idx).toInt();
+ if(port_num < 0 || port_num >= MIDI_PORTS)
+ return;
+
+ _port = port_num;
+ resetLearn();
+}
+
+void MidiAudioControl::chanChanged()
+{
+ _chan = channelSpinBox->value() - 1;
+ resetLearn();
+}
+
+void MidiAudioControl::updateCtrlBoxes()
+{
+ int idx = controlTypeComboBox->currentIndex();
+ if(idx == -1)
+ return;
+
+ if(idx == MusECore::MidiController::Program || idx == MusECore::MidiController::Pitch)
+ {
+ ctrlHiSpinBox->setEnabled(false);
+ ctrlLoSpinBox->setEnabled(false);
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlLoSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(0);
+ ctrlLoSpinBox->setValue(0);
+ ctrlHiSpinBox->blockSignals(false);
+ ctrlLoSpinBox->blockSignals(false);
+ }
+ else if(idx == MusECore::MidiController::Controller7)
+ {
+ ctrlHiSpinBox->setEnabled(false);
+ ctrlLoSpinBox->setEnabled(true);
+
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(0);
+ ctrlHiSpinBox->blockSignals(false);
+ }
+ else
+ {
+ ctrlHiSpinBox->setEnabled(true);
+ ctrlLoSpinBox->setEnabled(true);
+ }
+}
+
+void MidiAudioControl::ctrlTypeChanged(int idx)
+{
+ if(idx == -1)
+ return;
+
+ updateCtrlBoxes();
+
+ _ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value();
+ _ctrl = MusECore::midiCtrlTerms2Number(idx, _ctrl);
+
+ resetLearn();
+}
+
+void MidiAudioControl::ctrlHChanged()
+{
+ if(controlTypeComboBox->currentIndex() == -1)
+ return;
+ _ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value();
+ _ctrl = MusECore::midiCtrlTerms2Number(controlTypeComboBox->currentIndex(), _ctrl);
+
+ resetLearn();
+}
+
+void MidiAudioControl::ctrlLChanged()
+{
+ if(controlTypeComboBox->currentIndex() == -1)
+ return;
+ _ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value();
+ _ctrl = MusECore::midiCtrlTerms2Number(controlTypeComboBox->currentIndex(), _ctrl);
+
+ resetLearn();
+}
+
+void MidiAudioControl::configChanged()
+{
+ update();
+}
+
+void MidiAudioControl::update()
+{
+ portComboBox->blockSignals(true);
+ portComboBox->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.
+ continue;
+ //if(!(md->rwFlags() & 1 || md->isSynti()) && (i != outPort))
+ if(!(md->rwFlags() & 2) && (i != _port)) // Only readable ports, or current one.
+ continue;
+ QString name;
+ name.sprintf("%d:%s", i+1, MusEGlobal::midiPorts[i].portname().toLatin1().constData());
+ portComboBox->insertItem(item_idx, name, i);
+ if(_port == -1)
+ _port = i; // Initialize
+ if(i == _port)
+ portComboBox->setCurrentIndex(item_idx);
+ item_idx++;
+ }
+ portComboBox->blockSignals(false);
+
+ channelSpinBox->blockSignals(true);
+ channelSpinBox->setValue(_chan + 1);
+ channelSpinBox->blockSignals(false);
+
+ int type = MusECore::midiControllerType(_ctrl);
+ if(type < controlTypeComboBox->count())
+ {
+ controlTypeComboBox->blockSignals(true);
+ controlTypeComboBox->setCurrentIndex(type);
+ controlTypeComboBox->blockSignals(false);
+ }
+
+ int hv = (_ctrl >> 8) & 0xff;
+ int lv = _ctrl & 0xff;
+ if(type == MusECore::MidiController::Program || type == MusECore::MidiController::Pitch)
+ {
+ ctrlHiSpinBox->setEnabled(false);
+ ctrlLoSpinBox->setEnabled(false);
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlLoSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(0);
+ ctrlLoSpinBox->setValue(0);
+ ctrlHiSpinBox->blockSignals(false);
+ ctrlLoSpinBox->blockSignals(false);
+ }
+ else if(type == MusECore::MidiController::Controller7)
+ {
+ ctrlHiSpinBox->setEnabled(false);
+ ctrlLoSpinBox->setEnabled(true);
+
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(0);
+ ctrlHiSpinBox->blockSignals(false);
+
+ if(lv != ctrlLoSpinBox->value())
+ {
+ ctrlLoSpinBox->blockSignals(true);
+ ctrlLoSpinBox->setValue(lv);
+ ctrlLoSpinBox->blockSignals(false);
+ }
+ }
+ else
+ {
+ ctrlHiSpinBox->setEnabled(true);
+ ctrlLoSpinBox->setEnabled(true);
+ if(hv != ctrlHiSpinBox->value())
+ {
+ ctrlHiSpinBox->blockSignals(true);
+ ctrlHiSpinBox->setValue(hv);
+ ctrlHiSpinBox->blockSignals(false);
+ }
+ if(lv != ctrlLoSpinBox->value())
+ {
+ ctrlLoSpinBox->blockSignals(true);
+ ctrlLoSpinBox->setValue(lv);
+ ctrlLoSpinBox->blockSignals(false);
+ }
+ }
+}
+
+}
diff --git a/muse2/muse/widgets/midi_audio_control.h b/muse2/muse/widgets/midi_audio_control.h
new file mode 100644
index 00000000..887de942
--- /dev/null
+++ b/muse2/muse/widgets/midi_audio_control.h
@@ -0,0 +1,60 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+//
+// midi_audio_control.h
+// Copyright (C) 2012 by Tim E. Real (terminator356 at users.sourceforge.net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+#ifndef MIDI_AUDIO_CONTROL_H
+#define MIDI_AUDIO_CONTROL_H
+
+#include "ui_midi_audio_control_base.h"
+
+namespace MusEGui {
+
+class MidiAudioControl : public QDialog, public Ui::MidiAudioControlBase
+{
+ Q_OBJECT
+
+private:
+ int _port, _chan, _ctrl;
+ bool _is_learning;
+ void update();
+ void resetLearn();
+ void updateCtrlBoxes();
+
+private slots:
+ void heartbeat();
+ void learnChanged(bool);
+ void portChanged(int);
+ void chanChanged();
+ void ctrlTypeChanged(int);
+ void ctrlHChanged();
+ void ctrlLChanged();
+ void configChanged();
+
+public:
+ MidiAudioControl(int port = -1, int chan = 0, int ctrl = 0, QWidget* parent = 0);
+ int port() const { return _port; }
+ int chan() const { return _chan; }
+ int ctrl() const { return _ctrl; }
+};
+
+}
+
+#endif // MIDI_AUDIO_CONTROL_H
diff --git a/muse2/muse/widgets/midi_audio_control_base.ui b/muse2/muse/widgets/midi_audio_control_base.ui
new file mode 100644
index 00000000..2e341121
--- /dev/null
+++ b/muse2/muse/widgets/midi_audio_control_base.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MidiAudioControlBase</class>
+ <widget class="QDialog" name="MidiAudioControlBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>341</width>
+ <height>148</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Midi control</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="portComboBox"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Channel:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="channelSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>16</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Control type:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="controlTypeComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>Control7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Control14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Program</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Hi:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="ctrlHiSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Lo:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="ctrlLoSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QPushButton" name="learnPushButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Learn</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>18</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>MidiAudioControlBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>MidiAudioControlBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse2/muse/widgets/midisync.ui b/muse2/muse/widgets/midisync.ui
index a7464aaf..942a4e59 100644
--- a/muse2/muse/widgets/midisync.ui
+++ b/muse2/muse/widgets/midisync.ui
@@ -10,7 +10,7 @@ configuration dialog</comment>
<x>0</x>
<y>0</y>
<width>655</width>
- <height>419</height>
+ <height>445</height>
</rect>
</property>
<property name="windowTitle">
@@ -337,6 +337,100 @@ Enabled inputs in the list will
<item row="3" column="0">
<layout class="QHBoxLayout">
<item>
+ <widget class="QComboBox" name="syncRecFilterPreset">
+ <property name="toolTip">
+ <string>Averaging applied to recorded external tempo changes.</string>
+ </property>
+ <property name="whatsThis">
+ <string>External midi clock can be very jittery.
+Tempo is derived from it and recorded.
+It is usually desirable to average it and
+ limit the number of recorded changes.
+
+Tiny: 2 section 4/4 = 8 stages.
+1/8T note averaging, may produce jitter.
+
+Small: 3 section 12/8/4 = 24 stages.
+1/4 note averaging, may still produce jitter.
+
+Medium: 3 section 28/12/8 = 48 stages.
+1/2 note averaging. Less jitter.
+
+Large: 4 section 48/48/48/48 = 192 stages.
+Use this if the song has only one tempo.
+Very low quantization values can be used.
+
+Large pre-detect: 4 section 8/48/48/48 = 152
+ stages + first stage large step pre-detector.
+Use this if you expect sudden large tempo steps.
+
+None: Use only if high accuracy is needed for
+ audio alignment on playback. Caution: Records
+ thousands of tempo changes per minute. MusE
+ may slow and the song file will be large.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="syncRecFilterLabel">
+ <property name="text">
+ <string>Tempo record averaging</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QDoubleSpinBox" name="syncRecTempoValQuant">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="suffix">
+ <string>bpm</string>
+ </property>
+ <property name="minimum">
+ <double>0.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value">
+ <double>1.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="syncRecTempoValQuantLabel">
+ <property name="text">
+ <string>Tempo record quantization</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="0">
+ <layout class="QHBoxLayout">
+ <item>
<widget class="QSpinBox" name="syncDelaySpinBox">
<property name="toolTip">
<string>Send start to first clock delay</string>
@@ -379,7 +473,7 @@ Enabled inputs in the list will
</item>
</layout>
</item>
- <item row="4" column="0">
+ <item row="6" column="0">
<widget class="QTreeWidget" name="devicesListView">
<column>
<property name="text">
@@ -388,18 +482,18 @@ Enabled inputs in the list will
</column>
</widget>
</item>
- <item row="5" column="0">
- <widget class="QLabel" name="toBeDoneLabel">
+ <item row="7" column="0">
+ <widget class="QLabel" name="toBeDoneLabel">
<property name="text">
- <string>Note: Sync delay and MTC sync currently not fully implemented</string>
+ <string>Note: Sync delay and MTC sync currently not fully implemented</string>
</property>
<property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
- <bool>false</bool>
+ <bool>false</bool>
</property>
- </widget>
+ </widget>
</item>
</layout>
</widget>
diff --git a/muse2/muse/widgets/midisyncimpl.cpp b/muse2/muse/widgets/midisyncimpl.cpp
index 904e8759..e286ca74 100644
--- a/muse2/muse/widgets/midisyncimpl.cpp
+++ b/muse2/muse/widgets/midisyncimpl.cpp
@@ -28,6 +28,7 @@
#include <QTimer>
#include <QTreeWidgetItem>
#include <QHeaderView>
+#include <QComboBox>
#include "app.h"
#include "song.h"
@@ -137,32 +138,12 @@ void MidiSyncConfig::addDevice(QTreeWidgetItem *item, QTreeWidget *tree)
tree->addTopLevelItem(item);
}
-/*
-//---------------------------------------------------------
-// MidiSyncLViewItem
-// setDevice
-//---------------------------------------------------------
-
-void MidiSyncLViewItem::setDevice(MusECore::MidiDevice* d)
-{
- _device = d;
- if(_device)
- _syncInfo.copyParams(_device->syncInfo());
-}
-*/
-
-//---------------------------------------------------------
-// MidiSyncLViewItem
-// setPort
-//---------------------------------------------------------
-
void MidiSyncLViewItem::setPort(int port)
{
_port = port;
if(_port < 0 || port > MIDI_PORTS)
return;
- //_syncInfo.copyParams(MusEGlobal::midiPorts[port].syncInfo());
copyFromSyncInfo(MusEGlobal::midiPorts[port].syncInfo());
}
@@ -221,41 +202,6 @@ MidiSyncConfig::MidiSyncConfig(QWidget* parent)
_dirty = false;
applyButton->setEnabled(false);
- //inHeartBeat = true;
-
- //for(int i = 0; i < MIDI_PORTS; ++i)
- // tmpMidiSyncPorts[i] = midiSyncPorts[i];
-
- //bool ext = MusEGlobal::extSyncFlag.value();
- //syncMode->setButton(int(ext));
- //syncChanged(ext);
-// extSyncCheckbox->setChecked(MusEGlobal::extSyncFlag.value());
-
-// dstDevId->setValue(txDeviceId);
-// srcDevId->setValue(rxDeviceId);
-// srcSyncPort->setValue(rxSyncPort + 1);
-// dstSyncPort->setValue(txSyncPort + 1);
-
-// mtcSync->setChecked(genMTCSync);
-// mcSync->setChecked(genMCSync);
-// midiMachineControl->setChecked(genMMC);
-
-// acceptMTCCheckbox->setChecked(acceptMTC);
- //acceptMTCCheckbox->setChecked(false);
-// acceptMCCheckbox->setChecked(acceptMC);
-// acceptMMCCheckbox->setChecked(acceptMMC);
-
-// mtcSyncType->setCurrentItem(MusEGlobal::mtcType);
-
-// mtcOffH->setValue(MusEGlobal::mtcOffset.h());
-// mtcOffM->setValue(MusEGlobal::mtcOffset.m());
-// mtcOffS->setValue(MusEGlobal::mtcOffset.s());
-// mtcOffF->setValue(MusEGlobal::mtcOffset.f());
-// mtcOffSf->setValue(MusEGlobal::mtcOffset.sf());
-
-
-
-
devicesListView->setAllColumnsShowFocus(true);
QStringList columnnames;
columnnames << tr("Port")
@@ -284,9 +230,11 @@ MidiSyncConfig::MidiSyncConfig(QWidget* parent)
setToolTips(devicesListView->headerItem());
devicesListView->setFocusPolicy(Qt::NoFocus);
- //MSyncHeaderTip::add(devicesListView->header(), QString("Midi sync ports"));
-
-// updateSyncInfoLV();
+ syncRecFilterPreset->addItem(tr("None"), MusECore::MidiSyncInfo::NONE);
+ syncRecFilterPreset->addItem(tr("Tiny"), MusECore::MidiSyncInfo::TINY);
+ syncRecFilterPreset->addItem(tr("Small"), MusECore::MidiSyncInfo::SMALL);
+ syncRecFilterPreset->addItem(tr("Large"), MusECore::MidiSyncInfo::LARGE);
+ syncRecFilterPreset->addItem(tr("Large with pre-detect"), MusECore::MidiSyncInfo::LARGE_WITH_PRE_DETECT);
songChanged(-1);
@@ -308,14 +256,14 @@ MidiSyncConfig::MidiSyncConfig(QWidget* parent)
connect(mtcSyncType, SIGNAL(activated(int)), SLOT(syncChanged()));
connect(useJackTransportCheckbox, SIGNAL(clicked()), SLOT(syncChanged()));
connect(jackTransportMasterCheckbox, SIGNAL(clicked()), SLOT(syncChanged()));
+ connect(syncRecFilterPreset, SIGNAL(currentIndexChanged(int)), SLOT(syncChanged()));
+ connect(syncRecTempoValQuant, SIGNAL(valueChanged(double)), SLOT(syncChanged()));
connect(&MusEGlobal::extSyncFlag, SIGNAL(valueChanged(bool)), SLOT(extSyncChanged(bool)));
connect(syncDelaySpinBox, SIGNAL(valueChanged(int)), SLOT(syncChanged()));
// Done in show().
//connect(MusEGlobal::song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
//connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat()));
-
- //inHeartBeat = false;
}
MidiSyncConfig::~MidiSyncConfig()
@@ -356,6 +304,17 @@ void MidiSyncConfig::songChanged(int flags)
jackTransportMasterCheckbox->blockSignals(false);
useJackTransportCheckbox->blockSignals(false);
extSyncCheckbox->blockSignals(false);
+
+ int fp_idx = syncRecFilterPreset->findData(MusEGlobal::syncRecFilterPreset);
+ if(fp_idx != -1)
+ {
+ syncRecFilterPreset->blockSignals(true);
+ syncRecFilterPreset->setCurrentIndex(fp_idx);
+ syncRecFilterPreset->blockSignals(false);
+ }
+ syncRecTempoValQuant->blockSignals(true);
+ syncRecTempoValQuant->setValue(MusEGlobal::syncRecTempoValQuant);
+ syncRecTempoValQuant->blockSignals(false);
mtcSyncType->setCurrentIndex(MusEGlobal::mtcType);
@@ -400,9 +359,6 @@ void MidiSyncConfig::heartBeat()
{
if(!lvi->_curDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting current red icon\n");
-
lvi->_curDet = true;
lvi->_inDet = false;
lvi->setIcon(DEVCOL_IN, QIcon( *record1_Icon));
@@ -411,9 +367,6 @@ void MidiSyncConfig::heartBeat()
else
if(!lvi->_inDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting non-current green icon\n");
-
lvi->_inDet = true;
lvi->_curDet = false;
lvi->setIcon(DEVCOL_IN, QIcon( *dotIcon));
@@ -423,9 +376,6 @@ void MidiSyncConfig::heartBeat()
{
if(lvi->_curDet || lvi->_inDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting off icon\n");
-
lvi->_curDet = false;
lvi->_inDet = false;
lvi->setIcon(DEVCOL_IN, QIcon( *dothIcon));
@@ -437,9 +387,6 @@ void MidiSyncConfig::heartBeat()
{
if(!lvi->_tickDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting tick on icon\n");
-
lvi->_tickDet = true;
lvi->setIcon(DEVCOL_TICKIN, QIcon( *dotIcon));
}
@@ -448,9 +395,6 @@ void MidiSyncConfig::heartBeat()
{
if(lvi->_tickDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting tick off icon\n");
-
lvi->_tickDet = false;
lvi->setIcon(DEVCOL_TICKIN, QIcon( *dothIcon));
}
@@ -461,9 +405,6 @@ void MidiSyncConfig::heartBeat()
{
if(!lvi->_MRTDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting MRT on icon\n");
-
lvi->_MRTDet = true;
lvi->setIcon(DEVCOL_MRTIN, QIcon( *dotIcon));
}
@@ -472,9 +413,6 @@ void MidiSyncConfig::heartBeat()
{
if(lvi->_MRTDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting MRT off icon\n");
-
lvi->_MRTDet = false;
lvi->setIcon(DEVCOL_MRTIN, QIcon( *dothIcon));
}
@@ -487,9 +425,6 @@ void MidiSyncConfig::heartBeat()
{
if(!lvi->_MMCDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting MMC on icon\n");
-
lvi->_MMCDet = true;
lvi->setIcon(DEVCOL_MMCIN, QIcon( *dotIcon));
}
@@ -521,9 +456,6 @@ void MidiSyncConfig::heartBeat()
{
if(lvi->_MMCDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting MMC off icon\n");
-
lvi->_MMCDet = false;
lvi->setIcon(DEVCOL_MMCIN, QIcon( *dothIcon));
}
@@ -535,9 +467,6 @@ void MidiSyncConfig::heartBeat()
{
if(!lvi->_curMTCDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting current red icon\n");
-
lvi->_curMTCDet = true;
lvi->_MTCDet = false;
lvi->setIcon(DEVCOL_MTCIN, QIcon( *record1_Icon));
@@ -546,9 +475,6 @@ void MidiSyncConfig::heartBeat()
else
if(!lvi->_MTCDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting MTC on icon\n");
-
lvi->_MTCDet = true;
lvi->_curMTCDet = false;
lvi->setIcon(DEVCOL_MTCIN, QIcon( *dotIcon));
@@ -581,9 +507,6 @@ void MidiSyncConfig::heartBeat()
{
if(lvi->_curMTCDet || lvi->_MTCDet)
{
- // Added by Tim. p3.3.6
- //printf("MidiSyncConfig::heartBeat setting MTC off icon\n");
-
lvi->_MTCDet = false;
lvi->_curMTCDet = false;
lvi->setIcon(DEVCOL_MTCIN, QIcon( *dothIcon));
@@ -610,13 +533,6 @@ void MidiSyncConfig::heartBeat()
void MidiSyncConfig::syncChanged()
{
setDirty();
-
- //MusEGlobal::jackTransportMasterCheckbox->setEnabled(MusEGlobal::useJackTransport);
-
- //acceptMTCCheckbox->setEnabled(val);
-// acceptMTCCheckbox->setEnabled(false);
-// acceptMCCheckbox->setEnabled(val);
-// acceptMMCCheckbox->setEnabled(val);
}
//---------------------------------------------------------
@@ -702,24 +618,14 @@ void MidiSyncConfig::closeEvent(QCloseEvent* e)
void MidiSyncConfig::apply()
{
-// txDeviceId = dstDevId->value();
-// rxDeviceId = srcDevId->value();
-// rxSyncPort = srcSyncPort->value() - 1;
-// txSyncPort = dstSyncPort->value() - 1;
-
-// genMTCSync = mtcSync->isChecked();
-// genMCSync = mcSync->isChecked();
-// genMMC = midiMachineControl->isChecked();
+ // Protect all structures.
+ if(MusEGlobal::audio && MusEGlobal::audio->isRunning())
+ MusEGlobal::audio->msgIdle(true);
MusEGlobal::syncSendFirstClockDelay = syncDelaySpinBox->value();
MusEGlobal::mtcType = mtcSyncType->currentIndex();
- //MusEGlobal::extSyncFlag.setValue(syncMode->id(syncMode->selected()));
- //MusEGlobal::extSyncFlag.blockSignals(true);
MusEGlobal::extSyncFlag.setValue(extSyncCheckbox->isChecked());
-// if(MusEGlobal::extSyncFlag.value())
-// MusEGlobal::song->setMasterFlag(false);
- //MusEGlobal::extSyncFlag.blockSignals(false);
MusEGlobal::useJackTransport.setValue(useJackTransportCheckbox->isChecked());
// if(MusEGlobal::useJackTransport)
MusEGlobal::jackTransportMaster = jackTransportMasterCheckbox->isChecked();
@@ -729,33 +635,38 @@ void MidiSyncConfig::apply()
if(MusEGlobal::audioDevice)
MusEGlobal::audioDevice->setMaster(MusEGlobal::jackTransportMaster);
+ if(syncRecFilterPreset->currentIndex() != -1)
+ {
+ int fp_idx = syncRecFilterPreset->itemData(syncRecFilterPreset->currentIndex()).toInt();
+ if(fp_idx >= 0 && fp_idx < MusECore::MidiSyncInfo::TYPE_END)
+ {
+ MusEGlobal::syncRecFilterPreset = MusECore::MidiSyncInfo::SyncRecFilterPresetType(fp_idx);
+ if(MusEGlobal::midiSeq)
+ MusEGlobal::midiSeq->setSyncRecFilterPreset(MusEGlobal::syncRecFilterPreset);
+ }
+ }
+ MusEGlobal::syncRecTempoValQuant = syncRecTempoValQuant->value();
+ if(MusEGlobal::midiSeq)
+ MusEGlobal::midiSeq->setRecTempoValQuant(MusEGlobal::syncRecTempoValQuant);
+
MusEGlobal::mtcOffset.setH(mtcOffH->value());
MusEGlobal::mtcOffset.setM(mtcOffM->value());
MusEGlobal::mtcOffset.setS(mtcOffS->value());
MusEGlobal::mtcOffset.setF(mtcOffF->value());
MusEGlobal::mtcOffset.setSf(mtcOffSf->value());
-// acceptMC = acceptMCCheckbox->isChecked();
-// acceptMMC = acceptMMCCheckbox->isChecked();
-// acceptMTC = acceptMTCCheckbox->isChecked();
-
-
- //MidiSyncLViewItem* lvi = (MidiSyncLViewItem*)devicesListView->firstChild();
- //while(lvi)
for (int i = MIDI_PORTS-1; i >= 0; --i)
{
MidiSyncLViewItem* lvi = (MidiSyncLViewItem*)devicesListView->topLevelItem(i);
- //MusECore::MidiDevice* dev = lvi->device();
- // Does the device really exist?
- //if(midiDevices.find(dev) != midiDevices.end())
- // dev->syncInfo().copyParams(lvi->syncInfo());
int port = lvi->port();
if(port >= 0 && port < MIDI_PORTS)
- //MusEGlobal::midiPorts[port].syncInfo().copyParams(lvi->syncInfo());
lvi->copyToSyncInfo(MusEGlobal::midiPorts[port].syncInfo());
}
+ if(MusEGlobal::audio && MusEGlobal::audio->isRunning())
+ MusEGlobal::audio->msgIdle(false);
+
//muse->changeConfig(true); // save settings
_dirty = false;
@@ -777,7 +688,6 @@ void MidiSyncConfig::updateSyncInfoLV()
{
MusECore::MidiPort* port = &MusEGlobal::midiPorts[i];
MusECore::MidiDevice* dev = port->device();
- // p3.3.31
// Don't show if it is a synthesizer device.
// Hmm, some synths might support transport commands or even sync?
// If anything, the DSSI or VST synths just might...
@@ -791,9 +701,6 @@ void MidiSyncConfig::updateSyncInfoLV()
s.setNum(i+1);
MidiSyncLViewItem* lvi = new MidiSyncLViewItem(devicesListView);
lvi->setPort(i); // setPort will copy parameters.
- //MusECore::MidiSyncInfo& si = lvi->syncInfo();
- //si.copyParams(port->syncInfo());
- //lvi.copyFromSyncInfo(port->syncInfo());
MusECore::MidiSyncInfo& portsi = port->syncInfo();
lvi->setText(DEVCOL_NO, s);
@@ -925,11 +832,6 @@ void MidiSyncConfig::updateSyncInfoLV()
//lvi->setText(DEVCOL_MTCTYPE, "--");
}
- //lvi->setText(DEVCOL_RID, QString().setNum(si.idIn()) );
- //lvi->setRenameEnabled(DEVCOL_RID, true);
- //lvi->setIcon(DEVCOL_RCLK, QIcon( si.MCIn() ? *dotIcon : *dothIcon));
- //lvi->setIcon(DEVCOL_RMMC, QIcon( si.MMCIn() ? *dotIcon : *dothIcon));
- //lvi->setIcon(DEVCOL_RMTC, QIcon( si.MTCIn() ? *dotIcon : *dothIcon));
lvi->setText(DEVCOL_RID, QString().setNum(lvi->_idIn) );
lvi->setIcon(DEVCOL_RCLK, QIcon( lvi->_recMC ? *dotIcon : *dothIcon));
lvi->setIcon(DEVCOL_RMRT, QIcon( lvi->_recMRT ? *dotIcon : *dothIcon));
@@ -937,11 +839,6 @@ void MidiSyncConfig::updateSyncInfoLV()
lvi->setIcon(DEVCOL_RMTC, QIcon( lvi->_recMTC ? *dotIcon : *dothIcon));
lvi->setIcon(DEVCOL_RREWSTART, QIcon( lvi->_recRewOnStart ? *dotIcon : *dothIcon));
- //lvi->setText(DEVCOL_TID, QString().setNum(si.idOut()) );
- //lvi->setRenameEnabled(DEVCOL_TID, true);
- //lvi->setIcon(DEVCOL_TCLK, QIcon( si.MCOut() ? *dotIcon : *dothIcon));
- //lvi->setIcon(DEVCOL_TMMC, QIcon( si.MMCOut() ? *dotIcon : *dothIcon));
- //lvi->setIcon(DEVCOL_TMTC, QIcon( si.MTCOut() ? *dotIcon : *dothIcon));
lvi->setText(DEVCOL_TID, QString().setNum(lvi->_idOut) );
lvi->setIcon(DEVCOL_TCLK, QIcon(lvi->_sendMC ? *dotIcon : *dothIcon));
lvi->setIcon(DEVCOL_TMRT, QIcon(lvi->_sendMRT ? *dotIcon : *dothIcon));
@@ -988,38 +885,6 @@ void MidiSyncConfig::updateSyncInfoLV()
devicesListView->header()->setResizeMode(DEVCOL_TMRT, QHeaderView::Fixed);
devicesListView->header()->setResizeMode(DEVCOL_TMMC, QHeaderView::Fixed);
-
- /*
- for(MusECore::iMidiDevice id = midiDevices.begin(); id != midiDevices.end(); ++id)
- {
- MusECore::MidiDevice* dev = *id;
-
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[i];
- //MusECore::MidiDevice* dev = port->device();
- MidiSyncLViewItem* lvi = new MidiSyncLViewItem(devicesListView);
- //lvi->setPort(i);
- // setDevice will copy parameters.
- lvi->setDevice(dev);
- MusECore::MidiSyncInfo& si = lvi->syncInfo();
- //si.copyParams(dev->syncInfo());
-
- lvi->setText(DEVCOL_NAME, dev->name());
-
- lvi->setIcon(DEVCOL_IN, QIcon( si.MCSyncDetect() ? *dotIcon : *dothIcon));
-
- lvi->setText(DEVCOL_RID, QString().setNum(si.idIn()) );
- lvi->setIcon(DEVCOL_RCLK, QIcon( si.MCIn() ? *dotIcon : *dothIcon));
- lvi->setIcon(DEVCOL_RMMC, QIcon( si.MMCIn() ? *dotIcon : *dothIcon));
- lvi->setIcon(DEVCOL_RMTC, QIcon( si.MTCIn() ? *dotIcon : *dothIcon));
-
- lvi->setText(DEVCOL_TID, QString().setNum(si.idOut()) );
- lvi->setIcon(DEVCOL_TCLK, QIcon( si.MCOut() ? *dotIcon : *dothIcon));
- lvi->setIcon(DEVCOL_TMMC, QIcon( si.MMCOut() ? *dotIcon : *dothIcon));
- lvi->setIcon(DEVCOL_TMTC, QIcon( si.MTCOut() ? *dotIcon : *dothIcon));
-
- devicesListView->insertItem(lvi);
- }
- */
}
@@ -1027,7 +892,6 @@ void MidiSyncConfig::updateSyncInfoLV()
// dlvClicked
//---------------------------------------------------------
-//void MidiSyncConfig::dlvClicked(QListViewItem* item, const QPoint&, int col)
void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
{
if (item == 0)
@@ -1042,14 +906,6 @@ void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
//if(midiDevices.find(dev) == midiDevices.end())
// return;
- //int n;
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[no];
- //MusECore::MidiDevice* dev = port->device();
- //int rwFlags = dev ? dev->rwFlags() : 0;
- //int openFlags = dev ? dev->openFlags() : 0;
- //MusECore::MidiSyncInfo& si = lvi->syncInfo();
- //MusECore::MidiSyncInfo& portsi = MusEGlobal::midiPorts[no].syncInfo();
-
switch (col)
{
case DEVCOL_NO:
@@ -1060,8 +916,6 @@ void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
// If this is not the current midi sync in port, and sync in from this port is enabled,
// and sync is in fact detected on this port, allow the user to force this port to now be the
// current sync in port.
- //if(no != MusEGlobal::curMidiSyncInPort && si.MCIn() && MusEGlobal::midiPorts[no].syncInfo().MCSyncDetect())
- //if(no != MusEGlobal::curMidiSyncInPort && lvi->_recMC && MusEGlobal::midiPorts[no].syncInfo().MCSyncDetect())
if(no != MusEGlobal::curMidiSyncInPort)
{
if(lvi->_recMC && MusEGlobal::midiPorts[no].syncInfo().MCSyncDetect())
@@ -1084,8 +938,6 @@ void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
// If this is not the current midi sync in port, and sync in from this port is enabled,
// and sync is in fact detected on this port, allow the user to force this port to now be the
// current sync in port.
- //if(no != MusEGlobal::curMidiSyncInPort && si.MTCIn() && MusEGlobal::midiPorts[no].syncInfo().MTCDetect())
- //if(no != MusEGlobal::curMidiSyncInPort && lvi->_recMTC && MusEGlobal::midiPorts[no].syncInfo().MTCDetect())
if(no != MusEGlobal::curMidiSyncInPort)
{
if(lvi->_recMTC && MusEGlobal::midiPorts[no].syncInfo().MTCDetect())
@@ -1105,8 +957,6 @@ void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
case DEVCOL_RID:
break;
case DEVCOL_RCLK:
- //si.setMCIn(si.MCIn() ? false : true);
- //lvi->setIcon(DEVCOL_RCLK, QIcon( si.MCIn() ? *dotIcon : *dothIcon));
lvi->_recMC = (lvi->_recMC ? false : true);
lvi->setIcon(DEVCOL_RCLK, QIcon( lvi->_recMC ? *dotIcon : *dothIcon));
setDirty();
@@ -1117,15 +967,11 @@ void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
setDirty();
break;
case DEVCOL_RMMC:
- //si.setMMCIn(si.MMCIn() ? false : true);
- //lvi->setIcon(DEVCOL_RMMC, QIcon( si.MMCIn() ? *dotIcon : *dothIcon));
lvi->_recMMC = (lvi->_recMMC ? false : true);
lvi->setIcon(DEVCOL_RMMC, QIcon( lvi->_recMMC ? *dotIcon : *dothIcon));
setDirty();
break;
case DEVCOL_RMTC:
- //si.setMTCIn(si.MTCIn() ? false : true);
- //lvi->setIcon(DEVCOL_RMTC, QIcon( si.MTCIn() ? *dotIcon : *dothIcon));
lvi->_recMTC = (lvi->_recMTC ? false : true);
lvi->setIcon(DEVCOL_RMTC, QIcon( lvi->_recMTC ? *dotIcon : *dothIcon));
setDirty();
@@ -1138,8 +984,6 @@ void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
case DEVCOL_TID:
break;
case DEVCOL_TCLK:
- //si.setMCOut(si.MCOut() ? false : true);
- //lvi->setIcon(DEVCOL_TCLK, QIcon( si.MCOut() ? *dotIcon : *dothIcon));
lvi->_sendMC = (lvi->_sendMC ? false : true);
lvi->setIcon(DEVCOL_TCLK, QIcon( lvi->_sendMC ? *dotIcon : *dothIcon));
setDirty();
@@ -1150,15 +994,11 @@ void MidiSyncConfig::dlvClicked(QTreeWidgetItem* item, int col)
setDirty();
break;
case DEVCOL_TMMC:
- //si.setMMCOut(si.MMCOut() ? false : true);
- //lvi->setIcon(DEVCOL_TMMC, QIcon( si.MMCOut() ? *dotIcon : *dothIcon));
lvi->_sendMMC = (lvi->_sendMMC ? false : true);
lvi->setIcon(DEVCOL_TMMC, QIcon( lvi->_sendMMC ? *dotIcon : *dothIcon));
setDirty();
break;
case DEVCOL_TMTC:
- //si.setMTCOut(si.MTCOut() ? false : true);
- //lvi->setIcon(DEVCOL_TMTC, QIcon( si.MTCOut() ? *dotIcon : *dothIcon));
lvi->_sendMTC = (lvi->_sendMTC ? false : true);
lvi->setIcon(DEVCOL_TMTC, QIcon( lvi->_sendMTC ? *dotIcon : *dothIcon));
setDirty();
@@ -1183,21 +1023,13 @@ void MidiSyncConfig::dlvDoubleClicked(QTreeWidgetItem* item, int col)
MidiSyncLViewItem* lvi = (MidiSyncLViewItem*)item;
- //if(col == DEVCOL_RID)
- // lvi->startRename(DEVCOL_RID);
- //else
- //if(col == DEVCOL_TID)
- // lvi->startRename(DEVCOL_TID);
-
bool ok = false;
if(col == DEVCOL_RID)
{
- //int val = lvi->syncInfo().idIn();
int val = lvi->_idIn;
int newval = QInputDialog::getInteger(this, "Muse: Sync info" , "Enter new id number (127 = all):", val, 0, 127, 1, &ok);
if(ok)
{
- //lvi->syncInfo().setIdIn(newval);
lvi->_idIn = newval;
lvi->setText(DEVCOL_RID, QString().setNum(newval));
}
@@ -1205,12 +1037,10 @@ void MidiSyncConfig::dlvDoubleClicked(QTreeWidgetItem* item, int col)
else
if(col == DEVCOL_TID)
{
- //int val = lvi->syncInfo().idOut();
int val = lvi->_idOut;
int newval = QInputDialog::getInteger(this, "Muse: Sync info" , "Enter new id number (127 = global):", val, 0, 127, 1, &ok);
if(ok)
{
- //lvi->syncInfo().setIdOut(newval);
lvi->_idOut = newval;
lvi->setText(DEVCOL_TID, QString().setNum(newval));
}
@@ -1220,41 +1050,6 @@ void MidiSyncConfig::dlvDoubleClicked(QTreeWidgetItem* item, int col)
setDirty();
}
-/*
-//---------------------------------------------------------
-// renameOk
-//---------------------------------------------------------
-//void MidiSyncConfig::renameOk(QListViewItem* item, int col)
-void MidiSyncConfig::renameOk(QListViewItem* item, int col, const QString & text)
-{
- if(!item)
- return;
-
- MidiSyncLViewItem* lvi = (MidiSyncLViewItem*)item;
- QString t = text;
- bool ok;
- int id = text.toInt(&ok);
- if(!ok)
- {
- lvi->setText(t);
- return;
- }
- if(col == DEVCOL_RID)
- {
- //lvi->syncInfo().setIdIn(id);
- lvi->_idIn = id;
- setDirty();
- }
- else
- if(col == DEVCOL_TID)
- {
- //lvi->syncInfo().setIdOut(id);
- lvi->_idOut = id;
- setDirty();
- }
-}
-*/
-
//---------------------------------------------------------
// MidiSyncConfig::setDirty
//---------------------------------------------------------
diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp
index bee05d51..9c82b5f5 100644
--- a/muse2/muse/widgets/musewidgetsplug.cpp
+++ b/muse2/muse/widgets/musewidgetsplug.cpp
@@ -215,7 +215,7 @@ MusEGlobal::GlobalConfigValues config = {
QString("./"), // projectBaseFolder
true, // projectStoreInFolder
true, // useProjectSaveDialog
- 64, // minControlProcessPeriod
+ 256, // minControlProcessPeriod
false, // popupsDefaultStayOpen
false, // leftMouseButtonCanDecrease
false, // rangeMarkerWithoutMMB
diff --git a/muse2/muse/widgets/scldraw.cpp b/muse2/muse/widgets/scldraw.cpp
index 38adff25..aec769a0 100644
--- a/muse2/muse/widgets/scldraw.cpp
+++ b/muse2/muse/widgets/scldraw.cpp
@@ -636,7 +636,7 @@ int ScaleDraw::maxHeight(QPainter *p) const
//------------------------------------------------------------
QRect ScaleDraw::maxBoundingRect(QPainter *p) const
{
- int i, wl,h,wmax;
+ int i, wl; //,wmax;
int a, ar, amin, amax;
double arc;
@@ -645,7 +645,6 @@ QRect ScaleDraw::maxBoundingRect(QPainter *p) const
QFontMetrics fm = p->fontMetrics();
wl = maxLabelWidth(p, TRUE);
- h = fm.height();
switch(d_orient)
{
@@ -722,7 +721,7 @@ QRect ScaleDraw::maxBoundingRect(QPainter *p) const
r.setBottom(MusECore::qwtInt(d_yCenter - (d_radius + double(d_majLen + d_vpad)) * cos(arc))
+ fm.height() );
- wmax = d_len + d_majLen + d_hpad + wl;
+ //wmax = d_len + d_majLen + d_hpad + wl; DELETETHIS
r.setLeft(d_xorg - d_majLen - d_hpad - wl);
r.setWidth(d_len + 2*(d_majLen + d_hpad + wl));
diff --git a/muse2/muse/widgets/sliderbase.cpp b/muse2/muse/widgets/sliderbase.cpp
index 15497235..5909c64d 100644
--- a/muse2/muse/widgets/sliderbase.cpp
+++ b/muse2/muse/widgets/sliderbase.cpp
@@ -118,6 +118,7 @@ void SliderBase::wheelEvent(QWheelEvent *e)
setValue(value()-inc);
emit sliderMoved(value(), _id);
+ emit sliderMoved(value(), _id, (bool)(e->modifiers() & Qt::ShiftModifier));
}
@@ -184,6 +185,7 @@ void SliderBase::mousePressEvent(QMouseEvent *e)
d_mouseOffset = 0;
DoubleRange::incPages(d_direction);
emit sliderMoved(value(), _id);
+ emit sliderMoved(value(), _id, (bool)(e->modifiers() & Qt::ShiftModifier));
d_tmrID = startTimer(MusECore::qwtMax(250, 2 * d_updTime));
break;
@@ -394,6 +396,7 @@ void SliderBase::mouseMoveEvent(QMouseEvent *e)
}
if (value() != prevValue())
emit sliderMoved(value(), _id);
+ emit sliderMoved(value(), _id, (bool)(e->modifiers() & Qt::ShiftModifier));
}
}
@@ -444,7 +447,10 @@ void SliderBase::timerEvent(QTimerEvent*)
DoubleRange::incPages(d_direction);
if (value() != prevValue())
+ {
emit sliderMoved(value(), _id);
+ emit sliderMoved(value(), _id, false);
+ }
if (!d_timerTick)
{
@@ -456,7 +462,10 @@ void SliderBase::timerEvent(QTimerEvent*)
DoubleRange::fitValue(value() + double(d_direction) * inc);
if (value() != prevValue())
+ {
emit sliderMoved(value(), _id);
+ emit sliderMoved(value(), _id, false);
+ }
if (!d_timerTick)
{
@@ -620,6 +629,7 @@ void SliderBase::stepPages(int pages)
{
DoubleRange::incPages(pages);
emit sliderMoved(value(), _id);
+ emit sliderMoved(value(), _id, false);
}
@@ -722,7 +732,7 @@ void SliderBase::stepPages(int pages)
// slider with the mouse.
//
//.u Syntax
-//.f void SliderBase::sliderMoved(double value, int _id)
+//.f void SliderBase::sliderMoved(double value, int _id [, bool shift])
//
//.u Parameters
//.p double value -- new value
diff --git a/muse2/muse/widgets/sliderbase.h b/muse2/muse/widgets/sliderbase.h
index 56c7a586..abea5dd6 100644
--- a/muse2/muse/widgets/sliderbase.h
+++ b/muse2/muse/widgets/sliderbase.h
@@ -86,6 +86,7 @@ class SliderBase : public QWidget, public DoubleRange
void sliderPressed(int id);
void sliderReleased(int id);
void sliderMoved(double value, int id);
+ void sliderMoved(double value, int id, bool shift);
void sliderRightClicked(const QPoint &p, int id);
public:
diff --git a/muse2/share/locale/muse_cs.ts b/muse2/share/locale/muse_cs.ts
index 400acd3f..844a236b 100644
--- a/muse2/share/locale/muse_cs.ts
+++ b/muse2/share/locale/muse_cs.ts
@@ -89,20 +89,31 @@
<translation>Název=&quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="503"/>
+ <location filename="../../muse/midiseq.cpp" line="510"/>
<source>Bad timing</source>
<translation>Špatné načasování</translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="504"/>
+ <location filename="../../muse/midiseq.cpp" line="511"/>
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
-Also please check console output for any further error messages
+Also please check console output for any further error messages.
</source>
<translation>Kmitočet zdroje časování je %1hz, což je pod doporučeným minimem: 500hz!
To by u MIDI mohlo vést až ke slyšitelným problémům s časováním.
Podívejte se, prosím, na často kladené otázky na stránkách http://muse-sequencer.org na řešení.
+Také se, prosím, podívejte na výstup konzole kvůli jakýmkoli dalším chybovým hláškám.</translation>
+ </message>
+ <message>
+ <source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
+This could lead to audible timing problems for MIDI.
+Please see the FAQ on http://muse-sequencer.org for remedies.
+Also please check console output for any further error messages
+ </source>
+ <translation type="obsolete">Kmitočet zdroje časování je %1hz, což je pod doporučeným minimem: 500hz!
+To by u MIDI mohlo vést až ke slyšitelným problémům s časováním.
+Podívejte se, prosím, na často kladené otázky na stránkách http://muse-sequencer.org na řešení.
Také se, prosím, podívejte na výstup konzole kvůli jakýmkoli dalším chybovým hláškám</translation>
</message>
</context>
@@ -114,18 +125,34 @@ Také se, prosím, podívejte na výstup konzole kvůli jakýmkoli dalším chyb
<translation>O programu</translation>
</message>
<message>
- <location filename="../../muse/widgets/aboutbox.ui" line="51"/>
<source>Version 2 pre-alpha</source>
+ <translation type="obsolete">Verze 2</translation>
+ </message>
+ <message>
+ <source>(C) Copyright 1999-2010 Werner Schweer and others.
+See http://www.muse-sequencer.org for new versions and
+more information.
+
+Published under the GNU Public License</source>
+ <translation type="obsolete">(C) Autorské právo 1999-2010 Werner Schweer a další.
+Podívejte se na stránky http://www.muse-sequencer.org na nové verze a
+kvůli více informacím.
+
+Zveřejněno pod GNU Public License</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/aboutbox.ui" line="51"/>
+ <source>Version 2</source>
<translation>Verze 2</translation>
</message>
<message>
<location filename="../../muse/widgets/aboutbox.ui" line="61"/>
- <source>(C) Copyright 1999-2010 Werner Schweer and others.
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
See http://www.muse-sequencer.org for new versions and
more information.
Published under the GNU Public License</source>
- <translation>(C) Autorské právo 1999-2010 Werner Schweer a další.
+ <translation>(C) Autorské právo 1999-2012 Werner Schweer a další.
Podívejte se na stránky http://www.muse-sequencer.org na nové verze a
kvůli více informacím.
@@ -4797,6 +4824,84 @@ zaměření na jim příslušné plátno</translation>
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="14"/>
+ <source>Midi control</source>
+ <translation>Ovládání MIDI</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="28"/>
+ <source>Port:</source>
+ <translation>Přípojka:</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="44"/>
+ <source>Channel:</source>
+ <translation>Kanál:</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="71"/>
+ <source>Control type:</source>
+ <translation>Typ ovládání:</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="85"/>
+ <source>Control7</source>
+ <translation>Ovladač 7</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="90"/>
+ <source>Control14</source>
+ <translation>Ovladač 14</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="95"/>
+ <source>RPN</source>
+ <translation>RPN</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="100"/>
+ <source>NRPN</source>
+ <translation>NRPN</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="105"/>
+ <source>RPN14</source>
+ <translation>RPN 14</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="110"/>
+ <source>NRPN14</source>
+ <translation>NRPN 14</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="115"/>
+ <source>Pitch</source>
+ <translation>Výška tónu</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="120"/>
+ <source>Program</source>
+ <translation>Program</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="147"/>
+ <source>Hi:</source>
+ <translation>Vysoký:</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="179"/>
+ <source>Lo:</source>
+ <translation>Nízký:</translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="228"/>
+ <source>Learn</source>
+ <translation>Naučit se</translation>
+ </message>
+</context>
+<context>
<name>MidiFilterConfigBase</name>
<message>
<location filename="../../muse/mplugins/midifilter.ui" line="20"/>
@@ -6156,12 +6261,12 @@ mezi posláním &quot;začátku&quot; až po poslání prvních hodin.</translat
<context>
<name>MusECore::Song</name>
<message>
- <location filename="../../muse/song.cpp" line="2274"/>
+ <location filename="../../muse/song.cpp" line="2284"/>
<source>Jack shutdown!</source>
<translation>Vypnutí JACK!</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2275"/>
+ <location filename="../../muse/song.cpp" line="2285"/>
<source>Jack has detected a performance problem which has lead to
MusE being disconnected.
This could happen due to a number of reasons:
@@ -6195,71 +6300,98 @@ Pro pokračování, prosím, přezkoušejte stav Jacka,
zkuste Jack znovu spustit a klepněte na tlačítko &quot;Spustit znovu&quot;.</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2447"/>
- <location filename="../../muse/song.cpp" line="2612"/>
+ <location filename="../../muse/song.cpp" line="2464"/>
+ <location filename="../../muse/song.cpp" line="2702"/>
<source>Automation:</source>
<translation>Automatizace:</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2449"/>
+ <location filename="../../muse/song.cpp" line="2466"/>
<source>previous event</source>
<translation>Předchozí událost</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2453"/>
+ <location filename="../../muse/song.cpp" line="2470"/>
<source>next event</source>
<translation>Další událost</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2462"/>
- <location filename="../../muse/song.cpp" line="2617"/>
+ <location filename="../../muse/song.cpp" line="2479"/>
+ <location filename="../../muse/song.cpp" line="2707"/>
<source>set event</source>
<translation>Nastavit událost</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2464"/>
- <location filename="../../muse/song.cpp" line="2619"/>
+ <location filename="../../muse/song.cpp" line="2481"/>
+ <location filename="../../muse/song.cpp" line="2709"/>
<source>add event</source>
<translation>Přidat událost</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2468"/>
- <location filename="../../muse/song.cpp" line="2623"/>
+ <location filename="../../muse/song.cpp" line="2485"/>
+ <location filename="../../muse/song.cpp" line="2713"/>
<source>erase event</source>
<translation>Vymazat událost</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2472"/>
+ <location filename="../../muse/song.cpp" line="2489"/>
<source>erase range</source>
<translation>Vymazat rozsah</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2476"/>
+ <location filename="../../muse/song.cpp" line="2493"/>
<source>clear automation</source>
<translation>Smazat automatizaci</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2505"/>
+ <location filename="../../muse/song.cpp" line="2499"/>
+ <source>Midi control</source>
+ <translation>Ovládání MIDI</translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2501"/>
+ <source>Assign</source>
+ <translation>Přiřadit</translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2511"/>
+ <source>Clear</source>
+ <translation>Smazat</translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2556"/>
<source>Clear all controller events?</source>
<translation>Smazat všechny události ovladače?</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2505"/>
+ <location filename="../../muse/song.cpp" line="2556"/>
<source>&amp;Ok</source>
<translation>&amp;OK</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2505"/>
+ <location filename="../../muse/song.cpp" line="2556"/>
<source>&amp;Cancel</source>
<translation>Z&amp;rušit</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="3272"/>
+ <location filename="../../muse/song.cpp" line="2823"/>
+ <source>MusE: Tempo list</source>
+ <translation>MusE: Seznam tempa</translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2824"/>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
+ <translation>Byly nahrány vnější změny tempa.
+Mají se převzít do hlavního seznamu tempa?</translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="3416"/>
<source>MusE - external script failed</source>
<translation>MusE: Vnější skript selhal</translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="3273"/>
+ <location filename="../../muse/song.cpp" line="3417"/>
<source>MusE was unable to launch the script, error message:
%1</source>
<translation>MusE se skript nepodařilo spustit. Chybová zpráva:
@@ -6985,98 +7117,98 @@ prosím, MusE znovu. Promiňte (pokoušíme se to opravit)</translation>
<context>
<name>MusEGui::AudioStrip</name>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="687"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="678"/>
<source>panorama</source>
<translation>Vyvážení</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="689"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="680"/>
<source>aux send level</source>
<translation>Úroveň poslání Aux</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="712"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="703"/>
<source>Pan</source>
<translation>Vyvážení</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="804"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="794"/>
<source>1/2 channel</source>
<translation>1/2 kanály</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="819"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="809"/>
<source>Pre</source>
<translation>Před</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="820"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="810"/>
<source>pre fader - post fader</source>
<translation>Předprolínač - poprolínač</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="890"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="880"/>
<source>dB</source>
<translation>dB</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="922"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="911"/>
<source>record</source>
<translation>Nahrávat</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="934"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="923"/>
<source>mute</source>
<translation>Ztlumit</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="953"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="942"/>
<source>record downmix</source>
<translation>Nahrávat smíchání</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="955"/>
- <location filename="../../muse/mixer/astrip.cpp" line="959"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="944"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="948"/>
<source>solo mode</source>
<translation>Režim sóla</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="967"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="956"/>
<source>off</source>
<translation>Vypnuto</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="993"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="982"/>
<source>input routing</source>
<translation>Vstupní signálový tok</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1006"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="995"/>
<source>output routing</source>
<translation>Výstupní signálový tok</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1020"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1009"/>
<source>Off</source>
<translation>Vypnuto</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1021"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1010"/>
<source>Read</source>
<translation>Číst</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1022"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1011"/>
<source>Touch</source>
<translation>Dotknout se</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1023"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1012"/>
<source>Write</source>
<translation>Zapsat</translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1066"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1055"/>
<source>automation type</source>
<translation>Typ automatizace</translation>
</message>
@@ -7084,49 +7216,49 @@ prosím, MusE znovu. Promiňte (pokoušíme se to opravit)</translation>
<context>
<name>MusEGui::BigTime</name>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="62"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="63"/>
<source>format display</source>
<translation>Zobrazení formátu</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="79"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="80"/>
<source>bar</source>
<translation>Takt</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="80"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="81"/>
<source>beat</source>
<translation>Doba</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="81"/>
- <location filename="../../muse/widgets/bigtime.cpp" line="87"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="82"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="88"/>
<source>tick</source>
<translation>Tik</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="83"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="84"/>
<source>minute</source>
<translation>Minuta</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="84"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="85"/>
<source>second</source>
<translation>Sekunda</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="85"/>
- <location filename="../../muse/widgets/bigtime.cpp" line="88"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="86"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="89"/>
<source>frame</source>
<translation>Snímek</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="86"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="87"/>
<source>subframe</source>
<translation>Podsnímek</translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="104"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="105"/>
<source>MusE: Bigtime</source>
<translation>MusE: Velký ukazatel času</translation>
</message>
@@ -8325,13 +8457,13 @@ Chcete použít na všechny existující stopy MIDI nyní?</translation>
</message>
<message>
<location filename="../../muse/confmport.cpp" line="438"/>
- <location filename="../../muse/confmport.cpp" line="1286"/>
+ <location filename="../../muse/confmport.cpp" line="1290"/>
<source>in</source>
<translation>Vstup</translation>
</message>
<message>
<location filename="../../muse/confmport.cpp" line="461"/>
- <location filename="../../muse/confmport.cpp" line="1278"/>
+ <location filename="../../muse/confmport.cpp" line="1282"/>
<source>out</source>
<translation>Výstup</translation>
</message>
@@ -8363,184 +8495,184 @@ Chcete použít na všechny existující stopy MIDI nyní?</translation>
<translation>Vytvořit zařízení Jack</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="987"/>
- <location filename="../../muse/confmport.cpp" line="1015"/>
+ <location filename="../../muse/confmport.cpp" line="991"/>
+ <location filename="../../muse/confmport.cpp" line="1019"/>
<source>Port Number</source>
<translation>Číslo přípojky</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="988"/>
+ <location filename="../../muse/confmport.cpp" line="992"/>
<source>Enable gui</source>
<translation>Povolit rozhraní</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="989"/>
+ <location filename="../../muse/confmport.cpp" line="993"/>
<source>Enable reading</source>
<translation>Povolit čtení</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="990"/>
+ <location filename="../../muse/confmport.cpp" line="994"/>
<source>Enable writing</source>
<translation>Povolit zápis</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="991"/>
+ <location filename="../../muse/confmport.cpp" line="995"/>
<source>Port instrument</source>
<translation>Nástroj přípojky</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="992"/>
+ <location filename="../../muse/confmport.cpp" line="996"/>
<source>Midi device name. Click to edit (Jack)</source>
<translation>Název zařízení MIDI. Klepnout pro úpravu (Jack)</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="993"/>
+ <location filename="../../muse/confmport.cpp" line="997"/>
<source>Connections from Jack Midi outputs</source>
<translation>Spojení z výstupů MIDI Jack</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="994"/>
+ <location filename="../../muse/confmport.cpp" line="998"/>
<source>Connections to Jack Midi inputs</source>
<translation>Spojení do výstupů MIDI Jack</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="995"/>
+ <location filename="../../muse/confmport.cpp" line="999"/>
<source>Auto-connect these channels to new midi tracks</source>
<translation>Automaticky tyto kanály připojit do nových stop MIDI</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="998"/>
+ <location filename="../../muse/confmport.cpp" line="1002"/>
<source>Auto-connect new midi tracks to these channels</source>
<translation>Automaticky připojit nové stopy MIDI do těchto kanálů</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1000"/>
+ <location filename="../../muse/confmport.cpp" line="1004"/>
<source>Auto-connect new midi tracks to this channel</source>
<translation>Automaticky připojit nové stopy MIDI do tohoto kanálu</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1002"/>
+ <location filename="../../muse/confmport.cpp" line="1006"/>
<source>Device state</source>
<translation>Stav zařízení</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1017"/>
+ <location filename="../../muse/confmport.cpp" line="1021"/>
<source>Enable gui for device</source>
<translation>Povolit rozhraní pro zařízení</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1019"/>
+ <location filename="../../muse/confmport.cpp" line="1023"/>
<source>Enable reading from device</source>
<translation>Povolit čtení ze zařízení</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1021"/>
+ <location filename="../../muse/confmport.cpp" line="1025"/>
<source>Enable writing to device</source>
<translation>Povolit zápis na zařízení</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1023"/>
+ <location filename="../../muse/confmport.cpp" line="1027"/>
<source>Name of the midi device associated with this port number. Click to edit Jack midi name.</source>
<translation>Název zařízení MIDI spojeného s tímto číslem přípojky. Klepněte pro změnu názvu MIDI Jack.</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1026"/>
+ <location filename="../../muse/confmport.cpp" line="1030"/>
<source>Instrument connected to port</source>
<translation>Nástroj spojen s přípojkou</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1028"/>
+ <location filename="../../muse/confmport.cpp" line="1032"/>
<source>Connections from Jack Midi output ports</source>
<translation>Spojení z výstupních přípojek MIDI Jack</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1030"/>
+ <location filename="../../muse/confmport.cpp" line="1034"/>
<source>Connections to Jack Midi input ports</source>
<translation>Spojení k vstupním přípojkám MIDI Jack</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1032"/>
+ <location filename="../../muse/confmport.cpp" line="1036"/>
<source>Auto-connect these channels, on this port, to new midi tracks.</source>
<translation>Automaticky připojit tyto kanály, na této přípojce, do nových stop MIDI.</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1036"/>
+ <location filename="../../muse/confmport.cpp" line="1040"/>
<source>Connect new midi tracks to these channels, on this port.</source>
<translation>Připojit nové stopy MIDI do těchto kanálů, na této přípojce.</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1038"/>
+ <location filename="../../muse/confmport.cpp" line="1042"/>
<source>Connect new midi tracks to this channel, on this port.</source>
<translation>Připojit nové stopy MIDI do tohoto kanálu, na této přípojce.</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1041"/>
+ <location filename="../../muse/confmport.cpp" line="1045"/>
<source>State: result of opening the device</source>
<translation>Stav: Událost otevření zařízení</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1081"/>
+ <location filename="../../muse/confmport.cpp" line="1085"/>
<source>Port</source>
<translation>Přípojka</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1082"/>
+ <location filename="../../muse/confmport.cpp" line="1086"/>
<source>GUI</source>
<translation>Rozhraní</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1083"/>
+ <location filename="../../muse/confmport.cpp" line="1087"/>
<source>I</source>
<translation>I - Vstup</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1084"/>
+ <location filename="../../muse/confmport.cpp" line="1088"/>
<source>O</source>
<translation>O - Výstup</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1085"/>
+ <location filename="../../muse/confmport.cpp" line="1089"/>
<source>Instrument</source>
<translation>Nástroj</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1086"/>
+ <location filename="../../muse/confmport.cpp" line="1090"/>
<source>Device Name</source>
<translation>Název zařízení</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1087"/>
+ <location filename="../../muse/confmport.cpp" line="1091"/>
<source>In routes</source>
<translation>Tok vstupního signálu</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1088"/>
+ <location filename="../../muse/confmport.cpp" line="1092"/>
<source>Out routes</source>
<translation>Tok výstupního signálu</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1089"/>
+ <location filename="../../muse/confmport.cpp" line="1093"/>
<source>Def in ch</source>
<translation>Výchozí vstupní kanál</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1090"/>
+ <location filename="../../muse/confmport.cpp" line="1094"/>
<source>Def out ch</source>
<translation>Výchozí výstupní kanál</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1091"/>
+ <location filename="../../muse/confmport.cpp" line="1095"/>
<source>State</source>
<translation>Stav</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1171"/>
+ <location filename="../../muse/confmport.cpp" line="1175"/>
<source>&lt;unknown&gt;</source>
<translation>&lt;neznámý&gt;</translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1255"/>
- <location filename="../../muse/confmport.cpp" line="1317"/>
+ <location filename="../../muse/confmport.cpp" line="1259"/>
+ <location filename="../../muse/confmport.cpp" line="1321"/>
<source>&lt;none&gt;</source>
<translation>&lt;Žádný&gt;</translation>
</message>
@@ -9304,7 +9436,7 @@ Použít nastavení pro seřízení?</translation>
</message>
<message>
<location filename="../../muse/app.cpp" line="444"/>
- <location filename="../../muse/app.cpp" line="697"/>
+ <location filename="../../muse/app.cpp" line="695"/>
<source>Panic</source>
<translation>Nouzové zastavení</translation>
</message>
@@ -9342,8 +9474,8 @@ Použít nastavení pro seřízení?</translation>
</message>
<message>
<location filename="../../muse/app.cpp" line="465"/>
- <location filename="../../muse/app.cpp" line="1437"/>
- <location filename="../../muse/app.cpp" line="2666"/>
+ <location filename="../../muse/app.cpp" line="1435"/>
+ <location filename="../../muse/app.cpp" line="2664"/>
<source>&amp;Save</source>
<translation>&amp;Uložit</translation>
</message>
@@ -9522,308 +9654,308 @@ Také můžete v nabídce Soubor vybrat příkaz Uložit.</translation>
<translation>Smazat data automatizace</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="536"/>
+ <location filename="../../muse/app.cpp" line="534"/>
<source>Cascade</source>
<translation>Překrývat</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="537"/>
+ <location filename="../../muse/app.cpp" line="535"/>
<source>Tile</source>
<translation>Uspořádat jedno vedle druhého</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="538"/>
+ <location filename="../../muse/app.cpp" line="536"/>
<source>In rows</source>
<translation>V řádcích</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="539"/>
+ <location filename="../../muse/app.cpp" line="537"/>
<source>In columns</source>
<translation>Ve sloupcích</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="543"/>
+ <location filename="../../muse/app.cpp" line="541"/>
<source>Global Settings</source>
<translation>Celková nastavení</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="544"/>
+ <location filename="../../muse/app.cpp" line="542"/>
<source>Configure Shortcuts</source>
<translation>Nastavit klávesové zkratky</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="545"/>
+ <location filename="../../muse/app.cpp" line="543"/>
<source>Follow Song</source>
<translation>Sledovat píseň</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="546"/>
+ <location filename="../../muse/app.cpp" line="544"/>
<source>Don&apos;t Follow Song</source>
<translation>Nesledovat píseň</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="548"/>
+ <location filename="../../muse/app.cpp" line="546"/>
<source>Follow Page</source>
<translation>Sledovat píseň na stranách</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="551"/>
+ <location filename="../../muse/app.cpp" line="549"/>
<source>Follow Continuous</source>
<translation>Sledovat píseň stále</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="554"/>
+ <location filename="../../muse/app.cpp" line="552"/>
<source>Metronome</source>
<translation>Metronom</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="555"/>
+ <location filename="../../muse/app.cpp" line="553"/>
<source>Midi Sync</source>
<translation>Midi Sync</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="556"/>
+ <location filename="../../muse/app.cpp" line="554"/>
<source>Midi File Import/Export</source>
<translation>Zavedení/Vyvedení souboru MIDI</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="557"/>
+ <location filename="../../muse/app.cpp" line="555"/>
<source>Appearance Settings</source>
<translation>Nastavení vzhledu</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="558"/>
+ <location filename="../../muse/app.cpp" line="556"/>
<source>Midi Ports / Soft Synth</source>
<translation>Přípojky MIDI/Softwarové syntetizátory</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="561"/>
+ <location filename="../../muse/app.cpp" line="559"/>
<source>&amp;Manual</source>
<translation>&amp;Příručka</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="562"/>
+ <location filename="../../muse/app.cpp" line="560"/>
<source>&amp;MusE Homepage</source>
<translation>Stránky &amp;MusE</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="563"/>
+ <location filename="../../muse/app.cpp" line="561"/>
<source>&amp;Report Bug...</source>
<translation>&amp;Nahlásit chybu...</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="564"/>
+ <location filename="../../muse/app.cpp" line="562"/>
<source>&amp;About MusE</source>
<translation>&amp;O programu MusE</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="664"/>
+ <location filename="../../muse/app.cpp" line="662"/>
<source>Song Position</source>
<translation>Poloha písně</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="671"/>
+ <location filename="../../muse/app.cpp" line="669"/>
<source>Tempo</source>
<translation>Tempo</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="677"/>
+ <location filename="../../muse/app.cpp" line="675"/>
<source>Signature</source>
<translation>Taktové označení</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="682"/>
+ <location filename="../../muse/app.cpp" line="680"/>
<source>File Buttons</source>
<translation>Tlačítka pro soubor</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="689"/>
+ <location filename="../../muse/app.cpp" line="687"/>
<source>Undo/Redo</source>
<translation>Zpět/Znovu</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="693"/>
+ <location filename="../../muse/app.cpp" line="691"/>
<source>Transport</source>
<translation>Přesun</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="727"/>
+ <location filename="../../muse/app.cpp" line="725"/>
<source>&amp;File</source>
<translation>&amp;Soubor</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="756"/>
+ <location filename="../../muse/app.cpp" line="754"/>
<source>&amp;View</source>
<translation>&amp;Pohled</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="775"/>
+ <location filename="../../muse/app.cpp" line="773"/>
<source>&amp;Midi</source>
<translation>&amp;MIDI</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="800"/>
+ <location filename="../../muse/app.cpp" line="798"/>
<source>&amp;Audio</source>
<translation>&amp;Zvuk</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="814"/>
+ <location filename="../../muse/app.cpp" line="812"/>
<source>A&amp;utomation</source>
<translation>A&amp;utomatizace</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="827"/>
+ <location filename="../../muse/app.cpp" line="825"/>
<source>&amp;Windows</source>
<translation>&amp;Okna</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="840"/>
+ <location filename="../../muse/app.cpp" line="838"/>
<source>MusE Se&amp;ttings</source>
<translation>Nas&amp;tavení MusE</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="863"/>
+ <location filename="../../muse/app.cpp" line="861"/>
<source>&amp;Help</source>
<translation>&amp;Nápověda</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="874"/>
+ <location filename="../../muse/app.cpp" line="872"/>
<source>About &amp;Qt</source>
<translation>O &amp;Qt</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1139"/>
+ <location filename="../../muse/app.cpp" line="1137"/>
<source>Cannot read template</source>
<translation>Nelze přečíst předlohu</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1165"/>
+ <location filename="../../muse/app.cpp" line="1163"/>
<source>File open error</source>
<translation>Chyba při otevírání souboru</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1178"/>
+ <location filename="../../muse/app.cpp" line="1176"/>
<source>File read error</source>
<translation>Chyba při čtení souboru</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1190"/>
+ <location filename="../../muse/app.cpp" line="1188"/>
<source>Unknown File Format: %1</source>
<translation>Neznámý formát souboru: %1</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1301"/>
- <location filename="../../muse/app.cpp" line="1698"/>
- <location filename="../../muse/app.cpp" line="2612"/>
+ <location filename="../../muse/app.cpp" line="1299"/>
+ <location filename="../../muse/app.cpp" line="1696"/>
+ <location filename="../../muse/app.cpp" line="2610"/>
<source>MusE: Song: %1</source>
<translation>MusE: Píseň: %1</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1336"/>
+ <location filename="../../muse/app.cpp" line="1334"/>
<source>MusE: load project</source>
<translation>MusE: Nahrát projekt</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1351"/>
+ <location filename="../../muse/app.cpp" line="1349"/>
<source>MusE: load template</source>
<translation>MusE: Nahrát předlohu</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1397"/>
+ <location filename="../../muse/app.cpp" line="1395"/>
<source>MusE: Write File failed</source>
<translation>MusE: Zápis souboru se nezdařil</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1435"/>
+ <location filename="../../muse/app.cpp" line="1433"/>
<source>The current Project contains unsaved data
Save Current Project?</source>
<translation>Nynější projekt obsahuje neuložená data.
Uložit nynější projekt?</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1437"/>
- <location filename="../../muse/app.cpp" line="2666"/>
+ <location filename="../../muse/app.cpp" line="1435"/>
+ <location filename="../../muse/app.cpp" line="2664"/>
<source>S&amp;kip</source>
<translation>&amp;Přeskočit</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1437"/>
+ <location filename="../../muse/app.cpp" line="1435"/>
<source>&amp;Cancel</source>
<translation>Z&amp;rušit</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1679"/>
+ <location filename="../../muse/app.cpp" line="1677"/>
<source>MusE: Save As</source>
<translation>MusE: Uložit jako</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1745"/>
- <location filename="../../muse/app.cpp" line="1905"/>
+ <location filename="../../muse/app.cpp" line="1743"/>
+ <location filename="../../muse/app.cpp" line="1903"/>
<source>Nothing to edit</source>
<translation>Není co upravovat</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2401"/>
- <location filename="../../muse/app.cpp" line="2411"/>
- <location filename="../../muse/app.cpp" line="2442"/>
- <location filename="../../muse/app.cpp" line="2476"/>
- <location filename="../../muse/app.cpp" line="2484"/>
+ <location filename="../../muse/app.cpp" line="2399"/>
+ <location filename="../../muse/app.cpp" line="2409"/>
+ <location filename="../../muse/app.cpp" line="2440"/>
+ <location filename="../../muse/app.cpp" line="2474"/>
+ <location filename="../../muse/app.cpp" line="2482"/>
<source>MusE: Bounce to Track</source>
<translation>MusE: Odmíchat na stopu</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2402"/>
+ <location filename="../../muse/app.cpp" line="2400"/>
<source>No wave tracks found</source>
<translation>Nebyly nalezeny žádné stopy Wave</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2412"/>
- <location filename="../../muse/app.cpp" line="2517"/>
+ <location filename="../../muse/app.cpp" line="2410"/>
+ <location filename="../../muse/app.cpp" line="2515"/>
<source>No audio output tracks found</source>
<translation>Nebyly nalezeny žádné zvukové výstupní stopy</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2443"/>
+ <location filename="../../muse/app.cpp" line="2441"/>
<source>Select one audio output track,
and one target wave track</source>
<translation>Vyberte jednu zvukovou výstupní stopu
a jednu cílovou stopu Wave</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2477"/>
+ <location filename="../../muse/app.cpp" line="2475"/>
<source>Select one target wave track</source>
<translation>Vyberte jednu cílovou stopu Wave</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2485"/>
+ <location filename="../../muse/app.cpp" line="2483"/>
<source>Select one target wave track,
and one audio output track</source>
<translation>Vyberte jednu cílovou stopu Wave
a jednu zvukovou výstupní stopu</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2516"/>
- <location filename="../../muse/app.cpp" line="2541"/>
+ <location filename="../../muse/app.cpp" line="2514"/>
+ <location filename="../../muse/app.cpp" line="2539"/>
<source>MusE: Bounce to File</source>
<translation>MusE: Odmíchat do souboru</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2542"/>
+ <location filename="../../muse/app.cpp" line="2540"/>
<source>Select one audio output track</source>
<translation>Vyberte jednu zvukovou výstupní stopu</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2580"/>
+ <location filename="../../muse/app.cpp" line="2578"/>
<source>MusE: Bounce</source>
<translation>MusE: Odmíchat</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2581"/>
+ <location filename="../../muse/app.cpp" line="2579"/>
<source>set left/right marker for bounce range</source>
<translation>Nastavit levou/pravou značku pro oblast odmíchání</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2663"/>
+ <location filename="../../muse/app.cpp" line="2661"/>
<source>The current Project contains unsaved data
Load overwrites current Project:
Save Current Project?</source>
@@ -9832,12 +9964,32 @@ Nahrání přepíše nynější projekt:
Uložit nynější projekt?</translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2666"/>
+ <location filename="../../muse/app.cpp" line="2664"/>
<location filename="../../muse/importmidi.cpp" line="83"/>
<source>&amp;Abort</source>
<translation>&amp;Zrušit</translation>
</message>
<message>
+ <location filename="../../muse/app.cpp" line="2778"/>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation>Toto smaže všechna data automatizace
+u všech zvukových stop!
+Pokračovat?</translation>
+ </message>
+ <message>
+ <location filename="../../muse/app.cpp" line="2804"/>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation>Toto udělá v nynější poloze snímek
+automatizace všech ovladačů na všech
+zvukových stopách.
+Pokračovat?</translation>
+ </message>
+ <message>
<location filename="../../muse/exportmidi.cpp" line="139"/>
<source>MusE: Export Midi</source>
<translation>MusE: Vyvést MIDI</translation>
@@ -10098,8 +10250,13 @@ Files:</source>
<translation>Název části: %1
Soubory:</translation>
</message>
+ <message>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="915"/>
+ <source>Remove selected</source>
+ <translation>Odstranit vybrané</translation>
+ </message>
<message numerus="yes">
- <location filename="../../muse/arranger/pcanvas.cpp" line="2911"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2939"/>
<source>%n part(s) out of %1 could not be pasted.
Likely the selected track is the wrong type.</source>
<translation>
@@ -10112,7 +10269,7 @@ Pravděpodobně má vybraná stopa nesprávný typ.</numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../../muse/arranger/pcanvas.cpp" line="2912"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2940"/>
<source>%n part(s) could not be pasted.
Likely the selected track is the wrong type.</source>
<translation>
@@ -10125,32 +10282,32 @@ Pravděpodobně má vybraná stopa nesprávný typ.</numerusform>
</translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2937"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2965"/>
<source>Cannot paste: multiple tracks selected</source>
<translation>Nelze vložit: vybráno více stop</translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2946"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2974"/>
<source>Cannot paste: no track selected</source>
<translation>Nelze vložit: nevybrána žádná stopa</translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2966"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2994"/>
<source>Can only paste to midi/drum track</source>
<translation>Vložení možné jen do stopy MIDI/Bicí</translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2977"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="3005"/>
<source>Can only paste to wave track</source>
<translation>Vložení možné jen do stopy Wave</translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2988"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="3016"/>
<source>Can only paste to midi or wave track</source>
<translation>Vložení možné jen do stopy MIDI nebo Wave</translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2996"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="3024"/>
<source>Cannot paste: wrong data type</source>
<translation>Nelze vložit: Nesprávný datový typ</translation>
</message>
@@ -10399,152 +10556,157 @@ Pravděpodobně má vybraná stopa nesprávný typ.</numerusform>
<context>
<name>MusEGui::PluginDialog</name>
<message>
- <location filename="../../muse/plugin.cpp" line="2846"/>
+ <location filename="../../muse/plugin.cpp" line="2825"/>
<source>MusE: select plugin</source>
<translation>MusE: Vybrat přídavný modul</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2859"/>
+ <location filename="../../muse/plugin.cpp" line="2838"/>
<source>Type</source>
<translation>Typ</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2860"/>
+ <location filename="../../muse/plugin.cpp" line="2839"/>
<source>Lib</source>
<translation>Lib</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2861"/>
+ <location filename="../../muse/plugin.cpp" line="2840"/>
<source>Label</source>
<translation>Štítek</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2862"/>
+ <location filename="../../muse/plugin.cpp" line="2841"/>
<source>Name</source>
<translation>Název</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2863"/>
+ <location filename="../../muse/plugin.cpp" line="2842"/>
<source>AI</source>
<translation>Al</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2864"/>
+ <location filename="../../muse/plugin.cpp" line="2843"/>
<source>AO</source>
<translation>AO</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2865"/>
+ <location filename="../../muse/plugin.cpp" line="2844"/>
<source>CI</source>
<translation>Cl</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2866"/>
+ <location filename="../../muse/plugin.cpp" line="2845"/>
<source>CO</source>
<translation>CO</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2867"/>
+ <location filename="../../muse/plugin.cpp" line="2846"/>
<source>IP</source>
<translation>IP</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2868"/>
+ <location filename="../../muse/plugin.cpp" line="2847"/>
<source>id</source>
<translation>ID</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2869"/>
+ <location filename="../../muse/plugin.cpp" line="2848"/>
<source>Maker</source>
<translation>Výrobce</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2870"/>
+ <location filename="../../muse/plugin.cpp" line="2849"/>
<source>Copyright</source>
<translation>Autorské právo</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2874"/>
+ <location filename="../../muse/plugin.cpp" line="2853"/>
<source>Audio inputs</source>
<translation>Vstupy zvuku</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2875"/>
+ <location filename="../../muse/plugin.cpp" line="2854"/>
<source>Audio outputs</source>
<translation>Výstupy zvuku</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2876"/>
+ <location filename="../../muse/plugin.cpp" line="2855"/>
<source>Control inputs</source>
<translation>Vstupy ovládání</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2877"/>
+ <location filename="../../muse/plugin.cpp" line="2856"/>
<source>Control outputs</source>
<translation>Výstupy ovládání</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2878"/>
+ <location filename="../../muse/plugin.cpp" line="2857"/>
<source>In-place capable</source>
<translation>Schopen v místě</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2879"/>
+ <location filename="../../muse/plugin.cpp" line="2858"/>
<source>ID number</source>
<translation>Číslo ID</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2899"/>
+ <location filename="../../muse/plugin.cpp" line="2878"/>
<source>Ok</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2901"/>
+ <location filename="../../muse/plugin.cpp" line="2880"/>
<source>Cancel</source>
<translation>Zrušit</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2917"/>
+ <location filename="../../muse/plugin.cpp" line="2889"/>
+ <source>Show plugs:</source>
+ <translation>Ukázat přídavné moduly:</translation>
+ </message>
+ <message>
+ <location filename="../../muse/plugin.cpp" line="2896"/>
<source>Mono and Stereo</source>
<translation>Mono a stereo</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2922"/>
+ <location filename="../../muse/plugin.cpp" line="2901"/>
<source>Stereo</source>
<translation>Stereo</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2927"/>
+ <location filename="../../muse/plugin.cpp" line="2906"/>
<source>Mono</source>
<translation>Mono</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2932"/>
+ <location filename="../../muse/plugin.cpp" line="2911"/>
<source>Show All</source>
<translation>Ukázat vše</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2945"/>
+ <location filename="../../muse/plugin.cpp" line="2924"/>
<source>Select which types of plugins should be visible in the list.&lt;br&gt;Note that using mono plugins on stereo tracks is not a problem, two will be used in parallel.&lt;br&gt;Also beware that the &apos;all&apos; alternative includes plugins that may not be useful in an effect rack.</source>
<translation>Vyberte, které typy přídavných modulů mají být v seznamu viditelné.&lt;br&gt;Uvědomte si, že použití přídavných modulů monona stopy stereo není problém, dva budou použity souběžně.&lt;br&gt;Dejte si pozor na to, že alternativa &apos;vše&apos; zahrnuje přídavné moduly, které v přihrádce s efekty nemusí být užitečné.</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2957"/>
+ <location filename="../../muse/plugin.cpp" line="2936"/>
<source>Search in &apos;Label&apos; and &apos;Name&apos;:</source>
<translation>Hledat ve &apos;Štítek&apos; a &apos;Název&apos;:</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3120"/>
+ <location filename="../../muse/plugin.cpp" line="3099"/>
<source>dssi synth</source>
<translation>syntetizátor dssi</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3122"/>
+ <location filename="../../muse/plugin.cpp" line="3101"/>
<source>dssi effect</source>
<translation>efekt dssi</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3124"/>
+ <location filename="../../muse/plugin.cpp" line="3103"/>
<source>ladspa</source>
<translation>ladspa</translation>
</message>
@@ -10552,38 +10714,38 @@ Pravděpodobně má vybraná stopa nesprávný typ.</numerusform>
<context>
<name>MusEGui::PluginGui</name>
<message>
- <location filename="../../muse/plugin.cpp" line="3179"/>
+ <location filename="../../muse/plugin.cpp" line="3158"/>
<source>File Buttons</source>
<translation>Tlačítka pro soubor</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3181"/>
+ <location filename="../../muse/plugin.cpp" line="3160"/>
<source>Load Preset</source>
<translation>Nahrát přednastavení</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3185"/>
+ <location filename="../../muse/plugin.cpp" line="3164"/>
<source>Save Preset</source>
<translation>Uložit přednastavení</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3191"/>
- <location filename="../../muse/plugin.cpp" line="3194"/>
+ <location filename="../../muse/plugin.cpp" line="3170"/>
+ <location filename="../../muse/plugin.cpp" line="3173"/>
<source>bypass plugin</source>
<translation>Přeskočit přídavný modul pro tok signálu</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3692"/>
+ <location filename="../../muse/plugin.cpp" line="3678"/>
<source>MusE: load preset</source>
<translation>MusE: Nahrát přednastavení</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3717"/>
+ <location filename="../../muse/plugin.cpp" line="3703"/>
<source>Error reading preset. Might not be right type for this plugin</source>
<translation>Chyba při čtení přednastavení. Nemusí to být správný typ pro tento přídavný modul</translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3756"/>
+ <location filename="../../muse/plugin.cpp" line="3742"/>
<source>MusE: save preset</source>
<translation>MusE: Uložit přednastavení</translation>
</message>
@@ -11019,7 +11181,7 @@ zvolený název není jedinečný</translation>
<context>
<name>MusEGui::Strip</name>
<message>
- <location filename="../../muse/mixer/strip.cpp" line="313"/>
+ <location filename="../../muse/mixer/strip.cpp" line="326"/>
<source>Remove track?</source>
<translation>Odstranit stopu?</translation>
</message>
@@ -11027,143 +11189,168 @@ zvolený název není jedinečný</translation>
<context>
<name>MusEGui::TList</name>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="408"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="413"/>
<source>&lt;none&gt;</source>
<translation>&lt;Žádný&gt;</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="429"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="434"/>
<source>visible</source>
<translation>Viditelný</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="438"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="443"/>
<source>no clef</source>
<translation>Žádný klíč</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="440"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="445"/>
<source>Treble</source>
<translation>Houslový klíč</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="442"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="447"/>
<source>Bass</source>
<translation>Basový klíč</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="444"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="449"/>
<source>Grand</source>
<translation>Oba klíče</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="473"/>
- <location filename="../../muse/arranger/tlist.cpp" line="887"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="478"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="892"/>
<source>off</source>
<translation>Vypnuto</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="482"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="487"/>
<source>&lt;unknown&gt;</source>
<translation>&lt;neznámý&gt;</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="574"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="579"/>
<source>MusE: bad trackname</source>
<translation>MusE: Špatný název stopy</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="575"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="580"/>
<source>please choose a unique track name</source>
<translation>Vyberte, prosím, jedinečný název pro stopu</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1005"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1010"/>
<source>Unused Devices</source>
<translation>Nepoužívaná zařízení</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1095"/>
- <location filename="../../muse/arranger/tlist.cpp" line="2371"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1100"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2525"/>
<source>Update drummap?</source>
<translation>Obnovit rozložení bicích?</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1096"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1101"/>
<source>Do you want to use same port for all instruments in the drummap?</source>
<translation>Chcete pro všechny nástroje v rozložení bicích použít stejnou přípojku?</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1097"/>
- <location filename="../../muse/arranger/tlist.cpp" line="2373"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1102"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2527"/>
<source>&amp;Yes</source>
<translation>&amp;Ano</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1097"/>
- <location filename="../../muse/arranger/tlist.cpp" line="2373"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1102"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2527"/>
<source>&amp;No</source>
<translation>&amp;Ne</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1163"/>
- <location filename="../../muse/arranger/tlist.cpp" line="1204"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1168"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1209"/>
<source>show gui</source>
<translation>Ukázat uživatelské rozhraní</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1168"/>
- <location filename="../../muse/arranger/tlist.cpp" line="1209"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1173"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1214"/>
<source>show native gui</source>
<translation>Ukázat původní rozhraní</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1570"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1549"/>
+ <source>Midi control</source>
+ <translation>Ovládání MIDI</translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1553"/>
+ <source>Assign</source>
+ <translation>Přiřadit</translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1566"/>
+ <source>Clear</source>
+ <translation>Smazat</translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1685"/>
<source>Treble clef</source>
<translation>Houslový klíč</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1571"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1686"/>
<source>Bass clef</source>
<translation>Basový klíč</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1572"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1687"/>
<source>Grand Staff</source>
<translation>Oba klíče</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1602"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1717"/>
<source>Viewable automation</source>
<translation>Viditelná automatizace</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1735"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1733"/>
+ <source>Internal</source>
+ <translation>Vnitřní</translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1756"/>
+ <source>Synth</source>
+ <translation>Syntetizátor</translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1889"/>
<source>Delete Track</source>
<translation>Smazat stopu</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1736"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1890"/>
<source>Track Comment</source>
<translation>Poznámka ke stopě</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1739"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1893"/>
<source>Insert Track</source>
<translation>Vložit stopu</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="2321"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2475"/>
<source>Midi</source>
<translation>MIDI</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="2322"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2476"/>
<source>Drum</source>
<translation>Bicí</translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="2372"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2526"/>
<source>Do you want to use same port and channel for all instruments in the drummap?</source>
<translation>Chcete pro všechny nástroje v rozložení bicích použít stejnou přípojku a týž kanál?</translation>
</message>
@@ -12109,7 +12296,7 @@ Vytvořit jej?</translation>
<translation>Vytvoření adresáře se nezdařilo</translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="465"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="490"/>
<source>File
%1
exists. Overwrite?</source>
@@ -12118,12 +12305,12 @@ exists. Overwrite?</source>
existuje. Přepsat?</translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="479"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="504"/>
<source>MusE: write</source>
<translation>MusE: Zapsat</translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="500"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="525"/>
<source>Open File
%1
failed: %2</source>
@@ -12132,7 +12319,7 @@ failed: %2</source>
se nepodařilo otevřít: %2</translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="501"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="526"/>
<source>MusE: Open File</source>
<translation>MusE: Otevřít soubor</translation>
</message>
@@ -13363,258 +13550,258 @@ Robert Jonsson
<translation>Doba poklesu [ms]</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="91"/>
- <location filename="../plugins/2142.ui" line="132"/>
+ <location filename="../plugins/2142.ui" line="94"/>
+ <location filename="../plugins/2142.ui" line="138"/>
<source>dB</source>
<translation>dB</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="101"/>
+ <location filename="../plugins/2142.ui" line="104"/>
<source>Dry Level [dB]</source>
<translation>Síla hlasitosti nezměněného signálu [dB]</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="142"/>
+ <location filename="../plugins/2142.ui" line="148"/>
<source>Wet Level [dB]</source>
<translation>Síla hlasitosti změněného signálu [dB]</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="214"/>
+ <location filename="../plugins/2142.ui" line="220"/>
<source>Preset:</source>
<translation>Přednastavení:</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="233"/>
+ <location filename="../plugins/2142.ui" line="239"/>
<source>AfterBurn</source>
<translation>AfterBurn</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="238"/>
+ <location filename="../plugins/2142.ui" line="244"/>
<source>AfterBurn (Long)</source>
<translation>AfterBurn (dlouhý)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="243"/>
+ <location filename="../plugins/2142.ui" line="249"/>
<source>Ambience</source>
<translation>Atmosféra</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="248"/>
+ <location filename="../plugins/2142.ui" line="254"/>
<source>Ambience (Thick)</source>
<translation>Atmosféra (silná)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="253"/>
+ <location filename="../plugins/2142.ui" line="259"/>
<source>Ambience (Thick) - HD</source>
<translation>Atmosféra (silná) - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="258"/>
+ <location filename="../plugins/2142.ui" line="264"/>
<source>Cathedral</source>
<translation>Katedrála</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="263"/>
+ <location filename="../plugins/2142.ui" line="269"/>
<source>Cathedral - HD</source>
<translation>Katedrála - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="268"/>
+ <location filename="../plugins/2142.ui" line="274"/>
<source>Drum Chamber</source>
<translation>Síň bicích</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="273"/>
+ <location filename="../plugins/2142.ui" line="279"/>
<source>Garage</source>
<translation>Garáž</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="278"/>
+ <location filename="../plugins/2142.ui" line="284"/>
<source>Garage (Bright)</source>
<translation>Garáž (jasná)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="283"/>
+ <location filename="../plugins/2142.ui" line="289"/>
<source>Gymnasium</source>
<translation>Sportovní hala</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="288"/>
+ <location filename="../plugins/2142.ui" line="294"/>
<source>Gymnasium (Bright)</source>
<translation>Sportovní hala (jasná)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="293"/>
+ <location filename="../plugins/2142.ui" line="299"/>
<source>Gymnasium (Bright) - HD</source>
<translation>Sportovní hala (jasná) - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="298"/>
+ <location filename="../plugins/2142.ui" line="304"/>
<source>Hall (Small)</source>
<translation>Hala (malá)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="303"/>
+ <location filename="../plugins/2142.ui" line="309"/>
<source>Hall (Medium)</source>
<translation>Hala (střední)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="308"/>
+ <location filename="../plugins/2142.ui" line="314"/>
<source>Hall (Large)</source>
<translation>Hala (velká)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="313"/>
+ <location filename="../plugins/2142.ui" line="319"/>
<source>Hall (Large) - HD</source>
<translation>Hala (velká) - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="318"/>
+ <location filename="../plugins/2142.ui" line="324"/>
<source>Plate (Small)</source>
<translation>Deska (malá)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="323"/>
+ <location filename="../plugins/2142.ui" line="329"/>
<source>Plate (Medium)</source>
<translation>Deska (střední)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="328"/>
+ <location filename="../plugins/2142.ui" line="334"/>
<source>Plate (Large)</source>
<translation>Deska (velká)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="333"/>
+ <location filename="../plugins/2142.ui" line="339"/>
<source>Plate (Large) - HD</source>
<translation>Deska (velká) - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="338"/>
+ <location filename="../plugins/2142.ui" line="344"/>
<source>Pulse Chamber</source>
<translation>Síň rytmu</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="343"/>
+ <location filename="../plugins/2142.ui" line="349"/>
<source>Pulse Chamber (Reverse)</source>
<translation>Síň rytmu (obrácená)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="348"/>
+ <location filename="../plugins/2142.ui" line="354"/>
<source>Resonator (96 ms)</source>
<translation>Rezonátor (96 ms)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="353"/>
+ <location filename="../plugins/2142.ui" line="359"/>
<source>Resonator (152 ms)</source>
<translation>Rezonátor (152 ms)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="358"/>
+ <location filename="../plugins/2142.ui" line="364"/>
<source>Resonator (208 ms)</source>
<translation>Rezonátor (208 ms)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="363"/>
+ <location filename="../plugins/2142.ui" line="369"/>
<source>Room (Small)</source>
<translation>Pokoj (malý)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="368"/>
+ <location filename="../plugins/2142.ui" line="374"/>
<source>Room (Medium)</source>
<translation>Pokoj (střední)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="373"/>
+ <location filename="../plugins/2142.ui" line="379"/>
<source>Room (Large)</source>
<translation>Pokoj (velký)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="378"/>
+ <location filename="../plugins/2142.ui" line="384"/>
<source>Room (Large) - HD</source>
<translation>Pokoj (velký) - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="383"/>
+ <location filename="../plugins/2142.ui" line="389"/>
<source>Slap Chamber</source>
<translation>Síň plácnutí</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="388"/>
+ <location filename="../plugins/2142.ui" line="394"/>
<source>Slap Chamber - HD</source>
<translation>Síň plácnutí - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="393"/>
+ <location filename="../plugins/2142.ui" line="399"/>
<source>Slap Chamber (Bright)</source>
<translation>Síň plácnutí (jasná)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="398"/>
+ <location filename="../plugins/2142.ui" line="404"/>
<source>Slap Chamber (Bright) HD</source>
<translation>Síň plácnutí (jasná) HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="403"/>
+ <location filename="../plugins/2142.ui" line="409"/>
<source>Smooth Hall (Small)</source>
<translation>Klidná hala (malá)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="408"/>
+ <location filename="../plugins/2142.ui" line="414"/>
<source>Smooth Hall (Medium)</source>
<translation>Klidná hala (střední)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="413"/>
+ <location filename="../plugins/2142.ui" line="419"/>
<source>Smooth Hall (Large)</source>
<translation>Klidná hala (velká)</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="418"/>
+ <location filename="../plugins/2142.ui" line="424"/>
<source>Smooth Hall (Large) - HD</source>
<translation>Klidná hala (velká) - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="423"/>
+ <location filename="../plugins/2142.ui" line="429"/>
<source>Vocal Plate</source>
<translation>Hlasitá deska</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="428"/>
+ <location filename="../plugins/2142.ui" line="434"/>
<source>Vocal Plate - HD</source>
<translation>Hlasitá deska - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="433"/>
+ <location filename="../plugins/2142.ui" line="439"/>
<source>Warble Chamber</source>
<translation>Síň cvrlikání</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="438"/>
+ <location filename="../plugins/2142.ui" line="444"/>
<source>Warehoouse</source>
<translation>Skladiště</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="443"/>
+ <location filename="../plugins/2142.ui" line="449"/>
<source>Warehouse - HD</source>
<translation>Skladiště - HD</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="451"/>
+ <location filename="../plugins/2142.ui" line="457"/>
<source>Comb Filters</source>
<translation>Sdružené filtry</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="458"/>
+ <location filename="../plugins/2142.ui" line="464"/>
<source>Allpass Filters</source>
<translation>Všeprůchozí filtry</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="465"/>
+ <location filename="../plugins/2142.ui" line="471"/>
<source>Bandpass Filters</source>
<translation>Pásmové filtry</translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="472"/>
+ <location filename="../plugins/2142.ui" line="478"/>
<source>Enhanced Stereo</source>
<translation>Rozšířené stereo</translation>
</message>
diff --git a/muse2/share/locale/muse_de.ts b/muse2/share/locale/muse_de.ts
index 1ade0db6..6347b66d 100644
--- a/muse2/share/locale/muse_de.ts
+++ b/muse2/share/locale/muse_de.ts
@@ -89,18 +89,34 @@
<translation>KanalMaske=&quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="+503"/>
+ <location filename="../../muse/midiseq.cpp" line="+510"/>
<source>Bad timing</source>
- <translation type="unfinished"></translation>
+ <translation>Schlechter Taktgeber</translation>
</message>
<message>
<location line="+1"/>
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
+Also please check console output for any further error messages.
+ </source>
+ <translation>Die Frequenz des Taktgebers ist %1Hz; das ist unter dem empfohlenen Minimum von 500Hz!
+Dies könnte zu hörbaren Timingproblemen für MIDI führen.
+Bitte sehen sie in den FAQ unter http://muse-sequencer.org nach Lösungen.
+Bitte überprüfen sie außerdem die Konsolenmeldungen auf weitere Fehlermeldungen.
+</translation>
+ </message>
+ <message>
+ <source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
+This could lead to audible timing problems for MIDI.
+Please see the FAQ on http://muse-sequencer.org for remedies.
Also please check console output for any further error messages
</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Die Frequenz des Taktgebers ist %1Hz; das ist unter dem empfohlenen Minimum von 500Hz!
+Dies könnte zu hörbaren Timingproblemen für MIDI führen.
+Bitte sehen sie in den FAQ unter http://muse-sequencer.org nach Lösungen.
+Bitte überprüfen sie außerdem die Konsolenmeldungen auf weitere Fehlermeldungen.
+</translation>
</message>
</context>
<context>
@@ -111,18 +127,34 @@ Also please check console output for any further error messages
<translation>Projektinformation</translation>
</message>
<message>
- <location line="+37"/>
<source>Version 2 pre-alpha</source>
- <translation>Version 2 pre-alpha</translation>
+ <translation type="obsolete">Version 2 pre-alpha</translation>
</message>
<message>
- <location line="+10"/>
<source>(C) Copyright 1999-2010 Werner Schweer and others.
See http://www.muse-sequencer.org for new versions and
more information.
Published under the GNU Public License</source>
- <translation>(C) Copyright 1999-2010 Werner Schweer und andere.
+ <translation type="obsolete">(C) Copyright 1999-2010 Werner Schweer und andere.
+Siehe http://www.muse-sequencer.org für neue Versionen und
+mehr Informationen.
+
+Veröffentlicht unter der GNU Public License</translation>
+ </message>
+ <message>
+ <location line="+37"/>
+ <source>Version 2</source>
+ <translation>Version 2</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
+See http://www.muse-sequencer.org for new versions and
+more information.
+
+Published under the GNU Public License</source>
+ <translation>(C) Copyright 1999-2012 Werner Schweer und andere.
Siehe http://www.muse-sequencer.org für neue Versionen und
mehr Informationen.
@@ -314,7 +346,7 @@ Veröffentlicht unter der GNU Public License</translation>
<message>
<location line="+8"/>
<source>May require restarting MusE for best results</source>
- <translation type="unfinished"></translation>
+ <translation>Könnte einen Neustart von MusE erfordern für optimale Ergebnisse</translation>
</message>
<message>
<location line="+72"/>
@@ -630,7 +662,7 @@ Veröffentlicht unter der GNU Public License</translation>
<message>
<location line="+11"/>
<source>Samplerate</source>
- <translation type="unfinished"></translation>
+ <translation>Sample-Rate</translation>
</message>
<message>
<location line="+11"/>
@@ -4303,33 +4335,34 @@ den Fokus zur jeweilgen Canvas zurückgeben</translation>
<message>
<location line="+202"/>
<source>Choose start song or template</source>
- <translation type="unfinished"></translation>
+ <translation>Wählen Sie ein Lied oder eine Vorlage für den Start</translation>
</message>
<message>
<location line="+10"/>
<source>Reset to default</source>
- <translation type="unfinished"></translation>
+ <translation>Auf Standardwerte zurücksetzen</translation>
</message>
<message>
<location line="+34"/>
<source>start with template</source>
- <translation type="unfinished"></translation>
+ <translation>mit Vorlage starten</translation>
</message>
<message>
<location line="+43"/>
<source>Start template or song:</source>
- <translation type="unfinished"></translation>
+ <translation>Mit Vorlage oder Lied starten:</translation>
</message>
<message>
<location line="+10"/>
<source>Read MIDI Ports configuration from file,
or else automatically configure</source>
- <translation type="unfinished"></translation>
+ <translation>Lese MIDI-Port-Konfiguration von der Datei,
+oder konfiguriere sonst automatisch</translation>
</message>
<message>
<location line="+4"/>
<source>Read MIDI Ports configuration</source>
- <translation type="unfinished"></translation>
+ <translation>Lese MIDI-Port-Konfiguration</translation>
</message>
<message>
<location line="+98"/>
@@ -4813,6 +4846,84 @@ einen höheren Wert.</translation>
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="+14"/>
+ <source>Midi control</source>
+ <translation>MIDI-Steuerung</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Port:</source>
+ <translation>Port:</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Channel:</source>
+ <translation>Channel:</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Control type:</source>
+ <translation>Controller-Typ:</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Control7</source>
+ <translation>Controller7</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Control14</source>
+ <translation>Controller14</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN</source>
+ <translation>RPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN</source>
+ <translation>NRPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN14</source>
+ <translation>RPN14</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN14</source>
+ <translation>NRPN14</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Pitch</source>
+ <translation>Pitch-Bend</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Program</source>
+ <translation>Programm</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Hi:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Lo:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Learn</source>
+ <translation>Lernen</translation>
+ </message>
+</context>
+<context>
<name>MidiFilterConfigBase</name>
<message>
<location filename="../../muse/mplugins/midifilter.ui" line="+20"/>
@@ -5572,7 +5683,7 @@ bis zum Senden des ersten Clocks.</translation>
<message>
<location line="+262"/>
<source>Bank Select MSB. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Bank MSB. Ctrl+Doppelklick für an/aus.</translation>
</message>
<message>
<location line="+31"/>
@@ -5587,7 +5698,7 @@ bis zum Senden des ersten Clocks.</translation>
<message>
<location line="+177"/>
<source>Bank Select LSB. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Bank LSB. Ctrl+Doppelklick für an/aus.</translation>
</message>
<message>
<location line="+31"/>
@@ -5676,18 +5787,18 @@ bis zum Senden des ersten Clocks.</translation>
<message>
<location line="+137"/>
<source>Program. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Programm. Ctrl+Doppelklick für an/aus.</translation>
</message>
<message>
<location line="+67"/>
<source>Volume. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Lautstärke. Ctrl+Doppelklick für an/aus.</translation>
</message>
<message>
<location line="+67"/>
<location line="+3"/>
<source>Change stereo position. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Stereo-Position. Ctrl+Doppelklick für an/aus.</translation>
</message>
<message>
<location line="-104"/>
@@ -6175,7 +6286,7 @@ bis zum Senden des ersten Clocks.</translation>
<context>
<name>MusECore::Song</name>
<message>
- <location filename="../../muse/song.cpp" line="+2274"/>
+ <location filename="../../muse/song.cpp" line="+2284"/>
<source>Jack shutdown!</source>
<translation>Jack heruntergefahren!</translation>
</message>
@@ -6215,13 +6326,13 @@ versuchen, Jack neu zu starten und klicken dann auf den &quot;Neustart&quot;-
Knopf.</translation>
</message>
<message>
- <location line="+172"/>
- <location line="+165"/>
+ <location line="+179"/>
+ <location line="+238"/>
<source>Automation:</source>
<translation>Automatisierung:</translation>
</message>
<message>
- <location line="-163"/>
+ <location line="-236"/>
<source>previous event</source>
<translation>vorheriges Ereignis</translation>
</message>
@@ -6232,34 +6343,49 @@ Knopf.</translation>
</message>
<message>
<location line="+9"/>
- <location line="+155"/>
+ <location line="+228"/>
<source>set event</source>
<translation>setze Ereignis</translation>
</message>
<message>
- <location line="-153"/>
- <location line="+155"/>
+ <location line="-226"/>
+ <location line="+228"/>
<source>add event</source>
<translation>füge Ereignis hinzu</translation>
</message>
<message>
- <location line="-151"/>
- <location line="+155"/>
+ <location line="-224"/>
+ <location line="+228"/>
<source>erase event</source>
<translation>lösche Ereignis</translation>
</message>
<message>
- <location line="-151"/>
+ <location line="-224"/>
<source>erase range</source>
- <translation>Lösche Bereich</translation>
+ <translation>lösche Bereich</translation>
</message>
<message>
<location line="+4"/>
<source>clear automation</source>
- <translation>Lösche Automatisierung</translation>
+ <translation>lösche Automatisierung</translation>
</message>
<message>
- <location line="+29"/>
+ <location line="+6"/>
+ <source>Midi control</source>
+ <translation>MIDI-Steuerung</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Assign</source>
+ <translation>Zuweisen</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Clear</source>
+ <translation>Löschen</translation>
+ </message>
+ <message>
+ <location line="+45"/>
<source>Clear all controller events?</source>
<translation>Alle Controller-Ereignisse löschen?</translation>
</message>
@@ -6274,7 +6400,19 @@ Knopf.</translation>
<translation>&amp;Abbrechen</translation>
</message>
<message>
- <location line="+767"/>
+ <location line="+267"/>
+ <source>MusE: Tempo list</source>
+ <translation>MusE: Tempo-Liste</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
+ <translation>Es wurden externe Tempoänderungen aufgezeichnet.
+Sollen sie in die Master-Tempoliste übernommen werden?</translation>
+ </message>
+ <message>
+ <location line="+592"/>
<source>MusE - external script failed</source>
<translation>MusE - externes Skript fehlgeschlagen</translation>
</message>
@@ -7005,7 +7143,7 @@ Um Sie zu übernehmen, starten Sie MusE bitte neu.
<context>
<name>MusEGui::AudioStrip</name>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="+687"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="+678"/>
<source>panorama</source>
<translation>Panorama</translation>
</message>
@@ -7020,7 +7158,7 @@ Um Sie zu übernehmen, starten Sie MusE bitte neu.
<translation>Pan</translation>
</message>
<message>
- <location line="+92"/>
+ <location line="+91"/>
<source>1/2 channel</source>
<translation>1/2 Kanäle</translation>
</message>
@@ -7040,7 +7178,7 @@ Um Sie zu übernehmen, starten Sie MusE bitte neu.
<translation>dB</translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+31"/>
<source>record</source>
<translation>Aufnahme</translation>
</message>
@@ -7104,7 +7242,7 @@ Um Sie zu übernehmen, starten Sie MusE bitte neu.
<context>
<name>MusEGui::BigTime</name>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="+62"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="+63"/>
<source>format display</source>
<translation>Formatanzeige</translation>
</message>
@@ -7217,7 +7355,7 @@ Um Sie zu übernehmen, starten Sie MusE bitte neu.
<message>
<location line="+9"/>
<source>ctrl-double-click on/off</source>
- <translation type="unfinished"></translation>
+ <translation>Ctrl+Doppelklick für an/aus</translation>
</message>
<message>
<location line="+1"/>
@@ -8058,7 +8196,7 @@ click on part to mute/unmute</source>
<message>
<location filename="../../muse/widgets/genset.cpp" line="+497"/>
<source>MusE: Choose start template or song</source>
- <translation type="unfinished"></translation>
+ <translation>MusE: Lied oder eine Vorlage für den Start wählen</translation>
</message>
</context>
<context>
@@ -8345,18 +8483,18 @@ Möchten Sie sie jetzt auf alle existierende MIDI-Spuren anwenden?</translation>
</message>
<message>
<location line="+65"/>
- <location line="+848"/>
+ <location line="+852"/>
<source>in</source>
<translation>ein</translation>
</message>
<message>
- <location line="-825"/>
- <location line="+817"/>
+ <location line="-829"/>
+ <location line="+821"/>
<source>out</source>
<translation>aus</translation>
</message>
<message>
- <location line="-773"/>
+ <location line="-777"/>
<source>Show first aliases</source>
<translation>Zeige erste Aliase</translation>
</message>
@@ -8383,7 +8521,7 @@ Möchten Sie sie jetzt auf alle existierende MIDI-Spuren anwenden?</translation>
<translation>Jack-Gerät erstellen</translation>
</message>
<message>
- <location line="+286"/>
+ <location line="+290"/>
<location line="+28"/>
<source>Port Number</source>
<translation>Anschlussnummer</translation>
@@ -8739,7 +8877,7 @@ Möchten Sie sie jetzt auf alle existierende MIDI-Spuren anwenden?</translation>
<location line="-227"/>
<location line="+125"/>
<source>ctrl-double-click on/off</source>
- <translation type="unfinished"></translation>
+ <translation>Ctrl+Doppelklick für an/aus</translation>
</message>
<message>
<location line="-42"/>
@@ -9324,12 +9462,12 @@ Sync-Einstellungen anwenden?</translation>
</message>
<message>
<location line="+4"/>
- <location line="+253"/>
+ <location line="+251"/>
<source>Panic</source>
<translation>Panik</translation>
</message>
<message>
- <location line="-251"/>
+ <location line="-249"/>
<source>send note off to all midi channels</source>
<translation>Panik - &quot;Note aus&quot; Befehl an alle Midikanäle senden</translation>
</message>
@@ -9362,13 +9500,13 @@ Sync-Einstellungen anwenden?</translation>
</message>
<message>
<location line="+2"/>
- <location line="+972"/>
+ <location line="+970"/>
<location line="+1229"/>
<source>&amp;Save</source>
<translation>&amp;Speichern</translation>
</message>
<message>
- <location line="-2199"/>
+ <location line="-2197"/>
<location line="+3"/>
<source>Click this button to save the song you are editing. You will be prompted for a file name.
You can also select the Save command from the File menu.</source>
@@ -9499,12 +9637,12 @@ Alternativ das Lied mit dem Befehl &quot;Sichern&quot; im Menü &quot;Datei&quot
<message>
<location line="+2"/>
<source>Reset Instr.</source>
- <translation>Instr. zurücksetzen</translation>
+ <translation>Instrument zurücksetzen</translation>
</message>
<message>
<location line="+1"/>
<source>Init Instr.</source>
- <translation>Instr. initialisieren</translation>
+ <translation>Instrument initialisieren</translation>
</message>
<message>
<location line="+1"/>
@@ -9542,7 +9680,7 @@ Alternativ das Lied mit dem Befehl &quot;Sichern&quot; im Menü &quot;Datei&quot
<translation>Automatisierungsdaten löschen</translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+3"/>
<source>Cascade</source>
<translation>Staffeln</translation>
</message>
@@ -9858,6 +9996,26 @@ Aktuelles Projekt sichern?</translation>
<translation>&amp;Abbrechen</translation>
</message>
<message>
+ <location line="+114"/>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation>Dies wird alle Automatisierungsdaten
+von allen Audiospuren löschen!
+Fortsetzen?</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation>Dies nimmt an der momentanen Position
+einen Automatisierungs-Schnappschuss
+aller Controller von allen Audiospuren auf.
+Fortsetzen?</translation>
+ </message>
+ <message>
<location filename="../../muse/exportmidi.cpp" line="+139"/>
<source>MusE: Export Midi</source>
<translation>MusE: Midi exportieren</translation>
@@ -10114,8 +10272,13 @@ Files:</source>
<translation>Part Name: %1
Dateien:</translation>
</message>
+ <message>
+ <location line="+109"/>
+ <source>Remove selected</source>
+ <translation>Löschen</translation>
+ </message>
<message numerus="yes">
- <location line="+2105"/>
+ <location line="+2024"/>
<source>%n part(s) out of %1 could not be pasted.
Likely the selected track is the wrong type.</source>
<translation>
@@ -10368,7 +10531,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ.</numerusform>
<message>
<location line="+4"/>
<source>&amp;Pitch colors</source>
- <translation type="unfinished">Farbe nach &amp;Tonhöhe</translation>
+ <translation>Farbe nach &amp;Tonhöhe</translation>
</message>
<message>
<location line="+4"/>
@@ -10409,14 +10572,14 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ.</numerusform>
<context>
<name>MusEGui::PluginDialog</name>
<message>
- <location filename="../../muse/plugin.cpp" line="+2846"/>
+ <location filename="../../muse/plugin.cpp" line="+2825"/>
<source>MusE: select plugin</source>
<translation>MusE: PlugIn wählen</translation>
</message>
<message>
<location line="+13"/>
<source>Type</source>
- <translation type="unfinished">Typ</translation>
+ <translation>Typ</translation>
</message>
<message>
<location line="+1"/>
@@ -10476,32 +10639,32 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ.</numerusform>
<message>
<location line="+4"/>
<source>Audio inputs</source>
- <translation type="unfinished"></translation>
+ <translation>Audio-Eingänge</translation>
</message>
<message>
<location line="+1"/>
<source>Audio outputs</source>
- <translation type="unfinished"></translation>
+ <translation>Audio-Ausgänge</translation>
</message>
<message>
<location line="+1"/>
<source>Control inputs</source>
- <translation type="unfinished"></translation>
+ <translation>Steuerungs-Eingänge</translation>
</message>
<message>
<location line="+1"/>
<source>Control outputs</source>
- <translation type="unfinished"></translation>
+ <translation>Steuerungs-Ausgänge</translation>
</message>
<message>
<location line="+1"/>
<source>In-place capable</source>
- <translation type="unfinished"></translation>
+ <translation>In-Place-fähig</translation>
</message>
<message>
<location line="+1"/>
<source>ID number</source>
- <translation type="unfinished"></translation>
+ <translation>ID-Nummer</translation>
</message>
<message>
<location line="+20"/>
@@ -10514,7 +10677,12 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ.</numerusform>
<translation>Abbrechen</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+9"/>
+ <source>Show plugs:</source>
+ <translation>Zeige Plugins:</translation>
+ </message>
+ <message>
+ <location line="+7"/>
<source>Mono and Stereo</source>
<translation>Mono und Stereo</translation>
</message>
@@ -10536,22 +10704,22 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ.</numerusform>
<message>
<location line="+13"/>
<source>Select which types of plugins should be visible in the list.&lt;br&gt;Note that using mono plugins on stereo tracks is not a problem, two will be used in parallel.&lt;br&gt;Also beware that the &apos;all&apos; alternative includes plugins that may not be useful in an effect rack.</source>
- <translation type="unfinished"></translation>
+ <translation>Wählen Sie aus, welche Plugintypen in der Liste sichtbar sein sollen.&lt;br&gt;Es ist kein Problem, Mono-Plugins auf Stereospuren zu verwenden; dann werden zwei parallel verwendet.&lt;br&gt;Beachten Sie, dass die &quot;Alle&quot;-Alternative Plugings beinhaltet, die nicht in einem Effekteinschub nützlich sein könnten.</translation>
</message>
<message>
<location line="+175"/>
<source>dssi synth</source>
- <translation type="unfinished"></translation>
+ <translation>DSSI-Synth</translation>
</message>
<message>
<location line="+2"/>
<source>dssi effect</source>
- <translation type="unfinished"></translation>
+ <translation>DSSI-Effekt</translation>
</message>
<message>
<location line="+2"/>
<source>ladspa</source>
- <translation type="unfinished"></translation>
+ <translation>LADSPA</translation>
</message>
<message>
<location line="-167"/>
@@ -10583,7 +10751,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ.</numerusform>
<translation>Signalfluss PlugIn überspringen</translation>
</message>
<message>
- <location line="+498"/>
+ <location line="+505"/>
<source>MusE: load preset</source>
<translation>MusE: Vorlage laden</translation>
</message>
@@ -11030,7 +11198,7 @@ Titel ist nicht einzigartig</translation>
<context>
<name>MusEGui::Strip</name>
<message>
- <location filename="../../muse/mixer/strip.cpp" line="+313"/>
+ <location filename="../../muse/mixer/strip.cpp" line="+326"/>
<source>Remove track?</source>
<translation>Spur entfernen?</translation>
</message>
@@ -11038,7 +11206,7 @@ Titel ist nicht einzigartig</translation>
<context>
<name>MusEGui::TList</name>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="+408"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="+413"/>
<source>&lt;none&gt;</source>
<translation>&lt;kein&gt;</translation>
</message>
@@ -11090,29 +11258,29 @@ Titel ist nicht einzigartig</translation>
</message>
<message>
<location line="+520"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>Update drummap?</source>
<translation>Drumbelegung aktualisieren?</translation>
</message>
<message>
- <location line="-1275"/>
+ <location line="-1424"/>
<source>Do you want to use same port for all instruments in the drummap?</source>
<translation>Möchten Sie für alle Instrumente der Drumbelegung den selben Anschluss verwenden?</translation>
</message>
<message>
<location line="+1"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>&amp;Yes</source>
<translation>&amp;Ja</translation>
</message>
<message>
- <location line="-1276"/>
- <location line="+1276"/>
+ <location line="-1425"/>
+ <location line="+1425"/>
<source>&amp;No</source>
<translation>&amp;Nein</translation>
</message>
<message>
- <location line="-1210"/>
+ <location line="-1359"/>
<location line="+41"/>
<source>show gui</source>
<translation>GUI anzeigen</translation>
@@ -11124,7 +11292,22 @@ Titel ist nicht einzigartig</translation>
<translation>Native GUI anzeigen</translation>
</message>
<message>
- <location line="+361"/>
+ <location line="+335"/>
+ <source>Midi control</source>
+ <translation>MIDI-Steuerung</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Assign</source>
+ <translation>Zuweisen</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Clear</source>
+ <translation>Löschen</translation>
+ </message>
+ <message>
+ <location line="+119"/>
<source>Treble clef</source>
<translation>Violinschlüssel</translation>
</message>
@@ -11144,6 +11327,16 @@ Titel ist nicht einzigartig</translation>
<translation>Sichtbare Automatisierung</translation>
</message>
<message>
+ <location line="+16"/>
+ <source>Internal</source>
+ <translation>Intern</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Synth</source>
+ <translation>Synth</translation>
+ </message>
+ <message>
<location line="+133"/>
<source>Delete Track</source>
<translation>Spur löschen</translation>
@@ -11174,7 +11367,7 @@ Titel ist nicht einzigartig</translation>
<translation>Möchten Sie für alle Instrumente der Drumbelegung den selben Anschluss und Kanal verwenden?</translation>
</message>
<message>
- <location line="-1367"/>
+ <location line="-1516"/>
<source>Unused Devices</source>
<translation>Ungenutzte Geräte</translation>
</message>
@@ -12105,7 +12298,7 @@ Erzeugen?</translation>
<translation>Verzeichnis erzeugen schlug fehl</translation>
</message>
<message>
- <location line="+375"/>
+ <location line="+400"/>
<source>File
%1
exists. Overwrite?</source>
@@ -13379,20 +13572,20 @@ Robert Jonsson
<translation>Abschwellzeit [ms]</translation>
</message>
<message>
- <location line="+59"/>
- <location line="+41"/>
+ <location line="+62"/>
+ <location line="+44"/>
<source>dB</source>
<translation>dB</translation>
</message>
<message>
- <location line="-31"/>
+ <location line="-34"/>
<source>Dry Level [dB]</source>
<translation>Lautstärke des
unmodifizierten
Signals (Dry Level) [dB]</translation>
</message>
<message>
- <location line="+41"/>
+ <location line="+44"/>
<source>Wet Level [dB]</source>
<translation>Lautstärke des
modifizierten
diff --git a/muse2/share/locale/muse_en.ts b/muse2/share/locale/muse_en.ts
index 88df5126..fbc16f29 100644
--- a/muse2/share/locale/muse_en.ts
+++ b/muse2/share/locale/muse_en.ts
@@ -89,16 +89,16 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="503"/>
+ <location filename="../../muse/midiseq.cpp" line="510"/>
<source>Bad timing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="504"/>
+ <location filename="../../muse/midiseq.cpp" line="511"/>
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
-Also please check console output for any further error messages
+Also please check console output for any further error messages.
</source>
<translation type="unfinished"></translation>
</message>
@@ -112,12 +112,12 @@ Also please check console output for any further error messages
</message>
<message>
<location filename="../../muse/widgets/aboutbox.ui" line="51"/>
- <source>Version 2 pre-alpha</source>
+ <source>Version 2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../muse/widgets/aboutbox.ui" line="61"/>
- <source>(C) Copyright 1999-2010 Werner Schweer and others.
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
See http://www.muse-sequencer.org for new versions and
more information.
@@ -4724,6 +4724,84 @@ left button behave like the middle button in such areas.</source>
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="14"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="28"/>
+ <source>Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="44"/>
+ <source>Channel:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="71"/>
+ <source>Control type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="85"/>
+ <source>Control7</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="90"/>
+ <source>Control14</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="95"/>
+ <source>RPN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="100"/>
+ <source>NRPN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="105"/>
+ <source>RPN14</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="110"/>
+ <source>NRPN14</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="115"/>
+ <source>Pitch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="120"/>
+ <source>Program</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="147"/>
+ <source>Hi:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="179"/>
+ <source>Lo:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="228"/>
+ <source>Learn</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MidiFilterConfigBase</name>
<message>
<location filename="../../muse/mplugins/midifilter.ui" line="20"/>
@@ -6072,12 +6150,12 @@ Enabled inputs in the list will
<context>
<name>MusECore::Song</name>
<message>
- <location filename="../../muse/song.cpp" line="2274"/>
+ <location filename="../../muse/song.cpp" line="2284"/>
<source>Jack shutdown!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2275"/>
+ <location filename="../../muse/song.cpp" line="2285"/>
<source>Jack has detected a performance problem which has lead to
MusE being disconnected.
This could happen due to a number of reasons:
@@ -6096,71 +6174,97 @@ click on the Restart button.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2447"/>
- <location filename="../../muse/song.cpp" line="2612"/>
+ <location filename="../../muse/song.cpp" line="2464"/>
+ <location filename="../../muse/song.cpp" line="2702"/>
<source>Automation:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2449"/>
+ <location filename="../../muse/song.cpp" line="2466"/>
<source>previous event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2453"/>
+ <location filename="../../muse/song.cpp" line="2470"/>
<source>next event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2462"/>
- <location filename="../../muse/song.cpp" line="2617"/>
+ <location filename="../../muse/song.cpp" line="2479"/>
+ <location filename="../../muse/song.cpp" line="2707"/>
<source>set event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2464"/>
- <location filename="../../muse/song.cpp" line="2619"/>
+ <location filename="../../muse/song.cpp" line="2481"/>
+ <location filename="../../muse/song.cpp" line="2709"/>
<source>add event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2468"/>
- <location filename="../../muse/song.cpp" line="2623"/>
+ <location filename="../../muse/song.cpp" line="2485"/>
+ <location filename="../../muse/song.cpp" line="2713"/>
<source>erase event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2472"/>
+ <location filename="../../muse/song.cpp" line="2489"/>
<source>erase range</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2476"/>
+ <location filename="../../muse/song.cpp" line="2493"/>
<source>clear automation</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2505"/>
+ <location filename="../../muse/song.cpp" line="2499"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2501"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2511"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2556"/>
<source>Clear all controller events?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2505"/>
+ <location filename="../../muse/song.cpp" line="2556"/>
<source>&amp;Ok</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="2505"/>
+ <location filename="../../muse/song.cpp" line="2556"/>
<source>&amp;Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="3272"/>
+ <location filename="../../muse/song.cpp" line="2823"/>
+ <source>MusE: Tempo list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="2824"/>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/song.cpp" line="3416"/>
<source>MusE - external script failed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/song.cpp" line="3273"/>
+ <location filename="../../muse/song.cpp" line="3417"/>
<source>MusE was unable to launch the script, error message:
%1</source>
<translation type="unfinished"></translation>
@@ -6901,98 +7005,98 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::AudioStrip</name>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="687"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="678"/>
<source>panorama</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="689"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="680"/>
<source>aux send level</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="712"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="703"/>
<source>Pan</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="804"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="794"/>
<source>1/2 channel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="819"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="809"/>
<source>Pre</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="820"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="810"/>
<source>pre fader - post fader</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="890"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="880"/>
<source>dB</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="922"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="911"/>
<source>record</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="934"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="923"/>
<source>mute</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="953"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="942"/>
<source>record downmix</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="955"/>
- <location filename="../../muse/mixer/astrip.cpp" line="959"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="944"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="948"/>
<source>solo mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="967"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="956"/>
<source>off</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="993"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="982"/>
<source>input routing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1006"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="995"/>
<source>output routing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1020"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1009"/>
<source>Off</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1021"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1010"/>
<source>Read</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1022"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1011"/>
<source>Touch</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1023"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1012"/>
<source>Write</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="1066"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="1055"/>
<source>automation type</source>
<translation type="unfinished"></translation>
</message>
@@ -7000,49 +7104,49 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::BigTime</name>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="62"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="63"/>
<source>format display</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="79"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="80"/>
<source>bar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="80"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="81"/>
<source>beat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="81"/>
- <location filename="../../muse/widgets/bigtime.cpp" line="87"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="82"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="88"/>
<source>tick</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="83"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="84"/>
<source>minute</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="84"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="85"/>
<source>second</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="85"/>
- <location filename="../../muse/widgets/bigtime.cpp" line="88"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="86"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="89"/>
<source>frame</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="86"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="87"/>
<source>subframe</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="104"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="105"/>
<source>MusE: Bigtime</source>
<translation type="unfinished"></translation>
</message>
@@ -8225,13 +8329,13 @@ Do you want to apply to all existing midi tracks now?</source>
</message>
<message>
<location filename="../../muse/confmport.cpp" line="438"/>
- <location filename="../../muse/confmport.cpp" line="1286"/>
+ <location filename="../../muse/confmport.cpp" line="1290"/>
<source>in</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../muse/confmport.cpp" line="461"/>
- <location filename="../../muse/confmport.cpp" line="1278"/>
+ <location filename="../../muse/confmport.cpp" line="1282"/>
<source>out</source>
<translation type="unfinished"></translation>
</message>
@@ -8263,184 +8367,184 @@ Do you want to apply to all existing midi tracks now?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="987"/>
- <location filename="../../muse/confmport.cpp" line="1015"/>
+ <location filename="../../muse/confmport.cpp" line="991"/>
+ <location filename="../../muse/confmport.cpp" line="1019"/>
<source>Port Number</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="988"/>
+ <location filename="../../muse/confmport.cpp" line="992"/>
<source>Enable gui</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="989"/>
+ <location filename="../../muse/confmport.cpp" line="993"/>
<source>Enable reading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="990"/>
+ <location filename="../../muse/confmport.cpp" line="994"/>
<source>Enable writing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="991"/>
+ <location filename="../../muse/confmport.cpp" line="995"/>
<source>Port instrument</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="992"/>
+ <location filename="../../muse/confmport.cpp" line="996"/>
<source>Midi device name. Click to edit (Jack)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="993"/>
+ <location filename="../../muse/confmport.cpp" line="997"/>
<source>Connections from Jack Midi outputs</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="994"/>
+ <location filename="../../muse/confmport.cpp" line="998"/>
<source>Connections to Jack Midi inputs</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="995"/>
+ <location filename="../../muse/confmport.cpp" line="999"/>
<source>Auto-connect these channels to new midi tracks</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="998"/>
+ <location filename="../../muse/confmport.cpp" line="1002"/>
<source>Auto-connect new midi tracks to these channels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1000"/>
+ <location filename="../../muse/confmport.cpp" line="1004"/>
<source>Auto-connect new midi tracks to this channel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1002"/>
+ <location filename="../../muse/confmport.cpp" line="1006"/>
<source>Device state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1017"/>
+ <location filename="../../muse/confmport.cpp" line="1021"/>
<source>Enable gui for device</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1019"/>
+ <location filename="../../muse/confmport.cpp" line="1023"/>
<source>Enable reading from device</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1021"/>
+ <location filename="../../muse/confmport.cpp" line="1025"/>
<source>Enable writing to device</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1023"/>
+ <location filename="../../muse/confmport.cpp" line="1027"/>
<source>Name of the midi device associated with this port number. Click to edit Jack midi name.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1026"/>
+ <location filename="../../muse/confmport.cpp" line="1030"/>
<source>Instrument connected to port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1028"/>
+ <location filename="../../muse/confmport.cpp" line="1032"/>
<source>Connections from Jack Midi output ports</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1030"/>
+ <location filename="../../muse/confmport.cpp" line="1034"/>
<source>Connections to Jack Midi input ports</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1032"/>
+ <location filename="../../muse/confmport.cpp" line="1036"/>
<source>Auto-connect these channels, on this port, to new midi tracks.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1036"/>
+ <location filename="../../muse/confmport.cpp" line="1040"/>
<source>Connect new midi tracks to these channels, on this port.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1038"/>
+ <location filename="../../muse/confmport.cpp" line="1042"/>
<source>Connect new midi tracks to this channel, on this port.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1041"/>
+ <location filename="../../muse/confmport.cpp" line="1045"/>
<source>State: result of opening the device</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1081"/>
+ <location filename="../../muse/confmport.cpp" line="1085"/>
<source>Port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1082"/>
+ <location filename="../../muse/confmport.cpp" line="1086"/>
<source>GUI</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1083"/>
+ <location filename="../../muse/confmport.cpp" line="1087"/>
<source>I</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1084"/>
+ <location filename="../../muse/confmport.cpp" line="1088"/>
<source>O</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1085"/>
+ <location filename="../../muse/confmport.cpp" line="1089"/>
<source>Instrument</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1086"/>
+ <location filename="../../muse/confmport.cpp" line="1090"/>
<source>Device Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1087"/>
+ <location filename="../../muse/confmport.cpp" line="1091"/>
<source>In routes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1088"/>
+ <location filename="../../muse/confmport.cpp" line="1092"/>
<source>Out routes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1089"/>
+ <location filename="../../muse/confmport.cpp" line="1093"/>
<source>Def in ch</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1090"/>
+ <location filename="../../muse/confmport.cpp" line="1094"/>
<source>Def out ch</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1091"/>
+ <location filename="../../muse/confmport.cpp" line="1095"/>
<source>State</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1171"/>
+ <location filename="../../muse/confmport.cpp" line="1175"/>
<source>&lt;unknown&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/confmport.cpp" line="1255"/>
- <location filename="../../muse/confmport.cpp" line="1317"/>
+ <location filename="../../muse/confmport.cpp" line="1259"/>
+ <location filename="../../muse/confmport.cpp" line="1321"/>
<source>&lt;none&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -9174,7 +9278,7 @@ Apply sync settings?</source>
</message>
<message>
<location filename="../../muse/app.cpp" line="444"/>
- <location filename="../../muse/app.cpp" line="697"/>
+ <location filename="../../muse/app.cpp" line="695"/>
<source>Panic</source>
<translation type="unfinished"></translation>
</message>
@@ -9212,8 +9316,8 @@ Apply sync settings?</source>
</message>
<message>
<location filename="../../muse/app.cpp" line="465"/>
- <location filename="../../muse/app.cpp" line="1437"/>
- <location filename="../../muse/app.cpp" line="2666"/>
+ <location filename="../../muse/app.cpp" line="1435"/>
+ <location filename="../../muse/app.cpp" line="2664"/>
<source>&amp;Save</source>
<translation type="unfinished"></translation>
</message>
@@ -9391,317 +9495,332 @@ You can also select the Save command from the File menu.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="536"/>
+ <location filename="../../muse/app.cpp" line="534"/>
<source>Cascade</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="537"/>
+ <location filename="../../muse/app.cpp" line="535"/>
<source>Tile</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="538"/>
+ <location filename="../../muse/app.cpp" line="536"/>
<source>In rows</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="539"/>
+ <location filename="../../muse/app.cpp" line="537"/>
<source>In columns</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="543"/>
+ <location filename="../../muse/app.cpp" line="541"/>
<source>Global Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="544"/>
+ <location filename="../../muse/app.cpp" line="542"/>
<source>Configure Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="545"/>
+ <location filename="../../muse/app.cpp" line="543"/>
<source>Follow Song</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="546"/>
+ <location filename="../../muse/app.cpp" line="544"/>
<source>Don&apos;t Follow Song</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="548"/>
+ <location filename="../../muse/app.cpp" line="546"/>
<source>Follow Page</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="551"/>
+ <location filename="../../muse/app.cpp" line="549"/>
<source>Follow Continuous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="554"/>
+ <location filename="../../muse/app.cpp" line="552"/>
<source>Metronome</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="555"/>
+ <location filename="../../muse/app.cpp" line="553"/>
<source>Midi Sync</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="556"/>
+ <location filename="../../muse/app.cpp" line="554"/>
<source>Midi File Import/Export</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="557"/>
+ <location filename="../../muse/app.cpp" line="555"/>
<source>Appearance Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="558"/>
+ <location filename="../../muse/app.cpp" line="556"/>
<source>Midi Ports / Soft Synth</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="561"/>
+ <location filename="../../muse/app.cpp" line="559"/>
<source>&amp;Manual</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="562"/>
+ <location filename="../../muse/app.cpp" line="560"/>
<source>&amp;MusE Homepage</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="563"/>
+ <location filename="../../muse/app.cpp" line="561"/>
<source>&amp;Report Bug...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="564"/>
+ <location filename="../../muse/app.cpp" line="562"/>
<source>&amp;About MusE</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="664"/>
+ <location filename="../../muse/app.cpp" line="662"/>
<source>Song Position</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="671"/>
+ <location filename="../../muse/app.cpp" line="669"/>
<source>Tempo</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="677"/>
+ <location filename="../../muse/app.cpp" line="675"/>
<source>Signature</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="682"/>
+ <location filename="../../muse/app.cpp" line="680"/>
<source>File Buttons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="689"/>
+ <location filename="../../muse/app.cpp" line="687"/>
<source>Undo/Redo</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="693"/>
+ <location filename="../../muse/app.cpp" line="691"/>
<source>Transport</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="727"/>
+ <location filename="../../muse/app.cpp" line="725"/>
<source>&amp;File</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="756"/>
+ <location filename="../../muse/app.cpp" line="754"/>
<source>&amp;View</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="775"/>
+ <location filename="../../muse/app.cpp" line="773"/>
<source>&amp;Midi</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="800"/>
+ <location filename="../../muse/app.cpp" line="798"/>
<source>&amp;Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="814"/>
+ <location filename="../../muse/app.cpp" line="812"/>
<source>A&amp;utomation</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="827"/>
+ <location filename="../../muse/app.cpp" line="825"/>
<source>&amp;Windows</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="840"/>
+ <location filename="../../muse/app.cpp" line="838"/>
<source>MusE Se&amp;ttings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="863"/>
+ <location filename="../../muse/app.cpp" line="861"/>
<source>&amp;Help</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="874"/>
+ <location filename="../../muse/app.cpp" line="872"/>
<source>About &amp;Qt</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1139"/>
+ <location filename="../../muse/app.cpp" line="1137"/>
<source>Cannot read template</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1165"/>
+ <location filename="../../muse/app.cpp" line="1163"/>
<source>File open error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1178"/>
+ <location filename="../../muse/app.cpp" line="1176"/>
<source>File read error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1190"/>
+ <location filename="../../muse/app.cpp" line="1188"/>
<source>Unknown File Format: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1301"/>
- <location filename="../../muse/app.cpp" line="1698"/>
- <location filename="../../muse/app.cpp" line="2612"/>
+ <location filename="../../muse/app.cpp" line="1299"/>
+ <location filename="../../muse/app.cpp" line="1696"/>
+ <location filename="../../muse/app.cpp" line="2610"/>
<source>MusE: Song: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1336"/>
+ <location filename="../../muse/app.cpp" line="1334"/>
<source>MusE: load project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1351"/>
+ <location filename="../../muse/app.cpp" line="1349"/>
<source>MusE: load template</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1397"/>
+ <location filename="../../muse/app.cpp" line="1395"/>
<source>MusE: Write File failed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1435"/>
+ <location filename="../../muse/app.cpp" line="1433"/>
<source>The current Project contains unsaved data
Save Current Project?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1437"/>
- <location filename="../../muse/app.cpp" line="2666"/>
+ <location filename="../../muse/app.cpp" line="1435"/>
+ <location filename="../../muse/app.cpp" line="2664"/>
<source>S&amp;kip</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1437"/>
+ <location filename="../../muse/app.cpp" line="1435"/>
<source>&amp;Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1679"/>
+ <location filename="../../muse/app.cpp" line="1677"/>
<source>MusE: Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="1745"/>
- <location filename="../../muse/app.cpp" line="1905"/>
+ <location filename="../../muse/app.cpp" line="1743"/>
+ <location filename="../../muse/app.cpp" line="1903"/>
<source>Nothing to edit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2401"/>
- <location filename="../../muse/app.cpp" line="2411"/>
- <location filename="../../muse/app.cpp" line="2442"/>
- <location filename="../../muse/app.cpp" line="2476"/>
- <location filename="../../muse/app.cpp" line="2484"/>
+ <location filename="../../muse/app.cpp" line="2399"/>
+ <location filename="../../muse/app.cpp" line="2409"/>
+ <location filename="../../muse/app.cpp" line="2440"/>
+ <location filename="../../muse/app.cpp" line="2474"/>
+ <location filename="../../muse/app.cpp" line="2482"/>
<source>MusE: Bounce to Track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2402"/>
+ <location filename="../../muse/app.cpp" line="2400"/>
<source>No wave tracks found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2412"/>
- <location filename="../../muse/app.cpp" line="2517"/>
+ <location filename="../../muse/app.cpp" line="2410"/>
+ <location filename="../../muse/app.cpp" line="2515"/>
<source>No audio output tracks found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2443"/>
+ <location filename="../../muse/app.cpp" line="2441"/>
<source>Select one audio output track,
and one target wave track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2477"/>
+ <location filename="../../muse/app.cpp" line="2475"/>
<source>Select one target wave track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2485"/>
+ <location filename="../../muse/app.cpp" line="2483"/>
<source>Select one target wave track,
and one audio output track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2516"/>
- <location filename="../../muse/app.cpp" line="2541"/>
+ <location filename="../../muse/app.cpp" line="2514"/>
+ <location filename="../../muse/app.cpp" line="2539"/>
<source>MusE: Bounce to File</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2542"/>
+ <location filename="../../muse/app.cpp" line="2540"/>
<source>Select one audio output track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2580"/>
+ <location filename="../../muse/app.cpp" line="2578"/>
<source>MusE: Bounce</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2581"/>
+ <location filename="../../muse/app.cpp" line="2579"/>
<source>set left/right marker for bounce range</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2663"/>
+ <location filename="../../muse/app.cpp" line="2661"/>
<source>The current Project contains unsaved data
Load overwrites current Project:
Save Current Project?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/app.cpp" line="2666"/>
+ <location filename="../../muse/app.cpp" line="2664"/>
<location filename="../../muse/importmidi.cpp" line="83"/>
<source>&amp;Abort</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location filename="../../muse/app.cpp" line="2778"/>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/app.cpp" line="2804"/>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../../muse/exportmidi.cpp" line="139"/>
<source>MusE: Export Midi</source>
<translation type="unfinished"></translation>
@@ -9953,8 +10072,13 @@ Do you still want to import it?</source>
Files:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="915"/>
+ <source>Remove selected</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <location filename="../../muse/arranger/pcanvas.cpp" line="2911"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2939"/>
<source>%n part(s) out of %1 could not be pasted.
Likely the selected track is the wrong type.</source>
<translation>
@@ -9965,7 +10089,7 @@ Likely the selected track is the wrong type.</numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../../muse/arranger/pcanvas.cpp" line="2912"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2940"/>
<source>%n part(s) could not be pasted.
Likely the selected track is the wrong type.</source>
<translation>
@@ -9976,32 +10100,32 @@ Likely the selected track is the wrong type.</numerusform>
</translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2937"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2965"/>
<source>Cannot paste: multiple tracks selected</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2946"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2974"/>
<source>Cannot paste: no track selected</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2966"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="2994"/>
<source>Can only paste to midi/drum track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2977"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="3005"/>
<source>Can only paste to wave track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2988"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="3016"/>
<source>Can only paste to midi or wave track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/pcanvas.cpp" line="2996"/>
+ <location filename="../../muse/arranger/pcanvas.cpp" line="3024"/>
<source>Cannot paste: wrong data type</source>
<translation type="unfinished"></translation>
</message>
@@ -10248,152 +10372,157 @@ Likely the selected track is the wrong type.</numerusform>
<context>
<name>MusEGui::PluginDialog</name>
<message>
- <location filename="../../muse/plugin.cpp" line="2846"/>
+ <location filename="../../muse/plugin.cpp" line="2825"/>
<source>MusE: select plugin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2859"/>
+ <location filename="../../muse/plugin.cpp" line="2838"/>
<source>Type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2860"/>
+ <location filename="../../muse/plugin.cpp" line="2839"/>
<source>Lib</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2861"/>
+ <location filename="../../muse/plugin.cpp" line="2840"/>
<source>Label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2862"/>
+ <location filename="../../muse/plugin.cpp" line="2841"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2863"/>
+ <location filename="../../muse/plugin.cpp" line="2842"/>
<source>AI</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2864"/>
+ <location filename="../../muse/plugin.cpp" line="2843"/>
<source>AO</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2865"/>
+ <location filename="../../muse/plugin.cpp" line="2844"/>
<source>CI</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2866"/>
+ <location filename="../../muse/plugin.cpp" line="2845"/>
<source>CO</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2867"/>
+ <location filename="../../muse/plugin.cpp" line="2846"/>
<source>IP</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2868"/>
+ <location filename="../../muse/plugin.cpp" line="2847"/>
<source>id</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2869"/>
+ <location filename="../../muse/plugin.cpp" line="2848"/>
<source>Maker</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2870"/>
+ <location filename="../../muse/plugin.cpp" line="2849"/>
<source>Copyright</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2874"/>
+ <location filename="../../muse/plugin.cpp" line="2853"/>
<source>Audio inputs</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2875"/>
+ <location filename="../../muse/plugin.cpp" line="2854"/>
<source>Audio outputs</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2876"/>
+ <location filename="../../muse/plugin.cpp" line="2855"/>
<source>Control inputs</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2877"/>
+ <location filename="../../muse/plugin.cpp" line="2856"/>
<source>Control outputs</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2878"/>
+ <location filename="../../muse/plugin.cpp" line="2857"/>
<source>In-place capable</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2879"/>
+ <location filename="../../muse/plugin.cpp" line="2858"/>
<source>ID number</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2899"/>
+ <location filename="../../muse/plugin.cpp" line="2878"/>
<source>Ok</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2901"/>
+ <location filename="../../muse/plugin.cpp" line="2880"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2917"/>
+ <location filename="../../muse/plugin.cpp" line="2889"/>
+ <source>Show plugs:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/plugin.cpp" line="2896"/>
<source>Mono and Stereo</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2922"/>
+ <location filename="../../muse/plugin.cpp" line="2901"/>
<source>Stereo</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2927"/>
+ <location filename="../../muse/plugin.cpp" line="2906"/>
<source>Mono</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2932"/>
+ <location filename="../../muse/plugin.cpp" line="2911"/>
<source>Show All</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2945"/>
+ <location filename="../../muse/plugin.cpp" line="2924"/>
<source>Select which types of plugins should be visible in the list.&lt;br&gt;Note that using mono plugins on stereo tracks is not a problem, two will be used in parallel.&lt;br&gt;Also beware that the &apos;all&apos; alternative includes plugins that may not be useful in an effect rack.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3120"/>
+ <location filename="../../muse/plugin.cpp" line="3099"/>
<source>dssi synth</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3122"/>
+ <location filename="../../muse/plugin.cpp" line="3101"/>
<source>dssi effect</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3124"/>
+ <location filename="../../muse/plugin.cpp" line="3103"/>
<source>ladspa</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="2957"/>
+ <location filename="../../muse/plugin.cpp" line="2936"/>
<source>Search in &apos;Label&apos; and &apos;Name&apos;:</source>
<translation type="unfinished"></translation>
</message>
@@ -10401,38 +10530,38 @@ Likely the selected track is the wrong type.</numerusform>
<context>
<name>MusEGui::PluginGui</name>
<message>
- <location filename="../../muse/plugin.cpp" line="3179"/>
+ <location filename="../../muse/plugin.cpp" line="3158"/>
<source>File Buttons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3181"/>
+ <location filename="../../muse/plugin.cpp" line="3160"/>
<source>Load Preset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3185"/>
+ <location filename="../../muse/plugin.cpp" line="3164"/>
<source>Save Preset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3191"/>
- <location filename="../../muse/plugin.cpp" line="3194"/>
+ <location filename="../../muse/plugin.cpp" line="3170"/>
+ <location filename="../../muse/plugin.cpp" line="3173"/>
<source>bypass plugin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3692"/>
+ <location filename="../../muse/plugin.cpp" line="3678"/>
<source>MusE: load preset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3717"/>
+ <location filename="../../muse/plugin.cpp" line="3703"/>
<source>Error reading preset. Might not be right type for this plugin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/plugin.cpp" line="3756"/>
+ <location filename="../../muse/plugin.cpp" line="3742"/>
<source>MusE: save preset</source>
<translation type="unfinished"></translation>
</message>
@@ -10867,7 +10996,7 @@ the selected title is not unique</source>
<context>
<name>MusEGui::Strip</name>
<message>
- <location filename="../../muse/mixer/strip.cpp" line="313"/>
+ <location filename="../../muse/mixer/strip.cpp" line="326"/>
<source>Remove track?</source>
<translation type="unfinished"></translation>
</message>
@@ -10875,143 +11004,168 @@ the selected title is not unique</source>
<context>
<name>MusEGui::TList</name>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="408"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="413"/>
<source>&lt;none&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="429"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="434"/>
<source>visible</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="438"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="443"/>
<source>no clef</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="440"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="445"/>
<source>Treble</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="442"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="447"/>
<source>Bass</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="444"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="449"/>
<source>Grand</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="473"/>
- <location filename="../../muse/arranger/tlist.cpp" line="887"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="478"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="892"/>
<source>off</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="482"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="487"/>
<source>&lt;unknown&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="574"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="579"/>
<source>MusE: bad trackname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="575"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="580"/>
<source>please choose a unique track name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1005"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1010"/>
<source>Unused Devices</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1095"/>
- <location filename="../../muse/arranger/tlist.cpp" line="2371"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1100"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2525"/>
<source>Update drummap?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1096"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1101"/>
<source>Do you want to use same port for all instruments in the drummap?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1097"/>
- <location filename="../../muse/arranger/tlist.cpp" line="2373"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1102"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2527"/>
<source>&amp;Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1097"/>
- <location filename="../../muse/arranger/tlist.cpp" line="2373"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1102"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2527"/>
<source>&amp;No</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1163"/>
- <location filename="../../muse/arranger/tlist.cpp" line="1204"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1168"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1209"/>
<source>show gui</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1168"/>
- <location filename="../../muse/arranger/tlist.cpp" line="1209"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1173"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1214"/>
<source>show native gui</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1570"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1549"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1553"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1566"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1685"/>
<source>Treble clef</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1571"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1686"/>
<source>Bass clef</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1572"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1687"/>
<source>Grand Staff</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1602"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1717"/>
<source>Viewable automation</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1735"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1733"/>
+ <source>Internal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1756"/>
+ <source>Synth</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../muse/arranger/tlist.cpp" line="1889"/>
<source>Delete Track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1736"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1890"/>
<source>Track Comment</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="1739"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="1893"/>
<source>Insert Track</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="2321"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2475"/>
<source>Midi</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="2322"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2476"/>
<source>Drum</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="2372"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="2526"/>
<source>Do you want to use same port and channel for all instruments in the drummap?</source>
<translation type="unfinished"></translation>
</message>
@@ -11965,26 +12119,26 @@ Create it?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="465"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="490"/>
<source>File
%1
exists. Overwrite?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="500"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="525"/>
<source>Open File
%1
failed: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="479"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="504"/>
<source>MusE: write</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/widgets/filedialog.cpp" line="501"/>
+ <location filename="../../muse/widgets/filedialog.cpp" line="526"/>
<source>MusE: Open File</source>
<translation type="unfinished"></translation>
</message>
@@ -13195,258 +13349,258 @@ Robert Jonsson
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="91"/>
- <location filename="../plugins/2142.ui" line="132"/>
+ <location filename="../plugins/2142.ui" line="94"/>
+ <location filename="../plugins/2142.ui" line="138"/>
<source>dB</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="101"/>
+ <location filename="../plugins/2142.ui" line="104"/>
<source>Dry Level [dB]</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="142"/>
+ <location filename="../plugins/2142.ui" line="148"/>
<source>Wet Level [dB]</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="214"/>
+ <location filename="../plugins/2142.ui" line="220"/>
<source>Preset:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="233"/>
+ <location filename="../plugins/2142.ui" line="239"/>
<source>AfterBurn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="238"/>
+ <location filename="../plugins/2142.ui" line="244"/>
<source>AfterBurn (Long)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="243"/>
+ <location filename="../plugins/2142.ui" line="249"/>
<source>Ambience</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="248"/>
+ <location filename="../plugins/2142.ui" line="254"/>
<source>Ambience (Thick)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="253"/>
+ <location filename="../plugins/2142.ui" line="259"/>
<source>Ambience (Thick) - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="258"/>
+ <location filename="../plugins/2142.ui" line="264"/>
<source>Cathedral</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="263"/>
+ <location filename="../plugins/2142.ui" line="269"/>
<source>Cathedral - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="268"/>
+ <location filename="../plugins/2142.ui" line="274"/>
<source>Drum Chamber</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="273"/>
+ <location filename="../plugins/2142.ui" line="279"/>
<source>Garage</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="278"/>
+ <location filename="../plugins/2142.ui" line="284"/>
<source>Garage (Bright)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="283"/>
+ <location filename="../plugins/2142.ui" line="289"/>
<source>Gymnasium</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="288"/>
+ <location filename="../plugins/2142.ui" line="294"/>
<source>Gymnasium (Bright)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="293"/>
+ <location filename="../plugins/2142.ui" line="299"/>
<source>Gymnasium (Bright) - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="298"/>
+ <location filename="../plugins/2142.ui" line="304"/>
<source>Hall (Small)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="303"/>
+ <location filename="../plugins/2142.ui" line="309"/>
<source>Hall (Medium)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="308"/>
+ <location filename="../plugins/2142.ui" line="314"/>
<source>Hall (Large)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="313"/>
+ <location filename="../plugins/2142.ui" line="319"/>
<source>Hall (Large) - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="318"/>
+ <location filename="../plugins/2142.ui" line="324"/>
<source>Plate (Small)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="323"/>
+ <location filename="../plugins/2142.ui" line="329"/>
<source>Plate (Medium)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="328"/>
+ <location filename="../plugins/2142.ui" line="334"/>
<source>Plate (Large)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="333"/>
+ <location filename="../plugins/2142.ui" line="339"/>
<source>Plate (Large) - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="338"/>
+ <location filename="../plugins/2142.ui" line="344"/>
<source>Pulse Chamber</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="343"/>
+ <location filename="../plugins/2142.ui" line="349"/>
<source>Pulse Chamber (Reverse)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="348"/>
+ <location filename="../plugins/2142.ui" line="354"/>
<source>Resonator (96 ms)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="353"/>
+ <location filename="../plugins/2142.ui" line="359"/>
<source>Resonator (152 ms)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="358"/>
+ <location filename="../plugins/2142.ui" line="364"/>
<source>Resonator (208 ms)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="363"/>
+ <location filename="../plugins/2142.ui" line="369"/>
<source>Room (Small)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="368"/>
+ <location filename="../plugins/2142.ui" line="374"/>
<source>Room (Medium)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="373"/>
+ <location filename="../plugins/2142.ui" line="379"/>
<source>Room (Large)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="378"/>
+ <location filename="../plugins/2142.ui" line="384"/>
<source>Room (Large) - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="383"/>
+ <location filename="../plugins/2142.ui" line="389"/>
<source>Slap Chamber</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="388"/>
+ <location filename="../plugins/2142.ui" line="394"/>
<source>Slap Chamber - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="393"/>
+ <location filename="../plugins/2142.ui" line="399"/>
<source>Slap Chamber (Bright)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="398"/>
+ <location filename="../plugins/2142.ui" line="404"/>
<source>Slap Chamber (Bright) HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="403"/>
+ <location filename="../plugins/2142.ui" line="409"/>
<source>Smooth Hall (Small)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="408"/>
+ <location filename="../plugins/2142.ui" line="414"/>
<source>Smooth Hall (Medium)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="413"/>
+ <location filename="../plugins/2142.ui" line="419"/>
<source>Smooth Hall (Large)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="418"/>
+ <location filename="../plugins/2142.ui" line="424"/>
<source>Smooth Hall (Large) - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="423"/>
+ <location filename="../plugins/2142.ui" line="429"/>
<source>Vocal Plate</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="428"/>
+ <location filename="../plugins/2142.ui" line="434"/>
<source>Vocal Plate - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="433"/>
+ <location filename="../plugins/2142.ui" line="439"/>
<source>Warble Chamber</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="438"/>
+ <location filename="../plugins/2142.ui" line="444"/>
<source>Warehoouse</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="443"/>
+ <location filename="../plugins/2142.ui" line="449"/>
<source>Warehouse - HD</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="451"/>
+ <location filename="../plugins/2142.ui" line="457"/>
<source>Comb Filters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="458"/>
+ <location filename="../plugins/2142.ui" line="464"/>
<source>Allpass Filters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="465"/>
+ <location filename="../plugins/2142.ui" line="471"/>
<source>Bandpass Filters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../plugins/2142.ui" line="472"/>
+ <location filename="../plugins/2142.ui" line="478"/>
<source>Enhanced Stereo</source>
<translation type="unfinished"></translation>
</message>
diff --git a/muse2/share/locale/muse_es.ts b/muse2/share/locale/muse_es.ts
index e0407626..197d8da6 100644
--- a/muse2/share/locale/muse_es.ts
+++ b/muse2/share/locale/muse_es.ts
@@ -89,7 +89,7 @@
<translation> channelMask=&quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="+503"/>
+ <location filename="../../muse/midiseq.cpp" line="+510"/>
<source>Bad timing</source>
<translation type="unfinished"></translation>
</message>
@@ -98,7 +98,7 @@
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
-Also please check console output for any further error messages
+Also please check console output for any further error messages.
</source>
<translation type="unfinished"></translation>
</message>
@@ -111,22 +111,36 @@ Also please check console output for any further error messages
<translation></translation>
</message>
<message>
- <location line="+37"/>
<source>Version 2 pre-alpha</source>
- <translation>MusE 2.0 pre-alfa</translation>
+ <translation type="obsolete">MusE 2.0 pre-alfa</translation>
</message>
<message>
- <location line="+10"/>
<source>(C) Copyright 1999-2010 Werner Schweer and others.
See http://www.muse-sequencer.org for new versions and
more information.
Published under the GNU Public License</source>
- <translation>(C) Derechos de autor 1999-2010 Werner Schweer y otros.
+ <translation type="obsolete">(C) Derechos de autor 1999-2010 Werner Schweer y otros.
Ver http://www.muse-sequencer.org por nuevas versiones
y mas información.</translation>
</message>
<message>
+ <location line="+37"/>
+ <source>Version 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
+See http://www.muse-sequencer.org for new versions and
+more information.
+
+Published under the GNU Public License</source>
+ <translation type="unfinished">(C) Derechos de autor 1999-2010 Werner Schweer y otros.
+Ver http://www.muse-sequencer.org por nuevas versiones
+y mas información. {1999-2012 ?}</translation>
+ </message>
+ <message>
<location line="+14"/>
<source>&amp;Keep On Rocking!</source>
<translation>Volver a la sesión</translation>
@@ -4787,6 +4801,84 @@ Ajusta la sensibilidad de los controles de audio y
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="+14"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Channel:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Control type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Control7</source>
+ <translation type="unfinished">Control7</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Control14</source>
+ <translation type="unfinished">Control14</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN</source>
+ <translation type="unfinished">RPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN</source>
+ <translation type="unfinished">NRPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN14</source>
+ <translation type="unfinished">RPN14</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN14</source>
+ <translation type="unfinished">NRPN14</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Pitch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Program</source>
+ <translation type="unfinished">Programa</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Hi:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Lo:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Learn</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MidiFilterConfigBase</name>
<message>
<location filename="../../muse/mplugins/midifilter.ui" line="+20"/>
@@ -6149,7 +6241,7 @@ Entradas habilitadas en la lista
<context>
<name>MusECore::Song</name>
<message>
- <location filename="../../muse/song.cpp" line="+2274"/>
+ <location filename="../../muse/song.cpp" line="+2284"/>
<source>Jack shutdown!</source>
<translation>Detener Jack</translation>
</message>
@@ -6186,13 +6278,13 @@ Para comprobar el estado de Jack y reiniciar el servidor.
haga clic en el botón Reiniciar.</translation>
</message>
<message>
- <location line="+172"/>
- <location line="+165"/>
+ <location line="+179"/>
+ <location line="+238"/>
<source>Automation:</source>
<translation>Automatización</translation>
</message>
<message>
- <location line="-163"/>
+ <location line="-236"/>
<source>previous event</source>
<translation>evento anterior</translation>
</message>
@@ -6203,24 +6295,24 @@ haga clic en el botón Reiniciar.</translation>
</message>
<message>
<location line="+9"/>
- <location line="+155"/>
+ <location line="+228"/>
<source>set event</source>
<translation></translation>
</message>
<message>
- <location line="-153"/>
- <location line="+155"/>
+ <location line="-226"/>
+ <location line="+228"/>
<source>add event</source>
<translation>agregar evento</translation>
</message>
<message>
- <location line="-151"/>
- <location line="+155"/>
+ <location line="-224"/>
+ <location line="+228"/>
<source>erase event</source>
<translation>borrar evento</translation>
</message>
<message>
- <location line="-151"/>
+ <location line="-224"/>
<source>erase range</source>
<translation>borrar rango</translation>
</message>
@@ -6230,7 +6322,22 @@ haga clic en el botón Reiniciar.</translation>
<translation>limpiar automatizacion</translation>
</message>
<message>
- <location line="+29"/>
+ <location line="+6"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+45"/>
<source>Clear all controller events?</source>
<translation>Limpiar todos los eventos de control</translation>
</message>
@@ -6245,7 +6352,18 @@ haga clic en el botón Reiniciar.</translation>
<translation>&amp;Cancelar</translation>
</message>
<message>
- <location line="+767"/>
+ <location line="+267"/>
+ <source>MusE: Tempo list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+592"/>
<source>MusE - external script failed</source>
<translation>MusE - fallo de orden externa</translation>
</message>
@@ -6967,7 +7085,7 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::AudioStrip</name>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="+687"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="+678"/>
<source>panorama</source>
<translation>panorama</translation>
</message>
@@ -6982,7 +7100,7 @@ To apply the changes, please restart MusE. Sorry.
<translation>Paneo</translation>
</message>
<message>
- <location line="+92"/>
+ <location line="+91"/>
<source>1/2 channel</source>
<translation>Canales 1/2</translation>
</message>
@@ -7002,7 +7120,7 @@ To apply the changes, please restart MusE. Sorry.
<translation>dB</translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+31"/>
<source>record</source>
<translation>grabar</translation>
</message>
@@ -7066,7 +7184,7 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::BigTime</name>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="+62"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="+63"/>
<source>format display</source>
<translation>Formato de vista</translation>
</message>
@@ -8307,18 +8425,18 @@ Do you want to apply to all existing midi tracks now?</source>
</message>
<message>
<location line="+65"/>
- <location line="+848"/>
+ <location line="+852"/>
<source>in</source>
<translation>Entrada</translation>
</message>
<message>
- <location line="-825"/>
- <location line="+817"/>
+ <location line="-829"/>
+ <location line="+821"/>
<source>out</source>
<translation>Salida</translation>
</message>
<message>
- <location line="-773"/>
+ <location line="-777"/>
<source>Show first aliases</source>
<translation>Mostrar primero los álias</translation>
</message>
@@ -8345,7 +8463,7 @@ Do you want to apply to all existing midi tracks now?</source>
<translation>Crear conexión Jack</translation>
</message>
<message>
- <location line="+286"/>
+ <location line="+290"/>
<location line="+28"/>
<source>Port Number</source>
<translation>Número de puerto</translation>
@@ -9287,12 +9405,12 @@ Comprobar si Jack está en ejecución</translation>
</message>
<message>
<location line="+4"/>
- <location line="+253"/>
+ <location line="+251"/>
<source>Panic</source>
<translation>Pánico</translation>
</message>
<message>
- <location line="-251"/>
+ <location line="-249"/>
<source>send note off to all midi channels</source>
<translation>envia un apagado de nota (note off) a todos los canales midi</translation>
</message>
@@ -9325,13 +9443,13 @@ Comprobar si Jack está en ejecución</translation>
</message>
<message>
<location line="+2"/>
- <location line="+972"/>
+ <location line="+970"/>
<location line="+1229"/>
<source>&amp;Save</source>
<translation>&amp;Guardar</translation>
</message>
<message>
- <location line="-2199"/>
+ <location line="-2197"/>
<location line="+3"/>
<source>Click this button to save the song you are editing. You will be prompted for a file name.
You can also select the Save command from the File menu.</source>
@@ -9505,7 +9623,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo.</translation>
<translation>Limpiar datos de automatización</translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+3"/>
<source>Cascade</source>
<translation>Cascada</translation>
</message>
@@ -9821,6 +9939,21 @@ Guardar el proyecto actual?</translation>
<translation>&amp;Abortar</translation>
</message>
<message>
+ <location line="+114"/>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../../muse/exportmidi.cpp" line="+139"/>
<source>MusE: Export Midi</source>
<translation>MusE: Exportar MIDI</translation>
@@ -10076,8 +10209,13 @@ Files:</source>
<translation>Nombre de región: %1
Archivos:</translation>
</message>
+ <message>
+ <location line="+109"/>
+ <source>Remove selected</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <location line="+2105"/>
+ <location line="+2024"/>
<source>%n part(s) out of %1 could not be pasted.
Likely the selected track is the wrong type.</source>
<translation>
@@ -10369,7 +10507,7 @@ Probablemente la pista seleccionada es del tipo incorrecto.</numerusform>
<context>
<name>MusEGui::PluginDialog</name>
<message>
- <location filename="../../muse/plugin.cpp" line="+2846"/>
+ <location filename="../../muse/plugin.cpp" line="+2825"/>
<source>MusE: select plugin</source>
<translation>MusE: Selecciona el plugin</translation>
</message>
@@ -10474,7 +10612,12 @@ Probablemente la pista seleccionada es del tipo incorrecto.</numerusform>
<translation>Cancelar</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+9"/>
+ <source>Show plugs:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
<source>Mono and Stereo</source>
<translation>Mono y estereo</translation>
</message>
@@ -10543,7 +10686,7 @@ Probablemente la pista seleccionada es del tipo incorrecto.</numerusform>
<translation>saltar plugin</translation>
</message>
<message>
- <location line="+498"/>
+ <location line="+505"/>
<source>MusE: load preset</source>
<translation>MusE: Cargar plantilla</translation>
</message>
@@ -10989,7 +11132,7 @@ El título seleccionado ya existe.</translation>
<context>
<name>MusEGui::Strip</name>
<message>
- <location filename="../../muse/mixer/strip.cpp" line="+313"/>
+ <location filename="../../muse/mixer/strip.cpp" line="+326"/>
<source>Remove track?</source>
<translation type="unfinished"></translation>
</message>
@@ -10997,7 +11140,7 @@ El título seleccionado ya existe.</translation>
<context>
<name>MusEGui::TList</name>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="+408"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="+413"/>
<source>&lt;none&gt;</source>
<translation>&lt;ningúno&gt;</translation>
</message>
@@ -11054,29 +11197,29 @@ El título seleccionado ya existe.</translation>
</message>
<message>
<location line="+90"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>Update drummap?</source>
<translation>¿Actualizár mapa de percusión?</translation>
</message>
<message>
- <location line="-1275"/>
+ <location line="-1424"/>
<source>Do you want to use same port for all instruments in the drummap?</source>
<translation>¿Desea utilizar el mismo puerto para todos los instrumentos en el mapa de percusión?</translation>
</message>
<message>
<location line="+1"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>&amp;Yes</source>
<translation>Aceptar</translation>
</message>
<message>
- <location line="-1276"/>
- <location line="+1276"/>
+ <location line="-1425"/>
+ <location line="+1425"/>
<source>&amp;No</source>
<translation>Cancelar</translation>
</message>
<message>
- <location line="-1210"/>
+ <location line="-1359"/>
<location line="+41"/>
<source>show gui</source>
<translation>Ver interfáz</translation>
@@ -11088,7 +11231,22 @@ El título seleccionado ya existe.</translation>
<translation>Ver interfáz nativa</translation>
</message>
<message>
- <location line="+361"/>
+ <location line="+335"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+119"/>
<source>Treble clef</source>
<translation>Partitura de agudos</translation>
</message>
@@ -11108,6 +11266,16 @@ El título seleccionado ya existe.</translation>
<translation>Automatización visible</translation>
</message>
<message>
+ <location line="+16"/>
+ <source>Internal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Synth</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+133"/>
<source>Delete Track</source>
<translation>Borrar pista</translation>
@@ -12068,7 +12236,7 @@ no existe.
<translation>falló la creación de carpeta</translation>
</message>
<message>
- <location line="+375"/>
+ <location line="+400"/>
<source>File
%1
exists. Overwrite?</source>
@@ -13332,18 +13500,18 @@ Robert Jonsson
<translation>Decay [ms]</translation>
</message>
<message>
- <location line="+59"/>
- <location line="+41"/>
+ <location line="+62"/>
+ <location line="+44"/>
<source>dB</source>
<translation>dB</translation>
</message>
<message>
- <location line="-31"/>
+ <location line="-34"/>
<source>Dry Level [dB]</source>
<translation>Dry Level [dB]</translation>
</message>
<message>
- <location line="+41"/>
+ <location line="+44"/>
<source>Wet Level [dB]</source>
<translation>Wet Level [dB]</translation>
</message>
diff --git a/muse2/share/locale/muse_fr.ts b/muse2/share/locale/muse_fr.ts
index 9eb6abbf..4c1f27bf 100644
--- a/muse2/share/locale/muse_fr.ts
+++ b/muse2/share/locale/muse_fr.ts
@@ -89,7 +89,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="+503"/>
+ <location filename="../../muse/midiseq.cpp" line="+510"/>
<source>Bad timing</source>
<translation type="unfinished"></translation>
</message>
@@ -98,7 +98,7 @@
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
-Also please check console output for any further error messages
+Also please check console output for any further error messages.
</source>
<translation type="unfinished"></translation>
</message>
@@ -112,12 +112,12 @@ Also please check console output for any further error messages
</message>
<message>
<location line="+37"/>
- <source>Version 2 pre-alpha</source>
+ <source>Version 2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+10"/>
- <source>(C) Copyright 1999-2010 Werner Schweer and others.
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
See http://www.muse-sequencer.org for new versions and
more information.
@@ -590,7 +590,7 @@ Published under the GNU Public License</source>
<message>
<location filename="../../awl/midivolentry.cpp" line="+37"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="+1"/>
@@ -603,7 +603,7 @@ Published under the GNU Public License</source>
<message>
<location filename="../../awl/volentry.cpp" line="+34"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
</context>
<context>
@@ -782,7 +782,7 @@ Published under the GNU Public License</source>
<message>
<location line="+16"/>
<source>&amp;Cancel</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Annuler</translation>
</message>
</context>
<context>
@@ -2722,7 +2722,7 @@ Wave form 8 = &lt;i&gt;if &lt;b&gt;t&lt;/b&gt;&amp;#060 pi then sin(2*&lt;b&gt;t
<location line="+10"/>
<location line="+16"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="+42"/>
@@ -2737,7 +2737,7 @@ Wave form 8 = &lt;i&gt;if &lt;b&gt;t&lt;/b&gt;&amp;#060 pi then sin(2*&lt;b&gt;t
<message>
<location line="+16"/>
<source>&amp;Cancel</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Annuler</translation>
</message>
</context>
<context>
@@ -2790,7 +2790,7 @@ Wave form 8 = &lt;i&gt;if &lt;b&gt;t&lt;/b&gt;&amp;#060 pi then sin(2*&lt;b&gt;t
<message>
<location line="+26"/>
<source>&amp;Cancel</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Annuler</translation>
</message>
<message>
<location line="+3"/>
@@ -3231,7 +3231,7 @@ True range: Min: -8192 Max: 8191 (bias 0)</source>
<location line="+198"/>
<location line="+53"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="-261"/>
@@ -3276,7 +3276,7 @@ Caution! Watch out for controllers such as
<location line="+17"/>
<source>off</source>
<comment>dont care</comment>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="+23"/>
@@ -4729,6 +4729,84 @@ Distant</translation>
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="+14"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Channel:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Control type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Control7</source>
+ <translation type="unfinished">Control7</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Control14</source>
+ <translation type="unfinished">Control8</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN</source>
+ <translation type="unfinished">RPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN</source>
+ <translation type="unfinished">NRPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN14</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN14</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Pitch</source>
+ <translation type="unfinished">Hauteur</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Program</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Hi:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Lo:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Learn</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MidiFilterConfigBase</name>
<message>
<location filename="../../muse/mplugins/midifilter.ui" line="+20"/>
@@ -6077,7 +6155,7 @@ Enabled inputs in the list will
<context>
<name>MusECore::Song</name>
<message>
- <location filename="../../muse/song.cpp" line="+2274"/>
+ <location filename="../../muse/song.cpp" line="+2284"/>
<source>Jack shutdown!</source>
<translation type="unfinished"></translation>
</message>
@@ -6101,13 +6179,13 @@ click on the Restart button.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+172"/>
- <location line="+165"/>
+ <location line="+179"/>
+ <location line="+238"/>
<source>Automation:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-163"/>
+ <location line="-236"/>
<source>previous event</source>
<translation type="unfinished"></translation>
</message>
@@ -6118,24 +6196,24 @@ click on the Restart button.</source>
</message>
<message>
<location line="+9"/>
- <location line="+155"/>
+ <location line="+228"/>
<source>set event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-153"/>
- <location line="+155"/>
+ <location line="-226"/>
+ <location line="+228"/>
<source>add event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-151"/>
- <location line="+155"/>
+ <location line="-224"/>
+ <location line="+228"/>
<source>erase event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-151"/>
+ <location line="-224"/>
<source>erase range</source>
<translation type="unfinished"></translation>
</message>
@@ -6145,7 +6223,22 @@ click on the Restart button.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+29"/>
+ <location line="+6"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+45"/>
<source>Clear all controller events?</source>
<translation type="unfinished"></translation>
</message>
@@ -6157,10 +6250,21 @@ click on the Restart button.</source>
<message>
<location line="+0"/>
<source>&amp;Cancel</source>
+ <translation type="unfinished">&amp;Annuler</translation>
+ </message>
+ <message>
+ <location line="+267"/>
+ <source>MusE: Tempo list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+767"/>
+ <location line="+592"/>
<source>MusE - external script failed</source>
<translation type="unfinished"></translation>
</message>
@@ -6390,7 +6494,7 @@ Right-click to show GUI.</source>
<message>
<location line="+15"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Long</translation>
</message>
<message>
<location line="+10"/>
@@ -6870,7 +6974,7 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::AudioStrip</name>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="+687"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="+678"/>
<source>panorama</source>
<translation type="unfinished"></translation>
</message>
@@ -6885,7 +6989,7 @@ To apply the changes, please restart MusE. Sorry.
<translation type="unfinished">Pan</translation>
</message>
<message>
- <location line="+92"/>
+ <location line="+91"/>
<source>1/2 channel</source>
<translation type="unfinished">1/2 canal</translation>
</message>
@@ -6905,7 +7009,7 @@ To apply the changes, please restart MusE. Sorry.
<translation type="unfinished">dB</translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+31"/>
<source>record</source>
<translation type="unfinished"></translation>
</message>
@@ -6928,7 +7032,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+8"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="+26"/>
@@ -6969,7 +7073,7 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::BigTime</name>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="+62"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="+63"/>
<source>format display</source>
<translation type="unfinished"></translation>
</message>
@@ -7087,7 +7191,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+1"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="+425"/>
@@ -7339,7 +7443,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+1"/>
<source>Quantize</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Quantiser</translation>
</message>
<message>
<location line="+1"/>
@@ -7439,7 +7543,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+1"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Long</translation>
</message>
<message>
<location line="+1"/>
@@ -8161,7 +8265,7 @@ polyphonique</translation>
<message>
<location line="+1"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Long</translation>
</message>
<message>
<location line="+1"/>
@@ -8208,18 +8312,18 @@ Do you want to apply to all existing midi tracks now?</source>
</message>
<message>
<location line="+65"/>
- <location line="+848"/>
+ <location line="+852"/>
<source>in</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-825"/>
- <location line="+817"/>
+ <location line="-829"/>
+ <location line="+821"/>
<source>out</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-773"/>
+ <location line="-777"/>
<source>Show first aliases</source>
<translation type="unfinished"></translation>
</message>
@@ -8246,7 +8350,7 @@ Do you want to apply to all existing midi tracks now?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+286"/>
+ <location line="+290"/>
<location line="+28"/>
<source>Port Number</source>
<translation type="unfinished">Numéro de port</translation>
@@ -8596,7 +8700,7 @@ Do you want to apply to all existing midi tracks now?</source>
<location line="+124"/>
<location line="+104"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="-227"/>
@@ -9150,7 +9254,7 @@ droit</translation>
<message>
<location line="+5"/>
<source>Record</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Enregistre</translation>
</message>
<message>
<location line="+2"/>
@@ -9160,12 +9264,12 @@ Lecture (Play)</translation>
</message>
<message>
<location line="+4"/>
- <location line="+253"/>
+ <location line="+251"/>
<source>Panic</source>
<translation type="unfinished">Panique!</translation>
</message>
<message>
- <location line="-251"/>
+ <location line="-249"/>
<source>send note off to all midi channels</source>
<translation type="unfinished">envoyer ordre de relachement de note � tous les canaux
midi</translation>
@@ -9199,13 +9303,13 @@ midi</translation>
</message>
<message>
<location line="+2"/>
- <location line="+972"/>
+ <location line="+970"/>
<location line="+1229"/>
<source>&amp;Save</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-2199"/>
+ <location line="-2197"/>
<location line="+3"/>
<source>Click this button to save the song you are editing. You will be prompted for a file name.
You can also select the Save command from the File menu.</source>
@@ -9378,7 +9482,7 @@ You can also select the Save command from the File menu.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+3"/>
<source>Cascade</source>
<translation type="unfinished"></translation>
</message>
@@ -9605,7 +9709,7 @@ non encore sauvegardées. Enregistrer?</translation>
<message>
<location line="-1229"/>
<source>&amp;Cancel</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Annuler</translation>
</message>
<message>
<location line="+242"/>
@@ -9692,6 +9796,21 @@ avant d&apos;en ouvrir un autre?</translation>
<translation type="unfinished">&amp;Annuler</translation>
</message>
<message>
+ <location line="+114"/>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../../muse/exportmidi.cpp" line="+139"/>
<source>MusE: Export Midi</source>
<translation type="unfinished">MusE: exporter fichier MIDI</translation>
@@ -9831,7 +9950,7 @@ Do you still want to import it?</source>
<message>
<location line="+11"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Long</translation>
</message>
<message>
<location line="+10"/>
@@ -9940,8 +10059,13 @@ différent</translation>
Files:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location line="+109"/>
+ <source>Remove selected</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <location line="+2105"/>
+ <location line="+2024"/>
<source>%n part(s) out of %1 could not be pasted.
Likely the selected track is the wrong type.</source>
<translation type="unfinished">
@@ -10117,7 +10241,7 @@ sélectionnées</translation>
<message>
<location line="+4"/>
<source>Quantize</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Quantiser</translation>
</message>
<message>
<location line="+4"/>
@@ -10228,7 +10352,7 @@ sélectionnées</translation>
<context>
<name>MusEGui::PluginDialog</name>
<message>
- <location filename="../../muse/plugin.cpp" line="+2846"/>
+ <location filename="../../muse/plugin.cpp" line="+2825"/>
<source>MusE: select plugin</source>
<translation type="unfinished">MusE: choisir plugin</translation>
</message>
@@ -10333,7 +10457,12 @@ sélectionnées</translation>
<translation type="unfinished">Annuler</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+9"/>
+ <source>Show plugs:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
<source>Mono and Stereo</source>
<translation type="unfinished"></translation>
</message>
@@ -10402,7 +10531,7 @@ sélectionnées</translation>
<translation type="unfinished">Plugin de Direct (bypass)</translation>
</message>
<message>
- <location line="+498"/>
+ <location line="+505"/>
<source>MusE: load preset</source>
<translation type="unfinished">MusE: charger réglages</translation>
</message>
@@ -10847,7 +10976,7 @@ the selected title is not unique</source>
<context>
<name>MusEGui::Strip</name>
<message>
- <location filename="../../muse/mixer/strip.cpp" line="+313"/>
+ <location filename="../../muse/mixer/strip.cpp" line="+326"/>
<source>Remove track?</source>
<translation type="unfinished"></translation>
</message>
@@ -10855,7 +10984,7 @@ the selected title is not unique</source>
<context>
<name>MusEGui::TList</name>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="+408"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="+413"/>
<source>&lt;none&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -10888,7 +11017,7 @@ the selected title is not unique</source>
<location line="+29"/>
<location line="+414"/>
<source>off</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">off</translation>
</message>
<message>
<location line="-405"/>
@@ -10912,29 +11041,29 @@ the selected title is not unique</source>
</message>
<message>
<location line="+90"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>Update drummap?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1275"/>
+ <location line="-1424"/>
<source>Do you want to use same port for all instruments in the drummap?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>&amp;Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1276"/>
- <location line="+1276"/>
+ <location line="-1425"/>
+ <location line="+1425"/>
<source>&amp;No</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1210"/>
+ <location line="-1359"/>
<location line="+41"/>
<source>show gui</source>
<translation type="unfinished">montrer l&apos;interface</translation>
@@ -10946,7 +11075,22 @@ the selected title is not unique</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+361"/>
+ <location line="+335"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+119"/>
<source>Treble clef</source>
<translation type="unfinished"></translation>
</message>
@@ -10966,6 +11110,16 @@ the selected title is not unique</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+16"/>
+ <source>Internal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Synth</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+133"/>
<source>Delete Track</source>
<translation type="unfinished"></translation>
@@ -10973,7 +11127,7 @@ the selected title is not unique</source>
<message>
<location line="+1"/>
<source>Track Comment</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Commentaire pour la Piste</translation>
</message>
<message>
<location line="+3"/>
@@ -10983,7 +11137,7 @@ the selected title is not unique</source>
<message>
<location line="+582"/>
<source>Midi</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Midi</translation>
</message>
<message>
<location line="+1"/>
@@ -11922,7 +12076,7 @@ Create it?</source>
<translation>échec de la création du répertoire</translation>
</message>
<message>
- <location line="+375"/>
+ <location line="+400"/>
<source>File
%1
exists. Overwrite?</source>
@@ -12261,7 +12415,7 @@ p, li { white-space: pre-wrap; }
<message>
<location line="+32"/>
<source>&amp;Cancel</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Annuler</translation>
</message>
<message>
<location line="+3"/>
@@ -12493,7 +12647,7 @@ p, li { white-space: pre-wrap; }
<message>
<location line="+23"/>
<source>&amp;Cancel</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Annuler</translation>
</message>
<message>
<location line="+3"/>
@@ -13165,18 +13319,18 @@ Robert Jonsson
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+59"/>
- <location line="+41"/>
+ <location line="+62"/>
+ <location line="+44"/>
<source>dB</source>
<translation type="unfinished">dB</translation>
</message>
<message>
- <location line="-31"/>
+ <location line="-34"/>
<source>Dry Level [dB]</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+41"/>
+ <location line="+44"/>
<source>Wet Level [dB]</source>
<translation type="unfinished"></translation>
</message>
@@ -13997,7 +14151,7 @@ Robert Jonsson
<message>
<location line="+6"/>
<source>Quantize</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Quantiser</translation>
</message>
<message>
<location line="+1"/>
diff --git a/muse2/share/locale/muse_pl.ts b/muse2/share/locale/muse_pl.ts
index 8049f459..7b654e37 100644
--- a/muse2/share/locale/muse_pl.ts
+++ b/muse2/share/locale/muse_pl.ts
@@ -89,7 +89,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../muse/midiseq.cpp" line="+503"/>
+ <location filename="../../muse/midiseq.cpp" line="+510"/>
<source>Bad timing</source>
<translation type="unfinished"></translation>
</message>
@@ -98,7 +98,7 @@
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
-Also please check console output for any further error messages
+Also please check console output for any further error messages.
</source>
<translation type="unfinished"></translation>
</message>
@@ -112,12 +112,12 @@ Also please check console output for any further error messages
</message>
<message>
<location line="+37"/>
- <source>Version 2 pre-alpha</source>
+ <source>Version 2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+10"/>
- <source>(C) Copyright 1999-2010 Werner Schweer and others.
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
See http://www.muse-sequencer.org for new versions and
more information.
@@ -519,7 +519,7 @@ Published under the GNU Public License</source>
<message>
<location line="+5"/>
<source>Pitch</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Transpozycja</translation>
</message>
<message>
<location line="+5"/>
@@ -2192,7 +2192,7 @@ Wave form 8 = &lt;i&gt;if &lt;b&gt;t&lt;/b&gt;&amp;#060 pi then sin(2*&lt;b&gt;t
<location line="+91"/>
<location line="+140"/>
<source>Pitch</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Transpozycja</translation>
</message>
<message>
<location line="-378"/>
@@ -2539,7 +2539,7 @@ Wave form 8 = &lt;i&gt;if &lt;b&gt;t&lt;/b&gt;&amp;#060 pi then sin(2*&lt;b&gt;t
<message>
<location line="+26"/>
<source>Pan</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Panorama</translation>
</message>
</context>
<context>
@@ -4728,6 +4728,84 @@ Adjusts responsiveness of audio controls and
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <location filename="../../muse/widgets/midi_audio_control_base.ui" line="+14"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Channel:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Control type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Control7</source>
+ <translation type="unfinished">Kontroler7</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Control14</source>
+ <translation type="unfinished">Kontroler14</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN</source>
+ <translation type="unfinished">RPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN</source>
+ <translation type="unfinished">NRPN</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>RPN14</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>NRPN14</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Pitch</source>
+ <translation type="unfinished">Transpozycja</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Program</source>
+ <translation type="unfinished">Program</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Hi:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Lo:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Learn</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MidiFilterConfigBase</name>
<message>
<location filename="../../muse/mplugins/midifilter.ui" line="+20"/>
@@ -6076,7 +6154,7 @@ Enabled inputs in the list will
<context>
<name>MusECore::Song</name>
<message>
- <location filename="../../muse/song.cpp" line="+2274"/>
+ <location filename="../../muse/song.cpp" line="+2284"/>
<source>Jack shutdown!</source>
<translation type="unfinished"></translation>
</message>
@@ -6100,13 +6178,13 @@ click on the Restart button.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+172"/>
- <location line="+165"/>
+ <location line="+179"/>
+ <location line="+238"/>
<source>Automation:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-163"/>
+ <location line="-236"/>
<source>previous event</source>
<translation type="unfinished"></translation>
</message>
@@ -6117,24 +6195,24 @@ click on the Restart button.</source>
</message>
<message>
<location line="+9"/>
- <location line="+155"/>
+ <location line="+228"/>
<source>set event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-153"/>
- <location line="+155"/>
+ <location line="-226"/>
+ <location line="+228"/>
<source>add event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-151"/>
- <location line="+155"/>
+ <location line="-224"/>
+ <location line="+228"/>
<source>erase event</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-151"/>
+ <location line="-224"/>
<source>erase range</source>
<translation type="unfinished"></translation>
</message>
@@ -6144,7 +6222,22 @@ click on the Restart button.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+29"/>
+ <location line="+6"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+45"/>
<source>Clear all controller events?</source>
<translation type="unfinished"></translation>
</message>
@@ -6159,7 +6252,18 @@ click on the Restart button.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+767"/>
+ <location line="+267"/>
+ <source>MusE: Tempo list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+592"/>
<source>MusE - external script failed</source>
<translation type="unfinished"></translation>
</message>
@@ -6389,7 +6493,7 @@ Right-click to show GUI.</source>
<message>
<location line="+15"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Długość</translation>
</message>
<message>
<location line="+10"/>
@@ -6431,7 +6535,7 @@ Right-click to show GUI.</source>
<message>
<location line="+5"/>
<source>Pitch</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Transpozycja</translation>
</message>
<message>
<location line="+8"/>
@@ -6467,7 +6571,7 @@ Right-click to show GUI.</source>
<message>
<location line="+13"/>
<source>R</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">R</translation>
</message>
<message>
<location line="+1"/>
@@ -6492,7 +6596,7 @@ Right-click to show GUI.</source>
<message>
<location line="+1"/>
<source>Port</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Port</translation>
</message>
<message>
<location line="+1"/>
@@ -6595,7 +6699,7 @@ Right-click to show GUI.</source>
<message>
<location line="+2"/>
<source>Select</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Wybierz</translation>
</message>
<message>
<location line="+3"/>
@@ -6869,7 +6973,7 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::AudioStrip</name>
<message>
- <location filename="../../muse/mixer/astrip.cpp" line="+687"/>
+ <location filename="../../muse/mixer/astrip.cpp" line="+678"/>
<source>panorama</source>
<translation type="unfinished">Panorama</translation>
</message>
@@ -6881,10 +6985,10 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+23"/>
<source>Pan</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Panorama</translation>
</message>
<message>
- <location line="+92"/>
+ <location line="+91"/>
<source>1/2 channel</source>
<translation type="unfinished">kanał m/s</translation>
</message>
@@ -6904,7 +7008,7 @@ To apply the changes, please restart MusE. Sorry.
<translation type="unfinished">dB</translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+31"/>
<source>record</source>
<translation type="unfinished"></translation>
</message>
@@ -6968,7 +7072,7 @@ To apply the changes, please restart MusE. Sorry.
<context>
<name>MusEGui::BigTime</name>
<message>
- <location filename="../../muse/widgets/bigtime.cpp" line="+62"/>
+ <location filename="../../muse/widgets/bigtime.cpp" line="+63"/>
<source>format display</source>
<translation type="unfinished"></translation>
</message>
@@ -7092,7 +7196,7 @@ To apply the changes, please restart MusE. Sorry.
<location line="+425"/>
<location line="+236"/>
<source>Velocity</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Prędk. uderz. (vel)</translation>
</message>
<message>
<location line="-186"/>
@@ -7288,7 +7392,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+1"/>
<source>Invert</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Odwróć</translation>
</message>
<message>
<location line="+2"/>
@@ -7338,7 +7442,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+1"/>
<source>Quantize</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Kwantyzuj</translation>
</message>
<message>
<location line="+1"/>
@@ -7438,7 +7542,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+1"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Długość</translation>
</message>
<message>
<location line="+1"/>
@@ -7453,7 +7557,7 @@ To apply the changes, please restart MusE. Sorry.
<message>
<location line="+1"/>
<source>Port</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Port</translation>
</message>
<message>
<location line="+1"/>
@@ -7695,7 +7799,7 @@ Save Current Instrument?</source>
<message>
<location line="+3"/>
<source>Pitch</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Transpozycja</translation>
</message>
<message>
<location line="+2"/>
@@ -8153,7 +8257,7 @@ Kliknij na pojedynczy klocek aby go wyłączyć z odtwarzania.</translation>
<message>
<location line="+1"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Długość</translation>
</message>
<message>
<location line="+1"/>
@@ -8200,18 +8304,18 @@ Do you want to apply to all existing midi tracks now?</source>
</message>
<message>
<location line="+65"/>
- <location line="+848"/>
+ <location line="+852"/>
<source>in</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-825"/>
- <location line="+817"/>
+ <location line="-829"/>
+ <location line="+821"/>
<source>out</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-773"/>
+ <location line="-777"/>
<source>Show first aliases</source>
<translation type="unfinished"></translation>
</message>
@@ -8238,7 +8342,7 @@ Do you want to apply to all existing midi tracks now?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+286"/>
+ <location line="+290"/>
<location line="+28"/>
<source>Port Number</source>
<translation type="unfinished">Numer portu</translation>
@@ -8356,7 +8460,7 @@ Do you want to apply to all existing midi tracks now?</source>
<message>
<location line="+40"/>
<source>Port</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Port</translation>
</message>
<message>
<location line="+1"/>
@@ -8639,7 +8743,7 @@ Do you want to apply to all existing midi tracks now?</source>
<message>
<location line="+0"/>
<source>Pan</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Panorama</translation>
</message>
<message>
<location line="+15"/>
@@ -8867,7 +8971,7 @@ Note: It may be impossible to rewind fast
<message>
<location line="+142"/>
<source>Port</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Port</translation>
</message>
<message>
<location line="+1"/>
@@ -9149,19 +9253,19 @@ Apply sync settings?</source>
</message>
<message>
<location line="+4"/>
- <location line="+253"/>
+ <location line="+251"/>
<source>Panic</source>
<translation type="unfinished">Zatrzymaj wszystkie komunikaty midi!</translation>
</message>
<message>
- <location line="-251"/>
+ <location line="-249"/>
<source>send note off to all midi channels</source>
<translation type="unfinished">Zatrzymaj komunikaty midi na wszystkich kanałach!</translation>
</message>
<message>
<location line="+6"/>
<source>&amp;New</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Nowy</translation>
</message>
<message>
<location line="+1"/>
@@ -9188,13 +9292,13 @@ Apply sync settings?</source>
</message>
<message>
<location line="+2"/>
- <location line="+972"/>
+ <location line="+970"/>
<location line="+1229"/>
<source>&amp;Save</source>
<translation type="unfinished">&amp;Zapisz</translation>
</message>
<message>
- <location line="-2199"/>
+ <location line="-2197"/>
<location line="+3"/>
<source>Click this button to save the song you are editing. You will be prompted for a file name.
You can also select the Save command from the File menu.</source>
@@ -9370,7 +9474,7 @@ Zgrywanie śladu (bounce)</translation>
<translation type="unfinished">Wyczyść automatykę</translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+3"/>
<source>Cascade</source>
<translation type="unfinished"></translation>
</message>
@@ -9684,6 +9788,21 @@ Zapisać otwarty utwór?</translation>
<translation type="unfinished">&amp;Anuluj</translation>
</message>
<message>
+ <location line="+114"/>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../../muse/exportmidi.cpp" line="+139"/>
<source>MusE: Export Midi</source>
<translation type="unfinished">MuzA: Exportuj Midi</translation>
@@ -9821,12 +9940,12 @@ Do you still want to import it?</source>
<message>
<location line="+11"/>
<source>Len</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Długość</translation>
</message>
<message>
<location line="+10"/>
<source>Pitch</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Transpozycja</translation>
</message>
<message>
<location line="+9"/>
@@ -9929,8 +10048,13 @@ Do you still want to import it?</source>
Files:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location line="+109"/>
+ <source>Remove selected</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <location line="+2105"/>
+ <location line="+2024"/>
<source>%n part(s) out of %1 could not be pasted.
Likely the selected track is the wrong type.</source>
<translation type="unfinished">
@@ -10105,7 +10229,7 @@ Likely the selected track is the wrong type.</source>
<message>
<location line="+4"/>
<source>Quantize</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Kwantyzuj</translation>
</message>
<message>
<location line="+4"/>
@@ -10216,7 +10340,7 @@ Likely the selected track is the wrong type.</source>
<context>
<name>MusEGui::PluginDialog</name>
<message>
- <location filename="../../muse/plugin.cpp" line="+2846"/>
+ <location filename="../../muse/plugin.cpp" line="+2825"/>
<source>MusE: select plugin</source>
<translation type="unfinished">MuzA: wybierz wtyczkę</translation>
</message>
@@ -10321,7 +10445,12 @@ Likely the selected track is the wrong type.</source>
<translation type="unfinished">Anuluj</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+9"/>
+ <source>Show plugs:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
<source>Mono and Stereo</source>
<translation type="unfinished"></translation>
</message>
@@ -10390,7 +10519,7 @@ Likely the selected track is the wrong type.</source>
<translation type="unfinished">omiń wtyczkę (bypass)</translation>
</message>
<message>
- <location line="+498"/>
+ <location line="+505"/>
<source>MusE: load preset</source>
<translation type="unfinished">MuzA: załaduj ustawienie</translation>
</message>
@@ -10835,7 +10964,7 @@ the selected title is not unique</source>
<context>
<name>MusEGui::Strip</name>
<message>
- <location filename="../../muse/mixer/strip.cpp" line="+313"/>
+ <location filename="../../muse/mixer/strip.cpp" line="+326"/>
<source>Remove track?</source>
<translation type="unfinished"></translation>
</message>
@@ -10843,7 +10972,7 @@ the selected title is not unique</source>
<context>
<name>MusEGui::TList</name>
<message>
- <location filename="../../muse/arranger/tlist.cpp" line="+408"/>
+ <location filename="../../muse/arranger/tlist.cpp" line="+413"/>
<source>&lt;none&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -10900,29 +11029,29 @@ the selected title is not unique</source>
</message>
<message>
<location line="+90"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>Update drummap?</source>
<translation type="unfinished">Zaktualizować zestaw perkusyjny?</translation>
</message>
<message>
- <location line="-1275"/>
+ <location line="-1424"/>
<source>Do you want to use same port for all instruments in the drummap?</source>
<translation type="unfinished">Czy chcesz używać jednego portu midi dla wszystkich instrumentów w zestawie perkusyjnym?</translation>
</message>
<message>
<location line="+1"/>
- <location line="+1276"/>
+ <location line="+1425"/>
<source>&amp;Yes</source>
<translation type="unfinished">&amp;Tak</translation>
</message>
<message>
- <location line="-1276"/>
- <location line="+1276"/>
+ <location line="-1425"/>
+ <location line="+1425"/>
<source>&amp;No</source>
<translation type="unfinished">&amp;Nie</translation>
</message>
<message>
- <location line="-1210"/>
+ <location line="-1359"/>
<location line="+41"/>
<source>show gui</source>
<translation type="unfinished">pokaż interfejs użytkownika</translation>
@@ -10934,7 +11063,22 @@ the selected title is not unique</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+361"/>
+ <location line="+335"/>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+119"/>
<source>Treble clef</source>
<translation type="unfinished"></translation>
</message>
@@ -10954,6 +11098,16 @@ the selected title is not unique</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+16"/>
+ <source>Internal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Synth</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+133"/>
<source>Delete Track</source>
<translation type="unfinished"></translation>
@@ -10961,7 +11115,7 @@ the selected title is not unique</source>
<message>
<location line="+1"/>
<source>Track Comment</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Opis śladu</translation>
</message>
<message>
<location line="+3"/>
@@ -11453,7 +11607,7 @@ the selected title is not unique</source>
<message>
<location line="+4"/>
<source>Select</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Wybierz</translation>
</message>
<message>
<location line="+2"/>
@@ -11635,7 +11789,7 @@ Missing data is muted</source>
<message>
<location line="+23"/>
<source>Velocity</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Prędk. uderz. (vel)</translation>
</message>
</context>
<context>
@@ -11899,7 +12053,7 @@ Create it?</source>
<translation>tworzenie katalogu nie powiodło się</translation>
</message>
<message>
- <location line="+375"/>
+ <location line="+400"/>
<source>File
%1
exists. Overwrite?</source>
@@ -12121,7 +12275,7 @@ If swing is -33, you get a 1:2-rhythm.
<message>
<location line="+13"/>
<source>Velocity</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Prędk. uderz. (vel)</translation>
</message>
<message>
<location line="+7"/>
@@ -12260,7 +12414,7 @@ p, li { white-space: pre-wrap; }
<message>
<location line="+7"/>
<source>&amp;OK</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">&amp;Akceptuj</translation>
</message>
<message>
<location line="+3"/>
@@ -12780,7 +12934,7 @@ in current
<message>
<location line="+16"/>
<source>Invert</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Odwróć</translation>
</message>
<message>
<location line="+13"/>
@@ -12826,7 +12980,7 @@ in current
<location line="+12"/>
<location line="+538"/>
<source>Pitch</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Transpozycja</translation>
</message>
<message>
<location line="-506"/>
@@ -13152,18 +13306,18 @@ Robert Jonsson
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+59"/>
- <location line="+41"/>
+ <location line="+62"/>
+ <location line="+44"/>
<source>dB</source>
<translation type="unfinished">dB</translation>
</message>
<message>
- <location line="-31"/>
+ <location line="-34"/>
<source>Dry Level [dB]</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+41"/>
+ <location line="+44"/>
<source>Wet Level [dB]</source>
<translation type="unfinished"></translation>
</message>
@@ -13984,7 +14138,7 @@ Robert Jonsson
<message>
<location line="+6"/>
<source>Quantize</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Kwantyzuj</translation>
</message>
<message>
<location line="+1"/>
diff --git a/muse2/share/locale/muse_ru.ts b/muse2/share/locale/muse_ru.ts
index b3421a79..19876ed8 100644
--- a/muse2/share/locale/muse_ru.ts
+++ b/muse2/share/locale/muse_ru.ts
@@ -79,7 +79,7 @@
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
-Also please check console output for any further error messages
+Also please check console output for any further error messages.
</source>
<translation type="unfinished"></translation>
</message>
@@ -92,7 +92,7 @@ Also please check console output for any further error messages
</message>
<message>
<source>Version 2 pre-alpha</source>
- <translation>Версия 2.0~rc2 (svn revision: 0)</translation>
+ <translation type="obsolete">Версия 2.0~rc2 (svn revision: 0)</translation>
</message>
<message>
<source>(C) Copyright 1999-2010 Werner Schweer and others.
@@ -100,7 +100,7 @@ See http://www.muse-sequencer.org for new versions and
more information.
Published under the GNU Public License</source>
- <translation>(C) Copyright 1999-2010 Werner Schweer и другие.
+ <translation type="obsolete">(C) Copyright 1999-2010 Werner Schweer и другие.
На http://www.muse-sequencer.org смотрите новые версии и
дополнительную информацию.
@@ -114,6 +114,22 @@ Published under the GNU Public License</source>
<source>Alt+K</source>
<translation>Alt+K</translation>
</message>
+ <message>
+ <source>Version 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
+See http://www.muse-sequencer.org for new versions and
+more information.
+
+Published under the GNU Public License</source>
+ <translation type="unfinished">(C) Copyright 1999-2010 Werner Schweer и другие.
+На http://www.muse-sequencer.org смотрите новые версии и
+дополнительную информацию.
+
+Опубликовано на условиях GNU Public License {1999-2012 ?}</translation>
+ </message>
</context>
<context>
<name>AppearanceDialogBase</name>
@@ -3644,6 +3660,69 @@ Adjusts responsiveness of audio controls and
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Channel:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Control type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Control7</source>
+ <translation type="unfinished">Контрл7</translation>
+ </message>
+ <message>
+ <source>Control14</source>
+ <translation type="unfinished">Контрл14</translation>
+ </message>
+ <message>
+ <source>RPN</source>
+ <translation type="unfinished">RPN</translation>
+ </message>
+ <message>
+ <source>NRPN</source>
+ <translation type="unfinished">NRPN</translation>
+ </message>
+ <message>
+ <source>RPN14</source>
+ <translation type="unfinished">RPN14</translation>
+ </message>
+ <message>
+ <source>NRPN14</source>
+ <translation type="unfinished">NRPN14</translation>
+ </message>
+ <message>
+ <source>Pitch</source>
+ <translation type="unfinished">Высота тона</translation>
+ </message>
+ <message>
+ <source>Program</source>
+ <translation type="unfinished">Программа</translation>
+ </message>
+ <message>
+ <source>Hi:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Lo:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Learn</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MidiFilterConfigBase</name>
<message>
<source>MusE: Midi Input Filter</source>
@@ -4720,6 +4799,27 @@ click on the Restart button.</source>
<translation>MusE не смог запустить скрипт, ошибка:
%1</translation>
</message>
+ <message>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MusE: Tempo list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>MusEGui::Appearance</name>
@@ -7675,6 +7775,19 @@ Do you still want to import it?</source>
<source>About &amp;Qt</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>MusEGui::NoteInfo</name>
@@ -7821,6 +7934,10 @@ Likely the selected track is the wrong type.</source>
<source>Cannot paste: wrong data type</source>
<translation>Вставка невозможна: неверный тип данных</translation>
</message>
+ <message>
+ <source>Remove selected</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>MusEGui::PasteDialog</name>
@@ -8139,6 +8256,10 @@ Likely the selected track is the wrong type.</source>
<source>ladspa</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Show plugs:</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>MusEGui::PluginGui</name>
@@ -8622,6 +8743,26 @@ the selected title is not unique</source>
<source>&lt;unknown&gt;</source>
<translation type="unfinished">&lt;неизвестно&gt;</translation>
</message>
+ <message>
+ <source>Midi control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Assign</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Internal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Synth</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>MusEGui::TempoSig</name>
diff --git a/muse2/share/locale/muse_sv_SE.ts b/muse2/share/locale/muse_sv_SE.ts
index b8f1b25b..9c8808f3 100644
--- a/muse2/share/locale/muse_sv_SE.ts
+++ b/muse2/share/locale/muse_sv_SE.ts
@@ -73,15 +73,18 @@
</message>
<message>
<source>Bad timing</source>
- <translation type="unfinished"></translation>
+ <translation>Dålig timing</translation>
</message>
<message>
<source>Timing source frequency is %1hz, which is below the recommended minimum: 500hz!
This could lead to audible timing problems for MIDI.
Please see the FAQ on http://muse-sequencer.org for remedies.
-Also please check console output for any further error messages
+Also please check console output for any further error messages.
</source>
- <translation type="unfinished"></translation>
+ <translation>Frekvensen på tidkällan är %1hz vilket är under det rekommenderade minsta värdet: 500hz!
+Det kan leda till hörbara timingproblem för MIDI.
+See FAQ på http://muse-sequencer.org för lösningsförslag.
+See också terminalutskrifter för eventuella fler felmeddelanden.</translation>
</message>
</context>
<context>
@@ -91,24 +94,28 @@ Also please check console output for any further error messages
<translation>Om</translation>
</message>
<message>
- <source>Version 2 pre-alpha</source>
- <translation></translation>
+ <source>&amp;Keep On Rocking!</source>
+ <translation>&amp;Rocka på!</translation>
</message>
<message>
- <source>(C) Copyright 1999-2010 Werner Schweer and others.
-See http://www.muse-sequencer.org for new versions and
-more information.
-
-Published under the GNU Public License</source>
+ <source>Alt+K</source>
<translation></translation>
</message>
<message>
- <source>&amp;Keep On Rocking!</source>
- <translation>&amp;Rocka på!</translation>
+ <source>Version 2</source>
+ <translation></translation>
</message>
<message>
- <source>Alt+K</source>
- <translation></translation>
+ <source>(C) Copyright 1999-2012 Werner Schweer and others.
+See http://www.muse-sequencer.org for new versions and
+more information.
+
+Published under the GNU Public License</source>
+ <translation>(C) Copyright 1999-2012 Werner Schweer och andra.
+Se http://www.muse-sequencer.org för nya versioner och
+mer information.
+
+Publicerad under GNU Public License</translation>
</message>
</context>
<context>
@@ -355,107 +362,107 @@ Published under the GNU Public License</source>
</message>
<message>
<source>May require restarting MusE for best results</source>
- <translation type="unfinished"></translation>
+ <translation>Kan kräva omstart av MusE för bästa resultat</translation>
</message>
</context>
<context>
<name>ArrangerColumnsBase</name>
<message>
<source>Configure arranger columns</source>
- <translation type="unfinished"></translation>
+ <translation>Konfigurera arrangerarkolumner</translation>
</message>
<message>
<source>Columns:</source>
- <translation type="unfinished"></translation>
+ <translation>Kolumner:</translation>
</message>
<message>
<source>Name:</source>
- <translation type="unfinished">Namn:</translation>
+ <translation>Namn:</translation>
</message>
<message>
<source>Controller type:</source>
- <translation type="unfinished"></translation>
+ <translation>Kontroltyp:</translation>
</message>
<message>
<source>Midi controller type</source>
- <translation type="unfinished">Midi kontrolltyp</translation>
+ <translation>Midi kontrolltyp</translation>
</message>
<message>
<source>Control7</source>
- <translation type="unfinished">Kontroll7</translation>
+ <translation>Kontroll7</translation>
</message>
<message>
<source>Control14</source>
- <translation type="unfinished">Kontroll14</translation>
+ <translation>Kontroll14</translation>
</message>
<message>
<source>RPN</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>NRPN</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>RPN14</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>NRPN14</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>Pitch</source>
- <translation type="unfinished">Tonhöjd</translation>
+ <translation>Tonhöjd</translation>
</message>
<message>
<source>Program</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>H-Ctrl</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>Midi controller number high byte</source>
- <translation type="unfinished">Midikontroll-nummer, hög byte</translation>
+ <translation>Midikontroll-nummer, hög byte</translation>
</message>
<message>
<source>L-Ctrl</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>Midi controller number low byte</source>
- <translation type="unfinished"></translation>
+ <translation>Midikontrollnummer, låg byte</translation>
</message>
<message>
<source>*</source>
<comment>wild card</comment>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>affect CCs at</source>
- <translation type="unfinished"></translation>
+ <translation>påverkar CC vid</translation>
</message>
<message>
<source>begin of song</source>
- <translation type="unfinished"></translation>
+ <translation>början på sång</translation>
</message>
<message>
<source>current position</source>
- <translation type="unfinished"></translation>
+ <translation>nuvarande position</translation>
</message>
<message>
<source>&amp;Add</source>
- <translation type="unfinished">&amp;Lägg till</translation>
+ <translation>&amp;Lägg till</translation>
</message>
<message>
<source>&amp;Delete</source>
- <translation type="unfinished">&amp;Ta bort</translation>
+ <translation>&amp;Ta bort</translation>
</message>
<message>
<source>Done</source>
- <translation type="unfinished"></translation>
+ <translation>Färdig</translation>
</message>
</context>
<context>
@@ -516,7 +523,7 @@ Published under the GNU Public License</source>
</message>
<message>
<source>Samplerate</source>
- <translation type="unfinished"></translation>
+ <translation>Samplingshastighet</translation>
</message>
</context>
<context>
@@ -1924,47 +1931,47 @@ Wave form 8 = &lt;i&gt;if &lt;b&gt;t&lt;/b&gt;&amp;#060 pi then sin(2*&lt;b&gt;t
<name>DuplicateTracksBase</name>
<message>
<source>Duplicate tracks</source>
- <translation type="unfinished"></translation>
+ <translation>Duplicera spår</translation>
</message>
<message>
<source>Number of copies</source>
- <translation type="unfinished"></translation>
+ <translation>Antal kopior</translation>
</message>
<message>
<source>Copy all routes</source>
- <translation type="unfinished"></translation>
+ <translation>Kopiera alla kopplingar</translation>
</message>
<message>
<source>Default routing</source>
- <translation type="unfinished"></translation>
+ <translation>Förvald koppling</translation>
</message>
<message>
<source>No routes</source>
- <translation type="unfinished"></translation>
+ <translation>Inga kopplingar</translation>
</message>
<message>
<source>Copy parts</source>
- <translation type="unfinished"></translation>
+ <translation>Kopiera parter</translation>
</message>
<message>
<source>Copy standard controllers (vol, pan)</source>
- <translation type="unfinished"></translation>
+ <translation>Kopiera standardkontroller (vol, pan)</translation>
</message>
<message>
<source>Copy effects rack plugins</source>
- <translation type="unfinished"></translation>
+ <translation>Kopiera effektrack-instickseffekter</translation>
</message>
<message>
<source>Copy plugin controllers</source>
- <translation type="unfinished"></translation>
+ <translation>Kopiera instickseffekt-kontroller</translation>
</message>
<message>
<source>Ok</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>Cancel</source>
- <translation type="unfinished">Avbryt</translation>
+ <translation>Avbryt</translation>
</message>
</context>
<context>
@@ -2623,17 +2630,17 @@ Vanligtvis inställd på 127/127, eller genom att använda
<message>
<source>---</source>
<comment>dont care</comment>
- <translation type="unfinished"></translation>
+ <translation>ignorera</translation>
</message>
<message>
<source>*</source>
<comment>wild card</comment>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>off</source>
<comment>dont care</comment>
- <translation type="unfinished">av</translation>
+ <translation>av</translation>
</message>
</context>
<context>
@@ -3368,28 +3375,29 @@ fokus till respektive editor</translation>
</message>
<message>
<source>Choose start song or template</source>
- <translation type="unfinished"></translation>
+ <translation>Välj startsång eller mall</translation>
</message>
<message>
<source>Reset to default</source>
- <translation type="unfinished"></translation>
+ <translation>Återställ till förvalt</translation>
</message>
<message>
<source>start with template</source>
- <translation type="unfinished"></translation>
+ <translation>Starta med mall</translation>
</message>
<message>
<source>Start template or song:</source>
- <translation type="unfinished"></translation>
+ <translation>Startmall eller sång:</translation>
</message>
<message>
<source>Read MIDI Ports configuration from file,
or else automatically configure</source>
- <translation type="unfinished"></translation>
+ <translation>Läs MIDI-port konfiguration från fil,
+eller i annatfall, konfigurera automatiskt</translation>
</message>
<message>
<source>Read MIDI Ports configuration</source>
- <translation type="unfinished"></translation>
+ <translation>läs midi-portkonfiguration</translation>
</message>
</context>
<context>
@@ -3644,6 +3652,69 @@ fokus till respektive editor</translation>
</message>
</context>
<context>
+ <name>MidiAudioControlBase</name>
+ <message>
+ <source>Midi control</source>
+ <translation>Midikontroll</translation>
+ </message>
+ <message>
+ <source>Port:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Channel:</source>
+ <translation>Kanal:</translation>
+ </message>
+ <message>
+ <source>Control type:</source>
+ <translation>Kontrolltyp:</translation>
+ </message>
+ <message>
+ <source>Control7</source>
+ <translation>Kontroll7</translation>
+ </message>
+ <message>
+ <source>Control14</source>
+ <translation>Kontroll14</translation>
+ </message>
+ <message>
+ <source>RPN</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>NRPN</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>RPN14</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>NRPN14</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Pitch</source>
+ <translation>Tonhöjd</translation>
+ </message>
+ <message>
+ <source>Program</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Hi:</source>
+ <translation>Hög:</translation>
+ </message>
+ <message>
+ <source>Lo:</source>
+ <translation>Låg:</translation>
+ </message>
+ <message>
+ <source>Learn</source>
+ <translation>Lär</translation>
+ </message>
+</context>
+<context>
<name>MidiControllerEditDialogBase</name>
<message>
<source>MusE: Define Midi Controller</source>
@@ -4436,23 +4507,23 @@ program change-, pitchbend-, men inte SysEX- eller realtids-event på de valda k
</message>
<message>
<source>Bank Select MSB. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Bankval MSB. Ctrl-dubbelklick av/på.</translation>
</message>
<message>
<source>Bank Select LSB. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Bankval LSB. Ctrl-dubbelklick av/på.</translation>
</message>
<message>
<source>Program. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Program. Ctrl-dubbelklick av/på.</translation>
</message>
<message>
<source>Volume. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Volym. Ctrl-dubbelklick av/på.</translation>
</message>
<message>
<source>Change stereo position. Ctrl-double-click on/off.</source>
- <translation type="unfinished"></translation>
+ <translation>Byt stereo position. Ctrl-dubbelklick av/på.</translation>
</message>
</context>
<context>
@@ -4873,6 +4944,28 @@ För att fortsätta, säkerställ att Jack är igång och klicka på Omstart kna
%1</source>
<translation>MusE kunde inte starta skript, felmeddelande: %1</translation>
</message>
+ <message>
+ <source>Midi control</source>
+ <translation>Midikontroll</translation>
+ </message>
+ <message>
+ <source>Assign</source>
+ <translation>Tilldela</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Rensa</translation>
+ </message>
+ <message>
+ <source>MusE: Tempo list</source>
+ <translation>MusE: Tempolista</translation>
+ </message>
+ <message>
+ <source>External tempo changes were recorded.
+Transfer them to master tempo list?</source>
+ <translation>Externa tempoändringar har spelats in.
+För över dem till master-tempolistan?</translation>
+ </message>
</context>
<context>
<name>MusEGui::Appearance</name>
@@ -5395,18 +5488,21 @@ Högerklick för at visa GUI.</translation>
</message>
<message>
<source>Configure &amp;custom columns</source>
- <translation type="unfinished"></translation>
+ <translation>Konfigurera &amp;anpassade kolumner</translation>
</message>
<message>
<source>Changed Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Ändrade inställningar</translation>
</message>
<message>
<source>Unfortunately, the changed arranger column settings
cannot be applied while MusE is running.
To apply the changes, please restart MusE. Sorry.
(we&apos;ll try to fix that)</source>
- <translation type="unfinished"></translation>
+ <translation>Tyvärr kan inte de ändrade kolumninställningarna
+i arrangeraren appliceras när MusE kör.
+För att aktivera starta om MusE. (Vi kommer att
+försöka fixa det senare)</translation>
</message>
</context>
<context>
@@ -5671,7 +5767,7 @@ To apply the changes, please restart MusE. Sorry.
</message>
<message>
<source>ctrl-double-click on/off</source>
- <translation type="unfinished"></translation>
+ <translation>kontroll dubbelklick av/på</translation>
</message>
</context>
<context>
@@ -6316,7 +6412,7 @@ klicka på en part för att Tysta/Avtysta</translation>
<name>MusEGui::GlobalSettingsConfig</name>
<message>
<source>MusE: Choose start template or song</source>
- <translation type="unfinished"></translation>
+ <translation>MusE: Välj startsång eller mall</translation>
</message>
</context>
<context>
@@ -6964,7 +7060,7 @@ Vill du att gälla för alla befintliga MIDI-spår?</translation>
</message>
<message>
<source>ctrl-double-click on/off</source>
- <translation type="unfinished"></translation>
+ <translation>kontroll dubbelklick av/på</translation>
</message>
</context>
<context>
@@ -7870,32 +7966,52 @@ Vill du importera den ändå?</translation>
</message>
<message>
<source>Song Position</source>
- <translation type="unfinished"></translation>
+ <translation>Sångposition</translation>
</message>
<message>
<source>Tempo</source>
- <translation type="unfinished">Tempo</translation>
+ <translation>Tempo</translation>
</message>
<message>
<source>Signature</source>
- <translation type="unfinished">Signatur</translation>
+ <translation>Signatur</translation>
</message>
<message numerus="yes">
<source>%n part(s) out of %1 could not be imported.
Likely the selected track is the wrong type.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n parter av %1 kunde inte importeras.
+Antagligen var det valda spåret av fel typ.</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n part(s) could not be imported.
Likely the selected track is the wrong type.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n parter kunde inte importeras.
+Antagligen var det valda spåret av fel typ.</numerusform>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>This will clear all automation data on
+ all audio tracks!
+Proceed?</source>
+ <translation>Detta rensar all automationsdata på
+alla ljudspår!
+Fortsätt?</translation>
+ </message>
+ <message>
+ <source>This takes an automation snapshot of
+ all controllers on all audio tracks,
+ at the current position.
+Proceed?</source>
+ <translation>Detta tar en ögonblicks bild av automationen
+för alla kontrollrar på alla ljudspår vid den
+nuvarande positionen.
+Försätt?</translation>
+ </message>
</context>
<context>
<name>MusEGui::NoteInfo</name>
@@ -7925,7 +8041,7 @@ Likely the selected track is the wrong type.</source>
</message>
<message>
<source>delta/absolute mode</source>
- <translation type="unfinished"></translation>
+ <translation>delta/absolut-läge</translation>
</message>
</context>
<context>
@@ -8027,19 +8143,25 @@ Filer:</translation>
<message numerus="yes">
<source>%n part(s) out of %1 could not be pasted.
Likely the selected track is the wrong type.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n parter av %1 kunde inte klistras in.
+Antagligen var det valda spåret av fel typ.</numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n part(s) could not be pasted.
Likely the selected track is the wrong type.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n parter kunde inte klistras in.
+Antagligen var det valda spåret av fel typ.</numerusform>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Remove selected</source>
+ <translation>Ta bort valt</translation>
+ </message>
</context>
<context>
<name>MusEGui::PasteDialog</name>
@@ -8055,8 +8177,8 @@ Likely the selected track is the wrong type.</source>
</message>
<message numerus="yes">
<source>%n quarter(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1 kvartar</numerusform>
<numerusform></numerusform>
</translation>
</message>
@@ -8075,8 +8197,8 @@ Likely the selected track is the wrong type.</source>
</message>
<message numerus="yes">
<source>%n quarter(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1 kvartar</numerusform>
<numerusform></numerusform>
</translation>
</message>
@@ -8328,47 +8450,51 @@ Likely the selected track is the wrong type.</source>
</message>
<message>
<source>Type</source>
- <translation type="unfinished">Typ</translation>
+ <translation>Typ</translation>
</message>
<message>
<source>Audio inputs</source>
- <translation type="unfinished"></translation>
+ <translation>Ljudingång</translation>
</message>
<message>
<source>Audio outputs</source>
- <translation type="unfinished"></translation>
+ <translation>Ljudutgång</translation>
</message>
<message>
<source>Control inputs</source>
- <translation type="unfinished"></translation>
+ <translation>Kontrollingångar</translation>
</message>
<message>
<source>Control outputs</source>
- <translation type="unfinished"></translation>
+ <translation>Kontrollutgångar</translation>
</message>
<message>
<source>In-place capable</source>
- <translation type="unfinished"></translation>
+ <translation>Påplats-kapabel</translation>
</message>
<message>
<source>ID number</source>
- <translation type="unfinished"></translation>
+ <translation>ID-nummer</translation>
</message>
<message>
<source>Select which types of plugins should be visible in the list.&lt;br&gt;Note that using mono plugins on stereo tracks is not a problem, two will be used in parallel.&lt;br&gt;Also beware that the &apos;all&apos; alternative includes plugins that may not be useful in an effect rack.</source>
- <translation type="unfinished"></translation>
+ <translation>Välj vilka typer av instickseffekter som skall vara synliga i listan.&lt;br&gt;Notera att användning av mono effekter på ett stereospår inte är något problem, två instanser kommer&lt;br&gt; att att användas parallellt. Var också medveten om att &apos;alla&apos; alternativet inkluderar instickseffekter kanske inte går använda i ett effektrack.</translation>
</message>
<message>
<source>dssi synth</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<source>dssi effect</source>
- <translation type="unfinished"></translation>
+ <translation>dssi-effekt</translation>
</message>
<message>
<source>ladspa</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Show plugs:</source>
+ <translation>Visa instickseffekter:</translation>
</message>
</context>
<context>
@@ -8840,11 +8966,11 @@ Den valda titeln är inte unik</translation>
<name>MusEGui::SigToolbarWidget</name>
<message>
<source>time signature at current position</source>
- <translation type="unfinished">time signature vid nuvarande position</translation>
+ <translation>tid-signatur vid nuvarande position</translation>
</message>
<message>
<source>Signature: </source>
- <translation type="unfinished"></translation>
+ <translation>Signatur</translation>
</message>
</context>
<context>
@@ -8958,11 +9084,31 @@ Den valda titeln är inte unik</translation>
</message>
<message>
<source>off</source>
- <translation type="unfinished">av</translation>
+ <translation>av</translation>
</message>
<message>
<source>&lt;unknown&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;okänd&gt;</translation>
+ </message>
+ <message>
+ <source>Midi control</source>
+ <translation>Midikontroll</translation>
+ </message>
+ <message>
+ <source>Assign</source>
+ <translation>Tilldela</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Rensa</translation>
+ </message>
+ <message>
+ <source>Internal</source>
+ <translation>Intern</translation>
+ </message>
+ <message>
+ <source>Synth</source>
+ <translation>Synt</translation>
</message>
</context>
<context>
@@ -8976,11 +9122,11 @@ Den valda titeln är inte unik</translation>
<name>MusEGui::TempoToolbarWidget</name>
<message>
<source>tempo at current position</source>
- <translation type="unfinished">tempo vid nuvarande position</translation>
+ <translation>tempo vid nuvarande position</translation>
</message>
<message>
<source>Tempo: </source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
</context>
<context>
@@ -9062,27 +9208,27 @@ Den valda titeln är inte unik</translation>
</message>
<message>
<source>Undo/Redo tools</source>
- <translation type="unfinished"></translation>
+ <translation>Ångra/Gör om verktyg</translation>
</message>
<message>
<source>Panic</source>
- <translation type="unfinished">Panik</translation>
+ <translation>Panik</translation>
</message>
<message>
<source>Transport</source>
- <translation type="unfinished">Transport</translation>
+ <translation>Transport</translation>
</message>
<message>
<source>Song Position</source>
- <translation type="unfinished"></translation>
+ <translation>Sångposition</translation>
</message>
<message>
<source>Tempo</source>
- <translation type="unfinished">Tempo</translation>
+ <translation>Tempo</translation>
</message>
<message>
<source>Signature</source>
- <translation type="unfinished">Signatur</translation>
+ <translation>Signatur</translation>
</message>
</context>
<context>
diff --git a/muse2/share/templates/MusE.cfg b/muse2/share/templates/MusE.cfg
index 22ebbdea..550b44a8 100644
--- a/muse2/share/templates/MusE.cfg
+++ b/muse2/share/templates/MusE.cfg
@@ -12,7 +12,7 @@
<vstInPlace>0</vstInPlace>
<dummyAudioBufSize>512</dummyAudioBufSize>
<dummyAudioSampleRate>44100</dummyAudioSampleRate>
- <minControlProcessPeriod>64</minControlProcessPeriod>
+ <minControlProcessPeriod>256</minControlProcessPeriod>
<guiRefresh>20</guiRefresh>
<extendedMidi>1</extendedMidi>
<midiExportDivision>384</midiExportDivision>
diff --git a/muse2/synti/deicsonze/deicsonzegui.cpp b/muse2/synti/deicsonze/deicsonzegui.cpp
index b4965e7b..52f53b86 100644
--- a/muse2/synti/deicsonze/deicsonzegui.cpp
+++ b/muse2/synti/deicsonze/deicsonzegui.cpp
@@ -4558,7 +4558,7 @@ void DeicsOnzeGui::updatePreset() {
void DeicsOnzeGui::updateSelectPreset(int hbank, int lbank, int prog) {
//QTreeWidgetItem* cat = categoryListView->currentItem();
//QTreeWidgetItem* sub = subcategoryListView->currentItem();
- QTreeWidgetItem* pre = presetListView->currentItem();
+ //QTreeWidgetItem* pre = presetListView->currentItem();
//select category, subcategory, preset
//category
QList<QTreeWidgetItem *> qlcat =
@@ -4621,7 +4621,7 @@ void DeicsOnzeGui::updateSelectPreset(int hbank, int lbank, int prog) {
presetListView->scrollToItem(qpre);
updatePresetName(qpre->text(1), true);
updateProg(prog, true);
- pre=(QTreePreset*) qpre;
+ //pre=(QTreePreset*) qpre;
setEnabledPreset(true);
}
else {
diff --git a/muse2/synti/deicsonze/deicsonzeplugin.cpp b/muse2/synti/deicsonze/deicsonzeplugin.cpp
index 442a61c5..fff03bc1 100644
--- a/muse2/synti/deicsonze/deicsonzeplugin.cpp
+++ b/muse2/synti/deicsonze/deicsonzeplugin.cpp
@@ -300,12 +300,12 @@ void DeicsOnzeGui::buildGuiReverb() {
//for(int i = 0; i < plugI->plugin()->parameter(); i++) {
for(int i = 0; i < (int)plugI->plugin()->controlInPorts(); i++) {
///double min, max, val;
- float min, max, val;
+ float min, max; //, val;
plugI->range(i, &min, &max);
- val = _deicsOnze->getReverbParam(i);
// FIXME FIXME Tim
/*
+ val = _deicsOnze->getReverbParam(i);
if(plugI->isBool(i))
addPluginCheckBox(i, plugI->getParameterName(i), val > 0.0,
_reverbSuperWidget, grid, true);
@@ -351,12 +351,12 @@ void DeicsOnzeGui::buildGuiChorus() {
//for(int i = 0; i < plugI->plugin()->parameter(); i++) {
for(int i = 0; i < (int)plugI->plugin()->controlInPorts(); i++) {
///double min, max, val;
- float min, max, val;
+ float min, max; //, val;
plugI->range(i, &min, &max);
- val = _deicsOnze->getChorusParam(i);
// FIXME FIXME Tim
/*
+ val = _deicsOnze->getChorusParam(i);
if(plugI->isBool(i))
addPluginCheckBox(i, plugI->getParameterName(i), val > 0.0,
_chorusSuperWidget, grid, false);
diff --git a/muse2/synti/simpledrums2/simpledrums.cpp b/muse2/synti/simpledrums2/simpledrums.cpp
index 12e4fd18..4265c33c 100644
--- a/muse2/synti/simpledrums2/simpledrums.cpp
+++ b/muse2/synti/simpledrums2/simpledrums.cpp
@@ -664,10 +664,10 @@ const char* SimpleSynth::getPatchName(int /*index*/, int, int) const
\return MidiPatch with patch info for host
*/
//---------------------------------------------------------
-const MidiPatch* SimpleSynth::getPatchInfo(int index, const MidiPatch* patch) const
+const MidiPatch* SimpleSynth::getPatchInfo(int /*index*/, const MidiPatch* /*patch*/) const
{
SS_TRACE_IN
- index = 0; patch = 0;
+ //index = 0; patch = 0;
SS_TRACE_OUT
return 0;
}
@@ -1433,7 +1433,9 @@ static void* loadSampleThread(void* p)
// arg2 :sfi.frames is of type sf_count_t (== 64 bit) (long long)
// this requires format %lld (twice 'l' in format string (arg1)
// old code//printf("Resampling from %ld frames to %ld frames - srcration: %lf\n", sfi.frames, smp->frames, srcratio);
- printf("Resampling from %lld frames to %ld frames - srcration: %lf\n", sfi.frames, smp->frames, srcratio);
+ //printf("Resampling from %lld frames to %ld frames - srcration: %lf\n", sfi.frames, smp->frames, srcratio);
+ // Changed by Tim. Just avoid the hassle for now. Need to determine 32/64 bit and provide two different printf lines.
+ printf("Resampling to %ld frames - srcration: %lf\n", smp->frames, srcratio);
printf("Nr of new samples: %ld\n", smp->samples);
}
diff --git a/muse2/xpm/record_off.xpm b/muse2/xpm/record_off.xpm
index 3f25c366..d4891609 100644
--- a/muse2/xpm/record_off.xpm
+++ b/muse2/xpm/record_off.xpm
@@ -1,150 +1,70 @@
/* XPM */
static const char * record_off_xpm[] = {
-"15 15 132 2",
-" c None",
-". c #520002",
-"+ c #420002",
-"@ c #3F0002",
-"# c #350002",
-"$ c #3E0002",
-"% c #360002",
-"& c #370002",
-"* c #590006",
-"= c #490002",
-"- c #3F0000",
-"; c #450002",
-"> c #470003",
-", c #5A0006",
-"' c #430003",
-") c #3B0001",
-"! c #450200",
-"~ c #530006",
-"{ c #470000",
-"] c #520001",
-"^ c #5C0200",
-"/ c #760002",
-"( c #980201",
-"_ c #6E0006",
-": c #660004",
-"< c #630002",
-"[ c #3B0000",
-"} c #3B0200",
-"| c #5A0002",
-"1 c #4D0004",
-"2 c #610600",
-"3 c #740800",
-"4 c #990200",
-"5 c #B20201",
-"6 c #740000",
-"7 c #6E0200",
-"8 c #680200",
-"9 c #560200",
-"0 c #390100",
-"a c #460002",
-"b c #400000",
-"c c #590200",
-"d c #830800",
-"e c #A40B00",
-"f c #A80400",
-"g c #B00400",
-"h c #960400",
-"i c #6E0400",
-"j c #630300",
-"k c #450000",
-"l c #330000",
-"m c #700000",
-"n c #AA0300",
-"o c #A60300",
-"p c #AA0200",
-"q c #B40101",
-"r c #AC0400",
-"s c #8E0200",
-"t c #750000",
-"u c #590000",
-"v c #4B0002",
-"w c #680100",
-"x c #330002",
-"y c #9D0201",
-"z c #A70200",
-"A c #B00201",
-"B c #AC0001",
-"C c #B20101",
-"D c #C00000",
-"E c #AE0001",
-"F c #8C0004",
-"G c #530004",
-"H c #3A0000",
-"I c #540200",
-"J c #400002",
-"K c #560006",
-"L c #670006",
-"M c #7F0000",
-"N c #A70400",
-"O c #990300",
-"P c #AF0100",
-"Q c #8E0600",
-"R c #920400",
-"S c #9E0001",
-"T c #5A0004",
-"U c #430002",
-"V c #340000",
-"W c #510200",
-"X c #6A0004",
-"Y c #6C0200",
-"Z c #9C0200",
-"` c #B20200",
-" . c #930300",
-".. c #610000",
-"+. c #4F0003",
-"@. c #3F0003",
-"#. c #390002",
-"$. c #450003",
-"%. c #640002",
-"&. c #6A0200",
-"*. c #6A0400",
-"=. c #710001",
-"-. c #810004",
-";. c #900004",
-">. c #650000",
-",. c #540400",
-"'. c #500200",
-"). c #430000",
-"!. c #3F0004",
-"~. c #370001",
-"{. c #350000",
-"]. c #590300",
-"^. c #570000",
-"/. c #510004",
-"(. c #5F0004",
-"_. c #5D0002",
-":. c #4F0200",
-"<. c #3D0000",
-"[. c #450004",
-"}. c #4D0200",
-"|. c #4C0002",
-"1. c #440002",
-"2. c #490003",
-"3. c #380000",
-"4. c #370000",
-"5. c #3E0000",
-"6. c #310000",
-"7. c #390000",
-"8. c #4A0006",
-"9. c #440004",
-"0. c #670100",
-"a. c #5E0200",
-" ",
-" . + @ # $ % & ",
-" * = - ; > , - ' ) ! ",
-" ~ { ] ^ / ( _ : < [ } ",
-" | 1 ] 2 3 4 5 6 7 8 9 - 0 ",
-" a b c d e f 5 g h i j k l ",
-" @ - m n o p q r s t u v [ w ",
-" x > y z A B C D E F G = H I ",
-" J K L M N O P Q R S T U V W ",
-" # b X Y R Z ` .8 ..| +.@. ",
-" #.$.%.&.*.=.-.;.>.,.'.).!. ",
-" ~.{.].*.^./.(._.:.<.$ [. ",
-" }.} - ).a |.1.2.{ 3.} ",
-" 0 4.5.b 6.7.8.9. ",
-" 0.}.a. "};
+"13 13 54 1",
+" c None",
+". c #790000",
+"+ c #7A0000",
+"@ c #780000",
+"# c #770000",
+"$ c #740000",
+"% c #6B0000",
+"& c #730000",
+"* c #710000",
+"= c #640000",
+"- c #620000",
+"; c #6D0000",
+"> c #760000",
+", c #6A0000",
+"' c #5E0000",
+") c #5A0000",
+"! c #720000",
+"~ c #610000",
+"{ c #570000",
+"] c #530000",
+"^ c #5B0000",
+"/ c #6F0000",
+"( c #6E0000",
+"_ c #680000",
+": c #600000",
+"< c #580000",
+"[ c #4E0000",
+"} c #4A0000",
+"| c #510000",
+"1 c #5C0000",
+"2 c #560000",
+"3 c #450000",
+"4 c #460000",
+"5 c #4C0000",
+"6 c #520000",
+"7 c #590000",
+"8 c #550000",
+"9 c #500000",
+"0 c #4B0000",
+"a c #440000",
+"b c #3D0000",
+"c c #410000",
+"d c #490000",
+"e c #3F0000",
+"f c #380000",
+"g c #360000",
+"h c #3A0000",
+"i c #3E0000",
+"j c #3C0000",
+"k c #330000",
+"l c #2F0000",
+"m c #310000",
+"n c #300000",
+"o c #2E0000",
+" ..... ",
+" +.@@@@@@. ",
+" +.@.......# ",
+" #........@$ ",
+"%&.@.....@.*=",
+"-;>.......$,'",
+")=;$@...#!,~{",
+"]^-,/!!*(_:<[",
+"}|<'-===~12[3",
+" 4562<7<890a ",
+" bc3d}0}daef ",
+" ghbieijfk ",
+" lmmno "};
diff --git a/muse2/xpm/record_on.xpm b/muse2/xpm/record_on.xpm
index 64a67cf4..b0408a34 100644
--- a/muse2/xpm/record_on.xpm
+++ b/muse2/xpm/record_on.xpm
@@ -1,160 +1,88 @@
/* XPM */
static const char * record_on_xpm[] = {
-"15 15 142 2",
-" c None",
-". c #9B0500",
-"+ c #900601",
-"@ c #AF0205",
-"# c #980401",
-"$ c #AF0206",
-"% c #A70205",
-"& c #A80204",
-"* c #A9040A",
-"= c #990502",
-"- c #A00400",
-"; c #CC0004",
-"> c #A30404",
-", c #BD0212",
-"' c #B20207",
-") c #AC0201",
-"! c #A30800",
-"~ c #A70409",
-"{ c #990500",
-"] c #D50002",
-"^ c #DB0400",
-"/ c #E70004",
-"( c #F20010",
-"_ c #E30018",
-": c #E00010",
-"< c #C00202",
-"[ c #AB0200",
-"} c #AB0800",
-"| c #A90401",
-"1 c #A50406",
-"2 c #B90201",
-"3 c #DE1800",
-"4 c #E62300",
-"5 c #F10900",
-"6 c #FF0016",
-"7 c #E60000",
-"8 c #E40800",
-"9 c #E10900",
-"0 c #BB0600",
-"a c #BE0200",
-"b c #B00200",
-"c c #DA0400",
-"d c #EB2500",
-"e c #F33000",
-"f c #F80D00",
-"g c #FF0018",
-"h c #FE0F00",
-"i c #F11000",
-"j c #E40F00",
-"k c #DF0B00",
-"l c #B30200",
-"m c #A20200",
-"n c #BB0304",
-"o c #A00403",
-"p c #E40000",
-"q c #F90B00",
-"r c #FF0F00",
-"s c #F90006",
-"t c #FB0012",
-"u c #F40D00",
-"v c #EE0800",
-"w c #E70000",
-"x c #DA0000",
-"y c #D00004",
-"z c #AC0500",
-"A c #A40202",
-"B c #B40207",
-"C c #F40010",
-"D c #FD0014",
-"E c #FF0008",
-"F c #F70009",
-"G c #EE0010",
-"H c #D6000F",
-"I c #CF0009",
-"J c #A80800",
-"K c #BB0211",
-"L c #E10018",
-"M c #EA0000",
-"N c #F10B00",
-"O c #EE3000",
-"P c #EF0F00",
-"Q c #F5000D",
-"R c #DA0010",
-"S c #B10202",
-"T c #A50200",
-"U c #A70600",
-"V c #9B0403",
-"W c #970500",
-"X c #E20010",
-"Y c #E30800",
-"Z c #EF1000",
-"` c #F10800",
-" . c #FF0009",
-".. c #F01000",
-"+. c #E10800",
-"@. c #DE0000",
-"#. c #DA0004",
-"$. c #B80207",
-"%. c #AF0207",
-"&. c #EC0004",
-"*. c #AB0204",
-"=. c #B30207",
-"-. c #E20800",
-";. c #E20F00",
-">. c #E50002",
-",. c #EB000F",
-"'. c #EF000D",
-"). c #E00000",
-"!. c #D70F00",
-"~. c #B90500",
-"{. c #B10200",
-"]. c #AF020C",
-"^. c #A90201",
-"/. c #A70200",
-"(. c #DA0B00",
-"_. c #E20D00",
-":. c #D90000",
-"<. c #D5000F",
-"[. c #DD0010",
-"}. c #DC0004",
-"|. c #D30400",
-"1. c #AD0200",
-"2. c #AE0204",
-"3. c #B3020A",
-"4. c #9A0600",
-"5. c #AC0800",
-"6. c #AF0200",
-"7. c #C90000",
-"8. c #CD0004",
-"9. c #D10009",
-"0. c #CA0004",
-"a. c #B50207",
-"b. c #B40200",
-"c. c #9C0400",
-"d. c #A90400",
-"e. c #A30200",
-"f. c #AA0200",
-"g. c #B6020E",
-"h. c #A90402",
-"i. c #A50800",
-"j. c #AB0600",
-"k. c #B50302",
-" ",
-" . + @ # $ % & ",
-" * = - ; > , - ' ) ! ",
-" ~ { ] ^ / ( _ : < [ } ",
-" | 1 2 3 4 5 6 7 8 9 0 - a ",
-" > b c d e f g h i j k l m n ",
-" o - p q r s t u v w x y [ z ",
-" A B C 6 g D t E F G H I [ J ",
-" o K L M r N E O P Q R S T U ",
-" V W X Y Z ` ...+.@.#.$.%.&.",
-" *.=.< -.;.>.,.'.).!.~.{.]. ",
-" ^./.(._.:.<.[.}.|.1.2.3. ",
-" 4.5.6.7.8.9.0.a.b.c.} ",
-" d.e.6.b e.f.g.3. ",
-" h.z i.j.k. "};
+"13 13 72 1",
+" c None",
+". c #FF0000",
+"+ c #FE0000",
+"@ c #FC0101",
+"# c #F80202",
+"$ c #EA0707",
+"% c #F70303",
+"& c #F30505",
+"* c #E20A0A",
+"= c #E00A0A",
+"- c #EE0506",
+"; c #FB0101",
+"> c #E90707",
+", c #DB0C0C",
+"' c #D60E0E",
+") c #E30909",
+"! c #EF0505",
+"~ c #F90202",
+"{ c #FD0000",
+"] c #F60303",
+"^ c #EB0707",
+"/ c #DF0A0A",
+"( c #D10F0F",
+"_ c #CA1111",
+": c #D70E0D",
+"< c #E10A0A",
+"[ c #F00505",
+"} c #F40404",
+"| c #F60403",
+"1 c #F30404",
+"2 c #E70808",
+"3 c #DE0B0B",
+"4 c #D30E0E",
+"5 c #C71313",
+"6 c #C01515",
+"7 c #CA1212",
+"8 c #D30F0F",
+"9 c #DA0D0D",
+"0 c #E00B0B",
+"a c #E40909",
+"b c #E30A0A",
+"c c #D80D0D",
+"d c #D01010",
+"e c #BA1717",
+"f c #BB1717",
+"g c #C41414",
+"h c #CB1212",
+"i c #D40F0F",
+"j c #D30F10",
+"k c #CE1010",
+"l c #C91212",
+"m c #C21515",
+"n c #B91818",
+"o c #AE1B1B",
+"p c #B51A1A",
+"q c #BF1616",
+"r c #C31515",
+"s c #C11515",
+"t c #BE1616",
+"u c #B81818",
+"v c #B31A1A",
+"w c #AA1D1D",
+"x c #A51F1E",
+"y c #AF1B1B",
+"z c #B21A1A",
+"A c #B11A1B",
+"B c #A91D1D",
+"C c #A31F1F",
+"D c #9D2121",
+"E c #A02020",
+"F c #9F2121",
+"G c #9C2121",
+" .+++. ",
+" ..++.++++ ",
+" .++.......@ ",
+" @+......+.# ",
+"$%.+......+&*",
+"=-;.......%>,",
+"')!~{..+@]^/(",
+"_:<$[}|1!2345",
+"67890)ab3cd5e",
+" fghd8ijklmn ",
+" opeqmrstuvw ",
+" xwyzzAoBC ",
+" DEEFG "};