Browse Source

prepare release

master v2.4.0
Nils 2 years ago
parent
commit
33347f2419
  1. 5
      CHANGELOG
  2. 9
      README.md
  3. 2
      configure
  4. 20
      documentation/english.adoc
  5. 12
      documentation/english.part.adoc
  6. 17
      documentation/german.adoc
  7. 13
      documentation/german.part.adoc
  8. 4
      documentation/index.adoc
  9. 6
      documentation/manpageinclude.h2m
  10. 24
      documentation/out/english.html
  11. 20
      documentation/out/german.html
  12. 2
      documentation/out/index.html
  13. 13
      documentation/patroneo.1
  14. 22
      engine/api.py
  15. 6
      engine/config.py
  16. 27
      engine/pattern.py
  17. 22
      qtgui/mainwindow.py
  18. 56
      qtgui/pattern_grid.py
  19. 3000
      qtgui/resources.py
  20. BIN
      qtgui/resources/translations/de.qm
  21. 135
      qtgui/resources/translations/de.ts

5
CHANGELOG

@ -5,6 +5,11 @@ Two empty lines before the next entry.
External contributors notice at the end of the line: (LastName, FirstName / nick) External contributors notice at the end of the line: (LastName, FirstName / nick)
## 2022-010-14 2.4.0
Add option to split or subdivide a step: Polyrhythms and Techno-Kickdrums!
("Die Katze lässt das Mausen nicht" - Is this the final final release?)
## 2022-04-17 2.3.2 ## 2022-04-17 2.3.2
Hotfix: Don't discard user data when setting or deleting steps in a multiplicator-measure. Hotfix: Don't discard user data when setting or deleting steps in a multiplicator-measure.

9
README.md

@ -1,9 +1,9 @@
[//]: # (Generated 2022-04-17T21:13:03.381666. Changes belong into template/documentation/readme.template) [//]: # (Generated 2022-10-14T23:55:28.253667. Changes belong into template/documentation/readme.template)
# Patroneo # Patroneo
Program version 2.3.2 Program version 2.4.0
![Screenshot](https://git.laborejo.org/lss/Patroneo/raw/branch/master/documentation/screenshot.png "Screenshot") ![Screenshot](https://git.laborejo.org/lss/Patroneo/raw/branch/master/documentation/screenshot.png "Screenshot")
@ -13,10 +13,10 @@ Program version 2.3.2
Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a
program that sends digital "notes" to software instruments such as synthesizers and samplers. program that sends digital "notes" to software instruments such as synthesizers and samplers.
This program is feature-complete with version 2.3.0 in 2022. This program is feature-complete with version 2.4.0 in 2022.
Further releases will be limited to maintenance and fixing problems. Further releases will be limited to maintenance and fixing problems.
Patroneo is primarily designed for educational purposes, where the main goal is to teach the Patroneo was initially designed for educational purposes, where the main goal is to teach the
importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer
you can use to create real music. The constraints it presents will more likely boost your you can use to create real music. The constraints it presents will more likely boost your
creativity than suppressing it. creativity than suppressing it.
@ -51,6 +51,7 @@ It is possible to clone a git repository.
## Dependencies ## Dependencies
* Python 3.6 (maybe earlier) * Python 3.6 (maybe earlier)
* PyQt5 for Python 3 * PyQt5 for Python 3
* PyQt OpenGL and SVG modules, if they are separated in your distribution
* DejaVu Sans Sarif TTF (Font) (recommended, but not technically necessary) * DejaVu Sans Sarif TTF (Font) (recommended, but not technically necessary)
* libcalfbox-lss https://git.laborejo.org/lss/libcalfbox-lss * libcalfbox-lss https://git.laborejo.org/lss/libcalfbox-lss

2
configure

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
program=patroneo program=patroneo
version=2.3.2 version=2.4.0
. template/configure.template #. is the posix compatible version of source . template/configure.template #. is the posix compatible version of source

20
documentation/english.adoc

@ -1,5 +1,5 @@
:Author: Laborejo Software Suite :Author: Laborejo Software Suite
:Version: 2.3.2 :Version: 2.4.0
:iconfont-remote!: :iconfont-remote!:
:!webfonts: :!webfonts:
@ -25,7 +25,7 @@ https://asciidoctor.org/docs/user-manual/
= Patroneo = Patroneo
// Don't write in the empty line above line. It will be interpreted as author html tag // Don't write in the empty line above line. It will be interpreted as author html tag
For program version 2.3.2 For program version 2.4.0
== Introduction == Introduction
@ -33,10 +33,10 @@ For program version 2.3.2
Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a
program that sends digital "notes" to software instruments such as synthesizers and samplers. program that sends digital "notes" to software instruments such as synthesizers and samplers.
This program is feature-complete with version 2.3.0 in 2022. This program is feature-complete with version 2.4.0 in 2022.
Further releases will be limited to maintenance and fixing problems. Further releases will be limited to maintenance and fixing problems.
Patroneo is primarily designed for educational purposes, where the main goal is to teach the Patroneo was initially designed for educational purposes, where the main goal is to teach the
importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer
you can use to create real music. The constraints it presents will more likely boost your you can use to create real music. The constraints it presents will more likely boost your
creativity than suppressing it. creativity than suppressing it.
@ -91,6 +91,7 @@ makes some workflows faster and more convenient.
* Space: Start and pause playback * Space: Start and pause playback
* L: Play the current measure as a loop * L: Play the current measure as a loop
* Home: Set playback to the beginning of the track. * Home: Set playback to the beginning of the track.
* For more shortcuts please check the Edit menu
== Description of the graphical user interface and its functions == Description of the graphical user interface and its functions
@ -418,6 +419,17 @@ rotate your mouse wheel the velocity changes by 10 each. It doesn't matter which
To make all tones of a row quieter or louder hold the Alt key (not AltGr) and use your mousewheel To make all tones of a row quieter or louder hold the Alt key (not AltGr) and use your mousewheel
on a step of that row. on a step of that row.
===== Split or subdivide notes
To split a step even further, hold the mouse cursor over an activated note
and press a number key on the keyboard.
Key 1 means "no split", all other keys are a subdivision e.g. 3 is splits into 3 sounding notes.
All pitches are the same.
This can be used, for example, to create polyrhythmic patterns, or to divide "even" during swing.
Or of course to simply have more and faster notes :)
==== Pitches and Scales ==== Pitches and Scales
image:en_pitches.png[link="en_pitches.png"] image:en_pitches.png[link="en_pitches.png"]

12
documentation/english.part.adoc

@ -43,6 +43,7 @@ makes some workflows faster and more convenient.
* Space: Start and pause playback * Space: Start and pause playback
* L: Play the current measure as a loop * L: Play the current measure as a loop
* Home: Set playback to the beginning of the track. * Home: Set playback to the beginning of the track.
* For more shortcuts please check the Edit menu
== Description of the graphical user interface and its functions == Description of the graphical user interface and its functions
@ -370,6 +371,17 @@ rotate your mouse wheel the velocity changes by 10 each. It doesn't matter which
To make all tones of a row quieter or louder hold the Alt key (not AltGr) and use your mousewheel To make all tones of a row quieter or louder hold the Alt key (not AltGr) and use your mousewheel
on a step of that row. on a step of that row.
===== Split or subdivide notes
To split a step even further, hold the mouse cursor over an activated note
and press a number key on the keyboard.
Key 1 means "no split", all other keys are a subdivision e.g. 3 is splits into 3 sounding notes.
All pitches are the same.
This can be used, for example, to create polyrhythmic patterns, or to divide "even" during swing.
Or of course to simply have more and faster notes :)
==== Pitches and Scales ==== Pitches and Scales
image:en_pitches.png[link="en_pitches.png"] image:en_pitches.png[link="en_pitches.png"]

17
documentation/german.adoc

@ -1,5 +1,5 @@
:Author: Laborejo Software Suite :Author: Laborejo Software Suite
:Version: 2.3.2 :Version: 2.4.0
:iconfont-remote!: :iconfont-remote!:
:!webfonts: :!webfonts:
@ -25,7 +25,7 @@ https://asciidoctor.org/docs/user-manual/
= Patroneo = Patroneo
// Don't write in the empty line above line. It will be interpreted as author html tag // Don't write in the empty line above line. It will be interpreted as author html tag
Für Programmversion 2.3.2 Für Programmversion 2.4.0
== Benutzung == Benutzung
@ -94,7 +94,7 @@ macht die Tastatur manche Arbeitsabläufe schneller und bequemer.
* Leertaste: Start und Pause der Wiedergabe. * Leertaste: Start und Pause der Wiedergabe.
* L: aktuelle Taktpositionen in Schleife spielen. * L: aktuelle Taktpositionen in Schleife spielen.
* Pos1: Wiedergabe an den Anfang des Stückes setzen. * Pos1: Wiedergabe an den Anfang des Stückes setzen.
* Mehr Shortcuts sind im Bearbeiten-Menü
== Beschreibung der grafischen Oberfläche und ihrer Funktionen == Beschreibung der grafischen Oberfläche und ihrer Funktionen
@ -435,6 +435,17 @@ Um alle Töne einer Reihe leiser oder lauter zu machen hält man die Alt-Taste (
gedrückt und benutzt das Mausrad auf der jeweiligen Reihe. gedrückt und benutzt das Mausrad auf der jeweiligen Reihe.
===== Noten spalten oder unterteilen
Um einen Schritt noch weiter zu unterteilen hält man den Mauszeiger auf eine aktivierte Note
und drückt eine Nummertaste auf der Tastatur. Die Taste 1 ist dabei "keine Unterteilung", alle
weitere Tasten stehen für sich selbst. z.B. ist die 3 eine Unterteilung in 3 klingende Noten.
Die Tonhöhen sind hierbei alle gleich.
Dies kann z.B. benutzt werden um polyrhytmische Muster zu erstellen oder während eines Swing doch
wieder "gerade" zu teilen. Oder natürlich um einfach mehr und schnellere Noten zu haben :)
==== Tonhöhen, Skala und Tonleiter ==== Tonhöhen, Skala und Tonleiter
image:de_pitches.png[link="de_pitches.png"] image:de_pitches.png[link="de_pitches.png"]

13
documentation/german.part.adoc

@ -65,7 +65,7 @@ macht die Tastatur manche Arbeitsabläufe schneller und bequemer.
* Leertaste: Start und Pause der Wiedergabe. * Leertaste: Start und Pause der Wiedergabe.
* L: aktuelle Taktpositionen in Schleife spielen. * L: aktuelle Taktpositionen in Schleife spielen.
* Pos1: Wiedergabe an den Anfang des Stückes setzen. * Pos1: Wiedergabe an den Anfang des Stückes setzen.
* Mehr Shortcuts sind im Bearbeiten-Menü
== Beschreibung der grafischen Oberfläche und ihrer Funktionen == Beschreibung der grafischen Oberfläche und ihrer Funktionen
@ -406,6 +406,17 @@ Um alle Töne einer Reihe leiser oder lauter zu machen hält man die Alt-Taste (
gedrückt und benutzt das Mausrad auf der jeweiligen Reihe. gedrückt und benutzt das Mausrad auf der jeweiligen Reihe.
===== Noten spalten oder unterteilen
Um einen Schritt noch weiter zu unterteilen hält man den Mauszeiger auf eine aktivierte Note
und drückt eine Nummertaste auf der Tastatur. Die Taste 1 ist dabei "keine Unterteilung", alle
weitere Tasten stehen für sich selbst. z.B. ist die 3 eine Unterteilung in 3 klingende Noten.
Die Tonhöhen sind hierbei alle gleich.
Dies kann z.B. benutzt werden um polyrhytmische Muster zu erstellen oder während eines Swing doch
wieder "gerade" zu teilen. Oder natürlich um einfach mehr und schnellere Noten zu haben :)
==== Tonhöhen, Skala und Tonleiter ==== Tonhöhen, Skala und Tonleiter
image:de_pitches.png[link="de_pitches.png"] image:de_pitches.png[link="de_pitches.png"]

4
documentation/index.adoc

@ -1,5 +1,5 @@
:Author: Laborejo Software Suite :Author: Laborejo Software Suite
:Version: 2.3.2 :Version: 2.4.0
:iconfont-remote!: :iconfont-remote!:
:!webfonts: :!webfonts:
@ -21,7 +21,7 @@ https://asciidoctor.org/docs/user-manual/
== Patroneo Multi-Language Documentation == Patroneo Multi-Language Documentation
image::logo.png["logo", 320, 180] image::logo.png["logo", 320, 180]
For program version 2.3.2 For program version 2.4.0
This site is part of the https://www.laborejo.org[Laborejo Software Suite] This site is part of the https://www.laborejo.org[Laborejo Software Suite]

6
documentation/manpageinclude.h2m

@ -7,10 +7,10 @@ Patroneo - Easy to use pattern based midi sequencer.
Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a
program that sends digital "notes" to software instruments such as synthesizers and samplers. program that sends digital "notes" to software instruments such as synthesizers and samplers.
This program is feature-complete with version 2.3.0 in 2022. This program is feature-complete with version 2.4.0 in 2022.
Further releases will be limited to maintenance and fixing problems. Further releases will be limited to maintenance and fixing problems.
Patroneo is primarily designed for educational purposes, where the main goal is to teach the Patroneo was initially designed for educational purposes, where the main goal is to teach the
importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer
you can use to create real music. The constraints it presents will more likely boost your you can use to create real music. The constraints it presents will more likely boost your
creativity than suppressing it. creativity than suppressing it.
@ -24,7 +24,7 @@ Connect external synthesizers and samplers to create sounds.
https://www.laborejo.org/bugs https://www.laborejo.org/bugs
[copyright] [copyright]
Patroneo 2.3.2 - Copyright 2022 Patroneo 2.4.0 - Copyright 2022
Laborejo Software Suite Laborejo Software Suite
https://www.laborejo.org/ https://www.laborejo.org/

24
documentation/out/english.html

@ -500,7 +500,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<div id="preamble"> <div id="preamble">
<div class="sectionbody"> <div class="sectionbody">
<div class="paragraph"> <div class="paragraph">
<p>For program version 2.3.2</p> <p>For program version 2.4.0</p>
</div> </div>
</div> </div>
</div> </div>
@ -512,11 +512,11 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
program that sends digital "notes" to software instruments such as synthesizers and samplers.</p> program that sends digital "notes" to software instruments such as synthesizers and samplers.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p>This program is feature-complete with version 2.3.0 in 2022. <p>This program is feature-complete with version 2.4.0 in 2022.
Further releases will be limited to maintenance and fixing problems.</p> Further releases will be limited to maintenance and fixing problems.</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p>Patroneo is primarily designed for educational purposes, where the main goal is to teach the <p>Patroneo was initially designed for educational purposes, where the main goal is to teach the
importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer
you can use to create real music. The constraints it presents will more likely boost your you can use to create real music. The constraints it presents will more likely boost your
creativity than suppressing it.</p> creativity than suppressing it.</p>
@ -593,6 +593,9 @@ makes some workflows faster and more convenient.</p>
<li> <li>
<p>Home: Set playback to the beginning of the track.</p> <p>Home: Set playback to the beginning of the track.</p>
</li> </li>
<li>
<p>For more shortcuts please check the Edit menu</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
@ -1067,6 +1070,19 @@ rotate your mouse wheel the velocity changes by 10 each. It doesn&#8217;t matter
<p>To make all tones of a row quieter or louder hold the Alt key (not AltGr) and use your mousewheel <p>To make all tones of a row quieter or louder hold the Alt key (not AltGr) and use your mousewheel
on a step of that row.</p> on a step of that row.</p>
</div> </div>
<div class="sect4">
<h5 id="_split_or_subdivide_notes">Split or subdivide notes</h5>
<div class="paragraph">
<p>To split a step even further, hold the mouse cursor over an activated note
and press a number key on the keyboard.
Key 1 means "no split", all other keys are a subdivision e.g. 3 is splits into 3 sounding notes.
All pitches are the same.</p>
</div>
<div class="paragraph">
<p>This can be used, for example, to create polyrhythmic patterns, or to divide "even" during swing.
Or of course to simply have more and faster notes :)</p>
</div>
</div>
</div> </div>
<div class="sect3"> <div class="sect3">
<h4 id="_pitches_and_scales">2.3.3. Pitches and Scales</h4> <h4 id="_pitches_and_scales">2.3.3. Pitches and Scales</h4>
@ -1564,7 +1580,7 @@ The program is split in two parts. A shared "template" between the Laborejo Soft
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2022-04-17 21:13:03 +0200 Last updated 2022-10-14 23:55:28 +0200
</div> </div>
</div> </div>
</body> </body>

20
documentation/out/german.html

@ -504,7 +504,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<div id="preamble"> <div id="preamble">
<div class="sectionbody"> <div class="sectionbody">
<div class="paragraph"> <div class="paragraph">
<p>Für Programmversion 2.3.2</p> <p>Für Programmversion 2.4.0</p>
</div> </div>
</div> </div>
</div> </div>
@ -609,6 +609,9 @@ macht die Tastatur manche Arbeitsabläufe schneller und bequemer.</p>
<li> <li>
<p>Pos1: Wiedergabe an den Anfang des Stückes setzen.</p> <p>Pos1: Wiedergabe an den Anfang des Stückes setzen.</p>
</li> </li>
<li>
<p>Mehr Shortcuts sind im Bearbeiten-Menü</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
@ -1097,6 +1100,19 @@ egal über welchem Velocity Knopf (plus oder minus) man schwebt.</p>
<p>Um alle Töne einer Reihe leiser oder lauter zu machen hält man die Alt-Taste (nicht AltGR !) <p>Um alle Töne einer Reihe leiser oder lauter zu machen hält man die Alt-Taste (nicht AltGR !)
gedrückt und benutzt das Mausrad auf der jeweiligen Reihe.</p> gedrückt und benutzt das Mausrad auf der jeweiligen Reihe.</p>
</div> </div>
<div class="sect4">
<h5 id="_noten_spalten_oder_unterteilen">Noten spalten oder unterteilen</h5>
<div class="paragraph">
<p>Um einen Schritt noch weiter zu unterteilen hält man den Mauszeiger auf eine aktivierte Note
und drückt eine Nummertaste auf der Tastatur. Die Taste 1 ist dabei "keine Unterteilung", alle
weitere Tasten stehen für sich selbst. z.B. ist die 3 eine Unterteilung in 3 klingende Noten.
Die Tonhöhen sind hierbei alle gleich.</p>
</div>
<div class="paragraph">
<p>Dies kann z.B. benutzt werden um polyrhytmische Muster zu erstellen oder während eines Swing doch
wieder "gerade" zu teilen. Oder natürlich um einfach mehr und schnellere Noten zu haben :)</p>
</div>
</div>
</div> </div>
<div class="sect3"> <div class="sect3">
<h4 id="_tonhöhen_skala_und_tonleiter">3.3.3. Tonhöhen, Skala und Tonleiter</h4> <h4 id="_tonhöhen_skala_und_tonleiter">3.3.3. Tonhöhen, Skala und Tonleiter</h4>
@ -1616,7 +1632,7 @@ Ansonsten starten Sie patroneo mit diesem Befehl, Sprachcode ändern, vom Termin
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2022-04-17 21:13:03 +0200 Last updated 2022-10-14 23:55:28 +0200
</div> </div>
</div> </div>
</body> </body>

2
documentation/out/index.html

@ -449,7 +449,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
</div> </div>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p>For program version 2.3.2</p> <p>For program version 2.4.0</p>
</div> </div>
<div class="paragraph"> <div class="paragraph">
<p>This site is part of the <a href="https://www.laborejo.org">Laborejo Software Suite</a></p> <p>This site is part of the <a href="https://www.laborejo.org">Laborejo Software Suite</a></p>

13
documentation/patroneo.1

@ -1,11 +1,11 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH PATRONEO "1" "April 2022" "Patroneo 2.3.2" "User Commands" .TH PATRONEO "1" "October 2022" "Patroneo 2.4.0" "User Commands"
.SH NAME .SH NAME
Patroneo - Easy to use pattern based midi sequencer. Patroneo - Easy to use pattern based midi sequencer.
.SH DESCRIPTION .SH DESCRIPTION
usage: patroneo [\-h] [\-v] [\-s DIRECTORY] [\-p] [\-m] [\-V] usage: patroneo [\-h] [\-v] [\-s DIRECTORY] [\-p] [\-m] [\-V]
.PP .PP
Patroneo \- Version 2.3.2 \- Copyright 2022 by Laborejo Software Suite \- Patroneo \- Version 2.4.0 \- Copyright 2022 by Laborejo Software Suite \-
https://www.laborejo.org/patroneo https://www.laborejo.org/patroneo
.SS "options:" .SS "options:"
.TP .TP
@ -31,16 +31,17 @@ deactivating midi and audio.
\fB\-V\fR, \fB\-\-verbose\fR \fB\-V\fR, \fB\-\-verbose\fR
(Development) Switch the logger to INFO and print out (Development) Switch the logger to INFO and print out
all kinds of information to get a high\-level idea of all kinds of information to get a high\-level idea of
what the program is doing. what the program is doing. You can also set the
environment variable LSS_DEBUG=1
.SH USAGE .SH USAGE
Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a
program that sends digital "notes" to software instruments such as synthesizers and samplers. program that sends digital "notes" to software instruments such as synthesizers and samplers.
This program is feature-complete with version 2.3.0 in 2022. This program is feature-complete with version 2.4.0 in 2022.
Further releases will be limited to maintenance and fixing problems. Further releases will be limited to maintenance and fixing problems.
Patroneo is primarily designed for educational purposes, where the main goal is to teach the Patroneo was initially designed for educational purposes, where the main goal is to teach the
importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer
you can use to create real music. The constraints it presents will more likely boost your you can use to create real music. The constraints it presents will more likely boost your
creativity than suppressing it. creativity than suppressing it.
@ -62,7 +63,7 @@ Run without audio and midi. Skips all JACK checks. Used to just look at the GUI,
.SH "REPORTING BUGS" .SH "REPORTING BUGS"
https://www.laborejo.org/bugs https://www.laborejo.org/bugs
.SH COPYRIGHT .SH COPYRIGHT
Patroneo 2.3.2 - Copyright 2022 Patroneo 2.4.0 - Copyright 2022
Laborejo Software Suite Laborejo Software Suite
https://www.laborejo.org/ https://www.laborejo.org/
.SH "SEE ALSO" .SH "SEE ALSO"

22
engine/api.py

@ -196,13 +196,14 @@ class ClientCallbacks(Callbacks): #inherits from the templates api callbacks
func(stepDict) func(stepDict)
callbacks._dataChanged() callbacks._dataChanged()
def _removeStep(self, track, index, pitch, factor): def _removeStep(self, track, index, pitch, factor, split):
"""Opposite of _stepChanged""" """Opposite of _stepChanged"""
self._exportCacheChanged(track) self._exportCacheChanged(track)
stepDict = {"index": index, stepDict = {"index": index,
"factor": factor, "factor": factor,
"pitch": pitch, "pitch": pitch,
"velocity": 0, #it is off. "velocity": 0, #it is off.
"split": split,
} }
for func in self.removeStep: for func in self.removeStep:
func(stepDict) func(stepDict)
@ -1305,7 +1306,7 @@ def deleteSwitches(howMany, fromMeasureNumber):
updatePlayback() updatePlayback()
#Pattern Steps #Pattern Steps
#aka Notes
def setPattern(trackId, patternList, undoMessage): def setPattern(trackId, patternList, undoMessage):
"""Change the whole pattern, send a callback with the whole pattern. """Change the whole pattern, send a callback with the whole pattern.
This is also the main undo/redo function. This is also the main undo/redo function.
@ -1327,13 +1328,13 @@ def getAverageVelocity(trackId):
return session.data.trackById(trackId).pattern.averageVelocity return session.data.trackById(trackId).pattern.averageVelocity
def setStep(trackId, stepExportDict): def setStep(trackId, stepExportDict):
"""This is an atomic operation that only sets one switch and """This is an atomic operation that only sets one step and
only sends that switch back via callback. A simple GUI only sends that step back via callback. A simple GUI
will most like not listen to that callback since they will most like not listen to that callback since they
already changed the step on their side. Only useful for parallel already changed the step on their side. Only useful for parallel
views. views.
format: {'index': 0, 'pitch': 7, 'factor': 1, 'velocity': 90} format: {'index': 0, 'pitch': 7, 'factor': 1, 'velocity': 90, "split":1}
This is also for velocity! This is also for velocity!
@ -1376,19 +1377,22 @@ def removeStep(trackId, index, pitch):
track.pattern.buildExportCache() track.pattern.buildExportCache()
track.buildTrack() track.buildTrack()
updatePlayback() updatePlayback()
callbacks._removeStep(track, index, pitch, oldNote["factor"]) callbacks._removeStep(track, index, pitch, oldNote["factor"], oldNote["split"])
def toggleStep(trackId, index, pitch, factor=1, velocity=None): def toggleStep(trackId, index, pitch, factor=1, velocity=None, split=1):
"""Checks the current state of a step and decides if on or off. """Checks the current state of a step and decides if on or off.
Toggled Notes have average velocity and factor 1. If you need more fine control use setStep Toggled Notes have average velocity and factor 1. If you need more fine control use setStep
directly""" directly.
This is only used by the apc_mini input
"""
track = session.data.trackById(trackId) track = session.data.trackById(trackId)
if not track: return if not track: return
maybeNote = track.pattern.stepByIndexAndPitch(index, pitch) maybeNote = track.pattern.stepByIndexAndPitch(index, pitch)
if maybeNote is None: if maybeNote is None:
if velocity is None: if velocity is None:
velocity = getAverageVelocity(trackId) velocity = getAverageVelocity(trackId)
setStep(trackId, {'index': index, 'pitch': pitch, 'factor': factor, 'velocity': velocity}) setStep(trackId, {'index': index, 'pitch': pitch, 'factor': factor, 'velocity': velocity, "split":split})
else: else:
removeStep(trackId, index, pitch) removeStep(trackId, index, pitch)

6
engine/config.py

@ -21,7 +21,7 @@ METADATA = {
#release announcements, entries in software directories etc. #release announcements, entries in software directories etc.
"tagline" : 'Easy to use pattern based midi sequencer.', "tagline" : 'Easy to use pattern based midi sequencer.',
"version" : "2.3.2", "version" : "2.4.0",
"year" : "2022", "year" : "2022",
"author" : "Laborejo Software Suite", "author" : "Laborejo Software Suite",
"url" : "https://www.laborejo.org/patroneo", "url" : "https://www.laborejo.org/patroneo",
@ -51,10 +51,10 @@ METADATA = {
Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a Patroneo (which is Esperanto for "Pattern") is an easy to use, pattern based midi sequencer, a
program that sends digital "notes" to software instruments such as synthesizers and samplers. program that sends digital "notes" to software instruments such as synthesizers and samplers.
This program is feature-complete with version 2.3.0 in 2022. This program is feature-complete with version 2.4.0 in 2022.
Further releases will be limited to maintenance and fixing problems. Further releases will be limited to maintenance and fixing problems.
Patroneo is primarily designed for educational purposes, where the main goal is to teach the Patroneo was initially designed for educational purposes, where the main goal is to teach the
importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer importance of patterns and repetitions in any kind of music. However, Patroneo is a full sequencer
you can use to create real music. The constraints it presents will more likely boost your you can use to create real music. The constraints it presents will more likely boost your
creativity than suppressing it. creativity than suppressing it.

27
engine/pattern.py

@ -41,8 +41,9 @@ class Pattern(object):
Only existing steps (Switched On) are in self.data Only existing steps (Switched On) are in self.data
{"index": from 0 to parentTrack.parentData.howManyUnits * stretchfactor. But can be higher, will just not be played or exported., {"index": from 0 to parentTrack.parentData.howManyUnits * stretchfactor. But can be higher, will just not be played or exported.,
"factor": float, "factor": float,
"pitch": int 0-7, "pitch": int 0-maxPitch,
"velocity":int 0-127, "velocity":int 0-127,
"split": int 1-n, (GUI restricts n=9)
} }
The pitch is determined by an external scale, which is a list of midi pitches. The pitch is determined by an external scale, which is a list of midi pitches.
@ -127,7 +128,7 @@ class Pattern(object):
vel = self.averageVelocity vel = self.averageVelocity
for index in range(self.parentTrack.parentData.howManyUnits * self.parentTrack.patternLengthMultiplicator): for index in range(self.parentTrack.parentData.howManyUnits * self.parentTrack.patternLengthMultiplicator):
for pitchindex in range(l): for pitchindex in range(l):
lst.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel}) lst.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel, "split":1})
self.data = lst self.data = lst
def empty(self): def empty(self):
@ -141,7 +142,7 @@ class Pattern(object):
for index in range(self.parentTrack.parentData.howManyUnits * self.parentTrack.patternLengthMultiplicator): for index in range(self.parentTrack.parentData.howManyUnits * self.parentTrack.patternLengthMultiplicator):
for pitchindex in range(l): for pitchindex in range(l):
if not (index, pitchindex) in existing: if not (index, pitchindex) in existing:
lst.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel}) lst.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel, "split":1})
self.data = lst self.data = lst
def getRow(self, pitchindex): def getRow(self, pitchindex):
@ -194,14 +195,14 @@ class Pattern(object):
for i in range(numberOfRepeats): for i in range(numberOfRepeats):
for b in toRepeatChunk: for b in toRepeatChunk:
if b: if b:
newRow.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel}) newRow.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel, "split":1})
index += 1 index += 1
self._putRow(pitchindex, newRow) self._putRow(pitchindex, newRow)
def repeatFromStep(self, pitchindex, stepIndex): def repeatFromStep(self, pitchindex, stepIndex):
"""Includes the given step. """Includes the given step.
Uses original velocities and scale factors Uses original velocities, splits and scale factors
""" """
originalRow = self._getRowWithNoneFillers(pitchindex) originalRow = self._getRowWithNoneFillers(pitchindex)
toRepeatChunk = originalRow[:stepIndex+1] toRepeatChunk = originalRow[:stepIndex+1]
@ -225,7 +226,7 @@ class Pattern(object):
for index in range(self.parentTrack.parentData.howManyUnits * self.parentTrack.patternLengthMultiplicator): for index in range(self.parentTrack.parentData.howManyUnits * self.parentTrack.patternLengthMultiplicator):
if not index in existingIndices: if not index in existingIndices:
self.data.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel}) self.data.append({"index":index, "factor": 1, "pitch": pitchindex, "velocity":vel, "split":1})
def stepByIndexAndPitch(self, index, pitch): def stepByIndexAndPitch(self, index, pitch):
@ -263,6 +264,7 @@ class Pattern(object):
note["factor"] = pattern["factor"] #size multiplier -> longer or short note note["factor"] = pattern["factor"] #size multiplier -> longer or short note
note["velocity"] = pattern["velocity"] note["velocity"] = pattern["velocity"]
note["midipitch"] = self.scale[pattern["pitch"]] #we always report the untransposed note. For a GUI the pattern gets transposed, not the note. note["midipitch"] = self.scale[pattern["pitch"]] #we always report the untransposed note. For a GUI the pattern gets transposed, not the note.
note["split"] = pattern["split"]
note["exceedsPlayback"] = False #This is set by buildPattern. note["exceedsPlayback"] = False #This is set by buildPattern.
self.exportCache.append(note) self.exportCache.append(note)
@ -399,8 +401,17 @@ class Pattern(object):
pitch = 127 pitch = 127
elif pitch < 0: elif pitch < 0:
pitch = 0 pitch = 0
exportPattern += cbox.Pattern.serialize_event(startTick, 0x90 + self.parentTrack.midiChannel, pitch, velocity) # note on
exportPattern += cbox.Pattern.serialize_event(endTick-1, 0x80 + self.parentTrack.midiChannel, pitch, velocity) # note off #-1 ticks to create a small logical gap. Does not affect next note on.
#Split.
splitAmount = noteDict["split"]
for split in range(splitAmount):
dur = endTick-startTick
st = int(startTick + (split * dur / splitAmount)) #note on
end = int(st + dur/splitAmount -1) #note off
exportPattern += cbox.Pattern.serialize_event(st, 0x90 + self.parentTrack.midiChannel, pitch, velocity) # note on
exportPattern += cbox.Pattern.serialize_event(end-1, 0x80 + self.parentTrack.midiChannel, pitch, velocity) # note off #-1 ticks to create a small logical gap. Does not affect next note on.
pattern = cbox.Document.get_song().pattern_from_blob(exportPattern, oneMeasureInTicks) pattern = cbox.Document.get_song().pattern_from_blob(exportPattern, oneMeasureInTicks)
self._builtPatternCache[cacheHash] = pattern self._builtPatternCache[cacheHash] = pattern

22
qtgui/mainwindow.py

@ -643,6 +643,15 @@ class MainWindow(TemplateMainWindow):
self.songEditor.currentHoverStep.decreaseAugmentationFactor() self.songEditor.currentHoverStep.decreaseAugmentationFactor()
def stepSplit(self, value):
"""This happens during step/note hover. The hoverLeave event will send the changed data
to the api. We simply change our internal GUI value here"""
if value < 1 or value > 9:
value = 1 #Do it here so we don't have a surprise somewhere else, no matter if other functions check themselves.
if self.patternGrid.currentHoverStep:
self.patternGrid.currentHoverStep.split = value
self.patternGrid.currentHoverStep.setApperance() #update graphics
def createMenu(self): def createMenu(self):
#We have undo/redo since v2.1. Template menu entries were hidden before. #We have undo/redo since v2.1. Template menu entries were hidden before.
@ -653,7 +662,8 @@ class MainWindow(TemplateMainWindow):
self.menu.addMenuEntry("menuEdit", "actionGlobalOffsetSubmenu", QtCore.QCoreApplication.translate("Menu", "Global Rhythm Offset"), lambda: globalOffsetSubmenu(self), tooltip=QtCore.QCoreApplication.translate("Menu", "Shift the whole piece further down the timeline")) self.menu.addMenuEntry("menuEdit", "actionGlobalOffsetSubmenu", QtCore.QCoreApplication.translate("Menu", "Global Rhythm Offset"), lambda: globalOffsetSubmenu(self), tooltip=QtCore.QCoreApplication.translate("Menu", "Shift the whole piece further down the timeline"))
self.menu.addSeparator("menuEdit") self.menu.addSeparator("menuEdit")
#Measure Modifications
#Measure Modifications - Hover Shortcuts
self.menu.addMenuEntry("menuEdit", "actionHalftoneTransposeIncrease", QtCore.QCoreApplication.translate("Menu", "Increase halftone transpose for currently hovered measure (use shortcut!)"), lambda: self.halftoneTranspose(1), shortcut="h") self.menu.addMenuEntry("menuEdit", "actionHalftoneTransposeIncrease", QtCore.QCoreApplication.translate("Menu", "Increase halftone transpose for currently hovered measure (use shortcut!)"), lambda: self.halftoneTranspose(1), shortcut="h")
self.menu.addMenuEntry("menuEdit", "actionHalftoneTransposeDecrease", QtCore.QCoreApplication.translate("Menu", "Decrease halftone transpose for currently hovered measure (use shortcut!)"), lambda: self.halftoneTranspose(-1), shortcut="Shift+h") self.menu.addMenuEntry("menuEdit", "actionHalftoneTransposeDecrease", QtCore.QCoreApplication.translate("Menu", "Decrease halftone transpose for currently hovered measure (use shortcut!)"), lambda: self.halftoneTranspose(-1), shortcut="Shift+h")
@ -667,6 +677,16 @@ class MainWindow(TemplateMainWindow):
self.menu.addMenuEntry("menuEdit", "actionAugmentationFactorIncrease", QtCore.QCoreApplication.translate("Menu", "Increase augmentation factor for currently hovered measure (use shortcut!)"), lambda: self.augmentationFactor(1), shortcut="a") self.menu.addMenuEntry("menuEdit", "actionAugmentationFactorIncrease", QtCore.QCoreApplication.translate("Menu", "Increase augmentation factor for currently hovered measure (use shortcut!)"), lambda: self.augmentationFactor(1), shortcut="a")
self.menu.addMenuEntry("menuEdit", "actionAugmentationFactorDecrease", QtCore.QCoreApplication.translate("Menu", "Decrease augmentation factor for currently hovered measure (use shortcut!)"), lambda: self.augmentationFactor(-1), shortcut="Shift+a") self.menu.addMenuEntry("menuEdit", "actionAugmentationFactorDecrease", QtCore.QCoreApplication.translate("Menu", "Decrease augmentation factor for currently hovered measure (use shortcut!)"), lambda: self.augmentationFactor(-1), shortcut="Shift+a")
#Pattern Splitter - Hover Shortcuts
self.menu.addSeparator("menuEdit")
self.menu.addMenuEntry("menuEdit", "actionStepSplit1", QtCore.QCoreApplication.translate("Menu", "No Step Split (use shortcut!)"), lambda: self.stepSplit(1), shortcut="1")
splitTranslate = QtCore.QCoreApplication.translate("Menu", "[Only Shortcut] Split hovered Step in ")
for i in range(2, 10): #10 exclusive
strI = str(i)
self.menu.addMenuEntry("menuEdit", "actionStepSplit"+strI, splitTranslate + strI , lambda qtarg, i=i: self.stepSplit(i), shortcut=strI)
self.menu.addSubmenu("menuView", QtCore.QCoreApplication.translate("menu","View")) self.menu.addSubmenu("menuView", QtCore.QCoreApplication.translate("menu","View"))
self.menu.addMenuEntry("menuView", "actionMaximizeSongArea", QtCore.QCoreApplication.translate("menu", "Maximize Song Area"), self.maximizeSongArea) self.menu.addMenuEntry("menuView", "actionMaximizeSongArea", QtCore.QCoreApplication.translate("menu", "Maximize Song Area"), self.maximizeSongArea)

56
qtgui/pattern_grid.py

@ -88,6 +88,8 @@ class PatternGrid(QtWidgets.QGraphicsScene):
self._middleMouseDown = False self._middleMouseDown = False
self.currentHoverStep = None #used by the main window
#self.ticksToPixelRatio set by callback_timeSignatureChanged #self.ticksToPixelRatio set by callback_timeSignatureChanged
self.playhead = Playhead(parentScene = self) self.playhead = Playhead(parentScene = self)
self.addItem(self.playhead) self.addItem(self.playhead)
@ -124,7 +126,7 @@ class PatternGrid(QtWidgets.QGraphicsScene):
""" """
if (stepDict["index"], stepDict["pitch"]) in self._steps: if (stepDict["index"], stepDict["pitch"]) in self._steps:
guiStep = self._steps[stepDict["index"], stepDict["pitch"]] guiStep = self._steps[stepDict["index"], stepDict["pitch"]]
guiStep.on(velocityAndFactor = (stepDict["velocity"], stepDict["factor"])) guiStep.on(velocityAndFactorAndSplit = (stepDict["velocity"], stepDict["factor"], stepDict["split"]))
def callback_removeChanged(self, stepDict:dict): def callback_removeChanged(self, stepDict:dict):
"""This callback reaction was introduced after support for the APCMini. """This callback reaction was introduced after support for the APCMini.
@ -239,8 +241,8 @@ class PatternGrid(QtWidgets.QGraphicsScene):
for noteDict in exportDict["pattern"]: for noteDict in exportDict["pattern"]:
x = noteDict["index"] x = noteDict["index"]
y = noteDict["pitch"] y = noteDict["pitch"]
velocityAndFactor = (noteDict["velocity"], noteDict["factor"]) velocityAndFactorAndSplit = (noteDict["velocity"], noteDict["factor"], noteDict["split"])
self._steps[(x,y)].on(velocityAndFactor=velocityAndFactor, exceedsPlayback=noteDict["exceedsPlayback"]) self._steps[(x,y)].on(velocityAndFactorAndSplit=velocityAndFactorAndSplit, exceedsPlayback=noteDict["exceedsPlayback"])
self.scale.buildScale(exportDict["numberOfSteps"]) self.scale.buildScale(exportDict["numberOfSteps"])
self.scale.setScale(exportDict["scale"]) self.scale.setScale(exportDict["scale"])
@ -529,12 +531,21 @@ class Step(QtWidgets.QGraphicsRectItem):
self._factorChangeAllowed = False #during drag and drop this will be True. Used in the mouse steps. self._factorChangeAllowed = False #during drag and drop this will be True. Used in the mouse steps.
self.shadow = False self.shadow = False
#Velocity #Velocity
self._rememberVelocity = None self._rememberVelocity = None #check if to send new data on api in self.hoverLeaveEvent
self.velocityNumber = QtWidgets.QGraphicsSimpleTextItem() self.velocityNumber = QtWidgets.QGraphicsSimpleTextItem()
self.velocityNumber.setParentItem(self) self.velocityNumber.setParentItem(self)
self.velocityNumber.setBrush(self.parentScene.labelColor) self.velocityNumber.setBrush(self.parentScene.labelColor)
self.velocityNumber.setPos(offset*2,offset*2) #that is not pretty but you can see it under the cursor self.velocityNumber.setPos(offset*2,offset*2) #that is not pretty but you can see it under the cursor
#Split
self.split = 1
self._rememberSplit = None #check if to send new data on api in self.hoverLeaveEvent
self.splitNumber = QtWidgets.QGraphicsSimpleTextItem()
self.splitNumber.setParentItem(self)
self.splitNumber.setBrush(self.parentScene.labelColor)
self.splitNumber.setPos(SIZE_UNIT-offset*8,SIZE_UNIT-offset*9) # lower right corner. It is always "/n" where n is a single digit. So a fixed position and width.
#set in setApperance if > 1
if self.parentScene.parentView.parentMainWindow.ui.actionVelocitiesAlwaysVisible.isChecked(): if self.parentScene.parentView.parentMainWindow.ui.actionVelocitiesAlwaysVisible.isChecked():
self.velocityNumber.show() self.velocityNumber.show()
else: else:
@ -566,13 +577,20 @@ class Step(QtWidgets.QGraphicsRectItem):
rect.setWidth(SIZE_UNIT * self.factor - self.offset*2) rect.setWidth(SIZE_UNIT * self.factor - self.offset*2)
self.setRect(rect) self.setRect(rect)
if self.status: if self.status: #step/note is on
setWidth() setWidth()
assert self.parentScene.currentColor assert self.parentScene.currentColor
self.setBrush(self.parentScene.currentColor) self.setBrush(self.parentScene.currentColor)
self.velocityNumber.setBrush(self.parentScene.labelColor) self.velocityNumber.setBrush(self.parentScene.labelColor)
self.setZValue(_zValuesRelativeToScene["step"]) if self.split > 1:
self.splitNumber.show()
self.splitNumber.setBrush(self.parentScene.labelColor)
self.splitNumber.setText("/" + str(self.split))
else: else:
self.splitNumber.hide()
self.setZValue(_zValuesRelativeToScene["step"])
else: #step/note is off
self.setOpacity(1) self.setOpacity(1)
if self.shadow: if self.shadow:
setWidth() setWidth()
@ -606,18 +624,22 @@ class Step(QtWidgets.QGraphicsRectItem):
"index":self.column, "index":self.column,
"pitch":self.row, "pitch":self.row,
"factor":self.factor, "factor":self.factor,
"velocity":self.velocity} "velocity":self.velocity,
"split":self.split,
}
def useDefaultValues(self): def useDefaultValues(self):
self.velocity = api.getAverageVelocity(trackId=self.parentScene.parentView.parentMainWindow.currentTrackId) #already sets opacity and velocityNumber self.velocity = api.getAverageVelocity(trackId=self.parentScene.parentView.parentMainWindow.currentTrackId) #already sets opacity and velocityNumber
self._rememberVelocity = self.velocity self._rememberVelocity = self.velocity
self.factor = api.DEFAULT_FACTOR self.factor = api.DEFAULT_FACTOR
self.split=1
self._rememberSplit = self.split
self.initalized = True self.initalized = True
def on(self, velocityAndFactor=None, exceedsPlayback=None): def on(self, velocityAndFactorAndSplit=None, exceedsPlayback=None):
"""velocityAndFactor is a tuple""" """velocityAndFactorAndSplit is a tuple"""
if velocityAndFactor: #on load / by callback if velocityAndFactorAndSplit: #on load / by callback
self.velocity, self.factor = velocityAndFactor self.velocity, self.factor, self.split = velocityAndFactorAndSplit
else: #User clicked on an empty field. else: #User clicked on an empty field.
self.useDefaultValues() self.useDefaultValues()
@ -639,7 +661,8 @@ class Step(QtWidgets.QGraphicsRectItem):
self.status = False self.status = False
self.setRect(*self.defaultSize) self.setRect(*self.defaultSize)
self.setApperance() #sets color, main/sub size and exceedPlayback warning self.setApperance() #sets color, main/sub size and exceedPlayback warning
self.velocityNumber.hide() #just in case. self.velocityNumber.hide()
self.splitNumber.hide()
def mousePressEvent(self, event): def mousePressEvent(self, event):
@ -650,6 +673,7 @@ class Step(QtWidgets.QGraphicsRectItem):
api.removeStep(self.parentScene.parentView.parentMainWindow.currentTrackId, self.column, self.row) api.removeStep(self.parentScene.parentView.parentMainWindow.currentTrackId, self.column, self.row)
else: else:
self.on() self.on()
self.parentScene.currentHoverStep = self
self._factorChangeAllowed = True self._factorChangeAllowed = True
self._factorStartTime = time() #see mouseReleaseEvent self._factorStartTime = time() #see mouseReleaseEvent
else: else:
@ -691,10 +715,13 @@ class Step(QtWidgets.QGraphicsRectItem):
if the mouse cursor is not on that item anymore""" if the mouse cursor is not on that item anymore"""
if self.status: if self.status:
event.accept() event.accept()
self.statusMessage(QtCore.QCoreApplication.translate("Statusbar", "Note: Left click do deactivate. Middle click to listen. MouseWheel to change volume (+ALT key to change entire row). Right click for pattern options.")) self.statusMessage(QtCore.QCoreApplication.translate("Statusbar", "Note: Left click do deactivate. Middle click to listen. MouseWheel to change volume (+ALT key to change entire row). Number keys to split. Right click for pattern options."))
self.parentScene.currentHoverStep = self #this is replicated in self.mousePressEvent, turning the note on
self._rememberVelocity = self.velocity self._rememberVelocity = self.velocity
self._rememberSplit = self.split
else: else:
self.statusMessage(QtCore.QCoreApplication.translate("Statusbar", "Left click do activate note. Middle click to listen. Right click for pattern options.")) self.statusMessage(QtCore.QCoreApplication.translate("Statusbar", "Left click do activate note. Middle click to listen. Right click for pattern options."))
self.parentScene.currentHoverStep = None
event.ignore() event.ignore()
def hoverLeaveEvent(self, event): def hoverLeaveEvent(self, event):
@ -703,10 +730,11 @@ class Step(QtWidgets.QGraphicsRectItem):
if the mouse cursor is not on that item anymore""" if the mouse cursor is not on that item anymore"""
if not self.parentScene.parentView.parentMainWindow.ui.actionVelocitiesAlwaysVisible.isChecked(): if not self.parentScene.parentView.parentMainWindow.ui.actionVelocitiesAlwaysVisible.isChecked():
self.velocityNumber.hide() self.velocityNumber.hide()
self.parentScene.currentHoverStep = None
self.statusMessage("") self.statusMessage("")
if self.status: if self.status:
event.accept() event.accept()
if self.status and not self.velocity == self._rememberVelocity: if self.status and (self.velocity != self._rememberVelocity or self.split != self._rememberSplit): #check if there is an actual data change.
api.setStep(self.parentScene.parentView.parentMainWindow.currentTrackId, self.export()) api.setStep(self.parentScene.parentView.parentMainWindow.currentTrackId, self.export())
self._rememberVelocity = self.velocity self._rememberVelocity = self.velocity
else: else:

3000
qtgui/resources.py

File diff suppressed because it is too large

BIN
qtgui/resources/translations/de.qm

Binary file not shown.

135
qtgui/resources/translations/de.ts

@ -32,17 +32,17 @@
<context> <context>
<name>EventContextMenu</name> <name>EventContextMenu</name>
<message> <message>
<location filename="../../pattern_grid.py" line="417"/> <location filename="../../pattern_grid.py" line="419"/>
<source>Invert Steps</source> <source>Invert Steps</source>
<translation>Schritte invertieren</translation> <translation>Schritte invertieren</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="418"/> <location filename="../../pattern_grid.py" line="420"/>
<source>All Steps On</source> <source>All Steps On</source>
<translation>Alle Schritte an</translation> <translation>Alle Schritte an</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="419"/> <location filename="../../pattern_grid.py" line="421"/>
<source>All Steps Off</source> <source>All Steps Off</source>
<translation>Alles Schritte aus</translation> <translation>Alles Schritte aus</translation>
</message> </message>
@ -52,17 +52,17 @@
<translation type="obsolete">Reihe mit Wiederholung bis hier befüllen</translation> <translation type="obsolete">Reihe mit Wiederholung bis hier befüllen</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="424"/> <location filename="../../pattern_grid.py" line="426"/>
<source>Clear Row</source> <source>Clear Row</source>
<translation>Reihe löschen</translation> <translation>Reihe löschen</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="425"/> <location filename="../../pattern_grid.py" line="427"/>
<source>Invert Row</source> <source>Invert Row</source>
<translation>Reihe umkehren</translation> <translation>Reihe umkehren</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="423"/> <location filename="../../pattern_grid.py" line="425"/>
<source>Repeat to step {} incl. to fill Row</source> <source>Repeat to step {} incl. to fill Row</source>
<translation>Reihe mit Wiederholung bis Schritt {} befüllen</translation> <translation>Reihe mit Wiederholung bis Schritt {} befüllen</translation>
</message> </message>
@ -116,65 +116,75 @@
<context> <context>
<name>Menu</name> <name>Menu</name>
<message> <message>
<location filename="../../mainwindow.py" line="652"/> <location filename="../../mainwindow.py" line="661"/>
<source>Convert Grouping</source> <source>Convert Grouping</source>
<translation>Gruppierung umwandeln</translation> <translation>Gruppierung umwandeln</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="652"/> <location filename="../../mainwindow.py" line="661"/>
<source>Change step-grouping but keep your music the same</source> <source>Change step-grouping but keep your music the same</source>
<translation>Taktartaufspaltung durch Gruppierung umwandeln, versucht die Musik gleich klingen zu lassen</translation> <translation>Taktartaufspaltung durch Gruppierung umwandeln, versucht die Musik gleich klingen zu lassen</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="653"/> <location filename="../../mainwindow.py" line="662"/>
<source>Global Rhythm Offset</source> <source>Global Rhythm Offset</source>
<translation>Genereller Rhythmusversatz</translation> <translation>Genereller Rhythmusversatz</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="653"/> <location filename="../../mainwindow.py" line="662"/>
<source>Shift the whole piece further down the timeline</source> <source>Shift the whole piece further down the timeline</source>
<translation>Schiebt das gesamte Stück &amp;quot;später&amp;quot; auf die Timeline</translation> <translation>Schiebt das gesamte Stück &amp;quot;später&amp;quot; auf die Timeline</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="658"/> <location filename="../../mainwindow.py" line="668"/>
<source>Increase halftone transpose for currently hovered measure (use shortcut!)</source> <source>Increase halftone transpose for currently hovered measure (use shortcut!)</source>
<translation>Erhöhe Halbton-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erhöhe Halbton-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="659"/> <location filename="../../mainwindow.py" line="669"/>
<source>Decrease halftone transpose for currently hovered measure (use shortcut!)</source> <source>Decrease halftone transpose for currently hovered measure (use shortcut!)</source>
<translation>Erniedrige Halbton-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erniedrige Halbton-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="661"/> <location filename="../../mainwindow.py" line="671"/>
<source>Increase in-scale transpose for currently hovered measure (use shortcut!)</source> <source>Increase in-scale transpose for currently hovered measure (use shortcut!)</source>
<translation>Erhöhe Skalen-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erhöhe Skalen-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="662"/> <location filename="../../mainwindow.py" line="672"/>
<source>Decrease in-scale transpose for currently hovered measure (use shortcut!)</source> <source>Decrease in-scale transpose for currently hovered measure (use shortcut!)</source>
<translation>Erniedrige Skalen-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erniedrige Skalen-Transposition für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="664"/> <location filename="../../mainwindow.py" line="674"/>
<source>Increase step delay for currently hovered measure (use shortcut!)</source> <source>Increase step delay for currently hovered measure (use shortcut!)</source>
<translation>Erhöhe Schritt-Verzögerung für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erhöhe Schritt-Verzögerung für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="665"/> <location filename="../../mainwindow.py" line="675"/>
<source>Decrease step delay for currently hovered measure (use shortcut!)</source> <source>Decrease step delay for currently hovered measure (use shortcut!)</source>
<translation>Erniedrige Schritt-Verzögerung für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erniedrige Schritt-Verzögerung für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="667"/> <location filename="../../mainwindow.py" line="677"/>
<source>Increase augmentation factor for currently hovered measure (use shortcut!)</source> <source>Increase augmentation factor for currently hovered measure (use shortcut!)</source>
<translation>Erhöhe Augmentierungs-Faktor für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erhöhe Augmentierungs-Faktor für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="668"/> <location filename="../../mainwindow.py" line="678"/>
<source>Decrease augmentation factor for currently hovered measure (use shortcut!)</source> <source>Decrease augmentation factor for currently hovered measure (use shortcut!)</source>
<translation>Erniedrige Augmentierungs-Faktor für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation> <translation>Erniedrige Augmentierungs-Faktor für den Takt momentan unter dem Mauszeiger (Tastenkürzel benutzen!)</translation>
</message> </message>
<message>
<location filename="../../mainwindow.py" line="682"/>
<source>No Step Split (use shortcut!)</source>
<translation>Keine Spaltung (Tastenkürzel benutzen!)</translation>
</message>
<message>
<location filename="../../mainwindow.py" line="684"/>
<source>[Only Shortcut] Split hovered Step in </source>
<translation>[Tastenkürzel] Spalte Schritt unter Mauszeiger in </translation>
</message>
</context> </context>
<context> <context>
<name>NOOPengineHistory</name> <name>NOOPengineHistory</name>
@ -455,72 +465,72 @@
<context> <context>
<name>Scale</name> <name>Scale</name>
<message> <message>
<location filename="../../pattern_grid.py" line="827"/> <location filename="../../pattern_grid.py" line="855"/>
<source>Major</source> <source>Major</source>
<translation>Dur</translation> <translation>Dur</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="828"/> <location filename="../../pattern_grid.py" line="856"/>
<source>Minor</source> <source>Minor</source>
<translation>Moll</translation> <translation>Moll</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="829"/> <location filename="../../pattern_grid.py" line="857"/>
<source>Dorian</source> <source>Dorian</source>
<translation>Dorisch</translation> <translation>Dorisch</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="830"/> <location filename="../../pattern_grid.py" line="858"/>
<source>Phrygian</source> <source>Phrygian</source>
<translation>Phrygisch</translation> <translation>Phrygisch</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="831"/> <location filename="../../pattern_grid.py" line="859"/>
<source>Lydian</source> <source>Lydian</source>
<translation>Lydisch</translation> <translation>Lydisch</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="832"/> <location filename="../../pattern_grid.py" line="860"/>
<source>Mixolydian</source> <source>Mixolydian</source>
<translation>Mixolydisch</translation> <translation>Mixolydisch</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="833"/> <location filename="../../pattern_grid.py" line="861"/>
<source>Locrian</source> <source>Locrian</source>
<translation>Lokrisch</translation> <translation>Lokrisch</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="834"/> <location filename="../../pattern_grid.py" line="862"/>
<source>Blues</source> <source>Blues</source>
<translation>Blues</translation> <translation>Blues</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="835"/> <location filename="../../pattern_grid.py" line="863"/>
<source>Hollywood</source> <source>Hollywood</source>
<translation>Hollywood</translation> <translation>Hollywood</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="838"/> <location filename="../../pattern_grid.py" line="866"/>
<source>English</source> <source>English</source>
<translation>Englisch</translation> <translation>Englisch</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="839"/> <location filename="../../pattern_grid.py" line="867"/>
<source>Lilypond</source> <source>Lilypond</source>
<translation>Lilypond</translation> <translation>Lilypond</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="840"/> <location filename="../../pattern_grid.py" line="868"/>
<source>German</source> <source>German</source>
<translation>Deutsch</translation> <translation>Deutsch</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="841"/> <location filename="../../pattern_grid.py" line="869"/>
<source>Drums GM</source> <source>Drums GM</source>
<translation>Drums GM</translation> <translation>Drums GM</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="836"/> <location filename="../../pattern_grid.py" line="864"/>
<source>Chromatic</source> <source>Chromatic</source>
<translation>Chromatisch</translation> <translation>Chromatisch</translation>
</message> </message>
@ -568,20 +578,20 @@
<message> <message>
<location filename="../../pattern_grid.py" line="694"/> <location filename="../../pattern_grid.py" line="694"/>
<source>Note: Left click do deactivate. Middle click to listen. MouseWheel to change volume (+ALT key to change entire row). Right click for pattern options.</source> <source>Note: Left click do deactivate. Middle click to listen. MouseWheel to change volume (+ALT key to change entire row). Right click for pattern options.</source>
<translation>Note: Linksklick um auszuschalten. Mittelklick: Hören. Mausrad um Lautstärke zu ändern (+ALT Taste für die ganze Reihe). Rechtsklick für Muster-Optionen.</translation> <translation type="obsolete">Note: Linksklick um auszuschalten. Mittelklick: Hören. Mausrad um Lautstärke zu ändern (+ALT Taste für die ganze Reihe). Rechtsklick für Muster-Optionen.</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="697"/> <location filename="../../pattern_grid.py" line="723"/>
<source>Left click do activate note. Middle click to listen. Right click for pattern options.</source> <source>Left click do activate note. Middle click to listen. Right click for pattern options.</source>
<translation>Linksklick um Note anzuschalten. Mittelklick um zu hören. Rechtsklick für Muster-Optionen.</translation> <translation>Linksklick um Note anzuschalten. Mittelklick um zu hören. Rechtsklick für Muster-Optionen.</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="748"/> <location filename="../../pattern_grid.py" line="776"/>
<source>Pitch in MIDI half-tones. 60 = middle C. Enter number or spin the mouse wheel to change.</source> <source>Pitch in MIDI half-tones. 60 = middle C. Enter number or spin the mouse wheel to change.</source>
<translation>Tonhöhe in Midi-Halbtönen: 60 = Schlüssel-C. Gib eine Zahl ein oder drehe das Mausrum um sie zu verändern.</translation> <translation>Tonhöhe in Midi-Halbtönen: 60 = Schlüssel-C. Gib eine Zahl ein oder drehe das Mausrum um sie zu verändern.</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="1103"/> <location filename="../../pattern_grid.py" line="1131"/>
<source>Click to change volume for all notes in single steps, spin mouse wheel to change in steps of 10.</source> <source>Click to change volume for all notes in single steps, spin mouse wheel to change in steps of 10.</source>
<translation>Linksklick um alle Noten in Einerschritten lauter/leiser zu machen. Mausrad drehen für 10er Schritte.</translation> <translation>Linksklick um alle Noten in Einerschritten lauter/leiser zu machen. Mausrad drehen für 10er Schritte.</translation>
</message> </message>
@ -630,6 +640,11 @@
<source>Measure: Left click to deactivate. Middle click to show as shadows in current pattern. Right click for measure group options. Read the Edit menu for advanced modifications while hovering.</source> <source>Measure: Left click to deactivate. Middle click to show as shadows in current pattern. Right click for measure group options. Read the Edit menu for advanced modifications while hovering.</source>
<translation>Takt: Linksklick zum ausschalten. Mittelklick um als Schatten in momentaner Spur anzuzeigen. Rechtsklick für Taktgruppen-Optionen. Im Bearbeiten-Menü sind mehr Möglichkeiten.</translation> <translation>Takt: Linksklick zum ausschalten. Mittelklick um als Schatten in momentaner Spur anzuzeigen. Rechtsklick für Taktgruppen-Optionen. Im Bearbeiten-Menü sind mehr Möglichkeiten.</translation>
</message> </message>
<message>
<location filename="../../pattern_grid.py" line="718"/>
<source>Note: Left click do deactivate. Middle click to listen. MouseWheel to change volume (+ALT key to change entire row). Number keys to split. Right click for pattern options.</source>
<translation>Note: Linksklick um auszuschalten. Mittelklick: Hören. Mausrad um Lautstärke zu ändern (+ALT Taste für die ganze Reihe). Nummerntaste zum Spalten. Rechtsklick für Muster-Optionen.</translation>
</message>
</context> </context>
<context> <context>
<name>TimeSignature</name> <name>TimeSignature</name>
@ -864,72 +879,72 @@
<context> <context>
<name>TransposeControls</name> <name>TransposeControls</name>
<message> <message>
<location filename="../../pattern_grid.py" line="855"/> <location filename="../../pattern_grid.py" line="883"/>
<source>+Half Tone</source> <source>+Half Tone</source>
<translation>+Halbton</translation> <translation>+Halbton</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="857"/> <location filename="../../pattern_grid.py" line="885"/>
<source>Transpose the whole scale up a half tone (+1 midi note)</source> <source>Transpose the whole scale up a half tone (+1 midi note)</source>
<translation>Transponiere die Tonleiter einen Halbton aufwärts (+1 MIDI Tonhöhe)</translation> <translation>Transponiere die Tonleiter einen Halbton aufwärts (+1 MIDI Tonhöhe)</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="860"/> <location filename="../../pattern_grid.py" line="888"/>
<source>-Half Tone</source> <source>-Half Tone</source>
<translation>-Halbton</translation> <translation>-Halbton</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="862"/> <location filename="../../pattern_grid.py" line="890"/>
<source>Transpose the whole scale down a half tone (-1 midi note)</source> <source>Transpose the whole scale down a half tone (-1 midi note)</source>
<translation>Transponiere die Tonleiter einen Halbton abwärts (-1 MIDI Tonhöhe)</translation> <translation>Transponiere die Tonleiter einen Halbton abwärts (-1 MIDI Tonhöhe)</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="865"/> <location filename="../../pattern_grid.py" line="893"/>
<source>+Octave</source> <source>+Octave</source>
<translation>+Oktave</translation> <translation>+Oktave</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="867"/> <location filename="../../pattern_grid.py" line="895"/>
<source>Transpose the whole scale up an octave (+12 midi notes)</source> <source>Transpose the whole scale up an octave (+12 midi notes)</source>
<translation>Transponiere die Tonleiter eine Oktave aufwärts (+12 MIDI Tonhöhe)</translation> <translation>Transponiere die Tonleiter eine Oktave aufwärts (+12 MIDI Tonhöhe)</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="870"/> <location filename="../../pattern_grid.py" line="898"/>
<source>-Octave</source> <source>-Octave</source>
<translation>-Oktave</translation> <translation>-Oktave</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="872"/> <location filename="../../pattern_grid.py" line="900"/>
<source>Transpose the whole scale down an octave (-12 midi notes)</source> <source>Transpose the whole scale down an octave (-12 midi notes)</source>
<translation>Transponiere die Tonleiter eine Oktave abwärts (-12 MIDI Tonhöhe)</translation> <translation>Transponiere die Tonleiter eine Oktave abwärts (-12 MIDI Tonhöhe)</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="879"/> <location filename="../../pattern_grid.py" line="907"/>
<source>Set Scale to:</source> <source>Set Scale to:</source>
<translation>Benutze Tonleiter:</translation> <translation>Benutze Tonleiter:</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="881"/> <location filename="../../pattern_grid.py" line="909"/>
<source>Take the bottom note and build a predefined scale from it upwards.</source> <source>Take the bottom note and build a predefined scale from it upwards.</source>
<translation>Ändere die Tonleiter des Musters auf die Ausgewählte. Referenzton ist die unterste Reihe des Musters.</translation> <translation>Ändere die Tonleiter des Musters auf die Ausgewählte. Referenzton ist die unterste Reihe des Musters.</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="887"/> <location filename="../../pattern_grid.py" line="915"/>
<source>Set Notenames to:</source> <source>Set Notenames to:</source>
<translation>Benutze Notennamen:</translation> <translation>Benutze Notennamen:</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="889"/> <location filename="../../pattern_grid.py" line="917"/>
<source>Use this scheme as note names.</source> <source>Use this scheme as note names.</source>
<translation>Use this scheme as note names.</translation> <translation>Use this scheme as note names.</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="893"/> <location filename="../../pattern_grid.py" line="921"/>
<source>Choose how many different notes does this pattern should have.</source> <source>Choose how many different notes does this pattern should have.</source>
<translation>Anzahl der verschiedenen Tonhöhen-Stufen aus.</translation> <translation>Anzahl der verschiedenen Tonhöhen-Stufen aus.</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="896"/> <location filename="../../pattern_grid.py" line="924"/>
<source> Notes</source> <source> Notes</source>
<translation> Noten</translation> <translation> Noten</translation>
</message> </message>
@ -937,22 +952,22 @@
<context> <context>
<name>VelocityControls</name> <name>VelocityControls</name>
<message> <message>
<location filename="../../pattern_grid.py" line="1081"/> <location filename="../../pattern_grid.py" line="1109"/>
<source>+Velocity</source> <source>+Velocity</source>
<translation>+Velocity</translation> <translation>+Velocity</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="1084"/> <location filename="../../pattern_grid.py" line="1112"/>
<source>Make everything louder. Hover and mousewheel up/down to go in steps of 10.</source> <source>Make everything louder. Hover and mousewheel up/down to go in steps of 10.</source>
<translation>Alle Töne lauter machen. Mit dem Mauszeiger über dem Knopf bleiben und das Mausrad auf oder ab bewegen für 10er Schritte.</translation> <translation>Alle Töne lauter machen. Mit dem Mauszeiger über dem Knopf bleiben und das Mausrad auf oder ab bewegen für 10er Schritte.</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="1087"/> <location filename="../../pattern_grid.py" line="1115"/>
<source>-Velocity</source> <source>-Velocity</source>
<translation>-Velocity</translation> <translation>-Velocity</translation>
</message> </message>
<message> <message>
<location filename="../../pattern_grid.py" line="1090"/> <location filename="../../pattern_grid.py" line="1118"/>
<source>Make everything softer. Hover and mousewheel up/down to go in steps of 10.</source> <source>Make everything softer. Hover and mousewheel up/down to go in steps of 10.</source>
<translation>Alle Töne leiser machen. Mit dem Mauszeiger über dem Knopf bleiben und das Mausrad auf oder ab bewegen für 10er Schritte.</translation> <translation>Alle Töne leiser machen. Mit dem Mauszeiger über dem Knopf bleiben und das Mausrad auf oder ab bewegen für 10er Schritte.</translation>
</message> </message>
@ -1060,32 +1075,32 @@ Man kann sogar negative Zahlen eingeben, wobei es unmöglich ist vor die Jack-Tr
<context> <context>
<name>menu</name> <name>menu</name>
<message> <message>
<location filename="../../mainwindow.py" line="671"/> <location filename="../../mainwindow.py" line="691"/>
<source>View</source> <source>View</source>
<translation>Ansicht</translation> <translation>Ansicht</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="672"/> <location filename="../../mainwindow.py" line="692"/>
<source>Maximize Song Area</source> <source>Maximize Song Area</source>
<translation>Formeditor maximieren</translation> <translation>Formeditor maximieren</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="673"/> <location filename="../../mainwindow.py" line="693"/>
<source>Maximize Pattern Area</source> <source>Maximize Pattern Area</source>
<translation>Takteditor maximieren</translation> <translation>Takteditor maximieren</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="674"/> <location filename="../../mainwindow.py" line="694"/>
<source>Equal space for Pattern/Song Area</source> <source>Equal space for Pattern/Song Area</source>
<translation>Gleiche Größe für Form- und Takteditor</translation> <translation>Gleiche Größe für Form- und Takteditor</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="675"/> <location filename="../../mainwindow.py" line="695"/>
<source>Follow playhead in pattern-view by scrolling.</source> <source>Follow playhead in pattern-view by scrolling.</source>
<translation>Playhead in Musteransicht durch Scrollen verfolgen.</translation> <translation>Playhead in Musteransicht durch Scrollen verfolgen.</translation>
</message> </message>
<message> <message>
<location filename="../../mainwindow.py" line="676"/> <location filename="../../mainwindow.py" line="696"/>
<source>Velocity numbers are always visible</source> <source>Velocity numbers are always visible</source>
<translation>Lautstärkennummern sind immer sichtbar</translation> <translation>Lautstärkennummern sind immer sichtbar</translation>
</message> </message>

Loading…
Cancel
Save