From c36a5508aa42e596b005425208054af9a60734b4 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Wed, 14 Dec 2011 15:08:02 +0000 Subject: pulled fixes from release into trunk --- muse2/CMakeLists.txt | 6 +- muse2/ChangeLog | 141 ++ muse2/README | 165 +- muse2/README.de | 1 + muse2/muse/app.cpp | 306 ++- muse2/muse/app.h | 17 +- muse2/muse/arranger/alayout.cpp | 2 +- muse2/muse/arranger/arranger.cpp | 59 +- muse2/muse/arranger/arrangerview.cpp | 29 +- muse2/muse/arranger/arrangerview.h | 10 +- muse2/muse/arranger/pcanvas.cpp | 144 +- muse2/muse/arranger/pcanvas.h | 6 +- muse2/muse/arranger/tlist.cpp | 169 +- muse2/muse/audio.cpp | 54 +- muse2/muse/audio.h | 10 +- muse2/muse/audioprefetch.cpp | 7 +- muse2/muse/audiotrack.cpp | 36 +- muse2/muse/cliplist/cliplist.cpp | 2 + muse2/muse/cobject.cpp | 22 +- muse2/muse/cobject.h | 18 +- muse2/muse/conf.cpp | 148 +- muse2/muse/confmport.cpp | 169 +- muse2/muse/ctrl/ctrlcanvas.cpp | 2 +- muse2/muse/driver/alsamidi.cpp | 259 ++- muse2/muse/driver/jack.cpp | 164 +- muse2/muse/driver/jackaudio.h | 1 + muse2/muse/dssihost.cpp | 294 ++- muse2/muse/dssihost.h | 7 +- muse2/muse/gconfig.cpp | 11 +- muse2/muse/gconfig.h | 5 +- muse2/muse/globals.cpp | 6 + muse2/muse/globals.h | 1 + muse2/muse/helper.cpp | 638 ++++-- muse2/muse/helper.h | 9 +- muse2/muse/instruments/editinstrument.cpp | 50 +- muse2/muse/instruments/minstrument.cpp | 62 + muse2/muse/instruments/minstrument.h | 8 +- muse2/muse/liste/editevent.cpp | 7 +- muse2/muse/liste/listedit.cpp | 3 + muse2/muse/main.cpp | 116 +- muse2/muse/marker/markerview.cpp | 5 +- muse2/muse/marker/markerview.h | 2 +- muse2/muse/master/lmaster.cpp | 2 + muse2/muse/master/masteredit.cpp | 2 + muse2/muse/midiedit/drumedit.cpp | 2 + muse2/muse/midiedit/ecanvas.cpp | 91 +- muse2/muse/midiedit/pianoroll.cpp | 2 + muse2/muse/midiedit/scoreedit.cpp | 181 +- muse2/muse/midiedit/scoreedit.h | 74 +- muse2/muse/midiport.cpp | 12 +- muse2/muse/midiseq.cpp | 25 +- muse2/muse/mixer/amixer.cpp | 2 +- muse2/muse/mixer/astrip.cpp | 38 +- muse2/muse/mixer/mstrip.cpp | 6 +- muse2/muse/mixer/strip.cpp | 24 +- muse2/muse/mixer/strip.h | 1 + muse2/muse/node.cpp | 769 ++++--- muse2/muse/osc.cpp | 21 +- muse2/muse/osc.h | 6 + muse2/muse/part.cpp | 12 + muse2/muse/plugin.cpp | 117 +- muse2/muse/plugin.h | 115 +- muse2/muse/remote/pyapi.cpp | 4 +- muse2/muse/route.cpp | 725 +++---- muse2/muse/route.h | 12 +- muse2/muse/shortcuts.cpp | 2 +- muse2/muse/song.cpp | 155 +- muse2/muse/song.h | 5 +- muse2/muse/songfile.cpp | 50 +- muse2/muse/structure.cpp | 238 ++- muse2/muse/structure.h | 7 +- muse2/muse/synth.cpp | 61 +- muse2/muse/synth.h | 8 + muse2/muse/ticksynth.cpp | 1 + muse2/muse/track.cpp | 155 +- muse2/muse/track.h | 68 +- muse2/muse/undo.cpp | 16 +- muse2/muse/undo.h | 1 + muse2/muse/vst.h | 1 + muse2/muse/wave.cpp | 24 +- muse2/muse/wave.h | 6 +- muse2/muse/waveedit/waveedit.cpp | 1 + muse2/muse/wavetrack.cpp | 8 +- muse2/muse/widgets/citem.h | 2 +- muse2/muse/widgets/filedialog.cpp | 42 +- muse2/muse/widgets/filedialog.h | 1 + muse2/muse/widgets/genset.cpp | 56 +- muse2/muse/widgets/genset.h | 4 +- muse2/muse/widgets/gensetbase.ui | 121 +- muse2/muse/widgets/header.cpp | 6 +- muse2/muse/widgets/knob.cpp | 24 + muse2/muse/widgets/knob.h | 1 + muse2/muse/widgets/meter.cpp | 7 +- muse2/muse/widgets/midisync.ui | 13 + muse2/muse/widgets/mtrackinfo.cpp | 33 +- muse2/muse/widgets/musewidgetsplug.cpp | 3 +- muse2/muse/widgets/popupmenu.cpp | 23 +- muse2/muse/widgets/poslabel.cpp | 6 +- muse2/muse/widgets/projectcreate.ui | 99 +- muse2/muse/widgets/projectcreateimpl.cpp | 191 +- muse2/muse/widgets/projectcreateimpl.h | 19 +- muse2/muse/widgets/routepopup.cpp | 48 +- muse2/muse/widgets/synthconfigbase.ui | 14 +- muse2/muse/widgets/utils.cpp | 3 +- muse2/muse/widgets/visibletracks.cpp | 2 + muse2/muse/widgets/visibletracks.h | 3 +- muse2/muse/xml.cpp | 94 +- muse2/share/locale/muse_de.ts | 424 ++-- muse2/share/locale/muse_en.ts | 1354 +++++++------ muse2/share/locale/muse_es.ts | 3112 +++++++++++++++-------------- muse2/share/locale/muse_fr.ts | 242 ++- muse2/share/locale/muse_pl.ts | 242 ++- muse2/share/locale/muse_ru.ts | 238 ++- muse2/share/locale/muse_sv_SE.ts | 242 ++- muse2/share/templates/MusE.cfg | 1 - muse2/share/templates/audio.med | 269 ++- muse2/share/templates/default.med | 93 +- muse2/share/templates/midiGM.med | 99 +- muse2/share/templates/monorecord.med | 530 ++++- muse2/share/templates/synti.med | 166 +- muse2/synti/fluid/CMakeLists.txt | 6 - muse2/synti/fluidsynth/CMakeLists.txt | 6 - 122 files changed, 8384 insertions(+), 5676 deletions(-) diff --git a/muse2/CMakeLists.txt b/muse2/CMakeLists.txt index cfffaa8e..b670930e 100644 --- a/muse2/CMakeLists.txt +++ b/muse2/CMakeLists.txt @@ -66,9 +66,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.0beta2") -SET(MusE_VERSION_FULL "2.0beta2") -SET(MusE_INSTALL_NAME "muse-2.0beta") +SET(MusE_VERSION "2.0rc1") +SET(MusE_VERSION_FULL "2.0rc1") +SET(MusE_INSTALL_NAME "muse-2.0rc1") SET(MusE_EXEC_NAME "muse2") ## The directory where we will install the shared components: diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 4e59198b..356e62d5 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,5 +1,146 @@ +12.12.2011: + * Improved: Midi ports list now fills automatically at start. (Marked as p4.0.41 Tim...) + An effort to help new users and others. If auto-filling the mid ports proves too much or unpopular, a simple change + will keep them out of the list, yet still auto-create and auto-connect Jack midi devices, which is still better than before. + Even if and when 'set and forget' configuration is added, this initial filling step may be welcome for new users. + NOTE: Virtually impossible to 'auto-pair' together Jack midi inputs and outputs. But I'm working on it, some code in there... + - When opening a song, choosing only 'Song data', without configuration, now does not upset the midi configuration at all, + yet controller data was attempted to be kept - may need to remove that effort. + - Moved start song loading into main.cpp, with helper in app.cpp. Disabled Florian's 'hackish loader', may be fixed now - TO BE TESTED!. + - List only writeable ports in track list output port column and midi track info combo box. + - Jack midi devices now save an additional required rwFlags xml tag. + - ALSA Midi fixes: (Un)subscription errors. Delete our simple port! Unsubscribe from announce port. Ignore SND_SEQ_PORT_CAP_NO_EXPORT + ports like 'qjackctrl' or 'port'. TODO: Possibly auto-assign newly discovered devices to available midi ports, in alsaScanMidiPorts(). + - Hack: "Midi Through" ALSA and Jack devices pushed to end of list, and list sorted, so useful outputs appear first. + - Stopped our own ALSA client from appearing as Jack midi alsa_pcm device. +10.12.2011: + - More improvements to project save dialog. And tries to suggest parent folder if saving existing project. (Tim...) + - Midi ports dialog: Auto dis/connect the stated default channels when selecting a device. +09.12.2011: + - Fixed popup menu behaviour with (nonstandard!) checkable submenus (flo) + - Fixed wrong START_DRAG when clicking on popup-columns (flo) +06.12.2011: + - Fixed drawing of logarithmic values (god how I hate these conversions!..!$%) hopefully... + should be improved by precalulating max and min values (rj) +05.12.2011: + - Complete Spanish translation from Cristian Ramos (rj) +03.12.2011: + * Improved: Project save dialog: Now has quick save as Template. Separate project/result paths shown. Editable project folder. (Tim...) + * Added: Project directory in global settings dialog. + * Added: Untitled project unique names. + - Fixed bug saving compressed files with spaces in name, in filedialog.cpp fileOpen(). + More work in progress... +02.12.2011: + * Added: Project creation dialog now has file type combobox (.med, .med.gz, .med.bz2) (Tim) + * Fixed: Remaining bugs with Header saving and loading (ex track, drum list header). (Tim) + Made two slight fixes in Header::writeStatus and readStatus. Tested thoroughly OK. +01.12.2011: + - Removed global settings User Instruments dir. Now fixed to muse config. Support for old files included. (Tim...) + - Changed: In File Dialog, 'User' initial prepend path changed to muse ./config path. So user files + templates are shown. + - Fixed: Template directory changed from /home/templates to muse config directory. Support for old files included. + - Moved QSocketNotifier from Audio::Audio into MusE::MusE. + - Fixed mixer and main geometry restoration. Moved ahead of doReadGlobalConfig check. + - Work In Progress! More to follow... +28.11.2011: + *Fixed: DSSI synth audio inputs. This means dssi vocoders, samplers etc. should work now. (Tim...) + *Re-write: Fixed audio mixing, meter processing. Audio, and meters, for all mono <-> stereo route combinations work sensibly now. + - Do not apply the track pan or volume to extra synth channels above 2. + - (Re-)fixed valgrind 'invalid read size' in node.cpp, my very-old bad. Moved temp stack buffers to top. (Thnx to Flo) + - Window titles of ladspa and dssi plugins now have track name prefix to help identify them. + + - Added "Unused Devices" menu to the arranger's port popupmenu for rapid device selection (flo) +28.11.2011: + - MusE 2.0 release candidate 1 released (rj) +27.11.2011: + - fixed invalid read problem in node.cpp: replaced the (ab-)use + of a temporary stacked buffer (which was deleted too soon) + by the use of a temporary heap buffer (new[]) (flo) +26.11.2011: + - Added config properties for add-track menu, show all, show only visible and property for making visible what you add (rj) + - Split behaviour and style configuration to two tabs (rj) + - Adding invisible tracks no longer update track-info in arranger (rj) + - clicking the background in tracklist and arranger no longer clear focus (rj) + - moved configuration items for track visibility to global config (rj) + - Added right click quit to channel strips (rj) +25.11.2011: + - fixed segfault when closing and SndFileList had more than 1 entry (flo) + - fixed some mismatched deletes (delete vs delete[]) (flo) +24.11.2011: + - Fixed: xml song loading ignores very large text such as with Hexter-DSSI. Reported by jphaenlin. (Tim) + Changed all local buffers to QByteArray (for unlimited size). Test OK loading/saving large songs + Hexter-DSSI. + - Fixed "Invalid Read/Write"-bug with moving parts past the song's end or past the last track. (flo93) + The problem was: when the song was automatically enlargened / a new track has automatically been + created, the song was update()d, and thus songChanged() was called. Within + songChanged(), the PartCanvas clearDelete()d its items list, deleting every + data pointed to by that list. However, right after that, the current loop's + CItem* is still used (which has just been deleted, that is, invalidated.). + In case the loop will go on, there would be even more similar errors. + Solution: - Added UndoOp::ModifySongLen-action, and used that one for altering song length. + - changed Song::addTrack() to write into operation groups. + adapted all code using Song::addTrack() accordingly + - changed PartCanvas::moveItem() to support whole lists of operations. + - Fixed a small unused-parameter warning (flo) + - Updated broken (but unused) UndoOp::typeName() function (flo) + +23.11.2011: + - Fundamental audio engine fixes/changes together with a variety of other fixes. (Tim...) + - Process track and plugin dssi controls always now, even if off. Fixed problems adjusting/saving gui values. TODO: Dssi when off. + - User is now forbidden to do circular routing. Routing menu items are now disabled according to whether they would cause a loop. + Installed anti-circular routing mechanism, allows processing should a circular route actually exist (old files, bugs, deliberate? etc). + - Fixed jack.cpp: Connecting routes. Some code was not checking if routes were JACK_ROUTE types, leading to errors. + * Fixed: Soloing system problems. Forgot to solo-chain all the way back to a midi track. Also fixed crashes if soloing a circular route. + * Fixed: Aux Tracks. They should 'just work' always now. Required major processing-order changes and routing path support/checking. + NOTE: Cannot use a track's aux sends if the track has an input route path from ANY Aux Track! Aux knobs/labels now DISABLED in that case. +22.11.2011: + - Increased contrast for midi event drawing in parts (rj) 21.11.2011: - added super-glue feature (flo) +17.11.2011: + - Fixed all arranger/pianoroll/drumedit keyboard scrolling. (Tim) + Changed PartCanvas and EventCanvas ::keyPress() key scrolling sections. Plus custom behavior tweaks in each case. +16.11.2011: + - Ctrl+click or middle button now sets an absolute value for Knobs (as good as possible without advanced arithmetic) (rj) + - Structure operations: Split,Cut,Insert now work on audio tracks. The previous functionality with operating on selected + tracks have been split into separate menu items (rj) +15.11.2011: + - Fixed wacky arranger part selection via KB when 'Move single armed track with selection' set. (Tim) + Arranger::songChanged() was way too liberal, esp calling partsChanged(). Side benefit: Arranger speed-ups. + - Changed internal 'undo' shortcut from ctrl-y to standard shift-ctrl-z. (Tim) +14.11.2011: + - Fixed: Do not clear midi ports upon 'new' (template) or 'import midi'. (Tim) + Enabled some old code with which I had problems before, but that was long before 'clearing' fixes. + Remaining TODOS: 'New' Synth.med template still replaces existing midi ports, and only + the first port appears to be auto-connected to inputs upon import midi. + - fixed ScoreEdit bug: names are removed from the set on close and on delete. (Flo) + - indentation fixes in scoreedit.cpp,h and cobject.cpp (Flo) + - Removed 18.06.2011 experiment. Do not allow Synths to route to midi track inputs. (Tim) + It worked with MESS so far, allowed recording gui control movement. May prove useful + in future, but is a big auto-routing hassle ATM. Sections marked p4.0.35. +13.11.2011: + - ScoreEdit now saves some default init values (flo) + - seems like this fixed some valgrind bugs as well (flo) +12.11.2011: + - fixed "newly created subwins aren't focussed" problem (flo) + - when closing a subwin, automatically another (topmost) subwin + gets activated (flo) + - fixed "non-subwin topwin-states aren't restored when using + 'muse2 songfile.med'. (don't know who, probably Tim) +11.11.2011: + - Fixed all template .med song files. (Tim) +10.11.2011: + - Updated spanish translation by Cristian Ramos (rj) + - Fixed meters not updating upon vertically shrinking arranger. (Tim) + - Fixed TopWin xml errors such as "MusE: unknown tag at line xxxx". (Tim) + Used new TopLevelList::findType() in MusE::readToplevels() to find arranger, marker, and cliplist. Was broken ! + So, arranger now remembers its settings (mostly). + TODO: Fix broken default.med file, has serious xml errors. For long time MarkerView hasn't recalled its visibility. +09.11.2011: + - Further to 02.11.2011: Automatically convert old songs to use new 'fluid_synth' name. (Tim...) + - Added enum Synth::Type (MESS_SYNTH, DSSI_SYNTH etc) and used it throughout, ex. in findSynth(), also in song file. + Protects from name conflicts with future MESS, DSSI synths, and simplifies adding future types (say LV2 etc.) + - Simplified populateAddSynth(), made it agnostic. No more hard-coded synth type sorting - uses Synth::Type now. + - Fixed settings synth config lists not updated when 'Remove Instance' clicked. Also now shows the type in the lists. + - Fixed regression: No synthesizer patch names were listed. 07.11.2011: - fixed restore-window-state bug (flo) - fixed dialog translation problem (flo) diff --git a/muse2/README b/muse2/README index 1770950b..f9287458 100644 --- a/muse2/README +++ b/muse2/README @@ -17,99 +17,145 @@ details. `-----------------------------------------------------------------' ============================= - Requirements + Requirements: ============================= - CMake >= 2.4 - http:/www.cmake.org/HTML/Download.html + http:/www.cmake.org/HTML/Download.html - QT: Qt >= 4.2.0 - ftp://ftp.trolltech.com/qt/source - MusE does _not_ compile with older versions + http://qt.nokia.com/products/ + MusE does _not_ compile with older versions - gcc >= 4.x.x - 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/ + - libuuid + e2fsprogs package http://e2fsprogs.sourceforge.net/ + Some distros may include it in another package, offering a choice. + Optional: - fluidsynth >= 1.0.3 (formerly known as iiwusynth) from http://savannah.nongnu.org/download/fluid - - OSC (Open Sound Control) - - DSSI (Disposable Soft Synth Interface) with support for DSSI vst plugins. - (Both recommended - DSSI alone will have no DSSI GUIs. OSC alone does nothing, for now.) + - 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.) + + - dssi-vst Support for DSSI vst plugins http://www.breakfastquay.com/dssi-vst/ - - LASH Audio Session Handler + - LASH Audio Session Handler http://lash.nongnu.org/ + Recently LADISH has been emulating it instead. http://ladish.org/ - ConTeXt (for building documentation, by default the build script tries to build documentation, can be disabled by setting ENABLE_DOCUMENTATION to OFF) ============================= - Compiling: + Building MusE: ============================= - Download source from http://lmuse.sourceforge.net/ - - Command line to unpack source: - tar xvofz muse-x.y.z.tar.gz - where x.y.z is the version number. - Or just use a graphical de-compressor to unpack it somewhere. + - Unpack the source somewhere. + + You may also try the various MusE development SVN branches for + up-to-the-minute features and fixes, but they may be less stable. - To compile MusE, run the following commands from the top level directory where the source code was unpacked - (the directory where THIS README FILE is): + (the directory where THIS README FILE is found): ****************************************************** * Notice: * - * a quicker way is to run the ./compile_muse.sh * + * A quick way is to run the ./compile_muse.sh * * script in the same dir, it should perform the same * * steps for a basic setup without asking any * - * questions. If it fails you may be better of using * + * questions. If it fails you may be better off using * * the instructions below. * ****************************************************** - # Create build directory. Choose any name like 'build'. - mkdir build - # Enter build directory. - cd build - - # Create make system in the build directory. - # Optional is the location to install MusE, default /usr/local. - # Build type can be blank (to reset a previous cached type to 'empty'), - # debug, release, RelWithDebInfo and MinSizeRel. - # If no CMAKE_BUILD_TYPE is given at all, cmake uses either the previous - # cached value, or else 'empty' (plain unoptimized). - # ('Release' type is recommended, otherwise it builds a plain unoptimized program.) - cmake -DCMAKE_BUILD_TYPE=release [-DCMAKE_INSTALL_PREFIX=] ../ - - # Compile muse - make - - - Install MusE: - Run "make install" (as root user) + The build directory: + -------------------- + Building in a subdirectory is recommended to keep the build directory separate from the source tree. + So create a new subdirectory with a useful name like "build" or "debug" or "release": + mkdir build + Change directory (cd) to the new directory: + cd build + + Configuration: + -------------- + There are a few different ways to configure (notice the two dots): + + Type "cmake -i .." to run in step-by-step 'Wizard' mode. + + Or type "cmake -L .." to see options, then compose "cmake " yourself. + Some are: + + -DCMAKE_BUILD_TYPE= + can be blank (to reset a previous cached type to 'empty'), + debug, release, RelWithDebInfo and MinSizeRel. + Release is recommended, to get optimizations. + If no CMAKE_BUILD_TYPE is given at all, cmake uses either the previous + cached value, or else 'empty' (plain or default system optimizations). + + -DCMAKE_INSTALL_PREFIX= + The installation where the program is installed. + The default is to install in /usr/local. + + Or type "ccmake .." (if you have it - text-mode GUI). It may be blank so hit + 'C' to first-time configure. Fiddle with yer options if ye so desire, then hit + 'C' to configure then 'G' to generate and exit, or 'Q' to quit without + generating. + + Or there is also a desktop GUI for cmake called cmake-gui. + + Compiling: + ---------- + After configuration, while still in the build directory,type: + make + + Installing: + ---------- + After compiling, type: + make install (as root) + or + sudo make install ============================= - running MusE + Running MusE: ============================= - MusE is a realtime program which requires special rights to - work poperly. Recommended setup: + ------------------ + MusE is a realtime program which requires special rights to work properly. - - check if you are running a sufficiently new linux kernel > 2.6.x + - Check if you are running a sufficiently new linux kernel > 2.6.x + A modern, standard destop kernel might suit your needs. + However, for the best performance a so-called 'low latency' or 'realtime' + kernel may be required. Check your distro's packages for availability. - create an "audio" group if it does not already exists and put yourself into this group + - For realtime priority, you may want to ensure either the file: + /etc/security/limits.conf + or + /etc/security/limits.d/audio.conf + contains: + @audio - rtprio 95 + @audio - memlock unlimited + - make sure you can acces the realtime clock (RTC) chmod 660 /dev/rtc chgrp audio /dev/rtc @@ -119,18 +165,39 @@ details. inspect with: cat /proc/sys/dev/rtc/max-user-freq - - for MusE to gain RT priviledges load the "realtime-lsm" - modul; the modul should be configured to give all "audio" - group members realtime priviledges - - some distros do not load the alsa sequencer module by default. if necessary, load the alsa sequencer module with: /sbin/modprobe snd-seq - - start qjackctl - - start JACK with qjackctl - - - start MusE + - Start jack, typically by using the qjackctl application. + MusE can also be run without Jack. MusE will use a dummy audio + driver if Jack is not detected, or the -a option is given. + + + Running: + ------------------ + start MusE by typing: + muse2 + + Some are: + -h help + -v print version + -d debug mode: no threads, no RT + -D debug mode: enable some debug messages + specify twice for lots of debug messages + this may slow down MusE massively! + -m debug mode: trace midi Input + -M debug mode: trace midi Output + -s debug mode: trace sync + -a no audio + -P n set audio driver real time priority to n + (Dummy only, default 40. Else fixed by Jack.) + -Y n force midi real time priority to n (default: audio driver prio +2) + -p don't load LADSPA plugins + -I don't load DSSI plugins + -L don't use LASH + -l xx force locale to the given language/country code + (xx = de,en,es,fr,pl,ru,sv_SE) (JACK and all its clients (qjackctl & MusE) must run with the same user id) @@ -140,7 +207,7 @@ details. known bugs ============================= - - many + - not so many: only some usability quirks we're working on currently ==================================================================== Let us know whether MusE works for you !!! diff --git a/muse2/README.de b/muse2/README.de index 00b55960..04e2c301 100644 --- a/muse2/README.de +++ b/muse2/README.de @@ -67,4 +67,5 @@ Für Einzelheiten siehe COPYING. ==================================================================== Aktuelle(re) Infos gibt es auf der MusE Homepage http://lmuse.sourceforge.net/ +und in der englischen README diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index bd6bc560..148f3072 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -4,6 +4,7 @@ // $Id: app.cpp,v 1.113.2.68 2009/12/21 14:51:51 spamatica Exp $ // // (C) Copyright 1999-2011 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -33,6 +34,8 @@ #include #include #include +#include +#include #include @@ -55,6 +58,7 @@ #include "filedialog.h" #include "gconfig.h" #include "gui.h" +#include "helper.h" #include "icons.h" #include "instruments/editinstrument.h" #include "listedit.h" @@ -84,8 +88,11 @@ extern void exitJackAudio(); extern void exitDummyAudio(); extern void exitOSC(); extern void exitMidiAlsa(); -} +extern void initMidiSequencer(); +extern void initAudio(); +extern void initAudioPrefetch(); +} namespace MusEGui { @@ -94,12 +101,12 @@ namespace MusEGui { static pthread_t watchdogThread; //ErrorHandler *error; - #define PROJECT_LIST_LEN 6 static QString* projectList[PROJECT_LIST_LEN]; #ifdef HAVE_LASH #include +#include lash_client_t * lash_client = 0; extern snd_seq_t * alsaSeq; #endif /* HAVE_LASH */ @@ -171,14 +178,7 @@ bool MusE::seqStart() if(MusEGlobal::realTimeScheduling) { { - //pfprio = MusEGlobal::realTimePriority - 5; - // p3.3.40 pfprio = MusEGlobal::realTimePriority + 1; - - //midiprio = MusEGlobal::realTimePriority - 2; - // p3.3.37 - //midiprio = MusEGlobal::realTimePriority + 1; - // p3.3.40 midiprio = MusEGlobal::realTimePriority + 2; } } @@ -198,9 +198,6 @@ bool MusE::seqStart() MusEGlobal::audioPrefetch->msgSeek(0, true); // force - //MusEGlobal::midiSeqRunning = !midiSeq->start(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0); - // Changed by Tim. p3.3.22 - //MusEGlobal::midiSeq->start(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0); MusEGlobal::midiSeq->start(midiprio); int counter=0; @@ -224,7 +221,7 @@ bool MusE::seqStart() } return true; } - + //--------------------------------------------------------- // stop //--------------------------------------------------------- @@ -258,6 +255,7 @@ bool MusE::seqRestart() } seqStop(); } + if(!seqStart()) return false; @@ -299,7 +297,7 @@ void addProject(const QString& name) //--------------------------------------------------------- //MusE::MusE(int argc, char** argv) : QMainWindow(0, "mainwindow") -MusE::MusE(int argc, char** argv) : QMainWindow() +MusE::MusE(int /*argc*/, char** /*argv*/) : QMainWindow() { // By T356. For LADSPA plugins in plugin.cpp // QWidgetFactory::addWidgetFactory( new PluginWidgetFactory ); ddskrjo @@ -333,6 +331,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow() progress = 0; activeTopWin = NULL; currentMenuSharingTopwin = NULL; + waitingForTopwin = NULL; appName = QString("MusE"); setWindowTitle(appName); @@ -346,8 +345,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow() MusEGlobal::heartBeatTimer = new QTimer(this); MusEGlobal::heartBeatTimer->setObjectName("timer"); connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), MusEGlobal::song, SLOT(beat())); - - connect(this, SIGNAL(activeTopWinChanged(MusEGui::TopWin*)), SLOT(activeTopWinChangedSlot(MusEGui::TopWin*))); #ifdef ENABLE_PYTHON @@ -460,7 +457,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow() MusEGlobal::panicAction->setWhatsThis(tr("send note off to all midi channels")); connect(MusEGlobal::panicAction, SIGNAL(activated()), MusEGlobal::song, SLOT(panic())); - MusECore::initMidiInstruments(); + MusECore::initMidiInstruments(); MusECore::initMidiPorts(); MusECore::initMidiDevices(); @@ -706,7 +703,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow() //rlimit lim; //getrlimit(RLIMIT_RTPRIO, &lim); //printf("RLIMIT_RTPRIO soft:%d hard:%d\n", lim.rlim_cur, lim.rlim_max); // Reported 80, 80 even with non-RT kernel. - + if (MusEGlobal::realTimePriority < sched_get_priority_min(SCHED_FIFO)) MusEGlobal::realTimePriority = sched_get_priority_min(SCHED_FIFO); else if (MusEGlobal::realTimePriority > sched_get_priority_max(SCHED_FIFO)) @@ -721,18 +718,19 @@ MusE::MusE(int argc, char** argv) : QMainWindow() MusEGlobal::midiRTPrioOverride = sched_get_priority_max(SCHED_FIFO); } - // Changed by Tim. p3.3.17 - //MusEGlobal::midiSeq = new MusECore::MidiSeq(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0, "Midi"); - MusEGlobal::midiSeq = new MusECore::MidiSeq("Midi"); - MusEGlobal::audio = new MusECore::Audio(); - //MusEGlobal::audioPrefetch = new MusECore::AudioPrefetch(0, "Disc"); - MusEGlobal::audioPrefetch = new MusECore::AudioPrefetch("Prefetch"); - + MusECore::initMidiSequencer(); + MusECore::initAudio(); + + // Moved here from Audio::Audio + QSocketNotifier* ss = new QSocketNotifier(MusEGlobal::audio->getFromThreadFdr(), QSocketNotifier::Read, this); + connect(ss, SIGNAL(activated(int)), MusEGlobal::song, SLOT(seqSignal(int))); + + MusECore::initAudioPrefetch(); + //--------------------------------------------------- // Popups //--------------------------------------------------- - // when adding a menu to the main window, remember adding it to // either the leadingMenus or trailingMenus list! // also do NOT use menuBar()->addMenu(QString&), but ALWAYS @@ -961,6 +959,11 @@ MusE::MusE(int argc, char** argv) : QMainWindow() transport = new MusEGui::Transport(this, "transport"); bigtime = 0; + MusEGlobal::song->blockSignals(false); + + // Load start song moved to main.cpp p4.0.41 REMOVE Tim. + /* + //--------------------------------------------------- // load project // if no songname entered on command line: @@ -975,7 +978,8 @@ MusE::MusE(int argc, char** argv) : QMainWindow() name = argv[0]; else if (MusEGlobal::config.startMode == 0) { if (argc < 2) - name = projectList[0] ? *projectList[0] : QString("untitled"); + //name = projectList[0] ? *projectList[0] : QString("untitled"); + name = projectList[0] ? *projectList[0] : MusEGui::getUniqueUntitledName(); // p4.0.40 else name = argv[0]; printf("starting with selected song %s\n", MusEGlobal::config.startSong.toLatin1().constData()); @@ -989,19 +993,47 @@ MusE::MusE(int argc, char** argv) : QMainWindow() printf("starting with pre configured song %s\n", MusEGlobal::config.startSong.toLatin1().constData()); name = MusEGlobal::config.startSong; } - MusEGlobal::song->blockSignals(false); - loadProjectFile(name, useTemplate, true); - + + // loadProjectFile(name, useTemplate, true); //commented out by flo: see below (*) + */ + changeConfig(false); QSettings settings("MusE", "MusE-qt"); restoreGeometry(settings.value("MusE/geometry").toByteArray()); //restoreState(settings.value("MusE/windowState").toByteArray()); - MusEGlobal::song->update(); - - updateWindowMenu(); + MusEGlobal::song->update(); // commented out by flo: will be done by the below (*) + updateWindowMenu(); // same here + + // Load start song moved to main.cpp p4.0.41 REMOVE Tim. + /* + + // this is (*). + // this is a really hackish workaround for the loading-on-startup problem. + // i have absolutely no idea WHY it breaks when using loadProjectFile() + // above, but it does on my machine (it doesn't on others!). + // the problem can be worked around by delaying loading the song file. + // i use hackishSongOpenTimer for this, which calls after 10ms a slot + // which then does the actual loadProjectFile() call. + // FIXME: please, if anyone finds the real problem, FIX it and + // remove that dirty, dirty workaround! + hackishSongOpenFilename=name; + hackishSongOpenUseTemplate=useTemplate; + hackishSongOpenTimer=new QTimer(this); + hackishSongOpenTimer->setInterval(10); + hackishSongOpenTimer->setSingleShot(true); + connect(hackishSongOpenTimer, SIGNAL(timeout()), this, SLOT(hackishSongOpenTimerTimeout())); + hackishSongOpenTimer->start(); + */ } +// Load start song moved to main.cpp p4.0.41 REMOVE Tim. +//void MusE::hackishSongOpenTimerTimeout() +//{ + ///loadProjectFile(hackishSongOpenFilename, hackishSongOpenUseTemplate, true); + //loadProjectFile(hackishSongOpenFilename, hackishSongOpenUseTemplate, !hackishSongOpenUseTemplate); +//} + MusE::~MusE() { } @@ -1015,6 +1047,44 @@ void MusE::setHeartBeat() MusEGlobal::heartBeatTimer->start(1000/MusEGlobal::config.guiRefresh); } +//--------------------------------------------------- +// loadDefaultSong +// if no songname entered on command line: +// startMode: 0 - load last song +// 1 - load default template +// 2 - load configured start song +//--------------------------------------------------- + +void MusE::loadDefaultSong(int argc, char** argv) +{ + QString name; + bool useTemplate = false; + if (argc >= 2) + name = argv[0]; + else if (MusEGlobal::config.startMode == 0) { + if (argc < 2) + //name = projectList[0] ? *projectList[0] : QString("untitled"); + name = projectList[0] ? *projectList[0] : MusEGui::getUniqueUntitledName(); // p4.0.40 + else + name = argv[0]; + printf("starting with selected song %s\n", MusEGlobal::config.startSong.toLatin1().constData()); + } + else if (MusEGlobal::config.startMode == 1) { + printf("starting with default template\n"); + name = MusEGlobal::museGlobalShare + QString("/templates/default.med"); + useTemplate = true; + } + else if (MusEGlobal::config.startMode == 2) { + printf("starting with pre configured song %s\n", MusEGlobal::config.startSong.toLatin1().constData()); + name = MusEGlobal::config.startSong; + } + //loadProjectFile(name, useTemplate, true); + loadProjectFile(name, useTemplate, !useTemplate); + + //MusEGlobal::song->update(); + //updateWindowMenu(); +} + //--------------------------------------------------------- // resetDevices //--------------------------------------------------------- @@ -1156,7 +1226,8 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll QApplication::restoreOverrideCursor(); return; } - project.setFile("untitled"); + //project.setFile("untitled"); + project.setFile(MusEGui::getUniqueUntitledName()); // p4.0.40 MusEGlobal::museProject = MusEGlobal::museProjectInitPath; } else { @@ -1214,7 +1285,8 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll } if (!songTemplate) { addProject(project.absoluteFilePath()); - setWindowTitle(QString("MusE: Song: ") + project.completeBaseName()); + //setWindowTitle(QString("MusE: Song: ") + project.completeBaseName()); + setWindowTitle(QString("MusE: Song: ") + MusEGui::projectTitleFromFilename(project.absoluteFilePath())); } MusEGlobal::song->dirty = false; progress->setValue(30); @@ -1236,7 +1308,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll // set the geometry if the mixer has already been created. if(mixer1) { - //if(mixer1->geometry().size() != MusEGlobal::config.mixer1.geometry.size()) // p3.3.53 Moved below + //if(mixer1->geometry().size() != MusEGlobal::config.mixer1.geometry.size()) // Moved below // mixer1->resize(MusEGlobal::config.mixer1.geometry.size()); if(mixer1->geometry().topLeft() != MusEGlobal::config.mixer1.geometry.topLeft()) @@ -1244,7 +1316,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll } if(mixer2) { - //if(mixer2->geometry().size() != MusEGlobal::config.mixer2.geometry.size()) // p3.3.53 Moved below + //if(mixer2->geometry().size() != MusEGlobal::config.mixer2.geometry.size()) // Moved below // mixer2->resize(MusEGlobal::config.mixer2.geometry.size()); if(mixer2->geometry().topLeft() != MusEGlobal::config.mixer2.geometry.topLeft()) @@ -1273,7 +1345,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll arrangerView->scoreNamingChanged(); // inform the score menus about the new scores and their names progress->setValue(50); - // p3.3.53 Try this AFTER the song update above which does a mixer update... Tested OK - mixers resize properly now. + // Try this AFTER the song update above which does a mixer update... Tested OK - mixers resize properly now. if (loadAll) { if(mixer1) @@ -1336,10 +1408,13 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll void MusE::setUntitledProject() { setConfigDefaults(); - QString name("untitled"); + //QString name("untitled"); + QString name(MusEGui::getUniqueUntitledName()); // p4.0.40 + MusEGlobal::museProject = "./"; //QFileInfo(name).absolutePath(); project.setFile(name); - setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName())); + //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName())); + setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(name))); } //--------------------------------------------------------- @@ -1391,14 +1466,14 @@ void MusE::loadTemplate() if (!fn.isEmpty()) { // MusEGlobal::museProject = QFileInfo(fn).absolutePath(); - loadProjectFile(fn, true, true); + //loadProjectFile(fn, true, true); // With templates, don't clear midi ports. // Any named ports in the template file are useless since they likely // would not be found on other users' machines. // So keep whatever the user currently has set up for ports. // Note that this will also keep the current window configurations etc. // but actually that's also probably a good thing. p4.0.17 Tim. TESTING: Maybe some problems... - //loadProjectFile(fn, true, false); + loadProjectFile(fn, true, false); setUntitledProject(); } @@ -1410,7 +1485,11 @@ void MusE::loadTemplate() bool MusE::save() { - if (project.completeBaseName() == "untitled") + //if (project.completeBaseName() == "untitled") // p4.0.40 Must catch "untitled 1" "untitled 2" etc + //if (MusEGui::projectTitleFromFilename(project.absoluteFilePath()) == "untitled") + //if (MusEGui::projectTitleFromFilename(project.absoluteFilePath()) == MusEGui::getUniqueUntitledName()) + ///if (project.absoluteFilePath() == MusEGui::getUniqueUntitledName()) + if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) return saveAs(); else return save(project.filePath(), false); @@ -1542,7 +1621,7 @@ void MusE::closeEvent(QCloseEvent* event) MusECore::exitMetronome(); // Make sure to delete the menu. ~routingPopupMenu() will NOT be called automatically. - // Even though it is a child of MusE, it just passes MusE onto the underlying PopupMenus. p4.0.26 + // Even though it is a child of MusE, it just passes MusE onto the underlying PopupMenus. if(routingPopupMenu) delete routingPopupMenu; #if 0 @@ -1572,7 +1651,7 @@ void MusE::closeEvent(QCloseEvent* event) } #ifdef HAVE_LASH - // Disconnect gracefully from LASH. Tim. p3.3.14 + // Disconnect gracefully from LASH. if(lash_client) { if(MusEGlobal::debugMsg) @@ -1590,7 +1669,6 @@ void MusE::closeEvent(QCloseEvent* event) printf("MusE: Exiting OSC\n"); MusECore::exitOSC(); - // p3.3.47 delete MusEGlobal::audioPrefetch; delete MusEGlobal::audio; delete MusEGlobal::midiSeq; @@ -1619,8 +1697,8 @@ void MusE::showMarker(bool flag) markerView = new MusEGui::MarkerView(this); connect(markerView, SIGNAL(closed()), SLOT(markerClosed())); - toplevels.push_back(markerView); markerView->show(); + toplevels.push_back(markerView); } markerView->setVisible(flag); viewMarkerAction->setChecked(flag); @@ -1642,6 +1720,20 @@ void MusE::markerClosed() setCurrentMenuSharingTopwin(NULL); updateWindowMenu(); + + // focus the last activated topwin which is not the marker view + QList l = mdiArea->subWindowList(QMdiArea::StackingOrder); + for (QList::iterator lit=l.begin(); lit!=l.end(); lit++) + if ((*lit)->isVisible() && (*lit)->widget() != markerView) + { + if (MusEGlobal::debugMsg) + printf("bringing '%s' to front instead of closed arranger window\n",(*lit)->widget()->windowTitle().toAscii().data()); + + bringToFront((*lit)->widget()); + + break; + } + } //--------------------------------------------------------- @@ -1675,6 +1767,20 @@ void MusE::arrangerClosed() { viewArrangerAction->setChecked(false); updateWindowMenu(); + + // focus the last activated topwin which is not the arranger view + QList l = mdiArea->subWindowList(QMdiArea::StackingOrder); + for (QList::iterator lit=l.begin(); lit!=l.end(); lit++) + if ((*lit)->isVisible() && (*lit)->widget() != arrangerView) + { + if (MusEGlobal::debugMsg) + printf("bringing '%s' to front instead of closed arranger window\n",(*lit)->widget()->windowTitle().toAscii().data()); + + bringToFront((*lit)->widget()); + + break; + } + } //--------------------------------------------------------- @@ -1716,7 +1822,7 @@ MusEGui::RoutePopupMenu* MusE::getRoutingPopupMenu() bool MusE::saveAs() { QString name; - if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) { + //if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) // Use project dialog always now. if (MusEGlobal::config.useProjectSaveDialog) { MusEGui::ProjectCreateImpl pci(MusEGlobal::muse); if (pci.exec() == QDialog::Rejected) { @@ -1737,10 +1843,11 @@ bool MusE::saveAs() QMessageBox::warning(this,"Path error","Can't create project path", QMessageBox::Ok); return false; } - } - else { - name = MusEGui::getSaveFileName(QString(""), MusEGlobal::med_file_save_pattern, this, tr("MusE: Save As")); - } + //} + //else { + // name = MusEGui::getSaveFileName(QString(""), MusEGlobal::med_file_save_pattern, this, tr("MusE: Save As")); + //} + bool ok = false; if (!name.isEmpty()) { QString tempOldProj = MusEGlobal::museProject; @@ -1748,7 +1855,8 @@ bool MusE::saveAs() ok = save(name, true); if (ok) { project.setFile(name); - setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName())); + //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName())); + setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(name))); addProject(name); } else @@ -1830,8 +1938,8 @@ void MusE::openInScoreEdit(MusEGui::ScoreEdit* destination, MusECore::PartList* if (destination==NULL) // if no destination given, create a new one { destination = new MusEGui::ScoreEdit(this, 0, _arranger->cursorValue()); - destination->show(); toplevels.push_back(destination); + destination->show(); connect(destination, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*))); connect(destination, SIGNAL(name_changed()), arrangerView, SLOT(scoreNamingChanged())); //connect(muse, SIGNAL(configChanged()), destination, SLOT(config_changed())); @@ -1866,10 +1974,10 @@ void MusE::startPianoroll(MusECore::PartList* pl, bool showDefaultCtrls) { MusEGui::PianoRoll* pianoroll = new MusEGui::PianoRoll(pl, this, 0, _arranger->cursorValue()); - if(showDefaultCtrls) // p4.0.12 + if(showDefaultCtrls) pianoroll->addCtrl(); - pianoroll->show(); toplevels.push_back(pianoroll); + pianoroll->show(); connect(pianoroll, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*))); connect(MusEGlobal::muse, SIGNAL(configChanged()), pianoroll, SLOT(configChanged())); updateWindowMenu(); @@ -1890,8 +1998,8 @@ void MusE::startListEditor() void MusE::startListEditor(MusECore::PartList* pl) { MusEGui::ListEdit* listEditor = new MusEGui::ListEdit(pl); - listEditor->show(); toplevels.push_back(listEditor); + listEditor->show(); connect(listEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*))); connect(MusEGlobal::muse,SIGNAL(configChanged()), listEditor, SLOT(configChanged())); updateWindowMenu(); @@ -1904,8 +2012,8 @@ void MusE::startListEditor(MusECore::PartList* pl) void MusE::startMasterEditor() { MusEGui::MasterEdit* masterEditor = new MusEGui::MasterEdit(); - masterEditor->show(); toplevels.push_back(masterEditor); + masterEditor->show(); connect(masterEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*))); updateWindowMenu(); } @@ -1917,8 +2025,8 @@ void MusE::startMasterEditor() void MusE::startLMasterEditor() { MusEGui::LMaster* lmaster = new MusEGui::LMaster(); - lmaster->show(); toplevels.push_back(lmaster); + lmaster->show(); connect(lmaster, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*))); connect(MusEGlobal::muse, SIGNAL(configChanged()), lmaster, SLOT(configChanged())); updateWindowMenu(); @@ -1939,10 +2047,10 @@ void MusE::startDrumEditor() void MusE::startDrumEditor(MusECore::PartList* pl, bool showDefaultCtrls) { MusEGui::DrumEdit* drumEditor = new MusEGui::DrumEdit(pl, this, 0, _arranger->cursorValue()); - if(showDefaultCtrls) // p4.0.12 + if(showDefaultCtrls) drumEditor->addCtrl(); - drumEditor->show(); toplevels.push_back(drumEditor); + drumEditor->show(); connect(drumEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*))); connect(MusEGlobal::muse, SIGNAL(configChanged()), drumEditor, SLOT(configChanged())); updateWindowMenu(); @@ -1966,8 +2074,8 @@ void MusE::startWaveEditor(MusECore::PartList* pl) { MusEGui::WaveEdit* waveEditor = new MusEGui::WaveEdit(pl); waveEditor->show(); - connect(MusEGlobal::muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged())); toplevels.push_back(waveEditor); + connect(MusEGlobal::muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged())); connect(waveEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*))); updateWindowMenu(); } @@ -2088,6 +2196,19 @@ void MusE::toplevelDeleting(MusEGui::TopWin* tl) { activeTopWin=NULL; emit activeTopWinChanged(NULL); + + // focus the last activated topwin which is not the deleting one + QList l = mdiArea->subWindowList(QMdiArea::StackingOrder); + for (QList::iterator lit=l.begin(); lit!=l.end(); lit++) + if ((*lit)->isVisible() && (*lit)->widget() != tl) + { + if (MusEGlobal::debugMsg) + printf("bringing '%s' to front instead of closed window\n",(*lit)->widget()->windowTitle().toAscii().data()); + + bringToFront((*lit)->widget()); + + break; + } } if (tl == currentMenuSharingTopwin) @@ -2168,7 +2289,7 @@ void MusE::kbAccel(int key) MusEGlobal::song->setPlay(true); } - // p4.0.10 Tim. Normally each editor window handles these, to inc by the editor's raster snap value. + // Normally each editor window handles these, to inc by the editor's raster snap value. // But users were asking for a global version - "they don't work when I'm in mixer or transport". // Since no editor claimed the key event, we don't know a specific editor's snap setting, // so adopt a policy where the arranger is the 'main' raster reference, I guess... @@ -2649,7 +2770,8 @@ MusE::lash_idle_cb () int ok = save (ss.toAscii(), false); if (ok) { project.setFile(ss.toAscii()); - setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName())); + //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName())); + setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(project.absoluteFilePath()))); addProject(ss.toAscii()); MusEGlobal::museProject = QFileInfo(ss.toAscii()).absolutePath(); } @@ -3071,21 +3193,32 @@ void MusE::focusChanged(QWidget*, QWidget* now) if (currentMenuSharingTopwin && (currentMenuSharingTopwin!=activeTopWin)) currentMenuSharingTopwin->storeInitialState(); - + // if the activated widget is a QMdiSubWindow containing some TopWin + if ( (dynamic_cast(ptr)!=0) && + (dynamic_cast( ((QMdiSubWindow*)ptr)->widget() )!=0) ) + { + waitingForTopwin=(MusEGui::TopWin*) ((QMdiSubWindow*)ptr)->widget(); + return; + } while (ptr) { + if (MusEGlobal::heavyDebugMsg) + printf("focusChanged: at widget %p with type %s\n",ptr, typeid(*ptr).name()); + if ( (dynamic_cast(ptr)!=0) || // *ptr is a TopWin or a derived class (ptr==this) ) // the main window is selected break; ptr=dynamic_cast(ptr->parent()); //in the unlikely case that ptr is a QObject, this returns NULL, which stops the loop } + MusEGui::TopWin* win=dynamic_cast(ptr); // ptr is either NULL, this or the pointer to a TopWin - if (ptr!=this) // if the main win is selected, don't treat that as "none", but also don't handle it + + // if the main win or some deleting topwin is selected, + // don't treat that as "none", but also don't handle it + if (ptr!=this && (!win || !win->deleting()) ) { - MusEGui::TopWin* win=dynamic_cast(ptr); - // now 'win' is either NULL or the pointer to the active TopWin if (win!=activeTopWin) { @@ -3233,6 +3366,26 @@ void MusE::shareMenuAndToolbarChanged(MusEGui::TopWin* win, bool val) } } +void MusE::topwinMenuInited(MusEGui::TopWin* topwin) +{ + if (topwin==NULL) + return; + + if (topwin == waitingForTopwin) + { + if (waitingForTopwin->deleting()) + { + waitingForTopwin=NULL; + } + else + { + activeTopWin=waitingForTopwin; + waitingForTopwin=NULL; + emit activeTopWinChanged(activeTopWin); + } + } +} + void MusE::updateWindowMenu() { bool sep; @@ -3286,6 +3439,8 @@ void MusE::updateWindowMenu() void MusE::bringToFront(QWidget* widget) { MusEGui::TopWin* win=dynamic_cast(widget); + if (!win) return; + if (win->isMdiWin()) { win->show(); @@ -3449,4 +3604,19 @@ void MusE::tileSubWindows() } } +QString MusE::projectTitle() const +{ + return MusEGui::projectTitleFromFilename(project.fileName()); +} + +QString MusE::projectPath() const +{ + return MusEGui::projectPathFromFilename(project.absoluteFilePath()); +} + +QString MusE::projectExtension() const +{ + return MusEGui::projectExtensionFromFilename(project.fileName()); +} + } //namespace MusEGui diff --git a/muse2/muse/app.h b/muse2/muse/app.h index 27722e9a..184581dc 100644 --- a/muse2/muse/app.h +++ b/muse2/muse/app.h @@ -43,6 +43,7 @@ class QToolBar; class QToolButton; class QProgressDialog; class QMdiArea; +class QTimer; namespace MusECore { class AudioOutput; @@ -91,7 +92,7 @@ class TopWin; class Transport; class VisibleTracks; -#define MENU_ADD_SYNTH_ID_BASE 0x1000 +#define MENU_ADD_SYNTH_ID_BASE 0x8000 //--------------------------------------------------------- @@ -128,6 +129,7 @@ class MusE : public QMainWindow TopWin* activeTopWin; TopWin* currentMenuSharingTopwin; + TopWin* waitingForTopwin; std::list requiredToolbars; //always displayed std::list optionalToolbars; //only displayed when no toolbar-sharing window is active @@ -213,6 +215,10 @@ class MusE : public QMainWindow MidiTransformerDialog* midiTransformerDialog; QMenu* openRecent; + //QTimer* hackishSongOpenTimer; + //QString hackishSongOpenFilename; + //bool hackishSongOpenUseTemplate; + bool readMidi(FILE*); void read(MusECore::Xml& xml, bool skipConfig, bool isTemplate); void processTrack(MusECore::MidiTrack* track); @@ -327,6 +333,8 @@ class MusE : public QMainWindow void arrangeSubWindowsColumns(); void tileSubWindows(); + //void hackishSongOpenTimerTimeout(); + public slots: bool saveAs(); void bounceToFile(MusECore::AudioOutput* ao = 0); @@ -371,12 +379,14 @@ class MusE : public QMainWindow void addMdiSubWindow(QMdiSubWindow*); void shareMenuAndToolbarChanged(MusEGui::TopWin*, bool); + void topwinMenuInited(MusEGui::TopWin*); void updateWindowMenu(); public: MusE(int argc, char** argv); ~MusE(); + void loadDefaultSong(int argc, char** argv); Arranger* arranger() const { return _arranger; } QRect configGeometryMain; QProgressDialog *progress; @@ -384,10 +394,13 @@ class MusE : public QMainWindow void kbAccel(int); void changeConfig(bool writeFlag); void seqStop(); - bool seqStart(); + bool seqStart(); void setHeartBeat(); void importController(int, MusECore::MidiPort*, int); QString projectName() { return project.fileName(); } + QString projectTitle() const; + QString projectPath() const; + QString projectExtension() const; QWidget* mixer1Window(); QWidget* mixer2Window(); QWidget* transportWindow(); diff --git a/muse2/muse/arranger/alayout.cpp b/muse2/muse/arranger/alayout.cpp index a892356c..119da498 100644 --- a/muse2/muse/arranger/alayout.cpp +++ b/muse2/muse/arranger/alayout.cpp @@ -117,7 +117,7 @@ void TLLayout::setGeometry(const QRect &rect) QSize s1 = li[1]->sizeHint(); QSize s2 = li[2]->sizeHint(); - QSize s3 = li[3]->sizeHint(); + //QSize s3 = li[3]->sizeHint(); QSize s4 = li[4]->sizeHint(); QSize s5 = li[5]->sizeHint(); diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp index ae753378..cb024070 100644 --- a/muse2/muse/arranger/arranger.cpp +++ b/muse2/muse/arranger/arranger.cpp @@ -569,27 +569,40 @@ void Arranger::songChanged(int type) // Is it simply a midi controller value adjustment? Forget it. if(type != SC_MIDI_CONTROLLER) { - unsigned endTick = MusEGlobal::song->len(); - int offset = AL::sigmap.ticksMeasure(endTick); - hscroll->setRange(-offset, endTick + offset); //DEBUG - canvas->setOrigin(-offset, 0); - time->setOrigin(-offset, 0); - - int bar, beat; - unsigned tick; - AL::sigmap.tickValues(endTick, &bar, &beat, &tick); - if (tick || beat) - ++bar; - lenEntry->blockSignals(true); - lenEntry->setValue(bar); - lenEntry->blockSignals(false); - - if(type & SC_SONG_TYPE) // p4.0.7 Tim. + // TEST p4.0.36 Try these, may need more/less. + if(type & ( SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED | + SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED)) + { + unsigned endTick = MusEGlobal::song->len(); + int offset = AL::sigmap.ticksMeasure(endTick); + hscroll->setRange(-offset, endTick + offset); //DEBUG + canvas->setOrigin(-offset, 0); + time->setOrigin(-offset, 0); + + int bar, beat; + unsigned tick; + AL::sigmap.tickValues(endTick, &bar, &beat, &tick); + if (tick || beat) + ++bar; + lenEntry->blockSignals(true); + lenEntry->setValue(bar); + lenEntry->blockSignals(false); + } + + if(type & SC_SONG_TYPE) setMode(MusEGlobal::song->mtype()); - trackSelectionChanged(); - canvas->partsChanged(); - typeBox->setCurrentIndex(int(MusEGlobal::song->mtype())); + if(type & SC_SELECTION) // TEST p4.0.36 Try this alone, may need more. + trackSelectionChanged(); + + // Keep this light, partsChanged is a heavy move! TEST p4.0.36 Try these, may need more. + if(type & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED | + SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED | + SC_SIG | SC_TEMPO)) // Maybe sig. Requires tempo. + canvas->partsChanged(); + + //typeBox->setCurrentIndex(int(MusEGlobal::song->mtype())); // REMOVE Tim. Redundant. + if (type & SC_SIG) time->redraw(); if (type & SC_TEMPO) @@ -616,6 +629,14 @@ void Arranger::songChanged(int type) } } } + + // TEST p4.0.36 Try this + if(type & ( //SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED | + SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED | + SC_EVENT_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED)) //| + //SC_SIG | SC_TEMPO)) // Maybe sig. and tempo. No, moved above. + canvas->redraw(); + } updateTrackInfo(type); diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp index 3b726845..52be5194 100644 --- a/muse2/muse/arranger/arrangerview.cpp +++ b/muse2/muse/arranger/arrangerview.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +//#include #include #include #include @@ -129,6 +129,7 @@ ArrangerView::ArrangerView(QWidget* parent) connect(muse, SIGNAL(configChanged()), arranger, SLOT(configChanged())); connect(arranger, SIGNAL(setUsedTool(int)), editTools, SLOT(set(int))); connect(arranger, SIGNAL(selectionChanged()), SLOT(selectionChanged())); + connect(MusEGlobal::song, SIGNAL(songChanged(int)), visTracks, SLOT(updateVisibleTracksButtons())); @@ -167,8 +168,8 @@ ArrangerView::ArrangerView(QWidget* parent) scoreSubmenu = new QMenu(tr("Score"), this); scoreSubmenu->setIcon(QIcon(*scoreIconSet)); - scoreAllInOneSubsubmenu = new QMenu(tr("all parts in one staff"), this); - scoreOneStaffPerTrackSubsubmenu = new QMenu(tr("one staff per part"), this); + scoreAllInOneSubsubmenu = new QMenu(tr("all tracks in one staff"), this); + scoreOneStaffPerTrackSubsubmenu = new QMenu(tr("one staff per track"), this); scoreSubmenu->addMenu(scoreAllInOneSubsubmenu); scoreSubmenu->addMenu(scoreOneStaffPerTrackSubsubmenu); @@ -193,6 +194,10 @@ ArrangerView::ArrangerView(QWidget* parent) strGlobalInsertAction = new QAction(tr("Global Insert"), this); strGlobalSplitAction = new QAction(tr("Global Split"), this); + strGlobalCutSelAction = new QAction(tr("Global Cut - selected tracks"), this); + strGlobalInsertSelAction = new QAction(tr("Global Insert - selected tracks"), this); + strGlobalSplitSelAction = new QAction(tr("Global Split - selected tracks"), this); + //------------------------------------------------------------- @@ -246,7 +251,11 @@ ArrangerView::ArrangerView(QWidget* parent) menuStructure->addAction(strGlobalCutAction); menuStructure->addAction(strGlobalInsertAction); menuStructure->addAction(strGlobalSplitAction); - + menuStructure->addSeparator(); + menuStructure->addAction(strGlobalCutSelAction); + menuStructure->addAction(strGlobalInsertSelAction); + menuStructure->addAction(strGlobalSplitSelAction); + QMenu* functions_menu = menuBar()->addMenu(tr("Functions")); @@ -341,6 +350,9 @@ ArrangerView::ArrangerView(QWidget* parent) connect(strGlobalCutAction, SIGNAL(activated()), SLOT(globalCut())); connect(strGlobalInsertAction, SIGNAL(activated()), SLOT(globalInsert())); connect(strGlobalSplitAction, SIGNAL(activated()), SLOT(globalSplit())); + connect(strGlobalCutSelAction, SIGNAL(activated()), SLOT(globalCutSel())); + connect(strGlobalInsertSelAction, SIGNAL(activated()), SLOT(globalInsertSel())); + connect(strGlobalSplitSelAction, SIGNAL(activated()), SLOT(globalSplitSel())); @@ -351,7 +363,7 @@ ArrangerView::ArrangerView(QWidget* parent) connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged())); connect(cb, SIGNAL(selectionChanged()), SLOT(clipboardChanged())); - + MusEGlobal::muse->topwinMenuInited(this); // work around for probable QT/WM interaction bug. // for certain window managers, e.g xfce, this window is @@ -368,7 +380,7 @@ ArrangerView::~ArrangerView() void ArrangerView::closeEvent(QCloseEvent* e) { - emit deleted(static_cast(this)); + emit isDeleting(static_cast(this)); emit closed(); e->accept(); } @@ -729,4 +741,9 @@ void ArrangerView::globalCut() { MusECore::globalCut(); } void ArrangerView::globalInsert() { MusECore::globalInsert(); } void ArrangerView::globalSplit() { MusECore::globalSplit(); } +// variants only applicable for selected tracks +void ArrangerView::globalCutSel() { MusECore::globalCut(true); } +void ArrangerView::globalInsertSel() { MusECore::globalInsert(true); } +void ArrangerView::globalSplitSel() { MusECore::globalSplit(true); } + } // namespace MusEGui diff --git a/muse2/muse/arranger/arrangerview.h b/muse2/muse/arranger/arrangerview.h index de610bd6..c56767a6 100644 --- a/muse2/muse/arranger/arrangerview.h +++ b/muse2/muse/arranger/arrangerview.h @@ -89,7 +89,8 @@ class ArrangerView : public TopWin QMenu* master; QAction *strGlobalCutAction, *strGlobalInsertAction, *strGlobalSplitAction; - QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction; + QAction *strGlobalCutSelAction, *strGlobalInsertSelAction, *strGlobalSplitSelAction; + QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction; QAction *trackAInputAction, *trackAAuxAction; QAction *editCutAction, *editCopyAction, *editCopyRangeAction; QAction *editPasteAction, *editPasteCloneAction, *editPasteDialogAction, *editPasteCloneDialogAction; @@ -119,11 +120,14 @@ class ArrangerView : public TopWin void globalCut(); void globalInsert(); void globalSplit(); - void cmd(int); + void globalCutSel(); + void globalInsertSel(); + void globalSplitSel(); + void cmd(int); void addNewTrack(QAction* action); signals: - void deleted(MusEGui::TopWin*); + void isDeleting(MusEGui::TopWin*); void closed(); public slots: diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index d19fa082..f190de3b 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -3,7 +3,7 @@ // Linux Music Editor // $Id: pcanvas.cpp,v 1.48.2.26 2009/11/22 11:08:33 spamatica Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) -// (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -302,12 +302,9 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp QPoint newpos = raster(QPoint(nx, ny)); selectItem(ci, true); - MusECore::UndoOp operation=moveItem(ci, newpos, dtype); - if (operation.type != MusECore::UndoOp::DoNothing) - { + bool result=moveItem(operations, ci, newpos, dtype); + if (result) ci->move(newpos); - operations.push_back(operation); - } if(moving.size() == 1) { itemReleased(curItem, newpos); @@ -326,37 +323,41 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp //--------------------------------------------------------- // Changed by T356. -MusECore::UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) +bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& newpos, DragType t) { - MusECore::UndoOp result; NPart* npart = (NPart*) item; MusECore::Part* spart = npart->part(); MusECore::Track* track = npart->track(); + MusECore::Track* dtrack=NULL; unsigned dtick = newpos.x(); unsigned ntrack = y2pitch(item->mp().y()); MusECore::Track::TrackType type = track->type(); if (tracks->index(track) == ntrack && (dtick == spart->tick())) { - return MusECore::UndoOp(MusECore::UndoOp::DoNothing); + return false; } if (ntrack >= tracks->size()) { ntrack = tracks->size(); if (MusEGlobal::debugMsg) printf("PartCanvas::moveItem - add new track\n"); - MusECore::Track* newTrack = MusEGlobal::song->addTrack(type); // Add at end of list. + dtrack = MusEGlobal::song->addTrack(operations, type); // Add at end of list. + if (type == MusECore::Track::WAVE) { MusECore::WaveTrack* st = (MusECore::WaveTrack*) track; - MusECore::WaveTrack* dt = (MusECore::WaveTrack*) newTrack; + MusECore::WaveTrack* dt = (MusECore::WaveTrack*) dtrack; dt->setChannels(st->channels()); } emit tracklistChanged(); } - MusECore::Track* dtrack = tracks->index(ntrack); - if (dtrack->type() != type) { - QMessageBox::critical(this, QString("MusE"), - tr("Cannot copy/move/clone to different Track-Type")); - return MusECore::UndoOp(MusECore::UndoOp::DoNothing); + else + { + dtrack = tracks->index(ntrack); + if (dtrack->type() != type) { + QMessageBox::critical(this, QString("MusE"), + tr("Cannot copy/move/clone to different Track-Type")); + return false; + } } - + MusECore::Part* dpart; bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->events()->arefCount() > 1)); @@ -397,22 +398,24 @@ MusECore::UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragTyp if (t == MOVE_COPY || t == MOVE_CLONE) { // These will not increment ref count, and will not chain clones... // TODO FINDMICH: is this still correct (by flo93)? i doubt it! - result=MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart); + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); } else if (t == MOVE_MOVE) { dpart->setSelected(spart->selected()); // These will increment ref count if not a clone, and will chain clones... // TODO FINDMICH: is this still correct (by flo93)? i doubt it! - result=MusECore::UndoOp(MusECore::UndoOp::ModifyPart,spart, dpart, true, false); + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyPart,spart, dpart, true, false)); spart->setSelected(false); } - // else // will never happen -> result will always be defined + // else // will never happen -> operations will never be empty if (MusEGlobal::song->len() < (dpart->lenTick() + dpart->tick())) - MusEGlobal::song->setLen(dpart->lenTick() + dpart->tick()); - - return result; + operations.push_back( MusECore::UndoOp(MusECore::UndoOp::ModifySongLen, + dpart->lenTick() + dpart->tick(), + MusEGlobal::song->len() ) ); + + return true; } //--------------------------------------------------------- @@ -883,8 +886,8 @@ void PartCanvas::mousePress(QMouseEvent* event) default: if (item) emit trackChanged(item->part()->track()); - else - emit trackChanged(NULL); + //else -- don't see the point of removing track selection, commenting out (rj) + // emit trackChanged(NULL); break; case CutTool: if (item) splitItem(item, pt); @@ -1193,7 +1196,7 @@ void PartCanvas::keyPress(QKeyEvent* event) //If we're at topmost, leave if (!track) { - printf("no track above!\n"); + //printf("no track above!\n"); return; } int middle = curItem->x() + curItem->part()->lenTick()/2; @@ -1327,17 +1330,25 @@ void PartCanvas::keyPress(QKeyEvent* event) curItem = newItem; selectItem(newItem, true); - //Check if we've hit the upper or lower boundaries of the window. If so, set a new position + //Check if we've hit the left, right, upper or lower boundaries of the window. If so, scroll to new position. if (newItem->x() < mapxDev(0)) { - int curpos = pos[0]; - setPos(0,newItem->x(),true); - setPos(0,curpos,false); //Dummy to put the current position back once we've scrolled + emit horizontalScroll(rmapx(newItem->x() - xorg) - 10); // Leave some room. + } + else if (newItem->x() + newItem->width() > mapxDev(width())) { + int mx = rmapx(newItem->x()); + int newx = mx + rmapx(newItem->width()) - width(); + emit horizontalScroll( (newx > mx ? mx - 10 : newx + 10) - rmapx(xorg) ); + } + + if (newItem->y() < mapyDev(0)) { + int my = rmapy(newItem->y()); + int newy = my + rmapy(newItem->height()) - height(); + emit verticalScroll( (newy < my ? my - 10 : newy + 10) - rmapy(yorg) ); } - else if (newItem->x() > mapxDev(width())) { - int curpos = pos[0]; - setPos(0,newItem->x(),true); - setPos(0,curpos,false); //Dummy to put the current position back once we've scrolled + else if (newItem->y() + newItem->height() > mapyDev(height())) { + emit verticalScroll( rmapy(newItem->y() + newItem->height() - yorg) - height() + 10); } + redraw(); } } @@ -2299,9 +2310,9 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, MusECore::EventList* ev //else // color_brightness=64; // otherwise use dark color if (brightness >= 12000 && !pt->selected()) - color_brightness=64; // 96; // too bright: use dark color + color_brightness=54; // 96; // too bright: use dark color else - color_brightness=190; //160; // too dark: use lighter color + color_brightness=200; //160; // too dark: use lighter color } else color_brightness=80; @@ -3207,9 +3218,13 @@ void PartCanvas::viewDropEvent(QDropEvent* event) if (!track) { // we need to create a track for this drop if (text.endsWith(".mpt", Qt::CaseInsensitive)) { - track = MusEGlobal::song->addTrack(MusECore::Track::MIDI); // Add at end of list. + MusECore::Undo operations; + track = MusEGlobal::song->addTrack(operations, MusECore::Track::MIDI); // Add at end of list. + MusEGlobal::song->applyOperationGroup(operations); } else { - track = MusEGlobal::song->addTrack(MusECore::Track::WAVE); // Add at end of list. + MusECore::Undo operations; + track = MusEGlobal::song->addTrack(operations, MusECore::Track::WAVE); // Add at end of list. + MusEGlobal::song->applyOperationGroup(operations); } } if (track->type() == MusECore::Track::WAVE && @@ -3634,7 +3649,8 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, MusECore::AudioTra { double y; if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume - y = dbToVal(cl->curVal()); // represent volume between 0 and 1 + //printf("log conversion val=%f min=%f max=%f\n", cl->curVal(), min, max); + y = logToVal(cl->curVal(), min, max); // represent volume between 0 and 1 if (y < 0) y = 0.0; } else @@ -3647,7 +3663,8 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, MusECore::AudioTra { double y = ic->second.val; if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume - y = dbToVal(y); // represent volume between 0 and 1 + //printf("log conversion val=%f min=%f max=%f\n", cl->curVal(), min, max); + y = logToVal(y, min, max); // represent volume between 0 and 1 if (y < 0) y = 0.0; } else @@ -3746,7 +3763,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo { double y; if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume - y = dbToVal(cl->curVal()); // represent volume between 0 and 1 + y = logToVal(cl->curVal(), min, max); // represent volume between 0 and 1 if (y < 0) y = 0.0; } else @@ -3759,7 +3776,7 @@ void PartCanvas::checkAutomation(MusECore::Track * t, const QPoint &pointer, boo { double y = ic->second.val; if (cl->valueType() == MusECore::VAL_LOG ) { // use db scale for volume - y = dbToVal(y); // represent volume between 0 and 1 + y = logToVal(y, min, max); // represent volume between 0 and 1 if (y < 0) y = 0; } else @@ -3951,7 +3968,8 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) automation.currentCtrlList->range(&min,&max); double cvval; if (automation.currentCtrlList->valueType() == MusECore::VAL_LOG ) { // use db scale for volume - cvval = valToDb(yfraction); + printf("log conversion val=%f min=%f max=%f\n", yfraction, min, max); + cvval = valToLog(yfraction, min, max); //printf("calc yfraction = %f v=%f ",yfraction,cvval); if (cvval< min) cvval=min; if (cvval>max) cvval=max; @@ -3984,13 +4002,45 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) } -double PartCanvas::dbToVal(double inDb) +//--------------------------------------------------------- +// +// logToVal +// - represent logarithmic value on linear scale from 0 to 1 +// +//--------------------------------------------------------- +double PartCanvas::logToVal(double inLog, double min, double max) { - return (20.0*MusECore::fast_log10(inDb)+60.0) / 70.0; + //printf("logToVal inLog %f :", inLog); + if (inLog < min) inLog = min; + if (inLog > max) inLog = max; + double linMin = 20.0*MusECore::fast_log10(min); + double linMax = 20.0*MusECore::fast_log10(max); + double linVal = 20.0*MusECore::fast_log10(inLog); + + double outVal = (linVal-linMin) / (linMax - linMin); + // printf("inLog %f outVal %f linVal %f min %f max %f dbMin %f dbMax %f\n", inLog, outVal, linVal, min, max, linMin, linMax); + + return outVal; } -double PartCanvas::valToDb(double inV) + +//--------------------------------------------------------- +// +// valToLog +// - represent value from 0 to 1 as logarithmic value between min and max +// +//--------------------------------------------------------- +double PartCanvas::valToLog(double inV, double min, double max) { - return exp10((inV*70.0-60.0)/20.0); + double linMin = 20.0*MusECore::fast_log10(min); + double linMax = 20.0*MusECore::fast_log10(max); + + double linVal = (inV * (linMax - linMin)) + linMin; + double outVal = exp10((linVal)/20.0); + + //printf("::valToLog inV %f outVal %f linVal %f min %f max %f\n", inV, outVal, linVal, min, max); + if (outVal > max) outVal = max; + if (outVal < min) outVal = min; + return outVal; } //--------------------------------------------------------- diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index 78b88a5c..34395688 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -119,7 +119,7 @@ class PartCanvas : public Canvas { virtual void newItem(CItem*,bool); virtual bool deleteItem(CItem*); virtual void moveCanvasItems(CItemList&, int, int, DragType); - virtual MusECore::UndoOp moveItem(CItem*, const QPoint&, DragType); + virtual bool moveItem(MusECore::Undo& operations, CItem*, const QPoint&, DragType); virtual void updateSong(DragType, int); virtual void startDrag(CItem*, DragType); @@ -148,8 +148,8 @@ class PartCanvas : public Canvas { void checkAutomation(MusECore::Track * t, const QPoint& pointer, bool addNewCtrl); void processAutomationMovements(QPoint pos, bool addPoint); - double dbToVal(double inDb); - double valToDb(double inV); + double logToVal(double inLog, double min, double max); + double valToLog(double inV, double min, double max); protected: virtual void drawCanvas(QPainter&, const QRect&); diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 1e3ad419..620a24b7 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -62,6 +62,7 @@ #include "synth.h" #include "config.h" #include "popupmenu.h" +#include "menutitleitem.h" #ifdef DSSI_SUPPORT #include "dssihost.h" @@ -392,7 +393,7 @@ void TList::paint(const QRect& r) countVisible++; } //int count = ((MusECore::AudioTrack*)track)->controller()->size(); //commented out by flo: gives a "unused variable" warning - s.sprintf(" %d(%d) visible",countVisible, countAll); + s.sprintf(" %d(%d) %s",countVisible, countAll, tr("visible").toAscii().data()); } @@ -584,12 +585,17 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y) switch(t->type()) { case MusECore::Track::MIDI: case MusECore::Track::DRUM: + // FINDMICHJETZT: this is a notice for flo's experimental + // branch! don't forget NEW_DRUM here! + // please don't remove this. i'll do it when + // the time is there. case MusECore::Track::AUDIO_SOFTSYNTH: { MusECore::MidiTrack* track = (MusECore::MidiTrack*)t; //QPopupMenu* p = MusECore::midiPortsPopup(0); MusECore::MidiDevice* md = 0; + int potential_new_port_no=-1; int port = -1; if(t->type() == MusECore::Track::AUDIO_SOFTSYNTH) { @@ -602,25 +608,158 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y) port = track->outPort(); QMenu* p = MusECore::midiPortsPopup(this, port); // 0, port); + + if (t->type()==MusECore::Track::MIDI || t->type()==MusECore::Track::DRUM) //FINDMICHJETZT + { + // extend that menu a bit + + + // find first free port number + // do not permit numbers already used in other tracks! + // except if it's only used in this track. + int no; + for (no=0;notracks()->begin(); it!=MusEGlobal::song->tracks()->end(); it++) + { + MusECore::MidiTrack* mt=dynamic_cast(*it); + if (mt && mt!=t && mt->outPort()==no) + break; + } + if (it == MusEGlobal::song->tracks()->end()) + break; + } + + if (no==MIDI_PORTS) + { + delete p; + printf("THIS IS VERY UNLIKELY TO HAPPEN: no free midi ports! you have used all %i!\n",MIDI_PORTS); + break; + } + + + potential_new_port_no=no; + typedef std::map asmap; + typedef std::map::iterator imap; + + asmap mapALSA; + asmap mapJACK; + + int aix = 0x10000000; + int jix = 0x20000000; + for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i) + { + if((*i)->deviceType() == MusECore::MidiDevice::ALSA_MIDI) + { + // don't add devices which are used somewhere + int j; + for (j=0;j (std::string((*i)->name().toLatin1().constData()), aix) ); + + ++aix; + } + else if((*i)->deviceType() == MusECore::MidiDevice::JACK_MIDI) + { + // don't add devices which are used somewhere + int j; + for (j=0;j (std::string((*i)->name().toLatin1().constData()), jix) ); + ++jix; + } + } + + if (!mapALSA.empty() || !mapJACK.empty()) + { + QMenu* pup = p->addMenu(tr("Unused Devices")); + QAction* act; + + + if (!mapALSA.empty()) + { + pup->addAction(new MusEGui::MenuTitleItem("ALSA:", pup)); + + for(imap i = mapALSA.begin(); i != mapALSA.end(); ++i) + { + int idx = i->second; + QString s(i->first.c_str()); + MusECore::MidiDevice* md = MusEGlobal::midiDevices.find(s, MusECore::MidiDevice::ALSA_MIDI); + if(md) + { + if(md->deviceType() != MusECore::MidiDevice::ALSA_MIDI) + continue; + + act = pup->addAction(md->name()); + act->setData(idx); + } + } + } + + if (!mapALSA.empty() && !mapJACK.empty()) + pup->addSeparator(); + + if (!mapJACK.empty()) + { + pup->addAction(new MusEGui::MenuTitleItem("JACK:", pup)); + + for(imap i = mapJACK.begin(); i != mapJACK.end(); ++i) + { + int idx = i->second; + QString s(i->first.c_str()); + MusECore::MidiDevice* md = MusEGlobal::midiDevices.find(s, MusECore::MidiDevice::JACK_MIDI); + if(md) + { + if(md->deviceType() != MusECore::MidiDevice::JACK_MIDI) + continue; + + act = pup->addAction(md->name()); + act->setData(idx); + } + } + } + } + } + + QAction* act = p->exec(mapToGlobal(QPoint(x, y)), 0); if(!act) { delete p; break; } - + + QString acttext=act->text(); int n = act->data().toInt(); delete p; if(n < 0) // Invalid item. break; - if(n >= MIDI_PORTS) // Show port config dialog. + if(n == MIDI_PORTS) // Show port config dialog. { MusEGlobal::muse->configMidiPorts(); break; } + else if (n & 0x30000000) + { + int typ; + if (n & 0x10000000) + typ = MusECore::MidiDevice::ALSA_MIDI; + else + typ = MusECore::MidiDevice::JACK_MIDI; + MusECore::MidiDevice* sdev = MusEGlobal::midiDevices.find(acttext, typ); + + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[potential_new_port_no], sdev); + n=potential_new_port_no; + } // Changed by T356. //track->setOutPort(n); //MusEGlobal::audio->msgSetTrackOutPort(track, n); @@ -1049,7 +1188,7 @@ void TList::mousePressEvent(QMouseEvent* ev) if(act) { t = MusEGlobal::song->addNewTrack(act); // Add at end of list. - if(t) + if(t && t->isVisible()) { MusEGlobal::song->deselectTracks(); t->setSelected(true); @@ -1064,13 +1203,13 @@ void TList::mousePressEvent(QMouseEvent* ev) //delete synp; delete p; } - else if (button == Qt::LeftButton) { + /*else if (button == Qt::LeftButton) { if (!ctrl) { MusEGlobal::song->deselectTracks(); emit selectionChanged(0); } - } + }*/ return; } @@ -1108,7 +1247,8 @@ void TList::mousePressEvent(QMouseEvent* ev) return; } - mode = START_DRAG; + + mode = NORMAL; switch (col) { case COL_CLEF: @@ -1137,8 +1277,8 @@ void TList::mousePressEvent(QMouseEvent* ev) } delete p; } - break; + case COL_AUTOMATION: { if (!t->isMidiTrack()) { @@ -1174,6 +1314,8 @@ void TList::mousePressEvent(QMouseEvent* ev) case COL_RECORD: { + mode = START_DRAG; + bool val = !(t->recordFlag()); if (button == Qt::LeftButton) { if (!t->isMidiTrack()) { @@ -1212,6 +1354,7 @@ void TList::mousePressEvent(QMouseEvent* ev) } break; case COL_NONE: + mode = START_DRAG; break; case COL_CLASS: if (t->isMidiTrack()) @@ -1232,9 +1375,10 @@ void TList::mousePressEvent(QMouseEvent* ev) //MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14 //MusEGlobal::song->update(SC_ROUTE); // - break; + case COL_MUTE: + mode = START_DRAG; // p3.3.29 if ((button == Qt::RightButton) || (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier)) t->setOff(!t->off()); @@ -1248,11 +1392,13 @@ void TList::mousePressEvent(QMouseEvent* ev) MusEGlobal::song->update(SC_MUTE); break; case COL_SOLO: + mode = START_DRAG; MusEGlobal::audio->msgSetSolo(t, !t->solo()); MusEGlobal::song->update(SC_SOLO); break; case COL_NAME: + mode = START_DRAG; if (button == Qt::LeftButton) { if (!ctrl) { MusEGlobal::song->deselectTracks(); @@ -1327,11 +1473,13 @@ void TList::mousePressEvent(QMouseEvent* ev) break; case COL_TIMELOCK: + mode = START_DRAG; t->setLocked(!t->locked()); break; case COL_OCHANNEL: { + mode = START_DRAG; // or not? (flo) int delta = 0; if (button == Qt::RightButton) delta = 1; @@ -1397,6 +1545,9 @@ void TList::mousePressEvent(QMouseEvent* ev) } } break; + + default: + mode = START_DRAG; } redraw(); } diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index fd90c2c2..0b1574cc 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -25,8 +25,6 @@ #include #include -#include - #include "app.h" #include "song.h" #include "node.h" @@ -51,10 +49,18 @@ namespace MusEGlobal { MusECore::Audio* audio; MusECore::AudioDevice* audioDevice; // current audio device in use -extern unsigned int volatile midiExtSyncTicks; // p3.3.25 +extern unsigned int volatile midiExtSyncTicks; } namespace MusECore { + + +void initAudio() +{ + MusEGlobal::audio = new Audio(); +} + + extern double curTime(); //static const unsigned char mmcDeferredPlayMsg[] = { 0x7f, 0x7f, 0x06, 0x03 }; @@ -166,8 +172,11 @@ Audio::Audio() exit(-1); } sigFd = filedes[1]; - QSocketNotifier* ss = new QSocketNotifier(filedes[0], QSocketNotifier::Read); - MusEGlobal::song->connect(ss, SIGNAL(activated(int)), MusEGlobal::song, SLOT(seqSignal(int))); + sigFdr = filedes[0]; + + // Moved to MusE::MusE + //QSocketNotifier* ss = new QSocketNotifier(filedes[0], QSocketNotifier::Read); + //MusEGlobal::song->connect(ss, SIGNAL(activated(int)), MusEGlobal::song, SLOT(seqSignal(int))); } //--------------------------------------------------------- @@ -182,7 +191,9 @@ bool Audio::start() //process(MusEGlobal::segmentSize); // warm up caches state = STOP; _loopCount = 0; - MusEGlobal::muse->setHeartBeat(); + + MusEGlobal::muse->setHeartBeat(); + if (MusEGlobal::audioDevice) { //_running = true; //MusEGlobal::audioDevice->start(); @@ -221,9 +232,11 @@ bool Audio::start() // shall we really stop JACK transport and locate to // saved position? - MusEGlobal::audioDevice->stopTransport(); + MusEGlobal::audioDevice->stopTransport(); + //MusEGlobal::audioDevice->seekTransport(MusEGlobal::song->cPos().frame()); - MusEGlobal::audioDevice->seekTransport(MusEGlobal::song->cPos()); + MusEGlobal::audioDevice->seekTransport(MusEGlobal::song->cPos()); + return true; } @@ -531,6 +544,26 @@ void Audio::process1(unsigned samplePos, unsigned offset, unsigned frames) // Pre-process the metronome. ((AudioTrack*)metronome)->preProcessAlways(); + // Process Aux tracks first. + for(ciTrack it = tl->begin(); it != tl->end(); ++it) + { + if((*it)->isMidiTrack()) + continue; + track = (AudioTrack*)(*it); + if(!track->processed() && track->type() == Track::AUDIO_AUX) + { + //printf("Audio::process1 Do aux: track:%s\n", track->name().toLatin1().constData()); + channels = track->channels(); + // Just a dummy buffer. + float* buffer[channels]; + float data[frames * channels]; + for (int i = 0; i < channels; ++i) + buffer[i] = data + i * frames; + //printf("Audio::process1 calling track->copyData for track:%s\n", track->name().toLatin1()); + track->copyData(samplePos, channels, -1, -1, frames, buffer); + } + } + OutputList* ol = MusEGlobal::song->outputs(); for (ciAudioOutput i = ol->begin(); i != ol->end(); ++i) (*i)->process(samplePos, offset, frames); @@ -548,8 +581,11 @@ void Audio::process1(unsigned samplePos, unsigned offset, unsigned frames) track = (AudioTrack*)(*it); // Ignore unprocessed tracks which have an output route, because they will be processed by // whatever track(s) they are routed to. - if(!track->processed() && track->noOutRoute() && (track->type() != Track::AUDIO_OUTPUT)) + //if(!track->processed() && track->noOutRoute() && (track->type() != Track::AUDIO_OUTPUT)) + // No, do all. + if(!track->processed() && (track->type() != Track::AUDIO_OUTPUT)) { + //printf("Audio::process1 track:%s\n", track->name().toLatin1().constData()); channels = track->channels(); // Just a dummy buffer. float* buffer[channels]; diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h index 8d89be78..3c4eb17d 100644 --- a/muse2/muse/audio.h +++ b/muse2/muse/audio.h @@ -166,7 +166,9 @@ class Audio { int fromThreadFdw, fromThreadFdr; // message pipe int sigFd; // pipe fd for messages to gui - + //QSocketNotifier* _socketNotifier; + int sigFdr; + // record values: Pos startRecordPos; Pos endRecordPos; @@ -189,8 +191,12 @@ class Audio { public: Audio(); - virtual ~Audio() {} + virtual ~Audio() { } + // Access to message pipe (like from gui namespace), otherwise audio would need to depend on gui. + int getFromThreadFdw() { return sigFd; } + int getFromThreadFdr() { return sigFdr; } + void process(unsigned frames); bool sync(int state, unsigned frame); void shutdown(); diff --git a/muse2/muse/audioprefetch.cpp b/muse2/muse/audioprefetch.cpp index 9406911f..1fcb7cef 100644 --- a/muse2/muse/audioprefetch.cpp +++ b/muse2/muse/audioprefetch.cpp @@ -39,7 +39,11 @@ MusECore::AudioPrefetch* audioPrefetch; namespace MusECore { -// Added by Tim. p3.3.20 +void initAudioPrefetch() +{ + MusEGlobal::audioPrefetch = new AudioPrefetch("Prefetch"); +} + //#define AUDIOPREFETCH_DEBUG enum { PREFETCH_TICK, PREFETCH_SEEK @@ -140,6 +144,7 @@ void AudioPrefetch::msgTick() { PrefetchMsg msg; msg.id = PREFETCH_TICK; + msg.pos = 0; // seems to be unused, was uninitalized. while (sendMsg1(&msg, sizeof(msg))) { printf("AudioPrefetch::msgTick(): send failed!\n"); } diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp index b674e20c..aceacc75 100644 --- a/muse2/muse/audiotrack.cpp +++ b/muse2/muse/audiotrack.cpp @@ -107,7 +107,7 @@ AudioTrack::AudioTrack(TrackType t) _automationType = AUTO_OFF; //setChannels(1); setChannels(2); - addController(new CtrlList(AC_VOLUME,"Volume",0.0,3.16 /* roughly 10 db */, VAL_LOG)); + addController(new CtrlList(AC_VOLUME,"Volume",0.001,3.163 /* roughly 10 db */, VAL_LOG)); addController(new CtrlList(AC_PAN, "Pan", -1.0, 1.0, VAL_LINEAR)); addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0, VAL_LINEAR, true /*dont show in arranger */)); @@ -1610,8 +1610,40 @@ void AudioAux::read(Xml& xml) // getData //--------------------------------------------------------- -bool AudioAux::getData(unsigned /*pos*/, int ch, unsigned /*samples*/, float** data) +bool AudioAux::getData(unsigned pos, int ch, unsigned samples, float** data) { + // Make sure all the aux-supporting tracks are processed first so aux data is gathered. p4.0.37 + TrackList* tl = MusEGlobal::song->tracks(); + AudioTrack* track; + for(ciTrack it = tl->begin(); it != tl->end(); ++it) + { + if((*it)->isMidiTrack()) + continue; + track = (AudioTrack*)(*it); + // If there are any Aux route paths to the track, defer processing until the second main track processing pass. + if(!track->processed() && track->hasAuxSend() && !track->auxRefCount()) + { + int chans = track->channels(); + // Just a dummy buffer. + float* buff[chans]; + float buff_data[samples * chans]; + for (int i = 0; i < chans; ++i) + buff[i] = buff_data + i * samples; + + //printf("AudioAux::getData name:%s\n calling copyData on:%s auxRefCount:%d\n", + // name().toLatin1().constData(), track->name().toLatin1().constData(), track->auxRefCount()); + + track->copyData(pos, chans, -1, -1, samples, buff); + + /* float* buff[ch]; + float buff_data[samples * ch]; + for (int i = 0; i < ch; ++i) + buff[i] = buff_data + i * samples; + //printf("Audio::process1 calling track->copyData for track:%s\n", track->name().toLatin1()); + track->copyData(pos, ch, -1, -1, samples, buff); */ + } + } + for (int i = 0; i < ch; ++i) data[i] = buffer[i % channels()]; return true; diff --git a/muse2/muse/cliplist/cliplist.cpp b/muse2/muse/cliplist/cliplist.cpp index 1055f449..60041dae 100644 --- a/muse2/muse/cliplist/cliplist.cpp +++ b/muse2/muse/cliplist/cliplist.cpp @@ -32,6 +32,7 @@ #include "wave.h" #include "xml.h" #include "ui_cliplisteditorbase.h" +#include "app.h" namespace MusEGui { @@ -168,6 +169,7 @@ ClipListEdit::ClipListEdit(QWidget* parent) connect(editor->len, SIGNAL(valueChanged(const MusECore::Pos&)), SLOT(lenChanged(const MusECore::Pos&))); updateList(); + MusEGlobal::muse->topwinMenuInited(this); } ClipListEdit::~ClipListEdit() diff --git a/muse2/muse/cobject.cpp b/muse2/muse/cobject.cpp index 80fc7eae..50586d45 100644 --- a/muse2/muse/cobject.cpp +++ b/muse2/muse/cobject.cpp @@ -50,7 +50,7 @@ bool TopWin::initInited=false; TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlags f) : QMainWindow(parent, f) { - _isDeleting = false; + _isDeleting = false; if (initInited==false) initConfiguration(); @@ -78,7 +78,10 @@ TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlag mdisubwin=NULL; _sharesToolsAndMenu=_defaultSubwin[_type] ? _sharesWhenSubwin[_type] : _sharesWhenFree[_type]; if (_defaultSubwin[_type]) + { setIsMdiWin(true); + _savedToolbarState=_toolbarNonsharedInit[_type]; + } if (_sharesToolsAndMenu) menuBar()->hide(); @@ -125,7 +128,11 @@ void TopWin::readStatus(MusECore::Xml& xml) if (!sharesToolsAndMenu()) { if (!restoreState(QByteArray::fromHex(xml.parse1().toAscii()))) - fprintf(stderr,"ERROR: couldn't restore toolbars. however, this is not really a problem.\n"); + { + fprintf(stderr,"ERROR: couldn't restore toolbars. trying default configuration...\n"); + if (!restoreState(_toolbarNonsharedInit[_type])) + fprintf(stderr,"ERROR: couldn't restore default toolbars. this is not really a problem.\n"); + } } else { @@ -565,4 +572,15 @@ void TopWin::resize(const QSize& s) resize(s.width(), s.height()); } +TopWin* ToplevelList::findType(TopWin::ToplevelType type) const +{ + for (ciToplevel i = begin(); i != end(); ++i) + { + if((*i)->type() == type) + return (*i); + } + return 0; +} + + } // namespace MusEGui diff --git a/muse2/muse/cobject.h b/muse2/muse/cobject.h index 309d8424..f6ea2ce1 100644 --- a/muse2/muse/cobject.h +++ b/muse2/muse/cobject.h @@ -141,9 +141,21 @@ class TopWin : public QMainWindow }; -typedef std::list ToplevelList; -typedef ToplevelList::iterator iToplevel; -typedef ToplevelList::const_iterator ciToplevel; +//--------------------------------------------------------- +// ToplevelList +//--------------------------------------------------------- + +//typedef std::list ToplevelList; +//typedef ToplevelList::iterator iToplevel; +//typedef ToplevelList::const_iterator ciToplevel; + +typedef std::list::iterator iToplevel; +typedef std::list::const_iterator ciToplevel; + +class ToplevelList : public std::list { + public: + TopWin* findType(TopWin::ToplevelType) const; + }; } // namespace MusEGui diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index c11adf7b..ea2b33f3 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -220,7 +220,7 @@ static void readPortChannel(Xml& xml, int midiPort) // readConfigMidiPort //--------------------------------------------------------- -static void readConfigMidiPort(Xml& xml) +static void readConfigMidiPort(Xml& xml, bool skipConfig) { int idx = 0; QString device; @@ -234,11 +234,9 @@ static void readConfigMidiPort(Xml& xml) // FIXME: TODO: Make this user-configurable! QString instrument("GM"); + int rwFlags = 3; int openFlags = 1; - bool thruFlag = false; - //int dic = 0; - //int doc = 0; - int dic = -1; // p4.0.17 + int dic = -1; int doc = -1; MidiSyncInfo tmpSi; @@ -251,6 +249,19 @@ static void readConfigMidiPort(Xml& xml) QString tag = xml.s1(); switch (token) { case Xml::TagStart: + + // skipConfig added so it doesn't overwrite midi ports. p4.0.41 Tim. + // Try to keep the controller information. But, this may need to be moved below. + // Also may want to try to keep sync info, but that's a bit risky, so let's not for now. + if (tag == "channel") { + readPortChannel(xml, idx); + break; + } + else if (skipConfig){ + xml.skip(tag); + break; + } + if (tag == "name") device = xml.parse1(); else if (tag == "type") @@ -262,6 +273,8 @@ static void readConfigMidiPort(Xml& xml) } else if (tag == "openFlags") openFlags = xml.parseInt(); + else if (tag == "rwFlags") // Jack midi devs need this. p4.0.41 + rwFlags = xml.parseInt(); else if (tag == "defaultInChans") dic = xml.parseInt(); else if (tag == "defaultOutChans") @@ -270,16 +283,15 @@ static void readConfigMidiPort(Xml& xml) tmpSi.read(xml); else if (tag == "instrument") { instrument = xml.parse1(); - // Moved by Tim. - //MusEGlobal::midiPorts[idx].setInstrument( + //MusEGlobal::midiPorts[idx].setInstrument( // Moved below // registerMidiInstrument(instrument) // ); } else if (tag == "midithru") - thruFlag = xml.parseInt(); // obsolete - else if (tag == "channel") { - readPortChannel(xml, idx); - } + xml.parseInt(); // obsolete + //else if (tag == "channel") { + // readPortChannel(xml, idx); // Moved above + // } else xml.unknown("MidiDevice"); break; @@ -290,6 +302,10 @@ static void readConfigMidiPort(Xml& xml) break; case Xml::TagEnd: if (tag == "midiport") { + + if(skipConfig) // p4.0.41 + return; + //if (idx > MIDI_PORTS) { if (idx < 0 || idx >= MIDI_PORTS) { fprintf(stderr, "bad midi port %d (>%d)\n", @@ -305,9 +321,8 @@ static void readConfigMidiPort(Xml& xml) if(!dev && type == MidiDevice::JACK_MIDI) { if(MusEGlobal::debugMsg) - fprintf(stderr, "readConfigMidiPort: creating jack midi device %s\n", device.toLatin1().constData()); - //dev = MidiJackDevice::createJackMidiDevice(device, openFlags); - dev = MidiJackDevice::createJackMidiDevice(device); // p3.3.55 + fprintf(stderr, "readConfigMidiPort: creating jack midi device %s with rwFlags:%d\n", device.toLatin1().constData(), rwFlags); + dev = MidiJackDevice::createJackMidiDevice(device, rwFlags); } if(MusEGlobal::debugMsg && !dev) @@ -315,7 +330,7 @@ static void readConfigMidiPort(Xml& xml) MidiPort* mp = &MusEGlobal::midiPorts[idx]; - mp->setInstrument(registerMidiInstrument(instrument)); // By Tim. + mp->setInstrument(registerMidiInstrument(instrument)); if(dic != -1) // p4.0.17 Leave them alone unless set by song. mp->setDefaultInChannels(dic); if(doc != -1) @@ -480,7 +495,7 @@ static void loadConfigMetronom(Xml& xml) // readSeqConfiguration //--------------------------------------------------------- -static void readSeqConfiguration(Xml& xml) +static void readSeqConfiguration(Xml& xml, bool skipConfig) { for (;;) { Xml::Token token = xml.parse(); @@ -492,7 +507,7 @@ static void readSeqConfiguration(Xml& xml) if (tag == "metronom") loadConfigMetronom(xml); else if (tag == "midiport") - readConfigMidiPort(xml); + readConfigMidiPort(xml, skipConfig); else if (tag == "rcStop") MusEGlobal::rcStopNote = xml.parseInt(); else if (tag == "rcEnable") @@ -542,7 +557,7 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig midiport configuration and VOLUME. */ if (tag == "sequencer") { - readSeqConfiguration(xml); + readSeqConfiguration(xml, readOnlySequencer); break; } else if (readOnlySequencer) { @@ -580,8 +595,10 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MidiTrack::setVisible((bool)xml.parseInt()); else if (tag == "inputTracksVisible") AudioInput::setVisible((bool)xml.parseInt()); - else if (tag == "outputTracksVisible") + else if (tag == "outputTracksVisible") { + printf("output track set from config!\n"); AudioOutput::setVisible((bool)xml.parseInt()); + } else if (tag == "synthTracksVisible") SynthI::setVisible((bool)xml.parseInt()); else if (tag == "bigtimeVisible") @@ -624,7 +641,18 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEGlobal::config.geometryTransport = readGeometry(xml, tag); else if (tag == "geometryBigTime") MusEGlobal::config.geometryBigTime = readGeometry(xml, tag); - + else if (tag == "Mixer") { + if(mixers == 0) + MusEGlobal::config.mixer1.read(xml); + else + MusEGlobal::config.mixer2.read(xml); + ++mixers; + } + else if (tag == "geometryMain") + MusEGlobal::config.geometryMain = readGeometry(xml, tag); + + // don't insert else if(...) clauses between + // this line and "Global config stuff begins here". else if (!doReadGlobalConfig) { xml.skip(tag); break; @@ -636,9 +664,6 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig // ---- Global config stuff begins here ---- - else if (tag == "geometryMain") - MusEGlobal::config.geometryMain = readGeometry(xml, tag); - else if (tag == "theme") MusEGlobal::config.style = xml.parse1(); else if (tag == "styleSheetFile") @@ -847,20 +872,6 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEGlobal::config.canvasBgPixmap = xml.parse1(); else if (tag == "canvasCustomBgList") MusEGlobal::config.canvasCustomBgList = xml.parse1().split(";", QString::SkipEmptyParts); - - //else if (tag == "mixer1") - // MusEGlobal::config.mixer1.read(xml); - //else if (tag == "mixer2") - // MusEGlobal::config.mixer2.read(xml); - else if (tag == "Mixer") - { - if(mixers == 0) - MusEGlobal::config.mixer1.read(xml); - else - MusEGlobal::config.mixer2.read(xml); - ++mixers; - } - else if (tag == "bigtimeForegroundcolor") MusEGlobal::config.bigTimeForegroundColor = readColor(xml); else if (tag == "bigtimeBackgroundcolor") @@ -932,8 +943,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEGlobal::config.minControlProcessPeriod = xml.parseUInt(); else if (tag == "guiRefresh") MusEGlobal::config.guiRefresh = xml.parseInt(); - else if (tag == "userInstrumentsDir") - MusEGlobal::config.userInstrumentsDir = xml.parse1(); + else if (tag == "userInstrumentsDir") // Obsolete + MusEGlobal::config.userInstrumentsDir = xml.parse1(); // Keep for compatibility else if (tag == "startMode") MusEGlobal::config.startMode = xml.parseInt(); else if (tag == "startSong") @@ -950,6 +961,10 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEGlobal::config.leftMouseButtonCanDecrease = xml.parseInt(); else if (tag == "rangeMarkerWithoutMMB") MusEGlobal::config.rangeMarkerWithoutMMB = xml.parseInt(); + else if (tag == "addHiddenTracks") + MusEGlobal::config.addHiddenTracks = xml.parseInt(); + else if (tag == "unhideTracks") + MusEGlobal::config.unhideTracks = xml.parseInt(); // ---- the following only skips obsolete entries ---- else if ((tag == "arranger") || (tag == "geometryPianoroll") || (tag == "geometryDrumedit")) @@ -1173,7 +1188,6 @@ static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo) if (dev) { xml.strTag(level, "name", dev->name()); - // p3.3.38 //if(dynamic_cast(dev)) if(dev->deviceType() != MidiDevice::ALSA_MIDI) //xml.intTag(level, "type", MidiDevice::JACK_MIDI); @@ -1183,6 +1197,9 @@ static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo) // openFlags was read before, but never written here. //xml.intTag(level, "record", dev->rwFlags() & 0x2 ? 1 : 0); xml.intTag(level, "openFlags", dev->openFlags()); + + if(dev->deviceType() == MidiDevice::JACK_MIDI) + xml.intTag(level, "rwFlags", dev->rwFlags()); // Need this. Jack midi devs are created by app. p4.0.41 } mport->syncInfo().write(level, xml); // write out registered controller for all channels @@ -1249,9 +1266,8 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "dummyAudioBufSize", MusEGlobal::config.dummyAudioBufSize); xml.intTag(level, "dummyAudioSampleRate", MusEGlobal::config.dummyAudioSampleRate); xml.uintTag(level, "minControlProcessPeriod", MusEGlobal::config.minControlProcessPeriod); - xml.intTag(level, "guiRefresh", MusEGlobal::config.guiRefresh); - xml.strTag(level, "userInstrumentsDir", MusEGlobal::config.userInstrumentsDir); + // Removed by Orcan. 20101220 //xml.strTag(level, "helpBrowser", config.helpBrowser); xml.intTag(level, "extendedMidi", MusEGlobal::config.extendedMidi); @@ -1287,6 +1303,17 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "leftMouseButtonCanDecrease", MusEGlobal::config.leftMouseButtonCanDecrease); xml.intTag(level, "rangeMarkerWithoutMMB", MusEGlobal::config.rangeMarkerWithoutMMB); + xml.intTag(level, "unhideTracks", MusEGlobal::config.unhideTracks); + xml.intTag(level, "addHiddenTracks", MusEGlobal::config.addHiddenTracks); + + xml.intTag(level, "waveTracksVisible", MusECore::WaveTrack::visible()); + xml.intTag(level, "auxTracksVisible", MusECore::AudioAux::visible()); + xml.intTag(level, "groupTracksVisible", MusECore::AudioGroup::visible()); + xml.intTag(level, "midiTracksVisible", MusECore::MidiTrack::visible()); + xml.intTag(level, "inputTracksVisible", MusECore::AudioInput::visible()); + xml.intTag(level, "outputTracksVisible", MusECore::AudioOutput::visible()); + xml.intTag(level, "synthTracksVisible", MusECore::SynthI::visible()); + //for (int i = 0; i < 6; ++i) { for (int i = 0; i < NUM_FONTS; ++i) { char buffer[32]; @@ -1339,7 +1366,6 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const xml.colorTag(level, "auxTrackBg", MusEGlobal::config.auxTrackBg); xml.colorTag(level, "synthTrackBg", MusEGlobal::config.synthTrackBg); - // Removed by Tim. p3.3.6 //xml.intTag(level, "txSyncPort", txSyncPort); //xml.intTag(level, "rxSyncPort", rxSyncPort); xml.intTag(level, "mtctype", MusEGlobal::mtcType); @@ -1366,11 +1392,8 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "bigtimeVisible", MusEGlobal::config.bigTimeVisible); xml.intTag(level, "transportVisible", MusEGlobal::config.transportVisible); - //xml.intTag(level, "mixerVisible", MusEGlobal::config.mixerVisible); // Obsolete xml.intTag(level, "mixer1Visible", MusEGlobal::config.mixer1Visible); xml.intTag(level, "mixer2Visible", MusEGlobal::config.mixer2Visible); - //MusEGlobal::config.mixer1.write(level, xml, "mixer1"); - //MusEGlobal::config.mixer2.write(level, xml, "mixer2"); MusEGlobal::config.mixer1.write(level, xml); MusEGlobal::config.mixer2.write(level, xml); @@ -1423,20 +1446,9 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "midiFilterCtrl3", MusEGlobal::midiFilterCtrl3); xml.intTag(level, "midiFilterCtrl4", MusEGlobal::midiFilterCtrl4); - xml.intTag(level, "waveTracksVisible", MusECore::WaveTrack::visible()); - xml.intTag(level, "auxTracksVisible", MusECore::AudioAux::visible()); - xml.intTag(level, "groupTracksVisible", MusECore::AudioGroup::visible()); - xml.intTag(level, "midiTracksVisible", MusECore::MidiTrack::visible()); - xml.intTag(level, "inputTracksVisible", MusECore::AudioInput::visible()); - xml.intTag(level, "outputTracksVisible", MusECore::AudioOutput::visible()); - xml.intTag(level, "synthTracksVisible", MusECore::SynthI::visible()); - // Removed by Tim. p3.3.6 - //xml.intTag(level, "txDeviceId", txDeviceId); //xml.intTag(level, "rxDeviceId", rxDeviceId); - // Changed by Tim. p3.3.6 - //xml.intTag(level, "txSyncPort", txSyncPort); /* // To keep old muse versions happy... @@ -1458,8 +1470,6 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const } */ - // Added by Tim. p3.3.6 - //xml.tag(level++, "midiSyncInfo"); //for(iMusECore::MidiDevice id = MusECore::MusEGlobal::midiDevices.begin(); id != MusECore::MusEGlobal::midiDevices.end(); ++id) //{ @@ -1487,8 +1497,6 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "bigtimeVisible", viewBigtimeAction->isChecked()); xml.intTag(level, "transportVisible", viewTransportAction->isChecked()); - //xml.intTag(level, "markerVisible", viewMarkerAction->isChecked()); // Obsolete (done by song's toplevel list) - //xml.intTag(level, "mixerVisible", menuView->isItemChecked(aid1)); // Obsolete xml.geometryTag(level, "geometryMain", this); // FINDME: maybe remove this? do we want // the main win to jump around when loading? @@ -1497,18 +1505,13 @@ void MusE::writeConfiguration(int level, MusECore::Xml& xml) const if (bigtime) xml.geometryTag(level, "geometryBigTime", bigtime); - //if (audioMixer) - // xml.geometryTag(level, "geometryMixer", audioMixer); // Obsolete xml.intTag(level, "mixer1Visible", viewMixerAAction->isChecked()); xml.intTag(level, "mixer2Visible", viewMixerBAction->isChecked()); if (mixer1) - //mixer1->write(level, xml, "mixer1"); mixer1->write(level, xml); if (mixer2) - //mixer2->write(level, xml, "mixer2"); mixer2->write(level, xml); - //_arranger->writeStatus(level, xml); // Obsolete. done by song's toplevel list. arrangerview also handles arranger. writeSeqConfiguration(level, xml, true); MusEGui::write_function_dialog_config(level, xml); @@ -1646,18 +1649,12 @@ namespace MusEGlobal { // write //--------------------------------------------------------- -//void MixerConfig::write(MusECore::Xml& xml, const char* name) void MixerConfig::write(int level, MusECore::Xml& xml) -//void MixerConfig::write(int level, MusECore::Xml& xml, const char* name) { - //xml.stag(QString(name)); - //xml.tag(level++, name.toLatin1().constData()); xml.tag(level++, "Mixer"); - //xml.tag(level++, name); - + xml.strTag(level, "name", name); - //xml.tag("geometry", geometry); xml.qrectTag(level, "geometry", geometry); xml.intTag(level, "showMidiTracks", showMidiTracks); @@ -1669,19 +1666,14 @@ void MixerConfig::write(int level, MusECore::Xml& xml) xml.intTag(level, "showAuxTracks", showAuxTracks); xml.intTag(level, "showSyntiTracks", showSyntiTracks); - //xml.etag(name); - //xml.etag(level, name.toLatin1().constData()); xml.etag(level, "Mixer"); - //xml.etag(level, name); } //--------------------------------------------------------- // read //--------------------------------------------------------- -//void MixerConfig::read(QDomNode node) void MixerConfig::read(MusECore::Xml& xml) -//void MixerConfig::read(MusECore::Xml& xml, const QString& name) { for (;;) { MusECore::Xml::Token token(xml.parse()); diff --git a/muse2/muse/confmport.cpp b/muse2/muse/confmport.cpp index 00914b36..d45dd370 100644 --- a/muse2/muse/confmport.cpp +++ b/muse2/muse/confmport.cpp @@ -183,22 +183,25 @@ void MPConfig::changeDefOutputRoutes(QAction* act) MusEGlobal::audio->msgUpdateSoloStates(); MusEGlobal::song->update(SC_ROUTE); #else - int ch = 0; - for( ; ch < MIDI_CHANNELS; ++ch) - if(defch & (1 << ch)) break; - - MusEGlobal::audio->msgIdle(true); - for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) - { - // Leave drum track channel at current setting. - if((*it)->type() == MusECore::Track::DRUM) - (*it)->setOutPortAndUpdate(no); - else - (*it)->setOutPortAndChannelAndUpdate(no, ch); - } - MusEGlobal::audio->msgIdle(false); - MusEGlobal::audio->msgUpdateSoloStates(); - MusEGlobal::song->update(SC_MIDI_TRACK_PROP); + for(int ch = 0; ch < MIDI_CHANNELS; ++ch) + if(defch & (1 << ch)) + { + MusEGlobal::audio->msgIdle(true); + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + { + // Leave drum track channel at current setting. + if((*it)->type() == MusECore::Track::DRUM) + (*it)->setOutPortAndUpdate(no); + else + (*it)->setOutPortAndChannelAndUpdate(no, ch); + } + MusEGlobal::audio->msgIdle(false); + MusEGlobal::audio->msgUpdateSoloStates(); + MusEGlobal::song->update(SC_MIDI_TRACK_PROP); + + // Stop at the first output channel found. + break; + } #endif } } @@ -902,8 +905,105 @@ void MPConfig::rbClicked(QTableWidgetItem* item) sdev = 0; } + int allch = (1 << MIDI_CHANNELS) - 1; + MusECore::MidiTrackList* mtl = MusEGlobal::song->midis(); + + // Remove track routes to/from an existing port already using the selected device... + if(sdev) + { + for(int i = 0; i < MIDI_PORTS; ++i) + { + if(MusEGlobal::midiPorts[i].device() == sdev) + { + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + MusEGlobal::audio->msgRemoveRoute(MusECore::Route(i, allch), MusECore::Route(*it, allch)); + + // Turn on if and when multiple output routes are supported. + #if 0 + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch)); + + //MusEGlobal::audio->msgUpdateSoloStates(); + //MusEGlobal::song->update(SC_ROUTE); + #endif + + break; + } + } + } + + // Remove all track routes to/from this port... + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + // Remove all routes from this port to the tracks. + MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch)); + // Turn on if and when multiple output routes are supported. + #if 0 + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch)); + + //MusEGlobal::audio->msgUpdateSoloStates(); + //MusEGlobal::song->update(SC_ROUTE); + #endif + MusEGlobal::midiSeq->msgSetMidiDevice(port, sdev); MusEGlobal::muse->changeConfig(true); // save configuration file + + // Add all track routes to/from this port... + if(sdev) + { + int chbits = MusEGlobal::midiPorts[no].defaultInChannels(); + // Do not add input routes to synths. + if(!sdev->isSynti()) + { + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + { + // Remove all routes from this port to the tracks first. + //MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch)); + // Now connect all the specified routes. + if(chbits) + MusEGlobal::audio->msgAddRoute(MusECore::Route(no, chbits), MusECore::Route(*it, chbits)); + } + } + chbits = MusEGlobal::midiPorts[no].defaultOutChannels(); + // Turn on if and when multiple output routes are supported. + #if 0 + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + { + // Remove all routes from this port to the tracks first. + //MusEGlobal::audio->msgRemoveRoute(MusECore::Route(no, allch), MusECore::Route(*it, allch)); + // Now connect all the specified routes. + if(chbits) + MusEGlobal::audio->msgAddRoute(MusECore::Route(no, chbits), MusECore::Route(*it, chbits)); + } + //MusEGlobal::audio->msgUpdateSoloStates(); + //MusEGlobal::song->update(SC_ROUTE); + #else + for(int ch = 0; ch < MIDI_CHANNELS; ++ch) + if(chbits & (1 << ch)) + { + MusEGlobal::audio->msgIdle(true); + for(MusECore::iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) + { + // Leave drum track channel at current setting. + if((*it)->type() == MusECore::Track::DRUM) + (*it)->setOutPortAndUpdate(no); + else + (*it)->setOutPortAndChannelAndUpdate(no, ch); + } + MusEGlobal::audio->msgIdle(false); + //MusEGlobal::audio->msgUpdateSoloStates(); + //MusEGlobal::song->update(SC_MIDI_TRACK_PROP); + + // Stop at the first output channel found. + break; + } + #endif + } + + //MusEGlobal::audio->msgUpdateSoloStates(); + ////MusEGlobal::song->update(SC_ROUTE); + + MusEGlobal::audio->msgUpdateSoloStates(); MusEGlobal::song->update(); } } @@ -1061,7 +1161,8 @@ MPConfig::MPConfig(QWidget* parent) //popup = 0; instrPopup = 0; defpup = 0; - _showAliases = -1; // 0: Show first aliases, if available. Nah, stick with -1: none at first. + //_showAliases = -1; // 0: Show first aliases, if available. Nah, stick with -1: none at first. + _showAliases = 0; // 0: Show first aliases, if available. QStringList columnnames; columnnames << tr("Port") @@ -1125,8 +1226,7 @@ void MPConfig::songChanged(int flags) // Is it simply a midi controller value adjustment? Forget it. //if(flags == SC_MIDI_CONTROLLER) // return; - // No need for anything but this, yet. - if(!(flags & SC_CONFIG)) + if(!(flags & (SC_CONFIG | SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED))) return; // Get currently selected index... @@ -1299,32 +1399,29 @@ void MPConfig::songChanged(int flags) synthList->clear(); for (std::vector::iterator i = MusEGlobal::synthis.begin(); i != MusEGlobal::synthis.end(); ++i) { - //s = (*i)->baseName(); - //s = (*i)->name(); - QTreeWidgetItem* item = new QTreeWidgetItem(synthList); - //item->setText(0, s); item->setText(0, QString((*i)->baseName())); + item->setText(1, MusECore::synthType2String((*i)->synthType())); s.setNum((*i)->instances()); - item->setText(1, s); - item->setTextAlignment(1, Qt::AlignHCenter); - //item->setText(2, QString((*i)->baseName())); - item->setText(2, QString((*i)->name())); + item->setText(2, s); + //item->setTextAlignment(2, Qt::AlignHCenter); + item->setText(3, QString((*i)->name())); - item->setText(3, QString((*i)->version())); - item->setText(4, QString((*i)->description())); + item->setText(4, QString((*i)->version())); + item->setText(5, QString((*i)->description())); } instanceList->clear(); MusECore::SynthIList* sl = MusEGlobal::song->syntis(); for (MusECore::iSynthI si = sl->begin(); si != sl->end(); ++si) { QTreeWidgetItem* iitem = new QTreeWidgetItem(instanceList); iitem->setText(0, (*si)->name()); + iitem->setText(1, MusECore::synthType2String((*si)->synth()->synthType())); if ((*si)->midiPort() == -1) s = tr(""); else s.setNum((*si)->midiPort() + 1); - iitem->setText(1, s); - iitem->setTextAlignment(1, Qt::AlignHCenter); + iitem->setText(2, s); + //iitem->setTextAlignment(2, Qt::AlignHCenter); } synthList->resizeColumnToContents(1); mdevView->resizeColumnsToContents(); @@ -1345,7 +1442,10 @@ void MPConfig::addInstanceClicked() QTreeWidgetItem* item = synthList->currentItem(); if (item == 0) return; - MusECore::SynthI *si = MusEGlobal::song->createSynthI(item->text(0), item->text(2)); // Add at end of list. + // Add at end of list. + MusECore::SynthI *si = MusEGlobal::song->createSynthI(item->text(0), + item->text(3), + MusECore::string2SynthType(item->text(1))); if(!si) return; @@ -1374,8 +1474,9 @@ void MPConfig::removeInstanceClicked() MusECore::SynthIList* sl = MusEGlobal::song->syntis(); MusECore::iSynthI ii; for (ii = sl->begin(); ii != sl->end(); ++ii) { - if ((*ii)->iname() == item->text(0)) - break; + if( (*ii)->iname() == item->text(0) && + MusECore::synthType2String((*ii)->synth()->synthType()) == item->text(1) ) + break; } if (ii == sl->end()) { printf("synthesizerConfig::removeInstanceClicked(): synthi not found\n"); diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index f55eea5d..60e19ba7 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -1928,7 +1928,7 @@ void CtrlCanvas::drawOverlay(QPainter& p) //p.setFont(MusEGlobal::config.fonts[3]); //p.setPen(Qt::black); //p.drawText(width()/2-100,height()/2-10, "Use shift + pencil or line tool to draw new events"); - p.drawText(2 , y * 2, "Use shift + pencil or line tool to draw new events"); + p.drawText(2 , y * 2, "Drawing hint: Hold Ctrl to affect only existing events"); } } diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp index 3b6f5a20..4687f17f 100644 --- a/muse2/muse/driver/alsamidi.cpp +++ b/muse2/muse/driver/alsamidi.cpp @@ -48,6 +48,7 @@ static int alsaSeqFdo = -1; snd_seq_t* alsaSeq = 0; static snd_seq_addr_t musePort; +static snd_seq_addr_t announce_adr; //--------------------------------------------------------- // MidiAlsaDevice @@ -85,42 +86,55 @@ QString MidiAlsaDevice::open() QString estr; int wer = 0; int rer = 0; + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca(&pinfo); + //snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); + snd_seq_port_info_set_addr(pinfo, &adr); + + int cap = snd_seq_port_info_get_capability(pinfo); // subscribe for writing if (_openFlags & 1) { - snd_seq_port_subscribe_set_sender(subs, &musePort); - snd_seq_port_subscribe_set_dest(subs, &adr); - // Not already subscribed (or error)? Then try subscribing. - if(snd_seq_get_port_subscription(alsaSeq, subs) < 0) - { - //int error = snd_seq_subscribe_port(alsaSeq, subs); - wer = snd_seq_subscribe_port(alsaSeq, subs); - //if (error < 0) - if(wer < 0) - //return QString("Play: ")+QString(snd_strerror(error)); - estr += (QString("Play: ") + QString(snd_strerror(wer)) + QString(" ")); - } - if(!wer) + if(cap & SND_SEQ_PORT_CAP_SUBS_WRITE) + { + snd_seq_port_subscribe_set_sender(subs, &musePort); + snd_seq_port_subscribe_set_dest(subs, &adr); + // Not already subscribed (or error)? Then try subscribing. + if(snd_seq_get_port_subscription(alsaSeq, subs) < 0) + { + //int error = snd_seq_subscribe_port(alsaSeq, subs); + wer = snd_seq_subscribe_port(alsaSeq, subs); + //if (error < 0) + if(wer < 0) + //return QString("Play: ")+QString(snd_strerror(error)); + estr += (QString("Play: ") + QString(snd_strerror(wer)) + QString(" ")); + } + } + if(!wer && (cap & SND_SEQ_PORT_CAP_WRITE)) _writeEnable = true; } // subscribe for reading if (_openFlags & 2) { - snd_seq_port_subscribe_set_dest(subs, &musePort); - snd_seq_port_subscribe_set_sender(subs, &adr); - // Not already subscribed (or error)? Then try subscribing. - if(snd_seq_get_port_subscription(alsaSeq, subs) < 0) - { - //int error = snd_seq_subscribe_port(alsaSeq, subs); - rer = snd_seq_subscribe_port(alsaSeq, subs); - //if (error < 0) - if(rer < 0) - //return QString("Rec: ") + QString(snd_strerror(error)); - estr += (QString("Rec: ") + QString(snd_strerror(rer))); - } - if(!rer) + if(cap & SND_SEQ_PORT_CAP_SUBS_READ) + { + snd_seq_port_subscribe_set_dest(subs, &musePort); + snd_seq_port_subscribe_set_sender(subs, &adr); + // Not already subscribed (or error)? Then try subscribing. + if(snd_seq_get_port_subscription(alsaSeq, subs) < 0) + { + //int error = snd_seq_subscribe_port(alsaSeq, subs); + rer = snd_seq_subscribe_port(alsaSeq, subs); + //if (error < 0) + if(rer < 0) + //return QString("Rec: ") + QString(snd_strerror(error)); + estr += (QString("Rec: ") + QString(snd_strerror(rer))); + } + } + if(!rer && (cap & SND_SEQ_PORT_CAP_READ)) _readEnable = true; } @@ -141,6 +155,16 @@ void MidiAlsaDevice::close() // Allocated on stack, no need to call snd_seq_port_subscribe_free() later. snd_seq_port_subscribe_alloca(&subs); + int wer = 0; + int rer = 0; + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca(&pinfo); + //snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); + snd_seq_port_info_set_addr(pinfo, &adr); + + int cap = snd_seq_port_info_get_capability(pinfo); + // This function appears to be called only by MidiPort::setMidiDevice(), // which closes then opens the device. // Because the open flags are set BEFORE setMidiDevice() is called, we must ignore the flags. @@ -160,37 +184,49 @@ void MidiAlsaDevice::close() //if (_openFlags & 1) { //if (!(_openFlags & 1)) { - snd_seq_port_subscribe_set_sender(subs, &musePort); - snd_seq_port_subscribe_set_dest(subs, &adr); - - // Already subscribed? Then unsubscribe. - if(!snd_seq_get_port_subscription(alsaSeq, subs)) - { - if(!snd_seq_unsubscribe_port(alsaSeq, subs)) - _writeEnable = false; - else - printf("MidiAlsaDevice::close Error unsubscribing alsa midi port for writing\n"); + if(cap & SND_SEQ_PORT_CAP_SUBS_WRITE) + { + snd_seq_port_subscribe_set_sender(subs, &musePort); + snd_seq_port_subscribe_set_dest(subs, &adr); + + // Already subscribed? Then unsubscribe. + if(!snd_seq_get_port_subscription(alsaSeq, subs)) + { + wer = snd_seq_unsubscribe_port(alsaSeq, subs); + //if(!wer) + // _writeEnable = false; + //else + if(wer < 0) + printf("MidiAlsaDevice::close Error unsubscribing alsa midi port %d:%d for writing: %s\n", adr.client, adr.port, snd_strerror(wer)); + } + //else + //_writeEnable = false; } - else - _writeEnable = false; + _writeEnable = false; } //if (_openFlags & 2) { //if (!(_openFlags & 2)) { - snd_seq_port_subscribe_set_dest(subs, &musePort); - snd_seq_port_subscribe_set_sender(subs, &adr); - - // Already subscribed? Then unsubscribe. - if(!snd_seq_get_port_subscription(alsaSeq, subs)) - { - if(!snd_seq_unsubscribe_port(alsaSeq, subs)) - _readEnable = false; - else - printf("MidiAlsaDevice::close Error unsubscribing alsa midi port for reading\n"); - } - else - _readEnable = false; + if(cap & SND_SEQ_PORT_CAP_SUBS_READ) + { + snd_seq_port_subscribe_set_dest(subs, &musePort); + snd_seq_port_subscribe_set_sender(subs, &adr); + + // Already subscribed? Then unsubscribe. + if(!snd_seq_get_port_subscription(alsaSeq, subs)) + { + rer = snd_seq_unsubscribe_port(alsaSeq, subs); + //if(!rer) + // _readEnable = false; + //else + if(rer < 0) + printf("MidiAlsaDevice::close Error unsubscribing alsa midi port %d:%d for reading: %s\n", adr.client, adr.port, snd_strerror(rer)); + } + //else + // _readEnable = false; + } + _readEnable = false; } } @@ -698,6 +734,13 @@ bool initMidiAlsa() snd_seq_client_info_set_client(cinfo, -1); while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) { + const char* cname = snd_seq_client_info_get_name(cinfo); + //printf( "ALSA client name: %s\n", cname); + + // Put Midi Through and user clients after others. Insert other unwanted clients here: // p4.0.41 + if(snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT || strcmp("Midi Through", cname) == 0) + continue; + snd_seq_port_info_t *pinfo; snd_seq_port_info_alloca(&pinfo); snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); @@ -705,6 +748,8 @@ bool initMidiAlsa() while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) { unsigned int capability = snd_seq_port_info_get_capability(pinfo); + if (capability & SND_SEQ_PORT_CAP_NO_EXPORT) // Ignore ports like "qjackctl" or "port". p4.0.41 + continue; if ((capability & outCap) == 0) { const char *name = snd_seq_port_info_get_name(pinfo); if (strcmp("Timer", name) == 0 || @@ -726,29 +771,52 @@ bool initMidiAlsa() adr.client, adr.port, flags, capability); MusEGlobal::midiDevices.add(dev); - - /* - // Experimental... Need to list 'sensible' devices first and ignore unwanted ones... - // Add instance last in midi device list. - for(int i = 0; i < MIDI_PORTS; ++i) - { - MidiPort* mp = &MusEGlobal::midiPorts[i]; - if(mp->device() == 0) - { - // midiSeq might not be initialzed yet! - //MusEGlobal::midiSeq->msgSetMidiDevice(mp, dev); - mp->setMidiDevice(dev); - - //muse->changeConfig(true); // save configuration file - //update(); - break; - } } - */ - + } + + snd_seq_client_info_set_client(cinfo, -1); // Reset + while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) { + const char* cname = snd_seq_client_info_get_name(cinfo); + //printf( "ALSA client name: %s\n", cname); + + // Put Midi Through and user clients after others. Insert other unwanted clients here: // p4.0.41 + if( !(snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT || strcmp("Midi Through", cname) == 0) ) + continue; + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca(&pinfo); + snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); + snd_seq_port_info_set_port(pinfo, -1); + + while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) { + unsigned int capability = snd_seq_port_info_get_capability(pinfo); + if (capability & SND_SEQ_PORT_CAP_NO_EXPORT) // Ignore ports like "qjackctl" or "port". p4.0.41 + continue; + if ((capability & outCap) == 0) { + const char *name = snd_seq_port_info_get_name(pinfo); + if (strcmp("Timer", name) == 0 || + strcmp("Announce", name) == 0 || + strcmp("Receiver", name) == 0) + continue; + } + snd_seq_addr_t adr = *snd_seq_port_info_get_addr(pinfo); + MidiAlsaDevice* dev = new MidiAlsaDevice(adr, QString(snd_seq_port_info_get_name(pinfo))); + int flags = 0; + if (capability & outCap) + flags |= 1; + if (capability & inCap) + flags |= 2; + dev->setrwFlags(flags); + if (MusEGlobal::debugMsg) + printf("ALSA port add: <%s>, %d:%d flags %d 0x%0x\n", + snd_seq_port_info_get_name(pinfo), + adr.client, adr.port, + flags, capability); + MusEGlobal::midiDevices.add(dev); } } - + + //snd_seq_set_client_name(alsaSeq, "MusE Sequencer"); snd_seq_set_client_name(alsaSeq, MusEGlobal::audioDevice->clientName()); @@ -783,14 +851,14 @@ bool initMidiAlsa() // alsa port changes //----------------------------------------- - snd_seq_addr_t aadr; - aadr.client = SND_SEQ_CLIENT_SYSTEM; - aadr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE; + //snd_seq_addr_t aadr; + announce_adr.client = SND_SEQ_CLIENT_SYSTEM; + announce_adr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE; snd_seq_port_subscribe_t* subs; snd_seq_port_subscribe_alloca(&subs); snd_seq_port_subscribe_set_dest(subs, &musePort); - snd_seq_port_subscribe_set_sender(subs, &aadr); + snd_seq_port_subscribe_set_sender(subs, &announce_adr); error = snd_seq_subscribe_port(alsaSeq, subs); if (error < 0) { printf("Alsa: Subscribe System failed: %s", snd_strerror(error)); @@ -807,12 +875,35 @@ bool initMidiAlsa() void exitMidiAlsa() { if(alsaSeq) - { - int error = snd_seq_close(alsaSeq); // FIXME Hm, this did not get rid of a buch of valgrind leaks. - if(error < 0) + { + int error = 0; + snd_seq_port_subscribe_t* subs; + // Allocated on stack, no need to call snd_seq_port_subscribe_free() later. + snd_seq_port_subscribe_alloca(&subs); + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca(&pinfo); + //snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); + snd_seq_port_info_set_addr(pinfo, &announce_adr); + + snd_seq_port_subscribe_set_dest(subs, &musePort); + snd_seq_port_subscribe_set_sender(subs, &announce_adr); + + // Already subscribed? Then unsubscribe. + if(!snd_seq_get_port_subscription(alsaSeq, subs)) { - fprintf(stderr, "Could not close ALSA sequencer: %s\n", snd_strerror(error)); - } + error = snd_seq_unsubscribe_port(alsaSeq, subs); + if(error < 0) + printf("MusE: exitMidiAlsa: Error unsubscribing alsa midi Announce port %d:%d for reading: %s\n", announce_adr.client, announce_adr.port, snd_strerror(error)); + } + + error = snd_seq_delete_simple_port(alsaSeq, musePort.port); + if(error < 0) + fprintf(stderr, "MusE: Could not delete ALSA simple port: %s\n", snd_strerror(error)); + + error = snd_seq_close(alsaSeq); + if(error < 0) + fprintf(stderr, "MusE: Could not close ALSA sequencer: %s\n", snd_strerror(error)); } } @@ -852,7 +943,9 @@ void alsaScanMidiPorts() snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); snd_seq_port_info_set_port(pinfo, -1); while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) { - unsigned int capability = snd_seq_port_info_get_capability(pinfo); + unsigned int capability = snd_seq_port_info_get_capability(pinfo); + if (capability & SND_SEQ_PORT_CAP_NO_EXPORT) // Ignore ports like "qjackctl" or "port". p4.0.41 + continue; if (((capability & outCap) == 0) && ((capability & inCap) == 0)) continue; @@ -902,6 +995,8 @@ void alsaScanMidiPorts() // // check for devices to add // + // TODO: Possibly auto-add them to available midi ports. p4.0.41 + // for (std::list::iterator k = portList.begin(); k != portList.end(); ++k) { iMidiDevice i = MusEGlobal::midiDevices.begin(); // printf("ALSA port: <%s>\n", k->name); @@ -922,6 +1017,8 @@ void alsaScanMidiPorts() // printf("add device\n"); } } + + } //--------------------------------------------------------- diff --git a/muse2/muse/driver/jack.cpp b/muse2/muse/driver/jack.cpp index 733353d8..421152a7 100644 --- a/muse2/muse/driver/jack.cpp +++ b/muse2/muse/driver/jack.cpp @@ -735,7 +735,11 @@ void JackAudioDevice::connectJackMidiPorts() { RouteList* rl = md->outRoutes(); for (ciRoute r = rl->begin(); r != rl->end(); ++r) + { + if(r->type != Route::JACK_ROUTE) + continue; connect(port, r->jackPort); + } } } @@ -748,7 +752,11 @@ void JackAudioDevice::connectJackMidiPorts() { RouteList* rl = md->inRoutes(); for (ciRoute r = rl->begin(); r != rl->end(); ++r) + { + if(r->type != Route::JACK_ROUTE) + continue; connect(r->jackPort, port); + } } } } @@ -939,6 +947,8 @@ void JackAudioDevice::graphChanged() for (int i = 0;i < 20;i++) { erased = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; if (irl->channel != channel) continue; QString name = irl->name(); @@ -977,6 +987,8 @@ void JackAudioDevice::graphChanged() while (*pn) { bool found = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; if (irl->channel != channel) continue; QString name = irl->name(); @@ -1027,6 +1039,8 @@ void JackAudioDevice::graphChanged() for (int i = 0; i < 20 ; i++) { erased = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; if (irl->channel != channel) continue; QString name = irl->name(); @@ -1064,6 +1078,8 @@ void JackAudioDevice::graphChanged() while (*pn) { bool found = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; if (irl->channel != channel) continue; QString name = irl->name(); @@ -1139,6 +1155,8 @@ void JackAudioDevice::graphChanged() { erased = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; //if (irl->channel != channel) // continue; QString name = irl->name(); @@ -1181,6 +1199,8 @@ void JackAudioDevice::graphChanged() while (*pn) { bool found = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; //if (irl->channel != channel) // continue; QString name = irl->name(); @@ -1239,6 +1259,8 @@ void JackAudioDevice::graphChanged() { erased = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; //if (irl->channel != channel) // continue; QString name = irl->name(); @@ -1280,6 +1302,8 @@ void JackAudioDevice::graphChanged() while (*pn) { bool found = false; for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) { + if(irl->type != Route::JACK_ROUTE) + continue; //if (irl->channel != channel) // continue; QString name = irl->name(); @@ -1482,6 +1506,8 @@ void JackAudioDevice::start(int /*priority*/) RouteList* rl = ai->inRoutes(); void* port = ai->jackPort(ch); for (ciRoute ir = rl->begin(); ir != rl->end(); ++ir) { + if(ir->type != Route::JACK_ROUTE) + continue; if (ir->channel == ch) connect(ir->jackPort, port); } @@ -1495,6 +1521,8 @@ void JackAudioDevice::start(int /*priority*/) RouteList* rl = ai->outRoutes(); void* port = ai->jackPort(ch); for (ciRoute r = rl->begin(); r != rl->end(); ++r) { + if(r->type != Route::JACK_ROUTE) + continue; if (r->channel == ch) { connect(port, r->jackPort); } @@ -1602,6 +1630,107 @@ int JackAudioDevice::frameDelay() const } #endif +//--------------------------------------------------------- +// getJackPorts +//--------------------------------------------------------- + +void JackAudioDevice::getJackPorts(const char** ports, std::list& name_list, bool midi, bool physical, int aliases) + { + if (JACK_DEBUG) + printf("JackAudioDevice::getJackPorts()\n"); + //std::list clientList; + //if(!checkJackClient(_client)) return clientList; + //if(!checkJackClient(_client)) return; + QString qname; + //const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; + //const char** ports = jack_get_ports(_client, 0, type, JackPortIsInput); + //const char** ports = jack_get_ports(_client, 0, type, jflags); + + QString cname(jack_get_client_name(_client)); + + for (const char** p = ports; p && *p; ++p) { + jack_port_t* port = jack_port_by_name(_client, *p); + //int flags = jack_port_flags(port); + //if (!(flags & JackPortIsInput)) + // continue; + //char buffer[128]; + + int port_flags = jack_port_flags(port); + //printf("JackAudioDevice::getJackPorts port: %s flags: %d\n", *p, port_flags); + + // Ignore our own client ports. + if(jack_port_is_mine(_client, port)) + { + if(MusEGlobal::debugMsg) + printf("JackAudioDevice::getJackPorts ignoring own port: %s\n", *p); + continue; + } + + int nsz = jack_port_name_size(); + char buffer[nsz]; + + bool mthrough = false; + + if(midi) + { + strncpy(buffer, *p, nsz); + char a2[nsz]; + char* al[2]; + al[0] = buffer; + al[1] = a2; + int na = jack_port_get_aliases(port, al); + if(na >= 1) + { + qname = QString(al[0]); + //printf("Checking port name for: %s\n", (QString("alsa_pcm:") + cname + QString("/")).toLatin1().constData()); + // Ignore our own ALSA client! + if(qname.startsWith(QString("alsa_pcm:") + cname + QString("/"))) + continue; + // Put Midi Through after all others. + mthrough = qname.startsWith(QString("alsa_pcm:Midi-Through/")); + //if((physical && mthrough) || (!physical && !mthrough)) + //if(physical && mthrough) + // continue; + } + } + // Put physical/terminal ports before others. + bool is_phys = (port_flags & (JackPortIsTerminal | JackPortIsPhysical)) && !mthrough; + if((physical && !is_phys) || (!physical && is_phys)) + continue; + + + strncpy(buffer, *p, nsz); + if((aliases == 0) || (aliases == 1)) + { + char a2[nsz]; + char* al[2]; + al[0] = buffer; + al[1] = a2; + int na = jack_port_get_aliases(port, al); + int a = aliases; + if(a >= na) + { + a = na; + if(a > 0) + a--; + } + qname = QString(al[a]); + } + else + qname = QString(buffer); + + //clientList.push_back(QString(buffer)); + name_list.push_back(qname); + } + + // p3.3.37 + //if(ports) + //free(ports); + // jack_free(ports); // p4.0.29 + + //return clientList; + } + //--------------------------------------------------------- // outputPorts //--------------------------------------------------------- @@ -1612,9 +1741,11 @@ std::list JackAudioDevice::outputPorts(bool midi, int aliases) printf("JackAudioDevice::outputPorts()\n"); std::list clientList; if(!checkJackClient(_client)) return clientList; - QString qname; const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; const char** ports = jack_get_ports(_client, 0, type, JackPortIsOutput); + + /* + QString qname; for (const char** p = ports; p && *p; ++p) { jack_port_t* port = jack_port_by_name(_client, *p); //int flags = jack_port_flags(port); @@ -1666,12 +1797,15 @@ std::list JackAudioDevice::outputPorts(bool midi, int aliases) //clientList.push_back(QString(buffer)); clientList.push_back(qname); } - - // p3.3.37 - if(ports) - //free(ports); - jack_free(ports); // p4.0.29 + */ + if(ports) + { + getJackPorts(ports, clientList, midi, true, aliases); // Get physical ports first. + getJackPorts(ports, clientList, midi, false, aliases); // Get non-physical ports last. + jack_free(ports); + } + return clientList; } @@ -1683,11 +1817,14 @@ std::list JackAudioDevice::inputPorts(bool midi, int aliases) { if (JACK_DEBUG) printf("JackAudioDevice::inputPorts()\n"); + std::list clientList; if(!checkJackClient(_client)) return clientList; - QString qname; const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; const char** ports = jack_get_ports(_client, 0, type, JackPortIsInput); + + /* + QString qname; for (const char** p = ports; p && *p; ++p) { jack_port_t* port = jack_port_by_name(_client, *p); //int flags = jack_port_flags(port); @@ -1739,12 +1876,15 @@ std::list JackAudioDevice::inputPorts(bool midi, int aliases) //clientList.push_back(QString(buffer)); clientList.push_back(qname); } - - // p3.3.37 - if(ports) - //free(ports); - jack_free(ports); // p4.0.29 + */ + if(ports) + { + getJackPorts(ports, clientList, midi, true, aliases); // Get physical ports first. + getJackPorts(ports, clientList, midi, false, aliases); // Get non-physical ports last. + jack_free(ports); + } + return clientList; } diff --git a/muse2/muse/driver/jackaudio.h b/muse2/muse/driver/jackaudio.h index bd78d481..c4d37db9 100644 --- a/muse2/muse/driver/jackaudio.h +++ b/muse2/muse/driver/jackaudio.h @@ -50,6 +50,7 @@ class JackAudioDevice : public AudioDevice { // Free-running frame counter incremented always in process. jack_nframes_t _frameCounter; + void getJackPorts(const char** ports, std::list& name_list, bool midi, bool physical, int aliases); static int processAudio(jack_nframes_t frames, void*); public: diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index 92120dbb..2e4e6d35 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -99,6 +99,7 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument // That way we cover all bases - effect plugins and synths. // Non-synths will show up in the ladspa effect dialog, while synths will show up here... // There should be nothing left out... + // TIP: Until we add programs to plugins, comment these four checks to load dssi effects as synths, in order to have programs. if(descr->run_synth || descr->run_synth_adding || descr->run_multiple_synths || @@ -498,6 +499,9 @@ bool DssiSynthIF::init(DssiSynth* s) int inports = synth->_inports; if(inports != 0) { + posix_memalign((void**)&audioInSilenceBuf, 16, sizeof(float) * MusEGlobal::segmentSize); + memset(audioInSilenceBuf, 0, sizeof(float) * MusEGlobal::segmentSize); + audioInBuffers = new float*[inports]; for(int k = 0; k < inports; ++k) { @@ -723,6 +727,7 @@ DssiSynthIF::DssiSynthIF(SynthI* s) controls = 0; controlsOut = 0; audioInBuffers = 0; + audioInSilenceBuf = 0; audioOutBuffers = 0; } @@ -785,6 +790,9 @@ DssiSynthIF::~DssiSynthIF() delete[] audioInBuffers; } + if(audioInSilenceBuf) + free(audioInSilenceBuf); + if(audioOutBuffers) { for(unsigned long i = 0; i < synth->_outports; ++i) @@ -1420,7 +1428,7 @@ bool DssiSynthIF::processEvent(const MusECore::MidiPlayEvent& e, snd_seq_event_t // getData //--------------------------------------------------------- -MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MPEventList* el, MusECore::iMPEvent i, unsigned pos, int ports, unsigned n, float** buffer) +MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MPEventList* el, MusECore::iMPEvent start_event, unsigned pos, int ports, unsigned nframes, float** buffer) { //#ifdef DSSI_DEBUG // fprintf(stderr, "DssiSynthIF::getData elsize:%d pos:%d ports:%d samples:%d processed already?:%d\n", el->size(), pos, ports, n, synti->processed()); @@ -1440,19 +1448,11 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP // All ports must be connected to something! unsigned long nop, k; - // First, copy the given input buffers to our local input buffers. - //np = portsin > synth->_inports ? synth->_inports : portsin; - //for(k = 0; k < np; ++k) - // memcpy(audioInBuffers[k], inbuffer[k], sizeof(float) * n); - //for(; k < portsin; ++k) - // memset(audioInBuffers[k], 0, sizeof(float) * n); // Watch our limits. //willyfoobar-2011-02-13 //old code//np = ports > synth->_outports ? synth->_outports : ports; nop = ((unsigned long) ports) > synth->_outports ? synth->_outports : ((unsigned long) ports); - // TODO Number of inports requested? - //nip = ((unsigned long) iports) > synth->_inports ? synth->_inports : ((unsigned long) iports); const DSSI_Descriptor* dssi = synth->dssi; const LADSPA_Descriptor* descr = dssi->LADSPA_Plugin; @@ -1484,18 +1484,109 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP // Note for dssi-vst this MUST equal MusEGlobal::audio period. It doesn't like broken-up runs (it stutters), // even with fixed sizes. Could be a Wine + Jack thing, wanting a full Jack buffer's length. //unsigned long fixedsize = 2048; - unsigned long fixedsize = n; + unsigned long fixedsize = nframes; // For now, the fixed size is clamped to the MusEGlobal::audio buffer size. // TODO: We could later add slower processing over several cycles - // so that users can select a small MusEGlobal::audio period but a larger control period. - if(fixedsize > n) - fixedsize = n; + if(fixedsize > nframes) + fixedsize = nframes; unsigned long min_per = MusEGlobal::config.minControlProcessPeriod; - if(min_per > n) - min_per = n; + if(min_per > nframes) + min_per = nframes; + + // + // p4.0.38 Handle inputs... + // + if(!((MusECore::AudioTrack*)synti)->noInRoute()) + { + RouteList* irl = ((MusECore::AudioTrack*)synti)->inRoutes(); + iRoute i = irl->begin(); + if(i->track->isMidiTrack()) + { + //if(MusEGlobal::debugMsg) + //printf("DssiSynthIF::getData: Error: First route is a midi track route!\n"); + } + else + { + int ch = i->channel == -1 ? 0 : i->channel; + int remch = i->remoteChannel == -1 ? 0 : i->remoteChannel; + int chs = i->channels == -1 ? 0 : i->channels; + + if((unsigned)ch < synth->_inports && (unsigned)(ch + chs) <= synth->_inports) + { + //printf("DssiSynthIF::getData calling copyData on %s ch:%d remch:%d chs:%d\n", i->track->name().toLatin1().constData(), ch, remch, chs); + + int h = remch + chs; + for(int j = remch; j < h; ++j) + { + //printf(" setting used idx:%d\n", j); + synth->iUsedIdx[j] = true; + } + + ((MusECore::AudioTrack*)i->track)->copyData(pos, chs, ch, -1, nframes, &audioInBuffers[remch]); + } + } + + ++i; + for(; i != irl->end(); ++i) + { + if(i->track->isMidiTrack()) + { + //if(MusEGlobal::debugMsg) + // printf("DssiSynthIF::getData: Error: Route is a midi track route!\n"); + continue; + } + + int ch = i->channel == -1 ? 0 : i->channel; + int remch = i->remoteChannel == -1 ? 0 : i->remoteChannel; + int chs = i->channels == -1 ? 0 : i->channels; + if((unsigned)ch < synth->_inports && (unsigned)(ch + chs) <= synth->_inports) + { + //printf("DssiSynthIF::getData calling addData on %s ch:%d remch:%d chs:%d\n", i->track->name().toLatin1().constData(), ch, remch, chs); + + bool u1 = synth->iUsedIdx[remch]; + if(chs >= 2) + { + bool u2 = synth->iUsedIdx[remch + 1]; + if(u1 && u2) + ((MusECore::AudioTrack*)i->track)->addData(pos, chs, ch, -1, nframes, &audioInBuffers[remch]); + else + if(!u1 && !u2) + ((MusECore::AudioTrack*)i->track)->copyData(pos, chs, ch, -1, nframes, &audioInBuffers[remch]); + else + { + if(u1) + ((MusECore::AudioTrack*)i->track)->addData(pos, 1, ch, 1, nframes, &audioInBuffers[remch]); + else + ((MusECore::AudioTrack*)i->track)->copyData(pos, 1, ch, 1, nframes, &audioInBuffers[remch]); + + if(u2) + ((MusECore::AudioTrack*)i->track)->addData(pos, 1, ch + 1, 1, nframes, &audioInBuffers[remch + 1]); + else + ((MusECore::AudioTrack*)i->track)->copyData(pos, 1, ch + 1, 1, nframes, &audioInBuffers[remch + 1]); + } + } + else + { + if(u1) + ((MusECore::AudioTrack*)i->track)->addData(pos, 1, ch, -1, nframes, &audioInBuffers[remch]); + else + ((MusECore::AudioTrack*)i->track)->copyData(pos, 1, ch, -1, nframes, &audioInBuffers[remch]); + } + + int h = remch + chs; + for(int j = remch; j < h; ++j) + { + //printf(" setting used idx:%d\n", j); + synth->iUsedIdx[j] = true; + } + } + } + } + // Process automation control values now. // TODO: This needs to be respect frame resolution. Put this inside the sample loop below. if(MusEGlobal::automation && synti && synti->automationType() != AUTO_OFF && id() != -1) @@ -1507,11 +1598,11 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP } } - while(sample < n) + while(sample < nframes) { //unsigned long nsamp = n; //unsigned long nsamp = n - sample; - unsigned long nsamp = usefixedrate ? fixedsize : n - sample; + unsigned long nsamp = usefixedrate ? fixedsize : nframes - sample; bool found = false; unsigned long frame = 0; unsigned long index = 0; @@ -1525,7 +1616,7 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP // The events happened in the last period or even before that. Shift into this period with + n. This will sync with MusEGlobal::audio. // If the events happened even before current frame - n, make sure they are counted immediately as zero-frame. //evframe = (pos + frameOffset > v.frame + n) ? 0 : v.frame - pos - frameOffset + n; - evframe = (syncFrame > v.frame + n) ? 0 : v.frame - syncFrame + n; + evframe = (syncFrame > v.frame + nframes) ? 0 : v.frame - syncFrame + nframes; // Protection. Observed this condition. Why? Supposed to be linear timestamps. if(found && evframe < frame) { @@ -1545,7 +1636,7 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP //if(v.frame < startPos || v.frame >= (endPos + frameOffset) //if(evframe < sample || evframe >= n //if(evframe < sample || evframe >= (n + frameOffset) - if(evframe >= n + if(evframe >= nframes //|| (found && v.frame != frame) //|| (!usefixedrate && found && !v.unique && v.frame != frame) //|| (found && !v.unique && evframe != frame) @@ -1567,6 +1658,31 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP index = v.idx; // Set the ladspa control port value. controls[v.idx].val = v.value; + + // Need to update the automation value, otherwise it overwrites later with the last MusEGlobal::automation value. + if(id() != -1) + { + // Since we are now in the audio thread context, there's no need to send a message, + // just modify directly. + //MusEGlobal::audio->msgSetPluginCtrlVal(_track, genACnum(_id, k), controls[k].val); + synti->setPluginCtrlVal(genACnum(id(), v.idx), v.value); + + // Record automation. + // NO! Take care of this immediately in the OSC control handler, because we don't want + // any delay. + // OTOH Since this is the actual place and time where the control ports values + // are set, best to reflect what happens here to automation. + // However for dssi-vst it might be best to handle it that way. + + //AutomationType at = _track->automationType(); + // TODO: Taken from our native gui control handlers. + // This may need modification or may cause problems - + // we don't have the luxury of access to the dssi gui controls ! + //if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH)) + // enableController(k, false); + //_track->recordAutomation(id, v.value); + } + } // Process automation control values now. @@ -1583,8 +1699,8 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP if(found && !usefixedrate) //nsamp = frame - sample + 1; nsamp = frame - sample; - if(sample + nsamp >= n) // Safety check. - nsamp = n - sample; + if(sample + nsamp >= nframes) // Safety check. + nsamp = nframes - sample; //printf("DssiSynthIF::getData n:%d frame:%lu sample:%lu nsamp:%lu pos:%d fOffset:%d syncFrame:%lu loopcount:%d\n", // n, frame, sample, nsamp, pos, frameOffset, syncFrame, loopcount); // REMOVE Tim. @@ -1596,10 +1712,10 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP nevents = 0; // Process event list events... - for(; i != el->end(); ++i) + for(; start_event != el->end(); ++start_event) { //if(i->time() >= (endPos + frameOffset)) // NOTE: frameOffset? Tested, examined printouts of times: Seems OK for playback. - if(i->time() >= (pos + sample + nsamp + frameOffset)) // frameOffset? Test again... + if(start_event->time() >= (pos + sample + nsamp + frameOffset)) // frameOffset? Test again... break; #ifdef DSSI_DEBUG @@ -1611,40 +1727,40 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP if(synti->midiPort() != -1) { MusECore::MidiPort* mp = &MusEGlobal::midiPorts[synti->midiPort()]; - if(i->type() == MusECore::ME_CONTROLLER) + if(start_event->type() == MusECore::ME_CONTROLLER) { - int da = i->dataA(); - int db = i->dataB(); + int da = start_event->dataA(); + int db = start_event->dataB(); db = mp->limitValToInstrCtlRange(da, db); - if(!mp->setHwCtrlState(i->channel(), da, db)) + if(!mp->setHwCtrlState(start_event->channel(), da, db)) continue; } else - if(i->type() == MusECore::ME_PITCHBEND) + if(start_event->type() == MusECore::ME_PITCHBEND) { - int da = mp->limitValToInstrCtlRange(MusECore::CTRL_PITCH, i->dataA()); - if(!mp->setHwCtrlState(i->channel(), MusECore::CTRL_PITCH, da)) + int da = mp->limitValToInstrCtlRange(MusECore::CTRL_PITCH, start_event->dataA()); + if(!mp->setHwCtrlState(start_event->channel(), MusECore::CTRL_PITCH, da)) continue; } else - if(i->type() == MusECore::ME_PROGRAM) + if(start_event->type() == MusECore::ME_PROGRAM) { - if(!mp->setHwCtrlState(i->channel(), MusECore::CTRL_PROGRAM, i->dataA())) + if(!mp->setHwCtrlState(start_event->channel(), MusECore::CTRL_PROGRAM, start_event->dataA())) continue; } } // Returns false if the event was not filled. It was handled, but some other way. - if(processEvent(*i, &events[nevents])) + if(processEvent(*start_event, &events[nevents])) { // Time-stamp the event. p4.0.15 Tim. - int ft = i->time() - frameOffset - pos; + int ft = start_event->time() - frameOffset - pos; if(ft < 0) ft = 0; //if (ft >= (int)MusEGlobal::segmentSize) if (ft >= int(sample + nsamp)) { - printf("DssiSynthIF::getData: eventlist event time:%d out of range. pos:%d offset:%d ft:%d sample:%lu nsamp:%lu\n", i->time(), pos, frameOffset, ft, sample, nsamp); + printf("DssiSynthIF::getData: eventlist event time:%d out of range. pos:%d offset:%d ft:%d sample:%lu nsamp:%lu\n", start_event->time(), pos, frameOffset, ft, sample, nsamp); ///if (ft > (int)MusEGlobal::segmentSize) //ft = MusEGlobal::segmentSize - 1; ft = sample + nsamp - 1; @@ -1696,61 +1812,6 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP } } - /* - // - // p3.3.39 Handle inputs... - // - //if((MusEGlobal::song->bounceTrack != this) && !noInRoute()) - if(!((MusECore::AudioTrack*)synti)->noInRoute()) - { - RouteList* irl = ((MusECore::AudioTrack*)synti)->inRoutes(); - iRoute i = irl->begin(); - if(!i->track->isMidiTrack()) - { - //if(MusEGlobal::debugMsg) - printf("DssiSynthIF::getData: Error: First route is a midi track route!\n"); - } - else - { - int ch = i->channel == -1 ? 0 : i->channel; - int remch = i->remoteChannel == -1 ? 0 : i->remoteChannel; - int chs = i->channels == -1 ? 0 : i->channels; - - // TODO: - //if(ch >= synth->_inports) - //iUsedIdx[ch] = true; - //if(chs == 2) - // iUsedIdx[ch + 1] = true; - - //((MusECore::AudioTrack*)i->track)->copyData(framePos, channels, nframe, bp); - ((MusECore::AudioTrack*)i->track)->copyData(pos, ports, - //(i->track->type() == Track::AUDIO_SOFTSYNTH && i->channel != -1) ? i->channel : 0, - i->channel, - i->channels, - n, bp); - } - - //unsigned pos, int ports, unsigned n, float** buffer - - ++i; - for(; i != irl->end(); ++i) - { - if(i->track->isMidiTrack()) - { - //if(MusEGlobal::debugMsg) - printf("DssiSynthIF::getData: Error: Route is a midi track route!\n"); - continue; - } - //((MusECore::AudioTrack*)i->track)->addData(framePos, channels, nframe, bp); - ((MusECore::AudioTrack*)i->track)->addData(framePos, channels, - //(i->track->type() == Track::AUDIO_SOFTSYNTH && i->channel != -1) ? i->channel : 0, - i->channel, - i->channels, - nframe, bp); - } - } - */ - k = 0; // Connect the given buffers directly to the ports, up to a max of synth ports. for(; k < nop; ++k) @@ -1758,9 +1819,21 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP // Connect the remaining ports to some local buffers (not used yet). for(; k < synth->_outports; ++k) descr->connect_port(handle, synth->oIdx[k], audioOutBuffers[k] + sample); - // Just connect all inputs to some local buffers (not used yet). TODO: Support inputs. + // Connect all inputs either to some local buffers, or a silence buffer. for(k = 0; k < synth->_inports; ++k) - descr->connect_port(handle, synth->iIdx[k], audioInBuffers[k] + sample); + { + //printf(" k:%d synth->iIdx[k]:%d\n", k, synth->iIdx[k]); + if(synth->iUsedIdx[k]) + { + synth->iUsedIdx[k] = false; // Reset + descr->connect_port(handle, synth->iIdx[k], audioInBuffers[k] + sample); + } + else + { + //printf(" input used size:%ld idx:%ld = %d silencing...\n", synth->iUsedIdx.size(), k, synth->iUsedIdx[k]); + descr->connect_port(handle, synth->iIdx[k], audioInSilenceBuf + sample); + } + } // Run the synth for a period of time. This processes events and gets/fills our local buffers... if(synth->dssi->run_synth) @@ -1772,10 +1845,10 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP snd_seq_event_t* ev = events; synth->dssi->run_multiple_synths(1, &handle, nsamp, &ev, &nevents); } + // TIP: Until we add programs to plugins, uncomment these four checks to load dssi effects as synths, in order to have programs. //else //if(synth->dssi->LADSPA_Plugin->run) //{ - // // Just a test, worked OK. // synth->dssi->LADSPA_Plugin->run(handle, nsamp); //} @@ -1783,14 +1856,13 @@ MusECore::iMPEvent DssiSynthIF::getData(MusECore::MidiPort* /*mp*/, MusECore::MP loopcount++; // REMOVE Tim. } - return i; + return start_event; } //--------------------------------------------------------- // putEvent //--------------------------------------------------------- -//bool DssiSynthIF::putEvent(const MidiEvent& ev) bool DssiSynthIF::putEvent(const MusECore::MidiPlayEvent& ev) { #ifdef DSSI_DEBUG @@ -2033,16 +2105,37 @@ int DssiSynthIF::oscControl(unsigned long port, float value) fprintf(stderr, "DssiSynthIF::oscControl: fifo overflow: in control number:%lu\n", cport); } - MusECore::ciMidiCtl2LadspaPort ip = synth->port2MidiCtlMap.find(cport); - if(ip != synth->port2MidiCtlMap.end()) + // Record automation: + // Take care of this immediately, because we don't want the silly delay associated with + // processing the fifo one-at-a-time in the apply(). + // NOTE: With some vsts we don't receive control events until the user RELEASES a control. + // So the events all arrive at once when the user releases a control. + // That makes this pretty useless... But what the heck... + if(id() != -1) { + //int id = genACnum(_id, cport); + unsigned long pid = genACnum(id(), cport); + AutomationType at = synti->automationType(); + + // TODO: Taken from our native gui control handlers. + // This may need modification or may cause problems - + // we don't have the luxury of access to the dssi gui controls ! + if(at == AUTO_WRITE || (MusEGlobal::audio->isPlaying() && at == AUTO_TOUCH)) + enableController(cport, false); + + synti->recordAutomation(pid, value); + } + + //MusECore::ciMidiCtl2LadspaPort ip = synth->port2MidiCtlMap.find(cport); + //if(ip != synth->port2MidiCtlMap.end()) + //{ // TODO: TODO: Update midi MusE's midi controller knobs, sliders, boxes etc with a call to the midi port's setHwCtrlState() etc. // But first we need a ladspa2MidiValue() function! ... // // //float val = ladspa2MidiValue(ld, i, ?, ?); - } + //} return 0; } @@ -2064,8 +2157,8 @@ int DssiSynthIF::oscMidi(int a, int b, int c) { MusECore::MidiPlayEvent event(0, port, channel, a, b, c); - #ifdef DSSI_DEBUG - printf(stderr, "DssiSynthIF::oscMidi midi event chn:%d a:%d b:%d\n", event.channel(), event.dataA(), event.dataB()); + #ifdef DSSI_DEBUG + printf("DssiSynthIF::oscMidi midi event chn:%d a:%d b:%d\n", event.channel(), event.dataA(), event.dataB()); #endif MusEGlobal::midiPorts[port].sendEvent(event); @@ -2329,7 +2422,8 @@ QString DssiSynthIF::name() const { return synti->nam QString DssiSynthIF::lib() const { return synth ? synth->completeBaseName() : QString(); } QString DssiSynthIF::dirPath() const { return synth ? synth->absolutePath() : QString(); } QString DssiSynthIF::fileName() const { return synth ? synth->fileName() : QString(); } -MusECore::AudioTrack* DssiSynthIF::track() { return (MusECore::AudioTrack*)synti; } +QString DssiSynthIF::titlePrefix() const { return QString(); } +MusECore::AudioTrack* DssiSynthIF::track() { return (MusECore::AudioTrack*)synti; } void DssiSynthIF::enableController(unsigned long i, bool v) { controls[i].enCtrl = v; } bool DssiSynthIF::controllerEnabled(unsigned long i) const { return controls[i].enCtrl; } bool DssiSynthIF::controllerEnabled2(unsigned long i) const { return controls[i].en2Ctrl; } diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h index 9b00b642..2836d72e 100644 --- a/muse2/muse/dssihost.h +++ b/muse2/muse/dssihost.h @@ -76,7 +76,8 @@ class DssiSynth : public Synth { unsigned long _portCount, _inports, _outports, _controlInPorts, _controlOutPorts; std::vector iIdx; // Audio input index to port number. std::vector oIdx; // Audio output index to port number. - std::vector iUsedIdx; // During process, tells whether an audio input port was used by any input routes. + //std::vector iUsedIdx; // During process, tells whether an audio input port was used by any input routes. + std::vector iUsedIdx; // During process, tells whether an audio input port was used by any input routes. std::vector rpIdx; // Port number to control input index. Item is -1 if it's not a control input. MusECore::MidiCtl2LadspaPortMap midiCtl2PortMap; // Maps midi controller numbers to DSSI port numbers. MusECore::MidiCtl2LadspaPortMap port2MidiCtlMap; // Maps DSSI port numbers to midi controller numbers. @@ -88,6 +89,8 @@ class DssiSynth : public Synth { public: DssiSynth(QFileInfo&, const DSSI_Descriptor*); // removed const for QFileInfo virtual ~DssiSynth(); + virtual Type synthType() const { return DSSI_SYNTH; } + virtual void incInstances(int); virtual SynthIF* createSIF(SynthI*); @@ -122,6 +125,7 @@ class DssiSynthIF : public SynthIF, public PluginIBase float** audioInBuffers; float** audioOutBuffers; + float* audioInSilenceBuf; // Just all zeros all the time, so we don't have to clear for silence. public: DssiSynthIF(SynthI* s); @@ -195,6 +199,7 @@ class DssiSynthIF : public SynthIF, public PluginIBase QString lib() const; QString dirPath() const; QString fileName() const; + QString titlePrefix() const; MusECore::AudioTrack* track(); void enableController(unsigned long /*i*/, bool v = true); bool controllerEnabled(unsigned long /*i*/) const; diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index bb9f42f4..0abbbd76 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -129,8 +129,8 @@ GlobalConfigValues config = { -60.0, // double minSlider; false, // use Jack freewheel 20, // int guiRefresh; - QString(""), // userInstrumentsDir - //QString(""), // helpBrowser; // Obsolete + QString(""), // userInstrumentsDir // Obsolete. Must keep for compatibility. + //QString(""), // helpBrowser; // Obsolete true, // extendedMidi 384, // division for smf export QString(""), // copyright string for smf export @@ -187,7 +187,12 @@ GlobalConfigValues config = { 64, // minControlProcessPeriod false, // popupsDefaultStayOpen false, // leftMouseButtonCanDecrease - false // rangeMarkerWithoutMMB + false, // rangeMarkerWithoutMMB + true, // addHiddenTracks + true // unhideTracks + }; +//GlobalConfigValues globalConfig = config; + } // namespace MusEGlobal diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index d9038ea1..95b88170 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -109,7 +109,7 @@ struct GlobalConfigValues { double minSlider; bool freewheelMode; int guiRefresh; - QString userInstrumentsDir; + QString userInstrumentsDir; // Obsolete. Must keep for compatibility. bool extendedMidi; // extended smf format int midiDivision; // division for smf export @@ -164,6 +164,9 @@ struct GlobalConfigValues { bool popupsDefaultStayOpen; bool leftMouseButtonCanDecrease; bool rangeMarkerWithoutMMB; + bool addHiddenTracks; + bool unhideTracks; + }; diff --git a/muse2/muse/globals.cpp b/muse2/muse/globals.cpp index 05ba1011..d50ea1eb 100644 --- a/muse2/muse/globals.cpp +++ b/muse2/muse/globals.cpp @@ -165,6 +165,12 @@ const char* med_file_save_pattern[] = { QT_TRANSLATE_NOOP("file_patterns", "All Files (*)"), 0 }; +const char* project_create_file_save_pattern[] = { + QT_TRANSLATE_NOOP("file_patterns", "Uncompressed med Files (*.med)"), + QT_TRANSLATE_NOOP("file_patterns", "gzip compressed med Files (*.med.gz)"), + QT_TRANSLATE_NOOP("file_patterns", "bzip2 compressed med Files (*.med.bz2)"), + 0 + }; const char* image_file_pattern[] = { QT_TRANSLATE_NOOP("file_patterns", "(*.jpg *.gif *.png)"), diff --git a/muse2/muse/globals.h b/muse2/muse/globals.h index ae624fb8..7563c171 100644 --- a/muse2/muse/globals.h +++ b/muse2/muse/globals.h @@ -94,6 +94,7 @@ extern const char* midi_file_pattern[]; extern const char* midi_file_save_pattern[]; extern const char* med_file_pattern[]; extern const char* med_file_save_pattern[]; +extern const char* project_create_file_save_pattern[]; extern const char* image_file_pattern[]; //extern const char* ctrl_file_pattern[]; extern const char* part_file_pattern[]; diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index 682bfe8e..f560fbfb 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -20,6 +20,8 @@ // //========================================================= +#include + #include "helper.h" #include "part.h" #include "track.h" @@ -28,8 +30,22 @@ #include "icons.h" #include "synth.h" #include "functions.h" +#include "gconfig.h" + +#include "driver/jackmidi.h" +#include "route.h" +#include "mididev.h" +#include "globaldefs.h" +#include "audio.h" +#include "audiodev.h" +#include "midiseq.h" #include +#include +#include +#include +#include +//#include #ifdef DSSI_SUPPORT #include "dssihost.h" @@ -118,170 +134,56 @@ QMenu* populateAddSynth(QWidget* parent) //typedef std::multimap::iterator imap; typedef std::multimap::iterator imap; - MusECore::MessSynth* synMESS = 0; - QMenu* synpMESS = 0; - asmap mapMESS; - - #ifdef DSSI_SUPPORT - MusECore::DssiSynth* synDSSI = 0; - QMenu* synpDSSI = 0; - asmap mapDSSI; - #endif - #ifdef VST_SUPPORT - MusECore::VstSynth* synVST = 0; - QMenu* synpVST = 0; - asmap mapVST; - #endif + int ntypes = MusECore::Synth::SYNTH_TYPE_END; + asmap smaps[ntypes]; + QMenu* mmaps[ntypes]; + for(int itype = 0; itype < ntypes; ++itype) + mmaps[itype] = 0; - // Not necessary, but what the heck. - QMenu* synpOther = 0; - asmap mapOther; + MusECore::Synth* synth; + MusECore::Synth::Type type; - //const int synth_base_id = 0x1000; int ii = 0; for(std::vector::iterator i = MusEGlobal::synthis.begin(); i != MusEGlobal::synthis.end(); ++i) { - synMESS = dynamic_cast(*i); - if(synMESS) - { - mapMESS.insert( std::pair (std::string(synMESS->description().toLower().toLatin1().constData()), ii) ); - } - else - { - - #ifdef DSSI_SUPPORT - synDSSI = dynamic_cast(*i); - if(synDSSI) - { - mapDSSI.insert( std::pair (std::string(synDSSI->description().toLower().toLatin1().constData()), ii) ); - } - else - #endif - - { - #ifdef VST_SUPPORT - synVST = dynamic_cast(*i); - if(synVST) - { - mapVST.insert( std::pair (std::string(synVST->description().toLower().toLatin1().constData()), ii) ); - } - else - #endif - - { - mapOther.insert( std::pair (std::string((*i)->description().toLower().toLatin1().constData()), ii) ); - } - } - } + synth = *i; + type = synth->synthType(); + if(type >= ntypes) + continue; + smaps[type].insert( std::pair (std::string(synth->description().toLower().toLatin1().constData()), ii) ); ++ii; } int sz = MusEGlobal::synthis.size(); - for(imap i = mapMESS.begin(); i != mapMESS.end(); ++i) - { - int idx = i->second; - if(idx > sz) // Sanity check - continue; - MusECore::Synth* s = MusEGlobal::synthis[idx]; - if(s) + for(int itype = 0; itype < ntypes; ++itype) + { + for(imap i = smaps[itype].begin(); i != smaps[itype].end(); ++i) { - // No MESS sub-menu yet? Create it now. - if(!synpMESS) - synpMESS = new QMenu(parent); - QAction* sM = synpMESS->addAction(s->description() + " <" + s->name() + ">"); - sM->setData(MENU_ADD_SYNTH_ID_BASE + idx); - } - } - - #ifdef DSSI_SUPPORT - for(imap i = mapDSSI.begin(); i != mapDSSI.end(); ++i) - { - int idx = i->second; - if(idx > sz) - continue; - MusECore::Synth* s = MusEGlobal::synthis[idx]; - if(s) - { - // No DSSI sub-menu yet? Create it now. - if(!synpDSSI) - synpDSSI = new QMenu(parent); - //synpDSSI->insertItem(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">", MENU_ADD_SYNTH_ID_BASE + idx); - QAction* sD = synpDSSI->addAction(s->description() + " <" + s->name() + ">"); - sD->setData(MENU_ADD_SYNTH_ID_BASE + idx); - } - } - #endif - - #ifdef VST_SUPPORT - for(imap i = mapVST.begin(); i != mapVST.end(); ++i) - { - int idx = i->second; - if(idx > sz) - continue; - Synth* s = MusEGlobal::synthis[idx]; - if(s) - { - // No VST sub-menu yet? Create it now. - if(!synpVST) - synpVST = new QMenu(parent); - QAction* sV = synpVST->addAction(s->description() + " <" + "@default", s->name() + ">"); - sV->setData(MENU_ADD_SYNTH_ID_BASE + idx); - } - } - #endif - - for(imap i = mapOther.begin(); i != mapOther.end(); ++i) - { - int idx = i->second; - if(idx > sz) - continue; - MusECore::Synth* s = MusEGlobal::synthis[idx]; - // No Other sub-menu yet? Create it now. - if(!synpOther) - synpOther = new QMenu(parent); - //synpOther->insertItem(QT_TRANSLATE_NOOP("@default", s->description()) + " <" + QT_TRANSLATE_NOOP("@default", s->name()) + ">", MENU_ADD_SYNTH_ID_BASE + idx); - QAction* sO = synpOther->addAction(s->description() + " <" + s->name() + ">"); - sO->setData(MENU_ADD_SYNTH_ID_BASE + idx); - } - - if(synpMESS) - { - synpMESS->setIcon(*synthIcon); - synpMESS->setTitle("MESS"); - synp->addMenu(synpMESS); - } - - #ifdef DSSI_SUPPORT - if(synpDSSI) - { - synpDSSI->setIcon(*synthIcon); - synpDSSI->setTitle("DSSI"); - synp->addMenu(synpDSSI); - } - #endif - - #ifdef VST_SUPPORT - if(synpVST) - { - synpVST->setIcon(*synthIcon); - synpVST->setTitle("FST"); - synp->addMenu(synpVST); - } - #endif - - if(synpOther) - { - synpOther->setIcon(*synthIcon); - synpOther->setTitle(QObject::tr("Other")); - synp->addMenu(synpOther); + int idx = i->second; + if(idx > sz) // Sanity check + continue; + synth = MusEGlobal::synthis[idx]; + if(synth) + { + // No sub-menu yet? Create it now. + if(!mmaps[itype]) + { + mmaps[itype] = new QMenu(parent); + mmaps[itype]->setIcon(*synthIcon); + mmaps[itype]->setTitle(MusECore::synthType2String((MusECore::Synth::Type)itype)); + synp->addMenu(mmaps[itype]); + } + QAction* act = mmaps[itype]->addAction(synth->description() + " <" + synth->name() + ">"); + act->setData( MENU_ADD_SYNTH_ID_BASE * (itype + 1) + idx ); + } + } } - + return synp; } - //--------------------------------------------------------- // populateAddTrack // this is also used in "mixer" @@ -290,19 +192,27 @@ QMenu* populateAddSynth(QWidget* parent) QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll) { QActionGroup* grp = new QActionGroup(addTrack); + if (MusEGlobal::config.addHiddenTracks) + populateAll=true; - QAction* midi = addTrack->addAction(QIcon(*addtrack_addmiditrackIcon), + if (populateAll || MusECore::MidiTrack::visible()) { + QAction* midi = addTrack->addAction(QIcon(*addtrack_addmiditrackIcon), qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Midi Track"))); - midi->setData(MusECore::Track::MIDI); - grp->addAction(midi); - QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), + midi->setData(MusECore::Track::MIDI); + grp->addAction(midi); + } + if (populateAll || MusECore::MidiTrack::visible()) { + QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Drum Track"))); - drum->setData(MusECore::Track::DRUM); - grp->addAction(drum); - QAction* wave = addTrack->addAction(QIcon(*addtrack_wavetrackIcon), + drum->setData(MusECore::Track::DRUM); + grp->addAction(drum); + } + if (populateAll || MusECore::WaveTrack::visible()) { + QAction* wave = addTrack->addAction(QIcon(*addtrack_wavetrackIcon), qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Wave Track"))); - wave->setData(MusECore::Track::WAVE); - grp->addAction(wave); + wave->setData(MusECore::Track::WAVE); + grp->addAction(wave); + } if (populateAll || MusECore::AudioOutput::visible()) { QAction* aoutput = addTrack->addAction(QIcon(*addtrack_audiooutputIcon), @@ -332,20 +242,47 @@ QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll) grp->addAction(aaux); } - // Create a sub-menu and fill it with found synth types. Make addTrack the owner. - QMenu* synp = populateAddSynth(addTrack); - synp->setIcon(*synthIcon); - synp->setTitle(qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Synth"))); + if (populateAll || MusECore::SynthI::visible()) { + // Create a sub-menu and fill it with found synth types. Make addTrack the owner. + QMenu* synp = populateAddSynth(addTrack); + synp->setIcon(*synthIcon); + synp->setTitle(qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Synth"))); + + // Add the sub-menu to the given menu. + addTrack->addMenu(synp); + } - // Add the sub-menu to the given menu. - addTrack->addMenu(synp); - //QObject::connect(addTrack, SIGNAL(triggered(QAction *)), MusEGlobal::song, SLOT(addNewTrack(QAction *))); return grp; } + +//--------------------------------------------------------- +// getFilterExtension +//--------------------------------------------------------- -} // namespace MusEGui +QString getFilterExtension(const QString &filter) +{ + // + // Return the first extension found. Must contain at least one * character. + // + + int pos = filter.indexOf('*'); + if(pos == -1) + return QString(); + + QString filt; + int len = filter.length(); + ++pos; + for( ; pos < len; ++pos) + { + QChar c = filter[pos]; + if((c == ')') || (c == ';') || (c == ',') || (c == ' ')) + break; + filt += filter[pos]; + } + return filt; +} QStringList localizedStringListFromCharArray(const char** array, const char* context) { @@ -355,3 +292,374 @@ QStringList localizedStringListFromCharArray(const char** array, const char* con return temp; } + +QString browseProjectFolder(QWidget* parent) +{ + QString path; + if(!MusEGlobal::config.projectBaseFolder.isEmpty()) + { + QDir d(MusEGlobal::config.projectBaseFolder); + path = d.absolutePath(); + } + + QString dir = QFileDialog::getExistingDirectory(parent, qApp->tr("Select project directory"), path); + if(dir.isEmpty()) + dir = MusEGlobal::config.projectBaseFolder; + // projDirLineEdit->setText(dir); + //return QFileDialog::getExistingDirectory(this, qApp.tr("Select project directory"), path); + return dir; +} + +QString projectTitleFromFilename(QString filename) +{ + int idx; + idx = filename.lastIndexOf(".med.bz2", -1, Qt::CaseInsensitive); + if(idx == -1) + idx = filename.lastIndexOf(".med.gz", -1, Qt::CaseInsensitive); + if(idx == -1) + idx = filename.lastIndexOf(".med", -1, Qt::CaseInsensitive); + + if(idx != -1) + filename.truncate(idx); + + QFileInfo fi(filename); + + //return fi.baseName(); + return fi.fileName(); +} + +QString projectPathFromFilename(QString filename) +{ + QFileInfo fi(filename); + return QDir::cleanPath(fi.absolutePath()); +} + +QString projectExtensionFromFilename(QString filename) +{ + int idx; + idx = filename.lastIndexOf(".med.bz2", -1, Qt::CaseInsensitive); + if(idx == -1) + idx = filename.lastIndexOf(".med.gz", -1, Qt::CaseInsensitive); + if(idx == -1) + idx = filename.lastIndexOf(".med", -1, Qt::CaseInsensitive); + if(idx == -1) + idx = filename.lastIndexOf(".bz2", -1, Qt::CaseInsensitive); + if(idx == -1) + idx = filename.lastIndexOf(".gz", -1, Qt::CaseInsensitive); + + return (idx == -1) ? QString() : filename.right(filename.size() - idx); +} + +QString getUniqueUntitledName() +{ + QString filename("untitled"); + //QTemporaryFile tf(MusEGlobal::config.projectBaseFolder +"/" + s + "XXXXXX.med"); + //if(tf.open()) + // s = MusEGui::projectTitleFromFilename(tf.fileName()); + + QString fbase(MusEGlobal::config.projectBaseFolder); + + QString nfb = fbase; + if(MusEGlobal::config.projectStoreInFolder) + nfb += "/" + filename; + QFileInfo fi(nfb + "/" + filename + ".med"); // TODO p4.0.40 Check other extensions. + if(!fi.exists()) + //return filename; + return fi.filePath(); + + // Find a new filename + QString nfn = filename; + int idx; + for (idx=2; idx<10000; idx++) { + QString num = QString::number(idx); + nfn = filename + "_" + num; + nfb = fbase; + if(MusEGlobal::config.projectStoreInFolder) + nfb += "/" + nfn; + QFileInfo fi(nfb + "/" + nfn + ".med"); + if(!fi.exists()) + //break; + return fi.filePath(); + } + + //if(idx >= 10000) + printf("MusE error: Could not make untitled project name (10000 or more untitled projects in project dir - clean up!\n"); + + //return nfn; + + nfb = fbase; + if(MusEGlobal::config.projectStoreInFolder) + nfb += "/" + filename; + return nfb + "/" + filename + ".med"; +} + + +#if 1 + +// ------------------------------------------------------------------------------------------------------- +// populateMidiPorts() +// This version creats separate devices for input and output ports. +// It does not attempt to pair them together. +// ------------------------------------------------------------------------------------------------------- +void populateMidiPorts() +{ + if(!MusEGlobal::checkAudioDevice()) + return; + + MusECore::MidiDevice* dev = 0; + + int port_num = 0; + + // If Jack is running, prefer Jack midi devices over ALSA. + if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::JACK_AUDIO) + { + std::list sl; + sl = MusEGlobal::audioDevice->inputPorts(true, 1); // Ask for second aliases. + for(std::list::iterator i = sl.begin(); i != sl.end(); ++i) + { + dev = MusECore::MidiJackDevice::createJackMidiDevice(*i, 1); + if(dev) + { + //printf("populateMidiPorts Created jack writeable device: %s\n", dev->name().toLatin1().constData()); + //dev->setOpenFlags(1); + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev); + MusECore::Route srcRoute(dev, -1); + MusECore::Route dstRoute(*i, true, -1, MusECore::Route::JACK_ROUTE); + MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute); + if(++port_num == MIDI_PORTS) + return; + } + } + + sl = MusEGlobal::audioDevice->outputPorts(true, 1); // Ask for second aliases. + for(std::list::iterator i = sl.begin(); i != sl.end(); ++i) + { + dev = MusECore::MidiJackDevice::createJackMidiDevice(*i, 2); + if(dev) + { + //printf("populateMidiPorts Created jack readable device: %s\n", dev->name().toLatin1().constData()); + //dev->setOpenFlags(2); + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev); + MusECore::Route srcRoute(*i, false, -1, MusECore::Route::JACK_ROUTE); + MusECore::Route dstRoute(dev, -1); + MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute); + if(++port_num == MIDI_PORTS) + return; + } + } + } + else + // If Jack is not running, use ALSA devices. + if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::DUMMY_AUDIO) + { + for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i) + { + if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI) + continue; + dev = *i; + // Select only sensible devices first - not thru etc. + //if( ... ) + // continue; + + //dev->setOpenFlags(1); + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev); + + if(++port_num == MIDI_PORTS) + return; + } + + //for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i) + //{ + // if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI) + // continue; + // // Select the ones ignored in the first pass. + // if(! ... ) + // continue; + // + // dev->setOpenFlags(1); + // MusEGlobal::midiSeq->msgSetMidiDevice(port_num, dev); + // + // if(++port_num == MIDI_PORTS) + // return; + //} + } + + //MusEGlobal::muse->changeConfig(true); // save configuration file + //MusEGlobal::song->update(); + +} + +#else + +// ------------------------------------------------------------------------------------------------------- +// populateMidiPorts() +// This version worked somewhat well with system devices. +// But no, it is virtually impossible to tell from the names whether ports should be paired. +// There is too much room for error - what markers to look for ("capture_"/"playback_") etc. +// It works kind of OK with 'seq' Jack Midi ALSA devices, but not for 'raw' which have a different +// naming structure ("in-hw-0-0-0"/"out-hw-0-0-0"). +// It also fails to combine if the ports were named by a client app, for example another instance of MusE. +// ------------------------------------------------------------------------------------------------------- + +void populateMidiPorts() +{ + if(!MusEGlobal::checkAudioDevice()) + return; + + MusECore::MidiDevice* dev = 0; + + int port_num = 0; + + // If Jack is running, prefer Jack midi devices over ALSA. + if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::JACK_AUDIO) + { + std::list wsl; + std::list rsl; + //wsl = MusEGlobal::audioDevice->inputPorts(true, 1); // Ask for second aliases. + wsl = MusEGlobal::audioDevice->inputPorts(true, 0); // Ask for first aliases. + //rsl = MusEGlobal::audioDevice->outputPorts(true, 1); // Ask for second aliases. + rsl = MusEGlobal::audioDevice->outputPorts(true, 0); // Ask for first aliases. + + for(std::list::iterator wi = wsl.begin(); wi != wsl.end(); ++wi) + { + QString ws = *wi; + int y = ws.lastIndexOf("_"); + if(y >= 1) + { + int x = ws.lastIndexOf("_", y-1); + if(x >= 0) + ws.remove(x, y - x); + } + + + bool match_found = false; + for(std::list::iterator ri = rsl.begin(); ri != rsl.end(); ++ri) + { + QString rs = *ri; + int y = rs.lastIndexOf("_"); + if(y >= 1) + { + int x = rs.lastIndexOf("_", y-1); + if(x >= 0) + rs.remove(x, y - x); + } + + // Do we have a matching pair? + if(rs == ws) + { + // Would like to remove the client name, but no, we need it as a distinguishing identifier. + //int z = ws.indexOf(":"); + //if(z >= 0) + // ws.remove(0, z + 1); + + dev = MusECore::MidiJackDevice::createJackMidiDevice(ws, 3); + if(dev) + { + //printf("populateMidiPorts Created jack writeable/readable device: %s\n", dev->name().toLatin1().constData()); + //dev->setOpenFlags(1); + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev); + MusECore::Route devRoute(dev, -1); + MusECore::Route wdstRoute(*wi, true, -1, MusECore::Route::JACK_ROUTE); + MusECore::Route rsrcRoute(*ri, false, -1, MusECore::Route::JACK_ROUTE); + MusEGlobal::audio->msgAddRoute(devRoute, wdstRoute); + MusEGlobal::audio->msgAddRoute(rsrcRoute, devRoute); + if(++port_num == MIDI_PORTS) + return; + } + + rsl.erase(ri); // Done with this read port. Remove. + match_found = true; + break; + } + } + + if(!match_found) + { + // No match was found. Create a single writeable device. + QString s = *wi; + // Would like to remove the client name, but no, we need it as a distinguishing identifier. + //int z = s.indexOf(":"); + //if(z >= 0) + // s.remove(0, z + 1); + dev = MusECore::MidiJackDevice::createJackMidiDevice(s, 1); + if(dev) + { + //printf("populateMidiPorts Created jack writeable device: %s\n", dev->name().toLatin1().constData()); + //dev->setOpenFlags(1); + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev); + MusECore::Route srcRoute(dev, -1); + MusECore::Route dstRoute(*wi, true, -1, MusECore::Route::JACK_ROUTE); + MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute); + if(++port_num == MIDI_PORTS) + return; + } + } + } + + // Create the remaining readable ports as single readable devices. + for(std::list::iterator ri = rsl.begin(); ri != rsl.end(); ++ri) + { + QString s = *ri; + // Would like to remove the client name, but no, we need it as a distinguishing identifier. + //int z = s.indexOf(":"); + //if(z >= 0) + // s.remove(0, z + 1); + dev = MusECore::MidiJackDevice::createJackMidiDevice(s, 2); + if(dev) + { + //printf("populateMidiPorts Created jack readable device: %s\n", dev->name().toLatin1().constData()); + //dev->setOpenFlags(2); + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev); + MusECore::Route srcRoute(*ri, false, -1, MusECore::Route::JACK_ROUTE); + MusECore::Route dstRoute(dev, -1); + MusEGlobal::audio->msgAddRoute(srcRoute, dstRoute); + if(++port_num == MIDI_PORTS) + return; + } + } + } + else + // If Jack is not running, use ALSA devices. + if(MusEGlobal::audioDevice->deviceType() == MusECore::AudioDevice::DUMMY_AUDIO) + { + for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i) + { + if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI) + continue; + dev = *i; + // Select only sensible devices first - not thru etc. + //if( ... ) + // continue; + + //dev->setOpenFlags(1); + MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[port_num], dev); + + if(++port_num == MIDI_PORTS) + return; + } + + //for(MusECore::iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i) + //{ + // if((*i)->deviceType() != MusECore::MidiDevice::ALSA_MIDI) + // continue; + // // Select the ones ignored in the first pass. + // if(! ... ) + // continue; + // + // dev->setOpenFlags(1); + // MusEGlobal::midiSeq->msgSetMidiDevice(port_num, dev); + // + // if(++port_num == MIDI_PORTS) + // return; + //} + } + + //MusEGlobal::muse->changeConfig(true); // save configuration file + //MusEGlobal::song->update(); + +} +#endif // populateMidiPorts + + +} // namespace MusEGui + diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index e1bf93de..f9c9a78c 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -42,8 +42,15 @@ bool any_event_selected(const std::set&, bool in_range=false); namespace MusEGui { QMenu* populateAddSynth(QWidget* parent); QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll=false); +QStringList localizedStringListFromCharArray(const char** array, const char* context); +QString getFilterExtension(const QString &filter); +QString browseProjectFolder(QWidget* parent = 0); +QString projectTitleFromFilename(QString filename); +QString projectPathFromFilename(QString filename); +QString projectExtensionFromFilename(QString filename); +QString getUniqueUntitledName(); +void populateMidiPorts(); } -QStringList localizedStringListFromCharArray(const char** array, const char* context); #endif diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp index 742e0626..b90b872e 100644 --- a/muse2/muse/instruments/editinstrument.cpp +++ b/muse2/muse/instruments/editinstrument.cpp @@ -407,27 +407,10 @@ void EditInstrument::saveAs() if(!QDir(MusEGlobal::museUserInstruments).exists()) { - if(QMessageBox::question(this, - tr("MusE:"), - tr("The user instrument directory\n%1\ndoes not exist yet. Create it now?\n").arg(MusEGlobal::museUserInstruments) + - tr("(You can change the user instruments directory at Settings->Global Settings->Midi)"), - QMessageBox::Ok | QMessageBox::Default, - QMessageBox::Cancel | QMessageBox::Escape, - Qt::NoButton) == QMessageBox::Ok) - { - if(QDir().mkdir(MusEGlobal::museUserInstruments)) - printf("Created user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData()); - else - { - printf("Unable to create user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData()); - QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory '%1'").arg(MusEGlobal::museUserInstruments)); - //return; - path = MusEGlobal::museUser; - } - } - else - // return; - path = MusEGlobal::museUser; + printf("MusE Error! User instrument directory: %s does not exist. Should be created at startup!\n", MusEGlobal::museUserInstruments.toLatin1().constData()); + + //path = MusEGlobal::museUser; + //path = MusEGlobal::configPath; } //if (instrument->filePath().isEmpty()) @@ -699,27 +682,10 @@ void EditInstrument::fileSaveAs() if(!QDir(MusEGlobal::museUserInstruments).exists()) { - if(QMessageBox::question(this, - tr("MusE:"), - tr("The user instrument directory\n%1\ndoes not exist yet. Create it now?\n").arg(MusEGlobal::museUserInstruments) + - tr("(You can change the user instruments directory at Settings->Global Settings->Midi)"), - QMessageBox::Ok | QMessageBox::Default, - QMessageBox::Cancel | QMessageBox::Escape, - Qt::NoButton) == QMessageBox::Ok) - { - if(QDir().mkdir(MusEGlobal::museUserInstruments)) - printf("Created user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData()); - else - { - printf("Unable to create user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1().constData()); - QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory '%1'").arg(MusEGlobal::museUserInstruments)); - //return; - path = MusEGlobal::museUser; - } - } - else - // return; - path = MusEGlobal::museUser; + printf("MusE Error! User instrument directory: %s does not exist. Should be created at startup!\n", MusEGlobal::museUserInstruments.toLatin1().constData()); + + //path = MusEGlobal::museUser; + //path = MusEGlobal::configPath; } path += QString("/%1.idf").arg(so); diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index 8e8bb6c3..22ed3737 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -936,8 +936,69 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru // populatePatchPopup //--------------------------------------------------------- +void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MType songType, bool drum) + { + menu->clear(); + int mask = 0; + bool drumchan = chan == 9; + switch (songType) { + case MT_XG: mask = 4; break; + case MT_GS: mask = 2; break; + case MT_GM: + if(drumchan) + { + int id = (0xff << 16) + (0xff << 8) + 0x00; // First patch + QAction* act = menu->addAction(gmdrumname); + //act->setCheckable(true); + act->setData(id); + return; + } + mask = 1; + break; + case MT_UNKNOWN: mask = 7; break; + } + if (pg.size() > 1) { + for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) { + PatchGroup* pgp = *i; + //QMenu* pm = menu->addMenu(pgp->name); + MusEGui::PopupMenu* pm = new MusEGui::PopupMenu(pgp->name, menu, menu->stayOpen()); // Use the parent stayOpen here. + menu->addMenu(pm); + pm->setFont(MusEGlobal::config.fonts[0]); + const PatchList& pl = pgp->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if ((mp->typ & mask) && + ((drum && songType != MT_GM) || + (mp->drum == drumchan)) ) + { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + QAction* act = pm->addAction(mp->name); + //act->setCheckable(true); + act->setData(id); + } + + } + } + } + else if (pg.size() == 1 ){ + // no groups + const PatchList& pl = pg.front()->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if (mp->typ & mask) { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + QAction* act = menu->addAction(mp->name); + //act->setCheckable(true); + act->setData(id); + } + } + } + } // namespace MusECore +/* namespace MusEGui { void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* menu, int chan, MType songType, bool drum) @@ -1000,5 +1061,6 @@ void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* men } } } +*/ } // namespace MusEGui diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h index 3a645d7f..385e67b4 100644 --- a/muse2/muse/instruments/minstrument.h +++ b/muse2/muse/instruments/minstrument.h @@ -143,7 +143,7 @@ class MidiInstrument { virtual void reset(int, MType); virtual QString getPatchName(int,int,MType,bool); //virtual void populatePatchPopup(QMenu*, int, MType, bool); - //virtual void populatePatchPopup(MusEGui::PopupMenu*, int, MType, bool); + virtual void populatePatchPopup(MusEGui::PopupMenu*, int, MType, bool); void read(Xml&); void write(int level, Xml&); @@ -171,8 +171,8 @@ extern void removeMidiInstrument(const MidiInstrument* instr); } // namespace MusECore -namespace MusEGui { -extern void populatePatchPopup(MusECore::MidiInstrument*, PopupMenu*, int, MType, bool); -} +//namespace MusEGui { +//extern void populatePatchPopup(MusECore::MidiInstrument*, PopupMenu*, int, MType, bool); +//} #endif diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/liste/editevent.cpp index bca5729b..214f74c2 100644 --- a/muse2/muse/liste/editevent.cpp +++ b/muse2/muse/liste/editevent.cpp @@ -871,20 +871,17 @@ void EditCtrlDialog::instrPopup() int port = track->outPort(); MusECore::MidiInstrument* instr = MusEGlobal::midiPorts[port].instrument(); - ///instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //QMenu* pup = new QMenu(this); MusEGui::PopupMenu* pup = new MusEGui::PopupMenu(this); - populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); + //populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); + instr->populatePatchPopup(pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); - ///if(pop->actions().count() == 0) - /// return; if(pup->actions().count() == 0) { delete pup; return; } - ///QAction* rv = pop->exec(patchName->mapToGlobal(QPoint(10,5))); QAction* rv = pup->exec(patchName->mapToGlobal(QPoint(10,5))); if (rv) { val = rv->data().toInt(); diff --git a/muse2/muse/liste/listedit.cpp b/muse2/muse/liste/listedit.cpp index f6a77b85..6795cedb 100644 --- a/muse2/muse/liste/listedit.cpp +++ b/muse2/muse/liste/listedit.cpp @@ -45,6 +45,7 @@ #include "event.h" #include "midiport.h" #include "midictrl.h" +#include "app.h" namespace MusEGui { @@ -616,6 +617,8 @@ ListEdit::ListEdit(MusECore::PartList* pl) initShortcuts(); setWindowTitle("MusE: List Editor"); + + MusEGlobal::muse->topwinMenuInited(this); } //--------------------------------------------------------- diff --git a/muse2/muse/main.cpp b/muse2/muse/main.cpp index 0353d0d6..d946bf00 100644 --- a/muse2/muse/main.cpp +++ b/muse2/muse/main.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -31,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +45,7 @@ #include "audiodev.h" #include "gconfig.h" #include "globals.h" +#include "helper.h" #include "icons.h" #include "sync.h" #include "functions.h" @@ -267,9 +272,38 @@ int main(int argc, char* argv[]) if (! cPath.exists()) cPath.mkpath("."); + // Create user templates dir if it doesn't exist + QDir utemplDir = QDir(MusEGlobal::configPath + QString("/templates")); + if(!utemplDir.exists()) + { + utemplDir.mkpath("."); + // Support old versions: Copy existing templates over. + QDir old_utemplDir = QDir(QString(getenv("HOME")) + QString("/templates")); + // printf(" old templates dir:%s\n", (QString(getenv("HOME")) + QString("/templates")).toLatin1().constData()); + if(old_utemplDir.exists()) + { + //printf(" found old templates dir\n"); + // We really just want these, even though it's possible other filenames were saved. + // Another application might have used that directory. + QStringList flt; flt << "*.med" << "*.med.gz" << "*.med.bz2" << "*.mid" << "*.midi" << "*.kar"; + old_utemplDir.setNameFilters(flt); + + QFileInfoList fil = old_utemplDir.entryInfoList(); + QFileInfo fi; + foreach(fi, fil) + { + QString fn = fi.fileName(); + QFile f(fi.absoluteFilePath()); + f.copy(utemplDir.absolutePath() + "/" + fn); + //printf(" copy old template to:%s result:%d\n", QString(utemplPath.absolutePath() + "/" + fn).toLatin1().constData(), rv); + } + } + } + QFile cConf (MusEGlobal::configName); QFile cConfTempl (MusEGlobal::museGlobalShare + QString("/templates/MusE.cfg")); - if (! cConf.exists()) + bool cConfExists = cConf.exists(); + if (!cConfExists) { printf ("creating new config...\n"); if (cConfTempl.copy(MusEGlobal::configName)) @@ -303,10 +337,51 @@ int main(int argc, char* argv[]) MusEGui::init_function_dialogs(MusEGlobal::muse); MusEGui::initShortCuts(); + MusECore::readConfiguration(); - MusEGlobal::museUserInstruments = MusEGlobal::config.userInstrumentsDir; + // Need to put a sane default here because we can't use ~ in the file name string. + if(!cConfExists) + MusEGlobal::config.projectBaseFolder = MusEGlobal::museUser + QString("/MusE"); + //MusEGlobal::museUserInstruments = MusEGlobal::config.userInstrumentsDir; + + // Create user instruments dir if it doesn't exist + { + QString uinstrPath = MusEGlobal::configPath + QString("/instruments"); + QDir uinstrDir = QDir(uinstrPath); + if(!uinstrDir.exists()) + uinstrDir.mkpath("."); + + if(!MusEGlobal::config.userInstrumentsDir.isEmpty() && MusEGlobal::config.userInstrumentsDir != uinstrPath) // Only if it is different. + { + // Support old versions: Copy existing instruments over. + QDir old_uinstrDir(MusEGlobal::config.userInstrumentsDir); + //printf(" old instruments dir:%s\n", MusEGlobal::config.userInstrumentsDir.toLatin1().constData()); + if(old_uinstrDir.exists()) + { + //printf(" found old instruments dir\n"); + QStringList flt; flt << "*.idf"; + old_uinstrDir.setNameFilters(flt); + + QFileInfoList fil = old_uinstrDir.entryInfoList(); + QFileInfo fi; + foreach(fi, fil) + { + QString fn = fi.fileName(); + QFile f(fi.absoluteFilePath()); + QFile newf(uinstrDir.absolutePath() + "/" + fn); + if(!newf.exists()) + { + f.copy(newf.fileName()); + //printf(" copy old instrument to:%s result:%d\n", newf.fileName().toLatin1().constData(), rv); + } + } + } + } + MusEGlobal::museUserInstruments = uinstrPath; + } + if (MusEGlobal::config.useDenormalBias) printf("Denormal protection enabled.\n"); // SHOW MUSE SPLASH SCREEN @@ -324,7 +399,7 @@ int main(int argc, char* argv[]) stimer->start(6000); } } - + int i; QString optstr("ahvdDmMsP:Y:l:py"); @@ -393,6 +468,7 @@ int main(int argc, char* argv[]) } */ + AL::initDsp(); if (MusEGlobal::debugMsg) @@ -438,8 +514,7 @@ int main(int argc, char* argv[]) else MusEGlobal::realTimeScheduling = MusEGlobal::audioDevice->isRealtime(); - - // What unreliable nonsense. With Jack2 this reports true even if it is not running realtime. + // ??? With Jack2 this reports true even if it is not running realtime. // Jack says: "Cannot use real-time scheduling (RR/10)(1: Operation not permitted)". The kernel is non-RT. // I cannot seem to find a reliable answer to the question, even with dummy audio and system calls. //if (MusEGlobal::debugMsg) @@ -448,11 +523,7 @@ int main(int argc, char* argv[]) MusEGlobal::useJackTransport.setValue(true); // setup the prefetch fifo length now that the segmentSize is known - // Changed by Tim. p3.3.17 - // Changed to 4 *, JUST FOR TEST!!! MusEGlobal::fifoLength = 131072 / MusEGlobal::segmentSize; - //MusEGlobal::fifoLength = (131072 / MusEGlobal::segmentSize) * 4; - argc -= optind; ++argc; @@ -498,7 +569,6 @@ int main(int argc, char* argv[]) if(MusEGlobal::loadDSSI) MusECore::initDSSI(); - // p3.3.39 MusECore::initOSC(); MusEGui::initIcons(); @@ -517,21 +587,19 @@ int main(int argc, char* argv[]) ++it; } } - + MusEGlobal::muse = new MusEGui::MusE(argc, &argv[optind]); app.setMuse(MusEGlobal::muse); MusEGlobal::muse->setWindowIcon(*MusEGui::museIcon); - - // Added by Tim. p3.3.22 if (!MusEGlobal::debugMode) { if (mlockall(MCL_CURRENT | MCL_FUTURE)) perror("WARNING: Cannot lock memory:"); } MusEGlobal::muse->show(); - MusEGlobal::muse->seqStart(); - + MusEGlobal::muse->seqStart(); + #ifdef HAVE_LASH { MusEGui::lash_client = 0; @@ -542,14 +610,28 @@ int main(int argc, char* argv[]) MusEGui::lash_client = lash_init (lash_args, muse_name, lash_flags, LASH_PROTOCOL(2,0)); lash_alsa_client_id (MusEGui::lash_client, snd_seq_client_id (MusECore::alsaSeq)); if (!noAudio) { - // p3.3.38 - //char *jack_name = ((JackAudioDevice*)MusEGlobal::audioDevice)->getJackName(); const char *jack_name = MusEGlobal::audioDevice->clientName(); lash_jack_client_name (MusEGui::lash_client, jack_name); } } } #endif /* HAVE_LASH */ + + //-------------------------------------------------- + // Auto-fill the midi ports, if appropriate. p4.0.41 + //-------------------------------------------------- + if(argc < 2 && MusEGlobal::config.startMode == 1) + { + MusEGui::populateMidiPorts(); + //MusEGlobal::muse->changeConfig(true); // save configuration file + //MusEGlobal::song->update(); + } + + //-------------------------------------------------- + // Load the default song. + //-------------------------------------------------- + MusEGlobal::muse->loadDefaultSong(argc, &argv[optind]); // p4.0.41 + QTimer::singleShot(100, MusEGlobal::muse, SLOT(showDidYouKnowDialog())); int rv = app.exec(); diff --git a/muse2/muse/marker/markerview.cpp b/muse2/muse/marker/markerview.cpp index bc9e48b9..39ce4fc0 100644 --- a/muse2/muse/marker/markerview.cpp +++ b/muse2/muse/marker/markerview.cpp @@ -26,6 +26,7 @@ #include "markerview.h" #include "xml.h" #include "globals.h" +#include "app.h" #include "sync.h" #include "icons.h" #include "song.h" @@ -157,7 +158,7 @@ void MarkerItem::setTick(unsigned v) void MarkerView::closeEvent(QCloseEvent* e) { - emit deleted(static_cast(this)); + emit isDeleting(static_cast(this)); emit closed(); e->accept(); } @@ -296,6 +297,8 @@ MarkerView::MarkerView(QWidget* parent) updateList(); + MusEGlobal::muse->topwinMenuInited(this); + // work around for probable QT/WM interaction bug. // for certain window managers, e.g xfce, this window is // is displayed although not specifically set to show(); diff --git a/muse2/muse/marker/markerview.h b/muse2/muse/marker/markerview.h index b50ab7a4..06e22daf 100644 --- a/muse2/muse/marker/markerview.h +++ b/muse2/muse/marker/markerview.h @@ -96,7 +96,7 @@ class MarkerView : public TopWin { void songChanged(int); signals: - void deleted(MusEGui::TopWin*); + void isDeleting(MusEGui::TopWin*); void closed(); public: diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp index 52b488d0..f461e1d3 100644 --- a/muse2/muse/master/lmaster.cpp +++ b/muse2/muse/master/lmaster.cpp @@ -27,6 +27,7 @@ #include "xml.h" #include "song.h" #include "globals.h" +#include "app.h" #include "audio.h" //#include "posedit.h" //#include "sigedit.h" @@ -286,6 +287,7 @@ LMaster::LMaster() connect(keyButton, SIGNAL(clicked()), SLOT(insertKey())); initShortcuts(); + MusEGlobal::muse->topwinMenuInited(this); } //--------------------------------------------------------- diff --git a/muse2/muse/master/masteredit.cpp b/muse2/muse/master/masteredit.cpp index 191f82ab..f6169766 100644 --- a/muse2/muse/master/masteredit.cpp +++ b/muse2/muse/master/masteredit.cpp @@ -37,6 +37,7 @@ #include "doublelabel.h" ///#include "sigedit.h" #include "globals.h" +#include "app.h" #include @@ -269,6 +270,7 @@ MasterEdit::MasterEdit() connect(canvas, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); initTopwinState(); + MusEGlobal::muse->topwinMenuInited(this); } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index b07ebbbe..52e63da0 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -53,6 +53,7 @@ #include "vscale.h" #include "swidget.h" #include "globals.h" +#include "app.h" #include "icons.h" #include "filedialog.h" #include "drummap.h" @@ -535,6 +536,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un initTopwinState(); + MusEGlobal::muse->topwinMenuInited(this); } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index 9189d177..80d901bb 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: ecanvas.cpp,v 1.8.2.6 2009/05/03 04:14:00 terminator356 Exp $ // (C) Copyright 2001 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -325,54 +326,54 @@ void EventCanvas::keyPress(QKeyEvent* event) } // Select items by key (PianoRoll & DrumEditor) else if (key == shortcuts[SHRT_SEL_RIGHT].key || key == shortcuts[SHRT_SEL_RIGHT_ADD].key) { - iCItem i, iRightmost; - CItem* rightmost = NULL; - //Get the rightmost selected note (if any) - for (i = items.begin(); i != items.end(); ++i) { - if (i->second->isSelected()) { - iRightmost = i; rightmost = i->second; - } - } - if (rightmost) { - iCItem temp = iRightmost; temp++; - //If so, deselect current note and select the one to the right - if (temp != items.end()) { - if (key != shortcuts[SHRT_SEL_RIGHT_ADD].key) - deselectAll(); - - iRightmost++; - iRightmost->second->setSelected(true); - updateSelection(); - } - } - //if (rightmost && mapx(rightmost->event().tick()) > width()) for some reason this doesn't this doesnt move the event in view - // emit followEvent(rightmost->x()); - + rciCItem i; + for (i = items.rbegin(); i != items.rend(); ++i) + if (i->second->isSelected()) + break; + + if(i == items.rend()) + i = items.rbegin(); + + if(i != items.rbegin()) + --i; + if(i->second) + { + if (key != shortcuts[SHRT_SEL_RIGHT_ADD].key) + deselectAll(); + CItem* sel = i->second; + sel->setSelected(true); + updateSelection(); + if (sel->x() + sel->width() > mapxDev(width())) + { + int mx = rmapx(sel->x()); + int newx = mx + rmapx(sel->width()) - width(); + // Leave a bit of room for the specially-drawn drum notes. But good for piano too. + emit horizontalScroll( (newx > mx ? mx - 10: newx + 10) - rmapx(xorg) ); + } + } } //Select items by key: (PianoRoll & DrumEditor) else if (key == shortcuts[SHRT_SEL_LEFT].key || key == shortcuts[SHRT_SEL_LEFT_ADD].key) { - iCItem i, iLeftmost; - CItem* leftmost = NULL; - if (items.size() > 0 ) { - for (i = items.end(), i--; i != items.begin(); i--) { - if (i->second->isSelected()) { - iLeftmost = i; leftmost = i->second; - } - } - if (leftmost) { - if (iLeftmost != items.begin()) { - //Add item - if (key != shortcuts[SHRT_SEL_LEFT_ADD].key) - deselectAll(); - - iLeftmost--; - iLeftmost->second->setSelected(true); - updateSelection(); - } - } - //if (leftmost && mapx(leftmost->event().tick())< 0 ) for some reason this doesn't this doesnt move the event in view - // emit followEvent(leftmost->x()); - } + ciCItem i; + for (i = items.begin(); i != items.end(); ++i) + if (i->second->isSelected()) + break; + + if(i == items.end()) + i = items.begin(); + + if(i != items.begin()) + --i; + if(i->second) + { + if (key != shortcuts[SHRT_SEL_LEFT_ADD].key) + deselectAll(); + CItem* sel = i->second; + sel->setSelected(true); + updateSelection(); + if (sel->x() <= mapxDev(0)) + emit horizontalScroll(rmapx(sel->x() - xorg) - 10); // Leave a bit of room. + } } else if (key == shortcuts[SHRT_INC_PITCH].key) { modifySelected(NoteInfo::VAL_PITCH, 1); diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp index 926f4212..8c2a7a87 100644 --- a/muse2/muse/midiedit/pianoroll.cpp +++ b/muse2/muse/midiedit/pianoroll.cpp @@ -56,6 +56,7 @@ #include "tb1.h" #include "utils.h" #include "globals.h" +#include "app.h" #include "gconfig.h" #include "icons.h" #include "audio.h" @@ -532,6 +533,7 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name, } initTopwinState(); + MusEGlobal::muse->topwinMenuInited(this); } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index b06f2487..51e1cafc 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -166,6 +166,15 @@ QColor* mycolors; // array [NUM_MYCOLORS] set ScoreEdit::names; +int ScoreCanvas::_quant_power2_init=3; +int ScoreCanvas::_pixels_per_whole_init=300; +int ScoreCanvas::note_velo_init=64; +int ScoreCanvas::note_velo_off_init=64; +int ScoreCanvas::new_len_init=0; +ScoreCanvas::coloring_mode_t ScoreCanvas::coloring_mode_init=COLOR_MODE_BLACK; +bool ScoreCanvas::preamble_contains_timesig_init=true; +bool ScoreCanvas::preamble_contains_keysig_init=true; + //--------------------------------------------------------- // ScoreEdit @@ -293,8 +302,22 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) len_actions->addAction(n32_action); len_actions->addAction(nlast_action); - nlast_action->setChecked(true); - menu_command(CMD_NOTELEN_LAST); + switch (ScoreCanvas::new_len_init) + { + case 0: nlast_action->setChecked(true); menu_command(CMD_NOTELEN_LAST); break; + case 1: n1_action->setChecked(true); menu_command(CMD_NOTELEN_1); break; + case 2: n2_action->setChecked(true); menu_command(CMD_NOTELEN_2); break; + case 4: n4_action->setChecked(true); menu_command(CMD_NOTELEN_4); break; + case 8: n8_action->setChecked(true); menu_command(CMD_NOTELEN_8); break; + case 16: n16_action->setChecked(true); menu_command(CMD_NOTELEN_16); break; + case 32: n32_action->setChecked(true); menu_command(CMD_NOTELEN_32); break; + default: + cerr << "ERROR: THIS SHOULD NEVER HAPPEN. newLen is invalid in ScoreEdit::ScoreEdit.\n" << + " (newLen="<setChecked(true); + menu_command(CMD_NOTELEN_LAST); + } note_settings_toolbar->addSeparator(); @@ -316,7 +339,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) connect(velo_spinbox, SIGNAL(editingFinished()), SLOT(velo_box_changed())); connect(this,SIGNAL(velo_changed(int)), score_canvas, SLOT(set_velo(int))); note_settings_toolbar->addWidget(velo_spinbox); - velo_spinbox->setValue(64); + velo_spinbox->setValue(ScoreCanvas::note_velo_init); note_settings_toolbar->addWidget(new QLabel(tr("Off-Velocity:"), note_settings_toolbar)); velo_off_spinbox = new QSpinBox(this); @@ -327,7 +350,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) connect(velo_off_spinbox, SIGNAL(editingFinished()), SLOT(velo_off_box_changed())); connect(this,SIGNAL(velo_off_changed(int)), score_canvas, SLOT(set_velo_off(int))); note_settings_toolbar->addWidget(velo_off_spinbox); - velo_off_spinbox->setValue(64); + velo_off_spinbox->setValue(ScoreCanvas::note_velo_off_init); @@ -336,13 +359,16 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) quant_toolbar->addWidget(new QLabel(tr("Quantisation:"), quant_toolbar)); quant_combobox = new QComboBox(this); quant_combobox->addItem("2"); // if you add or remove items from - quant_combobox->addItem("4"); // here, also change quant_mapper[] - quant_combobox->addItem("8"); // in ScoreCanvas::set_quant()! + quant_combobox->addItem("4"); // here, also change all code regarding + quant_combobox->addItem("8"); // _quant_power2 and _quant_power2_init quant_combobox->addItem("16"); // and MAX_QUANT_POWER (must be log2(largest_value)) quant_combobox->addItem("32"); + quant_combobox->setCurrentIndex(score_canvas->quant_power2()-1); + // the above is intendedly executed BEFORE connecting. otherwise this would + // destroy pixels_per_whole_init! connect(quant_combobox, SIGNAL(currentIndexChanged(int)), score_canvas, SLOT(set_quant(int))); quant_toolbar->addWidget(quant_combobox); - quant_combobox->setCurrentIndex(2); + quant_toolbar->addSeparator(); @@ -353,7 +379,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) connect(px_per_whole_spinbox, SIGNAL(valueChanged(int)), score_canvas, SLOT(set_pixels_per_whole(int))); connect(score_canvas, SIGNAL(pixels_per_whole_changed(int)), px_per_whole_spinbox, SLOT(setValue(int))); quant_toolbar->addWidget(px_per_whole_spinbox); - px_per_whole_spinbox->setValue(300); + px_per_whole_spinbox->setValue(ScoreCanvas::_pixels_per_whole_init); QMenu* edit_menu = menuBar()->addMenu(tr("&Edit")); @@ -454,8 +480,18 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) menu_mapper->setMapping(color_velo_action, CMD_COLOR_VELO); menu_mapper->setMapping(color_part_action, CMD_COLOR_PART); - color_black_action->setChecked(true); - menu_command(CMD_COLOR_BLACK); + switch (ScoreCanvas::coloring_mode_init) + { + case 0: color_black_action->setChecked(true); menu_command(CMD_COLOR_BLACK); break; + case 1: color_velo_action->setChecked(true); menu_command(CMD_COLOR_VELO); break; + case 2: color_part_action->setChecked(true); menu_command(CMD_COLOR_PART); break; + default: + cerr << "ERROR: THIS SHOULD NEVER HAPPEN. noteColor is invalid in ScoreEdit::ScoreEdit.\n" << + " (noteColor="<setChecked(true); + menu_command(CMD_COLOR_BLACK); + } QMenu* preamble_menu = settings_menu->addMenu(tr("Set up &preamble")); preamble_keysig_action = preamble_menu->addAction(tr("Display &key signature")); @@ -466,8 +502,8 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) preamble_keysig_action->setCheckable(true); preamble_timesig_action->setCheckable(true); - preamble_keysig_action->setChecked(true); - preamble_timesig_action->setChecked(true); + preamble_keysig_action->setChecked(ScoreCanvas::preamble_contains_keysig_init); + preamble_timesig_action->setChecked(ScoreCanvas::preamble_contains_timesig_init); QAction* set_name_action = settings_menu->addAction(tr("Set Score &name"), menu_mapper, SLOT(map())); menu_mapper->setMapping(set_name_action, CMD_SET_NAME); @@ -503,6 +539,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) apply_velo=true; initTopwinState(); + MusEGlobal::muse->topwinMenuInited(this); } void ScoreEdit::init_shortcuts() @@ -587,7 +624,7 @@ bool ScoreEdit::set_name(QString newname, bool emit_signal, bool emergency_name) ScoreEdit::~ScoreEdit() { - + names.erase(name); } void ScoreEdit::velo_box_changed() @@ -602,9 +639,9 @@ void ScoreEdit::velo_off_box_changed() void ScoreEdit::song_changed(int flags) { - if(_isDeleting) // Ignore while while deleting to prevent crash. - return; - + if(_isDeleting) // Ignore while while deleting to prevent crash. + return; + if (flags & (SC_SELECTION | SC_EVENT_MODIFIED | SC_EVENT_REMOVED)) { map selection=get_events(score_canvas->get_all_parts(),1); @@ -673,8 +710,9 @@ void ScoreEdit::viewport_height_changed(int height) void ScoreEdit::closeEvent(QCloseEvent* e) { - _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored. - + _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored. + names.erase(name); + QSettings settings("MusE", "MusE-qt"); //settings.setValue("ScoreEdit/geometry", saveGeometry()); settings.setValue("ScoreEdit/windowState", saveState()); @@ -692,8 +730,8 @@ void ScoreEdit::menu_command(int cmd) { bool ok; QString newname = QInputDialog::getText(this, tr("Enter the new score title"), - tr("Enter the new score title"), QLineEdit::Normal, - name, &ok); + tr("Enter the new score title"), QLineEdit::Normal, + name, &ok); if (ok) { if (!set_name(newname)) @@ -1059,7 +1097,23 @@ void ScoreEdit::read_configuration(MusECore::Xml& xml) switch (token) { case MusECore::Xml::TagStart: - if (tag == "topwin") + if (tag=="quantPowerInit") + ScoreCanvas::_quant_power2_init=xml.parseInt(); + else if (tag=="pxPerWholeInit") + ScoreCanvas::_pixels_per_whole_init=xml.parseInt(); + else if (tag=="newNoteVeloInit") + ScoreCanvas::note_velo_init=xml.parseInt(); + else if (tag=="newNoteVeloOffInit") + ScoreCanvas::note_velo_off_init=xml.parseInt(); + else if (tag=="newLenInit") + ScoreCanvas::new_len_init=xml.parseInt(); + else if (tag=="noteColorInit") + ScoreCanvas::coloring_mode_init=(ScoreCanvas::coloring_mode_t)xml.parseInt(); + else if (tag=="preambleContainsKeysig") + ScoreCanvas::preamble_contains_keysig_init=xml.parseInt(); + else if (tag=="preambleContainsTimesig") + ScoreCanvas::preamble_contains_timesig_init=xml.parseInt(); + else if (tag == "topwin") TopWin::readConfiguration(SCORE, xml); else xml.unknown("ScoreEdit"); @@ -1079,7 +1133,18 @@ void ScoreEdit::read_configuration(MusECore::Xml& xml) void ScoreEdit::write_configuration(int level, MusECore::Xml& xml) { xml.tag(level++, "scoreedit"); + + xml.intTag(level, "quantPowerInit", ScoreCanvas::_quant_power2_init); + xml.intTag(level, "pxPerWholeInit", ScoreCanvas::_pixels_per_whole_init); + xml.intTag(level, "newNoteVeloInit", ScoreCanvas::note_velo_init); + xml.intTag(level, "newNoteVeloOffInit", ScoreCanvas::note_velo_off_init); + xml.intTag(level, "newLenInit", ScoreCanvas::new_len_init); + xml.intTag(level, "noteColorInit", ScoreCanvas::coloring_mode_init); + xml.intTag(level, "preambleContainsKeysig", ScoreCanvas::preamble_contains_keysig_init); + xml.intTag(level, "preambleContainsTimesig", ScoreCanvas::preamble_contains_timesig_init); + TopWin::writeConfiguration(SCORE, level, xml); + xml.etag(level, "scoreedit"); } @@ -1216,22 +1281,20 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget) : View(parent_wi dragged_event_part=NULL; last_len=384; - new_len=-1; + new_len=-1; // will be initalized with new_len_init by ScoreEdit::ScoreEdit(); - set_quant(2); //this is actually unneccessary, as while - //initalizing the quant_combobox, this gets - //called again. but for safety... - set_pixels_per_whole(300); //same as above. but safety rocks + _quant_power2=_quant_power2_init; // ScoreEdit relies on this to be done! + _pixels_per_whole_init = _pixels_per_whole_init; - set_velo(64); - set_velo_off(64); + note_velo=note_velo_init; + note_velo_off_init=note_velo_off_init; dragging_staff=false; - coloring_mode=COLOR_MODE_BLACK; - preamble_contains_keysig=true; - preamble_contains_timesig=true; + coloring_mode=coloring_mode_init; + preamble_contains_keysig=preamble_contains_keysig_init; + preamble_contains_timesig=preamble_contains_timesig_init; x_scroll_speed=0; @@ -1455,7 +1518,7 @@ void ScoreCanvas::song_changed(int flags) { if(parent && parent->deleting()) // Ignore while while deleting to prevent crash. return; - + if (flags & (SC_PART_MODIFIED | SC_PART_REMOVED | SC_PART_INSERTED | SC_TRACK_REMOVED)) { update_parts(); @@ -1534,7 +1597,7 @@ void color_image(QImage& img, const QColor& color) { uchar* ptr=img.bits(); //int bytes=img.byteCount(); - int bytes=img.bytesPerLine() * img.height(); // By Tim. For older Qt versions. Tested OK on Qt4.5. + int bytes=img.bytesPerLine() * img.height(); // By Tim. For older Qt versions. Tested OK on Qt4.5. int r,g,b; color.getRgb(&r,&g,&b); @@ -4280,16 +4343,16 @@ void ScoreCanvas::menu_command(int cmd) { switch (cmd) { - case CMD_COLOR_BLACK: coloring_mode=COLOR_MODE_BLACK; redraw(); break; - case CMD_COLOR_PART: coloring_mode=COLOR_MODE_PART; redraw(); break; - case CMD_COLOR_VELO: coloring_mode=COLOR_MODE_VELO; redraw(); break; - case CMD_NOTELEN_1: new_len=TICKS_PER_WHOLE/ 1; break; - case CMD_NOTELEN_2: new_len=TICKS_PER_WHOLE/ 2; break; - case CMD_NOTELEN_4: new_len=TICKS_PER_WHOLE/ 4; break; - case CMD_NOTELEN_8: new_len=TICKS_PER_WHOLE/ 8; break; - case CMD_NOTELEN_16: new_len=TICKS_PER_WHOLE/16; break; - case CMD_NOTELEN_32: new_len=TICKS_PER_WHOLE/32; break; - case CMD_NOTELEN_LAST: new_len=-1; break; + case CMD_COLOR_BLACK: coloring_mode_init=coloring_mode=COLOR_MODE_BLACK; redraw(); break; + case CMD_COLOR_PART: coloring_mode_init=coloring_mode=COLOR_MODE_PART; redraw(); break; + case CMD_COLOR_VELO: coloring_mode_init=coloring_mode=COLOR_MODE_VELO; redraw(); break; + case CMD_NOTELEN_1: new_len_init= 1; new_len=TICKS_PER_WHOLE/ 1; break; + case CMD_NOTELEN_2: new_len_init= 2; new_len=TICKS_PER_WHOLE/ 2; break; + case CMD_NOTELEN_4: new_len_init= 4; new_len=TICKS_PER_WHOLE/ 4; break; + case CMD_NOTELEN_8: new_len_init= 8; new_len=TICKS_PER_WHOLE/ 8; break; + case CMD_NOTELEN_16: new_len_init=16; new_len=TICKS_PER_WHOLE/16; break; + case CMD_NOTELEN_32: new_len_init=32; new_len=TICKS_PER_WHOLE/32; break; + case CMD_NOTELEN_LAST: new_len_init= 0; new_len=-1; break; default: cerr << "ERROR: ILLEGAL FUNCTION CALL: ScoreCanvas::menu_command called with unknown command ("<=0) && (val=0) && (val<5)) { int old_len=quant_len(); - _quant_power2=quant_mapper[val]; + _quant_power2=val+1; + _quant_power2_init=_quant_power2; set_pixels_per_whole(pixels_per_whole() * quant_len() / old_len ); @@ -4342,6 +4406,7 @@ void ScoreCanvas::set_pixels_per_whole(int val) // zero!) _pixels_per_whole=val; + _pixels_per_whole_init=val; for (list::iterator it=staves.begin(); it!=staves.end(); it++) it->calc_item_pos(); @@ -4383,6 +4448,7 @@ void ScoreCanvas::maybe_close_if_empty() void ScoreCanvas::set_velo(int velo) { note_velo=velo; + note_velo_init=velo; if (parent->get_apply_velo()) modify_velocity(get_all_parts(),1, 0,velo); @@ -4391,6 +4457,7 @@ void ScoreCanvas::set_velo(int velo) void ScoreCanvas::set_velo_off(int velo) { note_velo_off=velo; + note_velo_off_init=velo; if (parent->get_apply_velo()) modify_off_velocity(get_all_parts(),1, 0,velo); @@ -4586,24 +4653,23 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set o when changing toolbarstate when sharing and immediately after that * changing "share" status, the changed state isn't stored + * (could be solved by storing the current window when quitting/saving whatever) * ? pasting in editors sometimes fails oO? ( ERROR: reading eventlist * from clipboard failed. ignoring this one... ) [ not reproducible ] - * > o non-mdi topwin states aren't restored when launching muse2 somefile.med * ! o using super glue while a score editor displaying the glued parts * is open lets muse segfault. this may or may not be fixed in * the release branch :/ * * CURRENT TODO * > o fix valgrind problems (the two "FINDMICHJETZT" lines in scoreedit.cpp) - * > o newly created windows have to be focussed! + * > o add a songposition scrollbar-toolbar (in different sizes) + * this might be equivalent to "redo transport menu" (below). + * > o add toolbar(s) for tempo- etc spinboxes from the transport window * * IMPORTANT TODO + * o support edge-scrolling when opening a lasso * o add "dotted quarter" quantize option (for 6/8 beat) * o ticks-to-quarter spinboxes * o mirror most menus to an additional right-click context menu to avoid the long mouse pointer @@ -4628,6 +4694,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set::iterator dest, list::iterator src); void cleanup_staves(); void maybe_close_if_empty(); - + +// defaults ---------------------------------------------------------- + public: + enum coloring_mode_t {COLOR_MODE_BLACK, COLOR_MODE_PART, COLOR_MODE_VELO}; + static int _quant_power2_init; + static int _pixels_per_whole_init; + static int note_velo_init, note_velo_off_init; + static int new_len_init; + static coloring_mode_t coloring_mode_init; + static bool preamble_contains_timesig_init; + static bool preamble_contains_keysig_init; + // member variables --------------------------------------------------- + private: int _quant_power2; int _pixels_per_whole; @@ -746,7 +758,7 @@ class ScoreCanvas : public MusEGui::View bool srec; bool held_notes[128]; - enum {COLOR_MODE_BLACK, COLOR_MODE_PART, COLOR_MODE_VELO} coloring_mode; + coloring_mode_t coloring_mode; bool preamble_contains_keysig; bool preamble_contains_timesig; @@ -776,38 +788,38 @@ class ScoreCanvas : public MusEGui::View void add_new_parts(const std::map< MusECore::Part*, std::set >&); - public slots: - void x_scroll_event(int); - void y_scroll_event(int); - void song_changed(int); - void fully_recalculate(); - void goto_tick(int,bool); - void pos_changed(int i, unsigned u, bool b); - void heartbeat_timer_event(); - - void set_tool(int); - void set_quant(int); - void menu_command(int); - void preamble_keysig_slot(bool); - void preamble_timesig_slot(bool); - void set_pixels_per_whole(int); + public slots: + void x_scroll_event(int); + void y_scroll_event(int); + void song_changed(int); + void fully_recalculate(); + void goto_tick(int,bool); + void pos_changed(int i, unsigned u, bool b); + void heartbeat_timer_event(); - void set_velo(int); - void set_velo_off(int); + void set_tool(int); + void set_quant(int); + void menu_command(int); + void preamble_keysig_slot(bool); + void preamble_timesig_slot(bool); + void set_pixels_per_whole(int); - void set_steprec(bool); - - void update_parts(); //re-populates the sets from the sets + void set_velo(int); + void set_velo_off(int); + + void set_steprec(bool); + + void update_parts(); //re-populates the sets from the sets signals: - void xscroll_changed(int); - void yscroll_changed(int); - void viewport_width_changed(int); - void canvas_width_changed(int); - void preamble_width_changed(int); - void viewport_height_changed(int); - void canvas_height_changed(int); - void pixels_per_whole_changed(int); - void pos_add_changed(); + void xscroll_changed(int); + void yscroll_changed(int); + void viewport_width_changed(int); + void canvas_width_changed(int); + void preamble_width_changed(int); + void viewport_height_changed(int); + void canvas_height_changed(int); + void pixels_per_whole_changed(int); + void pos_add_changed(); protected: virtual void draw(QPainter& p, const QRect& rect); diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp index 19fef51b..b7d1d7b7 100644 --- a/muse2/muse/midiport.cpp +++ b/muse2/muse/midiport.cpp @@ -332,8 +332,8 @@ QMenu* midiPortsPopup(QWidget* parent, int checkPort) { MusECore::MidiDevice* md = MusEGlobal::midiPorts[pi].device(); //if(md && !md->isSynti() && (md->rwFlags() & 1)) - //if(md && (md->rwFlags() & 1)) - if(md && (md->rwFlags() & 1 || md->isSynti()) ) + if(md && (md->rwFlags() & 1)) + //if(md && (md->rwFlags() & 1 || md->isSynti()) ) // Revert. Hm, why synths? Only writeable ports. p4.0.41 break; } if(pi == MIDI_PORTS) @@ -352,8 +352,12 @@ QMenu* midiPortsPopup(QWidget* parent, int checkPort) for (int i = 0; i < MIDI_PORTS; ++i) { MidiPort* port = &MusEGlobal::midiPorts[i]; + MusECore::MidiDevice* md = port->device(); + //if(md && !(md->rwFlags() & 1 || md->isSynti()) && (i != checkPort)) + if(md && !(md->rwFlags() & 1) && (i != checkPort)) // Only writeable ports, or current one. + continue; name.sprintf("%d:%s", port->portno()+1, port->portname().toLatin1().constData()); - if(port->device() || (i == checkPort)) + if(md || (i == checkPort)) { act = p->addAction(name); act->setData(i); @@ -361,7 +365,7 @@ QMenu* midiPortsPopup(QWidget* parent, int checkPort) act->setChecked(i == checkPort); } - if(!port->device()) + if(!md) { if(!subp) // No submenu yet? Create it now. { diff --git a/muse2/muse/midiseq.cpp b/muse2/muse/midiseq.cpp index e31db7c7..1e46db11 100644 --- a/muse2/muse/midiseq.cpp +++ b/muse2/muse/midiseq.cpp @@ -44,6 +44,7 @@ #include "synth.h" #include "song.h" #include "gconfig.h" +#include namespace MusEGlobal { MusECore::MidiSeq* midiSeq; @@ -54,6 +55,12 @@ namespace MusECore { int MidiSeq::ticker = 0; +void initMidiSequencer() +{ + //MusEGlobal::midiSeq = new MidiSeq(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0, "Midi"); + MusEGlobal::midiSeq = new MidiSeq("Midi"); +} + //--------------------------------------------------------- // readMsg //--------------------------------------------------------- @@ -819,16 +826,16 @@ void MidiSeq::msgMsg(int id) void MidiSeq::msgSetMidiDevice(MidiPort* port, MidiDevice* device) { - MusECore::AudioMsg msg; - msg.id = MusECore::SEQM_IDLE; - msg.a = true; - Thread::sendMsg(&msg); - - port->setMidiDevice(device); + MusECore::AudioMsg msg; + msg.id = MusECore::SEQM_IDLE; + msg.a = true; + Thread::sendMsg(&msg); + + port->setMidiDevice(device); - msg.id = MusECore::SEQM_IDLE; - msg.a = false; - Thread::sendMsg(&msg); + msg.id = MusECore::SEQM_IDLE; + msg.a = false; + Thread::sendMsg(&msg); } // This does not appear to be used anymore. Was called in Audio::process1, now Audio::processMidi is called directly. p4.0.15 Tim. diff --git a/muse2/muse/mixer/amixer.cpp b/muse2/muse/mixer/amixer.cpp index 731af9a4..439a92b9 100644 --- a/muse2/muse/mixer/amixer.cpp +++ b/muse2/muse/mixer/amixer.cpp @@ -169,7 +169,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MusEGlobal::MixerConfig* c) setWindowIcon(*museIcon); QMenu* menuConfig = menuBar()->addMenu(tr("&Create")); - MusEGui::populateAddTrack(menuConfig); + MusEGui::populateAddTrack(menuConfig,true); connect(menuConfig, SIGNAL(triggered(QAction *)), MusEGlobal::song, SLOT(addNewTrack(QAction *))); QMenu* menuView = menuBar()->addMenu(tr("&View")); diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp index 10f281fb..9c393a1a 100644 --- a/muse2/muse/mixer/astrip.cpp +++ b/muse2/muse/mixer/astrip.cpp @@ -147,6 +147,7 @@ void AudioStrip::songChanged(int val) // Set the strip label's font. //label->setFont(MusEGlobal::config.fonts[1]); setLabelFont(); + setLabelText(); // Adjust minimum volume slider and label values. slider->setRange(MusEGlobal::config.minSlider-0.1, 10.0); @@ -203,7 +204,17 @@ void AudioStrip::songChanged(int val) pre->setChecked(src->prefader()); pre->blockSignals(false); } - } + + // Are there any Aux Track routing paths to this track? Then we cannot process aux for this track! + // Hate to do this, but as a quick visual reminder, seems most logical to disable Aux knobs and labels. + int rc = track->auxRefCount(); + int n = auxKnob.size(); + for (int idx = 0; idx < n; ++idx) + { + auxKnob[idx]->setEnabled( rc == 0 ); + auxLabel[idx]->setEnabled( rc == 0 ); + } + } if (val & SC_AUX) { int n = auxKnob.size(); for (int idx = 0; idx < n; ++idx) { @@ -333,11 +344,14 @@ void AudioStrip::updateOffState() stereo->setEnabled(val); label->setEnabled(val); + // Are there any Aux Track routing paths to this track? Then we cannot process aux for this track! + // Hate to do this, but as a quick visual reminder, seems most logical to disable Aux knobs and labels. + bool ae = track->auxRefCount() == 0 && val; int n = auxKnob.size(); for (int i = 0; i < n; ++i) { - auxKnob[i]->setEnabled(val); - auxLabel[i]->setEnabled(val); + auxKnob[i]->setEnabled(ae); + auxLabel[i]->setEnabled(ae); } if (pre) @@ -348,12 +362,12 @@ void AudioStrip::updateOffState() solo->setEnabled(val); if (mute) mute->setEnabled(val); - if (autoType) - autoType->setEnabled(val); - if (iR) - iR->setEnabled(val); - if (oR) - oR->setEnabled(val); + //if (autoType) + // autoType->setEnabled(val); + //if (iR) + // iR->setEnabled(val); + //if (oR) + // oR->setEnabled(val); if (off) { off->blockSignals(true); off->setChecked(track->off()); @@ -799,6 +813,12 @@ AudioStrip::AudioStrip(QWidget* parent, MusECore::AudioTrack* at) double val = MusECore::fast_log10(t->auxSend(idx))*20.0; ak->setValue(val); al->setValue(val); + + // Are there any Aux Track routing paths to this track? Then we cannot process aux for this track! + // Hate to do this, but as a quick visual reminder, seems most logical to disable Aux knobs and labels. + int rc = track->auxRefCount(); + ak->setEnabled( rc == 0 ); + al->setEnabled( rc == 0 ); } } else { diff --git a/muse2/muse/mixer/mstrip.cpp b/muse2/muse/mixer/mstrip.cpp index 2e51feb9..dc495aa6 100644 --- a/muse2/muse/mixer/mstrip.cpp +++ b/muse2/muse/mixer/mstrip.cpp @@ -448,9 +448,8 @@ void MidiStrip::updateOffState() // TODO: Disabled for now. //if (autoType) // autoType->setEnabled(val); - if (iR) - iR->setEnabled(val); - // TODO: Disabled for now. + //if (iR) + // iR->setEnabled(val); //if (oR) // oR->setEnabled(val); if (off) { @@ -504,6 +503,7 @@ void MidiStrip::songChanged(int val) // Set the strip label's font. //label->setFont(MusEGlobal::config.fonts[1]); setLabelFont(); + setLabelText(); } } diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp index b87c4629..c26a9a15 100644 --- a/muse2/muse/mixer/strip.cpp +++ b/muse2/muse/mixer/strip.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "globals.h" #include "gconfig.h" @@ -161,7 +163,8 @@ void Strip::setLabelText() //gradient.setColorAt(0, c.darker()); //gradient.setColorAt(0, c); //gradient.setColorAt(1, c.darker()); - gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(0, c); + gradient.setColorAt(0.5, c.lighter()); gradient.setColorAt(1, c); //palette.setBrush(QPalette::Button, gradient); //palette.setBrush(QPalette::Window, gradient); @@ -303,6 +306,23 @@ void Strip::resizeEvent(QResizeEvent* ev) setLabelText(); setLabelFont(); } - + +void Strip::mousePressEvent(QMouseEvent* ev) +{ + if (ev->button() == Qt::RightButton) { + QMenu* menu = new QMenu; + menu->addAction(tr("Remove track?")); + QPoint pt = QCursor::pos(); + QAction* act = menu->exec(pt, 0); + if (!act) + { + delete menu; + return; + } + MusEGlobal::song->removeTrack0(track); + MusEGlobal::audio->msgUpdateSoloStates(); + } +} + } // namespace MusEGui diff --git a/muse2/muse/mixer/strip.h b/muse2/muse/mixer/strip.h index 5b3b541b..d0cde1a6 100644 --- a/muse2/muse/mixer/strip.h +++ b/muse2/muse/mixer/strip.h @@ -73,6 +73,7 @@ class Strip : public QFrame { MusEGui::ComboBox* autoType; void setLabelText(); virtual void resizeEvent(QResizeEvent*); + virtual void mousePressEvent(QMouseEvent *); private slots: void recordToggled(bool); diff --git a/muse2/muse/node.cpp b/muse2/muse/node.cpp index dd41ba10..cb77f939 100644 --- a/muse2/muse/node.cpp +++ b/muse2/muse/node.cpp @@ -4,6 +4,7 @@ // $Id: node.cpp,v 1.36.2.25 2009/12/20 05:00:35 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -25,6 +26,8 @@ #include #include +#include + #include "node.h" #include "globals.h" #include "gconfig.h" @@ -44,7 +47,6 @@ //#define NODE_DEBUG //#define FIFO_DEBUG -// Added by Tim. p3.3.18 //#define METRONOME_DEBUG namespace MusECore { @@ -162,10 +164,19 @@ void Track::updateInternalSoloStates() void MidiTrack::updateInternalSoloStates() { - if(this == _tmpSoloChainTrack) - return; - - Track::updateInternalSoloStates(); + if(_nodeTraversed) // Anti circular mechanism. + { + fprintf(stderr, "MidiTrack::updateInternalSoloStates %s :\n MusE Warning: Please check your routes: Circular path found!\n", name().toLatin1().constData()); + return; + } + //if(this == _tmpSoloChainTrack) + // return; + + _nodeTraversed = true; + + Track::updateInternalSoloStates(); + + _nodeTraversed = false; // Reset. } @@ -175,40 +186,61 @@ void MidiTrack::updateInternalSoloStates() void AudioTrack::updateInternalSoloStates() { - if(this == _tmpSoloChainTrack) - return; - - Track::updateInternalSoloStates(); - - if(_tmpSoloChainDoIns) + if(_nodeTraversed) // Anti circular mechanism. + { + fprintf(stderr, "AudioTrack::updateInternalSoloStates %s :\n MusE Warning: Please check your routes: Circular path found!\n", name().toLatin1().constData()); + return; + } + //if(this == _tmpSoloChainTrack) + // return; + + _nodeTraversed = true; + + Track::updateInternalSoloStates(); + + if(_tmpSoloChainDoIns) + { + if(type() == AUDIO_SOFTSYNTH) + { + const MusECore::MidiTrackList* ml = MusEGlobal::song->midis(); + for(MusECore::ciMidiTrack im = ml->begin(); im != ml->end(); ++im) { - if(type() == AUDIO_SOFTSYNTH) - { - const MusECore::MidiTrackList* ml = MusEGlobal::song->midis(); - for(MusECore::ciMidiTrack im = ml->begin(); im != ml->end(); ++im) - { - MusECore::MidiTrack* mt = *im; - if(mt->outPort() >= 0 && mt->outPort() == ((SynthI*)this)->midiPort()) - mt->updateInternalSoloStates(); - } - } - - const RouteList* rl = inRoutes(); - for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir) - { - if(ir->type == Route::TRACK_ROUTE) - ir->track->updateInternalSoloStates(); - } + MusECore::MidiTrack* mt = *im; + if(mt->outPort() >= 0 && mt->outPort() == ((SynthI*)this)->midiPort()) + mt->updateInternalSoloStates(); } - else - { - const RouteList* rl = outRoutes(); - for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir) + } + + const RouteList* rl = inRoutes(); + for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir) + { + if(ir->type == Route::TRACK_ROUTE) + ir->track->updateInternalSoloStates(); + else + // Support Midi Port -> Audio Input solo chains. p4.0.37 Tim. + if(ir->type == Route::MIDI_PORT_ROUTE) + { + const MidiTrackList* ml = MusEGlobal::song->midis(); + for(ciMidiTrack im = ml->begin(); im != ml->end(); ++im) { - if(ir->type == Route::TRACK_ROUTE) - ir->track->updateInternalSoloStates(); + MidiTrack* mt = *im; + if(mt->outPort() == ir->midiPort && ((1 << mt->outChannel()) & ir->channel) ) + mt->updateInternalSoloStates(); } - } + } + } + } + else + { + const RouteList* rl = outRoutes(); + for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir) + { + if(ir->type == Route::TRACK_ROUTE) + ir->track->updateInternalSoloStates(); + } + } + + _nodeTraversed = false; // Reset. } @@ -221,6 +253,8 @@ void MidiTrack::updateSoloStates(bool noDec) if(noDec && !_solo) return; + _nodeTraversed = true; // Anti circular mechanism. + _tmpSoloChainTrack = this; _tmpSoloChainDoIns = false; _tmpSoloChainNoDec = noDec; @@ -244,6 +278,8 @@ void MidiTrack::updateSoloStates(bool noDec) } } } + + _nodeTraversed = false; // Reset. } @@ -256,6 +292,8 @@ void AudioTrack::updateSoloStates(bool noDec) if(noDec && !_solo) return; + _nodeTraversed = true; // Anti circular mechanism. + _tmpSoloChainTrack = this; _tmpSoloChainNoDec = noDec; updateSoloState(); @@ -301,6 +339,8 @@ void AudioTrack::updateSoloStates(bool noDec) ir->track->updateInternalSoloStates(); } } + + _nodeTraversed = false; // Reset. } @@ -327,7 +367,6 @@ void Track::setOff(bool val) // copyData //--------------------------------------------------------- -//void AudioTrack::copyData(unsigned pos, int dstChannels, unsigned nframes, float** dstBuffer) void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int srcChannels, unsigned nframes, float** dstBuffer) { //Changed by T356. 12/12/09. @@ -336,60 +375,51 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s // Make better use of AudioTrack::outBuffers as a post-effect pre-volume cache system for multiple calls here during processing. // Previously only WaveTrack used them. (Changed WaveTrack as well). + #ifdef NODE_DEBUG + printf("MusE: AudioTrack::copyData name:%s processed:%d\n", name().toLatin1().constData(), processed()); + #endif + if(srcStartChan == -1) srcStartChan = 0; - int srcChans = (srcChannels == -1) ? channels() : srcChannels; + int trackChans = channels(); + int srcChans = (srcChannels == -1) ? trackChans : srcChannels; int srcTotalOutChans = totalOutChannels(); if(channels() == 1) srcTotalOutChans = 1; - #ifdef NODE_DEBUG - printf("MusE: AudioTrack::copyData name:%s processed:%d\n", name().toLatin1().constData(), processed()); - #endif - // Special consideration for metronome: It is not part of the track list, // and it has no in or out routes, yet multiple output tracks may call addData on it ! // We can't tell how many output tracks call it, so we can only assume there might be more than one. // Not strictly necessary here because only addData is ever called, but just to be consistent... - //bool usedirectbuf = (outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT); - bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome); + //bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome); int i; - // p3.3.38 - //float* buffer[srcChannels]; float* buffer[srcTotalOutChans]; + float data[nframes * srcTotalOutChans]; - - //float data[nframes * srcChannels]; - //for(i = 0; i < srcChannels; ++i) - // buffer[i] = data + i * nframes; - // precalculate stereo volume double vol[2]; double _volume = volume(); double _pan = pan(); vol[0] = _volume * (1.0 - _pan); vol[1] = _volume * (1.0 + _pan); - float meter[srcChans]; + float meter[trackChans]; // Have we been here already during this process cycle? if(processed()) { // If there is only one (or no) output routes, it's an error - we've been called more than once per process cycle! + // No, this is no longer an error, it's deliberate. Processing no longer done in 'chains', now done randomly. p4.0.37 #ifdef NODE_DEBUG - if(usedirectbuf) - printf("MusE: AudioTrack::copyData Error! One or no out routes, but already processed! Copying local buffers anyway...\n"); + printf("MusE: AudioTrack::copyData name:%s already processed _haveData:%d\n", name().toLatin1().constData(), _haveData); #endif // Is there already some data gathered from a previous call during this process cycle? if(_haveData) { // Point the input buffers at our local cached 'pre-volume' buffers. They need processing, so continue on after. - //for(i = 0; i < srcChannels; ++i) - // buffer[i] = outBuffers[i]; - // p3.3.38 for(i = 0; i < srcTotalOutChans; ++i) buffer[i] = outBuffers[i]; } @@ -413,29 +443,16 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s { // First time here during this process cycle. - // Point the input buffers at a temporary stack buffer. - //float data[nframes * srcChannels]; - //for(i = 0; i < srcChannels; ++i) - // buffer[i] = data + i * nframes; - // p3.3.38 - float data[nframes * srcTotalOutChans]; - for(i = 0; i < srcTotalOutChans; ++i) - buffer[i] = data + i * nframes; - - // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc. - // For ex. if this is an audio input, Jack will set the pointers for us in AudioInput::getData! - // p3.3.29 1/27/10 Don't do any processing at all if off. Whereas, mute needs to be ready for action at all times, - // so still call getData before it. Off is NOT meant to be toggled rapidly, but mute is ! - //if(!getData(pos, srcChannels, nframes, buffer) || off() || (isMute() && !_prefader)) - //if(off() || !getData(pos, srcChannels, nframes, buffer) || (isMute() && !_prefader)) - // p3.3.38 - if(off() || !getData(pos, srcTotalOutChans, nframes, buffer) || (isMute() && !_prefader)) - { + _haveData = false; // Reset. + _processed = true; // Set this now. + + if(off()) + { #ifdef NODE_DEBUG - printf("MusE: AudioTrack::copyData name:%s dstChannels:%d zeroing buffers\n", name().toLatin1().constData(), dstChannels); + printf("MusE: AudioTrack::copyData name:%s dstChannels:%d Off, zeroing buffers\n", name().toLatin1().constData(), dstChannels); #endif - // No data was available. Zero the supplied buffers. + // Track is off. Zero the supplied buffers. unsigned int q; for(i = 0; i < dstChannels; ++i) { @@ -448,13 +465,12 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s memset(dstBuffer[i], 0, sizeof(float) * nframes); } - for(i = 0; i < srcChans; ++i) + _efxPipe->apply(0, nframes, 0); // Just process controls only, not audio (do not 'run'). + + for(i = 0; i < trackChans; ++i) { - //_meter[i] = 0; _meter[i] = 0.0; - - /* - if(!usedirectbuf) + /*if(!usedirectbuf) { if(MusEGlobal::config.useDenormalBias) { @@ -463,22 +479,49 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s } else memset(outBuffers[i], 0, sizeof(float) * nframes); - } - */ + } */ } - _haveData = false; - _processed = true; + //_haveData = false; + //_processed = true; + //_isProcessing = false; // Unblock. return; } + + // Point the input buffers at a temporary stack buffer. + for(i = 0; i < srcTotalOutChans; ++i) + buffer[i] = data + i * nframes; + + // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc. + // For ex. if this is an audio input, Jack will set the pointers for us in AudioInput::getData! + // Don't do any processing at all if off. Whereas, mute needs to be ready for action at all times, + // so still call getData before it. Off is NOT meant to be toggled rapidly, but mute is ! + if(!getData(pos, srcTotalOutChans, nframes, buffer) || (isMute() && !_prefader)) + { + #ifdef NODE_DEBUG + printf("MusE: AudioTrack::copyData name:%s srcTotalOutChans:%d zeroing buffers\n", name().toLatin1().constData(), srcTotalOutChans); + #endif + + // No data was available. Track is not off. Zero the working buffers and continue on. + unsigned int q; + for(i = 0; i < srcTotalOutChans; ++i) + { + if(MusEGlobal::config.useDenormalBias) + { + for(q = 0; q < nframes; ++q) + buffer[i][q] = MusEGlobal::denormalBias; + } + else + memset(buffer[i], 0, sizeof(float) * nframes); + } + } //--------------------------------------------------- // apply plugin chain //--------------------------------------------------- - // p3.3.41 //fprintf(stderr, "AudioTrack::copyData %s efx apply srcChans:%d\n", name().toLatin1().constData(), srcChans); - _efxPipe->apply(srcChans, nframes, buffer); + _efxPipe->apply(trackChans, nframes, buffer); //--------------------------------------------------- // aux sends @@ -525,18 +568,16 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s if(_prefader) { - for(i = 0; i < srcChans; ++i) + for(i = 0; i < trackChans; ++i) { float* p = buffer[i]; meter[i] = 0.0; for(unsigned k = 0; k < nframes; ++k) { - double f = fabs(*p); + double f = fabs(*p++); if(f > meter[i]) meter[i] = f; - ++p; } - //_meter[i] = lrint(meter[i] * 32767.0); _meter[i] = meter[i]; if(_meter[i] > _peak[i]) _peak[i] = _meter[i]; @@ -570,20 +611,19 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s else memset(outBuffers[i], 0, sizeof(float) * nframes); } - } - */ + } */ + - _haveData = false; - _processed = true; + if(!_prefader) + for(i = 0; i < trackChans; ++i) // Must process ALL channels, even if unconnected. Only max 2 channels. + _meter[i] = 0.0; + return; } // If we're using local cached 'pre-volume' buffers, copy the input buffers (as they are right now: post-effect pre-volume) back to them. - if(!usedirectbuf) + //if(!usedirectbuf) { - //for(i = 0; i < srcChannels; ++i) - // AL::dsp->cpy(outBuffers[i], buffer[i], nframes); - // p3.3.38 for(i = 0; i < srcTotalOutChans; ++i) AL::dsp->cpy(outBuffers[i], buffer[i], nframes); } @@ -606,9 +646,9 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s else memset(dstBuffer[i], 0, sizeof(float) * nframes); } - _processed = true; return; } + // Force a source range to fit actual available total out channels. if((srcStartChan + srcChans) > srcTotalOutChans) srcChans = srcTotalOutChans - srcStartChan; @@ -618,132 +658,94 @@ void AudioTrack::copyData(unsigned pos, int dstChannels, int srcStartChan, int s // postfader metering //--------------------------------------------------- - - if(srcChans == dstChannels) + #ifdef NODE_DEBUG + printf("MusE: AudioTrack::copyData trackChans:%d srcTotalOutChans:%d srcStartChan:%d srcChans:%d dstChannels:%d\n", trackChans, srcTotalOutChans, srcStartChan, srcChans, dstChannels); + #endif + + if(!_prefader) { - if(_prefader) + for(int c = 0; c < trackChans; ++c) { - for(int c = 0; c < dstChannels; ++c) + meter[c] = 0.0; + double v = (trackChans == 1 ? _volume : vol[c]); + float* sp = buffer[c]; + for(unsigned k = 0; k < nframes; ++k) { - // p3.3.38 - //float* sp = buffer[c]; - float* sp = buffer[c + srcStartChan]; - - float* dp = dstBuffer[c]; - for(unsigned k = 0; k < nframes; ++k) - *dp++ = (*sp++ * vol[c]); + float val = *sp++ * v; // If the track is mono pan has no effect on meters. + double f = fabs(val); + if(f > meter[c]) + meter[c] = f; } - } - else + _meter[c] = meter[c]; + if(_meter[c] > _peak[c]) + _peak[c] = _meter[c]; + } + } + + if(srcChans == dstChannels) + { + for(int c = 0; c < dstChannels; ++c) { - for(int c = 0; c < dstChannels; ++c) - { - meter[c] = 0.0; - - // p3.3.38 - //float* sp = buffer[c]; - float* sp = buffer[c + srcStartChan]; - - float* dp = dstBuffer[c]; - //printf("2 dstBuffer[c]=%d\n",long(dstBuffer[c])); - for(unsigned k = 0; k < nframes; ++k) - { - float val = *sp++ * vol[c]; - *dp++ = val; - double f = fabs(val); - if(f > meter[c]) - meter[c] = f; - } - //_meter[c] = lrint(meter[c] * 32767.0); - _meter[c] = meter[c]; - if(_meter[c] > _peak[c]) - _peak[c] = _meter[c]; - } + double v; + if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2. + //v = _volume; + v = 1.0; + else + if(srcChans >= 2) // If 2 channels apply pan normally. + v = vol[c]; + else + if(trackChans < 2) // If 1 channel and track is 1 channel, don't apply pan. + v = _volume; + else + v = vol[srcStartChan]; // Otherwise 1 channel but track is 2 channels. Apply the channel volume. + + float* sp = buffer[c + srcStartChan]; + float* dp = dstBuffer[c]; + for(unsigned k = 0; k < nframes; ++k) + //*dp++ = (*sp++ * vol[c]); + *dp++ = (*sp++ * v); } } else if(srcChans == 1 && dstChannels == 2) { - // p3.3.38 - //float* sp = buffer[0]; - float* sp = buffer[srcStartChan]; - - if(_prefader) + for(int c = 0; c < dstChannels; ++c) { - for(int c = 0; c < dstChannels; ++c) - { - float* dp = dstBuffer[c]; - for(unsigned k = 0; k < nframes; ++k) - *dp++ = (*sp++ * vol[c]); - } - } - else - { - meter[0] = 0.0; - for(unsigned k = 0; k < nframes; ++k) - { - float val = *sp++; - double f = fabs(val) * _volume; - if(f > meter[0]) - meter[0] = f; - *(dstBuffer[0] + k) = val * vol[0]; - *(dstBuffer[1] + k) = val * vol[1]; - } - //_meter[0] = lrint(meter[0] * 32767.0); - _meter[0] = meter[0]; - if(_meter[0] > _peak[0]) - _peak[0] = _meter[0]; + double v; + if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2. + //v = _volume; + v = 1.0; + else + if(trackChans <= 1) // If track is mono apply pan. + v = vol[c]; + else + v = vol[srcStartChan]; // Otherwise track is stereo, apply the same channel volume to both. + + float* sp = buffer[srcStartChan]; + float* dp = dstBuffer[c]; + for(unsigned k = 0; k < nframes; ++k) + //*dp++ = (*sp++ * vol[c]); + *dp++ = (*sp++ * v); } } else if(srcChans == 2 && dstChannels == 1) { - // p3.3.38 - //float* sp1 = buffer[0]; - //float* sp2 = buffer[1]; + //double v1 = (srcStartChan > 2 ? _volume : vol[srcStartChan]); // Don't apply pan to extra channels above 2. + //double v2 = (srcStartChan > 2 ? _volume : vol[srcStartChan + 1]); // + double v1 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan]); // Don't apply pan or volume to extra channels above 2. + double v2 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan + 1]); // + float* dp = dstBuffer[0]; float* sp1 = buffer[srcStartChan]; float* sp2 = buffer[srcStartChan + 1]; - - if(_prefader) - { - float* dp = dstBuffer[0]; - for(unsigned k = 0; k < nframes; ++k) - *dp++ = (*sp1++ * vol[0] + *sp2++ * vol[1]); - } - else - { - float* dp = dstBuffer[0]; - meter[0] = 0.0; - meter[1] = 0.0; - for(unsigned k = 0; k < nframes; ++k) - { - float val1 = *sp1++ * vol[0]; - float val2 = *sp2++ * vol[1]; - double f1 = fabs(val1); - if(f1 > meter[0]) - meter[0] = f1; - double f2 = fabs(val2); - if(f2 > meter[1]) - meter[1] = f2; - *dp++ = (val1 + val2); - } - //_meter[0] = lrint(meter[0] * 32767.0); - _meter[0] = meter[0]; - if(_meter[0] > _peak[0]) - _peak[0] = _meter[0]; - //_meter[1] = lrint(meter[1] * 32767.0); - _meter[1] = meter[1]; - if(_meter[1] > _peak[1]) - _peak[1] = _meter[1]; - } + for(unsigned k = 0; k < nframes; ++k) + //*dp++ = (*sp1++ * vol[0] + *sp2++ * vol[1]); + *dp++ = (*sp1++ * v1 + *sp2++ * v2); } - - _processed = true; } //--------------------------------------------------------- // addData //--------------------------------------------------------- -//void AudioTrack::addData(unsigned pos, int dstChannels, unsigned nframes, float** dstBuffer) void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int srcChannels, unsigned nframes, float** dstBuffer) { //Changed by T356. 12/12/09. @@ -752,21 +754,21 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr // Make better use of AudioTrack::outBuffers as a post-effect pre-volume cache system for multiple calls here during processing. // Previously only WaveTrack used them. (Changed WaveTrack as well). - //Added by Tim. p3.3.16 #ifdef NODE_DEBUG printf("MusE: AudioTrack::addData name:%s processed:%d\n", name().toLatin1().constData(), processed()); #endif - if (off()) - { - _processed = true; - return; - } + //if (off()) + //{ + // _processed = true; + // return; + //} if(srcStartChan == -1) srcStartChan = 0; - int srcChans = (srcChannels == -1) ? channels() : srcChannels; + int trackChans = channels(); + int srcChans = (srcChannels == -1) ? trackChans : srcChannels; int srcTotalOutChans = totalOutChannels(); if(channels() == 1) srcTotalOutChans = 1; @@ -774,18 +776,12 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr // Special consideration for metronome: It is not part of the track list, // and it has no in or out routes, yet multiple output tracks may call addData on it ! // We can't tell how many output tracks call it, so we can only assume there might be more than one. - //bool usedirectbuf = (outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT); - bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome); + //bool usedirectbuf = ((outRoutes()->size() <= 1) || (type() == AUDIO_OUTPUT)) && (this != metronome); int i; - // p3.3.38 - //float* buffer[srcChannels]; float* buffer[srcTotalOutChans]; - - //float data[nframes * srcChannels]; - //for (i = 0; i < srcChannels; ++i) - // buffer[i] = data + i * nframes; + float data[nframes * srcTotalOutChans]; // precalculate stereo volume double vol[2]; @@ -793,105 +789,96 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr double _pan = pan(); vol[0] = _volume * (1.0 - _pan); vol[1] = _volume * (1.0 + _pan); - float meter[srcChans]; + //float meter[srcChans]; + float meter[trackChans]; // Have we been here already during this process cycle? if(processed()) { // If there is only one (or no) output routes, it's an error - we've been called more than once per process cycle! + // No, this is no longer an error, it's deliberate. Processing no longer done in 'chains', now done randomly. p4.0.37 #ifdef NODE_DEBUG - if(usedirectbuf) - printf("MusE: AudioTrack::addData Error! One or no out routes, but already processed! Copying local buffers anyway...\n"); + printf("MusE: AudioTrack::addData name:%s already processed _haveData:%d\n", name().toLatin1().constData(), _haveData); #endif // Is there already some data gathered from a previous call during this process cycle? if(_haveData) { // Point the input buffers at our local cached 'pre-volume' buffers. They need processing, so continue on after. - //for(i = 0; i < srcChannels; ++i) - // buffer[i] = outBuffers[i]; - // p3.3.38 for(i = 0; i < srcTotalOutChans; ++i) buffer[i] = outBuffers[i]; } else + { // No data was available from a previous call during this process cycle. Nothing to add, just return. return; + } } else { // First time here during this process cycle. - // Point the input buffers at a temporary stack buffer. - //float data[nframes * srcChannels]; - //for(i = 0; i < srcChannels; ++i) - // buffer[i] = data + i * nframes; - // p3.3.38 - float data[nframes * srcTotalOutChans]; - for(i = 0; i < srcTotalOutChans; ++i) - buffer[i] = data + i * nframes; - + _haveData = false; // Reset. + _processed = true; // Set this now. - // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc. - // For ex. if this is an audio input, Jack will set the pointers for us. - //if(!getData(pos, srcChannels, nframes, buffer)) - // p3.3.38 - if(!getData(pos, srcTotalOutChans, nframes, buffer)) - { - // No data was available. Nothing to add, but zero our local buffers and the meters. - for(i = 0; i < srcChans; ++i) + if(off()) + { + #ifdef NODE_DEBUG + printf("MusE: AudioTrack::addData name:%s dstChannels:%d Track is Off \n", name().toLatin1().constData(), dstChannels); + #endif + + // Nothing to zero or add... + + _efxPipe->apply(0, nframes, 0); // Track is off. Just process controls only, not audio (do not 'run'). + + for(i = 0; i < trackChans; ++i) { - // If we're using local buffers, we must zero them so that the next thing requiring them - // during this process cycle will see zeros. - /* - if(!usedirectbuf) + _meter[i] = 0.0; + /*if(!usedirectbuf) { if(MusEGlobal::config.useDenormalBias) { - for(unsigned int q = 0; q < nframes; ++q) + for(q = 0; q < nframes; ++q) outBuffers[i][q] = MusEGlobal::denormalBias; - } - else + } + else memset(outBuffers[i], 0, sizeof(float) * nframes); - } - */ - - //_meter[i] = 0; - _meter[i] = 0.0; - } - - _haveData = false; - _processed = true; + } */ + } return; } - - /* - // p3.3.41 Added. - unsigned int q; - for(i = 0; i < srcChans; ++i) + + // Point the input buffers at a temporary stack buffer. + for(i = 0; i < srcTotalOutChans; ++i) + buffer[i] = data + i * nframes; + + // getData can use the supplied buffers, or change buffer to point to its own local buffers or Jack buffers etc. + // For ex. if this is an audio input, Jack will set the pointers for us. + if(!getData(pos, srcTotalOutChans, nframes, buffer)) { - if(MusEGlobal::config.useDenormalBias) - { - for(q = 0; q < nframes; ++q) + // No data was available. Track is not off. Zero the working buffers and continue on. + unsigned int q; + for(i = 0; i < srcTotalOutChans; ++i) + { + if(MusEGlobal::config.useDenormalBias) { - if(q & 1) - buffer[i][q] -= MusEGlobal::denormalBias; - else - buffer[i][q] += MusEGlobal::denormalBias; - } - } - } - */ - + for(q = 0; q < nframes; ++q) + buffer[i][q] = MusEGlobal::denormalBias; + } + else + memset(buffer[i], 0, sizeof(float) * nframes); + } + } + //--------------------------------------------------- // apply plugin chain //--------------------------------------------------- - // p3.3.41 //fprintf(stderr, "AudioTrack::addData %s efx apply srcChans:%d nframes:%ld %e %e %e %e\n", // name().toLatin1().constData(), srcChans, nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]); - _efxPipe->apply(srcChans, nframes, buffer); - // p3.3.41 + + _efxPipe->apply(trackChans, nframes, buffer); + //fprintf(stderr, "AudioTrack::addData after efx: %e %e %e %e\n", // buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]); @@ -940,18 +927,16 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr if(_prefader) { - for(i = 0; i < srcChans; ++i) + for(i = 0; i < trackChans; ++i) { float* p = buffer[i]; meter[i] = 0.0; for(unsigned k = 0; k < nframes; ++k) { - double f = fabs(*p); + double f = fabs(*p++); if(f > meter[i]) meter[i] = f; - ++p; } - //_meter[i] = lrint(meter[i] * 32767.0); _meter[i] = meter[i]; if(_meter[i] > _peak[i]) _peak[i] = _meter[i]; @@ -961,8 +946,7 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr if(isMute()) { // If we're using local buffers, we must zero them. - /* - if(!usedirectbuf) + /* if(!usedirectbuf) { for(i = 0; i < srcChannels; ++i) { @@ -974,20 +958,19 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr else memset(outBuffers[i], 0, sizeof(float) * nframes); } - } - */ + } */ - _haveData = false; - _processed = true; + if(!_prefader) + //for(i = 0; i < srcChans; ++i) + for(i = 0; i < trackChans; ++i) + _meter[i] = 0.0; + return; } // If we're using local cached 'pre-volume' buffers, copy the input buffers (as they are right now: post-effect pre-volume) back to them. - if(!usedirectbuf) + //if(!usedirectbuf) { - //for(i = 0; i < srcChannels; ++i) - // AL::dsp->cpy(outBuffers[i], buffer[i], nframes); - // p3.3.38 for(i = 0; i < srcTotalOutChans; ++i) AL::dsp->cpy(outBuffers[i], buffer[i], nframes); } @@ -1010,9 +993,9 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr else memset(dstBuffer[i], 0, sizeof(float) * nframes); } - _processed = true; return; } + // Force a source range to fit actual available total out channels. if((srcStartChan + srcChans) > srcTotalOutChans) srcChans = srcTotalOutChans - srcStartChan; @@ -1022,123 +1005,88 @@ void AudioTrack::addData(unsigned pos, int dstChannels, int srcStartChan, int sr // postfader metering //--------------------------------------------------- - if(srcChans == dstChannels) + #ifdef NODE_DEBUG + printf("MusE: AudioTrack::addData trackChans:%d srcTotalOutChans:%d srcChans:%d dstChannels:%d\n", trackChans, srcTotalOutChans, srcChans, dstChannels); + #endif + + if(!_prefader) { - if(_prefader) + for(int c = 0; c < trackChans; ++c) { - for(int c = 0; c < dstChannels; ++c) + meter[c] = 0.0; + double v = (trackChans == 1 ? _volume : vol[c]); + float* sp = buffer[c]; + for(unsigned k = 0; k < nframes; ++k) { - // p3.3.38 - //float* sp = buffer[c]; - float* sp = buffer[c + srcStartChan]; - - float* dp = dstBuffer[c]; - for(unsigned k = 0; k < nframes; ++k) - *dp++ += (*sp++ * vol[c]); + float val = *sp++ * v; // If the track is mono pan has no effect on meters. + double f = fabs(val); + if(f > meter[c]) + meter[c] = f; } - } - else + _meter[c] = meter[c]; + if(_meter[c] > _peak[c]) + _peak[c] = _meter[c]; + } + } + + if(srcChans == dstChannels) + { + for(int c = 0; c < dstChannels; ++c) { - for(int c = 0; c < dstChannels; ++c) - { - meter[c] = 0.0; - // p3.3.38 - //float* sp = buffer[c]; - float* sp = buffer[c + srcStartChan]; - - float* dp = dstBuffer[c]; - for(unsigned k = 0; k < nframes; ++k) - { - float val = *sp++ * vol[c]; - *dp++ += val; - double f = fabs(val); - if (f > meter[c]) - meter[c] = f; - } - //_meter[c] = lrint(meter[c] * 32767.0); - _meter[c] = meter[c]; - if(_meter[c] > _peak[c]) - _peak[c] = _meter[c]; - } + double v; + if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2. + //v = _volume; + v = 1.0; + else + if(srcChans >= 2) // If 2 channels apply pan normally. + v = vol[c]; + else + if(trackChans < 2) // If 1 channel and track is 1 channel, don't apply pan. + v = _volume; + else + v = vol[srcStartChan]; // Otherwise 1 channel but track is 2 channels. Apply the channel volume. + + float* sp = buffer[c + srcStartChan]; + float* dp = dstBuffer[c]; + for(unsigned k = 0; k < nframes; ++k) + //*dp++ += (*sp++ * vol[c]); + *dp++ += (*sp++ * v); } } else if(srcChans == 1 && dstChannels == 2) { - // p3.3.38 - float* sp = buffer[srcStartChan]; - - if(_prefader) + for(int c = 0; c < dstChannels; ++c) { - for(int c = 0; c < dstChannels; ++c) - { - float* dp = dstBuffer[c]; - //float* sp = buffer[0]; - for(unsigned k = 0; k < nframes; ++k) - *dp++ += (*sp++ * vol[c]); - } - } - else - { - //float* sp = buffer[0]; - meter[0] = 0.0; - for(unsigned k = 0; k < nframes; ++k) - { - float val = *sp++; - double f = fabs(val) * _volume; - if(f > meter[0]) - meter[0] = f; - *(dstBuffer[0] + k) += val * vol[0]; - *(dstBuffer[1] + k) += val * vol[1]; - } - //_meter[0] = lrint(meter[0] * 32767.0); - _meter[0] = meter[0]; - if(_meter[0] > _peak[0]) - _peak[0] = _meter[0]; + double v; + if(srcStartChan > 2) // Don't apply pan or volume to extra channels above 2. + //v = _volume; + v = 1.0; + else + if(trackChans <= 1) // If track is mono apply pan. + v = vol[c]; + else + v = vol[srcStartChan]; // Otherwise track is stereo, apply the same channel volume to both. + + float* sp = buffer[srcStartChan]; + float* dp = dstBuffer[c]; + for(unsigned k = 0; k < nframes; ++k) + //*dp++ += (*sp++ * vol[c]); + *dp++ += (*sp++ * v); } } else if(srcChans == 2 && dstChannels == 1) { - // p3.3.38 - //float* sp1 = buffer[0]; - //float* sp2 = buffer[1]; + //double v1 = (srcStartChan > 2 ? _volume : vol[srcStartChan]); // Don't apply pan to extra channels above 2. + //double v2 = (srcStartChan > 2 ? _volume : vol[srcStartChan + 1]); // + double v1 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan]); // Don't apply pan or volume to extra channels above 2. + double v2 = (srcStartChan > 2 ? 1.0 : vol[srcStartChan + 1]); // float* sp1 = buffer[srcStartChan]; float* sp2 = buffer[srcStartChan + 1]; - - if(_prefader) - { - float* dp = dstBuffer[0]; - for(unsigned k = 0; k < nframes; ++k) - *dp++ += (*sp1++ * vol[0] + *sp2++ * vol[1]); - } - else - { - float* dp = dstBuffer[0]; - meter[0] = 0.0; - meter[1] = 0.0; - for(unsigned k = 0; k < nframes; ++k) - { - float val1 = *sp1++ * vol[0]; - float val2 = *sp2++ * vol[1]; - double f1 = fabs(val1); - if(f1 > meter[0]) - meter[0] = f1; - double f2 = fabs(val2); - if(f2 > meter[1]) - meter[1] = f2; - *dp++ += (val1 + val2); - } - //_meter[0] = lrint(meter[0] * 32767.0); - _meter[0] = meter[0]; - if(_meter[0] > _peak[0]) - _peak[0] = _meter[0]; - //_meter[1] = lrint(meter[1] * 32767.0); - _meter[1] = meter[1]; - if(_meter[1] > _peak[1]) - _peak[1] = _meter[1]; - } + float* dp = dstBuffer[0]; + for(unsigned k = 0; k < nframes; ++k) + //*dp++ += (*sp1++ * vol[0] + *sp2++ * vol[1]); + *dp++ += (*sp1++ * v1 + *sp2++ * v2); } - - _processed = true; } //--------------------------------------------------------- @@ -1300,15 +1248,12 @@ bool AudioTrack::getData(unsigned pos, int channels, unsigned nframes, float** b printf(" calling copyData on %s...\n", ir->track->name().toLatin1().constData()); #endif - // p3.3.38 - //((AudioTrack*)ir->track)->copyData(pos, channels, nframes, buffer); ((AudioTrack*)ir->track)->copyData(pos, channels, //(ir->track->type() == Track::AUDIO_SOFTSYNTH && ir->channel != -1) ? ir->channel : 0, ir->channel, ir->channels, nframes, buffer); - // p3.3.41 //fprintf(stderr, "AudioTrack::getData %s data: nframes:%ld %e %e %e %e\n", name().toLatin1().constData(), nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]); ++ir; @@ -1320,8 +1265,6 @@ bool AudioTrack::getData(unsigned pos, int channels, unsigned nframes, float** b if(ir->track->isMidiTrack()) continue; - // p3.3.38 - //((AudioTrack*)ir->track)->addData(pos, channels, nframes, buffer); ((AudioTrack*)ir->track)->addData(pos, channels, //(ir->track->type() == Track::AUDIO_SOFTSYNTH && ir->channel != -1) ? ir->channel : 0, ir->channel, @@ -1344,12 +1287,11 @@ bool AudioInput::getData(unsigned, int channels, unsigned nframes, float** buffe void* jackPort = jackPorts[ch]; //float* jackbuf = 0; - //if (jackPort) { - // p3.3.41 Do not get buffers of unconnected client ports. Causes repeating leftover data, can be loud, or DC ! + // Do not get buffers of unconnected client ports. Causes repeating leftover data, can be loud, or DC ! if (jackPort && MusEGlobal::audioDevice->connections(jackPort)) { //buffer[ch] = MusEGlobal::audioDevice->getBuffer(jackPort, nframes); - // p3.3.41 If the client port buffer is also used by another channel (connected to the same jack port), + // If the client port buffer is also used by another channel (connected to the same jack port), // don't directly set pointer, copy the data instead. // Otherwise the next channel will interfere - it will overwrite the buffer ! // Verified symptoms: Can't use a splitter. Mono noise source on a stereo track sounds in mono. Etc... @@ -1366,8 +1308,6 @@ bool AudioInput::getData(unsigned, int channels, unsigned nframes, float** buffe { for (unsigned int i=0; i < nframes; i++) buffer[ch][i] += MusEGlobal::denormalBias; - - // p3.3.41 //fprintf(stderr, "AudioInput::getData %s Jack port %p efx apply channels:%d nframes:%ld %e %e %e %e\n", // name().toLatin1().constData(), jackPort, channels, nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]); } @@ -1384,8 +1324,6 @@ bool AudioInput::getData(unsigned, int channels, unsigned nframes, float** buffe memset(buffer[ch], 0, nframes * sizeof(float)); } - // p3.3.41 - //fprintf(stderr, "AudioInput::getData %s No Jack port efx apply channels:%d nframes:%ld %e %e %e %e\n", // name().toLatin1().constData(), channels, nframes, buffer[0][0], buffer[0][1], buffer[0][2], buffer[0][3]); } } @@ -1524,7 +1462,7 @@ void AudioTrack::record() return; } if (_recFile) { - // Line removed by Tim. p3.3.8 Oct 28, 2009 + // Line removed by Tim. Oct 28, 2009 //_recFile->seek(pos, 0); // // Fix for recorded waves being shifted ahead by an amount @@ -1570,7 +1508,6 @@ void AudioTrack::record() if( (pos >= fr) && (!MusEGlobal::song->punchout() || (!MusEGlobal::song->loop() && pos < MusEGlobal::song->rPos().frame())) ) { pos -= fr; - // Added by Tim. p3.3.8 //int position = _recFile->seek(0, SEEK_CUR); //printf("AudioTrack::record loopcnt:%d lframe:%d newpos:%d curpos:%d start:%d end:%d\n", MusEGlobal::audio->loopCount(), MusEGlobal::audio->loopFrame(), pos, position, MusEGlobal::audio->getStartRecordPos().frame(), MusEGlobal::audio->getEndRecordPos().frame()); @@ -1614,7 +1551,6 @@ void AudioOutput::processInit(unsigned nframes) void AudioOutput::process(unsigned pos, unsigned offset, unsigned n) { - //Added by Tim. p3.3.16 #ifdef NODE_DEBUG printf("MusE: AudioOutput::process name:%s processed:%d\n", name().toLatin1().constData(), processed()); #endif @@ -1622,9 +1558,6 @@ void AudioOutput::process(unsigned pos, unsigned offset, unsigned n) for (int i = 0; i < _channels; ++i) { buffer1[i] = buffer[i] + offset; } - - // p3.3.38 - //copyData(pos, _channels, n, buffer1); copyData(pos, _channels, -1, -1, n, buffer1); } @@ -1666,17 +1599,13 @@ void AudioOutput::processWrite() putFifo(_channels, _nframes, buffer); } } - // Changed by Tim. p3.3.18 + // Changed by Tim. //if (MusEGlobal::audioClickFlag && MusEGlobal::song->click()) { if (sendMetronome() && MusEGlobal::audioClickFlag && MusEGlobal::song->click()) { - // Added by Tim. p3.3.18 #ifdef METRONOME_DEBUG printf("MusE: AudioOutput::processWrite Calling metronome->addData frame:%u channels:%d frames:%lu\n", MusEGlobal::audio->pos().frame(), _channels, _nframes); #endif - - // p3.3.38 - //metronome->addData(MusEGlobal::audio->pos().frame(), _channels, _nframes, buffer); metronome->addData(MusEGlobal::audio->pos().frame(), _channels, -1, -1, _nframes, buffer); } } @@ -1721,7 +1650,6 @@ Fifo::~Fifo() { for (int i = 0; i < nbuffer; ++i) { - // p3.3.45 if(buffer[i]->buffer) { //printf("Fifo::~Fifo freeing buffer\n"); @@ -1742,7 +1670,6 @@ Fifo::~Fifo() bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos) { - // Added by Tim. p3.3.17 #ifdef FIFO_DEBUG printf("FIFO::put segs:%d samples:%lu pos:%u\n", segs, samples, pos); #endif @@ -1765,7 +1692,6 @@ bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos) // Changed by Tim. p3.3.15 //b->buffer = new float[n]; posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n); - // p3.3.45 if(!b->buffer) { printf("Fifo::put could not allocate buffer segs:%d samples:%lu pos:%u\n", segs, samples, pos); @@ -1774,7 +1700,6 @@ bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos) b->maxSize = n; } - // p3.3.45 if(!b->buffer) { printf("Fifo::put no buffer! segs:%d samples:%lu pos:%u\n", segs, samples, pos); @@ -1798,7 +1723,6 @@ bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos) bool Fifo::get(int segs, unsigned long samples, float** dst, unsigned* pos) { - // Added by Tim. p3.3.17 #ifdef FIFO_DEBUG printf("FIFO::get segs:%d samples:%lu\n", segs, samples); #endif @@ -1808,7 +1732,6 @@ bool Fifo::get(int segs, unsigned long samples, float** dst, unsigned* pos) return true; } FifoBuffer* b = buffer[ridx]; - // p3.3.45 if(!b->buffer) { printf("Fifo::get no buffer! segs:%d samples:%lu b->pos:%u\n", segs, samples, b->pos); @@ -1844,7 +1767,6 @@ void Fifo::remove() bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned pos) { - // Added by Tim. p3.3.17 #ifdef FIFO_DEBUG printf("Fifo::getWriteBuffer segs:%d samples:%lu pos:%u\n", segs, samples, pos); #endif @@ -1866,7 +1788,6 @@ bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned // Changed by Tim. p3.3.15 //b->buffer = new float[n]; posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n); - // p3.3.45 if(!b->buffer) { printf("Fifo::getWriteBuffer could not allocate buffer segs:%d samples:%lu pos:%u\n", segs, samples, pos); @@ -1875,8 +1796,6 @@ bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned b->maxSize = n; } - - // p3.3.45 if(!b->buffer) { printf("Fifo::getWriteBuffer no buffer! segs:%d samples:%lu pos:%u\n", segs, samples, pos); diff --git a/muse2/muse/osc.cpp b/muse2/muse/osc.cpp index 6959803e..7daeb9ff 100644 --- a/muse2/muse/osc.cpp +++ b/muse2/muse/osc.cpp @@ -841,7 +841,8 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin arguments << oscUrl << filePath << name - << QString("channel-1"); + //<< QString("channel-1"); + << (titlePrefix() + label); #ifdef OSC_DEBUG fprintf(stderr, "OscIF::oscInitGui starting QProcess\n"); @@ -885,7 +886,8 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin oscUrl.toLatin1().constData(), filePath.toLatin1().constData(), name.toLatin1().constData(), - "channel 1", (void*)0); + //"channel 1", (void*)0); + label.toLatin1().constData(), (void*)0); // Should not return after execlp. If so it's an error. fprintf(stderr, "exec %s %s %s %s %s failed: %s\n", @@ -941,13 +943,13 @@ void OscIF::oscShowGui(bool v) } //for (int i = 0; i < 5; ++i) { - for (int i = 0; i < 10; ++i) { // Give it a wee bit more time? + for (int i = 0; i < 20; ++i) { // Give it a wee bit more time? if (_uiOscPath) break; sleep(1); } if (_uiOscPath == 0) { - printf("OscIF::oscShowGui(): no _uiOscPath. Error: Timeout - synth gui did not start within 10 seconds.\n"); + printf("OscIF::oscShowGui(): no _uiOscPath. Error: Timeout - synth gui did not start within 20 seconds.\n"); return; } @@ -1091,10 +1093,14 @@ bool OscDssiIF::oscInitGui() _oscSynthIF->dssiSynth()->name(), _oscSynthIF->dssiSynthI()->name(), _oscSynthIF->dssiSynth()->fileName(), _oscSynthIF->dssi_ui_filename()); } + +QString OscDssiIF::titlePrefix() const +{ + return _oscSynthIF ? _oscSynthIF->titlePrefix() : QString(); +} #endif // DSSI_SUPPORT - //--------------------------------------------------------- // OscEffectIF:: // oscSetPluginI @@ -1165,6 +1171,11 @@ bool OscEffectIF::oscInitGui() _oscPluginI->plugin()->fileName(), _oscPluginI->dssi_ui_filename()); } +QString OscEffectIF::titlePrefix() const +{ + return _oscPluginI ? _oscPluginI->titlePrefix() : QString(); +} + #else //OSC_SUPPORT void initOSC() {} diff --git a/muse2/muse/osc.h b/muse2/muse/osc.h index 30df03cb..e3f1a26d 100644 --- a/muse2/muse/osc.h +++ b/muse2/muse/osc.h @@ -74,6 +74,8 @@ class OscIF virtual bool oscInitGui() { return false; } virtual void oscShowGui(bool); virtual bool oscGuiVisible() const; + + virtual QString titlePrefix() const { return QString(); } }; class OscEffectIF : public OscIF @@ -95,6 +97,8 @@ class OscEffectIF : public OscIF virtual int oscConfigure(lo_arg**); virtual bool oscInitGui(); + + virtual QString titlePrefix() const; }; #ifdef DSSI_SUPPORT @@ -117,6 +121,8 @@ class OscDssiIF : public OscIF virtual int oscConfigure(lo_arg**); virtual bool oscInitGui(); + + virtual QString titlePrefix() const; }; #endif // DSSI_SUPPORT diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index eb5b1af6..da01a5d5 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -750,6 +750,18 @@ WavePart::WavePart(const WavePart& p) : Part(p) Part::~Part() { + if (_prevClone!=this || _nextClone!=this) + { + printf("THIS MIGHT BE A HINT FOR BUGS: Part isn't unchained in ~Part()! i'll do that now. this is\n" + "not an actual bug, actually that manual unchain should be unneccessary if this was coded\n" + "properly. but as it wasn't, and the unchain was always done manually, this might be an\n" + "indicator that it have been forgotten. either your computer will explode in 3..2..1..now,\n" + "or you can ignore this message.\n" + "\n"); + + unchainClone(this); + } + _events->incRef(-1); if (_events->refCount() <= 0) delete _events; diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp index 2bdd0317..227a9daf 100644 --- a/muse2/muse/plugin.cpp +++ b/muse2/muse/plugin.cpp @@ -1573,65 +1573,60 @@ bool Pipeline::nativeGuiVisible(int idx) //--------------------------------------------------------- // apply +// If ports is 0, just process controllers only, not audio (do not 'run'). //--------------------------------------------------------- -//void Pipeline::apply(int ports, unsigned long nframes, float** buffer1) void Pipeline::apply(unsigned long ports, unsigned long nframes, float** buffer1) { // prepare a second set of buffers in case a plugin is not // capable of inPlace processing - - // Removed by Tim. p3.3.15 //float* buffer2[ports]; //float data[nframes * ports]; //for (int i = 0; i < ports; ++i) // buffer2[i] = data + i * nframes; - // p3.3.41 - //fprintf(stderr, "Pipeline::apply data: nframes:%lu %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]); + //fprintf(stderr, "Pipeline::apply data: nframes:%lu %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]); bool swap = false; for (iPluginI ip = begin(); ip != end(); ++ip) { PluginI* p = *ip; - if (p && p->on()) { - if (p->inPlaceCapable()) - { - if (swap) - //p->connect(ports, buffer2, buffer2); - //p->connect(ports, buffer, buffer); - p->apply(nframes, ports, buffer, buffer); // p4.0.21 - else - //p->connect(ports, buffer1, buffer1); - p->apply(nframes, ports, buffer1, buffer1); // - } - else - { - if (swap) - //p->connect(ports, buffer2, buffer1); - //p->connect(ports, buffer, buffer1); - p->apply(nframes, ports, buffer, buffer1); // - else - //p->connect(ports, buffer1, buffer2); - //p->connect(ports, buffer1, buffer); - p->apply(nframes, ports, buffer1, buffer); // - swap = !swap; - } - //p->apply(nframes); // Rem. p4.0.21 - } + + if(p) + { + //if (p && p->on()) { + if (p->on()) + { + //fprintf(stderr, "Pipeline::apply PluginI:%p on:%d\n", p, p->on()); + if (p->inPlaceCapable()) + { + if (swap) + p->apply(nframes, ports, buffer, buffer); + else + p->apply(nframes, ports, buffer1, buffer1); + } + else + { + if (swap) + p->apply(nframes, ports, buffer, buffer1); + else + p->apply(nframes, ports, buffer1, buffer); + swap = !swap; + } + } + else + { + p->apply(nframes, 0, 0, 0); // Do not process (run) audio, process controllers only. + } } - if (swap) + } + if (ports != 0 && swap) { - //for (int i = 0; i < ports; ++i) - for (unsigned long i = 0; i < ports; ++i) // p4.0.21 + for (unsigned long i = 0; i < ports; ++i) //memcpy(buffer1[i], buffer2[i], sizeof(float) * nframes); //memcpy(buffer1[i], buffer[i], sizeof(float) * nframes); AL::dsp->cpy(buffer1[i], buffer[i], nframes); } - - // p3.3.41 - //fprintf(stderr, "Pipeline::apply after data: nframes:%lu %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]); - } //--------------------------------------------------------- @@ -2439,6 +2434,7 @@ void PluginI::showGui() if (_plugin) { if (_gui == 0) makeGui(); + _gui->setWindowTitle(titlePrefix() + name()); if (_gui->isVisible()) _gui->hide(); else @@ -2557,8 +2553,18 @@ void PluginI::enable2AllControllers(bool v) controls[i].en2Ctrl = v; } +//--------------------------------------------------------- +// titlePrefix +//--------------------------------------------------------- + +QString PluginI::titlePrefix() const +{ + return _track->name() + QString(": "); +} + //--------------------------------------------------------- // apply +// If ports is 0, just process controllers only, not audio (do not 'run'). //--------------------------------------------------------- /* @@ -2653,7 +2659,6 @@ void PluginI::apply(unsigned long n) */ #if 1 -// p4.0.21 void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** bufOut) { // Process control value changes. @@ -2769,7 +2774,6 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** //controls[v.idx].val = v.value; controls[v.idx].tmpVal = v.value; - /* // Need to update the automation value, otherwise it overwrites later with the last MusEGlobal::automation value. if(_track && _id != -1) { @@ -2795,7 +2799,6 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** // enableController(k, false); //_track->recordAutomation(id, v.value); } - */ } // Now update the actual values from the temporary values... @@ -2813,20 +2816,23 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** nsamp = n - sample; //printf("PluginI::apply ports:%lu n:%lu frame:%lu sample:%lu nsamp:%lu syncFrame:%lu loopcount:%d\n", - // ports, n, frame, sample, nsamp, syncFrame, loopcount); // REMOVE Tim. + // ports, n, frame, sample, nsamp, syncFrame, loopcount); // Don't allow zero-length runs. This could/should be checked in the control loop instead. // Note this means it is still possible to get stuck in the top loop (at least for a while). if(nsamp == 0) continue; - connect(ports, sample, bufIn, bufOut); + if(ports != 0) + { + connect(ports, sample, bufIn, bufOut); - for(int i = 0; i < instances; ++i) - { - //fprintf(stderr, "PluginI::apply handle %d\n", i); - _plugin->apply(handle[i], nsamp); - } + for(int i = 0; i < instances; ++i) + { + //fprintf(stderr, "PluginI::apply handle %d\n", i); + _plugin->apply(handle[i], nsamp); + } + } sample += nsamp; loopcount++; // REMOVE Tim. @@ -3444,7 +3450,8 @@ PluginGui::PluginGui(MusECore::PluginIBase* p) params = 0; paramsOut = 0; plugin = p; - setWindowTitle(plugin->name()); + //setWindowTitle(plugin->name()); + setWindowTitle(plugin->titlePrefix() + plugin->name()); QToolBar* tools = addToolBar(tr("File Buttons")); @@ -4106,16 +4113,18 @@ void PluginGui::save() void PluginGui::bypassToggled(bool val) { + setWindowTitle(plugin->titlePrefix() + plugin->name()); plugin->setOn(val); MusEGlobal::song->update(SC_ROUTE); } //--------------------------------------------------------- -// songChanged +// setOn //--------------------------------------------------------- void PluginGui::setOn(bool val) { + setWindowTitle(plugin->titlePrefix() + plugin->name()); onOff->blockSignals(true); onOff->setChecked(val); onOff->blockSignals(false); @@ -4208,11 +4217,11 @@ void PluginGui::updateControls() } - if(!MusEGlobal::automation) - return; - AutomationType at = plugin->track()->automationType(); - if(at == AUTO_OFF) - return; + //if(!MusEGlobal::automation) + // return; + //AutomationType at = plugin->track()->automationType(); + //if(at == AUTO_OFF) + // return; if (params) { //for (int i = 0; i < plugin->parameters(); ++i) { for (unsigned long i = 0; i < plugin->parameters(); ++i) { // p4.0.21 diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h index 717f98b6..044fd863 100644 --- a/muse2/muse/plugin.h +++ b/muse2/muse/plugin.h @@ -72,18 +72,6 @@ class Xml; class MidiController; -/* -//--------------------------------------------------------- -// PluginBase -//--------------------------------------------------------- - -class PluginBase -{ - protected: - void range(unsigned long i, float*, float*) const; -}; -*/ - //--------------------------------------------------------- // Plugin //--------------------------------------------------------- @@ -155,13 +143,11 @@ class Plugin { if (plugin && plugin->cleanup) plugin->cleanup(handle); } - //void connectPort(LADSPA_Handle handle, int port, float* value) { - void connectPort(LADSPA_Handle handle, unsigned long port, float* value) { // p4.0.21 + void connectPort(LADSPA_Handle handle, unsigned long port, float* value) { if(plugin) plugin->connect_port(handle, port, value); } - //void apply(LADSPA_Handle handle, int n) { - void apply(LADSPA_Handle handle, unsigned long n) { // p4.0.21 + void apply(LADSPA_Handle handle, unsigned long n) { if(plugin) plugin->run(handle, n); } @@ -170,12 +156,10 @@ class Plugin { int oscConfigure(LADSPA_Handle /*handle*/, const char* /*key*/, const char* /*value*/); #endif - //int ports() { return plugin ? plugin->PortCount : 0; } unsigned long ports() { return _portCount; } LADSPA_PortDescriptor portd(unsigned long k) const { return plugin ? plugin->PortDescriptors[k] : 0; - //return _portDescriptors[k]; } LADSPA_PortRangeHint range(unsigned long i) { @@ -184,8 +168,7 @@ class Plugin { return plugin->PortRangeHints[i]; } - //double defaultValue(unsigned long port) const; - float defaultValue(unsigned long port) const; // p4.0.21 + float defaultValue(unsigned long port) const; void range(unsigned long i, float*, float*) const; CtrlValueType ctrlValueType(unsigned long /*i*/) const; CtrlList::Mode ctrlMode(unsigned long /*i*/) const; @@ -202,20 +185,6 @@ class Plugin { unsigned long controlInPorts() const { return _controlInPorts; } unsigned long controlOutPorts() const { return _controlOutPorts; } bool inPlaceCapable() const { return _inPlaceCapable; } - - /* - bool isLog(int k) const { - LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]]; - return LADSPA_IS_HINT_LOGARITHMIC(r.HintDescriptor); - } - bool isBool(int k) const { - return LADSPA_IS_HINT_TOGGLED(plugin->PortRangeHints[pIdx[k]].HintDescriptor); - } - bool isInt(int k) const { - LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]]; - return LADSPA_IS_HINT_INTEGER(r.HintDescriptor); - } - */ }; typedef std::list::iterator iPlugin; @@ -266,21 +235,18 @@ class PluginIBase ~PluginIBase(); virtual bool on() const = 0; virtual void setOn(bool /*val*/) = 0; - //virtual int pluginID() = 0; - virtual unsigned long pluginID() = 0; // p4.0.21 + virtual unsigned long pluginID() = 0; virtual int id() = 0; virtual QString pluginLabel() const = 0; virtual QString name() const = 0; virtual QString lib() const = 0; virtual QString dirPath() const = 0; virtual QString fileName() const = 0; + virtual QString titlePrefix() const = 0; virtual AudioTrack* track() = 0; - //virtual void enableController(int /*i*/, bool /*v*/ = true) = 0; - //virtual bool controllerEnabled(int /*i*/) const = 0; - //virtual bool controllerEnabled2(int /*i*/) const = 0; - virtual void enableController(unsigned long /*i*/, bool /*v*/ = true) = 0; // p4.0.21 + virtual void enableController(unsigned long /*i*/, bool /*v*/ = true) = 0; virtual bool controllerEnabled(unsigned long /*i*/) const = 0; virtual bool controllerEnabled2(unsigned long /*i*/) const = 0; virtual void updateControllers() = 0; @@ -288,12 +254,7 @@ class PluginIBase virtual void writeConfiguration(int /*level*/, Xml& /*xml*/) = 0; virtual bool readConfiguration(Xml& /*xml*/, bool /*readPreset*/=false) = 0; - //virtual int parameters() const = 0; - //virtual void setParam(int /*i*/, double /*val*/) = 0; - //virtual double param(int /*i*/) const = 0; - //virtual const char* paramName(int /*i*/) = 0; - //virtual LADSPA_PortRangeHint range(int /*i*/) = 0; - virtual unsigned long parameters() const = 0; // p4.0.21 + virtual unsigned long parameters() const = 0; virtual unsigned long parametersOut() const = 0; virtual void setParam(unsigned long /*i*/, float /*val*/) = 0; virtual float param(unsigned long /*i*/) const = 0; @@ -307,8 +268,6 @@ class PluginIBase virtual CtrlList::Mode ctrlMode(unsigned long /*i*/) const = 0; QString dssi_ui_filename() const; - //virtual void showGui(bool) = 0; // p4.0.20 - //virtual void showNativeGui(bool) = 0; // MusEGui::PluginGui* gui() const { return _gui; } void deleteGui(); }; @@ -353,7 +312,6 @@ class PluginBase #define AUDIO_IN (LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT) #define AUDIO_OUT (LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT) -//class PluginI { class PluginI : public PluginIBase { Plugin* _plugin; int channel; @@ -365,10 +323,8 @@ class PluginI : public PluginIBase { Port* controls; Port* controlsOut; - //int controlPorts; - //int controlOutPorts; - unsigned long controlPorts; // p4.0.21 - unsigned long controlOutPorts; // + unsigned long controlPorts; + unsigned long controlOutPorts; ///PluginGui* _gui; bool _on; @@ -400,26 +356,17 @@ class PluginI : public PluginIBase { void setTrack(AudioTrack* t) { _track = t; } AudioTrack* track() { return _track; } - //int pluginID() { return _plugin->id(); } - unsigned long pluginID() { return _plugin->id(); } // p4.0.21 + unsigned long pluginID() { return _plugin->id(); } void setID(int i); int id() { return _id; } void updateControllers(); bool initPluginInstance(Plugin*, int channels); void setChannels(int); - //void connect(int ports, float** src, float** dst); - //void apply(int n); - //void connect(unsigned ports, float** src, float** dst); - //void apply(unsigned n); - void connect(unsigned long ports, unsigned long offset, float** src, float** dst); // p4.0.21 - void apply(unsigned long n, unsigned long ports, float** bufIn, float** bufOut); // - - //void enableController(int i, bool v = true) { controls[i].enCtrl = v; } - //bool controllerEnabled(int i) const { return controls[i].enCtrl; } - //void enable2Controller(int i, bool v = true) { controls[i].en2Ctrl = v; } - //bool controllerEnabled2(int i) const { return controls[i].en2Ctrl; } - void enableController(unsigned long i, bool v = true) { controls[i].enCtrl = v; } // p4.0.21 + void connect(unsigned long ports, unsigned long offset, float** src, float** dst); + void apply(unsigned long n, unsigned long ports, float** bufIn, float** bufOut); + + void enableController(unsigned long i, bool v = true) { controls[i].enCtrl = v; } bool controllerEnabled(unsigned long i) const { return controls[i].enCtrl; } void enable2Controller(unsigned long i, bool v = true) { controls[i].en2Ctrl = v; } bool controllerEnabled2(unsigned long i) const { return controls[i].en2Ctrl; } @@ -434,6 +381,7 @@ class PluginI : public PluginIBase { QString lib() const { return _plugin->lib(); } QString dirPath() const { return _plugin->dirPath(); } QString fileName() const { return _plugin->fileName(); } + QString titlePrefix() const; #ifdef OSC_SUPPORT OscEffectIF& oscIF() { return _oscif; } @@ -453,8 +401,7 @@ class PluginI : public PluginIBase { void writeConfiguration(int level, Xml& xml); bool readConfiguration(Xml& xml, bool readPreset=false); bool loadControl(Xml& xml); - //bool setControl(const QString& s, double val); - bool setControl(const QString& s, float val); // p4.0.21 + bool setControl(const QString& s, float val); void showGui(); void showGui(bool); bool isDssiPlugin() const { return _plugin->isDssiPlugin(); } @@ -464,20 +411,8 @@ class PluginI : public PluginIBase { bool guiVisible(); bool nativeGuiVisible(); - //int parameters() const { return controlPorts; } - //void setParam(int i, double val) { controls[i].tmpVal = val; } - //double param(int i) const { return controls[i].val; } - //double defaultValue(unsigned int param) const; - //const char* paramName(int i) { return _plugin->portName(controls[i].idx); } - //LADSPA_PortDescriptor portd(int i) const { return _plugin->portd(controls[i].idx); } - //void range(int i, float* min, float* max) const { _plugin->range(controls[i].idx, min, max); } - //bool isAudioIn(int k) { return (_plugin->portd(k) & AUDIO_IN) == AUDIO_IN; } - //bool isAudioOut(int k) { return (_plugin->portd(k) & AUDIO_OUT) == AUDIO_OUT; } - //LADSPA_PortRangeHint range(int i) { return _plugin->range(controls[i].idx); } - // p4.0.21 unsigned long parameters() const { return controlPorts; } unsigned long parametersOut() const { return controlOutPorts; } - //void setParam(unsigned i, float val) { controls[i].tmpVal = val; } void setParam(unsigned long i, float val); float param(unsigned long i) const { return controls[i].val; } float paramOut(unsigned long i) const { return controlsOut[i].val; } @@ -500,8 +435,6 @@ class PluginI : public PluginIBase { // chain of connected efx inserts //--------------------------------------------------------- -//const int PipelineDepth = 4; // Moved to globaldefs.h - class Pipeline : public std::vector { float* buffer[MAX_CHANNELS]; @@ -525,8 +458,7 @@ class Pipeline : public std::vector { void deleteAllGuis(); bool guiVisible(int); bool nativeGuiVisible(int); - //void apply(int ports, unsigned long nframes, float** buffer); - void apply(unsigned long ports, unsigned long nframes, float** buffer); // p4.0.21 + void apply(unsigned long ports, unsigned long nframes, float** buffer); void move(int idx, bool up); bool empty(int idx) const; void setChannels(int); @@ -537,11 +469,6 @@ typedef Pipeline::const_iterator ciPluginI; extern void initPlugins(); -//extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val); -//extern void ladspaControlRange(const LADSPA_Descriptor* plugin, int i, float* min, float* max); -//extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctlnum, int* min, int* max, int* def); -//extern float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, int val); -// p4.0.21 extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, unsigned long port, float* val); extern void ladspaControlRange(const LADSPA_Descriptor* plugin, unsigned long port, float* min, float* max); extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long port, int ctlnum, int* min, int* max, int* def); @@ -593,8 +520,7 @@ struct GuiWidgets { }; QWidget* widget; int type; - //int param; - unsigned long param; // p4.0.21 + unsigned long param; }; //--------------------------------------------------------- @@ -604,13 +530,11 @@ struct GuiWidgets { class PluginGui : public QMainWindow { Q_OBJECT - //PluginI* plugin; // plugin instance MusECore::PluginIBase* plugin; // plugin instance GuiParam* params; GuiParam* paramsOut; - //int nobj; - unsigned long nobj; // number of widgets in gw // p4.0.21 + unsigned long nobj; // number of widgets in gw GuiWidgets* gw; QAction* onOff; @@ -640,7 +564,6 @@ class PluginGui : public QMainWindow { void heartBeat(); public: - //PluginGui(MusECore::PluginI*); PluginGui(MusECore::PluginIBase*); ~PluginGui(); diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp index 645c639e..de8f15ef 100644 --- a/muse2/muse/remote/pyapi.cpp +++ b/muse2/muse/remote/pyapi.cpp @@ -1129,7 +1129,9 @@ bool Song::event(QEvent* _e) break; } case QPybridgeEvent::SONG_ADD_TRACK: - MusEGlobal::song->addTrack((Track::TrackType)e->getP1()); // Add at end of list. + MusECore::Undo operations; + MusEGlobal::song->addTrack(operations, (Track::TrackType)e->getP1()); // Add at end of list. + MusEGlobal::song->applyOperationGroup(operations); break; case QPybridgeEvent::SONG_CHANGE_TRACKNAME: { Track* t = this->findTrack(e->getS1()); diff --git a/muse2/muse/route.cpp b/muse2/muse/route.cpp index f00c6d6c..1d494fb0 100644 --- a/muse2/muse/route.cpp +++ b/muse2/muse/route.cpp @@ -4,6 +4,7 @@ // $Id: route.cpp,v 1.18.2.3 2008/05/21 00:28:52 terminator356 Exp $ // // (C) Copyright 2003-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -37,8 +38,6 @@ //#define ROUTE_DEBUG -//#define ROUTE_MIDIPORT_NAME_PREFIX "MusE MidiPort " - namespace MusECore { const QString ROUTE_MIDIPORT_NAME_PREFIX = "MusE MidiPort "; @@ -57,9 +56,7 @@ Route::Route(void* t, int ch) type = JACK_ROUTE; } -//Route::Route(AudioTrack* t, int ch) Route::Route(Track* t, int ch, int chans) -//Route::Route(Track* t, int ch) { track = t; midiPort = -1; @@ -69,7 +66,6 @@ Route::Route(Track* t, int ch, int chans) type = TRACK_ROUTE; } -//Route::Route(MidiJackDevice* d) Route::Route(MidiDevice* d, int ch) { device = d; @@ -77,19 +73,10 @@ Route::Route(MidiDevice* d, int ch) channel = ch; channels = -1; remoteChannel = -1; - /* - //if(dynamic_cast(d)) - if(d->deviceType() == MidiDevice::JACK_MIDI) - type = JACK_MIDI_ROUTE; - else - //if(dynamic_cast(d)) - if(d->deviceType() == MidiDevice::ALSA_MIDI) - type = ALSA_MIDI_ROUTE; - */ type = MIDI_DEVICE_ROUTE; } -Route::Route(int port, int ch) // p3.3.49 +Route::Route(int port, int ch) { track = 0; midiPort = port; @@ -99,16 +86,12 @@ Route::Route(int port, int ch) // p3.3.49 type = MIDI_PORT_ROUTE; } -//Route::Route(const QString& s, bool dst, int ch) Route::Route(const QString& s, bool dst, int ch, int rtype) { - //Route node(name2route(s, dst)); Route node(name2route(s, dst, rtype)); channel = node.channel; if(channel == -1) channel = ch; - //if(channels == -1) - // channels = chans; channels = node.channels; remoteChannel = node.remoteChannel; type = node.type; @@ -123,14 +106,6 @@ Route::Route(const QString& s, bool dst, int ch, int rtype) jackPort = node.jackPort; midiPort = -1; } - /* - else - if (type == JACK_MIDI_ROUTE) - device = node.device; - else - if (type == ALSA_MIDI_ROUTE) - device = node.device; - */ else if(type == MIDI_DEVICE_ROUTE) { @@ -138,10 +113,10 @@ Route::Route(const QString& s, bool dst, int ch, int rtype) midiPort = -1; } else - if(type == MIDI_PORT_ROUTE) // p3.3.49 + if(type == MIDI_PORT_ROUTE) { track = 0; - midiPort = node.midiPort; // + midiPort = node.midiPort; } } @@ -179,31 +154,20 @@ void addRoute(Route src, Route dst) // dst.type, dst.channel, dst.name().toLatin1().constData()); if (src.type == Route::JACK_ROUTE) { - //if (dst.type != TRACK_ROUTE) - //{ - // fprintf(stderr, "addRoute: bad route 1\n"); - // exit(-1); - // return; - //} - if (dst.type == Route::TRACK_ROUTE) { if (dst.track->type() != Track::AUDIO_INPUT) { fprintf(stderr, "addRoute: source is jack, dest:%s is track but not audio input\n", dst.track->name().toLatin1().constData()); - //exit(-1); return; } if (dst.channel < 0) { fprintf(stderr, "addRoute: source is jack, dest:%s is track but invalid channel:%d\n", dst.track->name().toLatin1().constData(), dst.channel); - //exit(-1); return; } - //src.channel = src.dstChannel = dst.channel; src.channel = dst.channel; - //src.channels = dst.channels = 1; RouteList* inRoutes = dst.track->inRoutes(); for (ciRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) { @@ -221,28 +185,11 @@ void addRoute(Route src, Route dst) inRoutes->push_back(src); } else - //if (dst.type == Route::JACK_MIDI_ROUTE) if (dst.type == Route::MIDI_DEVICE_ROUTE) - //if (dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49 { - //MidiDevice *md = MusEGlobal::midiPorts[dst.midiPort].device(); - //if(dst.device->deviceType() == MidiDevice::JACK_MIDI) - //if(!md) - //{ - // fprintf(stderr, "addRoute: source is Jack, but no destination port device\n"); - // return; - //} - if(dst.device->deviceType() == MidiDevice::JACK_MIDI) - //if(md->deviceType() == MidiDevice::JACK_MIDI) { src.channel = dst.channel; - //src.channel = -1; - //src.channel = 0; - //src.channel = src.dstChannel = dst.channel; - //src.channels = dst.channels = 1; - //dst.channel = -1; - RouteList* routes = dst.device->inRoutes(); for (ciRoute i = routes->begin(); i != routes->end(); ++i) { @@ -262,45 +209,32 @@ void addRoute(Route src, Route dst) else { fprintf(stderr, "addRoute: source is Jack, but destination is not jack midi - type:%d\n", dst.device->deviceType()); - // exit(-1); return; } } else { fprintf(stderr, "addRoute: source is Jack, but destination is not track or midi - type:%d \n", dst.type); - // exit(-1); return; } } else if (dst.type == Route::JACK_ROUTE) { - //if (src.type != TRACK_ROUTE) - //{ - // fprintf(stderr, "addRoute: bad route 3\n"); - // exit(-1); - // return; - //} - if (src.type == Route::TRACK_ROUTE) { if (src.track->type() != Track::AUDIO_OUTPUT) { fprintf(stderr, "addRoute: destination is jack, source is track but not audio output\n"); - // exit(-1); return; } if (src.channel < 0) { fprintf(stderr, "addRoute: destination is jack, source:%s is track but invalid channel:%d\n", src.track->name().toLatin1().constData(), src.channel); - // exit(-1); return; } RouteList* outRoutes = src.track->outRoutes(); - //dst.channel = dst.dstChannel = src.channel; dst.channel = src.channel; - //dst.channels = src.channels = 1; for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) { @@ -318,17 +252,11 @@ void addRoute(Route src, Route dst) outRoutes->push_back(dst); } else - //if (src.type == Route::JACK_MIDI_ROUTE) if (src.type == Route::MIDI_DEVICE_ROUTE) { if(src.device->deviceType() == MidiDevice::JACK_MIDI) { dst.channel = src.channel; - //dst.channel = -1; - //src.channel = -1; - //dst.channel = dst.dstChannel = src.channel; - //dst.channels = src.channels = 1; - RouteList* routes = src.device->outRoutes(); for (ciRoute i = routes->begin(); i != routes->end(); ++i) { @@ -348,18 +276,16 @@ void addRoute(Route src, Route dst) else { fprintf(stderr, "addRoute: destination is Jack, but source is not jack midi - type:%d\n", src.device->deviceType()); - // exit(-1); return; } } else { fprintf(stderr, "addRoute: destination is Jack, but source is not track or midi - type:%d \n", src.type); - // exit(-1); return; } } - else if(src.type == Route::MIDI_PORT_ROUTE) // p3.3.49 + else if(src.type == Route::MIDI_PORT_ROUTE) { if(dst.type != Route::TRACK_ROUTE) { @@ -367,66 +293,18 @@ void addRoute(Route src, Route dst) return; } - // p4.0.14 - /* - if(dst.track->type() == Track::AUDIO_INPUT) - { - if(src.channel < 1 || src.channel >= (1 << MIDI_CHANNELS)) - { - fprintf(stderr, "addRoute: source is midi port:%d, but channel mask:%d out of range\n", src.midiPort, src.channel); - return; - } - - MidiPort *mp = &MusEGlobal::midiPorts[src.midiPort]; - //src.channel = dst.channel = -1; - RouteList* outRoutes = mp->outRoutes(); - iRoute ir = outRoutes->begin(); - for ( ; ir != outRoutes->end(); ++ir) - { - //if (*i == dst) // route already there - ir->dump(); - if (ir->type == Route::TRACK_ROUTE && ir->track == dst.track) // Does a route to the track exist? - { - //#ifdef ROUTE_DEBUG - fprintf(stderr, "addRoute: src midi port:%d dst audio in track:%s out route already exists. ir->channel:%d |= dst.channel:%d\n", - src.midiPort, dst.track->name().toLatin1().constData(), ir->channel, dst.channel); - //#endif - ir->channel |= dst.channel; // Bitwise OR the desired channel bit with the existing bit mask. - break; - //return; - } - } - if(ir == outRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with. - outRoutes->push_back(dst); - - RouteList* inRoutes = dst.track->inRoutes(); - - ir = inRoutes->begin(); - for ( ; ir != inRoutes->end(); ++ir) - { - if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == src.midiPort) // Does a route to the midi port exist? - { - fprintf(stderr, "addRoute: src midi port:%d dst audio in track:%s in route already exists. ir->channel:%d |= src.channel:%d\n", - src.midiPort, dst.track->name().toLatin1().constData(), ir->channel, src.channel); - ir->channel |= src.channel; // Bitwise OR the desired channel bit with the existing bit mask. - break; - } - } - if(ir == inRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with. - inRoutes->push_back(src); - - return; - } - */ - MidiPort *mp = &MusEGlobal::midiPorts[src.midiPort]; - // p4.0.17 Do not allow ports with synth midi devices to connect to audio ins! - if(dst.track->type() == Track::AUDIO_INPUT && mp->device() && mp->device()->isSynti()) - { - fprintf(stderr, "addRoute: destination is audio in, but source midi port:%d is synth device\n", src.midiPort); + // Do not allow ports with synth midi devices to connect to audio ins! p4.0.17 + //if(dst.track->type() == Track::AUDIO_INPUT && mp->device() && mp->device()->isSynti()) + //{ + // fprintf(stderr, "addRoute: destination is audio in, but source midi port:%d is synth device\n", src.midiPort); + // return; + //} + // Actually, do not allow synth ports to connect to any track. It may be useful in some cases, + // may be desired later, but for now it's just a routing hassle. p4.0.35 + if(mp->device() && mp->device()->isSynti()) return; - } if(dst.channel < 1 || dst.channel >= (1 << MIDI_CHANNELS)) { @@ -443,46 +321,39 @@ void addRoute(Route src, Route dst) src.channel = dst.channel; RouteList* outRoutes = mp->outRoutes(); - //for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) - iRoute ir = outRoutes->begin(); // p3.3.50 + iRoute ir = outRoutes->begin(); for ( ; ir != outRoutes->end(); ++ir) { - //if (*i == dst) // route already there - if (ir->type == Route::TRACK_ROUTE && ir->track == dst.track) // p3.3.50 Does a route to the track exist? + if (ir->type == Route::TRACK_ROUTE && ir->track == dst.track) // Does a route to the track exist? { - //#ifdef ROUTE_DEBUG - //fprintf(stderr, "addRoute: src midi port:%d dst track:%s route already exists.\n", src.midiPort, dst.track->name().toLatin1().constData()); - //#endif - ir->channel |= dst.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask. + ir->channel |= dst.channel; // Bitwise OR the desired channel bit with the existing bit mask. break; - - //return; } } #ifdef ROUTE_DEBUG fprintf(stderr, "addRoute: src midi port:%d dst track name:%s pushing dst and src routes\n", src.midiPort, dst.track->name().toLatin1().constData()); #endif - if(ir == outRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with. + if(ir == outRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with. outRoutes->push_back(dst); RouteList* inRoutes = dst.track->inRoutes(); - // p3.3.50 Make sure only one single route, with a channel mask, can ever exist. + // Make sure only one single route, with a channel mask, can ever exist. ir = inRoutes->begin(); for ( ; ir != inRoutes->end(); ++ir) { - if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == src.midiPort) // p3.3.50 Does a route to the midi port exist? + if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == src.midiPort) // Does a route to the midi port exist? { - ir->channel |= src.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask. + ir->channel |= src.channel; // Bitwise OR the desired channel bit with the existing bit mask. break; } } - if(ir == inRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with. + if(ir == inRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with. inRoutes->push_back(src); } - else if(dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49 + else if(dst.type == Route::MIDI_PORT_ROUTE) { if(src.type != Route::TRACK_ROUTE) { @@ -495,7 +366,6 @@ void addRoute(Route src, Route dst) return; } - //MidiDevice *md = MusEGlobal::midiPorts[dst.midiPort].device(); //if(!md) //{ @@ -506,24 +376,17 @@ void addRoute(Route src, Route dst) dst.channel = src.channel; RouteList* outRoutes = src.track->outRoutes(); - //for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) - iRoute ir = outRoutes->begin(); // p3.3.50 + iRoute ir = outRoutes->begin(); for ( ; ir != outRoutes->end(); ++ir) { - //if (*i == dst) // route already there - if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == dst.midiPort) // p3.3.50 Does a route to the midi port exist? + if (ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == dst.midiPort) // Does a route to the midi port exist? { - //#ifdef ROUTE_DEBUG - //fprintf(stderr, "addRoute: dst midi port:%d src track:%s route already exists.\n", dst.midiPort, src.track->name().toLatin1().constData()); - //#endif - //return; - - ir->channel |= dst.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask. + ir->channel |= dst.channel; // Bitwise OR the desired channel bit with the existing bit mask. break; } } - if(ir == outRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with. + if(ir == outRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with. outRoutes->push_back(dst); MidiPort *mp = &MusEGlobal::midiPorts[dst.midiPort]; @@ -533,167 +396,97 @@ void addRoute(Route src, Route dst) #endif RouteList* inRoutes = mp->inRoutes(); - // p3.3.50 Make sure only one single route, with a channel mask, can ever exist. + // Make sure only one single route, with a channel mask, can ever exist. ir = inRoutes->begin(); for ( ; ir != inRoutes->end(); ++ir) { - if (ir->type == Route::TRACK_ROUTE && ir->track == src.track) // p3.3.50 Does a route to the track exist? + if (ir->type == Route::TRACK_ROUTE && ir->track == src.track) // Does a route to the track exist? { - ir->channel |= src.channel; // p3.3.50 Bitwise OR the desired channel bit with the existing bit mask. + ir->channel |= src.channel; // Bitwise OR the desired channel bit with the existing bit mask. break; } } - if(ir == inRoutes->end()) // p3.3.50 Only if route not found, add the route, with the requested channel bits as mask to start with. + if(ir == inRoutes->end()) // Only if route not found, add the route, with the requested channel bits as mask to start with. inRoutes->push_back(src); - //inRoutes->insert(inRoutes->begin(), src); } else { - if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE) // p3.3.49 + if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE) { fprintf(stderr, "addRoute: source or destination are not track routes\n"); return; } - // Removed p3.3.49 - /* - //if ((src.type == Route::JACK_MIDI_ROUTE) || (src.type == Route::ALSA_MIDI_ROUTE)) - if(src.type == Route::MIDI_DEVICE_ROUTE) - { - //src.channel = src.dstChannel = dst.dstChannel = dst.channel; - src.channel = dst.channel; - //src.channels = dst.channels = 1; - RouteList* outRoutes = src.device->outRoutes(); - #ifdef ROUTE_DEBUG - fprintf(stderr, "addRoute: src name: %s looking for existing dest in out routes...\n", src.device->name().toLatin1().constData()); - #endif - for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) - { - if (*i == dst) // route already there - { - //#ifdef ROUTE_DEBUG - fprintf(stderr, "addRoute: src Jack or ALSA midi route already exists.\n"); - //#endif - return; - } - } - #ifdef ROUTE_DEBUG - fprintf(stderr, "addRoute: src midi dst name: %s pushing destination and source routes\n", dst.track->name().toLatin1().constData()); - #endif - - outRoutes->push_back(dst); - RouteList* inRoutes = dst.track->inRoutes(); - inRoutes->push_back(src); - } - else - */ + RouteList* outRoutes = src.track->outRoutes(); - { - ///if(dst.type == Route::MIDI_DEVICE_ROUTE) // Removed p3.3.49 - //{ - /// dst.channel = src.channel; - //src.channel = src.dstChannel = dst.dstChannel = dst.channel; - //src.channels = dst.channels = 1; - //} - //else - //{ - //src.channel = src.dstChannel = dst.dstChannel = dst.channel; - //src.channels = dst.channels = 1; - //} - - RouteList* outRoutes = src.track->outRoutes(); - - // - // Must enforce to ensure channel and channels are valid if defaults of -1 passed. - // - if(src.track->type() == Track::AUDIO_SOFTSYNTH) - { - if(src.channel == -1) - src.channel = 0; - if(src.channels == -1) - src.channels = src.track->channels(); - //if(dst.type == Route::TRACK_ROUTE) // p3.3.49 Removed - //{ - //if(dst.channel == -1) - // dst.channel = 0; - //if(dst.channels == -1) - // Yes, that's correct: dst channels = src track channels. - // dst.channels = src.track->channels(); - dst.channel = src.channel; - dst.channels = src.channels; - dst.remoteChannel = src.remoteChannel; - //} - } - //if(dst.type == Route::TRACK_ROUTE && dst.track->type() == Track::AUDIO_SOFTSYNTH) - //{ - // if(dst.channel == -1) - // dst.channel = 0; - // if(dst.channels == -1) - // Yes, that's correct: dst channels = src track channels. - // dst.channels = src.track->channels(); - //} - - for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) - { - if (*i == dst) // route already there - // TODO: - //if (i->type == dst.type && i->channel == dst.channel) + // + // Must enforce to ensure channel and channels are valid if defaults of -1 passed. + // + if(src.track->type() == Track::AUDIO_SOFTSYNTH) + { + if(src.channel == -1) + src.channel = 0; + if(src.channels == -1) + src.channels = src.track->channels(); + dst.channel = src.channel; + dst.channels = src.channels; + dst.remoteChannel = src.remoteChannel; + } + + for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) + { + if (*i == dst) // route already there + // TODO: + //if (i->type == dst.type && i->channel == dst.channel) + { + //if(i->type == Route::TRACK_ROUTE) + { + //if(i->track == dst.track) { - //if(i->type == Route::TRACK_ROUTE) + //if(i->channels == dst.channels) { - //if(i->track == dst.track) - { - //if(i->channels == dst.channels) - { - //#ifdef ROUTE_DEBUG - fprintf(stderr, "addRoute: src track route already exists.\n"); - //#endif - return; - } - //else - //{ - - //} - } + //#ifdef ROUTE_DEBUG + fprintf(stderr, "addRoute: src track route already exists.\n"); + //#endif + return; } - } - } - outRoutes->push_back(dst); - RouteList* inRoutes; - - // Removed p3.3.49 - /* - //if ((dst.type == Route::JACK_MIDI_ROUTE) || (dst.type == Route::ALSA_MIDI_ROUTE)) - if(dst.type == Route::MIDI_DEVICE_ROUTE) - { - #ifdef ROUTE_DEBUG - fprintf(stderr, "addRoute: src track dst midi name: %s pushing destination and source routes\n", dst.device->name().toLatin1().constData()); - #endif - inRoutes = dst.device->inRoutes(); - } - else - */ - - { - #ifdef ROUTE_DEBUG - //fprintf(stderr, "addRoute: src track ch:%d chs:%d dst track ch:%d chs:%d name: %s pushing destination and source routes\n", src.channel, src.channels, dst.channel, dst.channels, dst.track->name().toLatin1().constData()); - fprintf(stderr, "addRoute: src track ch:%d chs:%d remch:%d dst track ch:%d chs:%d remch:%d name: %s pushing dest and source routes\n", - src.channel, src.channels, src.remoteChannel, dst.channel, dst.channels, dst.remoteChannel, dst.track->name().toLatin1().constData()); - //fprintf(stderr, "addRoute: src track ch:%d dst track ch:%d name: %s pushing destination and source routes\n", src.channel, dst.channel, dst.track->name().toLatin1().constData()); - #endif - inRoutes = dst.track->inRoutes(); - } - - - // - // make sure AUDIO_AUX is processed last - // - if (src.track->type() == Track::AUDIO_AUX) - inRoutes->push_back(src); - else - inRoutes->insert(inRoutes->begin(), src); - } + //else + //{ + + //} + } + } + } + } + outRoutes->push_back(dst); + RouteList* inRoutes; + + #ifdef ROUTE_DEBUG + //fprintf(stderr, "addRoute: src track ch:%d chs:%d dst track ch:%d chs:%d name: %s pushing destination and source routes\n", src.channel, src.channels, dst.channel, dst.channels, dst.track->name().toLatin1().constData()); + fprintf(stderr, "addRoute: src track ch:%d chs:%d remch:%d dst track ch:%d chs:%d remch:%d name: %s pushing dest and source routes\n", + src.channel, src.channels, src.remoteChannel, dst.channel, dst.channels, dst.remoteChannel, dst.track->name().toLatin1().constData()); + //fprintf(stderr, "addRoute: src track ch:%d dst track ch:%d name: %s pushing destination and source routes\n", src.channel, dst.channel, dst.track->name().toLatin1().constData()); + #endif + inRoutes = dst.track->inRoutes(); + + // + // make sure AUDIO_AUX is processed last + // + if (src.track->type() == Track::AUDIO_AUX) // REMOVE Tim. This special aux code may not be useful or needed now. + inRoutes->push_back(src); // + else + inRoutes->insert(inRoutes->begin(), src); + + // Is the source an Aux Track or else does it have Aux Tracks routed to it? + // Update the destination track's aux ref count, and all tracks it is routed to. + if(src.track->auxRefCount()) + //dst.track->updateAuxStates( src.track->auxRefCount() ); + src.track->updateAuxRoute( src.track->auxRefCount(), dst.track ); + else + if(src.track->type() == Track::AUDIO_AUX) + //dst.track->updateAuxStates( 1 ); + src.track->updateAuxRoute( 1, dst.track ); } } @@ -709,12 +502,6 @@ void removeRoute(Route src, Route dst) if (src.type == Route::JACK_ROUTE) { - //if (dst.type != TRACK_ROUTE) - //{ - // fprintf(stderr, "removeRoute: bad route 1\n"); - // exit(-1); - // return; - //} if(!dst.isValid()) { printf("removeRoute: source is jack, invalid destination\n"); @@ -726,7 +513,6 @@ void removeRoute(Route src, Route dst) if (dst.track->type() != Track::AUDIO_INPUT) { fprintf(stderr, "removeRoute: source is jack, destination is track but not audio input\n"); - // exit(-1); return; } RouteList* inRoutes = dst.track->inRoutes(); @@ -741,7 +527,6 @@ void removeRoute(Route src, Route dst) } } else - //if (dst.type == Route::JACK_MIDI_ROUTE) if (dst.type == Route::MIDI_DEVICE_ROUTE) { RouteList* routes = dst.device->inRoutes(); @@ -758,18 +543,11 @@ void removeRoute(Route src, Route dst) else { fprintf(stderr, "removeRoute: source is jack, destination unknown\n"); - // exit(-1); return; } } else if (dst.type == Route::JACK_ROUTE) { - //if (src.type != TRACK_ROUTE) - //{ - // fprintf(stderr, "removeRoute: bad route 3\n"); - // exit(-1); - // return; - //} if(!src.isValid()) { printf("removeRoute: destination is jack, invalid source\n"); @@ -781,7 +559,6 @@ void removeRoute(Route src, Route dst) if (src.track->type() != Track::AUDIO_OUTPUT) { fprintf(stderr, "removeRoute: destination is jack, source is track but not audio output\n"); - // exit(-1); return; } RouteList* outRoutes = src.track->outRoutes(); @@ -795,7 +572,6 @@ void removeRoute(Route src, Route dst) } } else - //if (src.type == Route::JACK_MIDI_ROUTE) if (src.type == Route::MIDI_DEVICE_ROUTE) { RouteList* routes = src.device->outRoutes(); @@ -811,11 +587,10 @@ void removeRoute(Route src, Route dst) else { fprintf(stderr, "removeRoute: destination is jack, source unknown\n"); - // exit(-1); return; } } - else if(src.type == Route::MIDI_PORT_ROUTE) // p3.3.49 + else if(src.type == Route::MIDI_PORT_ROUTE) { if(dst.type != Route::TRACK_ROUTE) { @@ -829,19 +604,18 @@ void removeRoute(Route src, Route dst) RouteList* outRoutes = mp->outRoutes(); for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) { - //if (*i == dst) - if(i->type == Route::TRACK_ROUTE && i->track == dst.track) // p3.3.50 Is there a route to the track? + if(i->type == Route::TRACK_ROUTE && i->track == dst.track) // Is there a route to the track? { //printf("i->channel:%x dst.channel:%x\n", i->channel, dst.channel); - i->channel &= ~dst.channel; // p3.3.50 Unset the desired channel bits. + i->channel &= ~dst.channel; // Unset the desired channel bits. if(i->channel == 0) // Only if there are no channel bits set, erase the route. { //printf("erasing out route from midi port:%d\n", src.midiPort); outRoutes->erase(i); } - break; // For safety, keep looking and remove any more found. - // No, must break, else crash. There should only be one route anyway... + break; // For safety, keep looking and remove any more found. + // No, must break, else crash. There should only be one route anyway... } } } @@ -853,22 +627,21 @@ void removeRoute(Route src, Route dst) RouteList* inRoutes = dst.track->inRoutes(); for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) { - //if (*i == src) - if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == src.midiPort) // p3.3.50 Is there a route to the midi port? + if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == src.midiPort) // Is there a route to the midi port? { - i->channel &= ~src.channel; // p3.3.50 Unset the desired channel bits. + i->channel &= ~src.channel; // Unset the desired channel bits. if(i->channel == 0) // Only if there are no channel bits set, erase the route. inRoutes->erase(i); - break; // For safety, keep looking and remove any more found. - // No, must break, else crash. There should only be one route anyway... + break; // For safety, keep looking and remove any more found. + // No, must break, else crash. There should only be one route anyway... } } } else printf("removeRoute: source is midi port:%d but destination track invalid\n", src.midiPort); } - else if(dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49 + else if(dst.type == Route::MIDI_PORT_ROUTE) { if(src.type != Route::TRACK_ROUTE) { @@ -881,15 +654,14 @@ void removeRoute(Route src, Route dst) RouteList* outRoutes = src.track->outRoutes(); for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) { - //if (*i == dst) - if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == dst.midiPort) // p3.3.50 Is there a route to the midi port? + if (i->type == Route::MIDI_PORT_ROUTE && i->midiPort == dst.midiPort) // Is there a route to the midi port? { - i->channel &= ~dst.channel; // p3.3.50 Unset the desired channel bits. + i->channel &= ~dst.channel; // Unset the desired channel bits. if(i->channel == 0) // Only if there are no channel bits set, erase the route. outRoutes->erase(i); - break; // For safety, keep looking and remove any more found. - // No, must break, else crash. There should only be one route anyway... + break; // For safety, keep looking and remove any more found. + // No, must break, else crash. There should only be one route anyway... } } } @@ -902,15 +674,14 @@ void removeRoute(Route src, Route dst) RouteList* inRoutes = mp->inRoutes(); for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) { - //if (*i == src) - if (i->type == Route::TRACK_ROUTE && i->track == src.track) // p3.3.50 Is there a route to the track? + if (i->type == Route::TRACK_ROUTE && i->track == src.track) // Is there a route to the track? { - i->channel &= ~src.channel; // p3.3.50 Unset the desired channel bits. + i->channel &= ~src.channel; // Unset the desired channel bits. if(i->channel == 0) // Only if there are no channel bits set, erase the route. inRoutes->erase(i); - break; // For safety, keep looking and remove any more found. - // No, must break, else crash. There should only be one route anyway... + break; // For safety, keep looking and remove any more found. + // No, must break, else crash. There should only be one route anyway... } } } @@ -919,87 +690,54 @@ void removeRoute(Route src, Route dst) } else { - if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE) // p3.3.49 + if(src.type != Route::TRACK_ROUTE || dst.type != Route::TRACK_ROUTE) { fprintf(stderr, "removeRoute: source and destination are not tracks\n"); return; } - // Removed p3.3.49 - /* - //if((src.type == Route::JACK_MIDI_ROUTE) || (src.type == Route::ALSA_MIDI_ROUTE)) - if(src.type == Route::MIDI_DEVICE_ROUTE) + // Is the source an Aux Track or else does it have Aux Tracks routed to it? + // Update the destination track's aux ref count, and all tracks it is routed to. + if(src.isValid() && dst.isValid()) { - if(src.isValid()) - { - RouteList* outRoutes = src.device->outRoutes(); - for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) - { - if (*i == dst) { - outRoutes->erase(i); - break; - } - } - } + if(src.track->auxRefCount()) + //dst.track->updateAuxStates( -src.track->auxRefCount() ); + src.track->updateAuxRoute( -src.track->auxRefCount(), dst.track ); else - printf("removeRoute: source is midi but invalid\n"); - - if(dst.isValid()) + if(src.track->type() == Track::AUDIO_AUX) + //dst.track->updateAuxStates( -1 ); + src.track->updateAuxRoute( -1, dst.track ); + } + + if(src.isValid()) + { + RouteList* outRoutes = src.track->outRoutes(); + for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) { - RouteList* inRoutes = dst.track->inRoutes(); - for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) - { - if (*i == src) { - inRoutes->erase(i); - break; - } - } + if (*i == dst) { + outRoutes->erase(i); + break; + } } - else - printf("removeRoute: source is midi but destination invalid\n"); - } + } else - */ + printf("removeRoute: source is track but invalid\n"); + if(dst.isValid()) { - if(src.isValid()) - { - RouteList* outRoutes = src.track->outRoutes(); - for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) - { - if (*i == dst) { - outRoutes->erase(i); - break; - } - } - } - else - printf("removeRoute: source is track but invalid\n"); + RouteList* inRoutes; - if(dst.isValid()) + inRoutes = dst.track->inRoutes(); + for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) { - RouteList* inRoutes; - - //if ((dst.type == Route::JACK_MIDI_ROUTE) || (dst.type == Route::ALSA_MIDI_ROUTE)) - // Removed p3.3.49 - /* - if (dst.type == Route::MIDI_DEVICE_ROUTE) - inRoutes = dst.device->inRoutes(); - else - */ - - inRoutes = dst.track->inRoutes(); - for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) - { - if (*i == src) { - inRoutes->erase(i); - break; - } - } - } - else - printf("removeRoute: source is track but destination invalid\n"); - } + if (*i == src) { + inRoutes->erase(i); + break; + } + } + } + else + printf("removeRoute: source is track but destination invalid\n"); } } @@ -1013,9 +751,19 @@ void removeRoute(Route src, Route dst) // So far it only works with MidiDevice <-> Jack. //--------------------------------------------------------- -// p3.3.55 void removeAllRoutes(Route src, Route dst) { + // TODO: Is the source an Aux Track or else does it have Aux Tracks routed to it? + // Update the destination track's aux ref count, and all tracks it is routed to. + /* if(src.isValid() && dst.isValid()) + { + if(src.track->auxRefCount()) + dst.track->updateAuxStates( -src.track->auxRefCount() ); + else + if(src.track->type() == Track::TrackType::AUDIO_AUX)) + dst.track->updateAuxStates( -1 ); + } */ + if(src.isValid()) { if(src.type == Route::MIDI_DEVICE_ROUTE) @@ -1052,22 +800,11 @@ static QString track2name(const Track* n) QString Route::name() const { - // p3.3.38 Removed - /* - QString s; - if ((type == TRACK_ROUTE) && (channel != -1)) { -// if (channel != -1) { - QString c; - c.setNum(channel+1); - s = c + ":"; - } - */ - if(type == MIDI_DEVICE_ROUTE) { if(device) { - // p3.3.55 Removed for unified jack in/out devices, the actual port names are now different from device name. + // For unified jack in/out devices, the actual port names are now different from device name. // Like this: device: "MyJackDevice1" -> inport: "MyJackDevice1_in" outport: "MyJackDevice1_out" /* if(device->deviceType() == MidiDevice::JACK_MIDI) @@ -1075,8 +812,7 @@ QString Route::name() const else */ - //if(device->deviceType() == MidiDevice::ALSA_MIDI) - return device->name(); + return device->name(); } return QWidget::tr("None"); } @@ -1084,16 +820,14 @@ QString Route::name() const if(type == JACK_ROUTE) { if (!MusEGlobal::checkAudioDevice()) return ""; - //return s + MusEGlobal::audioDevice->portName(jackPort); return MusEGlobal::audioDevice->portName(jackPort); } else - if(type == MIDI_PORT_ROUTE) // p3.3.49 + if(type == MIDI_PORT_ROUTE) { return ROUTE_MIDIPORT_NAME_PREFIX + QString().setNum(midiPort); } else - //return s + track2name(track); return track2name(track); } @@ -1106,7 +840,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) { // printf("name2route %s\n", rn.toLatin1().constData()); int channel = -1; - //int channel = 0; QString s(rn); // Support old route style in med files. Obsolete. if (rn[0].isNumber() && rn[1]==':') @@ -1117,8 +850,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) if(rtype == -1) { - //if(dst) - //{ if(MusEGlobal::checkAudioDevice()) { void* p = MusEGlobal::audioDevice->findPort(s.toLatin1().constData()); @@ -1149,7 +880,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) return Route(*i, channel); } - // p3.3.49 if(s.left(ROUTE_MIDIPORT_NAME_PREFIX.length()) == ROUTE_MIDIPORT_NAME_PREFIX) { bool ok = false; @@ -1160,8 +890,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) } else { - //if(dst) - //{ if(rtype == Route::TRACK_ROUTE) { TrackList* tl = MusEGlobal::song->tracks(); @@ -1178,8 +906,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) AudioTrack* track = (AudioTrack*)*i; if(track->name() == s) return Route(track, channel); - //return Route(track, channel, 1); - //return Route(track, channel, track->channels()); } } } @@ -1191,7 +917,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) for(iMidiDevice i = MusEGlobal::midiDevices.begin(); i != MusEGlobal::midiDevices.end(); ++i) { if((*i)->name() == s) - //if (jmd->name() == rn) return Route(*i, channel); /* @@ -1224,7 +949,7 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) } } else - if(rtype == Route::MIDI_PORT_ROUTE) // p3.3.49 + if(rtype == Route::MIDI_PORT_ROUTE) { if(s.left(ROUTE_MIDIPORT_NAME_PREFIX.length()) == ROUTE_MIDIPORT_NAME_PREFIX) { @@ -1238,7 +963,6 @@ Route name2route(const QString& rn, bool /*dst*/, int rtype) printf(" name2route: <%s> not found\n", rn.toLatin1().constData()); return Route((Track*) 0, channel); - //return Route((Track*) 0, channel, 1); } //--------------------------------------------------------- @@ -1255,10 +979,6 @@ bool checkRoute(const QString& s, const QString& d) return false; if (src.type == Route::JACK_ROUTE) { - //if (dst.type != TRACK_ROUTE) { - // return false; - // } - if (dst.type == Route::TRACK_ROUTE) { if (dst.track->type() != Track::AUDIO_INPUT) { @@ -1274,12 +994,9 @@ bool checkRoute(const QString& s, const QString& d) } } else - //if (dst.type == Route::JACK_MIDI_ROUTE) if (dst.type == Route::MIDI_DEVICE_ROUTE) { - //src.channel = dst.channel; src.channel = -1; - //dst.channel = -1; RouteList* routes = dst.device->inRoutes(); for (ciRoute i = routes->begin(); i != routes->end(); ++i) { @@ -1293,10 +1010,6 @@ bool checkRoute(const QString& s, const QString& d) } else if (dst.type == Route::JACK_ROUTE) { - //if (src.type != TRACK_ROUTE) { - // return false; - // } - if (src.type == Route::TRACK_ROUTE) { if (src.track->type() != Track::AUDIO_OUTPUT) { @@ -1312,13 +1025,10 @@ bool checkRoute(const QString& s, const QString& d) } } else - //if (src.type == Route::JACK_MIDI_ROUTE) if (src.type == Route::MIDI_DEVICE_ROUTE) { RouteList* routes = src.device->outRoutes(); - //dst.channel = src.channel; dst.channel = -1; - //src.channel = -1; for (ciRoute i = routes->begin(); i != routes->end(); ++i) { if (*i == dst) { // route already there @@ -1329,7 +1039,7 @@ bool checkRoute(const QString& s, const QString& d) else return false; } - else if (src.type == Route::MIDI_PORT_ROUTE) // p3.3.49 + else if (src.type == Route::MIDI_PORT_ROUTE) { RouteList* outRoutes = MusEGlobal::midiPorts[src.midiPort].outRoutes(); for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) @@ -1339,13 +1049,11 @@ bool checkRoute(const QString& s, const QString& d) } } } - //else if (dst.type == Route::MIDI_PORT_ROUTE) // p3.3.49 + //else if (dst.type == Route::MIDI_PORT_ROUTE) //{ //} else { - //RouteList* outRoutes = ((src.type == Route::JACK_MIDI_ROUTE) || (src.type == Route::ALSA_MIDI_ROUTE)) ? - // src.device->outRoutes() : src.track->outRoutes(); RouteList* outRoutes = (src.type == Route::MIDI_DEVICE_ROUTE) ? src.device->outRoutes() : src.track->outRoutes(); for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) @@ -1366,7 +1074,7 @@ void Route::read(Xml& xml) { QString s; int dtype = MidiDevice::ALSA_MIDI; - int port = -1; // p3.3.49 + int port = -1; unsigned char rtype = Route::TRACK_ROUTE; for (;;) @@ -1397,7 +1105,7 @@ void Route::read(Xml& xml) if(tag == "name") s = xml.s2(); else - if(tag == "mport") // p3.3.49 + if(tag == "mport") { port = xml.s2().toInt(); rtype = Route::MIDI_PORT_ROUTE; @@ -1409,7 +1117,7 @@ void Route::read(Xml& xml) #ifdef ROUTE_DEBUG printf("Route::read(): tag end type:%d channel:%d name:%s\n", rtype, channel, s.toLatin1().constData()); #endif - if(rtype == MIDI_PORT_ROUTE) // p3.3.49 + if(rtype == MIDI_PORT_ROUTE) { if(port >= 0 && port < MIDI_PORTS) { @@ -1462,7 +1170,6 @@ void Route::read(Xml& xml) MidiDevice* md = *imd; if(md->name() == s && md->deviceType() == dtype) { - // p3.3.45 // We found a device, but if it is not in use by the song (port is -1), ignore it. // This prevents loading and propagation of bogus routes in the med file. if(md->midiPort() == -1) @@ -1509,7 +1216,7 @@ void Song::readRoute(Xml& xml) case Xml::End: return; case Xml::TagStart: - // p3.3.38 2010/02/03 Support old routes in med files. Now obsolete! + // 2010/02/03 Support old routes in med files. Now obsolete! if (tag == "srcNode") src = xml.parse1(); else if (tag == "dstNode") @@ -1545,7 +1252,7 @@ void Song::readRoute(Xml& xml) if(tag == "remch") remch = xml.s2().toInt(); else - if(tag == "channelMask") // p3.3.50 New channel mask for midi port-track routes. + if(tag == "channelMask") // New channel mask for midi port-track routes. ch = xml.s2().toInt(); else printf("Song::readRoute(): unknown attribute:%s\n", tag.toLatin1().constData()); @@ -1564,17 +1271,17 @@ void Song::readRoute(Xml& xml) // Support new routes. if(sroute.isValid() && droute.isValid()) { - // p3.3.49 Support pre- 1.1-RC2 midi-device-to-track routes. Obsolete. Replaced with midi port routes. + // Support pre- 1.1-RC2 midi-device-to-track routes. Obsolete. Replaced with midi port routes. if(sroute.type == Route::MIDI_DEVICE_ROUTE && droute.type == Route::TRACK_ROUTE) { if(sroute.device->midiPort() >= 0 && sroute.device->midiPort() < MIDI_PORTS - && ch >= 0 && ch < MIDI_CHANNELS) // p3.3.50 + && ch >= 0 && ch < MIDI_CHANNELS) { sroute.midiPort = sroute.device->midiPort(); sroute.device = 0; sroute.type = Route::MIDI_PORT_ROUTE; - sroute.channel = 1 << ch; // p3.3.50 Convert to new bit-wise channel mask. + sroute.channel = 1 << ch; // Convert to new bit-wise channel mask. droute.channel = sroute.channel; addRoute(sroute, droute); @@ -1586,13 +1293,13 @@ void Song::readRoute(Xml& xml) else if(sroute.type == Route::TRACK_ROUTE && droute.type == Route::MIDI_DEVICE_ROUTE) { if(droute.device->midiPort() >= 0 && droute.device->midiPort() < MIDI_PORTS - && ch >= 0 && ch < MIDI_CHANNELS) // p3.3.50 + && ch >= 0 && ch < MIDI_CHANNELS) { droute.midiPort = droute.device->midiPort(); droute.device = 0; droute.type = Route::MIDI_PORT_ROUTE; - droute.channel = 1 << ch; // p3.3.50 Convert to new bit-wise channel mask. + droute.channel = 1 << ch; // Convert to new bit-wise channel mask. sroute.channel = droute.channel; addRoute(sroute, droute); @@ -1659,7 +1366,7 @@ void Route::dump() const printf("Route dump: jack audio port <%s> channel %d\n", MusEGlobal::audioDevice->portName(jackPort).toLatin1().constData(), channel); } else - if (type == MIDI_PORT_ROUTE) // p3.3.49 + if (type == MIDI_PORT_ROUTE) { printf("Route dump: midi port <%d> channel mask %d\n", midiPort, channel); } @@ -1672,8 +1379,6 @@ void Route::dump() const if(device->deviceType() == MidiDevice::JACK_MIDI) { if(MusEGlobal::checkAudioDevice()) - //printf("jack midi port device <%s> ", MusEGlobal::audioDevice->portName(device->clientPort()).toLatin1().constData()); - // p3.3.55 { printf("jack midi device <%s> ", device->name().toLatin1().constData()); if(device->inClientPort()) @@ -1730,36 +1435,16 @@ bool Route::operator==(const Route& a) const { //if (!MusEGlobal::checkAudioDevice()) return false; //return MusEGlobal::audioDevice->portName(jackPort) == MusEGlobal::audioDevice->portName(a.jackPort); - // p3.3.55 Simplified. - return jackPort == a.jackPort; + return jackPort == a.jackPort; // Simplified. } else - if (type == MIDI_PORT_ROUTE) // p3.3.49 + if (type == MIDI_PORT_ROUTE) { return midiPort == a.midiPort; } else if (type == MIDI_DEVICE_ROUTE) { - // p3.3.55 Changed for unified jack in/out devices, the actual port names are now different from device name. - // Like this: device: "MyJackDevice1" -> inport: "MyJackDevice1_in" outport: "MyJackDevice1_out" - /* - if(device && a.device && device->deviceType() == a.device->deviceType()) - { - if(device->deviceType() == MidiDevice::JACK_MIDI) - { - if (!MusEGlobal::checkAudioDevice()) return false; - return MusEGlobal::audioDevice->portName(device->clientPort()) == MusEGlobal::audioDevice->portName(a.device->clientPort()); - } - else - if(device->deviceType() == MidiDevice::ALSA_MIDI) - // TODO: OK ?? - return device->clientPort() == a.device->clientPort() && (channel == a.channel); - else - if(device->deviceType() == MidiDevice::SYNTH_MIDI) - return device->name() == a.device->name(); - } - */ return device == a.device; } } @@ -1767,4 +1452,56 @@ bool Route::operator==(const Route& a) const return false; } +/* +//--------------------------------------------------------- +// isCircularRoute +// Recursive. +// If dst is valid, start traversal from there, not from src. +// Returns true if circular. +//--------------------------------------------------------- + +bool isCircularRoutePath(Track* src, Track* dst) +{ + //if(isMidiTrack() || _type == AUDIO_AUX) + //if(isMidiTrack()) + // return; + + bool rv = false; + + if(dst) + { + src->setNodeTraversed(true); + rv = isCircularRoutePath(dst, NULL); + src->setNodeTraversed(false); + //if(rv) + // fprintf(stderr, " Circular route %s -> %s\n", src->name().toLatin1().constData(), dst->name().toLatin1().constData()); + return rv; + } + + if(src->nodeTraversed()) + return true; + + src->setNodeTraversed(true); + + //printf("isCircularRoute %s\n", src->name().toLatin1().constData()); + + RouteList* orl = src->outRoutes(); + for (iRoute i = orl->begin(); i != orl->end(); ++i) + { + if( !(*i).isValid() || (*i).type != Route::TRACK_ROUTE ) + continue; + Track* t = (*i).track; + //if(t->isMidiTrack()) + // continue; + rv = isCircularRoutePath(src, NULL); + if(rv) + break; + } + + src->setNodeTraversed(false); + return rv; +} +*/ + + } // namespace MusECore diff --git a/muse2/muse/route.h b/muse2/muse/route.h index 36b00d47..587369bc 100644 --- a/muse2/muse/route.h +++ b/muse2/muse/route.h @@ -4,6 +4,7 @@ // $Id: route.h,v 1.5.2.1 2008/05/21 00:28:52 terminator356 Exp $ // // (C) Copyright 2001 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -43,17 +44,15 @@ class Xml; //--------------------------------------------------------- struct Route { - enum { TRACK_ROUTE=0, JACK_ROUTE=1, MIDI_DEVICE_ROUTE=2, MIDI_PORT_ROUTE=3 }; // p3.3.49 + enum { TRACK_ROUTE=0, JACK_ROUTE=1, MIDI_DEVICE_ROUTE=2, MIDI_PORT_ROUTE=3 }; union { - //AudioTrack* track; Track* track; - //MidiJackDevice* device; MidiDevice* device; void* jackPort; }; - int midiPort; // p3.3.49 Midi port number. Best not to put this in the union to avoid problems? + int midiPort; // Midi port number. Best not to put this in the union to avoid problems? //snd_seq_addr_t alsaAdr; @@ -75,7 +74,7 @@ struct Route { Route(void* t, int ch=-1); Route(Track* t, int ch = -1, int chans = -1); Route(MidiDevice* d, int ch); - Route(int port, int ch); // p3.3.49 + Route(int port, int ch); Route(const QString&, bool dst, int ch, int rtype = -1); Route(); @@ -84,7 +83,7 @@ struct Route { bool isValid() const { return ((type == TRACK_ROUTE) && (track != 0)) || ((type == JACK_ROUTE) && (jackPort != 0)) || ((type == MIDI_DEVICE_ROUTE) && (device != 0)) || - ((type == MIDI_PORT_ROUTE) && (midiPort >= 0) && (midiPort < MIDI_PORTS)); // p3.3.49 + ((type == MIDI_PORT_ROUTE) && (midiPort >= 0) && (midiPort < MIDI_PORTS)); } void read(Xml& xml); void dump() const; @@ -106,6 +105,7 @@ extern void removeRoute(Route, Route); extern void removeAllRoutes(Route, Route); // p3.3.55 extern Route name2route(const QString&, bool dst, int rtype = -1); extern bool checkRoute(const QString&, const QString&); +//extern bool isCircularRoutePath(Track* src, Track* dst); // Recursive. //--------------------------------------------------------- // RouteMenuMap diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp index 132eef97..cefb198e 100644 --- a/muse2/muse/shortcuts.cpp +++ b/muse2/muse/shortcuts.cpp @@ -66,7 +66,7 @@ void initShortCuts() defShrt(SHRT_COPY, Qt::CTRL + Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy"), INVIS_SHRT, "copy"); defShrt(SHRT_COPY_RANGE, Qt::CTRL + Qt::SHIFT + Qt::Key_C, QT_TRANSLATE_NOOP("shortcuts", "Edit: Copy in range"), GLOBAL_SHRT, "copy_range"); defShrt(SHRT_UNDO, Qt::CTRL + Qt::Key_Z, QT_TRANSLATE_NOOP("shortcuts", "Edit: Undo"), INVIS_SHRT, "undo"); - defShrt(SHRT_REDO, Qt::CTRL + Qt::Key_Y, QT_TRANSLATE_NOOP("shortcuts", "Edit: Redo"), INVIS_SHRT, "redo"); + defShrt(SHRT_REDO, Qt::CTRL + Qt::SHIFT + Qt::Key_Z, QT_TRANSLATE_NOOP("shortcuts", "Edit: Redo"), INVIS_SHRT, "redo"); defShrt(SHRT_CUT, Qt::CTRL + Qt::Key_X, QT_TRANSLATE_NOOP("shortcuts", "Edit: Cut"), INVIS_SHRT, "cut"); defShrt(SHRT_PASTE, Qt::CTRL + Qt::Key_V, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste"), INVIS_SHRT, "paste"); defShrt(SHRT_PASTE_DIALOG, Qt::CTRL + Qt::SHIFT + Qt::Key_V, QT_TRANSLATE_NOOP("shortcuts", "Edit: Paste (with dialog)"), GLOBAL_SHRT, "paste_dialog"); diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 70314035..36be50a0 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -156,6 +156,7 @@ void Song::setSig(const AL::TimeSignature& sig) Track* Song::addNewTrack(QAction* action, Track* insertAt) { +printf("Song::addNewTrack\n"); int n = action->data().toInt(); // Ignore negative numbers since this slot could be called by a menu or list etc. passing -1. if(n < 0) @@ -165,13 +166,20 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt) if(n >= MENU_ADD_SYNTH_ID_BASE) { n -= MENU_ADD_SYNTH_ID_BASE; + int ntype = n / MENU_ADD_SYNTH_ID_BASE; + if(ntype >= Synth::SYNTH_TYPE_END) + return 0; + + n %= MENU_ADD_SYNTH_ID_BASE; if(n >= (int)MusEGlobal::synthis.size()) return 0; - SynthI* si = createSynthI(MusEGlobal::synthis[n]->baseName(), MusEGlobal::synthis[n]->name(), insertAt); + //printf("Song::addNewTrack synth: type:%d idx:%d class:%s label:%s\n", ntype, n, MusEGlobal::synthis[n]->baseName().toLatin1().constData(), MusEGlobal::synthis[n]->name().toLatin1().constData()); + SynthI* si = createSynthI(MusEGlobal::synthis[n]->baseName(), MusEGlobal::synthis[n]->name(), (Synth::Type)ntype, insertAt); if(!si) return 0; - + if (MusEGlobal::config.unhideTracks) SynthI::setVisible(true); + // Add instance last in midi device list. for (int i = 0; i < MIDI_PORTS; ++i) { @@ -181,15 +189,19 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt) { MusEGlobal::midiSeq->msgSetMidiDevice(port, si); MusEGlobal::muse->changeConfig(true); // save configuration file - deselectTracks(); - si->setSelected(true); - update(); + if (SynthI::visible()) { + deselectTracks(); + si->setSelected(true); + update(); + } return si; } } - deselectTracks(); - si->setSelected(true); - update(SC_SELECTION); + if (SynthI::visible()) { + deselectTracks(); + si->setSelected(true); + update(SC_SELECTION); + } return si; } // Normal track. @@ -200,10 +212,14 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt) if((Track::TrackType)n >= Track::AUDIO_SOFTSYNTH) return 0; - Track* t = addTrack((Track::TrackType)n, insertAt); - deselectTracks(); - t->setSelected(true); - update(SC_SELECTION); + Undo operations; + Track* t = addTrack(operations, (Track::TrackType)n, insertAt); + applyOperationGroup(operations); + if (t->isVisible()) { + deselectTracks(); + t->setSelected(true); + update(SC_SELECTION); + } return t; } } @@ -216,53 +232,63 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt) // If insertAt is valid, inserts before insertAt. Else at the end after all tracks. //--------------------------------------------------------- -Track* Song::addTrack(Track::TrackType type, Track* insertAt) +Track* Song::addTrack(Undo& operations, Track::TrackType type, Track* insertAt) { + printf("Song::addTrack\n"); Track* track = 0; int lastAuxIdx = _auxs.size(); switch(type) { case Track::MIDI: track = new MidiTrack(); track->setType(Track::MIDI); + if (MusEGlobal::config.unhideTracks) MidiTrack::setVisible(true); break; case Track::DRUM: track = new MidiTrack(); track->setType(Track::DRUM); ((MidiTrack*)track)->setOutChannel(9); + if (MusEGlobal::config.unhideTracks) MidiTrack::setVisible(true); break; case Track::WAVE: track = new MusECore::WaveTrack(); ((AudioTrack*)track)->addAuxSend(lastAuxIdx); + if (MusEGlobal::config.unhideTracks) WaveTrack::setVisible(true); break; case Track::AUDIO_OUTPUT: track = new AudioOutput(); + if (MusEGlobal::config.unhideTracks) AudioOutput::setVisible(true); break; case Track::AUDIO_GROUP: track = new AudioGroup(); ((AudioTrack*)track)->addAuxSend(lastAuxIdx); + if (MusEGlobal::config.unhideTracks) AudioGroup::setVisible(true); break; case Track::AUDIO_AUX: track = new AudioAux(); + if (MusEGlobal::config.unhideTracks) AudioAux::setVisible(true); break; case Track::AUDIO_INPUT: track = new AudioInput(); ((AudioTrack*)track)->addAuxSend(lastAuxIdx); + if (MusEGlobal::config.unhideTracks) AudioInput::setVisible(true); break; case Track::AUDIO_SOFTSYNTH: printf("not implemented: Song::addTrack(SOFTSYNTH)\n"); // ((AudioTrack*)track)->addAuxSend(lastAuxIdx); break; default: - printf("Song::addTrack() illegal type %d\n", type); - abort(); + printf("THIS SHOULD NEVER HAPPEN: Song::addTrack() illegal type %d. returning NULL.\n" + "save your work if you can and expect soon crashes!\n", type); + return NULL; } track->setDefaultName(); int idx = insertAt ? _tracks.index(insertAt) : -1; - insertTrack1(track, idx); - msgInsertTrack(track, idx, true); - insertTrack3(track, idx); + // insertTrack1(track, idx); // this and the below are replaced + // msgInsertTrack(track, idx, true); // by the UndoOp-operation + // insertTrack3(track, idx); // does nothing + operations.push_back(UndoOp(UndoOp::AddTrack, idx, track)); // Add default track <-> midiport routes. if(track->isMidiTrack()) @@ -1928,7 +1954,7 @@ void Song::panic() // If clear_all is false, it will not touch things like midi ports. //--------------------------------------------------------- -void Song::clear(bool signal, bool /*clear_all*/) +void Song::clear(bool signal, bool clear_all) { if(MusEGlobal::debugMsg) printf("Song::clear\n"); @@ -1953,7 +1979,7 @@ void Song::clear(bool signal, bool /*clear_all*/) // p3.3.50 Reset this. MusEGlobal::midiPorts[i].setFoundInSongFile(false); - //if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems... + if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems... // This will also close the device. MusEGlobal::midiPorts[i].setMidiDevice(0); } @@ -1972,7 +1998,7 @@ void Song::clear(bool signal, bool /*clear_all*/) //if((*imd)->deviceType() == MidiDevice::JACK_MIDI) if(dynamic_cast< MidiJackDevice* >(*imd)) { - //if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems... + if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems... { // Remove the device from the list. MusEGlobal::midiDevices.erase(imd); @@ -2919,7 +2945,6 @@ void Song::insertTrack2(Track* track, int idx) break; default: fprintf(stderr, "unknown track type %d\n", track->type()); - // abort(); return; } @@ -2936,7 +2961,7 @@ void Song::insertTrack2(Track* track, int idx) for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i) { if ((*i)->isMidiTrack()) continue; - MusECore::WaveTrack* wt = (MusECore::WaveTrack*)*i; + MusECore::AudioTrack* wt = (MusECore::AudioTrack*)*i; if (wt->hasAuxSend()) { wt->addAuxSend(n); } @@ -2957,6 +2982,13 @@ void Song::insertTrack2(Track* track, int idx) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->outRoutes()->push_back(src); + // Is the source an Aux Track or else does it have Aux Tracks routed to it? + // Update the Audio Output track's aux ref count. p4.0.37 + if(r->track->auxRefCount()) + track->updateAuxRoute( r->track->auxRefCount(), NULL ); + else + if(r->track->type() == Track::AUDIO_AUX) + track->updateAuxRoute( 1, NULL ); } } else if (track->type() == Track::AUDIO_INPUT) @@ -2970,6 +3002,13 @@ void Song::insertTrack2(Track* track, int idx) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->inRoutes()->push_back(src); + // Is this track an Aux Track or else does it have Aux Tracks routed to it? + // Update the other track's aux ref count and all tracks it is connected to. p4.0.37 + if(track->auxRefCount()) + r->track->updateAuxRoute( track->auxRefCount(), NULL ); + else + if(track->type() == Track::AUDIO_AUX) + r->track->updateAuxRoute( 1, NULL ); } } else if (track->isMidiTrack()) // p3.3.50 @@ -3000,6 +3039,13 @@ void Song::insertTrack2(Track* track, int idx) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->outRoutes()->push_back(src); + // Is the source an Aux Track or else does it have Aux Tracks routed to it? + // Update this track's aux ref count. p4.0.37 + if(r->track->auxRefCount()) + track->updateAuxRoute( r->track->auxRefCount(), NULL ); + else + if(r->track->type() == Track::AUDIO_AUX) + track->updateAuxRoute( 1, NULL ); } rl = track->outRoutes(); for (ciRoute r = rl->begin(); r != rl->end(); ++r) @@ -3010,6 +3056,13 @@ void Song::insertTrack2(Track* track, int idx) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->inRoutes()->push_back(src); + // Is this track an Aux Track or else does it have Aux Tracks routed to it? + // Update the other track's aux ref count and all tracks it is connected to. p4.0.37 + if(track->auxRefCount()) + r->track->updateAuxRoute( track->auxRefCount(), NULL ); + else + if(track->type() == Track::AUDIO_AUX) + r->track->updateAuxRoute( 1, NULL ); } } @@ -3022,18 +3075,9 @@ void Song::insertTrack2(Track* track, int idx) // non realtime part of insertTrack //--------------------------------------------------------- +// empty. gets executed after the realtime part void Song::insertTrack3(Track* /*track*/, int /*idx*/)//prevent compiler warning: unused parameter { - //printf("Song::insertTrack3\n"); - - /* - switch(track->type()) { - case Track::AUDIO_SOFTSYNTH: - break; - default: - break; - } - */ } //--------------------------------------------------------- @@ -3153,6 +3197,13 @@ void Song::removeTrack2(Track* track) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->outRoutes()->removeRoute(src); + // Is the source an Aux Track or else does it have Aux Tracks routed to it? + // Update the Audio Output track's aux ref count. p4.0.37 + if(r->track->auxRefCount()) + track->updateAuxRoute( -r->track->auxRefCount(), NULL ); + else + if(r->track->type() == Track::AUDIO_AUX) + track->updateAuxRoute( -1, NULL ); } } else if (track->type() == Track::AUDIO_INPUT) @@ -3167,6 +3218,13 @@ void Song::removeTrack2(Track* track) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->inRoutes()->removeRoute(src); + // Is this track an Aux Track or else does it have Aux Tracks routed to it? + // Update the other track's aux ref count and all tracks it is connected to. p4.0.37 + if(track->auxRefCount()) + r->track->updateAuxRoute( -track->auxRefCount(), NULL ); + else + if(track->type() == Track::AUDIO_AUX) + r->track->updateAuxRoute( -1, NULL ); } } else if (track->isMidiTrack()) // p3.3.50 @@ -3198,6 +3256,13 @@ void Song::removeTrack2(Track* track) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->outRoutes()->removeRoute(src); + // Is the source an Aux Track or else does it have Aux Tracks routed to it? + // Update this track's aux ref count. p4.0.37 + if(r->track->auxRefCount()) + track->updateAuxRoute( -r->track->auxRefCount(), NULL ); + else + if(r->track->type() == Track::AUDIO_AUX) + track->updateAuxRoute( -1, NULL ); } rl = track->outRoutes(); for (ciRoute r = rl->begin(); r != rl->end(); ++r) @@ -3209,6 +3274,13 @@ void Song::removeTrack2(Track* track) Route src(track, r->channel, r->channels); src.remoteChannel = r->remoteChannel; r->track->inRoutes()->removeRoute(src); + // Is this track an Aux Track or else does it have Aux Tracks routed to it? + // Update the other track's aux ref count and all tracks it is connected to. p4.0.37 + if(track->auxRefCount()) + r->track->updateAuxRoute( -track->auxRefCount(), NULL ); + else + if(track->type() == Track::AUDIO_AUX) + r->track->updateAuxRoute( -1, NULL ); } } @@ -3219,21 +3291,10 @@ void Song::removeTrack2(Track* track) // non realtime part of removeTrack //--------------------------------------------------------- +//empty. gets executed after the realtime part void Song::removeTrack3(Track* /*track*/)//prevent of compiler warning: unused parameter - { - /* - switch(track->type()) { - case Track::AUDIO_SOFTSYNTH: - { - SynthI* s = (SynthI*) track; - s->deactivate3(); - } - break; - default: - break; - } - */ - } +{ +} //--------------------------------------------------------- // executeScript diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 7bbd831d..2c07396c 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -37,6 +37,7 @@ #include "al/sig.h" #include "undo.h" #include "track.h" +#include "synth.h" class QAction; class QFont; @@ -362,7 +363,7 @@ class Song : public QObject { // Configuration //----------------------------------------- - SynthI* createSynthI(const QString& sclass, const QString& label = QString(), Track* insertAt = 0); + SynthI* createSynthI(const QString& sclass, const QString& label = QString(), Synth::Type type = Synth::SYNTH_TYPE_END, Track* insertAt = 0); void rescanAlsaPorts(); @@ -410,7 +411,7 @@ class Song : public QObject { void setQuantize(bool val); void panic(); void seqSignal(int fd); - Track* addTrack(Track::TrackType type, Track* insertAt = 0); + Track* addTrack(Undo& operations, Track::TrackType type, Track* insertAt = 0); Track* addNewTrack(QAction* action, Track* insertAt = 0); QString getScriptPath(int id, bool delivered); void populateScriptMenu(QMenu* menuPlugins, QObject* receiver); diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp index 9adfd406..9a3c11f5 100644 --- a/muse2/muse/songfile.cpp +++ b/muse2/muse/songfile.cpp @@ -1325,13 +1325,19 @@ void MusE::readToplevels(MusECore::Xml& xml) } else if (tag == "marker") { showMarker(true); - if (toplevels.back()->type()==MusEGui::TopWin::MARKER) - toplevels.back()->readStatus(xml); + TopWin* tw = toplevels.findType(TopWin::MARKER); + if(!tw) + xml.skip("marker"); + else + tw->readStatus(xml); } else if (tag == "arrangerview") { showArranger(true); - if (toplevels.back()->type()==MusEGui::TopWin::ARRANGER) - toplevels.back()->readStatus(xml); + TopWin* tw = toplevels.findType(TopWin::ARRANGER); + if(!tw) + xml.skip("arrangerview"); + else + tw->readStatus(xml); } else if (tag == "waveedit") { if(!pl->empty()) @@ -1343,8 +1349,11 @@ void MusE::readToplevels(MusECore::Xml& xml) } else if (tag == "cliplist") { startClipList(true); - if (toplevels.back()->type()==MusEGui::TopWin::CLIPLIST) - toplevels.back()->readStatus(xml); + TopWin* tw = toplevels.findType(TopWin::CLIPLIST); + if(!tw) + xml.skip("cliplist"); + else + tw->readStatus(xml); } else xml.unknown("MusE"); @@ -1506,9 +1515,34 @@ void MusE::read(MusECore::Xml& xml, bool skipConfig, bool isTemplate) else if (tag == "configuration") if (skipConfig) //xml.skip(tag); - readConfiguration(xml,true /* only read sequencer settings */, false /* do NOT read global settings */); + readConfiguration(xml,true /* only read sequencer settings */, false /* do NOT read global settings, see below */); + // see even more below! else - readConfiguration(xml, false, false /* do NOT read global settings */); + readConfiguration(xml, false, false /* do NOT read global settings, see below */); + /* Explanation for why "do NOT read global settings": + * if you would use true here, then muse would overwrite certain global config stuff + * by the settings stored in the song. but you don't want this. imagine that you + * send a friend a .med file. your friend opens it and baaam, his configuration is + * garbled. why? well, because these readConfigurations here would have overwritten + * parts (but not all) of his global config (like MDI/SDI, toolbar states etc.) + * with the data stored in the song. (it IS stored there. dunny why, i find it pretty + * senseless.) + * + * If you've a problem which seems to be solved by replacing "false" with "true", i've + * a better solution for you: go into conf.cpp, in void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig) + * (around line 525), look for a comment like this: + * "Global and/or per-song config stuff ends here" (alternatively just search for + * "----"). Your problem is probably that some non-global setting should be loaded but + * is not. Fix it by either placing the else if (foo)... clause responsible for that + * setting to be loaded into the first part, that is, before "else if (!doReadGlobalConfig)" + * or (if the settings actually IS global and not per-song), ensure that the routine + * which writes the global (and not the song-)configuration really writes that setting. + * (it might happen that it formerly worked because it was written to the song instead + * of the global config by mistake, and now isn't loaded anymore. write it to the + * correct location.) + * + * -- flo93 + */ else if (tag == "song") { MusEGlobal::song->read(xml, isTemplate); diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp index 90d02908..70b19540 100644 --- a/muse2/muse/structure.cpp +++ b/muse2/muse/structure.cpp @@ -137,7 +137,7 @@ void adjustGlobalLists(Undo& operations, int startPos, int diff) // - cut master track //--------------------------------------------------------- -void globalCut() +void globalCut(bool onlySelectedTracks) { int lpos = MusEGlobal::song->lpos(); int rpos = MusEGlobal::song->rpos(); @@ -146,17 +146,11 @@ void globalCut() Undo operations; TrackList* tracks = MusEGlobal::song->tracks(); - bool at_least_one_selected=false; - - for (iTrack it = tracks->begin(); it != tracks->end(); ++it) - if ( (*it)->selected() ) { - at_least_one_selected=true; - break; - } for (iTrack it = tracks->begin(); it != tracks->end(); ++it) { - MidiTrack* track = dynamic_cast(*it); - if (track == 0 || (at_least_one_selected && !track->selected())) + //MidiTrack* track = dynamic_cast(*it); + Track* track = *it; + if (track == 0 || (onlySelectedTracks && !track->selected())) continue; PartList* pl = track->parts(); for (iPart p = pl->begin(); p != pl->end(); ++p) { @@ -169,63 +163,61 @@ void globalCut() operations.push_back(UndoOp(UndoOp::DeletePart,part)); } else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) { - // remove part tail - int len = lpos - t; - MidiPart* nPart = new MidiPart(*(MidiPart*)part); - nPart->setLenTick(len); - // - // cut Events in nPart - EventList* el = nPart->events(); - for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) - operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, nPart, false, false)); - - operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); - } + // remove part tail + int len = lpos - t; + Part *nPart; + if (track->isMidiTrack()) + nPart = new MidiPart(*(MidiPart*)part); + else + nPart = new WavePart(*(WavePart*)part); + + nPart->setLenTick(len); + // + // cut Events in nPart + EventList* el = nPart->events(); + for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) + operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, nPart, false, false)); + + operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); + } else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) { //---------------------- // remove part middle //---------------------- + Part* p1; + Part* p2; + Part* p3; + track->splitPart(part, lpos, p1, p2); + delete p2; + track->splitPart(part, rpos, p2, p3); + delete p2; + p3->setTick(lpos); + p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ + p3->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ - MidiPart* nPart = new MidiPart(*(MidiPart*)part); - EventList* el = nPart->events(); - iEvent is = el->lower_bound(lpos-t); - iEvent ie = el->lower_bound(rpos-t); //lower bound, because we do NOT want to erase the events at rpos-t - for (iEvent i = is; i != ie; ++i) - operations.push_back(UndoOp(UndoOp::DeleteEvent,i->second, nPart, false, false)); - - for (iEvent i = el->lower_bound(rpos-t); i != el->end(); ++i) { - Event event = i->second; - Event nEvent = event.clone(); - nEvent.setTick(nEvent.tick() - (rpos-lpos)); - // Indicate no undo, and do not do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::ModifyEvent,nEvent, event, nPart, false, false)); - } - nPart->setLenTick(l - (rpos-lpos)); // Indicate no undo, and do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); + operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, true)); + operations.push_back(UndoOp(UndoOp::AddPart,p3)); } else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) { // remove part head - MidiPart* nPart = new MidiPart(*(MidiPart*)part); - EventList* el = nPart->events(); - iEvent i_end = el->lower_bound(rpos-t); //lower bound, because we do NOT want to erase the events at rpos-t - for (iEvent it = el->begin(); it!=i_end; it++) - operations.push_back(UndoOp(UndoOp::DeleteEvent,it->second, nPart, false, false)); - - for (iEvent it = el->lower_bound(rpos-t); it!=el->end(); it++) { - Event event = it->second; - Event nEvent = event.clone(); - nEvent.setTick(nEvent.tick() - (rpos-t)); - // Indicate no undo, and do not do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::ModifyEvent,nEvent, event, nPart, false, false)); - } - - nPart->setLenTick(l - (rpos-t)); - operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); + Part* p1; + Part* p2; + track->splitPart(part, rpos, p1, p2); + delete p1; + p2->setTick(lpos); + p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ + operations.push_back(UndoOp(UndoOp::ModifyPart,part, p2, true, true)); } else if (t >= rpos) { - MidiPart* nPart = new MidiPart(*(MidiPart*)part); + // move part to the left + Part *nPart; + if (track->isMidiTrack()) + nPart = new MidiPart(*(MidiPart*)part); + else + nPart = new WavePart(*(WavePart*)part); + //MidiPart* nPart = new MidiPart(*(MidiPart*)part); int nt = part->tick(); nPart->setTick(nt - (rpos -lpos)); // Indicate no undo, and do port controller values but not clone parts. @@ -246,33 +238,24 @@ void globalCut() // - insert in master track //--------------------------------------------------------- -void globalInsert() - { - Undo operations=movePartsTotheRight(MusEGlobal::song->lpos(), MusEGlobal::song->rpos()-MusEGlobal::song->lpos(), true); +void globalInsert(bool onlySelectedTracks) +{ + Undo operations=movePartsTotheRight(MusEGlobal::song->lpos(), MusEGlobal::song->rpos()-MusEGlobal::song->lpos(), onlySelectedTracks); MusEGlobal::song->applyOperationGroup(operations); - } - +} Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selected, set* tracklist) - { +{ if (moveTicks<=0) return Undo(); Undo operations; TrackList* tracks = MusEGlobal::song->tracks(); - bool at_least_one_selected=false; - - for (iTrack it = tracks->begin(); it != tracks->end(); ++it) - if ( (*it)->selected() ) { - at_least_one_selected=true; - break; - } - for (iTrack it = tracks->begin(); it != tracks->end(); ++it) { - MidiTrack* track = dynamic_cast(*it); + Track* track = *it; if ( (track == 0) || - (only_selected && at_least_one_selected && !track->selected()) || + (only_selected && !track->selected()) || (tracklist && tracklist->find(track)==tracklist->end()) ) continue; PartList* pl = track->parts(); @@ -283,23 +266,23 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec if (t + l <= startTicks) continue; if (startTicks > t && startTicks < (t+l)) { - MidiPart* nPart = new MidiPart(*(MidiPart*)part); - nPart->setLenTick(l + moveTicks); - EventList* el = nPart->events(); - - for (riEvent i = el->rbegin(); i!=el->rend(); ++i) - { - if (i->first < startTicks-t) - break; - Event event = i->second; - Event nEvent = i->second.clone(); - nEvent.setTick(nEvent.tick() + moveTicks); - operations.push_back(UndoOp(UndoOp::ModifyEvent, nEvent, event, nPart, false, false)); - } - operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, true)); + // split part to insert new space + Part* p1; + Part* p2; + track->splitPart(part, startTicks, p1, p2); + p2->setTick(startTicks+moveTicks); + p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ + p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ + + operations.push_back(UndoOp(UndoOp::ModifyPart, part, p1, true, true)); + operations.push_back(UndoOp(UndoOp::AddPart, p2)); } else if (t >= startTicks) { - MidiPart* nPart = new MidiPart(*(MidiPart*)part); + Part *nPart; + if (track->isMidiTrack()) + nPart = new MidiPart(*(MidiPart*)part); + else + nPart = new WavePart(*(WavePart*)part); nPart->setTick(t + moveTicks); operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, false)); } @@ -317,47 +300,50 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec // - split all parts at the song position pointer //--------------------------------------------------------- -void globalSplit() - { - int pos = MusEGlobal::song->cpos(); - Undo operations; - TrackList* tracks = MusEGlobal::song->tracks(); - bool at_least_one_selected=false; - - for (iTrack it = tracks->begin(); it != tracks->end(); ++it) - if ( (*it)->selected() ) { - at_least_one_selected=true; - break; - } - - - for (iTrack it = tracks->begin(); it != tracks->end(); ++it) { - Track* track = *it; - if (track == 0 || (at_least_one_selected && !track->selected())) - continue; - - PartList* pl = track->parts(); - for (iPart p = pl->begin(); p != pl->end(); ++p) { - Part* part = p->second; - int p1 = part->tick(); - int l0 = part->lenTick(); - if (pos > p1 && pos < (p1+l0)) { - Part* p1; - Part* p2; - track->splitPart(part, pos, p1, p2); +void globalSplit(bool onlySelectedTracks) +{ + Undo operations=partSplitter(MusEGlobal::song->cpos(), onlySelectedTracks); + MusEGlobal::song->applyOperationGroup(operations); +} - p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - p2->events()->incARef(-1); // so we must decrement it first :/ +Undo partSplitter(unsigned int pos, bool onlySelectedTracks) +{ + Undo operations; + TrackList* tracks = MusEGlobal::song->tracks(); + + for (iTrack it = tracks->begin(); it != tracks->end(); ++it) { + Track* track = *it; + if (track == 0 || (onlySelectedTracks && !track->selected())) + continue; + + PartList* pl = track->parts(); + for (iPart p = pl->begin(); p != pl->end(); ++p) { + Part* part = p->second; + unsigned int p1 = part->tick(); + unsigned int l0 = part->lenTick(); + if (pos > p1 && pos < (p1+l0)) { + Part* p1; + Part* p2; + track->splitPart(part, pos, p1, p2); + + p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it + p2->events()->incARef(-1); // so we must decrement it first :/ + + //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ModifyPart + MusEGlobal::song->informAboutNewParts(part, p2); + operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, false)); + operations.push_back(UndoOp(UndoOp::AddPart,p2)); + if (MusEGlobal::debugMsg) + { + printf("in partSplitter: part1 %d\n",p1->events()->refCount()); + printf("in partSplitter: part2 %d\n",p2->events()->refCount()); + } + break; + } + } + } + return operations; +} - //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ModifyPart - MusEGlobal::song->informAboutNewParts(part, p2); - operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, false)); - operations.push_back(UndoOp(UndoOp::AddPart,p2)); - break; - } - } - } - MusEGlobal::song->applyOperationGroup(operations); - } } // namespace MusECore diff --git a/muse2/muse/structure.h b/muse2/muse/structure.h index b92c4e14..3a359dc0 100644 --- a/muse2/muse/structure.h +++ b/muse2/muse/structure.h @@ -28,10 +28,11 @@ namespace MusECore { Undo movePartsTotheRight(unsigned int startTick, int moveTick, bool only_selected=false, std::set* tracklist=NULL); +Undo partSplitter(unsigned int tick, bool onlySelectedTracks=false); void adjustGlobalLists(Undo& operations, int startPos, int diff); -void globalCut(); -void globalInsert(); -void globalSplit(); +void globalCut(bool onlySelectedTracks=false); +void globalInsert(bool onlySelectedTracks=false); +void globalSplit(bool onlySelectedTracks=false); } #endif diff --git a/muse2/muse/synth.cpp b/muse2/muse/synth.cpp index 93067835..7ab18bda 100644 --- a/muse2/muse/synth.cpp +++ b/muse2/muse/synth.cpp @@ -32,6 +32,7 @@ #include #include +#include //#include #include "app.h" @@ -62,6 +63,19 @@ namespace MusECore { extern void connectNodes(AudioTrack*, AudioTrack*); bool SynthI::_isVisible=false; +const char* synthTypes[] = { "METRONOME", "MESS", "DSSI", "VST", "UNKNOWN" }; +QString synthType2String(Synth::Type type) { return QString(synthTypes[type]); } + +Synth::Type string2SynthType(const QString& type) +{ + for(int i = 0; i < Synth::SYNTH_TYPE_END; ++i) + { + if(synthType2String((Synth::Type)i) == type) + return (Synth::Type)i; + } + return Synth::SYNTH_TYPE_END; +} + /* //--------------------------------------------------------- // description @@ -145,19 +159,17 @@ void MessSynthIF::setNativeGeometry(int x, int y, int w, int h) // search for synthesizer base class //--------------------------------------------------------- -//static Synth* findSynth(const QString& sclass) -static Synth* findSynth(const QString& sclass, const QString& label) +static Synth* findSynth(const QString& sclass, const QString& label, Synth::Type type = Synth::SYNTH_TYPE_END) { for (std::vector::iterator i = MusEGlobal::synthis.begin(); i != MusEGlobal::synthis.end(); ++i) { - //if ((*i)->baseName() == sclass) - //if ((*i)->name() == sclass) - if ( ((*i)->baseName() == sclass) && (label.isEmpty() || ((*i)->name() == label)) ) - - return *i; + if( ((*i)->baseName() == sclass) && + (label.isEmpty() || ((*i)->name() == label)) && + (type == Synth::SYNTH_TYPE_END || type == (*i)->synthType()) ) + return *i; } - printf("synthi class:%s label:%s not found\n", sclass.toLatin1().constData(), label.toLatin1().constData()); + printf("synthi type:%d class:%s label:%s not found\n", type, sclass.toLatin1().constData(), label.toLatin1().constData()); return 0; } @@ -166,10 +178,9 @@ static Synth* findSynth(const QString& sclass, const QString& label) // create a synthesizer instance of class "label" //--------------------------------------------------------- -static SynthI* createSynthInstance(const QString& sclass, const QString& label) +static SynthI* createSynthInstance(const QString& sclass, const QString& label, Synth::Type type = Synth::SYNTH_TYPE_END) { - //Synth* s = findSynth(sclass); - Synth* s = findSynth(sclass, label); + Synth* s = findSynth(sclass, label, type); SynthI* si = 0; if (s) { si = new SynthI(); @@ -652,13 +663,11 @@ void initMidiSynth() // If insertAt is valid, inserts before insertAt. Else at the end after all tracks. //--------------------------------------------------------- -SynthI* Song::createSynthI(const QString& sclass, const QString& label, Track* insertAt) +SynthI* Song::createSynthI(const QString& sclass, const QString& label, Synth::Type type, Track* insertAt) { //printf("Song::createSynthI calling ::createSynthI class:%s\n", sclass.toLatin1().constData()); - //SynthI* si = ::createSynthI(sclass); - //SynthI* si = ::createSynthI(sclass, label); - SynthI* si = createSynthInstance(sclass, label); + SynthI* si = createSynthInstance(sclass, label, type); if(!si) return 0; //printf("Song::createSynthI created SynthI. Before insertTrack1...\n"); @@ -705,6 +714,9 @@ void SynthI::write(int level, Xml& xml) const { xml.tag(level++, "SynthI"); AudioTrack::writeProperties(level, xml); + //xml.intTag(level, "synthType", synth()->synthType()); + xml.strTag(level, "synthType", synthType2String(synth()->synthType())); + xml.strTag(level, "class", synth()->baseName()); // To support plugins like dssi-vst where all the baseNames are the same 'dssi-vst' and the label is the name of the dll file. @@ -823,7 +835,8 @@ void SynthI::read(Xml& xml) { QString sclass; QString label; - + Synth::Type type = Synth::SYNTH_TYPE_END; + int port = -1; bool startgui = false; bool startngui = false; @@ -837,7 +850,10 @@ void SynthI::read(Xml& xml) case Xml::End: return; case Xml::TagStart: - if (tag == "class") + if (tag == "synthType") + //type = xml.parseInt(); + type = string2SynthType(xml.parse1()); + else if (tag == "class") sclass = xml.parse1(); else if (tag == "label") label = xml.parse1(); @@ -866,8 +882,15 @@ void SynthI::read(Xml& xml) break; case Xml::TagEnd: if (tag == "SynthI") { - //Synth* s = findSynth(sclass); - Synth* s = findSynth(sclass, label); + + // NOTICE: This is a hack to quietly change songs to use the new 'fluid_synth' name instead of 'fluidsynth'. + // Recent linker changes required the name change in fluidsynth's cmakelists. Nov 8, 2011 By Tim. + if(sclass == QString("fluidsynth") && + (type == Synth::SYNTH_TYPE_END || type == Synth::MESS_SYNTH) && + (label.isEmpty() || label == QString("FluidSynth")) ) + sclass = QString("fluid_synth"); + + Synth* s = findSynth(sclass, label, type); if (s == 0) return; if (initInstance(s, name())) diff --git a/muse2/muse/synth.h b/muse2/muse/synth.h index c5b63424..497395c0 100644 --- a/muse2/muse/synth.h +++ b/muse2/muse/synth.h @@ -72,6 +72,8 @@ class Synth { QString _version; public: + enum Type { METRO_SYNTH=0, MESS_SYNTH, DSSI_SYNTH, VST_SYNTH, SYNTH_TYPE_END }; + //Synth(const QFileInfo& fi); //Synth(const QFileInfo& fi, QString label); Synth(const QFileInfo& fi, QString label, QString descr, QString maker, QString ver); @@ -80,6 +82,7 @@ class Synth { //virtual const char* description() const { return ""; } //virtual const char* version() const { return ""; } + virtual Type synthType() const = 0; int instances() const { return _instances; } virtual void incInstances(int val) { _instances += val; } QString completeBaseName() /*const*/ { return info.completeBaseName(); } // ddskrjo @@ -117,6 +120,8 @@ class MessSynth : public Synth { //virtual const char* description() const; //virtual const char* version() const; + virtual Type synthType() const { return MESS_SYNTH; } + //virtual void* instantiate(); virtual void* instantiate(const QString&); @@ -363,6 +368,9 @@ class MessSynthIF : public SynthIF { virtual int getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max, int* initval); }; +extern QString synthType2String(Synth::Type); +extern Synth::Type string2SynthType(const QString&); + } // namespace MusECore namespace MusEGlobal { diff --git a/muse2/muse/ticksynth.cpp b/muse2/muse/ticksynth.cpp index 1edc0b12..6d3721ea 100644 --- a/muse2/muse/ticksynth.cpp +++ b/muse2/muse/ticksynth.cpp @@ -49,6 +49,7 @@ class MetronomeSynth : public Synth { //MetronomeSynth(const QFileInfo& fi) : Synth(fi, QString("Metronome")) {} MetronomeSynth(const QFileInfo& fi) : Synth(fi, QString("Metronome"), QString("Metronome"), QString(), QString()) {} virtual ~MetronomeSynth() {} + virtual Type synthType() const { return METRO_SYNTH; } virtual void incInstances(int) {} virtual void* instantiate(); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 2091d03e..e9aa0cf6 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -4,6 +4,7 @@ // $Id: track.cpp,v 1.34.2.11 2009/11/30 05:05:49 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -36,10 +37,12 @@ namespace MusECore { //bool Track::_isVisible=true; -unsigned int Track::_soloRefCnt = 0; +unsigned int Track::_soloRefCnt = 0; Track* Track::_tmpSoloChainTrack = 0; bool Track::_tmpSoloChainDoIns = false; bool Track::_tmpSoloChainNoDec = false; +//bool Track::_tmpIsAuxProcessing = false; +//int Track::_tmpIsAuxProcRefCount = 0; const char* Track::_cname[] = { "Midi", "Drum", "Wave", "AudioOut", "AudioIn", "AudioGroup", @@ -199,6 +202,8 @@ int Track::y() const void Track::init() { + _auxRouteCount = 0; + _nodeTraversed = false; _activity = 0; _lastActivity = 0; _recordFlag = false; @@ -233,6 +238,8 @@ Track::Track(Track::TrackType t) //Track::Track(const Track& t) Track::Track(const Track& t, bool cloneParts) { + _auxRouteCount = t._auxRouteCount; + _nodeTraversed = t._nodeTraversed; _activity = t._activity; _lastActivity = t._lastActivity; _recordFlag = t._recordFlag; @@ -298,6 +305,8 @@ Track::~Track() Track& Track::operator=(const Track& t) { + _auxRouteCount = t._auxRouteCount; + _nodeTraversed = t._nodeTraversed; _activity = t._activity; _lastActivity = t._lastActivity; _recordFlag = t._recordFlag; @@ -414,6 +423,107 @@ void Track::dump() const _name.toLatin1().constData(), _type, _parts.size(), _selected); } +//--------------------------------------------------------- +// updateAuxRoute +// Internal use. Update all the Aux ref counts of tracks dst is connected to. +// If dst is valid, start traversal from there, not from this track. +//--------------------------------------------------------- + +void Track::updateAuxRoute(int refInc, Track* dst) +{ + //if(isMidiTrack() || _type == AUDIO_AUX) + if(isMidiTrack()) + return; + + //printf("Track::updateAuxRoute %s _auxRouteCount:%d refInc:%d\n", name().toLatin1().constData(), _auxRouteCount, refInc); + + if(dst) + { + _nodeTraversed = true; + dst->updateAuxRoute(refInc, NULL); + _nodeTraversed = false; + return; + } + + if(_type == AUDIO_AUX) + return; + + if(_nodeTraversed) + { + fprintf(stderr, "Track::updateAuxRoute %s _auxRouteCount:%d refInc:%d :\n", name().toLatin1().constData(), _auxRouteCount, refInc); + if(refInc >= 0) + fprintf(stderr, " MusE Warning: Please check your routes: Circular path found!\n"); + else + fprintf(stderr, " MusE: Circular path removed.\n"); + return; + } + + _nodeTraversed = true; + + _auxRouteCount += refInc; + if(_auxRouteCount < 0) + { + fprintf(stderr, "Track::updateAuxRoute Ref underflow! %s _auxRouteCount:%d refInc:%d\n", name().toLatin1().constData(), _auxRouteCount, refInc); + //_auxRouteCount = 0; + } + + for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) + { + if( !(*i).isValid() || (*i).type != Route::TRACK_ROUTE ) + continue; + Track* t = (*i).track; + //if(t->isMidiTrack()) + // continue; + t->updateAuxRoute(refInc, NULL); + } + + _nodeTraversed = false; +} + +//--------------------------------------------------------- +// isCircularRoute +// If dst is valid, start traversal from there, not from this track. +// Returns true if circular. +//--------------------------------------------------------- + +bool Track::isCircularRoute(Track* dst) +{ + //if(isMidiTrack() || _type == AUDIO_AUX) + //if(isMidiTrack()) + // return; + + bool rv = false; + + if(dst) + { + _nodeTraversed = true; + rv = dst->isCircularRoute(NULL); + _nodeTraversed = false; + //if(rv) + // fprintf(stderr, " Circular route %s -> %s\n", name().toLatin1().constData(), dst->name().toLatin1().constData()); + return rv; + } + + if(_nodeTraversed) + return true; + + _nodeTraversed = true; + + for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) + { + if( !(*i).isValid() || (*i).type != Route::TRACK_ROUTE ) + continue; + Track* t = (*i).track; + //if(t->isMidiTrack()) + // continue; + rv = t->isCircularRoute(NULL); + if(rv) + break; + } + + _nodeTraversed = false; + return rv; +} //--------------------------------------------------------- // MidiTrack @@ -462,7 +572,6 @@ void MidiTrack::init() { _outPort = 0; _outChannel = 0; - // Changed by Tim. p3.3.8 //_inPortMask = 0xffff; ///_inPortMask = 0xffffffff; @@ -537,7 +646,7 @@ void MidiTrack::setOutPortAndChannelAndUpdate(int port, int ch) //--------------------------------------------------------- // setInPortAndChannelMask // For old song files with port mask (max 32 ports) and channel mask (16 channels), -// before midi routing was added (the iR button). p3.3.48 +// before midi routing was added (the iR button). //--------------------------------------------------------- void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask) @@ -550,7 +659,7 @@ void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask) for(int port = 0; port < 32; ++port) // 32 is the old maximum number of ports. { - // p3.3.50 If the port was not used in the song file to begin with, just ignore it. + // If the port was not used in the song file to begin with, just ignore it. // This saves from having all of the first 32 ports' channels connected. if(!MusEGlobal::midiPorts[port].foundInSongFile()) continue; @@ -558,34 +667,18 @@ void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask) //if(!(portmask & (1 << port))) // continue; - // p3.3.50 Removed. Allow to connect to port with no device so user can change device later. + // Removed. Allow to connect to port with no device so user can change device later. //MidiPort* mp = &MusEGlobal::midiPorts[port]; //MidiDevice* md = mp->device(); //if(!md) // continue; - //for(int ch = 0; ch < MIDI_CHANNELS; ++ch) // p3.3.50 Removed. - //{ - //if(!(chanmask & (1 << ch))) - // continue; - - //Route aRoute(md, ch); - //Route bRoute(this, ch); - Route aRoute(port, chanmask); // p3.3.50 + Route aRoute(port, chanmask); Route bRoute(this, chanmask); - // p3.3.50 Removed. - //iRoute iir = rl->begin(); - //for(; iir != rl->end(); ++iir) - //{ - //if(*iir == aRoute) - // if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == port) // p3.3.50 - // break; - //} - // Route wanted? //if((portmask & (1 << port)) && (chanmask & (1 << ch))) - if(portmask & (1 << port)) // p3.3.50 + if(portmask & (1 << port)) { // Route already exists? //if(iir != rl->end()) @@ -818,11 +911,11 @@ void MidiTrack::read(Xml& xml) //setInPortMask(xml.parseInt()); ///setInPortMask(xml.parseUInt()); //xml.skip(tag); // Obsolete. - portmask = xml.parseUInt(); // p3.3.48: Support old files. + portmask = xml.parseUInt(); // Support old files. else if (tag == "inchannelMap") ///setInChannelMask(xml.parseInt()); //xml.skip(tag); // Obsolete. - chanmask = xml.parseInt(); // p3.3.48: Support old files. + chanmask = xml.parseInt(); // Support old files. else if (tag == "locked") _locked = xml.parseInt(); else if (tag == "echo") @@ -843,7 +936,7 @@ void MidiTrack::read(Xml& xml) case Xml::TagEnd: if (tag == "miditrack" || tag == "drumtrack") { - setInPortAndChannelMask(portmask, chanmask); // p3.3.48: Support old files. + setInPortAndChannelMask(portmask, chanmask); // Support old files. return; } default: @@ -972,7 +1065,7 @@ void Track::writeRouting(int level, Xml& xml) const xml.tag(level++, s.toAscii().constData()); - // p3.3.38 New routing scheme. + // New routing scheme. s = "source"; if(r->type != Route::TRACK_ROUTE) s += QString(" type=\"%1\"").arg(r->type); @@ -994,10 +1087,10 @@ void Track::writeRouting(int level, Xml& xml) const if(r->type == Route::TRACK_ROUTE && r->track && r->track->type() == Track::AUDIO_INPUT) continue; - if(r->midiPort != -1 || !r->name().isEmpty()) // p3.3.49 + if(r->midiPort != -1 || !r->name().isEmpty()) { s = "Route"; - if(r->type == Route::MIDI_PORT_ROUTE) // p3.3.50 + if(r->type == Route::MIDI_PORT_ROUTE) { if(r->channel != -1 && r->channel != 0) s += QString(" channelMask=\"%1\"").arg(r->channel); // Use new channel mask. @@ -1019,14 +1112,14 @@ void Track::writeRouting(int level, Xml& xml) const s = "dest"; - //if(r->type == Route::MIDI_DEVICE_ROUTE) // p3.3.49 Obsolete since 1.1-RC2 + //if(r->type == Route::MIDI_DEVICE_ROUTE) // Obsolete since 1.1-RC2 // s += QString(QT_TRANSLATE_NOOP("@default", " devtype=\"%1\"")).arg(r->device->deviceType()); // //if(r->type != Route::TRACK_ROUTE) // if(r->type != Route::TRACK_ROUTE && r->type != Route::MIDI_PORT_ROUTE) s += QString(" type=\"%1\"").arg(r->type); //s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(r->name()); - if(r->type == Route::MIDI_PORT_ROUTE) // p3.3.49 + if(r->type == Route::MIDI_PORT_ROUTE) s += QString(" mport=\"%1\"/").arg(r->midiPort); else s += QString(" name=\"%1\"/").arg(Xml::xmlString(r->name())); diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 25a846ac..04cf71c2 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -4,6 +4,7 @@ // $Id: track.h,v 1.39.2.17 2009/12/20 05:00:35 terminator356 Exp $ // // (C) Copyright 1999-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -70,9 +71,10 @@ class Track { static bool _tmpSoloChainDoIns; static bool _tmpSoloChainNoDec; - // p3.3.38 RouteList _inRoutes; RouteList _outRoutes; + bool _nodeTraversed; // Internal anti circular route traversal flag. + int _auxRouteCount; // Number of aux paths feeding this track. QString _name; bool _recordFlag; @@ -89,8 +91,6 @@ class Track { int _activity; int _lastActivity; - //int _meter[MAX_CHANNELS]; - //int _peak[MAX_CHANNELS]; double _meter[MAX_CHANNELS]; double _peak[MAX_CHANNELS]; @@ -147,7 +147,10 @@ class Track { bool noInRoute() const { return _inRoutes.empty(); } bool noOutRoute() const { return _outRoutes.empty(); } void writeRouting(int, Xml&) const; - + bool isCircularRoute(Track* dst); + int auxRefCount() const { return _auxRouteCount; } // Number of Aux Tracks with routing paths to this track. + void updateAuxRoute(int refInc, Track* dst); // Internal use. + PartList* parts() { return &_parts; } const PartList* cparts() const { return &_parts; } Part* findPart(unsigned tick); @@ -168,20 +171,21 @@ class Track { virtual void setMute(bool val); virtual void setOff(bool val); - virtual void updateSoloStates(bool noDec) = 0; - virtual void updateInternalSoloStates(); - void updateSoloState(); void setInternalSolo(unsigned int val); - static void clearSoloRefCounts(); virtual void setSolo(bool val) = 0; virtual bool isMute() const = 0; - unsigned int internalSolo() const { return _internalSolo; } bool soloMode() const { return _soloRefCnt; } bool solo() const { return _solo; } bool mute() const { return _mute; } bool off() const { return _off; } bool recordFlag() const { return _recordFlag; } + // + // Internal use... + static void clearSoloRefCounts(); + void updateSoloState(); + virtual void updateSoloStates(bool noDec) = 0; + virtual void updateInternalSoloStates(); int activity() { return _activity; } void setActivity(int v) { _activity = v; } @@ -190,8 +194,6 @@ class Track { void addActivity(int v) { _activity += v; } void resetPeaks(); static void resetAllMeter(); - //int meter(int ch) const { return _meter[ch]; } - //int peak(int ch) const { return _peak[ch]; } double meter(int ch) const { return _meter[ch]; } double peak(int ch) const { return _peak[ch]; } void resetMeter(); @@ -220,9 +222,9 @@ class MidiTrack : public Track { int _outPort; int _outChannel; //int _inPortMask; - ///unsigned int _inPortMask; // bitmask of accepted record ports - ///int _inChannelMask; // bitmask of accepted record channels - bool _recEcho; // For midi (and audio). Whether to echo incoming record events to output device. + //unsigned int _inPortMask; // bitmask of accepted record ports + //int _inChannelMask; // bitmask of accepted record channels + bool _recEcho; // For midi (and audio). Whether to echo incoming record events to output device. EventList* _events; // tmp Events during midi import MPEventList* _mpevents; // tmp Events druring recording @@ -270,17 +272,17 @@ class MidiTrack : public Track { void setOutPortAndChannelAndUpdate(int /*port*/, int /*chan*/); //void setInPortMask(int i) { _inPortMask = i; } - ///void setInPortMask(unsigned int i) { _inPortMask = i; } // Obsolete - ///void setInChannelMask(int i) { _inChannelMask = i; } // + //void setInPortMask(unsigned int i) { _inPortMask = i; } // Obsolete + //void setInChannelMask(int i) { _inChannelMask = i; } // // Backward compatibility: For reading old songs. void setInPortAndChannelMask(unsigned int /*portmask*/, int /*chanmask*/); void setRecEcho(bool b) { _recEcho = b; } int outPort() const { return _outPort; } //int inPortMask() const { return _inPortMask; } - ///unsigned int inPortMask() const { return _inPortMask; } + //unsigned int inPortMask() const { return _inPortMask; } int outChannel() const { return _outChannel; } - ///int inChannelMask() const { return _inChannelMask; } + //int inChannelMask() const { return _inChannelMask; } bool recEcho() const { return _recEcho; } virtual bool isMute() const; @@ -298,14 +300,10 @@ class MidiTrack : public Track { clefTypes getClef() { return clefType; } }; -} // namespace MusECore - -namespace MusECore { - //--------------------------------------------------------- // AudioTrack // this track can hold audio automation data and can -// hold tracktypes AUDIO, AUDIO_MASTER, AUDIO_GROUP, +// hold tracktypes WAVE, AUDIO_GROUP, AUDIO_OUTPUT, // AUDIO_INPUT, AUDIO_SOFTSYNTH, AUDIO_AUX //--------------------------------------------------------- @@ -313,25 +311,19 @@ class AudioTrack : public Track { //friend class MidiTrack; //static unsigned int _soloRefCnt; - bool _haveData; + bool _haveData; // Whether we have data from a previous process call during current cycle. CtrlListList _controller; CtrlRecList _recEvents; // recorded automation events bool _prefader; // prefader metering std::vector _auxSend; - Pipeline* _efxPipe; - - AutomationType _automationType; - - //RouteList _inRoutes; - //RouteList _outRoutes; - - bool _sendMetronome; - //void readRecfile(Xml& xml); void readAuxSend(Xml& xml); - + + bool _sendMetronome; + AutomationType _automationType; + Pipeline* _efxPipe; protected: float** outBuffers; @@ -344,7 +336,7 @@ class AudioTrack : public Track { SndFile* _recFile; Fifo fifo; // fifo -> _recFile bool _processed; - + public: AudioTrack(TrackType t); //AudioTrack(TrackType t, int num_out_bufs = MAX_CHANNELS); @@ -424,12 +416,6 @@ class AudioTrack : public Track { void readVolume(Xml& xml); //void writeRouting(int, Xml&) const; - // routing - //RouteList* inRoutes() { return &_inRoutes; } - //RouteList* outRoutes() { return &_outRoutes; } - //bool noInRoute() const { return _inRoutes.empty(); } - //bool noOutRoute() const { return _outRoutes.empty(); } - virtual void preProcessAlways() { _processed = false; } virtual void addData(unsigned /*samplePos*/, int /*channels*/, int /*srcStartChan*/, int /*srcChannels*/, unsigned /*frames*/, float** /*buffer*/); virtual void copyData(unsigned /*samplePos*/, int /*channels*/, int /*srcStartChan*/, int /*srcChannels*/, unsigned /*frames*/, float** /*buffer*/); diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index eb554495..8587b108 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -50,8 +50,11 @@ const char* UndoOp::typeName() "AddTrack", "DeleteTrack", "ModifyTrack", "AddPart", "DeletePart", "ModifyPart", "AddEvent", "DeleteEvent", "ModifyEvent", - "AddTempo", "DeleteTempo", "AddSig", "DeleteSig", - "SwapTrack", "ModifyClip" + "AddTempo", "DeleteTempo", + "AddSig", "DeleteSig", + "AddKey", "DeleteKey", + "SwapTrack", "ModifyClip", "ModifyMarker", + "ModifySongLen", "DoNothing" }; return name[type]; } @@ -95,6 +98,7 @@ void UndoOp::dump() case ModifyMarker: case AddKey: case DeleteKey: + case ModifySongLen: case DoNothing: break; } @@ -530,6 +534,10 @@ void Song::doUndo2() MusEGlobal::keymap.addKey(i->a, (key_enum)i->b); updateFlags |= SC_KEY; break; + case UndoOp::ModifySongLen: + _len=i->b; + updateFlags = -1; // set all flags + break; case UndoOp::ModifyClip: case UndoOp::ModifyMarker: case UndoOp::DoNothing: @@ -767,6 +775,10 @@ void Song::doRedo2() MusEGlobal::keymap.delKey(i->a); updateFlags |= SC_KEY; break; + case UndoOp::ModifySongLen: + _len=i->a; + updateFlags = -1; // set all flags + break; case UndoOp::ModifyClip: case UndoOp::ModifyMarker: case UndoOp::DoNothing: diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index 19c252bf..af55a307 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -54,6 +54,7 @@ struct UndoOp { SwapTrack, ModifyClip, ModifyMarker, + ModifySongLen, // a = new len, b = old len DoNothing }; UndoType type; diff --git a/muse2/muse/vst.h b/muse2/muse/vst.h index b57b598d..b41e7137 100644 --- a/muse2/muse/vst.h +++ b/muse2/muse/vst.h @@ -50,6 +50,7 @@ class VstSynth : public Synth { } virtual ~VstSynth() {} + virtual Type synthType() const { return VST_SYNTH; } virtual void incInstances(int val); virtual void* instantiate(); //virtual SynthIF* createSIF() const; diff --git a/muse2/muse/wave.cpp b/muse2/muse/wave.cpp index 06759441..f22f6f97 100644 --- a/muse2/muse/wave.cpp +++ b/muse2/muse/wave.cpp @@ -105,7 +105,7 @@ SndFile::~SndFile() bool SndFile::openRead() { if (openFlag) { - printf("SndFile:: alread open\n"); + printf("SndFile:: already open\n"); return false; } QString p = path(); @@ -468,7 +468,7 @@ size_t SndFile::readWithHeap(int srcChannels, float** dst, size_t n, bool overwr { float *buffer = new float[n * sfinfo.channels]; int rn = readInternal(srcChannels,dst,n,overwrite, buffer); - delete buffer; + delete[] buffer; return rn; } @@ -588,11 +588,11 @@ size_t SndFile::write(int srcChannels, float** src, size_t n) else { printf("SndFile:write channel mismatch %d -> %d\n", srcChannels, dstChannels); - delete buffer; + delete[] buffer; return 0; } int nbr = sf_writef_float(sf, buffer, n) ; - delete buffer; + delete[] buffer; return nbr; } @@ -1120,6 +1120,22 @@ SndFileR::~SndFileR() } } +void SndFileList::clearDelete() +{ + // ~SndFile searches itself on the list (and will find for + // sure) and deletes the entry on its own. + while (!empty()) + delete *begin(); + + /* this is wrong, because ~SndFile deletes itself from the + * list, causing the iterator to be invalidated -> fail. + for (SndFileList::iterator i = begin(); i != end(); ++i) + delete *i; + clear(); + */ +} + + } // namespace MusECore namespace MusEGui { diff --git a/muse2/muse/wave.h b/muse2/muse/wave.h index 58e0ab87..535df939 100644 --- a/muse2/muse/wave.h +++ b/muse2/muse/wave.h @@ -182,11 +182,7 @@ class SndFileR { class SndFileList : public std::list { public: SndFile* search(const QString& name); - void clearDelete() { - for (SndFileList::iterator i = begin(); i != end(); ++i) - delete *i; - clear(); - } + void clearDelete(); }; typedef SndFileList::iterator iSndFile; diff --git a/muse2/muse/waveedit/waveedit.cpp b/muse2/muse/waveedit/waveedit.cpp index 537d8529..1c1115b1 100644 --- a/muse2/muse/waveedit/waveedit.cpp +++ b/muse2/muse/waveedit/waveedit.cpp @@ -289,6 +289,7 @@ WaveEdit::WaveEdit(MusECore::PartList* pl) } initTopwinState(); + MusEGlobal::muse->topwinMenuInited(this); } void WaveEdit::initShortcuts() diff --git a/muse2/muse/wavetrack.cpp b/muse2/muse/wavetrack.cpp index 9edeffb6..0d699cbe 100644 --- a/muse2/muse/wavetrack.cpp +++ b/muse2/muse/wavetrack.cpp @@ -229,8 +229,8 @@ bool WaveTrack::getData(unsigned framePos, int channels, unsigned nframe, float* ciRoute i = irl->begin(); if(i->track->isMidiTrack()) { - if(MusEGlobal::debugMsg) - printf("WaveTrack::getData: Error: First route is a midi track route!\n"); + //if(MusEGlobal::debugMsg) + // printf("WaveTrack::getData: Error: First route is a midi track route!\n"); return false; } // p3.3.38 @@ -246,8 +246,8 @@ bool WaveTrack::getData(unsigned framePos, int channels, unsigned nframe, float* { if(i->track->isMidiTrack()) { - if(MusEGlobal::debugMsg) - printf("WaveTrack::getData: Error: Route is a midi track route!\n"); + //if(MusEGlobal::debugMsg) + // printf("WaveTrack::getData: Error: Route is a midi track route!\n"); //return false; continue; } diff --git a/muse2/muse/widgets/citem.h b/muse2/muse/widgets/citem.h index 1777eb23..199d18b0 100644 --- a/muse2/muse/widgets/citem.h +++ b/muse2/muse/widgets/citem.h @@ -90,7 +90,7 @@ class CItem { }; typedef std::multimap >::iterator iCItem; -//typedef std::multimap >::const_iterator ciCItem; +typedef std::multimap >::const_iterator ciCItem; typedef std::multimap >::const_reverse_iterator rciCItem; //--------------------------------------------------------- diff --git a/muse2/muse/widgets/filedialog.cpp b/muse2/muse/widgets/filedialog.cpp index 68f2718f..7f2c1681 100644 --- a/muse2/muse/widgets/filedialog.cpp +++ b/muse2/muse/widgets/filedialog.cpp @@ -123,11 +123,13 @@ void MFileDialog::userToggled(bool flag) if (lastUserDir.isEmpty()) { - lastUserDir = MusEGlobal::museUser + QString("/") + baseDir; // Initialize if first time + //lastUserDir = MusEGlobal::museUser + QString("/") + baseDir; // Initialize if first time + lastUserDir = MusEGlobal::configPath + QString("/") + baseDir; // Initialize if first time // p4.0.39 } if (testDirCreate(this, lastUserDir)) - setDirectory(MusEGlobal::museUser); + //setDirectory(MusEGlobal::museUser); + setDirectory(MusEGlobal::configPath); // p4.0.39 else setDirectory(lastUserDir); @@ -270,34 +272,6 @@ void MFileDialog::directoryChanged(const QString&) } } - -//--------------------------------------------------------- -// getFilterExtension -//--------------------------------------------------------- - -QString getFilterExtension(const QString &filter) -{ - // - // Return the first extension found. Must contain at least one * character. - // - - int pos = filter.indexOf('*'); - if(pos == -1) - return QString(); - - QString filt; - int len = filter.length(); - ++pos; - for( ; pos < len; ++pos) - { - QChar c = filter[pos]; - if((c == ')') || (c == ';') || (c == ',') || (c == ' ')) - break; - filt += filter[pos]; - } - return filt; -} - //--------------------------------------------------------- // getOpenFileName //--------------------------------------------------------- @@ -509,10 +483,12 @@ FILE* fileOpen(QWidget* parent, QString name, const QString& ext, FILE* fp = 0; if (popenFlag) { if (strcmp(mode, "r") == 0) - zip += QString(" -d < "); + //zip += QString(" -d < "); + zip += QString(" -d < \""); // p4.0.40 else - zip += QString(" > "); - zip += name; + zip += QString(" > \""); + //zip += name; + zip = zip + name + QString("\""); // p4.0.40 fp = popen(zip.toAscii().data(), mode); } else { diff --git a/muse2/muse/widgets/filedialog.h b/muse2/muse/widgets/filedialog.h index b731b65a..b4e21e2c 100644 --- a/muse2/muse/widgets/filedialog.h +++ b/muse2/muse/widgets/filedialog.h @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: filedialog.h,v 1.2.2.2 2008/01/19 13:33:46 wschweer Exp $ // (C) Copyright 2000 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp index d7642b3b..ec2c8637 100644 --- a/muse2/muse/widgets/genset.cpp +++ b/muse2/muse/widgets/genset.cpp @@ -4,6 +4,7 @@ // $Id: genset.cpp,v 1.7.2.8 2009/12/01 03:52:40 terminator356 Exp $ // // (C) Copyright 2001-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -24,8 +25,10 @@ #include #include +#include #include #include +#include #include "genset.h" #include "app.h" @@ -33,6 +36,7 @@ #include "midiseq.h" #include "globals.h" #include "icons.h" +#include "helper.h" namespace MusEGui { @@ -93,12 +97,6 @@ GlobalSettingsConfig::GlobalSettingsConfig(QWidget* parent) } } - userInstrumentsPath->setText(MusEGlobal::config.userInstrumentsDir); - selectInstrumentsDirButton->setIcon(*openIcon); - defaultInstrumentsDirButton->setIcon(*undoIcon); - connect(selectInstrumentsDirButton, SIGNAL(clicked()), SLOT(selectInstrumentsPath())); - connect(defaultInstrumentsDirButton, SIGNAL(clicked()), SLOT(defaultInstrumentsPath())); - guiRefreshSelect->setValue(MusEGlobal::config.guiRefresh); minSliderSelect->setValue(int(MusEGlobal::config.minSlider)); minMeterSelect->setValue(MusEGlobal::config.minMeter); @@ -119,6 +117,9 @@ GlobalSettingsConfig::GlobalSettingsConfig(QWidget* parent) Period affects midi playback resolution. Shorter periods are desirable. */ + + projDirEntry->setText(MusEGlobal::config.projectBaseFolder); + projDirOpenToolButton->setIcon(*openIcon); startSongEntry->setText(MusEGlobal::config.startSong); startSongGroup->button(MusEGlobal::config.startMode)->setChecked(true); @@ -171,9 +172,14 @@ Shorter periods are desirable. popsDefStayOpenCheckBox->setChecked(MusEGlobal::config.popupsDefaultStayOpen); lmbDecreasesCheckBox->setChecked(MusEGlobal::config.leftMouseButtonCanDecrease); rangeMarkerWithoutMMBCheckBox->setChecked(MusEGlobal::config.rangeMarkerWithoutMMB); - + + addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks); + unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks); + //updateSettings(); // TESTING + connect(projDirOpenToolButton, SIGNAL(clicked()), SLOT(browseProjDir())); + connect(applyButton, SIGNAL(clicked()), SLOT(apply())); connect(okButton, SIGNAL(clicked()), SLOT(ok())); connect(cancelButton, SIGNAL(clicked()), SLOT(cancel())); @@ -258,6 +264,8 @@ void GlobalSettingsConfig::updateSettings() //dummyAudioRealRate->setText(dad ? QString().setNum(sampleRate) : "---"); //dummyAudioRealRate->setText(QString().setNum(sampleRate)); // Not used any more. p4.0.20 + projDirEntry->setText(MusEGlobal::config.projectBaseFolder); + startSongEntry->setText(MusEGlobal::config.startSong); startSongGroup->button(MusEGlobal::config.startMode)->setChecked(true); @@ -310,6 +318,9 @@ void GlobalSettingsConfig::updateSettings() lmbDecreasesCheckBox->setChecked(MusEGlobal::config.leftMouseButtonCanDecrease); rangeMarkerWithoutMMBCheckBox->setChecked(MusEGlobal::config.rangeMarkerWithoutMMB); + addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks); + unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks); + updateMdiSettings(); } @@ -350,7 +361,9 @@ void GlobalSettingsConfig::apply() MusEGlobal::config.useOutputLimiter = outputLimiterCheckBox->isChecked(); MusEGlobal::config.vstInPlace = vstInPlaceCheckBox->isChecked(); MusEGlobal::config.rtcTicks = rtcResolutions[rtcticks]; - MusEGlobal::config.userInstrumentsDir = userInstrumentsPath->text(); + + MusEGlobal::config.projectBaseFolder = projDirEntry->text(); + MusEGlobal::config.startSong = startSongEntry->text(); MusEGlobal::config.startMode = startSongGroup->checkedId(); int das = dummyAudioSize->currentIndex(); @@ -408,6 +421,9 @@ void GlobalSettingsConfig::apply() MusEGlobal::config.leftMouseButtonCanDecrease = lmbDecreasesCheckBox->isChecked(); MusEGlobal::config.rangeMarkerWithoutMMB = rangeMarkerWithoutMMBCheckBox->isChecked(); + MusEGlobal::config.addHiddenTracks = addHiddenCheckBox->isChecked(); + MusEGlobal::config.unhideTracks = unhideTracksCheckBox->isChecked(); + //MusEGlobal::muse->showMixer(MusEGlobal::config.mixerVisible); MusEGlobal::muse->showMixer1(MusEGlobal::config.mixer1Visible); MusEGlobal::muse->showMixer2(MusEGlobal::config.mixer2Visible); @@ -442,8 +458,6 @@ void GlobalSettingsConfig::apply() MusEGlobal::muse->resize(MusEGlobal::config.geometryMain.size()); MusEGlobal::muse->move(MusEGlobal::config.geometryMain.topLeft()); - MusEGlobal::museUserInstruments = MusEGlobal::config.userInstrumentsDir; - MusEGlobal::muse->setHeartBeat(); // set guiRefresh MusEGlobal::midiSeq->msgSetRtc(); // set midi tick rate @@ -546,21 +560,6 @@ void GlobalSettingsConfig::transportCurrent() transportY->setValue(r.y()); } -void GlobalSettingsConfig::selectInstrumentsPath() - { - QString dir = QFileDialog::getExistingDirectory(this, - tr("Selects instruments directory"), - MusEGlobal::config.userInstrumentsDir); - userInstrumentsPath->setText(dir); - } - -void GlobalSettingsConfig::defaultInstrumentsPath() - { - QString dir = MusEGlobal::configPath + "/instruments"; - userInstrumentsPath->setText(dir); - } - - void GlobalSettingsConfig::traditionalPreset() { for (std::list::iterator it = mdisettings.begin(); it!=mdisettings.end(); it++) @@ -598,5 +597,12 @@ void GlobalSettingsConfig::borlandPreset() updateMdiSettings(); } +void GlobalSettingsConfig::browseProjDir() +{ + QString dir = MusEGui::browseProjectFolder(this); + if(!dir.isEmpty()) + projDirEntry->setText(dir); +} + } // namespace MusEGui diff --git a/muse2/muse/widgets/genset.h b/muse2/muse/widgets/genset.h index 0e1697ee..b076a27f 100644 --- a/muse2/muse/widgets/genset.h +++ b/muse2/muse/widgets/genset.h @@ -4,6 +4,7 @@ // $Id: genset.h,v 1.3 2004/01/25 09:55:17 wschweer Exp $ // // (C) Copyright 2001 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -53,8 +54,7 @@ class GlobalSettingsConfig : public QDialog, public Ui::GlobalSettingsDialogBase void bigtimeCurrent(); void mainCurrent(); void transportCurrent(); - void selectInstrumentsPath(); - void defaultInstrumentsPath(); + void browseProjDir(); void traditionalPreset(); void mdiPreset(); void borlandPreset(); diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui index ba26cf38..124ee72a 100644 --- a/muse2/muse/widgets/gensetbase.ui +++ b/muse2/muse/widgets/gensetbase.ui @@ -30,7 +30,36 @@ Application - + + + + Project directory + + + + + + Projects: + + + false + + + + + + + + + + ... + + + + + + + @@ -413,14 +442,14 @@ - + Start Muse - + @@ -438,7 +467,7 @@ - + @@ -811,9 +840,9 @@ Adjusts responsiveness of audio controls and 2 - + - + @@ -1179,31 +1208,7 @@ Adjusts responsiveness of audio controls and - - - - Instruments Directory - - - - - - - - - - - - - - - - - - - - Qt::Vertical @@ -1223,7 +1228,7 @@ Adjusts responsiveness of audio controls and - GUI + GUI Behaviour @@ -1406,10 +1411,58 @@ left button behave like the middle button in such areas. + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + Allow adding hidden tracks in track list menu + + + + + + + Unhide tracks when adding hidden tracks + + + + + + + + + + - + + + + + GUI Style + + + MDI-subwindowness and sharing menus @@ -1460,8 +1513,8 @@ left button behave like the middle button in such areas. 0 0 - 482 - 143 + 512 + 378 diff --git a/muse2/muse/widgets/header.cpp b/muse2/muse/widgets/header.cpp index 2c1057c3..968e7f73 100644 --- a/muse2/muse/widgets/header.cpp +++ b/muse2/muse/widgets/header.cpp @@ -51,7 +51,7 @@ void Header::readStatus(MusECore::Xml& xml) for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { int logialIdx=abs((*it).toInt()); bool isHidden = (*it).toInt() < 0 ? true:false; - int section = visualIndex(logialIdx); + int section = visualIndex(logialIdx - (isHidden? 1:0)); moveSection(section, index); if (isHidden) hideSection(logialIdx-1); @@ -65,7 +65,7 @@ void Header::readStatus(MusECore::Xml& xml) bool foundIt=false; for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { int id=((*it).toInt()); - if ( id == i || i ==1-id ) + if ( id == i || i == -1 - id ) foundIt=true; } if (foundIt == false) { @@ -97,7 +97,7 @@ void Header::writeStatus(int level, MusECore::Xml& xml) const //xml.nput(level, "<%s> ", name()); xml.nput(level, "<%s> ", MusECore::Xml::xmlString(objectName()).toLatin1().constData()); int n = count(); - for (int i = n; i >= 0; --i) { + for (int i = n-1; i >= 0; --i) { if (isSectionHidden(logicalIndex(i))) xml.nput("%d ", -logicalIndex(i)-1); // hidden is stored as negative value starting from -1 else diff --git a/muse2/muse/widgets/knob.cpp b/muse2/muse/widgets/knob.cpp index 920d2028..269f65cf 100644 --- a/muse2/muse/widgets/knob.cpp +++ b/muse2/muse/widgets/knob.cpp @@ -323,6 +323,30 @@ void Knob::rangeChange() repaint(); } +void Knob::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::MidButton || e->modifiers() & Qt::ControlModifier) { + int xpos = e->x() - width() /2; + double v = float(e->y()) / height() * 1.2; + + double halfRange = (maxValue() - minValue())/2; + double midValue = minValue() + halfRange; + // apply to range + if (xpos < 0) { // left values + v = -v; + } + setValue(v * halfRange + midValue); + SliderBase::valueChange(); + + // fake a left-click to make the knob still "stick" to + // the mouse. + QMouseEvent temp(e->type(), e->pos(), Qt::LeftButton, e->buttons(), e->modifiers()); + SliderBase::mousePressEvent(&temp); + return; + } + SliderBase::mousePressEvent(e); +} + //--------------------------------------------------------- // resizeEvent //--------------------------------------------------------- diff --git a/muse2/muse/widgets/knob.h b/muse2/muse/widgets/knob.h index 483fafa6..bd8621a1 100644 --- a/muse2/muse/widgets/knob.h +++ b/muse2/muse/widgets/knob.h @@ -80,6 +80,7 @@ class Knob : public SliderBase, public ScaleIf virtual void paintEvent(QPaintEvent *); virtual void resizeEvent(QResizeEvent *e); + virtual void mousePressEvent(QMouseEvent *e); double getValue(const QPoint &p); void getScrollMode( QPoint &p, const Qt::MouseButton &button, int &scrollMode, int &direction ); void scaleChange() { repaint(); } diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp index 5c79ffb2..d9ca8e20 100644 --- a/muse2/muse/widgets/meter.cpp +++ b/muse2/muse/widgets/meter.cpp @@ -229,6 +229,8 @@ void Meter::setRange(double min, double max) void Meter::paintEvent(QPaintEvent* ev) { + // For some reason upon resizing we get double calls here and in resizeEvent. + QPainter p(this); p.setRenderHint(QPainter::Antialiasing); @@ -534,8 +536,11 @@ void Meter::drawVU(QPainter& p, const QRect& rect, const QPainterPath& drawPath, void Meter::resizeEvent(QResizeEvent* ev) { - QFrame::resizeEvent(ev); + // For some reason upon resizing we get double calls here and in paintEvent. + //printf("Meter::resizeEvent w:%d h:%d\n", ev->size().width(), ev->size().height()); cur_yv = -1; // Force re-initialization. + QFrame::resizeEvent(ev); + update(); } //--------------------------------------------------------- diff --git a/muse2/muse/widgets/midisync.ui b/muse2/muse/widgets/midisync.ui index 8fc6248a..81d7451e 100644 --- a/muse2/muse/widgets/midisync.ui +++ b/muse2/muse/widgets/midisync.ui @@ -388,6 +388,19 @@ Enabled inputs in the list will + + + + Note: Sync delay and MTC sync currently not fully implemeted + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp index b5460447..19e9729a 100644 --- a/muse2/muse/widgets/mtrackinfo.cpp +++ b/muse2/muse/widgets/mtrackinfo.cpp @@ -574,7 +574,8 @@ void MidiTrackInfo::setLabelText() //gradient.setColorAt(0, c.darker()); //gradient.setColorAt(0, c); //gradient.setColorAt(1, c.darker()); - gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(0, c); + gradient.setColorAt(0.5, c.lighter()); gradient.setColorAt(1, c); //palette.setBrush(QPalette::Button, gradient); //palette.setBrush(QPalette::Window, gradient); @@ -635,14 +636,17 @@ void MidiTrackInfo::iOutputPortChanged(int index) { if(!selected) return; + int port_num = iOutput->itemData(index).toInt(); + if(port_num < 0 || port_num >= MIDI_PORTS) + return; MusECore::MidiTrack* track = (MusECore::MidiTrack*)selected; - if (index == track->outPort()) + if (port_num == track->outPort()) return; // Changed by T356. - //track->setOutPort(index); + //track->setOutPort(port_num); MusEGlobal::audio->msgIdle(true); - //audio->msgSetTrackOutPort(track, index); - track->setOutPortAndUpdate(index); + //audio->msgSetTrackOutPort(track, port_num); + track->setOutPortAndUpdate(port_num); MusEGlobal::audio->msgIdle(false); //MusEGlobal::song->update(SC_MIDI_TRACK_PROP); @@ -1081,11 +1085,9 @@ void MidiTrackInfo::instrPopup() //QMenu* pup = new QMenu; PopupMenu* pup = new PopupMenu(true); - //instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); - populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); + instr->populatePatchPopup(pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); + //populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); - //if(pop->actions().count() == 0) - // return; if(pup->actions().count() == 0) { delete pup; @@ -1095,7 +1097,6 @@ void MidiTrackInfo::instrPopup() connect(pup, SIGNAL(triggered(QAction*)), SLOT(instrPopupActivated(QAction*))); //connect(pup, SIGNAL(hovered(QAction*)), SLOT(instrPopupActivated(QAction*))); - //QAction *act = pop->exec(iPatch->mapToGlobal(QPoint(10,5))); QAction *act = pup->exec(iPatch->mapToGlobal(QPoint(10,5))); if(act) { @@ -1346,12 +1347,20 @@ void MidiTrackInfo::updateTrackInfo(int flags) //iInput->clear(); iOutput->clear(); + int item_idx = 0; for (int i = 0; i < MIDI_PORTS; ++i) { + MusECore::MidiDevice* md = MusEGlobal::midiPorts[i].device(); + if(!md) // In the case of this combo box, don't bother listing empty ports. p4.0.41 + continue; + //if(!(md->rwFlags() & 1 || md->isSynti()) && (i != outPort)) + if(!(md->rwFlags() & 1) && (i != outPort)) // Only writeable ports, or current one. p4.0.41 + continue; QString name; name.sprintf("%d:%s", i+1, MusEGlobal::midiPorts[i].portname().toLatin1().constData()); - iOutput->insertItem(i, name); + iOutput->insertItem(item_idx, name, i); if (i == outPort) - iOutput->setCurrentIndex(i); + iOutput->setCurrentIndex(item_idx); + item_idx++; } iOutput->blockSignals(false); diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index 4068da57..f707fb7c 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -157,7 +157,8 @@ MusEGlobal::GlobalConfigValues config = { -60.0, // double minSlider; false, // use Jack freewheel 20, // int guiRefresh; - QString(""), // helpBrowser + QString(""), // userInstrumentsDir // Obsolete. Must keep for compatibility. + //QString(""), // helpBrowser // Obsolete true, // extendedMidi 384, // division for smf export QString(""), // copyright string for smf export diff --git a/muse2/muse/widgets/popupmenu.cpp b/muse2/muse/widgets/popupmenu.cpp index af546ec3..af870975 100644 --- a/muse2/muse/widgets/popupmenu.cpp +++ b/muse2/muse/widgets/popupmenu.cpp @@ -341,21 +341,38 @@ void PopupMenu::popHovered(QAction* action) void PopupMenu::mouseReleaseEvent(QMouseEvent *e) { - #ifdef POPUP_MENU_DISABLE_STAY_OPEN + QAction* action = actionAt(e->pos()); + if (!(action && action == activeAction() && !action->isSeparator() && action->isEnabled())) + action=NULL; + + #ifdef POPUP_MENU_DISABLE_STAY_OPEN + if (action && action->menu() != NULL && action->isCheckable()) + action->activate(QAction::Trigger); + QMenu::mouseReleaseEvent(e); + + if (action && action->menu() != NULL && action->isCheckable()) + close(); + return; #else // Check for Ctrl to stay open. if(!_stayOpen || (!MusEGlobal::config.popupsDefaultStayOpen && (e->modifiers() & Qt::ControlModifier) == 0)) { + if (action && action->menu() != NULL && action->isCheckable()) + action->activate(QAction::Trigger); + QMenu::mouseReleaseEvent(e); + + if (action && action->menu() != NULL && action->isCheckable()) + close(); + return; } //printf("PopupMenu::mouseReleaseEvent\n"); - QAction *action = actionAt(e->pos()); - if (action && action == activeAction() && !action->isSeparator() && action->isEnabled()) + if (action) action->activate(QAction::Trigger); else QMenu::mouseReleaseEvent(e); diff --git a/muse2/muse/widgets/poslabel.cpp b/muse2/muse/widgets/poslabel.cpp index 6cdcb27e..b893c58d 100644 --- a/muse2/muse/widgets/poslabel.cpp +++ b/muse2/muse/widgets/poslabel.cpp @@ -138,7 +138,11 @@ void PosLabel::setTickValue(unsigned val) if (val == _tickValue) return; if (val >= MAX_TICK) - abort(); + { + printf("THIS SHOULD NEVER HAPPEN: val=%u > MAX_TICK=%u in PosLabel::setTickValue()!\n",val, MAX_TICK); + val=MAX_TICK-1; + } + _tickValue = val; updateValue(); } diff --git a/muse2/muse/widgets/projectcreate.ui b/muse2/muse/widgets/projectcreate.ui index 406c83d6..d03f093c 100644 --- a/muse2/muse/widgets/projectcreate.ui +++ b/muse2/muse/widgets/projectcreate.ui @@ -17,28 +17,94 @@ - - - Project Name: + + + + + Projects folder: + + + + + + + true + + + + + + + ... + + + + + + + + + Qt::Horizontal + + + + Project Name: + + + + + + + Project is a Template + + + Qt::Horizontal - QSizePolicy::Fixed + QSizePolicy::Minimum + + + + 60 + 20 + + + + + + + + + + + + Project song file type: + + + + + + + + + + Qt::Horizontal - 75 + 40 20 @@ -87,9 +153,16 @@ - + + + ... + + + + + - Browse + ... @@ -123,6 +196,18 @@ + + projectNameEdit + templateCheckBox + projectFileTypeCB + createFolderCheckbox + storageDirEdit + browseDirButton + commentEdit + buttonBox + projDirLineEdit + projDirToolButton + diff --git a/muse2/muse/widgets/projectcreateimpl.cpp b/muse2/muse/widgets/projectcreateimpl.cpp index 31973101..665d725e 100644 --- a/muse2/muse/widgets/projectcreateimpl.cpp +++ b/muse2/muse/widgets/projectcreateimpl.cpp @@ -4,6 +4,7 @@ // $Id: ./muse/widgets/projectcreateimpl.cpp $ // // Copyright (C) 1999-2011 by Werner Schweer and others +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -21,12 +22,16 @@ // //========================================================= #include -#include -#include +#include +#include +#include + #include "projectcreateimpl.h" #include "gconfig.h" #include "globals.h" #include "app.h" +#include "helper.h" +#include "icons.h" namespace MusEGui { @@ -35,10 +40,51 @@ ProjectCreateImpl::ProjectCreateImpl(QWidget *parent) : { setupUi(this); - createFolderCheckbox->setChecked(MusEGlobal::config.projectStoreInFolder); + //bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath); + directoryPath = MusEGlobal::config.projectBaseFolder; + + QStringList filters = localizedStringListFromCharArray(MusEGlobal::project_create_file_save_pattern, "file_patterns"); + projectFileTypeCB->addItems(filters); + + QString proj_title = MusEGlobal::muse->projectTitle(); + QString proj_path = MusEGlobal::muse->projectPath(); + QString proj_ext = MusEGlobal::muse->projectExtension(); + + projectNameEdit->setText(proj_title); + + bool is_template = proj_path.startsWith(MusEGlobal::configPath + "/templates"); + + templateCheckBox->setChecked(is_template); + + projDirPath = proj_path; + + int type_idx = 0; + if(!proj_ext.isEmpty()) + { + // FIXME Imperfect. Trying to avoid adding yet another series of character strings. p4.0.40 + type_idx = projectFileTypeCB->findText(proj_ext, Qt::MatchContains | Qt::MatchCaseSensitive); + if(type_idx == -1) + type_idx = 0; + } + projectFileTypeCB->setCurrentIndex(type_idx); + + projDirToolButton->setIcon(*openIcon); + browseDirButton->setIcon(*openIcon); + restorePathButton->setIcon(*undoIcon); + + restorePathButton->setEnabled(false); // Disabled at first. + + //createFolderCheckbox->setChecked(MusEGlobal::config.projectStoreInFolder && is_new); // Suggest no folder if not new. + + connect(templateCheckBox,SIGNAL(clicked()), this, SLOT(templateButtonChanged())); + //connect(templateCheckBox,SIGNAL(clicked()), this, SLOT(updateDirectoryPath())); + connect(projDirToolButton,SIGNAL(clicked()), this, SLOT(browseProjDir())); + connect(restorePathButton,SIGNAL(clicked()), this, SLOT(restorePath())); connect(browseDirButton,SIGNAL(clicked()), this, SLOT(selectDirectory())); - connect(projectNameEdit,SIGNAL(textChanged(QString)), this, SLOT(updateDirectoryPath())); - connect(createFolderCheckbox,SIGNAL(clicked()), this, SLOT(updateDirectoryPath())); + //connect(projectNameEdit,SIGNAL(textChanged(QString)), this, SLOT(updateDirectoryPath())); + connect(projectNameEdit,SIGNAL(textChanged(QString)), this, SLOT(updateProjectName())); + connect(createFolderCheckbox,SIGNAL(clicked()), this, SLOT(createProjFolderChanged())); + connect(projectFileTypeCB,SIGNAL(currentIndexChanged(int)), this, SLOT(updateDirectoryPath())); connect(buttonBox, SIGNAL(accepted()), this, SLOT(ok())); #if QT_VERSION >= 0x040700 projectNameEdit->setPlaceholderText(""); @@ -46,52 +92,155 @@ ProjectCreateImpl::ProjectCreateImpl(QWidget *parent) : // as of Qt-4.7.1 //commentEdit->setPlaceholderText(""); #endif - directoryPath = MusEGlobal::config.projectBaseFolder; updateDirectoryPath(); show(); } void ProjectCreateImpl::selectDirectory() { - QFileDialog qfd; - qfd.selectFile(directoryPath); - qfd.setFileMode(QFileDialog::DirectoryOnly); - if (qfd.exec() == QDialog::Rejected) { - return; - } - directoryPath=qfd.selectedFiles().first(); + QString dpath = templateCheckBox->isChecked() ? + (overrideTemplDirPath.isEmpty() ? (MusEGlobal::configPath + QString("/templates")) : overrideTemplDirPath) : + (overrideDirPath.isEmpty() ? directoryPath : overrideDirPath); + + QString dir = QFileDialog::getExistingDirectory(this, tr("Select directory"), dpath); + if(dir.isEmpty()) + return; + + (templateCheckBox->isChecked() ? overrideTemplDirPath : overrideDirPath) = dir; + restorePathButton->setEnabled(true); updateDirectoryPath(); } -void ProjectCreateImpl::updateDirectoryPath() +void ProjectCreateImpl::updateProjectName() { + QString curExt = projectFileTypeCB->currentText(); + if(curExt.isEmpty()) + curExt = ".med"; + else + { + curExt = MusEGui::getFilterExtension(curExt); + // Do we have a valid extension? + if(curExt.isEmpty()) + curExt = ".med"; + } + QString name = ""; if (createFolderCheckbox->isChecked()) { if (!projectNameEdit->text().isEmpty()) - name = projectNameEdit->text() + "/" + projectNameEdit->text() + ".med"; + //name = projectNameEdit->text() + "/" + projectNameEdit->text() + ".med"; + name = projectNameEdit->text() + "/" + projectNameEdit->text() + curExt; //storageDirEdit->setText(directoryPath + name ); } else { if (!projectNameEdit->text().isEmpty()) - name = projectNameEdit->text() + ".med"; + //name = projectNameEdit->text() + ".med"; + name = projectNameEdit->text() + curExt; //storageDirEdit->setText(directoryPath +"/" + name); } - storageDirEdit->setText(directoryPath +"/" + name ); // Tim + + bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath); + + QString dpath = templateCheckBox->isChecked() ? + (overrideTemplDirPath.isEmpty() ? (MusEGlobal::configPath + QString("/templates")) : overrideTemplDirPath) : + (overrideDirPath.isEmpty() ? (is_new ? directoryPath : projDirPath) : overrideDirPath); + + QDir proj_dir(dpath); + //if(is_project && MusEGlobal::config.projectStoreInFolder) + bool is_project = dpath.startsWith(MusEGlobal::config.projectBaseFolder); + //bool is_template = dpath.startsWith(MusEGlobal::configPath + "/templates") && templateCheckBox->isChecked(); + //bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath) && MusEGlobal::config.projectStoreInFolder; + //bool is_new = (MusEGlobal::museProject == MusEGlobal::museProjectInitPath) && + MusEGlobal::config.projectStoreInFolder && + (templateCheckBox->isChecked() ? overrideTemplDirPath.isEmpty() : overrideDirPath.isEmpty()); + //bool is_template = is_new && dpath.startsWith(MusEGlobal::configPath + "/templates") && templateCheckBox->isChecked(); + if(!is_new && createFolderCheckbox->isChecked() && !templateCheckBox->isChecked() && + (templateCheckBox->isChecked() ? overrideTemplDirPath.isEmpty() : overrideDirPath.isEmpty())) + proj_dir.cdUp(); + dpath = proj_dir.absolutePath(); + + //if(!initProjPath.isEmpty()) + //{ + // initProjPath.clear(); + //} + + storageDirEdit->blockSignals(true); + storageDirEdit->setText(dpath + "/" + name ); + storageDirEdit->blockSignals(false); + + projDirLineEdit->setEnabled(!templateCheckBox->isChecked() && is_project); +} + +void ProjectCreateImpl::updateDirectoryPath() +{ + updateProjectName(); + + projDirLineEdit->blockSignals(true); + projDirLineEdit->setText(MusEGlobal::config.projectBaseFolder); + projDirLineEdit->blockSignals(false); } -QString ProjectCreateImpl::getProjectPath() +QString ProjectCreateImpl::getProjectPath() const { return storageDirEdit->text(); } -QString ProjectCreateImpl::getSongInfo() + +QString ProjectCreateImpl::getSongInfo() const { return commentEdit->toPlainText(); } + void ProjectCreateImpl::ok() { MusEGlobal::config.projectStoreInFolder = createFolderCheckbox->isChecked(); - MusEGlobal::config.projectBaseFolder = directoryPath; - MusEGlobal::muse->changeConfig(true); + //MusEGlobal::config.projectBaseFolder = directoryPath; + //MusEGlobal::muse->changeConfig(true); emit accept(); } +void ProjectCreateImpl::createProjFolderChanged() +{ + //MusEGlobal::config.projectStoreInFolder = createFolderCheckbox->isChecked(); + //MusEGlobal::muse->changeConfig(true); // Save to config file. + updateDirectoryPath(); +} + +void ProjectCreateImpl::browseProjDir() +{ + QString dir = MusEGui::browseProjectFolder(this); + if(!dir.isEmpty()) + { + directoryPath = dir; + MusEGlobal::config.projectBaseFolder = dir; + MusEGlobal::muse->changeConfig(true); // Save to config file. + updateDirectoryPath(); + } +} + +void ProjectCreateImpl::templateButtonChanged() +{ + restorePathButton->setEnabled(templateCheckBox->isChecked() ? !overrideTemplDirPath.isEmpty() : !overrideDirPath.isEmpty()); + updateDirectoryPath(); +} + +void ProjectCreateImpl::restorePath() +{ + if(templateCheckBox->isChecked()) + overrideTemplDirPath.clear(); + else + overrideDirPath.clear(); + restorePathButton->setEnabled(templateCheckBox->isChecked() ? !overrideTemplDirPath.isEmpty() : !overrideDirPath.isEmpty()); + updateDirectoryPath(); +} + +/* +bool ProjectCreateImpl::getProjectIsTemplate() const +{ + return templateCheckBox->isChecked(); +} + +QString ProjectCreateImpl::getTemplatePath() const +{ + return templDirPath; +} +*/ + } //namespace MusEGui diff --git a/muse2/muse/widgets/projectcreateimpl.h b/muse2/muse/widgets/projectcreateimpl.h index 258b0921..f08cb1bc 100644 --- a/muse2/muse/widgets/projectcreateimpl.h +++ b/muse2/muse/widgets/projectcreateimpl.h @@ -4,6 +4,7 @@ // $Id: ./muse/widgets/projectcreateimpl.h $ // // Copyright (C) 1999-2011 by Werner Schweer and others +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -33,18 +34,28 @@ class ProjectCreateImpl : public QDialog, Ui::ProjectCreate Q_OBJECT QString directoryPath; + QString overrideDirPath; + QString overrideTemplDirPath; + QString projDirPath; + public: explicit ProjectCreateImpl(QWidget *parent = 0); - QString getProjectPath(); - QString getSongInfo(); + QString getProjectPath() const; + QString getSongInfo() const; + //bool getProjectIsTemplate() const; + //QString getTemplatePath() const; signals: -public slots: +protected slots: + void updateProjectName(); void updateDirectoryPath(); void selectDirectory(); void ok(); - + void createProjFolderChanged(); + void browseProjDir(); + void templateButtonChanged(); + void restorePath(); }; } // namespace MusEGui diff --git a/muse2/muse/widgets/routepopup.cpp b/muse2/muse/widgets/routepopup.cpp index 80ae98bd..0f1f8264 100644 --- a/muse2/muse/widgets/routepopup.cpp +++ b/muse2/muse/widgets/routepopup.cpp @@ -43,10 +43,10 @@ namespace MusEGui { int RoutePopupMenu::addMenuItem(MusECore::AudioTrack* track, MusECore::Track* route_track, PopupMenu* lb, int id, int channel, int channels, bool isOutput) { // totalInChannels is only used by syntis. - int toch = ((MusECore::AudioTrack*)track)->totalOutChannels(); + //int toch = ((MusECore::AudioTrack*)track)->totalOutChannels(); // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user. - if(track->channels() == 1) - toch = 1; + //if(track->channels() == 1) + // toch = 1; // Don't add the last stray mono route if the track is stereo. //if(route_track->channels() > 1 && (channel+1 == chans)) @@ -95,6 +95,13 @@ int RoutePopupMenu::addMenuItem(MusECore::AudioTrack* track, MusECore::Track* ro } } } + + if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden. + { + if( (isOutput ? track : route_track)->isCircularRoute(isOutput ? route_track : track) ) + act->setEnabled(false); + } + return ++id; } @@ -259,6 +266,13 @@ int RoutePopupMenu::addSyntiPorts(MusECore::AudioTrack* t, PopupMenu* lb, int id } } } + + if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden. + { + if( (isOutput ? t : track)->isCircularRoute(isOutput ? track : t) ) + act->setEnabled(false); + } + ++id; } @@ -520,6 +534,13 @@ int RoutePopupMenu::nonSyntiTrackAddSyntis(MusECore::AudioTrack* t, PopupMenu* l } } } + + if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden. + { + if( (isOutput ? t : track)->isCircularRoute(isOutput ? track : t) ) + act->setEnabled(false); + } + ++id; } @@ -573,6 +594,13 @@ int RoutePopupMenu::nonSyntiTrackAddSyntis(MusECore::AudioTrack* t, PopupMenu* l } } } + + if(!act->isChecked()) // If circular route exists, allow user to break it, otherwise forbidden. + { + if( (isOutput ? t : track)->isCircularRoute(isOutput ? track : t) ) + act->setEnabled(false); + } + ++id; } } @@ -1062,9 +1090,8 @@ void RoutePopupMenu::prepare() for( ; pi < MIDI_PORTS; ++pi) { MusECore::MidiDevice* md = MusEGlobal::midiPorts[pi].device(); - //if(md && !md->isSynti() && (md->rwFlags() & 2)) - //if(md && (md->rwFlags() & 2)) // p4.0.27 - if(md && (md->rwFlags() & 2 || md->isSynti()) ) // p4.0.27 + if(md && !md->isSynti() && (md->rwFlags() & 2)) + //if(md && (md->rwFlags() & 2 || md->isSynti()) ) // p4.0.27 Reverted p4.0.35 break; } if(pi == MIDI_PORTS) @@ -1091,12 +1118,9 @@ void RoutePopupMenu::prepare() // continue; // Do not list synth devices! - ///if(md && md->isSynti()) - /// continue; - ///if(md && !(md->rwFlags() & 2)) - /// continue; - // p4.0.27 Go ahead. Synths esp MESS send out stuff. - if( md && !(md->rwFlags() & 2) && !md->isSynti() ) + if( md && (!(md->rwFlags() & 2) || md->isSynti()) ) + // p4.0.27 Go ahead. Synths esp MESS send out stuff. Reverted p4.0.35 + //if( md && !(md->rwFlags() & 2) && !md->isSynti() ) continue; //printf("MusE::prepareRoutingPopupMenu adding submenu portnum:%d\n", i); diff --git a/muse2/muse/widgets/synthconfigbase.ui b/muse2/muse/widgets/synthconfigbase.ui index 97f0beaa..500241a8 100644 --- a/muse2/muse/widgets/synthconfigbase.ui +++ b/muse2/muse/widgets/synthconfigbase.ui @@ -6,12 +6,12 @@ 0 0 - 630 + 810 492 - MusE: Synth Configuration + Midi Port and Soft Synth Configuration @@ -30,6 +30,11 @@ Name + + + Type + + Midi Port @@ -135,6 +140,11 @@ File + + + Type + + Inst diff --git a/muse2/muse/widgets/utils.cpp b/muse2/muse/widgets/utils.cpp index 708bef07..1641b267 100644 --- a/muse2/muse/widgets/utils.cpp +++ b/muse2/muse/widgets/utils.cpp @@ -528,7 +528,8 @@ int get_paste_len() if (p->endTick() > end_tick) end_tick=p->endTick(); - + + unchainClone(p); delete p; } } diff --git a/muse2/muse/widgets/visibletracks.cpp b/muse2/muse/widgets/visibletracks.cpp index f8ce06bf..4976ecf9 100644 --- a/muse2/muse/widgets/visibletracks.cpp +++ b/muse2/muse/widgets/visibletracks.cpp @@ -29,6 +29,7 @@ #include "action.h" #include "track.h" #include "synth.h" +#include "app.h" namespace MusEGui { @@ -130,6 +131,7 @@ void VisibleTracks::visibilityChanged(QAction* action) default: break; } + MusEGlobal::muse->changeConfig(true); // save settings emit visibilityChanged(); } diff --git a/muse2/muse/widgets/visibletracks.h b/muse2/muse/widgets/visibletracks.h index d56c9ce7..bf49c068 100644 --- a/muse2/muse/widgets/visibletracks.h +++ b/muse2/muse/widgets/visibletracks.h @@ -52,13 +52,14 @@ class VisibleTracks : public QToolBar { private slots: void visibilityChanged(QAction* action); + public slots: + void updateVisibleTracksButtons(); signals: void visibilityChanged(); public: VisibleTracks(QWidget* /*parent*/, const char* name = 0); // Needs a parent ! - void updateVisibleTracksButtons(); ~VisibleTracks(); }; diff --git a/muse2/muse/xml.cpp b/muse2/muse/xml.cpp index 139437c1..45bed368 100644 --- a/muse2/muse/xml.cpp +++ b/muse2/muse/xml.cpp @@ -4,6 +4,7 @@ // $Id: xml.cpp,v 1.17.2.6 2009/12/07 20:48:45 spamatica Exp $ // // (C) Copyright 2000 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -24,6 +25,7 @@ #include #include +#include #include #include #include @@ -112,9 +114,12 @@ void Xml::nextc() void Xml::token(int cc) { - char buffer[512]; + //char buffer[512]; + QByteArray buffer; + int i = 0; - for (; i < 511;) { + //for (; i < 511;) { + for (; i < 9999999;) { // Stop at a reasonably large amount 10 million. if (c == ' ' || c == '\t' || c == cc || c == '\n' || c == EOF) break; buffer[i++] = c; @@ -131,12 +136,16 @@ void Xml::token(int cc) void Xml::stoken() { - char buffer[1024*4]; + //char buffer[1024*4]; + QByteArray buffer; + int i = 0; buffer[i] = c; ++i; next(); - for (;i < 1024*4-1;) { + + //for (;i < 1024*4-1;) { + for (;i < 10000000*4-1;) { // Stop at a reasonably large amount 10 million. if (c == '"') { buffer[i++] = c; next(); @@ -207,8 +216,10 @@ QString Xml::strip(const QString& s) Xml::Token Xml::parse() { - char buffer[1024*1024]; // increase buffer -rj - char* p; + //char buffer[1024*1024]; // increase buffer -rj + //char* p; + QByteArray buffer; + int idx = 0; again: bool endFlag = false; @@ -262,15 +273,23 @@ Xml::Token Xml::parse() } if (c == '?') { next(); - p = buffer; + //p = buffer; + //p = buffer.data(); + idx = 0; for (;;) { if (c == '?' || c == EOF || c == '>') break; - *p++ = c; + + //*p++ = c; + buffer[idx++] = c; + // TODO: check overflow next(); } - *p = 0; + + //*p = 0; + buffer[idx] = 0; + _s1 = QString(buffer); if (c == EOF) { fprintf(stderr, "XML: unexpected EOF\n"); @@ -298,15 +317,23 @@ Xml::Token Xml::parse() } goto again; } - p = buffer; + //p = buffer; + //p = buffer.data(); + idx = 0; for (;;) { if (c == '/' || c == ' ' || c == '\t' || c == '>' || c == '\n' || c == EOF) break; // TODO: check overflow - *p++ = c; + + //*p++ = c; + buffer[idx++] = c; + next(); } - *p = 0; + + //*p = 0; + buffer[idx] = 0; + _s1 = QString(buffer); // skip white space: while (c == ' ' || c == '\t' || c == '\n') @@ -355,26 +382,43 @@ Xml::Token Xml::parse() fprintf(stderr, "XML: level = 0\n"); goto error; } - p = buffer; + //p = buffer; + //p = buffer.data(); + idx = 0; for (;;) { if (c == EOF || c == '<') break; if (c == '&') { next(); if (c == '<') { // be tolerant with old muse files - *p++ = '&'; + + //*p++ = '&'; + buffer[idx++] = '&'; + continue; } - char name[32]; - char* dp = name; - *dp++ = c; - for (; dp-name < 31;) { + + //char name[32]; + //char* dp = name; + QByteArray name; + int name_idx = 0; + + //*dp++ = c; + name[name_idx++] = c; + + //for (; dp-name < 31;) { + for (; name_idx < 9999999;) { // Stop at a reasonably large amount 10 million. next(); if (c == ';') break; - *dp++ = c; + + //*dp++ = c; + name[name_idx++] = c; } - *dp = 0; + + //*dp = 0; + name[name_idx] = 0; + if (strcmp(name, "lt") == 0) c = '<'; else if (strcmp(name, "gt") == 0) @@ -388,10 +432,16 @@ Xml::Token Xml::parse() else c = '?'; } - *p++ = c; + + //*p++ = c; + buffer[idx++] = c; + next(); } - *p = 0; + + //*p = 0; + buffer[idx] = 0; + _s1 = QString(buffer); if (c == '<') diff --git a/muse2/share/locale/muse_de.ts b/muse2/share/locale/muse_de.ts index 1284b82d..5b827ede 100644 --- a/muse2/share/locale/muse_de.ts +++ b/muse2/share/locale/muse_de.ts @@ -219,22 +219,22 @@ click on part to mute/unmute Alle Dateien (*) - + Add Midi Track Midispur hinzufügen - + Add Drum Track Schlagzeugspur hinzufügen - + Add Wave Track Wavespur hinzufügen - + Add Audio Output Audioausgang hinzufügen @@ -270,7 +270,7 @@ click on part to mute/unmute FST - + Add Synth Synthesizer hinzufügen @@ -5074,7 +5074,7 @@ Konfiguration MusE: Globale Einstellungen - + Audio Audio @@ -5200,12 +5200,11 @@ Konfiguration (Ticks/Sekunde) - GUI - GUI + GUI - + /sec /sek @@ -5254,7 +5253,22 @@ Bereichen die linke Maustaste wie die mittlere verhält. Shift + Rechtsklick setzt den linken Bereichs-Marker - + + Allow adding hidden tracks in track list menu + Erlaube es, verborgene Spurtypen hinzuzufügen in der Spurliste + + + + Unhide tracks when adding hidden tracks + Verborgene Spurentypen anzeigen, wenn ein solcher Typ hinzugefügt wird + + + + GUI Style + GUI-Stil + + + MDI-subwindowness and sharing menus Unterfenster und Menü-Teilen @@ -5298,12 +5312,12 @@ Bereichen die linke Maustaste wie die mittlere verhält. Hilfe Browser: - + Application Anwendung - + Start Muse MusE starten @@ -5483,7 +5497,22 @@ Bereichen die linke Maustaste wie die mittlere verhält. 16 - + + Project directory + Projektverzeichnis + + + + Projects: + Projekte: + + + + ... + ... + + + Main Window Hauptfenster @@ -5633,12 +5662,16 @@ einen höheren Wert. (Ticks/Viertelnote) - Instruments Directory - Instrumentenverzeichnis + Instrumentenverzeichnis - + + GUI Behaviour + GUI-Verhalten + + + Use old-style stop shortcut: Benutze altes Stopp-Kürzel: @@ -5648,12 +5681,12 @@ einen höheren Wert. Bewege "für Aufnahme scharfschalten" mit Auswahl - + On Launch Beim Start - + Behavior Verhalten @@ -7400,6 +7433,11 @@ bis zum Senden des ersten Clocks. Send sync delay Pause für das Senden von Sync + + + Note: Sync delay and MTC sync currently not fully implemeted + Hinweis: Sync delay und MTC sync sind momentan nicht komplett implementiert + MidiTrackInfoBase @@ -9917,7 +9955,7 @@ Wahrscheinlich hat dir ausgewählte Spur den falschen Typ. MusECore::Song - + Jack shutdown! Jack heruntergefahren! @@ -10016,7 +10054,7 @@ Knopf. &Abbrechen - + MusE - external script failed MusE - externes Skript fehlgeschlagen @@ -10064,6 +10102,14 @@ Knopf. Viertelnoten + + MusEGui + + + Select project directory + Projektverzeichnis auswählen + + MusEGui::Appearance @@ -10445,7 +10491,7 @@ Rechtsklick, um die GUI zu zeigen. Transport - + C&ut &Ausschneiden @@ -10551,13 +10597,13 @@ Rechtsklick, um die GUI zu zeigen. - all parts in one staff - alle Parts in ein System + all tracks in one staff + alle Spuren in ein System - one staff per part - ein System pro Part + one staff per track + ein System pro Spur @@ -10615,6 +10661,21 @@ Rechtsklick, um die GUI zu zeigen. Global Split Globales Aufteilen + + + Global Cut - selected tracks + Globaler Schnitt - markierte Spuren + + + + Global Insert - selected tracks + Globales Einfügen - markierte Spuren + + + + Global Split - selected tracks + Globales Aufteilen - markierte Spuren + &Edit @@ -10626,7 +10687,7 @@ Rechtsklick, um die GUI zu zeigen. &Struktur - + Functions Funktionen @@ -10686,7 +10747,7 @@ Rechtsklick, um die GUI zu zeigen. Fenster&konfiguration - + New Neu @@ -10753,7 +10814,7 @@ Rechtsklick, um die GUI zu zeigen. MusEGui::AudioStrip - + panorama Panorama @@ -10783,7 +10844,7 @@ Rechtsklick, um die GUI zu zeigen. Vor Regler - nach Regler - + dB dB @@ -10912,7 +10973,7 @@ Rechtsklick, um die GUI zu zeigen. MusEGui::ClipListEdit - + MusE: Clip List Editor MusE: Clip-Listen-Editor @@ -11026,7 +11087,7 @@ Rechtsklick, um die GUI zu zeigen. MusEGui::DrumEdit - + mute instrument Instrument stummschalten @@ -11382,7 +11443,7 @@ Rechtsklick, um die GUI zu zeigen. LV4 - + Muse: Load Drum Map MusE: Schlagzeugbelegung laden @@ -11447,50 +11508,40 @@ Rechtsklick, um die GUI zu zeigen. MusE: Datei schreiben schlug fehl - - - - MusE: - MusE: + MusE: - - The user instrument directory %1 does not exist yet. Create it now? - Das Benutzerinstrumentenverzeichnis + Das Benutzerinstrumentenverzeichnis %1 existiert nicht. Jetzt erzeugen? - - (You can change the user instruments directory at Settings->Global Settings->Midi) - (Sie können das Benutzer-Instrumentenversuchnis unter Einstellungen -> Globale Einstellungen -> Midi ändern) + (Sie können das Benutzer-Instrumentenversuchnis unter Einstellungen -> Globale Einstellungen -> Midi ändern) - - Unable to create user instrument directory '%1' - Konnte das Benutzer-Instrumentenverzeichnis "%1" nicht anlegen + Konnte das Benutzer-Instrumentenverzeichnis "%1" nicht anlegen - - + + MusE: Save Instrument Definition MusE: Instrumentendefinition speichern - - + + Instrument Definition (*.idf) Instrumentendefinition (*.idf) - + MusE: Save instrument as MusE: Instrument speichern unter @@ -11508,7 +11559,7 @@ Are you sure? Sind Sie sicher? - + MusE: Bad instrument name MusE: Ungeeigneter Instrumentenname @@ -11857,9 +11908,8 @@ click on part to mute/unmute MusEGui::GlobalSettingsConfig - Selects instruments directory - Wählt Instrumentenverzeichnis aus + Wählt Instrumentenverzeichnis aus @@ -11873,7 +11923,7 @@ click on part to mute/unmute MusEGui::LMaster - + MusE: Mastertrack MusE: Masterspur @@ -11988,7 +12038,7 @@ click on part to mute/unmute Wert - + Reposition of the initial tempo and signature events is not allowed Das Verschieben der initialen Tempo- und Taktmaß-Events ist nicht erlaubt @@ -12011,7 +12061,7 @@ click on part to mute/unmute MusEGui::ListEdit - + insert Note Note einfügen @@ -12176,18 +12226,18 @@ Möchten Sie sie jetzt auf alle existierende MIDI-Spuren anwenden? - + in ein - - + + out aus - + Show first aliases Zeige erste Aliase @@ -12393,13 +12443,13 @@ Möchten Sie sie jetzt auf alle existierende MIDI-Spuren anwenden? Status - + <unknown> <unbekannt> - + <none> <kein> @@ -12423,7 +12473,7 @@ Möchten Sie sie jetzt auf alle existierende MIDI-Spuren anwenden? MusEGui::MarkerView - + MusE: Marker MusE: Marker @@ -12496,7 +12546,7 @@ Möchten Sie sie jetzt auf alle existierende MIDI-Spuren anwenden? MusEGui::MasterEdit - + MusE: Mastertrack MusE: Masterspur @@ -13049,7 +13099,7 @@ Sync-Einstellungen anwenden? MusEGui::MidiTrackInfo - + <unknown> <unbekannt> @@ -13074,7 +13124,7 @@ Sync-Einstellungen anwenden? MusEGui::MusE - + Failed to start audio! Audio konnte nicht gestartet werden! @@ -13092,7 +13142,7 @@ Sync-Einstellungen anwenden? Timeout beim Warten auf Audio. Überprüfen Sie, ob Jack läuft. - + Und&o &Rückgängig @@ -13241,13 +13291,13 @@ Sync-Einstellungen anwenden? - - + + &Save &Speichern - + 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. @@ -13276,7 +13326,7 @@ Alternativ das Lied mit dem Befehl "Sichern" im Menü "Datei" - + Import Wave File Wavedatei importieren @@ -13531,7 +13581,7 @@ Alternativ das Lied mit dem Befehl "Sichern" im Menü "Datei" Transport - + &File &Datei @@ -13571,12 +13621,12 @@ Alternativ das Lied mit dem Befehl "Sichern" im Menü "Datei" &Hilfe - + Cannot read template Vorlage nicht lesbar - + File open error Fehler beim Datei öffnen @@ -13591,14 +13641,14 @@ Alternativ das Lied mit dem Befehl "Sichern" im Menü "Datei" Unbekanntes Dateiformat: %1 - - - + + + MusE: Song: %1 MusE: Lied: %1 - + MusE: load project Muse: Projekt laden @@ -13608,7 +13658,7 @@ Alternativ das Lied mit dem Befehl "Sichern" im Menü "Datei" Muse: Vorlage laden - + MusE: Write File failed MusE: Datei schreiben schlug fehl @@ -13621,29 +13671,28 @@ Aktuelles Projekt sichern? - + S&kip &Überspringen - + &Cancel &Abbrechen - - + MusE: Save As MusE: Speichern unter - + Nothing to edit Es gibt nichts zu editieren - + @@ -13703,7 +13752,7 @@ und eine Audio-Ausgangs-Spur Linken/rechten Marker für Abmischbereich einstellen - + The current Project contains unsaved data Load overwrites current Project: Save Current Project? @@ -13713,7 +13762,7 @@ Aktuelles Projekt sichern? - + &Abort &Abbrechen @@ -13779,7 +13828,7 @@ failed: schlug fehl: - + Import part is only valid for midi and wave tracks! Part importieren ist nur möglich für MIDI und WAVE-Spuren! @@ -13886,7 +13935,7 @@ Möchten Sie sie dennoch importieren? Kopieren/verschieben/klonen auf anderen Spurtyp nicht möglich - + C&ut &Ausschneiden @@ -13965,7 +14014,7 @@ Files: Dateien: - + %n part(s) out of %1 could not be pasted. Likely the selected track is the wrong type. @@ -14066,7 +14115,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. MusEGui::PianoRoll - + &Edit &Bearbeiten @@ -14273,7 +14322,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. MusEGui::PluginDialog - + MusE: select plugin MusE: PlugIn wählen @@ -14376,7 +14425,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. MusEGui::PluginGui - + File Buttons Datei-Knöpfe @@ -14412,35 +14461,43 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. MusE: Vorlage sichern + + MusEGui::ProjectCreateImpl + + + Select directory + Verzeichnis auswählen + + MusEGui::RoutePopupMenu - + - + - - + + Channel Kanal - - + + Soloing chain Solo-Kette - - + + Audio returns Audio-Rückkanäle - + Warning: No input devices! Warnung: Keine Eingangsgeräte! @@ -14450,7 +14507,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. Öffne MIDI-Konfig... - + <none> <kein> @@ -14479,7 +14536,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. MusEGui::ScoreCanvas - + Treble Violinschlüssel @@ -14499,7 +14556,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. Notenzeile entfernen - + Ambiguous part Unklarer Part @@ -14522,7 +14579,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. MusEGui::ScoreEdit - + Undo/Redo tools Rückgängig/Wiederholen-Werkzeuge @@ -14562,20 +14619,20 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. letzte - + - + Apply to new notes: Für neue Noten: - - + + Apply to selected notes: Für markierte Noten: - + Velocity: Dynamik: @@ -14595,7 +14652,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. Quantisierung: - + Pixels per whole: Pixel pro ganze Note: @@ -14745,7 +14802,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. Je nach &Part - + Set up &preamble &Preambel einstellen @@ -14765,7 +14822,7 @@ Wahrscheinlich hat die ausgewählte Spur den falschen Typ. Partitur&name setzen - + Enter the new score title Geben Sie den neuen Titel ein @@ -14833,15 +14890,28 @@ Titel ist nicht einzigartig Taktmaß-Skala + + MusEGui::Strip + + + Remove track? + Spur entfernen? + + MusEGui::TList - + <none> <kein> - + + visible + sichtbar + + + no clef kein Notenschlüssel @@ -14871,30 +14941,30 @@ Titel ist nicht einzigartig Bitte eindeutigen Spurnamen wählen - - + + Update drummap? Drumbelegung aktualisieren? - + Do you want to use same port for all instruments in the drummap? Möchten Sie für alle Instrumente der Drumbelegung den selben Anschluss verwenden? - + &Yes &Ja - - + + &No &Nein - + show gui GUI anzeigen @@ -14906,7 +14976,7 @@ Titel ist nicht einzigartig Native GUI anzeigen - + Treble clef Violinschlüssel @@ -14926,7 +14996,7 @@ Titel ist nicht einzigartig Sichtbare Automatisierung - + Delete Track Spur löschen @@ -14941,7 +15011,7 @@ Titel ist nicht einzigartig Spur einfügen - + Midi Midi @@ -14955,6 +15025,11 @@ Titel ist nicht einzigartig Do you want to use same port and channel for all instruments in the drummap? Möchten Sie für alle Instrumente der Drumbelegung den selben Anschluss und Kanal verwenden? + + + Unused Devices + Ungenutzte Geräte + MusEGui::TempoSig @@ -14967,7 +15042,7 @@ Titel ist nicht einzigartig MusEGui::Toolbar1 - + Off @@ -15007,7 +15082,7 @@ Titel ist nicht einzigartig Vollbild - + Piano roll Pianoroll @@ -15265,7 +15340,7 @@ Titel ist nicht einzigartig MusEGui::VisibleTracks - + Show wave tracks Zeige Wave-Spuren @@ -16650,12 +16725,34 @@ erweitert werden muss um nicht mehr als Projekt erzeugen - + + Projects folder: + Projektverzeichnis: + + + + + + ... + ...... + + + Project Name: Projekt-Name: - + + Project is a Template + Projekt ist eine Vorlage + + + + Project song file type: + Projekt-Lieddatei-Typ: + + + Project Path to song file: Projektpfad zur Lieddatei: @@ -16665,12 +16762,11 @@ erweitert werden muss um nicht mehr als Erzeuge Projektverzeichnis (empfohlen für Audioprojekte) - Browse - Durchsuchen + Durchsuchen - + Song information: Lied-Information: @@ -16811,9 +16907,8 @@ gegenwärtig nicht benutzt QObject - Other - Andere + Andere @@ -16848,7 +16943,7 @@ gegenwärtig nicht benutzt Neu - + create peakfile for Pegelspitzendatei erzeugen für @@ -16899,7 +16994,7 @@ Erzeugen? Verzeichnis erzeugen schlug fehl - + File %1 exists. Overwrite? @@ -16908,7 +17003,7 @@ exists. Overwrite? existiert. Überschreiben? - + Open File %1 failed: %2 @@ -16925,7 +17020,7 @@ exists besteht - + MusE: write MusE: schreiben @@ -16948,13 +17043,13 @@ failed: schlug fehl: - + MusE: Open File MusE: Datei öffnen - - + + None Kein @@ -18069,12 +18164,11 @@ Rhythmus Zufallsgenerator noch nicht eingeführt! SynthConfigBase - MusE: Synth Configuration - MusE: Synth Einstellung + MusE: Synth Einstellung - + Soft Synthesizer Software-Synthesizer @@ -18084,18 +18178,18 @@ Rhythmus Zufallsgenerator noch nicht eingeführt! Datei - + Instances Instanzen - + Name Name - + list of available software synthesizers Liste verfügbarer Software-Synthesizer @@ -18115,12 +18209,23 @@ Rhythmus Zufallsgenerator noch nicht eingeführt! Midi Anschluss - + + Midi Port and Soft Synth Configuration + MIDI-Port- und SoftSynth-Konfiguration + + + + + Type + Typ + + + Midi connections Midi Verbindungen - + Inst Inst @@ -18969,7 +19074,7 @@ Robert Jonsson - + @@ -18981,7 +19086,7 @@ Robert Jonsson Alle Dateien (*) - + Midi (*.mid) Midi (*.mid) @@ -19003,28 +19108,31 @@ Robert Jonsson + Uncompressed med Files (*.med) Unkomprimierte med-Dateien (*.med) - + + gzip compressed med Files (*.med.gz) Mit gzip komprimierte med-Dateien (*.med.gz) - + + bzip2 compressed med Files (*.med.bz2) Mit bzip2 komprimierte med-Dateien (*.med.bz2) - + mid Files (*.mid *.midi *.kar *.MID *.MIDI *.KAR) Midi-Dateien (*.mid *.midi *.kar *.MID *.MIDI *.KAR) - + (*.jpg *.gif *.png) (*.jpg *.gif *.png) diff --git a/muse2/share/locale/muse_en.ts b/muse2/share/locale/muse_en.ts index c6e38689..867761ce 100644 --- a/muse2/share/locale/muse_en.ts +++ b/muse2/share/locale/muse_en.ts @@ -4,42 +4,42 @@ @default - + Add Midi Track - + Add Drum Track - + Add Wave Track - + Add Audio Output - + Add Audio Group - + Add Audio Input - + Add Aux Send - + Add Synth @@ -4041,7 +4041,7 @@ Adjusts responsiveness of audio controls and - GUI + GUI Behaviour @@ -4104,42 +4104,57 @@ left button behave like the middle button in such areas. - + + Allow adding hidden tracks in track list menu + + + + + Unhide tracks when adding hidden tracks + + + + + GUI Style + + + + MDI-subwindowness and sharing menus - + Presets: - + traditional MusE SDI - + Cakewalk-like MDI - + Borland-/Mac-like MDI - + &Apply - + &Ok - + &Cancel @@ -5124,6 +5139,11 @@ Enabled inputs in the list will Send sync delay + + + Note: Sync delay and MTC sync currently not fully implemeted + + MidiTrackInfoBase @@ -5808,12 +5828,12 @@ Enabled inputs in the list will MusECore::Song - + Jack shutdown! - + Jack has detected a performance problem which has lead to MusE being disconnected. This could happen due to a number of reasons: @@ -5832,71 +5852,71 @@ click on the Restart button. - - + + Automation: - + previous event - + next event - - + + set event - - + + add event - - + + erase event - + erase range - + clear automation - + Clear all controller events? - + &Ok - + &Cancel - + MusE - external script failed - + MusE was unable to launch the script, error message: %1 @@ -6302,249 +6322,264 @@ Right-click to show GUI. - + C&ut - + &Copy - + Copy in range - + &Paste - + Paste (show dialog) - + Paste c&lone - + Paste clone (show dialog) - + &Insert Empty Measure - + Delete Selected Tracks - + Shrink selected parts - + Expand selected parts - + Clean selected parts - + Add Track - + Select - + Select &All - + &Deselect All - + Invert &Selection - + &Inside Loop - + &Outside Loop - + All &Parts on Track - + Score - - all parts in one staff + + all tracks in one staff - - one staff per part + + one staff per track - + New score window - + Pianoroll - + Drums - - + + List - + Wave - + Mastertrack - + Graphic - + Midi &Transform - + Global Cut - + Global Insert - + Global Split - + + Global Cut - selected tracks + + + + + Global Insert - selected tracks + + + + + Global Split - selected tracks + + + + &Edit - + &Structure - + Functions - + &Quantize Notes - + Change note &length - + Change note &velocity - + Crescendo/Decrescendo - + Transpose - + Erase Events (Not Parts) - + Move Events (Not Parts) - + Set Fixed Note Length - + Delete Overlapping Notes - + Legato - + Window &Config - - + + New @@ -6610,108 +6645,108 @@ Right-click to show GUI. MusEGui::AudioStrip - + panorama - + aux send level - + Pan - + 1/2 channel - + Pre - + pre fader - post fader - + dB - + record - + mute - + record downmix - - + + solo mode - + off - + iR - + input routing - + oR - + output routing - + Off - + Read - + Touch - + Write - + automation type @@ -6769,27 +6804,27 @@ Right-click to show GUI. MusEGui::ClipListEdit - + MusE: Clip List Editor - + Undo/Redo tools - + panic - + transport - + Window &Config @@ -6882,379 +6917,379 @@ Right-click to show GUI. MusEGui::DrumEdit - - - - mute instrument - - - sound name + mute instrument - volume percent + sound name - quantisation + volume percent - this input note triggers the sound + quantisation - note length + this input note triggers the sound - this is the note which is played + note length - output channel (hold ctl to affect all rows) + + this is the note which is played - output port (hold ctl to affect all rows) + output channel (hold ctl to affect all rows) - - shift + control key: draw velocity level 1 + output port (hold ctl to affect all rows) - control key: draw velocity level 2 + shift + control key: draw velocity level 1 - shift key: draw velocity level 3 + control key: draw velocity level 2 + shift key: draw velocity level 3 + + + + + draw velocity level 4 - + output channel (ctl: affect all rows) - + output port (ctl: affect all rows) - + &File - + Load Map - + Save Map - + Reset GM Map - + &Edit - + Cut - + Copy - + Copy events in range - + Paste - + Paste (with Dialog) - + Delete Events - + &Select - + Select All - + Select None - + Invert - + Inside Loop - + Outside Loop - + Previous Part - + Next Part - + Fu&nctions - + Re-order list - + Set Fixed Length - + Modify Velocity - + Crescendo/Decrescendo - + Quantize - + Erase Event - + Move Notes - + Delete Overlaps - + &Plugins - + Window &Config - + Drum tools - + Load Drummap - + Store Drummap - + Step Record - + Midi Input - + cursor tools - + Set step size for cursor edit - + panic - + transport - + ctrl - + Add Controller View - + M - + Sound - + Vol - + QNT - + E-Note - + Len - + A-Note - + Ch - + Port - + LV1 - + LV2 - + LV3 - + LV4 - + Muse: Load Drum Map - + MusE: Store Drum Map - + Drum map - + Reset the drum map with GM defaults? @@ -7697,7 +7732,7 @@ click on part to mute/unmute MusEGui::GlobalSettingsConfig - + Selects instruments directory @@ -7713,137 +7748,137 @@ click on part to mute/unmute MusEGui::LMaster - + MusE: Mastertrack - + &Edit - + Insert Tempo - + Insert Signature - + Insert Key - + Edit Positon - + Edit Value - + Delete Event - + Window &Config - + Undo/Redo tools - + Edit tools - + Tempo - + Timesig - + Key - + new tempo - + new signature - + new key - + panic - + transport - + Meter - + Time - + Type - + Value - + Reposition of the initial tempo and signature events is not allowed - + MusE: List Editor - + Input error, conversion not OK or value out of range - + Reposition of tempo and signature events to start position is not allowed! @@ -7851,127 +7886,127 @@ click on part to mute/unmute MusEGui::ListEdit - + insert Note - + insert SysEx - + insert Ctrl - + insert Meta - + insert Channel Aftertouch - + insert Poly Aftertouch - + &Edit - + Cut - + Copy - + Paste - + Delete Events - + Window &Config - + Undo/Redo tools - + Insert tools - + panic - + transport - + Tick - + Bar - + Type - + Ch - + Val A - + Val B - + Val C - + Len - + Comment @@ -8015,13 +8050,13 @@ Do you want to apply to all existing midi tracks now? - + in - + out @@ -8224,13 +8259,13 @@ Do you want to apply to all existing midi tracks now? - + <unknown> - - + + <none> @@ -8254,72 +8289,72 @@ Do you want to apply to all existing midi tracks now? MusEGui::MarkerView - + MusE: Marker - + add marker - + delete marker - + &Edit - + Window &Config - + Undo/Redo tools - + edit tools - + panic - + transport - + Bar:Beat:Tick - + Hr:Mn:Sc:Fr:Sf - + Lock - + Text - + Marker Properties @@ -8327,92 +8362,92 @@ Do you want to apply to all existing midi tracks now? MusEGui::MasterEdit - + MusE: Mastertrack - + Window &Config - + Undo/Redo tools - + panic - + transport - + Enable master - + Enable - + Enable usage of master track - + Info - + Cursor - + time at cursor position - + tempo at cursor position - + Off - + Bar - + Snap - + CurPos - + tempo at current position - + time signature at current position @@ -8850,7 +8885,7 @@ Apply sync settings? MusEGui::MidiTrackInfo - + <unknown> @@ -8893,622 +8928,622 @@ Apply sync settings? - + Und&o - + Re&do - + undo last change to song - + redo last undo - + Loop - + loop between left mark and right mark - + Punchin - + record starts at left mark - + Punchout - + record stops at right mark - + Start - + rewind to start position - + Rewind - + rewind current position - + Forward - + move current position - + Stop - + stop sequencer - + Play - + start sequencer play - + Record - + to record press record and then play - - + + Panic - + send note off to all midi channels - + &New - + Create New Song - + &Open - - + + Click this button to open a <em>new song</em>.<br>You can also select the <b>Open command</b> from the File menu. - + Open &Recent - - - + + + &Save - - + + 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. - + Save &As - + Import Midifile - + Export Midifile - + Import Part - - + + Import Wave File - + Find unused wave files - + &Quit - + Song Info - + Transport Panel - + Bigtime Window - + Mixer A - + Mixer B - + Cliplist - + Marker View - + Arranger View - + Fullscreen - + &Plugins - + Edit Instrument - + Input Plugins - + Transpose - + Midi Input Transform - + Midi Input Filter - + Midi Remote Control - + Rhythm Generator - + Reset Instr. - + Init Instr. - + Local Off - + Bounce to Track - + Bounce to File - + Restart Audio - + Mixer Automation - + Take Snapshot - + Clear Automation Data - + Cascade - + Tile - + In rows - + In columns - + Global Settings - + Configure Shortcuts - + Follow Song - + Don't Follow Song - + Follow Page - + Follow Continuous - + Metronome - + Midi Sync - + Midi File Import/Export - + Appearance Settings - + Midi Ports / Soft Synth - + &Manual - + &MusE Homepage - + &Report Bug... - + &About MusE - + File Buttons - + Undo/Redo - + Transport - + &File - + &View - + &Midi - + &Audio - + A&utomation - + &Windows - + MusE Se&ttings - + &Help - + Cannot read template - + File open error - + File read error - + Unknown File Format: %1 - - - + + + MusE: Song: %1 - + MusE: load project - + MusE: load template - + MusE: Write File failed - + The current Project contains unsaved data Save Current Project? - - + + S&kip - + &Cancel - - + + MusE: Save As - - + + Nothing to edit - - - - - + + + + + MusE: Bounce to Track - + No wave tracks found - - + + No audio output tracks found - + Select one audio output track, and one target wave track - + Select one target wave track - + Select one target wave track, and one audio output track - - + + MusE: Bounce to File - + Select one audio output track - + MusE: Bounce - + set left/right marker for bounce range - + The current Project contains unsaved data Load overwrites current Project: Save Current Project? - - + + &Abort @@ -9539,34 +9574,34 @@ browser on your machine. - + MusE: Import Midi - + Add midi file to current project? - + &Add to Project - + &Replace - + reading midifile - + failed: @@ -9609,29 +9644,29 @@ Likely the selected track is the wrong type. - + to import an audio file you have first to selecta wave track - + Import Wavefile - + This wave file has a samplerate of %1, as opposed to current setting %2. Do you still want to import it? - + &Yes - + &No @@ -9677,85 +9712,85 @@ Do you still want to import it? - + C&ut - + &Copy - + s&elect - + clones - + rename - + color - + delete - + split - + glue - + de-clone - - - + + + save part to disk - + wave edit - + file info - + MusE: save part - + Part name: %1 Files: - + %n part(s) out of %1 could not be pasted. Likely the selected track is the wrong type. @@ -9766,7 +9801,7 @@ Likely the selected track is the wrong type. - + %n part(s) could not be pasted. Likely the selected track is the wrong type. @@ -9777,32 +9812,32 @@ Likely the selected track is the wrong type. - + Cannot paste: multiple tracks selected - + Cannot paste: no track selected - + Can only paste to midi/drum track - + Can only paste to wave track - + Can only paste to midi or wave track - + Cannot paste: wrong data type @@ -9856,202 +9891,202 @@ Likely the selected track is the wrong type. MusEGui::PianoRoll - + &Edit - + C&ut - + &Copy - + Copy events in range - + &Paste - + Paste (with dialog) - + Delete &Events - + &Select - + Select &All - + &Deselect All - + Invert &Selection - + &Inside Loop - + &Outside Loop - + &Previous Part - + &Next Part - + Fu&nctions - + Quantize - + Modify Note Length - + Modify Velocity - + Crescendo/Decrescendo - + Transpose - + Erase Events - + Move Notes - + Set Fixed Length - + Delete Overlaps - + Legato - + &Plugins - + Window &Config - + &Event Color - + &Blue - + &Pitch colors - + &Velocity colors - + Pianoroll tools - + Step Record - + Midi Input - + Play Events - + panic - + transport - + ctrl - + Add Controller View @@ -10059,102 +10094,102 @@ Likely the selected track is the wrong type. MusEGui::PluginDialog - + MusE: select plugin - + Lib - + Label - + Name - + AI - + AO - + CI - + CO - + IP - + id - + Maker - + Copyright - + Ok - + Cancel - + Mono and Stereo - + Stereo - + Mono - + Show All - + Select which types of plugins should be visible in the list.<br>Note that using mono plugins on stereo tracks is not a problem, two will be used in parallell.<br>Also beware that the 'all' alternative includes plugins that probably not are usable by MusE. - + Search in 'Label' and 'Name': @@ -10162,38 +10197,38 @@ Likely the selected track is the wrong type. MusEGui::PluginGui - + File Buttons - + Load Preset - + Save Preset - - + + bypass plugin - + MusE: load preset - + Error reading preset. Might not be right type for this plugin - + MusE: save preset @@ -10201,63 +10236,63 @@ Likely the selected track is the wrong type. MusEGui::RoutePopupMenu - - - - - - - - + + + + + + + + Channel - - - + + + Soloing chain - - + + Audio returns - + Warning: No input devices! - + Open midi config... - - + + <none> - + Toggle all - + More... - + Audio sends - + Midi port sends @@ -10265,42 +10300,42 @@ Likely the selected track is the wrong type. MusEGui::ScoreCanvas - + Treble - + Bass - + Grand Staff - + Remove staff - + Ambiguous part - + There are two or more possible parts you could add the note to, but none matches the selected part. Please select the destination part by clicking on any note belonging to it and try again, or add a new stave containing only the destination part. - + No part - + There are no parts you could add the note to. @@ -10308,261 +10343,261 @@ Likely the selected track is the wrong type. MusEGui::ScoreEdit - + Undo/Redo tools - + Step recording tools - + Step Record - + panic - + transport - + Note settings - + Note length: - + last - - - + + + Apply to new notes: - - + + Apply to selected notes: - + Velocity: - + Off-Velocity: - + Quantisation settings - + Quantisation: - + Pixels per whole: - + &Edit - + C&ut - + &Copy - + Copy events in range - + &Paste - + Paste (with dialog) - + Delete &Events - + &Select - + Select &All - + &Deselect All - + Invert &Selection - + &Inside Loop - + &Outside Loop - + Fu&nctions - + &Quantize - + Change note &length - + Change note &velocity - + Crescendo/Decrescendo - + Transpose - + Erase Events - + Move Notes - + Set Fixed Length - + Delete Overlaps - + Legato - + Window &Config - + Note head &colors - + &Black - + &Velocity - + &Part - + Set up &preamble - + Display &key signature - + Display &time signature - + Set Score &name - - + + Enter the new score title - + Error - + Changing score title failed: the selected title is not unique @@ -10617,6 +10652,14 @@ the selected title is not unique + + MusEGui::Strip + + + Remove track? + + + MusEGui::TList @@ -10751,24 +10794,24 @@ the selected title is not unique MusEGui::Toolbar1 + - Off - + Solo - + Cursor - + Snap @@ -10791,57 +10834,57 @@ the selected title is not unique - + Piano roll - + List editor - + Drum editor - + Master track editor - + Master track list editor - + Wave editor - + Clip list - + Marker view - + Score editor - + Arranger - + <unknown toplevel type> @@ -11048,50 +11091,50 @@ the selected title is not unique MusEGui::VisibleTracks - - - - Show wave tracks - - - Show group tracks + Show wave tracks - Show aux tracks + Show group tracks - Show input tracks + Show aux tracks - Show output tracks + Show input tracks - Show midi tracks + Show output tracks + Show midi tracks + + + + + Show synth tracks - + Visible track types @@ -11557,11 +11600,6 @@ to be expanded by more than QObject - - - Other - - @@ -11600,8 +11638,8 @@ to be expanded by more than - - + + None @@ -12221,7 +12259,7 @@ p, li { white-space: pre-wrap; } SynthConfigBase - MusE: Synth Configuration + Midi Port and Soft Synth Configuration @@ -12231,57 +12269,63 @@ p, li { white-space: pre-wrap; } - + Name + + Type + + + + Midi Port - + Remove Instance - + Midi connections - + Soft Synthesizer - + Add Instance - + list of available software synthesizers - + File - + Inst - + Version - + Description diff --git a/muse2/share/locale/muse_es.ts b/muse2/share/locale/muse_es.ts index 454934f9..7a380e3f 100644 --- a/muse2/share/locale/muse_es.ts +++ b/muse2/share/locale/muse_es.ts @@ -250,17 +250,17 @@ haz click en una parte para silenciar/des-silenciar Route - + Ruta dest - + dest name="%1"/ - + nombre="%1"/ Velocity @@ -274,12 +274,12 @@ haz click en una parte para silenciar/des-silenciar Open midi config... - Confugurar MIDI + Configurar MIDI... Empty ports - Puerto vacio + Puertos no asignados @@ -289,7 +289,7 @@ haz click en una parte para silenciar/des-silenciar channelMask="%1" - + channelMask="%1" @@ -302,7 +302,7 @@ haz click en una parte para silenciar/des-silenciar Version 2 pre-alpha - Versión 2.0 pre-alfa + MusE 2.0 pre-alfa @@ -311,17 +311,19 @@ See http://www.muse-sequencer.org for new versions and more information. Published under the GNU Public License - + (C) Derechos de autor 1999-2010 Werner Schweer y otros. +Ver http://www.muse-sequencer.org por nuevas versiones +y mas información. &Keep On Rocking! - + Volver a la sesión Alt+K - + Alt+K @@ -380,7 +382,7 @@ Published under the GNU Public License Parts - Partes + Regiones show frames @@ -404,7 +406,7 @@ Published under the GNU Public License y-stretch - + Periodo Y @@ -613,12 +615,12 @@ Published under the GNU Public License Color name: - + Nombre de color Global opacity - + Opacidad global @@ -633,12 +635,12 @@ Published under the GNU Public License Palette - + Paleta MusE: Appearance settings - + MusE: Configuración de apariencia @@ -653,47 +655,47 @@ Published under the GNU Public License add to palette - + Agregar a la paleta B - + Azul S - S + Saturación H - + Matíz V - + Brillo G - + Verde R - R + Rojo clear - + Limpiar Style Sheet: - + Hoja de estilo @@ -1242,7 +1244,7 @@ Published under the GNU Public License off - apagado + Apagar @@ -1284,7 +1286,7 @@ Published under the GNU Public License MusE: ClipList - MusE: Lista de Clips + MusE: Lista de archivos de audio @@ -1304,7 +1306,7 @@ Published under the GNU Public License Len - Longitud + Duración @@ -1324,7 +1326,7 @@ Published under the GNU Public License Len: - Longitud: + Duración: @@ -1360,17 +1362,17 @@ Published under the GNU Public License 0 (single track) - + 0 (una sola pista) 1 (multiple tracks) - + 1 (Pistas multiples) Format: - + Formato: @@ -1390,12 +1392,12 @@ Published under the GNU Public License Division: - + División: Copyright: - + Derecho de autor Enable extended smf format @@ -1404,62 +1406,62 @@ Published under the GNU Public License MusE: Config Midi File Import/Export - + MusE: Configuración de la importacion/exportación MIDI Import: - + Importado Split tracks into &parts - + Dividir en pistas y regiones Alt+P - + Alt+P Split tracks into parts, or one single part - + Dividir en pistas y regiones o una sola región. Export: - + Exportado: Enable extended smf format (currently not implemented) - + Habilitar formato extendido smf (no implementado) Use &2-byte time signatures instead of standard 4 - + Compás de 2 bytes Alt+2 - + Alt+2 Note: Format 0 uses the FIRST midi track's name/comment in the arranger - + Nota: Formato 0 utiliza el nombre de la primera pista midi como comentario en el arreglista Save space by replacing note-offs with &zero velocity note-ons - + Ahorro de espacio por la sustitución de "note-off" con cero y la velocidad de "note-on" Alt+Z - + Alt+Z @@ -1467,7 +1469,7 @@ Published under the GNU Public License MusE: Crescendo/Decrescendo - MusE: Crescendo/Decrescendo + MusE: Crescendo/Decrescendo @@ -1492,18 +1494,18 @@ Published under the GNU Public License Start velocity - Intensidad al inicio + Velocidad al inicio % - + % End velocity - Intencidad al final + Velocidad al final @@ -1570,7 +1572,7 @@ Published under the GNU Public License Save configuration - Guardar Configuración + Guardar configuración @@ -1584,7 +1586,7 @@ Published under the GNU Public License Critical Error - Error Critico + Error critico @@ -1602,23 +1604,23 @@ Published under the GNU Public License Parsing error for file %1 - + Error de análisis del archivo %1 Load category dialog - + Cargar diálogo de la categoría Load set dialog - + Cargar grupo de diálogos Save set dialog - + Guardar grupo de diálogos @@ -1644,17 +1646,17 @@ Published under the GNU Public License Load set - + Cargar grupo Save set - + Guardar grupo Delete set - + Borrar grupo @@ -1701,19 +1703,19 @@ Published under the GNU Public License No more category supported - + No se soportan mas categorías You can not add more categories - + No se pueden agregar mas categorias Do you really want to delete %1 ? - + ¿Seguro desea borrar %1 ? @@ -1739,7 +1741,7 @@ Published under the GNU Public License You must first select a category. - + Primero debe seleccionar una categoria @@ -1752,7 +1754,8 @@ Published under the GNU Public License %1 is supposed to be affected to the hbank number %2, but there is already one on this slot. Do you want to replace it or to add it in the next free slot ? - + %1 Se supone que es el número de banco superior afectado %2, pero ya hay uno en esta ranura. + ¿Quiere reemplazarlo o añadir una ranura libre después? @@ -1778,7 +1781,7 @@ Published under the GNU Public License There is no more free category slot. - + No hay mas lugar para categorías. @@ -1788,12 +1791,12 @@ Published under the GNU Public License No more subcategory supported - + No se soportan mas sub categorías You can not add more subcategories - + No se pueden agregar mas sub categorias @@ -1805,7 +1808,7 @@ Published under the GNU Public License You must first select a subcategory. - + Primero debe seleccionar una sub categoria @@ -1816,12 +1819,13 @@ Published under the GNU Public License %1 is supposed to be affected to the lbank number %2, but there is already one on this slot. Do you want to replace it or to add it in the next free slot ? - + %1 Se supone que es el número de banco inferior afectado %2, pero ya hay uno en esta ranura. + ¿Quiere reemplazarlo o añadir una ranura libre después? There is no more free subcategory slot. - + No hay mas lugar para sub categorías. @@ -1831,12 +1835,12 @@ Published under the GNU Public License No more preset supported - + No se soportan mas preseteos You can not add more presets - + No se pueden agregar mas preseteos @@ -1850,7 +1854,7 @@ Published under the GNU Public License You must first select a preset. - + Primero selecciones un preseteo. @@ -1861,12 +1865,13 @@ Published under the GNU Public License %1 is supposed to be affected to the prog number %2, but there is already one on this slot. Do you want to replace it or to add it in the next free slot ? - + %1 Se supone que es afectada el número del programa %2,pero ya hay uno en esta ranura. + ¿Quieres reemplazarlo o añadir una ranura libre después? There is no more free preset slot. - + No hay mas lugar para preseteos. @@ -1876,7 +1881,7 @@ Published under the GNU Public License Browse set dialog - + Buscar ajustes de diálogo @@ -1889,7 +1894,7 @@ Published under the GNU Public License DeicsOnze - + DeicsOnze @@ -1899,17 +1904,17 @@ Published under the GNU Public License Program numerous - + Numero de programa INITVOICE - + InitVoice LBank - + Banco inferior @@ -1920,18 +1925,18 @@ Published under the GNU Public License Bank numerous - + Numero de banco NONE - NINGUNO + Ninguno HBank - + Banco superior @@ -1941,7 +1946,7 @@ Published under the GNU Public License Prog - + Programa @@ -1951,7 +1956,7 @@ Published under the GNU Public License DeicsOnze v0.5.5 Copyright (c) 2004-2006 Nil Geisweiller. Published under GPL licence. - + DeicsOnze v0.5.5 Derechos Reservados(c) 2004-2006 Nil Geisweiller. Publicado bajo licencia GPL. @@ -1966,32 +1971,32 @@ Published under the GNU Public License PL3 - + PL3 PL2 - + PL2 PL1 - + PL1 PR1 - + PR1 PR2 - + PR2 PR3 - + PR3 @@ -2002,7 +2007,7 @@ Published under the GNU Public License Pitch modulation depth - + Profundidad de modulación de tono @@ -2012,78 +2017,78 @@ Published under the GNU Public License LFO Sync - + LFO Sync Pitch modulation sensitivity - + Pitch modulation sensitivity Pitch Modulation Sensitivity - + Pitch Modulation Sensitivity LFO Delay - + LFO Delay LFO delay - + LFO delay LFO speed - + LFO speed Amplitude modulation depth - + Amplitude modulation depth Amplitude modulation sensitivity - + Amplitude modulation sensitivity Amplitude Modulation Sensitivity - + Amplitude Modulation Sensitivity AMS - + AMS LFO Waveform - + LFO Waveform Pitch Modulation Depth - + Pitch Modulation Depth PMD - + PMD LFO Speed - + LFO Speed AMD - + AMD @@ -2098,13 +2103,13 @@ Published under the GNU Public License PMS - + PMS Modulation Matrix - + Modulation Matrix @@ -2116,18 +2121,25 @@ Published under the GNU Public License <b>Algorithm 6</b> : addition of the three <i>Op 1, 2, 3</i> all modulated by <i>Op 4</i><br> <b>Algorithm 7</b> : addition of the three <i>Op 1, 2, 3</i> with <i>Op 3</i> modulated by <i>Op 4</i><br> <b>Algorithm 8</b> : addition of the four <i>Op 1, 2, 3, 4</i> - + <b>Algorithm 1</b> : <i>Op 1</i> modulated by <i>Op 2</i> modulated by <i>Op 3</i> modulated by <i>Op 4</i><br> +<b>Algorithm 2</b> : <i>Op 1</i> modulated by <i>Op 2</i> modulated by both <i>Op 3</i> and <i>Op 4</i><br> +<b>Algorithm 3</b> : <i>Op 1</i> modulated by both <i>Op 4</i> and <i>Op 2</i> modulated by <i>Op 3</i><br> +<b>Algorithm 4</b> : <i>Op 1</i> modulated by both <i>Op 2</i> and <i>Op 3</i> modulated by <i>Op 4</i><br> +<b>Algorithm 5</b> : (<i>Op 1</i> modulated by <i>Op 2</i>) add to (<i>Op 3</i> modulated by <i>Op 4</i>) <br> +<b>Algorithm 6</b> : addition of the three <i>Op 1, 2, 3</i> all modulated by <i>Op 4</i><br> +<b>Algorithm 7</b> : addition of the three <i>Op 1, 2, 3</i> with <i>Op 3</i> modulated by <i>Op 4</i><br> +<b>Algorithm 8</b> : addition of the four <i>Op 1, 2, 3, 4</i> Op4 Feedback - + Op4 Feedback Feedback level of the operator 4 - + Feedback level of the operator 4 @@ -2139,22 +2151,22 @@ Published under the GNU Public License Op &1 - + Op &1 Scaling 1 - + Scaling 1 LS1 - + LS1 RS1 - + RS1 @@ -2166,7 +2178,7 @@ Published under the GNU Public License Rate Scaling - + Rate Scaling @@ -2182,7 +2194,7 @@ Published under the GNU Public License Attack Rate of the operator 1 - + Attack Rate of the operator 1 @@ -2194,32 +2206,32 @@ Published under the GNU Public License Level Scaling - + Level Scaling Amplitude Envelope 1 - + Amplitude Envelope 1 RR1 - + RR1 D1R1 - + D1R1 D1L1 - + D1L1 D2R1 - + D2R1 @@ -2227,7 +2239,7 @@ Published under the GNU Public License Release Rate - + Release Rate @@ -2235,7 +2247,7 @@ Published under the GNU Public License 2° Decay Rate - + 2° Decay Rate @@ -2243,7 +2255,7 @@ Published under the GNU Public License 1° Decay Level - + 1° Decay Level @@ -2251,7 +2263,7 @@ Published under the GNU Public License 1° Decay Rate - + 1° Decay Rate @@ -2259,22 +2271,22 @@ Published under the GNU Public License Attack Rate - + Attack Rate AR1 - + AR1 Detune, OSCWave, EGShift 1 - + Detune, OSCWave, EGShift 1 DET1 - + DET1 @@ -2287,7 +2299,7 @@ Published under the GNU Public License Detune - Desafinación + Detune @@ -2295,7 +2307,7 @@ Published under the GNU Public License EG Shift - + EG Shift @@ -2303,7 +2315,7 @@ Published under the GNU Public License 96dB - + 96dB @@ -2311,7 +2323,7 @@ Published under the GNU Public License 48dB - + 48dB @@ -2319,7 +2331,7 @@ Published under the GNU Public License 24dB - + 24dB @@ -2327,7 +2339,7 @@ Published under the GNU Public License 12dB - + 12dB @@ -2335,7 +2347,7 @@ Published under the GNU Public License Wave form - + Wave form @@ -2350,17 +2362,24 @@ Wave form 5 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Wave form 6 = <i>if <b>t</b>&#060 pi then sin(2*<b>t</b>)*abs(sin(2*<b>t</b>)) else 0</i><br> Wave form 7 = <i>if <b>t</b>&#060 pi then abs(sin(2*<b>t</b>)) else 0</i><br> Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t</b>)*sin(2*<b>t</b>) else 0</i> - + Wave form 1 = <i>sin(<b>t</b>)</i><br> +Wave form 2 = <i>sin(<b>t</b>)*abs(sin(<b>t</b>))</i><br> +Wave form 3 = <i>if <b>t</b>&#060 pi then sin(<b>t</b>) else 0</i><br> +Wave form 4 = <i>if <b>t</b>&#060 pi then sin(<b>t</b>)*abs(sin(<b>t</b>)) else 0</i><br> +Wave form 5 = <i>if <b>t</b>&#060 pi then sin(2*<b>t</b>) else 0</i><br> +Wave form 6 = <i>if <b>t</b>&#060 pi then sin(2*<b>t</b>)*abs(sin(2*<b>t</b>)) else 0</i><br> +Wave form 7 = <i>if <b>t</b>&#060 pi then abs(sin(2*<b>t</b>)) else 0</i><br> +Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t</b>)*sin(2*<b>t</b>) else 0</i> Sensitivity 1 - + Sensitivity 1 KVS1 - + KVS1 @@ -2368,12 +2387,12 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Amplitude Modulation Enable - + Amplitude Modulation Enable AME1 - + AME1 @@ -2381,7 +2400,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Keyboard Velocity Sensitivity - + Keyboard Velocity Sensitivity @@ -2389,12 +2408,12 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Key Velocity Sensitivity - + Key Velocity Sensitivity EBS1 - + EBS1 @@ -2402,7 +2421,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t EG Bias Sensitivity - + EG Bias Sensitivity @@ -2410,17 +2429,17 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Eg Bias Sensitivity - + Eg Bias Sensitivity Frequency 1 - + Frequency 1 Coarse 1 - + Coarse 1 @@ -2428,12 +2447,12 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Coarse Ratio - + Coarse Ratio Fine 1 - + Fine 1 @@ -2441,12 +2460,12 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Fine Ratio - + Fine Ratio Freq 1 - + Freq 1 @@ -2454,7 +2473,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Fixed Frequency - + Fixed Frequency @@ -2462,7 +2481,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Toggle Fix Frequency - + Toggle Fix Frequency @@ -2470,12 +2489,12 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t FIX - + FIX OUT 1 - + OUT 1 @@ -2483,7 +2502,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Output Volume - + Output Volume @@ -2493,381 +2512,381 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Volume - Volumen + Volume Op &2 - + Op &2 Amplitude Envelope 2 - + Amplitude Envelope 2 D1R2 - + D1R2 D1L2 - + D1L2 D2R2 - + D2R2 RR2 - + RR2 AR2 - + AR2 Frequency 2 - + Frequency 2 Coarse 2 - + Coarse 2 Fine 2 - + Fine 2 Freq 2 - + Freq 2 Scaling 2 - + Scaling 2 LS2 - + LS2 RS2 - + RS2 OUT 2 - + OUT 2 Detune, OSCWave, EGShift 2 - + Detune, OSCWave, EGShift 2 DET2 - + DET2 Sensitivity 2 - + Sensitivity 2 EBS2 - + EBS2 KVS2 - + KVS2 AME2 - + AME2 Op &3 - + Op &3 Amplitude Envelope 3 - + Amplitude Envelope 3 D1R3 - + D1R3 D1L3 - + D1L3 D2R3 - + D2R3 RR3 - + RR3 AR3 - + AR3 Scaling 3 - + Scaling 3 LS3 - + LS3 RS3 - + RS3 OUT 3 - + OUT 3 Frequency 3 - + Frequency 3 Coarse 3 - + Coarse 3 Fine 3 - + Fine 3 Freq 3 - + Freq 3 Detune, OSCWave, EGShift 3 - + Detune, OSCWave, EGShift 3 DET3 - + DET3 Sensitivity 3 - + Sensitivity 3 EBS3 - + EBS3 KVS3 - + KVS3 AME3 - + AME3 Op &4 - + Op &4 amplitude Envelope 4 - + amplitude Envelope 4 AR4 - + AR4 D1R4 - + D1R4 D1L4 - + D1L4 D2R4 - + D2R4 RR4 - + RR4 Frequency 4 - + Frequency 4 Coarse 4 - + Coarse 4 Fine 4 - + Fine 4 Freq 4 - + Freq 4 Scaling 4 - + Scaling 4 LS4 - + LS4 RS4 - + RS4 OUT 4 - + OUT 4 Detune, OSCWave, EGShift 4 - + Detune, OSCWave, EGShift 4 DET4 - + DET4 Sensitivity 4 - + Sensitivity 4 EBS4 - + EBS4 KVS4 - + KVS4 AME4 - + AME4 &Func - + &Func Delay Pan Depth - + Delay Pan Depth Delay Pan LFO Freq - + Delay Pan LFO Freq Delay Ch Send Level - + Delay Ch Send Level Channel Chorus - + Channel Chorus Delay Feedback - + Delay Feedback Delay On/Off, Return Level - + Delay On/Off, Return Level On - Encendido + On Delay Beat Ratio - + Delay Beat Ratio Delay BPM - + Delay BPM Foot Control - + Foot Control @@ -2900,7 +2919,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Pitch Bend Range - + Pitch Bend Range @@ -2908,7 +2927,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Pitch - Tono + Pitch @@ -2916,29 +2935,29 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Amplitude - + Amplitude Modulation Wheel - + Modulation Wheel Breath Control - + Breath Control Pitch Bias - + Pitch Bias Envelope Bias - + Envelope Bias @@ -2948,172 +2967,172 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Phony Mode - + Phony Mode POLY - + POLY MONO - + MONO Potamento - + Portamento Portamento Mode - + Portamento Mode FINGER - + FINGER FULL - + FULL PT - + PT Portamento Time - + Portamento Time C&horus - + C&horus Chorus Parameters - + Chorus Parameters Channel send level - + Channel send level On/Off and Return level - + On/Off and Return level Select LADSPA plugin - + Select LADSPA plugin Change plugin - + Cambiar efecto &Reverb - + &Reverb Reverb Parameters - + &Config - + &Configuración Font Size - + Tamaño de fuente Quality - + Calidad High - + Alta Middle - + Media Low - + Baja Ultra low - + Muy baja Filter - + Filtro Save Mode (into the song) - + Guardar modo (en la sesión) Save only the used presets - + Guardar solo el preseteo Save the entire set - + Guardar todas las configuraciones Save the configuration - + Guardar configuración Configuration File - + Archivo de configuración Save... - + Guardar... Load... - + Abrir... Save as default - + Guardar por defecto @@ -3128,94 +3147,94 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Background - + Fondo Edit Text - + Editar texro Edit Background - + Editar fondo Red - + Rojo Blue - + Azúl Green - + Verde Set Path - + Ajustes de la ruta Image in the background : - + Imagen de fondo: Browse... - + Buscar... Load the set at the initialization : - + Cargar al iniciar Set Brightness, Detune, Attack and Release of the current channel to default - + Ajustes de Brightness, Detune, Attack y Release del canal actual por defecto Res. Ctrl - + Reestablecer Cut all notes off - + Apaga todas las notas Panic! - + Pánico! Number of Voices - + Número de voces Number of voices - + Número de voces Enable - + Habilitado @@ -3225,17 +3244,17 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Vol - + Volumen Channel Ctrl - + Controlador de canal Release - Relajación + Release @@ -3245,17 +3264,17 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Brightness - + Brillo Modulation - + Modulación Pan - + Panorámica @@ -3283,12 +3302,12 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Looped Events - + Bucle de eventos Selected Looped - + Selecionar bucle @@ -3616,7 +3635,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t textLabel3 - + textLabel3 @@ -3641,7 +3660,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Program - + Programa @@ -3652,7 +3671,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t pushButton4 - + pushButton4 @@ -3691,17 +3710,17 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t 200% - 5 1/3' {200%?} + 200% 100% - 5 1/3' {100%?} + 100% 0% - 5 1/3' {0%?} + 0% @@ -3711,7 +3730,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Alt+R - + Alt+R @@ -3721,7 +3740,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Alt+A - + Alt+A @@ -3731,7 +3750,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Alt+C - + Alt+C @@ -3762,22 +3781,22 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t MusE: Instrument Editor - + MusE: Editro de Instrumento High Bank: - + Banco superior: Low Bank: - + Banco inferior: Program: - + Programa: @@ -3791,7 +3810,7 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t Alt+D - + Alt+D @@ -3822,7 +3841,9 @@ Wave form 8 = <i>if <b>t</b>&#060 pi then sin(2*<b>t This is a list of commonly used midi controllers. Note that in MusE pitch and program changes are handled like normal controllers. - + Lista de controladores MIDI de uso común +Tenga en cuenta que en Muse cambios de tono +y el programa se manejan como los controladores normales. @@ -3866,7 +3887,7 @@ handled like normal controllers. Program - + Programa @@ -3883,12 +3904,12 @@ handled like normal controllers. Min - + Minimo Max - + Máximo @@ -3907,12 +3928,12 @@ handled like normal controllers. Hex Entry: - + Hexadecimal: &File - + Archivo @@ -3922,7 +3943,7 @@ handled like normal controllers. New - + Nuevo @@ -3932,7 +3953,7 @@ handled like normal controllers. Ctrl+N - + Ctrl+N @@ -3947,7 +3968,7 @@ handled like normal controllers. Ctrl+O - + Ctrl+O @@ -3962,7 +3983,7 @@ handled like normal controllers. Ctrl+S - + Ctrl+S @@ -3987,32 +4008,32 @@ handled like normal controllers. Instrument Name: - + Nombre de instrumento: Selected instrument name. - + Seleccionar nombre de instrumento List of defined instruments. - + Lista de instrumentos definidos Pa&tches - + Grupos List of groups and patches. - + Lista de grupos Group/Patch - + Grupos @@ -4025,159 +4046,159 @@ handled like normal controllers. Group or patch name - + Nombre de grupo o sección Patch high bank number - + Número de grupo de banco superior Patch high bank number. --- means don't care. - + Número de grupo de banco superior. --- dont care - + no importa Patch low bank number - + Número de grupo de banco inferior Patch low bank number. --- means don't care. - + Número de grupo de banco inferior. --- - + Patch program number - + Número de parte de programa Drum patch - + Parte de percusiòn If set, the patch is available only for drum channels. - + Si se establece, el grupo estará disponible únicamente para los canales de percusión. GM patch - + Grupo GM If set, the patch is available in a 'GM' or 'NO' midi song type. - + Si se establece, estará disponible el grupo "GM" para la sesión. GS patch - + Grupo GS If set, the patch is available in a 'GS' or 'NO' midi song type. - + Si se establece, estará disponible el grupo "GS" para la sesión. XG patch - + Grupo XG If set, the patch is available in an 'XG' or 'NO' midi song type. - + Si se establece, estará disponible el grupo "XG" para la sesión. Delete group or patch - + Borrar grupo New patch - + Nueva grupo New &Patch - + Nueva gru&po Alt+P - + Alt+P New group - + Nuevo grupo New &Group - + Nuevo &Grupo Alt+G - + Alt+G Contro&ller - + Contro&lador Common: - + Comunes: List of defined controllers - + Lista de controladores definidos List of defined controllers. - + Lista de controladores definidos. Min - + Mínimo Max - + Máximo Def - + Def Midi controller name - + Nombre de controlador MIDI @@ -4188,28 +4209,28 @@ handled like normal controllers. Midi controller type - + Tipo de controlador MIDI RPN14 - + RPN14 NRPN14 - + NRPN14 Midi controller number high byte - + Controlar número alto del byte MIDI Midi controller number low byte (* means drum controller) - + Controlador MIDI byte bajo (* significa que controla la percusión) @@ -4222,23 +4243,26 @@ Allows controllers for each instrument in replaced by the 'ANote' in the drum map. Examples: The GS and XG instruments' Drum controllers. - + Controlador MIDI byte bajo. + Byte bajo es * el controlador + regulador de percusión,-para las pistas de batería e + instrumentos GS / XG. * wild card - + * Range: - + Rango: Minimum value. If negative, auto-translate. - + Valor mínimo. Si es negativo,se traduce automaticamente. @@ -4261,18 +4285,29 @@ Type 'Pitch' is the exception. It is biased at zero, even with a negative minimum: 'Pitch': Min: -8192 Max: 8191 True range: Min: -8192 Max: 8191 (bias 0) - + Valor mínimo. Si el valor mínimo + es negativo, el rango automáticamente + se traduce en un rango positivo. + +El valor es determinado por el tipo de controlador +7-bit Controller7 / RPN: Bias = 64 +14-bit Controller14 / RPN14: Bias = 8192 + +'Pitch' es la excepción. Está fijada + a cero, incluso con un mínimo negativo +'Pitch': Min: -8192 Max: 8191 +True range: Min: -8192 Max: 8191 (bias 0) Maximum value - + Valor máximo Default: - + Por defecto: @@ -4291,7 +4326,7 @@ True range: Min: -8192 Max: 8191 (bias 0) Progr. - Progr. + Programa @@ -4306,7 +4341,7 @@ True range: Min: -8192 Max: 8191 (bias 0) Default value. Off: No default. - + El valor por defecto. Apagado: No hay valor por defecto. @@ -4325,7 +4360,15 @@ Caution! Watch out for controllers such as values. You should probably turn 'off' their default (in piano roll or drum edit, and instrument editor). - + Valor por defecto (inicial) . Apagado, no tiene valor predeterminado. + +Si se elije un valor por defecto , el valor será enviado + cuando el controlador se añada en la sesión + (en el editor de matríz o editor de lista). cuando + si la sesión se vuelve a cargar, el valor se vuelve a enviar. +De lo contrario el controlador permanece en su último valor. +Los controladores también se añaden automáticamente a una + sesión a la recepción de un evento de controlador midi. @@ -4336,47 +4379,47 @@ Caution! Watch out for controllers such as Add common controller - + Agregar controlador común &Add - + &Agregar Alt+A - + Alt+A Delete controller - + Borrar controlador Create a new controller - + Crear un nuevo controlador New &Controller - + Nuevo Alt+C - + Alt+C Null Param Hi: - + Byte alto no válido: Null parameter number High byte - + El número de byte alto no es válido. @@ -4387,37 +4430,42 @@ This prevents subsequent 'data' events from corrupting the RPN/NRPN controller. Typically, set to 127/127, or an unused RPN/NRPN controller number. - + Si se establece, 'nulo' el número de parámetro + será enviados después de cada evento RPN / NRPN. +Esto evita que los acontecimientos posteriores de "datos" + corrompan el controlador RPN / NRPN. +Por lo general, establezca a 127/127, o usar el + número de controlador RPN / NRPN. Lo: - + Inferior: Null parameter number Low byte - + El parametro inferior es nulo S&ysEx - + S&ysEx SysEx List: - + Lista se Sistema exclusivo (SysEx) New SysE&x - + Nuevo SysE&x Alt+X - + Alt+X @@ -4428,13 +4476,13 @@ Typically, set to 127/127, or an unused new item - + Nuevo ítem What's this? - + ¿Que es esto? @@ -4507,7 +4555,7 @@ Typically, set to 127/127, or an unused Length: - Longitud: + Duración: @@ -4736,7 +4784,7 @@ Typically, set to 127/127, or an unused CHANNEL SETUP - + CONFIGURACIÓN DE CANAL @@ -4803,7 +4851,7 @@ Typically, set to 127/127, or an unused Project - Proyecto + Sesión @@ -4815,7 +4863,7 @@ Datos de sesión fdialogbuttons - + Dialogo de botones @@ -4873,7 +4921,7 @@ Configuración MusE: Modify Note Length - MusE: Modificar duración de nota + MusE: Cambiar duración de notas @@ -4903,7 +4951,7 @@ Configuración lenNew = (lenOld * rate) + offset - + lenNew = (lenOld * rate) + offset @@ -4921,7 +4969,7 @@ Configuración MusE: Global Settings - MusE: Valores globales + MusE: Configuración global globales @@ -4942,7 +4990,7 @@ Configuración min. Meter Value - valor mínimo del vumeter + Valor mínimo del vúmetro min.Slider Val @@ -4956,7 +5004,7 @@ Configuración Ticks - Ticks + Tics @@ -4986,7 +5034,7 @@ Configuración Displayed Resolution (Ticks/Quarternote) Resolución mostrada -(ticks/negra) +(tics/negra) @@ -5047,7 +5095,7 @@ Configuración RTC Resolution (Ticks/Sec) Resolución del reloj -(Ticks/segundo) +(Tics/segundo) @@ -5062,23 +5110,24 @@ Configuración GUI Refresh Rate - Velocidad de refresco del GUI + Velocidad de refresco de la interfáz Use project save dialog - + Usar diálogo de guardado Some popup menus stay open (else hold Ctrl) - + Menús emergentes (si no mantenga presionado Ctrl) Allows some popup menus to stay open. Otherwise, hold Ctrl to keep them open. - + Permite tener abiertos algunos menús emengentes. +De lo contrario, mantenga la tecla Ctrl para mantenerlos abiertos. @@ -5086,42 +5135,46 @@ Otherwise, hold Ctrl to keep them open. values, while the right button increases. Users without a middle mouse button can select this option to make the left button behave like the middle button in such areas. - + En algunas zonas, el botón central del ratón disminuye el +valor, mientras que el botón derecho lo aumenta. Los usuarios +sin un botón central del ratón, puede seleccionar esta opción +para hacer que el botón de la izquierda se comporte como +el botón del medio. Use left mouse button for decreasing values - + Botón izquierdo del ratón reduce el valor Shift + Right click sets left range marker - + Ctrl + clic derecho establece marcador de la izquierda. MDI-subwindowness and sharing menus - + MDI Sub ventanas y posición de menús Presets: - + Preseteos: traditional MusE SDI - + Comportamiento tradicional de MusE Cakewalk-like MDI - + Comportamiento similar a Cakewalk Borland-/Mac-like MDI - + Comportamiento similar a Borland/Mac @@ -5145,32 +5198,32 @@ left button behave like the middle button in such areas. Application - + Aplicación Start Muse - + Inicio de MusE start with last song - + Abrir la última sesión start with song - + Abrir la sesión start song: - + Iniciar sesión: Views - + Vistas @@ -5179,7 +5232,7 @@ left button behave like the middle button in such areas. y-pos - + pos. Y @@ -5187,7 +5240,7 @@ left button behave like the middle button in such areas. show - + Ver @@ -5196,7 +5249,7 @@ left button behave like the middle button in such areas. x-pos - + Pos. X @@ -5204,7 +5257,7 @@ left button behave like the middle button in such areas. height - + Ancho @@ -5212,12 +5265,12 @@ left button behave like the middle button in such areas. width - + Altura Big Time - + Ventana de tiempo Arranger @@ -5235,7 +5288,7 @@ left button behave like the middle button in such areas. Cur - + Actual @@ -5244,82 +5297,82 @@ left button behave like the middle button in such areas. set current values - + Establecer valores actuales start with template: default.med - + Abrir la plantilla: default.med show splash screen - + Mostrar pantalla de inicio Mixer A - + Mezcaldora A Mixer B - + Mezcladora B show "Did you know?" dialog - + Ver dialogo ¿Sabia usted que? Start song - + Iniciar Sesión min. Slider Val - + Valor mínimo del potensiómetro Enable denormal protection - + Habilitar proteccion Enable output limiter - + Habilitar limitación de salida External Waveditor - + Editor de audio externo External Waveditor command - + Editor de audio externo (comando) Note: External editor opened from the internal editor. - + Note: El editor externo se abre desde adentro Dummy Audio Driver (settings require restart) - + Controlador de audio en vacío (El cambio requiere reinicio) Hz - + Hz Period size (Frames per period): - + Tamaño del período (Cuadros por período) @@ -5330,33 +5383,34 @@ left button behave like the middle button in such areas. Main Window - + Ventana principal Try to use Jack Freewheel - + Habilitar Jack para juego libre Speeds bounce operations - + Velocidad de las operaciones de rebote Use Jack Freewheel mode if possible. This dramatically speeds bounce operations. - + Usar juego libre para Jack si es posible +Reduce dramaticamente el tiempo de rebote. VST in-place - + VST emplazado Enable VST in-place processing (restart required) - + Activar VST en el prosesamiento (Requiere reiniciar) @@ -5364,18 +5418,19 @@ This dramatically speeds bounce operations. VST Ladspa effect rack plugins do not work or feedback loudly, even if they are supposed to be in-place capable. Setting requires a restart. - + Activar VST en el procesamiento. Desactive esta opción si + Rack de efectos Ladspa VST no está instalado (Requiere reiniciar) Minimum control period - + Periodo mínimo de control Minimum audio controller process period (samples). - + Período mínimo del control de proceso de audio (muestras) @@ -5384,7 +5439,12 @@ Adjusts responsiveness of audio controls and controller graphs. Set a low value for fast, smooth control. If it causes performance problems, set a higher value. - + Período mínimo del control de proceso de audio (muestras) +Ajusta la sensibilidad de los controles de audio y + gráficos de control. Establecer un valor bajo para un control rápido + y suave. + Si le causa problemas de rendimiento, establezca un + valor mayor. @@ -5439,12 +5499,12 @@ Adjusts responsiveness of audio controls and Sample rate - + Frecuencia de muestreo Shorter periods give better midi playback resolution. - + Períodos más cortos dan una mejor resolución de la reproducción midi. @@ -5465,32 +5525,33 @@ Adjusts responsiveness of audio controls and Midi Resolution (Ticks/Quarternote) - + Resolución MIDI +(Tics/Negra) Instruments Directory - + Carpeta de instrumentos Use old-style stop shortcut: - + Atajo antiguo para detener Move single armed track with selection - + Armar la pista con la selección (Grabar) On Launch - + Lanzar al inicio Behavior - + Comportamiento @@ -5643,7 +5704,7 @@ Adjusts responsiveness of audio controls and MusE: Legato - + MusE: Legato @@ -5663,32 +5724,32 @@ Adjusts responsiveness of audio controls and Looped Events - + Eventos del bucle Selected Looped - + Bucle seleccionado Settings - + Configuración ticks - + Tics Minimum Length - + Duración minima: Allow shortening notes - + Permitir notas cortas @@ -5950,7 +6011,7 @@ Adjusts responsiveness of audio controls and Goto Left Mark - Ir ala marca izquierda + Ir a marca izquierda @@ -5960,7 +6021,7 @@ Adjusts responsiveness of audio controls and Insert rest (step rec) - + Insertar el resto @@ -6104,27 +6165,27 @@ Adjusts responsiveness of audio controls and Form - + Forma GroupBox - + Grupos MDI subwin - + MDI sub ventana Shares menu when subwin - + Acciones de menú cuando es sub ventana Shares menu when free - + Acciones de menú cuando es ventana libre @@ -6147,7 +6208,7 @@ Adjusts responsiveness of audio controls and MIDI Click - Click MIDI + Clic MIDI @@ -6207,17 +6268,17 @@ Adjusts responsiveness of audio controls and Signature - compás + Compás Prerecord - pre-captura + Pre-captura Preroll - pre-escucha + Pre-escucha @@ -6237,37 +6298,37 @@ Adjusts responsiveness of audio controls and Choose outputs... - + Seleccionar salidas... 50 - 5 1/3' {25%?} {50?} + 50 % Audio volume - + % De volúmen de audio Hint: Enable metronome in Transportpanel - + Habilitar metrónomo en el panel de transporte Alt+A - + Alt+A Alt+O - + Alt+O Alt+C - + Alt+C @@ -6476,7 +6537,7 @@ clase de controladores en la lista de MusE. Controller - Caontrolador + Controlador @@ -6494,7 +6555,7 @@ clase de controladores en la lista de MusE. Pitch Bend - Rueda de bend + Rueda de afinación @@ -7289,28 +7350,28 @@ clase de controladores en la lista de MusE. Sync receiving and sending - + Sincronizar la recepción y envío Send and receive Jack transport - + Recepción y envío del transporte de Jack Send and receive Jack transport information, including stop, start and position. - + Información de la recepción y envío del transporte de Jack, incluye detener, iniciar y posición. Use Jack transport - + Usar transporte de Jack Make MusE the Jack transport Timebase Master - + Hacer de MusE el transporte de base de tiempo principal para Jack @@ -7320,17 +7381,22 @@ Allows Jack to show time as MusE will try to become master, but other Jack clients can also take over later. You can always click here again for Master. - + Hacer de MusE el transporte de base de tiempo principal para Jack +Permite a Jack para mostrar el tiempo como + Compases de MusE , pulso, e inserciones. +MusE tratará de convertirse en maestro, pero otros + clientes de Jack también pueden hacerlo más adelante. +Siempre puede hacer clic aquí de nuevo para definir como maestro. Jack transport Timebase Master - + Usar Jack como transporte maestro Control MusE timing by external midi clock or MTC sync - + Control de tiempo de MusE por el reloj MIDI externo o sincronización MTC @@ -7339,17 +7405,21 @@ You can always click here again for Master. MusE can sync to midi clock, or MTC quarter frame sync. Enabled inputs in the list will be in effect (RMC, RMMC, RMTC). - + Cuando está en modo esclavo, el tempo es + controlado externamente. +Muse se sincroniza con el reloj midi, o sincronización MTC +Entradas habilitadas en la lista + que rigen (RMC, RMMC, CRFM). Slave to external sync - + Esclavo de sincronía externa Send start to first clock delay - + Retraso del envío de empezar el primer reloj. @@ -7357,17 +7427,19 @@ Enabled inputs in the list will to synchronize to MusE. This value is the delay from sending start to sending the first clock. - + Permite "sincronización lenta" para dispositivos + sincronizar con Muse. Este valor es el + retraso del envío de empezar el primer reloj. ms - + ms Send sync delay - + Enviar retraso de sincronización @@ -7408,7 +7480,7 @@ Enabled inputs in the list will iR - + ER @@ -7444,7 +7516,7 @@ Enabled inputs in the list will Transp. - Transp. + Transporte Volume @@ -7458,42 +7530,42 @@ Enabled inputs in the list will Rec: - + Grabar Prog - + Programa Vol - + Volumen Pan - Balance + Panorama Delay - Delay + Retardo H-Bank - Banco-H + Banco-superior Compr. - Compr. + Compresión L-Bank - Banco-L + Banco-inferior Progr. @@ -7502,12 +7574,12 @@ Enabled inputs in the list will Velocity - Velocidad + Velocidad Length - Longitud + Duración input ports @@ -7543,17 +7615,17 @@ Puedes especificar más de un canal para grabar: all midi events are sent to this output channel - + Todos los eventos MIDI se envían a este canal de salida Out ch - + Canal de salida input routing - + Ruteo de entrada Inputs @@ -7567,49 +7639,52 @@ Puedes especificar más de un canal para grabar: oR - + SR input detect - + Detectar entrada Input detect indicator. Detects all note on-off, controller, aftertouch, program change, and pitchbend (but not sysex or realtime) events on the selected channels, on the selected midi ports. - + Indicador de entrada. Detecta todas las notas de encendido y apagado, eventos , + de control, aftertouch, cambio de programa, y pitchbend en los + canales seleccionados, en los puertos MIDI seleccionados. + (No detecta envios SysEx o tiempo real) W - + W Midi thru - + MIDI thru Pass input events through ('thru') to output. - + Pasar los eventos de entrada a la salida (Thru). Select instrument patch - + Seleccione el instrumento <unknown> - + <desconocido> Add all settings to song - + Agregar todos los ajustes a la sesión @@ -7619,43 +7694,43 @@ Puedes especificar más de un canal para grabar: Bank Select MSB. Double-click on/off. - + Banco superior. Doble clic enciende/apaga Bank Select LSB. Double-click on/off. - + Banco inferior. Doble clic enciende/apaga Program. Double-click on/off. - + Programa. Doble clic enciende/apaga Add bank + prog settings to song - + Agregar ajustes de banco y programa a la sesión Volume. Double-click on/off. - + Volumen. Doble click Enciende/Apaga Add vol setting to song - + Agregar ajustes de volumen a la sesión Change stereo position. Double-click on/off. - + Cambiar la panorámica del estéreo. Doble clic enciende/apaga Add pan setting to song - + Agregar ajuste de panorámica a la sesión @@ -7843,7 +7918,7 @@ Puedes especificar más de un canal para grabar: Length - Longitud + Duración @@ -8121,7 +8196,7 @@ Puedes especificar más de un canal para grabar: MusE: Move Notes - + MusE: mover notas @@ -8141,12 +8216,12 @@ Puedes especificar más de un canal para grabar: Looped Events - + Eventos del bucle Selected Looped - + Bucle seleccionado @@ -8156,12 +8231,12 @@ Puedes especificar más de un canal para grabar: Move by - + Mover ticks - + Tics @@ -9384,13 +9459,26 @@ on the MusE mailinglist. To proceed check the status of Jack and try to restart it and then . click on the Restart button. - + Jack ha detectado un problema de rendimiento y MusE lo ha +desconectado +Esto podría suceder debido a varias razones: +- Un problema de rendimiento con su configuración particular. +- Un fallo en Muse u otro software de conexión. +--Un error al azar que tal vez nunca vuelva a ocurrir. +- Jack fue detenido por usted u otra persona +- Jack se estrelló +Si el problema persiste estaremos dispuesto a analizarlo +La lista de correos de MusE ee encuentra disponible a través +del menú de ayuda. + +Para comprobar el estado de Jack y reiniciar el servidor. +haga clic en el botón Reiniciar. Automation: - Automatizacion + Automatización @@ -9433,7 +9521,7 @@ click on the Restart button. Clear all controller events? - Limpiar todos los controladores + Limpiar todos los eventos de control @@ -9463,61 +9551,66 @@ click on the Restart button. Main application font, and default font for any controls not defined here. - + Fuente principal de la aplicación y la fuente por +defecto para los controles no estan definidas. For small controls like mixer strips. Also timescale small numbers, arranger part name overlay, and effects rack. - + Para los controles pequeños, como: bandas de mezclador. +escala de tiempo, superposición de nombre en la región, +y rack de efectos. Midi track info panel. Transport controls. - + Panel de información de la pista MIDI - Control del transporte Controller graph and S/X buttons. Large numbers for time and tempo scale, and time signature. - + Controlador de gráficos y botones S / X. Una gran cantidad +de eventos de tempo y el tempo de la escala y compás. Time scale markers. - + Marcas de la escala de tiempo List editor: meta event edit dialog multi-line edit box. - + Editor de la lista: Editar meta evento de diálogo multi-línea Mixer label font. Auto-font-sizing up to chosen font size. Word-breaking but only with spaces. - + Fuente de la etiqueta del mezclador. Auto dimensionado del tamaño de la fuente elegida. +La separación de palabras, pero sólo con espacios. Maximum mixer label auto-font-sizing font size. - + Tamaño máximo de la fuente para etiqueta del mezclador. Global opacity (opposite of transparency). - + Opacidad global Standard - Estandar + Estandar Custom - Personalozado + Personalizado @@ -9527,12 +9620,12 @@ Word-breaking but only with spaces. Select style sheet - + Seleccionar hoja de estilo Qt style sheets (*.qss) - + Hoja de estilo QT (*.qss) @@ -9585,12 +9678,12 @@ Word-breaking but only with spaces. Notation clef - + Clave de la notación Enable recording. Click to toggle. - + Habilitar captura: Clic en el botón. @@ -9598,33 +9691,41 @@ Word-breaking but only with spaces. Right-click to toggle track on/off. Mute is designed for rapid, repeated action. On/Off is not! - + Indicador de silenciado: click para silenciar +Clic con el boton derecho del ratón +para Apagar/Encender Solo indicator. Click to toggle. Connected tracks are also 'phantom' soloed, indicated by a dark square. - + Indicador de Solo, clic en el botón. +Pistas "fantasmas" en solo, + seran indicadas por un cuadrado negro. Track type. Right-click to change midi and drum track types. - + Tipo de pista: Clic derecho alterna entre tipo MIDI/Percusión Track name. Double-click to edit. Right-click for more options. - + Nombre de pista: Doble clic para editar +Click derecho para mas opciones. Midi/drum track: Output channel number. Audio track: Channels. Mid/right-click to change. - + Pista MIDI/Percusión: Numero de canal de salida +Pista de audio: Canales. +Clic con el botón del medio +o el derecho para cambiar. @@ -9632,7 +9733,10 @@ Mid/right-click to change. Synth track: Assigned midi port. Left-click to change. Right-click to show GUI. - + Pista de MIDI/Percusión: Puerto de salida. +Pista de sintetizador: Asigna el puerto MIDI +Clic de ratón para cambiar +Clic derecho para ver la interfaz @@ -9642,7 +9746,7 @@ Right-click to show GUI. Notation clef. Select this tracks notation clef. - + Clave de la notación. Seleccione esta clave de la notación de las pistas. @@ -9662,7 +9766,7 @@ Right-click to show GUI. Bar - Compaz + Compás @@ -9672,13 +9776,13 @@ Right-click to show GUI. Len - + Len song length - bars - Duracion de compaz + Duración de compás @@ -9795,7 +9899,7 @@ Right-click to show GUI. Clef - + Clave @@ -9803,7 +9907,7 @@ Right-click to show GUI. MusE: Arranger - MusE: Ordenar + Ordenar @@ -9833,7 +9937,7 @@ Right-click to show GUI. Copy in range - Copia en rango + Copiar interior del rango @@ -9858,7 +9962,7 @@ Right-click to show GUI. &Insert Empty Measure - + &Insertar compás vacío @@ -9868,22 +9972,22 @@ Right-click to show GUI. Shrink selected parts - + Encojer regiones seleccionadas Expand selected parts - + Expander regiones seleccionadas Clean selected parts - Limpiar partes seleccionadas + Limpiar regiones seleccionadas Add Track - Agregar Pista + Agregar pista @@ -9893,83 +9997,83 @@ Right-click to show GUI. Select &All - Seleccion&ar Todo + Seleccion&ar todo &Deselect All - &Deseleccionar Todo + &Deseleccionar todo Invert &Selection - Invertir &Selección + Invertir &selección &Inside Loop - &Interior de bucle + &Interior del bucle &Outside Loop - &Exterior de Bucle + &Exterior del bucle All &Parts on Track - Todas las &Partes de la pista + Todas las regiones de la &pista Score - Partitura + Editor de partitura all parts in one staff - + Todas las regiones en un solo pentagrama one staff per part - + Un pentagrama por región. New score window - + Nueva ventana de partitura Pianoroll - Pianola + Editor de matriz Drums - Percusión + Editor de percusión List - Lista + Editor de lista Wave - Audio + Editor de audio Mastertrack - Pista Maestra + Pista maestra. Graphic - Gráfico + Editor gráfico @@ -9984,12 +10088,12 @@ Right-click to show GUI. Global Insert - Inserción Global + Inserción global Global Split - Partición Global + División global @@ -10014,17 +10118,17 @@ Right-click to show GUI. Change note &length - Cambiar duracion de nota + Cambiar duración de notas Change note &velocity - Cambiar intensidad de nota + Cambiar velocidad de notas Crescendo/Decrescendo - + Crescendo/Decrescendo @@ -10034,17 +10138,17 @@ Right-click to show GUI. Erase Events (Not Parts) - Borrar eventos (no partes) + Borrar eventos (no regiones) Move Events (Not Parts) - Mover eventos (no partes) + Mover eventos (no regiones) Set Fixed Note Length - Fijar duracion de notas + Igualar duración de notas @@ -10054,12 +10158,12 @@ Right-click to show GUI. Legato - + Legato Window &Config - + Comportamiento de ventana @@ -10083,7 +10187,7 @@ Right-click to show GUI. Routing - + Ruteado @@ -10192,22 +10296,22 @@ Right-click to show GUI. iR - + ER input routing - + Ruteado de entrada oR - + SR output routing - ruteado de entrada + ruteado de salida @@ -10245,7 +10349,7 @@ Right-click to show GUI. bar - compaz + compaa @@ -10256,7 +10360,7 @@ Right-click to show GUI. tick - parte + Tic @@ -10290,7 +10394,7 @@ Right-click to show GUI. MusE: Clip List Editor - MusE: Editor de lista de clips + MusE: Editor de lista de archivos de audio @@ -10310,7 +10414,7 @@ Right-click to show GUI. Window &Config - + Comportamiento de ventana @@ -10333,17 +10437,17 @@ Right-click to show GUI. select controller - selecciona controlador + Seleccionar controlador X - + X remove panel - quitar panel + Quitar el panel @@ -10375,7 +10479,7 @@ Right-click to show GUI. Instrument-defined - Definicion de instrumento + Definición de instrumento @@ -10396,7 +10500,7 @@ Right-click to show GUI. Common Controls - + Controles comunes @@ -10417,7 +10521,7 @@ Right-click to show GUI. volume percent - + Porcentaje de volumen @@ -10435,67 +10539,67 @@ Right-click to show GUI. note length - longitud de nota + Duración de nota this is the note which is played - + Esta es la nota que se toca output channel (hold ctl to affect all rows) - + canal de salida (mantener presionado Ctrl a afectar a todas las pistas) output port (hold ctl to affect all rows) - + Puerto de salida (Mantener presionado CTRL a afecta todas las pistas) shift + control key: draw velocity level 1 - + Shift + CTRL: Dibuja la velocidad 1 control key: draw velocity level 2 - + CTRL: Dibuja la velocidad 2 shift key: draw velocity level 3 - + Shift: Dibuja la velocidad 3 draw velocity level 4 - + Dibuja la velocidad 4 output channel (ctl: affect all rows) - + Canal de salida. (CTRL afecta todas las pistas) output port (ctl: affect all rows) - + Puerto de salida (CTRL afecta todas las pistas) &File - + Archivo Load Map - Carga Mapa + Cargar Mapa @@ -10505,7 +10609,7 @@ Right-click to show GUI. Reset GM Map - + Resetear mapa GM @@ -10525,7 +10629,7 @@ Right-click to show GUI. Copy events in range - + Copiar eventos del rango @@ -10535,12 +10639,12 @@ Right-click to show GUI. Paste (with Dialog) - + Pegar (con dialogo) Delete Events - + Borrar eventos @@ -10550,12 +10654,12 @@ Right-click to show GUI. Select All - + Seleccionar todo Select None - + No seleccionar nada @@ -10565,47 +10669,47 @@ Right-click to show GUI. Inside Loop - + Interior del bucle Outside Loop - + Exterior del bucle Previous Part - + Región anterior Next Part - + Región siguiente Fu&nctions - + Funciones Re-order list - + Reordenar la lista Set Fixed Length - + Fijar duración Modify Velocity - + Modificar la velocidad. Crescendo/Decrescendo - + Crescendo/Decrescendo @@ -10615,32 +10719,32 @@ Right-click to show GUI. Erase Event - + Borrar evento Move Notes - + Mover notas Delete Overlaps - + Eliminar superpuestos &Plugins - + Efectos Window &Config - + Drum tools - + Herramientas de percusión @@ -10655,7 +10759,7 @@ Right-click to show GUI. Step Record - + Grabación por pasos @@ -10665,12 +10769,12 @@ Right-click to show GUI. cursor tools - + Herramientas de cursor Set step size for cursor edit - + Establecer el tamaño del paso para modificar el cursor @@ -10680,7 +10784,7 @@ Right-click to show GUI. transport - + Transporte @@ -10690,7 +10794,7 @@ Right-click to show GUI. Add Controller View - + Agregar vista de controlador @@ -10705,7 +10809,7 @@ Right-click to show GUI. Vol - + Volumen @@ -10720,7 +10824,7 @@ Right-click to show GUI. Len - + Duraciòn @@ -10730,7 +10834,7 @@ Right-click to show GUI. Ch - + Canal @@ -10770,12 +10874,12 @@ Right-click to show GUI. Drum map - + Mapa de percusiòn Reset the drum map with GM defaults? - + ¿Resetear en mapa de percusión con el banco GM? @@ -10783,7 +10887,7 @@ Right-click to show GUI. MusE: Enter Channel Aftertouch - MusE: Introduce el AfterTouch del canal + MusE: Introduzca el AfterTouch del canal @@ -10837,19 +10941,22 @@ Right-click to show GUI. %1 does not exist yet. Create it now? - + El instrumento no existe en la carpeta +%1 +¿Desea crearlo ahora? + (You can change the user instruments directory at Settings->Global Settings->Midi) - + (Usted puede cambiar la carpeta del instrumento desde Ajustes->Configuración global->MIDI) Unable to create user instrument directory '%1' - + No es posible crear el instrumento en la carpeta '%1' @@ -10889,7 +10996,8 @@ Are you sure? Please choose a unique instrument name. (The name might be used by a hidden instrument.) - + Selecciones un nombre único al instrumento +(El nombre puede estar siendo utilizado por un instrumento oculto.) @@ -10904,38 +11012,38 @@ Are you sure? MusE: Bad patchgroup name - + MusE: Nombre de grupo erroneo. Please choose a unique patchgroup name - + Seleccione un nombre único al grupo MusE: Bad controller name - + MusE: Nombre del controlador no válido. Please choose a unique controller name - + El nombre del controlador ya existe MusE: Cannot add common controller - + MusE: No se puede agregar un controlador comun. A controller named '%1' already exists. - + El nombre de controlador '%1' ya existe. A controller number %1 already exists. - + El número de controlador %1 ya existe. @@ -10948,7 +11056,8 @@ Are you sure? The current Instrument contains unsaved data Save Current Instrument? - + El instrumento actual contiene datos sin guardar. +¿Desea guardarlos ahora? @@ -10988,7 +11097,7 @@ Save Current Instrument? Enter Hex - + Ingrese Hex @@ -11023,11 +11132,11 @@ with the pointer tool you can: select parts move parts copy parts - selecciona la Herramienta de Puntero: -con la herramienta de puntero puedes: - seleccionar partes - mover partes - copiar partes + Selecciona la herramienta Puntero: +con la herramienta de puntero puede: + seleccionar regiones + mover regiones + copiar regiones. @@ -11035,31 +11144,31 @@ con la herramienta de puntero puedes: with the pencil tool you can: create new parts modify length of parts - selecciona la Herramienta de Lápiz: -con la herramienta de lápiz puedes: - crear nuevas partes - modificar la longitud de las partes + Selecciona la Herramienta de Lápiz: +con la herramienta de Lápiz puede: + crear nuevas regiones + modificar la duración de las regiones. select Delete Tool: with the delete tool you can delete parts - selecciona la Herramienta de Borrado: -con la herramienta de borrado puedes borrar partes + selecciona la Herramienta de Borrar: +con la herramienta de Borrar puedes borrar regiones. select Cut Tool: with the cut tool you can split a part selecciona la Herramienta de Corte: -con la herramienta de core puedes partir una parte +con la herramienta de Corte puede dividir una región select Glue Tool: with the glue tool you can glue two parts - selecciona la Herramienta de Pegado: -con la herramienta de pegado puedes unir dos partes + selecciona la Herramienta de Unir: +con la herramienta de Unir puedes unir dos regiones. @@ -11085,17 +11194,17 @@ inserta un evento de cuantización de visualización select Muting Tool: click on part to mute/unmute selecciona la Herramienta de Silenciar: -haz click en una parte para silenciar/des-silenciar +haz click en una región para silenciar/des-silenciar Manipulate automation - + Manipular automatización Cursor tool - + Herramientas de cursor @@ -11110,7 +11219,7 @@ haz click en una parte para silenciar/des-silenciar eraser - + Borrador @@ -11125,7 +11234,7 @@ haz click en una parte para silenciar/des-silenciar glue - + Pegador @@ -11140,17 +11249,17 @@ haz click en una parte para silenciar/des-silenciar mute parts - silenciar partes + silenciar regiones edit automation - + Editar automatización cursor - + Cursor @@ -11203,7 +11312,7 @@ haz click en una parte para silenciar/des-silenciar show native gui - + Ver interfaz nativa @@ -11223,7 +11332,7 @@ haz click en una parte para silenciar/des-silenciar Do you really want to replace the effect %1? - + ¿Desea reemplazar el efecto %1? @@ -11231,7 +11340,7 @@ haz click en una parte para silenciar/des-silenciar Selects instruments directory - + Seleccionar carpeta de instrumentos @@ -11239,7 +11348,7 @@ haz click en una parte para silenciar/des-silenciar Track Info Columns - + Colunna de informaciòn de pistas @@ -11247,7 +11356,7 @@ haz click en una parte para silenciar/des-silenciar MusE: Mastertrack - + MusE: pista maestra @@ -11257,52 +11366,52 @@ haz click en una parte para silenciar/des-silenciar Insert Tempo - + Insertar tiempo Insert Signature - + Insertar signatura Insert Key - + Insertar clave Edit Positon - + Editar posición Edit Value - + Editar valor Delete Event - + Borrar evento Window &Config - + &Configuraciòn de la ventana Undo/Redo tools - + Herramientas de Deshacer/rehacer Edit tools - + Editar herramientas Tempo - Tempo + Timpo @@ -11312,7 +11421,7 @@ haz click en una parte para silenciar/des-silenciar Key - + Clave @@ -11327,17 +11436,17 @@ haz click en una parte para silenciar/des-silenciar new key - + Nueva clave panic - pánico + Pánico transport - + Transporte @@ -11362,22 +11471,22 @@ haz click en una parte para silenciar/des-silenciar Reposition of the initial tempo and signature events is not allowed - + Reposición del tempo inicial y la firma de eventos, no está permitido MusE: List Editor - + MusE: Editor de lista Input error, conversion not OK or value out of range - + Error de entrada,la conversión no escorrecta o valor está fuera de rango. Reposition of tempo and signature events to start position is not allowed! - + Reposición de los eventos de tempo y la firma a la posición inicial no está permitida! @@ -11435,22 +11544,22 @@ haz click en una parte para silenciar/des-silenciar Delete Events - + Borrar eventos Window &Config - + &Configuraciòn de la ventana Undo/Redo tools - + Herramientas de Deshacer/Rehacer Insert tools - + Insertar herramientas @@ -11460,17 +11569,17 @@ haz click en una parte para silenciar/des-silenciar transport - + Transporte Tick - Tick + Tic Bar - + Compàz @@ -11480,7 +11589,7 @@ haz click en una parte para silenciar/des-silenciar Ch - + @@ -11500,7 +11609,7 @@ haz click en una parte para silenciar/des-silenciar Len - + @@ -11514,75 +11623,76 @@ haz click en una parte para silenciar/des-silenciar Default input connections - + Conexión de entrada predeterminada Are you sure you want to apply to all existing midi tracks now? - + ¿Seguro que desea aplicar a todas las pistas MIDI existentes? Default output connections - + Conexión de salida predeterminada Setting will apply to new midi tracks. Do you want to apply to all existing midi tracks now? - + El sjuste se aplicará a las nuevas pistas MIDI. +¿Usted desea aplicar a todas las pistas MIDI existentes? MusE: bad device name - + MusE: Nombre del dispositivo incorrecto please choose a unique device name - + El nombre del dispositivo ya existe in - + Entrada out - + Salida Show first aliases - + Mostrar primero los álias Show second aliases - + Mostrsr después los álias Toggle all - + Cambiar todos Change all tracks now - + Cambiar todas las pistas ahora Create Jack device - + Crear conexión Jack @@ -11593,77 +11703,77 @@ Do you want to apply to all existing midi tracks now? Enable gui - + Habilitar visualización Enable reading - + Habilitar lectura Enable writing - + Habilitar escritura Port instrument - + Puerto de instrumento Midi device name. Click to edit (Jack) - + Nombre del dispositivo MIDI, Clic para editar (Jack) Connections from Jack Midi outputs - + Conexiones de salidas MIDI de Jack Connections to Jack Midi inputs - + Conexiones de entrada MIDI de Jack Auto-connect these channels to new midi tracks - + Conectar automaticamente a estos canales las nuevas pistas midi Auto-connect new midi tracks to these channels - + Conectar nuevas pistas MIDI a estos canales Auto-connect new midi tracks to this channel - + Autoconectar las nuevas pistas MIDI a este canal Device state - + Estado del dispositivo Enable gui for device - + Habilitar visualización para el dispositivo Enable reading from device - + Habilitar la lectura desde el dispositivo Enable writing to device - + Habilitar la escritura en el dispositivo Name of the midi device associated with this port number. Click to edit Jack midi name. - + Nombre del dispositivo MIDI asociado con este puerto. Haga clic para cambiar el nombre del dispositivo MIDI de Jack. @@ -11673,27 +11783,27 @@ Do you want to apply to all existing midi tracks now? Connections from Jack Midi output ports - + Conexiones de los puertos de salida MIDI de Jack Connections to Jack Midi input ports - + Conexiones de los puertos de entrada MIDI de Jack Auto-connect these channels, on this port, to new midi tracks. - + Conexión automática de estos canales, en este puerto, a las nuevas pistas MIDI. Connect new midi tracks to these channels, on this port. - + Conecte las nuevas pistas MIDI a estos canales, en este puerto. Connect new midi tracks to this channel, on this port. - + Conecte las nuevas pistas MIDI a este canal, en este puerto. @@ -11713,12 +11823,12 @@ Do you want to apply to all existing midi tracks now? I - + O - + @@ -11733,22 +11843,22 @@ Do you want to apply to all existing midi tracks now? In routes - + Rutas de entrada Out routes - + Rutas de salida Def in ch - + Definir canales de entrada Def out ch - + Definir canales de salida @@ -11758,13 +11868,13 @@ Do you want to apply to all existing midi tracks now? <unknown> - + <desconocido> <none> - + <ningúno> @@ -11808,12 +11918,12 @@ Do you want to apply to all existing midi tracks now? Window &Config - + &Comportamiento de ventana Undo/Redo tools - + Herramientas de Deshacer/Rehacer @@ -11828,12 +11938,12 @@ Do you want to apply to all existing midi tracks now? transport - + Transporte Bar:Beat:Tick - Barra:Golpe:Tick + Compás:Golpe:Tic @@ -11861,17 +11971,17 @@ Do you want to apply to all existing midi tracks now? MusE: Mastertrack - + MusE: Pista maestra Window &Config - + &Configuraciones de la ventana Undo/Redo tools - + Herramientas de Deshacer/Rehacer @@ -11881,22 +11991,22 @@ Do you want to apply to all existing midi tracks now? transport - + Transporte Enable master - + Habilitar maestro Enable - + Habilitado Enable usage of master track - + Habilitar el uso de la pista maestra @@ -11921,12 +12031,12 @@ Do you want to apply to all existing midi tracks now? Off - + Apagado Bar - + Compás @@ -11955,7 +12065,7 @@ Do you want to apply to all existing midi tracks now? New - + Nuevo @@ -11971,12 +12081,12 @@ Do you want to apply to all existing midi tracks now? double click on/off - + Docle click Enciende/Apaga VariationSend - + Variación del envío @@ -11986,7 +12096,7 @@ Do you want to apply to all existing midi tracks now? ReverbSend - + Envio de reverberancia @@ -11996,7 +12106,7 @@ Do you want to apply to all existing midi tracks now? ChorusSend - + Envio de corolizador @@ -12011,12 +12121,12 @@ Do you want to apply to all existing midi tracks now? Pan/Balance - + Panorama/Balance Pan - + Panorama @@ -12031,22 +12141,22 @@ Do you want to apply to all existing midi tracks now? solo mode - + modo solo iR - + ER input routing - + Ruteado de entrada oR - + SR @@ -12071,125 +12181,133 @@ Do you want to apply to all existing midi tracks now? Midi clock input detected - + Midi clock input detectado Midi tick input detected - + Midi tick input detectado Midi real time input detected - + Midi real time input detectado MMC input detected - + MMC input detectado MTC input detected - + MTC input detectado Detected SMPTE format - + Formato SMPTE detectado Receive id number. 127 = Global. Double click to edit. - + Recibido id number, 127 = global, Doble clic para editar Accept midi clock input - + MIDI clock input aceptado Accept midi real time input - + MIDI real time input aceptado Accept MMC input - + MMC input aceptado Accept MTC input - + MTC input aceptado Receive start rewinds before playing - + Iniciando rebobinado antes de reproducir Transmit id number. 127 = Global. Double click to edit. - + Transmitiendo id number 127 = global, Doble clic para editar Send midi clock output - + Enviar MIDI clock output Send midi realtime output - + Enviar MIDI realtime output Send MMC output - + Enviar MMC output Send MTC output - + Enviar MTC output Midi clock input detected. Current port actually used is red. Click to force a port to be used. - + Entrada de MIDI clock input detectado. +El puerto utilizado es de color rojo. +Haga clic para obligar a un puerto a utilizarlo. Midi realtime input detected, including start/stop/continue, and song position. - + MIDI realtime input detectado, incluye + Reproducir, Detener, Continuar y Posición +en la canción. MMC input detected, including stop/play/deferred play, and locate. - + MMC input detectado, incluye + Reproducir, Detener, Continuar y Posición +en la canción. MTC input detected, including forward quarter-frame sync and full-frame locate. Current port actually used is red. Click to force a port to be current. - + De entrada MTC detectadas, así como avanzar de cuartos de la sincronía y localizar fotograma completo. +El puerto actual utilizado es de color rojo. Haga clic para obligar a un puerto a actualizar. Detected SMPTE format: 24fps, 25fps, 30fps drop frame, or 30fps non-drop Detects format of MTC quarter and full frame, and MMC locate. - + Formato SMPTE detectado: 24fps, 25fps, 30fps drop frame, or 30fps non-drop +Detecta el formato de cuarto de MTC y de fotograma completo, y localiza MMC. Receive id number. 127 = global receive all, even if not global. - + Recibe número de identificación. 127 = Globales reciben de todo, incluso si no es global. @@ -12199,7 +12317,12 @@ Auto-acquire: If two or more port realtime inputs are enabled, then another can take over. Best if each turns off its clock at stop, so MusE can re-acquire the clock from another port. Click on detect indicator to force another. - + Aceptar la entrada del reloj MIDI. Sólo una entrada se utiliza para el reloj. +Auto-adquisición: Si dos o más entradas en tiempo real del puerto están habilitadas, + el reloj detecta por primera vez se utiliza, hasta que el reloj se ha perdido, + luego otro se haga cargo. Mejor si cada uno se apaga el reloj + en la parada, por lo que Muse puede volver a adquirir el reloj de otro puerto. +Haga clic en la detección de indicadores de forzar a otro. @@ -12210,36 +12333,47 @@ Non-clock events (start,stop etc) are This means you may have several master devices connected, and muse will accept input from them. - + Acepta la entrada de MIDI en tiempo real, incluyendo + iniciar / detener / continuar, y posición de la canción. +los eventos (start, stop, etc) son + aceptado por todos los puertos habilitados. +Esto significa que usted puede tener varios maestros + con los dispositivos conectados, y MusE aceptará la voluntad de + éstos. Accept MMC input, including stop/play/deferred play, and locate. - + Aceptar la entrada de MMC, incluida la parada / reproducción / reproducción diferida, y localización. Accept MTC input, including forward quarter-frame sync and full-frame locate. See 'rc' column for more help. - + Aceptar la entrada del MTC, incluso delante de cuartos de la sincronía y localizar de fotograma completo. +Ver columna "rc" para obtener más ayuda. When start is received, rewind before playing. Note: It may be impossible to rewind fast enough to synchronize with the external device. - + Aceptar la entrada de MIDI en tiempo real, incluyendo + recibir al inicio, rebobinar antes de reproducir. +Nota: Puede ser imposible para un rebobinado rápido + lo suficiente como para sincronizar con el dispositivo externo. Transmit id number. 127 = global transmit to all. - + Transmitir id number. 127 = global transmitir a todos. Send midi clock output. If 'Slave to External Sync' is chosen, muse can re-transmit clock to any other chosen ports. - + Enviar la salida de reloj MIDI. al 'Esclavo de sincronización externa " que elija, + MusE puede volver a transmitir el reloj a cualquier otro puerto elegido. @@ -12249,7 +12383,12 @@ Note: It may be impossible to rewind fast other chosen ports. This means you may have several slave devices connected, and muse can re-send realtime messages to any or all of them. - + Enviar salida MIDI en tiempo real, incluyendo el arranque / parada / continuación, + y de posición de canción. al 'Esclavo de sincronización externa "que se elija, + MusE puede volver a transmitir mensajes MIDI de entrada en tiempo real a cualquier + otros puertos elegidos. Esto significa que usted puede tener varios esclavos + los dispositivos conectados, y MusE puede volver a enviar mensajes en tiempo real + a cualquiera o todos ellos. @@ -12264,17 +12403,17 @@ Note: It may be impossible to rewind fast c - + c k - + k r - + r @@ -12284,67 +12423,67 @@ Note: It may be impossible to rewind fast t - + t type - + Tipo rid - + rid rc - + rc rr - + rr rm - + rm rt - + rt rw - + rw tid - + tid tc - + tc tr - + tr tm - + tm tt - + tt @@ -12355,7 +12494,8 @@ Note: It may be impossible to rewind fast Settings have changed Apply sync settings? - + La configuración ha cambiado +¿Desea aplicar la nueva configuración de sincronización? @@ -12365,7 +12505,7 @@ Apply sync settings? &No - + Ca&ncelar @@ -12375,7 +12515,7 @@ Apply sync settings? <none> - + <ninguno> @@ -12384,7 +12524,7 @@ Apply sync settings? <unknown> - + <desconocido> @@ -12393,7 +12533,7 @@ Apply sync settings? New - + Nuevo @@ -12410,24 +12550,25 @@ Apply sync settings? Failed to start audio! - Falla al iniciar el audio + Fallo al iniciar el audio Was not able to start audio, check if jack is running. - + No se puede iniciar el audio, verifique el estado de Jack Timeout waiting for audio to run. Check if jack is running. - + Sa agotó el tiempo de espera. +Comprobar si Jack está en ejecución Und&o - &Deshacer + Deshacer @@ -12548,7 +12689,7 @@ Apply sync settings? &New - &Nuevo + &Nueva sesión @@ -12559,7 +12700,7 @@ Apply sync settings? &Open - &Abrir + &Abrir sesión @@ -12605,7 +12746,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Import Part - Importar parte + Importar región. @@ -12626,7 +12767,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Song Info - Información de la sesión + Comentarios de la sesión @@ -12636,7 +12777,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Bigtime Window - Ventana del Gran reloj + Ventana de reloj @@ -12651,17 +12792,17 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Cliplist - Lista de Clips + Lista de archivos de audio Marker View - Ver marcas + Editor de marcadores Arranger View - ORdenar vistas + Ordenar vistas @@ -12671,7 +12812,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. &Plugins - + Efectos @@ -12681,7 +12822,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Input Plugins - Plugins e entrada + Efectos de entrada @@ -12711,12 +12852,12 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Reset Instr. - Reinicializa Instrumento + Resetear instrumento Init Instr. - Inicializa Instruemnto + Inicializar instruemnto @@ -12746,7 +12887,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Take Snapshot - + Obtener instantanea @@ -12761,47 +12902,47 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Tile - + Titulo In rows - + Filas In columns - + Columnas Global Settings - Selecciones Globales + Configuración global Configure Shortcuts - Configurar accesos directos + Configurar atajos Follow Song - seguir canción + Seguir canción Don't Follow Song - no sigas la canción + No seguir canción Follow Page - sigue la página + Seguir la página Follow Continuous - sigue contínuamente + Seguir contínuamente @@ -12821,7 +12962,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. Appearance Settings - Selecciones de apariencia + Opciones de apariencia @@ -12841,7 +12982,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. &Report Bug... - &Reportar una falla + &Reportar un fallo @@ -12851,7 +12992,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. File Buttons - + Columna de botones @@ -12866,7 +13007,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. &File - Archivo + Sesión @@ -12896,7 +13037,7 @@ Puedes seleccionar también el comando Guardar del men de Archivo. MusE Se&ttings - Configuraciones de MusE + Configuraciones @@ -12987,51 +13128,53 @@ Guardar la sesión actual? No wave tracks found - + No existe el archivo de audio No audio output tracks found - + No hay salidas de audio Select one audio output track, and one target wave track - + Seleccione una salida de salida de audio, +y una pista de audio. Select one target wave track - + Seleccione una pista de audio de destino Select one target wave track, and one audio output track - + Selecciones una pista de audio, +y una salida de audio. MusE: Bounce to File - + Rebotar a archivo Select one audio output track - + Seleccionar salida de audio MusE: Bounce - + MusE: Rebotar set left/right marker for bounce range - + Fije marcadores derecho e izquierdo para el rango de rebote. @@ -13066,13 +13209,14 @@ Guardar el proyecto actual? Unable to launch help - + No es posible enlazar la ayuda. For some reason MusE has to launch the default browser on your machine. - + Por alguna razón, MusE tiene que lanzar +el navegador por defecto @@ -13083,17 +13227,17 @@ browser on your machine. Add midi file to current project? - + ¿Agregar archivo MIDI a la sesión? &Add to Project - + Agregar a la sesión &Replace - + &Reemplazar @@ -13112,23 +13256,25 @@ falló: Import part is only valid for midi and wave tracks! - + Importar regiones es solo para pistas MIDI o de audio MusE: load part - + MusE: Cargar región. No track selected for import - + No hay pistas seleccionadas para la importaciòn %n part(s) out of %1 could not be imported. Likely the selected track is the wrong type. - + + %n Región(es) fuera de %1 no puede ser importada. +Probablemente la pista seleccionada es del tipo incorrecto. @@ -13136,36 +13282,40 @@ Likely the selected track is the wrong type. %n part(s) could not be imported. Likely the selected track is the wrong type. - + + %n Región(es) no puede ser importada. +Probablemente la pista seleccionada es del tipo incorrecto. to import an audio file you have first to selecta wave track - + Para importar un archivo de audio seleccione la pista de audio Import Wavefile - + Importar archivo de audio This wave file has a samplerate of %1, as opposed to current setting %2. Do you still want to import it? - + Este archivo tiene una frecuencia de muestreo de %1, +El valor actual de la sesión es %2. +¿Desea importarlo de todos modos? &Yes - + Aceptar &No - + Ca&ncelar @@ -13178,12 +13328,12 @@ Do you still want to import it? Start - + Iniciar Len - + Duración @@ -13206,7 +13356,7 @@ Do you still want to import it? Cannot copy/move/clone to different Track-Type - No puedo copiar/mover/clonar a un tipo diferente de pista + No se puede copiar/mover/clonar a un tipo diferente de pista @@ -13221,12 +13371,12 @@ Do you still want to import it? s&elect - + S&eleccionar clones - + Clonar @@ -13251,7 +13401,7 @@ Do you still want to import it? glue - + Unir @@ -13263,7 +13413,7 @@ Do you still want to import it? save part to disk - + Guardar región en el disco. @@ -13273,24 +13423,27 @@ Do you still want to import it? file info - + Información de archivo MusE: save part - + MusE: Guardar región. Part name: %1 Files: - + Nombre de región: %1 +Archivos: %n part(s) out of %1 could not be pasted. Likely the selected track is the wrong type. - + + %n Región(es) fuera de %1 no pueden ser pegadas. +Probablemente la pista seleccionada es del tipo incorrecto. @@ -13298,7 +13451,9 @@ Likely the selected track is the wrong type. %n part(s) could not be pasted. Likely the selected track is the wrong type. - + + %n Región(es) no puede ser pegada. +Probablemente la pista seleccionada es del tipo incorrecto. @@ -13315,22 +13470,22 @@ Likely the selected track is the wrong type. Can only paste to midi/drum track - + Solo se puede insertar pistas MIDI/Percusión Can only paste to wave track - + Solo se pueden insertar pistas de audio Can only paste to midi or wave track - + Solo se pueden insertar pistas de MIDI o audio Cannot paste: wrong data type - No puedo pegar: Tipo de datos equivocado + No válido: Tipo de datos equivocado @@ -13338,7 +13493,8 @@ Likely the selected track is the wrong type. %n quarter(s) - + + %n Negra(s) @@ -13346,13 +13502,13 @@ Likely the selected track is the wrong type. %1 quarter for floating-point arguments like 1.5 - + %1 Negra %1 quarters for floating-point arguments like 1.5 - + %1 Negras @@ -13360,7 +13516,8 @@ Likely the selected track is the wrong type. %n quarter(s) - + + %n Negra(s) @@ -13368,13 +13525,13 @@ Likely the selected track is the wrong type. %1 quarter for floating-point arguments like 1.5 - + %1 Negra %1 quarters for floating-point arguments like 1.5 - + %1 Negras @@ -13397,7 +13554,7 @@ Likely the selected track is the wrong type. Copy events in range - + Copiar eventos del rango @@ -13422,42 +13579,42 @@ Likely the selected track is the wrong type. Select &All - Seleccion&ar Todo + Seleccion&ar todo &Deselect All - &Deseleccionar Todo + &Deseleccionar todo Invert &Selection - Invertir &Selección + Invertir &selección &Inside Loop - &Interior de bucle + &Interior del bucle &Outside Loop - &Exterior de Bucle + &Exterior del bucle &Previous Part - + Región previa &Next Part - + Siguiente región Fu&nctions - + Fu&nciones @@ -13467,17 +13624,17 @@ Likely the selected track is the wrong type. Modify Note Length - + Modificar duraciòn de la nota Modify Velocity - + Modificar la velocidad. Crescendo/Decrescendo - + Crescendo/Decrescendo @@ -13487,7 +13644,7 @@ Likely the selected track is the wrong type. Erase Events - + Borrar eventos @@ -13497,7 +13654,7 @@ Likely the selected track is the wrong type. Set Fixed Length - + Fijar ajustes de duración @@ -13507,17 +13664,17 @@ Likely the selected track is the wrong type. Legato - + Legato &Plugins - + Efectos Window &Config - + &Configuraciòn de ventanas @@ -13532,22 +13689,22 @@ Likely the selected track is the wrong type. &Pitch colors - + Color por afinación &Velocity colors - + Color por velocidad Pianoroll tools - + Herramientas del editor de matríz Step Record - + Grabación por pasos @@ -13567,7 +13724,7 @@ Likely the selected track is the wrong type. transport - + Transportar @@ -13577,7 +13734,7 @@ Likely the selected track is the wrong type. Add Controller View - + Agregar visor de controladores @@ -13655,7 +13812,7 @@ Likely the selected track is the wrong type. Mono and Stereo - + Mono y estereo @@ -13670,17 +13827,17 @@ Likely the selected track is the wrong type. Show All - + Ver todo Select which types of plugins should be visible in the list.<br>Note that using mono plugins on stereo tracks is not a problem, two will be used in parallell.<br>Also beware that the 'all' alternative includes plugins that probably not are usable by MusE. - + Los tipos de efectos seleccionados deben ser visibles en la lista. Tenga en cuenta que el uso de Efectos <br> mono en pistas estéreo no es un problema, los dos canales serán utilizados en paralelo. <br> Tenga cuidado de que no "todos" los efectos son utilizables por Muse. Search in 'Label' and 'Name': - + Buscar en nombre y etiqueta @@ -13688,7 +13845,7 @@ Likely the selected track is the wrong type. File Buttons - + Botón de archivos @@ -13714,7 +13871,7 @@ Likely the selected track is the wrong type. Error reading preset. Might not be right type for this plugin - + Preseteo dañado o no corresponde al efecto @@ -13741,49 +13898,49 @@ Likely the selected track is the wrong type. Soloing chain - + Cadena de solos Audio returns - + Retornos de audio Warning: No input devices! - + Atención: no hay entradas Open midi config... - + Abrir la configuraciòn MIDI <none> - + <ningúno> Toggle all - + Cambiar todos More... - + Mas... Audio sends - + Envios de audio Midi port sends - + Puertos de envio MIDI @@ -13791,42 +13948,42 @@ Likely the selected track is the wrong type. Treble - + Agudos Bass - + Bajos Grand Staff - + Doble Remove staff - + Remover partitura Ambiguous part - + Parte ambígua There are two or more possible parts you could add the note to, but none matches the selected part. Please select the destination part by clicking on any note belonging to it and try again, or add a new stave containing only the destination part. - + Hay dos o más partes posibles que podría añadir la nota, pero ninguno coincide con la parte seleccionada. Por favor, seleccione la parte de destino haciendo clic en cualquier nota que le pertenecen y vuelva a intentarlo, evite agregar una nota nueva que existe la parte destino. No part - + No hay partitura There are no parts you could add the note to. - + No hay piezas en las que se pueda añadir la nota. @@ -13834,80 +13991,80 @@ Likely the selected track is the wrong type. Undo/Redo tools - + Herramientas Deshacer/Rehacer Step recording tools - + Herramienta de grabación por pasos Step Record - + Grabación por pasos panic - pánico + Pánico transport - + Transporte Note settings - + Propiedades de la nota Note length: - + Duración de nota: last - + Pasado Apply to new notes: - + Se aplica a nuevas notas Apply to selected notes: - + Aplicar a las notas seleccionadas Velocity: - + Velocidad: Off-Velocity: - + Off-Velocity: Quantisation settings - + Ajustes del cuantizado Quantisation: - + Cuantizado: Pixels per whole: - + Pixeles por entero: @@ -13927,7 +14084,7 @@ Likely the selected track is the wrong type. Copy events in range - + Copiar eventos del rango @@ -13937,12 +14094,12 @@ Likely the selected track is the wrong type. Paste (with dialog) - + Pegar (con diálogo) Delete &Events - + Borrar &eventos @@ -13952,17 +14109,17 @@ Likely the selected track is the wrong type. Select &All - Seleccion&ar Todo + Seleccion&ar todo &Deselect All - &Deseleccionar Todo + &Deseleccionar todo Invert &Selection - Invertir &Selección + Invertir &selección @@ -13972,32 +14129,32 @@ Likely the selected track is the wrong type. &Outside Loop - &Exterior de Bucle + &Exterior del bucle Fu&nctions - + Fu&nciones &Quantize - + Cuantizar Change note &length - + Cambiar duración de notas Change note &velocity - + Cambiar velocidad de las notas Crescendo/Decrescendo - + Crescendo/Decrescendo @@ -14007,89 +14164,90 @@ Likely the selected track is the wrong type. Erase Events - + Borrar eventos Move Notes - + Mover notas Set Fixed Length - + Cambiar duración de notas Delete Overlaps - + Borrar notas duplicadas Legato - + Legato Window &Config - + Comportamiento de ventana Note head &colors - + Color de las notas &Black - + Negro &Velocity - + Velocidad &Part - + Región Set up &preamble - + Establecer encabezado Display &key signature - + Ver armadura de clave Display &time signature - + Ver signatura de tiempo Set Score &name - + Ajuste de nombre del pentagrama Enter the new score title - + Ingrese el título de la nueva partitura Error - + Error Changing score title failed: the selected title is not unique - + Error al cambiar el título a la partitura: +El título seleccionado ya existe. @@ -14125,12 +14283,12 @@ the selected title is not unique Shortcut conflicts with %1 - + Conflicto en el atajo con Undefined - + Sin definir @@ -14146,92 +14304,92 @@ the selected title is not unique <none> - + <ningúno> no clef - + No hay clave Treble - + Agudo Bass - + Bajo Grand - + Doble MusE: bad trackname - + MusE: Nombre de pista erroneo please choose a unique track name - + Error: El nombre de pista ya existe Update drummap? - + ¿Actualizár mapa de percusión? Do you want to use same port for all instruments in the drummap? - + ¿Desea utilizar el mismo puerto para todos los instrumentos en el mapa de percusión? &Yes - + Aceptar &No - + Cancelar show gui - mostrar gui + Ver interfáz show native gui - + Ver interfáz nativa Treble clef - + Partitura de agudos Bass clef - + Partitura de Bajos Grand Staff - + Partitura doble Viewable automation - + Automatización visible @@ -14241,12 +14399,12 @@ the selected title is not unique Track Comment - + Comentario de la pista Insert Track - + Insertar pista @@ -14261,7 +14419,7 @@ the selected title is not unique Do you want to use same port and channel for all instruments in the drummap? - + ¿Desea utilizar el mismo puerto y canal para todos los instrumentos del mapa de percusión? @@ -14279,7 +14437,7 @@ the selected title is not unique Off - + Apagado @@ -14294,7 +14452,7 @@ the selected title is not unique Snap - Snap + Chasquido @@ -14302,62 +14460,62 @@ the selected title is not unique As subwindow - + Como sub ventana Shares tools and menu - + Herramientas y menús Fullscreen - + Pantalla completa Piano roll - + Editor de matríz List editor - + Editor de lista Drum editor - + Editro de percusión Master track editor - + Editor de pista maestra Master track list editor - + Editor de lista de pista maestra Wave editor - + Editro de audio Clip list - + Lista de audios Marker view - + Ver marcadores Score editor - + Editor de partituras @@ -14367,7 +14525,7 @@ the selected title is not unique <unknown toplevel type> - + <Tipo de nivel superior desconocido> @@ -14552,12 +14710,12 @@ the selected title is not unique Jack - + Jack Jack transport sync on/off - + Sincronizar a Jack Encendido/Apagado @@ -14576,48 +14734,48 @@ the selected title is not unique Show wave tracks - + Ver pistas de audio Show group tracks - + Ver grupos Show aux tracks - + Ver envios auxiliares Show input tracks - + Ver entradas de audio Show output tracks - + Ver salidas de audio Show midi tracks - + Ver pistas MIDI Show synth tracks - + Ver Sintetizadores Visible track types - + Ver tipo de pistas @@ -14630,12 +14788,12 @@ the selected title is not unique Func&tions - + Funciones &Gain - + &Ganancia 200% @@ -14660,7 +14818,7 @@ the selected title is not unique Other - + Otros @@ -14670,7 +14828,7 @@ the selected title is not unique C&ut - C&ortar + Cortar @@ -14680,32 +14838,32 @@ the selected title is not unique Edit in E&xternal Editor - + Abrir con editor externo Mute Selection - + Silenciar selección Normalize Selection - + Normalizar selección Fade In Selection - + Aparecer progresivamente Fade Out Selection - + Desvanecer progresivamente Reverse Selection - + Invertir selección @@ -14715,32 +14873,32 @@ the selected title is not unique Select &All - Seleccion&ar Todo + Seleccion&ar todo &Deselect All - &Deseleccionar Todo + &Deseleccionar todo Window &Config - + &Comportamiento de ventana Wave edit tools - + Herramientas de edición de audio transport - + Transporte WaveEdit tools - + Herramientas de edición de audio @@ -14758,7 +14916,7 @@ the selected title is not unique MusE - external editor failed - + MusE: Falla del editor de audio externo @@ -14766,12 +14924,15 @@ the selected title is not unique check if the editor setting in: Global Settings->Audio:External Waveditor is set to a valid editor. - + Muse no pudo lanzar el editor externo +Compruebe esta configuraciòn en: +Configuración global-> Audio: Editor de audio externo +que el comando del editor sea válido. MusE - file size changed - + MusE: Cambió el tamaño del archivo @@ -14779,7 +14940,10 @@ is set to a valid editor. since it must fit the selected region. Missing data is muted - + Al editar en el editor externo no se debe cambiar el tamaño del archivo +ya que debe ajustarse a la región seleccionada. + +Los datos faltantes se silenciarán. @@ -15134,12 +15298,12 @@ Missing data is muted Oscillator - Oscilador + Oscillator Brass - Metales + Brass @@ -15149,7 +15313,7 @@ Missing data is muted Flute - Flauta + Flute @@ -15189,7 +15353,7 @@ Missing data is muted Envelope Lo - Envolvente Lo + Envelope Lo Attack(ms) @@ -15210,31 +15374,31 @@ Missing data is muted Envelope Hi - Envolvente Hi + Envelope Hi Release - Relajación + Release Sustain - Sostenido + Sustain Decay - Decaimiento + Decay Attack - Ataque + Attack @@ -15244,18 +15408,18 @@ Missing data is muted ms - + ms cB - + cB Velocity - Velocidad + Velocity @@ -15445,62 +15609,62 @@ Missing data is muted MusE: Paste Parts - + MusE: Pegar regiones. Number and raster - + Cantidad y alineado insert - + Insertar times - + -Tiempos raster - + Trama ticks - + Tics Move, Merge, Clone - + Mover, Mezclar, Clonar Move everything to the right - + Mover todo a la derecha. Move only affected parts to the right - + Mover sólo las regiones afectadas a la derecha. Put everything into a single track - + Poner todo en una sola pista. Merge with existing parts - + Mezclar con las regiones existentes. Insert as clones (where possible) - + Insertar como clones (si es posible) @@ -15518,59 +15682,60 @@ Missing data is muted MusE: Paste Events - + MusE: Pegar eventos Number and raster - + Cantidad y alineado insert - + Insertar times - + -Tiempos raster - + Alineado ticks - + -Tics Paste options - + Opciones del pegado Always into existing parts - + Siempre en las regiones existentes. Never into existing parts - + Nunca en las regiones existentes. Into existing parts if part has not to be expanded by more than - + En las regiones existentes si mas de +una región no tiene que ser ampliada . Put everything into the (selected) part - + Poner todo lo seleccionado en una región. @@ -15926,32 +16091,32 @@ to be expanded by more than Create Project - + Crear sesión Project Name: - + Nombre del la sesión: Project Path to song file: - + Ruta de la sesión: Create project folder (recommended for audio projects) - + Crear carpeta para la sesión (recomendado para sesiones de audio) Browse - + Buscar Song information: - + Información de la sesión @@ -16092,19 +16257,19 @@ actualmente sin uso Other - + Otro Error - + Error Please first select the range for crescendo with the loop markers. - + Por favor, seleccione el rango de crescendo con los marcadores de bucle. @@ -16121,7 +16286,7 @@ actualmente sin uso Cannot convert sysex string - No puedo convertir el paquete de sistema exclusivo + No se puede convertir el paquete de sistema exclusivo @@ -16132,22 +16297,22 @@ actualmente sin uso generic midi - midi genánico + MIDI genérico new - nuevo + Nueva sesión create peakfile for - crear archivo de picos para + Crear archivo de picos MusE: get file name - MusE: obtener el nombre de archivo + MusE: Obtener el nombre de archivo the directory @@ -16177,31 +16342,38 @@ no existe %1 does not exist. Create it? - + La carpeta +%1 +no existe. +¿Desea crearla? MusE: create directory - MusE: crear directorio + MusE: Crear carpeta creating dir failed - fallóla creación de directorio + falló la creación de carpeta File %1 exists. Overwrite? - + El archivo +%1 +ya existe. ¿Desea sobreescribirlo? Open File %1 failed: %2 - + Abrir archivo +%1 +falló: %2 File @@ -16218,7 +16390,7 @@ existe MusE: write - MusE: escribe + MusE: Escribir Overwrite @@ -16248,7 +16420,7 @@ falló None - Ninguno + Ningúno Master @@ -16269,7 +16441,7 @@ falló No selection. Ignoring - + No hay nada seleccionado! @@ -16277,7 +16449,7 @@ falló MusE: Quantize - + MusE: Cuantizár @@ -16297,12 +16469,12 @@ falló Looped Events - + Eventos del bucle Selected Looped - + Seleccionar bucle @@ -16312,7 +16484,7 @@ falló Strength: - + Porcentaje: @@ -16322,12 +16494,12 @@ falló Threshold (ticks): - + Umbrál (Tics): Quantize Len - + Cuantizar duración @@ -16337,57 +16509,57 @@ falló Whole - + Totalidad Half - + Mitad 4th - + 4th 4th Triplet - + 4th Triplet 8th - + Octavos 8th Triplet - + Octavos con puntillo 16th - + 16th 16th Triplet - + 16th Triplet 32th - + 32th 32th Triplet - + 32th Triplet Swing: - + Oscilación: @@ -16396,7 +16568,10 @@ If swing=0, this is normal If swing is 33, you get a 2:1-rhythm. If swing is -33, you get a 1:2-rhythm. - + Si en el cambio propuesto la duración es menor que el umbral, no se hace nada. +Si la oscilación es = 0, esto es normal +Si la oscilación es de 33, se obtiene un ritmo 2:1. +Si la oscilación es de -33, se obtiene un ritmo1:2. @@ -16464,7 +16639,7 @@ If swing is -33, you get a 1:2-rhythm. MusE: Erase Notes - + MusE: Borrar notas @@ -16484,22 +16659,22 @@ If swing is -33, you get a 1:2-rhythm. Looped Events - + Eventos del bucle Selected Looped - + Bucle seleccionado Thresholds - + Umbrales ticks - + -Tics @@ -16509,7 +16684,7 @@ If swing is -33, you get a 1:2-rhythm. Length - Longitud + Duración @@ -16520,7 +16695,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:7px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If nothing is checked, everything is removed.</p> <p style=" margin-top:0px; margin-bottom:7px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If velocity is checked, only notes with velo &lt; threshold are removed.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If both are checked, notes with velo &lt; threshold OR with length &lt; threshold are removed.</p></body></html> - + @@ -16894,57 +17069,57 @@ en la lista de controles definidos por MusE MusE: Routing - + Muse: Ruteado Add Route - + Agregar ruta Source: - + Fuente: Destination: - + Destino: Connect - + Conectar connect source to destination - + Conectar fuente a destino Current Routes - + Rutas actuales Source - + Fuente Destination - + Destino Remove - + Eliminar remove selected route - + Eliminar ruta seleccionada @@ -16959,7 +17134,7 @@ en la lista de controles definidos por MusE SimpleDrums - Ladspa Plugin Chooser - + SimpleDrums - Selector de Efecto Ladspa @@ -16974,17 +17149,17 @@ en la lista de controles definidos por MusE Inports - + Puerto de entrada Outports - + Puerto de salida Creator - + Creador @@ -16994,17 +17169,17 @@ en la lista de controles definidos por MusE Alt+C - + Alt+C &OK - + Aceptar Alt+O - + Alt+O @@ -17012,22 +17187,22 @@ en la lista de controles definidos por MusE Clear and unload effect - + Limpiar y descargar efecto Load effect - + Cargar efecto Toggle display of effect parameters - + Vista de los parámetros de efecto Turn effect on/off - + Encender/Apagar efecto @@ -17255,7 +17430,7 @@ en la lista de controles definidos por MusE MusE: Set Note Length - + MusE: Cambiar duración de notas @@ -17275,12 +17450,12 @@ en la lista de controles definidos por MusE Looped Events - + Eventos en bucle Selected Looped - + Seleccionar bucle @@ -17290,12 +17465,12 @@ en la lista de controles definidos por MusE New length - + Nueva duración ticks - + -Tics @@ -17324,28 +17499,28 @@ en la lista de controles definidos por MusE Enter shortcut sequence - + Ingresar atajo Press keys to enter shortcut sequence! - + Ingrese la secuencia de teclas Old shortcut: - + Atajo anterior Undefined - + Sin definir New shortcut: - + Nuevo atajo @@ -17363,42 +17538,42 @@ en la lista de controles definidos por MusE Configure Keyboard Shortcuts - + Configurar atajos de teclado Shortcut Category - + Categoría de accesos rápidos Description - + Descripción Shortcut - + Acceso rápido &Clear - + Limpiar Alt+C - + Alt+C &Define - + &Definir Alt+D - + Alt+D @@ -17408,7 +17583,7 @@ en la lista de controles definidos por MusE Alt+A - + Alt+A @@ -17423,7 +17598,7 @@ en la lista de controles definidos por MusE DrumSynth 0.1 - + DrumSynth 0.1 @@ -17431,17 +17606,17 @@ en la lista de controles definidos por MusE &Load setup - + Cargar configuración &Save setup - + Guardar configuración Load sample dialog - + Cargar diálogo de muestra @@ -17460,12 +17635,12 @@ en la lista de controles definidos por MusE Song Information - + Información de la sesión Show on song load - + Mostrar al cargar la sesión @@ -17475,17 +17650,17 @@ en la lista de controles definidos por MusE Alt+C - + Alt+C &Ok - Ac&eptar + Aceptar Alt+O - + Alt+O @@ -17558,22 +17733,22 @@ en la lista de controles definidos por MusE Midi connections - + Conexiones de MIDI Inst - + Instrumento Version - + Versión Description - + Descripción @@ -17803,7 +17978,7 @@ en la lista de controles definidos por MusE MusE: Transpose - + MusE:-Transponer @@ -17823,12 +17998,12 @@ en la lista de controles definidos por MusE Looped Events - + Eventos del bucle Selected Looped - + Bucle seleccionadp @@ -17838,7 +18013,7 @@ en la lista de controles definidos por MusE Halftone-steps - + Semitonos @@ -17899,29 +18074,30 @@ en la lista de controles definidos por MusE Dialog - + Dialogo List of unused audio files in current project directory: - + Listar archivos de audio sin uso en la sesión Current project - + Sesión actual All .med files in current directory - + Todas las sesiones +en la carpeta actual Move files to 'unused' subdir - + Mover no usados a carpeta "unused" @@ -17934,13 +18110,13 @@ in current MusE: Load VAM Presets - + MusE: Cargar preseteos de VAM MusE: Save VAM Presets - + Guardar preseteos de VAM @@ -18153,7 +18329,15 @@ Jotsif Lindman Hörnlund Copyright(C) 2005 Robert Jonsson (rj@spamatica.se) - + VAM 1.0beta3 +Sintetizador análogo virtual para MusE +Liberado bajo licencia GPL. +Derechos Reservados(C) 2002 +Jotsif Lindman Hörnlund +( jotsif@linux.nu ) +Derechos Reservados(C) 2005 +Robert Jonsson +(rj@spamatica.se) @@ -18161,7 +18345,7 @@ Robert Jonsson MusE: Modify Velocity - MusE: Modificar velocidad + MusE: Modificar la velocidad. @@ -18195,7 +18379,7 @@ Robert Jonsson Rate: - Velocidad: + Porcentajes: @@ -18210,12 +18394,12 @@ Robert Jonsson Selected Looped - + Selecionar bucles veloNew = (veloOld * rate) + offset - + @@ -18350,32 +18534,32 @@ Robert Jonsson FreeVerb - + FreeVerb Room Size - Tamaño sala + Room Size Damping - Amortiguamiento + Damping Wet Level - + Wet Level Tap-Reverberator - + Tap-Reverb Decay [ms] - + Decay [ms] @@ -18386,252 +18570,252 @@ Robert Jonsson Dry Level [dB] - + Dry Level [dB] Wet Level [dB] - + Wet Level [dB] Preset: - + Preseteo: AfterBurn - + AfterBurn AfterBurn (Long) - + AfterBurn (Long) Ambience - + Ambience Ambience (Thick) - + Ambience (Thick) Ambience (Thick) - HD - + Ambience (Thick) - HD Cathedral - + Cathedral Cathedral - HD - + Cathedral - HD Drum Chamber - + Drum Chamber Garage - + Garage Garage (Bright) - + Garage (Bright) Gymnasium - + Gymnasium Gymnasium (Bright) - + Gymnasium (Bright) Gymnasium (Bright) - HD - + Gymnasium (Bright) - HD Hall (Small) - + Hall (Small) Hall (Medium) - + Hall (Medium) Hall (Large) - + Hall (Large) Hall (Large) - HD - + Hall (Large) - HD Plate (Small) - + Plate (Small) Plate (Medium) - + Plate (Medium) Plate (Large) - + Plate (Large) Plate (Large) - HD - + Plate (Large) - HD Pulse Chamber - + Pulse Chamber Pulse Chamber (Reverse) - + Pulse Chamber (Reverse) Resonator (96 ms) - + Resonator (96 ms) Resonator (152 ms) - + Resonator (152 ms) Resonator (208 ms) - + Resonator (208 ms) Room (Small) - + Room (Small) Room (Medium) - + Room (Medium) Room (Large) - + Room (Large) Room (Large) - HD - + Room (Large) - HD Slap Chamber - + Slap Chamber Slap Chamber - HD - + Slap Chamber - HD Slap Chamber (Bright) - + Slap Chamber (Bright) Slap Chamber (Bright) HD - + Slap Chamber (Bright) HD Smooth Hall (Small) - + Smooth Hall (Small) Smooth Hall (Medium) - + Smooth Hall (Medium) Smooth Hall (Large) - + Smooth Hall (Large) Smooth Hall (Large) - HD - + Smooth Hall (Large) - HD Vocal Plate - + Vocal Plate Vocal Plate - HD - + Vocal Plate - HD Warble Chamber - + Warble Chamber Warehoouse - + Warehoouse Warehouse - HD - + Warehouse - HD Comb Filters - + Filtros combinados Allpass Filters - + Sin filtros Bandpass Filters - + flitros de banda Enhanced Stereo - + Ampliar estéreo @@ -18639,873 +18823,873 @@ Robert Jonsson Transport: Start playback from current location - + Transporte: Iniciar reproducción desde la ubicación actual Transport: Toggle metronome - + Transporte: Alternar metrónomo Transport: Stop Playback - + Transporte : Detener reproducción Transport: Goto Start - + Transporte: Ir al comienzo Transport: Play, Stop, Rewind - + Transporte: Iniciar, Detener, Rebobinar Transport: Goto left marker - + Transporte: Ir a la marca izquierda Transport: Goto right marker - + Transporte: Ir a la marca derecha Transport: Toggle Loop section - + Transporte: Alternar selección del bucle Transport: Toggle Record - + Transporte Alternar grabación Transport: Clear all rec enabled tracks - + Transporte: deshabilitar el grabado en todas las pistas Toggle fullscreen - + Pantalla completa Edit: Copy - + Editar:Copiar Edit: Copy in range - + Editar: Copiar rango Edit: Undo - + Editar: Deshacer Edit: Redo - + Edit: Rehacer Edit: Cut - + Editar: Cortar Edit: Paste - + Editar: Pegar Edit: Paste (with dialog) - + Editar: Pegar (con diálogo) Edit: Delete - + Editar: Borrar File: New project - + Archivo: Nueva sesión File: Open from disk - + Archivo: Abrir desde disco File: Save project - + Archivo: Guardar sesión File: Open recent file - + Archivo: Sesiones recientes File: Save as - + Archivo: Guardar como File: Load template - + Archivo: Abrir plantilla File: Import midi file - + Archivo: Importar archivo MIDI File: Export midi file - + Archivo: Exportar archivo MIDI File: Import midi part - + Archivo: Importar región MIDI File: Import audio file - + Archivo: Importar archivo de audio File: Quit MusE - + Archivo: Cerrar MusE Edit: Select parts on track - + Editar: Seleccionar regiones de la pista Open pianoroll - + Abrir editor de matríz Open drumeditor - + Editar: Editor de percusión Open listeditor - + Abrir editor de lista Open waveeditor - + Abrir editor de audio Open graphical mastertrack editor - + Vista de pista maestra Open list mastertrack editor - + Lista de pista maestra Open midi transformer - + Abrir transformador MIDI Add midi track - + Agregar pista MIDI Add drum track - + Agregar pista de percusión Add wave track - + Agregar pista de audio Add audio output - + Agregar salida de audio Add audio group - + Agregar grupo de audio Add audio input - + Agregar entrada de audio Add audio aux - + Agregar envio auxiliar Structure: Global cut - + Estructura: Corte Globál Structure: Global insert - + Estructura: Inserción global Structure: Global split - + Estructura: División globál Structure: Cut events - + Estructura: Cortar eventos View: Open mixer #1 window - + Ver: Abrir mezclador #1 View: Open mixer #2 window - + Ver: Abrir mezclador #2 View: Toggle transport window - + Ver: Ventana alternativa del transporte View: Toggle bigtime window - + Ver: Ventana de reloj View: Open marker window - + Ver: Abrir ventana de marcadores Settings: Follow song by page - + Ajustes: Seguir página Settings: Follow song off - + Ajustes: No seguir canción Settings: Follow song continuous - + Ajustes: Seguir canción indefinidamente Settings: Global configuration - + Configuraciones: Configuración global Settings: Configure shortcuts - + Configuraciones: Atajos de teclado Settings: Configure metronome - + Configuraciones: Metrónomo Settings: Midi sync configuration - + Configuraciones: Sincronía MIDI Settings: Midi file import/export configuration - + Configuraciones: Configuracion de exportar/importar MIDI Settings: Appearance settings - + Configuraciones: Apariencia Settings: Midi ports / Soft Synth - + Configuraciones: Puertos MIDI/Sintetizadores virtuales Settings: Audio subsystem configuration - + Configuraciones: Configurar sub sistema de audio Midi: Edit midi instruments - + MIDI: Editar instrumentos Midi: Open midi input transform - + MIDI: Abrir el transformador de entrada MIDI Midi: Open midi input filter - + MIDI: Abrir el filtro de entrada MIDI Midi: Midi input transpose - + MIDI: Filtro de transporte de entrada Midi: Midi remote control - + MIDI: Control remoto MIDI Midi: Random rhythm generator - + MIDI: Generador de ritmo aleatorio Midi: Reset midi - + MIDI: Resetear MIDI Midi: Init midi - + MIDI: Inicializar MIDI Midi: Midi local off - + MIDI: MIDI local apagado Audio: Bounce audio to track - + Audio: Rebotar audio a pista Audio: Bounce audio to file - + Audio: Rebotar audio a archivo Audio: Restart audio - + Audio: Reiniciar audio Automation: Mixer automation - + Automatización: Mezcladora de automatización Automation: Take mixer snapshot - + Automatización: Tomar instantánea del mezclador Automation: Clear mixer automation - + Automatización: Limpiar la mezcladora de automatización Help: Open Manual - + Ayuda: Abrir manual Help: Toggle whatsthis mode - + Ayuda: Cambiar el modo ¿qué es esto? Edit: Edit selected part - + Editar: Seleccionar región Edit: Select nearest part on track above - + Editar: Seleccione la región más cercana por encima de la pista Edit: Add nearest part on track above - + Editar: Agregar la región más cercana por encima de la pista Edit: Select nearest part on track below - + Editar: Seleccione la región más cercana por debajo de la pista Edit: Add nearest part on track below - + Editar: Agregar la región más cercana por debajo de la pista Edit: Insert empty measure - + Editar: Insertar compás vacío Edit: Paste as clones - + Editar: Pegar como clon Edit: Paste as clones (with dialog) - + Editar: Pegar como clon (con diálogo) Select track above - + Seleccionar la pista anterior Select track below - + Seleccionar la pista siguiente Midi: Transpose - + MIDI: Transportar Edit: Select all - + Editar: Seleccionar todo Edit: Select none - + Editar: Deseleccionar Edit: Invert Selection - + Editar: Invertir selección Edit: Select events/parts inside locators - + Editar: seleccionar eventos/regiones dentro de los marcadores Edit: Select events/parts outside locators - + Editar: seleccionar eventos/regiones fuera de los marcadores Edit: Select previous part - + Edición: Seleccionar región anterior Edit: Select next part - + Editar: Seleccionar región siguiente Edit: Select nearest part/event to the left or move cursor - + Editar: Seleccione región /evento mas cercano a la izquierda o mover el cursor Edit: Add nearest part/event to the left to selection - + Edit: Añadir región/evento mas cercano a la izquierda a la selección Edit: Select nearest part/event to the right or move cursor - + Editar: seleccione la región/evento mas cercano la derecha o mover el cursor Edit: Add nearest part/event to the right to selection - + Edit: Añadir la región/evento a la derecha a la selección Edit: Set locators to selection - + Editar: Conjunto localizadores a la selección Edit: Increase pitch - + Editar: Subir afinación Edit: Decrease pitch - + Editar: Bajar afinación Edit: Increase event position - + Editar: Aumenta la posición del evento Edit: Decrease event position - + Editar: Disminuye la posición del evento View: Zoom in - + Ver: Acercar View: Zoom out - + Ver: Alejar View: Goto Current Position - + Ver: Ir a la posición actual View: Scroll left - + Ver: Mover a la izquierda Edit: Set Fixed Length on Midi Events - + Editar Igualar la duración de las notas MIDI Quantize - Cuantizar + Cuantizar Modify Note Length - + Modificar duraciòn Modify Velocity - + Modificar la velocidad Edit: Crescendo - + Editar: Crescendo Edit: Thin Out - + Editar: Truncar Edit: Erase Event - + Editar: Borrar evento Edit: Delete Overlaps - + Editar: Borrar notas duplicadas Edit: Note Shift - + Editar: Alterar nota Edit: Move Clock - + Editar: Mover reloj Edit: Copy Measure - + Editar: Copiar compás Edit: Erase Measure - + Editar: Vaciar compás Edit: Delete Measure - + Editar: Borrar compás Edit: Create Measure - + Editar: Crear compás Edit: Change Event Color - + Editar: Cambiar el color de evento Tool: Pointer - + Herramientas: Apuntador Tool: Pencil - + Herramientas: Lápiz Tool: Eraser - + Herramientas: Borrador Tool: Line Draw - + Herramientas: Linea de dibujo Tool: Cursor - + Herramientas: Cursor Add note velocity 1 - + Añadir velocidad de la nota 1 Add note velocity 2 - + Añadir velocidad de la nota 2 Add note velocity 3 - + Añadir velocidad de la nota 3 Add note velocity 4 - + Añadir velocidad de la nota 4 Cursor step size: larger - + Aumentar el paso de cursor Cursor step size: smaller - + Reducir el paso del cursor Instrument/Cursor up - + Instrumento, Incrementar valor Instrument/Cursor down - + Instrumento, Disminuir valor Tool: Scissor - + Herramientas: Tijeta Tool: Glue - + Herramienta: Unir Tool: Mute - + Herramienta: Silenciar Transport: Increase current position - + Transporte: Incrementar la posición actual Transport: Decrease current position - + Transporte: retroceder de la posición actual Transport: Increase current position, no snap - + Transporte: Adelantar de la posición actual, no snap Transport: Decrease current position, no snap - + Transporte: retroceder de la posición actual, no snap Quantize: Set quantize to 1/1 note - + Cuantizar: Ajustar cuantizado a 1/1 note Quantize: Set quantize to 1/2 note - + Cuantizar: Ajustar cuantizado a 1/2 note Quantize: Set quantize to 1/4 note - + Cuantizar: Ajustar cuantizado a 1/4 note Quantize: Set quantize to 1/8 note - + Cuantizar: Ajustar cuantizado a 1/8 note Quantize: Set quantize to 1/16 note - + Cuantizar: Ajustar cuantizado a 1/16 note Quantize: Set quantize to 1/32 note - + Cuantizar: Ajustar cuantizado a 1/32 note Quantize: Set quantize to 1/64 note - + Cuantizar: Ajustar cuantizado a 1/64 note Quantize: Toggle triol quantization - + Cuantizado: Ajuste de cauntización triol. Quantize: Toggle punctuation quantization - + Cuantización: Cambiar-puntuación-del cuantizado Quantize: Toggle punctuation quantization (2) - + Cuantización: Cambiar-puntuación-del cuantizado (2) Edit: Insert at location - + Editar: Insertar en la posición Edit: Increase length - + Editar: Incrementar duración Edit: Decrease length - + Editar: Acortar duración Insert Note - Insertar nota + Insertar nota Insert SysEx - Insertar sistema exclusivo + Insertar sistema exclusivo Insert Ctrl - Insertar controlador + Insertar controlador Insert Meta - Insertar Meta + Insertar Meta Insert Channel Aftertouch - Insertar AfterTouch de canal + Insertar AfterTouch de canal Insert Key Aftertouch - Insertar AfterTouch de tecla + Insertar AfterTouch de tecla Insert Tempo - + Insertar tempo Insert Signature - + Insertar armadura de clave Change Event Position - + Cambiar posición de evento Edit Event Value - + Editar valor del evento Insert Key - + Insertar clave Goto Next Marker - + Ir a la siguiente marca Goto Prev Marker - + Ir a la marca anterior diff --git a/muse2/share/locale/muse_fr.ts b/muse2/share/locale/muse_fr.ts index 99e3e5ef..eb19761e 100644 --- a/muse2/share/locale/muse_fr.ts +++ b/muse2/share/locale/muse_fr.ts @@ -226,22 +226,22 @@ cliquez sur une pièces pour la rendre muette ou pas. Tous les Fichiers (*) - + Add Midi Track Ajouter une Piste Midi - + Add Drum Track Ajouter une Piste de Batterie - + Add Wave Track Ajouter une Piste Audio - + Add Audio Output @@ -261,7 +261,7 @@ cliquez sur une pièces pour la rendre muette ou pas. - + Add Synth @@ -4998,12 +4998,11 @@ Time) (Tics par sec.) - GUI - GUI + GUI - + /sec /sec @@ -5048,7 +5047,22 @@ left button behave like the middle button in such areas. - + + Allow adding hidden tracks in track list menu + + + + + Unhide tracks when adding hidden tracks + + + + + GUI Style + + + + MDI-subwindowness and sharing menus @@ -5092,7 +5106,7 @@ left button behave like the middle button in such areas. Navigateur pour l'aide: - + Application @@ -5422,7 +5436,12 @@ Adjusts responsiveness of audio controls and - + + GUI Behaviour + + + + Use old-style stop shortcut: @@ -7171,6 +7190,11 @@ Enabled inputs in the list will Send sync delay + + + Note: Sync delay and MTC sync currently not fully implemeted + + MidiTrackInfoBase @@ -9147,7 +9171,7 @@ sélectionnées MusECore::Song - + Jack shutdown! @@ -9230,7 +9254,7 @@ click on the Restart button. - + MusE - external script failed @@ -9605,7 +9629,7 @@ Right-click to show GUI. - + C&ut Co&uper @@ -9711,12 +9735,12 @@ Right-click to show GUI. - all parts in one staff + all tracks in one staff - one staff per part + one staff per track @@ -9775,6 +9799,21 @@ Right-click to show GUI. Global Split Diviser Tout + + + Global Cut - selected tracks + + + + + Global Insert - selected tracks + + + + + Global Split - selected tracks + + &Edit @@ -9786,7 +9825,7 @@ Right-click to show GUI. &Structure - + Functions Fonctions @@ -9846,7 +9885,7 @@ Right-click to show GUI. - + New Nouveau @@ -9913,7 +9952,7 @@ Right-click to show GUI. MusEGui::AudioStrip - + panorama @@ -9943,7 +9982,7 @@ Right-click to show GUI. pre fader - post fader - + dB dB @@ -10072,7 +10111,7 @@ Right-click to show GUI. MusEGui::ClipListEdit - + MusE: Clip List Editor MusE: Editeur de la Liste de Clips @@ -10186,7 +10225,7 @@ Right-click to show GUI. MusEGui::DrumEdit - + mute instrument Rendre muet l'instrument @@ -10542,7 +10581,7 @@ Right-click to show GUI. LV4 - + Muse: Load Drum Map MusE: Charger Set de Batterie @@ -11013,7 +11052,7 @@ cliquez sur une pièces pour la rendre muette ou pas. MusEGui::GlobalSettingsConfig - + Selects instruments directory @@ -11029,7 +11068,7 @@ cliquez sur une pièces pour la rendre muette ou pas. MusEGui::LMaster - + MusE: Mastertrack @@ -11144,7 +11183,7 @@ cliquez sur une pièces pour la rendre muette ou pas. Valeur - + Reposition of the initial tempo and signature events is not allowed @@ -11167,7 +11206,7 @@ cliquez sur une pièces pour la rendre muette ou pas. MusEGui::ListEdit - + insert Note insére une note @@ -11332,18 +11371,18 @@ Do you want to apply to all existing midi tracks now? - + in - - + + out - + Show first aliases @@ -11541,13 +11580,13 @@ Do you want to apply to all existing midi tracks now? Etat - + <unknown> - + <none> @@ -11571,7 +11610,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MarkerView - + MusE: Marker MusE: Marqueur @@ -11644,7 +11683,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MasterEdit - + MusE: Mastertrack @@ -12167,7 +12206,7 @@ Apply sync settings? MusEGui::MidiTrackInfo - + <unknown> @@ -12210,7 +12249,7 @@ Apply sync settings? - + Und&o &Annuler @@ -12363,13 +12402,13 @@ midi - - + + &Save - + 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. @@ -12397,7 +12436,7 @@ You can also select the Save command from the File menu. - + Import Wave File Importer fichier WAV @@ -12692,7 +12731,7 @@ You can also select the Save command from the File menu. &Aide - + Cannot read template @@ -12713,13 +12752,13 @@ You can also select the Save command from the File menu. - - + + MusE: Song: %1 - + MusE: load project Muse: charger Projet @@ -12742,17 +12781,17 @@ non encore sauvegardées. Enregistrer? - + S&kip - + &Cancel - + MusE: Save As MusE: enregistrer sous @@ -12764,7 +12803,7 @@ non encore sauvegardées. Enregistrer? Rien � éditer - + @@ -12832,7 +12871,7 @@ avant d'en ouvrir un autre? - + &Abort &Annuler @@ -12898,7 +12937,7 @@ failed: échec: - + Import part is only valid for midi and wave tracks! @@ -12998,7 +13037,7 @@ Do you still want to import it? différent - + C&ut Co&uper @@ -13076,7 +13115,7 @@ Files: - + %n part(s) out of %1 could not be pasted. Likely the selected track is the wrong type. @@ -13170,7 +13209,7 @@ sélectionnées MusEGui::PianoRoll - + &Edit @@ -13373,7 +13412,7 @@ sélectionnées MusEGui::PluginDialog - + MusE: select plugin MusE: choisir plugin @@ -13515,32 +13554,32 @@ sélectionnées MusEGui::RoutePopupMenu - + - + - - + + Channel Canal - - + + Soloing chain - - + + Audio returns - + Warning: No input devices! @@ -13550,7 +13589,7 @@ sélectionnées - + <none> @@ -13579,7 +13618,7 @@ sélectionnées MusEGui::ScoreCanvas - + Treble @@ -13599,7 +13638,7 @@ sélectionnées - + Ambiguous part @@ -13622,7 +13661,7 @@ sélectionnées MusEGui::ScoreEdit - + Undo/Redo tools @@ -13662,20 +13701,20 @@ sélectionnées - + - + Apply to new notes: - - + + Apply to selected notes: - + Velocity: @@ -13695,7 +13734,7 @@ sélectionnées - + Pixels per whole: @@ -13845,7 +13884,7 @@ sélectionnées - + Set up &preamble @@ -13865,7 +13904,7 @@ sélectionnées - + Enter the new score title @@ -13931,6 +13970,14 @@ the selected title is not unique Echelle de la signature + + MusEGui::Strip + + + Remove track? + + + MusEGui::TList @@ -14065,7 +14112,7 @@ the selected title is not unique MusEGui::Toolbar1 - + Off @@ -14105,7 +14152,7 @@ the selected title is not unique - + Piano roll @@ -14369,7 +14416,7 @@ l'enregistrement MusEGui::VisibleTracks - + Show wave tracks @@ -15852,11 +15899,6 @@ port QObject - - - Other - - @@ -15903,7 +15945,7 @@ port nouveau - + create peakfile for créer fichier de crêtes pour @@ -16008,8 +16050,8 @@ failed: MusE: Ouvrir un Fichier - - + + None @@ -17243,12 +17285,11 @@ sélectionnées SynthConfigBase - MusE: Synth Configuration - MusE: Configuration Synth Virtuel + MusE: Configuration Synth Virtuel - + Soft Synthesizer Synthétiseur Virtuel @@ -17258,18 +17299,18 @@ sélectionnées Fichier - + Instances Exemplaires - + Name Nom - + list of available software synthesizers liste des synthétiseurs virtuels disponibles @@ -17294,12 +17335,23 @@ disponibles Port MIDI - + + Midi Port and Soft Synth Configuration + + + + + + Type + Type + + + Midi connections - + Inst diff --git a/muse2/share/locale/muse_pl.ts b/muse2/share/locale/muse_pl.ts index 0d948e0f..00fa0d2c 100644 --- a/muse2/share/locale/muse_pl.ts +++ b/muse2/share/locale/muse_pl.ts @@ -200,22 +200,22 @@ Kliknij na pojedynczy klocek aby go wyłączyć z odtwarzania. Wszystkie Pliki (*) - + Add Midi Track Dodaj Ślad Midi - + Add Drum Track Dodaj Ślad Perkusyjny - + Add Wave Track Dodaj Ślad Audio - + Add Audio Output Dodaj Wyjście Audio @@ -239,7 +239,7 @@ Kliknij na pojedynczy klocek aby go wyłączyć z odtwarzania. Gumka - + Add Synth @@ -4871,12 +4871,11 @@ RTC (Rzeczywista Rozdzielczość Zegara) (Tykanie/Sekunda) - GUI - Interfejs Użytkownika + Interfejs Użytkownika - + /sec /sek. @@ -4920,7 +4919,22 @@ left button behave like the middle button in such areas. - + + Allow adding hidden tracks in track list menu + + + + + Unhide tracks when adding hidden tracks + + + + + GUI Style + + + + MDI-subwindowness and sharing menus @@ -4964,7 +4978,7 @@ left button behave like the middle button in such areas. Przeglądarka pomocy: - + Application Zastosowanie @@ -5294,7 +5308,12 @@ Adjusts responsiveness of audio controls and - + + GUI Behaviour + + + + Use old-style stop shortcut: @@ -7018,6 +7037,11 @@ Enabled inputs in the list will Send sync delay + + + Note: Sync delay and MTC sync currently not fully implemeted + + MidiTrackInfoBase @@ -9128,7 +9152,7 @@ Zapisać otwarty utwór? MusECore::Song - + Jack shutdown! @@ -9211,7 +9235,7 @@ click on the Restart button. - + MusE - external script failed @@ -9586,7 +9610,7 @@ Right-click to show GUI. - + C&ut @@ -9692,12 +9716,12 @@ Right-click to show GUI. - all parts in one staff + all tracks in one staff - one staff per part + one staff per track @@ -9756,6 +9780,21 @@ Right-click to show GUI. Global Split Globalne Podzielenie + + + Global Cut - selected tracks + + + + + Global Insert - selected tracks + + + + + Global Split - selected tracks + + &Edit @@ -9767,7 +9806,7 @@ Right-click to show GUI. &Globalne - + Functions Opcje @@ -9827,7 +9866,7 @@ Right-click to show GUI. - + New Nowy @@ -9894,7 +9933,7 @@ Right-click to show GUI. MusEGui::AudioStrip - + panorama Panorama @@ -9924,7 +9963,7 @@ Right-click to show GUI. przed/ za tłumikiem - + dB dB @@ -10053,7 +10092,7 @@ Right-click to show GUI. MusEGui::ClipListEdit - + MusE: Clip List Editor @@ -10167,7 +10206,7 @@ Right-click to show GUI. MusEGui::DrumEdit - + mute instrument wyłącz instrument @@ -10523,7 +10562,7 @@ Right-click to show GUI. PV4 - + Muse: Load Drum Map MuzA: Załaduj zestaw perkusyjny @@ -10988,7 +11027,7 @@ Kliknij na pojedynczy klocek aby go wyłączyć z odtwarzania. MusEGui::GlobalSettingsConfig - + Selects instruments directory @@ -11004,7 +11043,7 @@ Kliknij na pojedynczy klocek aby go wyłączyć z odtwarzania. MusEGui::LMaster - + MusE: Mastertrack MuzA: Ślad Tempo/Metrum @@ -11119,7 +11158,7 @@ Kliknij na pojedynczy klocek aby go wyłączyć z odtwarzania. Wartość - + Reposition of the initial tempo and signature events is not allowed @@ -11142,7 +11181,7 @@ Kliknij na pojedynczy klocek aby go wyłączyć z odtwarzania. MusEGui::ListEdit - + insert Note Wstaw nutę @@ -11306,18 +11345,18 @@ Do you want to apply to all existing midi tracks now? - + in - - + + out - + Show first aliases @@ -11515,13 +11554,13 @@ Do you want to apply to all existing midi tracks now? Status - + <unknown> - + <none> @@ -11545,7 +11584,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MarkerView - + MusE: Marker MuzA: Znacznik @@ -11618,7 +11657,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MasterEdit - + MusE: Mastertrack MuzA: Ślad Tempo/Metrum @@ -12141,7 +12180,7 @@ Apply sync settings? MusEGui::MidiTrackInfo - + <unknown> @@ -12184,7 +12223,7 @@ Apply sync settings? - + Und&o Co&fnij @@ -12334,13 +12373,13 @@ Apply sync settings? - - + + &Save &Zapisz - + 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. @@ -12370,7 +12409,7 @@ Można też wybrać "Zapisz" z menu plik, lub "Ctrl-S". - + Import Wave File Import Pliku &Wave @@ -12666,7 +12705,7 @@ Zgrywanie śladu (bounce) P&omoc - + Cannot read template Nie można odczytać pliku szablonu @@ -12687,13 +12726,13 @@ Zgrywanie śladu (bounce) - - + + MusE: Song: %1 - + MusE: load project MuzA: ładuj utwór @@ -12716,17 +12755,17 @@ Zapisać otwarty utwór? - + S&kip - + &Cancel - + MusE: Save As MuzA: Zapisz Jako @@ -12738,7 +12777,7 @@ Zapisać otwarty utwór? Nie ma nic do edytowania - + @@ -12806,7 +12845,7 @@ Zapisać otwarty utwór? - + &Abort &Anuluj @@ -12870,7 +12909,7 @@ failed: - + Import part is only valid for midi and wave tracks! @@ -12969,7 +13008,7 @@ Do you still want to import it? Nie można skopiować/przenieść/sklonować do innego typu śladu - + C&ut @@ -13047,7 +13086,7 @@ Files: - + %n part(s) out of %1 could not be pasted. Likely the selected track is the wrong type. @@ -13140,7 +13179,7 @@ Likely the selected track is the wrong type. MusEGui::PianoRoll - + &Edit @@ -13343,7 +13382,7 @@ Likely the selected track is the wrong type. MusEGui::PluginDialog - + MusE: select plugin MuzA: wybierz wtyczkę @@ -13485,32 +13524,32 @@ Likely the selected track is the wrong type. MusEGui::RoutePopupMenu - + - + - - + + Channel - - + + Soloing chain - - + + Audio returns - + Warning: No input devices! @@ -13520,7 +13559,7 @@ Likely the selected track is the wrong type. - + <none> @@ -13549,7 +13588,7 @@ Likely the selected track is the wrong type. MusEGui::ScoreCanvas - + Treble @@ -13569,7 +13608,7 @@ Likely the selected track is the wrong type. - + Ambiguous part @@ -13592,7 +13631,7 @@ Likely the selected track is the wrong type. MusEGui::ScoreEdit - + Undo/Redo tools @@ -13632,20 +13671,20 @@ Likely the selected track is the wrong type. - + - + Apply to new notes: - - + + Apply to selected notes: - + Velocity: @@ -13665,7 +13704,7 @@ Likely the selected track is the wrong type. - + Pixels per whole: @@ -13815,7 +13854,7 @@ Likely the selected track is the wrong type. - + Set up &preamble @@ -13835,7 +13874,7 @@ Likely the selected track is the wrong type. - + Enter the new score title @@ -13901,6 +13940,14 @@ the selected title is not unique oś metrum + + MusEGui::Strip + + + Remove track? + + + MusEGui::TList @@ -14035,7 +14082,7 @@ the selected title is not unique MusEGui::Toolbar1 - + Off @@ -14075,7 +14122,7 @@ the selected title is not unique - + Piano roll @@ -14333,7 +14380,7 @@ the selected title is not unique MusEGui::VisibleTracks - + Show wave tracks @@ -15707,11 +15754,6 @@ currently not used QObject - - - Other - - @@ -15745,7 +15787,7 @@ currently not used nowy - + create peakfile for stwórz plik szczytu dla @@ -15845,8 +15887,8 @@ failed: MuzA: Otwórz plik - - + + None Brak @@ -16889,12 +16931,11 @@ Losowy Generator Rytmu jeszcze nie jest udostępniony! SynthConfigBase - MusE: Synth Configuration - MuzA: Konfiguracja Syntezatora Softowego + MuzA: Konfiguracja Syntezatora Softowego - + Soft Synthesizer Syntezator Softowy @@ -16904,18 +16945,18 @@ Losowy Generator Rytmu jeszcze nie jest udostępniony! Plik - + Instances Urządzenia - + Name Nazwa - + list of available software synthesizers lista wszystkich dostępnych syntezatorów softowych @@ -16935,12 +16976,23 @@ Losowy Generator Rytmu jeszcze nie jest udostępniony! Port Midi - + + Midi Port and Soft Synth Configuration + + + + + + Type + Typ + + + Midi connections Połączenia midi - + Inst Instr. diff --git a/muse2/share/locale/muse_ru.ts b/muse2/share/locale/muse_ru.ts index eb103ae5..4510daa7 100644 --- a/muse2/share/locale/muse_ru.ts +++ b/muse2/share/locale/muse_ru.ts @@ -204,22 +204,22 @@ click on part to mute/unmute Все файлы (*) - + Add Midi Track Добавить Midi Трек - + Add Drum Track Добавить трек с ударными - + Add Wave Track Добавить wave-трек - + Add Audio Output Добавить аудиовыход @@ -255,7 +255,7 @@ click on part to mute/unmute FST - + Add Synth Добавить синтезатор @@ -5474,7 +5474,22 @@ left button behave like the middle button in such areas. - + + Allow adding hidden tracks in track list menu + + + + + Unhide tracks when adding hidden tracks + + + + + GUI Style + + + + MDI-subwindowness and sharing menus @@ -5514,7 +5529,7 @@ left button behave like the middle button in such areas. &Отмена - + Audio Аудио @@ -5640,16 +5655,15 @@ left button behave like the middle button in such areas. (тиков/в сек) - GUI - ГИП + ГИП Help Browser: В чём читать справку: - + GUI Refresh Rate Частота обновления ГИП @@ -6030,7 +6044,12 @@ Adjusts responsiveness of audio controls and - + + GUI Behaviour + + + + Use old-style stop shortcut: Использовать старую "горячую клавишу" для остановки: @@ -8268,6 +8287,11 @@ Enabled inputs in the list will Send sync delay Посылать синхр. задержку + + + Note: Sync delay and MTC sync currently not fully implemeted + + MidiTrackInfo @@ -10834,7 +10858,7 @@ Likely the selected track is the wrong type. MusECore::Song - + Jack shutdown! Jack прекратил работу! @@ -10932,7 +10956,7 @@ click on the Restart button. - + MusE - external script failed MusE - ошибка запуска внешнего скрипта @@ -11323,7 +11347,7 @@ Right-click to show GUI. транспорт - + C&ut &Вырезать @@ -11429,12 +11453,12 @@ Right-click to show GUI. - all parts in one staff + all tracks in one staff - one staff per part + one staff per track @@ -11493,6 +11517,21 @@ Right-click to show GUI. Global Split Глобальное разделение + + + Global Cut - selected tracks + + + + + Global Insert - selected tracks + + + + + Global Split - selected tracks + + &Edit @@ -11504,7 +11543,7 @@ Right-click to show GUI. &Структура - + Functions @@ -11564,7 +11603,7 @@ Right-click to show GUI. - + New Новый @@ -11631,7 +11670,7 @@ Right-click to show GUI. MusEGui::AudioStrip - + panorama панорама @@ -11661,7 +11700,7 @@ Right-click to show GUI. пре федер - пост федер - + dB @@ -11790,7 +11829,7 @@ Right-click to show GUI. MusEGui::ClipListEdit - + MusE: Clip List Editor MusE: Редактор списка фрагментов @@ -11904,7 +11943,7 @@ Right-click to show GUI. MusEGui::DrumEdit - + mute instrument заглушить инструмент @@ -12260,7 +12299,7 @@ Right-click to show GUI. LV4 - + Muse: Load Drum Map Muse: Загрузить драм-карту @@ -12733,7 +12772,7 @@ click on part to mute/unmute MusEGui::GlobalSettingsConfig - + Selects instruments directory @@ -12749,7 +12788,7 @@ click on part to mute/unmute MusEGui::LMaster - + MusE: Mastertrack MusE: Мастер-трек @@ -12864,7 +12903,7 @@ click on part to mute/unmute Значение - + Reposition of the initial tempo and signature events is not allowed Изменение начального темпа и размера запрещено @@ -12887,7 +12926,7 @@ click on part to mute/unmute MusEGui::ListEdit - + insert Note вставить Ноту @@ -13051,18 +13090,18 @@ Do you want to apply to all existing midi tracks now? - + in в - - + + out вне (из) - + Show first aliases Показать первые псевдонимы @@ -13268,13 +13307,13 @@ Do you want to apply to all existing midi tracks now? Состояние - + <unknown> <неизвестно> - + <none> <ничего> @@ -13298,7 +13337,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MarkerView - + MusE: Marker MusE: Маркер @@ -13371,7 +13410,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MasterEdit - + MusE: Mastertrack MusE: Мастер-трек @@ -13924,7 +13963,7 @@ Apply sync settings? MusEGui::MidiTrackInfo - + <unknown> <неизвестно> @@ -13969,7 +14008,7 @@ Apply sync settings? - + Und&o &Отменить действие @@ -14118,13 +14157,13 @@ Apply sync settings? - - + + &Save &Сохранить - + 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. @@ -14153,7 +14192,7 @@ You can also select the Save command from the File menu. - + Import Wave File Импортировать WAV-файл @@ -14448,7 +14487,7 @@ You can also select the Save command from the File menu. - + Cannot read template Не могу прочитать шаблон @@ -14469,13 +14508,13 @@ You can also select the Save command from the File menu. - - + + MusE: Song: %1 - + MusE: load project MusE: Открыть проект @@ -14498,17 +14537,17 @@ Save Current Project? - + S&kip - + &Cancel - + MusE: Save As MusE: Сохранить как @@ -14520,7 +14559,7 @@ Save Current Project? Нечего редактировать - + @@ -14590,7 +14629,7 @@ Save Current Project? - + &Abort &Отмена @@ -14658,7 +14697,7 @@ failed: не удалось: - + Import part is only valid for midi and wave tracks! Импортирование партий допустимо только для midi и wave треков! @@ -14759,7 +14798,7 @@ Do you still want to import it? Невозможно копировать/перемещать/клонировать данные в другие типы дорожек - + C&ut &Вырезать @@ -14837,7 +14876,7 @@ Files: - + %n part(s) out of %1 could not be pasted. Likely the selected track is the wrong type. @@ -14930,7 +14969,7 @@ Likely the selected track is the wrong type. MusEGui::PianoRoll - + &Edit &Правка @@ -15133,7 +15172,7 @@ Likely the selected track is the wrong type. MusEGui::PluginDialog - + MusE: select plugin MusE: выбрать плагин @@ -15275,32 +15314,32 @@ Likely the selected track is the wrong type. MusEGui::RoutePopupMenu - + - + - - + + Channel Канал - - + + Soloing chain - - + + Audio returns - + Warning: No input devices! @@ -15310,7 +15349,7 @@ Likely the selected track is the wrong type. - + <none> <ничего> @@ -15339,7 +15378,7 @@ Likely the selected track is the wrong type. MusEGui::ScoreCanvas - + Treble @@ -15359,7 +15398,7 @@ Likely the selected track is the wrong type. - + Ambiguous part @@ -15382,7 +15421,7 @@ Likely the selected track is the wrong type. MusEGui::ScoreEdit - + Undo/Redo tools @@ -15422,20 +15461,20 @@ Likely the selected track is the wrong type. - + - + Apply to new notes: - - + + Apply to selected notes: - + Velocity: @@ -15455,7 +15494,7 @@ Likely the selected track is the wrong type. - + Pixels per whole: @@ -15605,7 +15644,7 @@ Likely the selected track is the wrong type. - + Set up &preamble @@ -15625,7 +15664,7 @@ Likely the selected track is the wrong type. - + Enter the new score title @@ -15691,6 +15730,14 @@ the selected title is not unique шкала ключей + + MusEGui::Strip + + + Remove track? + + + MusEGui::TList @@ -15825,7 +15872,7 @@ the selected title is not unique MusEGui::Toolbar1 - + Off @@ -15865,7 +15912,7 @@ the selected title is not unique - + Piano roll @@ -16123,7 +16170,7 @@ the selected title is not unique MusEGui::VisibleTracks - + Show wave tracks @@ -18051,9 +18098,8 @@ currently not used QObject - Other - Другой + Другой @@ -18093,7 +18139,7 @@ currently not used новый - + create peakfile for создать пиковый файл для @@ -18197,8 +18243,8 @@ failed: MusE: Открыть файл - - + + None Ничего @@ -19406,12 +19452,11 @@ click on the Restart button. SynthConfigBase - MusE: Synth Configuration - MusE: Настройка програм. синт. + MusE: Настройка програм. синт. - + Soft Synthesizer Программный синтезатор @@ -19421,18 +19466,18 @@ click on the Restart button. Файл - + Instances Выбранный - + Name Имя - + list of available software synthesizers список доступных программных синтезаторов @@ -19457,7 +19502,18 @@ click on the Restart button. MIDI-порт - + + Midi Port and Soft Synth Configuration + + + + + + Type + Тип + + + Inst Инстр diff --git a/muse2/share/locale/muse_sv_SE.ts b/muse2/share/locale/muse_sv_SE.ts index 545ffd1e..0bf20ae7 100644 --- a/muse2/share/locale/muse_sv_SE.ts +++ b/muse2/share/locale/muse_sv_SE.ts @@ -206,22 +206,22 @@ klicka på en part för att Tysta/Avtysta Alla filer (*) - + Add Midi Track Lägg till Midispår - + Add Drum Track Lägg till Trumspår - + Add Wave Track Lägg till Wavespår - + Add Audio Output Lägg till Ljudutgång @@ -245,7 +245,7 @@ klicka på en part för att Tysta/Avtysta sudd - + Add Synth @@ -4880,7 +4880,22 @@ left button behave like the middle button in such areas. - + + Allow adding hidden tracks in track list menu + + + + + Unhide tracks when adding hidden tracks + + + + + GUI Style + + + + MDI-subwindowness and sharing menus @@ -4920,7 +4935,7 @@ left button behave like the middle button in such areas. &Avbryt - + Audio Ljud @@ -5041,17 +5056,12 @@ left button behave like the middle button in such areas. RTC-Upplösning (Tick/Sek) - - - GUI - - Help Browser: Hjälpläsare: - + GUI Refresh Rate GUI-uppdateringsfrekvens @@ -5391,7 +5401,12 @@ Adjusts responsiveness of audio controls and - + + GUI Behaviour + + + + Use old-style stop shortcut: @@ -7074,6 +7089,11 @@ Enabled inputs in the list will Send sync delay + + + Note: Sync delay and MTC sync currently not fully implemeted + + MidiTrackInfoBase @@ -9164,7 +9184,7 @@ misslyckades: MusECore::Song - + Jack shutdown! @@ -9247,7 +9267,7 @@ click on the Restart button. &Avbryt - + MusE - external script failed @@ -9622,7 +9642,7 @@ Right-click to show GUI. - + C&ut Klipp &ut @@ -9728,12 +9748,12 @@ Right-click to show GUI. - all parts in one staff + all tracks in one staff - one staff per part + one staff per track @@ -9792,6 +9812,21 @@ Right-click to show GUI. Global Split Global delning + + + Global Cut - selected tracks + + + + + Global Insert - selected tracks + + + + + Global Split - selected tracks + + &Edit @@ -9803,7 +9838,7 @@ Right-click to show GUI. &Struktur - + Functions Funktioner @@ -9863,7 +9898,7 @@ Right-click to show GUI. - + New Ny @@ -9930,7 +9965,7 @@ Right-click to show GUI. MusEGui::AudioStrip - + panorama @@ -9960,7 +9995,7 @@ Right-click to show GUI. - + dB @@ -10089,7 +10124,7 @@ Right-click to show GUI. MusEGui::ClipListEdit - + MusE: Clip List Editor MusE: Clip-listredigerare @@ -10203,7 +10238,7 @@ Right-click to show GUI. MusEGui::DrumEdit - + mute instrument tysta instrument @@ -10559,7 +10594,7 @@ Right-click to show GUI. - + Muse: Load Drum Map Muse: Ladda trummappning @@ -11032,7 +11067,7 @@ klicka på en part för att Tysta/Avtysta MusEGui::GlobalSettingsConfig - + Selects instruments directory @@ -11048,7 +11083,7 @@ klicka på en part för att Tysta/Avtysta MusEGui::LMaster - + MusE: Mastertrack MusE: Masterspår @@ -11163,7 +11198,7 @@ klicka på en part för att Tysta/Avtysta Värde - + Reposition of the initial tempo and signature events is not allowed Ompositionering av initalt tempo och/eller signaturevent är inte tillåtet @@ -11186,7 +11221,7 @@ klicka på en part för att Tysta/Avtysta MusEGui::ListEdit - + insert Note Mata in Not @@ -11350,18 +11385,18 @@ Do you want to apply to all existing midi tracks now? - + in - - + + out - + Show first aliases @@ -11559,13 +11594,13 @@ Do you want to apply to all existing midi tracks now? Status - + <unknown> - + <none> @@ -11589,7 +11624,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MarkerView - + MusE: Marker MusE: Markör @@ -11662,7 +11697,7 @@ Do you want to apply to all existing midi tracks now? MusEGui::MasterEdit - + MusE: Mastertrack MusE: Masterspår @@ -12185,7 +12220,7 @@ Apply sync settings? MusEGui::MidiTrackInfo - + <unknown> @@ -12228,7 +12263,7 @@ Apply sync settings? - + Und&o &Ångra @@ -12377,13 +12412,13 @@ Apply sync settings? - - + + &Save &Spara - + 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. @@ -12412,7 +12447,7 @@ Du kan också välja menyalternativet Spara från Arkivmenyn. - + Import Wave File Importera ljudfil @@ -12707,7 +12742,7 @@ Du kan också välja menyalternativet Spara från Arkivmenyn. &Hjälp - + Cannot read template Kan inte läsa mall @@ -12728,13 +12763,13 @@ Du kan också välja menyalternativet Spara från Arkivmenyn. - - + + MusE: Song: %1 - + MusE: load project MusE: Öppna projekt @@ -12757,17 +12792,17 @@ Spara nuvarande Projekt? - + S&kip - + &Cancel &Avbryt - + MusE: Save As MusE: Spara Som @@ -12779,7 +12814,7 @@ Spara nuvarande Projekt? Inget att redigera - + @@ -12847,7 +12882,7 @@ Spara nuvarande Projekt? - + &Abort &Avbryt @@ -12912,7 +12947,7 @@ failed: misslyckades: - + Import part is only valid for midi and wave tracks! @@ -13011,7 +13046,7 @@ Do you still want to import it? Kan inte kopiera/flytta/klona till annan Spårtyp - + C&ut Klipp &ut @@ -13089,7 +13124,7 @@ Files: - + %n part(s) out of %1 could not be pasted. Likely the selected track is the wrong type. @@ -13182,7 +13217,7 @@ Likely the selected track is the wrong type. MusEGui::PianoRoll - + &Edit &Redigera @@ -13385,7 +13420,7 @@ Likely the selected track is the wrong type. MusEGui::PluginDialog - + MusE: select plugin MusE: välj plugin @@ -13527,32 +13562,32 @@ Likely the selected track is the wrong type. MusEGui::RoutePopupMenu - + - + - - + + Channel Kanal - - + + Soloing chain - - + + Audio returns - + Warning: No input devices! @@ -13562,7 +13597,7 @@ Likely the selected track is the wrong type. - + <none> @@ -13591,7 +13626,7 @@ Likely the selected track is the wrong type. MusEGui::ScoreCanvas - + Treble @@ -13611,7 +13646,7 @@ Likely the selected track is the wrong type. - + Ambiguous part @@ -13634,7 +13669,7 @@ Likely the selected track is the wrong type. MusEGui::ScoreEdit - + Undo/Redo tools @@ -13674,20 +13709,20 @@ Likely the selected track is the wrong type. - + - + Apply to new notes: - - + + Apply to selected notes: - + Velocity: @@ -13707,7 +13742,7 @@ Likely the selected track is the wrong type. - + Pixels per whole: @@ -13857,7 +13892,7 @@ Likely the selected track is the wrong type. - + Set up &preamble @@ -13877,7 +13912,7 @@ Likely the selected track is the wrong type. - + Enter the new score title @@ -13943,6 +13978,14 @@ the selected title is not unique signaturskala + + MusEGui::Strip + + + Remove track? + + + MusEGui::TList @@ -14077,7 +14120,7 @@ the selected title is not unique MusEGui::Toolbar1 - + Off @@ -14117,7 +14160,7 @@ the selected title is not unique - + Piano roll @@ -14375,7 +14418,7 @@ the selected title is not unique MusEGui::VisibleTracks - + Show wave tracks @@ -15774,9 +15817,8 @@ används inte för tillfället QObject - Other - Andra + Andra @@ -15820,7 +15862,7 @@ används inte för tillfället ny - + create peakfile for skapa "peak"-fil @@ -15926,8 +15968,8 @@ misslyckades: MusE: Öppna fil - - + + None Ingen @@ -17135,12 +17177,11 @@ i MusEs lista över definierade controllers SynthConfigBase - MusE: Synth Configuration - MusE: Syntinställningar + MusE: Syntinställningar - + Soft Synthesizer Mjukvarusynt @@ -17150,18 +17191,18 @@ i MusEs lista över definierade controllers Arkiv - + Instances Instanser - + Name Namn - + list of available software synthesizers lista med tillgängliga mjukvarusyntar @@ -17181,12 +17222,23 @@ i MusEs lista över definierade controllers Midiport - + + Midi Port and Soft Synth Configuration + + + + + + Type + Typ + + + Midi connections Midikopplingar - + Inst diff --git a/muse2/share/templates/MusE.cfg b/muse2/share/templates/MusE.cfg index b95593d0..b64d9029 100644 --- a/muse2/share/templates/MusE.cfg +++ b/muse2/share/templates/MusE.cfg @@ -14,7 +14,6 @@ 44100 64 20 - /home/flo/.config/MusE/instruments 1 384 384 diff --git a/muse2/share/templates/audio.med b/muse2/share/templates/audio.med index 27a3a79f..df4463ff 100644 --- a/muse2/share/templates/audio.med +++ b/muse2/share/templates/audio.med @@ -9,13 +9,6 @@ 0 0 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 1 00:00:00:00:00 1 @@ -24,21 +17,10 @@ 0 0 0 - 0 - - + + 0 0 - - 1 - 418 600 - -
-1 9 8 7 6 5 4 3 2 1 0
-
- 0 - 266 - 0 -
2 @@ -292,68 +274,6 @@ - - 96 - 126 - 753 - - 934 - 488 - 000000ff00000000fd00000000000003ae0000019e00000004000000040000000800000008fc00000002000000020000000400000014004400720075006d00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000f5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000198ffffffff00000000000000000000000a00700061006e0069006301000002be000000f8000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a90000020d0000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c000000000000000000000014004400720075006d00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000181ffffffff000000000000000000000012007400720061006e00730070006f007200740100000224ffffffff00000000000000000000000a00700061006e00690063010000034a000000b6000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a9000002570000000000000000 - 0 - 1 - 0 - - - - 96 - 0 - - 852 - 460 - 000000ff00000000fd000000000000035c0000018200000004000000040000000800000008fc0000000200000002000000040000001e005000690061006e006f0072006f006c006c00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000ae00000098000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c000000f800000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002120000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e005000690061006e006f0072006f006c006c00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c0073010000013affffffff000000000000000000000012007400720061006e00730070006f0072007401000001bfffffffff00000000000000000000000a00700061006e0069006301000002e50000011b00000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002ae0000000000000000 - 0 - 1 - 0 - - - - - 867 - 544 - 000000ff00000000fd000000000000036b000001e300000004000000040000000800000008fc0000000200000002000000060000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c00730100000049ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000074ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000000dbffffffff000000000000000000000012007400720061006e00730070006f007200740100000203ffffffff00000000000000000000000a00700061006e006900630100000329000000420000000000000000000000020000000100000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000025900000004000000040000000800000008fc0000000200000002000000060000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c007301000000d5ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000100ffffffff000000000000000000000012007400720061006e00730070006f007200740100000167ffffffff00000000000000000000000a00700061006e00690063010000028d000001730000000000000000000000020000000200000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000002650000019b0000000000000000 - 0 - 1 - 0 - - - - 0 - - 784 - 544 - 000000ff00000000fd0000000000000318000001ce00000004000000040000000800000008fc0000000200000002000000040000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f0072007401000000b0ffffffff00000000000000000000000a00700061006e0069006301000001d600000142000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000002bb0000000000000000 - 000000ff00000000fd00000000000004000000024500000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000d500000071000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c00000194000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000003a30000000000000000 - 0 - 1 - 0 - - - - - - 760 - 460 - 000000ff00000000fd0000000000000300000001ac00000004000000040000000800000008fc0000000100000002000000030000001e00570061007600650020006500640069007400200074006f006f006c00730100000000ffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f007200740100000184ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000027700000004000000040000000800000008fc0000000100000002000000040000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e00570061007600650020006500640069007400200074006f006f006c0073010000008cffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c007301000000d5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000210ffffffff0000000000000000 - 0 - 1 - 0 - - 1 @@ -444,6 +364,47 @@ 0 1 44100 + + Out 1 + 0 + 0 + 0 + 0 + 2 + 20 + 1 + 1 + 0 + 0 + 0 + + + + + + + + + Input 1 + 0 + 1 + 0 + 0 + 2 + 20 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + Track 1 0 @@ -453,13 +414,12 @@ 1 20 0 - 1 0 0 - 1 + 0 0 0 - + @@ -477,10 +437,10 @@ 1 0 0 - 1 + 0 0 0 - + @@ -498,10 +458,10 @@ 0 0 0 - 1 + 0 0 0 - + @@ -519,10 +479,10 @@ 0 0 0 - 1 + 0 0 0 - + @@ -540,10 +500,10 @@ 1 0 0 - 1 + 0 0 0 - + @@ -561,10 +521,10 @@ 0 0 0 - 1 + 0 0 0 - + @@ -582,8 +542,8 @@ 1 0 0 - 1 - + 0 + @@ -601,54 +561,70 @@ 1 0 0 - 1 - + 0 + - - Input 1 - 0 - 1 - 0 - 0 - 2 - 20 - 1 - 0 - 0 - 1 - 0 - 0 - - - - - - - - - Out 1 - 0 - 0 - 0 - 0 - 2 - 20 - 1 - 0 - 0 - 1 - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 @@ -675,11 +651,24 @@ 1 - 01d9d0cb000100000000000000000000000003ff000002440000000000000000fffffffefffffffe000000000200 + 0 + 0 + 850 + 382 1 000000ff00000000fd00000000000000000000000000000004000000040000000800000008fc00000000 1 + + 1 + 370 477 + +
7 9 8 6 5 4 3 2 1 0
+
+ 0 + 266 + 0 +
diff --git a/muse2/share/templates/default.med b/muse2/share/templates/default.med index af50ee89..49ccbc02 100644 --- a/muse2/share/templates/default.med +++ b/muse2/share/templates/default.med @@ -17,21 +17,8 @@ 0 0 0 - 0 - - 0 0 - - 1 - 418 600 - -
-1 9 8 7 6 5 4 3 2 1 0
-
- 0 - 266 - 0 -
2 @@ -285,68 +272,6 @@ - - 96 - 126 - 753 - - 934 - 488 - 000000ff00000000fd00000000000003ae0000019e00000004000000040000000800000008fc00000002000000020000000400000014004400720075006d00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000f5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000198ffffffff00000000000000000000000a00700061006e0069006301000002be000000f8000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a90000020d0000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c000000000000000000000014004400720075006d00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000181ffffffff000000000000000000000012007400720061006e00730070006f007200740100000224ffffffff00000000000000000000000a00700061006e00690063010000034a000000b6000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a9000002570000000000000000 - 0 - 1 - 0 - - - - 96 - 0 - - 852 - 460 - 000000ff00000000fd000000000000035c0000018200000004000000040000000800000008fc0000000200000002000000040000001e005000690061006e006f0072006f006c006c00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000ae00000098000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c000000f800000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002120000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e005000690061006e006f0072006f006c006c00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c0073010000013affffffff000000000000000000000012007400720061006e00730070006f0072007401000001bfffffffff00000000000000000000000a00700061006e0069006301000002e50000011b00000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002ae0000000000000000 - 0 - 1 - 0 - - - - - 867 - 544 - 000000ff00000000fd000000000000036b000001e300000004000000040000000800000008fc0000000200000002000000060000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c00730100000049ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000074ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000000dbffffffff000000000000000000000012007400720061006e00730070006f007200740100000203ffffffff00000000000000000000000a00700061006e006900630100000329000000420000000000000000000000020000000100000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000025900000004000000040000000800000008fc0000000200000002000000060000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c007301000000d5ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000100ffffffff000000000000000000000012007400720061006e00730070006f007200740100000167ffffffff00000000000000000000000a00700061006e00690063010000028d000001730000000000000000000000020000000200000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000002650000019b0000000000000000 - 0 - 1 - 0 - - - - 0 - - 784 - 544 - 000000ff00000000fd0000000000000318000001ce00000004000000040000000800000008fc0000000200000002000000040000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f0072007401000000b0ffffffff00000000000000000000000a00700061006e0069006301000001d600000142000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000002bb0000000000000000 - 000000ff00000000fd00000000000004000000024500000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000d500000071000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c00000194000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000003a30000000000000000 - 0 - 1 - 0 - - - - - - 760 - 460 - 000000ff00000000fd0000000000000300000001ac00000004000000040000000800000008fc0000000100000002000000030000001e00570061007600650020006500640069007400200074006f006f006c00730100000000ffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f007200740100000184ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000027700000004000000040000000800000008fc0000000100000002000000040000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e00570061007600650020006500640069007400200074006f006f006c0073010000008cffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c007301000000d5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000210ffffffff0000000000000000 - 0 - 1 - 0 - - 1 @@ -465,8 +390,6 @@ - - 0 @@ -493,11 +416,25 @@ 1 - 01d9d0cb000100000000000000000000000003ff000002440000000000000000000003ff00000244000000000000 + 0 + 0 + 850 + 382 1 000000ff00000000fd00000000000000000000000000000004000000040000000800000008fc00000000 1 + + 1 + 440 407 + +
7 9 8 6 5 4 3 2 1 0
+
+ 0 + 266 + 0 +
+ \ No newline at end of file diff --git a/muse2/share/templates/midiGM.med b/muse2/share/templates/midiGM.med index b2da48e4..54ec99a0 100644 --- a/muse2/share/templates/midiGM.med +++ b/muse2/share/templates/midiGM.med @@ -9,13 +9,6 @@ 0 0 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 1 00:00:00:00:00 1 @@ -24,21 +17,10 @@ 0 0 0 - 0 - - + + 0 0 - - 1 - 418 600 - -
-1 9 8 7 6 5 4 3 2 1 0
-
- 0 - 266 - 0 -
2 @@ -340,68 +322,6 @@ - - 96 - 126 - 753 - - 934 - 488 - 000000ff00000000fd00000000000003ae0000019e00000004000000040000000800000008fc00000002000000020000000400000014004400720075006d00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000f5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000198ffffffff00000000000000000000000a00700061006e0069006301000002be000000f8000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a90000020d0000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c000000000000000000000014004400720075006d00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000181ffffffff000000000000000000000012007400720061006e00730070006f007200740100000224ffffffff00000000000000000000000a00700061006e00690063010000034a000000b6000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a9000002570000000000000000 - 0 - 1 - 0 - - - - 96 - 0 - - 852 - 460 - 000000ff00000000fd000000000000035c0000018200000004000000040000000800000008fc0000000200000002000000040000001e005000690061006e006f0072006f006c006c00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000ae00000098000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c000000f800000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002120000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e005000690061006e006f0072006f006c006c00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c0073010000013affffffff000000000000000000000012007400720061006e00730070006f0072007401000001bfffffffff00000000000000000000000a00700061006e0069006301000002e50000011b00000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002ae0000000000000000 - 0 - 1 - 0 - - - - - 867 - 544 - 000000ff00000000fd000000000000036b000001e300000004000000040000000800000008fc0000000200000002000000060000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c00730100000049ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000074ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000000dbffffffff000000000000000000000012007400720061006e00730070006f007200740100000203ffffffff00000000000000000000000a00700061006e006900630100000329000000420000000000000000000000020000000100000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000025900000004000000040000000800000008fc0000000200000002000000060000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c007301000000d5ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000100ffffffff000000000000000000000012007400720061006e00730070006f007200740100000167ffffffff00000000000000000000000a00700061006e00690063010000028d000001730000000000000000000000020000000200000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000002650000019b0000000000000000 - 0 - 1 - 0 - - - - 0 - - 784 - 544 - 000000ff00000000fd0000000000000318000001ce00000004000000040000000800000008fc0000000200000002000000040000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f0072007401000000b0ffffffff00000000000000000000000a00700061006e0069006301000001d600000142000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000002bb0000000000000000 - 000000ff00000000fd00000000000004000000024500000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000d500000071000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c00000194000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000003a30000000000000000 - 0 - 1 - 0 - - - - - - 760 - 460 - 000000ff00000000fd0000000000000300000001ac00000004000000040000000800000008fc0000000100000002000000030000001e00570061007600650020006500640069007400200074006f006f006c00730100000000ffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f007200740100000184ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000027700000004000000040000000800000008fc0000000100000002000000040000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e00570061007600650020006500640069007400200074006f006f006c0073010000008cffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c007301000000d5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000210ffffffff0000000000000000 - 0 - 1 - 0 - - 1 @@ -644,11 +564,24 @@ 1 - 01d9d0cb000100000000000000000000000003ff000002440000000000000000000003ff00000244000000000000 + 0 + 0 + 850 + 382 1 000000ff00000000fd00000000000000000000000000000004000000040000000800000008fc00000000 1 + + 1 + 557 290 + +
7 9 8 6 5 4 3 2 1 0
+
+ 0 + 266 + 0 +
diff --git a/muse2/share/templates/monorecord.med b/muse2/share/templates/monorecord.med index dfcc2c78..4651a7eb 100644 --- a/muse2/share/templates/monorecord.med +++ b/muse2/share/templates/monorecord.med @@ -9,13 +9,6 @@ 0 0 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 1 00:00:00:00:00 1 @@ -24,21 +17,10 @@ 0 0 0 - 0 - - + + 0 0 - - 1 - 418 600 - -
-1 9 8 7 6 5 4 3 2 1 0
-
- 0 - 266 - 0 -
2 @@ -291,69 +273,400 @@
+ + generic midi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + generic midi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + generic midi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 96 - 126 - 753 - - 934 - 488 - 000000ff00000000fd00000000000003ae0000019e00000004000000040000000800000008fc00000002000000020000000400000014004400720075006d00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000f5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000198ffffffff00000000000000000000000a00700061006e0069006301000002be000000f8000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a90000020d0000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c000000000000000000000014004400720075006d00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000181ffffffff000000000000000000000012007400720061006e00730070006f007200740100000224ffffffff00000000000000000000000a00700061006e00690063010000034a000000b6000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a9000002570000000000000000 - 0 - 1 - 0 - - - - 96 - 0 - - 852 - 460 - 000000ff00000000fd000000000000035c0000018200000004000000040000000800000008fc0000000200000002000000040000001e005000690061006e006f0072006f006c006c00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000ae00000098000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c000000f800000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002120000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e005000690061006e006f0072006f006c006c00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c0073010000013affffffff000000000000000000000012007400720061006e00730070006f0072007401000001bfffffffff00000000000000000000000a00700061006e0069006301000002e50000011b00000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002ae0000000000000000 - 0 - 1 - 0 - - - - - 867 - 544 - 000000ff00000000fd000000000000036b000001e300000004000000040000000800000008fc0000000200000002000000060000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c00730100000049ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000074ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000000dbffffffff000000000000000000000012007400720061006e00730070006f007200740100000203ffffffff00000000000000000000000a00700061006e006900630100000329000000420000000000000000000000020000000100000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000025900000004000000040000000800000008fc0000000200000002000000060000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c007301000000d5ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000100ffffffff000000000000000000000012007400720061006e00730070006f007200740100000167ffffffff00000000000000000000000a00700061006e00690063010000028d000001730000000000000000000000020000000200000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000002650000019b0000000000000000 - 0 - 1 - 0 - - - - 0 - - 784 - 544 - 000000ff00000000fd0000000000000318000001ce00000004000000040000000800000008fc0000000200000002000000040000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f0072007401000000b0ffffffff00000000000000000000000a00700061006e0069006301000001d600000142000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000002bb0000000000000000 - 000000ff00000000fd00000000000004000000024500000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000d500000071000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c00000194000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000003a30000000000000000 - 0 - 1 - 0 - - - - - - 760 - 460 - 000000ff00000000fd0000000000000300000001ac00000004000000040000000800000008fc0000000100000002000000030000001e00570061007600650020006500640069007400200074006f006f006c00730100000000ffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f007200740100000184ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000027700000004000000040000000800000008fc0000000100000002000000040000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e00570061007600650020006500640069007400200074006f006f006c0073010000008cffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c007301000000d5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000210ffffffff0000000000000000 - 0 - 1 - 0 - - 1 @@ -444,15 +757,15 @@ 0 1 44100 - - Track 1 - 1 + + Out 1 + 0 0 0 0 1 20 - 0 + 1 0 0 0 @@ -462,7 +775,7 @@
-
+ Input 1 0 @@ -472,7 +785,6 @@ 1 20 1 - 1 0 0 0 @@ -483,33 +795,42 @@ - - Out 1 - 0 + + Track 1 + 1 0 0 0 1 20 - 1 + 0 + 1 0 0 0 - + - - - - + + + + + + + + + + + + 0 @@ -536,11 +857,24 @@ 1 - 01d9d0cb000100000000000000000000000003ff000002440000000000000000000003ff00000244000000000000 + 0 + 0 + 850 + 382 1 000000ff00000000fd00000000000000000000000000000004000000040000000800000008fc00000000 1 + + 1 + 557 290 + +
7 9 8 6 5 4 3 2 1 0
+
+ 0 + 266 + 0 +
diff --git a/muse2/share/templates/synti.med b/muse2/share/templates/synti.med index 1198359c..e242e775 100644 --- a/muse2/share/templates/synti.med +++ b/muse2/share/templates/synti.med @@ -9,13 +9,6 @@ 0 0 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 1 00:00:00:00:00 1 @@ -24,21 +17,10 @@ 0 0 0 - 0 - - + + 0 0 - - 1 - 418 600 - -
-1 9 8 7 6 5 4 3 2 1 0
-
- 0 - 266 - 0 -
2 @@ -430,7 +412,7 @@ - General Midi + generic midi @@ -695,68 +677,6 @@ - - 96 - 126 - 753 - - 934 - 488 - 000000ff00000000fd00000000000003ae0000019e00000004000000040000000800000008fc00000002000000020000000400000014004400720075006d00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000f5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000198ffffffff00000000000000000000000a00700061006e0069006301000002be000000f8000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a90000020d0000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c000000000000000000000014004400720075006d00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000181ffffffff000000000000000000000012007400720061006e00730070006f007200740100000224ffffffff00000000000000000000000a00700061006e00690063010000034a000000b6000000000000000000000002000000030000000c0063007500720073006f00720100000000ffffffff0000000000000000000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000081ffffffff000000000000000000000012004e006f0074006500200049006e0066006f01000001a9000002570000000000000000 - 0 - 1 - 0 - - - - 96 - 0 - - 852 - 460 - 000000ff00000000fd000000000000035c0000018200000004000000040000000800000008fc0000000200000002000000040000001e005000690061006e006f0072006f006c006c00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000ae00000098000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c000000f800000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002120000000000000000 - 000000ff00000000fd00000000000004000000024d00000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e005000690061006e006f0072006f006c006c00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c0073010000013affffffff000000000000000000000012007400720061006e00730070006f0072007401000001bfffffffff00000000000000000000000a00700061006e0069006301000002e50000011b00000000000000000000000200000002000000260050006f0073002f0053006e00610070002f0053006f006c006f002d0074006f006f006c00730100000000ffffffff000000000000000000000012004e006f0074006500200049006e0066006f0100000152000002ae0000000000000000 - 0 - 1 - 0 - - - - - 867 - 544 - 000000ff00000000fd000000000000036b000001e300000004000000040000000800000008fc0000000200000002000000060000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c00730100000049ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000074ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000000dbffffffff000000000000000000000012007400720061006e00730070006f007200740100000203ffffffff00000000000000000000000a00700061006e006900630100000329000000420000000000000000000000020000000100000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000025900000004000000040000000800000008fc0000000200000002000000060000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff00000000000000000000002800530074006500700020007200650063006f007200640069006e006700200074006f006f006c007301000000d5ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000100ffffffff000000000000000000000012007400720061006e00730070006f007200740100000167ffffffff00000000000000000000000a00700061006e00690063010000028d000001730000000000000000000000020000000200000022004e006500770020006e006f00740065002000730065007400740069006e006700730100000000ffffffff00000000000000000000002a005100750061006e007400690073006100740069006f006e002000730065007400740069006e0067007301000002650000019b0000000000000000 - 0 - 1 - 0 - - - - 0 - - 784 - 544 - 000000ff00000000fd0000000000000318000001ce00000004000000040000000800000008fc0000000200000002000000040000001e0055006e0064006f002f005200650064006f00200074006f006f006c00730100000000ffffffff000000000000000000000014004500640069007400200054006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f0072007401000000b0ffffffff00000000000000000000000a00700061006e0069006301000001d600000142000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000002bb0000000000000000 - 000000ff00000000fd00000000000004000000024500000004000000040000000800000008fc0000000200000002000000050000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e0055006e0064006f002f005200650064006f00200074006f006f006c0073010000008cffffffff000000000000000000000014004500640069007400200054006f006f006c007301000000d500000071000000000000000000000012007400720061006e00730070006f007200740100000146ffffffff00000000000000000000000a00700061006e00690063010000026c00000194000000000000000000000002000000020000001a0045006e00610062006c00650020006d006100730074006500720100000000ffffffff0000000000000000000000080049006e0066006f010000005d000003a30000000000000000 - 0 - 1 - 0 - - - - - - 760 - 460 - 000000ff00000000fd0000000000000300000001ac00000004000000040000000800000008fc0000000100000002000000030000001e00570061007600650020006500640069007400200074006f006f006c00730100000000ffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c00730100000049ffffffff000000000000000000000012007400720061006e00730070006f007200740100000184ffffffff0000000000000000 - 000000ff00000000fd00000000000004000000027700000004000000040000000800000008fc0000000100000002000000040000001800460069006c006500200042007500740074006f006e007301000000000000008c00000000000000000000001e00570061007600650020006500640069007400200074006f006f006c0073010000008cffffffff00000000000000000000001c0057006100760065004500640069007400200074006f006f006c007301000000d5ffffffff000000000000000000000012007400720061006e00730070006f007200740100000210ffffffff0000000000000000 - 0 - 1 - 0 - - 1 @@ -830,7 +750,7 @@ 1 0 - 12288 + 0 0 0 1 @@ -847,6 +767,25 @@ 18432 1 44100 + + Out 1 + 0 + 0 + 0 + 0 + 2 + 20 + 0 + 0 + 0 + 0 + + + + + + + Track 1 0 @@ -856,6 +795,7 @@ 0 20 0 + 1 0 0 0 @@ -870,30 +810,10 @@ Track 1 - 1 + 0 0 - - Out 1 - 0 - 0 - 0 - 0 - 2 - 20 - 0 - 1 - 0 - 0 - 0 - - - - - - - fluid-1 0 @@ -906,12 +826,13 @@ 0 0 0 - + + MESS fluid 1 @@ -932,15 +853,16 @@ 0 - + + MESS organ 0 0 - + @@ -964,17 +886,18 @@ 0 0 0 - + + MESS vam 3 0 - + @@ -990,6 +913,14 @@ + + + + + + + + @@ -1044,11 +975,24 @@ 1 - 01d9d0cb000100000000000000000000000003ff000002440000000000000000000003ff00000244000000000000 + 0 + 0 + 850 + 382 1 000000ff00000000fd00000000000000000000000000000004000000040000000800000008fc00000000 1 + + 1 + 370 477 + +
7 9 8 6 5 4 3 2 1 0
+
+ 0 + 266 + 0 +
diff --git a/muse2/synti/fluid/CMakeLists.txt b/muse2/synti/fluid/CMakeLists.txt index 8109493b..3789a745 100644 --- a/muse2/synti/fluid/CMakeLists.txt +++ b/muse2/synti/fluid/CMakeLists.txt @@ -73,7 +73,6 @@ set (FILES_TO_TRANSLATE set_target_properties ( fluid PROPERTIES PREFIX "" COMPILE_FLAGS "-fvisibility=hidden -include ${PROJECT_BINARY_DIR}/all-pic.h" - # LINK_FLAGS "${FLUIDSYN_LDFLAGS}" # "-lfluidsynth" ) ## @@ -82,11 +81,6 @@ set_target_properties ( fluid target_link_libraries(fluid synti ${QT_LIBRARIES} - # Can't do this. FLUIDSYN_LIBRARIES = fluidsynth, which is the name - # of our fluidsynth.so shared synthesizer library. - # This caused ../fluidsynth/fluidsynth.so to appear in the link line. - # Nov 1, 2011. fluidsynth module renamed fluid_synth to avoid bizarre new conflict on Ubuntu 11.10, seems due to LINK_FLAGS line. - # Got undefined symbol fluid_synth_cc, in fluid, at startup at runtime. So we can enable this now. ${FLUIDSYN_LIBRARIES} ) diff --git a/muse2/synti/fluidsynth/CMakeLists.txt b/muse2/synti/fluidsynth/CMakeLists.txt index 0e9f90bb..8ac178be 100644 --- a/muse2/synti/fluidsynth/CMakeLists.txt +++ b/muse2/synti/fluidsynth/CMakeLists.txt @@ -54,8 +54,6 @@ file (GLOB fluidsynth_source_files ## ## Define target ## -# Nov 1, 2011. fluidsynth module renamed fluid_synth to avoid bizarre new conflict on Ubuntu 11.10, seems due to LINK_FLAGS line. -# Got undefined symbol fluid_synth_set_reverb at startup at runtime. add_library ( fluid_synth SHARED ${fluidsynth_source_files} ${fluidsynth_mocs} @@ -83,7 +81,6 @@ set (FILES_TO_TRANSLATE set_target_properties ( fluid_synth PROPERTIES PREFIX "" COMPILE_FLAGS "-fvisibility=hidden -include ${PROJECT_BINARY_DIR}/all-pic.h" - # LINK_FLAGS "${FLUIDSYN_LDFLAGS}" # "-lfluidsynth" ) ## @@ -92,9 +89,6 @@ set_target_properties ( fluid_synth target_link_libraries(fluid_synth synti ${QT_LIBRARIES} - # Can't do this here, since FLUIDSYN_LIBRARIES evaluates - # to 'fluidsynth', the same name as our target. - # Fixed Nov 1, 2011 ${FLUIDSYN_LIBRARIES} ) -- cgit v1.2.3