diff --git a/.mailmap b/.mailmap index 7628795f9..71b6697c8 100644 --- a/.mailmap +++ b/.mailmap @@ -26,3 +26,6 @@ Thomas Clark Thomas Clark anonymous Locale updater <> grejppi +Johannes Lorenz +Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> +Noah Brecht diff --git a/.travis.yml b/.travis.yml index 5cf25ac71..091e2cb45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,26 +6,35 @@ cache: directories: - apt_mingw_cache - $HOME/.ccache + - $HOME/pbuilder-bases matrix: include: - env: TYPE=style - os: linux - env: TARGET_OS=win32 - env: TARGET_OS=win64 + - env: TARGET_OS=debian-sid TARGET_DEPLOY=True + - env: TARGET_OS=debian-sid TARGET_ARCH=i386 + - compiler: clang + env: TARGET_OS=debian-sid - os: osx osx_image: xcode8.3 install: ${TRAVIS_BUILD_DIR}/.travis/install.sh script: ${TRAVIS_BUILD_DIR}/.travis/script.sh after_script: ${TRAVIS_BUILD_DIR}/.travis/after_script.sh -before_deploy: make package +before_deploy: + - if [ "$TARGET_OS" != debian-sid ]; then make package; fi deploy: provider: releases api_key: secure: d4a+x4Gugpss7JK2DcHjyBZDmEFFh4iVfKDfITSD50T6Mc6At4LMgojvEu+6qT6IyOY2vm3UVT6fhyeuWDTRDwW9tfFlaHVA0h8aTRD+eAXOA7pQ8rEMwQO3+WCKuKTfEqUkpL4wxhww8dpkv54tqeIs0S4TBqz9tk8UhzU7XbE= - file: lmms-${TRAVIS_TAG:1}-$TARGET_OS.exe + file_glob: true + file: + - lmms-${TRAVIS_TAG:1}-$TARGET_OS.exe + - /var/cache/pbuilder/result/lmms_*.tar.xz skip_cleanup: true on: tags: true all_branches: true - condition: '("$TARGET_OS" = win??)' + condition: '"$TARGET_DEPLOY" = True' repo: LMMS/lmms diff --git a/.travis/debian_pkgs.sha256 b/.travis/debian_pkgs.sha256 new file mode 100644 index 000000000..96a4bd8aa --- /dev/null +++ b/.travis/debian_pkgs.sha256 @@ -0,0 +1,2 @@ +314ef4af137903dfb13e8c3ef1e6ea56cfdb23808d52ec4f5f50e288c73610c5 pbuilder_0.229.1_all.deb +fa82aa8ed3055c6f6330104deedf080b26778295e589426d4c4dd0f2c2a5defa debootstrap_1.0.95_all.deb diff --git a/.travis/linux..script.sh b/.travis/linux..script.sh index 354f1a876..e75b827ac 100755 --- a/.travis/linux..script.sh +++ b/.travis/linux..script.sh @@ -5,5 +5,11 @@ source /opt/qt59/bin/qt59-env.sh set -e +mkdir build +cd build + # shellcheck disable=SC2086 cmake -DUSE_WERROR=ON -DCMAKE_INSTALL_PREFIX=../target $CMAKE_FLAGS .. +make -j4 +make tests +./tests/tests diff --git a/.travis/linux.debian-sid.before_install.sh b/.travis/linux.debian-sid.before_install.sh new file mode 100755 index 000000000..89ee51523 --- /dev/null +++ b/.travis/linux.debian-sid.before_install.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sudo apt-get update -qq diff --git a/.travis/linux.debian-sid.install.sh b/.travis/linux.debian-sid.install.sh new file mode 100755 index 000000000..ecdcf6d91 --- /dev/null +++ b/.travis/linux.debian-sid.install.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +sudo apt-get install -y \ + debian-archive-keyring \ + dpkg \ + pbuilder + +# work around a pbuilder bug which breaks ccache +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666525 +cd /tmp +wget http://archive.ubuntu.com/ubuntu/pool/main/p/pbuilder/pbuilder_0.229.1_all.deb +wget http://archive.ubuntu.com/ubuntu/pool/main/d/debootstrap/debootstrap_1.0.95_all.deb +sha256sum -c "$TRAVIS_BUILD_DIR/.travis/debian_pkgs.sha256" +sudo dpkg -i pbuilder_0.229.1_all.deb debootstrap_1.0.95_all.deb +cd "$OLDPWD" diff --git a/.travis/linux.debian-sid.script.sh b/.travis/linux.debian-sid.script.sh new file mode 100755 index 000000000..a75a9f844 --- /dev/null +++ b/.travis/linux.debian-sid.script.sh @@ -0,0 +1,41 @@ +#!/bin/sh +set -e + +: "${TARGET_ARCH:=amd64}" + +BASETGZ="$HOME/pbuilder-bases/debian-sid-$TARGET_ARCH.tgz" +MIRROR=http://cdn-fastly.deb.debian.org/debian +KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg + +if [ -z "$TRAVIS_TAG" ] +then + sudo \ + sh -c "echo CCACHEDIR=$HOME/.ccache >> /etc/pbuilderrc" +fi + +if [ "$CC" = clang ] +then + sudo sh -c "echo EXTRAPACKAGES=clang >> /etc/pbuilderrc" +fi + +if [ ! -e "$BASETGZ.stamp" ] +then + mkdir -p "$HOME/pbuilder-bases" + # debootstrap fails to resolve dependencies which are virtual packages + # e.g. perl-openssl-abi-1.1 provided by perl-openssl-defaults, needed for building SWH + # See also: https://bugs.launchpad.net/ubuntu/+source/debootstrap/+bug/86536 + sudo pbuilder --create --basetgz "$BASETGZ" --mirror $MIRROR \ + --distribution sid --architecture $TARGET_ARCH \ + --debootstrapopts --variant=buildd \ + --debootstrapopts --keyring=$KEYRING \ + --debootstrapopts --include=perl,libxml2-utils,libxml-perl,liblist-moreutils-perl,perl-openssl-defaults + touch "$BASETGZ.stamp" +else + sudo pbuilder --update --basetgz "$BASETGZ" +fi + +DIR="$PWD" +cd .. +dpkg-source -b "$DIR" +env -i CC="$CC" CXX="$CXX" sudo pbuilder --build --debbuildopts "--jobs=auto" \ + --basetgz "$BASETGZ" ./*.dsc diff --git a/.travis/linux.win32.script.sh b/.travis/linux.win32.script.sh index d89cf1b75..6e930fd9b 100755 --- a/.travis/linux.win32.script.sh +++ b/.travis/linux.win32.script.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash - set -e +mkdir build +cd build + export CMAKE_OPTS="$CMAKE_FLAGS -DUSE_WERROR=ON" ../cmake/build_win32.sh + +make -j4 +make tests diff --git a/.travis/linux.win64.script.sh b/.travis/linux.win64.script.sh index 931e23d8d..d81fa9b58 100755 --- a/.travis/linux.win64.script.sh +++ b/.travis/linux.win64.script.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash - set -e +mkdir build +cd build + export CMAKE_OPTS="$CMAKE_FLAGS -DUSE_WERROR=ON" ../cmake/build_win64.sh + +make -j4 +make tests diff --git a/.travis/osx..script.sh b/.travis/osx..script.sh index 3253f4ed7..373e273f4 100755 --- a/.travis/osx..script.sh +++ b/.travis/osx..script.sh @@ -1,10 +1,16 @@ #!/usr/bin/env bash - set -e +mkdir build +cd build + # Workaround; No FindQt5.cmake module exists CMAKE_PREFIX_PATH="$(brew --prefix qt5)" export CMAKE_PREFIX_PATH # shellcheck disable=SC2086 cmake -DUSE_WERROR=OFF -DCMAKE_INSTALL_PREFIX=../target $CMAKE_FLAGS .. + +make -j4 +make tests +./tests/tests diff --git a/.travis/script.sh b/.travis/script.sh index 27e9ec7fb..70391a762 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -8,13 +8,11 @@ if [ "$TYPE" = 'style' ]; then # once it's fixed, it should be enabled again # shellcheck disable=SC2185 # shellcheck disable=SC2046 - shellcheck $(find -O3 "$TRAVIS_BUILD_DIR/.travis/" "$TRAVIS_BUILD_DIR/cmake/" -type f -name '*.sh' -o -name "*.sh.in") + shellcheck $(find -O3 . -maxdepth 3 -type f -name '*.sh' -o -name "*.sh.in") + shellcheck doc/bash-completion/lmms else - mkdir -p build - cd build - export CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=RelWithDebInfo" if [ -z "$TRAVIS_TAG" ]; then @@ -23,25 +21,21 @@ else "$TRAVIS_BUILD_DIR/.travis/$TRAVIS_OS_NAME.$TARGET_OS.script.sh" - make -j4 - make tests - - if [[ $TARGET_OS != win* ]]; then - tests/tests - fi - # Package and upload non-tagged builds if [ ! -z "$TRAVIS_TAG" ]; then # Skip, handled by travis deploy instead exit 0 elif [[ $TARGET_OS == win* ]]; then + cd build make -j4 package PACKAGE="$(ls lmms-*win*.exe)" elif [[ $TRAVIS_OS_NAME == osx ]]; then + cd build make -j4 install > /dev/null make dmg PACKAGE="$(ls lmms-*.dmg)" - else + elif [[ $TARGET_OS != debian-sid ]]; then + cd build make -j4 install > /dev/null make appimage PACKAGE="$(ls lmms-*.AppImage)" diff --git a/CMakeLists.txt b/CMakeLists.txt index 88aefadae..777245268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ INCLUDE(GenerateExportHeader) STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE) -SET(PROJECT_YEAR 2018) +SET(PROJECT_YEAR 2019) SET(PROJECT_AUTHOR "LMMS Developers") SET(PROJECT_URL "https://lmms.io") @@ -33,7 +33,7 @@ SET(PROJECT_COPYRIGHT "2008-${PROJECT_YEAR} ${PROJECT_AUTHOR}") SET(VERSION_MAJOR "1") SET(VERSION_MINOR "2") SET(VERSION_RELEASE "0") -SET(VERSION_STAGE "rc7") +SET(VERSION_STAGE "rc8") SET(VERSION_BUILD "0") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") IF(VERSION_STAGE) @@ -73,6 +73,8 @@ OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF) IF(LMMS_BUILD_APPLE) + # Fix linking on 10.14+. See issue #4762 on github + LINK_DIRECTORIES(/usr/local/lib) SET(WANT_ALSA OFF) SET(WANT_PULSEAUDIO OFF) SET(WANT_VST OFF) @@ -88,7 +90,6 @@ IF(LMMS_BUILD_WIN32) SET(WANT_ALSA OFF) SET(WANT_JACK OFF) SET(WANT_PULSEAUDIO OFF) - SET(WANT_PORTAUDIO OFF) SET(WANT_SNDIO OFF) SET(WANT_SOUNDIO OFF) SET(WANT_WINMM ON) @@ -96,7 +97,6 @@ IF(LMMS_BUILD_WIN32) SET(STATUS_ALSA "") SET(STATUS_JACK "") SET(STATUS_PULSEAUDIO "") - SET(STATUS_PORTAUDIO "") SET(STATUS_SOUNDIO "") SET(STATUS_WINMM "OK") SET(STATUS_APPLEMIDI "") diff --git a/cmake/linux/lmms.desktop b/cmake/linux/lmms.desktop index 0fb706a62..72a82da17 100644 --- a/cmake/linux/lmms.desktop +++ b/cmake/linux/lmms.desktop @@ -10,7 +10,7 @@ Comment[ca]=Producció fàcil de música per a tothom! Comment[fr]=Production facile de musique pour tout le monde ! Comment[pl]=Prosta produkcja muzyki dla każdego! Icon=lmms -Exec=env QT_X11_NO_NATIVE_MENUBAR=1 QT_AUTO_SCREEN_SCALE_FACTOR=1 lmms %f +Exec=lmms %f Terminal=false Type=Application Categories=Qt;AudioVideo;Audio;Midi; diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 7c3a4cf3b..2cefe73c6 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -187,10 +187,16 @@ rm -f "${APPDIR}/usr/lib/libwine.so.1" # Use system-provided carla rm -f "${APPDIR}usr/lib/"libcarla*.so -# Move jack out of LD_LIBRARY_PATH +# Remove bundled jack in LD_LIBRARY_PATH if exists if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then + rm "${APPDIR}/usr/lib/libjack.so.0" +fi + +# Bundle jack out of LD_LIBRARY_PATH +JACK_LIB=$(ldd "${APPDIR}/usr/bin/lmms.real" | sed -n 's/\tlibjack\.so\.0 => \(.\+\) (0x[0-9a-f]\+)/\1/p') +if [ -e "$JACK_LIB" ]; then mkdir -p "${APPDIR}usr/lib/lmms/optional/" - mv "${APPDIR}/usr/lib/libjack.so.0" "${APPDIR}usr/lib/lmms/optional/" + cp "$JACK_LIB" "${APPDIR}usr/lib/lmms/optional/" fi # Point the AppRun to the shim launcher diff --git a/cmake/modules/BashCompletion.cmake b/cmake/modules/BashCompletion.cmake index 0dc016178..c3916f201 100644 --- a/cmake/modules/BashCompletion.cmake +++ b/cmake/modules/BashCompletion.cmake @@ -73,9 +73,10 @@ ELSE() FILE(WRITE ${BASHCOMP_SCRIPT} "\ #!${BASH}\n\ set -e\n\ -BASHCOMP_PKG_PATH=\"${BASHCOMP_USER_PATH}\"\n\ if [ -w \"${BASHCOMP_PKG_PATH}\" ]; then\n\ BASHCOMP_PKG_PATH=\"${BASHCOMP_PKG_PATH}\"\n\ +else \n\ + BASHCOMP_PKG_PATH=\"\$DESTDIR${BASHCOMP_USER_PATH}\"\n\ fi\n\ echo -e \"\\nInstalling bash completion...\\n\"\n\ mkdir -p \"\$BASHCOMP_PKG_PATH\"\n\ diff --git a/cmake/modules/CheckSubmodules.cmake b/cmake/modules/CheckSubmodules.cmake index 38717f18e..65e5be08b 100644 --- a/cmake/modules/CheckSubmodules.cmake +++ b/cmake/modules/CheckSubmodules.cmake @@ -27,6 +27,12 @@ SET(DEPTH_VALUE 100) SET(MAX_ATTEMPTS 2) MESSAGE("\nValidating submodules...") +IF(NOT EXISTS "${CMAKE_SOURCE_DIR}/.gitmodules") + MESSAGE("Skipping the check because .gitmodules not detected." + "Please make sure you have all submodules in the source tree!" + ) + RETURN() +ENDIF() FILE(READ "${CMAKE_SOURCE_DIR}/.gitmodules" SUBMODULE_DATA) # Force English locale diff --git a/data/locale/en.ts b/data/locale/en.ts index 253bf4a57..2bc3ade23 100644 --- a/data/locale/en.ts +++ b/data/locale/en.ts @@ -153,105 +153,55 @@ If you're interested in translating LMMS in another language or want to imp AudioFileProcessorView - Open other sample + Open sample - - Click here, if you want to open another audio-file. A dialog will appear where you can select your file. Settings like looping-mode, start and end-points, amplify-value, and so on are not reset. So, it may not sound like the original sample. - - - - + Reverse sample - - If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. - - - - + Disable loop - - This button disables looping. The sample plays only once from start to end. - - - - - + + Enable loop - - This button enables forwards-looping. The sample loops between the end point and the loop point. - - - - - This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. - - - - + Continue sample playback across notes - - Enabling this option makes the sample continue playing across different notes - if you change pitch, or the note length stops before the end of the sample, then the next note played will continue where it left off. To reset the playback to the start of the sample, insert a note at the bottom of the keyboard (< 20 Hz) - - - - + Amplify: - - With this knob you can set the amplify ratio. When you set a value of 100% your sample isn't changed. Otherwise it will be amplified up or down (your actual sample-file isn't touched!) + + Start point: - - Startpoint: + + End point: - - With this knob you can set the point where AudioFileProcessor should begin playing your sample. - - - - - Endpoint: - - - - - With this knob you can set the point where AudioFileProcessor should stop playing your sample. - - - - + Loopback point: - - - With this knob you can set the point where the loop starts. - - AudioFileProcessorWaveView - + Sample length: @@ -279,18 +229,18 @@ If you're interested in translating LMMS in another language or want to imp - + CLIENT-NAME - + CHANNELS - AudioOss::setupWidget + AudioOss DEVICE @@ -305,25 +255,25 @@ If you're interested in translating LMMS in another language or want to imp AudioPortAudio::setupWidget - + BACKEND - + DEVICE - AudioPulseAudio::setupWidget + AudioPulseAudio - + DEVICE - + CHANNELS @@ -331,13 +281,13 @@ If you're interested in translating LMMS in another language or want to imp AudioSdl::setupWidget - + DEVICE - AudioSndio::setupWidget + AudioSndio DEVICE @@ -352,12 +302,12 @@ If you're interested in translating LMMS in another language or want to imp AudioSoundIo::setupWidget - + BACKEND - + DEVICE @@ -365,62 +315,62 @@ If you're interested in translating LMMS in another language or want to imp AutomatableModel - + &Reset (%1%2) - + &Copy value (%1%2) - + &Paste value (%1%2) - + &Paste value - + Edit song-global automation - + Remove song-global automation - + Remove all linked controls - + Connected to %1 - + Connected to controller - + Edit connection... - + Remove connection - + Connect to controller... @@ -428,17 +378,17 @@ If you're interested in translating LMMS in another language or want to imp AutomationEditor - + Please open an automation pattern with the context menu of a control! - + Values copied - + All selected values were copied to the clipboard. @@ -446,184 +396,124 @@ If you're interested in translating LMMS in another language or want to imp AutomationEditorWindow - + Play/pause current pattern (Space) - - Click here if you want to play the current pattern. This is useful while editing it. The pattern is automatically looped when the end is reached. - - - - + Stop playing of current pattern (Space) - - Click here if you want to stop playing of the current pattern. - - - - + Edit actions - + Draw mode (Shift+D) - + Erase mode (Shift+E) - + Flip vertically - + Flip horizontally - - Click here and the pattern will be inverted.The points are flipped in the y direction. - - - - - Click here and the pattern will be reversed. The points are flipped in the x direction. - - - - - Click here and draw-mode will be activated. In this mode you can add and move single values. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. - - - - - Click here and erase-mode will be activated. In this mode you can erase single values. You can also press 'Shift+E' on your keyboard to activate this mode. - - - - + Interpolation controls - + Discrete progression - + Linear progression - + Cubic Hermite progression - + Tension value for spline - - A higher tension value may make a smoother curve but overshoot some values. A low tension value will cause the slope of the curve to level off at each control point. - - - - - Click here to choose discrete progressions for this automation pattern. The value of the connected object will remain constant between control points and be set immediately to the new value when each control point is reached. - - - - - Click here to choose linear progressions for this automation pattern. The value of the connected object will change at a steady rate over time between control points to reach the correct value at each control point without a sudden change. - - - - - Click here to choose cubic hermite progressions for this automation pattern. The value of the connected object will change in a smooth curve and ease in to the peaks and valleys. - - - - + Tension: - + Cut selected values (%1+X) - + Copy selected values (%1+C) - + Paste values from clipboard (%1+V) - - Click here and selected values will be cut into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - - - - - Click here and selected values will be copied into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - - - - - Click here and the values from the clipboard will be pasted at the first visible measure. - - - - + Zoom controls - + + Horizontal zooming + + + + + Vertical zooming + + + + Quantization controls - + Quantization - - Quantization. Sets the smallest step size for the Automation Point. By default this also sets the length, clearing out other points in the range. Press <Ctrl> to override this behaviour. - - - - - + + Automation Editor - no pattern - - + + Automation Editor - %1 - + Model is already connected to this pattern. @@ -631,7 +521,7 @@ If you're interested in translating LMMS in another language or want to imp AutomationPattern - + Drag a control while pressing <%1> @@ -715,52 +605,42 @@ If you're interested in translating LMMS in another language or want to imp - - Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. - - - - - Click here to stop playing of current beat/bassline. - - - - + Beat selector - + Track and step actions - + Add beat/bassline - + Add sample-track - + Add automation-track - + Remove steps - + Add steps - + Clone Steps @@ -768,27 +648,27 @@ If you're interested in translating LMMS in another language or want to imp BBTCOView - + Open in Beat+Bassline-Editor - + Reset name - + Change name - + Change color - + Reset color to default @@ -796,12 +676,12 @@ If you're interested in translating LMMS in another language or want to imp BBTrack - + Beat/Bassline %1 - + Clone of %1 @@ -877,7 +757,7 @@ If you're interested in translating LMMS in another language or want to imp - Input Gain: + Input gain: @@ -887,12 +767,12 @@ If you're interested in translating LMMS in another language or want to imp - Input Noise: + Input noise: - Output Gain: + Output gain: @@ -902,27 +782,27 @@ If you're interested in translating LMMS in another language or want to imp - Output Clip: + Output clip: - Rate Enabled + Rate enabled - Enable samplerate-crushing + Enable sample-rate crushing - Depth Enabled + Depth enabled - Enable bitdepth-crushing + Enable bit-depth crushing @@ -957,30 +837,60 @@ If you're interested in translating LMMS in another language or want to imp - CaptionMenu + BitcrushControls - - &Help + + Input gain - - Help (not available) + + Input noise + + + + + Output gain + + + + + Output clip + + + + + Sample rate + + + + + Stereo difference + + + + + Levels + + + + + Rate enabled + + + + + Depth enabled CarlaInstrumentView - + Show GUI - - - Click here to show or hide the graphical user interface (GUI) of Carla. - - Controller @@ -1039,27 +949,27 @@ If you're interested in translating LMMS in another language or want to imp - + MAPPING FUNCTION - + OK - + Cancel - + LMMS - + Cycle Detected. @@ -1090,37 +1000,32 @@ If you're interested in translating LMMS in another language or want to imp ControllerView - + Controls - - Controllers are able to automate the value of a knob, slider, and other controls. - - - - + Rename controller - + Enter the new name for this controller - + LFO - + &Remove this controller - + Re&name this controller @@ -1129,77 +1034,97 @@ If you're interested in translating LMMS in another language or want to imp CrossoverEQControlDialog - Band 1/2 Crossover: + Band 1/2 crossover: - Band 2/3 Crossover: + Band 2/3 crossover: - Band 3/4 Crossover: + Band 3/4 crossover: + + + + + Band 1 gain - Band 1 Gain: + Band 1 gain: + + + + + Band 2 gain - Band 2 Gain: + Band 2 gain: + + + + + Band 3 gain - Band 3 Gain: + Band 3 gain: + + + + + Band 4 gain - Band 4 Gain: + Band 4 gain: - Band 1 Mute + Band 1 mute - Mute Band 1 + Mute band 1 - Band 2 Mute + Band 2 mute - Mute Band 2 + Mute band 2 - Band 3 Mute + Band 3 mute - Mute Band 3 + Mute band 3 - Band 4 Mute + Band 4 mute - Mute Band 4 + Mute band 4 @@ -1207,7 +1132,7 @@ If you're interested in translating LMMS in another language or want to imp DelayControls - Delay Samples + Delay samples @@ -1217,12 +1142,12 @@ If you're interested in translating LMMS in another language or want to imp - Lfo Frequency + LFO frequency - Lfo Amount + LFO amount @@ -1240,7 +1165,7 @@ If you're interested in translating LMMS in another language or want to imp - Delay Time + Delay time @@ -1250,7 +1175,7 @@ If you're interested in translating LMMS in another language or want to imp - Feedback Amount + Feedback amount @@ -1260,7 +1185,7 @@ If you're interested in translating LMMS in another language or want to imp - Lfo + LFO frequency @@ -1270,12 +1195,12 @@ If you're interested in translating LMMS in another language or want to imp - Lfo Amt + LFO amount - Out Gain + Out gain @@ -1344,12 +1269,12 @@ If you're interested in translating LMMS in another language or want to imp - Click to enable/disable Filter 1 + Enable/disable filter 1 - Click to enable/disable Filter 2 + Enable/disable filter 2 @@ -1367,7 +1292,7 @@ If you're interested in translating LMMS in another language or want to imp - Cutoff 1 frequency + Cutoff frequency 1 @@ -1397,7 +1322,7 @@ If you're interested in translating LMMS in another language or want to imp - Cutoff 2 frequency + Cutoff frequency 2 @@ -1413,25 +1338,25 @@ If you're interested in translating LMMS in another language or want to imp - LowPass + Low-pass - HiPass + Hi-pass - BandPass csg + Band-pass csg - BandPass czpg + Band-pass czpg @@ -1443,7 +1368,7 @@ If you're interested in translating LMMS in another language or want to imp - Allpass + All-pass @@ -1455,49 +1380,49 @@ If you're interested in translating LMMS in another language or want to imp - 2x LowPass + 2x Low-pass - RC LowPass 12dB + RC Low-pass 12 dB/oct - RC BandPass 12dB + RC Band-pass 12 dB/oct - RC HighPass 12dB + RC High-pass 12 dB/oct - RC LowPass 24dB + RC Low-pass 24 dB/oct - RC BandPass 24dB + RC Band-pass 24 dB/oct - RC HighPass 24dB + RC High-pass 24 dB/oct - Vocal Formant Filter + Vocal Formant @@ -1509,19 +1434,19 @@ If you're interested in translating LMMS in another language or want to imp - SV LowPass + SV Low-pass - SV BandPass + SV Band-pass - SV HighPass + SV High-pass @@ -1546,30 +1471,35 @@ If you're interested in translating LMMS in another language or want to imp Editor - + Transport controls - + Play (Space) - + Stop (Space) - + Record - + Record while playing + + + Toggle Step Recording + + Effect @@ -1624,7 +1554,7 @@ If you're interested in translating LMMS in another language or want to imp - + Name @@ -1634,12 +1564,12 @@ If you're interested in translating LMMS in another language or want to imp - + Description - + Author @@ -1647,94 +1577,57 @@ If you're interested in translating LMMS in another language or want to imp EffectView - - Toggles the effect on or off. - - - - + On/Off - + W/D - + Wet Level: - - The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. - - - - + DECAY - + Time: - - The Decay knob controls how many buffers of silence must pass before the plugin stops processing. Smaller values will reduce the CPU overhead but run the risk of clipping the tail on delay and reverb effects. - - - - + GATE - + Gate: - - The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. - - - - + Controls - - Effect plugins function as a chained series of effects where the signal will be processed from top to bottom. - -The On/Off switch allows you to bypass a given plugin at any point in time. - -The Wet/Dry knob controls the balance between the input signal and the effected signal that is the resulting output from the effect. The input for the stage is the output from the previous stage. So, the 'dry' signal for effects lower in the chain contains all of the previous effects. - -The Decay knob controls how long the signal will continue to be processed after the notes have been released. The effect will stop processing signals when the volume has dropped below a given threshold for a given length of time. This knob sets the 'given length of time'. Longer times will require more CPU, so this number should be set low for most effects. It needs to be bumped up for effects that produce lengthy periods of silence, e.g. delays. - -The Gate knob controls the 'given threshold' for the effect's auto shutdown. The clock for the 'given length of time' will begin as soon as the processed signal level drops below the level specified with this knob. - -The Controls button opens a dialog for editing the effect's parameters. - -Right clicking will bring up a context menu where you can change the order in which the effects are processed or delete an effect altogether. - - - - + Move &up - + Move &down - + &Remove this plugin @@ -1743,72 +1636,72 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoParameters - Predelay + Env pre-delay - Attack + Env attack - Hold + Env hold - Decay + Env decay - Sustain + Env sustain - Release + Env release - Modulation + Env mod amount - LFO Predelay + LFO pre-delay - LFO Attack + LFO attack - LFO speed + LFO frequency - LFO Modulation + LFO mod amount - LFO Wave Shape + LFO wave shape - Freq x 100 + LFO frequency x 100 - Modulate Env-Amount + Modulate env amount @@ -1816,226 +1709,123 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoView - + DEL - Predelay: + + Pre-delay: - - Use this knob for setting predelay of the current envelope. The bigger this value the longer the time before start of actual envelope. - - - - - + + ATT - + + Attack: - - Use this knob for setting attack-time of the current envelope. The bigger this value the longer the envelope needs to increase to attack-level. Choose a small value for instruments like pianos and a big value for strings. - - - - + HOLD - + Hold: - - Use this knob for setting hold-time of the current envelope. The bigger this value the longer the envelope holds attack-level before it begins to decrease to sustain-level. - - - - + DEC - + Decay: - - Use this knob for setting decay-time of the current envelope. The bigger this value the longer the envelope needs to decrease from attack-level to sustain-level. Choose a small value for instruments like pianos. - - - - + SUST - + Sustain: - - Use this knob for setting sustain-level of the current envelope. The bigger this value the higher the level on which the envelope stays before going down to zero. - - - - + REL - + Release: - - Use this knob for setting release-time of the current envelope. The bigger this value the longer the envelope needs to decrease from sustain-level to zero. Choose a big value for soft instruments like strings. - - - - - + + AMT - - + + Modulation amount: - - Use this knob for setting modulation amount of the current envelope. The bigger this value the more the according size (e.g. volume or cutoff-frequency) will be influenced by this envelope. - - - - - LFO predelay: - - - - - Use this knob for setting predelay-time of the current LFO. The bigger this value the the time until the LFO starts to oscillate. - - - - - LFO- attack: - - - - - Use this knob for setting attack-time of the current LFO. The bigger this value the longer the LFO needs to increase its amplitude to maximum. - - - - + SPD - - LFO speed: + + Frequency: - - Use this knob for setting speed of the current LFO. The bigger this value the faster the LFO oscillates and the faster will be your effect. - - - - - Use this knob for setting modulation amount of the current LFO. The bigger this value the more the selected size (e.g. volume or cutoff-frequency) will be influenced by this LFO. - - - - - Click here for a sine-wave. - - - - - Click here for a triangle-wave. - - - - - Click here for a saw-wave for current. - - - - - Click here for a square-wave. - - - - - Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. - - - - - Click here for random wave. - - - - + FREQ x 100 - - Click here if the frequency of this LFO should be multiplied by 100. + + Multiply LFO frequency by 100 - - multiply LFO-frequency by 100 + + MODULATE ENV AMOUNT - - MODULATE ENV-AMOUNT + + Control envelope amount by this LFO - - Click here to make the envelope-amount controlled by this LFO. - - - - - control envelope-amount by this LFO - - - - + ms/LFO: - + Hint - - Drag a sample from somewhere and drop it in this window. + + Drag and drop a sample into this window. @@ -2053,7 +1843,7 @@ Right clicking will bring up a context menu where you can change the order in wh - Low shelf gain + Low-shelf gain @@ -2078,7 +1868,7 @@ Right clicking will bring up a context menu where you can change the order in wh - High Shelf gain + High-shelf gain @@ -2088,7 +1878,7 @@ Right clicking will bring up a context menu where you can change the order in wh - Low Shelf res + Low-shelf res @@ -2113,7 +1903,7 @@ Right clicking will bring up a context menu where you can change the order in wh - High Shelf res + High-shelf res @@ -2128,7 +1918,7 @@ Right clicking will bring up a context menu where you can change the order in wh - Low Shelf freq + Low-shelf freq @@ -2153,7 +1943,7 @@ Right clicking will bring up a context menu where you can change the order in wh - High shelf freq + High-shelf freq @@ -2168,7 +1958,7 @@ Right clicking will bring up a context menu where you can change the order in wh - Low shelf active + Low-shelf active @@ -2193,7 +1983,7 @@ Right clicking will bring up a context menu where you can change the order in wh - High shelf active + High-shelf active @@ -2233,12 +2023,12 @@ Right clicking will bring up a context menu where you can change the order in wh - low pass type + Low-pass type - high pass type + High-pass type @@ -2261,7 +2051,7 @@ Right clicking will bring up a context menu where you can change the order in wh - Low Shelf + Low-shelf @@ -2286,7 +2076,7 @@ Right clicking will bring up a context menu where you can change the order in wh - High Shelf + High-shelf @@ -2296,7 +2086,7 @@ Right clicking will bring up a context menu where you can change the order in wh - In Gain + Input gain @@ -2308,7 +2098,7 @@ Right clicking will bring up a context menu where you can change the order in wh - Out Gain + Output gain @@ -2333,12 +2123,12 @@ Right clicking will bring up a context menu where you can change the order in wh - lp grp + LP group - hp grp + HP group @@ -2379,192 +2169,202 @@ Right clicking will bring up a context menu where you can change the order in wh - + + Render Looped Section: + + + + + time(s) + + + + File format settings - + File format: - + Sampling rate: - + 44100 Hz - + 48000 Hz - + 88200 Hz - + 96000 Hz - + 192000 Hz - + Bit depth: - + 16 Bit integer - + 24 Bit integer - + 32 Bit float - + Stereo mode: - + Mono - + Stereo - + Joint stereo - + Compression level: - + Bitrate: - + 64 KBit/s - + 128 KBit/s - + 160 KBit/s - + 192 KBit/s - + 256 KBit/s - + 320 KBit/s - + Use variable bitrate - + Quality settings - + Interpolation: - + Zero order hold - + Sinc worst (fastest) - + Sinc medium (recommended) - + Sinc best (slowest) - + Oversampling: - + 1x (None) - + 2x - + 4x - + 8x - + Start - + Cancel @@ -2595,17 +2395,17 @@ Please make sure you have write permission to the file and the directory contain - + Error - + Error while determining file-encoder device. Please try to choose a different output format. - + Rendering: %1% @@ -2613,14 +2413,14 @@ Please make sure you have write permission to the file and the directory contain Fader - - + + Set value - - + + Please enter a new value between %1 and %2: @@ -2638,7 +2438,7 @@ Please make sure you have write permission to the file and the directory contain - + Refresh list @@ -2646,47 +2446,47 @@ Please make sure you have write permission to the file and the directory contain FileBrowserTreeWidget - + Send to active instrument-track - + Open in new instrument-track/Song Editor - + Open in new instrument-track/B+B Editor - + Loading sample - + Please wait, loading sample for preview... - + Error - + does not appear to be a valid - + file - + --- Factory files --- @@ -2695,12 +2495,12 @@ Please make sure you have write permission to the file and the directory contain FlangerControls - Delay Samples + Delay samples - Lfo Frequency + LFO frequency @@ -2733,7 +2533,7 @@ Please make sure you have write permission to the file and the directory contain - Delay Time: + Delay time: @@ -2763,7 +2563,7 @@ Please make sure you have write permission to the file and the directory contain - Feedback Amount: + Feedback amount: @@ -2773,7 +2573,7 @@ Please make sure you have write permission to the file and the directory contain - White Noise Amount: + White noise amount: @@ -2785,395 +2585,348 @@ Please make sure you have write permission to the file and the directory contain FreeBoyInstrument - + Sweep time - + Sweep direction - - - Sweep RtShift amount - - - - Wave Pattern Duty + Sweep rate shift amount - Channel 1 volume + + Wave pattern duty cycle - - - Volume sweep direction + Channel 1 volume + Volume sweep direction + + + + + + Length of each step in sweep - + Channel 2 volume - + Channel 3 volume - + Channel 4 volume - + Shift Register width - - - Right Output level - - - - - Left Output level - - - Channel 1 to SO2 (Left) + Right output level - Channel 2 to SO2 (Left) + Left output level - Channel 3 to SO2 (Left) + Channel 1 to SO2 (Left) - Channel 4 to SO2 (Left) + Channel 2 to SO2 (Left) - Channel 1 to SO1 (Right) + Channel 3 to SO2 (Left) - Channel 2 to SO1 (Right) + Channel 4 to SO2 (Left) - Channel 3 to SO1 (Right) + Channel 1 to SO1 (Right) - Channel 4 to SO1 (Right) + Channel 2 to SO1 (Right) - Treble + Channel 3 to SO1 (Right) + Channel 4 to SO1 (Right) + + + + + Treble + + + + Bass FreeBoyInstrumentView - - - Sweep Time: - - - Sweep Time + Sweep time: - - The amount of increase or decrease in frequency + + Sweep time - Sweep RtShift amount: + Sweep rate shift amount: - Sweep RtShift amount + Sweep rate shift amount - - The rate at which increase or decrease in frequency occurs + + + Wave pattern duty cycle: - - - Wave pattern duty: - - - - - Wave Pattern Duty + + + Wave pattern duty cycle - - The duty cycle is the ratio of the duration (time) that a signal is ON versus the total period of the signal. + Square channel 1 volume: - - - Square Channel 1 Volume: + + Square channel 1 volume - - Square Channel 1 Volume - - - - - - + + + Length of each step in sweep: - - - + + + Length of each step in sweep - - - - The delay between step change + + Square channel 2 volume: - - Wave pattern duty + + Square channel 2 volume - - Square Channel 2 Volume: - - - - - Square Channel 2 Volume + Wave pattern channel volume: - - Wave Channel Volume: + + Wave pattern channel volume - - - Wave Channel Volume + + Noise channel volume: + + + + + Noise channel volume - Noise Channel Volume: + SO1 volume (Right): - - Noise Channel Volume + SO1 volume (Right) - - SO1 Volume (Right): + + SO2 volume (Left): - - SO1 Volume (Right) + + SO2 volume (Left) - - SO2 Volume (Left): - - - - - SO2 Volume (Left) - - - - + Treble: - + Treble - + Bass: - + Bass - - Sweep Direction + + Sweep direction - - - - - - Volume Sweep Direction + + + + + + Volume sweep direction - - Shift Register Width + + Shift register width - - Channel1 to SO1 (Right) + + Channel 1 to SO1 (Right) + + + + + Channel 2 to SO1 (Right) + + + + + Channel 3 to SO1 (Right) - Channel2 to SO1 (Right) + Channel 4 to SO1 (Right) - Channel3 to SO1 (Right) + Channel 1 to SO2 (Left) - - Channel4 to SO1 (Right) + + Channel 2 to SO2 (Left) - - Channel1 to SO2 (Left) + + Channel 3 to SO2 (Left) - Channel2 to SO2 (Left) + Channel 4 to SO2 (Left) - - Channel3 to SO2 (Left) - - - - - Channel4 to SO2 (Left) - - - - - Wave Pattern - - - - - Draw the wave here + + Wave pattern graph FxLine - + Channel send amount - - The FX channel receives input from one or more instrument tracks. - It in turn can be routed to multiple other FX channels. LMMS automatically takes care of preventing infinite loops for you and doesn't allow making a connection that would result in an infinite loop. - -In order to route the channel to another channel, select the FX channel and click on the "send" button on the channel you want to send to. The knob under the send button controls the level of signal that is sent to the channel. - -You can remove and move FX channels in the context menu, which is accessed by right-clicking the FX channel. - - - - - + Move &left - + Move &right - + Rename &channel - + R&emove channel - + Remove &unused channels @@ -3181,29 +2934,29 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxMixer - + Master - - - + + + FX %1 - + Volume - + Mute - + Solo @@ -3272,57 +3025,22 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrumentView - Open other GIG file - - - - - Click here to open another GIG file - - - - - Choose the patch - - - - - Click here to change which patch of the GIG file to use - - - - - - Change which instrument of the GIG file is being played - - - - - Which GIG file is currently being used - - - - - Which patch of the GIG file is currently being used - - - - - Gain - - - - - Factor to multiply samples by - - - - + Open GIG file - + + Choose patch + + + + + Gain: + + + + GIG Files (*.gig) @@ -3330,52 +3048,52 @@ You can remove and move FX channels in the context menu, which is accessed by ri GuiApplication - + Working directory - + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. - + Preparing UI - + Preparing song editor - + Preparing mixer - + Preparing controller rack - + Preparing project notes - + Preparing beat/bassline editor - + Preparing piano roll - + Preparing automation editor @@ -3476,139 +3194,104 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentFunctionArpeggioView - + ARPEGGIO - - An arpeggio is a method playing (especially plucked) instruments, which makes the music much livelier. The strings of such instruments (e.g. harps) are plucked like chords. The only difference is that this is done in a sequential order, so the notes are not played at the same time. Typical arpeggios are major or minor triads, but there are a lot of other possible chords, you can select. - - - - + RANGE - + Arpeggio range: - + octave(s) - - Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. - - - - + CYCLE - + Cycle notes: - + note(s) - - Jumps over n steps in the arpeggio and cycles around if we're over the note range. If the total note range is evenly divisible by the number of steps jumped over you will get stuck in a shorter arpeggio or even on one note. - - - - + SKIP - + Skip rate: - - - + + + % - - The skip function will make the arpeggiator pause one step randomly. From its start in full counter clockwise position and no effect it will gradually progress to full amnesia at maximum setting. - - - - + MISS - + Miss rate: - - The miss function will make the arpeggiator miss the intended note. - - - - + TIME - + Arpeggio time: - + ms - - Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - - - - + GATE - + Arpeggio gate: - - Use this knob for setting the arpeggio gate. The arpeggio gate specifies the percent of a whole arpeggio-tone that should be played. With this you can make cool staccato arpeggios. - - - - + Chord: - + Direction: - + Mode: @@ -4105,92 +3788,87 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentFunctionNoteStackingView - + STACKING - + Chord: - + RANGE - + Chord range: - + octave(s) - - - Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - - InstrumentMidiIOView - + ENABLE MIDI INPUT - - + + CHANNEL - - + + VELOCITY - + ENABLE MIDI OUTPUT - + PROGRAM - + NOTE - + MIDI devices to receive MIDI events from - + MIDI devices to send MIDI events to - + CUSTOM BASE VELOCITY - - Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity. - + BASE VELOCITY @@ -4198,13 +3876,13 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentMiscView - + MASTER PITCH - - Enables the use of Master Pitch + + Enables the use of master pitch @@ -4258,22 +3936,22 @@ You can remove and move FX channels in the context menu, which is accessed by ri - LowPass + Low-pass - HiPass + Hi-pass - BandPass csg + Band-pass csg - BandPass czpg + Band-pass czpg @@ -4283,7 +3961,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri - Allpass + All-pass @@ -4293,42 +3971,42 @@ You can remove and move FX channels in the context menu, which is accessed by ri - 2x LowPass + 2x Low-pass - RC LowPass 12dB + RC Low-pass 12 dB/oct - RC BandPass 12dB + RC Band-pass 12 dB/oct - RC HighPass 12dB + RC High-pass 12 dB/oct - RC LowPass 24dB + RC Low-pass 24 dB/oct - RC BandPass 24dB + RC Band-pass 24 dB/oct - RC HighPass 24dB + RC High-pass 24 dB/oct - Vocal Formant Filter + Vocal Formant @@ -4338,17 +4016,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri - SV LowPass + SV Low-pass - SV BandPass + SV Band-pass - SV HighPass + SV High-pass @@ -4375,57 +4053,37 @@ You can remove and move FX channels in the context menu, which is accessed by ri - - These tabs contain envelopes. They're very important for modifying a sound, in that they are almost always necessary for substractive synthesis. For example if you have a volume envelope, you can set when the sound should have a specific volume. If you want to create some soft strings then your sound has to fade in and out very softly. This can be done by setting large attack and release times. It's the same for other envelope targets like panning, cutoff frequency for the used filter and so on. Just monkey around with it! You can really make cool sounds out of a saw-wave with just some envelopes...! - - - - + FILTER - - Here you can select the built-in filter you want to use for this instrument-track. Filters are very important for changing the characteristics of a sound. - - - - + FREQ - - cutoff frequency: + + Cutoff frequency: - + Hz - - Use this knob for setting the cutoff frequency for the selected filter. The cutoff frequency specifies the frequency for cutting the signal by a filter. For example a lowpass-filter cuts all frequencies above the cutoff frequency. A highpass-filter cuts all frequencies below cutoff frequency, and so on... + + Q/RESO - - RESO + + Q/Resonance: - - Resonance: - - - - - Use this knob for setting Q/Resonance for the selected filter. Q/Resonance tells the filter how much it should amplify frequencies near Cutoff-frequency. - - - - + Envelopes, LFOs and filters are not supported by the current instrument. @@ -4475,12 +4133,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri - Master Pitch + Master pitch - + Default preset @@ -4488,52 +4146,52 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackView - + Volume - + Volume: - + VOL - + Panning - + Panning: - + PAN - + MIDI - + Input - + Output - + FX %1: %2 @@ -4541,22 +4199,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackWindow - + GENERAL SETTINGS - - Use these controls to view and edit the next/previous track in the song editor. + + Volume - - Instrument volume - - - - + Volume: @@ -4626,52 +4279,47 @@ You can remove and move FX channels in the context menu, which is accessed by ri - - Click here, if you want to save current instrument track settings in a preset file. Later you can load this preset by double-clicking it in the preset-browser. - - - - + SAVE - + Envelope, filter & LFO - + Chord stacking & arpeggio - + Effects - - MIDI settings + + MIDI - + Miscellaneous - + Save preset - + XML preset file (*.xpf) - + Plugin @@ -4689,18 +4337,18 @@ You can remove and move FX channels in the context menu, which is accessed by ri - - + + Set value - + Please enter a new value between -96.0 dBFS and 6.0 dBFS: - + Please enter a new value between %1 and %2: @@ -4733,21 +4381,16 @@ You can remove and move FX channels in the context menu, which is accessed by ri Link channels - - - Value: - - - Sorry, no help available. + Value: LadspaEffect - + Unknown LADSPA plugin %1 requested. @@ -4755,12 +4398,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri LcdSpinBox - + Set value - + Please enter a new value between %1 and %2: @@ -4838,116 +4481,106 @@ You can remove and move FX channels in the context menu, which is accessed by ri - - LFO Controller - - - - + BASE - - Base amount: + + Base: - todo + FREQ - - SPD + + LFO frequency: - - LFO-speed: - - - - - Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. - - - - + AMNT - + Modulation amount: - - Use this knob for setting modulation amount of the LFO. The bigger this value, the more the connected control (e.g. volume or cutoff-frequency) will be influenced by the LFO. - - - - + PHS - + Phase offset: - - degrees + + degrees - - With this knob you can set the phase offset of the LFO. That means you can move the point within an oscillation where the oscillator begins to oscillate. For example if you have a sine-wave and have a phase-offset of 180 degrees the wave will first go down. It's the same with a square-wave. + + Sine wave - - Click here for a sine-wave. + + Triangle wave - - Click here for a triangle-wave. + + Saw wave - - Click here for a saw-wave. + + Square wave - - Click here for a square-wave. + + Moog saw wave - - Click here for a moog saw-wave. + + Exponential wave - - Click here for an exponential wave. + + White noise - - Click here for white-noise. - - - - - Click here for a user-defined shape. + + User-defined shape. Double click to pick a file. + + + Mutliply modulation frequency by 1 + + + + + Mutliply modulation frequency by 100 + + + + + Divide modulation frequency by 100 + + LmmsCore @@ -4975,545 +4608,483 @@ Double click to pick a file. MainWindow - + Configuration file - + Error while parsing configuration file at line %1:%2: %3 - + Could not open file - + Could not open file %1 for writing. Please make sure you have write permission to the file and the directory containing the file and try again! - + Project recovery - + There is a recovery file present. It looks like the last session did not end properly or another instance of LMMS is already running. Do you want to recover the project of this session? - - - + + Recover - + Recover the file. Please don't run multiple instances of LMMS when you do this. - - + Discard - + Launch a default session and delete the restored files. This is not reversible. - + Version %1 - + Preparing plugin browser - + Preparing file browsers - + My Projects - + My Samples - + My Presets - + My Home - + Root directory - + Volumes - + My Computer - + Loading background artwork - + &File - + &New - + New from template - + &Open... - + &Recently Opened Projects - + &Save - + Save &As... - + Save as New &Version - + Save as default template - + Import... - + E&xport... - + E&xport Tracks... - + Export &MIDI... - + &Quit - + &Edit - + Undo - + Redo - + Settings - + &View - + &Tools - + &Help - + Online Help - + Help - - What's This? - - - - + About - + Create new project - + Create new project from template - + Open existing project - + Recently opened projects - + Save current project - + Export current project - - What's this? + + Metronome - - Toggle metronome + + + Song Editor - - Show/hide Song-Editor + + + Beat+Bassline Editor - - By pressing this button, you can show or hide the Song-Editor. With the help of the Song-Editor you can edit song-playlist and specify when which track should be played. You can also insert and move samples (e.g. rap samples) directly into the playlist. + + + Piano Roll - - Show/hide Beat+Bassline Editor + + + Automation Editor - - By pressing this button, you can show or hide the Beat+Bassline Editor. The Beat+Bassline Editor is needed for creating beats, and for opening, adding, and removing channels, and for cutting, copying and pasting beat and bassline-patterns, and for other things like that. + + + FX Mixer - - Show/hide Piano-Roll - - - - - Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. - - - - - Show/hide Automation Editor - - - - - Click here to show or hide the Automation Editor. With the help of the Automation Editor you can edit dynamic values in an easy way. - - - - - Show/hide FX Mixer - - - - - Click here to show or hide the FX Mixer. The FX Mixer is a very powerful tool for managing effects for your song. You can insert effects into different effect-channels. - - - - - Show/hide project notes - - - - - Click here to show or hide the project notes window. In this window you can put down your project notes. - - - - + Show/hide controller rack - + + Show/hide project notes + + + + Untitled - + Recover session. Please save your work! - + LMMS %1 - + Recovered project not saved - + This project was recovered from the previous session. It is currently unsaved and will be lost if you don't save it. Do you want to save it now? - + Project not saved - + The current project was modified since last saving. Do you want to save it now? - + Open Project - + LMMS (*.mmp *.mmpz) - + Save Project - + LMMS Project - + LMMS Project Template - + Save project template - + Overwrite default template? - + This will overwrite your current default template. - + Help not available - + Currently there's no help available in LMMS. Please visit http://lmms.sf.net/wiki for documentation on LMMS. - - Song Editor - - - - - Beat+Bassline Editor - - - - - Piano Roll - - - - - Automation Editor - - - - - FX Mixer - - - - - Project Notes - - - - + Controller Rack - + + Project Notes + + + + Volume as dBFS - + Smooth scroll - + Enable note labels in piano roll - + MIDI File (*.mid) - - + + untitled - - + + Select file for project-export... - + Select directory for writing exported tracks... - + Save project - + Project saved - + The project %1 is now saved. - + Project NOT saved. - + The project %1 was not saved! - + Import file - + MIDI sequences - + Hydrogen projects - + All file types @@ -5521,19 +5092,29 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MeterDialog - - + + Meter Numerator - - + + Meter numerator + + + + + Meter Denominator + Meter denominator + + + + TIME SIG @@ -5567,23 +5148,23 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiImport - - + + Setup incomplete - - You do not have set up a default soundfont in the settings dialog (Edit->Settings). Therefore no sound will be played back after importing this MIDI file. You should download a General MIDI soundfont, specify it in settings dialog and try again. + + You have not set up a default soundfont in the settings dialog (Edit->Settings). Therefore no sound will be played back after importing this MIDI file. You should download a General MIDI soundfont, specify it in settings dialog and try again. - + You did not compile LMMS with support for SoundFont2 player, which is used to add default sound to imported MIDI files. Therefore no sound will be played back after importing this MIDI file. - + Track @@ -5606,57 +5187,57 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiPort - + Input channel - + Output channel - + Input controller - + Output controller - + Fixed input velocity - + Fixed output velocity - + Fixed output note - + Output MIDI program - + Base velocity - + Receive MIDI-events - + Send MIDI-events @@ -5671,596 +5252,596 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroInstrument - - - Osc 1 Volume - - - - - Osc 1 Panning - - - Osc 1 Coarse detune + Osc 1 volume - Osc 1 Fine detune left + Osc 1 panning - Osc 1 Fine detune right + Osc 1 coarse detune - Osc 1 Stereo phase offset + Osc 1 fine detune left - Osc 1 Pulse width + Osc 1 fine detune right - Osc 1 Sync send on rise + Osc 1 stereo phase offset - Osc 1 Sync send on fall + Osc 1 pulse width + + + + + Osc 1 sync send on rise - Osc 2 Volume - - - - - Osc 2 Panning + Osc 1 sync send on fall - Osc 2 Coarse detune + Osc 2 volume - Osc 2 Fine detune left + Osc 2 panning - Osc 2 Fine detune right + Osc 2 coarse detune - Osc 2 Stereo phase offset + Osc 2 fine detune left - Osc 2 Waveform + Osc 2 fine detune right - Osc 2 Sync Hard + Osc 2 stereo phase offset - Osc 2 Sync Reverse + Osc 2 waveform + + + + + Osc 2 sync hard - Osc 3 Volume - - - - - Osc 3 Panning + Osc 2 sync reverse - Osc 3 Coarse detune + Osc 3 volume - Osc 3 Stereo phase offset + Osc 3 panning - Osc 3 Sub-oscillator mix + Osc 3 coarse detune - Osc 3 Waveform 1 + Osc 3 Stereo phase offset - Osc 3 Waveform 2 + Osc 3 sub-oscillator mix - Osc 3 Sync Hard + Osc 3 waveform 1 - Osc 3 Sync Reverse + Osc 3 waveform 2 + + + + + Osc 3 sync hard - LFO 1 Waveform - - - - - LFO 1 Attack + Osc 3 Sync reverse - LFO 1 Rate + LFO 1 waveform - LFO 1 Phase + LFO 1 attack + + + + + LFO 1 rate - LFO 2 Waveform - - - - - LFO 2 Attack + LFO 1 phase - LFO 2 Rate + LFO 2 waveform - LFO 2 Phase + LFO 2 attack + + + + + LFO 2 rate - Env 1 Pre-delay - - - - - Env 1 Attack + LFO 2 phase - Env 1 Hold + Env 1 pre-delay - Env 1 Decay + Env 1 attack - Env 1 Sustain + Env 1 hold - Env 1 Release + Env 1 decay - Env 1 Slope + Env 1 sustain + + + + + Env 1 release - Env 2 Pre-delay - - - - - Env 2 Attack + Env 1 slope - Env 2 Hold + Env 2 pre-delay - Env 2 Decay + Env 2 attack - Env 2 Sustain + Env 2 hold - Env 2 Release + Env 2 decay - Env 2 Slope + Env 2 sustain + + + + + Env 2 release - Osc2-3 modulation + Env 2 slope - Selected view + Osc 2+3 modulation - Vol1-Env1 - - - - - Vol1-Env2 + Selected view - Vol1-LFO1 + Osc 1 - Vol env 1 - Vol1-LFO2 + Osc 1 - Vol env 2 + + + + + Osc 1 - Vol LFO 1 - Vol2-Env1 - - - - - Vol2-Env2 + Osc 1 - Vol LFO 2 - Vol2-LFO1 + Osc 2 - Vol env 1 - Vol2-LFO2 + Osc 2 - Vol env 2 + + + + + Osc 2 - Vol LFO 1 - Vol3-Env1 - - - - - Vol3-Env2 + Osc 2 - Vol LFO 2 - Vol3-LFO1 + Osc 3 - Vol env 1 - Vol3-LFO2 + Osc 3 - Vol env 2 + + + + + Osc 3 - Vol LFO 1 - Phs1-Env1 - - - - - Phs1-Env2 + Osc 3 - Vol LFO 2 - Phs1-LFO1 + Osc 1 - Phs env 1 - Phs1-LFO2 + Osc 1 - Phs env 2 + + + + + Osc 1 - Phs LFO 1 - Phs2-Env1 - - - - - Phs2-Env2 + Osc 1 - Phs LFO 2 - Phs2-LFO1 + Osc 2 - Phs env 1 - Phs2-LFO2 + Osc 2 - Phs env 2 + + + + + Osc 2 - Phs LFO 1 - Phs3-Env1 - - - - - Phs3-Env2 + Osc 2 - Phs LFO 2 - Phs3-LFO1 + Osc 3 - Phs env 1 - Phs3-LFO2 + Osc 3 - Phs env 2 + + + + + Osc 3 - Phs LFO 1 - Pit1-Env1 - - - - - Pit1-Env2 + Osc 3 - Phs LFO 2 - Pit1-LFO1 + Osc 1 - Pit env 1 - Pit1-LFO2 + Osc 1 - Pit env 2 + + + + + Osc 1 - Pit LFO 1 - Pit2-Env1 - - - - - Pit2-Env2 + Osc 1 - Pit LFO 2 - Pit2-LFO1 + Osc 2 - Pit env 1 - Pit2-LFO2 + Osc 2 - Pit env 2 + + + + + Osc 2 - Pit LFO 1 - Pit3-Env1 - - - - - Pit3-Env2 + Osc 2 - Pit LFO 2 - Pit3-LFO1 + Osc 3 - Pit env 1 - Pit3-LFO2 + Osc 3 - Pit env 2 + + + + + Osc 3 - Pit LFO 1 - PW1-Env1 - - - - - PW1-Env2 + Osc 3 - Pit LFO 2 - PW1-LFO1 + Osc 1 - PW env 1 - PW1-LFO2 + Osc 1 - PW env 2 + + + + + Osc 1 - PW LFO 1 - Sub3-Env1 - - - - - Sub3-Env2 + Osc 1 - PW LFO 2 - Sub3-LFO1 + Osc 3 - Sub env 1 - Sub3-LFO2 + Osc 3 - Sub env 2 - - - Sine wave + + Osc 3 - Sub LFO 1 - - Bandlimited Triangle wave - - - - - Bandlimited Saw wave - - - - - Bandlimited Ramp wave + + Osc 3 - Sub LFO 2 - Bandlimited Square wave + + Sine wave - Bandlimited Moog saw wave + Bandlimited Triangle wave - - Soft square wave + Bandlimited Saw wave - Absolute sine wave + Bandlimited Ramp wave - - Exponential wave + Bandlimited Square wave - White noise + Bandlimited Moog saw wave - Digital Triangle wave + + Soft square wave - Digital Saw wave + Absolute sine wave - Digital Ramp wave + + Exponential wave - Digital Square wave + White noise + Digital Triangle wave + + + + + Digital Saw wave + + + + + Digital Ramp wave + + + + + Digital Square wave + + + + Digital Moog saw wave - + Triangle wave - + Saw wave - + Ramp wave - + Square wave - + Moog saw wave - + Abs. sine wave - + Random - + Random smooth @@ -6268,433 +5849,240 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroView - + Operators view - - The Operators view contains all the operators. These include both audible operators (oscillators) and inaudible operators, or modulators: Low-frequency oscillators and Envelopes. - -Knobs and other widgets in the Operators view have their own what's this -texts, so you can get more specific help for them that way. - - - - + Matrix view - - The Matrix view contains the modulation matrix. Here you can define the modulation relationships between the various operators: Each audible operator (oscillators 1-3) has 3-4 properties that can be modulated by any of the modulators. Using more modulations consumes more CPU power. - -The view is divided to modulation targets, grouped by the target oscillator. Available targets are volume, pitch, phase, pulse width and sub-osc ratio. Note: some targets are specific to one oscillator only. - -Each modulation target has 4 knobs, one for each modulator. By default the knobs are at 0, which means no modulation. Turning a knob to 1 causes that modulator to affect the modulation target as much as possible. Turning it to -1 does the same, but the modulation is inversed. - - - - - - + + + Volume - - - + + + Panning - - - + + + Coarse detune - - - + + + semitones - - - Finetune left + + + Fine tune left - - - - + + + + cents - - - Finetune right + + + Fine tune right - - - + + + Stereo phase offset - - - - - + + + + + deg - + Pulse width - + Send sync on pulse rise - + Send sync on pulse fall - + Hard sync oscillator 2 - + Reverse sync oscillator 2 - + Sub-osc mix - + Hard sync oscillator 3 - + Reverse sync oscillator 3 + + + + + + Attack + + + + + + Rate + + + + + + Phase + + + + + + Pre-delay + + + + + + Hold + + - - - Attack + Decay - Rate + Sustain - Phase - - - - - - Pre-delay - - - - - - Hold - - - - - - Decay - - - - - - Sustain - - - - - Release - - + + Slope - - Mix Osc2 with Osc3 + + Mix osc 2 with osc 3 - - Modulate amplitude of Osc3 with Osc2 + + Modulate amplitude of osc 3 by osc 2 - - Modulate frequency of Osc3 with Osc2 + + Modulate frequency of osc 3 by osc 2 - - Modulate phase of Osc3 with Osc2 + + Modulate phase of osc 3 by osc 2 + + + + + + + + - The CRS knob changes the tuning of oscillator 1 in semitone steps. - - - - The CRS knob changes the tuning of oscillator 2 in semitone steps. - - - - The CRS knob changes the tuning of oscillator 3 in semitone steps. - - - + - + + + + - FTL and FTR change the finetuning of the oscillator for left and right channels respectively. These can add stereo-detuning to the oscillator which widens the stereo image and causes an illusion of space. - - - + + - - The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. - - - + + - The PW knob controls the pulse width, also known as duty cycle, of oscillator 1. Oscillator 1 is a digital pulse wave oscillator, it doesn't produce bandlimited output, which means that you can use it as an audible oscillator but it will cause aliasing. You can also use it as an inaudible source of a sync signal, which can be used to synchronize oscillators 2 and 3. - - - + + + + - Send Sync on Rise: When enabled, the Sync signal is sent every time the state of oscillator 1 changes from low to high, ie. when the amplitude changes from -1 to 1. Oscillator 1's pitch, phase and pulse width may affect the timing of syncs, but its volume has no effect on them. Sync signals are sent independently for both left and right channels. - - - + + + + - Send Sync on Fall: When enabled, the Sync signal is sent every time the state of oscillator 1 changes from high to low, ie. when the amplitude changes from 1 to -1. Oscillator 1's pitch, phase and pulse width may affect the timing of syncs, but its volume has no effect on them. Sync signals are sent independently for both left and right channels. - - - - + + + + + - Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. - - - + - - Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. - - - - - Choose waveform for oscillator 2. - - - - - Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. - - - - - Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. - - - - - The SUB knob changes the mixing ratio of the two sub-oscs of oscillator 3. Each sub-osc can be set to produce a different waveform, and oscillator 3 can smoothly interpolate between them. All incoming modulations to oscillator 3 are applied to both sub-oscs/waveforms in the exact same way. - - - - - In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. - -Mix mode means no modulation: the outputs of the oscillators are simply mixed together. - - - - - In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. - -AM means amplitude modulation: Oscillator 3's amplitude (volume) is modulated by oscillator 2. - - - - - In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. - -FM means frequency modulation: Oscillator 3's frequency (pitch) is modulated by oscillator 2. The frequency modulation is implemented as phase modulation, which gives a more stable overall pitch than "pure" frequency modulation. - - - - - In addition to dedicated modulators, Monstro allows oscillator 3 to be modulated by the output of oscillator 2. - -PM means phase modulation: Oscillator 3's phase is modulated by oscillator 2. It differs from frequency modulation in that the phase changes are not cumulative. - - - - - Select the waveform for LFO 1. -"Random" and "Random smooth" are special waveforms: they produce random output, where the rate of the LFO controls how often the state of the LFO changes. The smooth version interpolates between these states with cosine interpolation. These random modes can be used to give "life" to your presets - add some of that analog unpredictability... - - - - - Select the waveform for LFO 2. -"Random" and "Random smooth" are special waveforms: they produce random output, where the rate of the LFO controls how often the state of the LFO changes. The smooth version interpolates between these states with cosine interpolation. These random modes can be used to give "life" to your presets - add some of that analog unpredictability... - - - - - - Attack causes the LFO to come on gradually from the start of the note. - - - - - - Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. - - - - - - PHS controls the phase offset of the LFO. - - - - - - PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. - - - - - - ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. - - - - - - HOLD controls how long the envelope stays at peak after the attack phase. - - - - - - DEC, or decay, controls how fast the envelope falls off from its peak, measured in milliseconds it would take to go from peak to zero. The actual decay may be shorter if sustain is used. - - - - - - SUS, or sustain, controls the sustain level of the envelope. The decay phase will not go below this level as long as the note is held. - - - - - - REL, or release, controls how long the release is for the note, measured in how long it would take to fall from peak to zero. Actual release may be shorter, depending on at what phase the note is released. - - - - - - The slope knob controls the curve or shape of the envelope. A value of 0 creates straight rises and falls. Negative values create curves that start slowly, peak quickly and fall of slowly again. Positive values create curves that start and end quickly, and stay longer near the peaks. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Modulation amount @@ -6718,7 +6106,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator - Dry Gain: + Dry gain: @@ -6728,7 +6116,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator - Lowpass stages: + Low-pass stages: @@ -6738,265 +6126,265 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator - Swap left and right input channel for reflections + Swap left and right input channels for reflections NesInstrument - - - Channel 1 Coarse detune - - - Channel 1 Volume + Channel 1 coarse detune - - Channel 1 Envelope length + + Channel 1 volume - - Channel 1 Duty cycle + + Channel 1 envelope length - - Channel 1 Sweep amount + + Channel 1 duty cycle - Channel 1 Sweep rate + Channel 1 sweep amount - - Channel 2 Coarse detune + + Channel 1 sweep rate + Channel 2 Coarse detune + + + + Channel 2 Volume - - Channel 2 Envelope length + + Channel 2 envelope length - - Channel 2 Duty cycle - - - - - Channel 2 Sweep amount + + Channel 2 duty cycle - Channel 2 Sweep rate + Channel 2 sweep amount - - Channel 3 Coarse detune + + Channel 2 sweep rate - Channel 3 Volume + Channel 3 coarse detune - - Channel 4 Volume + + Channel 3 volume - - Channel 4 Envelope length + + Channel 4 volume - - Channel 4 Noise frequency + + Channel 4 envelope length - - Channel 4 Noise frequency sweep + + Channel 4 noise frequency - - Master volume + + Channel 4 noise frequency sweep + Master volume + + + + Vibrato NesInstrumentView - - - - - - Volume - - - Coarse detune + + Volume - + + Coarse detune + + + + + + Envelope length - + Enable channel 1 - + Enable envelope 1 - + Enable envelope 1 loop - - - Enable sweep 1 - - - - Sweep amount + Enable sweep 1 + Sweep amount + + + + + Sweep rate - - + + 12.5% Duty cycle - - + + 25% Duty cycle - - + + 50% Duty cycle - - + + 75% Duty cycle - + Enable channel 2 - + Enable envelope 2 - + Enable envelope 2 loop - + Enable sweep 2 - + Enable channel 3 - + Noise Frequency - + Frequency sweep - + Enable channel 4 - + Enable envelope 4 - + Enable envelope 4 loop - + Quantize noise frequency when using note frequency - + Use note frequency for noise - + Noise mode - - Master Volume + + Master volume - + Vibrato @@ -7004,174 +6392,174 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator OpulenzInstrument - + Patch - - - Op 1 Attack - - - - - Op 1 Decay - - - Op 1 Sustain + Op 1 attack - Op 1 Release + Op 1 decay - Op 1 Level + Op 1 sustain - Op 1 Level Scaling + Op 1 release - Op 1 Frequency Multiple + Op 1 level - Op 1 Feedback + Op 1 level scaling - Op 1 Key Scaling Rate + Op 1 frequency multiplier - Op 1 Percussive Envelope + Op 1 feedback - Op 1 Tremolo + Op 1 key scaling rate - Op 1 Vibrato + Op 1 percussive envelope - - Op 1 Waveform + + Op 1 tremolo - - Op 2 Attack + + Op 1 vibrato - - Op 2 Decay + + Op 1 waveform - Op 2 Sustain + Op 2 attack - Op 2 Release + Op 2 decay - Op 2 Level + Op 2 sustain - Op 2 Level Scaling + Op 2 release - Op 2 Frequency Multiple + Op 2 level - Op 2 Key Scaling Rate + Op 2 level scaling - Op 2 Percussive Envelope + Op 2 frequency multiplier - Op 2 Tremolo + Op 2 key scaling rate - Op 2 Vibrato + Op 2 percussive envelope - - Op 2 Waveform + + Op 2 tremolo + + + + + Op 2 vibrato - FM - - - - - Vibrato Depth + Op 2 waveform - Tremolo Depth + FM + + + + + Vibrato depth + + + + + Tremolo depth OpulenzInstrumentView - + Attack - + Decay - + Release - + Frequency multiplier @@ -7179,29 +6567,29 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator OscillatorObject - + Osc %1 waveform - + Osc %1 harmonic - + Osc %1 volume - + Osc %1 panning - + Osc %1 fine detuning left @@ -7283,57 +6671,42 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PatmanView - - Open other patch + + Open patch - - Click here to open another patch-file. Loop and Tune settings are not reset. - - - - + Loop - + Loop mode - - Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. - - - - + Tune - + Tune mode - - Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. - - - - + No file selected - + Open patch file - + Patch-Files (*.pat) @@ -7341,37 +6714,42 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PatternView - + Open in piano-roll - + + Set as ghost in piano-roll + + + + Clear all notes - + Reset name - + Change name - + Add steps - + Remove steps - + Clone Steps @@ -7379,17 +6757,17 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakController - + Peak Controller - + Peak Controller Bug - + Due to a bug in older version of LMMS, the peak controllers may not be connect properly. Please ensure that peak controllers are connected properly and re-save this file. Sorry for any inconvenience caused. @@ -7416,7 +6794,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator - Base amount: + Base: @@ -7436,7 +6814,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator - Amount Multiplicator: + Amount multiplicator: @@ -7469,140 +6847,150 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator Treshold: - - - PeakControllerEffectControls - - Base value - - - - - Modulation amount - - - - - Attack - - - - - Release - - - - - Treshold - - - - + Mute output - - Abs Value + + Absolute value + + + + + PeakControllerEffectControls + + + Base value - - Amount Multiplicator + + Modulation amount + + + + + Attack + + + + + Release + + + + + Treshold + + + + + Mute output + + + + + Absolute value + + + + + Amount multiplicator PianoRoll - + Note Velocity - + Note Panning - + Mark/unmark current semitone - + Mark/unmark all corresponding octave semitones - + Mark current scale - + Mark current chord - + Unmark all - + Select all notes on this key - + Note lock - + Last note - + No scale - + No chord - + Velocity: %1% - + Panning: %1% left - + Panning: %1% right - + Panning: center - + Please open a pattern by double-clicking on it! - - + + Please enter a new value between %1 and %2: @@ -7610,174 +6998,129 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PianoRollWindow - + Play/pause current pattern (Space) - + Record notes from MIDI-device/channel-piano - + Record notes from MIDI-device/channel-piano while playing song or BB track - + + Record notes from MIDI-device/channel-piano, one step at the time + + + + Stop playing of current pattern (Space) - - Click here to play the current pattern. This is useful while editing it. The pattern is automatically looped when its end is reached. - - - - - Click here to record notes from a MIDI-device or the virtual test-piano of the according channel-window to the current pattern. When recording all notes you play will be written to this pattern and you can play and edit them afterwards. - - - - - Click here to record notes from a MIDI-device or the virtual test-piano of the according channel-window to the current pattern. When recording all notes you play will be written to this pattern and you will hear the song or BB track in the background. - - - - - Click here to stop playback of current pattern. - - - - + Edit actions - + Draw mode (Shift+D) - + Erase mode (Shift+E) - + Select mode (Shift+S) - - Detune mode (Shift+T) + + Pitch Bend mode (Shift+T) - - Click here and draw mode will be activated. In this mode you can add, resize and move notes. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. In this mode, hold %1 to temporarily go into select mode. - - - - - Click here and erase mode will be activated. In this mode you can erase notes. You can also press 'Shift+E' on your keyboard to activate this mode. - - - - - Click here and select mode will be activated. In this mode you can select notes. Alternatively, you can hold %1 in draw mode to temporarily use select mode. - - - - - Click here and detune mode will be activated. In this mode you can click a note to open its automation detuning. You can utilize this to slide notes from one to another. You can also press 'Shift+T' on your keyboard to activate this mode. - - - - + Quantize - + Copy paste controls - - Cut selected notes (%1+X) + + Cut (%1+X) - - Copy selected notes (%1+C) + + Copy (%1+C) - - Paste notes from clipboard (%1+V) + + Paste (%1+V) - - Click here and the selected notes will be cut into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - - - - - Click here and the selected notes will be copied into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - - - - - Click here and the notes from the clipboard will be pasted at the first visible measure. - - - - + Timeline controls - + Zoom and note controls - - This controls the magnification of an axis. It can be helpful to choose magnification for a specific task. For ordinary editing, the magnification should be fitted to your smallest notes. + + Horizontal zooming - - The 'Q' stands for quantization, and controls the grid size notes and control points snap to. With smaller quantization values, you can draw shorter notes in Piano Roll, and more exact control points in the Automation Editor. + + Quantization - - This lets you select the length of new notes. 'Last Note' means that LMMS will use the note length of the note you last edited + + Note length - - The feature is directly connected to the context-menu on the virtual keyboard, to the left in Piano Roll. After you have chosen the scale you want in this drop-down menu, you can right click on a desired key in the virtual keyboard, and then choose 'Mark current Scale'. LMMS will highlight all notes that belongs to the chosen scale, and in the key you have selected! + + Scale - - Let you select a chord which LMMS then can draw or highlight.You can find the most common chords in this drop-down menu. After you have selected a chord, click anywhere to place the chord, and right click on the virtual keyboard to open context menu and highlight the chord. To return to single note placement, you need to choose 'No chord' in this drop-down menu. + + Chord - - + + Clear ghost notes + + + + + Piano-Roll - %1 - - + + Piano-Roll - no pattern @@ -7785,7 +7128,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PianoView - + Base note @@ -7873,122 +7216,122 @@ Reason: "%2" - + &Redo - + %1+Y - + &Copy - + %1+C - + Cu&t - + %1+X - + &Paste - + %1+V - + Format Actions - + &Bold - + %1+B - + &Italic - + %1+I - + &Underline - + %1+U - + &Left - + %1+L - + C&enter - + %1+E - + &Right - + %1+R - + &Justify - + %1+J - + &Color... @@ -7996,22 +7339,22 @@ Reason: "%2" ProjectRenderer - + WAV (*.wav) - + FLAC (*.flac) - + OGG (*.ogg) - + MP3 (*.mp3) @@ -8115,7 +7458,7 @@ Reason: "%2" - Input Gain: + Input gain: @@ -8145,7 +7488,7 @@ Reason: "%2" - Output Gain: + Output gain: @@ -8153,7 +7496,7 @@ Reason: "%2" ReverbSCControls - Input Gain + Input gain @@ -8168,74 +7511,74 @@ Reason: "%2" - Output Gain + Output gain SampleBuffer - + Fail to open file - + Audio files are limited to %1 MB in size and %2 minutes of playing time - + Open audio file - + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - + Wave-Files (*.wav) - + OGG-Files (*.ogg) - + DrumSynth-Files (*.ds) - + FLAC-Files (*.flac) - + SPEEX-Files (*.spx) - + VOC-Files (*.voc) - + AIFF-Files (*.aif *.aiff) - + AU-Files (*.au) - + RAW-Files (*.raw) @@ -8243,32 +7586,32 @@ Reason: "%2" SampleTCOView - - double-click to select sample + + Double-click to open sample - + Delete (middle mousebutton) - + Cut - + Copy - + Paste - + Mute/unmute (<%1> + middle click) @@ -8276,18 +7619,18 @@ Reason: "%2" SampleTrack - + Volume - + Panning - - + + Sample track @@ -8295,32 +7638,32 @@ Reason: "%2" SampleTrackView - + Track volume - + Channel volume: - + VOL - + Panning - + Panning: - + PAN @@ -8334,7 +7677,7 @@ Reason: "%2" - + General settings @@ -8345,336 +7688,210 @@ Reason: "%2" - - Reset to default-value + + Reset to default value - + MISC - - Enable tooltips + + Use built-in NaN handler - - Show restart warning after changing settings - - - - - Display volume as dBFS - - - - - Compress project files per default - - - - - One instrument track window mode - - - - - HQ-mode for output audio-device - - - - - Compact track buttons - - - - - Sync VST plugins to host playback - - - - - Enable note labels in piano roll - - - - - Enable waveform display by default - - - - - Keep effects running even without input - - - - - Create backup file when saving a project - - - - - Reopen last project on start - - - - + PLUGIN EMBEDDING - + No embedding - + Embed using Qt API - + Embed using native Win32 API - + Embed using XEmbed protocol - + LANGUAGE - - + + Paths - + Directories - - LMMS working directory - - - - - Themes directory - - - - - Background artwork - - - - - VST-plugin directory - - - - - GIG directory - - - - - SF2 directory - - - - - LADSPA plugin directories - - - - - STK rawwave directory - - - - - Default Soundfont File - - - - - + + Performance settings - + Auto save - + Enable auto-save - + Allow auto-save while playing - + UI effects vs. performance - + Smooth scroll in Song Editor - + Show playback cursor in AudioFileProcessor - - + + Audio settings - + AUDIO INTERFACE - - + + MIDI settings - + MIDI INTERFACE - + OK - + Cancel - + Restart LMMS - - Please note that most changes won't take effect until you restart LMMS!<br><br>Do you want to restart now? <b>All your unsaved works will be lost!<b> + + Please note that most changes won't take effect until you restart LMMS! - + Frames: %1 Latency: %2 ms - - Here you can setup the internal buffer-size used by LMMS. Smaller values result in a lower latency but also may cause unusable sound or bad performance, especially on older computers or systems with a non-realtime kernel. - - - - + Choose LMMS working directory - + Choose your GIG directory - + Choose your SF2 directory - + Choose your VST-plugin directory - + Choose artwork-theme directory - + Choose LADSPA plugin directory - + Choose STK rawwave directory - + Choose default SoundFont - + Choose background artwork - + minutes - + minute - + Disabled - + Auto-save interval: %1 - - - Set the time between automatic backup to %1. -Remember to also save your project manually. You can choose to disable saving while playing, something some older systems find difficult. - - - - - Here you can select your preferred audio-interface. Depending on the configuration of your system during compilation time you can choose between ALSA, JACK, OSS and more. Below you see a box which offers controls to setup the selected audio-interface. - - - - - Here you can select your preferred MIDI-interface. Depending on the configuration of your system during compilation time you can choose between ALSA, OSS and more. Below you see a box which offers controls to setup the selected MIDI-interface. - - Song @@ -8694,12 +7911,12 @@ Remember to also save your project manually. You can choose to disable saving wh - + LMMS Error report - + The following errors occured while loading: @@ -8707,53 +7924,53 @@ Remember to also save your project manually. You can choose to disable saving wh SongEditor - + Could not open file - + Could not open file %1. You probably have no permissions to read this file. Please make sure to have at least read permissions to the file and try again. - + Could not write file - + Could not open %1 for writing. You probably are not permitted to write to this file. Please make sure you have write-access to the file and try again. - + Error in file - + The file %1 seems to contain errors and therefore can't be loaded. - + Version difference - + This %1 was created with LMMS %2. - + template - + project @@ -8764,53 +7981,40 @@ Remember to also save your project manually. You can choose to disable saving wh - TEMPO/BPM + TEMPO - tempo of song + Tempo in BPM - - The tempo of a song is specified in beats per minute (BPM). If you want to change the tempo of your song, change this value. Every measure has four beats, so the tempo in BPM specifies, how many measures / 4 should be played within a minute (or how many measures should be played within four minutes). - - - - + High quality mode - - + + + Master volume - - master volume - - - - - + + + Master pitch - - master pitch - - - - + Value: %1% - + Value: %1 semitones @@ -8818,85 +8022,80 @@ Remember to also save your project manually. You can choose to disable saving wh SongEditorWindow - + Song-Editor - + Play song (Space) - + Record samples from Audio-device - + Record samples from Audio-device while playing song or BB track - + Stop song (Space) - - Click here, if you want to play your whole song. Playing will be started at the song-position-marker (green). You can also move it while playing. - - - - - Click here, if you want to stop playing of your song. The song-position-marker will be set to the start of your song. - - - - + Track actions - + Add beat/bassline - + Add sample-track - + Add automation-track - + Edit actions - + Draw mode - + Edit mode (select and move) - + Timeline controls - + Zoom controls + + + Horizontal zooming + + SpectrumAnalyzerControlDialog @@ -8929,6 +8128,19 @@ Remember to also save your project manually. You can choose to disable saving wh + + StepRecorderWidget + + + Hint + + + + + Move recording curser using <Left/Right> arrows + + + SubWindow @@ -8960,7 +8172,7 @@ Remember to also save your project manually. You can choose to disable saving wh TempoSyncKnob - + Tempo Sync @@ -9010,42 +8222,42 @@ Remember to also save your project manually. You can choose to disable saving wh - + Custom - + Synced to Eight Beats - + Synced to Whole Note - + Synced to Half Note - + Synced to Quarter Note - + Synced to 8th Note - + Synced to 16th Note - + Synced to 32nd Note @@ -9054,36 +8266,36 @@ Remember to also save your project manually. You can choose to disable saving wh TimeDisplayWidget - click to change time units + Time units - + MIN - + SEC - + MSEC - + BAR - + BEAT - + TICK @@ -9091,43 +8303,43 @@ Remember to also save your project manually. You can choose to disable saving wh TimeLineWidget - - Enable/disable auto-scrolling + + Auto scrolling - - Enable/disable loop-points + + Loop points - + After stopping go back to begin - + After stopping go back to position at which playing was started - + After stopping keep position - - + + Hint - + Press <%1> to disable magnetic loop points. - + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. @@ -9176,13 +8388,13 @@ Please make sure you have read-permission to the file and the directory containi - + Cancel - + Please wait... @@ -9202,7 +8414,7 @@ Please make sure you have read-permission to the file and the directory containi - + Importing MIDI-file... @@ -9210,7 +8422,7 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObject - + Mute @@ -9218,58 +8430,58 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObjectView - - Current length - - - - Current position - - Press <%1> and drag to make a copy. + + Current length - - Press <%1> for free resizing. - - - - - Hint - - - - + + %1:%2 (%3:%4 to %5:%6) - + + Press <%1> and drag to make a copy. + + + + + Press <%1> for free resizing. + + + + + Hint + + + + Delete (middle mousebutton) - + Cut - + Copy - + Paste - + Mute/unmute (<%1> + middle click) @@ -9277,63 +8489,59 @@ Please make sure you have read-permission to the file and the directory containi TrackOperationsWidget - - Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. + + Press <%1> while clicking on move-grip to begin a new drag'n'drop action. - - Actions for this track + + Actions - + + Mute - - + + Solo - - Mute this track - - - - + Clone this track - + Remove this track - + Clear this track - + FX %1: %2 - + Assign to new FX Channel - + Turn all recording on - + Turn all recording off @@ -9342,179 +8550,144 @@ Please make sure you have read-permission to the file and the directory containi TripleOscillatorView - Use phase modulation for modulating oscillator 1 with oscillator 2 + Modulate phase of oscillator 1 by oscillator 2 - - Use amplitude modulation for modulating oscillator 1 with oscillator 2 + + Modulate amplitude of oscillator 1 by oscillator 2 - - Mix output of oscillator 1 & 2 + + Mix output of oscillators 1 & 2 - + Synchronize oscillator 1 with oscillator 2 - - Use frequency modulation for modulating oscillator 1 with oscillator 2 + + Modulate frequency of oscillator 1 by oscillator 2 - - Use phase modulation for modulating oscillator 2 with oscillator 3 + + Modulate phase of oscillator 2 by oscillator 3 + + + + + Modulate amplitude of oscillator 2 by oscillator 3 - Use amplitude modulation for modulating oscillator 2 with oscillator 3 + Mix output of oscillators 2 & 3 - - Mix output of oscillator 2 & 3 - - - - + Synchronize oscillator 2 with oscillator 3 - - Use frequency modulation for modulating oscillator 2 with oscillator 3 + + Modulate frequency of oscillator 2 by oscillator 3 - + Osc %1 volume: - - With this knob you can set the volume of oscillator %1. When setting a value of 0 the oscillator is turned off. Otherwise you can hear the oscillator as loud as you set it here. - - - - + Osc %1 panning: - - With this knob you can set the panning of the oscillator %1. A value of -100 means 100% left and a value of 100 moves oscillator-output right. - - - - + Osc %1 coarse detuning: - + semitones - - With this knob you can set the coarse detuning of oscillator %1. You can detune the oscillator 24 semitones (2 octaves) up and down. This is useful for creating sounds with a chord. - - - - + Osc %1 fine detuning left: - - + + cents - - With this knob you can set the fine detuning of oscillator %1 for the left channel. The fine-detuning is ranged between -100 cents and +100 cents. This is useful for creating "fat" sounds. - - - - + Osc %1 fine detuning right: - - With this knob you can set the fine detuning of oscillator %1 for the right channel. The fine-detuning is ranged between -100 cents and +100 cents. This is useful for creating "fat" sounds. - - - - + Osc %1 phase-offset: - - + + degrees - - With this knob you can set the phase-offset of oscillator %1. That means you can move the point within an oscillation where the oscillator begins to oscillate. For example if you have a sine-wave and have a phase-offset of 180 degrees the wave will first go down. It's the same with a square-wave. - - - - + Osc %1 stereo phase-detuning: - - With this knob you can set the stereo phase-detuning of oscillator %1. The stereo phase-detuning specifies the size of the difference between the phase-offset of left and right channel. This is very good for creating wide stereo sounds. + + Sine wave - - Use a sine-wave for current oscillator. + + Triangle wave - - Use a triangle-wave for current oscillator. + + Saw wave - - Use a saw-wave for current oscillator. + + Square wave - - Use a square-wave for current oscillator. + + Moog-like saw wave - - Use a moog-like saw-wave for current oscillator. + + Exponential wave - - Use an exponential wave for current oscillator. + + White noise - - Use white-noise for current oscillator. - - - - - Use a user-defined waveform for current oscillator. + + User-defined wave @@ -9539,113 +8712,73 @@ Please make sure you have read-permission to the file and the directory containi VestigeInstrumentView - - Open other VST-plugin + + + Open VST plugin - - Click here, if you want to open another VST-plugin. After clicking on this button, a file-open-dialog appears and you can select your file. + + Control VST plugin from LMMS host - - Control VST-plugin from LMMS host + + Open VST plugin preset - - Click here, if you want to control VST-plugin from host. - - - - - Open VST-plugin preset - - - - - Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - - - - + Previous (-) - - - Click here, if you want to switch to another VST-plugin preset program. - - - - + Save preset - - Click here, if you want to save current VST-plugin preset program. - - - - + Next (+) - - Click here to select presets that are currently loaded in VST. - - - - + Show/hide GUI - - Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - - - - + Turn off all notes - - Open VST-plugin - - - - + DLL-files (*.dll) - + EXE-files (*.exe) - - No VST-plugin loaded + + No VST plugin loaded - + Preset - + by - + - VST plugin control @@ -9653,12 +8786,12 @@ Please make sure you have read-permission to the file and the directory containi VisualizationWidget - - click to enable/disable visualization of master-output + + Oscilloscope - + Click to enable @@ -9666,69 +8799,43 @@ Please make sure you have read-permission to the file and the directory containi VstEffectControlDialog - + Show/hide - - Control VST-plugin from LMMS host + + Control VST plugin from LMMS host - - Click here, if you want to control VST-plugin from host. + + Open VST plugin preset - - Open VST-plugin preset - - - - - Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - - - - + Previous (-) - - - Click here, if you want to switch to another VST-plugin preset program. - - - - + Next (+) - - Click here to select presets that are currently loaded in VST. - - - - + Save preset - - Click here, if you want to save current VST-plugin preset program. - - - - - + + Effect by: - + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -9736,69 +8843,69 @@ Please make sure you have read-permission to the file and the directory containi VstPlugin - - + + The VST plugin %1 could not be loaded. - + Open Preset - - + + Vst Plugin Preset (*.fxp *.fxb) - + : default - + " - + ' - + Save Preset - + .fxp - + .FXP - + .FXB - + .fxb - + Loading plugin - + Please wait while loading VST plugin... @@ -9806,147 +8913,147 @@ Please make sure you have read-permission to the file and the directory containi WatsynInstrument - + Volume A1 - + Volume A2 - + Volume B1 - + Volume B2 - + Panning A1 - + Panning A2 - + Panning B1 - + Panning B2 - + Freq. multiplier A1 - + Freq. multiplier A2 - + Freq. multiplier B1 - + Freq. multiplier B2 - + Left detune A1 - + Left detune A2 - + Left detune B1 - + Left detune B2 - + Right detune A1 - + Right detune A2 - + Right detune B1 - + Right detune B2 - + A-B Mix - + A-B Mix envelope amount - + A-B Mix envelope attack - + A-B Mix envelope hold - + A-B Mix envelope decay - + A1-B2 Crosstalk - + A2-A1 modulation - + B2-B1 modulation - + Selected graph @@ -9954,459 +9061,408 @@ Please make sure you have read-permission to the file and the directory containi WatsynView - + Volume - + Panning - + Freq. multiplier - + Left detune - - + + cents - + Right detune - + A-B Mix - + Mix envelope amount - + Mix envelope attack - + Mix envelope hold - + Mix envelope decay - + Crosstalk - + Select oscillator A1 - + Select oscillator A2 - + Select oscillator B1 - + Select oscillator B2 - + Mix output of A2 to A1 - - Modulate amplitude of A1 with output of A2 + + Modulate amplitude of A1 by output of A2 - - Ring-modulate A1 and A2 + + Ring modulate A1 and A2 - - Modulate phase of A1 with output of A2 + + Modulate phase of A1 by output of A2 - + Mix output of B2 to B1 - - Modulate amplitude of B1 with output of B2 + + Modulate amplitude of B1 by output of B2 - - Ring-modulate B1 and B2 + + Ring modulate B1 and B2 - - Modulate phase of B1 with output of B2 + + Modulate phase of B1 by output of B2 - - - - + + + + Draw your own waveform here by dragging your mouse on this graph. - + Load waveform - - Click to load a waveform from a sample file + + Load a waveform from a sample file - + Phase left - - Click to shift phase by -15 degrees + + Shift phase by -15 degrees - + Phase right - - Click to shift phase by +15 degrees + + Shift phase by +15 degrees - + + Normalize - - Click to normalize - - - - + + Invert - - Click to invert - - - - + + Smooth - - Click to smooth - - - - + + Sine wave - - Click for sine wave - - - - - + + + Triangle wave - - Click for triangle wave + + Saw wave - - Click for saw wave - - - - + + Square wave - - - Click for square wave - - Xpressive - + Selected graph - + A1 - + A2 - + A3 - + W1 smoothing - + W2 smoothing - + W3 smoothing - - - PAN1 - - - - - PAN2 - - - REL TRANS + Panning 1 + + + + + Panning 2 + + + + + Rel trans XpressiveView - + + Draw your own waveform here by dragging your mouse on this graph. + + + + Select oscillator W1 - + Select oscillator W2 - + Select oscillator W3 - - Select OUTPUT 1 + + Select output O1 - - Select OUTPUT 2 + + Select output O2 - + Open help window - + + Sine wave - - Click for a sine-wave. + + + Moog-saw wave - - Moog-Saw wave - - - - - Click for a Moog-Saw-wave. - - - - + + Exponential wave - - Click for an exponential wave. - - - - + + Saw wave - - Click here for a saw-wave. + + + User-defined wave - - User defined wave - - - - - Click here for a user-defined shape. - - - - + + Triangle wave - - Click here for a triangle-wave. - - - - + + Square wave - - Click here for a square-wave. - - - - - White noise wave - - - - - Click here for white-noise. - - - + + White noise + + + + WaveInterpolate - + ExpressionValid - + General purpose 1: - + General purpose 2: - + General purpose 3: - + O1 panning: - + O2 panning: - + Release transition: - + Smoothness @@ -10420,12 +9476,12 @@ Please make sure you have read-permission to the file and the directory containi - Filter Frequency + Filter frequency - Filter Resonance + Filter resonance @@ -10435,112 +9491,107 @@ Please make sure you have read-permission to the file and the directory containi - FM Gain + FM gain - Resonance Center Frequency + Resonance center frequency - Resonance Bandwidth + Resonance bandwidth - Forward MIDI Control Change Events + Forward MIDI control change events ZynAddSubFxView - + Portamento: - + PORT - - Filter Frequency: + + Filter frequency: - + FREQ - - Filter Resonance: + + Filter resonance: - + RES - + Bandwidth: - + BW - - FM Gain: + + FM gain: - + FM GAIN - + Resonance center frequency: - + RES CF - + Resonance bandwidth: - + RES BW - - Forward MIDI Control Changes + + Forward MIDI control changes - + Show GUI - - - Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - - audioFileProcessor @@ -10608,100 +9659,72 @@ Please make sure you have read-permission to the file and the directory containi bitInvader - - Samplelength + + Sample length bitInvaderView - - Sample Length + + Sample length - + Draw your own waveform here by dragging your mouse on this graph. - + + Sine wave - - Click for a sine-wave. - - - - + + Triangle wave - - Click here for a triangle-wave. - - - - + + Saw wave - - Click here for a saw-wave. - - - - + + Square wave - - Click here for a square-wave. - - - - - White noise wave - - - - - Click here for white-noise. - - - + - User defined wave - - - - - Click here for a user-defined shape. + White noise + - Smooth + User-defined wave - - Click here to smooth waveform. + + + Smooth waveform - + Interpolation - + Normalize @@ -10750,47 +9773,31 @@ Please make sure you have read-permission to the file and the directory containi - Reset waveform - - - - Click here to reset the wavegraph back to default + Reset wavegraph - Smooth waveform - - - - Click here to apply smoothing to wavegraph + Smooth wavegraph - Increase wavegraph amplitude by 1dB - - - - Click here to increase wavegraph amplitude by 1dB + Increase wavegraph amplitude by 1 dB - Decrease wavegraph amplitude by 1dB - - - - Click here to decrease wavegraph amplitude by 1dB + Decrease wavegraph amplitude by 1 dB - Stereomode Maximum + Stereo mode: maximum @@ -10800,7 +9807,7 @@ Please make sure you have read-permission to the file and the directory containi - Stereomode Average + Stereo mode: average @@ -10810,7 +9817,7 @@ Please make sure you have read-permission to the file and the directory containi - Stereomode Unlinked + Stereo mode: unlinked @@ -10850,20 +9857,20 @@ Please make sure you have read-permission to the file and the directory containi fxLineLcdSpinBox - + Assign to: - - New FX Channel + + New FX channel graphModel - + Graph @@ -10887,12 +9894,12 @@ Please make sure you have read-permission to the file and the directory containi - Distortion Start + Start distortion - Distortion End + End distortion @@ -10902,7 +9909,7 @@ Please make sure you have read-permission to the file and the directory containi - Envelope Slope + Envelope slope @@ -10917,7 +9924,7 @@ Please make sure you have read-permission to the file and the directory containi - Frequency Slope + Frequency slope @@ -10945,7 +9952,7 @@ Please make sure you have read-permission to the file and the directory containi - Frequency Slope: + Frequency slope: @@ -10955,12 +9962,12 @@ Please make sure you have read-permission to the file and the directory containi - Envelope Length: + Envelope length: - Envelope Slope: + Envelope slope: @@ -10975,12 +9982,12 @@ Please make sure you have read-permission to the file and the directory containi - Distortion Start: + Start distortion: - Distortion End: + End distortion: @@ -11017,24 +10024,7 @@ Please make sure you have read-permission to the file and the directory containi - - This dialog displays information on all of the LADSPA plugins LMMS was able to locate. The plugins are divided into five categories based upon an interpretation of the port types and names. - -Available Effects are those that can be used by LMMS. In order for LMMS to be able to use an effect, it must, first and foremost, be an effect, which is to say, it has to have both input channels and output channels. LMMS identifies an input channel as an audio rate port containing 'in' in the name. Output channels are identified by the letters 'out'. Furthermore, the effect must have the same number of inputs and outputs and be real time capable. - -Unavailable Effects are those that were identified as effects, but either didn't have the same number of input and output channels or weren't real time capable. - -Instruments are plugins for which only output channels were identified. - -Analysis Tools are plugins for which only input channels were identified. - -Don't Knows are plugins for which no input or output channels were identified. - -Double clicking any of the plugins will bring up information on the ports. - - - - + Type: @@ -11197,153 +10187,153 @@ Double clicking any of the plugins will bring up information on the ports. lb302SynthView - + Cutoff Freq: - + Resonance: - + Env Mod: - + Decay: - + 303-es-que, 24dB/octave, 3 pole filter - + Slide Decay: - + DIST: - + Saw wave - + Click here for a saw-wave. - + Triangle wave - + Click here for a triangle-wave. - + Square wave - + Click here for a square-wave. - + Rounded square wave - + Click here for a square-wave with a rounded end. - + Moog wave - + Click here for a moog-like wave. - + Sine wave - + Click for a sine-wave. - - + + White noise wave - + Click here for an exponential wave. - + Click here for white-noise. - + Bandlimited saw wave - + Click here for bandlimited saw wave. - + Bandlimited square wave - + Click here for bandlimited square wave. - + Bandlimited triangle wave - + Click here for bandlimited triangle wave. - + Bandlimited moog saw wave - + Click here for bandlimited moog saw wave. @@ -11362,17 +10352,17 @@ Double clicking any of the plugins will bring up information on the ports. - Vibrato Gain + Vibrato gain - Vibrato Freq + Vibrato frequency - Stick Mix + Stick mix @@ -11387,12 +10377,12 @@ Double clicking any of the plugins will bring up information on the ports. - LFO Speed + LFO speed - LFO Depth + LFO depth @@ -11442,7 +10432,7 @@ Double clicking any of the plugins will bring up information on the ports. - Wood1 + Wood 1 @@ -11452,7 +10442,7 @@ Double clicking any of the plugins will bring up information on the ports. - Wood2 + Wood 2 @@ -11462,7 +10452,7 @@ Double clicking any of the plugins will bring up information on the ports. - Two Fixed + Two fixed @@ -11472,17 +10462,17 @@ Double clicking any of the plugins will bring up information on the ports. - Tubular Bells + Tubular bells - Uniform Bar + Uniform bar - Tuned Bar + Tuned bar @@ -11492,7 +10482,7 @@ Double clicking any of the plugins will bring up information on the ports. - Tibetan Bowl + Tibetan bowl @@ -11545,32 +10535,32 @@ Double clicking any of the plugins will bring up information on the ports. - Vib Gain + Vibrato gain - Vib Gain: + Vibrato gain: - Vib Freq + Vibrato frequency - Vib Freq: + Vibrato frequency: - Stick Mix + Stick mix - Stick Mix: + Stick mix: @@ -11595,22 +10585,22 @@ Double clicking any of the plugins will bring up information on the ports. - LFO Speed + LFO speed - LFO Speed: + LFO speed: - LFO Depth + LFO depth - LFO Depth: + LFO depth: @@ -11647,81 +10637,51 @@ Double clicking any of the plugins will bring up information on the ports. manageVSTEffectView - + - VST parameter control - - VST Sync + + VST sync - - Click here if you want to synchronize all parameters with VST plugin. - - - - - + + Automated - - Click here if you want to display automated parameters only. - - - - + Close - - - Close VST effect knob-controller window. - - manageVestigeInstrumentView - - + + - VST plugin control - + VST Sync - - Click here if you want to synchronize all parameters with VST plugin. - - - - - + + Automated - - Click here if you want to display automated parameters only. - - - - + Close - - - Close VST plugin knob-controller window. - - organicInstrument @@ -11744,58 +10704,43 @@ Double clicking any of the plugins will bring up information on the ports. - - The distortion knob adds distortion to the output of the instrument. - - - - + Volume: - - The volume knob controls the volume of the output of the instrument. It is cumulative with the instrument window's volume control. - - - - + Randomise - - The randomize button randomizes all knobs except the harmonics,main volume and distortion knobs. - - - - - + + Osc %1 waveform: - + Osc %1 volume: - + Osc %1 panning: - + Osc %1 stereo detuning - + cents - + Osc %1 harmonic: @@ -11866,12 +10811,12 @@ Double clicking any of the plugins will bring up information on the ports. - + Customizable wavetable synthesizer - + An oversampling bitcrusher @@ -11886,7 +10831,7 @@ Double clicking any of the plugins will bring up information on the ports. - + A 4-band Crossover Equalizer @@ -11901,22 +10846,22 @@ Double clicking any of the plugins will bring up information on the ports. - + plugin for processing dynamics in a flexible way - + A native eq plugin - + A native flanger plugin - + Emulation of GameBoy (TM) APU @@ -11926,7 +10871,7 @@ Double clicking any of the plugins will bring up information on the ports. - + Filter for importing Hydrogen files into LMMS @@ -11941,7 +10886,7 @@ Double clicking any of the plugins will bring up information on the ports. - + plugin for using arbitrary LADSPA-effects inside LMMS. @@ -11951,17 +10896,17 @@ Double clicking any of the plugins will bring up information on the ports. - + Filter for exporting MIDI-files from LMMS - + Filter for importing MIDI-files into LMMS - + Monstrous 3-oscillator synth with modulation matrix @@ -11971,12 +10916,12 @@ Double clicking any of the plugins will bring up information on the ports. - + A NES-like synthesizer - + 2-operator FM Synth @@ -11991,12 +10936,12 @@ Double clicking any of the plugins will bring up information on the ports. - + Plugin for controlling knobs with sound peaks - + Reverb algorithm by Sean Costello @@ -12006,12 +10951,12 @@ Double clicking any of the plugins will bring up information on the ports. - + LMMS port of sfxr - + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. @@ -12042,12 +10987,12 @@ This chip was used in the Commodore 64 computer. - + VST-host for using VST(i)-plugins within LMMS - + Vibrating string modeler @@ -12057,17 +11002,17 @@ This chip was used in the Commodore 64 computer. - + 4-oscillator modulatable wavetable synth - + plugin for waveshaping - + Mathematical expression parser @@ -12101,22 +11046,22 @@ This chip was used in the Commodore 64 computer. - Reverb Roomsize + Reverb room size - Reverb Damping + Reverb damping - Reverb Width + Reverb width - Reverb Level + Reverb level @@ -12126,26 +11071,26 @@ This chip was used in the Commodore 64 computer. - Chorus Lines + Chorus voices - Chorus Level + Chorus level - Chorus Speed + Chorus speed - Chorus Depth + Chorus depth - + A soundfont %1 could not be loaded. @@ -12153,92 +11098,69 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView - - Open other SoundFont file - - - - - Click here to open another SF2 file - - - - - Choose the patch - - - - - Gain - - - - - Apply reverb (if supported) - - - - - This button enables the reverb effect. This is useful for cool effects, but only works on files that support it. - - - - - Reverb Roomsize: - - - - - Reverb Damping: - - - - - Reverb Width: - - - - - Reverb Level: - - - - - Apply chorus (if supported) - - - - - This button enables the chorus effect. This is useful for cool echo effects, but only works on files that support it. - - - - - Chorus Lines: - - - - - Chorus Level: - - - - - Chorus Speed: - - - - - Chorus Depth: - - - - + + Open SoundFont file - + + Choose patch + + + + + Gain: + + + + + Apply reverb (if supported) + + + + + Room size: + + + + + Damping: + + + + + Width: + + + + + + Level: + + + + + Apply chorus (if supported) + + + + + Voices: + + + + + Speed: + + + + + Depth: + + + + SoundFont Files (*.sf2 *.sf3) @@ -12246,40 +11168,40 @@ This chip was used in the Commodore 64 computer. sfxrInstrument - - Wave Form + + Wave sidInstrument - - - Cutoff - - - Resonance + Cutoff frequency + Resonance + + + + Filter type - + Voice 3 off - + Volume - + Chip model @@ -12287,173 +11209,127 @@ This chip was used in the Commodore 64 computer. sidInstrumentView - + Volume: - + Resonance: - - + + Cutoff frequency: - - High-Pass filter + + High-pass filter - - Band-Pass filter + + Band-pass filter - - Low-Pass filter + + Low-pass filter - - Voice3 Off + + Voice 3 off - + MOS6581 SID - + MOS8580 SID - - + + Attack: - - Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. - - - - - + + Decay: - - Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. - - - - + Sustain: - - Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. - - - - - + + Release: - - The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. - - - - - + Pulse Width: - - The Pulse Width resolution allows the width to be smoothly swept with no discernable stepping. The Pulse waveform on Oscillator %1 must be selected to have any audible effect. - - - - + Coarse: - - The Coarse detuning allows to detune Voice %1 one octave up or down. + + Pulse wave - - Pulse Wave + + Triangle wave - - Triangle Wave + + Saw wave - - SawTooth - - - - + Noise - + Sync - - Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. + + Ring modulation - - Ring-Mod - - - - - Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. - - - - + Filtered - - When Filtered is on, Voice %1 will be processed through the Filter. When Filtered is off, Voice %1 appears directly at the output, and the Filter has no effect on it. - - - - + Test - - Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. + + Pulse width: @@ -12461,7 +11337,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControlDialog - WIDE + WIDTH @@ -12527,357 +11403,244 @@ This chip was used in the Commodore 64 computer. vestigeInstrument - + Loading plugin - - Please wait while loading VST-plugin... + + Please wait while loading the VST plugin... vibed - + String %1 volume - + String %1 stiffness - + Pick %1 position - + Pickup %1 position - - Pan %1 + + String %1 panning - - Detune %1 + + String %1 detune - - Fuzziness %1 + + String %1 fuzziness - - Length %1 + + String %1 length - + Impulse %1 - - Octave %1 + + String %1 vibedView - - Volume: + + String volume: - - The 'V' knob sets the volume of the selected string. - - - - + String stiffness: - - The 'S' knob sets the stiffness of the selected string. The stiffness of the string affects how long the string will ring out. The lower the setting, the longer the string will ring. - - - - + Pick position: - - The 'P' knob sets the position where the selected string will be 'picked'. The lower the setting the closer the pick is to the bridge. - - - - + Pickup position: - - The 'PU' knob sets the position where the vibrations will be monitored for the selected string. The lower the setting, the closer the pickup is to the bridge. + + String panning: - - Pan: + + String detune: - - The Pan knob determines the location of the selected string in the stereo field. + + String fuzziness: - - Detune: + + String length: - - The Detune knob modifies the pitch of the selected string. Settings less than zero will cause the string to sound flat. Settings greater than zero will cause the string to sound sharp. + + Impulse - - Fuzziness: - - - - - The Slap knob adds a bit of fuzz to the selected string which is most apparent during the attack, though it can also be used to make the string sound more 'metallic'. - - - - - Length: - - - - - The Length knob sets the length of the selected string. Longer strings will both ring longer and sound brighter, however, they will also eat up more CPU cycles. - - - - - Impulse or initial state - - - - - The 'Imp' selector determines whether the waveform in the graph is to be treated as an impulse imparted to the string by the pick or the initial state of the string. - - - - + Octave - - The Octave selector is used to choose which harmonic of the note the string will ring at. For example, '-2' means the string will ring two octaves below the fundamental, 'F' means the string will ring at the fundamental, and '6' means the string will ring six octaves above the fundamental. - - - - + Impulse Editor - - The waveform editor provides control over the initial state or impulse that is used to start the string vibrating. The buttons to the right of the graph will initialize the waveform to the selected type. The '?' button will load a waveform from a file--only the first 128 samples will be loaded. - -The waveform can also be drawn in the graph. - -The 'S' button will smooth the waveform. - -The 'N' button will normalize the waveform. - - - - - Vibed models up to nine independently vibrating strings. The 'String' selector allows you to choose which string is being edited. The 'Imp' selector chooses whether the graph represents an impulse or the initial state of the string. The 'Octave' selector chooses which harmonic the string should vibrate at. - -The graph allows you to control the initial state or impulse used to set the string in motion. - -The 'V' knob controls the volume. The 'S' knob controls the string's stiffness. The 'P' knob controls the pick position. The 'PU' knob controls the pickup position. - -'Pan' and 'Detune' hopefully don't need explanation. The 'Slap' knob adds a bit of fuzz to the sound of the string. - -The 'Length' knob controls the length of the string. - -The LED in the lower right corner of the waveform editor determines whether the string is active in the current instrument. - - - - + Enable waveform - - Click here to enable/disable waveform. + + Enable/disable string - + String - - The String selector is used to choose which string the controls are editing. A Vibed instrument can contain up to nine independently vibrating strings. The LED in the lower right corner of the waveform editor indicates whether the selected string is active. - - - - + + Sine wave - - Use a sine-wave for current oscillator. - - - - + + Triangle wave - - Use a triangle-wave for current oscillator. - - - - + + Saw wave - - Use a saw-wave for current oscillator. - - - - + + Square wave - - Use a square-wave for current oscillator. + + + White noise - - White noise wave + + + User-defined wave - - Use white-noise for current oscillator. + + + Smooth waveform - - User defined wave - - - - - Use a user-defined waveform for current oscillator. - - - - - Smooth - - - - - Click here to smooth waveform. - - - - - Normalize - - - - - Click here to normalize waveform. + + + Normalize waveform voiceObject - + Voice %1 pulse width - + Voice %1 attack - + Voice %1 decay - + Voice %1 sustain - + Voice %1 release - + Voice %1 coarse detuning - + Voice %1 wave shape - + Voice %1 sync - + Voice %1 ring modulate - + Voice %1 filtered - + Voice %1 test @@ -12906,42 +11669,26 @@ The LED in the lower right corner of the waveform editor determines whether the - Reset waveform - - - - Click here to reset the wavegraph back to default + Reset wavegraph - Smooth waveform - - - - Click here to apply smoothing to wavegraph + Smooth wavegraph - Increase graph amplitude by 1dB - - - - Click here to increase wavegraph amplitude by 1dB + Increase wavegraph amplitude by 1 dB - Decrease graph amplitude by 1dB - - - - Click here to decrease wavegraph amplitude by 1dB + Decrease wavegraph amplitude by 1 dB @@ -12951,7 +11698,7 @@ The LED in the lower right corner of the waveform editor determines whether the - Clip input signal to 0dB + Clip input signal to 0 dB diff --git a/data/locale/uk.ts b/data/locale/uk.ts index b6c803ef0..d5236a7aa 100644 --- a/data/locale/uk.ts +++ b/data/locale/uk.ts @@ -7359,7 +7359,7 @@ Please make sure you have read-permission to the file and the directory containi Vst Plugin Preset (*.fxp *.fxb) - Передустановка VST плагіна (*.fxp, *.fxb) + Передустановка VST плагіна (*.fxp *.fxb) : default diff --git a/data/themes/classic/clear_ghost_note.png b/data/themes/classic/clear_ghost_note.png new file mode 100644 index 000000000..c9f85a2b4 Binary files /dev/null and b/data/themes/classic/clear_ghost_note.png differ diff --git a/data/themes/classic/ghost_note.png b/data/themes/classic/ghost_note.png new file mode 100644 index 000000000..532245e11 Binary files /dev/null and b/data/themes/classic/ghost_note.png differ diff --git a/data/themes/classic/record_step_off.png b/data/themes/classic/record_step_off.png new file mode 100644 index 000000000..8da17a910 Binary files /dev/null and b/data/themes/classic/record_step_off.png differ diff --git a/data/themes/classic/record_step_on.png b/data/themes/classic/record_step_on.png new file mode 100644 index 000000000..700ba97f3 Binary files /dev/null and b/data/themes/classic/record_step_on.png differ diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index be17ee58f..12d90981d 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -127,6 +127,10 @@ PianoRoll { qproperty-noteOpacity: 128; qproperty-noteBorders: true; /* boolean property, set false to have borderless notes */ qproperty-selectedNoteColor: rgb( 0, 125, 255 ); + qproperty-ghostNoteColor: #000000; + qproperty-ghostNoteTextColor: #ffffff; + qproperty-ghostNoteOpacity: 50; + qproperty-ghostNoteBorders: true; qproperty-barColor: #4afd85; qproperty-markedSemitoneColor: rgba( 0, 255, 200, 60 ); /* Grid colors */ diff --git a/data/themes/default/clear_ghost_note.png b/data/themes/default/clear_ghost_note.png new file mode 100644 index 000000000..c9f85a2b4 Binary files /dev/null and b/data/themes/default/clear_ghost_note.png differ diff --git a/data/themes/default/ghost_note.png b/data/themes/default/ghost_note.png new file mode 100644 index 000000000..073442659 Binary files /dev/null and b/data/themes/default/ghost_note.png differ diff --git a/data/themes/default/record_step_off.png b/data/themes/default/record_step_off.png new file mode 100644 index 000000000..8da17a910 Binary files /dev/null and b/data/themes/default/record_step_off.png differ diff --git a/data/themes/default/record_step_on.png b/data/themes/default/record_step_on.png new file mode 100644 index 000000000..700ba97f3 Binary files /dev/null and b/data/themes/default/record_step_on.png differ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 625d8657a..5d889295c 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -146,6 +146,10 @@ PianoRoll { qproperty-noteOpacity: 165; qproperty-noteBorders: false; /* boolean property, set false to have borderless notes */ qproperty-selectedNoteColor: #064d79; + qproperty-ghostNoteColor: #000000; + qproperty-ghostNoteTextColor: #ffffff; + qproperty-ghostNoteOpacity: 50; + qproperty-ghostNoteBorders: false; qproperty-barColor: #078f3a; qproperty-markedSemitoneColor: rgba(255, 255, 255, 30); /* Grid colors */ diff --git a/debian/calf-ladspa.install b/debian/calf-ladspa.install new file mode 100644 index 000000000..c25e49dbc --- /dev/null +++ b/debian/calf-ladspa.install @@ -0,0 +1 @@ +usr/lib/*/lmms/ladspa/calf.so usr/lib/ladspa diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..c44b1790c --- /dev/null +++ b/debian/changelog @@ -0,0 +1,382 @@ +lmms (1.2.0~rc7.1) unstable; urgency=low + + * Upstream integration. + * Drop Debian menu entry (policy 9.6). + + -- Javier Serrano Polo Sat, 03 Nov 2018 02:43:42 +0100 + +lmms (1.1.3-8) unstable; urgency=low + + * Fix build (Closes: #897806). + * Allow recommendations (Closes: #891756). + + -- Javier Serrano Polo Sat, 13 Oct 2018 17:05:54 +0200 + +lmms (1.1.3-7.1) unstable; urgency=high + + * Non-maintainer upload. + + [ Javier Serrano Polo ] + * Fix build with Clang. + * Fix build with GCC 7 (Closes: #853527). + + [ Boyuan Yang ] + * Remove Patrick Winnertz from uploaders list. (Closes: #867759) + Thank you for your previous contributions! + + -- Boyuan Yang <073plan@gmail.com> Sat, 10 Mar 2018 11:32:05 +0800 + +lmms (1.1.3-7) unstable; urgency=low + + [ Javier Serrano Polo ] + * Separate flags for WINE_BUILD_FLAGS to fix build problem on i386. + + -- Petter Reinholdtsen Mon, 26 Dec 2016 07:36:54 +0000 + +lmms (1.1.3-6) unstable; urgency=low + + [ Javier Serrano Polo ] + * Build with install RUNPATH (reproducibility). + + -- Petter Reinholdtsen Sun, 25 Dec 2016 09:38:53 +0000 + +lmms (1.1.3-5) unstable; urgency=medium + + [ Javier Serrano Polo ] + * Add Wine stable path to PATH, otherwise wine package would be required. + * Sort plug-in embedded resources (reproducibility). + * Define NDEBUG instead of setting build type to honor optimization choice. + + -- Javier Serrano Polo Sat, 03 Sep 2016 17:31:05 +0200 + +lmms (1.1.3-4) unstable; urgency=medium + + [ Javier Serrano Polo ] + * Sort lists generated from globbing expressions (reproducibility). + * Fixed upgrade that installs recommended packages (Closes: #827039). + * Dropped unused build dependencies. + * Dropped workaround for #824715, wineg++ is fixed. + * Added contributors. + * Honor CONTRIBUTORS override. + * Replace __FILE__ (reproducibility). + * Use build type "Release" (reproducibility). + + -- Javier Serrano Polo Wed, 08 Jun 2016 01:25:37 +0200 + +lmms (1.1.3-3) unstable; urgency=medium + + [ Javier Serrano Polo ] + * Dropped Wine path from PATH. + * Fixed lmms-common upgrade (Closes: #825287). + * Hide vocoder plug-in, it is now in swh-plugins (Closes: #826110). + * Added workaround for #824715 (Closes: #825286). + + -- Petter Reinholdtsen Fri, 03 Jun 2016 08:51:31 +0000 + +lmms (1.1.3-2) unstable; urgency=medium + + [ Javier Serrano Polo ] + * Enabled vst plugin on i386 and amd64 (Closes: #763720). + * Made Calf and vocoder plugins available to other programs (Closes: #758888). + * Fixed version of metalish_dong01.ogg (Closes: #802588). + * Bumped Standards-Version to 3.9.7. Doxygen documentation is not very useful. + * Upgraded to Standards-Version 3.9.8. Ship icons in the default hicolor icon + theme directories. + * Use presets from zynaddsubfx-data. + * Fixed build problems with GCC 6 (Closes: #811697). + * Switch to PulseAudio back end on likely ALSA interception (Closes: #781479). + * Updated copyright information. + * Removed non-free projects. + + -- Petter Reinholdtsen Wed, 18 May 2016 09:09:23 +0000 + +lmms (1.1.3-1) unstable; urgency=low + + * New upstream version 1.1.3 (Closes: #788457). + - Drop well-defined-loop.patch, included upstream. + * Add config for git-buildpackage to use pristine-tar all the time. + * Change homepage url to new http://lmms.io/. + * Added fluid as build-depend. + * New patch find-fluid.patch to find the fluid binary in unstable. + * New patch gcc5.patch to get the code building with gcc 5 in + unstable (Closes: #777989). + * Added man-page-adjustment.patch to fix manpage formatting of AUTHOR + block. Discovered thanks to lintian. + + -- Petter Reinholdtsen Mon, 21 Sep 2015 13:54:02 +0200 + +lmms (1.0.3-5) unstable; urgency=low + + * Make lmms replace and break lmms-common (<< 1.0.0-1) to handle the + fact that /usr/share/menu/lmms moved from lmms-common to lmms in + this version (Closes: #765970). + + -- Petter Reinholdtsen Sun, 19 Oct 2014 23:43:08 +0200 + +lmms (1.0.3-4) unstable; urgency=low + + * Correct watch file to reflect '-src' part of upstream tarball. + * New desktop-argument.patch to let desktops know how to pass files to + lmms. Thanks to lintian for noticing the bug. + * Revert change to enable the vsl plugin in version 1.0.3-3, as it did + not work. Reopen bug #763720. + + -- Petter Reinholdtsen Wed, 08 Oct 2014 19:21:53 +0200 + +lmms (1.0.3-3) unstable; urgency=medium + + * Try to get vsl plugin working on i386 by build depending on libwine-dev + and wine32-dev-tools (Closes: #763720). Unable to get it working on + amd64. + + -- Petter Reinholdtsen Tue, 07 Oct 2014 12:13:16 +0200 + +lmms (1.0.3-2) unstable; urgency=medium + + * Change build rule to only enable ALSA support on Linux (Closes: #754718). + Patch from Steven Chamberlain with input from Guillem Jover. + * Drop libwine-dev build dependency to avoid build failure in the + vst plugin. It should be enabled when we figure out how to do it. + + -- Petter Reinholdtsen Thu, 02 Oct 2014 08:19:53 +0200 + +lmms (1.0.3-1) unstable; urgency=low + + * Move package into Debian Edu git repository and add myself as + co-maintainer. + * Update to upstream version 1.0.3. + * Correct build dependency on i386, use libwine-dev instead of the now + obsolete wine-dev (Closes: #748183). + * Update Standards-Version from 3.9.5 to 3.9.6. + * Add new well-defined-loop.patch to fix compile error triggered by + undefined loop behaviour (Closes: #753177). + + -- Petter Reinholdtsen Wed, 01 Oct 2014 23:00:19 +0200 + +lmms (1.0.0-1) unstable; urgency=low + + * New upstream version (Closes: #703900, #735764, #696271) + * Using a wraped-style control (Closes: #689347) + * Don't suggest vcf as it no longer exists (since a long time) + (Closes: #618350) + * Problems with jack backend were fixed long ago (Closes: #557421) + * No depends/recommends on wine anymore (Closes: #622215, #622080) + + -- Patrick Winnertz Thu, 24 Apr 2014 22:30:17 +0200 + +lmms (0.4.10-2.3) unstable; urgency=low + + * Non maintainer upload. + * Remove wine-related dependencies on amd64, thereby disabling building + VST plugin. (Closes: #676760) + + -- Hilko Bengen Wed, 27 Jun 2012 23:14:40 +0200 + +lmms (0.4.10-2.2) unstable; urgency=low + + * Non maintainer upload. + * Fix build failure with GCC 4.7. Closes: #667265. + * Turn on verbose build. + + -- Matthias Klose Tue, 17 Apr 2012 14:08:53 +0200 + +lmms (0.4.10-2.1) unstable; urgency=low + + * Non-maintainer upload. + * Fix FTBFS on GNU/kFreeBSD. Thanks Pino Toscano. (Closes: #641064) + + -- Robert Millan Fri, 27 Apr 2012 22:55:55 +0200 + +lmms (0.4.10-2) unstable; urgency=low + + * Removed build-dep on libestools2.0-dev (Closes: #614975) + + -- Patrick Winnertz Fri, 11 Mar 2011 09:37:43 +0100 + +lmms (0.4.10-1) unstable; urgency=low + + * Imported Upstream version 0.4.10 + * changed mode of patch + * Add source/format with 3.0 (quilt) and rearrange source a bit + * Bump standarts version to 3.9.1 - no further changes needed + + -- Patrick Winnertz Fri, 11 Feb 2011 20:03:06 +0100 + +lmms (0.4.7-2) unstable; urgency=low + + [ Reinhard Tartler ] + * Depend on wine only on i386 and amd64 (Closes: #590950) + + [ Patrick Winnertz ] + * Uploading patch from siretart, thanks for helping. + + -- Patrick Winnertz Mon, 02 Aug 2010 10:13:28 +0200 + +lmms (0.4.7-1) unstable; urgency=low + + * New upstream version + + -- Patrick Winnertz Thu, 29 Jul 2010 16:24:00 +0200 + +lmms (0.4.6-2) unstable; urgency=low + + * Build-depend on libestools2.0-dev (Closes: #589882) + + -- Patrick Winnertz Wed, 28 Jul 2010 11:55:16 +0200 + +lmms (0.4.6-1) unstable; urgency=low + + * New upstream version (Closes: #565733) + * Bumped standards version to 3.8.3, no further changes needed + + -- Patrick Winnertz Sun, 24 Jan 2010 16:40:39 +0100 + +lmms (0.4.5-1) unstable; urgency=low + + * New upstream version (Closes: #543645) + * Fix FTBFS on amd64 (Closes: #540671 #543017) + + -- Patrick Winnertz Fri, 11 Sep 2009 09:56:45 +0200 + +lmms (0.4.4-1) unstable; urgency=low + + * New upstream version (Closes: #511363) + * Provide menu file (Closes: #514905) + - The menufile is included in lmms-common and not in lmms + as it is not arch specific + * Bumped standards version to 3.8.2 no further changes needed + + -- Patrick Winnertz Wed, 05 Aug 2009 20:46:40 +0200 + +lmms (0.3.2-1) unstable; urgency=low + + * Decrease wine dependency to wine-bin as suggested. (Closes: #446163) + * Acknowlegded NMU from Pierre Habouzit in order to + fix FTBFS with gcc-4.3 which (Closes: #462202) + * Now including the singerbot plugin. (Closes: #443224) + * Add patch to prevent lmms from crashing. + + -- Patrick Winnertz Mon, 17 Mar 2008 10:56:12 +0100 + +lmms (0.3.1-1.1) unstable; urgency=low + + * Non-maintainer upload. + * Add g++-4.3.patch to fix g++-4.3 FTBFS (Closes: 462202). + + -- Pierre Habouzit Sun, 16 Mar 2008 23:21:56 +0000 + +lmms (0.3.1-1) unstable; urgency=low + + * Packaging new upstream release. + * Install Upstream Changelog (Closes: #441477) + Thanks to Felipe Sateler + * Lowered the caps dependency to Recommends (Closes: #446163) + * Added -i/-a to the build targets in rules in order to make sure that only + (in)dep packages are build. + * Changed my maintainer address + * Added patch to remove stereo_enhancer plugin which has a ftbfs with gcc + 4.2.3 + * Added imagemagick as build-dep since we have to convert a .png to a .xpm + via convert + * Doesn't install upstreams menu file, since it's outdated.. instead use + our own. + * Standard-Version bump to 3.7.3 + * Remove Homepage field from Description and create a own Header + * Added postinst and postrm for lmms-common to call update-menu if available + (this has to be done manually, since we doesn't use dh_installmenu to install + the menu file) + + -- Patrick Winnertz Thu, 06 Dec 2007 07:08:04 +0100 + +lmms (0.3.0-1) unstable; urgency=low + + [ Tobias Doerffel ] + * New upstream release. (Closes: #439301) + * Removed patch from Thomas Girard as upstream merged changes + + [ Patrick Winnertz ] + * Moved manpage into correct package (lmms) + * Removed manuall installation of Upstream Changelog, thanks to the power of + debhelper ;-) + * FTBFS with gcc 4.2 is fixed by upstream (Closes: #383295) + * lmms has now a proper menu entry (Closes: #383406) + * lmms depends now on the same version of lmms-common (Closes: #389037) + * fixed by upstream: arpeggio status is now saved (Closes: #433262) + * Added build-depends libqt3-i18n (Closes: #384406) + * Added watch file for lmms (Closes: #439302) + Thanks to Raphael Geissert + * Improved copyright file + * Doesn't build libsingerbot since it is experimental and doesn't work + correct yet + * Added several build-dependencys (libstk0-dev, libestools1.2-dev, ladspa-sdk, + libflac-dev, libwine-dev [i386], libqt3-i18n, libasound2-dev, + festival-dev, dpatch ) + * Take over this package from Florian Ragwitz, so set myself as maintainer + * Add a depends on a specific version of lmms-common + * Added several new dependencys to lmms + * Improved description of lmms and lmms-common + * Die on errors of clean, but don't die if the makefile doesn't exist + * Added watch file + + -- Patrick Winnertz Fri, 24 Aug 2007 08:23:34 +0200 + +lmms (0.2.1-1.1) unstable; urgency=high + + * Non-maintainer Upload + * Add Patch by Thomas Girard for segfault right after + lmms starting up (Closes: 382491) + + -- Michael Ablassmeier Tue, 5 Sep 2006 12:00:40 +0200 + +lmms (0.2.1-1) unstable; urgency=low + + * New upstream release. + * Bump up Standards-Version to 3.7.2 (no changes). + * Use DH_COMPAT 5. + + -- Florian Ragwitz Sun, 13 Aug 2006 14:40:13 +0200 + +lmms (0.1.4-1) unstable; urgency=low + + * New upstream release. + + -- Florian Ragwitz Sat, 4 Feb 2006 07:16:47 +0100 + +lmms (0.1.3-1) unstable; urgency=low + + * New upstream release. + * debian/lmms.1 was included by upstream. Removed it from debian/. + * Install lmms.1 in lmms-common instead of lmms to safe some mirror space. + * Added a lintian override for the above, as lintian is not smart enough to + check for manpages in other packages from the same source package on which + a package with a missing manpage depends. + + -- Florian Ragwitz Wed, 1 Feb 2006 18:28:42 +0100 + +lmms (0.1.2-1) unstable; urgency=low + + * New upstream release. + + -- Florian Ragwitz Thu, 22 Dec 2005 16:22:50 +0100 + +lmms (0.1.1-2) unstable; urgency=low + + * lmms-common doesn't depend on lmms anymore to remove a circular + dependencies (Closes: #339906). + + -- Florian Ragwitz Sun, 20 Nov 2005 12:27:08 +0100 + +lmms (0.1.1-1) unstable; urgency=low + + * New upstream release. + * Changed Maintainer address. + * Added libjack-dev to Build-Depends. + + -- Florian Ragwitz Mon, 31 Oct 2005 10:48:36 +0100 + +lmms (0.0.9+0.1.0rc1-1) unstable; urgency=low + + * Initial Release (Closes: #315976). + + -- Florian Ragwitz Fri, 22 Jul 2005 16:33:17 +0200 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 000000000..ec635144f --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..0997676c9 --- /dev/null +++ b/debian/control @@ -0,0 +1,118 @@ +Source: lmms +Section: sound +Priority: optional +Maintainer: Debian Edu Packaging Team +Uploaders: + Petter Reinholdtsen , + Israel Dahl , + Javier Serrano Polo , +Build-Depends: + cmake, + debhelper (>= 9.0.0), + fluid, + ladspa-sdk, + libasound2-dev [linux-any], + libfftw3-dev, + libfltk1.3-dev, + libfluidsynth-dev, + libgig-dev, + libjack-jackd2-dev, + libmp3lame-dev, + libpulse-dev, + libqt5x11extras5-dev, + libsamplerate0-dev, + libsdl1.2-dev, + libsndfile1-dev, + libsndio-dev, + libsoundio-dev, + libstk0-dev, + libvorbis-dev, + libxcb-keysyms1-dev, + libxcb-util0-dev, + portaudio19-dev, + qtbase5-private-dev, + qttools5-dev, + wine32-tools [i386] +Standards-Version: 4.2.1.4 +Homepage: http://lmms.io/ +Vcs-Browser: https://salsa.debian.org/debian-edu-pkg-team/lmms.git + +Package: lmms-bin +Architecture: any +Depends: lmms-common (>= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, + stk +Recommends: calf-ladspa, tap-plugins, caps, + lmms-vst-server:i386 (>= ${source:Version}) +Suggests: fil-plugins, mcp-plugins, omins, freepats, fluid-soundfont-gm, + ladspa-plugin +Replaces: lmms-common (<< 1.0.0-1) +Breaks: lmms-common (<< 1.0.0-1) +Multi-Arch: allowed +Description: Linux Multimedia Studio - minimal installation + LMMS aims to be a free alternative to popular (but commercial and closed- + source) programs like FruityLoops, Cubase and Logic giving you the ability of + producing music with your computer by creating cool loops, synthesizing and + mixing sounds, arranging samples, having more fun with your MIDI-keyboard + and much more... + . + LMMS combines the features of a tracker-/sequencer-program (pattern-/channel-/ + sample-/song-/effect-management) and those of powerful synthesizers and + samplers in a modern, user-friendly and easy to use graphical user-interface. + . + This package provides the minimal installation. + +Package: lmms +Architecture: any +Depends: calf-ladspa, lmms-bin, ${misc:Depends} +Description: Linux Multimedia Studio + LMMS aims to be a free alternative to popular (but commercial and closed- + source) programs like FruityLoops, Cubase and Logic giving you the ability of + producing music with your computer by creating cool loops, synthesizing and + mixing sounds, arranging samples, having more fun with your MIDI-keyboard + and much more... + . + LMMS combines the features of a tracker-/sequencer-program (pattern-/channel-/ + sample-/song-/effect-management) and those of powerful synthesizers and + samplers in a modern, user-friendly and easy to use graphical user-interface. + . + This package provides the recommended installation. + +Package: lmms-common +Architecture: all +Depends: zynaddsubfx-data, ${shlibs:Depends}, ${misc:Depends} +Pre-Depends: ${misc:Pre-Depends} +Description: Linux Multimedia Studio - common files + LMMS aims to be a free alternative to popular (but commercial and closed- + source) programs like FruityLoops, Cubase and Logic giving you the ability of + producing music with your computer by creating cool loops, synthesizing and + mixing sounds, arranging samples, having more fun with your MIDI-keyboard + and much more... + . + LMMS combines the features of a tracker-/sequencer-program (pattern-/channel-/ + sample-/song-/effect-management) and those of powerful synthesizers and + samplers in a modern, user-friendly and easy to use graphical user-interface. + . + This package contains the platform independent files such as samples, presets + and some example projects. + +Package: lmms-vst-server +Architecture: i386 +# Order matters to avoid wine64 +Depends: wine32, wine, ${shlibs:Depends}, ${misc:Depends} +Recommends: lmms-bin:any +Description: Linux Multimedia Studio - VST server + This package contains a helper application that loads VST plugins. + +Package: calf-ladspa +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Replaces: calf-plugins (<< 0.0.19) +Provides: ladspa-plugin +Description: Linux Multimedia Studio - Calf LADSPA plugins + Calf is a pack of audio plugins - effects and instruments. The goal is to + create a set of plugins using decent algorithms and parameter settings, + available in a form which is compatible with as many open source applications + as possible. + . + These plugins are distributed as part of Linux Multimedia Studio, but may be + used by other applications. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..3fbf0917e --- /dev/null +++ b/debian/copyright @@ -0,0 +1,1373 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: LMMS +Upstream-Contact: https://github.com/LMMS/lmms +Source: https://github.com/LMMS/lmms/tags +Comment: + This package was debianized by Florian Ragwitz on + Thu, 14 Apr 2005 13:24:57 +0200. + +Files: * +Copyright: + 1998-2000 Paul Kellett (mda-vst.com) + 1999-2004 Dag Lem + 2002 Kjetil S. Matheussen + 2003-2007 Rui Nuno Capela + 2003-2005 Shay Green + 2004-2014 Tobias Doerffel + 2004 Paul Davis + 2004 Torben Hohn + 2005-2008 Danny McRae + 2006-2008 Andreas Brandmaier + 2006-2008 Javier Serrano Polo + 2007-2014 Vesa Kivimäki + 2007-2013 Paul Giblock + 2007 Keith Marshall + 2008-2009 Andrew Kelley + 2008 Attila Herman + 2008 Csaba Hruska + 2013-2014 Raine M. Ekman + 2013 Mike Choi + 2014 David French + 2014 Hannu Haahti + 2014 Lukas Wohlschläger + 2014 Rubén Ibarra Pastor + 2014 Simon Symeonidis + 2014 Wong Cho Ching + Chrissy McManus + Gabriel + Gurjot Singh + Johannes Lorenz + Jonathan Aquilina + Jorrit Rouwe + Juan Fabián Simón + LocoMatt + Oskar Wallgren + Peter Hanappe + Sebastian Tilsch + Tobiasz Karoń (unfa) + Uroš Maravić +License: GPL-2+ + +Files: data/projects/demos/Alf42red-* + data/projects/demos/CapDan/CapDan-TwilightArea-* +Copyright: + 2010-2011 Armin Heller + 2011 Der Daniel (CapDan) +License: CC-BY-SA-3 + +Files: data/projects/demos/AngryLlama-* + data/projects/demos/Ashore.* + data/projects/demos/DnB.* + data/projects/demos/Farbro-* + data/projects/demos/Greippi* + data/projects/demos/Namitryus-* + data/projects/demos/Popsip-* + data/projects/demos/Root84-* + data/projects/demos/Shovon-* + data/projects/demos/Skiessi/* + data/projects/demos/StrictProduction-* + data/projects/demos/Thaledric-* + data/projects/demos/TobyDox-* + data/projects/demos/unfa-* + data/projects/shorties/DirtyLove.* + data/projects/shorties/Root84-* + data/projects/shorties/Skiessi-* + data/projects/shorties/sv-* +Copyright: + LMMS contributors +License: non-free + +Files: data/projects/demos/CapDan/CapDan-ReggaeTry.* + data/projects/demos/CapDan/CapDan-ReggaetonTry.* + data/projects/demos/CapDan/CapDan-ZeroSumGame-* + data/projects/demos/EsoXLB-* + data/projects/demos/Impulslogik-* + data/projects/demos/Momo64-* + data/projects/demos/Oglsdl-* + data/projects/demos/Settel-* + data/projects/demos/Socceroos-* + data/projects/demos/TameAnderson-* + data/projects/demos/Thomasso-* + data/projects/shorties/Crunk* + data/projects/shorties/Greshz-* + data/projects/shorties/Surrender-* +Copyright: + 2009 Achim Settelmeier + 2009 Peter Asplund (Surrender) + 2009 Thomasso + 2010 E.SoX (lowbudget) + 2010 Impulslogik + 2011 Der Daniel (CapDan) + 2011 Sam (socceroos) + 2011 mauro (momo64) + 2011 tame anderson + 2011 Ümit (oglsdl) + Greshz +License: Artistic-2 + +Files: data/projects/demos/Jousboxx-* +Copyright: + Jousboxx +License: CC-BY-SA-4 + +Files: data/projects/CoolSongs/Saber-* +Copyright: + Saber Rastikerdar +License: BSD-2-clause + +Files: include/ladspa.h +Copyright: + 2000-2002 Paul Barton-Davis + 2000-2002 Richard W.E. Furse + 2000-2002 Stefan Westerfeld +License: LGPL-2.1+ + +Files: plugins/LadspaEffect/calf/* +Copyright: + 2001-2010 Krzysztof Foltman + 2001-2010 Markus Schmidt + 2001-2010 Thor Harald Johansen + Alexandre Prokoudine + Carl Hetherington + Christian Holschuh + Damien Zammit + Dave Robillard + David Täht + Hans Baier + Hermann Meyer + Thorsten Wilms + Tom Szilagyi + Torben Hohn +License: LGPL-2+ +Comment: + COPYING is the GNU Lesser General Public License. Headers refer to version 2 of + this license instead of version 2.1. + +Files: plugins/LadspaEffect/calf/src/calf/vumeter.h +Copyright: + 2007 Krzysztof Foltman +License: GPL-2+ + +Files: plugins/LadspaEffect/caps/* +Copyright: + 1998 Robert Bristow-Johnson + 2001-2011 Tim Goetze + 2003-2009 David Yeh + 2004-2005 Steve Harris +License: GPL-2+ + +Files: plugins/LadspaEffect/cmt/* +Copyright: + 1998 Andy Sloane + 1999-2001 David A. Bartold + 2000-2002 Richard W.E. Furse + 2000 Jezar + 2002 Nathaniel Virgo +License: GPL-2+ + +Files: plugins/LadspaEffect/swh/* +Copyright: + 1999 Juhana Sadeharju + 2000-2003 Alexander Ehlert + 2000-2002 Steve Harris + Andy Wingo + Frank Neumann + Jesse Chappell + Joern Nettingsmeier + Marcus Andersson + Mark Knecht + Matthias Nagorni + Nathaniel Virgo + Pascal Haakmat + Patrick Shirkey + Paul Winkler +License: GPL-2+ + +Files: plugins/LadspaEffect/swh/gsm/* +Copyright: + 1992-1994 Carsten Bormann + 1992-1994 Jutta Degener +License: Bormann-Degener + +Files: plugins/LadspaEffect/swh/util/pitchscale.c +Copyright: + 1999 Stephan M. Sprenger +License: WOL + +Files: plugins/LadspaEffect/swh/vocoder_1337.c +Copyright: + Achim Settelmeier + Hexasoft + Josh Green +License: GPL-2+ + +Files: plugins/LadspaEffect/tap/* +Copyright: + 2004 Tom Szilagyi + Alexander Koenig +License: GPL-2+ + +Files: plugins/MidiImport/portsmf/* +Copyright: + 1999-2000 Phil Burk + 1999-2000 Ross Bencina + 2001-2006 Roger B. Dannenberg +License: Expat +Comment: + The Expat license constitutes the entire Portsmf license; however, + the PortMusic community also makes the following non-binding requests: + . + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included along with the + license above. + +Files: plugins/opl2/fmopl.* + plugins/opl2/mididata.h + plugins/opl2/opl.h + plugins/opl2/temuopl.* +Copyright: + 1999-2007 Simon Peter + 1999-2000 Tatsuyuki Satoh +License: LGPL-2.1+ + +Files: plugins/sfxr/readme.* + plugins/sfxr/sfxr.* +Copyright: + 2007 Tomas Pettersson + 2014 Wong Cho Ching +License: Expat and GPL-2+ + +Files: plugins/zynaddsubfx/zynaddsubfx/* +Copyright: + 2002-2009 Nasca Octavian Paul + 2009-2010 Mark McCurry + 2009 Alan Calvert + 2012 Jonathan Liles + Achim Settelmeier + Alexis Ballier + Andre Sklenar + Christopher Oliver + Damien Goutte-Gattat + Daniel Clemente + Emmanuel Saracco + Filipe Coelho + Gerald Folcher + Hans Petter Selasky + Harald Hvaal + Ilario Glasgo + James Morris + Johannes Lorenz + Jérémie Andréi + Lars Luthman + Lieven Moors + Olaf Schulz + Ryan Billing + Stephen Parry + Tobias Doerffel +License: GPL-2+ + +License: Artistic-2 + The Artistic License 2.0 + . + Copyright (c) 2000-2006, The Perl Foundation. + . + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + . + Preamble + . + This license establishes the terms under which a given free software + Package may be copied, modified, distributed, and/or redistributed. + The intent is that the Copyright Holder maintains some artistic + control over the development of that Package while still keeping the + Package available as open source and free software. + . + You are always permitted to make arrangements wholly outside of this + license directly with the Copyright Holder of a given Package. If the + terms of this license do not permit the full use that you propose to + make of the Package, you should contact the Copyright Holder and seek + a different licensing arrangement. + . + Definitions + . + "Copyright Holder" means the individual(s) or organization(s) + named in the copyright notice for the entire Package. + . + "Contributor" means any party that has contributed code or other + material to the Package, in accordance with the Copyright Holder's + procedures. + . + "You" and "your" means any person who would like to copy, + distribute, or modify the Package. + . + "Package" means the collection of files distributed by the + Copyright Holder, and derivatives of that collection and/or of + those files. A given Package may consist of either the Standard + Version, or a Modified Version. + . + "Distribute" means providing a copy of the Package or making it + accessible to anyone else, or in the case of a company or + organization, to others outside of your company or organization. + . + "Distributor Fee" means any fee that you charge for Distributing + this Package or providing support for this Package to another + party. It does not mean licensing fees. + . + "Standard Version" refers to the Package if it has not been + modified, or has been modified only in ways explicitly requested + by the Copyright Holder. + . + "Modified Version" means the Package, if it has been changed, and + such changes were not explicitly requested by the Copyright + Holder. + . + "Original License" means this Artistic License as Distributed with + the Standard Version of the Package, in its current version or as + it may be modified by The Perl Foundation in the future. + . + "Source" form means the source code, documentation source, and + configuration files for the Package. + . + "Compiled" form means the compiled bytecode, object code, binary, + or any other form resulting from mechanical transformation or + translation of the Source form. + . + Permission for Use and Modification Without Distribution + . + (1) You are permitted to use the Standard Version and create and use + Modified Versions for any purpose without restriction, provided that + you do not Distribute the Modified Version. + . + Permissions for Redistribution of the Standard Version + . + (2) You may Distribute verbatim copies of the Source form of the + Standard Version of this Package in any medium without restriction, + either gratis or for a Distributor Fee, provided that you duplicate + all of the original copyright notices and associated disclaimers. At + your discretion, such verbatim copies may or may not include a + Compiled form of the Package. + . + (3) You may apply any bug fixes, portability changes, and other + modifications made available from the Copyright Holder. The resulting + Package will still be considered the Standard Version, and as such + will be subject to the Original License. + . + Distribution of Modified Versions of the Package as Source + . + (4) You may Distribute your Modified Version as Source (either gratis + or for a Distributor Fee, and with or without a Compiled form of the + Modified Version) provided that you clearly document how it differs + from the Standard Version, including, but not limited to, documenting + any non-standard features, executables, or modules, and provided that + you do at least ONE of the following: + . + (a) make the Modified Version available to the Copyright Holder + of the Standard Version, under the Original License, so that the + Copyright Holder may include your modifications in the Standard + Version. + . + (b) ensure that installation of your Modified Version does not + prevent the user installing or running the Standard Version. In + addition, the Modified Version must bear a name that is different + from the name of the Standard Version. + . + (c) allow anyone who receives a copy of the Modified Version to + make the Source form of the Modified Version available to others + under + . + (i) the Original License or + . + (ii) a license that permits the licensee to freely copy, + modify and redistribute the Modified Version using the same + licensing terms that apply to the copy that the licensee + received, and requires that the Source form of the Modified + Version, and of any works derived from it, be made freely + available in that license fees are prohibited but Distributor + Fees are allowed. + . + Distribution of Compiled Forms of the Standard Version + or Modified Versions without the Source + . + (5) You may Distribute Compiled forms of the Standard Version without + the Source, provided that you include complete instructions on how to + get the Source of the Standard Version. Such instructions must be + valid at the time of your distribution. If these instructions, at any + time while you are carrying out such distribution, become invalid, you + must provide new instructions on demand or cease further distribution. + If you provide valid instructions or cease distribution within thirty + days after you become aware that the instructions are invalid, then + you do not forfeit any of your rights under this license. + . + (6) You may Distribute a Modified Version in Compiled form without + the Source, provided that you comply with Section 4 with respect to + the Source of the Modified Version. + . + Aggregating or Linking the Package + . + (7) You may aggregate the Package (either the Standard Version or + Modified Version) with other packages and Distribute the resulting + aggregation provided that you do not charge a licensing fee for the + Package. Distributor Fees are permitted, and licensing fees for other + components in the aggregation are permitted. The terms of this license + apply to the use and Distribution of the Standard or Modified Versions + as included in the aggregation. + . + (8) You are permitted to link Modified and Standard Versions with + other works, to embed the Package in a larger work of your own, or to + build stand-alone binary or bytecode versions of applications that + include the Package, and Distribute the result without restriction, + provided the result does not expose a direct interface to the Package. + . + Items That are Not Considered Part of a Modified Version + . + (9) Works (including, but not limited to, modules and scripts) that + merely extend or make use of the Package, do not, by themselves, cause + the Package to be a Modified Version. In addition, such works are not + considered parts of the Package itself, and are not subject to the + terms of this license. + . + General Provisions + . + (10) Any use, modification, and distribution of the Standard or + Modified Versions is governed by this Artistic License. By using, + modifying or distributing the Package, you accept this license. Do not + use, modify, or distribute the Package, if you do not accept this + license. + . + (11) If your Modified Version has been derived from a Modified + Version made by someone other than you, you are nevertheless required + to ensure that your Modified Version complies with the requirements of + this license. + . + (12) This license does not grant you the right to use any trademark, + service mark, tradename, or logo of the Copyright Holder. + . + (13) This license includes the non-exclusive, worldwide, + free-of-charge patent license to make, have made, use, offer to sell, + sell, import and otherwise transfer the Package with respect to any + patent claims licensable by the Copyright Holder that are necessarily + infringed by the Package. If you institute patent litigation + (including a cross-claim or counterclaim) against any party alleging + that the Package constitutes direct or contributory patent + infringement, then this Artistic License to you shall terminate on the + date that such litigation is filed. + . + (14) Disclaimer of Warranty: + THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS + IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL + LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL + DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: BSD-2-clause + All rights reserved. + . + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: Bormann-Degener + Any use of this software is permitted provided that this notice is not + removed and that neither the authors nor the Technische Universitaet Berlin + are deemed to have made any representations as to the suitability of this + software for any purpose nor are held responsible for any defects of + this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + . + As a matter of courtesy, the authors request to be informed about uses + this software has found, about bugs in this software, and about any + improvements that may be of general interest. + +License: CC-BY-SA-3 + Creative Commons Legal Code + . + Attribution-ShareAlike 3.0 Unported + . + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR + DAMAGES RESULTING FROM ITS USE. + . + License + . + THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE + COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY + COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS + AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + . + BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE + TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY + BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS + CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND + CONDITIONS. + . + 1. Definitions + . + a. "Adaptation" means a work based upon the Work, or upon the Work and + other pre-existing works, such as a translation, adaptation, + derivative work, arrangement of music or other alterations of a + literary or artistic work, or phonogram or performance and includes + cinematographic adaptations or any other form in which the Work may be + recast, transformed, or adapted including in any form recognizably + derived from the original, except that a work that constitutes a + Collection will not be considered an Adaptation for the purpose of + this License. For the avoidance of doubt, where the Work is a musical + work, performance or phonogram, the synchronization of the Work in + timed-relation with a moving image ("synching") will be considered an + Adaptation for the purpose of this License. + b. "Collection" means a collection of literary or artistic works, such as + encyclopedias and anthologies, or performances, phonograms or + broadcasts, or other works or subject matter other than works listed + in Section 1(f) below, which, by reason of the selection and + arrangement of their contents, constitute intellectual creations, in + which the Work is included in its entirety in unmodified form along + with one or more other contributions, each constituting separate and + independent works in themselves, which together are assembled into a + collective whole. A work that constitutes a Collection will not be + considered an Adaptation (as defined below) for the purposes of this + License. + c. "Creative Commons Compatible License" means a license that is listed + at https://creativecommons.org/compatiblelicenses that has been + approved by Creative Commons as being essentially equivalent to this + License, including, at a minimum, because that license: (i) contains + terms that have the same purpose, meaning and effect as the License + Elements of this License; and, (ii) explicitly permits the relicensing + of adaptations of works made available under that license under this + License or a Creative Commons jurisdiction license with the same + License Elements as this License. + d. "Distribute" means to make available to the public the original and + copies of the Work or Adaptation, as appropriate, through sale or + other transfer of ownership. + e. "License Elements" means the following high-level license attributes + as selected by Licensor and indicated in the title of this License: + Attribution, ShareAlike. + f. "Licensor" means the individual, individuals, entity or entities that + offer(s) the Work under the terms of this License. + g. "Original Author" means, in the case of a literary or artistic work, + the individual, individuals, entity or entities who created the Work + or if no individual or entity can be identified, the publisher; and in + addition (i) in the case of a performance the actors, singers, + musicians, dancers, and other persons who act, sing, deliver, declaim, + play in, interpret or otherwise perform literary or artistic works or + expressions of folklore; (ii) in the case of a phonogram the producer + being the person or legal entity who first fixes the sounds of a + performance or other sounds; and, (iii) in the case of broadcasts, the + organization that transmits the broadcast. + h. "Work" means the literary and/or artistic work offered under the terms + of this License including without limitation any production in the + literary, scientific and artistic domain, whatever may be the mode or + form of its expression including digital form, such as a book, + pamphlet and other writing; a lecture, address, sermon or other work + of the same nature; a dramatic or dramatico-musical work; a + choreographic work or entertainment in dumb show; a musical + composition with or without words; a cinematographic work to which are + assimilated works expressed by a process analogous to cinematography; + a work of drawing, painting, architecture, sculpture, engraving or + lithography; a photographic work to which are assimilated works + expressed by a process analogous to photography; a work of applied + art; an illustration, map, plan, sketch or three-dimensional work + relative to geography, topography, architecture or science; a + performance; a broadcast; a phonogram; a compilation of data to the + extent it is protected as a copyrightable work; or a work performed by + a variety or circus performer to the extent it is not otherwise + considered a literary or artistic work. + i. "You" means an individual or entity exercising rights under this + License who has not previously violated the terms of this License with + respect to the Work, or who has received express permission from the + Licensor to exercise rights under this License despite a previous + violation. + j. "Publicly Perform" means to perform public recitations of the Work and + to communicate to the public those public recitations, by any means or + process, including by wire or wireless means or public digital + performances; to make available to the public Works in such a way that + members of the public may access these Works from a place and at a + place individually chosen by them; to perform the Work to the public + by any means or process and the communication to the public of the + performances of the Work, including by public digital performance; to + broadcast and rebroadcast the Work by any means including signs, + sounds or images. + k. "Reproduce" means to make copies of the Work by any means including + without limitation by sound or visual recordings and the right of + fixation and reproducing fixations of the Work, including storage of a + protected performance or phonogram in digital form or other electronic + medium. + . + 2. Fair Dealing Rights. Nothing in this License is intended to reduce, + limit, or restrict any uses free from copyright or rights arising from + limitations or exceptions that are provided for in connection with the + copyright protection under copyright law or other applicable laws. + . + 3. License Grant. Subject to the terms and conditions of this License, + Licensor hereby grants You a worldwide, royalty-free, non-exclusive, + perpetual (for the duration of the applicable copyright) license to + exercise the rights in the Work as stated below: + . + a. to Reproduce the Work, to incorporate the Work into one or more + Collections, and to Reproduce the Work as incorporated in the + Collections; + b. to create and Reproduce Adaptations provided that any such Adaptation, + including any translation in any medium, takes reasonable steps to + clearly label, demarcate or otherwise identify that changes were made + to the original Work. For example, a translation could be marked "The + original work was translated from English to Spanish," or a + modification could indicate "The original work has been modified."; + c. to Distribute and Publicly Perform the Work including as incorporated + in Collections; and, + d. to Distribute and Publicly Perform Adaptations. + e. For the avoidance of doubt: + . + i. Non-waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme cannot be waived, the Licensor + reserves the exclusive right to collect such royalties for any + exercise by You of the rights granted under this License; + ii. Waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme can be waived, the Licensor waives the + exclusive right to collect such royalties for any exercise by You + of the rights granted under this License; and, + iii. Voluntary License Schemes. The Licensor waives the right to + collect royalties, whether individually or, in the event that the + Licensor is a member of a collecting society that administers + voluntary licensing schemes, via that society, from any exercise + by You of the rights granted under this License. + . + The above rights may be exercised in all media and formats whether now + known or hereafter devised. The above rights include the right to make + such modifications as are technically necessary to exercise the rights in + other media and formats. Subject to Section 8(f), all rights not expressly + granted by Licensor are hereby reserved. + . + 4. Restrictions. The license granted in Section 3 above is expressly made + subject to and limited by the following restrictions: + . + a. You may Distribute or Publicly Perform the Work only under the terms + of this License. You must include a copy of, or the Uniform Resource + Identifier (URI) for, this License with every copy of the Work You + Distribute or Publicly Perform. You may not offer or impose any terms + on the Work that restrict the terms of this License or the ability of + the recipient of the Work to exercise the rights granted to that + recipient under the terms of the License. You may not sublicense the + Work. You must keep intact all notices that refer to this License and + to the disclaimer of warranties with every copy of the Work You + Distribute or Publicly Perform. When You Distribute or Publicly + Perform the Work, You may not impose any effective technological + measures on the Work that restrict the ability of a recipient of the + Work from You to exercise the rights granted to that recipient under + the terms of the License. This Section 4(a) applies to the Work as + incorporated in a Collection, but this does not require the Collection + apart from the Work itself to be made subject to the terms of this + License. If You create a Collection, upon notice from any Licensor You + must, to the extent practicable, remove from the Collection any credit + as required by Section 4(c), as requested. If You create an + Adaptation, upon notice from any Licensor You must, to the extent + practicable, remove from the Adaptation any credit as required by + Section 4(c), as requested. + b. You may Distribute or Publicly Perform an Adaptation only under the + terms of: (i) this License; (ii) a later version of this License with + the same License Elements as this License; (iii) a Creative Commons + jurisdiction license (either this or a later license version) that + contains the same License Elements as this License (e.g., + Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible + License. If you license the Adaptation under one of the licenses + mentioned in (iv), you must comply with the terms of that license. If + you license the Adaptation under the terms of any of the licenses + mentioned in (i), (ii) or (iii) (the "Applicable License"), you must + comply with the terms of the Applicable License generally and the + following provisions: (I) You must include a copy of, or the URI for, + the Applicable License with every copy of each Adaptation You + Distribute or Publicly Perform; (II) You may not offer or impose any + terms on the Adaptation that restrict the terms of the Applicable + License or the ability of the recipient of the Adaptation to exercise + the rights granted to that recipient under the terms of the Applicable + License; (III) You must keep intact all notices that refer to the + Applicable License and to the disclaimer of warranties with every copy + of the Work as included in the Adaptation You Distribute or Publicly + Perform; (IV) when You Distribute or Publicly Perform the Adaptation, + You may not impose any effective technological measures on the + Adaptation that restrict the ability of a recipient of the Adaptation + from You to exercise the rights granted to that recipient under the + terms of the Applicable License. This Section 4(b) applies to the + Adaptation as incorporated in a Collection, but this does not require + the Collection apart from the Adaptation itself to be made subject to + the terms of the Applicable License. + c. If You Distribute, or Publicly Perform the Work or any Adaptations or + Collections, You must, unless a request has been made pursuant to + Section 4(a), keep intact all copyright notices for the Work and + provide, reasonable to the medium or means You are utilizing: (i) the + name of the Original Author (or pseudonym, if applicable) if supplied, + and/or if the Original Author and/or Licensor designate another party + or parties (e.g., a sponsor institute, publishing entity, journal) for + attribution ("Attribution Parties") in Licensor's copyright notice, + terms of service or by other reasonable means, the name of such party + or parties; (ii) the title of the Work if supplied; (iii) to the + extent reasonably practicable, the URI, if any, that Licensor + specifies to be associated with the Work, unless such URI does not + refer to the copyright notice or licensing information for the Work; + and (iv) , consistent with Ssection 3(b), in the case of an + Adaptation, a credit identifying the use of the Work in the Adaptation + (e.g., "French translation of the Work by Original Author," or + "Screenplay based on original Work by Original Author"). The credit + required by this Section 4(c) may be implemented in any reasonable + manner; provided, however, that in the case of a Adaptation or + Collection, at a minimum such credit will appear, if a credit for all + contributing authors of the Adaptation or Collection appears, then as + part of these credits and in a manner at least as prominent as the + credits for the other contributing authors. For the avoidance of + doubt, You may only use the credit required by this Section for the + purpose of attribution in the manner set out above and, by exercising + Your rights under this License, You may not implicitly or explicitly + assert or imply any connection with, sponsorship or endorsement by the + Original Author, Licensor and/or Attribution Parties, as appropriate, + of You or Your use of the Work, without the separate, express prior + written permission of the Original Author, Licensor and/or Attribution + Parties. + d. Except as otherwise agreed in writing by the Licensor or as may be + otherwise permitted by applicable law, if You Reproduce, Distribute or + Publicly Perform the Work either by itself or as part of any + Adaptations or Collections, You must not distort, mutilate, modify or + take other derogatory action in relation to the Work which would be + prejudicial to the Original Author's honor or reputation. Licensor + agrees that in those jurisdictions (e.g. Japan), in which any exercise + of the right granted in Section 3(b) of this License (the right to + make Adaptations) would be deemed to be a distortion, mutilation, + modification or other derogatory action prejudicial to the Original + Author's honor and reputation, the Licensor will waive or not assert, + as appropriate, this Section, to the fullest extent permitted by the + applicable national law, to enable You to reasonably exercise Your + right under Section 3(b) of this License (right to make Adaptations) + but not otherwise. + . + 5. Representations, Warranties and Disclaimer + . + UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR + OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY + KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, + INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, + FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF + LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, + WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION + OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + . + 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE + LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR + ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES + ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + . + 7. Termination + . + a. This License and the rights granted hereunder will terminate + automatically upon any breach by You of the terms of this License. + Individuals or entities who have received Adaptations or Collections + from You under this License, however, will not have their licenses + terminated provided such individuals or entities remain in full + compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will + survive any termination of this License. + b. Subject to the above terms and conditions, the license granted here is + perpetual (for the duration of the applicable copyright in the Work). + Notwithstanding the above, Licensor reserves the right to release the + Work under different license terms or to stop distributing the Work at + any time; provided, however that any such election will not serve to + withdraw this License (or any other license that has been, or is + required to be, granted under the terms of this License), and this + License will continue in full force and effect unless terminated as + stated above. + . + 8. Miscellaneous + . + a. Each time You Distribute or Publicly Perform the Work or a Collection, + the Licensor offers to the recipient a license to the Work on the same + terms and conditions as the license granted to You under this License. + b. Each time You Distribute or Publicly Perform an Adaptation, Licensor + offers to the recipient a license to the original Work on the same + terms and conditions as the license granted to You under this License. + c. If any provision of this License is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this License, and without further action + by the parties to this agreement, such provision shall be reformed to + the minimum extent necessary to make such provision valid and + enforceable. + d. No term or provision of this License shall be deemed waived and no + breach consented to unless such waiver or consent shall be in writing + and signed by the party to be charged with such waiver or consent. + e. This License constitutes the entire agreement between the parties with + respect to the Work licensed here. There are no understandings, + agreements or representations with respect to the Work not specified + here. Licensor shall not be bound by any additional provisions that + may appear in any communication from You. This License may not be + modified without the mutual written agreement of the Licensor and You. + f. The rights granted under, and the subject matter referenced, in this + License were drafted utilizing the terminology of the Berne Convention + for the Protection of Literary and Artistic Works (as amended on + September 28, 1979), the Rome Convention of 1961, the WIPO Copyright + Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 + and the Universal Copyright Convention (as revised on July 24, 1971). + These rights and subject matter take effect in the relevant + jurisdiction in which the License terms are sought to be enforced + according to the corresponding provisions of the implementation of + those treaty provisions in the applicable national law. If the + standard suite of rights granted under applicable copyright law + includes additional rights not granted under this License, such + additional rights are deemed to be included in the License; this + License is not intended to restrict the license of any rights under + applicable law. + . + Creative Commons Notice + . + Creative Commons is not a party to this License, and makes no warranty + whatsoever in connection with the Work. Creative Commons will not be + liable to You or any party on any legal theory for any damages + whatsoever, including without limitation any general, special, + incidental or consequential damages arising in connection to this + license. Notwithstanding the foregoing two (2) sentences, if Creative + Commons has expressly identified itself as the Licensor hereunder, it + shall have all rights and obligations of Licensor. + . + Except for the limited purpose of indicating to the public that the + Work is licensed under the CCPL, Creative Commons does not authorize + the use by either party of the trademark "Creative Commons" or any + related trademark or logo of Creative Commons without the prior + written consent of Creative Commons. Any permitted use will be in + compliance with Creative Commons' then-current trademark usage + guidelines, as may be published on its website or otherwise made + available upon request from time to time. For the avoidance of doubt, + this trademark restriction does not form part of the License. + . + Creative Commons may be contacted at https://creativecommons.org/. + +License: CC-BY-SA-4 + Attribution-ShareAlike 4.0 International + . + ======================================================================= + . + Creative Commons Corporation ("Creative Commons") is not a law firm and + does not provide legal services or legal advice. Distribution of + Creative Commons public licenses does not create a lawyer-client or + other relationship. Creative Commons makes its licenses and related + information available on an "as-is" basis. Creative Commons gives no + warranties regarding its licenses, any material licensed under their + terms and conditions, or any related information. Creative Commons + disclaims all liability for damages resulting from their use to the + fullest extent possible. + . + Using Creative Commons Public Licenses + . + Creative Commons public licenses provide a standard set of terms and + conditions that creators and other rights holders may use to share + original works of authorship and other material subject to copyright + and certain other rights specified in the public license below. The + following considerations are for informational purposes only, are not + exhaustive, and do not form part of our licenses. + . + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + . + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + . + ======================================================================= + . + Creative Commons Attribution-ShareAlike 4.0 International Public + License + . + By exercising the Licensed Rights (defined below), You accept and agree + to be bound by the terms and conditions of this Creative Commons + Attribution-ShareAlike 4.0 International Public License ("Public + License"). To the extent this Public License may be interpreted as a + contract, You are granted the Licensed Rights in consideration of Your + acceptance of these terms and conditions, and the Licensor grants You + such rights in consideration of benefits the Licensor receives from + making the Licensed Material available under these terms and + conditions. + . + . + Section 1 -- Definitions. + . + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + . + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + . + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + . + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + . + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + . + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + . + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + . + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + . + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + . + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + . + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + . + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + . + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + . + . + Section 2 -- Scope. + . + a. License grant. + . + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + . + a. reproduce and Share the Licensed Material, in whole or + in part; and + . + b. produce, reproduce, and Share Adapted Material. + . + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + . + 3. Term. The term of this Public License is specified in Section + 6(a). + . + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + . + 5. Downstream recipients. + . + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + . + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + . + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + . + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + . + b. Other rights. + . + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + . + 2. Patent and trademark rights are not licensed under this + Public License. + . + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + . + . + Section 3 -- License Conditions. + . + Your exercise of the Licensed Rights is expressly made subject to the + following conditions. + . + a. Attribution. + . + 1. If You Share the Licensed Material (including in modified + form), You must: + . + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + . + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + . + ii. a copyright notice; + . + iii. a notice that refers to this Public License; + . + iv. a notice that refers to the disclaimer of + warranties; + . + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + . + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + . + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + . + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + . + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + . + b. ShareAlike. + . + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + . + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + . + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + . + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + . + . + Section 4 -- Sui Generis Database Rights. + . + Where the Licensed Rights include Sui Generis Database Rights that + apply to Your use of the Licensed Material: + . + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + . + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + . + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + . + For the avoidance of doubt, this Section 4 supplements and does not + replace Your obligations under this Public License where the Licensed + Rights include other Copyright and Similar Rights. + . + . + Section 5 -- Disclaimer of Warranties and Limitation of Liability. + . + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + . + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + . + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + . + . + Section 6 -- Term and Termination. + . + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + . + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + . + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + . + 2. upon express reinstatement by the Licensor. + . + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + . + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + . + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + . + . + Section 7 -- Other Terms and Conditions. + . + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + . + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + . + . + Section 8 -- Interpretation. + . + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + . + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + . + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + . + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + . + . + ======================================================================= + . + Creative Commons is not a party to its public + licenses. Notwithstanding, Creative Commons may elect to apply one of + its public licenses to material it publishes and in those instances + will be considered the “Licensor.” The text of the Creative Commons + public licenses is dedicated to the public domain under the CC0 Public + Domain Dedication. Except for the limited purpose of indicating that + material is shared under a Creative Commons public license or as + otherwise permitted by the Creative Commons policies published at + creativecommons.org/policies, Creative Commons does not authorize the + use of the trademark "Creative Commons" or any other trademark or logo + of Creative Commons without its prior written consent including, + without limitation, in connection with any unauthorized modifications + to any of its public licenses or any other arrangements, + understandings, or agreements concerning use of licensed material. For + the avoidance of doubt, this paragraph does not form part of the + public licenses. + . + Creative Commons may be contacted at creativecommons.org. + +License: Expat + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License: GPL-2+ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + . + On Debian systems, the complete text of the GNU General Public License + can be found in `/usr/share/common-licenses/GPL-2'. + +License: LGPL-2+ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + . + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of the GNU Library General Public License + can be found in `/usr/share/common-licenses/LGPL-2'. + +License: LGPL-2.1+ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of the GNU Lesser General Public License + can be found in `/usr/share/common-licenses/LGPL-2.1'. + +License: WOL + Permission to use, copy, modify, distribute and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice and this license appear in all source copies. + THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF + ANY KIND. See http://www.dspguru.com/wol.htm for more information. + +License: non-free + This license does not comply with Debian Free Software Guidelines. diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 000000000..cec628c74 --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,2 @@ +[DEFAULT] +pristine-tar = True diff --git a/debian/lmms-bin.install b/debian/lmms-bin.install new file mode 100644 index 000000000..5d19a3103 --- /dev/null +++ b/debian/lmms-bin.install @@ -0,0 +1,7 @@ +usr/bin/lmms +usr/lib/*/lmms/ladspa/[a-b]* +usr/lib/*/lmms/ladspa/caps.so +usr/lib/*/lmms/ladspa/c[b-z]* +usr/lib/*/lmms/ladspa/[d-z]* +usr/lib/*/lmms/lib* +usr/lib/*/lmms/RemoteZynAddSubFx diff --git a/debian/lmms-bin.lintian-overrides b/debian/lmms-bin.lintian-overrides new file mode 100644 index 000000000..45e07c39d --- /dev/null +++ b/debian/lmms-bin.lintian-overrides @@ -0,0 +1,9 @@ +lmms: pkg-has-shlibs-control-file-but-no-actual-shared-libs +lmms: postinst-has-useless-call-to-ldconfig +lmms: postrm-has-useless-call-to-ldconfig + +# env is used to set the environment, then lmms is called. +lmms: desktop-command-not-in-package usr/share/applications/lmms.desktop env + +# Icon is in lmms-common. +lmms: menu-icon-missing usr/share/pixmaps/lmms.xpm diff --git a/debian/lmms-common.docs b/debian/lmms-common.docs new file mode 100644 index 000000000..a7b624a0a --- /dev/null +++ b/debian/lmms-common.docs @@ -0,0 +1 @@ +plugins/LadspaEffect/caps/caps.html diff --git a/debian/lmms-common.install b/debian/lmms-common.install new file mode 100644 index 000000000..467ee8798 --- /dev/null +++ b/debian/lmms-common.install @@ -0,0 +1,25 @@ +usr/share/applications +usr/share/bash-completion +usr/share/icons +usr/share/lmms/[a-o]* +usr/share/lmms/presets/[A-Y]* +usr/share/lmms/projects/demos/Alf42red-* +usr/share/lmms/projects/demos/CapDan +usr/share/lmms/projects/demos/EsoXLB-* +usr/share/lmms/projects/demos/Impulslogik-* +usr/share/lmms/projects/demos/Jousboxx-* +usr/share/lmms/projects/demos/Momo64-* +usr/share/lmms/projects/demos/Oglsdl-* +usr/share/lmms/projects/demos/Settel-* +usr/share/lmms/projects/demos/Socceroos-* +usr/share/lmms/projects/demos/TameAnderson-* +usr/share/lmms/projects/demos/Thomasso-* +usr/share/lmms/projects/shorties/Crunk* +usr/share/lmms/projects/shorties/Greshz-* +usr/share/lmms/projects/shorties/Surrender-* +usr/share/lmms/projects/templates +usr/share/lmms/projects/tutorials +usr/share/lmms/[q-z]* +usr/share/man +usr/share/mime +debian/lmms.xpm usr/share/pixmaps/ diff --git a/debian/lmms-common.links b/debian/lmms-common.links new file mode 100644 index 000000000..75596233c --- /dev/null +++ b/debian/lmms-common.links @@ -0,0 +1 @@ +usr/share/zynaddsubfx/banks usr/share/lmms/presets/ZynAddSubFX diff --git a/debian/lmms-common.maintscript b/debian/lmms-common.maintscript new file mode 100644 index 000000000..15d673556 --- /dev/null +++ b/debian/lmms-common.maintscript @@ -0,0 +1 @@ +dir_to_symlink /usr/share/lmms/presets/ZynAddSubFX ../../zynaddsubfx/banks 1.1.3-2~ diff --git a/debian/lmms-vst-server.install b/debian/lmms-vst-server.install new file mode 100644 index 000000000..1b520479d --- /dev/null +++ b/debian/lmms-vst-server.install @@ -0,0 +1 @@ +usr/lib/*/lmms/RemoteVstPlugin* diff --git a/debian/lmms.xpm b/debian/lmms.xpm new file mode 100644 index 000000000..425e3156d --- /dev/null +++ b/debian/lmms.xpm @@ -0,0 +1,103 @@ +/* XPM */ +static char * lmms_xpm[] = { +"24 24 76 1", +" c None", +". c #208B4D", +"+ c #208C4D", +"@ c #229452", +"# c #239654", +"$ c #239754", +"% c #299557", +"& c #2A9658", +"* c #239B56", +"= c #249B56", +"- c #249C57", +"; c #249D57", +"> c #259E58", +", c #259F59", +"' c #25A059", +") c #25A15A", +"! c #25A25A", +"~ c #25A35A", +"{ c #26A35B", +"] c #26A45B", +"^ c #26A55C", +"/ c #26A65C", +"( c #26A65D", +"_ c #3E9E67", +": c #26A75D", +"< c #28A75E", +"[ c #28A75F", +"} c #27A85E", +"| c #27A95E", +"1 c #27AA5F", +"2 c #27AB5F", +"3 c #29AC60", +"4 c #2AAC61", +"5 c #2FAC64", +"6 c #54A275", +"7 c #33AE67", +"8 c #56A477", +"9 c #2AB365", +"0 c #5BA67B", +"a c #3CB36F", +"b c #41B572", +"c c #64B285", +"d c #50BA7D", +"e c #58B881", +"f c #5CBA84", +"g c #56BC82", +"h c #5FBB86", +"i c #34D07B", +"j c #34D17A", +"k c #34D17B", +"l c #68C28F", +"m c #77C899", +"n c #7DCD9F", +"o c #90C7A8", +"p c #8CD2AA", +"q c #9AD7B4", +"r c #A9DDBF", +"s c #B0E0C5", +"t c #BDDDCB", +"u c #C3DFCF", +"v c #BFE6CF", +"w c #CBE3D5", +"x c #C5E6D3", +"y c #CDE9D9", +"z c #D1EDDD", +"A c #D7EFE2", +"B c #E1F0E8", +"C c #E6F5EC", +"D c #EAF6EF", +"E c #F3FAF6", +"F c #F7FBF9", +"G c #F8FBFA", +"H c #F6FCF9", +"I c #FCFEFD", +"J c #FDFEFE", +"K c #FFFFFF", +" ", +" kiiiiiiiiiiiiiiiiiij ", +" j92222222222222222229i ", +" i22222222222222222222i ", +" i22222222asvb22222222i ", +" i2222223nEKKHp4222222i ", +" i11111dzKKKKKKAg11111i ", +" i|||5qIKKBccBKKJr7|||i ", +" i}}lCKKFo%))&oGKKDm}}i ", +" i::KKKt_*(::(*_tKKK::i ", +" i//KKK@~//////~@KKK//i ", +" i^^KKK^^^^^^^^^^KKK^^i ", +" i]]KKK]]]]]]]]]]KKK]]i ", +" i{{KKKf{{{{{{{{fKKK{{i ", +" i!!KKKKyh!!!!exKKKK!!i ", +" i))KKKKKK))))KKKKKK))i ", +" i''KKKKKK''''KKKKKK''i ", +" i,,KKKKKK,,,,KKKKKK,,i ", +" i>>6uKKw0>>>>6uKKw0>>i ", +" i;;$+88.$;;;;$+88.$;;i ", +" i----##--------##----i ", +" j<==================[i ", +" jiiiiiiiiiiiiiiiiiii ", +" "}; diff --git a/debian/patches/build-amd64-20181013.patch b/debian/patches/build-amd64-20181013.patch new file mode 100644 index 000000000..9f8182903 --- /dev/null +++ b/debian/patches/build-amd64-20181013.patch @@ -0,0 +1,46 @@ +Description: Fix build as of 2018-10-13 + Fix build errors, possibly introduced with GCC 8. +Author: Javier Serrano Polo +Bug-Debian: https://bugs.debian.org/897806 + +Index: lmms-1.1.3/plugins/LadspaEffect/caps/dsp/FPTruncateMode.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/caps/dsp/FPTruncateMode.h ++++ lmms-1.1.3/plugins/LadspaEffect/caps/dsp/FPTruncateMode.h +@@ -40,9 +40,11 @@ class FPTruncateMode + + FPTruncateMode() + { ++#ifdef __i386__ + fstcw (cw0); + cw1 = cw0 | 0xC00; + fldcw (cw1); ++#endif + } + + ~FPTruncateMode() +Index: lmms-1.1.3/plugins/zynaddsubfx/zynaddsubfx/src/Synth/OscilGen.cpp +=================================================================== +--- lmms-1.1.3.orig/plugins/zynaddsubfx/zynaddsubfx/src/Synth/OscilGen.cpp ++++ lmms-1.1.3/plugins/zynaddsubfx/zynaddsubfx/src/Synth/OscilGen.cpp +@@ -33,7 +33,8 @@ + //operations on FFTfreqs + inline void clearAll(fft_t *freqs) + { +- memset(freqs, 0, synth->oscilsize / 2 * sizeof(fft_t)); ++ for(int i = 0; i < synth->oscilsize / 2; ++i) ++ freqs[i] = fft_t(0.0f, 0.0f); + } + + inline void clearDC(fft_t *freqs) +@@ -928,8 +929,8 @@ void OscilGen::getspectrum(int n, float + if(what == 0) { + for(int i = 0; i < n; ++i) + outoscilFFTfreqs[i] = fft_t(spc[i], spc[i]); +- memset(outoscilFFTfreqs + n, 0, +- (synth->oscilsize / 2 - n) * sizeof(fft_t)); ++ for(int i = n; i < synth->oscilsize / 2; ++i) ++ outoscilFFTfreqs[i] = fft_t(0.0f, 0.0f); + adaptiveharmonic(outoscilFFTfreqs, 0.0f); + adaptiveharmonicpostprocess(outoscilFFTfreqs, n - 1); + for(int i = 0; i < n; ++i) diff --git a/debian/patches/clang.patch b/debian/patches/clang.patch new file mode 100644 index 000000000..2e2a0a2f1 --- /dev/null +++ b/debian/patches/clang.patch @@ -0,0 +1,601 @@ +Description: Fix build with Clang + Several issues are present: + - Unused private elements. + - Wrong use of delete. + - Unsupported compiler options. + - Shifting negative values. + - Possible truncations. + - Uninitialized variables. + - Unused code. + - Hiding overloaded virtual functions. + - Declarations outside namespace. + - Mismatched class tag. + . + Be careful editing this patch because allegrosmfwr.cpp has CRLF terminators. +Author: Javier Serrano Polo +Bug: https://github.com/LMMS/lmms/issues/3073 + +Index: lmms-1.1.3/include/AutomatableModel.h +=================================================================== +--- lmms-1.1.3.orig/include/AutomatableModel.h 2017-01-03 13:01:47.000000000 +0100 ++++ lmms-1.1.3/include/AutomatableModel.h 2017-01-03 13:11:25.000000000 +0100 +@@ -307,7 +307,6 @@ + + // most objects will need this temporarily (until sampleExact is + // standard) +- float m_oldValue; + int m_setValueDepth; + + AutoModelVector m_linkedModels; +Index: lmms-1.1.3/plugins/LadspaEffect/calf/CMakeLists.txt +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/CMakeLists.txt 2017-01-03 16:03:14.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/CMakeLists.txt 2017-01-03 16:14:28.000000000 +0100 +@@ -7,11 +7,22 @@ + "${CMAKE_CURRENT_SOURCE_DIR}/src") + INSTALL(TARGETS calf LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") + SET_TARGET_PROPERTIES(calf PROPERTIES PREFIX "") ++ + SET(INLINE_FLAGS "") +-IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") +-SET(INLINE_FLAGS "-finline-functions-called-once -finline-limit=80") ++ ++INCLUDE(CheckCXXCompilerFlag) ++CHECK_CXX_COMPILER_FLAG(-finline-functions CXX_HAVE_INLINE_FUNCTIONS) ++IF(${CXX_HAVE_INLINE_FUNCTIONS}) ++ SET(INLINE_FLAGS "${INLINE_FLAGS} -finline-functions") + ENDIF() +-SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-O2 -finline-functions ${INLINE_FLAGS}") ++CHECK_CXX_COMPILER_FLAG(-finline-functions-called-once ++ CXX_HAVE_INLINE_FUNCTIONS_CALLED_ONCE) ++IF(${CXX_HAVE_INLINE_FUNCTIONS_CALLED_ONCE}) ++ SET(INLINE_FLAGS "${INLINE_FLAGS} -finline-functions-called-once \ ++ -finline-limit=80") ++ENDIF() ++ ++SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-O2 ${INLINE_FLAGS}") + + IF(LMMS_BUILD_WIN32) + ADD_CUSTOM_COMMAND(TARGET calf POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/calf.dll\"") +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/metadata.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/metadata.h 2017-01-03 17:41:17.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/metadata.h 2017-01-03 17:50:40.000000000 +0100 +@@ -51,7 +51,7 @@ + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = false, support_midi = false }; + PLUGIN_NAME_ID_LABEL("filter", "filter", "Filter") + /// do not export mode and inertia as CVs, as those are settings and not parameters +- bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } ++ bool is_cv(int param_no) const { return param_no != par_mode && param_no != par_inertia; } + }; + + /// Filterclavier - metadata +@@ -61,7 +61,7 @@ + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = true, support_midi = true }; + PLUGIN_NAME_ID_LABEL("filterclavier", "filterclavier", "Filterclavier") + /// do not export mode and inertia as CVs, as those are settings and not parameters +- bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } ++ bool is_cv(int param_no) const { return param_no != par_mode && param_no != par_inertia; } + }; + + struct reverb_metadata: public plugin_metadata +@@ -499,7 +499,7 @@ + PLUGIN_NAME_ID_LABEL("organ", "organ", "Organ") + + public: +- plugin_command_info *get_commands(); ++ plugin_command_info *get_commands() const; + const char *const *get_configure_vars() const; + }; + +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules.h 2017-01-03 19:02:59.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules.h 2017-01-03 19:30:35.000000000 +0100 +@@ -89,13 +89,14 @@ + using audio_module::ins; + using audio_module::outs; + using audio_module::params; ++ using FilterClass::calculate_filter; + + dsp::inertia inertia_cutoff, inertia_resonance, inertia_gain; + dsp::once_per_n timer; + bool is_active; + mutable volatile int last_generation, last_calculated_generation; + +- filter_module_with_inertia(float **ins, float **outs, float **params) ++ filter_module_with_inertia() + : inertia_cutoff(dsp::exponential_ramp(128), 20) + , inertia_resonance(dsp::exponential_ramp(128), 20) + , inertia_gain(dsp::exponential_ramp(128), 1.0) +@@ -193,7 +194,7 @@ + mutable float old_cutoff, old_resonance, old_mode; + public: + filter_audio_module() +- : filter_module_with_inertia(ins, outs, params) ++ : filter_module_with_inertia() + { + last_generation = 0; + old_mode = old_resonance = old_cutoff = -1; +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules_comp.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules_comp.h 2017-01-03 19:35:53.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules_comp.h 2017-01-03 19:38:06.000000000 +0100 +@@ -39,10 +39,10 @@ + class gain_reduction_audio_module + { + private: +- float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop; ++ float linSlope, detected, kneeStart, linKneeStart, kneeStop; + float compressedKneeStop, adjKneeStart, thres; + float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_comp; +- mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link; ++ mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection; + mutable volatile int last_generation; + uint32_t srate; + bool is_active; +@@ -69,7 +69,7 @@ + /// Main gate routine by Damien called by various audio modules + class expander_audio_module { + private: +- float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, linKneeStop; ++ float linSlope, detected, kneeStart, linKneeStart, kneeStop, linKneeStop; + float compressedKneeStop, adjKneeStart, range, thres, attack_coeff, release_coeff; + float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_gate; + mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_range, old_trigger, old_mute, old_detection, old_stereo_link; +@@ -142,7 +142,7 @@ + mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; + mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; + CalfScModes sc_mode; +- mutable CalfScModes sc_mode_old, sc_mode_old1; ++ mutable CalfScModes sc_mode_old1; + float f1_active, f2_active; + stereo_in_out_metering meters; + gain_reduction_audio_module compressor; +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules_limit.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules_limit.h 2017-01-03 19:39:00.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules_limit.h 2017-01-03 19:40:20.000000000 +0100 +@@ -37,7 +37,6 @@ + private: + typedef limiter_audio_module AM; + uint32_t clip_inL, clip_inR, clip_outL, clip_outR, asc_led; +- int mode, mode_old; + float meter_inL, meter_inR, meter_outL, meter_outR; + dsp::lookahead_limiter limiter; + public: +@@ -73,7 +72,6 @@ + unsigned int overall_buffer_size; + float *buffer; + int channels; +- float striprel[strips]; + float weight[strips]; + float weight_old[strips]; + float limit_old; +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules_mod.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/modules_mod.h 2017-01-03 19:41:55.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/modules_mod.h 2017-01-03 19:42:19.000000000 +0100 +@@ -160,8 +160,6 @@ + typedef pulsator_audio_module AM; + uint32_t clip_inL, clip_inR, clip_outL, clip_outR; + float meter_inL, meter_inR, meter_outL, meter_outR; +- float offset_old; +- int mode_old; + bool clear_reset; + dsp::simple_lfo lfoL, lfoR; + public: +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/organ.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/organ.h 2017-01-03 19:43:08.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/organ.h 2017-01-03 19:53:55.000000000 +0100 +@@ -318,6 +318,7 @@ + using drawbar_organ::note_on; + using drawbar_organ::note_off; + using drawbar_organ::control_change; ++ using drawbar_organ::pitch_bend; + enum { param_count = drawbar_organ::param_count}; + dsp::organ_parameters par_values; + uint32_t srate; +@@ -338,9 +339,9 @@ + void deactivate(); + uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); + /// No CV inputs for now +- bool is_cv(int param_no) { return false; } ++ bool is_cv(int param_no) const { return false; } + /// Practically all the stuff here is noisy +- bool is_noisy(int param_no) { return true; } ++ bool is_noisy(int param_no) const { return true; } + void execute(int cmd_no); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + char *configure(const char *key, const char *value); +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/preset.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/preset.h 2017-01-03 19:57:02.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/preset.h 2017-01-03 20:00:25.000000000 +0100 +@@ -27,7 +27,7 @@ + + namespace calf_plugins { + +-class plugin_ctl_iface; ++struct plugin_ctl_iface; + + /// Contents of single preset + struct plugin_preset +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/primitives.h +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/calf/primitives.h 2017-01-03 17:36:12.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/calf/primitives.h 2017-01-03 16:22:16.000000000 +0100 +@@ -370,11 +370,6 @@ + next_task = (unsigned)-1; + eob = false; + } +- inline bool is_next_tick() { +- if (time < next_task) +- return true; +- do_tasks(); +- } + inline void next_tick() { + time++; + } +@@ -382,14 +377,6 @@ + timeline.insert(std::pair(time+pos, t)); + next_task = timeline.begin()->first; + } +- void do_tasks() { +- std::multimap::iterator i = timeline.begin(); +- while(i != timeline.end() && i->first == time) { +- i->second->execute(this); +- i->second->dispose(); +- timeline.erase(i); +- } +- } + bool is_eob() { + return eob; + } +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/metadata.cpp +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/metadata.cpp 2017-01-03 17:52:03.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/metadata.cpp 2017-01-03 18:49:18.000000000 +0100 +@@ -29,6 +29,8 @@ + + const char *calf_plugins::calf_copyright_info = "(C) 2001-2009 Krzysztof Foltman, Thor Harald Johanssen, Markus Schmidt and others; license: LGPL"; + ++namespace calf_plugins { ++ + //////////////////////////////////////////////////////////////////////////// + + CALF_PORT_NAMES(flanger) = {"In L", "In R", "Out L", "Out R"}; +@@ -1105,7 +1107,7 @@ + + CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" }; + +-plugin_command_info *organ_metadata::get_commands() ++plugin_command_info *organ_metadata::get_commands() const + { + static plugin_command_info cmds[] = { + { "cmd_panic", "Panic!", "Stop all sounds and reset all controllers" }, +@@ -1439,6 +1441,8 @@ + + //////////////////////////////////////////////////////////////////////////// + ++}; // namespace calf_plugins ++ + calf_plugins::plugin_registry::plugin_registry() + { + #define PER_MODULE_ITEM(name, isSynth, jackname) plugins.push_back((new name##_metadata)); +Index: lmms-1.1.3/plugins/LadspaEffect/calf/src/modules.cpp +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/calf/src/modules.cpp 2017-01-03 19:32:38.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/calf/src/modules.cpp 2017-01-03 19:33:13.000000000 +0100 +@@ -339,7 +339,7 @@ + /////////////////////////////////////////////////////////////////////////////////////////////// + + filterclavier_audio_module::filterclavier_audio_module() +-: filter_module_with_inertia(ins, outs, params) ++: filter_module_with_inertia() + , min_gain(1.0) + , max_gain(32.0) + , last_note(-1) +Index: lmms-1.1.3/plugins/LadspaEffect/swh/flanger_1191.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/flanger_1191.c 2017-01-03 15:44:13.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/flanger_1191.c 2017-01-03 15:45:17.000000000 +0100 +@@ -266,7 +266,7 @@ + + // Calculate position in delay table + d_base = LIN_INTERP(frac, old_d_base, new_d_base); +- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; ++ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; + p_ph = n_ph + 0.5f; + while (p_ph > 1.0f) { + p_ph -= 1.0f; +@@ -392,7 +392,7 @@ + + // Calculate position in delay table + d_base = LIN_INTERP(frac, old_d_base, new_d_base); +- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; ++ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; + p_ph = n_ph + 0.5f; + while (p_ph > 1.0f) { + p_ph -= 1.0f; +Index: lmms-1.1.3/plugins/LadspaEffect/swh/gsm/short_term.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/gsm/short_term.c 2017-01-03 15:35:13.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/gsm/short_term.c 2017-01-03 15:35:55.000000000 +0100 +@@ -53,7 +53,7 @@ + #undef STEP + #define STEP( B, MIC, INVA ) \ + temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ +- temp1 = GSM_SUB( temp1, B << 1 ); \ ++ temp1 = GSM_SUB( temp1, B * 2 ); \ + temp1 = GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = GSM_ADD( temp1, temp1 ); + +Index: lmms-1.1.3/plugins/LadspaEffect/swh/multivoice_chorus_1201.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/multivoice_chorus_1201.c 2017-01-03 15:47:51.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/multivoice_chorus_1201.c 2017-01-03 15:48:18.000000000 +0100 +@@ -345,7 +345,7 @@ + if (count % 16 < laws) { + unsigned int t = count % 16; + // Calculate sinus phases +- float n_ph = (float)(law_p - abs(next_peak_pos[t] - count))/law_p; ++ float n_ph = (float)(law_p - labs(next_peak_pos[t] - count))/law_p; + float p_ph = n_ph + 0.5f; + if (p_ph > 1.0f) { + p_ph -= 1.0f; +@@ -488,7 +488,7 @@ + if (count % 16 < laws) { + unsigned int t = count % 16; + // Calculate sinus phases +- float n_ph = (float)(law_p - abs(next_peak_pos[t] - count))/law_p; ++ float n_ph = (float)(law_p - labs(next_peak_pos[t] - count))/law_p; + float p_ph = n_ph + 0.5f; + if (p_ph > 1.0f) { + p_ph -= 1.0f; +Index: lmms-1.1.3/plugins/LadspaEffect/swh/retro_flange_1208.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/retro_flange_1208.c 2017-01-03 15:46:35.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/retro_flange_1208.c 2017-01-03 15:47:02.000000000 +0100 +@@ -321,7 +321,7 @@ + prev_law_pos = count + law_p; + } + +- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; ++ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; + p_ph = n_ph + 0.5f; + if (p_ph > 1.0f) { + p_ph -= 1.0f; +@@ -446,7 +446,7 @@ + prev_law_pos = count + law_p; + } + +- n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; ++ n_ph = (float)(law_p - labs(next_law_pos - count))/(float)law_p; + p_ph = n_ph + 0.5f; + if (p_ph > 1.0f) { + p_ph -= 1.0f; +Index: lmms-1.1.3/plugins/LadspaEffect/swh/vynil_1905.c +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/swh/vynil_1905.c 2017-01-03 15:51:56.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/swh/vynil_1905.c 2017-01-03 16:01:32.000000000 +0100 +@@ -243,6 +243,8 @@ + buffer_s = malloc(sizeof(LADSPA_Data) * buffer_size); + buffer_mask = buffer_size - 1; + buffer_pos = 0; ++ click_buffer_omega.all = 0; ++ click_buffer_pos.all = 0; + click_gain = 0; + phi = 0.0f; /* Angular phase */ + +Index: lmms-1.1.3/plugins/LadspaEffect/tap/CMakeLists.txt +=================================================================== +--- lmms-1.1.3.orig/plugins/LadspaEffect/tap/CMakeLists.txt 2017-01-03 13:52:28.000000000 +0100 ++++ lmms-1.1.3/plugins/LadspaEffect/tap/CMakeLists.txt 2017-01-03 15:12:14.000000000 +0100 +@@ -1,7 +1,15 @@ + INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") + FILE(GLOB PLUGIN_SOURCES *.c) + LIST(SORT PLUGIN_SOURCES) +-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wno-write-strings -fomit-frame-pointer -fno-strict-aliasing -fstrength-reduce -funroll-loops -ffast-math") ++SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wno-write-strings \ ++ -fomit-frame-pointer -fno-strict-aliasing -funroll-loops -ffast-math") ++ ++INCLUDE(CheckCCompilerFlag) ++CHECK_C_COMPILER_FLAG(-fstrength-reduce C_HAVE_STRENGTH_REDUCE) ++IF(${C_HAVE_STRENGTH_REDUCE}) ++ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstrength-reduce") ++ENDIF() ++ + FOREACH(_item ${PLUGIN_SOURCES}) + GET_FILENAME_COMPONENT(_plugin "${_item}" NAME_WE) + ADD_LIBRARY("${_plugin}" MODULE "${_item}") +Index: lmms-1.1.3/plugins/MidiImport/portsmf/allegro.h +=================================================================== +--- lmms-1.1.3.orig/plugins/MidiImport/portsmf/allegro.h 2017-01-03 20:02:37.000000000 +0100 ++++ lmms-1.1.3/plugins/MidiImport/portsmf/allegro.h 2017-01-03 20:06:48.000000000 +0100 +@@ -842,6 +842,8 @@ + Alg_event_ptr write_track_name(std::ostream &file, int n, + Alg_events &events); + public: ++ using Alg_track::paste; ++ + int channel_offset_per_track; // used to encode track_num into channel + Alg_tracks track_list; // array of Alg_events + Alg_time_sigs time_sig; +Index: lmms-1.1.3/plugins/MidiImport/portsmf/allegrosmfwr.cpp +=================================================================== +--- lmms-1.1.3.orig/plugins/MidiImport/portsmf/allegrosmfwr.cpp 2017-01-03 20:07:50.000000000 +0100 ++++ lmms-1.1.3/plugins/MidiImport/portsmf/allegrosmfwr.cpp 2017-01-03 20:08:34.000000000 +0100 +@@ -57,13 +57,11 @@ + + Alg_seq_ptr seq; + +- int num_tracks; // number of tracks not counting tempo track + int division; // divisions per quarter note, default = 120 + int initial_tempo; + + int timesig_num; // numerator of time signature + int timesig_den; // denominator of time signature +- double timesig_when; // time of time signature + + int keysig; // number of sharps (+) or flats (-), -99 for undefined + char keysig_mode; // 'M' or 'm' for major/minor +Index: lmms-1.1.3/plugins/delay/stereodelay.cpp +=================================================================== +--- lmms-1.1.3.orig/plugins/delay/stereodelay.cpp 2017-01-03 13:40:27.000000000 +0100 ++++ lmms-1.1.3/plugins/delay/stereodelay.cpp 2017-01-03 13:42:16.000000000 +0100 +@@ -48,7 +48,7 @@ + { + if( m_buffer ) + { +- delete m_buffer; ++ delete[] m_buffer; + } + } + +@@ -84,7 +84,7 @@ + { + if( m_buffer ) + { +- delete m_buffer; ++ delete[] m_buffer; + } + + int bufferSize = ( int )( sampleRate * m_maxTime ); +Index: lmms-1.1.3/plugins/opl2/fmopl.c +=================================================================== +--- lmms-1.1.3.orig/plugins/opl2/fmopl.c 2017-01-03 20:11:03.000000000 +0100 ++++ lmms-1.1.3/plugins/opl2/fmopl.c 2017-01-03 20:22:23.000000000 +0100 +@@ -70,7 +70,7 @@ + /* final output shift , limit minimum and maximum */ + #define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */ + #define OPL_MAXOUT (0x7fff< + +Index: lmms-1.1.3/doc/CONTRIBUTORS +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ lmms-1.1.3/doc/CONTRIBUTORS 2016-07-12 00:41:47.000000000 +0200 +@@ -0,0 +1,77 @@ ++Tobias Doerffel ++Vesa ++Javier Serrano Polo ++Paul Giblock ++Tres Finocchiaro ++Lukas W ++Raine M. Ekman ++Wong Cho Ching ++Hannu Haahti ++Danny McRae ++Dave French ++Daniel Winzen ++Andreas Brandmaier ++Andrew Kelley ++Oskar Wallgren ++Mike Choi ++Alexandre Almeida ++NoiseByNorthwest ++Johannes Lorenz ++Stian Jørgensrud ++falkTX ++Csaba Hruska ++StakeoutPunch ++ma2moto ++mikobuntu ++8tab <8tab@wp.pl> ++Matthew Krafczyk ++Spekular ++Umcaruje ++DeRobyJ ++Jonathan Aquilina ++ra ++wongcc966422 ++Gurjot Singh ++Janne Sinisalo ++Krzysztof Foltman ++Lou Herard ++Paul Wayper ++Rüdiger Ranft ++Yann Collette ++grindhold ++midi-pascal ++unfa ++Ian Sannar ++Jaroslav Petrnoušek ++LYF610400210 ++Rafael Ruggiero ++psyomn ++quadro ++sarahkeefe ++Achim Settelmeier ++André Hentschel ++Armin Kazmi ++Attila Herman ++Christopher A. Oliver ++Devin Venable ++Fastigium ++Frank Mather ++Frederik ++Hexasoft ++Jens Lang ++Jesse Dubay ++Joel Muzzerall ++Kristi ++Markus Elfring ++Nikos Chantziaras ++Paul Nasca ++Peter Nelson ++Ra ++Steffen Baranowsky ++Thorsten Müller ++TonyChyi ++devin ++dnl-music ++fundamental ++groboclown ++zm1990s diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 000000000..aba1af044 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,3 @@ +contributors.patch +clang.patch +build-amd64-20181013.patch diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..5e8345845 --- /dev/null +++ b/debian/rules @@ -0,0 +1,35 @@ +#!/usr/bin/make -f + +#Rodney Dawes Version simplifies things :) + +DH_CMAKE_BUILD_DIR=obj -${DEB_BUILD_GNU_TYPE} +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) + +CMAKE_OPTS= -DCONTRIBUTORS=$(CURDIR)/doc/CONTRIBUTORS -DFORCE_VERSION=internal \ + -DWANT_QT5=1 +ifneq ($(DEB_HOST_ARCH_OS),linux) +CMAKE_OPTS+= -DWANT_ALSA=0 +endif + +ifeq ($(DEB_HOST_ARCH),i386) +export PATH := $(PATH):/usr/lib/wine +WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine +CMAKE_OPTS+= -DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH) +else +CMAKE_OPTS+= -DWANT_VST_NOWINE=1 \ + -DREMOTE_VST_PLUGIN_FILEPATH=../../i386-linux-gnu/lmms/RemoteVstPlugin +endif + +# Define NDEBUG. This helps with reproducible builds. +# Add -Wno-error=format-truncation because truncation is expected in snprintf. +export CFLAGS ?= $(shell dpkg-buildflags --get CFLAGS) -DNDEBUG +export CXXFLAGS ?= $(shell dpkg-buildflags --get CXXFLAGS) -DNDEBUG \ + -Wno-error=format-truncation + +%: + dh $@ --buildsystem cmake --parallel + +override_dh_auto_configure: + dh_auto_configure -- -DCMAKE_INSTALL_LIBDIR=lib/$(DEB_HOST_MULTIARCH) $(CMAKE_OPTS) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/watch b/debian/watch new file mode 100644 index 000000000..be099ee74 --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +version=3 +opts="filenamemangle=s/(?:.*\/)?v?(\d[\d\.]*)\.tar\.gz/lmms_$1.tar.gz/" \ +https://github.com/LMMS/lmms/tags (?:.*/)?v?(\d[\d\.]*)\.tar\.gz diff --git a/doc/AUTHORS b/doc/AUTHORS index 8dc5a3039..9244d1198 100644 --- a/doc/AUTHORS +++ b/doc/AUTHORS @@ -67,7 +67,7 @@ Tobiasz Karoń (unfa) UI Developer Johannes Lorenz - + Developer Rubén Ibarra Pastor diff --git a/doc/CONTRIBUTORS b/doc/CONTRIBUTORS new file mode 100644 index 000000000..4a791028f --- /dev/null +++ b/doc/CONTRIBUTORS @@ -0,0 +1,185 @@ +Tobias Junghans +Vesa +Tres Finocchiaro +Lukas W +Javier Serrano Polo +Paul Giblock +Dave French +Colin Wallace +Oskar Wallgren +Raine M. Ekman +Umcaruje +Michael Gregorius +Javier Serrano Polo +grejppi +Javier Serrano Polo +Hyunjin Song +Wong Cho Ching +Alexandre Almeida +Daniel Winzen +LMMS Service Account +Steffen Baranowsky +Danny McRae +Garrett +Hyunin Song +liushuyu +Andrew Kelley +Andreas Brandmaier +Fastigium +Spekular +Amadeus Folego +Jonas Trappenberg +M374LX +DomClark +grindhold +Mike Choi +Karmo Rosental +Christopher L. Simons +Dominic Clark +NoiseByNorthwest +falkTX +Johannes Lorenz +Rebecca DeField +Stian Jørgensrud +Ryan Roden-Corrent +midi-pascal +Augustin Cavalier +BaraMGB +Csaba Hruska +David Carlier +DeRobyJ +Hussam Eddin Alhomsi +Rüdiger Ranft +StakeoutPunch +ma2moto +mikobuntu +8tab <8tab@wp.pl> +Andrés +Matthew Krafczyk +mohamed +Alexandre +RebeccaDeField +Yann Collette +Aya Morisawa +Ben Bryan +Jonathan Aquilina +Mohammad Amin Sameti +ra +wongcc966422 +David CARLIER +Gurjot Singh +Janne Sinisalo +Krzysztof Foltman +Lou Herard +Paul Batchelor +Paul Wayper +Petter Reinholdtsen +TonyChyi +dnl-music +follower +midi-pascal +unfa +Andres +Arnout Engelen +Chris Aiken +Cyrille Bollu +Dan Williams +Ian Sannar +Jaroslav Petrnoušek +Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> +Johannes Lorenz +Kenneth Perry (thothonegan) +LYF610400210 +Lukas W +Mark-Agent003 +NeiroNext +Orbital Ink <31394502+Anonymouqs@users.noreply.github.com> +P THE AWESOME +Ra +Rafael Ruggiero +Rebecca LaVie +Roberto Giaconia +SecondFlight +Steffen Baranowsky +TheTravelingSpaceman +Thomas Clark +gnudles +liushuyu +miketurn +psyomn +quadro +sarahkeefe +Achim Settelmeier +André Hentschel +Armin Kazmi +Attila Herman +Bastian Kummer +Christopher A. Oliver +Devin Venable +Diego Ramos Ruggeri +Douglas <34612565+DouglasDGI@users.noreply.github.com> +DragonEagle +Filip Hron +Frank Mather +Frederik +Greg Simpson +Hexasoft +IvanMaldonado +Ivo Wetzel +Jens Lang +Jesse Dubay +Joel Muzzerall +Joshua Wade +Jousboxx +Jérôme Duval +Karmo Rosental +Kristi +Lee Avital +LocoMatt +Léo Andrès +Markus Elfring +Maurizio Lo Bosco +Mehdi +Mikobuntu +Mingcong Bai +Nikos Chantziaras +Noah Brecht +Ododo +Olivier Humbert +Paul Nasca +Peter Nelson +Ra +Ryan Schmidt +Shane Ambler +Simon Jackson (Netbook) +Simon van der Veldt +Stephen Seo +Steve Leonard +The Gitter Badger +Thorsten Müller +Tobias Junghans +Tobias Kortkamp +Tyler Ganter +Uroš Šišović +Wiley Yu +anonymous +devin +fholmer +flynn16 +follower +fundamental +gandalf3 +groboclown +irrenhaus3 +jasp00 +justnope +kamnxt +lmmsservice +m-xbutterfly +noahb01 +projectpitchin +rgwan +xhe +xy124 +z-up +zm1990s diff --git a/doc/bash-completion/lmms b/doc/bash-completion/lmms index 19fbf4723..ccff8f249 100644 --- a/doc/bash-completion/lmms +++ b/doc/bash-completion/lmms @@ -1,3 +1,4 @@ +#!/usr/bin/env bash # lmms(1) completion -*- shell-script -*- # use shellcheck: "shellcheck -e bash " diff --git a/include/AudioPortAudio.h b/include/AudioPortAudio.h index e4f27c7e1..e1288c3a4 100644 --- a/include/AudioPortAudio.h +++ b/include/AudioPortAudio.h @@ -34,6 +34,7 @@ class AudioPortAudioSetupUtil : public QObject { Q_OBJECT public slots: + void updateBackends(); void updateDevices(); void updateChannels(); @@ -87,6 +88,7 @@ public: virtual ~setupWidget(); virtual void saveSettings(); + virtual void show(); private: ComboBox * m_backend; diff --git a/include/Editor.h b/include/Editor.h index 4b9017e9e..ca4f7415e 100644 --- a/include/Editor.h +++ b/include/Editor.h @@ -51,6 +51,7 @@ protected slots: virtual void play() {} virtual void record() {} virtual void recordAccompany() {} + virtual void toggleStepRecording() {} virtual void stop() {} private slots: @@ -64,7 +65,7 @@ protected: /// /// \param record If set true, the editor's toolbar will contain record /// buttons in addition to the play and stop buttons. - Editor(bool record = false); + Editor(bool record = false, bool record_step = false); virtual ~Editor(); @@ -73,6 +74,7 @@ protected: QAction* m_playAction; QAction* m_recordAction; QAction* m_recordAccompanyAction; + QAction* m_toggleStepRecordingAction; QAction* m_stopAction; }; diff --git a/include/Graph.h b/include/Graph.h index b6de16371..4827bda40 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -169,6 +169,7 @@ public slots: void invert(); void shiftPhase( int _deg ); void clear(); + void clearInvisible(); signals: void lengthChanged(); diff --git a/include/InstrumentPlayHandle.h b/include/InstrumentPlayHandle.h index 3463a128b..426b413ce 100644 --- a/include/InstrumentPlayHandle.h +++ b/include/InstrumentPlayHandle.h @@ -42,14 +42,7 @@ public: virtual void play( sampleFrame * _working_buffer ) { - // if the instrument is midi-based, we can safely render right away - if( m_instrument->flags() & Instrument::IsMidiBased ) - { - m_instrument->play( _working_buffer ); - return; - } - - // if not, we need to ensure that all our nph's have been processed first + // ensure that all our nph's have been processed first ConstNotePlayHandleList nphv = NotePlayHandle::nphsOfInstrumentTrack( m_instrument->instrumentTrack(), true ); bool nphsLeft; diff --git a/include/MixHelpers.h b/include/MixHelpers.h index 7f919aba1..872319f82 100644 --- a/include/MixHelpers.h +++ b/include/MixHelpers.h @@ -33,6 +33,10 @@ namespace MixHelpers bool isSilent( const sampleFrame* src, int frames ); +bool useNaNHandler(); + +void setNaNHandler( bool use ); + bool sanitize( sampleFrame * src, int frames ); /*! \brief Add samples from src to dst */ diff --git a/include/Model.h b/include/Model.h index b40c21029..bc9f5c046 100644 --- a/include/Model.h +++ b/include/Model.h @@ -41,6 +41,10 @@ public: m_displayName( _display_name ), m_defaultConstructed( _default_constructed ) { +#if QT_VERSION < 0x050000 + connect( this, SIGNAL( dataChanged() ), this, + SLOT( thisDataChanged() ), Qt::DirectConnection ); +#endif } virtual ~Model() @@ -85,6 +89,19 @@ signals: // emitted if properties of the model (e.g. ranges) have changed void propertiesChanged(); +#if QT_VERSION < 0x050000 + // emitted along with dataChanged(), but with this model as an argument + // workaround for when QObject::sender() and Qt5 are unavailable + void dataChanged( Model * ); + +private slots: + void thisDataChanged() + { + emit dataChanged( this ); + } + +signals: +#endif } ; diff --git a/include/Pattern.h b/include/Pattern.h index eddbed313..3a1cc941c 100644 --- a/include/Pattern.h +++ b/include/Pattern.h @@ -187,6 +187,7 @@ public slots: protected slots: void openInPianoRoll(); + void setGhostInPianoRoll(); void resetName(); void changeName(); diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 8b0f1babf..b4115b054 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -38,6 +38,8 @@ #include "lmms_basics.h" #include "Song.h" #include "ToolTip.h" +#include "StepRecorder.h" +#include "StepRecorderWidget.h" class QPainter; class QPixmap; @@ -59,7 +61,9 @@ class PianoRoll : public QWidget Q_PROPERTY( QColor lineColor READ lineColor WRITE setLineColor ) Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor ) Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor ) + Q_PROPERTY( QColor ghostNoteColor READ ghostNoteColor WRITE setGhostNoteColor ) Q_PROPERTY( QColor noteTextColor READ noteTextColor WRITE setNoteTextColor ) + Q_PROPERTY( QColor ghostNoteTextColor READ ghostNoteTextColor WRITE setGhostNoteTextColor ) Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor ) Q_PROPERTY( QColor selectedNoteColor READ selectedNoteColor WRITE setSelectedNoteColor ) Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor ) @@ -68,6 +72,8 @@ class PianoRoll : public QWidget Q_PROPERTY( QColor markedSemitoneColor READ markedSemitoneColor WRITE setMarkedSemitoneColor ) Q_PROPERTY( int noteOpacity READ noteOpacity WRITE setNoteOpacity ) Q_PROPERTY( bool noteBorders READ noteBorders WRITE setNoteBorders ) + Q_PROPERTY( int ghostNoteOpacity READ ghostNoteOpacity WRITE setGhostNoteOpacity ) + Q_PROPERTY( bool ghostNoteBorders READ ghostNoteBorders WRITE setGhostNoteBorders ) Q_PROPERTY( QColor backgroundShade READ backgroundShade WRITE setBackgroundShade ) public: enum EditModes @@ -87,6 +93,8 @@ public: void showPanTextFloat(panning_t pan, const QPoint &pos, int timeout=-1); void setCurrentPattern( Pattern* newPattern ); + void setGhostPattern( Pattern* newPattern ); + void loadGhostNotes( const QDomElement & de ); inline void stopRecording() { @@ -98,6 +106,11 @@ public: return m_recording; } + inline bool isStepRecording() const + { + return m_stepRecorder.isRecording(); + } + const Pattern* currentPattern() const { return m_pattern; @@ -141,6 +154,14 @@ public: void setNoteOpacity( const int i ); bool noteBorders() const; void setNoteBorders( const bool b ); + QColor ghostNoteColor() const; + void setGhostNoteColor( const QColor & c ); + QColor ghostNoteTextColor() const; + void setGhostNoteTextColor( const QColor & c ); + int ghostNoteOpacity() const; + void setGhostNoteOpacity( const int i ); + bool ghostNoteBorders() const; + void setGhostNoteBorders( const bool b ); QColor backgroundShade() const; void setBackgroundShade( const QColor & c ); @@ -175,6 +196,7 @@ protected slots: void play(); void record(); void recordAccompany(); + bool toggleStepRecording(); void stop(); void startRecordNote( const Note & n ); @@ -192,9 +214,11 @@ protected slots: void updatePosition(const MidiTime & t ); void updatePositionAccompany(const MidiTime & t ); + void updatePositionStepRecording(const MidiTime & t ); void zoomingChanged(); void quantizeChanged(); + void noteLengthChanged(); void quantizeNotes(); void updateSemiToneMarkerMenu(); @@ -206,9 +230,12 @@ protected slots: void selectRegionFromPixels( int xStart, int xEnd ); + void clearGhostPattern(); + signals: void currentPatternChanged(); + void ghostPatternSet(bool); void semiToneMarkerMenuScaleSetEnabled(bool); void semiToneMarkerMenuChordSetEnabled(bool); @@ -309,6 +336,13 @@ private: static const QVector m_zoomLevels; Pattern* m_pattern; + NoteVector m_ghostNotes; + + inline const NoteVector & ghostNotes() const + { + return m_ghostNotes; + } + QScrollBar * m_leftRightScroll; QScrollBar * m_topBottomScroll; @@ -381,6 +415,9 @@ private: friend class PianoRollWindow; + StepRecorderWidget m_stepRecorderWidget; + StepRecorder m_stepRecorder; + // qproperty fields QColor m_barLineColor; QColor m_beatLineColor; @@ -388,6 +425,8 @@ private: QColor m_noteModeColor; QColor m_noteColor; QColor m_noteTextColor; + QColor m_ghostNoteColor; + QColor m_ghostNoteTextColor; QColor m_barColor; QColor m_selectedNoteColor; QColor m_textColor; @@ -395,7 +434,9 @@ private: QColor m_textShadow; QColor m_markedSemitoneColor; int m_noteOpacity; + int m_ghostNoteOpacity; bool m_noteBorders; + bool m_ghostNoteBorders; QColor m_backgroundShade; signals: @@ -412,7 +453,8 @@ public: PianoRollWindow(); const Pattern* currentPattern() const; - void setCurrentPattern(Pattern* pattern); + void setCurrentPattern( Pattern* pattern ); + void setGhostPattern( Pattern* pattern ); int quantization() const; @@ -420,6 +462,7 @@ public: void stop(); void record(); void recordAccompany(); + void toggleStepRecording(); void stopRecording(); bool isRecording() const; @@ -444,10 +487,14 @@ signals: private slots: - void patternRenamed(); + void updateAfterPatternChange(); + void ghostPatternSet( bool state ); private: + void patternRenamed(); void focusInEvent(QFocusEvent * event); + void stopStepRecording(); + void updateStepRecordingIcon(); PianoRoll* m_editor; @@ -456,6 +503,7 @@ private: ComboBox * m_noteLenComboBox; ComboBox * m_scaleComboBox; ComboBox * m_chordComboBox; + QPushButton * m_clearGhostButton; }; diff --git a/include/ProjectJournal.h b/include/ProjectJournal.h index a89c9725a..e0e738b70 100644 --- a/include/ProjectJournal.h +++ b/include/ProjectJournal.h @@ -77,6 +77,7 @@ public: } static jo_id_t idToSave( jo_id_t id ); + static jo_id_t idFromSave( jo_id_t id ); void clearJournal(); void stopAllJournalling(); diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 99160a967..27c658a3d 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -754,9 +754,15 @@ public: ProcessWatcher( RemotePlugin * ); virtual ~ProcessWatcher() = default; - void quit() + void stop() { m_quit = true; + quit(); + } + + void reset() + { + m_quit = false; } private: @@ -862,6 +868,9 @@ private: QProcess m_process; ProcessWatcher m_watcher; + QString m_exec; + QStringList m_args; + QMutex m_commMutex; bool m_splitChannels; #ifdef USE_QT_SHMEM diff --git a/include/SetupDialog.h b/include/SetupDialog.h index 254549df1..d9665bbbc 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -138,6 +138,7 @@ private: bool m_MMPZ; bool m_disableBackup; bool m_openLastProject; + bool m_NaNHandler; bool m_hqAudioDev; QString m_lang; QStringList m_languages; diff --git a/include/Song.h b/include/Song.h index 7ab1f54f6..d88a59e2b 100644 --- a/include/Song.h +++ b/include/Song.h @@ -103,8 +103,6 @@ public: } ; - - void processNextBuffer(); inline int getLoadingTrackCount() const @@ -203,9 +201,23 @@ public: { return m_recording; } + + inline void setLoopRenderCount(int count) + { + if (count < 1) + m_loopRenderCount = 1; + else + m_loopRenderCount = count; + m_loopRenderRemaining = m_loopRenderCount; + } + + inline int getLoopRenderCount() const + { + return m_loopRenderCount; + } bool isExportDone() const; - std::pair getExportEndpoints() const; + int getExportProgress() const; inline void setRenderBetweenMarkers( bool renderBetweenMarkers ) { @@ -424,7 +436,14 @@ private: tact_t m_elapsedTacts; VstSyncController m_vstSyncController; - + + int m_loopRenderCount; + int m_loopRenderRemaining; + MidiTime m_exportSongBegin; + MidiTime m_exportLoopBegin; + MidiTime m_exportLoopEnd; + MidiTime m_exportSongEnd; + MidiTime m_exportEffectiveLength; friend class LmmsCore; friend class SongEditor; diff --git a/include/SongEditor.h b/include/SongEditor.h index e31d0f862..f9b6aad1b 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -159,6 +159,7 @@ public: protected: virtual void resizeEvent( QResizeEvent * event ); + virtual void changeEvent( QEvent * ); protected slots: void play(); diff --git a/include/StepRecorder.h b/include/StepRecorder.h new file mode 100644 index 000000000..b9653b1bb --- /dev/null +++ b/include/StepRecorder.h @@ -0,0 +1,143 @@ +/* + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef STEP_RECORDER_H +#define STEP_RECORDER_H + +#include +#include +#include +#include + +#include "Note.h" +#include "lmms_basics.h" +#include "Pattern.h" + +class PianoRoll; +class StepRecorderWidget; + +class StepRecorder : public QObject +{ + Q_OBJECT + + public: + StepRecorder(PianoRoll& pianoRoll, StepRecorderWidget& stepRecorderWidget); + + void initialize(); + void start(const MidiTime& currentPosition,const MidiTime& stepLength); + void stop(); + void notePressed(const Note & n); + void noteReleased(const Note & n); + bool keyPressEvent(QKeyEvent* ke); + bool mousePressEvent(QMouseEvent* ke); + void setCurrentPattern(Pattern* newPattern); + void setStepsLength(const MidiTime& newLength); + + QVector getCurStepNotes(); + + bool isRecording() const + { + return m_isRecording; + } + + QColor curStepNoteColor() const + { + return QColor(245,3,139); // radiant pink + } + + private slots: + void removeNotesReleasedForTooLong(); + + private: + void stepForwards(); + void stepBackwards(); + + void applyStep(); + void dismissStep(); + void prepareNewStep(); + + MidiTime getCurStepEndPos(); + + void updateCurStepNotes(); + void updateWidget(); + + bool allCurStepNotesReleased(); + + PianoRoll& m_pianoRoll; + StepRecorderWidget& m_stepRecorderWidget; + + bool m_isRecording = false; + MidiTime m_curStepStartPos = 0; + MidiTime m_curStepEndPos = 0; + + MidiTime m_stepsLength; + MidiTime m_curStepLength; // current step length refers to the step currently recorded. it may defer from m_stepsLength + // since the user can make current step larger + + QTimer m_updateReleasedTimer; + + Pattern* m_pattern; + + class StepNote + { + public: + StepNote(const Note & note) : m_note(note), m_pressed(true) {}; + + void setPressed() + { + m_pressed = true; + } + + void setReleased() + { + m_pressed = false; + releasedTimer.start(); + } + + int timeSinceReleased() + { + return releasedTimer.elapsed(); + } + + bool isPressed() const + { + return m_pressed; + } + + bool isReleased() const + { + return !m_pressed; + } + + Note m_note; + + private: + bool m_pressed; + QTime releasedTimer; + } ; + + QVector m_curStepNotes; // contains the current recorded step notes (i.e. while user still press the notes; before they are applied to the pattern) + + StepNote* findCurStepNote(const int key); + + bool m_isStepInProgress = false; +}; + +#endif //STEP_RECORDER_H \ No newline at end of file diff --git a/include/StepRecorderWidget.h b/include/StepRecorderWidget.h new file mode 100644 index 000000000..0e4512169 --- /dev/null +++ b/include/StepRecorderWidget.h @@ -0,0 +1,92 @@ +/* + * StepRecorderWidget.h - widget that provide gui markers for step recording + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of"the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ +#ifndef STEP_RECOREDER_WIDGET_H +#define STEP_RECOREDER_WIDGET_H + +#include "lmms_basics.h" +#include "Note.h" + +#include +#include +#include + +class StepRecorderWidget : public QWidget +{ + Q_OBJECT + +public: + StepRecorderWidget( + QWidget * parent, + const int ppt, + const int marginTop, + const int marginBottom, + const int marginLeft, + const int marginRight); + + //API used by PianoRoll + void setPixelsPerTact(int ppt); + void setCurrentPosition(MidiTime currentPosition); + void setBottomMargin(const int marginBottom); + + //API used by StepRecorder + void setStepsLength(MidiTime stepsLength); + void setStartPosition(MidiTime pos); + void setEndPosition(MidiTime pos); + + void showHint(); + +private: + virtual void paintEvent(QPaintEvent * pe); + + int xCoordOfTick(int tick); + + void drawVerLine(QPainter* painter, int x, const QColor& color, int top, int bottom); + void drawVerLine(QPainter* painter, const MidiTime& pos, const QColor& color, int top, int bottom); + + void updateBoundaries(); + + MidiTime m_stepsLength; + MidiTime m_curStepStartPos; + MidiTime m_curStepEndPos; + + int m_ppt; // pixels per tact + MidiTime m_currentPosition; // current position showed by on PianoRoll + + QColor m_colorLineStart; + QColor m_colorLineEnd; + + // boundaries within piano roll window + int m_top; + int m_bottom; + int m_left; + int m_right; + + const int m_marginTop; + int m_marginBottom; // not const since can change on resize of edit-note area + const int m_marginLeft; + const int m_marginRight; + +signals: + void positionChanged(const MidiTime & t); +} ; + +#endif //STEP_RECOREDER_WIDGET_H diff --git a/include/SubWindow.h b/include/SubWindow.h index 067f9e312..f6247d061 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -92,7 +92,6 @@ private: bool m_hasFocus; static void elideText( QLabel *label, QString text ); - bool isMaximized(); void adjustTitleBar(); private slots: diff --git a/include/VstSyncController.h b/include/VstSyncController.h index 1c920182e..33f2ee036 100644 --- a/include/VstSyncController.h +++ b/include/VstSyncController.h @@ -39,7 +39,7 @@ public: VstSyncController(); ~VstSyncController(); - void setAbsolutePosition( int ticks ); + void setAbsolutePosition( double ticks ); void setPlaybackState( bool enabled ) { diff --git a/include/VstSyncData.h b/include/VstSyncData.h index d8694f1b2..f9696252a 100644 --- a/include/VstSyncData.h +++ b/include/VstSyncData.h @@ -42,7 +42,7 @@ struct VstSyncData { bool isPlaying; - float ppqPos; + double ppqPos; int timeSigNumer; int timeSigDenom; bool isCycle; diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index b4a1081f6..4f139f8b3 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -91,8 +91,6 @@ ENDIF("${PLUGIN_LIST}" STREQUAL "") IF(MSVC) SET(MSVC_INCOMPATIBLE_PLUGINS LadspaEffect - sid - #VstEffect zynaddsubfx ) message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}") diff --git a/plugins/MidiExport/MidiExport.cpp b/plugins/MidiExport/MidiExport.cpp index c5aa75149..1860527c1 100644 --- a/plugins/MidiExport/MidiExport.cpp +++ b/plugins/MidiExport/MidiExport.cpp @@ -275,7 +275,8 @@ void MidiExport::writePattern(MidiNoteVector &pat, QDomNode n, // TODO interpret pan="0" fxch="0" pitchrange="1" MidiNote mnote; mnote.pitch = qMax(0, qMin(127, note.attribute("key", "0").toInt() + base_pitch)); - mnote.volume = qMin(qRound(base_volume * LocaleHelper::toDouble(note.attribute("vol", "100"))), 127); + // Map from LMMS volume to MIDI velocity + mnote.volume = qMin(qRound(base_volume * LocaleHelper::toDouble(note.attribute("vol", "100")) * (127.0 / 200.0)), 127); mnote.time = base_time + note.attribute("pos", "0").toInt(); mnote.duration = note.attribute("len", "0").toInt(); pat.push_back(mnote); diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 46fac9299..e31c24508 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -428,7 +428,7 @@ bool MidiImport::readSMF( TrackContainer* tc ) Note n( (ticks < 1 ? 1 : ticks ), noteEvt->get_start_time() * ticksPerBeat, noteEvt->get_identifier() - 12, - noteEvt->get_loud()); + noteEvt->get_loud() * (200.f / 127.f)); // Map from MIDI velocity to LMMS volume ch->addNote( n ); } diff --git a/plugins/MidiImport/portsmf/allegro.cpp b/plugins/MidiImport/portsmf/allegro.cpp index 653ff4c07..3f7b84073 100644 --- a/plugins/MidiImport/portsmf/allegro.cpp +++ b/plugins/MidiImport/portsmf/allegro.cpp @@ -54,8 +54,10 @@ void Alg_atoms::expand() maxlen += (maxlen >> 2); // add 25% char **new_atoms = new Alg_attribute[maxlen]; // now do copy - memcpy(new_atoms, atoms, len * sizeof(Alg_attribute)); - if (atoms) delete[] atoms; + if (atoms) { + memcpy(new_atoms, atoms, len * sizeof(Alg_attribute)); + delete[] atoms; + } atoms = new_atoms; } diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index 5d22f93bd..d92717d37 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -90,7 +90,13 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } - connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); +#if QT_VERSION < 0x050000 + connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ), + this, SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( knobFModel[i], &FloatModel::dataChanged, this, + [this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection); +#endif } } @@ -100,10 +106,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) -void VstEffectControls::setParameter( void ) +void VstEffectControls::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_effect->m_plugin != NULL ) { @@ -377,9 +381,16 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls * m_vi->knobFModel[ i ] = new FloatModel( LocaleHelper::toFloat(s_dumpValues.at(2)), 0.0f, 1.0f, 0.01f, _eff, tr( paramStr ) ); } - connect( m_vi->knobFModel[ i ], SIGNAL( dataChanged() ), this, - SLOT( setParameter() ) ); - vstKnobs[ i ] ->setModel( m_vi->knobFModel[ i ] ); + + FloatModel * model = m_vi->knobFModel[i]; +#if QT_VERSION < 0x050000 + connect( model, SIGNAL( dataChanged( Model * ) ), this, + SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( model, &FloatModel::dataChanged, this, + [this, model]() { setParameter( model ); }, Qt::DirectConnection); +#endif + vstKnobs[ i ] ->setModel( model ); } int i = 0; @@ -472,10 +483,8 @@ void manageVSTEffectView::displayAutomatedOnly( void ) -void manageVSTEffectView::setParameter( void ) +void manageVSTEffectView::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_effect->m_plugin != NULL ) { diff --git a/plugins/VstEffect/VstEffectControls.h b/plugins/VstEffect/VstEffectControls.h index e4f099fd1..092669f94 100644 --- a/plugins/VstEffect/VstEffectControls.h +++ b/plugins/VstEffect/VstEffectControls.h @@ -70,7 +70,7 @@ protected slots: void rollPreset( void ); void rolrPreset( void ); void selPreset( void ); - void setParameter( void ); + void setParameter( Model * action ); protected: virtual void paintEvent( QPaintEvent * _pe ); @@ -110,7 +110,7 @@ public: protected slots: void syncPlugin( void ); void displayAutomatedOnly( void ); - void setParameter( void ); + void setParameter( Model * action ); void closeWindow(); private: diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index ecc77be0b..6680ed5d6 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -474,6 +474,7 @@ void bitInvaderView::modelChanged() void bitInvaderView::sinWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToSine(); Engine::getSong()->setModified(); } @@ -483,6 +484,7 @@ void bitInvaderView::sinWaveClicked() void bitInvaderView::triangleWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToTriangle(); Engine::getSong()->setModified(); } @@ -492,6 +494,7 @@ void bitInvaderView::triangleWaveClicked() void bitInvaderView::sawWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToSaw(); Engine::getSong()->setModified(); } @@ -501,6 +504,7 @@ void bitInvaderView::sawWaveClicked() void bitInvaderView::sqrWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToSquare(); Engine::getSong()->setModified(); } @@ -510,6 +514,7 @@ void bitInvaderView::sqrWaveClicked() void bitInvaderView::noiseWaveClicked() { + m_graph->model()->clearInvisible(); m_graph->model()->setWaveToNoise(); Engine::getSong()->setModified(); } @@ -520,35 +525,12 @@ void bitInvaderView::noiseWaveClicked() void bitInvaderView::usrWaveClicked() { QString fileName = m_graph->model()->setWaveToUser(); - ToolTip::add( m_usrWaveBtn, fileName ); - Engine::getSong()->setModified(); - /* - m_graph->model()->setWaveToNoise(); - Engine::getSong()->setModified(); - // zero sample_shape - for (int i = 0; i < sample_length; i++) + if (!fileName.isEmpty()) { - sample_shape[i] = 0; + ToolTip::add(m_usrWaveBtn, fileName); + m_graph->model()->clearInvisible(); + Engine::getSong()->setModified(); } - - // load user shape - sampleBuffer buffer; - QString af = buffer.openAudioFile(); - if ( af != "" ) - { - buffer.setAudioFile( af ); - - // copy buffer data - sample_length = min( sample_length, static_cast( - buffer.frames() ) ); - for ( int i = 0; i < sample_length; i++ ) - { - sample_shape[i] = (float)*buffer.data()[i]; - } - } - - sampleChanged(); - */ } diff --git a/plugins/peak_controller_effect/peak_controller_effect.cpp b/plugins/peak_controller_effect/peak_controller_effect.cpp index e8b31d6a0..9d1e6ccf4 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect.cpp @@ -65,7 +65,7 @@ PeakControllerEffect::PeakControllerEffect( Effect( &peakcontrollereffect_plugin_descriptor, _parent, _key ), m_effectId( rand() ), m_peakControls( this ), - m_lastSample( m_peakControls.m_baseModel.value() ), //sets the value to the Peak Controller's Base value (rather than 0 like in previous versions) + m_lastSample( 0 ), m_autoController( NULL ) { m_autoController = new PeakController( Engine::getSong(), this ); diff --git a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp index 08d207a10..ff87d0d99 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp @@ -53,6 +53,7 @@ PeakControllerEffectControls( PeakControllerEffect * _eff ) : void PeakControllerEffectControls::loadSettings( const QDomElement & _this ) { m_baseModel.loadSettings( _this, "base" ); + m_effect->m_lastSample = m_baseModel.value(); //Set initial Peak Controller output to Base m_amountModel.loadSettings( _this, "amount" ); m_muteModel.loadSettings( _this, "mute" ); diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp index 2eb46be56..e671d4f05 100644 --- a/plugins/sid/sid_instrument.cpp +++ b/plugins/sid/sid_instrument.cpp @@ -324,7 +324,8 @@ void sidInstrument::playNote( NotePlayHandle * _n, cSID *sid = static_cast( _n->m_pluginData ); int delta_t = clockrate * frames / samplerate + 4; - short buf[frames]; + // avoid variable length array for msvc compat + short* buf = reinterpret_cast(_working_buffer + offset); unsigned char sidreg[NUMSIDREGS]; for (int c = 0; c < NUMSIDREGS; c++) @@ -429,7 +430,8 @@ void sidInstrument::playNote( NotePlayHandle * _n, if(num!=frames) printf("!!!Not enough samples\n"); - for( fpp_t frame = 0; frame < frames; ++frame ) + // loop backwards to avoid overwriting data in the short-to-float conversion + for( fpp_t frame = frames - 1; frame >= 0; frame-- ) { sample_t s = float(buf[frame])/32768.0; for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 73ea33a51..f4aabd265 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -114,6 +114,9 @@ public: void createUI( QWidget *parent ) override { Q_UNUSED(parent); + if ( !hasEditor() ) { + return; + } if ( embedMethod() != "none" ) { m_pluginSubWindow.reset(new vstSubWin( gui->mainWindow()->workspace() )); VstPlugin::createUI( m_pluginSubWindow.get() ); @@ -214,7 +217,13 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } - connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); +#if QT_VERSION < 0x050000 + connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ), + this, SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( knobFModel[i], &FloatModel::dataChanged, this, + [this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection); +#endif } } m_pluginMutex.unlock(); @@ -223,10 +232,8 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) -void vestigeInstrument::setParameter( void ) +void vestigeInstrument::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_plugin != NULL ) { @@ -969,8 +976,16 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume m_vi->knobFModel[ i ] = new FloatModel( LocaleHelper::toFloat(s_dumpValues.at(2)), 0.0f, 1.0f, 0.01f, castModel(), tr( paramStr ) ); } - connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); - vstKnobs[i] ->setModel( m_vi->knobFModel[i] ); + + FloatModel * model = m_vi->knobFModel[i]; +#if QT_VERSION < 0x050000 + connect( model, SIGNAL( dataChanged( Model * ) ), this, + SLOT( setParameter( Model * ) ), Qt::DirectConnection ); +#else + connect( model, &FloatModel::dataChanged, this, + [this, model]() { setParameter( model ); }, Qt::DirectConnection); +#endif + vstKnobs[i] ->setModel( model ); } int i = 0; @@ -1101,10 +1116,8 @@ manageVestigeInstrumentView::~manageVestigeInstrumentView() -void manageVestigeInstrumentView::setParameter( void ) +void manageVestigeInstrumentView::setParameter( Model * action ) { - - Model *action = qobject_cast(sender()); int knobUNID = action->displayName().toInt(); if ( m_vi->m_plugin != NULL ) { diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 2c007efc0..3b92eea8f 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -73,7 +73,7 @@ public: virtual PluginView * instantiateView( QWidget * _parent ); protected slots: - void setParameter( void ); + void setParameter( Model * action ); void handleConfigChange( QString cls, QString attr, QString value ); void reloadPlugin(); @@ -109,7 +109,7 @@ public: protected slots: void syncPlugin( void ); void displayAutomatedOnly( void ); - void setParameter( void ); + void setParameter( Model * action ); void closeWindow(); diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 8589c8c5c..a9ed335f0 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -65,6 +65,7 @@ # include #endif +#include #include #include #include @@ -415,8 +416,8 @@ private: // host to plugin synchronisation data structure struct in { - float lastppqPos; - float m_Timestamp; + double lastppqPos; + double m_Timestamp; int32_t m_lastFlags; } ; @@ -913,6 +914,14 @@ void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out ) static char eventsBuffer[sizeof( VstEvents ) + sizeof( VstMidiEvent * ) * MIDI_EVENT_BUFFER_COUNT]; static VstMidiEvent vme[MIDI_EVENT_BUFFER_COUNT]; + // first sort events chronologically, since some plugins + // (e.g. Sinnah) can hang if they're out of order + std::stable_sort( m_midiEvents.begin(), m_midiEvents.end(), + []( const VstMidiEvent &a, const VstMidiEvent &b ) + { + return a.deltaFrames < b.deltaFrames; + } ); + VstEvents* events = (VstEvents *) eventsBuffer; events->reserved = 0; events->numEvents = m_midiEvents.size(); @@ -1609,10 +1618,20 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, } else if( __plugin->m_vstSyncData->isPlaying ) { - __plugin->m_in->lastppqPos += ( - __plugin->m_vstSyncData->hasSHM ? - __plugin->m_vstSyncData->m_bpm : - __plugin->m_bpm ) / (float)10340; + if( __plugin->m_vstSyncData->hasSHM ) + { + __plugin->m_in->lastppqPos += + __plugin->m_vstSyncData->m_bpm / 60.0 + * __plugin->m_vstSyncData->m_bufferSize + / __plugin->m_vstSyncData->m_sampleRate; + } + else + { + __plugin->m_in->lastppqPos += + __plugin->m_bpm / 60.0 + * __plugin->bufferSize() + / __plugin->sampleRate(); + } _timeInfo.ppqPos = __plugin->m_in->lastppqPos; } // _timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos; @@ -1945,7 +1964,9 @@ DWORD WINAPI RemoteVstPlugin::processingThread( LPVOID _param ) RemotePluginClient::message m; while( ( m = _this->receiveMessage() ).id != IdQuit ) { - if( m.id == IdStartProcessing || m.id == IdMidiEvent ) + if( m.id == IdStartProcessing + || m.id == IdMidiEvent + || m.id == IdVstSetParameter ) { _this->processMessage( m ); } diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index fa8255afe..07bed93b6 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -1,32 +1,39 @@ IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) + IF(MSVC) + SET(VCPKG_ROOT "${CMAKE_FIND_ROOT_PATH}") + INSTALL(FILES "${VCPKG_ROOT}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + ELSE(MSVC) + INSTALL(FILES "${MINGW_PREFIX}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${MINGW_PREFIX}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + ENDIF(MSVC) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") ELSEIF(LMMS_BUILD_WIN64 AND MSVC) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) - IF(NOT CMAKE_GENERATOR_32) - IF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) - SET(CMAKE_GENERATOR_32 "Visual Studio 14 2015") - SET(MSVC_YEAR 2015) - ELSEIF(MSVC_VER VERSION_EQUAL 19.10 OR MSVC_VER VERSION_EQUAL 19.10) + IF(NOT CMAKE_GENERATOR_32) + IF(MSVC_VER VERSION_GREATER 19.10 OR MSVC_VER VERSION_EQUAL 19.10) SET(CMAKE_GENERATOR_32 "Visual Studio 15 2017") SET(MSVC_YEAR 2017) + ELSEIF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) + SET(CMAKE_GENERATOR_32 "Visual Studio 14 2015") + SET(MSVC_YEAR 2015) ELSE() MESSAGE(SEND_WARNING "Can't build RemoteVstPlugin32, unknown MSVC version ${MSVC_VER} and no CMAKE_GENERATOR_32 set") RETURN() ENDIF() ENDIF() - IF(NOT QT_32_PREFIX AND NOT USING_VCPKG) + IF(NOT QT_32_PREFIX) GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") ENDIF() - IF(NOT QT_32_PREFIX) - MESSAGE(WARNING "Can't build RemoteVstPlugin32, QT_32_PREFIX not set") - RETURN() - ELSEIF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) - MESSAGE(WARNING "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") - RETURN() + #TODO: qt5 installed using vcpkg: I don't know how to detect if the user built the x86 version of qt5 from here. At least not cleanly. + #So for the moment, we'll allow the built. + IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) + MESSAGE(WARNING "No Qt 32 bit installation found at ${QT_32_PREFIX}. If you're using VCPKG you can ignore this message if you've built x86-windows version of qt5") ENDIF() ExternalProject_Add(RemoteVstPlugin32 @@ -38,6 +45,17 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) + + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") + + #TODO: find a solution when not using vcpkg for qt + SET(VCPKG_ROOT_32 "${CMAKE_FIND_ROOT_PATH}/../x86-windows") + + INSTALL(FILES "${VCPKG_ROOT_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/pcre2-16.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/double-conversion.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${VCPKG_ROOT_32}/bin/qt5core.dll" DESTINATION "${PLUGIN_DIR}/32") + ELSEIF(LMMS_BUILD_LINUX) # Use winegcc ExternalProject_Add(RemoteVstPlugin32 @@ -47,6 +65,9 @@ ELSEIF(LMMS_BUILD_LINUX) "-DCMAKE_CXX_COMPILER=${WINEGCC}" "-DCMAKE_CXX_FLAGS=-m32" ) + + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32") + ELSEIF(CMAKE_TOOLCHAIN_FILE_32) ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" @@ -55,13 +76,11 @@ ELSEIF(CMAKE_TOOLCHAIN_FILE_32) "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_32}" "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE_32}" ) + INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32") + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") ELSE() - message(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") + MESSAGE(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") RETURN() ENDIF() -IF(LMMS_BUILD_LINUX) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") -ELSEIF(LMMS_BUILD_WIN32) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}") -ENDIF() diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 5138a58a6..2e69802b2 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -152,7 +152,7 @@ VstPlugin::VstPlugin( const QString & _plugin ) : tryLoad( "RemoteVstPlugin64" ); break; case PE::MachineType::i386: - tryLoad( "RemoteVstPlugin32" ); + tryLoad( "32/RemoteVstPlugin32" ); break; default: m_failed = true; diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index e083a30a9..f1d37fa3e 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -163,6 +163,10 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp "${WINRC}") INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION "${PLUGIN_DIR}") +IF(LMMS_BUILD_WIN32) + SET_TARGET_PROPERTIES(RemoteZynAddSubFx PROPERTIES LINK_FLAGS "${LINK_FLAGS} -mwindows") +ENDIF(LMMS_BUILD_WIN32) + # Remove useless dependencies from FLTK. Use fltk-config to avoid static library # in older environments SET(FLTK_FILTERED_LDFLAGS ${FLTK_LIBRARIES}) diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index ad8d9a78c..85e5b0118 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -121,13 +121,20 @@ ZynAddSubFxInstrument::ZynAddSubFxInstrument( { initPlugin(); - connect( &m_portamentoModel, SIGNAL( dataChanged() ), this, SLOT( updatePortamento() ) ); - connect( &m_filterFreqModel, SIGNAL( dataChanged() ), this, SLOT( updateFilterFreq() ) ); - connect( &m_filterQModel, SIGNAL( dataChanged() ), this, SLOT( updateFilterQ() ) ); - connect( &m_bandwidthModel, SIGNAL( dataChanged() ), this, SLOT( updateBandwidth() ) ); - connect( &m_fmGainModel, SIGNAL( dataChanged() ), this, SLOT( updateFmGain() ) ); - connect( &m_resCenterFreqModel, SIGNAL( dataChanged() ), this, SLOT( updateResCenterFreq() ) ); - connect( &m_resBandwidthModel, SIGNAL( dataChanged() ), this, SLOT( updateResBandwidth() ) ); + connect( &m_portamentoModel, SIGNAL( dataChanged() ), + this, SLOT( updatePortamento() ), Qt::DirectConnection ); + connect( &m_filterFreqModel, SIGNAL( dataChanged() ), + this, SLOT( updateFilterFreq() ), Qt::DirectConnection ); + connect( &m_filterQModel, SIGNAL( dataChanged() ), + this, SLOT( updateFilterQ() ), Qt::DirectConnection ); + connect( &m_bandwidthModel, SIGNAL( dataChanged() ), + this, SLOT( updateBandwidth() ), Qt::DirectConnection ); + connect( &m_fmGainModel, SIGNAL( dataChanged() ), + this, SLOT( updateFmGain() ), Qt::DirectConnection ); + connect( &m_resCenterFreqModel, SIGNAL( dataChanged() ), + this, SLOT( updateResCenterFreq() ), Qt::DirectConnection ); + connect( &m_resBandwidthModel, SIGNAL( dataChanged() ), + this, SLOT( updateResBandwidth() ), Qt::DirectConnection ); // now we need a play-handle which cares for calling play() InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrumentTrack ); @@ -137,7 +144,7 @@ ZynAddSubFxInstrument::ZynAddSubFxInstrument( this, SLOT( reloadPlugin() ) ); connect( instrumentTrack()->pitchRangeModel(), SIGNAL( dataChanged() ), - this, SLOT( updatePitchRange() ) ); + this, SLOT( updatePitchRange() ), Qt::DirectConnection ); } diff --git a/src/3rdparty/rpmalloc/rpmalloc b/src/3rdparty/rpmalloc/rpmalloc index 36b1942fb..b5bdc1805 160000 --- a/src/3rdparty/rpmalloc/rpmalloc +++ b/src/3rdparty/rpmalloc/rpmalloc @@ -1 +1 @@ -Subproject commit 36b1942fbc309b139e56a03166ba19a87f28f26c +Subproject commit b5bdc18051bb74a22f0bde4bcc90b01cf590b496 diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 62b783da4..1780da5e1 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -466,7 +466,8 @@ void AutomatableModel::linkModel( AutomatableModel* model ) if( !model->hasLinkedModels() ) { - QObject::connect( this, SIGNAL( dataChanged() ), model, SIGNAL( dataChanged() ) ); + QObject::connect( this, SIGNAL( dataChanged() ), + model, SIGNAL( dataChanged() ), Qt::DirectConnection ); } } } @@ -522,7 +523,8 @@ void AutomatableModel::setControllerConnection( ControllerConnection* c ) m_controllerConnection = c; if( c ) { - QObject::connect( m_controllerConnection, SIGNAL( valueChanged() ), this, SIGNAL( dataChanged() ) ); + QObject::connect( m_controllerConnection, SIGNAL( valueChanged() ), + this, SIGNAL( dataChanged() ), Qt::DirectConnection ); QObject::connect( m_controllerConnection, SIGNAL( destroyed() ), this, SLOT( unlinkControllerConnection() ) ); m_valueChanged = true; emit dataChanged(); diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 86f2c7af8..937be570f 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -772,6 +772,16 @@ void AutomationPattern::resolveAllIDs() { a->addObject( dynamic_cast( o ), false ); } + else + { + // FIXME: Remove this block once the automation system gets fixed + // This is a temporary fix for https://github.com/LMMS/lmms/issues/3781 + o = Engine::projectJournal()->journallingObject(ProjectJournal::idFromSave(*k)); + if( o && dynamic_cast( o ) ) + { + a->addObject( dynamic_cast( o ), false ); + } + } } a->m_idsToResolve.clear(); a->dataChanged(); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 85a00780b..7870415f9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -67,6 +67,7 @@ set(LMMS_SRCS core/TrackContainer.cpp core/ValueBuffer.cpp core/VstSyncController.cpp + core/StepRecorder.cpp core/audio/AudioAlsa.cpp core/audio/AudioDevice.cpp diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index af398d389..45e36e12f 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -117,7 +117,7 @@ void ControllerConnection::setController( Controller * _controller ) { _controller->addConnection( this ); QObject::connect( _controller, SIGNAL( valueChanged() ), - this, SIGNAL( valueChanged() ) ); + this, SIGNAL( valueChanged() ), Qt::DirectConnection ); } m_ownsController = diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index e1a2e092f..cdbf079d3 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -26,6 +26,11 @@ #include "lmms_math.h" #include "ValueBuffer.h" +#include + + +static bool s_NaNHandler; + namespace MixHelpers { @@ -68,10 +73,24 @@ bool isSilent( const sampleFrame* src, int frames ) return true; } +bool useNaNHandler() +{ + return s_NaNHandler; +} + +void setNaNHandler( bool use ) +{ + s_NaNHandler = use; +} /*! \brief Function for sanitizing a buffer of infs/nans - returns true if those are found */ bool sanitize( sampleFrame * src, int frames ) { + if( !useNaNHandler() ) + { + return false; + } + bool found = false; for( int f = 0; f < frames; ++f ) { @@ -79,12 +98,23 @@ bool sanitize( sampleFrame * src, int frames ) { if( isinf( src[f][c] ) || isnan( src[f][c] ) ) { - src[f][c] = 0.0f; + #ifdef LMMS_DEBUG + printf("Bad data, clearing buffer. frame: "); + printf("%d: value %f\n", f, src[f][c]); + #endif + for( int f = 0; f < frames; ++f ) + { + for( int c = 0; c < 2; ++c ) + { + src[f][c] = 0.0f; + } + } found = true; + return found; } else { - src[f][c] = qBound( -4.0f, src[f][c], 4.0f ); + src[f][c] = qBound( -1000.0f, src[f][c], 1000.0f ); } } } @@ -168,6 +198,13 @@ void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuff void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ) { + if ( !useNaNHandler() ) + { + addMultipliedByBuffer( dst, src, coeffSrc, coeffSrcBuf, + frames ); + return; + } + for( int f = 0; f < frames; ++f ) { dst[f][0] += ( isinf( src[f][0] ) || isnan( src[f][0] ) ) ? 0.0f : src[f][0] * coeffSrc * coeffSrcBuf->values()[f]; @@ -177,6 +214,13 @@ void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, f void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ) { + if ( !useNaNHandler() ) + { + addMultipliedByBuffers( dst, src, coeffSrcBuf1, coeffSrcBuf2, + frames ); + return; + } + for( int f = 0; f < frames; ++f ) { dst[f][0] += ( isinf( src[f][0] ) || isnan( src[f][0] ) ) @@ -205,6 +249,12 @@ struct AddSanitizedMultipliedOp void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ) { + if ( !useNaNHandler() ) + { + addMultiplied( dst, src, coeffSrc, frames ); + return; + } + run<>( dst, src, frames, AddSanitizedMultipliedOp(coeffSrc) ); } diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index d652def42..8c838f136 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -177,11 +177,6 @@ void NotePlayHandle::setVolume( volume_t _volume ) void NotePlayHandle::setPanning( panning_t panning ) { Note::setPanning( panning ); - - MidiEvent event( MidiMetaEvent, midiChannel(), midiKey(), panningToMidi( panning ) ); - event.setMetaEvent( MidiNotePanning ); - - m_instrumentTrack->processOutEvent( event ); } diff --git a/src/core/ProjectJournal.cpp b/src/core/ProjectJournal.cpp index 57646aeaa..ce811dbc5 100644 --- a/src/core/ProjectJournal.cpp +++ b/src/core/ProjectJournal.cpp @@ -164,6 +164,11 @@ jo_id_t ProjectJournal::idToSave( jo_id_t id ) return id & ~EO_ID_MSB; } +jo_id_t ProjectJournal::idFromSave( jo_id_t id ) +{ + return id | EO_ID_MSB; +} + diff --git a/src/core/ProjectRenderer.cpp b/src/core/ProjectRenderer.cpp index 57975356e..71a5aaff8 100644 --- a/src/core/ProjectRenderer.cpp +++ b/src/core/ProjectRenderer.cpp @@ -185,25 +185,17 @@ void ProjectRenderer::run() // Skip first empty buffer. Engine::mixer()->nextBuffer(); - const Song::PlayPos & exportPos = Engine::getSong()->getPlayPos( - Song::Mode_PlaySong ); m_progress = 0; - std::pair exportEndpoints = Engine::getSong()->getExportEndpoints(); - tick_t startTick = exportEndpoints.first.getTicks(); - tick_t endTick = exportEndpoints.second.getTicks(); - tick_t lengthTicks = endTick - startTick; // Now start processing Engine::mixer()->startProcessing(false); // Continually track and emit progress percentage to listeners. - while( exportPos.getTicks() < endTick && - Engine::getSong()->isExporting() == true - && !m_abort ) + while (!Engine::getSong()->isExportDone() && !m_abort) { m_fileDev->processNextBuffer(); - const int nprog = lengthTicks == 0 ? 100 : (exportPos.getTicks()-startTick) * 100 / lengthTicks; - if( m_progress != nprog ) + const int nprog = Engine::getSong()->getExportProgress(); + if (m_progress != nprog) { m_progress = nprog; emit progressChanged( m_progress ); diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index d68f6aa65..23654d782 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -55,7 +55,10 @@ ProcessWatcher::ProcessWatcher( RemotePlugin * _p ) : void ProcessWatcher::run() { - while( !m_quit && (m_plugin->isRunning() || m_plugin->messagesLeft()) ) + m_plugin->m_process.start( m_plugin->m_exec, m_plugin->m_args ); + exec(); + m_plugin->m_process.moveToThread( m_plugin->thread() ); + while( !m_quit && m_plugin->messagesLeft() ) { msleep( 200 ); } @@ -123,9 +126,13 @@ RemotePlugin::RemotePlugin() : #endif connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), - this, SLOT( processFinished( int, QProcess::ExitStatus ) ) ); + this, SLOT( processFinished( int, QProcess::ExitStatus ) ), + Qt::DirectConnection ); connect( &m_process, SIGNAL( errorOccurred( QProcess::ProcessError ) ), - this, SLOT( processErrored( QProcess::ProcessError ) ) ); + this, SLOT( processErrored( QProcess::ProcessError ) ), + Qt::DirectConnection ); + connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), + &m_watcher, SLOT( quit() ), Qt::DirectConnection ); } @@ -133,7 +140,7 @@ RemotePlugin::RemotePlugin() : RemotePlugin::~RemotePlugin() { - m_watcher.quit(); + m_watcher.stop(); m_watcher.wait(); if( m_failed == false ) @@ -207,6 +214,11 @@ bool RemotePlugin::init(const QString &pluginExecutable, return failed(); } + // ensure the watcher is ready in case we're running again + // (e.g. 32-bit VST plugins on Windows) + m_watcher.wait(); + m_watcher.reset(); + QStringList args; #ifdef SYNC_WITH_SHM_FIFO // swap in and out for bidirectional communication @@ -219,7 +231,10 @@ bool RemotePlugin::init(const QString &pluginExecutable, #ifndef DEBUG_REMOTE_PLUGIN m_process.setProcessChannelMode( QProcess::ForwardedChannels ); m_process.setWorkingDirectory( QCoreApplication::applicationDirPath() ); - m_process.start( exec, args ); + m_exec = exec; + m_args = args; + // we start the process on the watcher thread to work around QTBUG-8819 + m_process.moveToThread( &m_watcher ); m_watcher.start( QThread::LowestPriority ); #else qDebug() << exec << args; diff --git a/src/core/RenderManager.cpp b/src/core/RenderManager.cpp index 9cad4dd1e..019e14acf 100644 --- a/src/core/RenderManager.cpp +++ b/src/core/RenderManager.cpp @@ -103,7 +103,7 @@ void RenderManager::renderTracks() Track* tk = (*it); Track::TrackTypes type = tk->type(); - // Don't mute automation tracks + // Don't render automation tracks if ( tk->isMuted() == false && ( type == Track::InstrumentTrack || type == Track::SampleTrack ) ) { @@ -115,7 +115,11 @@ void RenderManager::renderTracks() for( auto it = t2.begin(); it != t2.end(); ++it ) { Track* tk = (*it); - if ( tk->isMuted() == false ) + Track::TrackTypes type = tk->type(); + + // Don't render automation tracks + if ( tk->isMuted() == false && + ( type == Track::InstrumentTrack || type == Track::SampleTrack ) ) { m_unmuted.push_back(tk); } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 6f060664e..2f57b51c3 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -86,7 +86,9 @@ Song::Song() : m_patternToPlay( NULL ), m_loopPattern( false ), m_elapsedTicks( 0 ), - m_elapsedTacts( 0 ) + m_elapsedTacts( 0 ), + m_loopRenderCount(1), + m_loopRenderRemaining(1) { for(int i = 0; i < Mode_Count; ++i) m_elapsedMilliSeconds[i] = 0; connect( &m_tempoModel, SIGNAL( dataChanged() ), @@ -258,8 +260,6 @@ void Song::processNextBuffer() m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); - m_vstSyncController.setAbsolutePosition( - tl->loopBegin().getTicks() ); m_vstSyncController.setPlaybackJumped( true ); emit updateSampleTracks(); @@ -286,8 +286,6 @@ void Song::processNextBuffer() int ticks = m_playPos[m_playMode].getTicks() + ( int )( currentFrame / framesPerTick ); - m_vstSyncController.setAbsolutePosition( ticks ); - // did we play a whole tact? if( ticks >= MidiTime::ticksPerTact() ) { @@ -324,13 +322,12 @@ void Song::processNextBuffer() // wrap milli second counter setToTimeByTicks(ticks); - m_vstSyncController.setAbsolutePosition( ticks ); m_vstSyncController.setPlaybackJumped( true ); } } m_playPos[m_playMode].setTicks( ticks ); - if( checkLoop ) + if (checkLoop || m_loopRenderRemaining > 1) { m_vstSyncController.startCycle( tl->loopBegin().getTicks(), tl->loopEnd().getTicks() ); @@ -340,11 +337,12 @@ void Song::processNextBuffer() // beginning of the range if( m_playPos[m_playMode] >= tl->loopEnd() ) { + if (m_loopRenderRemaining > 1) + m_loopRenderRemaining--; ticks = tl->loopBegin().getTicks(); m_playPos[m_playMode].setTicks( ticks ); setToTime(tl->loopBegin()); - m_vstSyncController.setAbsolutePosition( ticks ); m_vstSyncController.setPlaybackJumped( true ); emit updateSampleTracks(); @@ -359,7 +357,17 @@ void Song::processNextBuffer() m_playPos[m_playMode].setCurrentFrame( currentFrame ); } - f_cnt_t framesToPlay = + if( framesPlayed == 0 ) + { + // update VST sync position after we've corrected frame/ + // tick count but before actually playing any frames + m_vstSyncController.setAbsolutePosition( + m_playPos[m_playMode].getTicks() + + m_playPos[m_playMode].currentFrame() + / (double) framesPerTick ); + } + + f_cnt_t framesToPlay = Engine::mixer()->framesPerPeriod() - framesPlayed; f_cnt_t framesLeft = ( f_cnt_t )framesPerTick - @@ -476,29 +484,41 @@ void Song::setModified(bool value) } } -std::pair Song::getExportEndpoints() const +bool Song::isExportDone() const { - if ( m_renderBetweenMarkers ) + return !isExporting() || m_playPos[m_playMode] >= m_exportSongEnd; +} + +int Song::getExportProgress() const +{ + MidiTime pos = m_playPos[m_playMode]; + + if (pos >= m_exportSongEnd) { - return std::pair( - m_playPos[Mode_PlaySong].m_timeLine->loopBegin(), - m_playPos[Mode_PlaySong].m_timeLine->loopEnd() - ); + return 100; } - else if ( m_exportLoop ) + else if (pos <= m_exportSongBegin) { - return std::pair( MidiTime(0, 0), MidiTime(m_length, 0) ); + return 0; + } + else if (pos >= m_exportLoopEnd) + { + pos = (m_exportLoopBegin-m_exportSongBegin) + (m_exportLoopEnd - m_exportLoopBegin) * + m_loopRenderCount + (pos - m_exportLoopEnd); + } + else if ( pos >= m_exportLoopBegin ) + { + pos = (m_exportLoopBegin-m_exportSongBegin) + ((m_exportLoopEnd - m_exportLoopBegin) * + (m_loopRenderCount - m_loopRenderRemaining)) + (pos - m_exportLoopBegin); } else { - // if not exporting as a loop, we leave one bar of padding at the end of the song to accomodate reverb, etc. - return std::pair( MidiTime(0, 0), MidiTime(m_length+1, 0) ); + pos = (pos - m_exportSongBegin); } + + return (float)pos/(float)m_exportEffectiveLength*100.0f; } - - - void Song::playSong() { m_recording = false; @@ -702,7 +722,10 @@ void Song::stop() m_playPos[m_playMode].setCurrentFrame( 0 ); m_vstSyncController.setPlaybackState( m_exporting ); - m_vstSyncController.setAbsolutePosition( m_playPos[m_playMode].getTicks() ); + m_vstSyncController.setAbsolutePosition( + m_playPos[m_playMode].getTicks() + + m_playPos[m_playMode].currentFrame() + / (double) Engine::framesPerTick() ); // remove all note-play-handles that are active Engine::mixer()->clear(); @@ -719,15 +742,41 @@ void Song::stop() void Song::startExport() { stop(); - if(m_renderBetweenMarkers) + if (m_renderBetweenMarkers) { + m_exportSongBegin = m_exportLoopBegin = m_playPos[Mode_PlaySong].m_timeLine->loopBegin(); + m_exportSongEnd = m_exportLoopEnd = m_playPos[Mode_PlaySong].m_timeLine->loopEnd(); + m_playPos[Mode_PlaySong].setTicks( m_playPos[Mode_PlaySong].m_timeLine->loopBegin().getTicks() ); } else { + m_exportSongEnd = MidiTime(m_length, 0); + + // Handle potentially ridiculous loop points gracefully. + if (m_loopRenderCount > 1 && m_playPos[Mode_PlaySong].m_timeLine->loopEnd() > m_exportSongEnd) + { + m_exportSongEnd = m_playPos[Mode_PlaySong].m_timeLine->loopEnd(); + } + + if (!m_exportLoop) + m_exportSongEnd += MidiTime(1,0); + + m_exportSongBegin = MidiTime(0,0); + m_exportLoopBegin = m_playPos[Mode_PlaySong].m_timeLine->loopBegin() < m_exportSongEnd && + m_playPos[Mode_PlaySong].m_timeLine->loopEnd() <= m_exportSongEnd ? + m_playPos[Mode_PlaySong].m_timeLine->loopBegin() : MidiTime(0,0); + m_exportLoopEnd = m_playPos[Mode_PlaySong].m_timeLine->loopBegin() < m_exportSongEnd && + m_playPos[Mode_PlaySong].m_timeLine->loopEnd() <= m_exportSongEnd ? + m_playPos[Mode_PlaySong].m_timeLine->loopEnd() : MidiTime(0,0); + m_playPos[Mode_PlaySong].setTicks( 0 ); } + m_exportEffectiveLength = (m_exportLoopBegin - m_exportSongBegin) + (m_exportLoopEnd - m_exportLoopBegin) + * m_loopRenderCount + (m_exportSongEnd - m_exportLoopEnd); + m_loopRenderRemaining = m_loopRenderCount; + playSong(); m_exporting = true; diff --git a/src/core/StepRecorder.cpp b/src/core/StepRecorder.cpp new file mode 100644 index 000000000..7a63e88e2 --- /dev/null +++ b/src/core/StepRecorder.cpp @@ -0,0 +1,366 @@ +/* + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "StepRecorder.h" +#include "StepRecorderWidget.h" +#include "PianoRoll.h" + +#include + +#include +using std::min; +using std::max; + +const int REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS = 70; + +StepRecorder::StepRecorder(PianoRoll& pianoRoll, StepRecorderWidget& stepRecorderWidget): + m_pianoRoll(pianoRoll), + m_stepRecorderWidget(stepRecorderWidget) +{ + m_stepRecorderWidget.hide(); +} + +void StepRecorder::initialize() +{ + connect(&m_updateReleasedTimer, SIGNAL(timeout()), this, SLOT(removeNotesReleasedForTooLong())); +} + +void StepRecorder::start(const MidiTime& currentPosition, const MidiTime& stepLength) +{ + m_isRecording = true; + + setStepsLength(stepLength); + + // quantize current position to get start recording position + const int q = m_pianoRoll.quantization(); + const int curPosTicks = currentPosition.getTicks(); + const int QuantizedPosTicks = (curPosTicks / q) * q; + const MidiTime& QuantizedPos = MidiTime(QuantizedPosTicks); + + m_curStepStartPos = QuantizedPos; + m_curStepLength = 0; + + m_stepRecorderWidget.show(); + + m_stepRecorderWidget.showHint(); + + prepareNewStep(); +} + +void StepRecorder::stop() +{ + m_stepRecorderWidget.hide(); + m_isRecording = false; +} + +void StepRecorder::notePressed(const Note & n) +{ + //if this is the first pressed note in step, advance position + if(!m_isStepInProgress) + { + m_isStepInProgress = true; + + //move curser one step forwards + stepForwards(); + } + + StepNote* stepNote = findCurStepNote(n.key()); + if(stepNote == nullptr) + { + m_curStepNotes.append(new StepNote(Note(m_curStepLength, m_curStepStartPos, n.key(), n.getVolume(), n.getPanning()))); + m_pianoRoll.update(); + } + else if (stepNote->isReleased()) + { + stepNote->setPressed(); + } +} + +void StepRecorder::noteReleased(const Note & n) +{ + StepNote* stepNote = findCurStepNote(n.key()); + + if(stepNote != nullptr && stepNote->isPressed()) + { + stepNote->setReleased(); + + //if m_updateReleasedTimer is not already active, activate it + //(when activated, the timer will re-set itself as long as there are released notes) + if(!m_updateReleasedTimer.isActive()) + { + m_updateReleasedTimer.start(REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS); + } + + //check if all note are released, apply notes to pattern(or dimiss if length is zero) and prepare to record next step + if(allCurStepNotesReleased()) + { + if(m_curStepLength > 0) + { + applyStep(); + } + else + { + dismissStep(); + } + } + } +} + +bool StepRecorder::keyPressEvent(QKeyEvent* ke) +{ + bool event_handled = false; + + switch(ke->key()) + { + case Qt::Key_Right: + { + if(!ke->isAutoRepeat()) + { + stepForwards(); + } + event_handled = true; + break; + } + + case Qt::Key_Left: + { + if(!ke->isAutoRepeat()) + { + stepBackwards(); + } + event_handled = true; + break; + } + } + + return event_handled; +} + +void StepRecorder::setStepsLength(const MidiTime& newLength) +{ + if(m_isStepInProgress) + { + //update current step length by the new amount : (number_of_steps * newLength) + m_curStepLength = (m_curStepLength / m_stepsLength) * newLength; + + updateCurStepNotes(); + } + + m_stepsLength = newLength; + + updateWidget(); +} + +QVector StepRecorder::getCurStepNotes() +{ + QVector notes; + + if(m_isStepInProgress) + { + for(StepNote* stepNote: m_curStepNotes) + { + notes.append(&stepNote->m_note); + } + } + + return notes; +} + +void StepRecorder::stepForwards() +{ + if(m_isStepInProgress) + { + m_curStepLength += m_stepsLength; + + updateCurStepNotes(); + } + else + { + m_curStepStartPos += m_stepsLength; + } + + updateWidget(); +} + +void StepRecorder::stepBackwards() +{ + if(m_isStepInProgress) + { + if(m_curStepLength > 0) + { + m_curStepLength = max(m_curStepLength - m_stepsLength, 0); + } + else + { + //if length is already zero - move starting position backwards + m_curStepStartPos = max(m_curStepStartPos - m_stepsLength, 0); + } + + updateCurStepNotes(); + } + else + { + m_curStepStartPos = max(m_curStepStartPos - m_stepsLength, 0); + } + + updateWidget(); +} + +void StepRecorder::applyStep() +{ + m_pattern->addJournalCheckPoint(); + + for (const StepNote* stepNote : m_curStepNotes) + { + m_pattern->addNote(stepNote->m_note, false); + } + + m_pattern->rearrangeAllNotes(); + m_pattern->updateLength(); + m_pattern->dataChanged(); + Engine::getSong()->setModified(); + + prepareNewStep(); +} + +void StepRecorder::dismissStep() +{ + if(!m_isStepInProgress) + { + return; + } + + prepareNewStep(); +} + +void StepRecorder::prepareNewStep() +{ + for(StepNote* stepNote : m_curStepNotes) + { + delete stepNote; + } + m_curStepNotes.clear(); + + m_isStepInProgress = false; + + m_curStepStartPos = getCurStepEndPos(); + m_curStepLength = 0; + + updateWidget(); +} + +void StepRecorder::setCurrentPattern( Pattern* newPattern ) +{ + if(m_pattern != NULL && m_pattern != newPattern) + { + dismissStep(); + } + + m_pattern = newPattern; +} + +void StepRecorder::removeNotesReleasedForTooLong() +{ + int nextTimout = std::numeric_limits::max(); + bool notesRemoved = false; + + QMutableVectorIterator itr(m_curStepNotes); + while (itr.hasNext()) + { + StepNote* stepNote = itr.next(); + + if(stepNote->isReleased()) + { + const int timeSinceReleased = stepNote->timeSinceReleased(); // capture value to avoid wraparound when calculting nextTimout + if (timeSinceReleased >= REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS) + { + delete stepNote; + itr.remove(); + notesRemoved = true; + } + else + { + nextTimout = min(nextTimout, REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS - timeSinceReleased); + } + } + } + + if(notesRemoved) + { + m_pianoRoll.update(); + } + + if(nextTimout != std::numeric_limits::max()) + { + m_updateReleasedTimer.start(nextTimout); + } + else + { + // no released note found for next timout, stop timer + m_updateReleasedTimer.stop(); + } +} + +MidiTime StepRecorder::getCurStepEndPos() +{ + return m_curStepStartPos + m_curStepLength; +} + +void StepRecorder::updateCurStepNotes() +{ + for (StepNote* stepNote : m_curStepNotes) + { + stepNote->m_note.setLength(m_curStepLength); + stepNote->m_note.setPos(m_curStepStartPos); + } +} + +void StepRecorder::updateWidget() +{ + m_stepRecorderWidget.setStartPosition(m_curStepStartPos); + m_stepRecorderWidget.setEndPosition(getCurStepEndPos()); + m_stepRecorderWidget.setStepsLength(m_stepsLength); +} + +bool StepRecorder::allCurStepNotesReleased() +{ + for (const StepNote* stepNote : m_curStepNotes) + { + if(stepNote->isPressed()) + { + return false; + } + } + + return true; +} + +StepRecorder::StepNote* StepRecorder::findCurStepNote(const int key) +{ + for (StepNote* stepNote : m_curStepNotes) + { + if(stepNote->m_note.key() == key) + { + return stepNote; + } + } + + return nullptr; +} diff --git a/src/core/Track.cpp b/src/core/Track.cpp index aec0e5150..5e6758fde 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -909,10 +909,18 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) else if( m_action == MoveSelection ) { const int dx = me->x() - m_initialMousePos.x(); + const bool snap = !(me->modifiers() & Qt::ControlModifier) && + me->button() == Qt::NoButton; QVector so = m_trackView->trackContainerView()->selectedObjects(); QVector tcos; - MidiTime smallest_pos, t; + int smallestPos = 0; + MidiTime dtick = MidiTime( static_cast( dx * + MidiTime::ticksPerTact() / ppt ) ); + if( snap ) + { + dtick = dtick.toNearestTact(); + } // find out smallest position of all selected objects for not // moving an object before zero for( QVector::iterator it = so.begin(); @@ -926,23 +934,18 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) } TrackContentObject * tco = tcov->m_tco; tcos.push_back( tco ); - smallest_pos = qMin( smallest_pos, - (int)tco->startPosition() + - static_cast( dx * - MidiTime::ticksPerTact() / ppt ) ); + smallestPos = qMin( smallestPos, + (int)tco->startPosition() + dtick ); + } + dtick -= smallestPos; + if( snap ) + { + dtick = dtick.toAbsoluteTact(); // round toward 0 } for( QVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) { - t = ( *it )->startPosition() + - static_cast( dx *MidiTime::ticksPerTact() / - ppt )-smallest_pos; - if( ! ( me->modifiers() & Qt::ControlModifier ) - && me->button() == Qt::NoButton ) - { - t = t.toNearestTact(); - } - ( *it )->movePosition( t ); + ( *it )->movePosition( ( *it )->startPosition() + dtick ); } } else if( m_action == Resize || m_action == ResizeLeft ) diff --git a/src/core/VstSyncController.cpp b/src/core/VstSyncController.cpp index b441d0507..dd9660cb5 100644 --- a/src/core/VstSyncController.cpp +++ b/src/core/VstSyncController.cpp @@ -136,12 +136,12 @@ VstSyncController::~VstSyncController() -void VstSyncController::setAbsolutePosition( int ticks ) +void VstSyncController::setAbsolutePosition( double ticks ) { #ifdef VST_SNC_LATENCY - m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 ) - m_syncData->m_latency; + m_syncData->ppqPos = ( ( ticks + 0 ) / 48.0 ) - m_syncData->m_latency; #else - m_syncData->ppqPos = ( ( ticks + 0 ) / (float)48 ); + m_syncData->ppqPos = ( ( ticks + 0 ) / 48.0 ); #endif } diff --git a/src/core/audio/AudioPort.cpp b/src/core/audio/AudioPort.cpp index eda000bb9..71544dde2 100644 --- a/src/core/audio/AudioPort.cpp +++ b/src/core/audio/AudioPort.cpp @@ -118,7 +118,9 @@ void AudioPort::doProcessing() { if( ph->buffer() ) { - if( ph->usesBuffer() ) + if( ph->usesBuffer() + && ( ph->type() == PlayHandle::TypeNotePlayHandle + || !MixHelpers::isSilent( ph->buffer(), fpp ) ) ) { m_bufferUsage = true; MixHelpers::add( m_portBuffer, ph->buffer(), fpp ); diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index 6abb29453..5566d7a36 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -27,6 +27,10 @@ #include "AudioPortAudio.h" #ifndef LMMS_HAVE_PORTAUDIO +void AudioPortAudioSetupUtil::updateBackends() +{ +} + void AudioPortAudioSetupUtil::updateDevices() { } @@ -328,6 +332,28 @@ int AudioPortAudio::_process_callback( + +void AudioPortAudioSetupUtil::updateBackends() +{ + PaError err = Pa_Initialize(); + if( err != paNoError ) { + printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) ); + return; + } + + const PaHostApiInfo * hi; + for( int i = 0; i < Pa_GetHostApiCount(); ++i ) + { + hi = Pa_GetHostApiInfo( i ); + m_backendModel.addItem( hi->name ); + } + + Pa_Terminate(); +} + + + + void AudioPortAudioSetupUtil::updateDevices() { PaError err = Pa_Initialize(); @@ -409,37 +435,6 @@ AudioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : m_channels->setLabel( tr( "CHANNELS" ) ); m_channels->move( 308, 20 );*/ - // Setup models - PaError err = Pa_Initialize(); - if( err != paNoError ) { - printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) ); - return; - } - - // todo: setup backend model - const PaHostApiInfo * hi; - for( int i = 0; i < Pa_GetHostApiCount(); ++i ) - { - hi = Pa_GetHostApiInfo( i ); - m_setupUtil.m_backendModel.addItem( hi->name ); - } - - Pa_Terminate(); - - - const QString& backend = ConfigManager::inst()->value( "audioportaudio", - "backend" ); - const QString& device = ConfigManager::inst()->value( "audioportaudio", - "device" ); - - int i = qMax( 0, m_setupUtil.m_backendModel.findText( backend ) ); - m_setupUtil.m_backendModel.setValue( i ); - - m_setupUtil.updateDevices(); - - i = qMax( 0, m_setupUtil.m_deviceModel.findText( device ) ); - m_setupUtil.m_deviceModel.setValue( i ); - connect( &m_setupUtil.m_backendModel, SIGNAL( dataChanged() ), &m_setupUtil, SLOT( updateDevices() ) ); @@ -478,6 +473,33 @@ void AudioPortAudio::setupWidget::saveSettings() } + + +void AudioPortAudio::setupWidget::show() +{ + if( m_setupUtil.m_backendModel.size() == 0 ) + { + // populate the backend model the first time we are shown + m_setupUtil.updateBackends(); + + const QString& backend = ConfigManager::inst()->value( + "audioportaudio", "backend" ); + const QString& device = ConfigManager::inst()->value( + "audioportaudio", "device" ); + + int i = qMax( 0, m_setupUtil.m_backendModel.findText( backend ) ); + m_setupUtil.m_backendModel.setValue( i ); + + m_setupUtil.updateDevices(); + + i = qMax( 0, m_setupUtil.m_deviceModel.findText( device ) ); + m_setupUtil.m_deviceModel.setValue( i ); + } + + AudioDeviceSetupWidget::show(); +} + + #endif diff --git a/src/core/main.cpp b/src/core/main.cpp index 0289f0c53..f579ec8f6 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -65,6 +65,7 @@ #include "GuiApplication.h" #include "ImportFilter.h" #include "MainWindow.h" +#include "MixHelpers.h" #include "OutputSettings.h" #include "ProjectRenderer.h" #include "RenderManager.h" @@ -105,6 +106,21 @@ static inline QString baseName( const QString & file ) } +#ifdef LMMS_BUILD_WIN32 +// Workaround for old MinGW +#ifdef __MINGW32__ +extern "C" _CRTIMP errno_t __cdecl freopen_s(FILE** _File, + const char *_Filename, const char *_Mode, FILE *_Stream); +#endif + +// For qInstallMessageHandler +void consoleMessageHandler(QtMsgType type, + const QMessageLogContext &context, const QString &msg) +{ + QByteArray localMsg = msg.toLocal8Bit(); + fprintf(stderr, "%s\n", localMsg.constData()); +} +#endif inline void loadTranslation( const QString & tname, @@ -243,6 +259,33 @@ int main( int argc, char * * argv ) signal(SIGFPE, signalHandler); #endif +#ifdef LMMS_BUILD_WIN32 + // Don't touch redirected streams here + // GetStdHandle should be called before AttachConsole + HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE); + FILE *fIn, *fOut, *fErr; + // Enable console output if available + if (AttachConsole(ATTACH_PARENT_PROCESS)) + { + if (!hStdIn) + { + freopen_s(&fIn, "CONIN$", "r", stdin); + } + if (!hStdOut) + { + freopen_s(&fOut, "CONOUT$", "w", stdout); + } + if (!hStdErr) + { + freopen_s(&fErr, "CONOUT$", "w", stderr); + } + } + // Make Qt's debug message handlers work + qInstallMessageHandler(consoleMessageHandler); +#endif + // initialize memory managers NotePlayHandleManager::init(); @@ -301,7 +344,13 @@ int main( int argc, char * * argv ) return EXIT_FAILURE; } #endif - +#ifdef LMMS_BUILD_LINUX + // don't let OS steal the menu bar. FIXME: only effective on Qt4 + QCoreApplication::setAttribute( Qt::AA_DontUseNativeMenuBar ); +#endif +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif QCoreApplication * app = coreOnly ? new QCoreApplication( argc, argv ) : new MainApplication( argc, argv ); @@ -646,6 +695,10 @@ int main( int argc, char * * argv ) ConfigManager::inst()->loadConfigFile(configFile); + // Hidden settings + MixHelpers::setNaNHandler( ConfigManager::inst()->value( "app", + "nanhandler", "1" ).toInt() ); + // set language QString pos = ConfigManager::inst()->value( "app", "language" ); if( pos.isEmpty() ) @@ -930,5 +983,15 @@ int main( int argc, char * * argv ) printf( "\n" ); } +#ifdef LMMS_BUILD_WIN32 + // Cleanup console + HWND hConsole = GetConsoleWindow(); + if (hConsole) + { + SendMessage(hConsole, WM_CHAR, (WPARAM)VK_RETURN, (LPARAM)0); + FreeConsole(); + } +#endif + return ret; } diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 5b4050bca..d5ff64612 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -87,6 +87,7 @@ SET(LMMS_SRCS gui/widgets/TrackLabelButton.cpp gui/widgets/TrackRenameLineEdit.cpp gui/widgets/VisualizationWidget.cpp + gui/widgets/StepRecorderWidget.cpp PARENT_SCOPE ) diff --git a/src/gui/ExportProjectDialog.cpp b/src/gui/ExportProjectDialog.cpp index b50c9941b..f3b432f99 100644 --- a/src/gui/ExportProjectDialog.cpp +++ b/src/gui/ExportProjectDialog.cpp @@ -128,6 +128,7 @@ void ExportProjectDialog::accept() void ExportProjectDialog::closeEvent( QCloseEvent * _ce ) { + Engine::getSong()->setLoopRenderCount(1); if( m_renderManager ) { m_renderManager->abortProcessing(); } @@ -187,6 +188,7 @@ void ExportProjectDialog::startExport() Engine::getSong()->setExportLoop( exportLoopCB->isChecked() ); Engine::getSong()->setRenderBetweenMarkers( renderMarkersCB->isChecked() ); + Engine::getSong()->setLoopRenderCount(loopCountSB->value()); connect( m_renderManager.get(), SIGNAL( progressChanged( int ) ), progressBar, SLOT( setValue( int ) ) ); diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 63053663a..440e37d10 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -73,7 +73,7 @@ FxMixerView::FxMixerView() : // Set margins ml->setContentsMargins( 0, 4, 0, 0 ); - + // Channel area m_channelAreaWidget = new QWidget; chLayout = new QHBoxLayout( m_channelAreaWidget ); @@ -138,9 +138,9 @@ FxMixerView::FxMixerView() : ml->addWidget( newChannelBtn, 0, Qt::AlignTop ); - // add the stacked layout for the effect racks of fx channels + // add the stacked layout for the effect racks of fx channels ml->addWidget( m_racksWidget, 0, Qt::AlignTop | Qt::AlignRight ); - + setCurrentFxLine( m_fxChannelViews[0]->m_fxLine ); setLayout( ml ); @@ -219,10 +219,10 @@ void FxMixerView::refreshDisplay() chLayout->addWidget(m_fxChannelViews[i]->m_fxLine); m_racksLayout->addWidget( m_fxChannelViews[i]->m_rackView ); } - + // set selected fx line to 0 setCurrentFxLine( 0 ); - + // update all fx lines for( int i = 0; i < m_fxChannelViews.size(); ++i ) { @@ -308,7 +308,7 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, connect(&fxChannel->m_soloModel, SIGNAL( dataChanged() ), _mv, SLOT ( toggledSolo() ) ); ToolTip::add( m_soloBtn, tr( "Solo FX channel" ) ); - + // Create EffectRack for the channel m_rackView = new EffectRackView( &fxChannel->m_fxChain, _mv->m_racksWidget ); m_rackView->setFixedSize( 245, FxLine::FxLineHeight ); @@ -354,6 +354,8 @@ void FxMixerView::updateFxLine(int index) // does current channel send to this channel? int selIndex = m_currentFxLine->channelIndex(); FxLine * thisLine = m_fxChannelViews[index]->m_fxLine; + thisLine->setToolTip( Engine::fxMixer()->effectChannel( index )->m_name ); + FloatModel * sendModel = mix->channelSendModel(selIndex, index); if( sendModel == NULL ) { diff --git a/src/gui/GuiApplication.cpp b/src/gui/GuiApplication.cpp index 5518eb81d..a7a3d1baa 100644 --- a/src/gui/GuiApplication.cpp +++ b/src/gui/GuiApplication.cpp @@ -55,11 +55,6 @@ GuiApplication* GuiApplication::instance() GuiApplication::GuiApplication() { - // enable HiDPI scaling before showing anything (Qt 5.6+ only) - #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); - #endif - // prompt the user to create the LMMS working directory (e.g. ~/Documents/lmms) if it doesn't exist if ( !ConfigManager::inst()->hasWorkingDir() && QMessageBox::question( NULL, diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 678f5bff9..38db2287c 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -66,6 +66,8 @@ #include "MidiApple.h" #include "MidiDummy.h" +constexpr int BUFFERSIZE_RESOLUTION = 32; + inline void labelWidget( QWidget * _w, const QString & _txt ) { QLabel * title = new QLabel( _txt, _w ); @@ -98,6 +100,8 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : "disablebackup" ).toInt() ), m_openLastProject( ConfigManager::inst()->value( "app", "openlastproject" ).toInt() ), + m_NaNHandler( ConfigManager::inst()->value( "app", + "nanhandler", "1" ).toInt() ), m_hqAudioDev( ConfigManager::inst()->value( "mixer", "hqaudio" ).toInt() ), m_lang( ConfigManager::inst()->value( "app", @@ -126,7 +130,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : m_compactTrackButtons( ConfigManager::inst()->value( "ui", "compacttrackbuttons" ).toInt() ), m_syncVSTPlugins( ConfigManager::inst()->value( "ui", - "syncvstplugins" ).toInt() ), + "syncvstplugins", "1" ).toInt() ), m_animateAFP(ConfigManager::inst()->value( "ui", "animateafp", "1" ).toInt() ), m_printNoteLabels(ConfigManager::inst()->value( "ui", @@ -134,7 +138,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : m_displayWaveform(ConfigManager::inst()->value( "ui", "displaywaveform").toInt() ), m_disableAutoQuit(ConfigManager::inst()->value( "ui", - "disableautoquit").toInt() ), + "disableautoquit", "1" ).toInt() ), m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ) { setWindowIcon( embed::getIconPixmap( "setup_general" ) ); @@ -176,12 +180,12 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : bufsize_tw->setFixedHeight( 80 ); m_bufSizeSlider = new QSlider( Qt::Horizontal, bufsize_tw ); - m_bufSizeSlider->setRange( 1, 256 ); + m_bufSizeSlider->setRange( 1, 128 ); m_bufSizeSlider->setTickPosition( QSlider::TicksBelow ); m_bufSizeSlider->setPageStep( 8 ); m_bufSizeSlider->setTickInterval( 8 ); m_bufSizeSlider->setGeometry( 10, 16, 340, 18 ); - m_bufSizeSlider->setValue( m_bufferSize / 64 ); + m_bufSizeSlider->setValue( m_bufferSize / BUFFERSIZE_RESOLUTION ); connect( m_bufSizeSlider, SIGNAL( valueChanged( int ) ), this, SLOT( setBufferSize( int ) ) ); @@ -245,6 +249,15 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : misc_tw->setFixedHeight( YDelta*labelNumber + HeaderSize ); + // Advanced setting, hidden for now + if( false ) + { + LedCheckBox * useNaNHandler = new LedCheckBox( + tr( "Use built-in NaN handler" ), + misc_tw ); + useNaNHandler->setChecked( m_NaNHandler ); + } + TabWidget* embed_tw = new TabWidget( tr( "PLUGIN EMBEDDING" ), general); embed_tw->setFixedHeight( 48 ); m_vstEmbedComboBox = new QComboBox( embed_tw ); @@ -813,6 +826,8 @@ void SetupDialog::accept() QString::number( !m_disableBackup ) ); ConfigManager::inst()->setValue( "app", "openlastproject", QString::number( m_openLastProject ) ); + ConfigManager::inst()->setValue( "app", "nanhandler", + QString::number( m_NaNHandler ) ); ConfigManager::inst()->setValue( "mixer", "hqaudio", QString::number( m_hqAudioDev ) ); ConfigManager::inst()->setValue( "ui", "smoothscroll", @@ -877,7 +892,7 @@ void SetupDialog::accept() void SetupDialog::setBufferSize( int _value ) { - const int step = DEFAULT_BUFFER_SIZE / 64; + const int step = DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION; if( _value > step && _value % step ) { int mod_value = _value % step; @@ -897,7 +912,7 @@ void SetupDialog::setBufferSize( int _value ) m_bufSizeSlider->setValue( _value ); } - m_bufferSize = _value * 64; + m_bufferSize = _value * BUFFERSIZE_RESOLUTION; m_bufSizeLbl->setText( tr( "Frames: %1\nLatency: %2 ms" ).arg( m_bufferSize ).arg( 1000.0f * m_bufferSize / @@ -910,7 +925,7 @@ void SetupDialog::setBufferSize( int _value ) void SetupDialog::resetBufSize() { - setBufferSize( DEFAULT_BUFFER_SIZE / 64 ); + setBufferSize( DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION ); } diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 7340d428c..c47184137 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -174,32 +174,6 @@ void SubWindow::elideText( QLabel *label, QString text ) -/** - * @brief SubWindow::isMaximized - * - * This function checks if the subwindow is maximized. - * QMdiSubWindow::isMaximized() doesn't work on MacOS. - * Therefore we need our own implementation for checking this - * @return true if the subwindow is maximized at the moment. - * false if it's not. - */ -bool SubWindow::isMaximized() -{ -#ifdef LMMS_BUILD_APPLE - // check if subwindow size is identical to the MdiArea size, accounting for scrollbars - int hScrollBarHeight = mdiArea()->horizontalScrollBar()->isVisible() ? mdiArea()->horizontalScrollBar()->size().height() : 0; - int vScrollBarWidth = mdiArea()->verticalScrollBar()->isVisible() ? mdiArea()->verticalScrollBar()->size().width() : 0; - QSize areaSize( this->mdiArea()->size().width() - vScrollBarWidth, this->mdiArea()->size().height() - hScrollBarHeight ); - - return areaSize == this->size(); -#else - return QMdiSubWindow::isMaximized(); -#endif -} - - - - /** * @brief SubWindow::getTrueNormalGeometry * @@ -388,8 +362,11 @@ void SubWindow::focusChanged( QMdiSubWindow *subWindow ) */ void SubWindow::resizeEvent( QResizeEvent * event ) { - adjustTitleBar(); + // When the parent QMdiArea gets resized, maximized subwindows also gets resized, if any. + // In that case, we should call QMdiSubWindow::resizeEvent first + // to ensure we get the correct window state. QMdiSubWindow::resizeEvent( event ); + adjustTitleBar(); // if the window was resized and ISN'T minimized/maximized/fullscreen, // then save the current size diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index 4e51a19f4..9c2f38559 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -89,7 +89,7 @@ TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, QTimer * updateTimer = new QTimer( this ); connect( updateTimer, SIGNAL( timeout() ), this, SLOT( updatePosition() ) ); - updateTimer->start( 50 ); + updateTimer->start( 1000 / 60 ); // 60 fps connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int,int ) ), this, SLOT( update() ) ); } diff --git a/src/gui/dialogs/export_project.ui b/src/gui/dialogs/export_project.ui index 1ec4fe123..6b175de78 100644 --- a/src/gui/dialogs/export_project.ui +++ b/src/gui/dialogs/export_project.ui @@ -7,19 +7,19 @@ 0 0 379 - 374 + 400 379 - 374 + 400 379 - 374 + 400 @@ -40,6 +40,47 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Render Looped Section: + + + + + + + time(s) + + + 1 + + + 99 + + + 1 + + + + + + diff --git a/src/gui/editors/Editor.cpp b/src/gui/editors/Editor.cpp index bdc3e55d4..b82453acf 100644 --- a/src/gui/editors/Editor.cpp +++ b/src/gui/editors/Editor.cpp @@ -73,11 +73,12 @@ void Editor::togglePlayStop() play(); } -Editor::Editor(bool record) : +Editor::Editor(bool record, bool stepRecord) : m_toolBar(new DropToolBar(this)), m_playAction(nullptr), m_recordAction(nullptr), m_recordAccompanyAction(nullptr), + m_toggleStepRecordingAction(nullptr), m_stopAction(nullptr) { m_toolBar = addDropToolBarToTop(tr("Transport controls")); @@ -93,11 +94,13 @@ Editor::Editor(bool record) : m_recordAction = new QAction(embed::getIconPixmap("record"), tr("Record"), this); m_recordAccompanyAction = new QAction(embed::getIconPixmap("record_accompany"), tr("Record while playing"), this); + m_toggleStepRecordingAction = new QAction(embed::getIconPixmap("record_step_off"), tr("Toggle Step Recording"), this); // Set up connections connect(m_playAction, SIGNAL(triggered()), this, SLOT(play())); connect(m_recordAction, SIGNAL(triggered()), this, SLOT(record())); connect(m_recordAccompanyAction, SIGNAL(triggered()), this, SLOT(recordAccompany())); + connect(m_toggleStepRecordingAction, SIGNAL(triggered()), this, SLOT(toggleStepRecording())); connect(m_stopAction, SIGNAL(triggered()), this, SLOT(stop())); new QShortcut(Qt::Key_Space, this, SLOT(togglePlayStop())); @@ -108,6 +111,10 @@ Editor::Editor(bool record) : addButton(m_recordAction, "recordButton"); addButton(m_recordAccompanyAction, "recordAccompanyButton"); } + if(stepRecord) + { + addButton(m_toggleStepRecordingAction, "stepRecordButton"); + } addButton(m_stopAction, "stopButton"); } diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index e5f6458b5..bf65444f2 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -62,6 +62,7 @@ #include "stdshims.h" #include "TextFloat.h" #include "TimeLineWidget.h" +#include "StepRecorderWidget.h" using std::move; @@ -177,11 +178,15 @@ PianoRoll::PianoRoll() : m_ctrlMode( ModeDraw ), m_mouseDownRight( false ), m_scrollBack( false ), + m_stepRecorderWidget(this, DEFAULT_PR_PPT, PR_TOP_MARGIN, PR_BOTTOM_MARGIN + m_notesEditHeight, WHITE_KEY_WIDTH, 0), + m_stepRecorder(*this, m_stepRecorderWidget), m_barLineColor( 0, 0, 0 ), m_beatLineColor( 0, 0, 0 ), m_lineColor( 0, 0, 0 ), m_noteModeColor( 0, 0, 0 ), m_noteColor( 0, 0, 0 ), + m_ghostNoteColor( 0, 0, 0 ), + m_ghostNoteTextColor( 0, 0, 0 ), m_barColor( 0, 0, 0 ), m_selectedNoteColor( 0, 0, 0 ), m_textColor( 0, 0, 0 ), @@ -189,7 +194,9 @@ PianoRoll::PianoRoll() : m_textShadow( 0, 0, 0 ), m_markedSemitoneColor( 0, 0, 0 ), m_noteOpacity( 255 ), + m_ghostNoteOpacity( 255 ), m_noteBorders( true ), + m_ghostNoteBorders( true ), m_backgroundShade( 0, 0, 0 ) { // gui names of edit modes @@ -319,6 +326,10 @@ PianoRoll::PianoRoll() : connect( m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ), this, SLOT( updatePosition( const MidiTime & ) ) ); + //update timeline when in step-recording mode + connect( &m_stepRecorderWidget, SIGNAL( positionChanged( const MidiTime & ) ), + this, SLOT( updatePositionStepRecording( const MidiTime & ) ) ); + // update timeline when in record-accompany mode connect( Engine::getSong()->getPlayPos( Song::Mode_PlaySong ).m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ), @@ -391,7 +402,7 @@ PianoRoll::PianoRoll() : // Note length change can cause a redraw if Q is set to lock connect( &m_noteLenModel, SIGNAL( dataChanged() ), - this, SLOT( quantizeChanged() ) ); + this, SLOT( noteLengthChanged() ) ); // Set up scale model const InstrumentFunctionNoteStacking::ChordTable& chord_table = @@ -440,6 +451,8 @@ PianoRoll::PianoRoll() : //connection for selecion from timeline connect( m_timeLine, SIGNAL( regionSelectedFromPixels( int, int ) ), this, SLOT( selectRegionFromPixels( int, int ) ) ); + + m_stepRecorder.initialize(); } @@ -448,6 +461,7 @@ void PianoRoll::reset() { m_lastNoteVolume = DefaultVolume; m_lastNotePanning = DefaultPanning; + clearGhostPattern(); } void PianoRoll::showTextFloat(const QString &text, const QPoint &pos, int timeout) @@ -599,6 +613,48 @@ PianoRoll::~PianoRoll() } +void PianoRoll::setGhostPattern( Pattern* newPattern ) +{ + // Expects a pointer to a pattern or nullptr. + m_ghostNotes.clear(); + if( newPattern != nullptr ) + { + for( Note *note : newPattern->notes() ) + { + Note * new_note = new Note( note->length(), note->pos(), note->key() ); + m_ghostNotes.push_back( new_note ); + } + emit ghostPatternSet( true ); + } +} + + +void PianoRoll::loadGhostNotes( const QDomElement & de ) +{ + // Load ghost notes from DOM element. + if( de.isElement() ) + { + QDomNode node = de.firstChild(); + while( !node.isNull() ) + { + Note * n = new Note; + n->restoreState( node.toElement() ); + m_ghostNotes.push_back( n ); + node = node.nextSibling(); + } + emit ghostPatternSet( true ); + } +} + + +void PianoRoll::clearGhostPattern() +{ + setGhostPattern( nullptr ); + emit ghostPatternSet( false ); + update(); +} + + void PianoRoll::setCurrentPattern( Pattern* newPattern ) { if( hasValidPattern() ) @@ -613,12 +669,19 @@ void PianoRoll::setCurrentPattern( Pattern* newPattern ) Engine::getSong()->playPattern( NULL ); } + if(m_stepRecorder.isRecording()) + { + m_stepRecorder.stop(); + } + // set new data m_pattern = newPattern; m_currentPosition = 0; m_currentNote = NULL; m_startKey = INITIAL_START_KEY; + m_stepRecorder.setCurrentPattern(newPattern); + if( ! hasValidPattern() ) { //resizeEvent( NULL ); @@ -801,6 +864,30 @@ bool PianoRoll::noteBorders() const void PianoRoll::setNoteBorders( const bool b ) { m_noteBorders = b; } +QColor PianoRoll::ghostNoteColor() const +{ return m_ghostNoteColor; } + +void PianoRoll::setGhostNoteColor( const QColor & c ) +{ m_ghostNoteColor = c; } + +QColor PianoRoll::ghostNoteTextColor() const +{ return m_ghostNoteTextColor; } + +void PianoRoll::setGhostNoteTextColor( const QColor & c ) +{ m_ghostNoteTextColor = c; } + +int PianoRoll::ghostNoteOpacity() const +{ return m_ghostNoteOpacity; } + +void PianoRoll::setGhostNoteOpacity( const int i ) +{ m_ghostNoteOpacity = i; } + +bool PianoRoll::ghostNoteBorders() const +{ return m_ghostNoteBorders; } + +void PianoRoll::setGhostNoteBorders( const bool b ) +{ m_ghostNoteBorders = b; } + QColor PianoRoll::backgroundShade() const { return m_backgroundShade; } @@ -810,7 +897,6 @@ void PianoRoll::setBackgroundShade( const QColor & c ) - void PianoRoll::drawNoteRect( QPainter & p, int x, int y, int width, const Note * n, const QColor & noteCol, const QColor & noteTextColor, const QColor & selCol, const int noteOpc, const bool borders, bool drawNoteName ) @@ -990,6 +1076,7 @@ void PianoRoll::shiftSemiTone( int amount ) // shift notes by amount semitones { if (!hasValidPattern()) {return;} + m_pattern->addJournalCheckPoint(); bool useAllNotes = ! isSelection(); for( Note *note : m_pattern->notes() ) { @@ -1016,6 +1103,7 @@ void PianoRoll::shiftPos( int amount ) //shift notes pos by amount { if (!hasValidPattern()) {return;} + m_pattern->addJournalCheckPoint(); bool useAllNotes = ! isSelection(); bool first = true; @@ -1083,8 +1171,19 @@ int PianoRoll::selectionCount() const // how many notes are selected? -void PianoRoll::keyPressEvent(QKeyEvent* ke ) +void PianoRoll::keyPressEvent(QKeyEvent* ke) { + if(m_stepRecorder.isRecording()) + { + bool handled = m_stepRecorder.keyPressEvent(ke); + if(handled) + { + ke->accept(); + update(); + return; + } + } + if( hasValidPattern() && ke->modifiers() == Qt::NoModifier ) { const int key_num = PianoView::getKeyFromKeyEvent( ke ) + ( DefaultOctave - 1 ) * KeysPerOctave; @@ -1833,7 +1932,7 @@ void PianoRoll::testPlayNote( Note * n ) { m_lastKey = n->key(); - if( ! n->isPlaying() && ! m_recording ) + if( ! n->isPlaying() && ! m_recording && ! m_stepRecorder.isRecording()) { n->setIsPlaying( true ); @@ -2066,6 +2165,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) NOTE_EDIT_MIN_HEIGHT, height() - PR_TOP_MARGIN - NOTE_EDIT_RESIZE_BAR - PR_BOTTOM_MARGIN - KEY_AREA_MIN_HEIGHT ); + + m_stepRecorderWidget.setBottomMargin(PR_BOTTOM_MARGIN + m_notesEditHeight); repaint(); return; } @@ -3024,6 +3125,50 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) QPolygonF editHandles; + // -- Begin ghost pattern + if( !m_ghostNotes.empty() ) + { + for( const Note *note : m_ghostNotes ) + { + int len_ticks = note->length(); + + if( len_ticks == 0 ) + { + continue; + } + else if( len_ticks < 0 ) + { + len_ticks = 4; + } + const int key = note->key() - m_startKey + 1; + + int pos_ticks = note->pos(); + + int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact(); + const int x = ( pos_ticks - m_currentPosition ) * + m_ppt / MidiTime::ticksPerTact(); + // skip this note if not in visible area at all + if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) + { + continue; + } + + // is the note in visible area? + if( key > 0 && key <= visible_keys ) + { + + // we've done and checked all, let's draw the + // note + drawNoteRect( p, x + WHITE_KEY_WIDTH, + y_base - key * KEY_LINE_HEIGHT, + note_width, note, ghostNoteColor(), ghostNoteTextColor(), selectedNoteColor(), + ghostNoteOpacity(), ghostNoteBorders(), drawNoteNames ); + } + + } + } + // -- End ghost pattern + for( const Note *note : m_pattern->notes() ) { int len_ticks = note->length(); @@ -3112,6 +3257,41 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) } } + //draw current step recording notes + for( const Note *note : m_stepRecorder.getCurStepNotes() ) + { + int len_ticks = note->length(); + + if( len_ticks == 0 ) + { + continue; + } + + const int key = note->key() - m_startKey + 1; + + int pos_ticks = note->pos(); + + int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact(); + const int x = ( pos_ticks - m_currentPosition ) * + m_ppt / MidiTime::ticksPerTact(); + // skip this note if not in visible area at all + if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) + { + continue; + } + + // is the note in visible area? + if( key > 0 && key <= visible_keys ) + { + + // we've done and checked all, let's draw the note + drawNoteRect( p, x + WHITE_KEY_WIDTH, + y_base - key * KEY_LINE_HEIGHT, + note_width, note, m_stepRecorder.curStepNoteColor(), noteTextColor(), selectedNoteColor(), + noteOpacity(), noteBorders(), drawNoteNames ); + } + } + p.setPen( QPen( noteColor(), NOTE_EDIT_LINE_WIDTH + 2 ) ); p.drawPoints( editHandles ); @@ -3269,7 +3449,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) } if( nv.size() > 0 ) { - const int step = we->delta() > 0 ? 1.0 : -1.0; + const int step = we->delta() > 0 ? 1 : -1; if( m_noteEditMode == NoteEditVolume ) { for ( Note * n : nv ) @@ -3511,6 +3691,34 @@ void PianoRoll::recordAccompany() +bool PianoRoll::toggleStepRecording() +{ + if(m_stepRecorder.isRecording()) + { + m_stepRecorder.stop(); + } + else + { + if(hasValidPattern()) + { + if(Engine::getSong()->isPlaying()) + { + m_stepRecorder.start(0, newNoteLen()); + } + else + { + m_stepRecorder.start( + Engine::getSong()->getPlayPos( + Song::Mode_PlayPattern), newNoteLen()); + } + } + } + + return m_stepRecorder.isRecording();; +} + + + void PianoRoll::stop() { @@ -3524,22 +3732,29 @@ void PianoRoll::stop() void PianoRoll::startRecordNote(const Note & n ) { - if( m_recording && hasValidPattern() && + if(hasValidPattern()) + { + if( m_recording && Engine::getSong()->isPlaying() && (Engine::getSong()->playMode() == desiredPlayModeForAccompany() || - Engine::getSong()->playMode() == Song::Mode_PlayPattern )) - { - MidiTime sub; - if( Engine::getSong()->playMode() == Song::Mode_PlaySong ) + Engine::getSong()->playMode() == Song::Mode_PlayPattern )) { - sub = m_pattern->startPosition(); + MidiTime sub; + if( Engine::getSong()->playMode() == Song::Mode_PlaySong ) + { + sub = m_pattern->startPosition(); + } + Note n1( 1, Engine::getSong()->getPlayPos( + Engine::getSong()->playMode() ) - sub, + n.key(), n.getVolume(), n.getPanning() ); + if( n1.pos() >= 0 ) + { + m_recordingNotes << n1; + } } - Note n1( 1, Engine::getSong()->getPlayPos( - Engine::getSong()->playMode() ) - sub, - n.key(), n.getVolume(), n.getPanning() ); - if( n1.pos() >= 0 ) + else if (m_stepRecorder.isRecording()) { - m_recordingNotes << n1; + m_stepRecorder.notePressed(n); } } } @@ -3549,28 +3764,35 @@ void PianoRoll::startRecordNote(const Note & n ) void PianoRoll::finishRecordNote(const Note & n ) { - if( m_recording && hasValidPattern() && - Engine::getSong()->isPlaying() && - ( Engine::getSong()->playMode() == - desiredPlayModeForAccompany() || - Engine::getSong()->playMode() == - Song::Mode_PlayPattern ) ) + if(hasValidPattern()) { - for( QList::Iterator it = m_recordingNotes.begin(); - it != m_recordingNotes.end(); ++it ) + if( m_recording && + Engine::getSong()->isPlaying() && + ( Engine::getSong()->playMode() == + desiredPlayModeForAccompany() || + Engine::getSong()->playMode() == + Song::Mode_PlayPattern ) ) { - if( it->key() == n.key() ) + for( QList::Iterator it = m_recordingNotes.begin(); + it != m_recordingNotes.end(); ++it ) { - Note n1( n.length(), it->pos(), - it->key(), it->getVolume(), - it->getPanning() ); - n1.quantizeLength( quantization() ); - m_pattern->addNote( n1 ); - update(); - m_recordingNotes.erase( it ); - break; + if( it->key() == n.key() ) + { + Note n1( n.length(), it->pos(), + it->key(), it->getVolume(), + it->getPanning() ); + n1.quantizeLength( quantization() ); + m_pattern->addNote( n1 ); + update(); + m_recordingNotes.erase( it ); + break; + } } } + else if (m_stepRecorder.isRecording()) + { + m_stepRecorder.noteReleased(n); + } } } @@ -3580,6 +3802,7 @@ void PianoRoll::finishRecordNote(const Note & n ) void PianoRoll::horScrolled(int new_pos ) { m_currentPosition = new_pos; + m_stepRecorderWidget.setCurrentPosition(m_currentPosition); emit positionChanged( m_currentPosition ); update(); } @@ -3950,6 +4173,13 @@ void PianoRoll::updatePositionAccompany( const MidiTime & t ) } +void PianoRoll::updatePositionStepRecording( const MidiTime & t ) +{ + if( m_stepRecorder.isRecording() ) + { + autoScroll( t ); + } +} void PianoRoll::zoomingChanged() @@ -3959,6 +4189,8 @@ void PianoRoll::zoomingChanged() assert( m_ppt > 0 ); m_timeLine->setPixelsPerTact( m_ppt ); + m_stepRecorderWidget.setPixelsPerTact( m_ppt ); + update(); } @@ -3970,7 +4202,11 @@ void PianoRoll::quantizeChanged() update(); } - +void PianoRoll::noteLengthChanged() +{ + m_stepRecorder.setStepsLength(newNoteLen()); + update(); +} int PianoRoll::quantization() const @@ -4107,7 +4343,7 @@ Note * PianoRoll::noteUnderMouse() PianoRollWindow::PianoRollWindow() : - Editor(true), + Editor(true, true), m_editor(new PianoRoll()) { setCentralWidget( m_editor ); @@ -4115,6 +4351,7 @@ PianoRollWindow::PianoRollWindow() : m_playAction->setToolTip(tr( "Play/pause current pattern (Space)" ) ); m_recordAction->setToolTip(tr( "Record notes from MIDI-device/channel-piano" ) ); m_recordAccompanyAction->setToolTip( tr( "Record notes from MIDI-device/channel-piano while playing song or BB track" ) ); + m_toggleStepRecordingAction->setToolTip( tr( "Record notes from MIDI-device/channel-piano, one step at the time" ) ); m_stopAction->setToolTip( tr( "Stop playing of current pattern (Space)" ) ); DropToolBar *notesActionsToolBar = addDropToolBarToTop( tr( "Edit actions" ) ); @@ -4221,8 +4458,15 @@ PianoRollWindow::PianoRollWindow() : m_chordComboBox = new ComboBox( m_toolBar ); m_chordComboBox->setModel( &m_editor->m_chordModel ); m_chordComboBox->setFixedSize( 105, 22 ); - m_chordComboBox->setToolTip( tr( "Chord") ); + m_chordComboBox->setToolTip( tr( "Chord" ) ); + // -- Clear ghost pattern button + m_clearGhostButton = new QPushButton( m_toolBar ); + m_clearGhostButton->setIcon( embed::getIconPixmap( "clear_ghost_note" ) ); + m_clearGhostButton->setToolTip( tr( "Clear ghost notes" ) ); + m_clearGhostButton->setEnabled( false ); + connect( m_clearGhostButton, SIGNAL( clicked() ), m_editor, SLOT( clearGhostPattern() ) ); + connect( m_editor, SIGNAL( ghostPatternSet( bool ) ), this, SLOT( ghostPatternSet( bool ) ) ); zoomAndNotesToolBar->addWidget( zoom_lbl ); zoomAndNotesToolBar->addWidget( m_zoomingComboBox ); @@ -4243,6 +4487,9 @@ PianoRollWindow::PianoRollWindow() : zoomAndNotesToolBar->addWidget( chord_lbl ); zoomAndNotesToolBar->addWidget( m_chordComboBox ); + zoomAndNotesToolBar->addSeparator(); + zoomAndNotesToolBar->addWidget( m_clearGhostButton ); + // setup our actual window setFocusPolicy( Qt::StrongFocus ); setFocus(); @@ -4251,7 +4498,7 @@ PianoRollWindow::PianoRollWindow() : // Connections connect( m_editor, SIGNAL( currentPatternChanged() ), this, SIGNAL( currentPatternChanged() ) ); - connect( m_editor, SIGNAL( currentPatternChanged() ), this, SLOT( patternRenamed() ) ); + connect( m_editor, SIGNAL( currentPatternChanged() ), this, SLOT( updateAfterPatternChange() ) ); } @@ -4265,6 +4512,14 @@ const Pattern* PianoRollWindow::currentPattern() const +void PianoRollWindow::setGhostPattern( Pattern* pattern ) +{ + m_editor->setGhostPattern( pattern ); +} + + + + void PianoRollWindow::setCurrentPattern( Pattern* pattern ) { m_editor->setCurrentPattern( pattern ); @@ -4272,8 +4527,8 @@ void PianoRollWindow::setCurrentPattern( Pattern* pattern ) if ( pattern ) { setWindowTitle( tr( "Piano-Roll - %1" ).arg( pattern->name() ) ); - connect( pattern->instrumentTrack(), SIGNAL( nameChanged() ), this, SLOT( patternRenamed()) ); - connect( pattern, SIGNAL( dataChanged() ), this, SLOT( patternRenamed() ) ); + connect( pattern->instrumentTrack(), SIGNAL( nameChanged() ), this, SLOT( updateAfterPatternChange()) ); + connect( pattern, SIGNAL( dataChanged() ), this, SLOT( updateAfterPatternChange() ) ); } else { @@ -4318,6 +4573,8 @@ void PianoRollWindow::stop() void PianoRollWindow::record() { + stopStepRecording(); //step recording mode is mutually exclusive with other record modes + m_editor->record(); } @@ -4326,11 +4583,25 @@ void PianoRollWindow::record() void PianoRollWindow::recordAccompany() { + stopStepRecording(); //step recording mode is mutually exclusive with other record modes + m_editor->recordAccompany(); } +void PianoRollWindow::toggleStepRecording() +{ + if(isRecording()) + { + // step recording mode is mutually exclusive with other record modes + // stop them before starting step recording + stop(); + } + m_editor->toggleStepRecording(); + + updateStepRecordingIcon(); +} void PianoRollWindow::stopRecording() { @@ -4350,6 +4621,21 @@ void PianoRollWindow::reset() void PianoRollWindow::saveSettings( QDomDocument & doc, QDomElement & de ) { + if( !m_editor->ghostNotes().empty() ) + { + QDomElement ghostNotesRoot = doc.createElement( "ghostnotes" ); + for( Note *note : m_editor->ghostNotes() ) + { + QDomElement ghostNoteNode = doc.createElement( "ghostnote" ); + ghostNoteNode.setAttribute( "len", note->length() ); + ghostNoteNode.setAttribute( "key", note->key() ); + ghostNoteNode.setAttribute( "pos", note->pos() ); + + ghostNotesRoot.appendChild(ghostNoteNode); + } + de.appendChild( ghostNotesRoot ); + } + MainWindow::saveWidgetState( this, de ); } @@ -4358,6 +4644,8 @@ void PianoRollWindow::saveSettings( QDomDocument & doc, QDomElement & de ) void PianoRollWindow::loadSettings( const QDomElement & de ) { + m_editor->loadGhostNotes( de.firstChildElement("ghostnotes") ); + MainWindow::restoreWidgetState( this, de ); } @@ -4371,6 +4659,11 @@ QSize PianoRollWindow::sizeHint() const +void PianoRollWindow::updateAfterPatternChange() +{ + patternRenamed(); + updateStepRecordingIcon(); //pattern change turn step recording OFF - update icon accordingly +} void PianoRollWindow::patternRenamed() { @@ -4387,8 +4680,37 @@ void PianoRollWindow::patternRenamed() +void PianoRollWindow::ghostPatternSet( bool state ) +{ + m_clearGhostButton->setEnabled( state ); +} + + + + void PianoRollWindow::focusInEvent( QFocusEvent * event ) { // when the window is given focus, also give focus to the actual piano roll m_editor->setFocus( event->reason() ); } + +void PianoRollWindow::stopStepRecording() +{ + if(m_editor->isStepRecording()) + { + m_editor->toggleStepRecording(); + updateStepRecordingIcon(); + } +} + +void PianoRollWindow::updateStepRecordingIcon() +{ + if(m_editor->isStepRecording()) + { + m_toggleStepRecordingAction->setIcon(embed::getIconPixmap("record_step_on")); + } + else + { + m_toggleStepRecordingAction->setIcon(embed::getIconPixmap("record_step_off")); + } +} diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index a2e52e200..3e57ba026 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -654,7 +654,7 @@ ComboBoxModel *SongEditor::zoomingModel() const SongEditorWindow::SongEditorWindow(Song* song) : - Editor(Engine::mixer()->audioDev()->supportsCapture()), + Editor(Engine::mixer()->audioDev()->supportsCapture(), false), m_editor(new SongEditor(song)), m_crtlAction( NULL ) { @@ -746,6 +746,16 @@ void SongEditorWindow::resizeEvent(QResizeEvent *event) } +void SongEditorWindow::changeEvent(QEvent *event) +{ + QWidget::changeEvent(event); + if (event->type() == QEvent::WindowStateChange) + { + m_editor->realignTracks(); + } +} + + void SongEditorWindow::play() { emit playTriggered(); diff --git a/src/gui/widgets/EffectView.cpp b/src/gui/widgets/EffectView.cpp index 97f8bbed0..2a492128b 100644 --- a/src/gui/widgets/EffectView.cpp +++ b/src/gui/widgets/EffectView.cpp @@ -70,14 +70,14 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : m_autoQuit = new TempoSyncKnob( knobBright_26, this ); m_autoQuit->setLabel( tr( "DECAY" ) ); m_autoQuit->move( 60, 5 ); - m_autoQuit->setEnabled( isEnabled ); + m_autoQuit->setEnabled( isEnabled && !effect()->m_autoQuitDisabled ); m_autoQuit->setHintText( tr( "Time:" ), "ms" ); m_gate = new Knob( knobBright_26, this ); m_gate->setLabel( tr( "GATE" ) ); m_gate->move( 93, 5 ); - m_gate->setEnabled( isEnabled ); + m_gate->setEnabled( isEnabled && !effect()->m_autoQuitDisabled ); m_gate->setHintText( tr( "Gate:" ), "" ); diff --git a/src/gui/widgets/EnvelopeAndLfoView.cpp b/src/gui/widgets/EnvelopeAndLfoView.cpp index fcbfa9424..cdad83d4f 100644 --- a/src/gui/widgets/EnvelopeAndLfoView.cpp +++ b/src/gui/widgets/EnvelopeAndLfoView.cpp @@ -419,9 +419,9 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) p.fillRect( x5, y_base - 1, 2, 2, end_points_color ); - int LFO_GRAPH_W = s_lfoGraph->width() - 6; // substract border + int LFO_GRAPH_W = s_lfoGraph->width() - 3; // substract border int LFO_GRAPH_H = s_lfoGraph->height() - 6; // substract border - int graph_x_base = LFO_GRAPH_X + 3; + int graph_x_base = LFO_GRAPH_X + 2; int graph_y_base = LFO_GRAPH_Y + 3 + LFO_GRAPH_H / 2; const float frames_for_graph = SECS_PER_LFO_OSCILLATION * diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index e9a00c304..f93ed523c 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -720,6 +720,15 @@ void graphModel::clear() } +// Clear any part of the graph that isn't displayed +void graphModel::clearInvisible() +{ + const int graph_length = length(); + const int full_graph_length = m_samples.size(); + for( int i = graph_length; i < full_graph_length; i++ ) + m_samples[i] = 0; + emit samplesChanged( graph_length, full_graph_length - 1 ); +} void graphModel::drawSampleAt( int x, float val ) { diff --git a/src/gui/widgets/StepRecorderWidget.cpp b/src/gui/widgets/StepRecorderWidget.cpp new file mode 100644 index 000000000..f59e235fc --- /dev/null +++ b/src/gui/widgets/StepRecorderWidget.cpp @@ -0,0 +1,155 @@ +/* + * StepRecoderWidget.cpp - widget that provide gui markers for step recording + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "StepRecorderWidget.h" +#include "TextFloat.h" +#include "embed.h" + +StepRecorderWidget::StepRecorderWidget( + QWidget * parent, + const int ppt, + const int marginTop, + const int marginBottom, + const int marginLeft, + const int marginRight) : + QWidget(parent), + m_marginTop(marginTop), + m_marginBottom(marginBottom), + m_marginLeft(marginLeft), + m_marginRight(marginRight) +{ + const QColor baseColor = QColor(255, 0, 0);// QColor(204, 163, 0); // Orange + m_colorLineEnd = baseColor.lighter(150); + m_colorLineStart = baseColor.darker(120); + + setAttribute(Qt::WA_NoSystemBackground, true); + setPixelsPerTact(ppt); + + m_top = m_marginTop; + m_left = m_marginLeft; +} + +void StepRecorderWidget::setPixelsPerTact(int ppt) +{ + m_ppt = ppt; +} + +void StepRecorderWidget::setCurrentPosition(MidiTime currentPosition) +{ + m_currentPosition = currentPosition; +} + +void StepRecorderWidget::setBottomMargin(const int marginBottom) +{ + m_marginBottom = marginBottom; +} + +void StepRecorderWidget::setStartPosition(MidiTime pos) +{ + m_curStepStartPos = pos; +} + +void StepRecorderWidget::setEndPosition(MidiTime pos) +{ + m_curStepEndPos = pos; + emit positionChanged(m_curStepEndPos); +} + +void StepRecorderWidget::showHint() +{ + TextFloat::displayMessage(tr( "Hint" ), tr("Move recording curser using arrows"), + embed::getIconPixmap("hint")); +} + +void StepRecorderWidget::setStepsLength(MidiTime stepsLength) +{ + m_stepsLength = stepsLength; +} + +void StepRecorderWidget::paintEvent(QPaintEvent * pe) +{ + QPainter painter(this); + + updateBoundaries(); + + move(0, 0); + + //draw steps ruler + painter.setPen(m_colorLineEnd); + + MidiTime curPos = m_curStepEndPos; + int x = xCoordOfTick(curPos); + while(x <= m_right) + { + const int w = 2; + const int h = 4; + painter.drawRect(x - 1, m_top, w, h); + curPos += m_stepsLength; + x = xCoordOfTick(curPos); + } + + //draw current step start/end position lines + if(m_curStepStartPos != m_curStepEndPos) + { + drawVerLine(&painter, m_curStepStartPos, m_colorLineStart, m_top, m_bottom); + } + + drawVerLine(&painter, m_curStepEndPos, m_colorLineEnd, m_top, m_bottom); + + //if the line is adjacent to the keyboard at the left - it cannot be seen. + //add another line to make it clearer + if(m_curStepEndPos == 0) + { + drawVerLine(&painter, xCoordOfTick(m_curStepEndPos) + 1, m_colorLineEnd, m_top, m_bottom); + } +} + +int StepRecorderWidget::xCoordOfTick(int tick) +{ + return m_marginLeft + ((tick - m_currentPosition) * m_ppt / MidiTime::ticksPerTact()); +} + + +void StepRecorderWidget::drawVerLine(QPainter* painter, int x, const QColor& color, int top, int bottom) +{ + if(x >= m_marginLeft && x <= (width() - m_marginRight)) + { + painter->setPen(color); + painter->drawLine( x, top, x, bottom ); + } +} + +void StepRecorderWidget::drawVerLine(QPainter* painter, const MidiTime& pos, const QColor& color, int top, int bottom) +{ + drawVerLine(painter, xCoordOfTick(pos), color, top, bottom); +} + +void StepRecorderWidget::updateBoundaries() +{ + setFixedSize(parentWidget()->size()); + + m_bottom = height() - m_marginBottom; + m_right = width() - m_marginTop; + + //(no need to change top and left as they are static) +} + diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 298430b03..a927e8aad 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -126,10 +126,14 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) : setName( tr( "Default preset" ) ); - connect( &m_baseNoteModel, SIGNAL( dataChanged() ), this, SLOT( updateBaseNote() ) ); - connect( &m_pitchModel, SIGNAL( dataChanged() ), this, SLOT( updatePitch() ) ); - connect( &m_pitchRangeModel, SIGNAL( dataChanged() ), this, SLOT( updatePitchRange() ) ); - connect( &m_effectChannelModel, SIGNAL( dataChanged() ), this, SLOT( updateEffectChannel() ) ); + connect( &m_baseNoteModel, SIGNAL( dataChanged() ), + this, SLOT( updateBaseNote() ), Qt::DirectConnection ); + connect( &m_pitchModel, SIGNAL( dataChanged() ), + this, SLOT( updatePitch() ), Qt::DirectConnection ); + connect( &m_pitchRangeModel, SIGNAL( dataChanged() ), + this, SLOT( updatePitchRange() ), Qt::DirectConnection ); + connect( &m_effectChannelModel, SIGNAL( dataChanged() ), + this, SLOT( updateEffectChannel() ), Qt::DirectConnection ); } diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index 05d316f00..32baf0b14 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -637,6 +637,18 @@ void PatternView::openInPianoRoll() + +void PatternView::setGhostInPianoRoll() +{ + gui->pianoRoll()->setGhostPattern( m_pat ); + gui->pianoRoll()->parentWidget()->show(); + gui->pianoRoll()->show(); + gui->pianoRoll()->setFocus(); +} + + + + void PatternView::resetName() { m_pat->setName( m_pat->m_instrumentTrack->name() ); @@ -663,8 +675,14 @@ void PatternView::constructContextMenu( QMenu * _cm ) _cm->insertAction( _cm->actions()[0], a ); connect( a, SIGNAL( triggered( bool ) ), this, SLOT( openInPianoRoll() ) ); - _cm->insertSeparator( _cm->actions()[1] ); + QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ), + tr( "Set as ghost in piano-roll" ), _cm ); + if( m_pat->empty() ) { b->setEnabled( false ); } + _cm->insertAction( _cm->actions()[1], b ); + connect( b, SIGNAL( triggered( bool ) ), + this, SLOT( setGhostInPianoRoll() ) ); + _cm->insertSeparator( _cm->actions()[2] ); _cm->addSeparator(); _cm->addAction( embed::getIconPixmap( "edit_erase" ),