A way to control (change) a parameter over time as a response to
triggering, holding, and releasing a note.
Did your eyes just glaze over? Let's try again:
Imagine that you're playing a note on the keyboard and you have
your other hand on a knob (volume, filter cutoff, etc.). As you play
the note, you twist the knob (often up, then down... or down, then up).
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/doc/MidiInstrumentMapping.ods and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/doc/MidiInstrumentMapping.ods differ
diff -Nru hydrogen-0.9.6~beta1/data/hydrogen.default.conf hydrogen-0.9.6~beta2/data/hydrogen.default.conf
--- hydrogen-0.9.6~beta1/data/hydrogen.default.conf 2011-09-17 17:03:54.000000000 +0000
+++ hydrogen-0.9.6~beta2/data/hydrogen.default.conf 2012-05-25 12:19:45.000000000 +0000
@@ -13,8 +13,8 @@
true
false
false
- 400
- true
+ 400
+ false
true
true
false
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/i18n/hydrogen.de.qm and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/i18n/hydrogen.de.qm differ
diff -Nru hydrogen-0.9.6~beta1/data/i18n/hydrogen.de.ts hydrogen-0.9.6~beta2/data/i18n/hydrogen.de.ts
--- hydrogen-0.9.6~beta1/data/i18n/hydrogen.de.ts 2011-09-12 11:54:45.000000000 +0000
+++ hydrogen-0.9.6~beta2/data/i18n/hydrogen.de.ts 2012-05-25 12:19:45.000000000 +0000
@@ -620,14 +620,14 @@
Director
Director
- Dirigent
+ Dirigent
Director_UI
Dialog
- Dialog
+ Dialog
@@ -735,15 +735,15 @@
Export to a single track
-
+ Als einzelne Spur exportieren
Export to seperate tracks
-
+ Mehrspur Export
Both
-
+ Beides
This version of hydrogen is not able to export songs with tempo changes. If you proceed, the song will be exported without tempo changes.
@@ -790,23 +790,23 @@
22050
- 22050
+ 22050
44100
- 44100
+ 44100
48000
- 48000
+ 48000
96000
- 96000
+ 96000
192000
- 192000
+ 192000
SampleDepth in Bit:
@@ -814,19 +814,19 @@
8
- 8
+ 8
16
- 16
+ 16
24
- 24
+ 24
32
- 32
+ 32
Templates:
@@ -834,43 +834,43 @@
WAV in CD quality "44,1kHz, 16 bit PCM"
-
+ WAV in CD Qualität "44,1kHz, 16 bit PCM"
WAV in ADAT quality "48 kHz, 16 bit PCM"
-
+ WAV in ADAT Qualität "48 kHz, 16 bit PCM"
WAV in better quality "48 kHz, 24 bit PCM"
-
+ WAV in besserer Qualität "48 kHz, 24 bit PCM"
WAV LOFI "22.05kHz, 8 bit PCM
-
+ WAV in geringster Qualität "22.05kHz, 8 bit PCM
WAV best Mixdown quality "96 kHz, 32 bit PCM"
-
+ WAV beste Qualität "96 kHz, 32 bit PCM"
AIFF in CD quality "41 kHz, 16 bit PCM"
-
+ AIFF in CD Qualität "41 kHz, 16 bit PCM"
AIFF in ADAT quality "48 kHz, 16 bit PCM"
-
+ AIFF in ADAT Qualität "48 kHz, 16 bit PCM"
AIFF in better quality "48 kHz, 24 bit PCM"
-
+ AIFF in besserer Qualität "48 kHz, 24 bit PCM"
FLAC lossless compressor in good quality "48 kHz"
-
+ FLAC verlustfreie Kompression in guter Qualität "48 kHz"
OGG Vorbis loosely compressed in good quality "VBR"
-
+ OGG Vorbis gering komprimiert in guter Qualität "VBR"
@@ -895,21 +895,21 @@
H2Core::SongEditorPanelBpmWidget
BPM
-
+ BPM
H2Core::SongEditorPanelTagWidget
Tag
-
+ Tag
H2Core::SoundLibraryPropertiesDialog
SoundLibrary Properties
- Soundlibrary Eigenschaften
+ Soundlibrary Eigenschaften
&Ok
@@ -921,12 +921,12 @@
This is not possible, you can only save changes inside instruments to the current loaded sound library
- Nicht möglich, es lassen sich nur Änderungen an Instrumenten innerhalb der aktuell verwendeten Soundlibrary speichern.
+ Nicht möglich, es lassen sich nur Änderungen an Instrumenten innerhalb der aktuell verwendeten Soundlibrary speichern.
Warning! Changing the drumkit name will result in creating a new drumkit with this name.
Are you sure?
- Achtung! Bei Ă„nderungen des Drumkit-Namens wird ein neues Drumkit dieses Namens erstellt.
+ Achtung! Bei Ă„nderungen des Drumkit-Namens wird ein neues Drumkit dieses Namens erstellt.
Sind sie sicher?
@@ -1010,7 +1010,7 @@
Auto-Stop-Note
-
+ Auto-Stop-Note
@@ -1729,15 +1729,15 @@
Loaded Soundlibrary
- Geladene Klangbibliothek
+ Geladene Klangbibliothek
Midi keyboard or computer keys play whole drumset or single instruments
- Midi-Tatertur oder Tastertur anschläge spielen die geladene Klangbibliothek im Grund-Ton oder das ausgewählte Instrument mit Tonhöhen-Veränderung
+ Midi-Tastertur oder Tasterturanschläge spielen die geladene Klangbibliothek im Grund-Ton oder das ausgewählte Instrument mit Tonhöhen-Veränderung
NoteKey
- Note
+ Note
destructive mode pre delete settings
@@ -1749,7 +1749,7 @@
Piano
-
+ Piano
Show piano roll editor
@@ -2284,15 +2284,15 @@
Driver restart required.
Restart driver?
-
+ Treiber-Neustart notwendig. Soll der Treiber nun neu gestartet werden?
&Ok
- &OK
+ &OK
&Cancel
- &Abbrechen
+ &Abbrechen
@@ -2515,7 +2515,7 @@
Audio output details
-
+ Details des Audio Ausgangs
Post-Fader
@@ -2527,7 +2527,7 @@
Track output
- Spur Ausgang
+ Spur Ausgang
Use lash
@@ -2535,35 +2535,35 @@
first step, adjust timing mismatch between controller/keyboard trigger latency and computed bpm
- Zuerst, justiere die Zeitdifferenz zwischen Tastatur-/Controller-Anschlägen und den von Hydrogen errechneten BPM-Werten
+ Zuerst, justiere die Zeitdifferenz zwischen Tastatur-/Controller-Anschlägen und den von Hydrogen errechneten BPM-Werten
Beat counter drift compensation in 1/10 ms
- Takt-Zähler-Kompensation in 1/10 ms
+ Takt-Zähler-Kompensation in 1/10 ms
second step, adjust offset between last controller/keybord trigger and the deferred sequencer startup
- Zweitens, justiere die Zeitdifferenz zwischen letzten Tastatur/Controller Anschlag und dem zeitverzögerten Sequenzer Start.
+ Zweitens, justiere die Zeitdifferenz zwischen letzten Tastatur/Controller Anschlag und dem zeitverzögerten Sequenzer Start.
Beat counter start offset in ms
- Takt-Zähler-Startverzögerung in ms
+ Takt-Zähler-Startverzögerung in ms
create per-instrument outputs
-
+ Ausgänge pro Spur erstellen
Path to the Rubberband command-line utility
-
+ Pfad zum Rubberband Kommondozeilenprogram
Maximum number of bars
-
+ Maximale Anzahl an Takten
&Reopen last used playlist
-
+ &Zuletzt benutzte Playlist wiederherstellen
@@ -2571,21 +2571,21 @@
Unsaved changes left. This changes will be lost.
Are you sure?
- Es sind noch nicht gespeicherte änderungen vorhanden. Diese Änderungen werden verloren gehen.
+ Es sind noch nicht gespeicherte änderungen vorhanden. Diese Änderungen werden verloren gehen.
Sind sie sicher?
&Ok
- &OK
+ &OK
&Cancel
- &Abbrechen
+ &Abbrechen
Close dialog! maybe there is some unsaved work on sample.
Are you sure?
- Schließe Fenster. Möglicherweise sind noch ungespeicherte änderungen an diesen Sampel.
+ Schließe Fenster. Möglicherweise sind noch ungespeicherte änderungen an diesen Sampel.
Sind sie sicher?
@@ -2593,71 +2593,71 @@
SampleEditor_UI
Dialog
- Dialog
+ Dialog
P&lay original sample
- Spie&le Original
+ Spie&le Original
&Apply Changes
- &Anwenden
+ &Anwenden
&Close
- &SchlieĂźen
+ &SchlieĂźen
Adjust sample start frame
- Justiere Sampel-Start
+ Justiere Sample-Start
Adjust sample loop begin frame
- Justieren den Sampel Loop-Anfang
+ Justiere den Sample Loop-Anfang
set processing
- Sampleverarbeitung einstellen
+ Sampleverarbeitung einstellen
forward
- vörwärts
+ vorwärts
reverse
- rückwärts
+ rückwärts
pingpong
- hin und her
+ hin und her
loops
- Wiederholungen
+ Wiederholungen
Adjust sample end & loop end frame
- Justiere Sampel ende & Wiederholungs-Ende
+ Justiere Sample ende & Wiederholungs-Ende
&Play
- S&piele
+ &Abspielen
new sample length:
- Neue Sempellänge:
+ Neue Samplelänge:
fade-out type
- Art der Ausblendung
+ Art der Ausblendung
volume
-
+ Lautstärke
panorama
-
+ Panorama
Sample length to beat:
@@ -2669,155 +2669,155 @@
1/64
- 1/64
+ 1/64
1/32
- 1/32
+ 1/32
1/16
- 1/16
+ 1/16
1/8
- 1/8
+ 1/8
1/4
- 1/4
+ 1/4
1/2
- 1/2
+ 1/2
1
- 1
+ 1
2
- 2
+ 2
3
- 3
+ 3
4
- 4
+ 4
5
- 5
+ 5
6
- 6
+ 6
7
- 7
+ 7
8
- 8
+ 8
9
- 9
+ 9
10
- 10
+ 10
11
- 11
+ 11
12
- 12
+ 12
13
- 13
+ 13
14
- 14
+ 14
15
- 15
+ 15
16
- 16
+ 16
17
- 17
+ 17
18
- 18
+ 18
19
- 19
+ 19
20
- 20
+ 20
21
- 21
+ 21
22
- 22
+ 22
23
- 23
+ 23
24
- 24
+ 24
25
- 25
+ 25
26
- 26
+ 26
27
- 27
+ 27
28
- 28
+ 28
29
- 29
+ 29
30
- 30
+ 30
31
- 31
+ 31
32
- 32
+ 32
Pitch the sample in semitones, cents
@@ -2846,7 +2846,7 @@
0
- 0
+ 0
Start
@@ -2876,7 +2876,7 @@
End
-
+ Ende
"Rubberband Audio Processor" : Change the tempo (sample length) and pitch of audio.
@@ -2973,11 +2973,11 @@
Enable time line edit
-
+ Timeline Editor aktivieren
Pattern %1
-
+ Pattern %1
@@ -3020,11 +3020,11 @@
Cancel
- Abbrechen
+ Abbrechen
Ok
- OK
+ OK
@@ -3103,11 +3103,11 @@
&Ok
- &OK
+ &OK
&Cancel
- &Abbrechen
+ &Abbrechen
@@ -3434,7 +3434,7 @@
Please supply at least a valid name
-
+ Bitte gĂĽltigen Dateinamen angeben!
@@ -3486,15 +3486,15 @@
VirtualPatternDialog_UI
Dialog
- Dialog
+ Dialog
OK
- OK
+ OK
Cancel
- Abbrechen
+ Abbrechen
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/i18n/hydrogen.fr.qm and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/i18n/hydrogen.fr.qm differ
diff -Nru hydrogen-0.9.6~beta1/data/i18n/hydrogen.fr.ts hydrogen-0.9.6~beta2/data/i18n/hydrogen.fr.ts
--- hydrogen-0.9.6~beta1/data/i18n/hydrogen.fr.ts 2011-09-12 11:54:45.000000000 +0000
+++ hydrogen-0.9.6~beta2/data/i18n/hydrogen.fr.ts 2012-05-25 12:19:45.000000000 +0000
@@ -5,7 +5,7 @@
AboutDialog
<b>Project page</b><br>
- <b>Page de projet</b><br>
+ <b>Page du projet</b><br>
About
@@ -25,7 +25,7 @@
Translator:%1Alessandro Cominu
- Traducteur:%1Alessandro Cominu
+ Traducteurs:%1Yan Morin, Olivier Humbert, DYP et Fred Courchesne
@@ -405,7 +405,8 @@
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; color:#ffffff;">consider it more useful to permit linking proprietary applications with the</p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; color:#ffffff;">library. If this is what you want to do, use the GNU Library General</p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; color:#ffffff;">Public License instead of this License.</p></body></html>
-
+ Ne pas traduire la licence
+
@@ -518,7 +519,7 @@
Samplerate: %1
- Taux d'Ă©chantillonage: %1
+ Fréquence: %1 Hz
s
@@ -538,15 +539,15 @@
Sample length:
- Taille d'Ă©chantillon:
+ Durée:
Please do not preview samples which are longer than 10 minutes!
- Merci de ne pas faire des previews sur des Ă©chantillons de plus de 10 minutes !
+ Merci de ne pas faire des previews sur des Ă©chantillons de plus de 10 minutes!
Sample length:
- Taille d'Ă©chantillon:
+ Durée:
@@ -561,7 +562,7 @@
Samplerate:
- Taux d'Ă©chantillonnage:
+ Fréquence:
Size:
@@ -569,7 +570,7 @@
Length:
- Longueur:
+ Durée:
Pla&y samples by clicking
@@ -585,11 +586,11 @@
&Play Sample
- Jouer Ă©chantillon (&P)
+ &Jouer l'Ă©chantillon
&Filename to instrument name
-
+ &Nom de fichier comme nom d'instrument
Open
@@ -601,7 +602,7 @@
&Stop
- &Stop
+ &ArrĂŞter
View hidden folders
@@ -613,21 +614,21 @@
Set automatic velocity
- Régler automatiquement la vélocité
+ Réglage de vélocité auto
Director
Director
- Conducteur
+ Directeur
Director_UI
Dialog
- Dialogue
+ Dialogue
@@ -723,29 +724,29 @@
Export failed!
- Export raté!
+ Échec de l'exportation!
The file %1 exists.
Overwrite the existing file?
- Le fichier %1 existe.
-Remplacer le fichier existant ?
+ Le fichier %1 existe déjà .
+Écraser le fichier existant ?
Export to a single track
-
+ Mode piste unique
Export to seperate tracks
- Exporter en pistes séparées
+ Mode multipistes
Both
-
+ Mode combiné
This version of hydrogen is not able to export songs with tempo changes. If you proceed, the song will be exported without tempo changes.
-
+ Cette version d'Hydrogen n'est pas capable d'exporter des morceaux comportant des changements de tempo. Si vous poursuivez, ce morceau sera exporter sans changement de tempo.
@@ -784,7 +785,8 @@
Samplerate in Hz:
- Taux d'Ă©chantillonnage en Hz:
+ L'ancienne Ă©tiquette "Taux d'Ă©chantillonnage en Hz:" Ă©tait beaucoup trop longue
+ Fréquence:
22050
@@ -808,7 +810,8 @@
SampleDepth in Bit:
- Profondeur d'Ă©chantillonnage en Bit:
+ L'ancienne Ă©tiquette "Profondeur d'Ă©chantillonnage en Bit:" Ă©tait beaucoup trop longue
+ RĂ©solution:
8
@@ -828,7 +831,7 @@
Templates:
- Gabarits:
+ Format:
WAV in CD quality "44,1kHz, 16 bit PCM"
@@ -1068,7 +1071,7 @@
Sound library
- Bibliothèque de sons
+ Bibliothèque
@@ -1118,7 +1121,7 @@
Remove FX
-
+ Retirer l'effet
@@ -1299,7 +1302,7 @@
Hydrogen Ready.
- Hydrogen est prĂŞt.
+ Hydrogen est pret.
&Save
@@ -1343,11 +1346,11 @@
Open &Demo
- Ouvrir une &démo...
+ Ouvrir un &demo
Open &recent
- Ouvrir un fichier rĂ©¢
+ Ouvrir un fichier rĂ©¢...
Save &as...
@@ -1379,7 +1382,7 @@
&Cancel
- Annuler (&C)
+ &Annuler
Unknown audio driver
@@ -1439,7 +1442,7 @@
Song saved.
- &Le morceau a été enregistré.
+ Morceau enregistré.
Unknown error %1
@@ -1471,7 +1474,7 @@
Hydrogen Pattern (*.h2pattern)
- Motif d'hydrogen (*.h2pattern)
+ Motif Hydrogen (*.h2pattern)
Save Pattern as ...
@@ -1511,7 +1514,7 @@
&Clear all
- E&ffacer tout
+ Effacer &tout
&Save library
@@ -1519,15 +1522,15 @@
&Export library
- &Exporter la bibliothèque...
+ &Exporter une bibliothèque...
Playlist &editor
- Navigateur de la liste de lecture...
+ &Navigateur de liste de lecture...
&Import library
- &Importer la bibliothèque...
+ &Importer une bibliothèque...
@@ -1558,7 +1561,7 @@
Director
- Conducteur
+ &Directeur
@@ -1749,7 +1752,7 @@
Loaded Soundlibrary
- Charger la bibliothèque de sons
+ Bibliothèque chargée
Quantize incoming keyboard/midi events = Off
@@ -1789,8 +1792,7 @@
Right click into pattern editor add note-off-note or edit note-length, velocity or pan
- note-off-note ? c'est quoi ?
- Un click droit dans l'éditeur de motif ajoute une note-off-note ou édite la profondeur de note; la vélocité ou le panoramique
+ Un click droit dans l'éditeur de motif ajoute une note off ou édite la profondeur de note, la vélocité ou la balance
@@ -1953,7 +1955,7 @@
Mixer
- Table de mixage
+ Mixage
Show Instrument Rack
@@ -1961,7 +1963,7 @@
Instrument rack
- Liste des instruments
+ Instruments
Pause.
@@ -2045,15 +2047,15 @@
Recalculate Rubberband modified samples if bpm will change
- Recalcule l'échantillon modifié par Rubberband si les bpm changent
+ Recalcule l'échantillon modifié par Rubberband si le bpm change
Recalculate all samples using Rubberband ON
- Recalcule tous les Ă©chantillons qui utilisent Rubberband ON
+ Recalcule tous les Ă©chantillons qui utilisent Rubberband
Recalculate all samples using Rubberband OFF
- Recalcule tous les Ă©chantillons qui utilisent Rubberband OFF
+ Recalcule tous les Ă©chantillons qui n'utilisent pas Rubberband
@@ -2076,7 +2078,7 @@
No Song selected!
- Aucun morceau de sélectionné
+ Aucun morceau n'est sélectionné!
Load Playlist
@@ -2111,8 +2113,9 @@
Do not use a console based Editor
Sorry, but this will not work for the moment.
Aucun éditeur par défaut de régler. Veuillez régler l'éditeur par défaut.
+
N'utiliser pas un Ă©diteur en mode console.
-Désolé, mais un éditeur en mode console ne fonctionne pas présentement.
+Désolé, mais un éditeur en mode console ne fonctionnera pas présentement.
Set your Default Editor
@@ -2120,7 +2123,7 @@
No Script selected!
- Aucun script de sélectionné
+ Aucun script de sélectionné!
Error loading song.
@@ -2152,31 +2155,31 @@
&Playlist
- Liste de lecture (&P)
+ &Liste de lecture
Add song to Play&list
- Ajouter le morceau Ă la &Liste de lecture
+ &Ajouter un morceau Ă la &liste
Add ¤t song to Playlist
- Ajouter &ce morceau Ă la Liste de Lecture
+ Ajouter &ce morceau Ă la liste
&Remove selected song from Playlist
- Enleve&r le morceau sélectionné de la Liste de Lecture
+ &Retirer le morceau sélectionné
&Open Playlist
- &Ouvrir la Liste de Lecture
+ &Ouvrir une liste de lecture
&Save Playlist
- &Sauver la Liste de Lecture
+ Enregi&strer
Save Playlist &as
- S&auver la Liste de Lecture comme
+ Enregistrer so&us...
&Scripts
@@ -2184,19 +2187,19 @@
&Add Script to selected song
- &Ajouter un Script à la chanson sélectionnée
+ &Ajouter un script au morceau sélectionné
&Edit selected Script
- Édit&er le Script sélectionné
+ Édit&er le script sélectionné
&Remove selected Script
- Enleve&r le Script sélectionné
+ &Retirer le script sélectionné
&Create a new Script
- &Créer un nouveau Script
+ &Créer un nouveau script
Rewind
@@ -2228,23 +2231,23 @@
Remove all songs from &Playlist
- Efface tous les morceaux depuis la Liste de Lecture (&P)
+ &Vider la liste de lecture
Playlist Browser
-
+ Navigateur de liste de lecture
No song selected!
-
+ Auncun morceau sélectionné!
Playlist: set song no. %1
-
+ Liste: choisir le morceau #%1
no Script
-
+ Aucun script
@@ -2608,12 +2611,12 @@
&Cancel
- Annuler (&C)
+ &Annuler
Close dialog! maybe there is some unsaved work on sample.
Are you sure?
- Fermeture du dialogue! Peut être y a-t'il du travail non sauvegardé sur l'échantillon.
+ Fermeture de la boite de dialogue! Peut être y a-t'il du travail non sauvegardé sur l'échantillon.
Êtes-vous sûr ?
@@ -2637,11 +2640,11 @@
Adjust sample start frame
-
+ Ajuster le point de départ de l'échantillon
Adjust sample loop begin frame
-
+ Ajuster le début de la boucle de l'échantillon
set processing
@@ -2665,7 +2668,7 @@
Adjust sample end & loop end frame
-
+ Ajuster le point d'arrivé de l'échantillon
&Play
@@ -2702,7 +2705,20 @@
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">more informations about you can find here:</p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.breakfastquay.com/rubberband/ "><span style=" text-decoration: underline; color:#0000ff;">http://www.breakfastquay.com/rubberband/ </span></a></p></body></html>
-
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;">Niveaux de "croustillance" : </p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;"> 0 Ă©quivaut Ă --no-transients --no-lamination --window-long</p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;"> 1 Ă©quivalent Ă --no-transients --no-lamination</p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;"> 2 Ă©quivalent Ă --no-transients</p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;"> 3, Ă©quivalent Ă --bl-transients</p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;"> 4 options de traitement par défaut </p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;"> 5 Ă©quivalent Ă --no-lamination --window-short (peut-ĂŞtre bon pour la batterie) </p>
+<p style="-qt-paragraph-type:empty;margin: 0px;-qt-block-indent:0;text-indent:0px;"></p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;">Vous pouvez trouver plus d'informations ici (en anglais seulement): </p>
+<p style="margin:0px;-qt-block-indent:0;text-indent:0px;"><a href="http://www.breakfastquay.com/rubberband/"><span style="text-decoration: underline; color:#0000ff;">http://www.breakfastquay.com/rubberband/</span></a></p></body></html>
0
@@ -2878,11 +2894,11 @@
Start
-
+ DĂ©part
Loop
-
+ Boucle
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
@@ -2904,15 +2920,15 @@
End
-
+ Fin
"Rubberband Audio Processor" : Change the tempo (sample length) and pitch of audio.
-
+ "Processeur audio Rubberband" : Modifie le tempo et la hauteur de l'Ă©chantillon.
Pitch (Semitone,Cent)
-
+ Hauteur (Demi-ton, Pourcent)
@@ -3109,7 +3125,7 @@
Hydrogen Pattern (*.h2pattern)
- Motif d'hydrogen (*.h2pattern)
+ Motif Hydrogen (*.h2pattern)
Virtual Pattern
@@ -3126,8 +3142,7 @@
The pattern-file exists.
Overwrite the existing pattern?
- Le fichier de motif existe.
-Remplacer le motif existant ?
+ Le fichier de motif existe. Écraser le motif existant ?
&Ok
@@ -3135,7 +3150,7 @@
&Cancel
- Annuler (&C)
+ &Annuler
@@ -3161,7 +3176,7 @@
&Cancel
- Annuler (&C)
+ &Annuler
Form1
@@ -3203,7 +3218,7 @@
Browse
- Naviguer
+ Explorer
Export
@@ -3242,7 +3257,7 @@
Downloading SoundLibrary...
- Téléchargement de la bibliothèque de sons.
+ Téléchargement de la bibliothèque de sons...
Import drumkit
@@ -3321,7 +3336,7 @@
License...
- Licence
+ Licence...
Edit server list
@@ -3366,7 +3381,7 @@
&Cancel
- Annuler (&C)
+ &Annuler
Songs
@@ -3423,7 +3438,7 @@
Save changes made to instruments into sound library
- Enregistrer les changements des instruments dans la bibliothèque de sons
+ Enregistrer les changements appliqués aux instruments dans la bibliothèque de sons
@@ -3502,7 +3517,7 @@
SoundLibraryTree
Sound library
- Bibliothèque de sons
+ Bibliothèque
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/patternEditor/background_rec-new.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/patternEditor/background_rec-new.png differ
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/patternEditor/btn_drum_piano_off.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/patternEditor/btn_drum_piano_off.png differ
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/patternEditor/btn_drum_piano_on.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/patternEditor/btn_drum_piano_on.png differ
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/playerControlPanel/background_Control.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/playerControlPanel/background_Control.png differ
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/playerControlPanel/statusLED_off.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/playerControlPanel/statusLED_off.png differ
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/playerControlPanel/statusLED_on.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/playerControlPanel/statusLED_on.png differ
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/skin_btn_off.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/skin_btn_off.png differ
Binary files /tmp/3DHNB5OL3x/hydrogen-0.9.6~beta1/data/img/gray/skin_btn_over.png and /tmp/iBeviblT_a/hydrogen-0.9.6~beta2/data/img/gray/skin_btn_over.png differ
diff -Nru hydrogen-0.9.6~beta1/data/xsd/drumkit.xsd hydrogen-0.9.6~beta2/data/xsd/drumkit.xsd
--- hydrogen-0.9.6~beta1/data/xsd/drumkit.xsd 2011-07-21 20:13:55.000000000 +0000
+++ hydrogen-0.9.6~beta2/data/xsd/drumkit.xsd 2012-05-25 12:19:45.000000000 +0000
@@ -66,7 +66,7 @@
-
+
diff -Nru hydrogen-0.9.6~beta1/debian/changelog hydrogen-0.9.6~beta2/debian/changelog
--- hydrogen-0.9.6~beta1/debian/changelog 2012-03-16 10:03:35.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/changelog 2012-07-12 22:20:04.000000000 +0000
@@ -1,15 +1,40 @@
-hydrogen (0.9.6~beta1-1ubuntu2) precise; urgency=low
+hydrogen (0.9.6~beta2-1~12.04) precise; urgency=medium
- * No-change rebuild against libarchive12.
+ * Import from debian wheezy.
- -- Martin Pitt Fri, 16 Mar 2012 11:03:35 +0100
+ -- DNS777 Thu, 12 Jul 2012 15:00:00 +0000
-hydrogen (0.9.6~beta1-1ubuntu1) precise; urgency=low
+hydrogen (0.9.6~beta2-1) unstable; urgency=low
- * Replace rsvg with rsvg-convert in debian/rules to prevent FTBFS with
- newer librsvg2-bin (LP: #935170)
+ * Team upload.
+ * New upstream release.
+ * Refresh patches.
+ * Don't install extra/serverTools directory, it is no longer provided.
+ * Fix off-by-one error in JACK MIDI.
+ Thanks to Roland Mas for the patch! (Closes: #661725)
+
+ -- Alessio Treglia Tue, 12 Jun 2012 11:50:06 +0200
+
+hydrogen (0.9.6~beta1-3) unstable; urgency=low
+
+ * Team upload.
+
+ [ Adrian Knoth ]
+ * Add patch to fix FTBFS with gcc-4.7 (Closes: #667203).
+
+ [ Alessio Treglia ]
+ * Update debian/copyright to machine-readable format.
+ * Bump Standards-Version.
+ * Regenerate debian/control.
+
+ -- Alessio Treglia Tue, 08 May 2012 11:28:41 -0700
+
+hydrogen (0.9.6~beta1-2) unstable; urgency=low
+
+ * Replace rsvg with rsvg-convert to convert SVG to PNG image (LP: #935170):
+ - Future versions of librsvg won't provide the 'rsvg' tool anymore.
- -- Alessio Treglia Sat, 18 Feb 2012 16:43:33 +0100
+ -- Alessio Treglia Sat, 18 Feb 2012 17:46:48 +0100
hydrogen (0.9.6~beta1-1) unstable; urgency=low
diff -Nru hydrogen-0.9.6~beta1/debian/control hydrogen-0.9.6~beta2/debian/control
--- hydrogen-0.9.6~beta1/debian/control 2012-02-18 15:44:28.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/control 2012-06-12 09:49:47.000000000 +0000
@@ -1,12 +1,13 @@
Source: hydrogen
Section: sound
Priority: optional
-Maintainer: Ubuntu Developers
-XSBC-Original-Maintainer: Debian Multimedia Maintainers
-Uploaders: Jonas Smedegaard
-Build-Depends: devscripts (>= 2.10.7~),
- cdbs (>= 0.4.73~),
- debhelper (>= 6),
+Maintainer: Debian Multimedia Maintainers
+Uploaders:
+ Jonas Smedegaard
+Build-Depends:
+ cdbs (>= 0.4.70~),
+ devscripts,
+ debhelper,
dh-buildinfo,
cmake,
libqt4-dev,
@@ -26,15 +27,19 @@
libportmidi-dev,
librsvg2-bin,
netpbm
-Standards-Version: 3.9.2
+Standards-Version: 3.9.3
Homepage: http://www.hydrogen-music.org/
Vcs-Git: git://git.debian.org/git/pkg-multimedia/hydrogen.git
Vcs-Browser: http://git.debian.org/?p=pkg-multimedia/hydrogen.git;a=summary
Package: hydrogen
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Recommends: hydrogen-drumkits, rubberband-cli
+Depends:
+ ${misc:Depends},
+ ${shlibs:Depends}
+Recommends:
+ hydrogen-drumkits,
+ rubberband-cli
Description: advanced drum machine/step sequencer
Hydrogen is an advanced drum machine. It's main goal is to bring
professional yet simple and intuitive pattern-based drum programming.
diff -Nru hydrogen-0.9.6~beta1/debian/control.in hydrogen-0.9.6~beta2/debian/control.in
--- hydrogen-0.9.6~beta1/debian/control.in 2012-02-18 15:44:28.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/control.in 2012-05-08 18:22:14.000000000 +0000
@@ -1,19 +1,24 @@
Source: hydrogen
Section: sound
Priority: optional
-Maintainer: Ubuntu Developers
-XSBC-Original-Maintainer: Debian Multimedia Maintainers
-Uploaders: Jonas Smedegaard
-Build-Depends: @cdbs@
-Standards-Version: 3.9.2
+Maintainer: Debian Multimedia Maintainers
+Uploaders:
+ Jonas Smedegaard
+Build-Depends:
+ @cdbs@
+Standards-Version: 3.9.3
Homepage: http://www.hydrogen-music.org/
Vcs-Git: git://git.debian.org/git/pkg-multimedia/hydrogen.git
Vcs-Browser: http://git.debian.org/?p=pkg-multimedia/hydrogen.git;a=summary
Package: hydrogen
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Recommends: hydrogen-drumkits, rubberband-cli
+Depends:
+ ${misc:Depends},
+ ${shlibs:Depends}
+Recommends:
+ hydrogen-drumkits,
+ rubberband-cli
Description: advanced drum machine/step sequencer
Hydrogen is an advanced drum machine. It's main goal is to bring
professional yet simple and intuitive pattern-based drum programming.
diff -Nru hydrogen-0.9.6~beta1/debian/copyright hydrogen-0.9.6~beta2/debian/copyright
--- hydrogen-0.9.6~beta1/debian/copyright 2012-01-27 09:39:22.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/copyright 2012-05-08 18:22:19.000000000 +0000
@@ -1,16 +1,18 @@
-Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=173
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Hydrogen
Upstream-Contact: Alessandro Cominu (Comix)
Source: http://sourceforge.net/projects/hydrogen/
Files: *
-Copyright: 2002-2008, Alessandro Cominu (Comix)
+Copyright:
+ 2002-2008, Alessandro Cominu (Comix)
2002-2008, Jonathan Dempsey
2008, Sebastian Moors
License: GPL-2+
Files: */ladspa.h
-Copyright: 2000-2002, Richard W.E. Furse
+Copyright:
+ 2000-2002, Richard W.E. Furse
2000-2002, Paul Barton-Davis
2000-2002, Stefan Westerfeld
License: LGPL-2.1+
diff -Nru hydrogen-0.9.6~beta1/debian/patches/09_portaudio_v2.patch hydrogen-0.9.6~beta2/debian/patches/09_portaudio_v2.patch
--- hydrogen-0.9.6~beta1/debian/patches/09_portaudio_v2.patch 2012-01-27 01:29:37.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/patches/09_portaudio_v2.patch 2012-06-12 09:35:50.000000000 +0000
@@ -5,7 +5,7 @@
--- hydrogen.orig/src/core/src/IO/PortAudioDriver.h
+++ hydrogen/src/core/src/IO/PortAudioDriver.h
-@@ -28,6 +28,11 @@
+@@ -30,6 +30,11 @@
#ifdef H2CORE_HAVE_PORTAUDIO
diff -Nru hydrogen-0.9.6~beta1/debian/patches/1007_off_by_one_in_jackmidi.patch hydrogen-0.9.6~beta2/debian/patches/1007_off_by_one_in_jackmidi.patch
--- hydrogen-0.9.6~beta1/debian/patches/1007_off_by_one_in_jackmidi.patch 1970-01-01 00:00:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/patches/1007_off_by_one_in_jackmidi.patch 2012-06-12 09:42:54.000000000 +0000
@@ -0,0 +1,39 @@
+Description: Fix off-by-one error in JACK MIDI
+ Fixed bug whereby a MIDI event is only sent when there is another
+ one queued.
+Author: Roland Mas
+Bug-Debian: http://bugs.debian.org/661725
+---
+ src/core/src/IO/jack_midi_driver.cpp | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- hydrogen.orig/src/core/src/IO/jack_midi_driver.cpp
++++ hydrogen/src/core/src/IO/jack_midi_driver.cpp
+@@ -234,11 +234,12 @@ JackMidiDriver::JackMidiRead(jack_nframe
+ if (buffer == NULL)
+ break;
+
+- memcpy(buffer, jack_buffer + (4 * rx_in_pos) + 1, len);
+ t++;
+ rx_in_pos++;
+ if (rx_in_pos >= JACK_MIDI_BUFFER_MAX)
+ rx_in_pos = 0;
++
++ memcpy(buffer, jack_buffer + (4 * rx_in_pos) + 1, len);
+ }
+ unlock();
+ }
+@@ -394,6 +395,13 @@ void JackMidiDriver::handleQueueNote(Not
+ if (vel < 0 || vel > 127)
+ return;
+
++ buffer[0] = 0x80 | channel; /* note off */
++ buffer[1] = key;
++ buffer[2] = 0;
++ buffer[3] = 0;
++
++ JackMidiOutEvent(buffer, 3);
++
+ buffer[0] = 0x90 | channel; /* note on */
+ buffer[1] = key;
+ buffer[2] = vel;
diff -Nru hydrogen-0.9.6~beta1/debian/patches/ftbfs-gcc-4.7.diff hydrogen-0.9.6~beta2/debian/patches/ftbfs-gcc-4.7.diff
--- hydrogen-0.9.6~beta1/debian/patches/ftbfs-gcc-4.7.diff 1970-01-01 00:00:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/patches/ftbfs-gcc-4.7.diff 2012-06-12 09:39:50.000000000 +0000
@@ -0,0 +1,40 @@
+Description: Fix missing #includes to avoid build failures with GCC 4.7
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=667203
+Author: Matthias Klose
+Forwarded: no
+---
+ src/core/src/IO/portmidi_driver.cpp | 1 +
+ src/gui/src/MainForm.cpp | 1 +
+ src/gui/src/SongEditor/SongEditor.cpp | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- hydrogen.orig/src/core/src/IO/portmidi_driver.cpp
++++ hydrogen/src/core/src/IO/portmidi_driver.cpp
+@@ -32,6 +32,7 @@
+ #ifdef WIN32
+ #include
+ #endif
++#include
+
+ #ifdef H2CORE_HAVE_PORTMIDI
+
+--- hydrogen.orig/src/gui/src/SongEditor/SongEditor.cpp
++++ hydrogen/src/gui/src/SongEditor/SongEditor.cpp
+@@ -21,6 +21,7 @@
+ */
+
+ #include
++#include
+ #include
+ #include
+
+--- hydrogen.orig/src/gui/src/MainForm.cpp
++++ hydrogen/src/gui/src/MainForm.cpp
+@@ -20,6 +20,7 @@
+ *
+ */
+
++#include
+ #include
+ #include
+ #include
diff -Nru hydrogen-0.9.6~beta1/debian/patches/series hydrogen-0.9.6~beta2/debian/patches/series
--- hydrogen-0.9.6~beta1/debian/patches/series 2012-01-27 09:15:11.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/patches/series 2012-06-12 09:41:35.000000000 +0000
@@ -2,3 +2,5 @@
1001_rubberband_path.patch
1005_name_shouldnt_repeat_genericname.patch
1006_porttime.patch
+ftbfs-gcc-4.7.diff
+1007_off_by_one_in_jackmidi.patch
diff -Nru hydrogen-0.9.6~beta1/debian/rules hydrogen-0.9.6~beta2/debian/rules
--- hydrogen-0.9.6~beta1/debian/rules 2012-02-18 16:26:51.000000000 +0000
+++ hydrogen-0.9.6~beta2/debian/rules 2012-06-12 10:41:16.000000000 +0000
@@ -34,7 +34,6 @@
export QTDIR=/usr/share/qt4
DEB_INSTALL_MANPAGES_hydrogen = debian/hydrogen.1
-DEB_INSTALL_EXAMPLES_hydrogen = extra/serverTools
# Put aside upstream-shipped autogenerated files during build
upstreamtmpfiles = $(wildcard data/doc/*.html data/doc/*.docbook)
diff -Nru hydrogen-0.9.6~beta1/DEVELOPERS hydrogen-0.9.6~beta2/DEVELOPERS
--- hydrogen-0.9.6~beta1/DEVELOPERS 2011-05-12 18:51:07.000000000 +0000
+++ hydrogen-0.9.6~beta2/DEVELOPERS 2012-05-25 12:19:45.000000000 +0000
@@ -56,15 +56,14 @@
release. Remember, after tagging the release you may not
commit changes to the tag.
- svn cp http://svn.assembla.com/svn/hydrogen/trunk \
- http://svn.assembla.com/svn/hydrogen/tags/0.9.4
+ git tag -a 0.9.4 -m "Tagging 0.9.4"
9. If this is a major release (e.g. 0.9.4), then make a branch for
maintenance patches for your release. If this is a maintenance
release (e.g. 0.9.4.1) then skip this step.
- svn cp http://svn.assembla.com/svn/hydrogen/trunk \
- http://svn.assembla.com/svn/hydrogen/branches/0.9.4
+ git branch 0.9.4
+ git push origin 0.9.4
10. Make announcements.
diff -Nru hydrogen-0.9.6~beta1/INSTALL.txt hydrogen-0.9.6~beta2/INSTALL.txt
--- hydrogen-0.9.6~beta1/INSTALL.txt 2011-07-03 11:21:31.000000000 +0000
+++ hydrogen-0.9.6~beta2/INSTALL.txt 2012-05-25 12:19:45.000000000 +0000
@@ -44,9 +44,9 @@
http://www.hydrogen-music.org/
The source code for the current development version can be checked out
-via Subversion:
+via git:
- $ svn co http://svn.assembla.com/svn/hydrogen/trunk hydrogen
+ $ git clone git://github.com/hydrogen-music/hydrogen.git
3. Binary Packages
------------------
diff -Nru hydrogen-0.9.6~beta1/linux/debian/rules hydrogen-0.9.6~beta2/linux/debian/rules
--- hydrogen-0.9.6~beta1/linux/debian/rules 2011-09-13 20:55:34.000000000 +0000
+++ hydrogen-0.9.6~beta2/linux/debian/rules 2012-05-25 12:19:45.000000000 +0000
@@ -64,8 +64,8 @@
mkdir -p $(CURDIR)/debian/hydrogen/usr/bin
cd ../builddebian; $(MAKE) install
- #remove not used .svn dirs
- find $(CURDIR)/debian/hydrogen/ -name '.svn' | xargs rm -rf
+ #remove not used .git dirs
+ find $(CURDIR)/debian/hydrogen/ -name '.git' | xargs rm -rf
docs:
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/basics/instrument.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/basics/instrument.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/basics/instrument.h 2011-12-06 11:23:10.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/basics/instrument.h 2012-05-25 12:19:45.000000000 +0000
@@ -100,9 +100,10 @@
* load an instrument from an XMLNode
* \param node the XMLDode to read from
* \param dk_path the directory holding the drumkit data
+ * \param dk_name the name of the drumkit
* \return a new Instrument instance
*/
- static Instrument* load_from( XMLNode* node, const QString& dk_path );
+ static Instrument* load_from( XMLNode* node, const QString& dk_path, const QString& dk_name );
/**
* get an instrument layer from the list
@@ -236,9 +237,16 @@
/** get the stop notes of the instrument */
bool is_stop_notes() const;
+ ///< set the name of the related drumkit
+ void set_drumkit_name( const QString& name );
+ ///< get the name of the related drumkits
+ const QString& get_drumkit_name() const;
+
+
private:
int __id; ///< instrument id, should be unique
QString __name; ///< instrument name
+ QString __drumkit_name; ///< the name of the drumkit this instrument belongs tos
float __gain; ///< gain of the instrument
float __volume; ///< volume of the instrument
float __pan_l; ///< left pan of the instrument
@@ -516,8 +524,20 @@
__layers[ idx ] = layer;
}
+inline void Instrument::set_drumkit_name( const QString& name )
+{
+ __drumkit_name = name;
+}
+
+inline const QString& Instrument::get_drumkit_name() const
+{
+ return __drumkit_name;
+}
+
};
+
+
#endif // H2C_INSTRUMENT_H
/* vim: set softtabstop=4 expandtab: */
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/basics/instrument_list.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/basics/instrument_list.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/basics/instrument_list.h 2011-07-08 16:41:38.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/basics/instrument_list.h 2012-05-25 12:19:45.000000000 +0000
@@ -140,7 +140,7 @@
* \param dk_path the directory holding the drumkit data
* \return a new InstrumentList instance
*/
- static InstrumentList* load_from( XMLNode* node, const QString& dk_path );
+ static InstrumentList* load_from( XMLNode* node, const QString& dk_path, const QString& dk_name );
private:
std::vector __instruments; ///< the list of instruments
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/basics/song.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/basics/song.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/basics/song.h 2011-07-08 16:41:38.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/basics/song.h 2012-05-25 12:19:45.000000000 +0000
@@ -139,6 +139,10 @@
const QString& get_license() {
return __license;
}
+
+ const QString& get_author() {
+ return __author;
+ }
const QString& get_filename() {
return __filename;
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/config.h.in hydrogen-0.9.6~beta2/src/core/include/hydrogen/config.h.in
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/config.h.in 2011-07-01 21:09:04.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/config.h.in 2012-05-25 12:19:45.000000000 +0000
@@ -20,7 +20,7 @@
#define H2CORE_VERSION_PATCH @VERSION_PATCH@
#define H2CORE_VERSION "@VERSION@"
#define H2CORE_REVISION "@REVISION@"
-#define H2CORE_VERSION_FULL "@VERSION@-svn-@REVISION@"
+#define H2CORE_VERSION_FULL "@VERSION@-@REVISION@"
#cmakedefine HAVE_SSCANF
#cmakedefine HAVE_RTCLOCK
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/event_queue.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/event_queue.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/event_queue.h 2011-10-21 16:00:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/event_queue.h 2012-05-25 12:19:45.000000000 +0000
@@ -24,6 +24,7 @@
#define EVENT_QUEUE_H
#include
+#include
#include
#define MAX_EVENTS 1024
@@ -46,7 +47,8 @@
EVENT_RECALCULATERUBBERBAND,
EVENT_PROGRESS,
EVENT_JACK_SESSION,
- EVENT_PLAYLIST_LOADSONG
+ EVENT_PLAYLIST_LOADSONG,
+ EVENT_UNDO_REDO
};
@@ -71,6 +73,23 @@
void push_event( EventType type, int nValue );
Event pop_event();
+ struct AddMidiNoteVector
+ {
+ int m_column; //position
+ int m_row; //instrument row
+ int m_pattern; // pattern number
+ int m_length;
+ float f_velocity;
+ float f_pan_L;
+ float f_pan_R;
+ Note::Key nk_noteKeyVal;
+ Note::Octave no_octaveKeyVal;
+ bool b_isMidi;
+ bool b_isInstrumentMode;
+ bool b_noteExist;
+ };
+ std::vector m_addMidiNoteVector;
+
private:
EventQueue();
static EventQueue *__instance;
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/hydrogen.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/hydrogen.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/hydrogen.h 2011-11-04 23:07:04.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/hydrogen.h 2012-05-25 12:19:45.000000000 +0000
@@ -108,15 +108,15 @@
int getPatternPos();
void setPatternPos( int pos );
-
+
void triggerRelocateDuringPlay();
long getTickForPosition( int );
- void restartDrivers();
+ void restartDrivers();
void startExportSong( const QString& filename, int rate, int depth );
- void stopExportSong();
+ void stopExportSong( bool reconnectOldDriver );
AudioOutput* getAudioOutput();
MidiInput* getMidiInput();
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/IO/JackOutput.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/IO/JackOutput.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/IO/JackOutput.h 2011-07-02 20:05:19.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/IO/JackOutput.h 2012-05-25 12:19:45.000000000 +0000
@@ -76,7 +76,6 @@
}
- void setPortName( int nPort, bool bLeftChannel, const QString& sName );
void makeTrackOutputs( Song * );
void setTrackOutput( int, Instrument * );
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/LocalFileMng.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/LocalFileMng.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/LocalFileMng.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/LocalFileMng.h 2012-05-25 12:19:45.000000000 +0000
@@ -58,7 +58,7 @@
std::vector getPatternDirList();
std::vector getSongList();
std::vector getPatternsForDrumkit( const QString& );
- std::vector getAllPatternName();
+ std::vector getAllPatternNames();
int getPatternList( const QString& );
int mergeAllPatternList( std::vector );
diff -Nru hydrogen-0.9.6~beta1/src/core/include/hydrogen/Preferences.h hydrogen-0.9.6~beta2/src/core/include/hydrogen/Preferences.h
--- hydrogen-0.9.6~beta1/src/core/include/hydrogen/Preferences.h 2011-11-04 23:07:04.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/include/hydrogen/Preferences.h 2012-05-25 12:19:45.000000000 +0000
@@ -149,7 +149,7 @@
NO_JACK_TIME_MASTER = 1,
PRE_FADER = 1,
SET_PLAY_OFF = 1,
- BC_OFF = 1,
+ BC_OFF = 1
};
@@ -160,6 +160,7 @@
int m_nDefaultUILayout;
+
QString m_sPreferencesFilename;
QString m_sPreferencesDirectory;
@@ -169,20 +170,12 @@
bool __playselectedinstrument; // midi keys and keys play instrument or drumset
- // __rightclickedpattereditor
- // 0 = note length
- // 1 = note off"
- // 2 = edit velocity
- // 3 = edit pan
- // 4 = edit lead lag
- int __rightclickedpattereditor; //right click into pattern editor add note-off-note or edit note-length
-
int m_nRecPreDelete; //index of record note pre delete function 0 = off
int m_nRecPostDelete;
bool m_bFollowPlayhead;
- bool __usetimeline;
+
// switch to enable / disable lash, only on h2 startup
bool m_brestartLash;
@@ -239,8 +232,7 @@
///Rubberband CLI
QString m_rubberBandCLIexecutable;
- ///rubberband bpm change queue
- bool m_useTheRubberbandBpmChangeEvent;
+
/// Returns an instance of PreferencesMng class
static void create_instance();
static Preferences* get_instance() { assert(__instance); return __instance; }
@@ -586,13 +578,35 @@
jackSessionApplicationPath = path;
}
- bool getJackSessionUseSessionDir(){
- return m_bjackSessionUseSessionDir;
+#endif
+
+ bool getUseTimelineBpm(){
+ return __useTimelineBpm;
}
- void setJackSessionUseSessionDir( bool val ){
- m_bjackSessionUseSessionDir = val;
+ void setUseTimelineBpm( bool val ){
+ __useTimelineBpm = val;
}
-#endif
+
+ int getRubberBandCalcTime(){
+ return __rubberBandCalcTime;
+ }
+ void setRubberBandCalcTime( int val ){
+ __rubberBandCalcTime = val;
+ }
+
+ int getRubberBandBatchMode(){
+ return m_useTheRubberbandBpmChangeEvent;
+ }
+ void setRubberBandBatchMode( int val ){
+ m_useTheRubberbandBpmChangeEvent = val;
+ }
+
+ int getLastOpenTab(){
+ return m_nLastOpenTab;
+ }
+ void setLastOpenTab(int n){
+ m_nLastOpenTab = n;
+ }
private:
static Preferences *__instance;
@@ -604,6 +618,9 @@
QString demoPath;
//___ General properties ___
+ int __rubberBandCalcTime;
+ ///rubberband bpm change queue
+ bool m_useTheRubberbandBpmChangeEvent;
bool m_bPatternModePlaysSelected; /// Behaviour of Pattern Mode
bool m_brestoreLastSong; ///< Restore last song?
bool m_brestoreLastPlaylist;
@@ -627,12 +644,13 @@
#ifdef H2CORE_HAVE_JACKSESSION
QString jackSessionUUID;
QString jackSessionApplicationPath;
- bool m_bjackSessionUseSessionDir;
#endif
bool waitingForSessionHandler;
+ bool __useTimelineBpm;
//___ GUI properties ___
QString m_sQTStyle;
+ int m_nLastOpenTab;
QString applicationFontFamily;
int applicationFontPointSize;
diff -Nru hydrogen-0.9.6~beta1/src/core/src/basics/drumkit.cpp hydrogen-0.9.6~beta2/src/core/src/basics/drumkit.cpp
--- hydrogen-0.9.6~beta1/src/core/src/basics/drumkit.cpp 2011-07-22 07:34:04.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/basics/drumkit.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -90,21 +90,6 @@
}
Drumkit* drumkit = Drumkit::load_from( &root, dk_path.left( dk_path.lastIndexOf( "/" ) ) );
if( load_samples ) drumkit->load_samples();
- /*
- if( load_samples ) {
- InstrumentList* instruments = drumkit->get_instruments();
- for( int i=0; isize(); i++ ) {
- Instrument* instrument = ( *instruments )[i];
- for ( int n = 0; n < MAX_LAYERS; n++ ) {
- InstrumentLayer* layer = instrument->get_layer( n );
- if( layer ) {
- Sample* sample = layer->get_sample();
- if( sample ) sample->load();
- }
- }
- }
- }
- */
return drumkit;
}
@@ -126,9 +111,8 @@
WARNINGLOG( "instrumentList node not found" );
drumkit->set_instruments( new InstrumentList() );
} else {
- drumkit->set_instruments( InstrumentList::load_from( &instruments_node, dk_path ) );
+ drumkit->set_instruments( InstrumentList::load_from( &instruments_node, dk_path, drumkit_name ) );
}
- //if( drumkit->__logger->should_log( Logger::Debug ) ) drumkit->dump();
return drumkit;
}
@@ -341,7 +325,7 @@
TAR* tar_file;
char tar_path[1024];
strncpy( tar_path, gzd_name.toLocal8Bit(), 1024 );
- if ( tar_open( &tar_file, tar_path, NULL, O_RDONLY, 0, TAR_VERBOSE | TAR_GNU ) == -1 ) {
+ if ( tar_open( &tar_file, tar_path, NULL, O_RDONLY, 0, TAR_GNU ) == -1 ) {
_ERRORLOG( QString( "tar_open(): %1" ).arg( QString::fromLocal8Bit( strerror( errno ) ) ) );
return false;
}
diff -Nru hydrogen-0.9.6~beta1/src/core/src/basics/instrument.cpp hydrogen-0.9.6~beta2/src/core/src/basics/instrument.cpp
--- hydrogen-0.9.6~beta1/src/core/src/basics/instrument.cpp 2011-07-08 16:41:38.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/basics/instrument.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -155,8 +155,10 @@
}
if ( is_live )
AudioEngine::get_instance()->lock( RIGHT_HERE );
+
this->set_id( instrument->get_id() );
this->set_name( instrument->get_name() );
+ this->set_drumkit_name( drumkit->get_name() );
this->set_gain( instrument->get_gain() );
this->set_volume( instrument->get_volume() );
this->set_pan_l( instrument->get_pan_l() );
@@ -185,11 +187,12 @@
delete drumkit;
}
-Instrument* Instrument::load_from( XMLNode* node, const QString& dk_path )
+Instrument* Instrument::load_from( XMLNode* node, const QString& dk_path, const QString& dk_name )
{
int id = node->read_int( "id", EMPTY_INSTR_ID, false, false );
if ( id==EMPTY_INSTR_ID ) return 0;
Instrument* instrument = new Instrument( id, node->read_string( "name", "" ), 0 );
+ instrument->set_drumkit_name( dk_name );
instrument->set_volume( node->read_float( "volume", 1.0f ) );
instrument->set_muted( node->read_bool( "isMuted", false ) );
instrument->set_pan_l( node->read_float( "pan_L", 1.0f ) );
diff -Nru hydrogen-0.9.6~beta1/src/core/src/basics/instrument_list.cpp hydrogen-0.9.6~beta2/src/core/src/basics/instrument_list.cpp
--- hydrogen-0.9.6~beta1/src/core/src/basics/instrument_list.cpp 2011-07-08 16:41:38.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/basics/instrument_list.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -63,7 +63,7 @@
}
}
-InstrumentList* InstrumentList::load_from( XMLNode* node, const QString& dk_path )
+InstrumentList* InstrumentList::load_from( XMLNode* node, const QString& dk_path, const QString& dk_name )
{
InstrumentList* instruments = new InstrumentList();
XMLNode instrument_node = node->firstChildElement( "instrument" );
@@ -74,7 +74,7 @@
ERRORLOG( QString( "instrument count >= %2, stop reading instruments" ).arg( MAX_INSTRUMENTS ) );
break;
}
- Instrument* instrument = Instrument::load_from( &instrument_node, dk_path );
+ Instrument* instrument = Instrument::load_from( &instrument_node, dk_path, dk_name );
if( instrument ) {
( *instruments ) << instrument;
} else {
diff -Nru hydrogen-0.9.6~beta1/src/core/src/basics/pattern_list.cpp hydrogen-0.9.6~beta2/src/core/src/basics/pattern_list.cpp
--- hydrogen-0.9.6~beta1/src/core/src/basics/pattern_list.cpp 2011-07-18 21:30:45.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/basics/pattern_list.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -125,8 +125,6 @@
Pattern* PatternList::replace( int idx, Pattern* pattern )
{
- ERRORLOG( QString("idx=%1 and __patterns.size()=%2").arg( idx ).arg( __patterns.size() ) );
-
/*
* if we insert a new pattern (copy, add new pattern, undo delete pattern and so on will do this)
* idx is > __pattern.size(). thats why i add +1 to assert expression
diff -Nru hydrogen-0.9.6~beta1/src/core/src/helpers/filesystem.cpp hydrogen-0.9.6~beta2/src/core/src/helpers/filesystem.cpp
--- hydrogen-0.9.6~beta1/src/core/src/helpers/filesystem.cpp 2011-07-21 20:13:13.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/helpers/filesystem.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -59,7 +59,7 @@
#else
__sys_data_path = QCoreApplication::applicationDirPath().append( "/data" ) ;
#endif
- __usr_data_path = QDir::homePath().append( "/Library/Application Support/Hydrogen" );
+ __usr_data_path = QDir::homePath().append( "/Library/Application Support/Hydrogen/data" );
#elif WIN32
__sys_data_path = QCoreApplication::applicationDirPath().append( "/data" ) ;
__usr_data_path = QCoreApplication::applicationDirPath().append( "/hydrogen/data" ) ;
@@ -208,8 +208,12 @@
return false;
}
if ( !recursive ) {
- ERRORLOG( QString( "unable to remove directory %1 without recursive parameter set to true" ).arg( path ) );
- return false;
+ QDir dir;
+ bool ret = dir.rmdir( path );
+ if( !ret ) {
+ ERRORLOG( QString( "unable to remove dir %1 without recursive argument, maybe it is not empty?" ).arg( path ) );
+ }
+ return ret;
}
return rm_fr( path );
}
@@ -249,12 +253,16 @@
if( !file_readable( click_file() ) ) return false;
if( !file_readable( empty_song() ) ) return false;
if( !file_readable( empty_sample() ) ) return false;
- if( !file_readable( sys_gui_config() ) ) return false;
- if( !file_readable( sys_core_config() ) ) return false;
+
+ //@Jeremy: Please check if those files are obsolote
+ //if( !file_readable( sys_gui_config() ) ) return false;
+ //if( !file_readable( sys_core_config() ) ) return false;
+ //if( !file_readable( pattern_xsd() ) ) return false;
+
if( !dir_readable( sys_drumkits_dir() ) ) return false;
if( !file_readable( drumkit_xsd() ) ) return false;
if( !file_readable( drumkit_pattern_xsd() ) ) return false;
- if( !file_readable( pattern_xsd() ) ) return false;
+
INFOLOG( QString( "system wide data path %1 is usable." ).arg( __sys_data_path ) );
return true;
}
diff -Nru hydrogen-0.9.6~beta1/src/core/src/helpers/legacy.cpp hydrogen-0.9.6~beta2/src/core/src/helpers/legacy.cpp
--- hydrogen-0.9.6~beta1/src/core/src/helpers/legacy.cpp 2011-07-21 20:14:05.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/helpers/legacy.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -125,7 +125,6 @@
}
drumkit->set_instruments( instruments );
}
- //if( drumkit->__logger->should_log( Logger::Debug ) ) drumkit->dump();
return drumkit;
}
diff -Nru hydrogen-0.9.6~beta1/src/core/src/helpers/xml.cpp hydrogen-0.9.6~beta2/src/core/src/helpers/xml.cpp
--- hydrogen-0.9.6~beta1/src/core/src/helpers/xml.cpp 2011-07-22 07:34:04.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/helpers/xml.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -164,8 +164,14 @@
}
QTextStream out( &file );
out << toString().toUtf8();
+ out.flush();
+
+ bool rv = true;
+ if ( !toString().isEmpty() && file.size() == 0 )
+ rv = false;
+
file.close();
- return true;
+ return rv;
};
void XMLDoc::set_root( const QString& node_name, const QString& xmlns )
diff -Nru hydrogen-0.9.6~beta1/src/core/src/hydrogen.cpp hydrogen-0.9.6~beta2/src/core/src/hydrogen.cpp
--- hydrogen-0.9.6~beta1/src/core/src/hydrogen.cpp 2011-11-08 22:10:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/hydrogen.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -119,29 +119,29 @@
AudioOutput *m_pAudioDriver = NULL; ///< Audio output
QMutex mutex_OutputPointer; ///< Mutex for audio output pointer, allows multiple readers
- ///< When locking this AND AudioEngine, always lock AudioEngine first.
+///< When locking this AND AudioEngine, always lock AudioEngine first.
MidiInput *m_pMidiDriver = NULL; ///< MIDI input
MidiOutput *m_pMidiDriverOut = NULL; ///< MIDI output
// overload the the > operator of Note objects for priority_queue
struct compare_pNotes {
-bool operator() (Note* pNote1, Note* pNote2) {
- return (pNote1->get_humanize_delay()
- + pNote1->get_position() * m_pAudioDriver->m_transport.m_nTickSize)
- >
- (pNote2->get_humanize_delay()
- + pNote2->get_position() * m_pAudioDriver->m_transport.m_nTickSize);
-}
+ bool operator() (Note* pNote1, Note* pNote2) {
+ return (pNote1->get_humanize_delay()
+ + pNote1->get_position() * m_pAudioDriver->m_transport.m_nTickSize)
+ >
+ (pNote2->get_humanize_delay()
+ + pNote2->get_position() * m_pAudioDriver->m_transport.m_nTickSize);
+ }
};
- /// Song Note FIFO
+/// Song Note FIFO
std::priority_queue, compare_pNotes > m_songNoteQueue;
std::deque m_midiNoteQueue; ///< Midi Note FIFO
Song *m_pSong; ///< Current song
PatternList* m_pNextPatterns; ///< Next pattern (used only in Pattern mode)
bool m_bAppendNextPattern; ///< Add the next pattern to the list instead
- /// of replace.
+/// of replace.
bool m_bDeleteNextPattern; ///< Delete the next pattern from the list.
@@ -218,96 +218,96 @@
inline timeval currentTime2()
{
- struct timeval now;
- gettimeofday( &now, NULL );
- return now;
+ struct timeval now;
+ gettimeofday( &now, NULL );
+ return now;
}
inline int randomValue( int max )
{
- return rand() % max;
+ return rand() % max;
}
inline float getGaussian( float z )
{
- // gaussian distribution -- dimss
- float x1, x2, w;
- do {
- x1 = 2.0 * ( ( ( float ) rand() ) / RAND_MAX ) - 1.0;
- x2 = 2.0 * ( ( ( float ) rand() ) / RAND_MAX ) - 1.0;
- w = x1 * x1 + x2 * x2;
- } while ( w >= 1.0 );
+ // gaussian distribution -- dimss
+ float x1, x2, w;
+ do {
+ x1 = 2.0 * ( ( ( float ) rand() ) / RAND_MAX ) - 1.0;
+ x2 = 2.0 * ( ( ( float ) rand() ) / RAND_MAX ) - 1.0;
+ w = x1 * x1 + x2 * x2;
+ } while ( w >= 1.0 );
- w = sqrtf( ( -2.0 * logf( w ) ) / w );
- return x1 * w * z + 0.0; // tunable
+ w = sqrtf( ( -2.0 * logf( w ) ) / w );
+ return x1 * w * z + 0.0; // tunable
}
void audioEngine_raiseError( unsigned nErrorCode )
{
- EventQueue::get_instance()->push_event( EVENT_ERROR, nErrorCode );
+ EventQueue::get_instance()->push_event( EVENT_ERROR, nErrorCode );
}
void updateTickSize()
{
- float sampleRate = ( float )m_pAudioDriver->getSampleRate();
- m_pAudioDriver->m_transport.m_nTickSize =
- ( sampleRate * 60.0 / m_pSong->__bpm / m_pSong->__resolution );
+ float sampleRate = ( float )m_pAudioDriver->getSampleRate();
+ m_pAudioDriver->m_transport.m_nTickSize =
+ ( sampleRate * 60.0 / m_pSong->__bpm / m_pSong->__resolution );
}
void audioEngine_init()
{
- ___INFOLOG( "*** Hydrogen audio engine init ***" );
+ ___INFOLOG( "*** Hydrogen audio engine init ***" );
- // check current state
- if ( m_audioEngineState != STATE_UNINITIALIZED ) {
- ___ERRORLOG( "Error the audio engine is not in UNINITIALIZED state" );
- AudioEngine::get_instance()->unlock();
- return;
- }
-
- m_pSong = NULL;
- m_pPlayingPatterns = new PatternList();
- m_pNextPatterns = new PatternList();
- m_nSongPos = -1;
- m_nSelectedPatternNumber = 0;
- m_nSelectedInstrumentNumber = 0;
- m_nPatternTickPosition = 0;
- m_pMetronomeInstrument = NULL;
- m_pAudioDriver = NULL;
-
- m_pMainBuffer_L = NULL;
- m_pMainBuffer_R = NULL;
-
- srand( time( NULL ) );
-
- // Create metronome instrument
- QString sMetronomeFilename = Filesystem::click_file();
- m_pMetronomeInstrument =
- new Instrument( METRONOME_INSTR_ID, "metronome" );
- m_pMetronomeInstrument->set_layer(
- new InstrumentLayer( Sample::load( sMetronomeFilename ) ),
- 0
- );
+ // check current state
+ if ( m_audioEngineState != STATE_UNINITIALIZED ) {
+ ___ERRORLOG( "Error the audio engine is not in UNINITIALIZED state" );
+ AudioEngine::get_instance()->unlock();
+ return;
+ }
+
+ m_pSong = NULL;
+ m_pPlayingPatterns = new PatternList();
+ m_pNextPatterns = new PatternList();
+ m_nSongPos = -1;
+ m_nSelectedPatternNumber = 0;
+ m_nSelectedInstrumentNumber = 0;
+ m_nPatternTickPosition = 0;
+ m_pMetronomeInstrument = NULL;
+ m_pAudioDriver = NULL;
+
+ m_pMainBuffer_L = NULL;
+ m_pMainBuffer_R = NULL;
+
+ srand( time( NULL ) );
+
+ // Create metronome instrument
+ QString sMetronomeFilename = Filesystem::click_file();
+ m_pMetronomeInstrument =
+ new Instrument( METRONOME_INSTR_ID, "metronome" );
+ m_pMetronomeInstrument->set_layer(
+ new InstrumentLayer( Sample::load( sMetronomeFilename ) ),
+ 0
+ );
- // Change the current audio engine state
- m_audioEngineState = STATE_INITIALIZED;
+ // Change the current audio engine state
+ m_audioEngineState = STATE_INITIALIZED;
#ifdef H2CORE_HAVE_LADSPA
- Effects::create_instance();
+ Effects::create_instance();
#endif
- AudioEngine::create_instance();
- Playlist::create_instance();
+ AudioEngine::create_instance();
+ Playlist::create_instance();
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_INITIALIZED );
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_INITIALIZED );
}
@@ -315,45 +315,45 @@
void audioEngine_destroy()
{
- // check current state
- if ( m_audioEngineState != STATE_INITIALIZED ) {
- ___ERRORLOG( "Error the audio engine is not in INITIALIZED state" );
- return;
- }
- AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
-
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- ___INFOLOG( "*** Hydrogen audio engine shutdown ***" );
-
- // delete all copied notes in the song notes queue
- while ( !m_songNoteQueue.empty() ) {
- m_songNoteQueue.top()->get_instrument()->dequeue();
- delete m_songNoteQueue.top();
- m_songNoteQueue.pop();
- }
- // delete all copied notes in the midi notes queue
- for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
- Note *note = m_midiNoteQueue[i];
- delete note;
- note = NULL;
- }
- m_midiNoteQueue.clear();
-
- // change the current audio engine state
- m_audioEngineState = STATE_UNINITIALIZED;
-
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_UNINITIALIZED );
-
- delete m_pPlayingPatterns;
- m_pPlayingPatterns = NULL;
+ // check current state
+ if ( m_audioEngineState != STATE_INITIALIZED ) {
+ ___ERRORLOG( "Error the audio engine is not in INITIALIZED state" );
+ return;
+ }
+ AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ ___INFOLOG( "*** Hydrogen audio engine shutdown ***" );
+
+ // delete all copied notes in the song notes queue
+ while ( !m_songNoteQueue.empty() ) {
+ m_songNoteQueue.top()->get_instrument()->dequeue();
+ delete m_songNoteQueue.top();
+ m_songNoteQueue.pop();
+ }
+ // delete all copied notes in the midi notes queue
+ for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
+ Note *note = m_midiNoteQueue[i];
+ delete note;
+ note = NULL;
+ }
+ m_midiNoteQueue.clear();
+
+ // change the current audio engine state
+ m_audioEngineState = STATE_UNINITIALIZED;
+
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_UNINITIALIZED );
+
+ delete m_pPlayingPatterns;
+ m_pPlayingPatterns = NULL;
- delete m_pNextPatterns;
- m_pNextPatterns = NULL;
+ delete m_pNextPatterns;
+ m_pNextPatterns = NULL;
- delete m_pMetronomeInstrument;
- m_pMetronomeInstrument = NULL;
+ delete m_pMetronomeInstrument;
+ m_pMetronomeInstrument = NULL;
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->unlock();
}
@@ -366,39 +366,39 @@
/// return -2 = Driver connect() error
int audioEngine_start( bool bLockEngine, unsigned nTotalFrames )
{
- if ( bLockEngine ) {
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- }
-
- ___INFOLOG( "[audioEngine_start]" );
-
- // check current state
- if ( m_audioEngineState != STATE_READY ) {
- ___ERRORLOG( "Error the audio engine is not in READY state" );
- if ( bLockEngine ) {
- AudioEngine::get_instance()->unlock();
- }
- return 0; // FIXME!!
- }
-
- m_fMasterPeak_L = 0.0f;
- m_fMasterPeak_R = 0.0f;
- m_pAudioDriver->m_transport.m_nFrames = nTotalFrames; // reset total frames
- m_nSongPos = -1;
- m_nPatternStartTick = -1;
- m_nPatternTickPosition = 0;
-
- // prepare the tickSize for this song
- updateTickSize();
-
- // change the current audio engine state
- m_audioEngineState = STATE_PLAYING;
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PLAYING );
-
- if ( bLockEngine ) {
- AudioEngine::get_instance()->unlock();
- }
- return 0; // per ora restituisco sempre OK
+ if ( bLockEngine ) {
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ }
+
+ ___INFOLOG( "[audioEngine_start]" );
+
+ // check current state
+ if ( m_audioEngineState != STATE_READY ) {
+ ___ERRORLOG( "Error the audio engine is not in READY state" );
+ if ( bLockEngine ) {
+ AudioEngine::get_instance()->unlock();
+ }
+ return 0; // FIXME!!
+ }
+
+ m_fMasterPeak_L = 0.0f;
+ m_fMasterPeak_R = 0.0f;
+ m_pAudioDriver->m_transport.m_nFrames = nTotalFrames; // reset total frames
+ m_nSongPos = -1;
+ m_nPatternStartTick = -1;
+ m_nPatternTickPosition = 0;
+
+ // prepare the tickSize for this song
+ updateTickSize();
+
+ // change the current audio engine state
+ m_audioEngineState = STATE_PLAYING;
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PLAYING );
+
+ if ( bLockEngine ) {
+ AudioEngine::get_instance()->unlock();
+ }
+ return 0; // per ora restituisco sempre OK
}
@@ -406,53 +406,53 @@
/// Stop the audio engine
void audioEngine_stop( bool bLockEngine )
{
- if ( bLockEngine ) {
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- }
- ___INFOLOG( "[audioEngine_stop]" );
-
- // check current state
- if ( m_audioEngineState != STATE_PLAYING ) {
- ___ERRORLOG( "Error the audio engine is not in PLAYING state" );
- if ( bLockEngine ) {
- AudioEngine::get_instance()->unlock();
- }
- return;
- }
-
- // change the current audio engine state
- m_audioEngineState = STATE_READY;
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
-
- m_fMasterPeak_L = 0.0f;
- m_fMasterPeak_R = 0.0f;
-// m_nPatternTickPosition = 0;
- m_nPatternStartTick = -1;
-
- // delete all copied notes in the song notes queue
- while(!m_songNoteQueue.empty()){
- m_songNoteQueue.top()->get_instrument()->dequeue();
- delete m_songNoteQueue.top();
- m_songNoteQueue.pop();
- }
- /* // delete all copied notes in the playing notes queue
- for (unsigned i = 0; i < m_playingNotesQueue.size(); ++i) {
- Note *note = m_playingNotesQueue[i];
- delete note;
- }
- m_playingNotesQueue.clear();
- */
-
- // delete all copied notes in the midi notes queue
- for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
- Note *note = m_midiNoteQueue[i];
- delete note;
- }
- m_midiNoteQueue.clear();
-
- if ( bLockEngine ) {
- AudioEngine::get_instance()->unlock();
- }
+ if ( bLockEngine ) {
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ }
+ ___INFOLOG( "[audioEngine_stop]" );
+
+ // check current state
+ if ( m_audioEngineState != STATE_PLAYING ) {
+ ___ERRORLOG( "Error the audio engine is not in PLAYING state" );
+ if ( bLockEngine ) {
+ AudioEngine::get_instance()->unlock();
+ }
+ return;
+ }
+
+ // change the current audio engine state
+ m_audioEngineState = STATE_READY;
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
+
+ m_fMasterPeak_L = 0.0f;
+ m_fMasterPeak_R = 0.0f;
+ // m_nPatternTickPosition = 0;
+ m_nPatternStartTick = -1;
+
+ // delete all copied notes in the song notes queue
+ while(!m_songNoteQueue.empty()){
+ m_songNoteQueue.top()->get_instrument()->dequeue();
+ delete m_songNoteQueue.top();
+ m_songNoteQueue.pop();
+ }
+ /* // delete all copied notes in the playing notes queue
+ for (unsigned i = 0; i < m_playingNotesQueue.size(); ++i) {
+ Note *note = m_playingNotesQueue[i];
+ delete note;
+ }
+ m_playingNotesQueue.clear();
+ */
+
+ // delete all copied notes in the midi notes queue
+ for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
+ Note *note = m_midiNoteQueue[i];
+ delete note;
+ }
+ m_midiNoteQueue.clear();
+
+ if ( bLockEngine ) {
+ AudioEngine::get_instance()->unlock();
+ }
}
//
@@ -461,233 +461,233 @@
inline void audioEngine_process_checkBPMChanged()
{
- if ( ( m_audioEngineState == STATE_READY ) || ( m_audioEngineState == STATE_PLAYING ) ) {
+ if ( ( m_audioEngineState == STATE_READY ) || ( m_audioEngineState == STATE_PLAYING ) ) {
+
+ float fNewTickSize =
+ m_pAudioDriver->getSampleRate() * 60.0
+ / m_pSong->__bpm
+ / m_pSong->__resolution;
+
+ if ( fNewTickSize != m_pAudioDriver->m_transport.m_nTickSize ) {
+ // cerco di convertire ...
+ float fTickNumber =
+ ( float )m_pAudioDriver->m_transport.m_nFrames
+ / ( float )m_pAudioDriver->m_transport.m_nTickSize;
+
+ m_pAudioDriver->m_transport.m_nTickSize = fNewTickSize;
+
+ if ( m_pAudioDriver->m_transport.m_nTickSize == 0 ) {
+ return;
+ }
+
+ ___WARNINGLOG( "Tempo change: Recomputing ticksize and frame position" );
+ long long nNewFrames = ( long long )( fTickNumber * fNewTickSize );
+ // update frame position
+ m_pAudioDriver->m_transport.m_nFrames = nNewFrames;
- float fNewTickSize =
- m_pAudioDriver->getSampleRate() * 60.0
- / m_pSong->__bpm
- / m_pSong->__resolution;
-
- if ( fNewTickSize != m_pAudioDriver->m_transport.m_nTickSize ) {
- // cerco di convertire ...
- float fTickNumber =
- ( float )m_pAudioDriver->m_transport.m_nFrames
- / ( float )m_pAudioDriver->m_transport.m_nTickSize;
-
- m_pAudioDriver->m_transport.m_nTickSize = fNewTickSize;
-
- if ( m_pAudioDriver->m_transport.m_nTickSize == 0 ) {
- return;
- }
-
- ___WARNINGLOG( "Tempo change: Recomputing ticksize and frame position" );
- long long nNewFrames = ( long long )( fTickNumber * fNewTickSize );
- // update frame position
- m_pAudioDriver->m_transport.m_nFrames = nNewFrames;
-
#ifdef H2CORE_HAVE_JACK
- if ( JackOutput::class_name() == m_pAudioDriver->class_name()
- && m_audioEngineState == STATE_PLAYING ) {
- static_cast< JackOutput* >( m_pAudioDriver )
- ->calculateFrameOffset();
- }
-#endif
- EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
- }
- }
+ if ( JackOutput::class_name() == m_pAudioDriver->class_name()
+ && m_audioEngineState == STATE_PLAYING ) {
+ static_cast< JackOutput* >( m_pAudioDriver )
+ ->calculateFrameOffset();
+ }
+#endif
+ EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
+ }
+ }
}
inline void audioEngine_process_playNotes( unsigned long nframes )
{
- unsigned int framepos;
+ unsigned int framepos;
- if ( m_audioEngineState == STATE_PLAYING ) {
- framepos = m_pAudioDriver->m_transport.m_nFrames;
- } else {
- // use this to support realtime events when not playing
- framepos = m_nRealtimeFrames;
- }
-
- // reading from m_songNoteQueue
- while ( !m_songNoteQueue.empty() ) {
- Note *pNote = m_songNoteQueue.top();
-
- // verifico se la nota rientra in questo ciclo
- unsigned int noteStartInFrames =
- (int)( pNote->get_position() * m_pAudioDriver->m_transport.m_nTickSize );
-
- // if there is a negative Humanize delay, take into account so
- // we don't miss the time slice. ignore positive delay, or we
- // might end the queue processing prematurely based on NoteQueue
- // placement. the sampler handles positive delay.
- if (pNote->get_humanize_delay() < 0) {
- noteStartInFrames += pNote->get_humanize_delay();
- }
-
- // m_nTotalFrames <= NotePos < m_nTotalFrames + bufferSize
- bool isNoteStart = ( ( noteStartInFrames >= framepos )
- && ( noteStartInFrames < ( framepos + nframes ) ) );
- bool isOldNote = noteStartInFrames < framepos;
- if ( isNoteStart || isOldNote ) {
- // Humanize - Velocity parameter
- if ( m_pSong->get_humanize_velocity_value() != 0 ) {
- float random = m_pSong->get_humanize_velocity_value()
- * getGaussian( 0.2 );
- pNote->set_velocity(
- pNote->get_velocity()
- + ( random
- - ( m_pSong->get_humanize_velocity_value() / 2.0 ) )
- );
- if ( pNote->get_velocity() > 1.0 ) {
- pNote->set_velocity( 1.0 );
- } else if ( pNote->get_velocity() < 0.0 ) {
- pNote->set_velocity( 0.0 );
- }
- }
-
- // Random Pitch ;)
- const float fMaxPitchDeviation = 2.0;
- pNote->set_pitch( pNote->get_pitch()
- + ( fMaxPitchDeviation * getGaussian( 0.2 )
- - fMaxPitchDeviation / 2.0 )
- * pNote->get_instrument()->get_random_pitch_factor() );
-
- Instrument * noteInstrument = pNote->get_instrument();
- if ( noteInstrument->is_stop_notes() ){
- Note *pOffNote = new Note( noteInstrument,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- -1,
- 0 );
- pOffNote->set_note_off( true );
- AudioEngine::get_instance()->get_sampler()->note_on( pOffNote );
- }
-
- AudioEngine::get_instance()->get_sampler()->note_on( pNote );
-
- m_songNoteQueue.pop(); // rimuovo la nota dalla lista di note
- pNote->get_instrument()->dequeue();
- // raise noteOn event
- int nInstrument = m_pSong->get_instrument_list()->index( pNote->get_instrument() );
- EventQueue::get_instance()->push_event( EVENT_NOTEON, nInstrument );
- continue;
- } else {
- // this note will not be played
- break;
- }
- }
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ framepos = m_pAudioDriver->m_transport.m_nFrames;
+ } else {
+ // use this to support realtime events when not playing
+ framepos = m_nRealtimeFrames;
+ }
+
+ // reading from m_songNoteQueue
+ while ( !m_songNoteQueue.empty() ) {
+ Note *pNote = m_songNoteQueue.top();
+
+ // verifico se la nota rientra in questo ciclo
+ unsigned int noteStartInFrames =
+ (int)( pNote->get_position() * m_pAudioDriver->m_transport.m_nTickSize );
+
+ // if there is a negative Humanize delay, take into account so
+ // we don't miss the time slice. ignore positive delay, or we
+ // might end the queue processing prematurely based on NoteQueue
+ // placement. the sampler handles positive delay.
+ if (pNote->get_humanize_delay() < 0) {
+ noteStartInFrames += pNote->get_humanize_delay();
+ }
+
+ // m_nTotalFrames <= NotePos < m_nTotalFrames + bufferSize
+ bool isNoteStart = ( ( noteStartInFrames >= framepos )
+ && ( noteStartInFrames < ( framepos + nframes ) ) );
+ bool isOldNote = noteStartInFrames < framepos;
+ if ( isNoteStart || isOldNote ) {
+ // Humanize - Velocity parameter
+ if ( m_pSong->get_humanize_velocity_value() != 0 ) {
+ float random = m_pSong->get_humanize_velocity_value()
+ * getGaussian( 0.2 );
+ pNote->set_velocity(
+ pNote->get_velocity()
+ + ( random
+ - ( m_pSong->get_humanize_velocity_value() / 2.0 ) )
+ );
+ if ( pNote->get_velocity() > 1.0 ) {
+ pNote->set_velocity( 1.0 );
+ } else if ( pNote->get_velocity() < 0.0 ) {
+ pNote->set_velocity( 0.0 );
+ }
+ }
+
+ // Random Pitch ;)
+ const float fMaxPitchDeviation = 2.0;
+ pNote->set_pitch( pNote->get_pitch()
+ + ( fMaxPitchDeviation * getGaussian( 0.2 )
+ - fMaxPitchDeviation / 2.0 )
+ * pNote->get_instrument()->get_random_pitch_factor() );
+
+ Instrument * noteInstrument = pNote->get_instrument();
+ if ( noteInstrument->is_stop_notes() ){
+ Note *pOffNote = new Note( noteInstrument,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ -1,
+ 0 );
+ pOffNote->set_note_off( true );
+ AudioEngine::get_instance()->get_sampler()->note_on( pOffNote );
+ }
+
+ AudioEngine::get_instance()->get_sampler()->note_on( pNote );
+
+ m_songNoteQueue.pop(); // rimuovo la nota dalla lista di note
+ pNote->get_instrument()->dequeue();
+ // raise noteOn event
+ int nInstrument = m_pSong->get_instrument_list()->index( pNote->get_instrument() );
+ EventQueue::get_instance()->push_event( EVENT_NOTEON, nInstrument );
+ continue;
+ } else {
+ // this note will not be played
+ break;
+ }
+ }
}
void audioEngine_seek( long long nFrames, bool bLoopMode )
{
- if ( m_pAudioDriver->m_transport.m_nFrames == nFrames ) {
- return;
- }
-
- if ( nFrames < 0 ) {
- ___ERRORLOG( "nFrames < 0" );
- }
-
- char tmp[200];
- sprintf( tmp, "seek in %lld (old pos = %d)",
- nFrames,
- ( int )m_pAudioDriver->m_transport.m_nFrames );
- ___INFOLOG( tmp );
-
- m_pAudioDriver->m_transport.m_nFrames = nFrames;
-
- int tickNumber_start = ( unsigned )(
- m_pAudioDriver->m_transport.m_nFrames
- / m_pAudioDriver->m_transport.m_nTickSize );
-// sprintf(tmp, "[audioEngine_seek()] tickNumber_start = %d", tickNumber_start);
-// hydrogenInstance->infoLog(tmp);
-
- bool loop = m_pSong->is_loop_enabled();
-
- if ( bLoopMode ) {
- loop = true;
- }
-
- m_nSongPos = findPatternInTick( tickNumber_start, loop, &m_nPatternStartTick );
-// sprintf(tmp, "[audioEngine_seek()] m_nSongPos = %d", m_nSongPos);
-// hydrogenInstance->infoLog(tmp);
+ if ( m_pAudioDriver->m_transport.m_nFrames == nFrames ) {
+ return;
+ }
+
+ if ( nFrames < 0 ) {
+ ___ERRORLOG( "nFrames < 0" );
+ }
+
+ char tmp[200];
+ sprintf( tmp, "seek in %lld (old pos = %d)",
+ nFrames,
+ ( int )m_pAudioDriver->m_transport.m_nFrames );
+ ___INFOLOG( tmp );
+
+ m_pAudioDriver->m_transport.m_nFrames = nFrames;
+
+ int tickNumber_start = ( unsigned )(
+ m_pAudioDriver->m_transport.m_nFrames
+ / m_pAudioDriver->m_transport.m_nTickSize );
+ // sprintf(tmp, "[audioEngine_seek()] tickNumber_start = %d", tickNumber_start);
+ // hydrogenInstance->infoLog(tmp);
+
+ bool loop = m_pSong->is_loop_enabled();
+
+ if ( bLoopMode ) {
+ loop = true;
+ }
+
+ m_nSongPos = findPatternInTick( tickNumber_start, loop, &m_nPatternStartTick );
+ // sprintf(tmp, "[audioEngine_seek()] m_nSongPos = %d", m_nSongPos);
+ // hydrogenInstance->infoLog(tmp);
- audioEngine_clearNoteQueue();
+ audioEngine_clearNoteQueue();
}
inline void audioEngine_process_transport()
{
- if ( ( m_audioEngineState == STATE_READY )
- || ( m_audioEngineState == STATE_PLAYING ) ) {
- m_pAudioDriver->updateTransportInfo();
- unsigned long nNewFrames = m_pAudioDriver->m_transport.m_nFrames;
-
- // ??? audioEngine_seek returns IMMEDIATELY
- // when nNewFrames == m_pAudioDriver->m_transport.m_nFrames ???
- // audioEngine_seek( nNewFrames, true );
-
- switch ( m_pAudioDriver->m_transport.m_status ) {
- case TransportInfo::ROLLING:
-
- if ( m_audioEngineState == STATE_READY ) {
- audioEngine_start( false, nNewFrames ); // no engine lock
- }
-
- if ( m_pSong->__bpm != m_pAudioDriver->m_transport.m_nBPM ) {
- ___INFOLOG(
- QString( "song bpm: (%1) gets transport bpm: (%2)" )
- .arg( m_pSong->__bpm )
- .arg( m_pAudioDriver->m_transport.m_nBPM ) );
-
- m_pSong->__bpm = m_pAudioDriver->m_transport.m_nBPM;
- }
-
- m_nRealtimeFrames = m_pAudioDriver->m_transport.m_nFrames;
- break;
-
-
- case TransportInfo::STOPPED:
- if ( m_audioEngineState == STATE_PLAYING ) {
- audioEngine_stop( false ); // no engine lock
- }
-
- if ( m_pSong->__bpm != m_pAudioDriver->m_transport.m_nBPM ) {
- m_pSong->__bpm = m_pAudioDriver->m_transport.m_nBPM;
- }
-
- // go ahead and increment the realtimeframes by buffersize
- // to support our realtime keyboard and midi event timing
- m_nRealtimeFrames += m_nBufferSize;
- break;
- }
- }
+ if ( ( m_audioEngineState == STATE_READY )
+ || ( m_audioEngineState == STATE_PLAYING ) ) {
+ m_pAudioDriver->updateTransportInfo();
+ unsigned long nNewFrames = m_pAudioDriver->m_transport.m_nFrames;
+
+ // ??? audioEngine_seek returns IMMEDIATELY
+ // when nNewFrames == m_pAudioDriver->m_transport.m_nFrames ???
+ // audioEngine_seek( nNewFrames, true );
+
+ switch ( m_pAudioDriver->m_transport.m_status ) {
+ case TransportInfo::ROLLING:
+
+ if ( m_audioEngineState == STATE_READY ) {
+ audioEngine_start( false, nNewFrames ); // no engine lock
+ }
+
+ if ( m_pSong->__bpm != m_pAudioDriver->m_transport.m_nBPM ) {
+ ___INFOLOG(
+ QString( "song bpm: (%1) gets transport bpm: (%2)" )
+ .arg( m_pSong->__bpm )
+ .arg( m_pAudioDriver->m_transport.m_nBPM ) );
+
+ m_pSong->__bpm = m_pAudioDriver->m_transport.m_nBPM;
+ }
+
+ m_nRealtimeFrames = m_pAudioDriver->m_transport.m_nFrames;
+ break;
+
+
+ case TransportInfo::STOPPED:
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ audioEngine_stop( false ); // no engine lock
+ }
+
+ if ( m_pSong->__bpm != m_pAudioDriver->m_transport.m_nBPM ) {
+ m_pSong->__bpm = m_pAudioDriver->m_transport.m_nBPM;
+ }
+
+ // go ahead and increment the realtimeframes by buffersize
+ // to support our realtime keyboard and midi event timing
+ m_nRealtimeFrames += m_nBufferSize;
+ break;
+ }
+ }
}
void audioEngine_clearNoteQueue()
{
- //___INFOLOG( "clear notes...");
+ //___INFOLOG( "clear notes...");
- // delete all copied notes in the song notes queue
- while (!m_songNoteQueue.empty()) {
- m_songNoteQueue.top()->get_instrument()->dequeue();
- delete m_songNoteQueue.top();
- m_songNoteQueue.pop();
- }
-
- AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
-
- // delete all copied notes in the midi notes queue
- for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
- delete m_midiNoteQueue[i];
- }
- m_midiNoteQueue.clear();
+ // delete all copied notes in the song notes queue
+ while (!m_songNoteQueue.empty()) {
+ m_songNoteQueue.top()->get_instrument()->dequeue();
+ delete m_songNoteQueue.top();
+ m_songNoteQueue.pop();
+ }
+
+ AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
+
+ // delete all copied notes in the midi notes queue
+ for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
+ delete m_midiNoteQueue[i];
+ }
+ m_midiNoteQueue.clear();
}
@@ -696,230 +696,230 @@
/// Clear all audio buffers
inline void audioEngine_process_clearAudioBuffers( uint32_t nFrames )
{
- QMutexLocker mx( &mutex_OutputPointer );
+ QMutexLocker mx( &mutex_OutputPointer );
- // clear main out Left and Right
- if ( m_pAudioDriver ) {
- m_pMainBuffer_L = m_pAudioDriver->getOut_L();
- m_pMainBuffer_R = m_pAudioDriver->getOut_R();
- } else {
- m_pMainBuffer_L = m_pMainBuffer_R = 0;
- }
- if ( m_pMainBuffer_L ) {
- memset( m_pMainBuffer_L, 0, nFrames * sizeof( float ) );
- }
- if ( m_pMainBuffer_R ) {
- memset( m_pMainBuffer_R, 0, nFrames * sizeof( float ) );
- }
+ // clear main out Left and Right
+ if ( m_pAudioDriver ) {
+ m_pMainBuffer_L = m_pAudioDriver->getOut_L();
+ m_pMainBuffer_R = m_pAudioDriver->getOut_R();
+ } else {
+ m_pMainBuffer_L = m_pMainBuffer_R = 0;
+ }
+ if ( m_pMainBuffer_L ) {
+ memset( m_pMainBuffer_L, 0, nFrames * sizeof( float ) );
+ }
+ if ( m_pMainBuffer_R ) {
+ memset( m_pMainBuffer_R, 0, nFrames * sizeof( float ) );
+ }
#ifdef H2CORE_HAVE_JACK
- JackOutput* jo = dynamic_cast(m_pAudioDriver);
- if( jo && jo->has_track_outs() ) {
- float* buf;
- int k;
- for( k=0 ; kgetNumTracks() ; ++k ) {
- buf = jo->getTrackOut_L(k);
- if( buf ) {
- memset( buf, 0, nFrames * sizeof( float ) );
- }
- buf = jo->getTrackOut_R(k);
- if( buf ) {
- memset( buf, 0, nFrames * sizeof( float ) );
- }
- }
- }
+ JackOutput* jo = dynamic_cast(m_pAudioDriver);
+ if( jo && jo->has_track_outs() ) {
+ float* buf;
+ int k;
+ for( k=0 ; kgetNumTracks() ; ++k ) {
+ buf = jo->getTrackOut_L(k);
+ if( buf ) {
+ memset( buf, 0, nFrames * sizeof( float ) );
+ }
+ buf = jo->getTrackOut_R(k);
+ if( buf ) {
+ memset( buf, 0, nFrames * sizeof( float ) );
+ }
+ }
+ }
#endif
- mx.unlock();
+ mx.unlock();
#ifdef H2CORE_HAVE_LADSPA
- if ( m_audioEngineState >= STATE_READY ) {
- Effects* pEffects = Effects::get_instance();
- for ( unsigned i = 0; i < MAX_FX; ++i ) { // clear FX buffers
- LadspaFX* pFX = pEffects->getLadspaFX( i );
- if ( pFX ) {
- assert( pFX->m_pBuffer_L );
- assert( pFX->m_pBuffer_R );
- memset( pFX->m_pBuffer_L, 0, nFrames * sizeof( float ) );
- memset( pFX->m_pBuffer_R, 0, nFrames * sizeof( float ) );
- }
- }
- }
+ if ( m_audioEngineState >= STATE_READY ) {
+ Effects* pEffects = Effects::get_instance();
+ for ( unsigned i = 0; i < MAX_FX; ++i ) { // clear FX buffers
+ LadspaFX* pFX = pEffects->getLadspaFX( i );
+ if ( pFX ) {
+ assert( pFX->m_pBuffer_L );
+ assert( pFX->m_pBuffer_R );
+ memset( pFX->m_pBuffer_L, 0, nFrames * sizeof( float ) );
+ memset( pFX->m_pBuffer_R, 0, nFrames * sizeof( float ) );
+ }
+ }
+ }
#endif
}
/// Main audio processing function. Called by audio drivers.
int audioEngine_process( uint32_t nframes, void* /*arg*/ )
{
- timeval startTimeval = currentTime2();
+ timeval startTimeval = currentTime2();
- audioEngine_process_clearAudioBuffers( nframes );
+ audioEngine_process_clearAudioBuffers( nframes );
- if( m_audioEngineState < STATE_READY) {
- return 0;
- }
-
-
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
- if( m_audioEngineState < STATE_READY) {
- AudioEngine::get_instance()->unlock();
- return 0;
- }
-
- if ( m_nBufferSize != nframes ) {
- ___INFOLOG(
- QString( "Buffer size changed. Old size = %1, new size = %2" )
- .arg( m_nBufferSize )
- .arg( nframes )
- );
- m_nBufferSize = nframes;
- }
-
- // m_pAudioDriver->bpm updates Song->__bpm. (!!(Calls audioEngine_seek))
- audioEngine_process_transport();
- audioEngine_process_checkBPMChanged(); // m_pSong->__bpm decides tick size
-
- bool sendPatternChange = false;
- // always update note queue.. could come from pattern or realtime input
- // (midi, keyboard)
- int res2 = audioEngine_updateNoteQueue( nframes );
- if ( res2 == -1 ) { // end of song
- ___INFOLOG( "End of song received, calling engine_stop()" );
- AudioEngine::get_instance()->unlock();
- m_pAudioDriver->stop();
- m_pAudioDriver->locate( 0 ); // locate 0, reposition from start of the song
-
- if ( ( m_pAudioDriver->class_name() == DiskWriterDriver::class_name() )
- || ( m_pAudioDriver->class_name() == FakeDriver::class_name() ) ) {
- ___INFOLOG( "End of song." );
- return 1; // kill the audio AudioDriver thread
- }
+ if( m_audioEngineState < STATE_READY) {
+ return 0;
+ }
+
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ if( m_audioEngineState < STATE_READY) {
+ AudioEngine::get_instance()->unlock();
+ return 0;
+ }
+
+ if ( m_nBufferSize != nframes ) {
+ ___INFOLOG(
+ QString( "Buffer size changed. Old size = %1, new size = %2" )
+ .arg( m_nBufferSize )
+ .arg( nframes )
+ );
+ m_nBufferSize = nframes;
+ }
+
+ // m_pAudioDriver->bpm updates Song->__bpm. (!!(Calls audioEngine_seek))
+ audioEngine_process_transport();
+ audioEngine_process_checkBPMChanged(); // m_pSong->__bpm decides tick size
+
+ bool sendPatternChange = false;
+ // always update note queue.. could come from pattern or realtime input
+ // (midi, keyboard)
+ int res2 = audioEngine_updateNoteQueue( nframes );
+ if ( res2 == -1 ) { // end of song
+ ___INFOLOG( "End of song received, calling engine_stop()" );
+ AudioEngine::get_instance()->unlock();
+ m_pAudioDriver->stop();
+ m_pAudioDriver->locate( 0 ); // locate 0, reposition from start of the song
+
+ if ( ( m_pAudioDriver->class_name() == DiskWriterDriver::class_name() )
+ || ( m_pAudioDriver->class_name() == FakeDriver::class_name() ) ) {
+ ___INFOLOG( "End of song." );
+ return 1; // kill the audio AudioDriver thread
+ }
#ifdef H2CORE_HAVE_JACK
- else if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
- // Do something clever :-s ... Jakob Lund
- // Mainly to keep sync with Ardour.
- static_cast(m_pAudioDriver)->locateInNCycles( 0 );
- }
-#endif
- return 0;
- } else if ( res2 == 2 ) { // send pattern change
- sendPatternChange = true;
- }
-
- // play all notes
- audioEngine_process_playNotes( nframes );
-
- // SAMPLER
- AudioEngine::get_instance()->get_sampler()->process( nframes, m_pSong );
- float* out_L = AudioEngine::get_instance()->get_sampler()->__main_out_L;
- float* out_R = AudioEngine::get_instance()->get_sampler()->__main_out_R;
- for ( unsigned i = 0; i < nframes; ++i ) {
- m_pMainBuffer_L[ i ] += out_L[ i ];
- m_pMainBuffer_R[ i ] += out_R[ i ];
- }
-
- // SYNTH
- AudioEngine::get_instance()->get_synth()->process( nframes );
- out_L = AudioEngine::get_instance()->get_synth()->m_pOut_L;
- out_R = AudioEngine::get_instance()->get_synth()->m_pOut_R;
- for ( unsigned i = 0; i < nframes; ++i ) {
- m_pMainBuffer_L[ i ] += out_L[ i ];
- m_pMainBuffer_R[ i ] += out_R[ i ];
- }
+ else if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
+ // Do something clever :-s ... Jakob Lund
+ // Mainly to keep sync with Ardour.
+ static_cast(m_pAudioDriver)->locateInNCycles( 0 );
+ }
+#endif
+ return 0;
+ } else if ( res2 == 2 ) { // send pattern change
+ sendPatternChange = true;
+ }
+
+ // play all notes
+ audioEngine_process_playNotes( nframes );
+
+ // SAMPLER
+ AudioEngine::get_instance()->get_sampler()->process( nframes, m_pSong );
+ float* out_L = AudioEngine::get_instance()->get_sampler()->__main_out_L;
+ float* out_R = AudioEngine::get_instance()->get_sampler()->__main_out_R;
+ for ( unsigned i = 0; i < nframes; ++i ) {
+ m_pMainBuffer_L[ i ] += out_L[ i ];
+ m_pMainBuffer_R[ i ] += out_R[ i ];
+ }
+
+ // SYNTH
+ AudioEngine::get_instance()->get_synth()->process( nframes );
+ out_L = AudioEngine::get_instance()->get_synth()->m_pOut_L;
+ out_R = AudioEngine::get_instance()->get_synth()->m_pOut_R;
+ for ( unsigned i = 0; i < nframes; ++i ) {
+ m_pMainBuffer_L[ i ] += out_L[ i ];
+ m_pMainBuffer_R[ i ] += out_R[ i ];
+ }
- timeval renderTime_end = currentTime2();
+ timeval renderTime_end = currentTime2();
- timeval ladspaTime_start = renderTime_end;
+ timeval ladspaTime_start = renderTime_end;
#ifdef H2CORE_HAVE_LADSPA
- // Process LADSPA FX
- if ( m_audioEngineState >= STATE_READY ) {
- for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
- LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX );
- if ( ( pFX ) && ( pFX->isEnabled() ) ) {
- pFX->processFX( nframes );
- float *buf_L = NULL;
- float *buf_R = NULL;
- if ( pFX->getPluginType() == LadspaFX::STEREO_FX ) {
- buf_L = pFX->m_pBuffer_L;
- buf_R = pFX->m_pBuffer_R;
- } else { // MONO FX
- buf_L = pFX->m_pBuffer_L;
- buf_R = buf_L;
- }
- for ( unsigned i = 0; i < nframes; ++i ) {
- m_pMainBuffer_L[ i ] += buf_L[ i ];
- m_pMainBuffer_R[ i ] += buf_R[ i ];
- if ( buf_L[ i ] > m_fFXPeak_L[nFX] )
- m_fFXPeak_L[nFX] = buf_L[ i ];
- if ( buf_R[ i ] > m_fFXPeak_R[nFX] )
- m_fFXPeak_R[nFX] = buf_R[ i ];
- }
- }
- }
- }
-#endif
- timeval ladspaTime_end = currentTime2();
-
- // update master peaks
- float val_L;
- float val_R;
- if ( m_audioEngineState >= STATE_READY ) {
- for ( unsigned i = 0; i < nframes; ++i ) {
- val_L = m_pMainBuffer_L[i];
- val_R = m_pMainBuffer_R[i];
- if ( val_L > m_fMasterPeak_L ) {
- m_fMasterPeak_L = val_L;
- }
- if ( val_R > m_fMasterPeak_R ) {
- m_fMasterPeak_R = val_R;
- }
- }
- }
-
- // update total frames number
- if ( m_audioEngineState == STATE_PLAYING ) {
- m_pAudioDriver->m_transport.m_nFrames += nframes;
- }
-
-// float fRenderTime = (renderTime_end.tv_sec - renderTime_start.tv_sec) * 1000.0 + (renderTime_end.tv_usec - renderTime_start.tv_usec) / 1000.0;
- float fLadspaTime =
- ( ladspaTime_end.tv_sec - ladspaTime_start.tv_sec ) * 1000.0
- + ( ladspaTime_end.tv_usec - ladspaTime_start.tv_usec ) / 1000.0;
-
- timeval finishTimeval = currentTime2();
- m_fProcessTime =
- ( finishTimeval.tv_sec - startTimeval.tv_sec ) * 1000.0
- + ( finishTimeval.tv_usec - startTimeval.tv_usec ) / 1000.0;
+ // Process LADSPA FX
+ if ( m_audioEngineState >= STATE_READY ) {
+ for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
+ LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX );
+ if ( ( pFX ) && ( pFX->isEnabled() ) ) {
+ pFX->processFX( nframes );
+ float *buf_L = NULL;
+ float *buf_R = NULL;
+ if ( pFX->getPluginType() == LadspaFX::STEREO_FX ) {
+ buf_L = pFX->m_pBuffer_L;
+ buf_R = pFX->m_pBuffer_R;
+ } else { // MONO FX
+ buf_L = pFX->m_pBuffer_L;
+ buf_R = buf_L;
+ }
+ for ( unsigned i = 0; i < nframes; ++i ) {
+ m_pMainBuffer_L[ i ] += buf_L[ i ];
+ m_pMainBuffer_R[ i ] += buf_R[ i ];
+ if ( buf_L[ i ] > m_fFXPeak_L[nFX] )
+ m_fFXPeak_L[nFX] = buf_L[ i ];
+ if ( buf_R[ i ] > m_fFXPeak_R[nFX] )
+ m_fFXPeak_R[nFX] = buf_R[ i ];
+ }
+ }
+ }
+ }
+#endif
+ timeval ladspaTime_end = currentTime2();
+
+ // update master peaks
+ float val_L;
+ float val_R;
+ if ( m_audioEngineState >= STATE_READY ) {
+ for ( unsigned i = 0; i < nframes; ++i ) {
+ val_L = m_pMainBuffer_L[i];
+ val_R = m_pMainBuffer_R[i];
+ if ( val_L > m_fMasterPeak_L ) {
+ m_fMasterPeak_L = val_L;
+ }
+ if ( val_R > m_fMasterPeak_R ) {
+ m_fMasterPeak_R = val_R;
+ }
+ }
+ }
+
+ // update total frames number
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ m_pAudioDriver->m_transport.m_nFrames += nframes;
+ }
+
+ // float fRenderTime = (renderTime_end.tv_sec - renderTime_start.tv_sec) * 1000.0 + (renderTime_end.tv_usec - renderTime_start.tv_usec) / 1000.0;
+ float fLadspaTime =
+ ( ladspaTime_end.tv_sec - ladspaTime_start.tv_sec ) * 1000.0
+ + ( ladspaTime_end.tv_usec - ladspaTime_start.tv_usec ) / 1000.0;
+
+ timeval finishTimeval = currentTime2();
+ m_fProcessTime =
+ ( finishTimeval.tv_sec - startTimeval.tv_sec ) * 1000.0
+ + ( finishTimeval.tv_usec - startTimeval.tv_usec ) / 1000.0;
- float sampleRate = ( float )m_pAudioDriver->getSampleRate();
- m_fMaxProcessTime = 1000.0 / ( sampleRate / nframes );
+ float sampleRate = ( float )m_pAudioDriver->getSampleRate();
+ m_fMaxProcessTime = 1000.0 / ( sampleRate / nframes );
#ifdef CONFIG_DEBUG
- if ( m_fProcessTime > m_fMaxProcessTime ) {
- ___WARNINGLOG( "" );
- ___WARNINGLOG( "----XRUN----" );
- ___WARNINGLOG( QString( "XRUN of %1 msec (%2 > %3)" )
+ if ( m_fProcessTime > m_fMaxProcessTime ) {
+ ___WARNINGLOG( "" );
+ ___WARNINGLOG( "----XRUN----" );
+ ___WARNINGLOG( QString( "XRUN of %1 msec (%2 > %3)" )
.arg( ( m_fProcessTime - m_fMaxProcessTime ) )
.arg( m_fProcessTime ).arg( m_fMaxProcessTime ) );
- ___WARNINGLOG( QString( "Ladspa process time = %1" ).arg( fLadspaTime ) );
- ___WARNINGLOG( "------------" );
- ___WARNINGLOG( "" );
- // raise xRun event
- EventQueue::get_instance()->push_event( EVENT_XRUN, -1 );
- }
+ ___WARNINGLOG( QString( "Ladspa process time = %1" ).arg( fLadspaTime ) );
+ ___WARNINGLOG( "------------" );
+ ___WARNINGLOG( "" );
+ // raise xRun event
+ EventQueue::get_instance()->push_event( EVENT_XRUN, -1 );
+ }
#endif
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->unlock();
- if ( sendPatternChange ) {
- EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
- }
+ if ( sendPatternChange ) {
+ EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
+ }
- return 0;
+ return 0;
}
@@ -928,44 +928,44 @@
void audioEngine_setupLadspaFX( unsigned nBufferSize )
{
- //___INFOLOG( "buffersize=" + to_string(nBufferSize) );
+ //___INFOLOG( "buffersize=" + to_string(nBufferSize) );
- if ( m_pSong == NULL ) {
- //___INFOLOG( "m_pSong=NULL" );
- return;
- }
- if ( nBufferSize == 0 ) {
- ___ERRORLOG( "nBufferSize=0" );
- return;
- }
+ if ( m_pSong == NULL ) {
+ //___INFOLOG( "m_pSong=NULL" );
+ return;
+ }
+ if ( nBufferSize == 0 ) {
+ ___ERRORLOG( "nBufferSize=0" );
+ return;
+ }
#ifdef H2CORE_HAVE_LADSPA
- for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
- LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX );
- if ( pFX == NULL ) {
- return;
- }
-
- pFX->deactivate();
-
-// delete[] pFX->m_pBuffer_L;
-// pFX->m_pBuffer_L = NULL;
-// delete[] pFX->m_pBuffer_R;
-// pFX->m_pBuffer_R = NULL;
-// if ( nBufferSize != 0 ) {
- //pFX->m_nBufferSize = nBufferSize;
- //pFX->m_pBuffer_L = new float[ nBufferSize ];
- //pFX->m_pBuffer_R = new float[ nBufferSize ];
-// }
-
- Effects::get_instance()->getLadspaFX( nFX )->connectAudioPorts(
- pFX->m_pBuffer_L,
- pFX->m_pBuffer_R,
- pFX->m_pBuffer_L,
- pFX->m_pBuffer_R
- );
- pFX->activate();
- }
+ for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
+ LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX );
+ if ( pFX == NULL ) {
+ return;
+ }
+
+ pFX->deactivate();
+
+ // delete[] pFX->m_pBuffer_L;
+ // pFX->m_pBuffer_L = NULL;
+ // delete[] pFX->m_pBuffer_R;
+ // pFX->m_pBuffer_R = NULL;
+ // if ( nBufferSize != 0 ) {
+ //pFX->m_nBufferSize = nBufferSize;
+ //pFX->m_pBuffer_L = new float[ nBufferSize ];
+ //pFX->m_pBuffer_R = new float[ nBufferSize ];
+ // }
+
+ Effects::get_instance()->getLadspaFX( nFX )->connectAudioPorts(
+ pFX->m_pBuffer_L,
+ pFX->m_pBuffer_R,
+ pFX->m_pBuffer_L,
+ pFX->m_pBuffer_R
+ );
+ pFX->activate();
+ }
#endif
}
@@ -974,13 +974,13 @@
void audioEngine_renameJackPorts()
{
#ifdef H2CORE_HAVE_JACK
- // renames jack ports
- if ( m_pSong == NULL ) {
- return;
- }
- if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
- static_cast< JackOutput* >( m_pAudioDriver )->makeTrackOutputs( m_pSong );
- }
+ // renames jack ports
+ if ( m_pSong == NULL ) {
+ return;
+ }
+ if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
+ static_cast< JackOutput* >( m_pAudioDriver )->makeTrackOutputs( m_pSong );
+ }
#endif
}
@@ -988,89 +988,89 @@
void audioEngine_setSong( Song *newSong )
{
- ___WARNINGLOG( QString( "Set song: %1" ).arg( newSong->__name ) );
+ ___WARNINGLOG( QString( "Set song: %1" ).arg( newSong->__name ) );
- AudioEngine::get_instance()->lock( RIGHT_HERE );
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
- if ( m_audioEngineState == STATE_PLAYING ) {
- m_pAudioDriver->stop();
- audioEngine_stop( false );
- }
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ m_pAudioDriver->stop();
+ audioEngine_stop( false );
+ }
- // check current state
- if ( m_audioEngineState != STATE_PREPARED ) {
- ___ERRORLOG( "Error the audio engine is not in PREPARED state" );
- }
+ // check current state
+ if ( m_audioEngineState != STATE_PREPARED ) {
+ ___ERRORLOG( "Error the audio engine is not in PREPARED state" );
+ }
- m_pPlayingPatterns->clear();
- m_pNextPatterns->clear();
+ m_pPlayingPatterns->clear();
+ m_pNextPatterns->clear();
- EventQueue::get_instance()->push_event( EVENT_SELECTED_PATTERN_CHANGED, -1 );
- EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
- EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
+ EventQueue::get_instance()->push_event( EVENT_SELECTED_PATTERN_CHANGED, -1 );
+ EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
+ EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
- //sleep( 1 );
+ //sleep( 1 );
- audioEngine_clearNoteQueue();
+ audioEngine_clearNoteQueue();
- assert( m_pSong == NULL );
- m_pSong = newSong;
+ assert( m_pSong == NULL );
+ m_pSong = newSong;
- // setup LADSPA FX
- audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
+ // setup LADSPA FX
+ audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
- // update ticksize
- audioEngine_process_checkBPMChanged();
+ // update ticksize
+ audioEngine_process_checkBPMChanged();
- // find the first pattern and set as current
- if ( m_pSong->get_pattern_list()->size() > 0 ) {
- m_pPlayingPatterns->add( m_pSong->get_pattern_list()->get( 0 ) );
- }
+ // find the first pattern and set as current
+ if ( m_pSong->get_pattern_list()->size() > 0 ) {
+ m_pPlayingPatterns->add( m_pSong->get_pattern_list()->get( 0 ) );
+ }
- audioEngine_renameJackPorts();
+ audioEngine_renameJackPorts();
- m_pAudioDriver->setBpm( m_pSong->__bpm );
+ m_pAudioDriver->setBpm( m_pSong->__bpm );
- // change the current audio engine state
- m_audioEngineState = STATE_READY;
+ // change the current audio engine state
+ m_audioEngineState = STATE_READY;
- m_pAudioDriver->locate( 0 );
+ m_pAudioDriver->locate( 0 );
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->unlock();
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
}
void audioEngine_removeSong()
{
- AudioEngine::get_instance()->lock( RIGHT_HERE );
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
- if ( m_audioEngineState == STATE_PLAYING ) {
- m_pAudioDriver->stop();
- audioEngine_stop( false );
- }
-
- // check current state
- if ( m_audioEngineState != STATE_READY ) {
- ___ERRORLOG( "Error the audio engine is not in READY state" );
- AudioEngine::get_instance()->unlock();
- return;
- }
-
- m_pSong = NULL;
- m_pPlayingPatterns->clear();
- m_pNextPatterns->clear();
-
- audioEngine_clearNoteQueue();
-
- // change the current audio engine state
- m_audioEngineState = STATE_PREPARED;
- AudioEngine::get_instance()->unlock();
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ m_pAudioDriver->stop();
+ audioEngine_stop( false );
+ }
+
+ // check current state
+ if ( m_audioEngineState != STATE_READY ) {
+ ___ERRORLOG( "Error the audio engine is not in READY state" );
+ AudioEngine::get_instance()->unlock();
+ return;
+ }
+
+ m_pSong = NULL;
+ m_pPlayingPatterns->clear();
+ m_pNextPatterns->clear();
+
+ audioEngine_clearNoteQueue();
+
+ // change the current audio engine state
+ m_audioEngineState = STATE_PREPARED;
+ AudioEngine::get_instance()->unlock();
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PREPARED );
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PREPARED );
}
@@ -1078,315 +1078,327 @@
// return 2 = send pattern changed event!!
inline int audioEngine_updateNoteQueue( unsigned nFrames )
{
- static int nLastTick = -1;
- bool bSendPatternChange = false;
- int nMaxTimeHumanize = 2000;
- int nLeadLagFactor = m_pAudioDriver->m_transport.m_nTickSize * 5; // 5 ticks
-
- unsigned int framepos;
- if ( m_audioEngineState == STATE_PLAYING ) {
- framepos = m_pAudioDriver->m_transport.m_nFrames;
- } else {
- // use this to support realtime events when not playing
- framepos = m_nRealtimeFrames;
- }
-
- int tickNumber_start = 0;
-
- // We need to look ahead in the song for notes with negative offsets
- // from LeadLag or Humanize. When starting from the beginning, we prime
- // the note queue with notes between 0 and nFrames plus
- // lookahead. lookahead should be equal or greater than the
- // nLeadLagFactor + nMaxTimeHumanize.
- int lookahead = nLeadLagFactor + nMaxTimeHumanize + 1;
- m_nLookaheadFrames = lookahead;
- if ( framepos == 0
- || ( m_audioEngineState == STATE_PLAYING
- && m_pSong->get_mode() == Song::SONG_MODE
- && m_nSongPos == -1 ) ) {
- tickNumber_start = (int)( framepos
- / m_pAudioDriver->m_transport.m_nTickSize );
- }
- else {
- tickNumber_start = (int)( (framepos + lookahead)
- / m_pAudioDriver->m_transport.m_nTickSize );
- }
- int tickNumber_end = (int)( (framepos + nFrames + lookahead)
- / m_pAudioDriver->m_transport.m_nTickSize );
-
- int tick = tickNumber_start;
-
-// ___WARNINGLOG( "Lookahead: " + to_string( lookahead
-// / m_pAudioDriver->m_transport.m_nTickSize ) );
- // get initial timestamp for first tick
- gettimeofday( &m_currentTickTime, NULL );
-
-
- while ( tick <= tickNumber_end ) {
- if ( tick == nLastTick ) {
- ++tick;
- continue;
- } else {
- nLastTick = tick;
- }
-
-
- // midi events now get put into the m_songNoteQueue as well,
- // based on their timestamp
- while ( m_midiNoteQueue.size() > 0 ) {
- Note *note = m_midiNoteQueue[0];
-
- if ( ( int )note->get_position() <= tick ) {
- // printf ("tick=%d pos=%d\n", tick, note->getPosition());
- m_midiNoteQueue.pop_front();
- note->get_instrument()->enqueue();
- m_songNoteQueue.push( note );
- } else {
- break;
- }
- }
-
- if ( m_audioEngineState != STATE_PLAYING ) {
- // only keep going if we're playing
- continue;
- }
-
-// if ( m_nPatternStartTick == -1 ) { // for debugging pattern mode :s
-// ___WARNINGLOG( "m_nPatternStartTick == -1; tick = "
-// + to_string( tick ) );
-// }
-
-
- // SONG MODE
- bool doErase = m_audioEngineState == STATE_PLAYING
- && Preferences::get_instance()->getRecordEvents()
- && Preferences::get_instance()->getDestructiveRecord()
- && Preferences::get_instance()->m_nRecPreDelete == 0;
- if ( m_pSong->get_mode() == Song::SONG_MODE ) {
- if ( m_pSong->get_pattern_group_vector()->size() == 0 ) {
- // there's no song!!
- ___ERRORLOG( "no patterns in song." );
- m_pAudioDriver->stop();
- return -1;
- }
-
- m_nSongPos = findPatternInTick( tick,
- m_pSong->is_loop_enabled(),
- &m_nPatternStartTick );
- if ( m_nSongSizeInTicks != 0 ) {
- m_nPatternTickPosition = ( tick - m_nPatternStartTick )
- % m_nSongSizeInTicks;
- } else {
- m_nPatternTickPosition = tick - m_nPatternStartTick;
- }
-
-
- if ( m_nPatternTickPosition == 0 ) {
- bSendPatternChange = true;
- }
-
-// PatternList *pPatternList =
-// (*(m_pSong->getPatternGroupVector()))[m_nSongPos];
- if ( m_nSongPos == -1 ) {
- ___INFOLOG( "song pos = -1" );
- if ( m_pSong->is_loop_enabled() == true ) {
- m_nSongPos = findPatternInTick( 0,
- true,
- &m_nPatternStartTick );
- } else {
-
- ___INFOLOG( "End of Song" );
-
- if( Hydrogen::get_instance()->getMidiOutput() != NULL ){
- Hydrogen::get_instance()->getMidiOutput()->handleQueueAllNoteOff();
- }
-
- return -1;
- }
- }
- PatternList *pPatternList = ( *( m_pSong->get_pattern_group_vector() ) )[m_nSongPos];
- m_pPlayingPatterns->clear();
- for ( int i=0; i< pPatternList->size(); ++i ) {
- Pattern* pattern = pPatternList->get(i);
- m_pPlayingPatterns->add( pattern );
- pattern->extand_with_flattened_virtual_patterns( m_pPlayingPatterns );
- }
- // Set destructive record depending on punch area
- doErase = doErase && Preferences::get_instance()->inPunchArea(m_nSongPos);
- }
- // PATTERN MODE
- else if ( m_pSong->get_mode() == Song::PATTERN_MODE ) {
- // per ora considero solo il primo pattern, se ce ne
- // saranno piu' di uno bisognera' prendere quello piu'
- // piccolo
-
- //m_nPatternTickPosition = tick % m_pCurrentPattern->getSize();
- int nPatternSize = MAX_NOTES;
-
-
- if ( Preferences::get_instance()->patternModePlaysSelected() )
- {
- m_pPlayingPatterns->clear();
- Pattern * pattern = m_pSong->get_pattern_list()->get(m_nSelectedPatternNumber);
- m_pPlayingPatterns->add( pattern );
- pattern->extand_with_flattened_virtual_patterns( m_pPlayingPatterns );
- }
-
-
- if ( m_pPlayingPatterns->size() != 0 ) {
- Pattern *pFirstPattern = m_pPlayingPatterns->get( 0 );
- nPatternSize = pFirstPattern->get_length();
- }
-
- if ( nPatternSize == 0 ) {
- ___ERRORLOG( "nPatternSize == 0" );
- }
-
- if ( ( tick == m_nPatternStartTick + nPatternSize )
- || ( m_nPatternStartTick == -1 ) ) {
- if ( m_pNextPatterns->size() > 0 ) {
- Pattern * p;
- for ( uint i = 0;
- i < m_pNextPatterns->size();
- i++ ) {
- p = m_pNextPatterns->get( i );
-// ___WARNINGLOG( QString( "Got pattern # %1" )
-// .arg( i + 1 ) );
- // if the pattern isn't playing
- // already, start it now.
- if ( ( m_pPlayingPatterns->del( p ) ) == NULL ) {
- m_pPlayingPatterns->add( p );
- }
- }
- m_pNextPatterns->clear();
- bSendPatternChange = true;
- }
- if ( m_nPatternStartTick == -1 ) {
- m_nPatternStartTick = tick - (tick % nPatternSize);
-// ___WARNINGLOG( "set Pattern Start Tick to "
-// + to_string( m_nPatternStartTick ) );
- } else {
- m_nPatternStartTick = tick;
- }
- }
- m_nPatternTickPosition = tick - m_nPatternStartTick;
- if ( m_nPatternTickPosition > nPatternSize ) {
- m_nPatternTickPosition = tick % nPatternSize;
- }
- }
-
- // metronome
-// if ( ( m_nPatternStartTick == tick )
-// || ( ( tick - m_nPatternStartTick ) % 48 == 0 ) ) {
- if ( m_nPatternTickPosition % 48 == 0 ) {
- float fPitch;
- float fVelocity;
-// ___INFOLOG( "Beat: " + to_string(m_nPatternTickPosition / 48 + 1)
-// + "@ " + to_string( tick ) );
- if ( m_nPatternTickPosition == 0 ) {
- fPitch = 3;
- fVelocity = 1.0;
- EventQueue::get_instance()->push_event( EVENT_METRONOME, 1 );
- } else {
- fPitch = 0;
- fVelocity = 0.8;
- EventQueue::get_instance()->push_event( EVENT_METRONOME, 0 );
- }
- if ( Preferences::get_instance()->m_bUseMetronome ) {
- m_pMetronomeInstrument->set_volume(
- Preferences::get_instance()->m_fMetronomeVolume
- );
- Note *pMetronomeNote = new Note( m_pMetronomeInstrument,
- tick,
- fVelocity,
- 0.5,
- 0.5,
- -1,
- fPitch
- );
- m_pMetronomeInstrument->enqueue();
- m_songNoteQueue.push( pMetronomeNote );
- }
- }
-
- // update the notes queue
- if ( m_pPlayingPatterns->size() != 0 ) {
- for ( unsigned nPat = 0 ;
- nPat < m_pPlayingPatterns->size() ;
- ++nPat ) {
- Pattern *pPattern = m_pPlayingPatterns->get( nPat );
- assert( pPattern != NULL );
- Pattern::notes_t* notes = (Pattern::notes_t*)pPattern->get_notes();
- // Delete notes before attempting to play them
- if ( doErase ) {
- FOREACH_NOTE_IT_BOUND(notes,it,m_nPatternTickPosition) {
- Note* pNote = it->second;
- assert( pNote != NULL );
- if ( pNote->get_just_recorded() == false ) {
- delete pNote;
- notes->erase( it );
- }
- }
- }
-
- // Now play notes
- FOREACH_NOTE_CST_IT_BOUND(notes,it,m_nPatternTickPosition) {
- Note *pNote = it->second;
- if ( pNote ) {
- pNote->set_just_recorded( false );
- int nOffset = 0;
-
- // Swing
- float fSwingFactor = m_pSong->get_swing_factor();
-
- if ( ( ( m_nPatternTickPosition % 12 ) == 0 )
- && ( ( m_nPatternTickPosition % 24 ) != 0 ) ) {
- // da l'accento al tick 4, 12, 20, 36...
- nOffset += ( int )(
- 6.0
- * m_pAudioDriver->m_transport.m_nTickSize
- * fSwingFactor
- );
- }
-
- // Humanize - Time parameter
- if ( m_pSong->get_humanize_time_value() != 0 ) {
- nOffset += ( int )(
- getGaussian( 0.3 )
- * m_pSong->get_humanize_time_value()
- * nMaxTimeHumanize
- );
- }
- //~
- // Lead or Lag - timing parameter
- nOffset += (int) ( pNote->get_lead_lag()
- * nLeadLagFactor);
- //~
-
- if((tick == 0) && (nOffset < 0)) {
- nOffset = 0;
- }
- Note *pCopiedNote = new Note( pNote );
- pCopiedNote->set_position( tick );
-
- // humanize time
- pCopiedNote->set_humanize_delay( nOffset );
- pNote->get_instrument()->enqueue();
- m_songNoteQueue.push( pCopiedNote );
- //pCopiedNote->dumpInfo();
- }
- }
- }
- }
- ++tick;
- }
-
-
- // audioEngine_process must send the pattern change event after mutex unlock
- if ( bSendPatternChange ) {
- return 2;
- }
- return 0;
+ static int nLastTick = -1;
+ bool bSendPatternChange = false;
+ int nMaxTimeHumanize = 2000;
+ int nLeadLagFactor = m_pAudioDriver->m_transport.m_nTickSize * 5; // 5 ticks
+
+ unsigned int framepos;
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ framepos = m_pAudioDriver->m_transport.m_nFrames;
+ } else {
+ // use this to support realtime events when not playing
+ framepos = m_nRealtimeFrames;
+ }
+
+ int tickNumber_start = 0;
+
+ // We need to look ahead in the song for notes with negative offsets
+ // from LeadLag or Humanize. When starting from the beginning, we prime
+ // the note queue with notes between 0 and nFrames plus
+ // lookahead. lookahead should be equal or greater than the
+ // nLeadLagFactor + nMaxTimeHumanize.
+ int lookahead = nLeadLagFactor + nMaxTimeHumanize + 1;
+ m_nLookaheadFrames = lookahead;
+ if ( framepos == 0
+ || ( m_audioEngineState == STATE_PLAYING
+ && m_pSong->get_mode() == Song::SONG_MODE
+ && m_nSongPos == -1 ) ) {
+ tickNumber_start = (int)( framepos
+ / m_pAudioDriver->m_transport.m_nTickSize );
+ }
+ else {
+ tickNumber_start = (int)( (framepos + lookahead)
+ / m_pAudioDriver->m_transport.m_nTickSize );
+ }
+ int tickNumber_end = (int)( (framepos + nFrames + lookahead)
+ / m_pAudioDriver->m_transport.m_nTickSize );
+
+ int tick = tickNumber_start;
+
+ // ___WARNINGLOG( "Lookahead: " + to_string( lookahead
+ // / m_pAudioDriver->m_transport.m_nTickSize ) );
+ // get initial timestamp for first tick
+ gettimeofday( &m_currentTickTime, NULL );
+
+
+ while ( tick <= tickNumber_end ) {
+ if ( tick == nLastTick ) {
+ ++tick;
+ continue;
+ } else {
+ nLastTick = tick;
+ }
+
+
+ // midi events now get put into the m_songNoteQueue as well,
+ // based on their timestamp
+ while ( m_midiNoteQueue.size() > 0 ) {
+ Note *note = m_midiNoteQueue[0];
+
+ if ( ( int )note->get_position() <= tick ) {
+ // printf ("tick=%d pos=%d\n", tick, note->getPosition());
+ m_midiNoteQueue.pop_front();
+ note->get_instrument()->enqueue();
+ m_songNoteQueue.push( note );
+ } else {
+ break;
+ }
+ }
+
+ if ( m_audioEngineState != STATE_PLAYING ) {
+ // only keep going if we're playing
+ continue;
+ }
+
+ // if ( m_nPatternStartTick == -1 ) { // for debugging pattern mode :s
+ // ___WARNINGLOG( "m_nPatternStartTick == -1; tick = "
+ // + to_string( tick ) );
+ // }
+
+
+ // SONG MODE
+ bool doErase = m_audioEngineState == STATE_PLAYING
+ && Preferences::get_instance()->getRecordEvents()
+ && Preferences::get_instance()->getDestructiveRecord()
+ && Preferences::get_instance()->m_nRecPreDelete == 0;
+ if ( m_pSong->get_mode() == Song::SONG_MODE ) {
+ if ( m_pSong->get_pattern_group_vector()->size() == 0 ) {
+ // there's no song!!
+ ___ERRORLOG( "no patterns in song." );
+ m_pAudioDriver->stop();
+ return -1;
+ }
+
+ m_nSongPos = findPatternInTick( tick,
+ m_pSong->is_loop_enabled(),
+ &m_nPatternStartTick );
+ if ( m_nSongSizeInTicks != 0 ) {
+ m_nPatternTickPosition = ( tick - m_nPatternStartTick )
+ % m_nSongSizeInTicks;
+ } else {
+ m_nPatternTickPosition = tick - m_nPatternStartTick;
+ }
+
+
+ if ( m_nPatternTickPosition == 0 ) {
+ bSendPatternChange = true;
+ }
+
+ // PatternList *pPatternList =
+ // (*(m_pSong->getPatternGroupVector()))[m_nSongPos];
+ if ( m_nSongPos == -1 ) {
+ ___INFOLOG( "song pos = -1" );
+ if ( m_pSong->is_loop_enabled() == true ) {
+ m_nSongPos = findPatternInTick( 0,
+ true,
+ &m_nPatternStartTick );
+ } else {
+
+ ___INFOLOG( "End of Song" );
+
+ if( Hydrogen::get_instance()->getMidiOutput() != NULL ){
+ Hydrogen::get_instance()->getMidiOutput()->handleQueueAllNoteOff();
+ }
+
+ return -1;
+ }
+ }
+ PatternList *pPatternList = ( *( m_pSong->get_pattern_group_vector() ) )[m_nSongPos];
+ m_pPlayingPatterns->clear();
+ for ( int i=0; i< pPatternList->size(); ++i ) {
+ Pattern* pattern = pPatternList->get(i);
+ m_pPlayingPatterns->add( pattern );
+ pattern->extand_with_flattened_virtual_patterns( m_pPlayingPatterns );
+ }
+ // Set destructive record depending on punch area
+ doErase = doErase && Preferences::get_instance()->inPunchArea(m_nSongPos);
+ }
+ // PATTERN MODE
+ else if ( m_pSong->get_mode() == Song::PATTERN_MODE ) {
+ // per ora considero solo il primo pattern, se ce ne
+ // saranno piu' di uno bisognera' prendere quello piu'
+ // piccolo
+
+ //m_nPatternTickPosition = tick % m_pCurrentPattern->getSize();
+ int nPatternSize = MAX_NOTES;
+
+
+ if ( Preferences::get_instance()->patternModePlaysSelected() )
+ {
+ m_pPlayingPatterns->clear();
+ Pattern * pattern = m_pSong->get_pattern_list()->get(m_nSelectedPatternNumber);
+ m_pPlayingPatterns->add( pattern );
+ pattern->extand_with_flattened_virtual_patterns( m_pPlayingPatterns );
+ }
+
+
+ if ( m_pPlayingPatterns->size() != 0 ) {
+ Pattern *pFirstPattern = m_pPlayingPatterns->get( 0 );
+ nPatternSize = pFirstPattern->get_length();
+ }
+
+ if ( nPatternSize == 0 ) {
+ ___ERRORLOG( "nPatternSize == 0" );
+ }
+
+ if ( ( tick == m_nPatternStartTick + nPatternSize )
+ || ( m_nPatternStartTick == -1 ) ) {
+ if ( m_pNextPatterns->size() > 0 ) {
+ Pattern * p;
+ for ( uint i = 0;
+ i < m_pNextPatterns->size();
+ i++ ) {
+ p = m_pNextPatterns->get( i );
+ // ___WARNINGLOG( QString( "Got pattern # %1" )
+ // .arg( i + 1 ) );
+ // if the pattern isn't playing
+ // already, start it now.
+ if ( ( m_pPlayingPatterns->del( p ) ) == NULL ) {
+ m_pPlayingPatterns->add( p );
+ }
+ }
+ m_pNextPatterns->clear();
+ bSendPatternChange = true;
+ }
+ if ( m_nPatternStartTick == -1 ) {
+ m_nPatternStartTick = tick - (tick % nPatternSize);
+ // ___WARNINGLOG( "set Pattern Start Tick to "
+ // + to_string( m_nPatternStartTick ) );
+ } else {
+ m_nPatternStartTick = tick;
+ }
+ }
+ m_nPatternTickPosition = tick - m_nPatternStartTick;
+ if ( m_nPatternTickPosition > nPatternSize ) {
+ m_nPatternTickPosition = tick % nPatternSize;
+ }
+ }
+
+ // metronome
+ // if ( ( m_nPatternStartTick == tick )
+ // || ( ( tick - m_nPatternStartTick ) % 48 == 0 ) ) {
+ if ( m_nPatternTickPosition % 48 == 0 ) {
+ float fPitch;
+ float fVelocity;
+ // ___INFOLOG( "Beat: " + to_string(m_nPatternTickPosition / 48 + 1)
+ // + "@ " + to_string( tick ) );
+ if ( m_nPatternTickPosition == 0 ) {
+ fPitch = 3;
+ fVelocity = 1.0;
+ EventQueue::get_instance()->push_event( EVENT_METRONOME, 1 );
+ } else {
+ fPitch = 0;
+ fVelocity = 0.8;
+ EventQueue::get_instance()->push_event( EVENT_METRONOME, 0 );
+ }
+ if ( Preferences::get_instance()->m_bUseMetronome ) {
+ m_pMetronomeInstrument->set_volume(
+ Preferences::get_instance()->m_fMetronomeVolume
+ );
+ Note *pMetronomeNote = new Note( m_pMetronomeInstrument,
+ tick,
+ fVelocity,
+ 0.5,
+ 0.5,
+ -1,
+ fPitch
+ );
+ m_pMetronomeInstrument->enqueue();
+ m_songNoteQueue.push( pMetronomeNote );
+ }
+ }
+
+ // update the notes queue
+ if ( m_pPlayingPatterns->size() != 0 ) {
+ for ( unsigned nPat = 0 ;
+ nPat < m_pPlayingPatterns->size() ;
+ ++nPat ) {
+ Pattern *pPattern = m_pPlayingPatterns->get( nPat );
+ assert( pPattern != NULL );
+ Pattern::notes_t* notes = (Pattern::notes_t*)pPattern->get_notes();
+ // Delete notes before attempting to play them
+ if ( doErase ) {
+ FOREACH_NOTE_IT_BOUND(notes,it,m_nPatternTickPosition) {
+ Note* pNote = it->second;
+ assert( pNote != NULL );
+ if ( pNote->get_just_recorded() == false ) {
+ EventQueue::AddMidiNoteVector noteAction;
+ noteAction.m_column = pNote->get_position();
+ noteAction.m_row = pNote->get_instrument_id();
+ noteAction.m_pattern = nPat;
+ noteAction.f_velocity = pNote->get_velocity();
+ noteAction.f_pan_L = pNote->get_pan_l();
+ noteAction.f_pan_R = pNote->get_pan_r();
+ noteAction.m_length = -1;
+ noteAction.no_octaveKeyVal = pNote->get_octave();
+ noteAction.nk_noteKeyVal = pNote->get_key();
+ noteAction.b_isInstrumentMode = false;
+ noteAction.b_isMidi = false;
+ noteAction.b_noteExist = false;
+ EventQueue::get_instance()->m_addMidiNoteVector.push_back(noteAction);
+ }
+ }
+ }
+
+ // Now play notes
+ FOREACH_NOTE_CST_IT_BOUND(notes,it,m_nPatternTickPosition) {
+ Note *pNote = it->second;
+ if ( pNote ) {
+ pNote->set_just_recorded( false );
+ int nOffset = 0;
+
+ // Swing
+ float fSwingFactor = m_pSong->get_swing_factor();
+
+ if ( ( ( m_nPatternTickPosition % 12 ) == 0 )
+ && ( ( m_nPatternTickPosition % 24 ) != 0 ) ) {
+ // da l'accento al tick 4, 12, 20, 36...
+ nOffset += ( int )(
+ 6.0
+ * m_pAudioDriver->m_transport.m_nTickSize
+ * fSwingFactor
+ );
+ }
+
+ // Humanize - Time parameter
+ if ( m_pSong->get_humanize_time_value() != 0 ) {
+ nOffset += ( int )(
+ getGaussian( 0.3 )
+ * m_pSong->get_humanize_time_value()
+ * nMaxTimeHumanize
+ );
+ }
+ //~
+ // Lead or Lag - timing parameter
+ nOffset += (int) ( pNote->get_lead_lag()
+ * nLeadLagFactor);
+ //~
+
+ if((tick == 0) && (nOffset < 0)) {
+ nOffset = 0;
+ }
+ Note *pCopiedNote = new Note( pNote );
+ pCopiedNote->set_position( tick );
+
+ // humanize time
+ pCopiedNote->set_humanize_delay( nOffset );
+ pNote->get_instrument()->enqueue();
+ m_songNoteQueue.push( pCopiedNote );
+ //pCopiedNote->dumpInfo();
+ }
+ }
+ }
+ }
+ ++tick;
+ }
+
+
+ // audioEngine_process must send the pattern change event after mutex unlock
+ if ( bSendPatternChange ) {
+ return 2;
+ }
+ return 0;
}
@@ -1394,101 +1406,101 @@
/// restituisce l'indice relativo al patternGroup in base al tick
inline int findPatternInTick( int nTick, bool bLoopMode, int *pPatternStartTick )
{
- assert( m_pSong );
+ assert( m_pSong );
- int nTotalTick = 0;
- m_nSongSizeInTicks = 0;
+ int nTotalTick = 0;
+ m_nSongSizeInTicks = 0;
- std::vector *pPatternColumns = m_pSong->get_pattern_group_vector();
- int nColumns = pPatternColumns->size();
+ std::vector *pPatternColumns = m_pSong->get_pattern_group_vector();
+ int nColumns = pPatternColumns->size();
- int nPatternSize;
- for ( int i = 0; i < nColumns; ++i ) {
- PatternList *pColumn = ( *pPatternColumns )[ i ];
- if ( pColumn->size() != 0 ) {
- // tengo in considerazione solo il primo pattern. I
- // pattern nel gruppo devono avere la stessa lunghezza.
- nPatternSize = pColumn->get( 0 )->get_length();
- } else {
- nPatternSize = MAX_NOTES;
- }
-
- if ( ( nTick >= nTotalTick ) && ( nTick < nTotalTick + nPatternSize ) ) {
- ( *pPatternStartTick ) = nTotalTick;
- return i;
- }
- nTotalTick += nPatternSize;
- }
-
- if ( bLoopMode ) {
- m_nSongSizeInTicks = nTotalTick;
- int nLoopTick = 0;
- if ( m_nSongSizeInTicks != 0 ) {
- nLoopTick = nTick % m_nSongSizeInTicks;
- }
- nTotalTick = 0;
- for ( int i = 0; i < nColumns; ++i ) {
- PatternList *pColumn = ( *pPatternColumns )[ i ];
- if ( pColumn->size() != 0 ) {
- // tengo in considerazione solo il primo
- // pattern. I pattern nel gruppo devono avere la
- // stessa lunghezza.
- nPatternSize = pColumn->get( 0 )->get_length();
- } else {
- nPatternSize = MAX_NOTES;
- }
-
- if ( ( nLoopTick >= nTotalTick )
- && ( nLoopTick < nTotalTick + nPatternSize ) ) {
- ( *pPatternStartTick ) = nTotalTick;
- return i;
- }
- nTotalTick += nPatternSize;
- }
- }
-
- QString err = QString( "[findPatternInTick] tick = %1. No pattern found" ).arg( QString::number(nTick) );
- ___ERRORLOG( err );
- return -1;
+ int nPatternSize;
+ for ( int i = 0; i < nColumns; ++i ) {
+ PatternList *pColumn = ( *pPatternColumns )[ i ];
+ if ( pColumn->size() != 0 ) {
+ // tengo in considerazione solo il primo pattern. I
+ // pattern nel gruppo devono avere la stessa lunghezza.
+ nPatternSize = pColumn->get( 0 )->get_length();
+ } else {
+ nPatternSize = MAX_NOTES;
+ }
+
+ if ( ( nTick >= nTotalTick ) && ( nTick < nTotalTick + nPatternSize ) ) {
+ ( *pPatternStartTick ) = nTotalTick;
+ return i;
+ }
+ nTotalTick += nPatternSize;
+ }
+
+ if ( bLoopMode ) {
+ m_nSongSizeInTicks = nTotalTick;
+ int nLoopTick = 0;
+ if ( m_nSongSizeInTicks != 0 ) {
+ nLoopTick = nTick % m_nSongSizeInTicks;
+ }
+ nTotalTick = 0;
+ for ( int i = 0; i < nColumns; ++i ) {
+ PatternList *pColumn = ( *pPatternColumns )[ i ];
+ if ( pColumn->size() != 0 ) {
+ // tengo in considerazione solo il primo
+ // pattern. I pattern nel gruppo devono avere la
+ // stessa lunghezza.
+ nPatternSize = pColumn->get( 0 )->get_length();
+ } else {
+ nPatternSize = MAX_NOTES;
+ }
+
+ if ( ( nLoopTick >= nTotalTick )
+ && ( nLoopTick < nTotalTick + nPatternSize ) ) {
+ ( *pPatternStartTick ) = nTotalTick;
+ return i;
+ }
+ nTotalTick += nPatternSize;
+ }
+ }
+
+ QString err = QString( "[findPatternInTick] tick = %1. No pattern found" ).arg( QString::number(nTick) );
+ ___ERRORLOG( err );
+ return -1;
}
void audioEngine_noteOn( Note *note )
{
- // check current state
- if ( ( m_audioEngineState != STATE_READY )
- && ( m_audioEngineState != STATE_PLAYING ) ) {
- ___ERRORLOG( "Error the audio engine is not in READY state" );
- delete note;
- return;
- }
+ // check current state
+ if ( ( m_audioEngineState != STATE_READY )
+ && ( m_audioEngineState != STATE_PLAYING ) ) {
+ ___ERRORLOG( "Error the audio engine is not in READY state" );
+ delete note;
+ return;
+ }
- m_midiNoteQueue.push_back( note );
+ m_midiNoteQueue.push_back( note );
}
/*
void audioEngine_noteOff( Note *note )
{
- if ( note == NULL ) {
- ___ERRORLOG( "Error, note == NULL" );
- }
-
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
- // check current state
- if ( ( m_audioEngineState != STATE_READY )
- && ( m_audioEngineState != STATE_PLAYING ) ) {
- ___ERRORLOG( "Error the audio engine is not in READY state" );
- delete note;
- AudioEngine::get_instance()->unlock();
- return;
- }
+ if ( note == NULL ) {
+ ___ERRORLOG( "Error, note == NULL" );
+ }
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ // check current state
+ if ( ( m_audioEngineState != STATE_READY )
+ && ( m_audioEngineState != STATE_PLAYING ) ) {
+ ___ERRORLOG( "Error the audio engine is not in READY state" );
+ delete note;
+ AudioEngine::get_instance()->unlock();
+ return;
+ }
// AudioEngine::get_instance()->get_sampler()->note_off( note );
- AudioEngine::get_instance()->unlock();
- delete note;
+ AudioEngine::get_instance()->unlock();
+ delete note;
}
*/
@@ -1502,215 +1514,215 @@
AudioOutput* createDriver( const QString& sDriver )
{
- ___INFOLOG( QString( "Driver: '%1'" ).arg( sDriver ) );
- Preferences *pPref = Preferences::get_instance();
- AudioOutput *pDriver = NULL;
-
- if ( sDriver == "Oss" ) {
- pDriver = new OssDriver( audioEngine_process );
- if ( pDriver->class_name() == NullDriver::class_name() ) {
- delete pDriver;
- pDriver = NULL;
- }
- } else if ( sDriver == "Jack" ) {
- pDriver = new JackOutput( audioEngine_process );
- if ( pDriver->class_name() == NullDriver::class_name() ) {
- delete pDriver;
- pDriver = NULL;
- } else {
+ ___INFOLOG( QString( "Driver: '%1'" ).arg( sDriver ) );
+ Preferences *pPref = Preferences::get_instance();
+ AudioOutput *pDriver = NULL;
+
+ if ( sDriver == "Oss" ) {
+ pDriver = new OssDriver( audioEngine_process );
+ if ( pDriver->class_name() == NullDriver::class_name() ) {
+ delete pDriver;
+ pDriver = NULL;
+ }
+ } else if ( sDriver == "Jack" ) {
+ pDriver = new JackOutput( audioEngine_process );
+ if ( pDriver->class_name() == NullDriver::class_name() ) {
+ delete pDriver;
+ pDriver = NULL;
+ } else {
#ifdef H2CORE_HAVE_JACK
- static_cast(pDriver)->setConnectDefaults(
- Preferences::get_instance()->m_bJackConnectDefaults
- );
-#endif
- }
- } else if ( sDriver == "Alsa" ) {
- pDriver = new AlsaAudioDriver( audioEngine_process );
- if ( pDriver->class_name() == NullDriver::class_name() ) {
- delete pDriver;
- pDriver = NULL;
- }
- } else if ( sDriver == "PortAudio" ) {
- pDriver = new PortAudioDriver( audioEngine_process );
- if ( pDriver->class_name() == NullDriver::class_name() ) {
- delete pDriver;
- pDriver = NULL;
- }
- }
-//#ifdef Q_OS_MACX
- else if ( sDriver == "CoreAudio" ) {
- ___INFOLOG( "Creating CoreAudioDriver" );
- pDriver = new CoreAudioDriver( audioEngine_process );
- if ( pDriver->class_name() == NullDriver::class_name() ) {
- delete pDriver;
- pDriver = NULL;
- }
- }
-//#endif
- else if ( sDriver == "Fake" ) {
- ___WARNINGLOG( "*** Using FAKE audio driver ***" );
- pDriver = new FakeDriver( audioEngine_process );
- } else {
- ___ERRORLOG( "Unknown driver " + sDriver );
- audioEngine_raiseError( Hydrogen::UNKNOWN_DRIVER );
- }
-
- if ( pDriver ) {
- // initialize the audio driver
- int res = pDriver->init( pPref->m_nBufferSize );
- if ( res != 0 ) {
- ___ERRORLOG( "Error starting audio driver [audioDriver::init()]" );
- delete pDriver;
- pDriver = NULL;
- }
- }
+ static_cast(pDriver)->setConnectDefaults(
+ Preferences::get_instance()->m_bJackConnectDefaults
+ );
+#endif
+ }
+ } else if ( sDriver == "Alsa" ) {
+ pDriver = new AlsaAudioDriver( audioEngine_process );
+ if ( pDriver->class_name() == NullDriver::class_name() ) {
+ delete pDriver;
+ pDriver = NULL;
+ }
+ } else if ( sDriver == "PortAudio" ) {
+ pDriver = new PortAudioDriver( audioEngine_process );
+ if ( pDriver->class_name() == NullDriver::class_name() ) {
+ delete pDriver;
+ pDriver = NULL;
+ }
+ }
+ //#ifdef Q_OS_MACX
+ else if ( sDriver == "CoreAudio" ) {
+ ___INFOLOG( "Creating CoreAudioDriver" );
+ pDriver = new CoreAudioDriver( audioEngine_process );
+ if ( pDriver->class_name() == NullDriver::class_name() ) {
+ delete pDriver;
+ pDriver = NULL;
+ }
+ }
+ //#endif
+ else if ( sDriver == "Fake" ) {
+ ___WARNINGLOG( "*** Using FAKE audio driver ***" );
+ pDriver = new FakeDriver( audioEngine_process );
+ } else {
+ ___ERRORLOG( "Unknown driver " + sDriver );
+ audioEngine_raiseError( Hydrogen::UNKNOWN_DRIVER );
+ }
+
+ if ( pDriver ) {
+ // initialize the audio driver
+ int res = pDriver->init( pPref->m_nBufferSize );
+ if ( res != 0 ) {
+ ___ERRORLOG( "Error starting audio driver [audioDriver::init()]" );
+ delete pDriver;
+ pDriver = NULL;
+ }
+ }
- return pDriver;
+ return pDriver;
}
/// Start all audio drivers
void audioEngine_startAudioDrivers()
{
- Preferences *preferencesMng = Preferences::get_instance();
+ Preferences *preferencesMng = Preferences::get_instance();
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- QMutexLocker mx(&mutex_OutputPointer);
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ QMutexLocker mx(&mutex_OutputPointer);
- ___INFOLOG( "[audioEngine_startAudioDrivers]" );
+ ___INFOLOG( "[audioEngine_startAudioDrivers]" );
- // check current state
- if ( m_audioEngineState != STATE_INITIALIZED ) {
- ___ERRORLOG( QString( "Error the audio engine is not in INITIALIZED"
+ // check current state
+ if ( m_audioEngineState != STATE_INITIALIZED ) {
+ ___ERRORLOG( QString( "Error the audio engine is not in INITIALIZED"
" state. state=%1" )
.arg( m_audioEngineState ) );
- AudioEngine::get_instance()->unlock();
- return;
- }
-
- if ( m_pAudioDriver ) { // check if the audio m_pAudioDriver is still alive
- ___ERRORLOG( "The audio driver is still alive" );
- }
- if ( m_pMidiDriver ) { // check if midi driver is still alive
- ___ERRORLOG( "The MIDI driver is still active" );
- }
-
-
- QString sAudioDriver = preferencesMng->m_sAudioDriver;
-// sAudioDriver = "Auto";
- if ( sAudioDriver == "Auto" ) {
- if ( ( m_pAudioDriver = createDriver( "Jack" ) ) == NULL ) {
- if ( ( m_pAudioDriver = createDriver( "Alsa" ) ) == NULL ) {
- if ( ( m_pAudioDriver = createDriver( "CoreAudio" ) ) == NULL ) {
- if ( ( m_pAudioDriver = createDriver( "PortAudio" ) ) == NULL ) {
- if ( ( m_pAudioDriver = createDriver( "Oss" ) ) == NULL ) {
- audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
- ___ERRORLOG( "Error starting audio driver" );
- ___ERRORLOG( "Using the NULL output audio driver" );
-
- // use the NULL output driver
- m_pAudioDriver = new NullDriver( audioEngine_process );
- m_pAudioDriver->init( 0 );
- }
- }
- }
- }
- }
- } else {
- m_pAudioDriver = createDriver( sAudioDriver );
- if ( m_pAudioDriver == NULL ) {
- audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
- ___ERRORLOG( "Error starting audio driver" );
- ___ERRORLOG( "Using the NULL output audio driver" );
-
- // use the NULL output driver
- m_pAudioDriver = new NullDriver( audioEngine_process );
- m_pAudioDriver->init( 0 );
- }
- }
+ AudioEngine::get_instance()->unlock();
+ return;
+ }
+
+ if ( m_pAudioDriver ) { // check if the audio m_pAudioDriver is still alive
+ ___ERRORLOG( "The audio driver is still alive" );
+ }
+ if ( m_pMidiDriver ) { // check if midi driver is still alive
+ ___ERRORLOG( "The MIDI driver is still active" );
+ }
+
+
+ QString sAudioDriver = preferencesMng->m_sAudioDriver;
+ // sAudioDriver = "Auto";
+ if ( sAudioDriver == "Auto" ) {
+ if ( ( m_pAudioDriver = createDriver( "Jack" ) ) == NULL ) {
+ if ( ( m_pAudioDriver = createDriver( "Alsa" ) ) == NULL ) {
+ if ( ( m_pAudioDriver = createDriver( "CoreAudio" ) ) == NULL ) {
+ if ( ( m_pAudioDriver = createDriver( "PortAudio" ) ) == NULL ) {
+ if ( ( m_pAudioDriver = createDriver( "Oss" ) ) == NULL ) {
+ audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
+ ___ERRORLOG( "Error starting audio driver" );
+ ___ERRORLOG( "Using the NULL output audio driver" );
+
+ // use the NULL output driver
+ m_pAudioDriver = new NullDriver( audioEngine_process );
+ m_pAudioDriver->init( 0 );
+ }
+ }
+ }
+ }
+ }
+ } else {
+ m_pAudioDriver = createDriver( sAudioDriver );
+ if ( m_pAudioDriver == NULL ) {
+ audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
+ ___ERRORLOG( "Error starting audio driver" );
+ ___ERRORLOG( "Using the NULL output audio driver" );
+
+ // use the NULL output driver
+ m_pAudioDriver = new NullDriver( audioEngine_process );
+ m_pAudioDriver->init( 0 );
+ }
+ }
- if ( preferencesMng->m_sMidiDriver == "ALSA" ) {
+ if ( preferencesMng->m_sMidiDriver == "ALSA" ) {
#ifdef H2CORE_HAVE_ALSA
- // Create MIDI driver
- AlsaMidiDriver *alsaMidiDriver = new AlsaMidiDriver();
- m_pMidiDriverOut = alsaMidiDriver;
- m_pMidiDriver = alsaMidiDriver;
- m_pMidiDriver->open();
- m_pMidiDriver->setActive( true );
+ // Create MIDI driver
+ AlsaMidiDriver *alsaMidiDriver = new AlsaMidiDriver();
+ m_pMidiDriverOut = alsaMidiDriver;
+ m_pMidiDriver = alsaMidiDriver;
+ m_pMidiDriver->open();
+ m_pMidiDriver->setActive( true );
#endif
- } else if ( preferencesMng->m_sMidiDriver == "PortMidi" ) {
+ } else if ( preferencesMng->m_sMidiDriver == "PortMidi" ) {
#ifdef H2CORE_HAVE_PORTMIDI
- m_pMidiDriver = new PortMidiDriver();
- m_pMidiDriver->open();
- m_pMidiDriver->setActive( true );
+ m_pMidiDriver = new PortMidiDriver();
+ m_pMidiDriver->open();
+ m_pMidiDriver->setActive( true );
#endif
- } else if ( preferencesMng->m_sMidiDriver == "CoreMidi" ) {
+ } else if ( preferencesMng->m_sMidiDriver == "CoreMidi" ) {
#ifdef H2CORE_HAVE_COREMIDI
- m_pMidiDriver = new CoreMidiDriver();
- m_pMidiDriver->open();
- m_pMidiDriver->setActive( true );
+ m_pMidiDriver = new CoreMidiDriver();
+ m_pMidiDriver->open();
+ m_pMidiDriver->setActive( true );
#endif
- } else if ( preferencesMng->m_sMidiDriver == "JackMidi" ) {
+ } else if ( preferencesMng->m_sMidiDriver == "JackMidi" ) {
#ifdef H2CORE_HAVE_JACK
- JackMidiDriver *jackMidiDriver = new JackMidiDriver();
- m_pMidiDriverOut = jackMidiDriver;
- m_pMidiDriver = jackMidiDriver;
- m_pMidiDriver->open();
- m_pMidiDriver->setActive( true );
-#endif
- }
-
- // change the current audio engine state
- if ( m_pSong == NULL ) {
- m_audioEngineState = STATE_PREPARED;
- } else {
- m_audioEngineState = STATE_READY;
- }
-
-
- if ( m_pSong ) {
- m_pAudioDriver->setBpm( m_pSong->__bpm );
- }
-
- if ( m_audioEngineState == STATE_PREPARED ) {
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PREPARED );
- } else if ( m_audioEngineState == STATE_READY ) {
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
- }
-
- // Unlocking earlier might execute the jack process() callback before we
- // are fully initialized.
- mx.unlock();
- AudioEngine::get_instance()->unlock();
-
- if ( m_pAudioDriver ) {
- int res = m_pAudioDriver->connect();
- if ( res != 0 ) {
- audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
- ___ERRORLOG( "Error starting audio driver [audioDriver::connect()]" );
- ___ERRORLOG( "Using the NULL output audio driver" );
-
- mx.relock();
- delete m_pAudioDriver;
- m_pAudioDriver = new NullDriver( audioEngine_process );
- mx.unlock();
- m_pAudioDriver->init( 0 );
- m_pAudioDriver->connect();
- }
-
- if ( ( m_pMainBuffer_L = m_pAudioDriver->getOut_L() ) == NULL ) {
- ___ERRORLOG( "m_pMainBuffer_L == NULL" );
- }
- if ( ( m_pMainBuffer_R = m_pAudioDriver->getOut_R() ) == NULL ) {
- ___ERRORLOG( "m_pMainBuffer_R == NULL" );
- }
+ JackMidiDriver *jackMidiDriver = new JackMidiDriver();
+ m_pMidiDriverOut = jackMidiDriver;
+ m_pMidiDriver = jackMidiDriver;
+ m_pMidiDriver->open();
+ m_pMidiDriver->setActive( true );
+#endif
+ }
+
+ // change the current audio engine state
+ if ( m_pSong == NULL ) {
+ m_audioEngineState = STATE_PREPARED;
+ } else {
+ m_audioEngineState = STATE_READY;
+ }
+
+
+ if ( m_pSong ) {
+ m_pAudioDriver->setBpm( m_pSong->__bpm );
+ }
+
+ if ( m_audioEngineState == STATE_PREPARED ) {
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PREPARED );
+ } else if ( m_audioEngineState == STATE_READY ) {
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
+ }
+
+ // Unlocking earlier might execute the jack process() callback before we
+ // are fully initialized.
+ mx.unlock();
+ AudioEngine::get_instance()->unlock();
+
+ if ( m_pAudioDriver ) {
+ int res = m_pAudioDriver->connect();
+ if ( res != 0 ) {
+ audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
+ ___ERRORLOG( "Error starting audio driver [audioDriver::connect()]" );
+ ___ERRORLOG( "Using the NULL output audio driver" );
+
+ mx.relock();
+ delete m_pAudioDriver;
+ m_pAudioDriver = new NullDriver( audioEngine_process );
+ mx.unlock();
+ m_pAudioDriver->init( 0 );
+ m_pAudioDriver->connect();
+ }
+
+ if ( ( m_pMainBuffer_L = m_pAudioDriver->getOut_L() ) == NULL ) {
+ ___ERRORLOG( "m_pMainBuffer_L == NULL" );
+ }
+ if ( ( m_pMainBuffer_R = m_pAudioDriver->getOut_R() ) == NULL ) {
+ ___ERRORLOG( "m_pMainBuffer_R == NULL" );
+ }
#ifdef H2CORE_HAVE_JACK
- audioEngine_renameJackPorts();
+ audioEngine_renameJackPorts();
#endif
- audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
- }
+ audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
+ }
}
@@ -1720,45 +1732,45 @@
/// Stop all audio drivers
void audioEngine_stopAudioDrivers()
{
- ___INFOLOG( "[audioEngine_stopAudioDrivers]" );
+ ___INFOLOG( "[audioEngine_stopAudioDrivers]" );
- // check current state
- if ( m_audioEngineState == STATE_PLAYING ) {
- audioEngine_stop();
- }
-
- if ( ( m_audioEngineState != STATE_PREPARED )
- && ( m_audioEngineState != STATE_READY ) ) {
- ___ERRORLOG( QString( "Error: the audio engine is not in PREPARED"
+ // check current state
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ audioEngine_stop();
+ }
+
+ if ( ( m_audioEngineState != STATE_PREPARED )
+ && ( m_audioEngineState != STATE_READY ) ) {
+ ___ERRORLOG( QString( "Error: the audio engine is not in PREPARED"
" or READY state. state=%1" )
.arg( m_audioEngineState ) );
- return;
- }
+ return;
+ }
- // change the current audio engine state
- m_audioEngineState = STATE_INITIALIZED;
- EventQueue::get_instance()->push_event( EVENT_STATE, STATE_INITIALIZED );
-
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
- // delete MIDI driver
- if ( m_pMidiDriver ) {
- m_pMidiDriver->close();
- delete m_pMidiDriver;
- m_pMidiDriver = NULL;
- m_pMidiDriverOut = NULL;
- }
-
- // delete audio driver
- if ( m_pAudioDriver ) {
- m_pAudioDriver->disconnect();
- QMutexLocker mx( &mutex_OutputPointer );
- delete m_pAudioDriver;
- m_pAudioDriver = NULL;
- mx.unlock();
- }
+ // change the current audio engine state
+ m_audioEngineState = STATE_INITIALIZED;
+ EventQueue::get_instance()->push_event( EVENT_STATE, STATE_INITIALIZED );
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ // delete MIDI driver
+ if ( m_pMidiDriver ) {
+ m_pMidiDriver->close();
+ delete m_pMidiDriver;
+ m_pMidiDriver = NULL;
+ m_pMidiDriverOut = NULL;
+ }
+
+ // delete audio driver
+ if ( m_pAudioDriver ) {
+ m_pAudioDriver->disconnect();
+ QMutexLocker mx( &mutex_OutputPointer );
+ delete m_pAudioDriver;
+ m_pAudioDriver = NULL;
+ mx.unlock();
+ }
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->unlock();
}
@@ -1766,8 +1778,8 @@
/// Restart all audio and midi drivers
void audioEngine_restartAudioDrivers()
{
- audioEngine_stopAudioDrivers();
- audioEngine_startAudioDrivers();
+ audioEngine_stopAudioDrivers();
+ audioEngine_startAudioDrivers();
}
@@ -1786,24 +1798,24 @@
const char* Hydrogen::__class_name = "Hydrogen";
Hydrogen::Hydrogen()
- : Object( __class_name )
+ : Object( __class_name )
{
- if ( __instance ) {
- ERRORLOG( "Hydrogen audio engine is already running" );
- throw H2Exception( "Hydrogen audio engine is already running" );
- }
-
- INFOLOG( "[Hydrogen]" );
-
- hydrogenInstance = this;
-// __instance = this;
- audioEngine_init();
- // Prevent double creation caused by calls from MIDI thread
- __instance = this;
- audioEngine_startAudioDrivers();
- for(int i = 0; i<128; i++){
- m_nInstrumentLookupTable[i] = i;
- }
+ if ( __instance ) {
+ ERRORLOG( "Hydrogen audio engine is already running" );
+ throw H2Exception( "Hydrogen audio engine is already running" );
+ }
+
+ INFOLOG( "[Hydrogen]" );
+
+ hydrogenInstance = this;
+ // __instance = this;
+ audioEngine_init();
+ // Prevent double creation caused by calls from MIDI thread
+ __instance = this;
+ audioEngine_startAudioDrivers();
+ for(int i = 0; i<128; i++){
+ m_nInstrumentLookupTable[i] = i;
+ }
}
@@ -1811,44 +1823,44 @@
Hydrogen::~Hydrogen()
{
- INFOLOG( "[~Hydrogen]" );
- if ( m_audioEngineState == STATE_PLAYING ) {
- audioEngine_stop();
- }
- removeSong();
- audioEngine_stopAudioDrivers();
- audioEngine_destroy();
- __kill_instruments();
- __instance = NULL;
+ INFOLOG( "[~Hydrogen]" );
+ if ( m_audioEngineState == STATE_PLAYING ) {
+ audioEngine_stop();
+ }
+ removeSong();
+ audioEngine_stopAudioDrivers();
+ audioEngine_destroy();
+ __kill_instruments();
+ __instance = NULL;
}
void Hydrogen::create_instance()
{
- // Create all the other instances that we need
- // ....and in the right order
- Logger::create_instance();
- MidiMap::create_instance();
- Preferences::create_instance();
- EventQueue::create_instance();
- MidiActionManager::create_instance();
-
- if( __instance == 0 ) {
- __instance = new Hydrogen;
- }
-
- // See audioEngine_init() for:
- // AudioEngine::create_instance();
- // Effects::create_instance();
- // Playlist::create_instance();
+ // Create all the other instances that we need
+ // ....and in the right order
+ Logger::create_instance();
+ MidiMap::create_instance();
+ Preferences::create_instance();
+ EventQueue::create_instance();
+ MidiActionManager::create_instance();
+
+ if( __instance == 0 ) {
+ __instance = new Hydrogen;
+ }
+
+ // See audioEngine_init() for:
+ // AudioEngine::create_instance();
+ // Effects::create_instance();
+ // Playlist::create_instance();
}
/// Start the internal sequencer
void Hydrogen::sequencer_play()
{
- getSong()->get_pattern_list()->set_to_old();
- m_pAudioDriver->play();
+ getSong()->get_pattern_list()->set_to_old();
+ m_pAudioDriver->play();
}
@@ -1856,40 +1868,40 @@
/// Stop the internal sequencer
void Hydrogen::sequencer_stop()
{
- if( Hydrogen::get_instance()->getMidiOutput() != NULL ){
- Hydrogen::get_instance()->getMidiOutput()->handleQueueAllNoteOff();
- }
+ if( Hydrogen::get_instance()->getMidiOutput() != NULL ){
+ Hydrogen::get_instance()->getMidiOutput()->handleQueueAllNoteOff();
+ }
- m_pAudioDriver->stop();
- Preferences::get_instance()->setRecordEvents(false);
+ m_pAudioDriver->stop();
+ Preferences::get_instance()->setRecordEvents(false);
}
void Hydrogen::setSong( Song *pSong )
{
- audioEngine_setSong( pSong );
+ audioEngine_setSong( pSong );
}
void Hydrogen::removeSong()
{
- audioEngine_removeSong();
+ audioEngine_removeSong();
}
Song* Hydrogen::getSong()
{
- return m_pSong;
+ return m_pSong;
}
void Hydrogen::midi_noteOn( Note *note )
{
- audioEngine_noteOn( note );
+ audioEngine_noteOn( note );
}
@@ -1903,551 +1915,599 @@
bool forcePlay,
int msg1 )
{
- UNUSED( pitch );
+ UNUSED( pitch );
- Preferences *pref = Preferences::get_instance();
- unsigned int realcolumn = 0;
- unsigned res = pref->getPatternEditorGridResolution();
- int nBase = pref->isPatternEditorUsingTriplets() ? 3 : 4;
- int scalar = ( 4 * MAX_NOTES ) / ( res * nBase );
- bool hearnote = forcePlay;
-
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
-
- Song *song = getSong();
- if ( !pref->__playselectedinstrument ){
- if ( instrument >= ( int )song->get_instrument_list()->size() ) {
- // unused instrument
- AudioEngine::get_instance()->unlock();
- return;
- }
- }
-
- // Get current partern and column, compensating for "lookahead" if required
- Pattern* currentPattern = NULL;
- unsigned int column = 0;
- unsigned int lookaheadTicks = m_nLookaheadFrames / m_pAudioDriver->m_transport.m_nTickSize;
- bool doRecord = pref->getRecordEvents();
- if ( m_pSong->get_mode() == Song::SONG_MODE && doRecord &&
- m_audioEngineState == STATE_PLAYING ) {
-
- // Recording + song playback mode + actually playing
- PatternList *pPatternList = m_pSong->get_pattern_list();
- int ipattern = getPatternPos(); // playlist index
- if ( ipattern < 0 || ipattern >= (int) pPatternList->size() ) {
- AudioEngine::get_instance()->unlock(); // unlock the audio engine
- return;
- }
- // Locate column -- may need to jump back in the pattern list
- column = getTickPosition();
- while ( column < lookaheadTicks ) {
- ipattern -= 1;
- if ( ipattern < 0 || ipattern >= (int) pPatternList->size() ) {
- AudioEngine::get_instance()->unlock(); // unlock the audio engine
- return;
- }
- // Convert from playlist index to actual pattern index
- std::vector *pColumns = m_pSong->get_pattern_group_vector();
- for ( int i = 0; i <= ipattern; ++i ) {
- PatternList *pColumn = ( *pColumns )[i];
- currentPattern = pColumn->get( 0 );
- }
- column = column + currentPattern->get_length();
-// WARNINGLOG( "Undoing lookahead: corrected (" + to_string( ipattern+1 ) +
-// "," + to_string( (int) ( column - currentPattern->get_length() ) -
-// (int) lookaheadTicks ) + ") -> (" + to_string(ipattern) +
-// "," + to_string( (int) column - (int) lookaheadTicks ) + ")." );
- }
- column -= lookaheadTicks;
- // Convert from playlist index to actual pattern index (if not already done above)
- if ( currentPattern == NULL ) {
- std::vector *pColumns = m_pSong->get_pattern_group_vector();
- for ( int i = 0; i <= ipattern; ++i ) {
- PatternList *pColumn = ( *pColumns )[i];
- currentPattern = pColumn->get( 0 );
- }
- }
-
- // Cancel recording if punch area disagrees
- doRecord = pref->inPunchArea( ipattern );
-
- } else {
-
- // Not song-record mode
- PatternList *pPatternList = m_pSong->get_pattern_list();
- if ( ( m_nSelectedPatternNumber != -1 )
- && ( m_nSelectedPatternNumber < ( int )pPatternList->size() ) ) {
- currentPattern = pPatternList->get( m_nSelectedPatternNumber );
- }
- if( currentPattern == NULL ){
- AudioEngine::get_instance()->unlock(); // unlock the audio engine
- return;
- }
- // Locate column -- may need to wrap around end of pattern
- column = getTickPosition();
- if ( column >= lookaheadTicks ) {
- column -= lookaheadTicks;
- } else {
- lookaheadTicks %= currentPattern->get_length();
- column = (column + currentPattern->get_length() - lookaheadTicks)
- % currentPattern->get_length();
- }
-
- }
-
- realcolumn = getRealtimeTickPosition();
-
- if ( pref->getQuantizeEvents() ) {
- // quantize it to scale
- unsigned qcolumn = ( unsigned )::round( column / ( double )scalar ) * scalar;
-
- //we have to make sure that no beat is added on the last displayed note in a bar
- //for example: if the pattern has 4 beats, the editor displays 5 beats, so we should avoid adding beats an note 5.
- if ( qcolumn == currentPattern->get_length() ) qcolumn = 0;
- column = qcolumn;
- }
-
-
- unsigned position = column;
- m_naddrealtimenotetickposition = column;
-
-
- Instrument *instrRef = 0;
- if ( song ) {
- instrRef = song->get_instrument_list()->get( m_nInstrumentLookupTable[ instrument ] );//getlookuptable index = instrument+36, ziel wert = der entprechende wert -36
- }
-
- if ( currentPattern && ( getState() == STATE_PLAYING ) ) {
-
- if( doRecord && pref->getDestructiveRecord() && pref->m_nRecPreDelete>0 ) {
- // Delete notes around current note if option toggled
-
- int postdelete = 0;
- int predelete = 0;
- int prefpredelete = pref->m_nRecPreDelete-1;
- int prefpostdelete = pref->m_nRecPostDelete;
- int length = currentPattern->get_length();
- bool fp = false;
- postdelete = column;
-
- switch (prefpredelete) {
- case 0: predelete = length ; postdelete = 0; fp = true; break;
- case 1: predelete = length ; fp = true; break;
- case 2: predelete = length / 2; fp = true; break;
- case 3: predelete = length / 4; fp = true; break;
- case 4: predelete = length / 8; fp = true; break;
- case 5: predelete = length / 16; fp = true; break;
- case 6: predelete = length / 32; fp = true; break;
- case 7: predelete = length / 64; fp = true; break;
- case 8: predelete = length / 64; break;
- case 9: predelete = length / 32; break;
- case 10: predelete = length / 16; break;
- case 11: predelete = length / 8; break;
- case 12: predelete = length / 4; break;
- case 13: predelete = length / 2; break;
- case 14: predelete = length; break;
- case 15: break;
- default : predelete = 1; break;
- }
-
- if(!fp ){
- switch (prefpostdelete) {
- case 0: postdelete = column; break;
- case 1: postdelete -= length / 64; break;
- case 2: postdelete -= length / 32; break;
- case 3: postdelete -= length / 16; break;
- case 4: postdelete -= length / 8; break;
- case 5: postdelete -= length / 4; break;
- case 6: postdelete -= length / 2; break;
- case 7: postdelete -= length ; break;
- default : postdelete = column; break;
- }
- if (postdelete<0) postdelete = 0;
-
- }
-
- Pattern::notes_t* notes = (Pattern::notes_t*)currentPattern->get_notes();
- FOREACH_NOTE_IT_BEGIN_END(notes,it) {
- Note *pNote = it->second;
- assert( pNote );
-
- if( pref->__playselectedinstrument ){//fix me
- if( song->get_instrument_list()->get( getSelectedInstrumentNumber()) == pNote->get_instrument() ){
- if(prefpredelete>=1 && prefpredelete <=14 )
- pNote->set_just_recorded( false );
- if( (prefpredelete == 15) && (pNote->get_just_recorded() == false)){
- delete pNote;
- notes->erase( it );
- continue;
- }
- if( ( pNote->get_just_recorded() == false ) && (static_cast( pNote->get_position() ) >= postdelete && pNote->get_position() < column + predelete +1 )){
- delete pNote;
- notes->erase( it );
- }
- }
- continue;
- }
-
- if ( !fp && pNote->get_instrument() != instrRef ) {
- continue;
- }
-
- if(prefpredelete>=1 && prefpredelete <=14 )
- pNote->set_just_recorded( false );
-
- if( (prefpredelete == 15) && (pNote->get_just_recorded() == false)){
- delete pNote;
- notes->erase( it );
- continue;
- }
-
- if( ( pNote->get_just_recorded() == false ) && ( static_cast( pNote->get_position() ) >= postdelete && pNote->get_position() erase( it );
- }
-
- }
- }
- assert( currentPattern != NULL );
-
- bool bNoteAlreadyExist = false;
- Note *pNoteOld = NULL;
- for ( unsigned nNote = 0 ;
- nNote < currentPattern->get_length() ;
- nNote++ ) {
- const Pattern::notes_t* notes = currentPattern->get_notes();
- FOREACH_NOTE_CST_IT_BOUND(notes,it,nNote) {
- pNoteOld = it->second;
- if ( pNoteOld!=NULL ) {
- if ( pNoteOld->get_instrument() == instrRef
- && nNote==column ) {
- bNoteAlreadyExist = true;
- break;
- }
- }
- }
- }
-
- if ( bNoteAlreadyExist ) {
- // in this case, we'll leave the note alone
- // hear note only if not playing too
- if ( pref->getHearNewNotes()
- && getState() == STATE_READY ) {
- hearnote = true;
- }
- // Update velocity and flag as just recorded
- if ( doRecord ) {
- pNoteOld->set_velocity( velocity );
- pNoteOld->set_just_recorded( true );
- }
- } else if ( !doRecord ) {
- if ( pref->getHearNewNotes()
- && ( getState() == STATE_READY
- || getState() == STATE_PLAYING ) ) {
- hearnote = true;
- }
- } else {
- if ( !pref->__playselectedinstrument ){
- // create the new note
- Note *note = new Note( instrRef,
- position,
- velocity,
- pan_L,
- pan_R,
- -1,
- 0 );
- currentPattern->insert_note( note, column );
-
- // hear note if its not in the future
- if ( pref->getHearNewNotes()
- && position <= getTickPosition() ) {
- hearnote = true;
- }
-
- note->set_just_recorded( true );
- song->__is_modified = true;
-
- EventQueue::get_instance()->push_event( EVENT_PATTERN_MODIFIED, -1 );
- }
- else if ( pref->__playselectedinstrument ){
-
- Note *note = new Note( song->get_instrument_list()->get( getSelectedInstrumentNumber()),
- position,
- velocity,
- pan_L,
- pan_R,
- -1,
- 0 );
-
- int divider = msg1 / 12;
- Note::Octave octave = (Note::Octave)(divider -3);
- Note::Key notehigh = (Note::Key)(msg1 - (12 * divider));
- note->set_midi_info( notehigh, octave, msg1 );
-
- currentPattern->insert_note( note, column );
-
- // hear note if its not in the future
- if ( pref->getHearNewNotes()
- && position <= getTickPosition() ) {
- hearnote = true;
- }
-
- note->set_just_recorded( true );
- song->__is_modified = true;
-
- EventQueue::get_instance()->push_event( EVENT_PATTERN_MODIFIED, -1 );
- }
- }
- } else if ( pref->getHearNewNotes() ) {
- hearnote = true;
- }
-
- if ( !pref->__playselectedinstrument ){
- if ( hearnote && instrRef ) {
- Note *note2 = new Note( instrRef,
- realcolumn,
- velocity,
- pan_L,
- pan_R,
- -1,
- 0 );
- midi_noteOn( note2 );
- }
- }else
- {
- if ( hearnote ) {
- Note *note2 = new Note( song->get_instrument_list()->get( getSelectedInstrumentNumber()),
- realcolumn,
- velocity,
- pan_L,
- pan_R,
- -1,
- 0 );
-
- int divider = msg1 / 12;
- Note::Octave octave = (Note::Octave)(divider -3);
- Note::Key notehigh = (Note::Key)(msg1 - (12 * divider));
-
- //ERRORLOG( QString( "octave: %1, note: %2, instrument %3" ).arg( octave ).arg(notehigh).arg(instrument));
- note2->set_midi_info( notehigh, octave, msg1 );
- midi_noteOn( note2 );
- }
+ Preferences *pref = Preferences::get_instance();
+ unsigned int realcolumn = 0;
+ unsigned res = pref->getPatternEditorGridResolution();
+ int nBase = pref->isPatternEditorUsingTriplets() ? 3 : 4;
+ int scalar = ( 4 * MAX_NOTES ) / ( res * nBase );
+ bool hearnote = forcePlay;
+ int currentPatternNumber;
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+
+ Song *song = getSong();
+ if ( !pref->__playselectedinstrument ){
+ if ( instrument >= ( int )song->get_instrument_list()->size() ) {
+ // unused instrument
+ AudioEngine::get_instance()->unlock();
+ return;
+ }
+ }
+
+ // Get current partern and column, compensating for "lookahead" if required
+ Pattern* currentPattern = NULL;
+ unsigned int column = 0;
+ unsigned int lookaheadTicks = m_nLookaheadFrames / m_pAudioDriver->m_transport.m_nTickSize;
+ bool doRecord = pref->getRecordEvents();
+ if ( m_pSong->get_mode() == Song::SONG_MODE && doRecord &&
+ m_audioEngineState == STATE_PLAYING ) {
+
+ // Recording + song playback mode + actually playing
+ PatternList *pPatternList = m_pSong->get_pattern_list();
+ int ipattern = getPatternPos(); // playlist index
+ if ( ipattern < 0 || ipattern >= (int) pPatternList->size() ) {
+ AudioEngine::get_instance()->unlock(); // unlock the audio engine
+ return;
+ }
+ // Locate column -- may need to jump back in the pattern list
+ column = getTickPosition();
+ while ( column < lookaheadTicks ) {
+ ipattern -= 1;
+ if ( ipattern < 0 || ipattern >= (int) pPatternList->size() ) {
+ AudioEngine::get_instance()->unlock(); // unlock the audio engine
+ return;
+ }
+ // Convert from playlist index to actual pattern index
+ std::vector *pColumns = m_pSong->get_pattern_group_vector();
+ for ( int i = 0; i <= ipattern; ++i ) {
+ PatternList *pColumn = ( *pColumns )[i];
+ currentPattern = pColumn->get( 0 );
+ currentPatternNumber = i;
+ }
+ column = column + currentPattern->get_length();
+ // WARNINGLOG( "Undoing lookahead: corrected (" + to_string( ipattern+1 ) +
+ // "," + to_string( (int) ( column - currentPattern->get_length() ) -
+ // (int) lookaheadTicks ) + ") -> (" + to_string(ipattern) +
+ // "," + to_string( (int) column - (int) lookaheadTicks ) + ")." );
+ }
+ column -= lookaheadTicks;
+ // Convert from playlist index to actual pattern index (if not already done above)
+ if ( currentPattern == NULL ) {
+ std::vector *pColumns = m_pSong->get_pattern_group_vector();
+ for ( int i = 0; i <= ipattern; ++i ) {
+ PatternList *pColumn = ( *pColumns )[i];
+ currentPattern = pColumn->get( 0 );
+ currentPatternNumber = i;
+ }
+ }
+
+ // Cancel recording if punch area disagrees
+ doRecord = pref->inPunchArea( ipattern );
+
+ } else {
+
+ // Not song-record mode
+ PatternList *pPatternList = m_pSong->get_pattern_list();
+ if ( ( m_nSelectedPatternNumber != -1 )
+ && ( m_nSelectedPatternNumber < ( int )pPatternList->size() ) ) {
+ currentPattern = pPatternList->get( m_nSelectedPatternNumber );
+ currentPatternNumber = m_nSelectedPatternNumber;
+ }
+ if( currentPattern == NULL ){
+ AudioEngine::get_instance()->unlock(); // unlock the audio engine
+ return;
+ }
+ // Locate column -- may need to wrap around end of pattern
+ column = getTickPosition();
+ if ( column >= lookaheadTicks ) {
+ column -= lookaheadTicks;
+ } else {
+ lookaheadTicks %= currentPattern->get_length();
+ column = (column + currentPattern->get_length() - lookaheadTicks)
+ % currentPattern->get_length();
+ }
+
+ }
+
+ realcolumn = getRealtimeTickPosition();
+
+ if ( pref->getQuantizeEvents() ) {
+ // quantize it to scale
+ unsigned qcolumn = ( unsigned )::round( column / ( double )scalar ) * scalar;
+
+ //we have to make sure that no beat is added on the last displayed note in a bar
+ //for example: if the pattern has 4 beats, the editor displays 5 beats, so we should avoid adding beats an note 5.
+ if ( qcolumn == currentPattern->get_length() ) qcolumn = 0;
+ column = qcolumn;
+ }
+
+
+ unsigned position = column;
+ m_naddrealtimenotetickposition = column;
+
+
+ Instrument *instrRef = 0;
+ if ( song ) {
+ instrRef = song->get_instrument_list()->get( m_nInstrumentLookupTable[ instrument ] );//getlookuptable index = instrument+36, ziel wert = der entprechende wert -36
+ }
+
+ if ( currentPattern && ( getState() == STATE_PLAYING ) ) {
+
+ if( doRecord && pref->getDestructiveRecord() && pref->m_nRecPreDelete>0 ) {
+ // Delete notes around current note if option toggled
+
+ int postdelete = 0;
+ int predelete = 0;
+ int prefpredelete = pref->m_nRecPreDelete-1;
+ int prefpostdelete = pref->m_nRecPostDelete;
+ int length = currentPattern->get_length();
+ bool fp = false;
+ postdelete = column;
+
+ switch (prefpredelete) {
+ case 0: predelete = length ; postdelete = 0; fp = true; break;
+ case 1: predelete = length ; fp = true; break;
+ case 2: predelete = length / 2; fp = true; break;
+ case 3: predelete = length / 4; fp = true; break;
+ case 4: predelete = length / 8; fp = true; break;
+ case 5: predelete = length / 16; fp = true; break;
+ case 6: predelete = length / 32; fp = true; break;
+ case 7: predelete = length / 64; fp = true; break;
+ case 8: predelete = length / 64; break;
+ case 9: predelete = length / 32; break;
+ case 10: predelete = length / 16; break;
+ case 11: predelete = length / 8; break;
+ case 12: predelete = length / 4; break;
+ case 13: predelete = length / 2; break;
+ case 14: predelete = length; break;
+ case 15: break;
+ default : predelete = 1; break;
+ }
+
+ if(!fp ){
+ switch (prefpostdelete) {
+ case 0: postdelete = column; break;
+ case 1: postdelete -= length / 64; break;
+ case 2: postdelete -= length / 32; break;
+ case 3: postdelete -= length / 16; break;
+ case 4: postdelete -= length / 8; break;
+ case 5: postdelete -= length / 4; break;
+ case 6: postdelete -= length / 2; break;
+ case 7: postdelete -= length ; break;
+ default : postdelete = column; break;
+ }
+ if (postdelete<0) postdelete = 0;
+
+ }
+
+ Pattern::notes_t* notes = (Pattern::notes_t*)currentPattern->get_notes();
+ FOREACH_NOTE_IT_BEGIN_END(notes,it) {
+ Note *pNote = it->second;
+ assert( pNote );
+ int currentPosition = pNote->get_position();
+
+ if( pref->__playselectedinstrument ){//fix me
+ if( song->get_instrument_list()->get( getSelectedInstrumentNumber()) == pNote->get_instrument() ){
+ if(prefpredelete>=1 && prefpredelete <=14 )
+ pNote->set_just_recorded( false );
+ if( (prefpredelete == 15) && (pNote->get_just_recorded() == false)){
+ bool replaceExisting = false;
+ if(column == currentPosition)
+ replaceExisting = true;
+ EventQueue::AddMidiNoteVector noteAction;
+ noteAction.m_column = currentPosition;
+ noteAction.m_row = pNote->get_instrument_id();//getSelectedInstrumentNumber();
+ noteAction.m_pattern = currentPatternNumber;
+ noteAction.f_velocity = velocity;
+ noteAction.f_pan_L = pan_L;
+ noteAction.f_pan_R = pan_R;
+ noteAction.m_length = -1;
+
+ int divider = msg1 / 12;
+ noteAction.no_octaveKeyVal = (Note::Octave)(divider -3);
+ noteAction.nk_noteKeyVal = (Note::Key)(msg1 - (12 * divider));
+ noteAction.b_isInstrumentMode = replaceExisting;
+ noteAction.b_isMidi = true;
+ noteAction.b_noteExist = replaceExisting;
+ EventQueue::get_instance()->m_addMidiNoteVector.push_back(noteAction);
+ continue;
+ }
+ if( ( pNote->get_just_recorded() == false ) && (static_cast( pNote->get_position() ) >= postdelete && pNote->get_position() < column + predelete +1 )){
+ bool replaceExisting = false;
+ if(column == currentPosition)
+ replaceExisting = true;
+ EventQueue::AddMidiNoteVector noteAction;
+ noteAction.m_column = currentPosition;
+ noteAction.m_row = pNote->get_instrument_id();//getSelectedInstrumentNumber();
+ noteAction.m_pattern = currentPatternNumber;
+ noteAction.f_velocity = velocity;
+ noteAction.f_pan_L = pan_L;
+ noteAction.f_pan_R = pan_R;
+ noteAction.m_length = -1;
+
+ int divider = msg1 / 12;
+ noteAction.no_octaveKeyVal = (Note::Octave)(divider -3);
+ noteAction.nk_noteKeyVal = (Note::Key)(msg1 - (12 * divider));
+ noteAction.b_isInstrumentMode = replaceExisting;
+ noteAction.b_isMidi = true;
+ noteAction.b_noteExist = replaceExisting;
+ EventQueue::get_instance()->m_addMidiNoteVector.push_back(noteAction);
+ }
+ }
+ continue;
+ }
+
+ if ( !fp && pNote->get_instrument() != instrRef ) {
+ continue;
+ }
+
+ if(prefpredelete>=1 && prefpredelete <=14 )
+ pNote->set_just_recorded( false );
+
+ if( (prefpredelete == 15) && (pNote->get_just_recorded() == false)){
+
+ bool replaceExisting = false;
+ if(column == currentPosition)
+ replaceExisting = true;
+ EventQueue::AddMidiNoteVector noteAction;
+ noteAction.m_column = currentPosition;
+ noteAction.m_row = pNote->get_instrument_id();//m_nInstrumentLookupTable[ instrument ];
+ noteAction.m_pattern = currentPatternNumber;
+ noteAction.f_velocity = velocity;
+ noteAction.f_pan_L = pan_L;
+ noteAction.f_pan_R = pan_R;
+ noteAction.m_length = -1;
+ noteAction.no_octaveKeyVal = (Note::Octave)0;
+ noteAction.nk_noteKeyVal = (Note::Key)0;
+ noteAction.b_isInstrumentMode = false;
+ noteAction.b_isMidi = false;
+ noteAction.b_noteExist = replaceExisting;
+ EventQueue::get_instance()->m_addMidiNoteVector.push_back(noteAction);
+ continue;
+ }
+
+ if( ( pNote->get_just_recorded() == false ) && ( static_cast( pNote->get_position() ) >= postdelete && pNote->get_position() get_instrument_id();//m_nInstrumentLookupTable[ instrument ];
+ noteAction.m_pattern = currentPatternNumber;
+ noteAction.f_velocity = velocity;
+ noteAction.f_pan_L = pan_L;
+ noteAction.f_pan_R = pan_R;
+ noteAction.m_length = -1;
+ noteAction.no_octaveKeyVal = (Note::Octave)0;
+ noteAction.nk_noteKeyVal = (Note::Key)0;
+ noteAction.b_isInstrumentMode = false;
+ noteAction.b_isMidi = false;
+ noteAction.b_noteExist = replaceExisting;
+ EventQueue::get_instance()->m_addMidiNoteVector.push_back(noteAction);
+ }
+ }
+ }
+ assert( currentPattern != NULL );
+ if( doRecord ){
+ bool bNoteAlreadyExist = false;
+ Note::Key myKey = (Note::Key)0;
+ Note::Octave myOctave = (Note::Octave)0;
+
+ if(pref->__playselectedinstrument){
+ instrRef = song->get_instrument_list()->get( getSelectedInstrumentNumber() );
+ int divider = msg1 / 12;
+ myKey = (Note::Key)(msg1 - (12 * divider));
+ myOctave = (Note::Octave)(divider -3);
+ }
+ else
+ {
+ instrRef = song->get_instrument_list()->get( m_nInstrumentLookupTable[ instrument ] );
+ }
+
+ Note* pNoteold = currentPattern->find_note( column, -1, instrRef, myKey, myOctave );
+ if( pNoteold ) {
+ bNoteAlreadyExist = true;
+ }
+ if ( !pref->__playselectedinstrument ){
+
+ EventQueue::AddMidiNoteVector noteAction;
+ noteAction.m_column = column;
+ noteAction.m_row = m_nInstrumentLookupTable[ instrument ];
+ noteAction.m_pattern = currentPatternNumber;
+ noteAction.f_velocity = velocity;
+ noteAction.f_pan_L = pan_L;
+ noteAction.f_pan_R = pan_R;
+ noteAction.m_length = -1;
+ noteAction.no_octaveKeyVal = (Note::Octave)0;
+ noteAction.nk_noteKeyVal = (Note::Key)0;
+ noteAction.b_isInstrumentMode = false;
+ noteAction.b_isMidi = true;
+ noteAction.b_noteExist = bNoteAlreadyExist;
+ EventQueue::get_instance()->m_addMidiNoteVector.push_back(noteAction);
+
+ // hear note if its not in the future
+ if ( pref->getHearNewNotes()
+ && position <= getTickPosition() ) {
+ hearnote = true;
+ }
+ }
+ else if ( pref->__playselectedinstrument ){
+
+ EventQueue::AddMidiNoteVector noteAction;
+ noteAction.m_column = column;
+ noteAction.m_row = getSelectedInstrumentNumber();
+ noteAction.m_pattern = currentPatternNumber;
+ noteAction.f_velocity = velocity;
+ noteAction.f_pan_L = pan_L;
+ noteAction.f_pan_R = pan_R;
+ noteAction.m_length = -1;
+
+ int divider = msg1 / 12;
+ noteAction.no_octaveKeyVal = (Note::Octave)(divider -3);
+ noteAction.nk_noteKeyVal = (Note::Key)(msg1 - (12 * divider));
+ noteAction.b_isInstrumentMode = true;
+ noteAction.b_isMidi = true;
+ noteAction.b_noteExist = bNoteAlreadyExist;
+ EventQueue::get_instance()->m_addMidiNoteVector.push_back(noteAction);
+
+ // hear note if its not in the future
+ if ( pref->getHearNewNotes()
+ && position <= getTickPosition() ) {
+ hearnote = true;
+ }
+ }
+ }
+ } else if ( pref->getHearNewNotes() ) {
+ hearnote = true;
+ }
+
+ if ( !pref->__playselectedinstrument ){
+ if ( hearnote && instrRef ) {
+ Note *note2 = new Note( instrRef,
+ realcolumn,
+ velocity,
+ pan_L,
+ pan_R,
+ -1,
+ 0 );
+ midi_noteOn( note2 );
+ }
+ }else
+ {
+ if ( hearnote ) {
+ Note *note2 = new Note( song->get_instrument_list()->get( getSelectedInstrumentNumber()),
+ realcolumn,
+ velocity,
+ pan_L,
+ pan_R,
+ -1,
+ 0 );
+
+ int divider = msg1 / 12;
+ Note::Octave octave = (Note::Octave)(divider -3);
+ Note::Key notehigh = (Note::Key)(msg1 - (12 * divider));
+
+ //ERRORLOG( QString( "octave: %1, note: %2, instrument %3" ).arg( octave ).arg(notehigh).arg(instrument));
+ note2->set_midi_info( notehigh, octave, msg1 );
+ midi_noteOn( note2 );
+ }
- }
+ }
- AudioEngine::get_instance()->unlock(); // unlock the audio engine
+ AudioEngine::get_instance()->unlock(); // unlock the audio engine
}
float Hydrogen::getMasterPeak_L()
{
- return m_fMasterPeak_L;
+ return m_fMasterPeak_L;
}
float Hydrogen::getMasterPeak_R()
{
- return m_fMasterPeak_R;
+ return m_fMasterPeak_R;
}
unsigned long Hydrogen::getTickPosition()
{
- return m_nPatternTickPosition;
+ return m_nPatternTickPosition;
}
unsigned long Hydrogen::getRealtimeTickPosition()
{
- //unsigned long initTick = audioEngine_getTickPosition();
- unsigned int initTick = ( unsigned int )( m_nRealtimeFrames
- / m_pAudioDriver->m_transport.m_nTickSize );
- unsigned long retTick;
+ //unsigned long initTick = audioEngine_getTickPosition();
+ unsigned int initTick = ( unsigned int )( m_nRealtimeFrames
+ / m_pAudioDriver->m_transport.m_nTickSize );
+ unsigned long retTick;
- struct timeval currtime;
- struct timeval deltatime;
+ struct timeval currtime;
+ struct timeval deltatime;
- double sampleRate = ( double ) m_pAudioDriver->getSampleRate();
- gettimeofday ( &currtime, NULL );
+ double sampleRate = ( double ) m_pAudioDriver->getSampleRate();
+ gettimeofday ( &currtime, NULL );
- timersub( &currtime, &m_currentTickTime, &deltatime );
+ timersub( &currtime, &m_currentTickTime, &deltatime );
- // add a buffers worth for jitter resistance
- double deltaSec =
- ( double ) deltatime.tv_sec
- + ( deltatime.tv_usec / 1000000.0 )
- + ( m_pAudioDriver->getBufferSize() / ( double )sampleRate );
+ // add a buffers worth for jitter resistance
+ double deltaSec =
+ ( double ) deltatime.tv_sec
+ + ( deltatime.tv_usec / 1000000.0 )
+ + ( m_pAudioDriver->getBufferSize() / ( double )sampleRate );
- retTick = ( unsigned long ) ( ( sampleRate
- / ( double ) m_pAudioDriver->m_transport.m_nTickSize )
- * deltaSec );
+ retTick = ( unsigned long ) ( ( sampleRate
+ / ( double ) m_pAudioDriver->m_transport.m_nTickSize )
+ * deltaSec );
- retTick = initTick + retTick;
+ retTick = initTick + retTick;
- return retTick;
+ return retTick;
}
PatternList* Hydrogen::getCurrentPatternList()
{
- return m_pPlayingPatterns;
+ return m_pPlayingPatterns;
}
PatternList * Hydrogen::getNextPatterns()
{
- return m_pNextPatterns;
+ return m_pNextPatterns;
}
/// Set the next pattern (Pattern mode only)
void Hydrogen::sequencer_setNextPattern( int pos, bool appendPattern, bool deletePattern )
{
- m_bAppendNextPattern = appendPattern;
- m_bDeleteNextPattern = deletePattern;
+ m_bAppendNextPattern = appendPattern;
+ m_bDeleteNextPattern = deletePattern;
- AudioEngine::get_instance()->lock( RIGHT_HERE );
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
- if ( m_pSong && m_pSong->get_mode() == Song::PATTERN_MODE ) {
- PatternList *patternList = m_pSong->get_pattern_list();
- Pattern * p = patternList->get( pos );
- if ( ( pos >= 0 ) && ( pos < ( int )patternList->size() ) ) {
- // if p is already on the next pattern list, delete it.
- if ( m_pNextPatterns->del( p ) == NULL ) {
-// WARNINGLOG( "Adding to nextPatterns" );
- m_pNextPatterns->add( p );
- }/* else {
+ if ( m_pSong && m_pSong->get_mode() == Song::PATTERN_MODE ) {
+ PatternList *patternList = m_pSong->get_pattern_list();
+ Pattern * p = patternList->get( pos );
+ if ( ( pos >= 0 ) && ( pos < ( int )patternList->size() ) ) {
+ // if p is already on the next pattern list, delete it.
+ if ( m_pNextPatterns->del( p ) == NULL ) {
+ // WARNINGLOG( "Adding to nextPatterns" );
+ m_pNextPatterns->add( p );
+ }/* else {
// WARNINGLOG( "Removing " + to_string(pos) );
- }*/
- } else {
- ERRORLOG( QString( "pos not in patternList range. pos=%1 "
- "patternListSize=%2" )
- .arg( pos )
- .arg( patternList->size() ) );
- m_pNextPatterns->clear();
- }
- } else {
- ERRORLOG( "can't set next pattern in song mode" );
- m_pNextPatterns->clear();
- }
+ }*/
+ } else {
+ ERRORLOG( QString( "pos not in patternList range. pos=%1 "
+ "patternListSize=%2" )
+ .arg( pos )
+ .arg( patternList->size() ) );
+ m_pNextPatterns->clear();
+ }
+ } else {
+ ERRORLOG( "can't set next pattern in song mode" );
+ m_pNextPatterns->clear();
+ }
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->unlock();
}
int Hydrogen::getPatternPos()
{
- return m_nSongPos;
+ return m_nSongPos;
}
void Hydrogen::restartDrivers()
{
- audioEngine_restartAudioDrivers();
+ audioEngine_restartAudioDrivers();
}
-
/// Export a song to a wav file, returns the elapsed time in mSec
void Hydrogen::startExportSong( const QString& filename, int rate, int depth )
{
- if ( getState() == STATE_PLAYING ) {
- sequencer_stop();
- }
- AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
- Preferences *pPref = Preferences::get_instance();
-
- m_oldEngineMode = m_pSong->get_mode();
- m_bOldLoopEnabled = m_pSong->is_loop_enabled();
+ if ( getState() == STATE_PLAYING ) {
+ sequencer_stop();
+ }
+ AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
+ Preferences *pPref = Preferences::get_instance();
+
+ m_oldEngineMode = m_pSong->get_mode();
+ m_bOldLoopEnabled = m_pSong->is_loop_enabled();
+
+ m_pSong->set_mode( Song::SONG_MODE );
+ m_pSong->set_loop_enabled( true );
+ // unsigned nSamplerate = m_pAudioDriver->getSampleRate();
+ unsigned nSamplerate = (unsigned)rate;
+ // stop all audio drivers
+ audioEngine_stopAudioDrivers();
- m_pSong->set_mode( Song::SONG_MODE );
- m_pSong->set_loop_enabled( true );
-// unsigned nSamplerate = m_pAudioDriver->getSampleRate();
- unsigned nSamplerate = (unsigned)rate;
- // stop all audio drivers
- audioEngine_stopAudioDrivers();
+ /*
+ FIXME: Questo codice fa davvero schifo....
+ */
- /*
- FIXME: Questo codice fa davvero schifo....
- */
+ m_pAudioDriver = new DiskWriterDriver( audioEngine_process, nSamplerate, filename, depth);
- m_pAudioDriver = new DiskWriterDriver( audioEngine_process, nSamplerate, filename, depth);
-
- // reset
- m_pAudioDriver->m_transport.m_nFrames = 0; // reset total frames
- m_pAudioDriver->setBpm( m_pSong->__bpm );
- m_nSongPos = 0;
- m_nPatternTickPosition = 0;
- m_audioEngineState = STATE_PLAYING;
- m_nPatternStartTick = -1;
+ // reset
+ m_pAudioDriver->m_transport.m_nFrames = 0; // reset total frames
+ //m_pAudioDriver->setBpm( m_pSong->__bpm );
+ m_nSongPos = 0;
+ m_nPatternTickPosition = 0;
+ m_audioEngineState = STATE_PLAYING;
+ m_nPatternStartTick = -1;
- int res = m_pAudioDriver->init( pPref->m_nBufferSize );
- if ( res != 0 ) {
- ERRORLOG( "Error starting disk writer driver "
- "[DiskWriterDriver::init()]" );
- }
+ int res = m_pAudioDriver->init( pPref->m_nBufferSize );
+ if ( res != 0 ) {
+ ERRORLOG( "Error starting disk writer driver "
+ "[DiskWriterDriver::init()]" );
+ }
- m_pMainBuffer_L = m_pAudioDriver->getOut_L();
- m_pMainBuffer_R = m_pAudioDriver->getOut_R();
+ m_pMainBuffer_L = m_pAudioDriver->getOut_L();
+ m_pMainBuffer_R = m_pAudioDriver->getOut_R();
- audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
+ audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
- audioEngine_seek( 0, false );
+ audioEngine_seek( 0, false );
- res = m_pAudioDriver->connect();
- if ( res != 0 ) {
- ERRORLOG( "Error starting disk writer driver "
- "[DiskWriterDriver::connect()]" );
- }
+ res = m_pAudioDriver->connect();
+ if ( res != 0 ) {
+ ERRORLOG( "Error starting disk writer driver "
+ "[DiskWriterDriver::connect()]" );
+ }
}
+void Hydrogen::stopExportSong( bool reconnectOldDriver )
+{
+ if ( m_pAudioDriver->class_name() != DiskWriterDriver::class_name() ) {
+ return;
+ }
+ // audioEngine_stopAudioDrivers();
+ m_pAudioDriver->disconnect();
-void Hydrogen::stopExportSong()
-{
- if ( m_pAudioDriver->class_name() != DiskWriterDriver::class_name() ) {
- return;
- }
+ m_audioEngineState = STATE_INITIALIZED;
+ delete m_pAudioDriver;
+ m_pAudioDriver = NULL;
-// audioEngine_stopAudioDrivers();
- m_pAudioDriver->disconnect();
+ m_pMainBuffer_L = NULL;
+ m_pMainBuffer_R = NULL;
- m_audioEngineState = STATE_INITIALIZED;
- delete m_pAudioDriver;
- m_pAudioDriver = NULL;
+ m_pSong->set_mode( m_oldEngineMode );
+ m_pSong->set_loop_enabled( m_bOldLoopEnabled );
- m_pMainBuffer_L = NULL;
- m_pMainBuffer_R = NULL;
+ m_nSongPos = -1;
+ m_nPatternTickPosition = 0;
- m_pSong->set_mode( m_oldEngineMode );
- m_pSong->set_loop_enabled( m_bOldLoopEnabled );
+ if(!reconnectOldDriver) return;
- m_nSongPos = -1;
- m_nPatternTickPosition = 0;
- audioEngine_startAudioDrivers();
+ audioEngine_startAudioDrivers();
- if ( m_pAudioDriver ) {
- m_pAudioDriver->setBpm( m_pSong->__bpm );
- } else {
- ERRORLOG( "m_pAudioDriver = NULL" );
- }
+ if ( m_pAudioDriver ) {
+ m_pAudioDriver->setBpm( m_pSong->__bpm );
+ } else {
+ ERRORLOG( "m_pAudioDriver = NULL" );
+ }
}
-
/// Used to display audio driver info
AudioOutput* Hydrogen::getAudioOutput()
{
- return m_pAudioDriver;
+ return m_pAudioDriver;
}
@@ -2455,152 +2515,152 @@
/// Used to display midi driver info
MidiInput* Hydrogen::getMidiInput()
{
- return m_pMidiDriver;
+ return m_pMidiDriver;
}
MidiOutput* Hydrogen::getMidiOutput()
{
- return m_pMidiDriverOut;
+ return m_pMidiDriverOut;
}
void Hydrogen::setMasterPeak_L( float value )
{
- m_fMasterPeak_L = value;
+ m_fMasterPeak_L = value;
}
void Hydrogen::setMasterPeak_R( float value )
{
- m_fMasterPeak_R = value;
+ m_fMasterPeak_R = value;
}
int Hydrogen::getState()
{
- return m_audioEngineState;
+ return m_audioEngineState;
}
void Hydrogen::setCurrentPatternList( PatternList *pPatternList )
{
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- m_pPlayingPatterns = pPatternList;
- EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ m_pPlayingPatterns = pPatternList;
+ EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
+ AudioEngine::get_instance()->unlock();
}
float Hydrogen::getProcessTime()
{
- return m_fProcessTime;
+ return m_fProcessTime;
}
float Hydrogen::getMaxProcessTime()
{
- return m_fMaxProcessTime;
+ return m_fMaxProcessTime;
}
int Hydrogen::loadDrumkit( Drumkit *drumkitInfo )
{
- int old_ae_state = m_audioEngineState;
- if( m_audioEngineState >= STATE_READY ) {
- m_audioEngineState = STATE_PREPARED;
- }
-
- INFOLOG( drumkitInfo->get_name() );
- m_currentDrumkit = drumkitInfo->get_name();
- LocalFileMng fileMng;
- QString sDrumkitPath = Filesystem::drumkit_path_search( drumkitInfo->get_name() );
-
-
- //current instrument list
- InstrumentList *songInstrList = m_pSong->get_instrument_list();
-
- //new instrument list
- InstrumentList *pDrumkitInstrList = drumkitInfo->get_instruments();
-
- /*
- If the old drumkit is bigger then the new drumkit,
- delete all instruments with a bigger pos then
- pDrumkitInstrList->size(). Otherwise the instruments
- from our old instrumentlist with
- pos > pDrumkitInstrList->size() stay in the
- new instrumentlist
-
- wolke: info!
- this has moved to the end of this function
- because we get lost objects in memory
- now:
- 1. the new drumkit will loaded
- 2. all not used instruments will complete deleted
-
- old funktion:
- while ( pDrumkitInstrList->size() < songInstrList->size() )
- {
- songInstrList->del(songInstrList->size() - 1);
- }
- */
-
- //needed for the new delete function
- int instrumentDiff = songInstrList->size() - pDrumkitInstrList->size();
-
- for ( unsigned nInstr = 0; nInstr < pDrumkitInstrList->size(); ++nInstr ) {
- Instrument *pInstr = NULL;
- if ( nInstr < songInstrList->size() ) {
- //instrument exists already
- pInstr = songInstrList->get( nInstr );
- assert( pInstr );
- } else {
- pInstr = new Instrument();
- // The instrument isn't playing yet; no need for locking
- // :-) - Jakob Lund. AudioEngine::get_instance()->lock(
- // "Hydrogen::loadDrumkit" );
- songInstrList->add( pInstr );
- // AudioEngine::get_instance()->unlock();
- }
-
- Instrument *pNewInstr = pDrumkitInstrList->get( nInstr );
- assert( pNewInstr );
- INFOLOG( QString( "Loading instrument (%1 of %2) [%3]" )
- .arg( nInstr )
- .arg( pDrumkitInstrList->size() )
- .arg( pNewInstr->get_name() ) );
-
- // creo i nuovi layer in base al nuovo strumento
- // Moved code from here right into the Instrument class - Jakob Lund.
- pInstr->load_from( drumkitInfo, pNewInstr );
- }
-
-
-//wolke: new delete funktion
- if ( instrumentDiff >=0 ){
- for ( int i = 0; i < instrumentDiff ; i++ ){
- removeInstrument(
- m_pSong->get_instrument_list()->size() - 1,
- true
- );
- }
- }
-
- #ifdef H2CORE_HAVE_JACK
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- renameJackPorts();
- AudioEngine::get_instance()->unlock();
- #endif
+ int old_ae_state = m_audioEngineState;
+ if( m_audioEngineState >= STATE_READY ) {
+ m_audioEngineState = STATE_PREPARED;
+ }
+
+ INFOLOG( drumkitInfo->get_name() );
+ m_currentDrumkit = drumkitInfo->get_name();
+ LocalFileMng fileMng;
+ QString sDrumkitPath = Filesystem::drumkit_path_search( drumkitInfo->get_name() );
+
+
+ //current instrument list
+ InstrumentList *songInstrList = m_pSong->get_instrument_list();
+
+ //new instrument list
+ InstrumentList *pDrumkitInstrList = drumkitInfo->get_instruments();
+
+ /*
+ If the old drumkit is bigger then the new drumkit,
+ delete all instruments with a bigger pos then
+ pDrumkitInstrList->size(). Otherwise the instruments
+ from our old instrumentlist with
+ pos > pDrumkitInstrList->size() stay in the
+ new instrumentlist
+
+ wolke: info!
+ this has moved to the end of this function
+ because we get lost objects in memory
+ now:
+ 1. the new drumkit will loaded
+ 2. all not used instruments will complete deleted
+
+ old funktion:
+ while ( pDrumkitInstrList->size() < songInstrList->size() )
+ {
+ songInstrList->del(songInstrList->size() - 1);
+ }
+ */
+
+ //needed for the new delete function
+ int instrumentDiff = songInstrList->size() - pDrumkitInstrList->size();
- m_audioEngineState = old_ae_state;
+ for ( unsigned nInstr = 0; nInstr < pDrumkitInstrList->size(); ++nInstr ) {
+ Instrument *pInstr = NULL;
+ if ( nInstr < songInstrList->size() ) {
+ //instrument exists already
+ pInstr = songInstrList->get( nInstr );
+ assert( pInstr );
+ } else {
+ pInstr = new Instrument();
+ // The instrument isn't playing yet; no need for locking
+ // :-) - Jakob Lund. AudioEngine::get_instance()->lock(
+ // "Hydrogen::loadDrumkit" );
+ songInstrList->add( pInstr );
+ // AudioEngine::get_instance()->unlock();
+ }
+
+ Instrument *pNewInstr = pDrumkitInstrList->get( nInstr );
+ assert( pNewInstr );
+ INFOLOG( QString( "Loading instrument (%1 of %2) [%3]" )
+ .arg( nInstr )
+ .arg( pDrumkitInstrList->size() )
+ .arg( pNewInstr->get_name() ) );
+
+ // creo i nuovi layer in base al nuovo strumento
+ // Moved code from here right into the Instrument class - Jakob Lund.
+ pInstr->load_from( drumkitInfo, pNewInstr );
+ }
+
+
+ //wolke: new delete funktion
+ if ( instrumentDiff >=0 ){
+ for ( int i = 0; i < instrumentDiff ; i++ ){
+ removeInstrument(
+ m_pSong->get_instrument_list()->size() - 1,
+ true
+ );
+ }
+ }
- return 0; //ok
+#ifdef H2CORE_HAVE_JACK
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ renameJackPorts();
+ AudioEngine::get_instance()->unlock();
+#endif
+
+ m_audioEngineState = old_ae_state;
+
+ return 0; //ok
}
@@ -2608,89 +2668,89 @@
//Hydrogen::loadDrumkit to delete the instruments by number
void Hydrogen::removeInstrument( int instrumentnumber, bool conditional )
{
- Instrument *pInstr = m_pSong->get_instrument_list()->get( instrumentnumber );
+ Instrument *pInstr = m_pSong->get_instrument_list()->get( instrumentnumber );
- PatternList* pPatternList = getSong()->get_pattern_list();
-
- if ( conditional ) {
- // new! this check if a pattern has an active note if there is an note
- //inside the pattern the intrument would not be deleted
- for ( int nPattern = 0 ;
- nPattern < (int)pPatternList->size() ;
- ++nPattern ) {
- if( pPatternList
- ->get( nPattern )
- ->references( pInstr ) ) {
- return;
- }
- }
- } else {
- getSong()->purge_instrument( pInstr );
- }
-
- Song *pSong = getSong();
- InstrumentList* pList = pSong->get_instrument_list();
- if(pList->size()==1){
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- Instrument* pInstr = pList->get( 0 );
- pInstr->set_name( (QString( "Instrument 1" )) );
- // remove all layers
- for ( int nLayer = 0; nLayer < MAX_LAYERS; nLayer++ ) {
- InstrumentLayer* pLayer = pInstr->get_layer( nLayer );
- delete pLayer;
- pInstr->set_layer( NULL, nLayer );
- }
- AudioEngine::get_instance()->unlock();
- EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
- INFOLOG("clear last instrument to empty instrument 1 instead delete the last instrument");
- return;
- }
-
- // if the instrument was the last on the instruments list, select the
- // next-last
- if ( instrumentnumber
- >= (int)getSong()->get_instrument_list()->size() - 1 ) {
- Hydrogen::get_instance()
- ->setSelectedInstrumentNumber(
- std::max(0, instrumentnumber - 1)
- );
- }
- // delete the instrument from the instruments list
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- getSong()->get_instrument_list()->del( instrumentnumber );
- getSong()->__is_modified = true;
- AudioEngine::get_instance()->unlock();
-
- // At this point the instrument has been removed from both the
- // instrument list and every pattern in the song. Hence there's no way
- // (NOTE) to play on that instrument, and once all notes have stopped
- // playing it will be save to delete.
- // the ugly name is just for debugging...
- QString xxx_name = QString( "XXX_%1" ) . arg( pInstr->get_name() );
- pInstr->set_name( xxx_name );
- __instrument_death_row.push_back( pInstr );
- __kill_instruments(); // checks if there are still notes.
-
- // this will force a GUI update.
- EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
+ PatternList* pPatternList = getSong()->get_pattern_list();
+
+ if ( conditional ) {
+ // new! this check if a pattern has an active note if there is an note
+ //inside the pattern the intrument would not be deleted
+ for ( int nPattern = 0 ;
+ nPattern < (int)pPatternList->size() ;
+ ++nPattern ) {
+ if( pPatternList
+ ->get( nPattern )
+ ->references( pInstr ) ) {
+ return;
+ }
+ }
+ } else {
+ getSong()->purge_instrument( pInstr );
+ }
+
+ Song *pSong = getSong();
+ InstrumentList* pList = pSong->get_instrument_list();
+ if(pList->size()==1){
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ Instrument* pInstr = pList->get( 0 );
+ pInstr->set_name( (QString( "Instrument 1" )) );
+ // remove all layers
+ for ( int nLayer = 0; nLayer < MAX_LAYERS; nLayer++ ) {
+ InstrumentLayer* pLayer = pInstr->get_layer( nLayer );
+ delete pLayer;
+ pInstr->set_layer( NULL, nLayer );
+ }
+ AudioEngine::get_instance()->unlock();
+ EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
+ INFOLOG("clear last instrument to empty instrument 1 instead delete the last instrument");
+ return;
+ }
+
+ // if the instrument was the last on the instruments list, select the
+ // next-last
+ if ( instrumentnumber
+ >= (int)getSong()->get_instrument_list()->size() - 1 ) {
+ Hydrogen::get_instance()
+ ->setSelectedInstrumentNumber(
+ std::max(0, instrumentnumber - 1)
+ );
+ }
+ // delete the instrument from the instruments list
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ getSong()->get_instrument_list()->del( instrumentnumber );
+ getSong()->__is_modified = true;
+ AudioEngine::get_instance()->unlock();
+
+ // At this point the instrument has been removed from both the
+ // instrument list and every pattern in the song. Hence there's no way
+ // (NOTE) to play on that instrument, and once all notes have stopped
+ // playing it will be save to delete.
+ // the ugly name is just for debugging...
+ QString xxx_name = QString( "XXX_%1" ) . arg( pInstr->get_name() );
+ pInstr->set_name( xxx_name );
+ __instrument_death_row.push_back( pInstr );
+ __kill_instruments(); // checks if there are still notes.
+
+ // this will force a GUI update.
+ EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
}
void Hydrogen::raiseError( unsigned nErrorCode )
{
- audioEngine_raiseError( nErrorCode );
+ audioEngine_raiseError( nErrorCode );
}
unsigned long Hydrogen::getTotalFrames()
{
- return m_pAudioDriver->m_transport.m_nFrames;
+ return m_pAudioDriver->m_transport.m_nFrames;
}
unsigned long Hydrogen::getRealtimeFrames()
{
- return m_nRealtimeFrames;
+ return m_nRealtimeFrames;
}
/**
@@ -2701,68 +2761,68 @@
*/
long Hydrogen::getTickForPosition( int pos )
{
- int nPatternGroups = m_pSong->get_pattern_group_vector()->size();
- if( nPatternGroups == 0 ) return -1;
+ int nPatternGroups = m_pSong->get_pattern_group_vector()->size();
+ if( nPatternGroups == 0 ) return -1;
- if ( pos >= nPatternGroups ) {
- if ( m_pSong->is_loop_enabled() ) {
- pos = pos % nPatternGroups;
- } else {
- WARNINGLOG( QString( "patternPos > nPatternGroups. pos:"
- " %1, nPatternGroups: %2")
- .arg( pos )
- .arg( nPatternGroups ) );
- return -1;
- }
- }
-
- std::vector *pColumns = m_pSong->get_pattern_group_vector();
- long totalTick = 0;
- int nPatternSize;
- Pattern *pPattern = NULL;
- for ( int i = 0; i < pos; ++i ) {
- PatternList *pColumn = ( *pColumns )[ i ];
- // prendo solo il primo. I pattern nel gruppo devono avere la
- // stessa lunghezza
- pPattern = pColumn->get( 0 );
- if ( pPattern ) {
- nPatternSize = pPattern->get_length();
- } else {
- nPatternSize = MAX_NOTES;
- }
-
- totalTick += nPatternSize;
- }
- return totalTick;
+ if ( pos >= nPatternGroups ) {
+ if ( m_pSong->is_loop_enabled() ) {
+ pos = pos % nPatternGroups;
+ } else {
+ WARNINGLOG( QString( "patternPos > nPatternGroups. pos:"
+ " %1, nPatternGroups: %2")
+ .arg( pos )
+ .arg( nPatternGroups ) );
+ return -1;
+ }
+ }
+
+ std::vector *pColumns = m_pSong->get_pattern_group_vector();
+ long totalTick = 0;
+ int nPatternSize;
+ Pattern *pPattern = NULL;
+ for ( int i = 0; i < pos; ++i ) {
+ PatternList *pColumn = ( *pColumns )[ i ];
+ // prendo solo il primo. I pattern nel gruppo devono avere la
+ // stessa lunghezza
+ pPattern = pColumn->get( 0 );
+ if ( pPattern ) {
+ nPatternSize = pPattern->get_length();
+ } else {
+ nPatternSize = MAX_NOTES;
+ }
+
+ totalTick += nPatternSize;
+ }
+ return totalTick;
}
/// Set the position in the song
void Hydrogen::setPatternPos( int pos )
{
- if ( pos < -1 )
- pos = -1;
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- EventQueue::get_instance()->push_event( EVENT_METRONOME, 1 );
- long totalTick = getTickForPosition( pos );
- if ( totalTick < 0 ) {
- AudioEngine::get_instance()->unlock();
- return;
- }
-
- if ( getState() != STATE_PLAYING ) {
- // find pattern immediately when not playing
-// int dummy;
-// m_nSongPos = findPatternInTick( totalTick,
-// m_pSong->is_loop_enabled(),
-// &dummy );
- m_nSongPos = pos;
- m_nPatternTickPosition = 0;
- }
- m_pAudioDriver->locate(
- ( int ) ( totalTick * m_pAudioDriver->m_transport.m_nTickSize )
- );
+ if ( pos < -1 )
+ pos = -1;
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ EventQueue::get_instance()->push_event( EVENT_METRONOME, 1 );
+ long totalTick = getTickForPosition( pos );
+ if ( totalTick < 0 ) {
+ AudioEngine::get_instance()->unlock();
+ return;
+ }
+
+ if ( getState() != STATE_PLAYING ) {
+ // find pattern immediately when not playing
+ // int dummy;
+ // m_nSongPos = findPatternInTick( totalTick,
+ // m_pSong->is_loop_enabled(),
+ // &dummy );
+ m_nSongPos = pos;
+ m_nPatternTickPosition = 0;
+ }
+ m_pAudioDriver->locate(
+ ( int ) ( totalTick * m_pAudioDriver->m_transport.m_nTickSize )
+ );
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->unlock();
}
@@ -2771,11 +2831,11 @@
void Hydrogen::getLadspaFXPeak( int nFX, float *fL, float *fR )
{
#ifdef H2CORE_HAVE_LADSPA
- ( *fL ) = m_fFXPeak_L[nFX];
- ( *fR ) = m_fFXPeak_R[nFX];
+ ( *fL ) = m_fFXPeak_L[nFX];
+ ( *fR ) = m_fFXPeak_R[nFX];
#else
- ( *fL ) = 0;
- ( *fR ) = 0;
+ ( *fL ) = 0;
+ ( *fR ) = 0;
#endif
}
@@ -2784,8 +2844,8 @@
void Hydrogen::setLadspaFXPeak( int nFX, float fL, float fR )
{
#ifdef H2CORE_HAVE_LADSPA
- m_fFXPeak_L[nFX] = fL;
- m_fFXPeak_R[nFX] = fR;
+ m_fFXPeak_L[nFX] = fL;
+ m_fFXPeak_R[nFX] = fR;
#endif
}
@@ -2793,176 +2853,176 @@
void Hydrogen::onTapTempoAccelEvent()
{
#ifndef WIN32
- INFOLOG( "tap tempo" );
- static timeval oldTimeVal;
+ INFOLOG( "tap tempo" );
+ static timeval oldTimeVal;
- struct timeval now;
- gettimeofday(&now, NULL);
+ struct timeval now;
+ gettimeofday(&now, NULL);
- float fInterval =
- (now.tv_sec - oldTimeVal.tv_sec) * 1000.0
- + (now.tv_usec - oldTimeVal.tv_usec) / 1000.0;
+ float fInterval =
+ (now.tv_sec - oldTimeVal.tv_sec) * 1000.0
+ + (now.tv_usec - oldTimeVal.tv_usec) / 1000.0;
- oldTimeVal = now;
+ oldTimeVal = now;
- if ( fInterval < 1000.0 ) {
- setTapTempo( fInterval );
- }
+ if ( fInterval < 1000.0 ) {
+ setTapTempo( fInterval );
+ }
#endif
}
void Hydrogen::setTapTempo( float fInterval )
{
-// infoLog( "set tap tempo" );
- static float fOldBpm1 = -1;
- static float fOldBpm2 = -1;
- static float fOldBpm3 = -1;
- static float fOldBpm4 = -1;
- static float fOldBpm5 = -1;
- static float fOldBpm6 = -1;
- static float fOldBpm7 = -1;
- static float fOldBpm8 = -1;
-
- float fBPM = 60000.0 / fInterval;
-
- if ( fabs( fOldBpm1 - fBPM ) > 20 ) { // troppa differenza, niente media
- fOldBpm1 = fBPM;
- fOldBpm2 = fBPM;
- fOldBpm3 = fBPM;
- fOldBpm4 = fBPM;
- fOldBpm5 = fBPM;
- fOldBpm6 = fBPM;
- fOldBpm7 = fBPM;
- fOldBpm8 = fBPM;
- }
-
- if ( fOldBpm1 == -1 ) {
- fOldBpm1 = fBPM;
- fOldBpm2 = fBPM;
- fOldBpm3 = fBPM;
- fOldBpm4 = fBPM;
- fOldBpm5 = fBPM;
- fOldBpm6 = fBPM;
- fOldBpm7 = fBPM;
- fOldBpm8 = fBPM;
- }
-
- fBPM = ( fBPM + fOldBpm1 + fOldBpm2 + fOldBpm3 + fOldBpm4 + fOldBpm5
- + fOldBpm6 + fOldBpm7 + fOldBpm8 ) / 9.0;
-
-
- INFOLOG( QString( "avg BPM = %1" ).arg( fBPM ) );
- fOldBpm8 = fOldBpm7;
- fOldBpm7 = fOldBpm6;
- fOldBpm6 = fOldBpm5;
- fOldBpm5 = fOldBpm4;
- fOldBpm4 = fOldBpm3;
- fOldBpm3 = fOldBpm2;
- fOldBpm2 = fOldBpm1;
- fOldBpm1 = fBPM;
+ // infoLog( "set tap tempo" );
+ static float fOldBpm1 = -1;
+ static float fOldBpm2 = -1;
+ static float fOldBpm3 = -1;
+ static float fOldBpm4 = -1;
+ static float fOldBpm5 = -1;
+ static float fOldBpm6 = -1;
+ static float fOldBpm7 = -1;
+ static float fOldBpm8 = -1;
+
+ float fBPM = 60000.0 / fInterval;
+
+ if ( fabs( fOldBpm1 - fBPM ) > 20 ) { // troppa differenza, niente media
+ fOldBpm1 = fBPM;
+ fOldBpm2 = fBPM;
+ fOldBpm3 = fBPM;
+ fOldBpm4 = fBPM;
+ fOldBpm5 = fBPM;
+ fOldBpm6 = fBPM;
+ fOldBpm7 = fBPM;
+ fOldBpm8 = fBPM;
+ }
+
+ if ( fOldBpm1 == -1 ) {
+ fOldBpm1 = fBPM;
+ fOldBpm2 = fBPM;
+ fOldBpm3 = fBPM;
+ fOldBpm4 = fBPM;
+ fOldBpm5 = fBPM;
+ fOldBpm6 = fBPM;
+ fOldBpm7 = fBPM;
+ fOldBpm8 = fBPM;
+ }
+
+ fBPM = ( fBPM + fOldBpm1 + fOldBpm2 + fOldBpm3 + fOldBpm4 + fOldBpm5
+ + fOldBpm6 + fOldBpm7 + fOldBpm8 ) / 9.0;
+
+
+ INFOLOG( QString( "avg BPM = %1" ).arg( fBPM ) );
+ fOldBpm8 = fOldBpm7;
+ fOldBpm7 = fOldBpm6;
+ fOldBpm6 = fOldBpm5;
+ fOldBpm5 = fOldBpm4;
+ fOldBpm4 = fOldBpm3;
+ fOldBpm3 = fOldBpm2;
+ fOldBpm2 = fOldBpm1;
+ fOldBpm1 = fBPM;
- AudioEngine::get_instance()->lock( RIGHT_HERE );
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
-// m_pAudioDriver->setBpm( fBPM );
-// m_pSong->setBpm( fBPM );
+ // m_pAudioDriver->setBpm( fBPM );
+ // m_pSong->setBpm( fBPM );
- setBPM( fBPM );
+ setBPM( fBPM );
- AudioEngine::get_instance()->unlock();
+ AudioEngine::get_instance()->unlock();
}
// Called with audioEngine in LOCKED state.
void Hydrogen::setBPM( float fBPM )
{
- if ( m_pAudioDriver && m_pSong ) {
- m_pAudioDriver->setBpm( fBPM );
- m_pSong->__bpm = fBPM;
- m_nNewBpmJTM = fBPM;
-// audioEngine_process_checkBPMChanged();
- }
+ if ( m_pAudioDriver && m_pSong ) {
+ m_pAudioDriver->setBpm( fBPM );
+ m_pSong->__bpm = fBPM;
+ m_nNewBpmJTM = fBPM;
+ // audioEngine_process_checkBPMChanged();
+ }
}
void Hydrogen::restartLadspaFX()
{
- if ( m_pAudioDriver ) {
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
- AudioEngine::get_instance()->unlock();
- } else {
- ERRORLOG( "m_pAudioDriver = NULL" );
- }
+ if ( m_pAudioDriver ) {
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
+ AudioEngine::get_instance()->unlock();
+ } else {
+ ERRORLOG( "m_pAudioDriver = NULL" );
+ }
}
int Hydrogen::getSelectedPatternNumber()
{
- return m_nSelectedPatternNumber;
+ return m_nSelectedPatternNumber;
}
void Hydrogen::setSelectedPatternNumberWithoutGuiEvent( int nPat )
{
- if ( nPat == m_nSelectedPatternNumber
- || ( nPat + 1 > m_pSong->get_pattern_list()->size() ) )
- return;
-
- if ( Preferences::get_instance()->patternModePlaysSelected() ) {
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
- m_nSelectedPatternNumber = nPat;
- AudioEngine::get_instance()->unlock();
- } else {
- m_nSelectedPatternNumber = nPat;
- }
+ if ( nPat == m_nSelectedPatternNumber
+ || ( nPat + 1 > m_pSong->get_pattern_list()->size() ) )
+ return;
+
+ if ( Preferences::get_instance()->patternModePlaysSelected() ) {
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ m_nSelectedPatternNumber = nPat;
+ AudioEngine::get_instance()->unlock();
+ } else {
+ m_nSelectedPatternNumber = nPat;
+ }
}
void Hydrogen::setSelectedPatternNumber( int nPat )
{
- // FIXME: controllare se e' valido..
- if ( nPat == m_nSelectedPatternNumber ) return;
-
-
- if ( Preferences::get_instance()->patternModePlaysSelected() ) {
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
- m_nSelectedPatternNumber = nPat;
- AudioEngine::get_instance()->unlock();
- } else {
- m_nSelectedPatternNumber = nPat;
- }
+ // FIXME: controllare se e' valido..
+ if ( nPat == m_nSelectedPatternNumber ) return;
+
- EventQueue::get_instance()->push_event( EVENT_SELECTED_PATTERN_CHANGED, -1 );
+ if ( Preferences::get_instance()->patternModePlaysSelected() ) {
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ m_nSelectedPatternNumber = nPat;
+ AudioEngine::get_instance()->unlock();
+ } else {
+ m_nSelectedPatternNumber = nPat;
+ }
+
+ EventQueue::get_instance()->push_event( EVENT_SELECTED_PATTERN_CHANGED, -1 );
}
int Hydrogen::getSelectedInstrumentNumber()
{
- return m_nSelectedInstrumentNumber;
+ return m_nSelectedInstrumentNumber;
}
void Hydrogen::setSelectedInstrumentNumber( int nInstrument )
{
- if ( m_nSelectedInstrumentNumber == nInstrument ) return;
+ if ( m_nSelectedInstrumentNumber == nInstrument ) return;
- m_nSelectedInstrumentNumber = nInstrument;
- EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
+ m_nSelectedInstrumentNumber = nInstrument;
+ EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
}
#ifdef H2CORE_HAVE_JACK
void Hydrogen::renameJackPorts()
{
- if( Preferences::get_instance()->m_bJackTrackOuts == true ){
- audioEngine_renameJackPorts();
- }
+ if( Preferences::get_instance()->m_bJackTrackOuts == true ){
+ audioEngine_renameJackPorts();
+ }
}
#endif
@@ -2971,161 +3031,161 @@
void Hydrogen::setbeatsToCount( int beatstocount)
{
- m_nbeatsToCount = beatstocount;
+ m_nbeatsToCount = beatstocount;
}
int Hydrogen::getbeatsToCount()
{
- return m_nbeatsToCount;
+ return m_nbeatsToCount;
}
void Hydrogen::setNoteLength( float notelength)
{
- m_ntaktoMeterCompute = notelength;
+ m_ntaktoMeterCompute = notelength;
}
float Hydrogen::getNoteLength()
{
- return m_ntaktoMeterCompute;
+ return m_ntaktoMeterCompute;
}
int Hydrogen::getBcStatus()
{
- return eventCount;
+ return eventCount;
}
void Hydrogen::setBcOffsetAdjust()
{
- //individual fine tuning for the beatcounter
- //to adjust ms_offset from different people and controller
- Preferences *pref = Preferences::get_instance();
+ //individual fine tuning for the beatcounter
+ //to adjust ms_offset from different people and controller
+ Preferences *pref = Preferences::get_instance();
- m_nCoutOffset = pref->m_countOffset;
- m_nStartOffset = pref->m_startOffset;
+ m_nCoutOffset = pref->m_countOffset;
+ m_nStartOffset = pref->m_startOffset;
}
void Hydrogen::handleBeatCounter()
{
- // Get first time value:
- if (beatCount == 1)
- gettimeofday(¤tTime,NULL);
-
- eventCount++;
-
- // Set wlastTime to wcurrentTime to remind the time:
- lastTime = currentTime;
-
- // Get new time:
- gettimeofday(¤tTime,NULL);
-
-
- // Build doubled time difference:
- lastBeatTime = (double)(
- lastTime.tv_sec
- + (double)(lastTime.tv_usec * US_DIVIDER)
- + (int)m_nCoutOffset * .0001
- );
- currentBeatTime = (double)(
- currentTime.tv_sec
- + (double)(currentTime.tv_usec * US_DIVIDER)
- );
- beatDiff = beatCount == 1 ? 0 : currentBeatTime - lastBeatTime;
-
- //if differences are to big reset the beatconter
- if( beatDiff > 3.001 * 1/m_ntaktoMeterCompute ){
- eventCount = 1;
- beatCount = 1;
- return;
- }
- // Only accept differences big enough
- if (beatCount == 1 || beatDiff > .001) {
- if (beatCount > 1)
- beatDiffs[beatCount - 2] = beatDiff ;
- // Compute and reset:
- if (beatCount == m_nbeatsToCount){
- // unsigned long currentframe = getRealtimeFrames();
- double beatTotalDiffs = 0;
- for(int i = 0; i < (m_nbeatsToCount - 1); i++)
- beatTotalDiffs += beatDiffs[i];
- double beatDiffAverage =
- beatTotalDiffs
- / (beatCount - 1)
- * m_ntaktoMeterCompute ;
- beatCountBpm =
- (float) ((int) (60 / beatDiffAverage * 100))
- / 100;
- AudioEngine::get_instance()->lock( RIGHT_HERE );
- if ( beatCountBpm > 500)
- beatCountBpm = 500;
- setBPM( beatCountBpm );
- AudioEngine::get_instance()->unlock();
- if (Preferences::get_instance()->m_mmcsetplay
- == Preferences::SET_PLAY_OFF) {
- beatCount = 1;
- eventCount = 1;
- }else{
- if ( m_audioEngineState != STATE_PLAYING ){
- unsigned bcsamplerate =
- m_pAudioDriver->getSampleRate();
- unsigned long rtstartframe = 0;
- if ( m_ntaktoMeterCompute <= 1){
- rtstartframe =
- bcsamplerate
- * beatDiffAverage
- * ( 1/ m_ntaktoMeterCompute );
- }else
- {
- rtstartframe =
- bcsamplerate
- * beatDiffAverage
- / m_ntaktoMeterCompute ;
- }
-
- int sleeptime =
- ( (float) rtstartframe
- / (float) bcsamplerate
- * (int) 1000 )
- + (int)m_nCoutOffset
- + (int) m_nStartOffset;
+ // Get first time value:
+ if (beatCount == 1)
+ gettimeofday(¤tTime,NULL);
+
+ eventCount++;
+
+ // Set wlastTime to wcurrentTime to remind the time:
+ lastTime = currentTime;
+
+ // Get new time:
+ gettimeofday(¤tTime,NULL);
+
+
+ // Build doubled time difference:
+ lastBeatTime = (double)(
+ lastTime.tv_sec
+ + (double)(lastTime.tv_usec * US_DIVIDER)
+ + (int)m_nCoutOffset * .0001
+ );
+ currentBeatTime = (double)(
+ currentTime.tv_sec
+ + (double)(currentTime.tv_usec * US_DIVIDER)
+ );
+ beatDiff = beatCount == 1 ? 0 : currentBeatTime - lastBeatTime;
+
+ //if differences are to big reset the beatconter
+ if( beatDiff > 3.001 * 1/m_ntaktoMeterCompute ){
+ eventCount = 1;
+ beatCount = 1;
+ return;
+ }
+ // Only accept differences big enough
+ if (beatCount == 1 || beatDiff > .001) {
+ if (beatCount > 1)
+ beatDiffs[beatCount - 2] = beatDiff ;
+ // Compute and reset:
+ if (beatCount == m_nbeatsToCount){
+ // unsigned long currentframe = getRealtimeFrames();
+ double beatTotalDiffs = 0;
+ for(int i = 0; i < (m_nbeatsToCount - 1); i++)
+ beatTotalDiffs += beatDiffs[i];
+ double beatDiffAverage =
+ beatTotalDiffs
+ / (beatCount - 1)
+ * m_ntaktoMeterCompute ;
+ beatCountBpm =
+ (float) ((int) (60 / beatDiffAverage * 100))
+ / 100;
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ if ( beatCountBpm > 500)
+ beatCountBpm = 500;
+ setBPM( beatCountBpm );
+ AudioEngine::get_instance()->unlock();
+ if (Preferences::get_instance()->m_mmcsetplay
+ == Preferences::SET_PLAY_OFF) {
+ beatCount = 1;
+ eventCount = 1;
+ }else{
+ if ( m_audioEngineState != STATE_PLAYING ){
+ unsigned bcsamplerate =
+ m_pAudioDriver->getSampleRate();
+ unsigned long rtstartframe = 0;
+ if ( m_ntaktoMeterCompute <= 1){
+ rtstartframe =
+ bcsamplerate
+ * beatDiffAverage
+ * ( 1/ m_ntaktoMeterCompute );
+ }else
+ {
+ rtstartframe =
+ bcsamplerate
+ * beatDiffAverage
+ / m_ntaktoMeterCompute ;
+ }
+
+ int sleeptime =
+ ( (float) rtstartframe
+ / (float) bcsamplerate
+ * (int) 1000 )
+ + (int)m_nCoutOffset
+ + (int) m_nStartOffset;
#ifdef WIN32
- Sleep( sleeptime );
+ Sleep( sleeptime );
#else
- usleep( 1000 * sleeptime );
+ usleep( 1000 * sleeptime );
#endif
- sequencer_play();
- }
+ sequencer_play();
+ }
- beatCount = 1;
- eventCount = 1;
- return;
- }
- }
- else {
- beatCount ++;
- }
- }
- return;
+ beatCount = 1;
+ eventCount = 1;
+ return;
+ }
+ }
+ else {
+ beatCount ++;
+ }
+ }
+ return;
}
//~ beatcounter
// jack transport master
unsigned long Hydrogen::getHumantimeFrames()
{
- return m_nHumantimeFrames;
+ return m_nHumantimeFrames;
}
void Hydrogen::setHumantimeFrames(unsigned long hframes)
{
- m_nHumantimeFrames = hframes;
+ m_nHumantimeFrames = hframes;
}
@@ -3133,105 +3193,105 @@
#ifdef H2CORE_HAVE_JACK
void Hydrogen::offJackMaster()
{
- if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
- static_cast< JackOutput* >( m_pAudioDriver )->com_release();
- }
+ if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
+ static_cast< JackOutput* >( m_pAudioDriver )->com_release();
+ }
}
void Hydrogen::onJackMaster()
{
- if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
- static_cast< JackOutput* >( m_pAudioDriver )->initTimeMaster();
- }
+ if ( m_pAudioDriver->class_name() == JackOutput::class_name() ) {
+ static_cast< JackOutput* >( m_pAudioDriver )->initTimeMaster();
+ }
}
unsigned long Hydrogen::getTimeMasterFrames()
{
- float allframes = 0 ;
+ float allframes = 0 ;
- if ( m_pAudioDriver->m_transport.m_status == TransportInfo::STOPPED ){
+ if ( m_pAudioDriver->m_transport.m_status == TransportInfo::STOPPED ){
- int oldtick = getTickPosition();
- for (int i = 0; i <= getPatternPos(); i++){
- float framesforposition =
- (long)getTickForHumanPosition(i)
- * (float)m_pAudioDriver->m_transport.m_nTickSize;
- allframes = framesforposition + allframes;
- }
- unsigned long framesfortimemaster = (unsigned int)(
- allframes
- + oldtick * (float)m_pAudioDriver->m_transport.m_nTickSize
- );
- m_nHumantimeFrames = framesfortimemaster;
- return framesfortimemaster;
- }else
- {
- return m_nHumantimeFrames;
- }
+ int oldtick = getTickPosition();
+ for (int i = 0; i <= getPatternPos(); i++){
+ float framesforposition =
+ (long)getTickForHumanPosition(i)
+ * (float)m_pAudioDriver->m_transport.m_nTickSize;
+ allframes = framesforposition + allframes;
+ }
+ unsigned long framesfortimemaster = (unsigned int)(
+ allframes
+ + oldtick * (float)m_pAudioDriver->m_transport.m_nTickSize
+ );
+ m_nHumantimeFrames = framesfortimemaster;
+ return framesfortimemaster;
+ }else
+ {
+ return m_nHumantimeFrames;
+ }
}
#endif
long Hydrogen::getTickForHumanPosition( int humanpos )
{
- std::vector< PatternList* > * columns = m_pSong->get_pattern_group_vector();
-
- int nPatternGroups = columns->size();
- if ( humanpos >= nPatternGroups ) {
- if ( m_pSong->is_loop_enabled() ) {
- humanpos = humanpos % nPatternGroups;
- } else {
- return -1;
- }
- }
-
-// std::vector *pColumns =
-// m_pSong->get_pattern_group_vector()[ humanpos - 1 ]
-// .get( 0 )->get_length();
-
-// ERRORLOG( "Kick me!" );
- if ( humanpos == 0 ) return 0;
- Pattern *pPattern = columns->at( humanpos - 1 )->get( 0 );
- if ( pPattern ) {
- return pPattern->get_length();
- } else {
- return MAX_NOTES;
- }
-// int nPatternSize;
-
-// pColumns
-
-/* Pattern *pPattern = NULL;
- for ( int i = 0; i < humanpos; ++i ) {
- PatternList *pColumn = ( *pColumns )[ i ];
- pPattern = pColumn->get( 0 );
- if ( pPattern ) {
- nPatternSize = pPattern->get_length();
- } else {
- nPatternSize = MAX_NOTES;
- }
-
- humanTick = nPatternSize;
- }*/
-// return humanTick;
+ std::vector< PatternList* > * columns = m_pSong->get_pattern_group_vector();
+
+ int nPatternGroups = columns->size();
+ if ( humanpos >= nPatternGroups ) {
+ if ( m_pSong->is_loop_enabled() ) {
+ humanpos = humanpos % nPatternGroups;
+ } else {
+ return -1;
+ }
+ }
+
+ // std::vector *pColumns =
+ // m_pSong->get_pattern_group_vector()[ humanpos - 1 ]
+ // .get( 0 )->get_length();
+
+ // ERRORLOG( "Kick me!" );
+ if ( humanpos == 0 ) return 0;
+ Pattern *pPattern = columns->at( humanpos - 1 )->get( 0 );
+ if ( pPattern ) {
+ return pPattern->get_length();
+ } else {
+ return MAX_NOTES;
+ }
+ // int nPatternSize;
+
+ // pColumns
+
+ /* Pattern *pPattern = NULL;
+ for ( int i = 0; i < humanpos; ++i ) {
+ PatternList *pColumn = ( *pColumns )[ i ];
+ pPattern = pColumn->get( 0 );
+ if ( pPattern ) {
+ nPatternSize = pPattern->get_length();
+ } else {
+ nPatternSize = MAX_NOTES;
+ }
+
+ humanTick = nPatternSize;
+ }*/
+ // return humanTick;
}
float Hydrogen::getNewBpmJTM()
{
- return m_nNewBpmJTM;
+ return m_nNewBpmJTM;
}
void Hydrogen::setNewBpmJTM( float bpmJTM )
{
- m_nNewBpmJTM = bpmJTM;
+ m_nNewBpmJTM = bpmJTM;
}
void Hydrogen::ComputeHumantimeFrames(uint32_t nFrames)
{
- if ( ( m_audioEngineState == STATE_PLAYING ) )
- m_nHumantimeFrames = nFrames + m_nHumantimeFrames;
+ if ( ( m_audioEngineState == STATE_PLAYING ) )
+ m_nHumantimeFrames = nFrames + m_nHumantimeFrames;
}
@@ -3239,106 +3299,106 @@
void Hydrogen::triggerRelocateDuringPlay()
{
- if ( m_pSong->get_mode() == Song::PATTERN_MODE )
- m_nPatternStartTick = -1; // This forces the barline position
+ if ( m_pSong->get_mode() == Song::PATTERN_MODE )
+ m_nPatternStartTick = -1; // This forces the barline position
}
void Hydrogen::togglePlaysSelected()
{
- if ( getSong()->get_mode() != Song::PATTERN_MODE )
- return;
- Preferences * P = Preferences::get_instance();
-
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
- bool isPlaysSelected = P->patternModePlaysSelected();
-
- if (isPlaysSelected)
- {
- m_pPlayingPatterns->clear();
- Pattern * pSelectedPattern =
- m_pSong
- ->get_pattern_list()
- ->get(m_nSelectedPatternNumber);
- m_pPlayingPatterns->add( pSelectedPattern );
- }
-
- P->setPatternModePlaysSelected( !isPlaysSelected );
-
- AudioEngine::get_instance()->unlock();
-
+ if ( getSong()->get_mode() != Song::PATTERN_MODE )
+ return;
+ Preferences * P = Preferences::get_instance();
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ bool isPlaysSelected = P->patternModePlaysSelected();
+
+ if (isPlaysSelected)
+ {
+ m_pPlayingPatterns->clear();
+ Pattern * pSelectedPattern =
+ m_pSong
+ ->get_pattern_list()
+ ->get(m_nSelectedPatternNumber);
+ m_pPlayingPatterns->add( pSelectedPattern );
+ }
+
+ P->setPatternModePlaysSelected( !isPlaysSelected );
+
+ AudioEngine::get_instance()->unlock();
+
}
void Hydrogen::__kill_instruments()
{
- int c = 0;
- Instrument * pInstr = NULL;
- while ( __instrument_death_row.size()
- && __instrument_death_row.front()->is_queued() == 0 ) {
- pInstr = __instrument_death_row.front();
- __instrument_death_row.pop_front();
- INFOLOG( QString( "Deleting unused instrument (%1). "
- "%2 unused remain." )
- . arg( pInstr->get_name() )
- . arg( __instrument_death_row.size() ) );
- delete pInstr;
- c++;
- }
- if ( __instrument_death_row.size() ) {
- pInstr = __instrument_death_row.front();
- INFOLOG( QString( "Instrument %1 still has %2 active notes. "
- "Delaying 'delete instrument' operation." )
- . arg( pInstr->get_name() )
- . arg( pInstr->is_queued() ) );
- }
+ int c = 0;
+ Instrument * pInstr = NULL;
+ while ( __instrument_death_row.size()
+ && __instrument_death_row.front()->is_queued() == 0 ) {
+ pInstr = __instrument_death_row.front();
+ __instrument_death_row.pop_front();
+ INFOLOG( QString( "Deleting unused instrument (%1). "
+ "%2 unused remain." )
+ . arg( pInstr->get_name() )
+ . arg( __instrument_death_row.size() ) );
+ delete pInstr;
+ c++;
+ }
+ if ( __instrument_death_row.size() ) {
+ pInstr = __instrument_death_row.front();
+ INFOLOG( QString( "Instrument %1 still has %2 active notes. "
+ "Delaying 'delete instrument' operation." )
+ . arg( pInstr->get_name() )
+ . arg( pInstr->is_queued() ) );
+ }
}
void Hydrogen::__panic()
{
- sequencer_stop();
- AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
+ sequencer_stop();
+ AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
}
int Hydrogen::__get_selected_PatterNumber()
{
- return m_nSelectedPatternNumber;
+ return m_nSelectedPatternNumber;
}
unsigned int Hydrogen::__getMidiRealtimeNoteTickPosition()
{
- return m_naddrealtimenotetickposition;
+ return m_naddrealtimenotetickposition;
}
void Hydrogen::sortTimelineVector()
{
- //sort the timeline vector to beats a < b
- sort(m_timelinevector.begin(), m_timelinevector.end(), TimelineComparator());
+ //sort the timeline vector to beats a < b
+ sort(m_timelinevector.begin(), m_timelinevector.end(), TimelineComparator());
}
void Hydrogen::sortTimelineTagVector()
{
- //sort the timeline vector to beats a < b
- sort(m_timelinetagvector.begin(), m_timelinetagvector.end(), TimelineTagComparator());
+ //sort the timeline vector to beats a < b
+ sort(m_timelinetagvector.begin(), m_timelinetagvector.end(), TimelineTagComparator());
}
void Hydrogen::setTimelineBpm()
{
- //time line test
- if ( Preferences::get_instance()->__usetimeline ){
- float bpm = m_pSong->__bpm;
- for ( int i = 0; i < static_cast(m_timelinevector.size() ); i++){
- if( m_timelinevector[i].m_htimelinebeat > getPatternPos() ){
- break;
- }
- bpm = m_timelinevector[i].m_htimelinebpm;
- }//for
- if(bpm != m_pSong->__bpm){
- setBPM( bpm );
- }
- }//if
+ //time line test
+ if ( Preferences::get_instance()->getUseTimelineBpm() ){
+ float bpm = m_pSong->__bpm;
+ for ( int i = 0; i < static_cast(m_timelinevector.size() ); i++){
+ if( m_timelinevector[i].m_htimelinebeat > getPatternPos() ){
+ break;
+ }
+ bpm = m_timelinevector[i].m_htimelinebpm;
+ }//for
+ if(bpm != m_pSong->__bpm){
+ setBPM( bpm );
+ }
+ }//if
}
};
diff -Nru hydrogen-0.9.6~beta1/src/core/src/IO/coremidi_driver.cpp hydrogen-0.9.6~beta2/src/core/src/IO/coremidi_driver.cpp
--- hydrogen-0.9.6~beta1/src/core/src/IO/coremidi_driver.cpp 2011-03-17 10:38:22.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/IO/coremidi_driver.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -76,9 +76,14 @@
} else if ( ( nEventType >= 224 ) && ( nEventType < 240 ) ) { // Pitch Wheel Change
msg.m_nChannel = nEventType - 224;
msg.m_type = MidiMessage::PITCH_WHEEL;
- } else if ( ( nEventType >= 240 ) && ( nEventType < 256 ) ) { // System Exclusive
- msg.m_nChannel = nEventType - 240;
- msg.m_type = MidiMessage::SYSTEM_EXCLUSIVE;
+ } else if ( ( nEventType >= 240 ) && ( nEventType < 256 ) ) { // System Exclusive
+ msg.m_type = MidiMessage::SYSEX;
+ for(int i = 0; i< packet->length;i++){
+ msg.m_sysexData.push_back(packet->data[i]);
+ }
+ instance->handleMidiMessage( msg );
+ packet = MIDIPacketNext( packet );
+ return;
} else {
___ERRORLOG( QString( "Unhandled midi message type: %1" ).arg( nEventType ) );
___INFOLOG( "MIDI msg: " );
diff -Nru hydrogen-0.9.6~beta1/src/core/src/IO/disk_writer_driver.cpp hydrogen-0.9.6~beta2/src/core/src/IO/disk_writer_driver.cpp
--- hydrogen-0.9.6~beta1/src/core/src/IO/disk_writer_driver.cpp 2011-07-08 16:42:02.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/IO/disk_writer_driver.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
+#include
#include "DiskWriterDriver.h"
#include
@@ -37,8 +38,12 @@
void* diskWriterDriver_thread( void* param )
{
- Object* __object = ( Object* )param;
+
+ Object* __object = ( Object* )param;
DiskWriterDriver *pDriver = ( DiskWriterDriver* )param;
+ EventQueue::get_instance()->push_event( EVENT_PROGRESS, 0 );
+ pDriver->setBpm( Hydrogen::get_instance()->getSong()->__bpm );
+ pDriver->audioEngine_process_checkBPMChanged();
__INFOLOG( "DiskWriterDriver thread start" );
// always rolling, no user interaction
@@ -130,72 +135,106 @@
float *pData_R = pDriver->m_pOut_R;
- //calculate exact song length in frames (no loops).
+ Hydrogen* engine = Hydrogen::get_instance();
+
std::vector *pPatternColumns = Hydrogen::get_instance()->getSong()->get_pattern_group_vector();
int nColumns = pPatternColumns->size();
int nPatternSize;
- int nSongSize = 0;
- for ( int i = 0; i < nColumns; ++i ) {
- PatternList *pColumn = ( *pPatternColumns )[ i ];
+ int validBpm = engine->getSong()->__bpm;
+ float oldBPM = 0;
+ float ticksize = 0;
+ for ( int patternposition = 0; patternposition < nColumns; ++patternposition ) {
+ PatternList *pColumn = ( *pPatternColumns )[ patternposition ];
if ( pColumn->size() != 0 ) {
nPatternSize = pColumn->get( 0 )->get_length();
} else {
nPatternSize = MAX_NOTES;
- }
- nSongSize += nPatternSize;
- }
+ }
- float ticksize = pDriver->m_nSampleRate * 60.0 / Hydrogen::get_instance()->getSong()->__bpm / 192 *4;
- //here we have the song length in frames dependent from bpm and samplerate
- unsigned songLengthInFrames = ticksize * nSongSize;
-
- unsigned frameNumber = 0;
- int lastRun = 0;
- while ( frameNumber < songLengthInFrames ) {
-
- int usedBuffer = pDriver->m_nBufferSize;
-
- //this will calculate the the size from -last- (end of song) used frame buffer,
- //which is mostly smaller than pDriver->m_nBufferSize
- if( songLengthInFrames - frameNumber < pDriver->m_nBufferSize ){
- lastRun = songLengthInFrames - frameNumber;
- usedBuffer = lastRun;
- };
-
- frameNumber += usedBuffer;
- int ret = pDriver->m_processCallback( usedBuffer, NULL );
-
- for ( unsigned i = 0; i < usedBuffer; i++ ) {
- if(pData_L[i] > 1){
- pData[i * 2] = 1;
- }
- else if(pData_L[i] < -1){
- pData[i * 2] = -1;
- }else
- {
- pData[i * 2] = pData_L[i];
- }
-
- if(pData_R[i] > 1){
- pData[i * 2 + 1] = 1;
- }
- else if(pData_R[i] < -1){
- pData[i * 2 + 1] = -1;
- }else
- {
- pData[i * 2 + 1] = pData_R[i];
- }
- }
- int res = sf_writef_float( m_file, pData, usedBuffer );
- if ( res != ( int )usedBuffer ) {
- __ERRORLOG( "Error during sf_write_float" );
- }
-
- float fPercent = ( float ) frameNumber / ( float )songLengthInFrames * 100.0;
- EventQueue::get_instance()->push_event( EVENT_PROGRESS, ( int )fPercent );
-// frameNuber += lastrun;
- }
+ ticksize = pDriver->m_nSampleRate * 60.0 / engine->getSong()->__bpm / engine->getSong()->__resolution;
+ // check pattern bpm if timeline bpm is in use
+ if(Preferences::get_instance()->getUseTimelineBpm() ){
+ if( engine->m_timelinevector.size() >= 1 ){
+
+ for ( int t = 0; t < engine->m_timelinevector.size(); t++){
+ if(engine->m_timelinevector[t].m_htimelinebeat == patternposition && engine->m_timelinevector[t].m_htimelinebpm != validBpm){
+ validBpm = engine->m_timelinevector[t].m_htimelinebpm;
+ }
+
+ }
+ }
+ pDriver->setBpm(validBpm);
+ ticksize = pDriver->m_nSampleRate * 60.0 / validBpm / Hydrogen::get_instance()->getSong()->__resolution;
+ pDriver->audioEngine_process_checkBPMChanged();
+ engine->setPatternPos(patternposition);
+
+ // delay needed time to calculate all rubberband samples
+ if( Preferences::get_instance()->getRubberBandBatchMode() && validBpm != oldBPM ){
+ EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
+ int sleepTime = Preferences::get_instance()->getRubberBandCalcTime()+1;
+ while ((sleepTime = sleep(sleepTime)) > 0);
+ }
+ oldBPM = validBpm;
+
+ }
+ else
+ {
+ ticksize = pDriver->m_nSampleRate * 60.0 / Hydrogen::get_instance()->getSong()->__bpm / Hydrogen::get_instance()->getSong()->__resolution;
+ //pDriver->m_transport.m_nTickSize = ticksize;
+ }
+
+
+ //here we have the pattern length in frames dependent from bpm and samplerate
+ unsigned patternLengthInFrames = ticksize * nPatternSize;
+
+ unsigned frameNumber = 0;
+ int lastRun = 0;
+ while ( frameNumber < patternLengthInFrames ) {
+
+ int usedBuffer = pDriver->m_nBufferSize;
+
+ //this will calculate the the size from -last- (end of pattern) used frame buffer,
+ //which is mostly smaller than pDriver->m_nBufferSize
+ if( patternLengthInFrames - frameNumber < pDriver->m_nBufferSize ){
+ lastRun = patternLengthInFrames - frameNumber;
+ usedBuffer = lastRun;
+ };
+
+ frameNumber += usedBuffer;
+ int ret = pDriver->m_processCallback( usedBuffer, NULL );
+
+ for ( unsigned i = 0; i < usedBuffer; i++ ) {
+ if(pData_L[i] > 1){
+ pData[i * 2] = 1;
+ }
+ else if(pData_L[i] < -1){
+ pData[i * 2] = -1;
+ }else
+ {
+ pData[i * 2] = pData_L[i];
+ }
+
+ if(pData_R[i] > 1){
+ pData[i * 2 + 1] = 1;
+ }
+ else if(pData_R[i] < -1){
+ pData[i * 2 + 1] = -1;
+ }else
+ {
+ pData[i * 2 + 1] = pData_R[i];
+ }
+ }
+ int res = sf_writef_float( m_file, pData, usedBuffer );
+ if ( res != ( int )usedBuffer ) {
+ __ERRORLOG( "Error during sf_write_float" );
+ }
+ }
+
+ // this progress bar methode is not exact but ok enough to give users a usable visible progress feedback
+ float fPercent = ( float )(patternposition +1) / ( float )nColumns * 100.0;
+ EventQueue::get_instance()->push_event( EVENT_PROGRESS, ( int )fPercent );
+ }
delete[] pData;
pData = NULL;
@@ -206,7 +245,6 @@
pthread_exit( NULL );
-// Hydrogen::get_instance()->stopExportSong();
return NULL;
}
@@ -259,7 +297,8 @@
pthread_create( &diskWriterDriverThread, &attr, diskWriterDriver_thread, this );
- return 0;
+ return 0;
+
}
@@ -267,13 +306,13 @@
/// disconnect
void DiskWriterDriver::disconnect()
{
- INFOLOG( "[disconnect]" );
-
+ INFOLOG( "[disconnect]" );
delete[] m_pOut_L;
m_pOut_L = NULL;
delete[] m_pOut_R;
m_pOut_R = NULL;
+
}
@@ -320,5 +359,31 @@
m_transport.m_nBPM = fBPM;
}
+void DiskWriterDriver::audioEngine_process_checkBPMChanged()
+{
+ float fNewTickSize =
+ getSampleRate() * 60.0
+ / Hydrogen::get_instance()->getSong()->__bpm
+ / Hydrogen::get_instance()->getSong()->__resolution;
+
+ if ( fNewTickSize != m_transport.m_nTickSize ) {
+ // cerco di convertire ...
+ float fTickNumber =
+ ( float )m_transport.m_nFrames
+ / ( float )m_transport.m_nTickSize;
+
+ m_transport.m_nTickSize = fNewTickSize;
+
+ if ( m_transport.m_nTickSize == 0 ) {
+ return;
+ }
+
+ // update frame position
+ m_transport.m_nFrames = ( long long )( fTickNumber * fNewTickSize );
+
+ // currently unuseble here
+ //EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
+ }
+}
};
diff -Nru hydrogen-0.9.6~beta1/src/core/src/IO/DiskWriterDriver.h hydrogen-0.9.6~beta2/src/core/src/IO/DiskWriterDriver.h
--- hydrogen-0.9.6~beta1/src/core/src/IO/DiskWriterDriver.h 2011-01-06 09:27:15.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/IO/DiskWriterDriver.h 2012-05-25 12:19:45.000000000 +0000
@@ -60,7 +60,9 @@
void disconnect();
void write( float* buffer_L, float* buffer_R, unsigned int bufferSize );
-
+
+ void audioEngine_process_checkBPMChanged();
+
unsigned getBufferSize() {
return m_nBufferSize;
}
@@ -81,6 +83,7 @@
private:
+
};
};
diff -Nru hydrogen-0.9.6~beta1/src/core/src/IO/jack_midi_driver.cpp hydrogen-0.9.6~beta2/src/core/src/IO/jack_midi_driver.cpp
--- hydrogen-0.9.6~beta1/src/core/src/IO/jack_midi_driver.cpp 2011-07-22 19:32:06.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/IO/jack_midi_driver.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -62,12 +62,12 @@
void
JackMidiDriver::JackMidiWrite(jack_nframes_t nframes)
{
- int error;
+ int error;
int events;
int i;
void *buf;
jack_midi_event_t event;
- uint8_t buffer[8];
+ uint8_t buffer[13];// 13 is needed if we get sysex goto messages
if (input_port == NULL)
return;
@@ -114,8 +114,8 @@
msg.m_type = MidiMessage::NOTE_ON;
msg.m_nData1 = buffer[1];
msg.m_nData2 = buffer[2];
- msg.m_nChannel = buffer[0] & 0xF;
- handleMidiMessage(msg);
+ msg.m_nChannel = buffer[0] & 0xF;
+ handleMidiMessage(msg);
break;
case 0xB: /* control change */
msg.m_type = MidiMessage::CONTROL_CHANGE;
@@ -131,10 +131,22 @@
msg.m_nChannel = buffer[0] & 0xF;
handleMidiMessage(msg);
break;
- case 0xF:
- switch (buffer[0]) {
- case 0xF0: /* system exclusive */
- break;
+ case 0xF:
+ switch (buffer[0]) {
+ case 0xF0: /* system exclusive */
+ msg.m_type = MidiMessage::SYSEX;
+ if(buffer[3] == 06 ){// MMC message
+ for ( int i = 0; i < sizeof(buffer) && i<6; i++ ) {
+ msg.m_sysexData.push_back( buffer[i] );
+ }
+ }else
+ {
+ for ( int i = 0; i < sizeof(buffer); i++ ) {
+ msg.m_sysexData.push_back( buffer[i] );
+ }
+ }
+ handleMidiMessage(msg);
+ break;
case 0xF1:
msg.m_type = MidiMessage::QUARTER_FRAME;
msg.m_nData1 = buffer[1];
@@ -319,8 +331,11 @@
JackMidiDriver::~JackMidiDriver()
{
if (jack_client != NULL)
+ {
+ jack_port_unregister( jack_client, input_port);
+ jack_port_unregister( jack_client, output_port);
jack_deactivate(jack_client);
-
+ }
pthread_mutex_destroy(&mtx);
}
diff -Nru hydrogen-0.9.6~beta1/src/core/src/IO/jack_output.cpp hydrogen-0.9.6~beta2/src/core/src/IO/jack_output.cpp
--- hydrogen-0.9.6~beta1/src/core/src/IO/jack_output.cpp 2011-11-08 22:10:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/IO/jack_output.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -206,7 +206,7 @@
}
}
memset( track_output_ports_L, 0, sizeof(track_output_ports_L) );
- memset( track_output_ports_R, 0, sizeof(track_output_ports_R) );
+ memset( track_output_ports_R, 0, sizeof(track_output_ports_R) );
}
unsigned JackOutput::getBufferSize()
@@ -737,22 +737,6 @@
}
-void JackOutput::setPortName( int nPort, bool bLeftChannel, const QString& sName )
-{
-// infoLog( "[setPortName] " + sName );
- jack_port_t *pPort;
- if ( bLeftChannel ) {
- pPort = track_output_ports_L[ nPort ];
- } else {
- pPort = track_output_ports_R[ nPort ];
- }
-
- int err = jack_port_set_name( pPort, sName.toLocal8Bit() );
- if ( err != 0 ) {
- ERRORLOG( " Error in jack_port_set_name!" );
- }
-}
-
int JackOutput::getNumTracks()
{
// INFOLOG( "get num tracks()" );
@@ -774,33 +758,26 @@
enum session_events{
SAVE_SESSION,
SAVE_AND_QUIT,
- SAVE_TEMPLATE,
- SAVE_SESSION_NEW_FILE
+ SAVE_TEMPLATE
};
jack_session_event_t *ev = (jack_session_event_t *) event;
/* Valid Song is needed */
if(Hydrogen::get_instance()->getSong()->get_filename().isEmpty()){
- EventQueue::get_instance()->push_event(EVENT_JACK_SESSION, SAVE_SESSION_NEW_FILE);
- jack_session_reply(client, ev );
- jack_session_event_free (ev);
- return;
+ Hydrogen::get_instance()->getSong()->set_filename("Untitled_Song");
}
-
- QString songfilename;
- if(Preferences::get_instance()->getJackSessionUseSessionDir()){
- QString jackSessionDirectory = (QString)ev->session_dir;
- QStringList list1 = Hydrogen::get_instance()->getSong()->get_filename().split("/");
- QString realFillename = list1[list1.size()-1];
- qDebug()<< realFillename;
- Hydrogen::get_instance()->getSong()->set_filename(jackSessionDirectory + realFillename);
- songfilename = "\"${SESSION_DIR}\"" + realFillename;
- }else
- {
- songfilename = Hydrogen::get_instance()->getSong()->get_filename();
+ if(Hydrogen::get_instance()->getSong()->get_filename().contains(" ")){
+ QStringList removeWhiteSpaces = Hydrogen::get_instance()->getSong()->get_filename().split(" ");
+ Hydrogen::get_instance()->getSong()->set_filename( removeWhiteSpaces.join("_") );
}
+ QString songfilename;
+ QString jackSessionDirectory = (QString)ev->session_dir;
+ QStringList list1 = Hydrogen::get_instance()->getSong()->get_filename().split("/");
+ QString realFillename = list1[list1.size()-1];
+ Hydrogen::get_instance()->getSong()->set_filename(jackSessionDirectory + realFillename);
+ songfilename = "\"${SESSION_DIR}\"" + realFillename;
QString retval = QString(Preferences::get_instance()->getJackSessionApplicationPath() + " -s" + songfilename + " --jacksessionid " + ev->client_uuid);
const char * filename = retval.toAscii().data();
@@ -809,10 +786,8 @@
EventQueue::get_instance()->push_event(EVENT_JACK_SESSION, SAVE_SESSION);
}
if (ev->type == JackSessionSaveAndQuit) {
- if(Preferences::get_instance()->getJackSessionUseSessionDir()){
EventQueue::get_instance()->push_event(EVENT_JACK_SESSION, SAVE_SESSION);
- }
- EventQueue::get_instance()->push_event(EVENT_JACK_SESSION, SAVE_AND_QUIT);
+ EventQueue::get_instance()->push_event(EVENT_JACK_SESSION, SAVE_AND_QUIT);
}
ev->command_line = strdup (filename);
diff -Nru hydrogen-0.9.6~beta1/src/core/src/IO/midi_input.cpp hydrogen-0.9.6~beta2/src/core/src/IO/midi_input.cpp
--- hydrogen-0.9.6~beta1/src/core/src/IO/midi_input.cpp 2011-11-07 22:45:33.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/IO/midi_input.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -306,7 +306,8 @@
4 Fast Forward
5 Rewind
6 Record strobe (punch in)
- 7 Record exit (punch out)
+ 7 Record exit (punch out)
+ 8 Record ready
9 Pause
@@ -315,7 +316,7 @@
240 127 id 6 68 6 1 hr mn sc fr ff 247
*/
-
+
MidiActionManager * aH = MidiActionManager::get_instance();
MidiMap * mM = MidiMap::get_instance();
Hydrogen *pEngine = Hydrogen::get_instance();
@@ -323,12 +324,11 @@
pEngine->lastMidiEventParameter = msg.m_nData1;
-
if ( msg.m_sysexData.size() == 6 ) {
if (
- ( msg.m_sysexData[0] == 0xF0 ) &&
+ ( msg.m_sysexData[0] == 240 ) &&
( msg.m_sysexData[1] == 127 ) &&
- ( msg.m_sysexData[2] == 127 ) &&
+ //( msg.m_sysexData[2] == 0 ) &&
( msg.m_sysexData[3] == 6 ) ) {
@@ -356,8 +356,8 @@
}
case 4: // FAST FWD
- pEngine->lastMidiEvent = "MMC_FAST_FWD";
- aH->handleAction(mM->getMMCAction("MMC_FAST_FWD"));
+ pEngine->lastMidiEvent = "MMC_FAST_FORWARD";
+ aH->handleAction(mM->getMMCAction("MMC_FAST_FORWARD"));
break;
@@ -376,6 +376,11 @@
aH->handleAction(mM->getMMCAction("MMC_RECORD_EXIT"));
break;
+ case 8: // RECORD READY
+ pEngine->lastMidiEvent = "MMC_RECORD_READY";
+ aH->handleAction(mM->getMMCAction("MMC_RECORD_READY"));
+ break;
+
case 9: //PAUSE
pEngine->lastMidiEvent = "MMC_PAUSE";
aH->handleAction(mM->getMMCAction("MMC_PAUSE"));
diff -Nru hydrogen-0.9.6~beta1/src/core/src/IO/PortAudioDriver.h hydrogen-0.9.6~beta2/src/core/src/IO/PortAudioDriver.h
--- hydrogen-0.9.6~beta1/src/core/src/IO/PortAudioDriver.h 2011-01-06 09:27:15.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/IO/PortAudioDriver.h 2012-05-25 12:19:45.000000000 +0000
@@ -26,6 +26,8 @@
#include
#include
+#include
+
#ifdef H2CORE_HAVE_PORTAUDIO
#include
diff -Nru hydrogen-0.9.6~beta1/src/core/src/local_file_mgr.cpp hydrogen-0.9.6~beta2/src/core/src/local_file_mgr.cpp
--- hydrogen-0.9.6~beta1/src/core/src/local_file_mgr.cpp 2011-10-24 14:05:32.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/local_file_mgr.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -256,12 +256,22 @@
//LIB_ID just in work to get better usability
//writeXmlString( &rootNode, "LIB_ID", "in_work" );
writeXmlString( rootNode, "pattern_for_drumkit", drumkit_name );
+ writeXmlString( rootNode, "author", song->get_author() );
+ writeXmlString( rootNode, "license", song->get_license() );
// pattern
QDomNode patternNode = doc.createElement( "pattern" );
writeXmlString( patternNode, "pattern_name", realpatternname );
- writeXmlString( patternNode, "category", pat->get_category() );
+
+ QString category;
+ if ( pat->get_category().isEmpty() )
+ category = "No category";
+ else
+ category = pat->get_category();
+
+
+ writeXmlString( patternNode, "category", category );
writeXmlString( patternNode, "size", QString("%1").arg( pat->get_length() ) );
QDomNode noteListNode = doc.createElement( "noteList" );
@@ -293,21 +303,26 @@
doc.appendChild( rootNode );
+ int rv = 0;
QFile file( sPatternXmlFilename );
if ( !file.open(QIODevice::WriteOnly) )
- return 0;
+ rv = 1;
QTextStream TextStream( &file );
doc.save( TextStream, 1 );
+
+ if( file.size() == 0)
+ rv = 1;
+
file.close();
QFile anotherTestfile( sPatternXmlFilename );
if ( !anotherTestfile.exists() )
- return 1;
+ rv = 1;
- return 0; // ok
+ return rv; // ok
}
@@ -405,7 +420,12 @@
}
-std::vector LocalFileMng::getAllPatternName()
+/**
+ * Return the names of all patterns in the soundlibrary.
+ * \return A vector of QString elements which represent the pattern names.
+ */
+
+std::vector LocalFileMng::getAllPatternNames()
{
std::vector alllist;
@@ -428,7 +448,11 @@
return alllist;
}
-
+/**
+ * Generate a list of all used categories. This includes only patterns which are located in
+ * hydrogens soundlibrary.
+ * \return A vector of QString elements which represent the pattern categories.
+ */
std::vector LocalFileMng::getAllCategoriesFromPattern()
{
@@ -438,7 +462,6 @@
std::vector categorylist;
for (uint i = 0; i < m_allPatternList.size(); ++i) {
QString patternInfoFile = m_allPatternList[i];
-
QDomDocument doc = LocalFileMng::openXmlDocument( patternInfoFile );
@@ -450,29 +473,32 @@
QString sCategoryName( LocalFileMng::readXmlString( patternNode,"category", "" ) );
- if ( !sCategoryName.isEmpty() ){
- bool test = true;
- for (uint i = 0; i < categorylist.size(); ++i){
- if ( sCategoryName == categorylist[i] ){
- test = false;
- }
- }
- if (test == true){
- categorylist.push_back(sCategoryName);
-
- //this merge new categories to user categories list
- bool test2 = true;
- for( cur_testpatternCategories = pPref->m_patternCategories.begin(); cur_testpatternCategories != pPref->m_patternCategories.end(); ++cur_testpatternCategories ){
- if ( sCategoryName == *cur_testpatternCategories ){
- test2 = false;
- }
- }
-
- if (test2 == true ) {
- pPref->m_patternCategories.push_back( sCategoryName );
- }
- }
- }
+ if ( sCategoryName.isEmpty() ){
+ sCategoryName = "No category";
+ }
+
+ bool test = true;
+ for (uint i = 0; i < categorylist.size(); ++i){
+ if ( sCategoryName == categorylist[i] ){
+ test = false;
+ }
+ }
+ if (test == true){
+ categorylist.push_back( sCategoryName );
+
+ //this merge new categories to user categories list
+ bool test2 = true;
+ for( cur_testpatternCategories = pPref->m_patternCategories.begin(); cur_testpatternCategories != pPref->m_patternCategories.end(); ++cur_testpatternCategories ){
+ if ( sCategoryName == *cur_testpatternCategories ){
+ test2 = false;
+ }
+ }
+
+ if (test2 == true ) {
+ pPref->m_patternCategories.push_back( sCategoryName );
+ }
+ }
+
}
}
@@ -480,7 +506,11 @@
return categorylist;
}
-
+/**
+ * Generate a list of all patterns for a given drumkit
+ * \param sDrumkit the name of drumkit
+ * \return A vector of QString elements which represent the pattern names.
+ */
std::vector LocalFileMng::getPatternsForDrumkit( const QString& sDrumkit )
{
@@ -508,14 +538,14 @@
return list;
}
-
+/**
+ * Return a list of drumkits that are located inside a directory.
+ * \param sDirectory The directory where the method looks for drumkits
+ * \return A vector of QString elements which represent the drumkits.
+ */
std::vector LocalFileMng::getDrumkitsFromDirectory( QString sDirectory )
{
- /*
- returns a list of all drumkits in the given directory
- */
-
std::vector list;
QDir dir( sDirectory );
@@ -540,12 +570,15 @@
}
+/**
+ * Merge two vectors of QStrings.
+ * \param firstVector The first vector.
+ * \param secondVector The second vector.
+ * \return The resulting vector which is a union of firstVector and secondVector.
+ */
std::vector mergeQStringVectors( std::vector firstVector , std::vector secondVector )
{
- /*
- merges two vectors ( containing drumkits). Elements of the first vector have priority
- */
if( firstVector.size() == 0 ) return secondVector;
if( secondVector.size() == 0 ) return firstVector;
@@ -575,6 +608,11 @@
}
+/**
+ * Return a list of directories that may contain patterns
+ * \return A vector of QString elements which represent the directory names.
+ */
+
std::vector LocalFileMng::getPatternDirList()
{
return getDrumkitsFromDirectory( Preferences::get_instance()->getDataDirectory() + "patterns" );
@@ -587,10 +625,17 @@
return 0;
}
-int LocalFileMng::savePlayList( const std::string& patternname)
+
+/**
+ * Save the currently loaded playlist to disk.
+ * \param playlist_name The filename of the output file.
+ * \return Returns an Errorcode.
+ */
+
+int LocalFileMng::savePlayList( const std::string& filename)
{
- std::string name = patternname.c_str();
+ std::string name = filename.c_str();
std::string realname = name.substr(name.rfind("/")+1);
@@ -600,18 +645,14 @@
QDomNode rootNode = doc.createElement( "playlist" );
- //LIB_ID just in work to get better usability
writeXmlString( rootNode, "Name", QString (realname.c_str()) );
- writeXmlString( rootNode, "LIB_ID", "in_work" );
QDomNode playlistNode = doc.createElement( "Songs" );
for ( uint i = 0; i < Hydrogen::get_instance()->m_PlayList.size(); ++i ){
QDomNode nextNode = doc.createElement( "next" );
LocalFileMng::writeXmlString ( nextNode, "song", Hydrogen::get_instance()->m_PlayList[i].m_hFile );
-
LocalFileMng::writeXmlString ( nextNode, "script", Hydrogen::get_instance()->m_PlayList[i].m_hScript );
-
LocalFileMng::writeXmlString ( nextNode, "enabled", Hydrogen::get_instance()->m_PlayList[i].m_hScriptEnabled );
playlistNode.appendChild( nextNode );
@@ -620,44 +661,51 @@
rootNode.appendChild( playlistNode );
doc.appendChild( rootNode );
- QString filename = QString( patternname.c_str() );
- QFile file(filename);
+ int rv = 0;
+ QFile file( filename.c_str() );
if ( !file.open(QIODevice::WriteOnly) )
- return 0;
+ rv = 1;
QTextStream TextStream( &file );
doc.save( TextStream, 1 );
+ if( file.size() == 0)
+ rv = 1;
+
file.close();
- return 0; // ok
+ return rv; // ok
}
-int LocalFileMng::loadPlayList( const std::string& patternname)
+/**
+ * Load a playlist from disk.
+ * \param filename The name of the playlist to be saved.
+ * \return Returns an Errorcode.
+ */
+
+int LocalFileMng::loadPlayList( const std::string& filename)
{
- std::string playlistInfoFile = patternname;
+ std::string playlistInfoFile = filename;
std::ifstream verify( playlistInfoFile.c_str() , std::ios::in | std::ios::binary );
if ( verify == NULL ) {
- //ERRORLOG( "Load Playlist: Data file " + playlistInfoFile + " not found." );
- return 0;
+ return 1;
}
- QDomDocument doc = LocalFileMng::openXmlDocument( QString( patternname.c_str() ) );
+ QDomDocument doc = LocalFileMng::openXmlDocument( QString( filename.c_str() ) );
Hydrogen::get_instance()->m_PlayList.clear();
QDomNode rootNode = doc.firstChildElement( "playlist" ); // root element
if ( rootNode.isNull() ) {
ERRORLOG( "Error reading playlist: playlist node not found" );
- return 0;
+ return 1;
}
QDomNode playlistNode = rootNode.firstChildElement( "Songs" );
if ( ! playlistNode.isNull() ) {
- // new code :)
Hydrogen::get_instance()->m_PlayList.clear();
QDomNode nextNode = playlistNode.firstChildElement( "next" );
while ( ! nextNode.isNull() ) {
@@ -768,12 +816,6 @@
void LocalFileMng::writeXmlString( QDomNode parent, const QString& name, const QString& text )
{
- /*
- TiXmlElement versionNode( name.toAscii() );
- TiXmlText versionText( text.toAscii() );
- versionNode.appendChild( versionText );
- parent->appendChild( versionNode );
- */
QDomDocument doc;
QDomElement elem = doc.createElement( name );
QDomText t = doc.createTextNode( text );
@@ -893,8 +935,6 @@
.arg( enc )
.toLocal8Bit();
- //_INFOLOG( QString("Using '%1' encoding for TinyXML file").arg(enc) );
-
while( !file.atEnd() ) {
line = file.readLine();
LocalFileMng::convertFromTinyXMLString( &line );
@@ -1036,12 +1076,6 @@
LocalFileMng::writeXmlString( songNode, "humanize_velocity", QString("%1").arg( song->get_humanize_velocity_value() ) );
LocalFileMng::writeXmlString( songNode, "swing_factor", QString("%1").arg( song->get_swing_factor() ) );
- /* LocalFileMng::writeXmlBool( &songNode, "delayFXEnabled", song->m_bDelayFXEnabled );
- LocalFileMng::writeXmlString( &songNode, "delayFXWetLevel", QString("%1").arg( song->m_fDelayFXWetLevel ) );
- LocalFileMng::writeXmlString( &songNode, "delayFXFeedback", QString("%1").arg( song->m_fDelayFXFeedback ) );
- LocalFileMng::writeXmlString( &songNode, "delayFXTime", QString("%1").arg( song->m_nDelayFXTime ) );
- */
-
// instrument list
QDomNode instrumentListNode = doc.createElement( "instrumentList" );
unsigned nInstrument = song->get_instrument_list()->size();
@@ -1054,8 +1088,8 @@
QDomNode instrumentNode = doc.createElement( "instrument" );
LocalFileMng::writeXmlString( instrumentNode, "id", QString("%1").arg( instr->get_id() ) );
- //LocalFileMng::writeXmlString( instrumentNode, "drumkit", instr->get_drumkit_name() );
LocalFileMng::writeXmlString( instrumentNode, "name", instr->get_name() );
+ LocalFileMng::writeXmlString( instrumentNode, "drumkit", instr->get_drumkit_name() );
LocalFileMng::writeXmlString( instrumentNode, "volume", QString("%1").arg( instr->get_volume() ) );
LocalFileMng::writeXmlBool( instrumentNode, "isMuted", instr->is_muted() );
LocalFileMng::writeXmlString( instrumentNode, "pan_L", QString("%1").arg( instr->get_pan_l() ) );
@@ -1263,40 +1297,42 @@
songNode.appendChild( ladspaFxNode );
doc.appendChild( songNode );
+
+ //bpm time line
+ QDomNode bpmTimeLine = doc.createElement( "BPMTimeLine" );
+ if(Hydrogen::get_instance()->m_timelinevector.size() >= 1 ){
+ for ( int t = 0; t < static_cast(Hydrogen::get_instance()->m_timelinevector.size()); t++){
+ QDomNode newBPMNode = doc.createElement( "newBPM" );
+ LocalFileMng::writeXmlString( newBPMNode, "BAR",QString("%1").arg( Hydrogen::get_instance()->m_timelinevector[t].m_htimelinebeat ));
+ LocalFileMng::writeXmlString( newBPMNode, "BPM", QString("%1").arg( Hydrogen::get_instance()->m_timelinevector[t].m_htimelinebpm ) );
+ bpmTimeLine.appendChild( newBPMNode );
+ }
+ }
+ songNode.appendChild( bpmTimeLine );
+
+ //time line tag
+ QDomNode timeLineTag = doc.createElement( "timeLineTag" );
+ if(Hydrogen::get_instance()->m_timelinetagvector.size() >= 1 ){
+ for ( int t = 0; t < static_cast(Hydrogen::get_instance()->m_timelinetagvector.size()); t++){
+ QDomNode newTAGNode = doc.createElement( "newTAG" );
+ LocalFileMng::writeXmlString( newTAGNode, "BAR",QString("%1").arg( Hydrogen::get_instance()->m_timelinetagvector[t].m_htimelinetagbeat ));
+ LocalFileMng::writeXmlString( newTAGNode, "TAG", QString("%1").arg( Hydrogen::get_instance()->m_timelinetagvector[t].m_htimelinetag ) );
+ timeLineTag.appendChild( newTAGNode );
+ }
+ }
+ songNode.appendChild( timeLineTag );
+
QFile file(filename);
if ( !file.open(QIODevice::WriteOnly) )
- rv = 1;
-
-//bpm time line
- QDomNode bpmTimeLine = doc.createElement( "BPMTimeLine" );
- if(Hydrogen::get_instance()->m_timelinevector.size() >= 1 ){
- for ( int t = 0; t < static_cast(Hydrogen::get_instance()->m_timelinevector.size()); t++){
- QDomNode newBPMNode = doc.createElement( "newBPM" );
- LocalFileMng::writeXmlString( newBPMNode, "BAR",QString("%1").arg( Hydrogen::get_instance()->m_timelinevector[t].m_htimelinebeat ));
- LocalFileMng::writeXmlString( newBPMNode, "BPM", QString("%1").arg( Hydrogen::get_instance()->m_timelinevector[t].m_htimelinebpm ) );
- bpmTimeLine.appendChild( newBPMNode );
- }
- }
- songNode.appendChild( bpmTimeLine );
-
-//time line tag
- QDomNode timeLineTag = doc.createElement( "timeLineTag" );
- if(Hydrogen::get_instance()->m_timelinetagvector.size() >= 1 ){
- for ( int t = 0; t < static_cast(Hydrogen::get_instance()->m_timelinetagvector.size()); t++){
- QDomNode newTAGNode = doc.createElement( "newTAG" );
- LocalFileMng::writeXmlString( newTAGNode, "BAR",QString("%1").arg( Hydrogen::get_instance()->m_timelinetagvector[t].m_htimelinetagbeat ));
- LocalFileMng::writeXmlString( newTAGNode, "TAG", QString("%1").arg( Hydrogen::get_instance()->m_timelinetagvector[t].m_htimelinetag ) );
- timeLineTag.appendChild( newTAGNode );
- }
- }
- songNode.appendChild( timeLineTag );
+ rv = 1;
QTextStream TextStream( &file );
doc.save( TextStream, 1 );
- file.close();
-
+ if( file.size() == 0)
+ rv = 1;
+ file.close();
if( rv ) {
WARNINGLOG("File save reported an error.");
@@ -1304,6 +1340,7 @@
song->__is_modified = false;
INFOLOG("Save was successful.");
}
+
song->set_filename( filename );
return rv;
diff -Nru hydrogen-0.9.6~beta1/src/core/src/midi_action.cpp hydrogen-0.9.6~beta2/src/core/src/midi_action.cpp
--- hydrogen-0.9.6~beta1/src/core/src/midi_action.cpp 2011-11-04 23:35:12.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/midi_action.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
@@ -127,6 +128,10 @@
<< "PLAY/PAUSE_TOGGLE"
<< "STOP"
<< "PAUSE"
+ << "RECORD_READY"
+ << "RECORD/STROBE_TOGGLE"
+ << "RECORD_STROBE"
+ << "RECORD_EXIT"
<< "MUTE"
<< "UNMUTE"
<< "MUTE_TOGGLE"
@@ -135,6 +140,7 @@
<< "BPM_INCR"
<< "BPM_DECR"
<< "BPM_CC_RELATIVE"
+ << "BPM_FINE_CC_RELATIVE"
<< "MASTER_VOLUME_RELATIVE"
<< "MASTER_VOLUME_ABSOLUTE"
<< "STRIP_VOLUME_RELATIVE"
@@ -148,12 +154,19 @@
<< "EFFECT3_LEVEL_ABSOLUTE"
<< "EFFECT4_LEVEL_ABSOLUTE"
<< "SELECT_NEXT_PATTERN"
+ << "SELECT_NEXT_PATTERN_CC_ABSOLUT"
<< "SELECT_NEXT_PATTERN_PROMPTLY"
+ << "SELECT_AND_PLAY_PATTERN"
<< "PAN_RELATIVE"
<< "PAN_ABSOLUTE"
<< "BEATCOUNTER"
<< "TAP_TEMPO"
- << "SELECT_INSTRUMENT";
+ << "PLAYLIST_NEXT_SONG"
+ << "PLAYLIST_PREV_SONG"
+ << "TOGGLE_METRONOME"
+ << "SELECT_INSTRUMENT"
+ << "UNDO_ACTION"
+ << "REDO_ACTION";
eventList << ""
<< "MMC_PLAY"
@@ -163,6 +176,7 @@
<< "MMC_REWIND"
<< "MMC_RECORD_STROBE"
<< "MMC_RECORD_EXIT"
+ << "MMC_RECORD_READY"
<< "MMC_PAUSE"
<< "NOTE"
<< "CC";
@@ -273,23 +287,51 @@
return true;
}
- if( sActionString == "SELECT_NEXT_PATTERN" ){
+ if( sActionString == "SELECT_NEXT_PATTERN" ){
bool ok;
int row = pAction->getParameter1().toInt(&ok,10);
if( row> pEngine->getSong()->get_pattern_list()->size() -1 )
return false;
- pEngine->setSelectedPatternNumber( row );
- pEngine->sequencer_setNextPattern( row, false, true );
+ if(Preferences::get_instance()->patternModePlaysSelected())
+ pEngine->setSelectedPatternNumber( row );
+ else
+ pEngine->sequencer_setNextPattern( row, false, true );
return true;
}
- if( sActionString == "SELECT_NEXT_PATTERN_PROMPTLY" ){
+ if( sActionString == "SELECT_NEXT_PATTERN_CC_ABSOLUT" ){
+ bool ok;
+ int row = pAction->getParameter2().toInt(&ok,10);
+ if( row> pEngine->getSong()->get_pattern_list()->size() -1 )
+ return false;
+ if(Preferences::get_instance()->patternModePlaysSelected())
+ pEngine->setSelectedPatternNumber( row );
+ else
+ return true;// only usefully in normal pattern mode
+ return true;
+ }
+
+ if( sActionString == "SELECT_NEXT_PATTERN_PROMPTLY" ){// obsolete, use SELECT_NEXT_PATTERN_CC_ABSOLUT instead
bool ok;
int row = pAction->getParameter2().toInt(&ok,10);
pEngine->setSelectedPatternNumberWithoutGuiEvent( row );
return true;
}
+ if( sActionString == "SELECT_AND_PLAY_PATTERN"){
+ bool ok;
+ int row = pAction->getParameter1().toInt(&ok,10);
+ pEngine->setSelectedPatternNumber( row );
+ pEngine->sequencer_setNextPattern( row, false, true );
+
+ int nState = pEngine->getState();
+ if ( nState == STATE_READY ){
+ pEngine->sequencer_play();
+ }
+
+ return true;
+ }
+
if( sActionString == "SELECT_INSTRUMENT" ){
bool ok;
int instrument_number = pAction->getParameter2().toInt(&ok,10) ;
@@ -603,6 +645,48 @@
return true;
}
+ if( sActionString == "BPM_FINE_CC_RELATIVE" ){
+ /*
+ * increments/decrements the BPM
+ * this is useful if the bpm is set by a rotary control knob
+ */
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ int mult = 1;
+
+ //second parameter of cc command
+ //this value should be 1 to decrement and something other then 1 to increment the bpm
+ int cc_param = 1;
+
+ //this Action should be triggered only by CC commands
+
+ bool ok;
+ mult = pAction->getParameter1().toInt(&ok,10);
+ cc_param = pAction->getParameter2().toInt(&ok,10);
+
+ if( lastBpmChangeCCParameter == -1)
+ {
+ lastBpmChangeCCParameter = cc_param;
+ }
+
+ Song* pSong = pEngine->getSong();
+
+ if ( lastBpmChangeCCParameter >= cc_param && pSong->__bpm < 300) {
+ pEngine->setBPM( pSong->__bpm - 0.01*mult );
+ }
+
+ if ( lastBpmChangeCCParameter < cc_param && pSong->__bpm > 40 ) {
+ pEngine->setBPM( pSong->__bpm + 0.01*mult );
+ }
+
+ lastBpmChangeCCParameter = cc_param;
+
+ AudioEngine::get_instance()->unlock();
+
+ return true;
+ }
+
if( sActionString == "BPM_INCR" ){
AudioEngine::get_instance()->lock( RIGHT_HERE );
@@ -622,8 +706,6 @@
return true;
}
-
-
if( sActionString == "BPM_DECR" ){
AudioEngine::get_instance()->lock( RIGHT_HERE );
@@ -652,6 +734,74 @@
pEngine->setTimelineBpm();
return true;
}
-
- return false;
+
+ if( sActionString == "PLAYLIST_NEXT_SONG"){
+ int songnumber = Playlist::get_instance()->getActiveSongNumber();
+ if(songnumber+1 >= 0 && songnumber+1 <= pEngine->m_PlayList.size()-1){
+ Playlist::get_instance()->setNextSongByNumber( songnumber + 1 );
+ }
+ return true;
+ }
+
+ if( sActionString == "PLAYLIST_PREV_SONG"){
+ int songnumber = Playlist::get_instance()->getActiveSongNumber();
+ if(songnumber-1 >= 0 && songnumber-1 <= pEngine->m_PlayList.size()-1){
+ Playlist::get_instance()->setNextSongByNumber( songnumber - 1 );
+ }
+ return true;
+ }
+
+ if( sActionString == "RECORD_READY"){
+ if ( pEngine->getState() != STATE_PLAYING ) {
+ if (!Preferences::get_instance()->getRecordEvents()) {
+ Preferences::get_instance()->setRecordEvents(true);
+ }
+ else {
+ Preferences::get_instance()->setRecordEvents(false);
+ }
+ }
+ return true;
+ }
+ if( sActionString == "RECORD/STROBE_TOGGLE"){
+ if (!Preferences::get_instance()->getRecordEvents()) {
+ Preferences::get_instance()->setRecordEvents(true);
+ }
+ else {
+ Preferences::get_instance()->setRecordEvents(false);
+ }
+ return true;
+ }
+
+ if( sActionString == "RECORD_STROBE"){
+
+ if (!Preferences::get_instance()->getRecordEvents()) {
+ Preferences::get_instance()->setRecordEvents(true);
+ }
+ return true;
+ }
+
+ if( sActionString == "RECORD_EXIT"){
+
+ if (Preferences::get_instance()->getRecordEvents()) {
+ Preferences::get_instance()->setRecordEvents(false);
+ }
+ return true;
+ }
+
+ if( sActionString == "TOGGLE_METRONOME"){
+
+ Preferences::get_instance()->m_bUseMetronome = !Preferences::get_instance()->m_bUseMetronome;
+ return true;
+ }
+
+ if( sActionString == "UNDO_ACTION"){
+ EventQueue::get_instance()->push_event( EVENT_UNDO_REDO, 0);// 0 = undo
+ return true;
+ }
+
+ if( sActionString == "REDO_ACTION"){
+ EventQueue::get_instance()->push_event( EVENT_UNDO_REDO, 1);// 1 = redo
+ return true;
+ }
+ return false;
}
diff -Nru hydrogen-0.9.6~beta1/src/core/src/object.cpp hydrogen-0.9.6~beta2/src/core/src/object.cpp
--- hydrogen-0.9.6~beta1/src/core/src/object.cpp 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/object.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -27,6 +27,20 @@
#include
#include
+
+/**
+* @class Object
+*
+* @brief Base class of all components of hydrogen.
+*
+* Every component of hydrogen is inherited from the
+* Object class. Each object has a qualified name
+* and gets registered in a memory map at creation.
+* This memory map helps to debug memory leaks and
+* can be printed at any time.
+*
+*/
+
namespace H2Core {
Logger* Object::__logger = 0;
diff -Nru hydrogen-0.9.6~beta1/src/core/src/preferences.cpp hydrogen-0.9.6~beta2/src/core/src/preferences.cpp
--- hydrogen-0.9.6~beta1/src/core/src/preferences.cpp 2011-11-04 23:07:04.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/preferences.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -73,10 +73,6 @@
m_brestartLash = false;
m_bsetLash = false;
-#ifdef H2CORE_HAVE_JACKSESSION
- m_bjackSessionUseSessionDir = false;
-#endif
-
//init pre delete default
m_nRecPreDelete = 0;
m_nRecPostDelete = 0;
@@ -89,6 +85,7 @@
//rubberband bpm change queue
m_useTheRubberbandBpmChangeEvent = false;
+ __rubberBandCalcTime = 5;
QString rubberBandCLIPath = getenv( "PATH" );
QStringList rubberBandCLIPathList = rubberBandCLIPath.split(":");//linx use ":" as seperator. maybe windows and osx use other seperators
@@ -157,14 +154,6 @@
__playsamplesonclicking = false; // audio file browser
__playselectedinstrument = false; // midi keyboard and keyboard play only selected instrument
- // __rightclickedpattereditor
- // 0 = note length
- // 1 = note off"
- // 2 = edit velocity
- // 3 = edit pan
- // 4 = edit lead lag
- __rightclickedpattereditor = 0; //right click into pattern editor add note-off-note or edit note-length
-
recordEvents = false; // not recording by default
destructiveRecord = false; // not destructively recording by default
punchInPos = 0;
@@ -172,7 +161,7 @@
__expandSongItem = true; //SoundLibraryPanel
__expandPatternItem = true; //SoundLibraryPanel
- __usetimeline = false; // use timeline
+ __useTimelineBpm = false; // use timeline
/////////////////////////////////////////////////////////////////////////
@@ -395,22 +384,19 @@
m_brestoreLastPlaylist = LocalFileMng::readXmlBool( rootNode, "restoreLastPlaylist", m_brestoreLastPlaylist );
m_bPatternModePlaysSelected = LocalFileMng::readXmlBool( rootNode, "patternModePlaysSelected", TRUE );
m_bUseLash = LocalFileMng::readXmlBool( rootNode, "useLash", FALSE );
- __usetimeline = LocalFileMng::readXmlBool( rootNode, "useTimeLine", __usetimeline );
+ __useTimelineBpm = LocalFileMng::readXmlBool( rootNode, "useTimeLine", __useTimelineBpm );
maxBars = LocalFileMng::readXmlInt( rootNode, "maxBars", 400 );
m_nDefaultUILayout = LocalFileMng::readXmlInt( rootNode, "defaultUILayout", UI_LAYOUT_SINGLE_PANE );
+ m_nLastOpenTab = LocalFileMng::readXmlInt( rootNode, "lastOpenTab", 0 );
//restore the right m_bsetlash value
m_bsetLash = m_bUseLash;
-
+ m_useTheRubberbandBpmChangeEvent = LocalFileMng::readXmlBool( rootNode, "useTheRubberbandBpmChangeEvent", m_useTheRubberbandBpmChangeEvent );
m_nRecPreDelete = LocalFileMng::readXmlInt( rootNode, "preDelete", 0 );
m_nRecPostDelete = LocalFileMng::readXmlInt( rootNode, "postDelete", 0 );
hearNewNotes = LocalFileMng::readXmlBool( rootNode, "hearNewNotes", hearNewNotes );
quantizeEvents = LocalFileMng::readXmlBool( rootNode, "quantizeEvents", quantizeEvents );
-
-#ifdef H2CORE_HAVE_JACKSESSION
- m_bjackSessionUseSessionDir = LocalFileMng::readXmlBool( rootNode, "JackSessionUseSessionDir", m_bjackSessionUseSessionDir );
-#endif
//rubberband
if( readPrefFileforotherplaces ){
@@ -751,19 +737,18 @@
LocalFileMng::writeXmlString( rootNode, "patternModePlaysSelected", m_bPatternModePlaysSelected ? "true": "false" );
LocalFileMng::writeXmlString( rootNode, "useLash", m_bsetLash ? "true": "false" );
- LocalFileMng::writeXmlString( rootNode, "useTimeLine", __usetimeline ? "true": "false" );
+ LocalFileMng::writeXmlString( rootNode, "useTimeLine", __useTimelineBpm ? "true": "false" );
LocalFileMng::writeXmlString( rootNode, "maxBars", QString::number( maxBars ) );
LocalFileMng::writeXmlString( rootNode, "defaultUILayout", QString::number( m_nDefaultUILayout ) );
+ LocalFileMng::writeXmlString( rootNode, "lastOpenTab", QString::number( m_nLastOpenTab ) );
+
+ LocalFileMng::writeXmlString( rootNode, "useTheRubberbandBpmChangeEvent", m_useTheRubberbandBpmChangeEvent ? "true": "false" );
LocalFileMng::writeXmlString( rootNode, "preDelete", QString("%1").arg(m_nRecPreDelete) );
LocalFileMng::writeXmlString( rootNode, "postDelete", QString("%1").arg(m_nRecPostDelete) );
-#ifdef H2CORE_HAVE_JACKSESSION
- LocalFileMng::writeXmlString( rootNode, "JackSessionUseSessionDir", m_bjackSessionUseSessionDir ? "true": "false" );
-#endif
-
//show development version warning
LocalFileMng::writeXmlString( rootNode, "showDevelWarning", m_bShowDevelWarning ? "true": "false" );
diff -Nru hydrogen-0.9.6~beta1/src/core/src/sampler/sampler.cpp hydrogen-0.9.6~beta2/src/core/src/sampler/sampler.cpp
--- hydrogen-0.9.6~beta1/src/core/src/sampler/sampler.cpp 2011-07-22 14:41:09.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/core/src/sampler/sampler.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -591,9 +591,21 @@
if ( ( nSamplePos + 1 ) >= nSampleFrames ) {
//we reach the last audioframe.
//set this last frame to zero do nothin wrong.
- fVal_L = 0.0;
- fVal_R = 0.0;
+ fVal_L = 0.0;
+ fVal_R = 0.0;
} else {
+ // some interpolation methods need 4 frames data.
+ float last_l;
+ float last_r;
+ if ( ( nSamplePos + 2 ) >= nSampleFrames ) {
+ last_l = 0.0;
+ last_r = 0.0;
+ }else
+ {
+ last_l = pSample_data_L[nSamplePos + 2];
+ last_r = pSample_data_R[nSamplePos + 2];
+ }
+
switch( __interpolateMode ){
case LINEAR:
@@ -607,16 +619,16 @@
fVal_R = cosine_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff);
break;
case THIRD:
- fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], pSample_data_L[nSamplePos + 2] ,fDiff);
- fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], pSample_data_R[nSamplePos + 2], fDiff);
+ fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff);
+ fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff);
break;
case CUBIC:
- fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], pSample_data_L[nSamplePos + 2] ,fDiff);
- fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], pSample_data_R[nSamplePos + 2], fDiff);
+ fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff);
+ fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff);
break;
case HERMITE:
- fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], pSample_data_L[nSamplePos + 2] ,fDiff);
- fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], pSample_data_R[nSamplePos + 2], fDiff);
+ fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff);
+ fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff);
break;
}
}
@@ -693,6 +705,18 @@
fVal_L = 0.0;
fVal_R = 0.0;
} else {
+ // some interpolation methods need 4 frames data.
+ float last_l;
+ float last_r;
+ if ( ( nSamplePos + 2 ) >= nSampleFrames ) {
+ last_l = 0.0;
+ last_r = 0.0;
+ }else
+ {
+ last_l = pSample_data_L[nSamplePos + 2];
+ last_r = pSample_data_R[nSamplePos + 2];
+ }
+
switch( __interpolateMode ){
case LINEAR:
@@ -706,16 +730,16 @@
fVal_R = cosine_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff);
break;
case THIRD:
- fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], pSample_data_L[nSamplePos + 2] ,fDiff);
- fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], pSample_data_R[nSamplePos + 2], fDiff);
+ fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff);
+ fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff);
break;
case CUBIC:
- fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], pSample_data_L[nSamplePos + 2] ,fDiff);
- fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], pSample_data_R[nSamplePos + 2], fDiff);
+ fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff);
+ fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff);
break;
case HERMITE:
- fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], pSample_data_L[nSamplePos + 2] ,fDiff);
- fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], pSample_data_R[nSamplePos + 2], fDiff);
+ fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff);
+ fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff);
break;
}
// methode Interpolate produce an extra function call and eat much more time here.
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/AboutDialog.cpp hydrogen-0.9.6~beta2/src/gui/src/AboutDialog.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/AboutDialog.cpp 2011-11-29 23:07:08.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/AboutDialog.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -66,6 +66,7 @@
authorList.push_back( Author( "Christian Vorhof", "", "Interface design concept" ) );
authorList.push_back( Author( "Daniil Kolpakov", "", "" ) );
authorList.push_back( Author( "Daniel Tonda Castillo", "", "Spanish manual" ) );
+ authorList.push_back( Author( "Dave Allan", "", "Manual review" ) );
authorList.push_back( Author( "Dave Fancella", "", "" ) );
authorList.push_back( Author( "Dave Phillips", "", "Bug reports, ideas" ) );
authorList.push_back( Author( "Derrick Karpo", "", "Patches, testing" ) );
@@ -103,10 +104,9 @@
QString sAuthors;
sAuthors += tr( "Main coder and mantainer: " );
- sAuthors += "";
-
- sAuthors += QString( "" ) + trUtf8( "Translator:%1Alessandro Cominu" ).arg( " " );
+ sAuthors += "Alessandro Cominu (aka Comix) [2001-2008]
";
+ sAuthors += "Michael Wolkstein (aka Wolke) [2008-now]
";
+ sAuthors += "Sebastian Moors (aka Mauser) [2008-now]
";
sAuthors += "Thanks to: ";
@@ -121,7 +121,7 @@
sAuthors += "";
- authorsTxt->setText( sAuthors );
+ authorsText->setText( sAuthors );
logoLabel->setPixmap( QPixmap( Skin::getImagePath() +"/about/aboutLogo.png" ) );
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/EventListener.h hydrogen-0.9.6~beta2/src/gui/src/EventListener.h
--- hydrogen-0.9.6~beta1/src/gui/src/EventListener.h 2011-10-21 16:00:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/EventListener.h 2012-05-25 12:19:45.000000000 +0000
@@ -40,6 +40,7 @@
virtual void progressEvent( int nValue ) { UNUSED( nValue ); }
virtual void jacksessionEvent( int nValue) { UNUSED( nValue ); }
virtual void playlistLoadSongEvent( int nIndex ){ UNUSED( nIndex ); }
+ virtual void undoRedoActionEvent( int nValue ){ UNUSED( nValue ); }
virtual ~EventListener() {}
};
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/ExportSongDialog.cpp hydrogen-0.9.6~beta2/src/gui/src/ExportSongDialog.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/ExportSongDialog.cpp 2011-09-29 12:04:51.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/ExportSongDialog.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -35,10 +35,14 @@
#include
#include
#include
+#include
#include
#include
#include
#include
+#include
+#include
+#include
#include
@@ -59,7 +63,7 @@
exportTypeCombo->addItem(trUtf8("Export to seperate tracks"));
exportTypeCombo->addItem(trUtf8("Both"));
- HydrogenApp::get_instance()->addEventListener( this );
+ HydrogenApp::get_instance()->addEventListener( this );
m_pProgressBar->setValue( 0 );
sampleRateCombo->setCurrentIndex(1);
@@ -78,7 +82,39 @@
m_sExtension = ".wav";
m_bOverwriteFiles = false;
+ // use of rubberband batch
+ if(checkUseOfRubberband()){
+ b_oldRubberbandBatchMode = Preferences::get_instance()->getRubberBandBatchMode();
+ toggleRubberbandCheckBox->setChecked(Preferences::get_instance()->getRubberBandBatchMode());
+ connect(toggleRubberbandCheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleRubberbandBatchMode( bool )));
+ }else
+ {
+ b_oldRubberbandBatchMode = Preferences::get_instance()->getRubberBandBatchMode();
+ toggleRubberbandCheckBox->setEnabled( false );
+ }
+
+
+ // use of timeline
+ if( Hydrogen::get_instance()->m_timelinevector.size() > 0 ){
+ toggleTimeLineBPMCheckBox->setChecked(Preferences::get_instance()->getUseTimelineBpm());
+ b_oldTimeLineBPMMode = Preferences::get_instance()->getUseTimelineBpm();
+ connect(toggleTimeLineBPMCheckBox, SIGNAL(toggled(bool)), this, SLOT(togglTimeLineBPMMode( bool )));
+ }else
+ {
+ b_oldTimeLineBPMMode = Preferences::get_instance()->getUseTimelineBpm();
+ toggleTimeLineBPMCheckBox->setEnabled( false );
+ }
+
+ // use of interpolation mode
+ m_oldInterpolation = AudioEngine::get_instance()->get_sampler()->getInterpolateMode();
+ resampleComboBox->setCurrentIndex( m_oldInterpolation );
+ connect(resampleComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(resampleComboBoIndexChanged(int)));
+
+ // if rubberbandBatch calculate time needed by lib rubberband to resample samples
+ if(b_oldRubberbandBatchMode){
+ calculateRubberbandTime();
+ }
}
@@ -152,7 +188,6 @@
m_bOverwriteFiles = false;
-
/* If the song has a tempo change, notify the user
* that hydrogen is unable export songs with
* tempo changes correctly
@@ -162,13 +197,8 @@
bool warn = Preferences::get_instance()->getShowExportWarning();
std::vector timelineVector = engine->m_timelinevector;
- if( timelineVector.size() > 0 ){
- int res = QMessageBox::information( this, "Hydrogen", tr( "This version of hydrogen is not able to export songs with tempo changes. If you proceed, the song will be exported without tempo changes."), QMessageBox::Yes | QMessageBox::No | QMessageBox::YesToAll);
- if (res == QMessageBox::No ) return;
- if (res == QMessageBox::YesToAll ) Preferences::get_instance()->setShowExportWarning(true);
- }
-
- /* 0: Export to single track
+
+ /* 0: Export to single track
* 1: Export to multiple tracks
* 2: Export to both
*/
@@ -207,47 +237,46 @@
void ExportSongDialog::exportTracks()
{
- Song *pSong = Hydrogen::get_instance()->getSong();
+ Song *pSong = Hydrogen::get_instance()->getSong();
if( m_nInstrument <= pSong->get_instrument_list()->size() -1 ){
- bool instrumentexists = false;
- //if a instrument contains no notes we jump to the next instrument
- unsigned nPatterns = pSong->get_pattern_list()->size();
- for ( unsigned i = 0; i < nPatterns; i++ ) {
- Pattern *pat = pSong->get_pattern_list()->get( i );
- const Pattern::notes_t* notes = pat->get_notes();
- FOREACH_NOTE_CST_IT_BEGIN_END(notes,it) {
- Note *pNote = it->second;
- assert( pNote );
+ bool instrumentexists = false;
+ //if a instrument contains no notes we jump to the next instrument
+ unsigned nPatterns = pSong->get_pattern_list()->size();
+ for ( unsigned i = 0; i < nPatterns; i++ ) {
+ Pattern *pat = pSong->get_pattern_list()->get( i );
+ const Pattern::notes_t* notes = pat->get_notes();
+ FOREACH_NOTE_CST_IT_BEGIN_END(notes,it) {
+ Note *pNote = it->second;
+ assert( pNote );
if( pNote->get_instrument()->get_name() == Hydrogen::get_instance()->getSong()->get_instrument_list()->get(m_nInstrument)->get_name() ){
- instrumentexists = true;
- break;
- }
+ instrumentexists = true;
+ break;
+ }
- }
- }
+ }
+ }
- if( !instrumentexists ){
+ if( !instrumentexists ){
if( m_nInstrument == Hydrogen::get_instance()->getSong()->get_instrument_list()->size() -1 ){
- m_bExportTrackouts = false;//
- HydrogenApp::get_instance()->getMixer()->soloClicked( m_nInstrument );//solo instrument. this will disable all other instrument-solos
- HydrogenApp::get_instance()->getMixer()->soloClicked( m_nInstrument );//unsolo this instrument because exporting is finished
+ m_bExportTrackouts = false;
+ HydrogenApp::get_instance()->getMixer()->unmuteAll( true );
m_nInstrument = 0;
- return;
+ return;
}else {
m_nInstrument++;
exportTracks();
return;
- }
- }
+ }
+ }
QStringList filenameList = exportNameTxt->text().split( m_sExtension );
-
+
QString firstItem;
if( !filenameList.isEmpty() ){
firstItem = filenameList.first();
- }
+ }
QString newItem = firstItem + "-" + Hydrogen::get_instance()->getSong()->get_instrument_list()->get(m_nInstrument)->get_name();
QString filename = newItem.append(m_sExtension);
@@ -256,25 +285,32 @@
int res = QMessageBox::information( this, "Hydrogen", tr( "The file %1 exists. \nOverwrite the existing file?").arg(filename), QMessageBox::Yes | QMessageBox::No | QMessageBox::YesToAll );
if (res == QMessageBox::No ) return;
if (res == QMessageBox::YesToAll ) m_bOverwriteFiles = true;
- }
+ }
- Hydrogen::get_instance()->stopExportSong();
- m_bExporting = false;
+ //Hydrogen::get_instance()->stopExportSong();
+ Hydrogen::get_instance()->stopExportSong( false );
+ m_bExporting = false;
HydrogenApp::get_instance()->getMixer()->soloClicked( m_nInstrument );
- //Preferences::get_instance()->m_bUseMetronome = !Preferences::get_instance()->m_bUseMetronome;
- Hydrogen::get_instance()->startExportSong( filename, sampleRateCombo->currentText().toInt(), sampleDepthCombo->currentText().toInt() );
-
+ Hydrogen::get_instance()->startExportSong( filename, sampleRateCombo->currentText().toInt(), sampleDepthCombo->currentText().toInt() );
+
if(! (m_nInstrument == Hydrogen::get_instance()->getSong()->get_instrument_list()->size() -1 )){
- m_nInstrument++;
+ m_nInstrument++;
}
- }
+ }
+
}
void ExportSongDialog::on_closeBtn_clicked()
{
- Hydrogen::get_instance()->stopExportSong();
+ Hydrogen::get_instance()->stopExportSong( true );
m_bExporting = false;
+ if(Preferences::get_instance()->getRubberBandBatchMode()){
+ EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
+ }
+ Preferences::get_instance()->setRubberBandBatchMode( b_oldRubberbandBatchMode );
+ Preferences::get_instance()->setUseTimelineBpm( b_oldTimeLineBPMMode );
+ setResamplerMode(m_oldInterpolation);
accept();
}
@@ -411,48 +447,198 @@
}
if( filename.endsWith( ".ogg" ) || filename.endsWith( ".OGG" ) ){
+ if( templateCombo->currentIndex() != 9 ){
templateCombo->setCurrentIndex( 9 );//ogg
- }
+ }
+ }
else if( filename.endsWith( ".flac" ) || filename.endsWith( ".FLAC" ) ){
label->show();
label_2->show();
- templateCombo->setCurrentIndex( 8 );//flac
+ if( templateCombo->currentIndex() != 8 ){
+ templateCombo->setCurrentIndex( 8 );//flac
+ }
}
else if( filename.endsWith( ".aiff" ) || filename.endsWith( ".AIFF" ) ){
label->show();
label_2->show();
- templateCombo->setCurrentIndex( 5 );//aiff
+ if( templateCombo->currentIndex() < 5 || templateCombo->currentIndex() > 7 ){
+ templateCombo->setCurrentIndex( 5 );//aiff
+ }
}
else if( filename.endsWith( ".wav" ) || filename.endsWith( ".WAV" ) ){
label->show();
label_2->show();
- templateCombo->setCurrentIndex( 0 );//wav
- }
-}
+ if( templateCombo->currentIndex() > 4 ){
+ templateCombo->setCurrentIndex( 0 );//wav
+ }
+ }
+}
void ExportSongDialog::progressEvent( int nValue )
{
m_pProgressBar->setValue( nValue );
- if ( nValue == 100 ) {
-
- m_bExporting = false;
- //Preferences::get_instance()->m_bUseMetronome = !Preferences::get_instance()->m_bUseMetronome;
+ if ( nValue == 100 ) {
+
+ m_bExporting = false;
if( m_nInstrument == Hydrogen::get_instance()->getSong()->get_instrument_list()->size() -1 ){
- HydrogenApp::get_instance()->getMixer()->soloClicked( m_nInstrument );
+ HydrogenApp::get_instance()->getMixer()->unmuteAll( false );
m_nInstrument = 0;
- m_bExportTrackouts = false;
+ m_bExportTrackouts = false;
- }
+ }
- //QFile check( exportNameTxt->text() );
- //if ( ! check.exists() ) {
- // QMessageBox::information( this, "Hydrogen", trUtf8("Export failed!") );
- //}
-
- if( m_bExportTrackouts ){
- exportTracks();
- }
- }
+ if( m_bExportTrackouts ){
+ exportTracks();
+ }
+ }
+
+ if ( nValue < 100 ) {
+ closeBtn->setEnabled(false);
+ resampleComboBox->setEnabled(false);
+
+ }else
+ {
+ closeBtn->setEnabled(true);
+ resampleComboBox->setEnabled(true);
+ }
+}
+
+void ExportSongDialog::toggleRubberbandBatchMode(bool toggled)
+{
+ Preferences::get_instance()->setRubberBandBatchMode(toggled);
+ if(toggled){
+ calculateRubberbandTime();
+ }
+}
+
+void ExportSongDialog::togglTimeLineBPMMode(bool toggled)
+{
+ Preferences::get_instance()->setUseTimelineBpm(toggled);
+}
+
+void ExportSongDialog::resampleComboBoIndexChanged(int index )
+{
+ setResamplerMode(index);
+}
+
+void ExportSongDialog::setResamplerMode(int index)
+{
+ switch ( index ){
+ case 0:
+ AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::LINEAR );
+ break;
+ case 1:
+ AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::COSINE );
+ break;
+ case 2:
+ AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::THIRD );
+ break;
+ case 3:
+ AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::CUBIC );
+ break;
+ case 4:
+ AudioEngine::get_instance()->get_sampler()->setInterpolateMode( Sampler::HERMITE );
+ break;
+ }
+}
+
+
+void ExportSongDialog::calculateRubberbandTime()
+{
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ closeBtn->setEnabled(false);
+ resampleComboBox->setEnabled(false);
+ okBtn->setEnabled(false);
+ Hydrogen* engine = Hydrogen::get_instance();
+ float oldBPM = engine->getSong()->__bpm;
+ float lowBPM = oldBPM;
+
+ if( engine->m_timelinevector.size() >= 1 ){
+ for ( int t = 0; t < engine->m_timelinevector.size(); t++){
+ if(engine->m_timelinevector[t].m_htimelinebpm < lowBPM){
+ lowBPM = engine->m_timelinevector[t].m_htimelinebpm;
+ }
+
+ }
+ }
+
+ engine->setBPM(lowBPM);
+ time_t sTime = time(NULL);
+ Hydrogen *pEngine = Hydrogen::get_instance();
+ Song *song = pEngine->getSong();
+ assert(song);
+ if(song){
+ InstrumentList *songInstrList = song->get_instrument_list();
+ assert(songInstrList);
+ for ( unsigned nInstr = 0; nInstr < songInstrList->size(); ++nInstr ) {
+ Instrument *pInstr = songInstrList->get( nInstr );
+ assert( pInstr );
+ if ( pInstr ){
+ for ( int nLayer = 0; nLayer < MAX_LAYERS; nLayer++ ) {
+ InstrumentLayer *pLayer = pInstr->get_layer( nLayer );
+ if ( pLayer ) {
+ Sample *pSample = pLayer->get_sample();
+ if ( pSample ) {
+ if( pSample->get_rubberband().use ) {
+ Sample *newSample = Sample::load(
+ pSample->get_filepath(),
+ pSample->get_loops(),
+ pSample->get_rubberband(),
+ *pSample->get_velocity_envelope(),
+ *pSample->get_pan_envelope()
+ );
+ if( !newSample ){
+ continue;
+ }
+ delete pSample;
+ // insert new sample from newInstrument
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+ pLayer->set_sample( newSample );
+ AudioEngine::get_instance()->unlock();
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Preferences::get_instance()->setRubberBandCalcTime(time(NULL) - sTime);
+ engine->setBPM(oldBPM);
+ closeBtn->setEnabled(true);
+ resampleComboBox->setEnabled(true);
+ okBtn->setEnabled(true);
+ QApplication::restoreOverrideCursor();
+
+}
+
+bool ExportSongDialog::checkUseOfRubberband()
+{
+ Hydrogen *pEngine = Hydrogen::get_instance();
+ Song *song = pEngine->getSong();
+ assert(song);
+ if(song){
+ InstrumentList *songInstrList = song->get_instrument_list();
+ assert(songInstrList);
+ for ( unsigned nInstr = 0; nInstr < songInstrList->size(); ++nInstr ) {
+ Instrument *pInstr = songInstrList->get( nInstr );
+ assert( pInstr );
+ if ( pInstr ){
+ for ( int nLayer = 0; nLayer < MAX_LAYERS; nLayer++ ) {
+ InstrumentLayer *pLayer = pInstr->get_layer( nLayer );
+ if ( pLayer ) {
+ Sample *pSample = pLayer->get_sample();
+ if ( pSample ) {
+ if( pSample->get_rubberband().use ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/ExportSongDialog.h hydrogen-0.9.6~beta2/src/gui/src/ExportSongDialog.h
--- hydrogen-0.9.6~beta1/src/gui/src/ExportSongDialog.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/ExportSongDialog.h 2012-05-25 12:19:45.000000000 +0000
@@ -52,14 +52,26 @@
void on_okBtn_clicked();
void on_exportNameTxt_textChanged(const QString& text);
void on_templateCombo_currentIndexChanged(int index );
+ void toggleRubberbandBatchMode(bool toggled);
+ void togglTimeLineBPMMode(bool toggled);
+ void resampleComboBoIndexChanged(int index );
private:
- bool m_bExporting;
+
+ void setResamplerMode(int index);
+ void calculateRubberbandTime();
+ bool checkUseOfRubberband();
+
+ bool m_bExporting;
void exportTracks();
bool m_bExportTrackouts;
bool m_bOverwriteFiles;
uint m_nInstrument;
QString m_sExtension;
+ bool b_oldRubberbandBatchMode;
+ bool b_oldTimeLineBPMMode;
+ int m_oldInterpolation;
+
};
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/HydrogenApp.cpp hydrogen-0.9.6~beta2/src/gui/src/HydrogenApp.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/HydrogenApp.cpp 2011-10-21 16:00:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/HydrogenApp.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -22,6 +22,11 @@
#include
#include
+#include
+#include
+#include
+#include
+#include
#include "HydrogenApp.h"
#include "Skin.h"
@@ -32,6 +37,7 @@
#include "HelpBrowser.h"
#include "LadspaFXProperties.h"
#include "InstrumentRack.h"
+#include "Director.h"
#include "PatternEditor/PatternEditorPanel.h"
#include "InstrumentEditor/InstrumentEditorPanel.h"
@@ -39,19 +45,14 @@
#include "SongEditor/SongEditorPanel.h"
#include "PlaylistEditor/PlaylistDialog.h"
#include "SampleEditor/SampleEditor.h"
-#include "Director.h"
-
#include "Mixer/Mixer.h"
#include "Mixer/MixerLine.h"
+#include "UndoActions.h"
+
-#include
-#include
-#include
-#include
-//#include
#include
-//#include
+
using namespace H2Core;
@@ -117,7 +118,7 @@
m_pDirector = new Director( 0 );
// m_pSampleEditor = new SampleEditor( 0 );
- showInfoSplash(); // First time information
+ showInfoSplash(); // First time information
}
@@ -127,13 +128,9 @@
INFOLOG( "[~HydrogenApp]" );
m_pEventQueueTimer->stop();
+
//delete the undo tmp directory
- QString dataDir = Preferences::get_instance()->getTmpDirectory();
- QString cmd = QString( "rm -rf \"" ) + dataDir + "\"";
- INFOLOG( cmd );
- if ( system( cmd.toLocal8Bit() ) != 0 ) {
- ERRORLOG( "Error executing '" + cmd + "'" );
- }
+ cleanupTemporaryFiles();
delete m_pHelpBrowser;
delete m_pAudioEngineInfoForm;
@@ -181,11 +178,11 @@
m_pMainForm->resize( mainFormProp.width, mainFormProp.height );
m_pMainForm->move( mainFormProp.x, mainFormProp.y );
- QSplitter *pSplitter = new QSplitter( NULL );
+ pSplitter = new QSplitter( NULL );
pSplitter->setOrientation( Qt::Vertical );
pSplitter->setOpaqueResize( true );
- QTabWidget *pTab = new QTabWidget( NULL );
+ pTab = new QTabWidget( NULL );
pTab->setStyleSheet("color: white;");
// SONG EDITOR
@@ -198,7 +195,7 @@
m_pSongEditorPanel->resize( songEditorProp.width, songEditorProp.height );
if( uiLayout == Preferences::UI_LAYOUT_TABBED)
- pTab->addTab( m_pSongEditorPanel, "Song Editor" );
+ pTab->addTab( m_pSongEditorPanel, trUtf8("Song Editor") );
// this HBox will contain the InstrumentRack and the Pattern editor
QWidget *pSouthPanel = new QWidget( pSplitter );
@@ -211,9 +208,9 @@
m_pInstrumentRack = new InstrumentRack( NULL );
if( uiLayout == Preferences::UI_LAYOUT_TABBED ){
- pTab->setMovable(true);
- pTab->setTabsClosable(true);
- pTab->addTab( pSouthPanel, " Instrument + Pattern " );
+ pTab->setMovable( false );
+ pTab->setTabsClosable( false );
+ pTab->addTab( pSouthPanel, trUtf8( "Instrument + Pattern") );
}
// PATTERN EDITOR
@@ -239,8 +236,10 @@
if( uiLayout == Preferences::UI_LAYOUT_SINGLE_PANE)
pMainVBox->addWidget( pSplitter );
- else
- pMainVBox->addWidget( pTab );
+ else {
+ pMainVBox->addWidget( pTab );
+
+ }
mainArea->setLayout( pMainVBox );
@@ -255,7 +254,7 @@
m_pMixer->move( mixerProp.x, mixerProp.y );
if( uiLayout == Preferences::UI_LAYOUT_TABBED){
- pTab->addTab(m_pMixer,"Mixer");
+ pTab->addTab(m_pMixer,trUtf8("Mixer"));
}
m_pMixer->updateMixer();
@@ -289,10 +288,19 @@
}
#endif
-// m_pMainForm->showMaximized();
+ if( uiLayout == Preferences::UI_LAYOUT_TABBED){
+ pTab->setCurrentIndex( Preferences::get_instance()->getLastOpenTab() );
+ QObject::connect(pTab, SIGNAL(currentChanged(int)),this,SLOT(currentTabChanged(int)));
+ }
}
+
+void HydrogenApp::currentTabChanged(int index)
+{
+ Preferences::get_instance()->setLastOpenTab( index );
+}
+
void HydrogenApp::closeFXProperties()
{
#ifdef H2CORE_HAVE_LADSPA
@@ -335,7 +343,39 @@
void HydrogenApp::showMixer(bool show)
{
- m_pMixer->setVisible( show );
+ /*
+ * Switch to Mixer tab with alt+m in tabbed mode,
+ * otherwise open mixer window
+ */
+
+ Preferences *pPref = Preferences::get_instance();
+ int uiLayout = pPref->getDefaultUILayout();
+
+ if( uiLayout == Preferences::UI_LAYOUT_TABBED )
+ {
+ pTab->setCurrentIndex( 2 );
+ } else {
+ m_pMixer->setVisible( show );
+ }
+}
+
+void HydrogenApp::showInstrumentPanel(bool show)
+{
+ /*
+ * Switch to pattern editor/instrument tab in tabbed mode,
+ * otherwise hide instrument panel
+ */
+
+ Preferences *pPref = Preferences::get_instance();
+ int uiLayout = pPref->getDefaultUILayout();
+
+ if( uiLayout == Preferences::UI_LAYOUT_TABBED )
+ {
+ pTab->setCurrentIndex( 1 );
+ getInstrumentRack()->setHidden( show );
+ } else {
+ getInstrumentRack()->setHidden( show );
+ }
}
@@ -521,12 +561,45 @@
case EVENT_PLAYLIST_LOADSONG:
pListener->playlistLoadSongEvent( event.value );
break;
+
+ case EVENT_UNDO_REDO:
+ pListener->undoRedoActionEvent( event.value );
+ break;
+
default:
ERRORLOG( QString("[onEventQueueTimer] Unhandled event: %1").arg( event.type ) );
}
}
- }
+ }
+
+ // midi notes
+ while(!pQueue->m_addMidiNoteVector.empty()){
+
+ int rounds = 1;
+ if(pQueue->m_addMidiNoteVector[0].b_noteExist)// runn twice, delete old note and add new note. this let the undo stack consistent
+ rounds = 2;
+ for(int i = 0; im_addMidiNoteVector[0].m_column,
+ pQueue->m_addMidiNoteVector[0].m_row,
+ pQueue->m_addMidiNoteVector[0].m_pattern,
+ pQueue->m_addMidiNoteVector[0].m_length,
+ pQueue->m_addMidiNoteVector[0].f_velocity,
+ pQueue->m_addMidiNoteVector[0].f_pan_L,
+ pQueue->m_addMidiNoteVector[0].f_pan_R,
+ 0.0,
+ pQueue->m_addMidiNoteVector[0].nk_noteKeyVal,
+ pQueue->m_addMidiNoteVector[0].no_octaveKeyVal,
+ false,
+ false,
+ pQueue->m_addMidiNoteVector[0].b_isMidi,
+ pQueue->m_addMidiNoteVector[0].b_isInstrumentMode);
+
+ HydrogenApp::get_instance()->m_undoStack->push( action );
+ }
+ pQueue->m_addMidiNoteVector.erase(pQueue->m_addMidiNoteVector.begin());
+
+ }
}
@@ -547,3 +620,26 @@
}
}
+
+/**
+ * Adds temporary file to the list
+ */
+void HydrogenApp::addTemporaryFile( const QString& path)
+{
+ temporaryFileList.append( path );
+}
+
+
+/**
+ * Removes temporary files that were created
+ * for undo'ing things.
+ */
+void HydrogenApp::cleanupTemporaryFiles()
+{
+ for (int i = 0; i < temporaryFileList.size(); ++i){
+ Filesystem::rm( temporaryFileList[i] );
+ }
+
+ Filesystem::rm( Preferences::get_instance()->getTmpDirectory() );
+}
+
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/HydrogenApp.h hydrogen-0.9.6~beta2/src/gui/src/HydrogenApp.h
--- hydrogen-0.9.6~beta1/src/gui/src/HydrogenApp.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/HydrogenApp.h 2012-05-25 12:19:45.000000000 +0000
@@ -32,6 +32,7 @@
#include
#include
#include
+ #include
namespace H2Core
{
@@ -71,6 +72,7 @@
void showPreferencesDialog();
void showMixer(bool bShow);
+ void showInstrumentPanel(bool);
void showAudioEngineInfoForm();
void showPlaylistDialog();
void showDirector();
@@ -89,6 +91,8 @@
InstrumentRack* getInstrumentRack(){ return m_pInstrumentRack; }
QUndoStack* m_undoStack;
+ QTabWidget *pTab;
+ QSplitter *pSplitter;
void setStatusBarMessage( const QString& msg, int msec = 0 );
@@ -105,8 +109,12 @@
void onDrumkitLoad( QString name );
void enableDestructiveRecMode();
+ void cleanupTemporaryFiles();
+ void addTemporaryFile( const QString& );
+
public slots:
void onEventQueueTimer();
+ void currentTabChanged(int);
private:
static HydrogenApp *m_pInstance; ///< HydrogenApp instance
@@ -114,6 +122,7 @@
#ifdef H2CORE_HAVE_LADSPA
LadspaFXProperties *m_pLadspaFXProperties[MAX_FX];
#endif
+
MainForm *m_pMainForm;
Mixer *m_pMixer;
PatternEditorPanel* m_pPatternEditorPanel;
@@ -128,6 +137,7 @@
Director *m_pDirector;
QTimer *m_pEventQueueTimer;
std::vector m_eventListeners;
+ QStringList temporaryFileList;
// implement EngineListener interface
void engineError(uint nErrorCode);
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/InstrumentEditor/InstrumentEditor.cpp hydrogen-0.9.6~beta2/src/gui/src/InstrumentEditor/InstrumentEditor.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/InstrumentEditor/InstrumentEditor.cpp 2011-12-04 16:40:41.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/InstrumentEditor/InstrumentEditor.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -847,7 +847,7 @@
void InstrumentEditor::rubberbandbpmchangeEvent()
{
- if( !Preferences::get_instance()->m_useTheRubberbandBpmChangeEvent /*&& Preferences::get_instance()->__usetimeline */){
+ if( !Preferences::get_instance()->getRubberBandBatchMode() /*&& Preferences::get_instance()->__usetimeline */){
//we return also if time-line is activated. this wont work.
// INFOLOG( "Tempo change: Recomputing rubberband samples is disabled" );
return;
@@ -892,6 +892,6 @@
}
}
}
- }
+ }
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/main.cpp hydrogen-0.9.6~beta2/src/gui/src/main.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/main.cpp 2011-11-04 23:20:37.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/main.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -130,6 +130,7 @@
defaultPalette.setColor( QPalette::HighlightedText, QColor( 255, 255, 255 ) );
pQApp->setPalette( defaultPalette );
+ pQApp->setStyleSheet("QToolTip {padding: 1px; border: 1px solid rgb(199, 202, 204); background-color: rgb(227, 243, 252); color: rgb(64, 64, 66);}");
}
@@ -411,13 +412,6 @@
MainForm *pMainForm = new MainForm( pQApp, songFilename );
pMainForm->show();
pSplash->finish( pMainForm );
- bool loadlist = HydrogenApp::get_instance()->getPlayListDialog()->loadListByFileName( playlistFilename );
- if( loadlist ){
- Playlist::get_instance()->setNextSongByNumber( 0 );
- }else
- {
- ___ERRORLOG ( "Error loading the playlist" );
- }
if( ! playlistFilename.isEmpty() ){
bool loadlist = HydrogenApp::get_instance()->getPlayListDialog()->loadListByFileName( playlistFilename );
@@ -451,6 +445,7 @@
delete H2Core::Logger::get_instance();
if (H2Core::Object::count_active()) {
+
H2Core::Object::write_objects_map_to_cerr();
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/MainForm.cpp hydrogen-0.9.6~beta2/src/gui/src/MainForm.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/MainForm.cpp 2011-12-04 16:23:30.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/MainForm.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -250,7 +250,7 @@
m_pFileMenu->addSeparator(); // -----
m_pFileMenu->addAction( trUtf8( "&Open" ), this, SLOT( action_file_open() ), QKeySequence( "Ctrl+O" ) );
- m_pFileMenu->addAction( trUtf8( "&Open Demo" ), this, SLOT( action_file_openDemo() ), QKeySequence( "Ctrl+D" ) );
+ m_pFileMenu->addAction( trUtf8( "Open &Demo" ), this, SLOT( action_file_openDemo() ), QKeySequence( "Ctrl+D" ) );
m_pRecentFilesMenu = m_pFileMenu->addMenu( trUtf8( "Open &recent" ) );
@@ -281,7 +281,7 @@
//~ FILE menu
// Undo menu
- QMenu *m_pUndoMenu = m_pMenubar->addMenu( trUtf8( "Undo" ) );
+ QMenu *m_pUndoMenu = m_pMenubar->addMenu( trUtf8( "&Undo" ) );
m_pUndoMenu->addAction( trUtf8( "Undo" ), this, SLOT( action_undo() ), QKeySequence( "Ctrl+Z" ) );
m_pUndoMenu->addAction( trUtf8( "Redo" ), this, SLOT( action_redo() ), QKeySequence( "Shift+Ctrl+Z" ) );
m_pUndoMenu->addAction( trUtf8( "Undo history" ), this, SLOT( openUndoStack() ), QKeySequence( "" ) );
@@ -300,16 +300,32 @@
// Tools menu
QMenu *m_pToolsMenu = m_pMenubar->addMenu( trUtf8( "&Tools" ));
-// if ( Preferences::get_instance()->getInterfaceMode() == Preferences::SINGLE_PANED ) {
-// m_pWindowMenu->addAction( trUtf8("Show song editor"), this, SLOT( action_window_showSongEditor() ), QKeySequence( "" ) );
-// }
m_pToolsMenu->addAction( trUtf8("Playlist &editor"), this, SLOT( action_window_showPlaylistDialog() ), QKeySequence( "" ) );
m_pToolsMenu->addAction( trUtf8("Director"), this, SLOT( action_window_show_DirectorWidget() ), QKeySequence( "Alt+D" ) );
m_pToolsMenu->addAction( trUtf8("&Mixer"), this, SLOT( action_window_showMixer() ), QKeySequence( "Alt+M" ) );
m_pToolsMenu->addAction( trUtf8("&Instrument Rack"), this, SLOT( action_window_showDrumkitManagerPanel() ), QKeySequence( "Alt+I" ) );
- m_pToolsMenu->addAction( trUtf8("&Preferences"), this, SLOT( showPreferencesDialog() ), QKeySequence( "Alt+P" ) );
+
+
+ m_pInputModeMenu = m_pToolsMenu->addMenu( trUtf8( "Input mode" ) );
+ m_pInstrumentAction = m_pInputModeMenu->addAction( trUtf8( "Instrument" ), this, SLOT( action_toggle_input_mode()), QKeySequence( "Ctrl+Alt+I" ) );
+ m_pInstrumentAction->setCheckable( true );
+
+ m_pDrumkitAction = m_pInputModeMenu->addAction( trUtf8( "Drumkit" ), this, SLOT( action_toggle_input_mode()), QKeySequence( "Ctrl+Alt+D" ) );
+ m_pDrumkitAction->setCheckable( true );
+
+ if( Preferences::get_instance()->__playselectedinstrument )
+ {
+ m_pInstrumentAction->setChecked( true );
+ m_pDrumkitAction->setChecked (false );
+ } else {
+ m_pInstrumentAction->setChecked( false );
+ m_pDrumkitAction->setChecked (true );
+ }
+
+
+ m_pToolsMenu->addAction( trUtf8("&Preferences"), this, SLOT( showPreferencesDialog() ), QKeySequence( "Alt+P" ) );
//~ Tools menu
@@ -470,6 +486,7 @@
fd->setFilter( trUtf8("Hydrogen Song (*.h2song)") );
fd->setAcceptMode( QFileDialog::AcceptSave );
fd->setWindowTitle( trUtf8( "Save song" ) );
+ fd->setSidebarUrls( fd->sidebarUrls() << QUrl::fromLocalFile( Filesystem::songs_dir() ) );
Song *song = Hydrogen::get_instance()->getSong();
QString defaultFilename;
@@ -486,7 +503,7 @@
fd->selectFile( defaultFilename );
QString filename;
- if (fd->exec() == QDialog::Accepted) {
+ if (fd->exec() == QDialog::Accepted) {
filename = fd->selectedFiles().first();
}
@@ -510,10 +527,10 @@
Song *song = Hydrogen::get_instance()->getSong();
QString filename = song->get_filename();
- if ( filename.isEmpty() ) {
- // just in case!
- return action_file_save_as();
- }
+ if ( filename.isEmpty() ) {
+ // just in case!
+ return action_file_save_as();
+ }
bool saved = false;
saved = song->save( filename );
@@ -538,6 +555,19 @@
}
+void MainForm::action_toggle_input_mode()
+{
+ if( !Preferences::get_instance()->__playselectedinstrument )
+ {
+ Preferences::get_instance()->__playselectedinstrument = true;
+ m_pInstrumentAction->setChecked( true );
+ m_pDrumkitAction->setChecked (false );
+ } else {
+ Preferences::get_instance()->__playselectedinstrument = false;
+ m_pInstrumentAction->setChecked( false );
+ m_pDrumkitAction->setChecked (true );
+ }
+}
void MainForm::action_help_about() {
@@ -579,6 +609,7 @@
fd->setAcceptMode ( QFileDialog::AcceptSave );
fd->setWindowTitle ( trUtf8 ( "Save Pattern as ..." ) );
fd->setDirectory ( dir );
+ fd->setSidebarUrls( fd->sidebarUrls() << QUrl::fromLocalFile( Filesystem::patterns_dir() ) );
@@ -768,7 +799,6 @@
{
bool isVisible = HydrogenApp::get_instance()->getMixer()->isVisible();
h2app->showMixer( !isVisible );
- qDebug()<< isVisible;
}
@@ -1257,7 +1287,6 @@
//int songnumber = 0;
HydrogenApp* app = HydrogenApp::get_instance();
Hydrogen* engine = Hydrogen::get_instance();
-
switch (k->key()) {
case Qt::Key_Space:
onPlayStopAccelEvent();
@@ -1293,7 +1322,17 @@
onSaveAccelEvent();
return TRUE;
break;
-
+/*
+ case Qt::Key_T:
+ if( engine->getSong()->get_mode() == Song::PATTERN_MODE ){
+ engine->getSong()->set_mode( Song::SONG_MODE);
+ }
+ else if ( engine->getSong()->get_mode() == Song::SONG_MODE ) {
+ engine->getSong()->set_mode( Song::PATTERN_MODE );
+ }
+ return TRUE;
+ break;
+*/
case Qt::Key_F5 :
if( engine->m_PlayList.size() == 0)
break;
@@ -1469,9 +1508,6 @@
case 1:
action_file_exit();
break;
- case 3:
- action_file_save();
- QMessageBox::information( this, "Hydrogen", trUtf8( "Sorry, the Hydrogen-Songfile is not saved properly in this Jack-Session! You have to repeat the \"Save-Session\" procedure from your Jack-Session-Manager.") );
}
}
@@ -1647,6 +1683,13 @@
h2app->m_undoStack->redo();
}
+void MainForm::undoRedoActionEvent( int nEvent ){
+ if(nEvent == 0)
+ h2app->m_undoStack->undo();
+ else if(nEvent == 1)
+ h2app->m_undoStack->redo();
+}
+
bool MainForm::handleSelectNextPrevSongOnPlaylist( int step )
{
int playlistSize= Hydrogen::get_instance()->m_PlayList.size();
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/MainForm.h hydrogen-0.9.6~beta2/src/gui/src/MainForm.h
--- hydrogen-0.9.6~beta1/src/gui/src/MainForm.h 2011-10-21 16:00:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/MainForm.h 2012-05-25 12:19:45.000000000 +0000
@@ -27,6 +27,7 @@
#include
#include
+#include
#include "EventListener.h"
@@ -55,6 +56,7 @@
virtual void errorEvent( int nErrorCode );
virtual void jacksessionEvent( int nValue);
virtual void playlistLoadSongEvent(int nIndex);
+ virtual void undoRedoActionEvent( int nEvent );
static void usr1SignalHandler(int unused);
@@ -65,7 +67,7 @@
void action_file_new();
void action_file_open();
void action_file_openDemo();
- void action_file_save();
+ void action_file_save();
void action_file_save_as();
void action_file_openPattern();
void action_file_export_pattern_as();
@@ -112,6 +114,8 @@
void action_undo();
void action_redo();
+ void action_toggle_input_mode();
+
void handleSigUsr1();
private slots:
@@ -130,6 +134,9 @@
void functionDeleteInstrument(int instrument);
+ QMenu *m_pInputModeMenu;
+ QAction *m_pInstrumentAction;
+ QAction *m_pDrumkitAction;
QMenu *m_pRecentFilesMenu;
QAction *m_pRecentFileAction0;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/Mixer/Mixer.cpp hydrogen-0.9.6~beta2/src/gui/src/Mixer/Mixer.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/Mixer/Mixer.cpp 2011-05-09 01:37:41.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/Mixer/Mixer.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -210,7 +210,28 @@
Hydrogen::get_instance()->setSelectedInstrumentNumber(nLine);
}
-
+void Mixer::unmuteAll( bool findSelectedInstr )
+{
+ if(findSelectedInstr)
+ unmuteAll( Hydrogen::get_instance()->getSelectedInstrumentNumber() );
+ else
+ unmuteAll( 0 );
+}
+
+void Mixer::unmuteAll( int selectedInstrument )
+{
+ Hydrogen *pEngine = Hydrogen::get_instance();
+ Song *pSong = pEngine->getSong();
+ InstrumentList *pInstrList = pSong->get_instrument_list();
+ int nInstruments = pInstrList->size();
+ for ( int i = 0; i < nInstruments; ++i ) {
+ m_pMixerLine[i]->setMuteClicked( false );
+ m_pMixerLine[i]->setSoloClicked( false );
+ pInstrList->get( i )->set_muted( false );
+ }
+ // select first instrument after unmute all
+ Hydrogen::get_instance()->setSelectedInstrumentNumber(selectedInstrument);
+}
void Mixer::soloClicked(MixerLine* ref)
{
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/Mixer/Mixer.h hydrogen-0.9.6~beta2/src/gui/src/Mixer/Mixer.h
--- hydrogen-0.9.6~beta1/src/gui/src/Mixer/Mixer.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/Mixer/Mixer.h 2012-05-25 12:19:45.000000000 +0000
@@ -59,6 +59,8 @@
void noteOnClicked(MixerLine* ref);
void noteOffClicked(MixerLine* ref);
void muteClicked(MixerLine* ref);
+ void unmuteAll( bool findSelectedInstr);
+ void unmuteAll( int selectedInstr);
void soloClicked(MixerLine* ref);
void volumeChanged(MixerLine* ref);
void panChanged(MixerLine* ref);
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/DrumPatternEditor.cpp hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/DrumPatternEditor.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/DrumPatternEditor.cpp 2011-07-21 20:13:49.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/DrumPatternEditor.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -46,8 +46,6 @@
#include
#include
-#include
-
using namespace std;
using namespace H2Core;
@@ -63,7 +61,6 @@
, m_pPattern( NULL )
, m_pPatternEditorPanel( panel )
{
- //setAttribute(Qt::WA_NoBackground);
setFocusPolicy(Qt::ClickFocus);
m_nGridWidth = Preferences::get_instance()->getPatternEditorGridWidth();
@@ -166,7 +163,15 @@
return;
}
Instrument *pSelectedInstrument = pSong->get_instrument_list()->get( row );
- if (ev->button() == Qt::LeftButton ) {
+
+
+ if( ev->button() == Qt::LeftButton && (ev->modifiers() & Qt::ShiftModifier) )
+ {
+ //shift + leftClick: add noteOff note
+ SE_addNoteRightClickAction *action = new SE_addNoteRightClickAction( nColumn, row, __selectedPatternNumber );
+ HydrogenApp::get_instance()->m_undoStack->push( action );
+ }
+ else if (ev->button() == Qt::LeftButton ) {
H2Core::Note *pDraggedNote = m_pPattern->find_note( nColumn, nRealColumn, pSelectedInstrument );
@@ -178,6 +183,7 @@
Note::Key oldNoteKeyVal = Note::C;
Note::Octave oldOctaveKeyVal = Note::P8;
+ bool noteExisted = false;
if( pDraggedNote ){
oldLength = pDraggedNote->get_length();
oldVelocity = pDraggedNote->get_velocity();
@@ -186,8 +192,10 @@
oldLeadLag = pDraggedNote->get_lead_lag();
oldNoteKeyVal = pDraggedNote->get_key();
oldOctaveKeyVal = pDraggedNote->get_octave();
+ noteExisted = true;
}
+
SE_addNoteAction *action = new SE_addNoteAction( nColumn,
row,
__selectedPatternNumber,
@@ -197,22 +205,17 @@
oldPan_R,
oldLeadLag,
oldNoteKeyVal,
- oldOctaveKeyVal );
+ oldOctaveKeyVal,
+ noteExisted,
+ Preferences::get_instance()->getHearNewNotes(),
+ false,
+ false);
+
HydrogenApp::get_instance()->m_undoStack->push( action );
- } else if (ev->button() == Qt::RightButton ) {
+
+ } else if (ev->button() == Qt::RightButton ) {
m_bRightBtnPressed = true;
- // __rightclickedpattereditor
- // 0 = note length
- // 1 = note off"
- // 2 = edit velocity
- // 3 = edit pan
- // 4 = edit lead lag
- if ( Preferences::get_instance()->__rightclickedpattereditor == 1){
- SE_addNoteRightClickAction *action = new SE_addNoteRightClickAction( nColumn, row, __selectedPatternNumber );
- HydrogenApp::get_instance()->m_undoStack->push( action );
- return;
- }
- // AudioEngine::get_instance()->lock( RIGHT_HERE );
+
m_pDraggedNote = m_pPattern->find_note( nColumn, nRealColumn, pSelectedInstrument, false );
// needed for undo note length
__nRealColumn = nRealColumn;
@@ -223,7 +226,6 @@
} else {
__oldLength = -1;
}
- // AudioEngine::get_instance()->unlock();
}
}
@@ -236,7 +238,11 @@
float oldPan_R,
float oldLeadLag,
int oldNoteKeyVal,
- int oldOctaveKeyVal )
+ int oldOctaveKeyVal,
+ bool listen,
+ bool isMidi,
+ bool isInstrumentMode,
+ bool isNoteOff)
{
Hydrogen *pEngine = Hydrogen::get_instance();
@@ -252,45 +258,70 @@
Song *pSong = Hydrogen::get_instance()->getSong();
- int nInstruments = pSong->get_instrument_list()->size();
Instrument *pSelectedInstrument = pSong->get_instrument_list()->get( row );
m_bRightBtnPressed = false;
- AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
+ AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
- bool bNoteAlreadyExist = false;
- Pattern::notes_t* notes = (Pattern::notes_t*)pPattern->get_notes();
- FOREACH_NOTE_IT_BOUND(notes,it,nColumn) {
- Note *pNote = it->second;
- assert( pNote );
- if ( pNote->get_instrument() == pSelectedInstrument ) {
- // the note exists...remove it!
- bNoteAlreadyExist = true;
- delete pNote;
- notes->erase( it );
- break;
- }
- }
+ bool bNoteAlreadyExist = false;
+ if(!isInstrumentMode){
+ Pattern::notes_t* notes = (Pattern::notes_t*)pPattern->get_notes();
+ FOREACH_NOTE_IT_BOUND(notes,it,nColumn) {
+ Note *pNote = it->second;
+ assert( pNote );
+ if ( pNote->get_instrument() == pSelectedInstrument ) {
+
+ // the note exists...remove it!
+ bNoteAlreadyExist = true;
+ delete pNote;
+ notes->erase( it );
+ break;
+ }
+ }
+ }
+ else
+ {
+ Note* note = pPattern->find_note( nColumn, -1, pSelectedInstrument, (Note::Key)oldNoteKeyVal, (Note::Octave)oldOctaveKeyVal );
+ if( note ) {
+
+ // the note exists...remove it!
+ bNoteAlreadyExist = true;
+ m_pPattern->remove_note( note );
+ delete note;
+ }
+ }
- if ( bNoteAlreadyExist == false ) {
+
+ if ( bNoteAlreadyExist == false ) {
// create the new note
- const unsigned nPosition = nColumn;
- const float fVelocity = oldVelocity;
- const float fPan_L = oldPan_L ;
- const float fPan_R = oldPan_R;
+ unsigned nPosition = nColumn;
+ float fVelocity = oldVelocity;
+ float fPan_L = oldPan_L ;
+ float fPan_R = oldPan_R;
int nLength = oldLength;
+
+ if( isNoteOff )
+ {
+ fVelocity = 0.0f;
+ fPan_L = 0.5f;
+ fPan_R = 0.5f;
+ nLength = 1;
+ }
+
const float fPitch = 0.0f;
Note *pNote = new Note( pSelectedInstrument, nPosition, fVelocity, fPan_L, fPan_R, nLength, fPitch );
- pNote->set_note_off( false );
- pNote->set_lead_lag( oldLeadLag );
- pNote->set_key_octave( (Note::Key)oldNoteKeyVal, (Note::Octave)oldOctaveKeyVal );
+ pNote->set_note_off( isNoteOff );
+ if( !isNoteOff ) pNote->set_lead_lag( oldLeadLag );
+ pNote->set_key_octave( (Note::Key)oldNoteKeyVal, (Note::Octave)oldOctaveKeyVal );
pPattern->insert_note( pNote );
- // hear note
- Preferences *pref = Preferences::get_instance();
- if ( pref->getHearNewNotes() ) {
+ if(isMidi){
+ pNote->set_just_recorded(true);
+ }
+ // hear note
+ if ( listen && !isNoteOff ) {
Note *pNote2 = new Note( pSelectedInstrument, 0, fVelocity, fPan_L, fPan_R, nLength, fPitch);
AudioEngine::get_instance()->get_sampler()->note_on(pNote2);
}
@@ -314,61 +345,6 @@
}
-void DrumPatternEditor::addNoteRightClickAction( int nColumn, int row, int selectedPatternNumber )
-{
-
- Hydrogen *pEngine = Hydrogen::get_instance();
- PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
-
- H2Core::Pattern *pPattern;
- if ( (selectedPatternNumber != -1) && ( (uint)selectedPatternNumber < pPatternList->size() ) ) {
- pPattern = pPatternList->get( selectedPatternNumber );
- }
- else {
- pPattern = NULL;
- }
-
- Song *pSong = Hydrogen::get_instance()->getSong();
- int nInstruments = pSong->get_instrument_list()->size();
- Instrument *pSelectedInstrument = pSong->get_instrument_list()->get( row );
-
-
- m_bRightBtnPressed = true;
- m_pDraggedNote = NULL;
-
- AudioEngine::get_instance()->lock( RIGHT_HERE );
-
- // create the new note
- const unsigned nPosition = nColumn;
- const float fVelocity = 0.0f;
- const float fPan_L = 0.5f;
- const float fPan_R = 0.5f;
- const int nLength = 1;
- const float fPitch = 0.0f;
- Note *poffNote = new Note( pSelectedInstrument, nPosition, fVelocity, fPan_L, fPan_R, nLength, fPitch);
- poffNote->set_note_off( true );
- pPattern->insert_note( poffNote );
-
- pSong->__is_modified = true;
-
- AudioEngine::get_instance()->unlock();
-
- // update the selected line
- int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
- if (nSelectedInstrument != row) {
- Hydrogen::get_instance()->setSelectedInstrumentNumber( row );
- }
- else {
- update( 0, 0, width(), height() );
- m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
- m_pPatternEditorPanel->getPanEditor()->updateEditor();
- m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
- m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
- m_pPatternEditorPanel->getPianoRollEditor()->updateEditor();
- }
-}
-
-
void DrumPatternEditor::mouseReleaseEvent(QMouseEvent *ev)
{
UNUSED( ev );
@@ -378,7 +354,7 @@
return;
}
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor == 0 ) ) {
+ if ( m_bRightBtnPressed && m_pDraggedNote ) {
if ( m_pDraggedNote->get_note_off() ) return;
SE_editNoteLenghtAction *action = new SE_editNoteLenghtAction( m_pDraggedNote->get_position(), m_pDraggedNote->get_position(), __row, m_pDraggedNote->get_length(),__oldLength, __selectedPatternNumber);
@@ -387,7 +363,7 @@
}
-void DrumPatternEditor::editNoteLenghtAction( int nColumn, int nRealColumn, int row, int length, int selectedPatternNumber )
+void DrumPatternEditor::editNoteLengthAction( int nColumn, int nRealColumn, int row, int length, int selectedPatternNumber )
{
Hydrogen *pEngine = Hydrogen::get_instance();
PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
@@ -401,7 +377,6 @@
Note *pDraggedNote;
Song *pSong = pEngine->getSong();
- int nInstruments = pSong->get_instrument_list()->size();
Instrument *pSelectedInstrument = pSong->get_instrument_list()->get( row );
AudioEngine::get_instance()->lock( RIGHT_HERE );
pDraggedNote = pPattern->find_note( nColumn, nRealColumn, pSelectedInstrument, false );
@@ -428,14 +403,8 @@
return;
}
- // __rightclickedpattereditor
- // 0 = note length
- // 1 = note off"
- // 2 = edit velocity
- // 3 = edit pan
- // 4 = edit lead lag
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor == 0 ) ) {
+ if ( m_bRightBtnPressed && m_pDraggedNote ) {
if ( m_pDraggedNote->get_note_off() ) return;
int nTickColumn = getColumn( ev );
@@ -839,7 +808,6 @@
m_pPatternEditorPanel->getPanEditor()->updateEditor();
m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
- /// \todo [DrumPatternEditor::setResolution] aggiornare la risoluzione del Ruler in alto."
}
@@ -891,7 +859,6 @@
void DrumPatternEditor::selectedPatternChangedEvent()
{
- //cout << "selected pattern changed EVENT" << endl;
updateEditor();
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/DrumPatternEditor.h hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/DrumPatternEditor.h
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/DrumPatternEditor.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/DrumPatternEditor.h 2012-05-25 12:19:45.000000000 +0000
@@ -74,9 +74,12 @@
float oldPan_R,
float oldLeadLag,
int oldNoteKeyVal,
- int oldOctaveKeyVal );
- void addNoteRightClickAction( int nColumn, int nRow, int selectedPatternNumber );
- void editNoteLenghtAction( int nColumn, int nRealColumn, int row, int length, int selectedPatternNumber );
+ int oldOctaveKeyVal,
+ bool listen,
+ bool isMidi,
+ bool isInstrumentMode,
+ bool isNoteOff);
+ void editNoteLengthAction( int nColumn, int nRealColumn, int row, int length, int selectedPatternNumber );
void undoRedoAction( int column,
QString mode,
int nSelectedPatternNumber,
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/NotePropertiesRuler.cpp hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/NotePropertiesRuler.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/NotePropertiesRuler.cpp 2011-07-12 14:38:16.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/NotePropertiesRuler.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -149,7 +149,7 @@
sprintf( valueChar, "%#.2f", val);
( HydrogenApp::get_instance() )->setStatusBarMessage( QString("Set note velocity [%1]").arg( valueChar ), 2000 );
}
- else if ( m_mode == PAN ){
+ else if ( m_mode == PAN && !pNote->get_note_off() ){
float pan_L, pan_R;
float val = (pNote->get_pan_r() - pNote->get_pan_l() + 0.5) + delta;
@@ -263,7 +263,7 @@
__mode = "VELOCITY";
}
- else if ( m_mode == PAN ){
+ else if ( m_mode == PAN && !pNote->get_note_off() ){
__oldPan_L = pNote->get_pan_l();
__oldPan_R = pNote->get_pan_r();
@@ -348,7 +348,7 @@
sprintf( valueChar, "%#.2f", val);
HydrogenApp::get_instance()->setStatusBarMessage( QString("Set note velocity [%1]").arg( valueChar ), 2000 );
}
- else if ( m_mode == PAN ){
+ else if ( m_mode == PAN && !pNote->get_note_off() ){
float pan_L, pan_R;
if ( (ev->button() == Qt::MidButton) || (ev->modifiers() == Qt::ControlModifier && ev->button() == Qt::LeftButton) ) {
val = 0.5;
@@ -762,7 +762,7 @@
FOREACH_NOTE_CST_IT_BOUND(notes,coit,pos) {
Note *pNote = coit->second;
assert( pNote );
- if ( pNote->get_instrument() != pSong->get_instrument_list()->get( nSelectedInstrument ) ) {
+ if ( pNote->get_note_off() || pNote->get_instrument() != pSong->get_instrument_list()->get( nSelectedInstrument ) ) {
continue;
}
uint x_pos = 20 + pNote->get_position() * m_nGridWidth;
@@ -1015,13 +1015,6 @@
p.setPen( QPen( res_1, 1, Qt::DashLine ) );
if (y == 40) p.setPen( QPen( QColor(0,0,0), 1, Qt::SolidLine ) );
p.drawLine(20, y, 20 + nNotes * m_nGridWidth, y);
-/* if (y == 20 )p.drawText ( 5, y +2 , QString("O"));
- if (y == 30 )p.drawText ( 6, y +2 , QString("c"));
- if (y == 40 )p.drawText ( 7, y +2 , QString("t"));
- if (y == 50 )p.drawText ( 5, y +2 , QString("a"));
- if (y == 60 )p.drawText ( 6, y +2 , QString("v"));
- if (y == 70 )p.drawText ( 6, y +2 , QString("e"));
-*/
}
for (unsigned y = 90; y < 210; y = y + 10 ) {
@@ -1029,16 +1022,6 @@
if ( y == 100 ||y == 120 ||y == 140 ||y == 170 ||y == 190)
p.setPen( QPen( QColor( 0, 0, 0 ), 7, Qt::SolidLine, Qt::FlatCap ) );
p.drawLine(20, y, 20 + nNotes * m_nGridWidth, y);
-/* if (y == 100 )p.drawText ( 5, y +2 , QString("H"));
- if (y == 110 )p.drawText ( 6, y +2 , QString("a"));
- if (y == 120 )p.drawText ( 7, y +2 , QString("l"));
- if (y == 130 )p.drawText ( 5, y +2 , QString("f"));
- if (y == 150 )p.drawText ( 5, y +2 , QString("s"));
- if (y == 160 )p.drawText ( 6, y +2 , QString("t"));
- if (y == 170 )p.drawText ( 7, y +2 , QString("e"));
- if (y == 180 )p.drawText ( 5, y +2 , QString("p"));
- if (y == 190 )p.drawText ( 5, y +2 , QString("s"));
-*/
}
// vertical lines
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorInstrumentList.cpp hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorInstrumentList.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorInstrumentList.cpp 2011-07-12 14:38:16.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorInstrumentList.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -65,26 +65,26 @@
m_pMuteBtn = new ToggleButton(
this,
- "/patternEditor/btn_mute_on.png",
- "/patternEditor/btn_mute_off.png",
- "/patternEditor/btn_mute_off.png",
- QSize( 9, 9 )
+ "/mixerPanel/btn_mute_on.png",
+ "/mixerPanel/btn_mute_off.png",
+ "/mixerPanel/btn_mute_off.png",
+ QSize( 18, 13 )
);
- //m_pMuteBtn->setText( "M" );
- m_pMuteBtn->move( 155, 5 );
+ m_pMuteBtn->move( 145, 5 );
m_pMuteBtn->setPressed(false);
+ m_pMuteBtn->setToolTip( trUtf8("Mute instrument") );
connect(m_pMuteBtn, SIGNAL(clicked(Button*)), this, SLOT(muteClicked()));
m_pSoloBtn = new ToggleButton(
this,
- "/patternEditor/btn_solo_on.png",
- "/patternEditor/btn_solo_off.png",
- "/patternEditor/btn_solo_off.png",
- QSize( 9, 9 )
+ "/mixerPanel/btn_solo_on.png",
+ "/mixerPanel/btn_solo_off.png",
+ "/mixerPanel/btn_solo_off.png",
+ QSize( 18, 13 )
);
- //m_pSoloBtn->setText( "S" );
- m_pSoloBtn->move( 165, 5 );
+ m_pSoloBtn->move( 163, 5 );
m_pSoloBtn->setPressed(false);
+ m_pSoloBtn->setToolTip( trUtf8("Solo") );
connect(m_pSoloBtn, SIGNAL(clicked(Button*)), this, SLOT(soloClicked()));
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorPanel.cpp hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorPanel.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorPanel.cpp 2011-07-08 16:42:02.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorPanel.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -50,8 +50,6 @@
#include
-#include
-
void PatternEditorPanel::updateSLnameLabel( )
{
@@ -119,7 +117,6 @@
}
__pattern_size_combo->update();
connect(__pattern_size_combo, SIGNAL( valueChanged( QString ) ), this, SLOT( patternSizeChanged(QString) ) );
- //editor_top_hbox->addWidget(__pattern_size_combo);
// GRID resolution
@@ -140,11 +137,10 @@
__resolution_combo->update();
__resolution_combo->move( 121, 2 );
connect(__resolution_combo, SIGNAL(valueChanged(QString)), this, SLOT(gridResolutionChanged(QString)));
- //editor_top_hbox->addWidget(__resolution_combo);
PixmapWidget *pRec = new PixmapWidget( NULL );
- pRec->setFixedSize( 110, 20 );
+ pRec->setFixedSize( 158, 20 );
pRec->setPixmap( "/patternEditor/background_rec-new.png" );
pRec->move( 0, 3 );
editor_top_hbox_2->addWidget( pRec );
@@ -173,10 +169,23 @@
QSize(15, 13)
);
quantizeEventsBtn->move( 90, 3 );
- quantizeEventsBtn->setPressed( pPref->getQuantizeEvents());
+ quantizeEventsBtn->setPressed( pPref->getQuantizeEvents());
quantizeEventsBtn->setToolTip( trUtf8( "Quantize keyboard/midi events to grid" ) );
connect( quantizeEventsBtn, SIGNAL(clicked(Button*)), this, SLOT( quantizeEventsBtnClick(Button*)));
+ // Editor mode
+ __show_drum_btn = new ToggleButton(
+ pRec,
+ "/patternEditor/btn_drum_piano_on.png",
+ "/patternEditor/btn_drum_piano_off.png",
+ "/patternEditor/btn_drum_piano_off.png",
+ QSize(17, 13)
+ );
+ __show_drum_btn->move( 137, 3 );
+ __show_drum_btn->setPressed( false );
+ __show_drum_btn->setToolTip( trUtf8( "Show piano roll editor" ) );
+ connect(__show_drum_btn, SIGNAL(clicked(Button*)), this, SLOT( showDrumEditorBtnClick(Button*)));
+
__recpredelete = new QComboBox( NULL );
__recpredelete->setFixedSize( 130, 20 );
__recpredelete->move( 2, 1 );
@@ -218,46 +227,6 @@
editor_top_hbox_2->addWidget( __recpostdelete );
connect( __recpostdelete, SIGNAL( currentIndexChanged( int ) ), this, SLOT( recPostDeleteSelect( int) ) );
- QComboBox *selInstrument = new QComboBox( NULL );
- selInstrument->setFixedSize( 100, 20 );
- selInstrument->move( 2, 1 );
- selInstrument->addItem ( QString( "drumset" ));
- selInstrument->addItem ( QString( "instrument" ));
- selInstrument->update();
- selInstrument->setToolTip( trUtf8( "Midi keyboard or computer keys play whole drumset or single instruments" ) );
- editor_top_hbox_2->addWidget( selInstrument );
- connect( selInstrument, SIGNAL( currentIndexChanged( QString ) ), this, SLOT( playselectedinstrument(QString) ) );
-
- __rightclickSelection = new QComboBox( NULL );
- __rightclickSelection->setFixedSize( 100, 20 );
- __rightclickSelection->move( 2, 1 );
- __rightclickSelection->addItem ( QString( "note length" ));
- __rightclickSelection->addItem ( QString( "note off" ));
- __rightclickSelection->update();
- __rightclickSelection->setToolTip( trUtf8( "Right click into pattern editor add note-off-note or edit note-length, velocity or pan" ) );
- editor_top_hbox_2->addWidget( __rightclickSelection );
- connect( __rightclickSelection, SIGNAL( currentIndexChanged( QString ) ), this, SLOT( rightclickSelect(QString) ) );
-
-//---------------------------experimental pianoroll--------------------------------------
-// show drum editor btn
- __show_drum_btn = new ToggleButton(
- NULL,
- "/skin_btn_on.png",
- "/skin_btn_off.png",
- "/skin_btn_over.png",
- QSize(60, 17),
- true
- );
- __show_drum_btn->setText( trUtf8("Piano") );
- __show_drum_btn->setPressed( false );
- __show_drum_btn->setToolTip( trUtf8( "Show piano roll editor" ) );
- connect(__show_drum_btn, SIGNAL(clicked(Button*)), this, SLOT( showDrumEditorBtnClick(Button*)));
- editor_top_hbox_2->addWidget(__show_drum_btn);
-
-// hide the butten during develop on piano roll editor
-//__show_drum_btn->hide();
-
-//---------------------------------------------------------------------------------------
// zoom-in btn
Button *zoom_in_btn = new Button(
@@ -267,11 +236,8 @@
"/songEditor/btn_new_over.png",
QSize(19, 13)
);
-// zoom_in_btn->move( 51, 3 );
-// zoom_in_btn->setText("+");
zoom_in_btn->setToolTip( trUtf8( "Zoom in" ) );
connect(zoom_in_btn, SIGNAL(clicked(Button*)), this, SLOT( zoomInBtnClicked(Button*) ) );
- //editor_top_hbox_2->addWidget(zoom_in_btn);
// zoom-out btn
@@ -282,11 +248,8 @@
"/songEditor/btn_minus_over.png",
QSize(19, 13)
);
-// zoom_out_btn->move( 2, 3 );
- //zoom_out_btn->setText("-");
zoom_out_btn->setToolTip( trUtf8( "Zoom out" ) );
connect( zoom_out_btn, SIGNAL(clicked(Button*)), this, SLOT( zoomOutBtnClicked(Button*) ) );
- //editor_top_hbox_2->addWidget(zoom_out_btn);
// End Editor TOP
@@ -332,9 +295,6 @@
m_pPianoRollEditor = new PianoRollEditor( m_pPianoRollScrollView->viewport(), this );
m_pPianoRollScrollView->setWidget( m_pPianoRollEditor );
-// connect( m_pPianoRollScrollView->verticalScrollBar(), SIGNAL( valueChanged(int) ), this, SLOT( on_patternEditorScroll(int) ) );
-
-
m_pPianoRollScrollView->hide();
//~ EDITOR
@@ -437,7 +397,6 @@
m_pPatternNameLbl = new QLabel( NULL );
m_pPatternNameLbl->setFont( boldFont );
m_pPatternNameLbl->setText( "pattern name label" );
- //m_pPatternNameLbl->setFixedWidth(200);
m_pPatternNameLbl->setPalette(label_palette);
@@ -677,7 +636,6 @@
m_pPattern = pPatternList->get( nSelectedPatternNumber );
QString sCurrentPatternName = m_pPattern->get_name();
this->setWindowTitle( ( trUtf8( "Pattern editor - %1").arg( sCurrentPatternName ) ) );
- //m_pNameLCD->setText( sCurrentPatternName );
m_pPatternNameLbl->setText( sCurrentPatternName );
// update pattern size combobox
@@ -694,7 +652,6 @@
m_pPattern = NULL;
this->setWindowTitle( ( trUtf8( "Pattern editor - %1").arg(QString("No pattern selected.")) ) );
- //m_pNameLCD->setText( trUtf8( "No pattern selected" ) );
m_pPatternNameLbl->setText( trUtf8( "No pattern selected" ) );
}
@@ -754,12 +711,7 @@
QScrollArea *pScrollArea = m_pEditorScrollView;
-// if ( m_pPianoRollScrollView->isVisible() ) {
-// pScrollArea = m_pPianoRollScrollView;
-// }
-// else {
- pScrollArea = m_pEditorScrollView;
-// }
+ pScrollArea = m_pEditorScrollView;
m_pPatternEditorHScrollBar->setMinimum( pScrollArea->horizontalScrollBar()->minimum() );
m_pPatternEditorHScrollBar->setMaximum( pScrollArea->horizontalScrollBar()->maximum() );
@@ -778,7 +730,6 @@
void PatternEditorPanel::showEvent ( QShowEvent *ev )
{
UNUSED( ev );
-// m_pPatternEditorVScrollBar->setValue( m_pPatternEditorVScrollBar->maximum() );
}
@@ -805,8 +756,7 @@
void PatternEditorPanel::showDrumEditorBtnClick(Button *ref)
{
UNUSED( ref );
- if ( !__show_drum_btn->isPressed() ){
- __show_drum_btn->setText( trUtf8("Piano") );
+ if ( !__show_drum_btn->isPressed() ){
__show_drum_btn->setToolTip( trUtf8( "Show piano roll editor" ) );
m_pPianoRollScrollView->hide();
m_pEditorScrollView->show();
@@ -816,14 +766,10 @@
// force a re-sync of extern scrollbars
resizeEvent( NULL );
- //
- __rightclickSelection->clear();
- __rightclickSelection->addItem ( QString( "note length" ));
- __rightclickSelection->addItem ( QString( "note off" ));
+
}
else
- {
- __show_drum_btn->setText( trUtf8("Drum") );
+ {
__show_drum_btn->setToolTip( trUtf8( "Show drum editor" ) );
m_pPianoRollScrollView->show();
m_pPianoRollScrollView->verticalScrollBar()->setValue( 250 );
@@ -833,13 +779,6 @@
m_pPianoRollEditor->updateEditor(); // force an update
// force a re-sync of extern scrollbars
resizeEvent( NULL );
-
- __rightclickSelection->clear();
- __rightclickSelection->addItem ( QString( "note length" ));
- __rightclickSelection->addItem ( QString( "note off" ));
- __rightclickSelection->addItem ( QString( "edit velocity" ));
- __rightclickSelection->addItem ( QString( "edit pan" ));
- __rightclickSelection->addItem ( QString( "edit lead lag" ));
}
}
@@ -905,7 +844,6 @@
if ( nSelected > 0 && nSelected <= 32 ) {
m_pPattern->set_length( nEighth * nSelected );
- //m_pPatternSizeLCD->setText( QString( "%1" ).arg( nSelected ) );
}
else {
ERRORLOG( QString("[patternSizeChanged] Unhandled case %1").arg( nSelected ) );
@@ -1007,6 +945,7 @@
m_pNoteNoteKeyScrollView->hide();
m_pNotePanScrollView->show();
+
m_pNotePanEditor->updateEditor();
}
else if ( text == trUtf8( "Lead and Lag" ) ) {
@@ -1014,6 +953,7 @@
m_pNotePanScrollView->hide();
m_pNoteNoteKeyScrollView->hide();
m_pNoteLeadLagScrollView->show();
+
m_pNoteLeadLagEditor->updateEditor();
}
@@ -1035,51 +975,6 @@
}
-
-void PatternEditorPanel::playselectedinstrument( QString text )
-{
- if ( text == "drumset" ){
- Preferences::get_instance()->__playselectedinstrument = false;
- }else
- {
- Preferences::get_instance()->__playselectedinstrument = true;
- }
-}
-
-
-void PatternEditorPanel::rightclickSelect( QString text )
-{
-// __rightclickedpattereditor
-// 0 = note length
-// 1 = note off"
-// 2 = edit velocity
-// 3 = edit pan
-// 4 = edit lead lag
-
- if ( text == "note length" ){
- Preferences::get_instance()->__rightclickedpattereditor = 0;
- }
- else if ( text == "note off" ) {
- Preferences::get_instance()->__rightclickedpattereditor = 1;
- }
- else if ( text == "edit velocity" ) {
- Preferences::get_instance()->__rightclickedpattereditor = 2;
-// propertiesComboChanged( "Velocity" );
- __pPropertiesCombo->set_text("Velocity");
- }
- else if ( text == "edit pan" ) {
- Preferences::get_instance()->__rightclickedpattereditor = 3;
-// propertiesComboChanged( "Pan" );
- __pPropertiesCombo->set_text("Pan");
- }
- else if ( text == "edit lead lag" ) {
- Preferences::get_instance()->__rightclickedpattereditor = 4;
-// propertiesComboChanged( "Lead and Lag" );
- __pPropertiesCombo->set_text( "Lead and Lag" );
- }
-
-}
-
void PatternEditorPanel::recPreDeleteSelect( int index )
{
Preferences::get_instance()->m_nRecPreDelete = index;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorPanel.h hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorPanel.h
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorPanel.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorPanel.h 2012-05-25 12:19:45.000000000 +0000
@@ -24,12 +24,11 @@
#ifndef PATTERN_EDITOR_PANEL_H
#define PATTERN_EDITOR_PANEL_H
-#include
-
#include
#include "PianoRollEditor.h"
#include "../EventListener.h"
+#include "../widgets/LCDCombo.h"
class Button;
class ToggleButton;
@@ -42,6 +41,8 @@
class PianoRollEditor;
+enum patternEditorRightClickMode { VELOCITY_SELECTED, PAN_SELECTED, LEAD_LAG_SELECTED };
+
namespace H2Core
{
class Pattern;
@@ -66,6 +67,7 @@
NotePropertiesRuler* getNoteKeyEditor() { return m_pNoteNoteKeyEditor; }
PatternEditorInstrumentList* getInstrumentList() { return m_pInstrumentList; }
PianoRollEditor* getPianoRollEditor() { return m_pPianoRollEditor; }
+ QString getPropertiesComboText(){ return __pPropertiesCombo->getText(); }
void updateSLnameLabel();
void displayorHidePrePostCB();
@@ -98,8 +100,6 @@
void moveDownBtnClicked(Button *);
void moveUpBtnClicked(Button *);
- void playselectedinstrument( QString text );
- void rightclickSelect( QString text );
void recPreDeleteSelect( int index );
void recPostDeleteSelect( int index );
@@ -119,7 +119,7 @@
// ~Editor top
- //
+ //note properties combo
LCDCombo * __pPropertiesCombo;
// drum editor
@@ -154,8 +154,6 @@
// note notekey editor
QScrollArea* m_pNoteNoteKeyScrollView;
NotePropertiesRuler *m_pNoteNoteKeyEditor;
-
-
QScrollBar *m_pPatternEditorHScrollBar;
QScrollBar *m_pPatternEditorVScrollBar;
@@ -171,9 +169,6 @@
Button *sizeDropdownBtn;
Button *resDropdownBtn;
-
-
- QComboBox* __rightclickSelection;
bool m_bEnablePatternResize;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorRuler.cpp hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorRuler.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorRuler.cpp 2011-07-08 16:42:02.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorRuler.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -20,20 +20,22 @@
*
*/
-#include
-#include
-
#include
#include
#include
#include
using namespace H2Core;
+#include
+#include
+
+
#include "PatternEditorRuler.h"
#include "PatternEditorPanel.h"
#include "../HydrogenApp.h"
#include "../Skin.h"
+
const char* PatternEditorRuler::__class_name = "PatternEditorRuler";
PatternEditorRuler::PatternEditorRuler( QWidget* parent )
@@ -46,7 +48,6 @@
Preferences *pPref = Preferences::get_instance();
- //QColor backgroundColor(230, 230, 230);
UIStyle *pStyle = pPref->getDefaultUIStyle();
QColor backgroundColor( pStyle->m_patternEditor_backgroundColor.getRed(), pStyle->m_patternEditor_backgroundColor.getGreen(), pStyle->m_patternEditor_backgroundColor.getBlue() );
@@ -58,7 +59,6 @@
m_nRulerHeight = 25;
resize( m_nRulerWidth, m_nRulerHeight );
-// setFixedSize( size() );
bool ok = m_tickPosition.load( Skin::getImagePath() + "/patternEditor/tickPosition.png" );
if( ok == false ){
@@ -146,7 +146,6 @@
if (oldNTicks != m_nTicks) {
// redraw all
bRedrawAll = true;
- //update( 0, 0, width(), height() );
}
oldNTicks = m_nTicks;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorRuler.h hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorRuler.h
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PatternEditorRuler.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PatternEditorRuler.h 2012-05-25 12:19:45.000000000 +0000
@@ -24,7 +24,6 @@
#define PATTERN_EDITOR_RULER_H
#include "../EventListener.h"
-
#include
#include
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PianoRollEditor.cpp hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PianoRollEditor.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PianoRollEditor.cpp 2011-07-18 13:51:26.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PianoRollEditor.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -38,6 +38,7 @@
#include "../HydrogenApp.h"
+
const char* PianoRollEditor::__class_name = "PianoRollEditor";
PianoRollEditor::PianoRollEditor( QWidget *pParent, PatternEditorPanel *panel )
@@ -516,6 +517,13 @@
if (ev->button() == Qt::LeftButton ) {
+ if ( ev->modifiers() & Qt::ShiftModifier ){
+
+ SE_addPianoRollNoteOffAction *action = new SE_addPianoRollNoteOffAction( nColumn, pressedline, __selectedPatternNumber, nSelectedInstrumentnumber );
+ HydrogenApp::get_instance()->m_undoStack->push( action );
+ return;
+ }
+
unsigned nRealColumn = 0;
if( ev->x() > 20 ) {
nRealColumn = (ev->x() - 20) / static_cast(m_nGridWidth);
@@ -567,21 +575,6 @@
nRealColumn = (ev->x() - 20) / static_cast(m_nGridWidth);
}
-//
- // __rightclickedpattereditor
- // 0 = note length
- // 1 = note off"
- // 2 = edit velocity
- // 3 = edit pan
- // 4 = edit lead lag
-
- if ( Preferences::get_instance()->__rightclickedpattereditor == 1){
-
- SE_addNoteRightClickPianoRollAction *action = new SE_addNoteRightClickPianoRollAction( nColumn, pressedline, __selectedPatternNumber, nSelectedInstrumentnumber );
- HydrogenApp::get_instance()->m_undoStack->push( action );
-
- }
-
// AudioEngine::get_instance()->lock( RIGHT_HERE );
@@ -622,130 +615,91 @@
float oldPan_R,
float oldLeadLag,
int oldNoteKeyVal,
- int oldOctaveKeyVal )
+ int oldOctaveKeyVal,
+ bool noteOff )
{
- Hydrogen *pEngine = Hydrogen::get_instance();
- Song *pSong = pEngine->getSong();
- PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
- H2Core::Pattern *pPattern;
-
- Instrument *pSelectedInstrument = NULL;
- pSelectedInstrument = pSong->get_instrument_list()->get( selectedinstrument );
- assert(pSelectedInstrument);
-
- if ( ( selectedPatternNumber != -1 ) && ( (uint)selectedPatternNumber < pPatternList->size() ) ) {
- pPattern = pPatternList->get( selectedPatternNumber );
- }
- else {
- pPattern = NULL;
- }
-
- Note::Octave pressedoctave = (Note::Octave)(3 - (pressedLine / 12 ));
- Note::Key pressednotekey;
- if ( pressedLine < 12 ){
- pressednotekey = (Note::Key)(11 - pressedLine);
- }
- else
- {
- pressednotekey = (Note::Key)(11 - pressedLine % 12);
- }
-
- m_bRightBtnPressed = false;
-
- bool bNoteAlreadyExist = false;
- AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
- Note* note = m_pPattern->find_note( nColumn, -1, pSelectedInstrument, pressednotekey, pressedoctave );
- if( note ) {
- // the note exists...remove it!
- bNoteAlreadyExist = true;
- m_pPattern->remove_note( note );
- delete note;
- }
-
- if ( bNoteAlreadyExist == false ) {
- // create the new note
- const unsigned nPosition = nColumn;
- const float fVelocity = oldVelocity;
- const float fPan_L = oldPan_L;
- const float fPan_R = oldPan_R;
- int nLength = oldLength;
- const float fPitch = 0.0f;
- Note *pNote = new Note( pSelectedInstrument, nPosition, fVelocity, fPan_L, fPan_R, nLength, fPitch );
- pNote->set_note_off( false );
- pNote->set_lead_lag( oldLeadLag );
- pNote->set_key_octave( pressednotekey, pressedoctave );
- pPattern->insert_note( pNote );
- // hear note
- Preferences *pref = Preferences::get_instance();
- if ( pref->getHearNewNotes() ) {
- Note *pNote2 = new Note( pSelectedInstrument, 0, fVelocity, fPan_L, fPan_R, nLength, fPitch);
- pNote2->set_key_octave( pressednotekey, pressedoctave );
- AudioEngine::get_instance()->get_sampler()->note_on(pNote2);
- }
- }
- pSong->__is_modified = true;
- AudioEngine::get_instance()->unlock(); // unlock the audio engine
-
- updateEditor();
- m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
- m_pPatternEditorPanel->getPanEditor()->updateEditor();
- m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
- m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
- m_pPatternEditorPanel->getDrumPatternEditor()->updateEditor();
+ Hydrogen *pEngine = Hydrogen::get_instance();
+ Song *pSong = pEngine->getSong();
+ PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
+ H2Core::Pattern *pPattern;
+
+ Instrument *pSelectedInstrument = NULL;
+ pSelectedInstrument = pSong->get_instrument_list()->get( selectedinstrument );
+ assert(pSelectedInstrument);
+
+ if ( ( selectedPatternNumber != -1 ) && ( (uint)selectedPatternNumber < pPatternList->size() ) ) {
+ pPattern = pPatternList->get( selectedPatternNumber );
+ }
+ else {
+ pPattern = NULL;
+ }
+
+ Note::Octave pressedoctave = (Note::Octave)(3 - (pressedLine / 12 ));
+ Note::Key pressednotekey;
+ if ( pressedLine < 12 ){
+ pressednotekey = (Note::Key)(11 - pressedLine);
+ }
+ else
+ {
+ pressednotekey = (Note::Key)(11 - pressedLine % 12);
+ }
+
+ m_bRightBtnPressed = false;
+
+ bool bNoteAlreadyExist = false;
+ AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
+ Note* note = m_pPattern->find_note( nColumn, -1, pSelectedInstrument, pressednotekey, pressedoctave );
+ if( note ) {
+ // the note exists...remove it!
+ bNoteAlreadyExist = true;
+ m_pPattern->remove_note( note );
+ delete note;
+ }
+
+ if ( bNoteAlreadyExist == false ) {
+ // create the new note
+ unsigned nPosition = nColumn;
+ float fVelocity = oldVelocity;
+ float fPan_L = oldPan_L;
+ float fPan_R = oldPan_R;
+ int nLength = oldLength;
+ float fPitch = 0.0f;
+
+ if(noteOff)
+ {
+ fVelocity = 0.0f;
+ fPan_L = 0.5f;
+ fPan_R = 0.5f;
+ nLength = 1;
+ fPitch = 0.0f;
+ }
+
+
+ Note *pNote = new Note( pSelectedInstrument, nPosition, fVelocity, fPan_L, fPan_R, nLength, fPitch );
+ pNote->set_note_off( noteOff );
+ if(! noteOff) pNote->set_lead_lag( oldLeadLag );
+ pNote->set_key_octave( pressednotekey, pressedoctave );
+ pPattern->insert_note( pNote );
+ // hear note
+ Preferences *pref = Preferences::get_instance();
+ if ( pref->getHearNewNotes() && !noteOff ) {
+ Note *pNote2 = new Note( pSelectedInstrument, 0, fVelocity, fPan_L, fPan_R, nLength, fPitch);
+ pNote2->set_key_octave( pressednotekey, pressedoctave );
+ AudioEngine::get_instance()->get_sampler()->note_on(pNote2);
+ }
+ }
+ pSong->__is_modified = true;
+ AudioEngine::get_instance()->unlock(); // unlock the audio engine
+
+ updateEditor();
+ m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
+ m_pPatternEditorPanel->getPanEditor()->updateEditor();
+ m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
+ m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
+ m_pPatternEditorPanel->getDrumPatternEditor()->updateEditor();
}
-void PianoRollEditor::addNoteRightClickAction( int nColumn, int pressedLine, int selectedPatternNumber, int selectedinstrument)
-{
- Hydrogen *pEngine = Hydrogen::get_instance();
- Song *pSong = pEngine->getSong();
- PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
- H2Core::Pattern *pPattern;
-
- Instrument *pSelectedInstrument = NULL;
- pSelectedInstrument = pSong->get_instrument_list()->get( selectedinstrument );
- assert(pSelectedInstrument);
-
- if ( ( selectedPatternNumber != -1 ) && ( (uint)selectedPatternNumber < pPatternList->size() ) ) {
- pPattern = pPatternList->get( selectedPatternNumber );
- }
- else {
- pPattern = NULL;
- }
-
- Note::Octave pressedoctave = (Note::Octave)(3 - (pressedLine / 12 ));
- Note::Key pressednotekey;
- if ( pressedLine < 12 ){
- pressednotekey = (Note::Key)(11 - pressedLine);
- }
- else
- {
- pressednotekey = (Note::Key)(11 - pressedLine % 12);
- }
-
- AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
- // create the new note
- const unsigned nPosition = nColumn;
- const float fVelocity = 0.0f;
- const float fPan_L = 0.5f;
- const float fPan_R = 0.5f;
- const int nLength = 1;
- const float fPitch = 0.0f;
- Note *poffNote = new Note( pSelectedInstrument, nPosition, fVelocity, fPan_L, fPan_R, nLength, fPitch);
- poffNote->set_note_off( true );
- poffNote->set_key_octave( pressednotekey, pressedoctave );
- pPattern->insert_note( poffNote );
-
- pSong->__is_modified = true;
- AudioEngine::get_instance()->unlock(); // unlock the audio engine
-
- updateEditor();
- m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
- m_pPatternEditorPanel->getPanEditor()->updateEditor();
- m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
- m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
- m_pPatternEditorPanel->getDrumPatternEditor()->updateEditor();
-}
@@ -760,14 +714,7 @@
return;
}
- // __rightclickedpattereditor
- // 0 = note length
- // 1 = note off"
- // 2 = edit velocity
- // 3 = edit pan
- // 4 = edit lead lag
-
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor == 0 ) ) {
+ if (m_bRightBtnPressed && m_pDraggedNote ) {
if ( m_pDraggedNote->get_note_off() ) return;
int nTickColumn = getColumn( ev );
@@ -799,8 +746,10 @@
m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
}
+ QString selectedProperty = m_pPatternEditorPanel->getPropertiesComboText();
+
//edit velocity
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor == 2 ) ) {
+ if (m_bRightBtnPressed && m_pDraggedNote && selectedProperty == trUtf8( "Velocity" ) ) {
if ( m_pDraggedNote->get_note_off() ) return;
AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
@@ -834,7 +783,7 @@
}
//edit pan
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor == 3 ) ) {
+ if (m_bRightBtnPressed && m_pDraggedNote && selectedProperty == trUtf8( "Pan" ) ) {
if ( m_pDraggedNote->get_note_off() ) return;
AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
@@ -875,7 +824,7 @@
}
//edit lead lag
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor == 4 ) ) {
+ if (m_bRightBtnPressed && m_pDraggedNote && selectedProperty == trUtf8( "Lead and Lag" )) {
if ( m_pDraggedNote->get_note_off() ) return;
AudioEngine::get_instance()->lock( RIGHT_HERE ); // lock the audio engine
@@ -930,18 +879,20 @@
return;
}
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor == 0 ) ) {
+ if ( m_bRightBtnPressed && m_pDraggedNote ) {
if ( m_pDraggedNote->get_note_off() ) return;
- SE_editNoteLenghtPianoRollAction *action = new SE_editNoteLenghtPianoRollAction( m_pDraggedNote->get_position(), m_pDraggedNote->get_position(), m_pDraggedNote->get_length(),__oldLength, __selectedPatternNumber, __selectedInstrumentnumber, __pressedLine );
- HydrogenApp::get_instance()->m_undoStack->push( action );
- return;
- }
- if (m_bRightBtnPressed && m_pDraggedNote && ( Preferences::get_instance()->__rightclickedpattereditor >=2 ) ) {
- if ( m_pDraggedNote->get_note_off() ) return;
- SE_editNotePropertiesPianoRollAction *action = new SE_editNotePropertiesPianoRollAction( m_pDraggedNote->get_position(),
+ if( m_pDraggedNote->get_length() != __oldLength )
+ {
+ SE_editPianoRollNoteLengthAction *action = new SE_editPianoRollNoteLengthAction( m_pDraggedNote->get_position(), m_pDraggedNote->get_position(), m_pDraggedNote->get_length(),__oldLength, __selectedPatternNumber, __selectedInstrumentnumber, __pressedLine );
+ HydrogenApp::get_instance()->m_undoStack->push( action );
+ }
+
+
+ if( __velocity == __oldVelocity && __oldLeadLag == __leadLag && __oldPan_L == __pan_L && __oldPan_R == __pan_R ) return;
+ SE_editNotePropertiesPianoRollAction *action = new SE_editNotePropertiesPianoRollAction( m_pDraggedNote->get_position(),
m_pDraggedNote->get_position(),
__selectedPatternNumber,
__selectedInstrumentnumber,
@@ -954,12 +905,12 @@
__leadLag,
__oldLeadLag,
__pressedLine );
- HydrogenApp::get_instance()->m_undoStack->push( action );
+ HydrogenApp::get_instance()->m_undoStack->push( action );
}
}
-void PianoRollEditor::editNoteLenghtAction( int nColumn, int nRealColumn, int length, int selectedPatternNumber, int nSelectedInstrumentnumber, int pressedline)
+void PianoRollEditor::editNoteLengthAction( int nColumn, int nRealColumn, int length, int selectedPatternNumber, int nSelectedInstrumentnumber, int pressedline)
{
Hydrogen *pEngine = Hydrogen::get_instance();
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PianoRollEditor.h hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PianoRollEditor.h
--- hydrogen-0.9.6~beta1/src/gui/src/PatternEditor/PianoRollEditor.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PatternEditor/PianoRollEditor.h 2012-05-25 12:19:45.000000000 +0000
@@ -64,9 +64,9 @@
float oldPan_R,
float oldLeadLag,
int oldNoteKeyVal,
- int oldOctaveKeyVal );
+ int oldOctaveKeyVal,
+ bool noteOff);
- void addNoteRightClickAction( int nColumn, int pressedLine, int selectedPatternNumber, int selectedInstrumentnumber);
void editNotePropertiesAction( int nColumn,
int nRealColumn,
int selectedPatternNumber,
@@ -76,7 +76,7 @@
float pan_R,
float leadLag,
int pressedLine );
- void editNoteLenghtAction( int nColumn, int nRealColumn, int length, int selectedPatternNumber, int nSelectedInstrumentnumber, int pressedLine );
+ void editNoteLengthAction( int nColumn, int nRealColumn, int length, int selectedPatternNumber, int nSelectedInstrumentnumber, int pressedLine );
public slots:
void updateEditor();
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PlayerControl.cpp hydrogen-0.9.6~beta2/src/gui/src/PlayerControl.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PlayerControl.cpp 2011-11-04 22:40:50.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PlayerControl.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -114,6 +114,8 @@
m_pRecBtn->setToolTip( trUtf8("Record") );
connect(m_pRecBtn, SIGNAL(clicked(Button*)), this, SLOT(recBtnClicked(Button*)));
connect(m_pRecBtn, SIGNAL(rightClicked(Button*)), this, SLOT(recBtnRightClicked(Button*)));
+ MidiAction* pAction = new MidiAction("RECORD_READY");
+ m_pRecBtn->setAction( pAction );
// Record+delete button
@@ -145,7 +147,7 @@
m_pPlayBtn->setPressed(false);
m_pPlayBtn->setToolTip( trUtf8("Play/ Pause") );
connect(m_pPlayBtn, SIGNAL(clicked(Button*)), this, SLOT(playBtnClicked(Button*)));
- MidiAction* pAction = new MidiAction("PLAY");
+ pAction = new MidiAction("PLAY");
m_pPlayBtn->setAction( pAction );
@@ -186,53 +188,37 @@
m_pSongLoopBtn->move(310, 17);
m_pSongLoopBtn->setToolTip( trUtf8("Loop song") );
connect( m_pSongLoopBtn, SIGNAL( clicked(Button*) ), this, SLOT( songLoopBtnClicked(Button*) ) );
-//~ CONTROLS
-// MODE
- PixmapWidget *pModePanel = new PixmapWidget( NULL );
- pModePanel->setFixedSize( 90, 43 );
- pModePanel->setPixmap( "/playerControlPanel/background_Mode.png" );
- hbox->addWidget( pModePanel );
+
// Live mode button
m_pLiveModeBtn = new ToggleButton(
- pModePanel,
+ pControlsPanel,
"/playerControlPanel/statusLED_on.png",
"/playerControlPanel/statusLED_off.png",
"/playerControlPanel/statusLED_off.png",
- QSize(11, 9)
+ QSize(68, 9)
);
- m_pLiveModeBtn->move(10, 4);
+ m_pLiveModeBtn->move(180, 5);
m_pLiveModeBtn->setPressed(true);
m_pLiveModeBtn->setToolTip( trUtf8("Pattern Mode") );
connect(m_pLiveModeBtn, SIGNAL(clicked(Button*)), this, SLOT(liveModeBtnClicked(Button*)));
// Song mode button
m_pSongModeBtn = new ToggleButton(
- pModePanel,
+ pControlsPanel,
"/playerControlPanel/statusLED_on.png",
"/playerControlPanel/statusLED_off.png",
"/playerControlPanel/statusLED_off.png",
- QSize(11, 9)
+ QSize(68, 9)
);
- m_pSongModeBtn->move(10, 15);
+ m_pSongModeBtn->move(253, 5);
m_pSongModeBtn->setPressed(false);
m_pSongModeBtn->setToolTip( trUtf8("Song Mode") );
connect(m_pSongModeBtn, SIGNAL(clicked(Button*)), this, SLOT(songModeBtnClicked(Button*)));
- // Switch mode button
- m_pSwitchModeBtn = new Button(
- pModePanel,
- "/playerControlPanel/btn_mode_on.png",
- "/playerControlPanel/btn_mode_off.png",
- "/playerControlPanel/btn_mode_over.png",
- QSize(69, 13)
- );
- m_pSwitchModeBtn->move(10, 26);
- m_pSwitchModeBtn->setToolTip( trUtf8("Switch Song/ Pattern Mode") );
- connect(m_pSwitchModeBtn, SIGNAL(clicked(Button*)), this, SLOT(switchModeBtnClicked(Button*)));
-//~ MODE
+//~ CONTROLS
// BC on off
PixmapWidget *pControlsBBTBConoffPanel = new PixmapWidget( NULL );
@@ -372,7 +358,7 @@
);
m_pRubberBPMChange->move( 133, 3 );
m_pRubberBPMChange->setToolTip( trUtf8("Recalculate Rubberband modified samples if bpm will change") );
- m_pRubberBPMChange->setPressed(false);
+ m_pRubberBPMChange->setPressed( Preferences::get_instance()->getRubberBandBatchMode());
connect( m_pRubberBPMChange, SIGNAL( clicked( Button* ) ), this, SLOT(rubberbandButtonToggle( Button* ) ) );
QString program = Preferences::get_instance()->m_rubberBandCLIexecutable;
//test the path. if test fails, no button
@@ -393,7 +379,11 @@
QSize( 20, 13 )
);
m_pMetronomeBtn->move( 10, 26 );
+ m_pMetronomeBtn->setToolTip( trUtf8("Switch metronome on/off") );
connect( m_pMetronomeBtn, SIGNAL( clicked( Button* ) ), this, SLOT(metronomeButtonClicked( Button* ) ) );
+ pAction = new MidiAction("TOGGLE_METRONOME");
+ m_pMetronomeBtn->setAction( pAction );
+
//~ BPM
@@ -757,32 +747,6 @@
-/// Switch mode
-void PlayerControl::switchModeBtnClicked(Button* ref)
-{
- UNUSED( ref );
-
- Song *song = m_pEngine->getSong();
-
- m_pEngine->sequencer_stop();
- m_pEngine->setPatternPos( 0 ); // from start
- if( song->get_mode() == Song::PATTERN_MODE ) {
- m_pEngine->getSong()->set_mode( Song::SONG_MODE );
- m_pSongModeBtn->setPressed(true);
- m_pLiveModeBtn->setPressed(false);
- (HydrogenApp::get_instance())->setStatusBarMessage(trUtf8("Song mode selected."), 5000);
- }
- else {
- m_pEngine->getSong()->set_mode( Song::PATTERN_MODE );
- m_pSongModeBtn->setPressed(false);
- m_pLiveModeBtn->setPressed(true);
- (HydrogenApp::get_instance())->setStatusBarMessage(trUtf8("Pattern mode selected."), 5000);
- }
-}
-
-
-
-
/// Set Song mode
void PlayerControl::songModeBtnClicked(Button* ref)
{
@@ -871,12 +835,12 @@
Preferences *pPref = Preferences::get_instance();
if (m_pRubberBPMChange->isPressed()) {
EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
- pPref->m_useTheRubberbandBpmChangeEvent = true;
+ pPref->setRubberBandBatchMode(true);
(HydrogenApp::get_instance())->setScrollStatusBarMessage(trUtf8("Recalculate all samples using Rubberband ON"), 2000);
}
else {
- pPref->m_useTheRubberbandBpmChangeEvent = false;
+ pPref->setRubberBandBatchMode(false);
(HydrogenApp::get_instance())->setScrollStatusBarMessage(trUtf8("Recalculate all samples using Rubberband OFF"), 2000);
}
}
@@ -1097,7 +1061,7 @@
}
else if ( pRef == m_pShowInstrumentRackBtn ) {
bool isVisible = pH2App->getInstrumentRack()->isVisible();
- pH2App->getInstrumentRack()->setHidden( isVisible );
+ pH2App->showInstrumentPanel( isVisible );
}
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PlayerControl.h hydrogen-0.9.6~beta2/src/gui/src/PlayerControl.h
--- hydrogen-0.9.6~beta1/src/gui/src/PlayerControl.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PlayerControl.h 2012-05-25 12:19:45.000000000 +0000
@@ -98,8 +98,7 @@
void stopBtnClicked(Button* ref);
void updatePlayerControl();
void songModeBtnClicked(Button* ref);
- void liveModeBtnClicked(Button* ref);
- void switchModeBtnClicked(Button* ref);
+ void liveModeBtnClicked(Button* ref);
void jackTransportBtnClicked(Button* ref);
//jack time master
void jackMasterBtnClicked(Button* ref);
@@ -141,8 +140,7 @@
ToggleButton *m_pSongLoopBtn;
ToggleButton *m_pSongModeBtn;
- ToggleButton *m_pLiveModeBtn;
- Button *m_pSwitchModeBtn;
+ ToggleButton *m_pLiveModeBtn;
//beatcounter
ToggleButton *m_pBConoffBtn;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PreferencesDialog.cpp hydrogen-0.9.6~beta2/src/gui/src/PreferencesDialog.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/PreferencesDialog.cpp 2011-11-08 22:10:00.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PreferencesDialog.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -61,60 +61,56 @@
pPref->loadPreferences( false ); // reload user's preferences
driverComboBox->clear();
- driverComboBox->addItem( "Auto" );
- driverComboBox->addItem( "JACK" );
- driverComboBox->addItem( "ALSA" );
- driverComboBox->addItem( "OSS" );
+ driverComboBox->addItem( "Auto" );
+#ifdef H2CORE_HAVE_JACK
+ driverComboBox->addItem( "Jack" );
+#endif
+#ifdef H2CORE_HAVE_ALSA
+ driverComboBox->addItem( "Alsa" );
+#endif
+#ifdef H2CORE_HAVE_OSS
+ driverComboBox->addItem( "Oss" );
+#endif
+#ifdef H2CORE_HAVE_PORTAUDIO
driverComboBox->addItem( "PortAudio" );
-#ifdef Q_OS_MACX
+#endif
+#ifdef H2CORE_HAVE_COREAUDIO
driverComboBox->addItem( "CoreAudio" );
#endif
- // Selected audio Driver
- QString sAudioDriver = pPref->m_sAudioDriver;
- if (sAudioDriver == "Auto") {
- driverComboBox->setCurrentIndex(0);
- }
- else if (sAudioDriver == "Jack") {
- driverComboBox->setCurrentIndex(1);
- }
- else if ( sAudioDriver == "Alsa" ) {
- driverComboBox->setCurrentIndex(2);
- }
- else if ( sAudioDriver == "Oss" ) {
- driverComboBox->setCurrentIndex(3);
- }
- else if ( sAudioDriver == "PortAudio" ) {
- driverComboBox->setCurrentIndex(4);
- }
- else if ( sAudioDriver == "CoreAudio" ) {
- driverComboBox->setCurrentIndex(5);
- }
- else {
- ERRORLOG( "Unknown audio driver from preferences [" + sAudioDriver + "]" );
- }
+
+ if( driverComboBox->findText(pPref->m_sAudioDriver) > -1){
+ driverComboBox->setCurrentIndex(driverComboBox->findText(pPref->m_sAudioDriver));
+ }
+ else
+ {
+ driverInfoLbl->setText("Select your Audio Driver");
+ ERRORLOG( "Unknown midi input from preferences [" + pPref->m_sAudioDriver + "]" );
+ }
m_pMidiDriverComboBox->clear();
+#ifdef H2CORE_HAVE_ALSA
m_pMidiDriverComboBox->addItem( "ALSA" );
+#endif
+#ifdef H2CORE_HAVE_PORTMIDI
m_pMidiDriverComboBox->addItem( "PortMidi" );
- m_pMidiDriverComboBox->addItem( "CoreMidi" );
- m_pMidiDriverComboBox->addItem( "JackMidi" );
+#endif
+#ifdef H2CORE_HAVE_COREMIDI
+ m_pMidiDriverComboBox->addItem( "CoreMidi" );
+#endif
+#ifdef H2CORE_HAVE_JACK
+ m_pMidiDriverComboBox->addItem( "JackMidi" );
+#endif
- if ( pPref->m_sMidiDriver == "ALSA" ) {
- m_pMidiDriverComboBox->setCurrentIndex(0);
- }
- else if ( pPref->m_sMidiDriver == "PortMidi" ) {
- m_pMidiDriverComboBox->setCurrentIndex(1);
- }
- else if ( pPref->m_sMidiDriver == "CoreMidi" ) {
- m_pMidiDriverComboBox->setCurrentIndex(2);
- }
- else if ( pPref->m_sMidiDriver == "JackMidi" ) {
- m_pMidiDriverComboBox->setCurrentIndex(3);
- }
- else {
- ERRORLOG( "Unknown midi input from preferences [" + pPref->m_sMidiDriver + "]" );
+
+ if( m_pMidiDriverComboBox->findText(pPref->m_sMidiDriver) > -1){
+ m_pMidiDriverComboBox->setCurrentIndex(m_pMidiDriverComboBox->findText(pPref->m_sMidiDriver));
+ }
+ else
+ {
+ driverInfoLbl->setText("Select your Midi Driver");
+ ERRORLOG( "Unknown midi input from preferences [" + pPref->m_sMidiDriver + "]" );
}
m_pIgnoreNoteOffCheckBox->setChecked( pPref->m_bMidiNoteOffIgnore );
@@ -130,7 +126,9 @@
maxVoicesTxt->setValue( pPref->m_nMaxNotes );
// JACK
- trackOutsCheckBox->setChecked( pPref->m_bJackTrackOuts );
+ trackOutsCheckBox->setChecked( pPref->m_bJackTrackOuts );
+ connect(trackOutsCheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleTrackOutsCheckBox( bool )));
+
connectDefaultsCheckBox->setChecked( pPref->m_bJackConnectDefaults );
trackOutputComboBox->setCurrentIndex( pPref->m_nJackTrackOutputMode );
//~ JACK
@@ -262,13 +260,6 @@
rubberbandLineEdit->hide();
#endif
-#ifdef H2CORE_HAVE_JACKSESSION
- useJackSessinStoreFiles->setVisible(true);
- useJackSessinStoreFiles->setChecked(pPref->getJackSessionUseSessionDir());
-#else
- useJackSessinStoreFiles->setVisible(false);
-#endif
-
m_bNeedDriverRestart = false;
connect(m_pMidiDriverComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT( onMidiDriverComboBoxIndexChanged(int) ));
}
@@ -338,7 +329,6 @@
}
// JACK
- pPref->m_bJackTrackOuts = trackOutsCheckBox->isChecked();
pPref->m_bJackConnectDefaults = connectDefaultsCheckBox->isChecked();
@@ -424,10 +414,6 @@
//path to rubberband
pPref-> m_rubberBandCLIexecutable = rubberbandLineEdit->text();
-#ifdef H2CORE_HAVE_JACKSESSION
- pPref->setJackSessionUseSessionDir(useJackSessinStoreFiles->isChecked());
-#endif
-
//check preferences
if ( pPref->m_brestartLash == true ){
pPref->m_bsetLash = true ;
@@ -520,7 +506,7 @@
trackOutsCheckBox->setEnabled( false );
connectDefaultsCheckBox->setEnabled(false);
}
- else if ( driverComboBox->currentText() == "JACK" ) { // JACK
+ else if ( driverComboBox->currentText() == "Jack" ) { // JACK
info += trUtf8("Jack Audio Connection Kit Driver Low latency audio driver");
if ( !bJack_support ) {
info += trUtf8("Not compiled ");
@@ -533,7 +519,7 @@
connectDefaultsCheckBox->setEnabled(true);
trackOutsCheckBox->setEnabled( true );
}
- else if ( driverComboBox->currentText() == "ALSA" ) { // ALSA
+ else if ( driverComboBox->currentText() == "Alsa" ) { // ALSA
info += trUtf8("ALSA Driver ");
if ( !bAlsa_support ) {
info += trUtf8("Not compiled ");
@@ -722,3 +708,8 @@
m_bNeedDriverRestart = true;
}
+void PreferencesDialog::toggleTrackOutsCheckBox(bool toggled)
+{
+ Preferences::get_instance()->m_bJackTrackOuts = toggled;
+ m_bNeedDriverRestart = true;
+}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/PreferencesDialog.h hydrogen-0.9.6~beta2/src/gui/src/PreferencesDialog.h
--- hydrogen-0.9.6~beta1/src/gui/src/PreferencesDialog.h 2011-09-12 11:54:45.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/PreferencesDialog.h 2012-05-25 12:19:45.000000000 +0000
@@ -53,6 +53,7 @@
void on_styleComboBox_activated( int index );
void on_useLashCheckbox_clicked();
void onMidiDriverComboBoxIndexChanged( int index );
+ void toggleTrackOutsCheckBox(bool toggled);
private:
bool m_bNeedDriverRestart;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditor.cpp hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditor.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditor.cpp 2011-10-24 10:31:06.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditor.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -56,6 +56,15 @@
const char* SongEditor::__class_name = "SongEditor";
+
+SongEditorGridRepresentationItem::SongEditorGridRepresentationItem(int x, int y, bool value)
+{
+ this->x = x;
+ this->y = y;
+ this->value = value;
+}
+
+
SongEditor::SongEditor( QWidget *parent )
: QWidget( parent )
, Object( __class_name )
@@ -71,8 +80,6 @@
Preferences *pref = Preferences::get_instance();
m_nMaxPatternSequence = pref->getMaxBars();
-
-
int m_nInitialWidth = 10 + m_nMaxPatternSequence * m_nGridWidth;
int m_nInitialHeight = 10;
@@ -142,7 +149,6 @@
if ( ev->x() < 10 ) {
return;
}
- //WARNINGLOG( "editor-pressed" );
int nRow = ev->y() / m_nGridHeight;
int nColumn = ( (int)ev->x() - 10 ) / (int)m_nGridWidth;
@@ -177,7 +183,6 @@
}
if ( bOverExistingPattern ) {
- qDebug() << "select over existing!!";
// MOVE PATTERNS
// INFOLOG( "[mousePressEvent] Move patterns" );
m_bIsMoving = true;
@@ -189,7 +194,6 @@
}
else {
// INFOLOG( "[mousePressEvent] Select patterns" );
- qDebug() << "select!!";
// select patterns
m_bShowLasso = true;
m_lasso.setCoords( ev->x(), ev->y(), ev->x(), ev->y() );
@@ -240,7 +244,6 @@
void SongEditor::addPattern( int nColumn , int nRow )
{
- qDebug() << "add pattern!";
Hydrogen *pEngine = Hydrogen::get_instance();
Song *pSong = pEngine->getSong();
PatternList *pPatternList = pSong->get_pattern_list();
@@ -277,7 +280,6 @@
void SongEditor::deletePattern( int nColumn , int nRow, unsigned nColumnIndex )
{
- qDebug() << "delete pattern!";
Hydrogen *pEngine = Hydrogen::get_instance();
Song *pSong = pEngine->getSong();
PatternList *pPatternList = pSong->get_pattern_list();
@@ -395,13 +397,45 @@
void SongEditor::mouseReleaseEvent( QMouseEvent *ev )
{
UNUSED(ev);
+
if ( m_bIsMoving ) { // fine dello spostamento dei pattern
- AudioEngine::get_instance()->lock( RIGHT_HERE );
// create the new patterns
+
+ /*
+ * For the proper handling of undo events we have to make sure
+ * that the array m_movingCells does not include cells that are
+ * already existing.
+ *
+ * Example: A song consists of a sequence with the cells 0,1 and 3.
+ * Consider that we the two first cells 0 and 1 get moved one
+ * cell to the right (to 2,3). An undo action would now delete
+ * (2,3) for and re-create 0,1. Cell 3 got deleted now, but it existed
+ * before the first move operation.
+ */
+
+ SongEditorGridRepresentationItem* item;
+ m_existingCells.clear();
+ for ( uint i = 0; i < m_movingCells.size(); i++ )
+ {
+ QPoint cell = m_movingCells[ i ];
+
+ //looking for cell identified with (cell.x/cell.y) in the gridRepresentation
+ bool found = false;
+ foreach(item, gridRepresentation)
+ {
+ if(item->x == cell.x() && item->y == cell.y())
+ {
+ found = true;
+ }
+ }
+
+ if( found ){
+ m_existingCells.push_back(cell);
+ }
+ }
- SE_movePatternCellAction *action = new SE_movePatternCellAction( m_movingCells, m_selectedCells , m_bIsCtrlPressed);
+ SE_movePatternCellAction *action = new SE_movePatternCellAction( m_movingCells, m_selectedCells , m_existingCells, m_bIsCtrlPressed);
HydrogenApp::get_instance()->m_undoStack->push( action );
-
}
setCursor( QCursor( Qt::ArrowCursor ) );
@@ -412,13 +446,25 @@
update();
}
+/**
+ * @brief moves or copies a cell which represents a pattern
+ * @param movingCells Target cells for move/copy action
+ * @param selectedCells Currently selected cells for move/copy action
+ * @param existingCells Cells which are included in selected/movingCells but where existing before(import for undo).
+ * @param bIsCtrlPressed If ctrl is pressed, do copy instead of move
+ * @param undo Determine if this is an undo-operation
+ */
-void SongEditor::movePatternCellAction( std::vector movingCells, std::vector selectedCells, bool bIsCtrlPressed, bool undo )
+void SongEditor::movePatternCellAction( std::vector movingCells, std::vector selectedCells, std::vector existingCells, bool bIsCtrlPressed, bool undo )
{
Hydrogen *pEngine = Hydrogen::get_instance();
PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
vector* pColumns = pEngine->getSong()->get_pattern_group_vector();
+
+ AudioEngine::get_instance()->lock( RIGHT_HERE );
+
+ //create the new patterns
for ( uint i = 0; i < movingCells.size(); i++ ) {
QPoint cell = movingCells[ i ];
if ( cell.x() < 0 || cell.y() < 0 || cell.y() >= (int)pPatternList->size() ) {
@@ -441,12 +487,27 @@
pColumn->add( pPatternList->get( cell.y() ) );
}
- if ( bIsCtrlPressed ) { // COPY
- if ( undo )
- {
+ if ( bIsCtrlPressed) //Copy
+ {
+ if( undo )
+ {
// remove the old patterns
for ( uint i = 0; i < selectedCells.size(); i++ ) {
QPoint cell = selectedCells[ i ];
+
+ bool existing = false;
+ for ( uint i = 0; i < existingCells.size(); i++ ) {
+ QPoint existing_cell = existingCells[ i ];
+ if(existing_cell.x() == cell.x() && existing_cell.y() == cell.y()) existing = true;
+ }
+
+ //this cell existed before. Don't delete it!
+ if(existing){
+ continue;
+ }
+
+
+
PatternList* pColumn = NULL;
if ( cell.x() < (int)pColumns->size() ) {
pColumn = (*pColumns)[ cell.x() ];
@@ -457,18 +518,7 @@
}
pColumn->del(pPatternList->get( cell.y() ) );
}
- for ( uint i = 0; i < movingCells.size(); i++ ) {
- QPoint cell = movingCells[ i ];
- PatternList* pColumn = NULL;
- if ( cell.x() < (int)pColumns->size() ) {
- pColumn = (*pColumns)[ cell.x() ];
- }
- else {
- pColumn = new PatternList();
- pColumns->push_back( pColumn );
- }
- pColumn->del(pPatternList->get( cell.y() ) );
- }
+
}
}
else { // MOVE
@@ -476,15 +526,49 @@
for ( uint i = 0; i < selectedCells.size(); i++ ) {
QPoint cell = selectedCells[ i ];
PatternList* pColumn = NULL;
- if ( cell.x() < (int)pColumns->size() ) {
- pColumn = (*pColumns)[ cell.x() ];
- }
- else {
- pColumn = new PatternList();
- pColumns->push_back( pColumn );
- }
- pColumn->del(pPatternList->get( cell.y() ) );
- }
+
+ /*
+ * Check first if pattern was present in movingCells.
+ * If it was, don't delete it!
+ */
+
+ bool moved = false;
+ for ( uint i = 0; i < movingCells.size(); i++ ) {
+ QPoint cell2 = movingCells[ i ];
+ if( cell.x() == cell2.x() && cell.y() == cell2.y() ){
+ moved = true;
+ }
+ }
+
+ if( moved )
+ {
+ continue;
+ }
+
+ if( undo )
+ {
+ bool existing = false;
+ for ( uint i = 0; i < existingCells.size(); i++ ) {
+ QPoint existing_cell = existingCells[ i ];
+ if(existing_cell.x() == cell.x() && existing_cell.y() == cell.y()) existing = true;
+ }
+
+ //this cell existed before. Don't delete it!
+ if(existing){
+ continue;
+ }
+ }
+
+
+ if ( cell.x() < (int)pColumns->size() ) {
+ pColumn = (*pColumns)[ cell.x() ];
+ }
+ else {
+ pColumn = new PatternList();
+ pColumns->push_back( pColumn );
+ }
+ pColumn->del(pPatternList->get( cell.y() ) );
+ }
}
// remove the empty patternlist at the end of the song
@@ -638,6 +722,14 @@
PatternList *patList = song->get_pattern_list();
vector* pColumns = song->get_pattern_group_vector();
uint listLength = patList->size();
+
+ //Drawing the pattern based on the gridRepresentation array
+
+ while (!gridRepresentation.isEmpty())
+ delete gridRepresentation.takeFirst();
+
+
+
for (uint i = 0; i < pColumns->size(); i++) {
PatternList* pColumn = (*pColumns)[ i ];
@@ -659,7 +751,9 @@
if (position == -1) {
WARNINGLOG( QString("[drawSequence] position == -1, group = %1").arg( i ) );
}
- drawPattern( i, position, false );
+ //normal pattern
+
+ gridRepresentation.append(new SongEditorGridRepresentationItem(i,position,false));
}//if
for ( Pattern::virtual_patterns_cst_it_t it = pat->get_flattened_virtual_patterns()->begin(); it != pat->get_flattened_virtual_patterns()->end(); ++it) {
@@ -668,13 +762,22 @@
if (position == -1) {
WARNINGLOG( QString("[drawSequence] position == -1, group = %1").arg( i ) );
}
- drawPattern( i, position, true );
+ //virtual pattern
+ gridRepresentation.append(new SongEditorGridRepresentationItem(i,position,true));
drawnAsVirtual.insert(*it);
}
}
}
}
+
+ //Draw the patterns according to the gridRepresentation
+ SongEditorGridRepresentationItem* s;
+ foreach(s, gridRepresentation)
+ {
+ drawPattern( s->x, s->y, s->value);
+ }
+
// Moving cells
p.begin( m_pSequencePixmap );
// p.setRasterOp( Qt::XorROP );
@@ -724,7 +827,6 @@
int x = 10 + m_nGridWidth * pos;
int y = m_nGridHeight * number;
-// p.setPen( patternColor.light( 120 ) ); // willie - For the bevel - haven't yet figured how it's supposed to work...
p.fillRect( x + 1, y + 3, m_nGridWidth - 1, m_nGridHeight - 5, patternColor );
}
@@ -783,6 +885,7 @@
line = new QLineEdit( "Inline Pattern Name", this );
line->setFrame( false );
line->hide();
+ line->setAcceptDrops( false );
connect( line, SIGNAL(editingFinished()), this, SLOT(inlineEditingFinished()) );
connect( line, SIGNAL(returnPressed()), this, SLOT(inlineEditingEntered()) );
@@ -795,13 +898,12 @@
m_playingPattern_off_Pixmap.load( Skin::getImagePath() + "/songEditor/playingPattern_off.png" );
m_pPatternPopup = new QMenu( this );
- //m_pPatternPopup->addAction( trUtf8("Edit"), this, SLOT( patternPopup_edit() ) );obsolete in >=0.9.4, because the patterneditor switch by clicking an each item to the corresponding pattern
m_pPatternPopup->addAction( trUtf8("Copy"), this, SLOT( patternPopup_copy() ) );
m_pPatternPopup->addAction( trUtf8("Delete"), this, SLOT( patternPopup_delete() ) );
m_pPatternPopup->addAction( trUtf8("Fill/Clear ..."), this, SLOT( patternPopup_fill() ) );
m_pPatternPopup->addAction( trUtf8("Properties"), this, SLOT( patternPopup_properties() ) );
m_pPatternPopup->addAction( trUtf8("Load Pattern"), this, SLOT( patternPopup_load() ) );
- m_pPatternPopup->addAction( trUtf8("Save Pattern"), this, SLOT( patternPopup_save() ) );
+ m_pPatternPopup->addAction( trUtf8("Save Pattern"), this, SLOT( patternPopup_save() ) );
m_pPatternPopup->addAction( trUtf8("Virtual Pattern"), this, SLOT( patternPopup_virtualPattern() ) );
HydrogenApp::get_instance()->addEventListener( this );
@@ -823,7 +925,7 @@
update();
///here we check the timeline && m_pSong->get_mode() == Song::SONG_MODE
Hydrogen *engine = Hydrogen::get_instance();
- if ( ( Preferences::get_instance()->__usetimeline ) && ( engine->getSong()->get_mode() == Song::SONG_MODE ) ){
+ if ( ( Preferences::get_instance()->getUseTimelineBpm() ) && ( engine->getSong()->get_mode() == Song::SONG_MODE ) ){
for ( int i = 0; i < static_cast(engine->m_timelinevector.size()); i++){
if ( ( engine->m_timelinevector[i].m_htimelinebeat == engine->getPatternPos() )
&& ( engine->getNewBpmJTM() != engine->m_timelinevector[i].m_htimelinebpm ) ){
@@ -852,19 +954,6 @@
} else {
engine->setSelectedPatternNumber( row );
if (ev->button() == Qt::RightButton) {
- /*
- if ( song->getMode() == Song::PATTERN_MODE ) {
-
- PatternList *pCurrentPatternList = engine->getCurrentPatternList();
- if ( pCurrentPatternList->size() == 0 ) {
- // nessun pattern e' attivo. seleziono subito questo.
- pCurrentPatternList->add( patternList->get( row ) );
- }
- else {
- engine->setNextPattern( row );
- }
- }
- */
m_pPatternPopup->popup( QPoint( ev->globalX(), ev->globalY() ) );
}
}
@@ -880,32 +969,7 @@
void SongEditorPatternList::togglePattern( int row ) {
Hydrogen *engine = Hydrogen::get_instance();
-/* Song *song = engine->getSong();
- PatternList *patternList = song->get_pattern_list();*/
-
-// PatternList *pCurrentPatternList = engine->getCurrentPatternList();
-
-// bool isPatternPlaying = false;
engine->sequencer_setNextPattern( row, false, true );
-
-// for ( uint i = 0; i < pCurrentPatternList->size(); ++i ) {
-// if ( pCurrentPatternList->get( i ) == patternList->get( row ) ) {
-// // the pattern is already playing, stop it!
-// isPatternPlaying = true;
-// break;
-// }
-// }
-//
-// if ( isPatternPlaying ) {
-// //pCurrentPatternList->del( patternList->get( row ) );
-// engine->sequencer_setNextPattern( row, false, true ); // remove from the playing pattern list
-// }
-// else {
-// // the pattern is not playing, add it to the list
-// //pCurrentPatternList->add( patternList->get( row ) );
-// engine->sequencer_setNextPattern( row, true, false ); // add to the playing pattern list
-// }
-
createBackground();
update();
}
@@ -1129,7 +1193,7 @@
void SongEditorPatternList::patternPopup_load()
{
-
+ HydrogenApp *hydrogenApp = HydrogenApp::get_instance();
Hydrogen *engine = Hydrogen::get_instance();
int tmpselectedpatternpos = engine->getSelectedPatternNumber();
@@ -1158,9 +1222,11 @@
//create a unique sequencefilename
time_t thetime;
thetime = time(NULL);
- QString sequenceFileName = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "SEQ.xml" );
- SE_loadPatternAction *action = new SE_loadPatternAction( filename, oldPatternName, sequenceFileName, tmpselectedpatternpos );
- HydrogenApp::get_instance()->m_undoStack->push( action );
+
+ QString sequenceFilename = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "SEQ.xml" );
+ SE_loadPatternAction *action = new SE_loadPatternAction( filename, oldPatternName, sequenceFilename, tmpselectedpatternpos );
+ hydrogenApp->addTemporaryFile( sequenceFilename );
+ hydrogenApp->m_undoStack->push( action );
@@ -1289,6 +1355,7 @@
{
Hydrogen *pEngine = Hydrogen::get_instance();
+ HydrogenApp *hydrogenApp = HydrogenApp::get_instance();
Song *song = pEngine->getSong();
PatternList *pSongPatternList = song->get_pattern_list();
int patternPosition = pEngine->getSelectedPatternNumber();
@@ -1296,13 +1363,15 @@
//create a unique sequencefilename
time_t thetime;
thetime = time(NULL);
- QString sequenceFileName = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "SEQ.xml" );
+ QString sequenceFilename = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "SEQ.xml" );
//create a unique patternfilename
- QString patternFilename = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "PAT.xml" );
+ QString patternFilename = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "PAT.xml" );
- SE_deletePatternFromListAction *action = new SE_deletePatternFromListAction( patternFilename , sequenceFileName, patternPosition );
- HydrogenApp::get_instance()->m_undoStack->push( action );
+ SE_deletePatternFromListAction *action = new SE_deletePatternFromListAction( patternFilename , sequenceFilename, patternPosition );
+ hydrogenApp->addTemporaryFile( sequenceFilename );
+ hydrogenApp->addTemporaryFile( patternFilename );
+ hydrogenApp->m_undoStack->push( action );
}
@@ -1436,6 +1505,7 @@
void SongEditorPatternList::patternPopup_copy()
{
Hydrogen *pEngine = Hydrogen::get_instance();
+ HydrogenApp *hydrogenApp = HydrogenApp::get_instance();
Song *pSong = pEngine->getSong();
PatternList *pPatternList = pSong->get_pattern_list();
int nSelectedPattern = pEngine->getSelectedPatternNumber();
@@ -1457,8 +1527,9 @@
int err =1;
err = fileMng.savePattern( pSong, pEngine->getCurrentDrumkitname(), pPatternList->size() -1 , patternFilename, pNewPattern->get_name(), 4 );
- SE_copyPatternAction *action = new SE_copyPatternAction( patternFilename ,nSelectedPattern + 1 );
- HydrogenApp::get_instance()->m_undoStack->push( action );
+ SE_copyPatternAction *action = new SE_copyPatternAction( patternFilename ,nSelectedPattern + 1 );
+ hydrogenApp->addTemporaryFile( patternFilename );
+ hydrogenApp->m_undoStack->push( action );
}
//delete the tmp pattern
@@ -1643,15 +1714,17 @@
//create a unique sequencefilename
Song *song = Hydrogen::get_instance()->getSong();
Pattern *pat = song->get_pattern_list()->get( nTargetPattern );
+ HydrogenApp *hydrogenApp = HydrogenApp::get_instance();
QString oldPatternName = pat->get_name();
time_t thetime;
thetime = time(NULL);
- QString sequenceFileName = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "SEQ.xml" );
- SE_loadPatternAction *action = new SE_loadPatternAction( sPatternName, oldPatternName, sequenceFileName, nTargetPattern );
- HydrogenApp::get_instance()->m_undoStack->push( action );
-
+ QString sequenceFilename = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "SEQ.xml" );
+ SE_loadPatternAction *action = new SE_loadPatternAction( sPatternName, oldPatternName, sequenceFilename, nTargetPattern );
+
+ hydrogenApp->addTemporaryFile( sequenceFilename);
+ hydrogenApp->m_undoStack->push( action );
}
}
@@ -1816,7 +1889,7 @@
//draw tempo content
- if(pref->__usetimeline){
+ if(pref->getUseTimelineBpm()){
p.setPen( textColor );
}else
{
@@ -1855,7 +1928,7 @@
// Right-click+drag
int column = (ev->x() / m_nGridWidth);
Preferences* pPref = Preferences::get_instance();
- if ( column >= (int)Hydrogen::get_instance()->getSong()->get_pattern_group_vector()->size() ) {
+ if ( column > (int)Hydrogen::get_instance()->getSong()->get_pattern_group_vector()->size() ) {
pPref->setPunchOutPos(-1);
return;
}
@@ -1876,7 +1949,7 @@
int column = (ev->x() / m_nGridWidth);
m_bRightBtnPressed = false;
- if ( column >= (int)Hydrogen::get_instance()->getSong()->get_pattern_group_vector()->size() ) {
+ if ( column > (int)Hydrogen::get_instance()->getSong()->get_pattern_group_vector()->size() ) {
return;
}
@@ -1918,7 +1991,7 @@
pPref->setPunchOutPos(-1);
update();
}
- else if( ( ev->button() == Qt::LeftButton || ev->button() == Qt::RightButton ) && ev->y() <= 25 && Preferences::get_instance()->__usetimeline ){
+ else if( ( ev->button() == Qt::LeftButton || ev->button() == Qt::RightButton ) && ev->y() <= 25 && Preferences::get_instance()->getUseTimelineBpm() ){
int column = (ev->x() / m_nGridWidth);
SongEditorPanelBpmWidget dialog( this , column );
if (dialog.exec() == QDialog::Accepted) {
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditor.h hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditor.h
--- hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditor.h 2011-01-17 23:08:21.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditor.h 2012-05-25 12:19:45.000000000 +0000
@@ -24,8 +24,10 @@
#define SONG_EDITOR_H
#include
+#include
#include
+#include
#include
#include "../EventListener.h"
@@ -41,6 +43,16 @@
static const uint SONG_EDITOR_MIN_GRID_WIDTH = 8;
static const uint SONG_EDITOR_MAX_GRID_WIDTH = 16;
+
+class SongEditorGridRepresentationItem
+{
+ public:
+ SongEditorGridRepresentationItem(int x, int y, bool value);
+ int x;
+ int y;
+ bool value;
+};
+
///
/// Song editor
///
@@ -64,9 +76,12 @@
void deletePattern( int nColumn, int nRow, unsigned nColumnIndex);
void clearThePatternSequenseVector( QString filename );
void updateEditorandSetTrue();
- void movePatternCellAction( std::vector movingCells, std::vector selectedCells, bool bIsCtrlPressed, bool undo);
+ void movePatternCellAction( std::vector movingCells, std::vector selectedCells, std::vector m_existingCells, bool bIsCtrlPressed, bool undo);
private:
+ //holds a list for active patterns for each pattern
+ QList gridRepresentation;
+
unsigned m_nGridHeight;
unsigned m_nGridWidth;
unsigned m_nMaxPatternSequence;
@@ -79,6 +94,8 @@
std::vector m_selectedCells;
std::vector m_movingCells;
+ std::vector m_existingCells;
+
QPoint m_clickPoint; // Usato come riferimento per le operazioni di spostamento
bool m_bShowLasso;
QRect m_lasso;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditorPanelBpmWidget_UI.ui hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditorPanelBpmWidget_UI.ui
--- hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditorPanelBpmWidget_UI.ui 2011-01-06 09:29:16.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditorPanelBpmWidget_UI.ui 2012-05-25 12:19:45.000000000 +0000
@@ -6,7 +6,7 @@
0
0
- 195
+ 198
151
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditorPanel.cpp hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditorPanel.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditorPanel.cpp 2011-10-24 14:05:32.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditorPanel.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -67,7 +67,7 @@
m_pTimeLineToggleBtn->move( 133, 6 );
m_pTimeLineToggleBtn->setToolTip( trUtf8( "Enable time line edit") );
connect( m_pTimeLineToggleBtn, SIGNAL( clicked( Button* ) ), this, SLOT( timeLineBtnPressed(Button* ) ) );
- m_pTimeLineToggleBtn->setPressed( Preferences::get_instance()->__usetimeline );
+ m_pTimeLineToggleBtn->setPressed( Preferences::get_instance()->getUseTimelineBpm() );
// clear sequence button
@@ -446,7 +446,10 @@
thetime = time(NULL);
QString filename = Preferences::get_instance()->getTmpDirectory() +QString("%1").arg(thetime)+ QString( "SEQ.xml" );
SE_deletePatternSequenceAction *action = new SE_deletePatternSequenceAction( filename );
- HydrogenApp::get_instance()->m_undoStack->push( action );
+ HydrogenApp *hydrogenApp = HydrogenApp::get_instance();
+
+ hydrogenApp->m_undoStack->push( action );
+ hydrogenApp->addTemporaryFile( filename );
}
@@ -511,12 +514,12 @@
void SongEditorPanel::timeLineBtnPressed( Button* pBtn )
{
if( m_pTimeLineToggleBtn->isPressed() ){
- Preferences::get_instance()->__usetimeline = true;
+ Preferences::get_instance()->setUseTimelineBpm( true );
Hydrogen::get_instance()->setTimelineBpm();
}
else
{
- Preferences::get_instance()->__usetimeline = false;
+ Preferences::get_instance()->setUseTimelineBpm( false );
}
m_pPositionRuler->createBackground();
}
@@ -571,4 +574,5 @@
{
resyncExternalScrollBar();
m_pModeActionBtn->setPressed( Preferences::get_instance()->patternModePlaysSelected() );
+ HydrogenApp::get_instance()->getSongEditorPanel()->updateAll();
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditorPanelTagWidget_UI.ui hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditorPanelTagWidget_UI.ui
--- hydrogen-0.9.6~beta1/src/gui/src/SongEditor/SongEditorPanelTagWidget_UI.ui 2011-01-06 09:29:16.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/SongEditor/SongEditorPanelTagWidget_UI.ui 2012-05-25 12:19:45.000000000 +0000
@@ -6,8 +6,8 @@
0
0
- 289
- 417
+ 293
+ 420
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/SoundLibrary/SoundLibraryImportDialog.cpp hydrogen-0.9.6~beta2/src/gui/src/SoundLibrary/SoundLibraryImportDialog.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/SoundLibrary/SoundLibraryImportDialog.cpp 2011-10-21 15:12:15.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/SoundLibrary/SoundLibraryImportDialog.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -257,7 +257,7 @@
if ( sInfo.m_sType == "pattern" ) {
H2Core::LocalFileMng mng;
- std::vector patternList = mng.getAllPatternName();
+ std::vector patternList = mng.getAllPatternNames();
for ( uint i = 0; i < patternList.size(); ++i ) {
if ( patternList[ i ] == sName ) {
return true;
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/SoundLibrary/SoundLibraryPanel.cpp hydrogen-0.9.6~beta2/src/gui/src/SoundLibrary/SoundLibraryPanel.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/SoundLibrary/SoundLibraryPanel.cpp 2011-05-18 21:27:38.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/SoundLibrary/SoundLibraryPanel.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -253,7 +253,6 @@
//this is the second step to push the mng.funktion
std::vector allPatternDirList = mng.getallPatternList();
- std::vector patternNameList = mng.getAllPatternName();
std::vector allCategoryNameList = mng.getAllCategoriesFromPattern();
//now sorting via category
@@ -266,7 +265,7 @@
for (uint i = 0; i < allPatternDirList.size(); ++i) {
QString patternCategory = mng.getCategoryFromPatternName( allPatternDirList[i]);
- if ( patternCategory == categoryName ){
+ if ( patternCategory == categoryName || patternCategory.isEmpty() && categoryName == "No category" ){
QTreeWidgetItem* pPatternItem = new QTreeWidgetItem( pCategoryItem );
pPatternItem->setText( 0, mng.getPatternNameFromPatternDir( allPatternDirList[i] ));
pPatternItem->setToolTip( 0, mng.getDrumkitNameForPattern( allPatternDirList[i] ));
@@ -572,7 +571,7 @@
//if we delete the current loaded drumkit we can get truble with some empty pointers
// TODO this check is really unsafe
if ( item->text(0) == Hydrogen::get_instance()->getCurrentDrumkitname() ){
- QMessageBox::warning( this, "Hydrogen", QString( "You try to delet the current loaded drumkit.\nThis is not possible!") );
+ QMessageBox::warning( this, "Hydrogen", QString( "It is not possible to delete the currently loaded drumkit.\nTo delete this drumkit first load another drumkit.") );
return;
}
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/UI/about_dialog.ui hydrogen-0.9.6~beta2/src/gui/src/UI/about_dialog.ui
--- hydrogen-0.9.6~beta1/src/gui/src/UI/about_dialog.ui 2011-11-29 23:07:08.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/UI/about_dialog.ui 2012-05-25 12:19:45.000000000 +0000
@@ -126,17 +126,365 @@
&Authors
-
+
10
- 0
- 501
+ 10
+ 511
241
-
- ##
+
+ true
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">This program is distributed under the terms of the GPL v2.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> GNU GENERAL PUBLIC LICENSE</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Version 2, June 1991</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Copyright (C) 1989, 1991 Free Software Foundation, Inc.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 675 Mass Ave, Cambridge, MA 02139, USA</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Everyone is permitted to copy and distribute verbatim copies</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> of this license document, but changing it is not allowed.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Preamble</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> The licenses for most software are designed to take away your</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">freedom to share and change it. By contrast, the GNU General Public</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">License is intended to guarantee your freedom to share and change free</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">software--to make sure the software is free for all its users. This</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">General Public License applies to most of the Free Software</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Foundation's software and to any other program whose authors commit to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">using it. (Some other Free Software Foundation software is covered by</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">the GNU Library General Public License instead.) You can apply it to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">your programs, too.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> When we speak of free software, we are referring to freedom, not</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">price. Our General Public Licenses are designed to make sure that you</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">have the freedom to distribute copies of free software (and charge for</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">this service if you wish), that you receive source code or can get it</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">if you want it, that you can change the software or use pieces of it</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">in new free programs; and that you know you can do these things.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> To protect your rights, we need to make restrictions that forbid</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">anyone to deny you these rights or to ask you to surrender the rights.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">These restrictions translate to certain responsibilities for you if you</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">distribute copies of the software, or if you modify it.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> For example, if you distribute copies of such a program, whether</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">gratis or for a fee, you must give the recipients all the rights that</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">you have. You must make sure that they, too, receive or can get the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">source code. And you must show them these terms so they know their</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">rights.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> We protect your rights with two steps: (1) copyright the software, and</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">(2) offer you this license which gives you legal permission to copy,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">distribute and/or modify the software.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Also, for each author's protection and ours, we want to make certain</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">that everyone understands that there is no warranty for this free</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">software. If the software is modified by someone else and passed on, we</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">want its recipients to know that what they have is not the original, so</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">that any problems introduced by others will not reflect on the original</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">authors' reputations.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Finally, any free program is threatened constantly by software</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">patents. We wish to avoid the danger that redistributors of a free</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">program will individually obtain patent licenses, in effect making the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">program proprietary. To prevent this, we have made it clear that any</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">patent must be licensed for everyone's free use or not licensed at all.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> The precise terms and conditions for copying, distribution and</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">modification follow.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> GNU GENERAL PUBLIC LICENSE</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 0. This License applies to any program or other work which contains</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">a notice placed by the copyright holder saying it may be distributed</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">under the terms of this General Public License. The "Program", below,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">refers to any such program or work, and a "work based on the Program"</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">means either the Program or any derivative work under copyright law:</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">that is to say, a work containing the Program or a portion of it,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">either verbatim or with modifications and/or translated into another</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">language. (Hereinafter, translation is included without limitation in</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">the term "modification".) Each licensee is addressed as "you".</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Activities other than copying, distribution and modification are not</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">covered by this License; they are outside its scope. The act of</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">running the Program is not restricted, and the output from the Program</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">is covered only if its contents constitute a work based on the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Program (independent of having been made by running the Program).</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Whether that is true depends on what the Program does.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 1. You may copy and distribute verbatim copies of the Program's</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">source code as you receive it, in any medium, provided that you</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">conspicuously and appropriately publish on each copy an appropriate</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">copyright notice and disclaimer of warranty; keep intact all the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">notices that refer to this License and to the absence of any warranty;</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">and give any other recipients of the Program a copy of this License</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">along with the Program.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">You may charge a fee for the physical act of transferring a copy, and</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">you may at your option offer warranty protection in exchange for a fee.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 2. You may modify your copy or copies of the Program or any portion</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">of it, thus forming a work based on the Program, and copy and</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">distribute such modifications or work under the terms of Section 1</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">above, provided that you also meet all of these conditions:</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> a) You must cause the modified files to carry prominent notices</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> stating that you changed the files and the date of any change.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> b) You must cause any work that you distribute or publish, that in</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> whole or in part contains or is derived from the Program or any</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> part thereof, to be licensed as a whole at no charge to all third</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> parties under the terms of this License.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> c) If the modified program normally reads commands interactively</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> when run, you must cause it, when started running for such</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> interactive use in the most ordinary way, to print or display an</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> announcement including an appropriate copyright notice and a</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> notice that there is no warranty (or else, saying that you provide</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> a warranty) and that users may redistribute the program under</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> these conditions, and telling the user how to view a copy of this</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> License. (Exception: if the Program itself is interactive but</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> does not normally print such an announcement, your work based on</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> the Program is not required to print an announcement.)</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">These requirements apply to the modified work as a whole. If</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">identifiable sections of that work are not derived from the Program,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">and can be reasonably considered independent and separate works in</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">themselves, then this License, and its terms, do not apply to those</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">sections when you distribute them as separate works. But when you</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">distribute the same sections as part of a whole which is a work based</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">on the Program, the distribution of the whole must be on the terms of</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">this License, whose permissions for other licensees extend to the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">entire whole, and thus to each and every part regardless of who wrote it.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Thus, it is not the intent of this section to claim rights or contest</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">your rights to work written entirely by you; rather, the intent is to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">exercise the right to control the distribution of derivative or</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">collective works based on the Program.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">In addition, mere aggregation of another work not based on the Program</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">with the Program (or with a work based on the Program) on a volume of</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">a storage or distribution medium does not bring the other work under</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">the scope of this License.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 3. You may copy and distribute the Program (or a work based on it,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">under Section 2) in object code or executable form under the terms of</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Sections 1 and 2 above provided that you also do one of the following:</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> a) Accompany it with the complete corresponding machine-readable</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> source code, which must be distributed under the terms of Sections</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 1 and 2 above on a medium customarily used for software interchange; or,</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> b) Accompany it with a written offer, valid for at least three</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> years, to give any third party, for a charge no more than your</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> cost of physically performing source distribution, a complete</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> machine-readable copy of the corresponding source code, to be</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> distributed under the terms of Sections 1 and 2 above on a medium</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> customarily used for software interchange; or,</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> c) Accompany it with the information you received as to the offer</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> to distribute corresponding source code. (This alternative is</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> allowed only for noncommercial distribution and only if you</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> received the program in object code or executable form with such</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> an offer, in accord with Subsection b above.)</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">The source code for a work means the preferred form of the work for</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">making modifications to it. For an executable work, complete source</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">code means all the source code for all modules it contains, plus any</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">associated interface definition files, plus the scripts used to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">control compilation and installation of the executable. However, as a</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">special exception, the source code distributed need not include</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">anything that is normally distributed (in either source or binary</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">form) with the major components (compiler, kernel, and so on) of the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">operating system on which the executable runs, unless that component</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">itself accompanies the executable.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">If distribution of executable or object code is made by offering</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">access to copy from a designated place, then offering equivalent</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">access to copy the source code from the same place counts as</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">distribution of the source code, even though third parties are not</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">compelled to copy the source along with the object code.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 4. You may not copy, modify, sublicense, or distribute the Program</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">except as expressly provided under this License. Any attempt</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">otherwise to copy, modify, sublicense or distribute the Program is</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">void, and will automatically terminate your rights under this License.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">However, parties who have received copies, or rights, from you under</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">this License will not have their licenses terminated so long as such</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">parties remain in full compliance.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 5. You are not required to accept this License, since you have not</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">signed it. However, nothing else grants you permission to modify or</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">distribute the Program or its derivative works. These actions are</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">prohibited by law if you do not accept this License. Therefore, by</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">modifying or distributing the Program (or any work based on the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Program), you indicate your acceptance of this License to do so, and</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">all its terms and conditions for copying, distributing or modifying</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">the Program or works based on it.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 6. Each time you redistribute the Program (or any work based on the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Program), the recipient automatically receives a license from the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">original licensor to copy, distribute or modify the Program subject to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">these terms and conditions. You may not impose any further</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">restrictions on the recipients' exercise of the rights granted herein.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">You are not responsible for enforcing compliance by third parties to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">this License.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 7. If, as a consequence of a court judgment or allegation of patent</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">infringement or for any other reason (not limited to patent issues),</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">conditions are imposed on you (whether by court order, agreement or</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">otherwise) that contradict the conditions of this License, they do not</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">excuse you from the conditions of this License. If you cannot</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">distribute so as to satisfy simultaneously your obligations under this</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">License and any other pertinent obligations, then as a consequence you</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">may not distribute the Program at all. For example, if a patent</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">license would not permit royalty-free redistribution of the Program by</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">all those who receive copies directly or indirectly through you, then</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">the only way you could satisfy both it and this License would be to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">refrain entirely from distribution of the Program.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">If any portion of this section is held invalid or unenforceable under</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">any particular circumstance, the balance of the section is intended to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">apply and the section as a whole is intended to apply in other</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">circumstances.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">It is not the purpose of this section to induce you to infringe any</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">patents or other property right claims or to contest validity of any</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">such claims; this section has the sole purpose of protecting the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">integrity of the free software distribution system, which is</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">implemented by public license practices. Many people have made</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">generous contributions to the wide range of software distributed</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">through that system in reliance on consistent application of that</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">system; it is up to the author/donor to decide if he or she is willing</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">to distribute software through any other system and a licensee cannot</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">impose that choice.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">This section is intended to make thoroughly clear what is believed to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">be a consequence of the rest of this License.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 8. If the distribution and/or use of the Program is restricted in</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">certain countries either by patents or by copyrighted interfaces, the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">original copyright holder who places the Program under this License</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">may add an explicit geographical distribution limitation excluding</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">those countries, so that distribution is permitted only in or among</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">countries not thus excluded. In such case, this License incorporates</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">the limitation as if written in the body of this License.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 9. The Free Software Foundation may publish revised and/or new versions</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">of the General Public License from time to time. Such new versions will</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">be similar in spirit to the present version, but may differ in detail to</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">address new problems or concerns.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Each version is given a distinguishing version number. If the Program</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">specifies a version number of this License which applies to it and "any</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">later version", you have the option of following the terms and conditions</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">either of that version or of any later version published by the Free</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Software Foundation. If the Program does not specify a version number of</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">this License, you may choose any version ever published by the Free Software</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Foundation.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 10. If you wish to incorporate parts of the Program into other free</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">programs whose distribution conditions are different, write to the author</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">to ask for permission. For software which is copyrighted by the Free</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Software Foundation, write to the Free Software Foundation; we sometimes</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">make exceptions for this. Our decision will be guided by the two goals</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">of preserving the free status of all derivatives of our free software and</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">of promoting the sharing and reuse of software generally.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> NO WARRANTY</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">REPAIR OR CORRECTION.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">POSSIBILITY OF SUCH DAMAGES.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> END OF TERMS AND CONDITIONS</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> How to Apply These Terms to Your New Programs</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> If you develop a new program, and you want it to be of the greatest</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">possible use to the public, the best way to achieve this is to make it</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">free software which everyone can redistribute and change under these terms.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> To do so, attach the following notices to the program. It is safest</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">to attach them to the start of each source file to most effectively</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">convey the exclusion of warranty; and each file should have at least</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">the "copyright" line and a pointer to where the full notice is found.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> <one line to give the program's name and a brief idea of what it does.></span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Copyright (C) 19yy <name of author></span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> This program is free software; you can redistribute it and/or modify</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> it under the terms of the GNU General Public License as published by</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> the Free Software Foundation; either version 2 of the License, or</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> (at your option) any later version.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> This program is distributed in the hope that it will be useful,</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> but WITHOUT ANY WARRANTY; without even the implied warranty of</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> GNU General Public License for more details.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> You should have received a copy of the GNU General Public License</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> along with this program; if not, write to the Free Software</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Also add information on how to contact you by electronic and paper mail.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">If the program is interactive, make it output a short notice like this</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">when it starts in an interactive mode:</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Gnomovision version 69, Copyright (C) 19yy name of author</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> This is free software, and you are welcome to redistribute it</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> under certain conditions; type `show c' for details.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">The hypothetical commands `show w' and `show c' should show the appropriate</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">parts of the General Public License. Of course, the commands you use may</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">be called something other than `show w' and `show c'; they could even be</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">mouse-clicks or menu items--whatever suits your program.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">You should also get your employer (if you work as a programmer) or your</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">school, if any, to sign a "copyright disclaimer" for the program, if</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">necessary. Here is a sample; alter the names:</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Yoyodyne, Inc., hereby disclaims all copyright interest in the program</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> `Gnomovision' (which makes passes at compilers) written by James Hacker.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> <signature of Ty Coon>, 1 April 1989</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> Ty Coon, President of Vice</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">This General Public License does not permit incorporating your program into</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">proprietary programs. If your program is a subroutine library, you may</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">consider it more useful to permit linking proprietary applications with the</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">library. If this is what you want to do, use the GNU Library General</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">Public License instead of this License.</span></p></body></html>
@@ -160,7 +508,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;">This program is distributed under the terms of the GPL v2.</span></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; color:#ffffff;"> GNU GENERAL PUBLIC LICENSE</span></p>
@@ -507,6 +855,10 @@
+ layoutWidget
+ logoLabel
+ TabWidget3
+ aboutTxt
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/UI/ExportSongDialog_UI.ui hydrogen-0.9.6~beta2/src/gui/src/UI/ExportSongDialog_UI.ui
--- hydrogen-0.9.6~beta1/src/gui/src/UI/ExportSongDialog_UI.ui 2011-01-08 21:54:12.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/UI/ExportSongDialog_UI.ui 2012-05-25 12:19:45.000000000 +0000
@@ -6,8 +6,8 @@
0
0
- 490
- 312
+ 495
+ 336
@@ -17,7 +17,7 @@
20
- 260
+ 290
461
28
@@ -86,7 +86,7 @@
10
- 170
+ 200
471
81
@@ -171,7 +171,10 @@
- true
+ false
+
+
+
@@ -414,6 +417,121 @@
+
+
+
+ 20
+ 165
+ 461
+ 31
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+
+ 0
+ 0
+
+
+
+ Interpolation:
+
+
+
+ -
+
+
+
+ 100
+ 25
+
+
+
+ Choose type of interpolation methode
+
+ -
+
+ Linear
+
+
+ -
+
+ Cosine
+
+
+ -
+
+ Third
+
+
+ -
+
+ Cubic
+
+
+ -
+
+ Hermite
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Enable tempo changing
+
+
+ TimeLine BPM
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Enable use of rubberband batch processor
+
+
+ Rubberbad Batch
+
+
+
+
+
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/UI/PreferencesDialog_UI.ui hydrogen-0.9.6~beta2/src/gui/src/UI/PreferencesDialog_UI.ui
--- hydrogen-0.9.6~beta1/src/gui/src/UI/PreferencesDialog_UI.ui 2011-10-28 19:49:39.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/UI/PreferencesDialog_UI.ui 2012-05-25 12:19:45.000000000 +0000
@@ -330,19 +330,6 @@
Alt+R
-
-
-
- 10
- 100
- 511
- 31
-
-
-
- Save song files in Jack Session Directory (default on)
-
-
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/UndoActions.h hydrogen-0.9.6~beta2/src/gui/src/UndoActions.h
--- hydrogen-0.9.6~beta1/src/gui/src/UndoActions.h 2011-11-30 09:11:46.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/UndoActions.h 2012-05-25 12:19:45.000000000 +0000
@@ -329,10 +329,11 @@
class SE_movePatternCellAction : public QUndoCommand
{
public:
- SE_movePatternCellAction( std::vector movingCells, std::vector selectedCells, bool bIsCtrlPressed ){
+ SE_movePatternCellAction( std::vector movingCells, std::vector selectedCells, std::vector existingCells, bool bIsCtrlPressed ){
setText( QString( "Move/copy selected cells" ) );
__selectedCells = selectedCells;
__movingCells = movingCells;
+ __existingCells = existingCells;
__bIsCtrlPressed = bIsCtrlPressed;
}
@@ -340,18 +341,19 @@
{
//qDebug() << "move/copy selected cells undo";
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getSongEditorPanel()->getSongEditor()->movePatternCellAction( __selectedCells, __movingCells, __bIsCtrlPressed, true );
+ h2app->getSongEditorPanel()->getSongEditor()->movePatternCellAction( __selectedCells, __movingCells, __existingCells, __bIsCtrlPressed, true );
}
virtual void redo()
{
//qDebug() << "move/copy selected cells redo";
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getSongEditorPanel()->getSongEditor()->movePatternCellAction( __movingCells, __selectedCells, __bIsCtrlPressed, false );
+ h2app->getSongEditorPanel()->getSongEditor()->movePatternCellAction( __movingCells, __selectedCells, __existingCells, __bIsCtrlPressed, false );
}
private:
std::vector __selectedCells;
std::vector __movingCells;
+ std::vector __existingCells;
bool __bIsCtrlPressed;
};
@@ -478,9 +480,17 @@
float oldPan_R,
float oldLeadLag,
int oldNoteKeyVal,
- int oldOctaveKeyVal ){
- setText( QString( "Add note ( %1, %2)" ).arg( nColumn ).arg( nRow ) );
- //setText("add Pattern");
+ int oldOctaveKeyVal,
+ bool noteExisted,
+ bool listen,
+ bool isMidi,
+ bool isInstrumentMode){
+
+ if( noteExisted ){
+ setText( QString( "Delete note ( %1, %2)" ).arg( nColumn ).arg( nRow ) );
+ } else {
+ setText( QString( "Add note ( %1, %2)" ).arg( nColumn ).arg( nRow ) );
+ }
__nColumn = nColumn;
__nRow = nRow;
__selectedPatternNumber = selectedPatternNumber;
@@ -491,11 +501,15 @@
__oldLeadLag = oldLeadLag;
__oldNoteKeyVal = oldNoteKeyVal;
__oldOctaveKeyVal = oldOctaveKeyVal;
+ __listen = listen;
+ __isMidi = isMidi;
+ __isInstrumentMode = isInstrumentMode;
}
virtual void undo()
{
- //qDebug() << "Add note Undo ";
+ //qDebug() << "Add note Undo ";
HydrogenApp* h2app = HydrogenApp::get_instance();
+ __isMidi = false; // undo is never a midi event.
h2app->getPatternEditorPanel()->getDrumPatternEditor()->addOrDeleteNoteAction( __nColumn,
__nRow,
__selectedPatternNumber,
@@ -505,11 +519,15 @@
__oldPan_R,
__oldLeadLag,
__oldNoteKeyVal,
- __oldOctaveKeyVal );
+ __oldOctaveKeyVal,
+ __listen,
+ __isMidi,
+ __isInstrumentMode,
+ false );
}
virtual void redo()
{
- //qDebug() << "Add Note Redo " ;
+ //qDebug() << "Add Note Redo " ;
HydrogenApp* h2app = HydrogenApp::get_instance();
h2app->getPatternEditorPanel()->getDrumPatternEditor()->addOrDeleteNoteAction( __nColumn,
__nRow,
@@ -520,7 +538,11 @@
__oldPan_R,
__oldLeadLag,
__oldNoteKeyVal,
- __oldOctaveKeyVal );
+ __oldOctaveKeyVal,
+ __listen,
+ __isMidi,
+ __isInstrumentMode,
+ false );
}
private:
int __nColumn;
@@ -533,6 +555,9 @@
float __oldLeadLag;
int __oldNoteKeyVal;
int __oldOctaveKeyVal;
+ bool __listen;
+ bool __isMidi;
+ bool __isInstrumentMode;
};
@@ -550,13 +575,13 @@
{
//qDebug() << "Add off note Note Undo ";
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getDrumPatternEditor()->addOrDeleteNoteAction( __nColumn, __nRow, __selectedPatternNumber, -1, 0.8f, 0.5f, 0.5f, 0.0, 0, 0 );
+ h2app->getPatternEditorPanel()->getDrumPatternEditor()->addOrDeleteNoteAction( __nColumn, __nRow, __selectedPatternNumber, -1, 0.8f, 0.5f, 0.5f, 0.0, 0, 0, false, false, false, true);
}
virtual void redo()
{
//qDebug() << "Add off note Note Redo " ;
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getDrumPatternEditor()->addNoteRightClickAction( __nColumn, __nRow, __selectedPatternNumber );
+ h2app->getPatternEditorPanel()->getDrumPatternEditor()->addOrDeleteNoteAction( __nColumn, __nRow, __selectedPatternNumber, -1, 0.8f, 0.5f, 0.5f, 0.0, 0, 0, false, false, false, true);
}
private:
int __nColumn;
@@ -580,13 +605,13 @@
{
//qDebug() << "Change note length Undo ";
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getDrumPatternEditor()->editNoteLenghtAction( __nColumn, __nRealColumn, __row, __oldLength, __selectedPatternNumber );
+ h2app->getPatternEditorPanel()->getDrumPatternEditor()->editNoteLengthAction( __nColumn, __nRealColumn, __row, __oldLength, __selectedPatternNumber );
}
virtual void redo()
{
//qDebug() << "Change note length Redo " ;
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getDrumPatternEditor()->editNoteLenghtAction( __nColumn, __nRealColumn, __row, __length, __selectedPatternNumber );
+ h2app->getPatternEditorPanel()->getDrumPatternEditor()->editNoteLengthAction( __nColumn, __nRealColumn, __row, __length, __selectedPatternNumber );
}
private:
int __nColumn;
@@ -878,7 +903,8 @@
__oldPan_R,
__oldLeadLag,
__oldNoteKeyVal,
- __oldOctaveKeyVal );
+ __oldOctaveKeyVal,
+ false );
}
virtual void redo()
{
@@ -894,7 +920,8 @@
__oldPan_R,
__oldLeadLag,
__oldNoteKeyVal,
- __oldOctaveKeyVal );
+ __oldOctaveKeyVal,
+ false );
}
private:
int __nColumn;
@@ -910,12 +937,11 @@
int __oldOctaveKeyVal;
};
-class SE_addNoteRightClickPianoRollAction : public QUndoCommand
+class SE_addPianoRollNoteOffAction : public QUndoCommand
{
public:
- SE_addNoteRightClickPianoRollAction( int nColumn, int pressedLine, int selectedPatternNumber, int nSelectedInstrumentnumber ){
+ SE_addPianoRollNoteOffAction( int nColumn, int pressedLine, int selectedPatternNumber, int nSelectedInstrumentnumber ){
setText( QString( "Add piano roll NOTE_OFF note ( %1, %2 )" ).arg( nColumn ).arg( pressedLine ) );
- //setText("add Pattern");
__nColumn = nColumn;
__pressedLine = pressedLine;
__selectedPatternNumber = selectedPatternNumber;
@@ -925,13 +951,14 @@
{
//qDebug() << "Add off note Note Undo ";
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getPianoRollEditor()->addOrDeleteNoteAction( __nColumn, __pressedLine, __selectedPatternNumber, __nSelectedInstrumentnumber, -1, 0.8f, 0.5f, 0.5f, 0.0, 0, 0 );
+ h2app->getPatternEditorPanel()->getPianoRollEditor()->addOrDeleteNoteAction( __nColumn, __pressedLine, __selectedPatternNumber, __nSelectedInstrumentnumber, -1, 0.8f, 0.5f, 0.5f, 0.0, 0, 0 , true);
}
virtual void redo()
{
//qDebug() << "Add off note Note Redo " ;
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getPianoRollEditor()->addNoteRightClickAction( __nColumn, __pressedLine, __selectedPatternNumber, __nSelectedInstrumentnumber);
+ h2app->getPatternEditorPanel()->getPianoRollEditor()->addOrDeleteNoteAction( __nColumn, __pressedLine, __selectedPatternNumber, __nSelectedInstrumentnumber, -1, 0.8f, 0.5f, 0.5f, 0.0, 0, 0, true);
+
}
private:
int __nColumn;
@@ -941,10 +968,10 @@
};
-class SE_editNoteLenghtPianoRollAction : public QUndoCommand
+class SE_editPianoRollNoteLengthAction : public QUndoCommand
{
public:
- SE_editNoteLenghtPianoRollAction( int nColumn, int nRealColumn, int length, int oldLength, int selectedPatternNumber, int nSelectedInstrumentnumber, int pressedLine){
+ SE_editPianoRollNoteLengthAction( int nColumn, int nRealColumn, int length, int oldLength, int selectedPatternNumber, int nSelectedInstrumentnumber, int pressedLine){
setText( QString( "Change piano roll note length " ) );
__nColumn = nColumn;
__nRealColumn = nRealColumn;
@@ -958,13 +985,13 @@
{
//qDebug() << "Change note length Piano Roll Undo ";
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getPianoRollEditor()->editNoteLenghtAction( __nColumn, __nRealColumn, __oldLength, __selectedPatternNumber, __nSelectedInstrumentnumber, __pressedLine);
+ h2app->getPatternEditorPanel()->getPianoRollEditor()->editNoteLengthAction( __nColumn, __nRealColumn, __oldLength, __selectedPatternNumber, __nSelectedInstrumentnumber, __pressedLine);
}
virtual void redo()
{
//qDebug() << "Change note length Piano RollRedo " ;
HydrogenApp* h2app = HydrogenApp::get_instance();
- h2app->getPatternEditorPanel()->getPianoRollEditor()->editNoteLenghtAction( __nColumn,
+ h2app->getPatternEditorPanel()->getPianoRollEditor()->editNoteLengthAction( __nColumn,
__nRealColumn,
__length,
__selectedPatternNumber,
diff -Nru hydrogen-0.9.6~beta1/src/gui/src/widgets/Button.cpp hydrogen-0.9.6~beta2/src/gui/src/widgets/Button.cpp
--- hydrogen-0.9.6~beta1/src/gui/src/widgets/Button.cpp 2011-11-27 00:35:04.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/gui/src/widgets/Button.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -65,9 +65,7 @@
m_overPixmap.fill( QColor( 0, 180, 0 ) );
}
- // default text font
- m_textFont.setPointSize( 10 );
- m_textFont.setBold( true );
+ this->setStyleSheet("font-size: 9px; font-weight: bold;");
}
@@ -159,11 +157,6 @@
}
}
-
-
-
-
-
void Button::enterEvent(QEvent *ev)
{
UNUSED( ev );
@@ -246,7 +239,7 @@
if ( !m_sText.isEmpty() ) {
- painter.setFont( m_textFont );
+ painter.setFont( m_textFont );
QColor shadow(150, 150, 150, 100);
QColor text(10, 10, 10);
@@ -284,7 +277,6 @@
ToggleButton::ToggleButton( QWidget *pParent, const QString& sOnImg, const QString& sOffImg, const QString& sOverImg, QSize size, bool use_skin_style )
: Button( pParent, sOnImg, sOffImg, sOverImg, size, use_skin_style )
{
-
}
diff -Nru hydrogen-0.9.6~beta1/src/tests/xml.cpp hydrogen-0.9.6~beta2/src/tests/xml.cpp
--- hydrogen-0.9.6~beta1/src/tests/xml.cpp 2011-07-22 07:34:28.000000000 +0000
+++ hydrogen-0.9.6~beta2/src/tests/xml.cpp 2012-05-25 12:19:45.000000000 +0000
@@ -1,4 +1,5 @@
+#include
#include
#include
diff -Nru hydrogen-0.9.6~beta1/todo_undo_implementation hydrogen-0.9.6~beta2/todo_undo_implementation
--- hydrogen-0.9.6~beta1/todo_undo_implementation 2011-01-16 08:46:14.000000000 +0000
+++ hydrogen-0.9.6~beta2/todo_undo_implementation 2012-05-25 12:19:45.000000000 +0000
@@ -25,6 +25,8 @@
+ Edit note length Pattern Editor (right cklicking) | Done
+ Add/Remove note Piano Roll Editor | Done
+ Add/Remove noteoff note Piano Roll Editor | Done
+ + Add/Remove note via Midi | Done
+ + Destructive recording (Delete Notes) | Done
+ Edit note length Piano Roll Editor (right cklicking) | Done
+ Edit velocity Piano Roll Editor | Done
+ Edit pan Piano Roll Editor | Done
diff -Nru hydrogen-0.9.6~beta1/tools/git hydrogen-0.9.6~beta2/tools/git
--- hydrogen-0.9.6~beta1/tools/git 2011-01-12 07:26:26.000000000 +0000
+++ hydrogen-0.9.6~beta2/tools/git 1970-01-01 00:00:00.000000000 +0000
@@ -1,142 +0,0 @@
-#! /bin/bash
-
-ABSPATH=$(readlink -f $0)
-
-GIT_BASE=${GIT_BASE:-${ABSPATH%/*/*/*}}
-
-PRJ=hydrogen
-SVN_URL=http://svn.assembla.com/svn/hydrogen
-BRANCHES_TO_TRACK="trunk undo jeremyz"
-
-LOCAL_REPO=local
-LOCAL_DIR=${GIT_BASE}/${PRJ}
-SVN_CLONE_REPO=svn_clone
-SVN_CLONE_DIR=${GIT_BASE}/${PRJ}_svn
-
-RED="\033[0;31m"
-RESET="\033[0m"
-
-URL_COLOR="\033[0;34m"
-LRC="\033[0;33m" # LOCAL REPO COLOR
-LBC="\033[0;36m" # LOCAL BRANCH COLOR
-SRC="\033[0;35m" # SVN CLONE REPO COLOR
-SBC="\033[0;32m" # SVN CLONE BRANCH COLOR
-DSBC="\033[0;37m" # DISTANT SVN BRANCH COLOR
-
-function error() {
- echo -e " => ${RED}FAILURE${RESET}" && exit 1
-}
-
-function ask_ok() {
- echo -n -e "$1${RESET}[${RED}Y${RESET}n] : "
- read OK
- if [ "$OK" = "" -o "$OK" = "y" -o "$OK" = "Y" ]; then
- return 0
- fi
- echo -e "${RED}abort${RESET}" && return 1
-}
-
-function create_svn_clone() {
- echo -e "** clone from ${URL_COLOR}${SVN_URL}${RESET}" && cd $GIT_BASE && git svn clone ${SVN_URL} -T trunk -b branches -t tags ${PRJ}_svn || error
- cd ${SVN_CLONE_DIR}
- for branch in $BRANCHES_TO_TRACK; do
- echo -e "** checkout ${DSBC}${branch}${RESET} in ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${branch}_svn${RESET}" && git checkout $branch -b ${branch}_svn || error
- done
- echo -e "** add ${LRC}${LOCAL_DIR}${RESET} as repo ${LRC}${LOCAL_REPO}${RESET}" && git remote add ${LOCAL_REPO} ${LOCAL_DIR} || error
-}
-
-function create_local_repo() {
- echo -e "** git init ${LRC}${LOCAL_DIR}${RESET}" && git init ${LOCAL_DIR}|| error
- echo -e "** cd ${LRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
- echo -e "** add ${SRC}${SVN_CLONE_DIR}${RESET} as repo ${SRC}${SVN_CLONE_REPO}${RESET}" && git remote add ${SVN_CLONE_REPO} ${SVN_CLONE_DIR} || error
- echo -e "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
- for branch in $BRANCHES_TO_TRACK; do
- echo -e "** checkout ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${branch}_svn${RESET} to ${SBC}${branch}${RESET}" && git checkout ${SVN_CLONE_REPO}/${branch}_svn -b ${branch} || error
- done
-}
-
-function fetch_svn(){
- echo -e "** cd ${SRC}${SVN_CLONE_DIR}${RESET}" && cd ${SVN_CLONE_DIR} || error
- echo -e "** fetch from ${URL_COLOR}${SVN_URL}${RESET}" && git svn fetch || error
- BRANCHES=$(git branch | sed -e s/*//)
- for branch in $BRANCHES; do
- echo -e "** rebase ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${branch}${RESET}" && git checkout $branch && git svn rebase || error
- done
- echo -e "** cd ${SRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
- echo -e "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
-}
-
-function pull_from_clone() {
- #echo -e "** cd ${SRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
- #echo -e "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
- #echo -e "** merge ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_CLONE_B}${RESET} within ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET}" && git merge ${SVN_CLONE_REPO}/${SVN_CLONE_B} || error
- echo -e "To do so :"
- echo -e " ${LRC}- save your current work ${SRC}$ git stash save NAME${RESET}"
- echo -e " ${LRC}- leave your current branch ${SRC}$ git checkout ANOTHER_BRANCH${RESET}"
- echo -e " ${LRC}- delete your branch ${SRC}$ git branch -D ${LOCAL_B}${RESET}"
- echo -e " ${LRC}- checkout your branch ${SRC}$ git checkout ${SVN_CLONE_REPO}/${LOCAL_B}_svn -b ${LOCAL_B}${RESET}"
- echo -e " ${LRC}- apply your current work ${SRC}$ git stash pop/apply${RESET}"
-}
-
-function push_to_clone() {
- echo -e "** cd ${SRC}${SVN_CLONE_DIR}${RESET}" && cd ${SVN_CLONE_DIR} || error
- echo -e "** checkout ${SBC}${SVN_CLONE_B}${RESET}" && git checkout ${SVN_CLONE_B} || error
- echo -e "** fetch ${LRC}${LOCAL_REPO}${RESET}" && git fetch ${LOCAL_REPO} || error
- echo -e "** rebase ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET} within ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_CLONE_B}${RESET}" && git rebase ${LOCAL_REPO}/${LOCAL_B} || error
- #git log --format="%H %an %s" $SVN_HEAD..$LOCAL_HEAD
- echo -e "** cd ${SRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
- echo -e "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
-}
-
-function dcommit() {
- echo -e "** cd ${SRC}${SVN_CLONE_DIR}${RESET}" && cd ${SVN_CLONE_DIR} || error
- echo -e "** checkout ${SBC}${SVN_CLONE_B}${RESET}" && git checkout ${SVN_CLONE_B} || error
- echo -e "** rebase ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_CLONE_B}${RESET}" && git svn rebase || error
- echo -e "** dcommit ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_CLONE_B}${RESET} to ${URL_COLOR}${SVN_URL}${RESET}" && git svn dcommit
-}
-
-if [ ! -d ${SVN_CLONE_DIR} ]; then
- ask_ok "clone svn repository ${URL_COLOR}${SVN_URL}${RESET} to ${SRC}${SVN_CLONE_DIR}${RESET} " && create_svn_clone
-fi
-if [ ! -d ${LOCAL_DIR} ]; then
- ask_ok "create local repository within ${LRC}${LOCAL_DIR}${RESET} " && create_local_repo
-fi
-
-cd ${LOCAL_DIR}
-LOCAL_B=$(git branch |grep '*' | gawk '{print $2;}') || error
-LOCAL_HEAD=$(git show --format="%H" HEAD | head -n 1 | gawk '{print $1 }') || error
-echo -e "** ${LRC}${LOCAL_REPO}${RESET} current branch is ${LBC}${LOCAL_B}${RESET} head ${RED}${LOCAL_HEAD}${RESET}"
-cd ${SVN_CLONE_DIR}
-SVN_CLONE_B=${LOCAL_B}_svn
-SVN_HEAD=$(git show --format="%H" HEAD | head -n 1 | gawk '{print $1 }') || error
-echo -e "** ${LRC}${SVN_CLONE_REPO}${RESET} corresponding branch is ${LBC}${SVN_CLONE_B}${RESET} head ${RED}${SVN_HEAD}${RESET}"
-cd ${LOCAL_DIR}
-
-while [ 1 ]; do
- echo -e "\nOptions :"
- echo -e " # 1) ${RED}fetch svn${RESET} and update branches within ${SRC}${SVN_CLONE_DIR}${RESET}"
- echo -e " # 2) ${RED}push${RESET} ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET} within ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_CLONE_B}${RESET}"
- echo -e " # 3) ${RED}push${RESET} ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_CLONE_B}${RESET} to ${URL_COLOR}${SVN_URL}${RESET}"
- echo -e " # 4) ${RED}pull${RESET} ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_CLONE_B}${RESET} within ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET}"
- echo -e " # q) ${RED}QUIT${RESET}"
- echo -n -e "\nyour choice : "
- read CHOICE
- echo ""
- case $CHOICE in
- q)
- exit 0
- ;;
- 1)
- fetch_svn
- ;;
- 2)
- push_to_clone
- ;;
- 3)
- dcommit
- ;;
- 4)
- pull_from_clone
- ;;
- esac
-done