diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a1561e5e..fc2cf1361 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ INCLUDE(FindPkgConfig) SET(VERSION_MAJOR "1") SET(VERSION_MINOR "0") -SET(VERSION_PATCH "90") +SET(VERSION_PATCH "91") #SET(VERSION_SUFFIX "") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") IF(VERSION_SUFFIX) @@ -660,6 +660,8 @@ SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS " SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS " \\\${unregisterExtension} \\\".mmp\\\" \\\"LMMS Project\\\" \\\${unregisterExtension} \\\".mmpz\\\" \\\"LMMS Project (compressed)\\\" + DeleteRegKey HKCR \\\"LMMS Project\\\" + DeleteRegKey HKCR \\\"LMMS Project (compressed)\\\" ") ELSE(WIN32) SET(CPACK_STRIP_FILES "bin/lmms;${PLUGIN_DIR}/*.so") diff --git a/data/locale/fr.ts b/data/locale/fr.ts index e6ccb95fd..fc9015c97 100644 --- a/data/locale/fr.ts +++ b/data/locale/fr.ts @@ -43,11 +43,11 @@ If you're interested in translating LMMS in another language or want to imp Copyright (c) 2004-2014, LMMS developers - Copyright (c) 2004-2008, les développeurs de LMMS {2004-2010,?} {2004-2014,?} + Copyright (c) 2004-2014, les développeurs de LMMS <html><head/><body><p><a href="http://lmms.sourceforge.net"><span style=" text-decoration: underline; color:#0000ff;">http://lmms.sourceforge.net</span></a></p></body></html> - + <html><head/><body><p><a href="http://lmms.sourceforge.net"><span style=" text-decoration: underline; color:#0000ff;">http://lmms.sourceforge.net</span></a></p></body></html> @@ -113,18 +113,18 @@ If you're interested in translating LMMS in another language or want to imp Continue sample playback across notes - + Continuer de jouer l'échantillon à traver les notes Enabling this option makes the sample continue playing across different notes - if you change pitch, or the note length stops before the end of the sample, then the next note played will continue where it left off. To reset the playback to the start of the sample, insert a note at the bottom of the keyboard (< 20 Hz) - + Activer cette option fait que l'échantillon continue de jouer à traver les différentes notes - si vous changez la hauteur, ou si la longueur de la note s'arrête avant la fin de l'échantillon, alors la note suivante jouée continuera où elle aura été arrêtée. Pour remettre à zéro le jeu au début de l'échantillon, insérez une note en bas du clavier (< 20 Hz) AudioFileProcessorWaveView Sample length: - + Longueur de l'échantillon: @@ -237,171 +237,171 @@ If you're interested in translating LMMS in another language or want to imp Remove song-global automation - + Supprime l'automation globale de la chanson Remove all linked controls - + Supprime tous les contrôles liés AutomationEditor Play/pause current pattern (Space) - Jouer/Mettre en pause le motif (Barre d'espace) + Jouer/Mettre en pause le motif (Barre d'espace) Stop playing of current pattern (Space) - Arrêter de jouer le motif (Barre d'espace) + Arrêter de jouer le motif courant (Barre d'espace) Click here if you want to play the current pattern. This is useful while editing it. The pattern is automatically looped when the end is reached. - Cliquez ici si vous souhaitez jouer le motif. Ceci est utile pendant son édition. Le motif est automatiquement rejoué lorsque sa fin est atteinte. + Cliquez ici si vous souhaitez jouer le motif courant. Ceci est utile pendant son édition. Le motif est automatiquement rejoué lorsque sa fin est atteinte. Click here if you want to stop playing of the current pattern. - Cliquez ici si vous souhaitez arrêter de jouer le motif. + Cliquez ici si vous souhaitez arrêter de jouer le motif courant. Draw mode (Shift+D) - Mode dessin (Shift+D) + Mode dessin (Shift+D) Erase mode (Shift+E) - Mode effacement (Shift+E) + Mode effacement (Shift+E) Click here and draw-mode will be activated. In this mode you can add and move single values. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. - Cliquez ici et le mode dessin sera activé. Dans ce mode vous pourrez ajouter et déplacer des valeurs particulières. Ceci est le mode par défaut qui est utilisé la plupart du temps. Vous pouvez aussi appuyer sur les touches 'Shift+D' de votre clavier pour activer ce mode. + Cliquez ici et le mode dessin sera activé. Dans ce mode vous pourrez ajouter et déplacer des valeurs particulières. Ceci est le mode par défaut qui est utilisé la plupart du temps. Vous pouvez aussi appuyer sur les touches 'Shift+D' de votre clavier pour activer ce mode. Click here and erase-mode will be activated. In this mode you can erase single values. You can also press 'Shift+E' on your keyboard to activate this mode. - Cliquez ici et le mode effacement sera activé. Dans ce mode vous pourrez effacer des valeurs particulières. Vous pouvez aussi appuyer sur les touches 'Shift+E' de votre clavier pour activer ce mode. + Cliquez ici et le mode effacement sera activé. Dans ce mode vous pourrez effacer des valeurs particulières. Vous pouvez aussi appuyer sur les touches 'Shift+E' de votre clavier pour activer ce mode. Cut selected values (Ctrl+X) - Couper les valeurs sélectionnées (Ctrl+X) + Couper les valeurs sélectionnées (Ctrl+X) Copy selected values (Ctrl+C) - Copier les valeurs sélectionnées (Ctrl+C) + Copier les valeurs sélectionnées (Ctrl+C) Paste values from clipboard (Ctrl+V) - Coller les valeurs sélectionnées (Ctrl+V) + Coller les valeurs sélectionnées (Ctrl+V) Click here and selected values will be cut into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - Cliquez ici et les valeurs sélectionnées seront coupées et copiées dans le presse-papier. Vous pourrez les coller n'importe où dans n'importe quel motif en cliquant sur le bouton coller. + Cliquez ici et les valeurs sélectionnées seront coupées et copiées dans le presse-papier. Vous pourrez les coller n'importe où dans n'importe quel motif en cliquant sur le bouton coller. Click here and selected values will be copied into the clipboard. You can paste them anywhere in any pattern by clicking on the paste button. - Cliquez ici et les valeurs sélectionnées seront copiées dans le presse-papier. Vous pourrez les coller n'importe où dans n'importe quel motif en cliquant sur le bouton coller. + Cliquez ici et les valeurs sélectionnées seront copiées dans le presse-papier. Vous pourrez les coller n'importe où dans n'importe quel motif en cliquant sur le bouton coller. Click here and the values from the clipboard will be pasted at the first visible measure. - Cliquez ici et les valeurs se trouvant dans le presse-papier seront collées sur la première mesure visible. + Cliquez ici et les valeurs se trouvant dans le presse-papier seront collées sur la première mesure visible. Automation Editor - no pattern - Éditeur d'automation - pas de motif + Éditeur d'automation - pas de motif Automation Editor - %1 - Éditeur d'automation - %1 + Éditeur d'automation - %1 Please open an automation pattern with the context menu of a control! - Veuillez ouvrir un motif d'automation avec le menu contextuel d'un contrôle ! + Veuillez ouvrir un motif d'automation avec le menu contextuel d'un contrôle ! Values copied - Les valeurs ont été copiées + Les valeurs ont été copiées All selected values were copied to the clipboard. - Toutes les valeurs ont été copiées dans le presse-papier. + Toutes les valeurs ont été copiées dans le presse-papier. Discrete progression - + Progression discrète Linear progression - + Progression linéaire Cubic Hermite progression - + Progression cubique de Hermite Tension: - + Tension : Click here to choose discrete progressions for this automation pattern. The value of the connected object will remain constant between control points and be set immediately to the new value when each control point is reached. - + Cliquez ici pour choisir la progression discrète pour ce motif d'automation. La valeur de l'objet connecté restera contante entre les points de contrôle et se verra affecter immédiatement une nouvelle valeur quand un point de contrôle est atteint. Click here to choose linear progressions for this automation pattern. The value of the connected object will change at a steady rate over time between control points to reach the correct value at each control point without a sudden change. - + Cliquez ici pour choisir la progression linéaire pour ce motif d'automation. La valeur de l'objet connecté changera à un taux contant entre les points de contrôle et atteindra la valeur correcte à chaque point de contrôle sans changement soudain. Click here to choose cubic hermite progressions for this automation pattern. The value of the connected object will change in a smooth curve and ease in to the peaks and valleys. - + Cliquez ici pour choisir la progression cubique de Hermite pour ce motif d'automation. La valeur de l'objet connecté changera suivant une courbe lisse. Tension value for spline - + Valeur de tension pour la spline A higher tension value may make a smoother curve but overshoot some values. A low tension value will cause the slope of the curve to level off at each control point. - + Une valeur de tension élevée donne une courbe plus lisse mais introduit des dépassements pour certaines valeurs. Une valeur de tension basse fera que la pente de la courbe se stabilisera à chaque point de contrôle. AutomationPattern Drag a control while pressing <Ctrl> - Déplacer un contrôle en appuyant sur <Ctrl> + Déplacer un contrôle en appuyant sur <Ctrl> AutomationPatternView double-click to open this pattern in automation editor - double-cliquer pour ouvrir ce motif dans l'éditeur d'automation + double-cliquer pour ouvrir ce motif dans l'éditeur d'automation Open in Automation editor - Ouvrir dans l'éditeur d'automation + Ouvrir dans l'éditeur d'automation Clear - Effacer + Effacer Reset name - Réinitialiser le nom + Réinitialiser le nom Change name - Changer le nom + Changer le nom %1 Connections - %1 connexions + %1 connexions Disconnect "%1" - Déconnecter "%1" + Déconnecter "%1" AutomationTrack Automation track - Piste d'automation + Piste d'automation @@ -482,11 +482,11 @@ If you're interested in translating LMMS in another language or want to imp Confirm Delete - + Confirmer la suppression Confirm delete? There are existing connection(s) associted with this controller. There is no way to undo. - + Confirmer la suppression ? Il existe des connection(s) associée(s) avec ce contrôleur. Il n'est pas possible d'annuler cette action. @@ -1037,7 +1037,7 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo Export as loop (remove end silence) - + Exporter sous la forme d'une boucle (supprime le silence de fin) @@ -1082,130 +1082,130 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo InstrumentFunctionArpeggio Arpeggio - Arpège + Arpège Arpeggio type - Type d'arpège + Type d'arpège Arpeggio range - Gamme d'arpège + Plage d'arpège Arpeggio time - Temps d'arpège + Temps d'arpège Arpeggio gate - Durée d'arpège + Durée d'arpège Arpeggio direction - Sens d'arpège + Direction de l'arpège Arpeggio mode - Mode d'arpège + Mode d'arpège Up - Ascendant + Ascendant Down - Descendant + Descendant Up and down - Ascendant et descendant + Ascendant et descendant Random - Aléatoire + Aléatoire Free - Libre + Libre Sort - Tri + Tri Sync - + Sync InstrumentFunctionArpeggioView ARPEGGIO - ARPÈGE + ARPÈGE An arpeggio is a method playing (especially plucked) instruments, which makes the music much livelier. The strings of such instruments (e.g. harps) are plucked like chords. The only difference is that this is done in a sequential order, so the notes are not played at the same time. Typical arpeggios are major or minor triads, but there are a lot of other possible chords, you can select. - Un arpège est une façon de jouer des instruments (en particulier ceux à cordes pincées), qui rend la musique plus vivante. Les cordes de tels instruments (p. ex. les harpes) sont pincées comme des accords. La seule différence est que cela est fait de manière séquentielle, ce qui fait que les notes ne sont pas jouées en même temps. Les arpèges typiques sont des triades majeures ou mineures, mais il y a beaucoup d'autres accords possibles, vous pouvez choisr. + Un arpège est une façon de jouer des instruments (en particulier ceux à cordes pincées), qui rend la musique plus vivante. Les cordes de tels instruments (p. ex. les harpes) sont pincées comme des accords. La seule différence est que cela est fait de manière séquentielle, ce qui fait que les notes ne sont pas jouées en même temps. Les arpèges typiques sont des triades majeures ou mineures, mais il y a beaucoup d'autres accords possibles, vous pouvez choisr. RANGE - GAMME + PLAGE Arpeggio range: - Gamme d'arpège : + Plage d'arpège : octave(s) - octave(s) + octave(s) Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. - Utilisez ce bouton pour régler la gamme d'octaves de l'arpège. L'arpège sélectionné sera joué sur le nombre d'octaves choisi. + Utilisez ce bouton pour régler la plage de l'arpège en octaves. L'arpège sélectionné sera joué sur le nombre d'octaves choisi. TIME - TEMPS + TEMPS Arpeggio time: - Temps d'arpège : + Temps d'arpège : ms - ms + ms Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - Utilisez ce bouton pour régler le temps d'arpège en millisecondes. Le temps d'arpège indique la durée pendant laquelle chaque note de l'arpège sera joué. + Utilisez ce bouton pour régler le temps d'arpège en millisecondes. Le temps d'arpège indique la durée pendant laquelle chaque note de l'arpège sera joué. GATE - + DUREE Arpeggio gate: - Durée d'arpège : + Durée d'arpège : % - % + % Use this knob for setting the arpeggio gate. The arpeggio gate specifies the percent of a whole arpeggio-tone that should be played. With this you can make cool staccato arpeggios. - Utilisez ce bouton pour régler la durée d'arpège. La durée d'arpège indique le pourcentage d'une note complète de l'arpège qui sera joué. Avec ceci vous pouvez faire de beaux arpèges staccato. + Utilisez ce bouton pour régler la durée d'arpège. La durée d'arpège indique le pourcentage d'une note complète de l'arpège qui sera joué. Avec ceci vous pouvez faire de beaux arpèges staccato. Chord: - + Accord: Direction: - Sens : + Direction : Mode: - Mode : + Mode : @@ -1576,7 +1576,7 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo Minor - + Mineur @@ -1599,11 +1599,11 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo STACKING - + EMPILEMENT Chord: - + Accord: @@ -1638,7 +1638,7 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo NOTE - + NOTE @@ -1713,31 +1713,31 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo RC LowPass 12dB - + RC Passe Bas 12dB RC BandPass 12dB - + RC Passe Bande 12dB RC HighPass 12dB - + RC Passe Haut 12dB RC LowPass 24dB - + RC Passe Bas 24dB RC BandPass 24dB - + RC Passe Bande 24dB RC HighPass 24dB - + RC Passe Haut 24dB Vocal Formant Filter - + Filtre Formant Vocal @@ -1780,11 +1780,11 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo FREQ - FRÉQ + FRÉQ cutoff frequency: - + Fréquence de coupure: @@ -1823,7 +1823,7 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo Pitch range - + Plage de hauteur @@ -1953,11 +1953,11 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo Pitch range (semitones) - + Plage de hauteur (demi-tons) RANGE - GAMME + PLAGE @@ -2128,7 +2128,8 @@ Un clic-droit fera apparaître un menu contextuel où vous pourrez changer l&apo Click here for a user-defined shape. Double click to pick a file. - + Cliquez ici pour une forme définie par l'utilisateur. +Double cliquez pour choisir un fichier. @@ -2355,39 +2356,39 @@ Veuillez visiter http://lmms.sf.net/wiki pour la documentation de LMMS. Save as new &version - + Enregistrer comme nouvelle &version E&xport tracks... - + E&xporter les pistes... LMMS (*.mmp *.mmpz) - + LMMS (*.mmp *.mmpz) LMMS Project (*.mmp *.mmpz);;LMMS Project Template (*.mpt) - + Projet LMMS (*.mmp *.mmpz);;Modèle de projet LMMS (*.mpt) Version %1 - + Version %1 Project recovery - + Récupération de projet It looks like the last session did not end properly. Do you want to recover the project of this session? - + Il semble que la dernière session ne se soit pas terminée correctement. Voulez-vous récupérer le projet de cette session? Configuration file - + Fichier de configuration Error while parsing configuration file at line %1:%2: %3 - + Erreur pendant l'analyse du fichier de configuration à la ligne %1:%2:%3 @@ -2503,7 +2504,7 @@ Veuillez visiter http://lmms.sf.net/wiki pour la documentation de LMMS. Fixed output note - + Note de sortie fixe @@ -2604,11 +2605,11 @@ Veuillez visiter http://lmms.sf.net/wiki pour la documentation de LMMS. Peak Controller Bug - + Bug du contrôleur de crêtes Due to a bug in older version of LMMS, the peak controllers may not be connect properly. Please ensure that peak controllers are connected properly and re-save this file. Sorry for any inconvenience caused. - + A cause d'un bug dans les anciennes versions de LMMS, les contrôleurs de crêtes peuvent ne pas s'être connecté correctement. Verifiez que les contrôleurs de crêtes sont connectés correctement et re-sauvegardez ce fichier. Désolé pour la gène occasionnée. @@ -2638,31 +2639,31 @@ Veuillez visiter http://lmms.sf.net/wiki pour la documentation de LMMS. Attack: - Attaque : + Attaque : Release: - Relâchement : + Relâchement : AMNT - + AMNT MULT - + MULT Amount Multiplicator: - + Multiplicateur de quantité: ATCK - + ATCK DCAY - + DCAY @@ -2681,19 +2682,19 @@ Veuillez visiter http://lmms.sf.net/wiki pour la documentation de LMMS. Attack - Attaque + Attaque Release - Relâchement + Relâchement Abs Value - + Valeur Abs Amount Multiplicator - + Multiplicateur de quantité @@ -2740,87 +2741,87 @@ Raison : "%2" C Note name - + C Db Note name - + Db C# Note name - + C# D Note name - + D Eb Note name - + Eb D# Note name - + D# E Note name - + E Fb Note name - + Fb Gb Note name - + Gb F# Note name - + F# G Note name - + G Ab Note name - + Ab G# Note name - + G# A Note name - + A Bb Note name - + Bb A# Note name - + A# B Note name - + B @@ -2874,108 +2875,108 @@ Raison : "%2" SampleBuffer Open audio file - Ouvrir un fichier audio + Ouvrir un fichier audio All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw *.mp3) - Tous les fichiers audio (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw *.mp3) + Tous les fichiers audio (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw *.mp3) Wave-Files (*.wav) - Fichiers WAVE (*.wav) + Fichiers WAVE (*.wav) OGG-Files (*.ogg) - Fichiers OGG (*.ogg) + Fichiers OGG (*.ogg) DrumSynth-Files (*.ds) - Fichiers DrumSynth (*.ds) + Fichiers DrumSynth (*.ds) FLAC-Files (*.flac) - Fichiers FLAC (*.flac) + Fichiers FLAC (*.flac) SPEEX-Files (*.spx) - Fichiers SPEEX (*.spx) + Fichiers SPEEX (*.spx) MP3-Files (*.mp3) - Fichiers MP3 (*.mp3) + Fichiers MP3 (*.mp3) VOC-Files (*.voc) - Fichiers VOC (*.voc) + Fichiers VOC (*.voc) AIFF-Files (*.aif *.aiff) - Fichiers AIFF (*.aif *.aiff) + Fichiers AIFF (*.aif *.aiff) AU-Files (*.au) - Fichiers AU (*.au) + Fichiers AU (*.au) RAW-Files (*.raw) - Fichiers RAW (*.raw) + Fichiers RAW (*.raw) SampleTCOView double-click to select sample - Double-cliquez pour choisir un échantillon + Double-cliquez pour choisir un échantillon Delete (middle mousebutton) - + Supprimer (bouton du milieu de la souris) Cut - Couper + Couper Copy - Copier + Copier Paste - Coller + Coller Mute/unmute (<Ctrl> + middle click) - Couper/Jouer (<Ctrl> + clic-milieu) + Couper/Jouer (<Ctrl> + clic-milieu) Set/clear record - Régler/Effacer l'enregistrement + Régler/Effacer l'enregistrement SampleTrack Sample track - Piste d'échantillon + Piste d'échantillon Volume - Volume + Volume SampleTrackView Track volume - Volume de la piste + Volume de la piste Channel volume: - Volume du canal : + Volume du canal : VOL - VOL + VOL @@ -3061,50 +3062,50 @@ Raison : "%2" TimeDisplayWidget click to change time units - + cliquez pour changer les unités de temps TrackContainer Couldn't import file - Le fichier n'a pas pu être importé + Le fichier n'a pas pu être importé Couldn't find a filter for importing file %1. You should convert this file into a format supported by LMMS using another software. - Aucun filtre n'a pu être trouvé pour importer le fichier %1. + Aucun filtre n'a pu être trouvé pour importer le fichier %1. Vous devriez convertir ce fichier dans un format pris en charge par LMMS en utilisant un autre logiciel. Couldn't open file - Le fichier n'a pas pu être ouvert + Le fichier n'a pas pu être ouvert Couldn't open file %1 for reading. Please make sure you have read-permission to the file and the directory containing the file and try again! - Le fichier %1 n'a pas pu être ouvert en lecture. + Le fichier %1 n'a pas pu être ouvert en lecture. Veuillez vérifier que vous avez les droits en lecture pour ce fichier et le répertoire qui contient ce fichier et réessayez ! Loading project... - Chargement du projet... + Chargement du projet... Cancel - Annuler + Annuler Please wait... - Veuillez patienter... + Veuillez patienter... Importing MIDI-file... - Importation du fichier MIDI... + Importation du fichier MIDI... Importing FLP-file... - Importation du fichier FLP... + Importation du fichier FLP... @@ -3254,22 +3255,22 @@ Veuillez vérifier que vous avez les droits en lecture pour ce fichier et le ré Ui Contributors ordered by number of commits: - + Contributeurs classés par nombre de commits: Involved - + Impliqué VersionedSaveDialog Increment version number - + Incrémenter le numéro de version Decrement version number - + Décrémenter le numéro de version @@ -3312,110 +3313,110 @@ Veuillez vérifier que vous avez les droits en lecture pour ce fichier et le ré Control VST-plugin from LMMS host - + Contrôler le greffon VST à partir de l'hôte LMMS Click here, if you want to control VST-plugin from host. - + Cliquez ici si vous voulez contrôler le greffon VST à partir de l'hôte. Open VST-plugin preset - + Ouvrir les pré-réglages du greffon VST Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + Cliquez ici si vous voulez ouvrir un autre pré-réglage de greffon VST *.fxp, *.fxb. Previous (-) - + Précédent (-) Click here, if you want to switch to another VST-plugin preset program. - + Cliquez ici si vous voulez passer à un autre programme de pré-réglage de plugin VST. Save preset - Enregistrer le préréglage + Enregistrer le pré-réglage Click here, if you want to save current VST-plugin preset program. - + Cliquez ici si vous voulez sauvegarder le programme de pré-réglage de greffon VST courant. Next (+) - + Suivant (+) Click here to select presets that are currently loaded in VST. - + Cliquez ici pour sélectionner les pré-réglages qui sont actuellement chargés dans le VST. Preset - + Pré-réglage by - + par - VST plugin control - + - contrôle de greffon VST VstEffectControlDialog Show/hide - + Montrer/Cacher Control VST-plugin from LMMS host - + Contrôler le greffon VST à partir de l'hôte LMMS Click here, if you want to control VST-plugin from host. - + Cliquez ici si vous voulez contrôler le greffon VST à partir de l'hôte. Open VST-plugin preset - + Ouvrir le pré-réglage du greffon VST Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + Cliquez ici si vous voulez ouvrir un autre pré-réglage de greffon VST *.fxp, *.fxb. Previous (-) - + Précédent (-) Click here, if you want to switch to another VST-plugin preset program. - + Cliquez ici si vous voulez passer à un autre programme de pré-réglage de plugin VST. Next (+) - + Suivant (+) Click here to select presets that are currently loaded in VST. - + Cliquez ici pour sélectionner les pré-réglages qui sont actuellement chargés dans le VST. Save preset - Enregistrer le préréglage + Enregistrer le pré-réglage Click here, if you want to save current VST-plugin preset program. - + Cliquez ici si vous voulez sauvegarder le programme de pré-réglage de greffon VST courant. Effect by: - + Effet par: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> - + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -3440,78 +3441,78 @@ S'il fonctionne avec d'autres logiciels VST sous Linux, merci de conta Open Preset - + Ouvrir le Pré-réglage Vst Plugin Preset (*.fxp *.fxb) - + Pré-réglage de Greffon VST (*.fxp *.fxb) : default - + : défaut " - + " ' - + ' Save Preset - + Enregistrer le pré-réglage .fxp - + .fxp .FXP - + .FXP .FXB - + .FXB .fxb - + .fxb ZynAddSubFxInstrument Portamento - + Portamento Filter Frequency - + Fréquence du Filtre Filter Resonance - + Résonance du Filtre Bandwidth - + Largeur de bande FM Gain - + Gain FM Resonance Center Frequency - + Fréquence Centrale de la Résonance Resonance Bandwidth - + Largeur de Bande de la Résonance Forward MIDI Control Change Events - + Transmet les évènements MIDI Control Change @@ -3526,63 +3527,63 @@ S'il fonctionne avec d'autres logiciels VST sous Linux, merci de conta Portamento: - + Portamento: PORT - + PORT Filter Frequency: - + Fréquence du Filtre: FREQ - FRÉQ + FRÉQ Filter Resonance: - + Résonance du Filtre: RES - RES + RES Bandwidth: - + Largeur de bande: BW - + BW FM Gain: - + Gain FM: FM GAIN - + GAIN FM Resonance center frequency: - + Fréquence centrale de la résonance: RES CF - + RES CF Resonance bandwidth: - + Largeur de Bande de la Résonance: RES BW - + RES BW Forward MIDI Control Changes - + Transmet les évènements MIDI Control Change @@ -3609,7 +3610,8 @@ S'il fonctionne avec d'autres logiciels VST sous Linux, merci de conta Stutter - + ?? + Bégaiement @@ -3686,11 +3688,11 @@ S'il fonctionne avec d'autres logiciels VST sous Linux, merci de conta Remove steps - Supprimer des pas + Supprimer des pas Add steps - Ajouter des pas + Ajouter des pas @@ -3720,7 +3722,7 @@ S'il fonctionne avec d'autres logiciels VST sous Linux, merci de conta Clone of %1 - + Clone de %1 @@ -3838,7 +3840,7 @@ Veuillez vérifier que vous avez les droits d'accès en écriture pour ce f fader Please enter a new value between %1 and %2: - Veuillez entrer un valeur entre %1 et %2 : + Veuillez entrer un valeur entre %1 et %2 : @@ -4586,62 +4588,62 @@ En double-cliquant sur ces greffons vous ferez apparaître des informations sur manageVSTEffectView - VST parameter control - + - Paramètre de contrôle VST VST Sync - + VST Sync Click here if you want to synchronize all parameters with VST plugin. - + Cliquez ici si vous voulez synchroniser tous les paramètres avec le greffon VST. Automated - + Automatique Click here if you want to display automated parameters only. - + Cliquez ici si vous voulez seulement afficher les paramètres automatiques. Close - + Fermer Close VST effect knob-controller window. - + Fermer la fenêtre des boutons contrôleurs des effets VST. manageVestigeInstrumentView - VST plugin control - + - contrôle de greffon VST VST Sync - + VST Sync Click here if you want to synchronize all parameters with VST plugin. - + Cliquez ici si vous voulez synchroniser tous les paramètres avec le greffon VST. Automated - + Automatique Click here if you want to display automated parameters only. - + Cliquez ici si vous voulez seulement afficher les paramètres automatiques. Close - + Fermer Close VST plugin knob-controller window. - + Fermer la fenêtre des boutons contrôleurs des effets VST. @@ -4655,39 +4657,39 @@ En double-cliquant sur ces greffons vous ferez apparaître des informations sur opl2instrument Patch - Son + Son Op 1 Attack - + Op 1 Decay - + Op 1 Sustain - + Op 1 Release - + Op 1 Level - + Op 1 Level Scaling - + Op 1 Frequency Multiple - + Op 1 Feedback - + Op 1 Key Scaling Rate @@ -4759,15 +4761,15 @@ En double-cliquant sur ces greffons vous ferez apparaître des informations sur FM - + FM Vibrato Depth - + Profondeur de Vibrato Tremolo Depth - + Profondeur de Trémolo @@ -5269,27 +5271,27 @@ utilisez la molette de la souris pour régler le volume d'un pas Mark/unmark current semitone - + Cocher/décocher le demi-ton courant Mark current scale - + Cocher la gamme courante Mark current chord - + Cocher l'accord courant Unmark all - + Déchocher tout No scale - + Pas de gamme No chord - + Pas d'accord @@ -5405,15 +5407,15 @@ This chip was used in the Commodore 64 computer. 2-operator FM Synth - + Synthé FM à 2 opérateurs Filter for importing Hydrogen files into LMMS - + Filtre pour importer des fichiers Hydrogen dans LMMS LMMS port of sfxr - + Port LMMS de sfxr @@ -5712,35 +5714,35 @@ Latence : %2 ms One instrument track window mode - + Mode fenêtre une piste d'instrument Compact track buttons - + Boutons de piste compacte Sync VST plugins to host playback - + Sync les greffons VST à la lecture de l'hôte Enable note labels in piano roll - + Activer les étiquettes de note dans le piano virtuel Enable waveform display by default - + Activer l'affichage de forme d'onde par défaut Smooth scroll in Song Editor - + Déplacement fluide dans l'Editeur de Chanson Enable auto save feature - + Activer la fonction de sauvegarde automatique Show playback cursor in AudioFileProcessor - + Afficher le curseur de lecture dans AudioFileProcessor @@ -5877,7 +5879,7 @@ Latence : %2 ms sfxrInstrument Wave Form - + Forme d'Onde @@ -6106,11 +6108,11 @@ Latence : %2 ms Hydrogen projects - + Projets Hydrogen Select directory for writing exported tracks... - + Sélectionnez un répertoire pour écrire les pistes exportées... @@ -6231,7 +6233,7 @@ Veuillez vérifier que vous avez les droits en lecture pour ce fichier et le ré Could not open %1 for writing. You probably are not permitted to write to this file. Please make sure you have write-access to the file and try again. - + Ne peux pas ouvrir %1 en écriture. Vous n'avez probablement pas les droits pour écrire dans ce fichier. Assurez vous que vous avez les droits d'accès en écriture pour ce fichier et essayez à nouveau. @@ -6344,11 +6346,11 @@ Veuillez vérifier que vous avez les droits en lecture pour ce fichier et le ré Press <Ctrl> to disable magnetic loop points. - + Appuyez sur <Ctrl> pour désactiver les marqueur magnétiques de jeu en boucle. Hold <Shift> to move the begin loop point; Press <Ctrl> to disable magnetic loop points. - + Maintenez <Shift> pour déplacer le marqueur de début de jeu en boucle. Appuyez sur <Ctrl> pour désactiver les marqueurs magnétiques de jeu en boucle. diff --git a/data/nsis_branding.bmp b/data/nsis_branding.bmp index 901497e2c..a7e75e3c1 100644 Binary files a/data/nsis_branding.bmp and b/data/nsis_branding.bmp differ diff --git a/data/themes/default/fader_background.png b/data/themes/default/fader_background.png index 2c0d0dd49..682ff4c92 100644 Binary files a/data/themes/default/fader_background.png and b/data/themes/default/fader_background.png differ diff --git a/data/themes/default/help.png b/data/themes/default/help.png index 86b64075f..f38f9a76b 100644 Binary files a/data/themes/default/help.png and b/data/themes/default/help.png differ diff --git a/data/themes/default/mixer_send_off.png b/data/themes/default/mixer_send_off.png index 0adafe296..1be1ad54f 100644 Binary files a/data/themes/default/mixer_send_off.png and b/data/themes/default/mixer_send_off.png differ diff --git a/data/themes/default/mixer_send_on.png b/data/themes/default/mixer_send_on.png index e4b865587..15c8fac44 100644 Binary files a/data/themes/default/mixer_send_on.png and b/data/themes/default/mixer_send_on.png differ diff --git a/data/themes/default/new_channel.png b/data/themes/default/new_channel.png new file mode 100644 index 000000000..8a27695df Binary files /dev/null and b/data/themes/default/new_channel.png differ diff --git a/data/themes/default/random_wave_active.png b/data/themes/default/random_wave_active.png index 38b089c63..b65a9a0c3 100644 Binary files a/data/themes/default/random_wave_active.png and b/data/themes/default/random_wave_active.png differ diff --git a/data/themes/default/random_wave_inactive.png b/data/themes/default/random_wave_inactive.png index 9a35c9d16..47184549a 100644 Binary files a/data/themes/default/random_wave_inactive.png and b/data/themes/default/random_wave_inactive.png differ diff --git a/data/themes/default/soundfont_file.png b/data/themes/default/soundfont_file.png index e5fb2a2cc..774c82498 100644 Binary files a/data/themes/default/soundfont_file.png and b/data/themes/default/soundfont_file.png differ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index d5c973e87..0ee1b8427 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -1,7 +1,9 @@ /******************** * LMMS style sheet * ********************/ -QLabel { + +/* most foreground text items */ +QLabel, QTreeWidget, QListWidget, QGroupBox { color: #e0e0e0; } @@ -15,6 +17,18 @@ QMdiArea { AutomationEditor { background-color: rgb(0, 0, 0); + color: #e0e0e0; + qproperty-vertexColor: #ff77af; + qproperty-gridColor: #808080; + + qproperty-graphColor: qlineargradient(spread:reflect, + x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(153, 175, 255, 250), stop:1 rgba(153, 175, 255, 100)); + /*#99afff;*/ + qproperty-scaleColor: qlineargradient(spread:reflect, + x1:0, y1:0.5, x2:1, y2:0.5, + stop:0 #333, stop:1 #202020); + /*rgb( 32, 32, 32 );*/ } /* text box */ @@ -95,6 +109,10 @@ QMenu::indicator:selected { PianoRoll { background-color: rgb(0, 0, 0); + qproperty-gridColor: rgb( 128, 128, 128 ); + qproperty-noteModeColor: rgb( 255, 255, 255 ); + qproperty-noteColor: rgb( 119, 199, 216 ); + qproperty-barColor: #4afd85; } /* main toolbar oscilloscope - can have transparent bg now */ @@ -250,13 +268,10 @@ nStateButton { /* track background colors */ trackContentWidget { - qproperty-darkerColor1: rgb( 50, 50, 50 ); - qproperty-darkerColor2: rgb( 20, 20, 20 ); - qproperty-darkerColor3: rgb( 15, 15, 15 ); - qproperty-lighterColor1: rgb( 50, 50, 50 ); - qproperty-lighterColor2: rgb( 40, 40, 40 ); - qproperty-lighterColor3: rgb( 30, 30, 30 ); - qproperty-gradMidPoint: 0.33; + qproperty-darkerColor: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 rgb( 50, 50, 50 ), stop:0.33 rgb( 20, 20, 20 ), stop:1 rgb( 15, 15, 15 ) ); + qproperty-lighterColor: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 rgb( 50, 50, 50 ), stop:0.33 rgb( 40, 40, 40 ), stop:1 rgb( 30, 30, 30 ) ); } @@ -469,6 +484,19 @@ FxMixerView QPushButton, EffectRackView QPushButton, ControllerRackView QPushBut font-size: 10px; } +FxLine { + background: #5b6571; + color: #e0e0e0; + qproperty-backgroundActive: qlineargradient(spread:reflect, x1:0, y1:0, x2:1, y2:0, + stop:0 #7b838d, stop:1 #6b7581 ); +} + +/* persistent peak markers for fx peak meters */ +fader { + qproperty-peakGreen: rgb( 74, 253, 133); + qproperty-peakRed: rgb( 255, 100, 100); +} + timeLine { font-size: 8px; } @@ -507,6 +535,7 @@ AutomationPatternView { /* bb-pattern */ bbTCOView { + color: rgb( 128, 182, 175 ); /* default colour for bb-tracks, used when the colour hasn't been defined by the user */ qproperty-textColor: rgb( 255, 255, 255 ); } diff --git a/data/themes/default/vst_plugin_file.png b/data/themes/default/vst_plugin_file.png index 3a9804d23..caca1e4c5 100644 Binary files a/data/themes/default/vst_plugin_file.png and b/data/themes/default/vst_plugin_file.png differ diff --git a/data/themes/default/whatsthis.png b/data/themes/default/whatsthis.png index 55cc0c9b7..cad033f4d 100644 Binary files a/data/themes/default/whatsthis.png and b/data/themes/default/whatsthis.png differ diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 9ff61bf25..5256cf72a 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -1,9 +1,9 @@ /* * AutomationEditor.h - declaration of class AutomationEditor which is a window - * where you can edit dynamic values in an easy way + * where you can edit dynamic values in an easy way * * Copyright (c) 2006-2008 Javier Serrano Polo - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -23,8 +23,8 @@ * */ -#ifndef _AUTOMATION_EDITOR_H -#define _AUTOMATION_EDITOR_H +#ifndef AUTOMATION_EDITOR_H +#define AUTOMATION_EDITOR_H #include #include @@ -50,6 +50,10 @@ class toolButton; class AutomationEditor : public QWidget, public JournallingObject { Q_OBJECT + Q_PROPERTY( QColor gridColor READ gridColor WRITE setGridColor ) + Q_PROPERTY( QColor vertexColor READ vertexColor WRITE setVertexColor ) + Q_PROPERTY( QBrush scaleColor READ scaleColor WRITE setScaleColor ) + Q_PROPERTY( QBrush graphColor READ graphColor WRITE setGraphColor ) public: void setCurrentPattern( AutomationPattern * _new_pattern ); @@ -75,6 +79,15 @@ public: void setPauseIcon( bool pause ); + // qproperty access methods + QColor gridColor() const; + QBrush graphColor() const; + QColor vertexColor() const; + QBrush scaleColor() const; + void setGridColor( const QColor & c ); + void setGraphColor( const QBrush & c ); + void setVertexColor( const QColor & c ); + void setScaleColor( const QBrush & c ); public slots: void update(); @@ -252,7 +265,10 @@ private: void drawAutomationPoint( QPainter & p, timeMap::iterator it ); bool inBBEditor(); - + QColor m_gridColor; + QBrush m_graphColor; + QColor m_vertexColor; + QBrush m_scaleColor; friend class engine; diff --git a/include/FxLine.h b/include/FxLine.h index 5ee4d2ec2..2445e2aac 100644 --- a/include/FxLine.h +++ b/include/FxLine.h @@ -40,6 +40,7 @@ class FxLine : public QWidget { Q_OBJECT public: + Q_PROPERTY( QBrush backgroundActive READ backgroundActive WRITE setBackgroundActive ) FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex); ~FxLine(); @@ -54,10 +55,16 @@ public: knob * m_sendKnob; SendButtonIndicator * m_sendBtn; + QBrush backgroundActive() const; + void setBackgroundActive( const QBrush & c ); + + static const int FxLineHeight; + private: FxMixerView * m_mv; LcdWidget* m_lcd; int m_channelIndex; + QBrush m_backgroundActive; private slots: void renameChannel(); diff --git a/include/FxMixer.h b/include/FxMixer.h index f8a7c86f6..8136d9ed4 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -140,6 +140,7 @@ private: // make sure we have at least num channels void allocateChannelsTo(int num); + QMutex m_sendsMutex; void addChannelLeaf( int _ch, sampleFrame * _buf ); diff --git a/include/FxMixerView.h b/include/FxMixerView.h index 6449a0306..8e96797c6 100644 --- a/include/FxMixerView.h +++ b/include/FxMixerView.h @@ -22,11 +22,12 @@ * */ -#ifndef _FX_MIXER_VIEW_H -#define _FX_MIXER_VIEW_H +#ifndef FX_MIXER_VIEW_H +#define FX_MIXER_VIEW_H #include #include +#include #include #include "FxLine.h" @@ -54,6 +55,7 @@ public: FxLine * m_fxLine; pixmapButton * m_muteBtn; fader * m_fader; + EffectRackView * m_rackView; }; @@ -94,7 +96,7 @@ public: // make sure the display syncs up with the fx mixer. // useful for loading projects void refreshDisplay(); - + private slots: void updateFaders(); void addNewChannel(); @@ -108,9 +110,12 @@ private: QScrollArea * channelArea; QHBoxLayout * chLayout; QWidget * m_channelAreaWidget; - EffectRackView * m_rackView; + QStackedLayout * m_racksLayout; + QWidget * m_racksWidget; void updateMaxChannelSelector(); + + friend class FxChannelView; } ; #endif diff --git a/include/Instrument.h b/include/Instrument.h index 987d1429f..88c8e9a19 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -23,8 +23,8 @@ * */ -#ifndef _INSTRUMENT_H -#define _INSTRUMENT_H +#ifndef INSTRUMENT_H +#define INSTRUMENT_H #include @@ -101,7 +101,7 @@ public: // sub-classes can re-implement this for receiving all incoming // MIDI-events - inline virtual bool handleMidiEvent( const MidiEvent&, const MidiTime& = MidiTime() ) + inline virtual bool handleMidiEvent( const MidiEvent&, const MidiTime& = MidiTime(), f_cnt_t offset = 0 ) { return true; } @@ -119,13 +119,13 @@ public: virtual bool isFromTrack( const track * _track ) const; - -protected: inline InstrumentTrack * instrumentTrack() const { return m_instrumentTrack; } + +protected: // instruments may use this to apply a soft fade out at the end of // notes - method does this only if really less or equal // desiredReleaseFrames() frames are left diff --git a/include/InstrumentPlayHandle.h b/include/InstrumentPlayHandle.h index cf472db9e..1e1b7d5da 100644 --- a/include/InstrumentPlayHandle.h +++ b/include/InstrumentPlayHandle.h @@ -22,11 +22,12 @@ * */ -#ifndef _INSTRUMENT_PLAY_HANDLE_H -#define _INSTRUMENT_PLAY_HANDLE_H +#ifndef INSTRUMENT_PLAY_HANDLE_H +#define INSTRUMENT_PLAY_HANDLE_H #include "PlayHandle.h" #include "Instrument.h" +#include "NotePlayHandle.h" class InstrumentPlayHandle : public PlayHandle @@ -45,6 +46,32 @@ public: virtual void play( sampleFrame * _working_buffer ) { + // if the instrument is midi-based, we can safely render right away + if( m_instrument->flags() & Instrument::IsMidiBased ) + { + m_instrument->play( _working_buffer ); + return; + } + + // if not, we need to ensure that all our nph's have been processed first + ConstNotePlayHandleList nphv = NotePlayHandle::nphsOfInstrumentTrack( m_instrument->instrumentTrack(), true ); + + bool nphsLeft; + do + { + nphsLeft = false; + foreach( const NotePlayHandle * cnph, nphv ) + { + NotePlayHandle * nph = const_cast( cnph ); + if( nph->state() != ThreadableJob::Done && ! nph->isFinished() ) + { + nphsLeft = true; + nph->process(); + } + } + } + while( nphsLeft ); + m_instrument->play( _working_buffer ); } diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 6f9a0c6cf..ea10447c5 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -23,8 +23,8 @@ * */ -#ifndef _INSTRUMENT_TRACK_H -#define _INSTRUMENT_TRACK_H +#ifndef INSTRUMENT_TRACK_H +#define INSTRUMENT_TRACK_H #include "AudioPort.h" #include "InstrumentFunctions.h" @@ -71,10 +71,10 @@ public: MidiEvent applyMasterKey( const MidiEvent& event ); - virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); - virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); + virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ); + virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ); // silence all running notes played by this track - void silenceAllNotes(); + void silenceAllNotes( bool removeIPH = false ); bool isSustainPedalPressed() const { @@ -160,6 +160,8 @@ public: { return &m_baseNoteModel; } + + int baseNote() const; Piano *pianoModel() { diff --git a/include/MidiController.h b/include/MidiController.h index cb0fb6b88..5d28c8e43 100644 --- a/include/MidiController.h +++ b/include/MidiController.h @@ -44,10 +44,10 @@ public: virtual ~MidiController(); virtual void processInEvent( const MidiEvent & _me, - const MidiTime & _time ); + const MidiTime & _time, f_cnt_t offset = 0 ); virtual void processOutEvent( const MidiEvent& _me, - const MidiTime & _time) + const MidiTime & _time, f_cnt_t offset = 0 ) { // No output yet } diff --git a/include/MidiEventProcessor.h b/include/MidiEventProcessor.h index dafcfb6cd..0ca6ce59e 100644 --- a/include/MidiEventProcessor.h +++ b/include/MidiEventProcessor.h @@ -22,8 +22,8 @@ * */ -#ifndef _MIDI_EVENT_PROCESSOR_H -#define _MIDI_EVENT_PROCESSOR_H +#ifndef MIDI_EVENT_PROCESSOR_H +#define MIDI_EVENT_PROCESSOR_H #include "MidiEvent.h" #include "MidiTime.h" @@ -42,8 +42,8 @@ public: } // to be implemented by inheriting classes - virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ) = 0; - virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ) = 0; + virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) = 0; + virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) = 0; } ; diff --git a/include/Mixer.h b/include/Mixer.h index 9a20cae5a..7007e1801 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -229,7 +229,7 @@ public: return m_playHandles; } - void removePlayHandles( track * _track ); + void removePlayHandles( track * _track, bool removeIPHs = true ); bool hasNotePlayHandles(); diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h index d2a5170b7..c564b1fc8 100644 --- a/include/NotePlayHandle.h +++ b/include/NotePlayHandle.h @@ -94,7 +94,7 @@ public: /*! Returns whether playback of note is finished and thus handle can be deleted */ virtual bool isFinished() const { - return m_released && framesLeft() <= 0; + return m_released && framesLeft() <= 0 && m_scheduledNoteOff < 0; } /*! Returns number of frames left for playback */ @@ -264,6 +264,7 @@ private: // played after release f_cnt_t m_releaseFramesDone; // number of frames done after // release of note + f_cnt_t m_scheduledNoteOff; // variable for scheduling noteoff at next period NotePlayHandleList m_subNotes; // used for chords and arpeggios volatile bool m_released; // indicates whether note is released bool m_hasParent; diff --git a/include/PianoRoll.h b/include/PianoRoll.h index ea6758214..157f3b051 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -53,6 +53,10 @@ class toolButton; class PianoRoll : public QWidget, public SerializingObject { Q_OBJECT + Q_PROPERTY( QColor gridColor READ gridColor WRITE setGridColor ) + Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor ) + Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor ) + Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor ) public: /*! \brief Resets settings to default when e.g. creating a new project */ void reset(); @@ -93,7 +97,16 @@ public: } void setPauseIcon( bool pause ); - + + // qproperty acces functions + QColor gridColor() const; + void setGridColor( const QColor & _c ); + QColor noteModeColor() const; + void setNoteModeColor( const QColor & _c ); + QColor noteColor() const; + void setNoteColor( const QColor & _c ); + QColor barColor() const; + void setBarColor( const QColor & _c ); protected: virtual void closeEvent( QCloseEvent * _ce ); @@ -110,7 +123,7 @@ protected: int getKey( int _y ) const; static inline void drawNoteRect( QPainter & _p, int _x, int _y, - int _width, note * _n ); + int _width, note * _n, const QColor & noteCol ); void removeSelection(); void selectAll(); void getSelectedNotes( NoteVector & _selected_notes ); @@ -352,6 +365,11 @@ private: friend class engine; + // qproperty fields + QColor m_gridColor; + QColor m_noteModeColor; + QColor m_noteColor; + QColor m_barColor; signals: void positionChanged( const MidiTime & ); diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index edf09efbe..40eb78632 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -52,7 +52,7 @@ #include #endif -#include +#include #if QT_VERSION >= 0x040400 #include @@ -75,7 +75,7 @@ #ifdef USE_QT_SHMEM -#include +#include #if QT_VERSION >= 0x040400 #include diff --git a/include/SendButtonIndicator.h b/include/SendButtonIndicator.h index 2b0819791..8615bc392 100644 --- a/include/SendButtonIndicator.h +++ b/include/SendButtonIndicator.h @@ -11,22 +11,23 @@ class FxLine; class FxMixerView; -class SendButtonIndicator : public QLabel { - public: - SendButtonIndicator( QWidget * _parent, FxLine * _owner, - FxMixerView * _mv); +class SendButtonIndicator : public QLabel +{ +public: + SendButtonIndicator( QWidget * _parent, FxLine * _owner, + FxMixerView * _mv); - virtual void mousePressEvent( QMouseEvent * e ); - void updateLightStatus(); + virtual void mousePressEvent( QMouseEvent * e ); + void updateLightStatus(); - private: +private: - FxLine * m_parent; - FxMixerView * m_mv; - QPixmap qpmOn; - QPixmap qpmOff; + FxLine * m_parent; + FxMixerView * m_mv; + static QPixmap * s_qpmOn; + static QPixmap * s_qpmOff; - FloatModel * getSendModel(); + FloatModel * getSendModel(); }; #endif // SENDBUTTONINDICATOR_H diff --git a/include/bb_track.h b/include/bb_track.h index f9001f61e..dac1cd5f5 100644 --- a/include/bb_track.h +++ b/include/bb_track.h @@ -39,7 +39,7 @@ class TrackContainer; class bbTCO : public trackContentObject { public: - bbTCO( track * _track, unsigned int _color = 0 ); + bbTCO( track * _track ); virtual ~bbTCO(); virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); @@ -49,13 +49,24 @@ public: return( "bbtco" ); } - inline unsigned int color() const + unsigned int color() const { - return( m_color ); + return( m_color.rgb() ); } - inline static unsigned int defaultColor() + + QColor colorObj() const { - return qRgb( 128, 182, 175 ); + return m_color; + } + + void setColor( const QColor & c ) + { + m_color = QColor( c ); + } + + void setUseStyleColor( bool b ) + { + m_useStyleColor = b; } int bbTrackIndex(); @@ -63,7 +74,8 @@ public: virtual trackContentObjectView * createView( trackView * _tv ); private: - unsigned int m_color; + QColor m_color; + bool m_useStyleColor; friend class bbTCOView; @@ -91,6 +103,7 @@ protected slots: void resetName(); void changeName(); void changeColor(); + void resetColor(); protected: @@ -144,6 +157,26 @@ public: m_disabledTracks.removeAll( _track ); } + static void setLastTCOColor( const QColor & c ) + { + if( ! s_lastTCOColor ) + { + s_lastTCOColor = new QColor( c ); + } + else + { + *s_lastTCOColor = QColor( c ); + } + } + + static void clearLastTCOColor() + { + if( s_lastTCOColor ) + { + delete s_lastTCOColor; + } + s_lastTCOColor = NULL; + } protected: inline virtual QString nodeName() const @@ -158,6 +191,7 @@ private: typedef QMap infoMap; static infoMap s_infoMap; + static QColor * s_lastTCOColor; friend class bbTrackView; diff --git a/include/fader.h b/include/fader.h index 02bc475c2..500c5e49d 100644 --- a/include/fader.h +++ b/include/fader.h @@ -45,8 +45,8 @@ */ -#ifndef _FADER_H -#define _FADER_H +#ifndef FADER_H +#define FADER_H #include #include @@ -61,6 +61,8 @@ class fader : public QWidget, public FloatModelView { Q_OBJECT public: + Q_PROPERTY( QColor peakGreen READ peakGreen WRITE setPeakGreen ) + Q_PROPERTY( QColor peakRed READ peakRed WRITE setPeakRed ) fader( FloatModel * _model, const QString & _name, QWidget * _parent ); virtual ~fader(); @@ -70,6 +72,10 @@ public: void setPeak_R( float fPeak ); float getPeak_R() { return m_fPeakValue_R; } + QColor peakGreen() const; + QColor peakRed() const; + void setPeakGreen( const QColor & c ); + void setPeakRed( const QColor & c ); private: virtual void contextMenuEvent( QContextMenuEvent * _me ); @@ -85,7 +91,7 @@ private: float fRange = m_model->maxValue() - m_model->minValue(); float realVal = m_model->value() - m_model->minValue(); - return height() - ( ( height() - m_knob.height() ) * ( realVal / fRange ) ); + return height() - ( ( height() - ( *s_knob ).height() ) * ( realVal / fRange ) ); } FloatModel * m_model; @@ -103,9 +109,9 @@ private: QTime m_lastPeakTime_L; QTime m_lastPeakTime_R; - QPixmap m_back; - QPixmap m_leds; - QPixmap m_knob; + static QPixmap * s_back; + static QPixmap * s_leds; + static QPixmap * s_knob; int m_moveStartPoint; float m_startValue; @@ -113,6 +119,8 @@ private: static textFloat * s_textFloat; void updateTextFloat(); + QColor m_peakGreen; + QColor m_peakRed; } ; diff --git a/include/track.h b/include/track.h index d07b25191..1bca67394 100644 --- a/include/track.h +++ b/include/track.h @@ -278,15 +278,8 @@ class trackContentWidget : public QWidget, public JournallingObject Q_OBJECT // qproperties for track background gradients - Q_PROPERTY( QColor darkerColor1 READ darkerColor1 WRITE setDarkerColor1 ) - Q_PROPERTY( QColor darkerColor2 READ darkerColor2 WRITE setDarkerColor2 ) - Q_PROPERTY( QColor darkerColor3 READ darkerColor3 WRITE setDarkerColor3 ) - - Q_PROPERTY( QColor lighterColor1 READ lighterColor1 WRITE setLighterColor1 ) - Q_PROPERTY( QColor lighterColor2 READ lighterColor2 WRITE setLighterColor2 ) - Q_PROPERTY( QColor lighterColor3 READ lighterColor3 WRITE setLighterColor3 ) - - Q_PROPERTY( float gradMidPoint READ gradMidPoint WRITE setGradMidPoint ) + Q_PROPERTY( QBrush darkerColor READ darkerColor WRITE setDarkerColor ) + Q_PROPERTY( QBrush lighterColor READ lighterColor WRITE setLighterColor ) public: trackContentWidget( trackView * _parent ); @@ -312,25 +305,11 @@ public: // qproperty access methods - QColor darkerColor1() const; - QColor darkerColor2() const; - QColor darkerColor3() const; + QBrush darkerColor() const; + QBrush lighterColor() const; - QColor lighterColor1() const; - QColor lighterColor2() const; - QColor lighterColor3() const; - - float gradMidPoint() const; - - void setDarkerColor1( const QColor & _c ); - void setDarkerColor2( const QColor & _c ); - void setDarkerColor3( const QColor & _c ); - - void setLighterColor1( const QColor & _c ); - void setLighterColor2( const QColor & _c ); - void setLighterColor3( const QColor & _c ); - - void setGradMidPoint( float _g ); + void setDarkerColor( const QBrush & _c ); + void setLighterColor( const QBrush & _c ); public slots: void update(); @@ -373,13 +352,8 @@ private: QPixmap m_background; // qproperty fields - QColor m_darkerColor1; - QColor m_darkerColor2; - QColor m_darkerColor3; - QColor m_lighterColor1; - QColor m_lighterColor2; - QColor m_lighterColor3; - float m_gradMidPoint; + QBrush m_darkerColor; + QBrush m_lighterColor; } ; diff --git a/plugins/LadspaEffect/swh/alias_1407.c b/plugins/LadspaEffect/swh/alias_1407.c index 444d9ed28..c3190e36c 100644 --- a/plugins/LadspaEffect/swh/alias_1407.c +++ b/plugins/LadspaEffect/swh/alias_1407.c @@ -240,7 +240,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (aliasDescriptor) { free((LADSPA_PortDescriptor *)aliasDescriptor->PortDescriptors); free((char **)aliasDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/allpass_1895.c b/plugins/LadspaEffect/swh/allpass_1895.c index 062f4e32f..8bbf534b0 100644 --- a/plugins/LadspaEffect/swh/allpass_1895.c +++ b/plugins/LadspaEffect/swh/allpass_1895.c @@ -1346,7 +1346,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (allpass_nDescriptor) { free((LADSPA_PortDescriptor *)allpass_nDescriptor->PortDescriptors); free((char **)allpass_nDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/am_pitchshift_1433.c b/plugins/LadspaEffect/swh/am_pitchshift_1433.c index adc5f3029..65130c6df 100644 --- a/plugins/LadspaEffect/swh/am_pitchshift_1433.c +++ b/plugins/LadspaEffect/swh/am_pitchshift_1433.c @@ -455,7 +455,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (amPitchshiftDescriptor) { free((LADSPA_PortDescriptor *)amPitchshiftDescriptor->PortDescriptors); free((char **)amPitchshiftDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/amp_1181.c b/plugins/LadspaEffect/swh/amp_1181.c index 2bf8dd3d8..30e870538 100644 --- a/plugins/LadspaEffect/swh/amp_1181.c +++ b/plugins/LadspaEffect/swh/amp_1181.c @@ -233,7 +233,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (ampDescriptor) { free((LADSPA_PortDescriptor *)ampDescriptor->PortDescriptors); free((char **)ampDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/bandpass_a_iir_1893.c b/plugins/LadspaEffect/swh/bandpass_a_iir_1893.c index c477a4b88..e46f06511 100644 --- a/plugins/LadspaEffect/swh/bandpass_a_iir_1893.c +++ b/plugins/LadspaEffect/swh/bandpass_a_iir_1893.c @@ -277,7 +277,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (bandpass_a_iirDescriptor) { free((LADSPA_PortDescriptor *)bandpass_a_iirDescriptor->PortDescriptors); free((char **)bandpass_a_iirDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/bandpass_iir_1892.c b/plugins/LadspaEffect/swh/bandpass_iir_1892.c index 4f160c4f0..b723b8717 100644 --- a/plugins/LadspaEffect/swh/bandpass_iir_1892.c +++ b/plugins/LadspaEffect/swh/bandpass_iir_1892.c @@ -343,7 +343,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (bandpass_iirDescriptor) { free((LADSPA_PortDescriptor *)bandpass_iirDescriptor->PortDescriptors); free((char **)bandpass_iirDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/bode_shifter_1431.c b/plugins/LadspaEffect/swh/bode_shifter_1431.c index 597864a18..4c48355c6 100644 --- a/plugins/LadspaEffect/swh/bode_shifter_1431.c +++ b/plugins/LadspaEffect/swh/bode_shifter_1431.c @@ -458,7 +458,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (bodeShifterDescriptor) { free((LADSPA_PortDescriptor *)bodeShifterDescriptor->PortDescriptors); free((char **)bodeShifterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/bode_shifter_cv_1432.c b/plugins/LadspaEffect/swh/bode_shifter_cv_1432.c index 067e17c21..41fb4f043 100644 --- a/plugins/LadspaEffect/swh/bode_shifter_cv_1432.c +++ b/plugins/LadspaEffect/swh/bode_shifter_cv_1432.c @@ -523,7 +523,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (bodeShifterCVDescriptor) { free((LADSPA_PortDescriptor *)bodeShifterCVDescriptor->PortDescriptors); free((char **)bodeShifterCVDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/butterworth_1902.c b/plugins/LadspaEffect/swh/butterworth_1902.c index 74bd6d489..0e218babe 100644 --- a/plugins/LadspaEffect/swh/butterworth_1902.c +++ b/plugins/LadspaEffect/swh/butterworth_1902.c @@ -741,7 +741,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (bwxover_iirDescriptor) { free((LADSPA_PortDescriptor *)bwxover_iirDescriptor->PortDescriptors); free((char **)bwxover_iirDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/chebstortion_1430.c b/plugins/LadspaEffect/swh/chebstortion_1430.c index baa5d9694..d7b71afa7 100644 --- a/plugins/LadspaEffect/swh/chebstortion_1430.c +++ b/plugins/LadspaEffect/swh/chebstortion_1430.c @@ -399,7 +399,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (chebstortionDescriptor) { free((LADSPA_PortDescriptor *)chebstortionDescriptor->PortDescriptors); free((char **)chebstortionDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/comb_1190.c b/plugins/LadspaEffect/swh/comb_1190.c index 7f72b8cd7..1e01570ae 100644 --- a/plugins/LadspaEffect/swh/comb_1190.c +++ b/plugins/LadspaEffect/swh/comb_1190.c @@ -340,7 +340,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (combDescriptor) { free((LADSPA_PortDescriptor *)combDescriptor->PortDescriptors); free((char **)combDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/comb_1887.c b/plugins/LadspaEffect/swh/comb_1887.c index 81a7268bd..23dc53400 100644 --- a/plugins/LadspaEffect/swh/comb_1887.c +++ b/plugins/LadspaEffect/swh/comb_1887.c @@ -1352,7 +1352,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (comb_nDescriptor) { free((LADSPA_PortDescriptor *)comb_nDescriptor->PortDescriptors); free((char **)comb_nDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/comb_splitter_1411.c b/plugins/LadspaEffect/swh/comb_splitter_1411.c index 1ffb152d7..70d78e726 100644 --- a/plugins/LadspaEffect/swh/comb_splitter_1411.c +++ b/plugins/LadspaEffect/swh/comb_splitter_1411.c @@ -341,7 +341,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (combSplitterDescriptor) { free((LADSPA_PortDescriptor *)combSplitterDescriptor->PortDescriptors); free((char **)combSplitterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/const_1909.c b/plugins/LadspaEffect/swh/const_1909.c index 3bfc221ef..31633b276 100644 --- a/plugins/LadspaEffect/swh/const_1909.c +++ b/plugins/LadspaEffect/swh/const_1909.c @@ -250,7 +250,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (constDescriptor) { free((LADSPA_PortDescriptor *)constDescriptor->PortDescriptors); free((char **)constDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/crossover_dist_1404.c b/plugins/LadspaEffect/swh/crossover_dist_1404.c index fdffacf68..7ad6c4d3b 100644 --- a/plugins/LadspaEffect/swh/crossover_dist_1404.c +++ b/plugins/LadspaEffect/swh/crossover_dist_1404.c @@ -276,7 +276,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (crossoverDistDescriptor) { free((LADSPA_PortDescriptor *)crossoverDistDescriptor->PortDescriptors); free((char **)crossoverDistDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/dc_remove_1207.c b/plugins/LadspaEffect/swh/dc_remove_1207.c index 76593f8ca..ff795118f 100644 --- a/plugins/LadspaEffect/swh/dc_remove_1207.c +++ b/plugins/LadspaEffect/swh/dc_remove_1207.c @@ -235,7 +235,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (dcRemoveDescriptor) { free((LADSPA_PortDescriptor *)dcRemoveDescriptor->PortDescriptors); free((char **)dcRemoveDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/decay_1886.c b/plugins/LadspaEffect/swh/decay_1886.c index da878478b..eab8570d3 100644 --- a/plugins/LadspaEffect/swh/decay_1886.c +++ b/plugins/LadspaEffect/swh/decay_1886.c @@ -325,7 +325,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (decayDescriptor) { free((LADSPA_PortDescriptor *)decayDescriptor->PortDescriptors); free((char **)decayDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/decimator_1202.c b/plugins/LadspaEffect/swh/decimator_1202.c index 2975605bd..6765d350e 100644 --- a/plugins/LadspaEffect/swh/decimator_1202.c +++ b/plugins/LadspaEffect/swh/decimator_1202.c @@ -335,7 +335,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (decimatorDescriptor) { free((LADSPA_PortDescriptor *)decimatorDescriptor->PortDescriptors); free((char **)decimatorDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/declip_1195.c b/plugins/LadspaEffect/swh/declip_1195.c index f25417976..bc3db16c2 100644 --- a/plugins/LadspaEffect/swh/declip_1195.c +++ b/plugins/LadspaEffect/swh/declip_1195.c @@ -235,7 +235,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (declipDescriptor) { free((LADSPA_PortDescriptor *)declipDescriptor->PortDescriptors); free((char **)declipDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/delay_1898.c b/plugins/LadspaEffect/swh/delay_1898.c index 998c1bbbd..57c8f0195 100644 --- a/plugins/LadspaEffect/swh/delay_1898.c +++ b/plugins/LadspaEffect/swh/delay_1898.c @@ -1093,7 +1093,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (delay_nDescriptor) { free((LADSPA_PortDescriptor *)delay_nDescriptor->PortDescriptors); free((char **)delay_nDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/delayorama_1402.c b/plugins/LadspaEffect/swh/delayorama_1402.c index a0cb2a861..a5d1bcce8 100644 --- a/plugins/LadspaEffect/swh/delayorama_1402.c +++ b/plugins/LadspaEffect/swh/delayorama_1402.c @@ -847,7 +847,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (delayoramaDescriptor) { free((LADSPA_PortDescriptor *)delayoramaDescriptor->PortDescriptors); free((char **)delayoramaDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/diode_1185.c b/plugins/LadspaEffect/swh/diode_1185.c index cfc2d22d4..bce602ae4 100644 --- a/plugins/LadspaEffect/swh/diode_1185.c +++ b/plugins/LadspaEffect/swh/diode_1185.c @@ -264,7 +264,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (diodeDescriptor) { free((LADSPA_PortDescriptor *)diodeDescriptor->PortDescriptors); free((char **)diodeDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/divider_1186.c b/plugins/LadspaEffect/swh/divider_1186.c index cf9fad685..6c7de0170 100644 --- a/plugins/LadspaEffect/swh/divider_1186.c +++ b/plugins/LadspaEffect/swh/divider_1186.c @@ -331,7 +331,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (dividerDescriptor) { free((LADSPA_PortDescriptor *)dividerDescriptor->PortDescriptors); free((char **)dividerDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/dj_eq_1901.c b/plugins/LadspaEffect/swh/dj_eq_1901.c index 950eedad4..a4baa9602 100644 --- a/plugins/LadspaEffect/swh/dj_eq_1901.c +++ b/plugins/LadspaEffect/swh/dj_eq_1901.c @@ -674,7 +674,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (dj_eq_monoDescriptor) { free((LADSPA_PortDescriptor *)dj_eq_monoDescriptor->PortDescriptors); free((char **)dj_eq_monoDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/dj_flanger_1438.c b/plugins/LadspaEffect/swh/dj_flanger_1438.c index b970886a9..1c7a9ce2d 100644 --- a/plugins/LadspaEffect/swh/dj_flanger_1438.c +++ b/plugins/LadspaEffect/swh/dj_flanger_1438.c @@ -472,7 +472,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (djFlangerDescriptor) { free((LADSPA_PortDescriptor *)djFlangerDescriptor->PortDescriptors); free((char **)djFlangerDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/dyson_compress_1403.c b/plugins/LadspaEffect/swh/dyson_compress_1403.c index 22cc0fa94..552edb7b0 100644 --- a/plugins/LadspaEffect/swh/dyson_compress_1403.c +++ b/plugins/LadspaEffect/swh/dyson_compress_1403.c @@ -885,7 +885,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (dysonCompressDescriptor) { free((LADSPA_PortDescriptor *)dysonCompressDescriptor->PortDescriptors); free((char **)dysonCompressDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/fad_delay_1192.c b/plugins/LadspaEffect/swh/fad_delay_1192.c index 85d0c3dee..9d4ec77b3 100644 --- a/plugins/LadspaEffect/swh/fad_delay_1192.c +++ b/plugins/LadspaEffect/swh/fad_delay_1192.c @@ -388,7 +388,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (fadDelayDescriptor) { free((LADSPA_PortDescriptor *)fadDelayDescriptor->PortDescriptors); free((char **)fadDelayDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/fast_lookahead_limiter_1913.c b/plugins/LadspaEffect/swh/fast_lookahead_limiter_1913.c index 8295e2298..8589caf3a 100644 --- a/plugins/LadspaEffect/swh/fast_lookahead_limiter_1913.c +++ b/plugins/LadspaEffect/swh/fast_lookahead_limiter_1913.c @@ -703,7 +703,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (fastLookaheadLimiterDescriptor) { free((LADSPA_PortDescriptor *)fastLookaheadLimiterDescriptor->PortDescriptors); free((char **)fastLookaheadLimiterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/flanger_1191.c b/plugins/LadspaEffect/swh/flanger_1191.c index e542316fd..e5741f2e5 100644 --- a/plugins/LadspaEffect/swh/flanger_1191.c +++ b/plugins/LadspaEffect/swh/flanger_1191.c @@ -544,7 +544,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (flangerDescriptor) { free((LADSPA_PortDescriptor *)flangerDescriptor->PortDescriptors); free((char **)flangerDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/foldover_1213.c b/plugins/LadspaEffect/swh/foldover_1213.c index 8f2ad857e..5f4884476 100644 --- a/plugins/LadspaEffect/swh/foldover_1213.c +++ b/plugins/LadspaEffect/swh/foldover_1213.c @@ -255,7 +255,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (foldoverDescriptor) { free((LADSPA_PortDescriptor *)foldoverDescriptor->PortDescriptors); free((char **)foldoverDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/foverdrive_1196.c b/plugins/LadspaEffect/swh/foverdrive_1196.c index 94306d01e..f608e3ade 100644 --- a/plugins/LadspaEffect/swh/foverdrive_1196.c +++ b/plugins/LadspaEffect/swh/foverdrive_1196.c @@ -234,7 +234,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (foverdriveDescriptor) { free((LADSPA_PortDescriptor *)foverdriveDescriptor->PortDescriptors); free((char **)foverdriveDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/freq_tracker_1418.c b/plugins/LadspaEffect/swh/freq_tracker_1418.c index 831c6de15..73a7111ea 100644 --- a/plugins/LadspaEffect/swh/freq_tracker_1418.c +++ b/plugins/LadspaEffect/swh/freq_tracker_1418.c @@ -319,7 +319,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (freqTrackerDescriptor) { free((LADSPA_PortDescriptor *)freqTrackerDescriptor->PortDescriptors); free((char **)freqTrackerDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/gate_1410.c b/plugins/LadspaEffect/swh/gate_1410.c index d6fdf7da8..71527ace2 100644 --- a/plugins/LadspaEffect/swh/gate_1410.c +++ b/plugins/LadspaEffect/swh/gate_1410.c @@ -582,7 +582,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (gateDescriptor) { free((LADSPA_PortDescriptor *)gateDescriptor->PortDescriptors); free((char **)gateDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/giant_flange_1437.c b/plugins/LadspaEffect/swh/giant_flange_1437.c index dd2031806..fd022d7b1 100644 --- a/plugins/LadspaEffect/swh/giant_flange_1437.c +++ b/plugins/LadspaEffect/swh/giant_flange_1437.c @@ -637,7 +637,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (giantFlangeDescriptor) { free((LADSPA_PortDescriptor *)giantFlangeDescriptor->PortDescriptors); free((char **)giantFlangeDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/gong_1424.c b/plugins/LadspaEffect/swh/gong_1424.c index ea2f4161d..b7e0656b2 100644 --- a/plugins/LadspaEffect/swh/gong_1424.c +++ b/plugins/LadspaEffect/swh/gong_1424.c @@ -947,7 +947,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (gongDescriptor) { free((LADSPA_PortDescriptor *)gongDescriptor->PortDescriptors); free((char **)gongDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/gong_beater_1439.c b/plugins/LadspaEffect/swh/gong_beater_1439.c index 26f967a11..b80e164d3 100644 --- a/plugins/LadspaEffect/swh/gong_beater_1439.c +++ b/plugins/LadspaEffect/swh/gong_beater_1439.c @@ -400,7 +400,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (gongBeaterDescriptor) { free((LADSPA_PortDescriptor *)gongBeaterDescriptor->PortDescriptors); free((char **)gongBeaterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/gsm_1215.c b/plugins/LadspaEffect/swh/gsm_1215.c index 279e2b1c1..55c0f2628 100644 --- a/plugins/LadspaEffect/swh/gsm_1215.c +++ b/plugins/LadspaEffect/swh/gsm_1215.c @@ -493,7 +493,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (gsmDescriptor) { free((LADSPA_PortDescriptor *)gsmDescriptor->PortDescriptors); free((char **)gsmDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/gverb_1216.c b/plugins/LadspaEffect/swh/gverb_1216.c index d7e5a9214..e9bdac87d 100644 --- a/plugins/LadspaEffect/swh/gverb_1216.c +++ b/plugins/LadspaEffect/swh/gverb_1216.c @@ -429,7 +429,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (gverbDescriptor) { free((LADSPA_PortDescriptor *)gverbDescriptor->PortDescriptors); free((char **)gverbDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/hard_limiter_1413.c b/plugins/LadspaEffect/swh/hard_limiter_1413.c index ab1ab0f62..bf41e6acd 100644 --- a/plugins/LadspaEffect/swh/hard_limiter_1413.c +++ b/plugins/LadspaEffect/swh/hard_limiter_1413.c @@ -286,7 +286,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (hardLimiterDescriptor) { free((LADSPA_PortDescriptor *)hardLimiterDescriptor->PortDescriptors); free((char **)hardLimiterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/harmonic_gen_1220.c b/plugins/LadspaEffect/swh/harmonic_gen_1220.c index 26c19630f..bbd2324c7 100644 --- a/plugins/LadspaEffect/swh/harmonic_gen_1220.c +++ b/plugins/LadspaEffect/swh/harmonic_gen_1220.c @@ -542,7 +542,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (harmonicGenDescriptor) { free((LADSPA_PortDescriptor *)harmonicGenDescriptor->PortDescriptors); free((char **)harmonicGenDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/hermes_filter_1200.c b/plugins/LadspaEffect/swh/hermes_filter_1200.c index a15d7c9e8..d313d376e 100644 --- a/plugins/LadspaEffect/swh/hermes_filter_1200.c +++ b/plugins/LadspaEffect/swh/hermes_filter_1200.c @@ -1998,7 +1998,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (hermesFilterDescriptor) { free((LADSPA_PortDescriptor *)hermesFilterDescriptor->PortDescriptors); free((char **)hermesFilterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/highpass_iir_1890.c b/plugins/LadspaEffect/swh/highpass_iir_1890.c index e0bca2a14..d00ddd159 100644 --- a/plugins/LadspaEffect/swh/highpass_iir_1890.c +++ b/plugins/LadspaEffect/swh/highpass_iir_1890.c @@ -278,7 +278,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (highpass_iirDescriptor) { free((LADSPA_PortDescriptor *)highpass_iirDescriptor->PortDescriptors); free((char **)highpass_iirDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/hilbert_1440.c b/plugins/LadspaEffect/swh/hilbert_1440.c index 4a6546b27..a52b21390 100644 --- a/plugins/LadspaEffect/swh/hilbert_1440.c +++ b/plugins/LadspaEffect/swh/hilbert_1440.c @@ -316,7 +316,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (hilbertDescriptor) { free((LADSPA_PortDescriptor *)hilbertDescriptor->PortDescriptors); free((char **)hilbertDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/imp_1199.c b/plugins/LadspaEffect/swh/imp_1199.c index 62c2deff3..ec1b35028 100644 --- a/plugins/LadspaEffect/swh/imp_1199.c +++ b/plugins/LadspaEffect/swh/imp_1199.c @@ -628,7 +628,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (impDescriptor) { free((LADSPA_PortDescriptor *)impDescriptor->PortDescriptors); free((char **)impDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/impulse_1885.c b/plugins/LadspaEffect/swh/impulse_1885.c index e4ebd2d41..cc53506b7 100644 --- a/plugins/LadspaEffect/swh/impulse_1885.c +++ b/plugins/LadspaEffect/swh/impulse_1885.c @@ -257,7 +257,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (impulse_fcDescriptor) { free((LADSPA_PortDescriptor *)impulse_fcDescriptor->PortDescriptors); free((char **)impulse_fcDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/inv_1429.c b/plugins/LadspaEffect/swh/inv_1429.c index 1a38faff6..e0a6f7715 100644 --- a/plugins/LadspaEffect/swh/inv_1429.c +++ b/plugins/LadspaEffect/swh/inv_1429.c @@ -207,7 +207,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (invDescriptor) { free((LADSPA_PortDescriptor *)invDescriptor->PortDescriptors); free((char **)invDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/karaoke_1409.c b/plugins/LadspaEffect/swh/karaoke_1409.c index 4c3091f77..9dd09c336 100644 --- a/plugins/LadspaEffect/swh/karaoke_1409.c +++ b/plugins/LadspaEffect/swh/karaoke_1409.c @@ -274,7 +274,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (karaokeDescriptor) { free((LADSPA_PortDescriptor *)karaokeDescriptor->PortDescriptors); free((char **)karaokeDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/latency_1914.c b/plugins/LadspaEffect/swh/latency_1914.c index 5744a2086..202b65baa 100644 --- a/plugins/LadspaEffect/swh/latency_1914.c +++ b/plugins/LadspaEffect/swh/latency_1914.c @@ -259,7 +259,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (artificialLatencyDescriptor) { free((LADSPA_PortDescriptor *)artificialLatencyDescriptor->PortDescriptors); free((char **)artificialLatencyDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/lcr_delay_1436.c b/plugins/LadspaEffect/swh/lcr_delay_1436.c index 5ae8db3bc..f9d4df7b6 100644 --- a/plugins/LadspaEffect/swh/lcr_delay_1436.c +++ b/plugins/LadspaEffect/swh/lcr_delay_1436.c @@ -733,7 +733,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (lcrDelayDescriptor) { free((LADSPA_PortDescriptor *)lcrDelayDescriptor->PortDescriptors); free((char **)lcrDelayDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/lowpass_iir_1891.c b/plugins/LadspaEffect/swh/lowpass_iir_1891.c index be1c806c1..a8ecb9ad4 100644 --- a/plugins/LadspaEffect/swh/lowpass_iir_1891.c +++ b/plugins/LadspaEffect/swh/lowpass_iir_1891.c @@ -280,7 +280,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (lowpass_iirDescriptor) { free((LADSPA_PortDescriptor *)lowpass_iirDescriptor->PortDescriptors); free((char **)lowpass_iirDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/ls_filter_1908.c b/plugins/LadspaEffect/swh/ls_filter_1908.c index 97c366a40..e67177bcd 100644 --- a/plugins/LadspaEffect/swh/ls_filter_1908.c +++ b/plugins/LadspaEffect/swh/ls_filter_1908.c @@ -308,7 +308,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (lsFilterDescriptor) { free((LADSPA_PortDescriptor *)lsFilterDescriptor->PortDescriptors); free((char **)lsFilterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/matrix_ms_st_1421.c b/plugins/LadspaEffect/swh/matrix_ms_st_1421.c index 2fddf9311..e1c81d8d2 100644 --- a/plugins/LadspaEffect/swh/matrix_ms_st_1421.c +++ b/plugins/LadspaEffect/swh/matrix_ms_st_1421.c @@ -266,7 +266,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (matrixMSStDescriptor) { free((LADSPA_PortDescriptor *)matrixMSStDescriptor->PortDescriptors); free((char **)matrixMSStDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/matrix_spatialiser_1422.c b/plugins/LadspaEffect/swh/matrix_spatialiser_1422.c index 7812ddfff..74b3f1cfd 100644 --- a/plugins/LadspaEffect/swh/matrix_spatialiser_1422.c +++ b/plugins/LadspaEffect/swh/matrix_spatialiser_1422.c @@ -424,7 +424,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (matrixSpatialiserDescriptor) { free((LADSPA_PortDescriptor *)matrixSpatialiserDescriptor->PortDescriptors); free((char **)matrixSpatialiserDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/matrix_st_ms_1420.c b/plugins/LadspaEffect/swh/matrix_st_ms_1420.c index 8c97c7cb9..0d18f98b2 100644 --- a/plugins/LadspaEffect/swh/matrix_st_ms_1420.c +++ b/plugins/LadspaEffect/swh/matrix_st_ms_1420.c @@ -245,7 +245,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (matrixStMSDescriptor) { free((LADSPA_PortDescriptor *)matrixStMSDescriptor->PortDescriptors); free((char **)matrixStMSDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/mbeq_1197.c b/plugins/LadspaEffect/swh/mbeq_1197.c index a9bea01fe..e1c88d33e 100644 --- a/plugins/LadspaEffect/swh/mbeq_1197.c +++ b/plugins/LadspaEffect/swh/mbeq_1197.c @@ -885,7 +885,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (mbeqDescriptor) { free((LADSPA_PortDescriptor *)mbeqDescriptor->PortDescriptors); free((char **)mbeqDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/mod_delay_1419.c b/plugins/LadspaEffect/swh/mod_delay_1419.c index b27a7612e..30ae3e553 100644 --- a/plugins/LadspaEffect/swh/mod_delay_1419.c +++ b/plugins/LadspaEffect/swh/mod_delay_1419.c @@ -318,7 +318,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (modDelayDescriptor) { free((LADSPA_PortDescriptor *)modDelayDescriptor->PortDescriptors); free((char **)modDelayDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/multivoice_chorus_1201.c b/plugins/LadspaEffect/swh/multivoice_chorus_1201.c index 5f69bf04e..24c100dd4 100644 --- a/plugins/LadspaEffect/swh/multivoice_chorus_1201.c +++ b/plugins/LadspaEffect/swh/multivoice_chorus_1201.c @@ -656,7 +656,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (multivoiceChorusDescriptor) { free((LADSPA_PortDescriptor *)multivoiceChorusDescriptor->PortDescriptors); free((char **)multivoiceChorusDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/notch_iir_1894.c b/plugins/LadspaEffect/swh/notch_iir_1894.c index 396e44fa2..69009967b 100644 --- a/plugins/LadspaEffect/swh/notch_iir_1894.c +++ b/plugins/LadspaEffect/swh/notch_iir_1894.c @@ -343,7 +343,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (notch_iirDescriptor) { free((LADSPA_PortDescriptor *)notch_iirDescriptor->PortDescriptors); free((char **)notch_iirDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/phasers_1217.c b/plugins/LadspaEffect/swh/phasers_1217.c index 14673e360..da50e11e8 100644 --- a/plugins/LadspaEffect/swh/phasers_1217.c +++ b/plugins/LadspaEffect/swh/phasers_1217.c @@ -1377,7 +1377,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (lfoPhaserDescriptor) { free((LADSPA_PortDescriptor *)lfoPhaserDescriptor->PortDescriptors); free((char **)lfoPhaserDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/pitch_scale_1193.c b/plugins/LadspaEffect/swh/pitch_scale_1193.c index c811a84bc..ce3f81163 100644 --- a/plugins/LadspaEffect/swh/pitch_scale_1193.c +++ b/plugins/LadspaEffect/swh/pitch_scale_1193.c @@ -327,7 +327,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (pitchScaleDescriptor) { free((LADSPA_PortDescriptor *)pitchScaleDescriptor->PortDescriptors); free((char **)pitchScaleDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/pitch_scale_1194.c b/plugins/LadspaEffect/swh/pitch_scale_1194.c index 747c16ea6..62d6be129 100644 --- a/plugins/LadspaEffect/swh/pitch_scale_1194.c +++ b/plugins/LadspaEffect/swh/pitch_scale_1194.c @@ -311,7 +311,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (pitchScaleHQDescriptor) { free((LADSPA_PortDescriptor *)pitchScaleHQDescriptor->PortDescriptors); free((char **)pitchScaleHQDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/plate_1423.c b/plugins/LadspaEffect/swh/plate_1423.c index 0127bb6f0..f73e8f138 100644 --- a/plugins/LadspaEffect/swh/plate_1423.c +++ b/plugins/LadspaEffect/swh/plate_1423.c @@ -401,7 +401,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (plateDescriptor) { free((LADSPA_PortDescriptor *)plateDescriptor->PortDescriptors); free((char **)plateDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/pointer_cast_1910.c b/plugins/LadspaEffect/swh/pointer_cast_1910.c index 464fb1b64..7465bd145 100644 --- a/plugins/LadspaEffect/swh/pointer_cast_1910.c +++ b/plugins/LadspaEffect/swh/pointer_cast_1910.c @@ -310,7 +310,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (pointerCastDistortionDescriptor) { free((LADSPA_PortDescriptor *)pointerCastDistortionDescriptor->PortDescriptors); free((char **)pointerCastDistortionDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/rate_shifter_1417.c b/plugins/LadspaEffect/swh/rate_shifter_1417.c index 750f82972..21e03cbc3 100644 --- a/plugins/LadspaEffect/swh/rate_shifter_1417.c +++ b/plugins/LadspaEffect/swh/rate_shifter_1417.c @@ -314,7 +314,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (rateShifterDescriptor) { free((LADSPA_PortDescriptor *)rateShifterDescriptor->PortDescriptors); free((char **)rateShifterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/retro_flange_1208.c b/plugins/LadspaEffect/swh/retro_flange_1208.c index 5df5cc338..c96dff58e 100644 --- a/plugins/LadspaEffect/swh/retro_flange_1208.c +++ b/plugins/LadspaEffect/swh/retro_flange_1208.c @@ -581,7 +581,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (retroFlangeDescriptor) { free((LADSPA_PortDescriptor *)retroFlangeDescriptor->PortDescriptors); free((char **)retroFlangeDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/revdelay_1605.c b/plugins/LadspaEffect/swh/revdelay_1605.c index 1b014b902..e714ee5e2 100644 --- a/plugins/LadspaEffect/swh/revdelay_1605.c +++ b/plugins/LadspaEffect/swh/revdelay_1605.c @@ -540,7 +540,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (revdelayDescriptor) { free((LADSPA_PortDescriptor *)revdelayDescriptor->PortDescriptors); free((char **)revdelayDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/ringmod_1188.c b/plugins/LadspaEffect/swh/ringmod_1188.c index 5c4c16b39..393ad86b2 100644 --- a/plugins/LadspaEffect/swh/ringmod_1188.c +++ b/plugins/LadspaEffect/swh/ringmod_1188.c @@ -632,7 +632,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (ringmod_2i1oDescriptor) { free((LADSPA_PortDescriptor *)ringmod_2i1oDescriptor->PortDescriptors); free((char **)ringmod_2i1oDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/satan_maximiser_1408.c b/plugins/LadspaEffect/swh/satan_maximiser_1408.c index 913711574..acf99ac3c 100644 --- a/plugins/LadspaEffect/swh/satan_maximiser_1408.c +++ b/plugins/LadspaEffect/swh/satan_maximiser_1408.c @@ -344,7 +344,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (satanMaximiserDescriptor) { free((LADSPA_PortDescriptor *)satanMaximiserDescriptor->PortDescriptors); free((char **)satanMaximiserDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sc1_1425.c b/plugins/LadspaEffect/swh/sc1_1425.c index 8a5e143ef..4b2ce94f1 100644 --- a/plugins/LadspaEffect/swh/sc1_1425.c +++ b/plugins/LadspaEffect/swh/sc1_1425.c @@ -473,7 +473,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sc1Descriptor) { free((LADSPA_PortDescriptor *)sc1Descriptor->PortDescriptors); free((char **)sc1Descriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sc2_1426.c b/plugins/LadspaEffect/swh/sc2_1426.c index a95abd777..dcad834bc 100644 --- a/plugins/LadspaEffect/swh/sc2_1426.c +++ b/plugins/LadspaEffect/swh/sc2_1426.c @@ -491,7 +491,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sc2Descriptor) { free((LADSPA_PortDescriptor *)sc2Descriptor->PortDescriptors); free((char **)sc2Descriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sc3_1427.c b/plugins/LadspaEffect/swh/sc3_1427.c index e89609bf5..27edde705 100644 --- a/plugins/LadspaEffect/swh/sc3_1427.c +++ b/plugins/LadspaEffect/swh/sc3_1427.c @@ -562,7 +562,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sc3Descriptor) { free((LADSPA_PortDescriptor *)sc3Descriptor->PortDescriptors); free((char **)sc3Descriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sc4_1882.c b/plugins/LadspaEffect/swh/sc4_1882.c index 5ac873302..3ff1fd002 100644 --- a/plugins/LadspaEffect/swh/sc4_1882.c +++ b/plugins/LadspaEffect/swh/sc4_1882.c @@ -618,7 +618,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sc4Descriptor) { free((LADSPA_PortDescriptor *)sc4Descriptor->PortDescriptors); free((char **)sc4Descriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sc4m_1916.c b/plugins/LadspaEffect/swh/sc4m_1916.c index ee9a952a5..4d92a213e 100644 --- a/plugins/LadspaEffect/swh/sc4m_1916.c +++ b/plugins/LadspaEffect/swh/sc4m_1916.c @@ -568,7 +568,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sc4mDescriptor) { free((LADSPA_PortDescriptor *)sc4mDescriptor->PortDescriptors); free((char **)sc4mDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/se4_1883.c b/plugins/LadspaEffect/swh/se4_1883.c index 585d474e0..2c1ddce6e 100644 --- a/plugins/LadspaEffect/swh/se4_1883.c +++ b/plugins/LadspaEffect/swh/se4_1883.c @@ -614,7 +614,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (se4Descriptor) { free((LADSPA_PortDescriptor *)se4Descriptor->PortDescriptors); free((char **)se4Descriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/shaper_1187.c b/plugins/LadspaEffect/swh/shaper_1187.c index f036a57fb..89fc699b4 100644 --- a/plugins/LadspaEffect/swh/shaper_1187.c +++ b/plugins/LadspaEffect/swh/shaper_1187.c @@ -260,7 +260,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (shaperDescriptor) { free((LADSPA_PortDescriptor *)shaperDescriptor->PortDescriptors); free((char **)shaperDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sifter_1210.c b/plugins/LadspaEffect/swh/sifter_1210.c index 8adcdbd27..1c05217b8 100644 --- a/plugins/LadspaEffect/swh/sifter_1210.c +++ b/plugins/LadspaEffect/swh/sifter_1210.c @@ -438,7 +438,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sifterDescriptor) { free((LADSPA_PortDescriptor *)sifterDescriptor->PortDescriptors); free((char **)sifterDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sin_cos_1881.c b/plugins/LadspaEffect/swh/sin_cos_1881.c index 500b6808b..d12977141 100644 --- a/plugins/LadspaEffect/swh/sin_cos_1881.c +++ b/plugins/LadspaEffect/swh/sin_cos_1881.c @@ -296,7 +296,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sinCosDescriptor) { free((LADSPA_PortDescriptor *)sinCosDescriptor->PortDescriptors); free((char **)sinCosDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/single_para_1203.c b/plugins/LadspaEffect/swh/single_para_1203.c index d189c2682..ef322fe36 100644 --- a/plugins/LadspaEffect/swh/single_para_1203.c +++ b/plugins/LadspaEffect/swh/single_para_1203.c @@ -312,7 +312,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (singleParaDescriptor) { free((LADSPA_PortDescriptor *)singleParaDescriptor->PortDescriptors); free((char **)singleParaDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/sinus_wavewrapper_1198.c b/plugins/LadspaEffect/swh/sinus_wavewrapper_1198.c index 02be6d68a..d8dc7b2cc 100644 --- a/plugins/LadspaEffect/swh/sinus_wavewrapper_1198.c +++ b/plugins/LadspaEffect/swh/sinus_wavewrapper_1198.c @@ -244,7 +244,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (sinusWavewrapperDescriptor) { free((LADSPA_PortDescriptor *)sinusWavewrapperDescriptor->PortDescriptors); free((char **)sinusWavewrapperDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/smooth_decimate_1414.c b/plugins/LadspaEffect/swh/smooth_decimate_1414.c index 532b84b0a..c63e6ce6f 100644 --- a/plugins/LadspaEffect/swh/smooth_decimate_1414.c +++ b/plugins/LadspaEffect/swh/smooth_decimate_1414.c @@ -329,7 +329,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (smoothDecimateDescriptor) { free((LADSPA_PortDescriptor *)smoothDecimateDescriptor->PortDescriptors); free((char **)smoothDecimateDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/split_1406.c b/plugins/LadspaEffect/swh/split_1406.c index 48c9f7117..2fa1bee7b 100644 --- a/plugins/LadspaEffect/swh/split_1406.c +++ b/plugins/LadspaEffect/swh/split_1406.c @@ -240,7 +240,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (splitDescriptor) { free((LADSPA_PortDescriptor *)splitDescriptor->PortDescriptors); free((char **)splitDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/step_muxer_1212.c b/plugins/LadspaEffect/swh/step_muxer_1212.c index 94dc51e73..9c27b84e1 100644 --- a/plugins/LadspaEffect/swh/step_muxer_1212.c +++ b/plugins/LadspaEffect/swh/step_muxer_1212.c @@ -532,7 +532,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (stepMuxerDescriptor) { free((LADSPA_PortDescriptor *)stepMuxerDescriptor->PortDescriptors); free((char **)stepMuxerDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/surround_encoder_1401.c b/plugins/LadspaEffect/swh/surround_encoder_1401.c index c0f970e7e..d4b6ace01 100644 --- a/plugins/LadspaEffect/swh/surround_encoder_1401.c +++ b/plugins/LadspaEffect/swh/surround_encoder_1401.c @@ -414,7 +414,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (surroundEncoderDescriptor) { free((LADSPA_PortDescriptor *)surroundEncoderDescriptor->PortDescriptors); free((char **)surroundEncoderDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/svf_1214.c b/plugins/LadspaEffect/swh/svf_1214.c index 24117d757..c1a74aa0b 100644 --- a/plugins/LadspaEffect/swh/svf_1214.c +++ b/plugins/LadspaEffect/swh/svf_1214.c @@ -408,7 +408,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (svfDescriptor) { free((LADSPA_PortDescriptor *)svfDescriptor->PortDescriptors); free((char **)svfDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/tape_delay_1211.c b/plugins/LadspaEffect/swh/tape_delay_1211.c index 5338dadfa..0b680ccf2 100644 --- a/plugins/LadspaEffect/swh/tape_delay_1211.c +++ b/plugins/LadspaEffect/swh/tape_delay_1211.c @@ -645,7 +645,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (tapeDelayDescriptor) { free((LADSPA_PortDescriptor *)tapeDelayDescriptor->PortDescriptors); free((char **)tapeDelayDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/transient_1206.c b/plugins/LadspaEffect/swh/transient_1206.c index 6e63fd526..782593e5e 100644 --- a/plugins/LadspaEffect/swh/transient_1206.c +++ b/plugins/LadspaEffect/swh/transient_1206.c @@ -465,7 +465,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (transientDescriptor) { free((LADSPA_PortDescriptor *)transientDescriptor->PortDescriptors); free((char **)transientDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/triple_para_1204.c b/plugins/LadspaEffect/swh/triple_para_1204.c index 8d3e63f3f..ef7a26b7c 100644 --- a/plugins/LadspaEffect/swh/triple_para_1204.c +++ b/plugins/LadspaEffect/swh/triple_para_1204.c @@ -593,7 +593,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (tripleParaDescriptor) { free((LADSPA_PortDescriptor *)tripleParaDescriptor->PortDescriptors); free((char **)tripleParaDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/valve_1209.c b/plugins/LadspaEffect/swh/valve_1209.c index 2ab03dd17..8f10428a0 100644 --- a/plugins/LadspaEffect/swh/valve_1209.c +++ b/plugins/LadspaEffect/swh/valve_1209.c @@ -332,7 +332,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (valveDescriptor) { free((LADSPA_PortDescriptor *)valveDescriptor->PortDescriptors); free((char **)valveDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/valve_rect_1405.c b/plugins/LadspaEffect/swh/valve_rect_1405.c index 9a87af2fa..a4191a4fd 100644 --- a/plugins/LadspaEffect/swh/valve_rect_1405.c +++ b/plugins/LadspaEffect/swh/valve_rect_1405.c @@ -401,7 +401,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (valveRectDescriptor) { free((LADSPA_PortDescriptor *)valveRectDescriptor->PortDescriptors); free((char **)valveRectDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/vocoder_1337.c b/plugins/LadspaEffect/swh/vocoder_1337.c index 0fb51688a..1ac1048df 100644 --- a/plugins/LadspaEffect/swh/vocoder_1337.c +++ b/plugins/LadspaEffect/swh/vocoder_1337.c @@ -420,9 +420,9 @@ void __attribute__((constructor)) swh_init() { /*****************************************************************************/ -/* _fini() is called automatically when the library is unloaded. */ +/* __attribute__((destructor)) swh_fini() is called automatically when the library is unloaded. */ void -_fini() { + __attribute__((destructor)) swh_fini() { long lIndex; if (g_psDescriptor) { free((char *)g_psDescriptor->Label); diff --git a/plugins/LadspaEffect/swh/vynil_1905.c b/plugins/LadspaEffect/swh/vynil_1905.c index 03112ac8e..187aa0f8f 100644 --- a/plugins/LadspaEffect/swh/vynil_1905.c +++ b/plugins/LadspaEffect/swh/vynil_1905.c @@ -712,7 +712,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (vynilDescriptor) { free((LADSPA_PortDescriptor *)vynilDescriptor->PortDescriptors); free((char **)vynilDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/wave_terrain_1412.c b/plugins/LadspaEffect/swh/wave_terrain_1412.c index 46791bdc1..bb77bd825 100644 --- a/plugins/LadspaEffect/swh/wave_terrain_1412.c +++ b/plugins/LadspaEffect/swh/wave_terrain_1412.c @@ -231,7 +231,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (waveTerrainDescriptor) { free((LADSPA_PortDescriptor *)waveTerrainDescriptor->PortDescriptors); free((char **)waveTerrainDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/xfade_1915.c b/plugins/LadspaEffect/swh/xfade_1915.c index 3d0d01d01..3a4ca2345 100644 --- a/plugins/LadspaEffect/swh/xfade_1915.c +++ b/plugins/LadspaEffect/swh/xfade_1915.c @@ -598,7 +598,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (xfadeDescriptor) { free((LADSPA_PortDescriptor *)xfadeDescriptor->PortDescriptors); free((char **)xfadeDescriptor->PortNames); diff --git a/plugins/LadspaEffect/swh/zm1_1428.c b/plugins/LadspaEffect/swh/zm1_1428.c index 5c3c19b5d..baf063bfc 100644 --- a/plugins/LadspaEffect/swh/zm1_1428.c +++ b/plugins/LadspaEffect/swh/zm1_1428.c @@ -232,7 +232,7 @@ void __attribute__((constructor)) swh_init() { } } -void _fini() { +void __attribute__((destructor)) swh_fini() { if (zm1Descriptor) { free((LADSPA_PortDescriptor *)zm1Descriptor->PortDescriptors); free((char **)zm1Descriptor->PortNames); diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp index 5fe9c6716..0a653a75f 100644 --- a/plugins/kicker/kicker.cpp +++ b/plugins/kicker/kicker.cpp @@ -108,6 +108,8 @@ void kickerInstrument::saveSettings( QDomDocument & _doc, void kickerInstrument::loadSettings( const QDomElement & _this ) { + m_versionModel.loadSettings( _this, "version" ); + m_startFreqModel.loadSettings( _this, "startfreq" ); m_endFreqModel.loadSettings( _this, "endfreq" ); m_decayModel.loadSettings( _this, "decay" ); @@ -126,18 +128,22 @@ void kickerInstrument::loadSettings( const QDomElement & _this ) m_clickModel.loadSettings( _this, "click" ); m_slopeModel.loadSettings( _this, "slope" ); m_startNoteModel.loadSettings( _this, "startnote" ); + if( m_versionModel.value() < 1 ) + { + m_startNoteModel.setValue( false ); + } m_endNoteModel.loadSettings( _this, "endnote" ); - m_versionModel.loadSettings( _this, "version" ); // Try to maintain backwards compatibility if( !_this.hasAttribute( "version" ) ) { + m_decayModel.setValue( m_decayModel.value() * 1.33f ); m_envModel.setValue( 1.0f ); m_slopeModel.setValue( 1.0f ); m_clickModel.setValue( 0.0f ); - m_versionModel.setValue( KICKER_PRESET_VERSION ); } + m_versionModel.setValue( KICKER_PRESET_VERSION ); } diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index 83b824d52..91a8119a2 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -1,14 +1,14 @@ /* - * lb302.cpp - implementation of class lb302 which is a bass synth attempting + * lb302.cpp - implementation of class lb302 which is a bass synth attempting * to emulate the Roland TB303 bass synth * * Copyright (c) 2006-2008 Paul Giblock - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * lb302FilterIIR2 is based on the gsyn filter code by Andy Sloane. - * - * lb302Filter3Pole is based on the TB303 instrument written by + * + * lb302Filter3Pole is based on the TB303 instrument written by * Josep M Comajuncosas for the CSounds library * * This program is free software; you can redistribute it and/or @@ -39,6 +39,7 @@ #include "pixmap_button.h" #include "templates.h" #include "tooltip.h" +#include "BandLimitedWave.h" #include "embed.cpp" #include "moc_lb302.cxx" @@ -49,10 +50,10 @@ // // New config // -#define LB_24_IGNORE_ENVELOPE -#define LB_FILTERED +#define LB_24_IGNORE_ENVELOPE +#define LB_FILTERED //#define LB_DECAY -//#define LB_24_RES_TRICK +//#define LB_24_RES_TRICK #define LB_DIST_RATIO 4.0 #define LB_24_VOL_ADJUST 3.0 @@ -143,7 +144,7 @@ lb302FilterIIR2::lb302FilterIIR2(lb302FilterKnobState* p_fs) : { m_dist = new DspEffectLibrary::Distortion( 1.0, 1.0f); - + }; @@ -183,7 +184,7 @@ float lb302FilterIIR2::process(const float& samp) vcf_d2 = vcf_d1; vcf_d1 = ret; - if(fs->dist > 0) + if(fs->dist > 0) ret=m_dist->nextSample(ret); // output = IIR2 + dry @@ -200,7 +201,7 @@ lb302Filter3Pole::lb302Filter3Pole(lb302FilterKnobState *p_fs) : ay1(0), ay2(0), aout(0), - lastin(0) + lastin(0) { }; @@ -225,7 +226,7 @@ void lb302Filter3Pole::envRecalc() w = vcf_e0 + vcf_c0; k = (fs->cutoff > 0.975)?0.975:fs->cutoff; kfco = 50.f + (k)*((2300.f-1600.f*(fs->envmod))+(w) * - (700.f+1500.f*(k)+(1500.f+(k)*(engine::mixer()->processingSampleRate()/2.f-6000.f)) * + (700.f+1500.f*(k)+(1500.f+(k)*(engine::mixer()->processingSampleRate()/2.f-6000.f)) * (fs->envmod)) ); //+iacc*(.3+.7*kfco*kenvmod)*kaccent*kaccurve*2000 @@ -249,7 +250,7 @@ void lb302Filter3Pole::envRecalc() } -float lb302Filter3Pole::process(const float& samp) +float lb302Filter3Pole::process(const float& samp) { float ax1 = lastin; float ay11 = ay1; @@ -274,12 +275,12 @@ lb302Synth::lb302Synth( InstrumentTrack * _instrumentTrack ) : vcf_mod_knob( 0.1f, 0.0f, 1.0f, 0.005f, this, tr( "VCF Envelope Mod" ) ), vcf_dec_knob( 0.1f, 0.0f, 1.0f, 0.005f, this, tr( "VCF Envelope Decay" ) ), dist_knob( 0.0f, 0.0f, 1.0f, 0.01f, this, tr( "Distortion" ) ), - wave_shape( 0.0f, 0.0f, 7.0f, this, tr( "Waveform" ) ), + wave_shape( 8.0f, 0.0f, 11.0f, this, tr( "Waveform" ) ), slide_dec_knob( 0.6f, 0.0f, 1.0f, 0.005f, this, tr( "Slide Decay" ) ), slideToggle( false, this, tr( "Slide" ) ), accentToggle( false, this, tr( "Accent" ) ), deadToggle( false, this, tr( "Dead" ) ), - db24Toggle( false, this, tr( "24dB/oct Filter" ) ) + db24Toggle( false, this, tr( "24dB/oct Filter" ) ) { @@ -330,7 +331,7 @@ lb302Synth::lb302Synth( InstrumentTrack * _instrumentTrack ) : vca_attack = 1.0 - 0.96406088; vca_decay = 0.99897516; - vco_shape = SAWTOOTH; + vco_shape = BL_SAWTOOTH; // Experimenting with a0 between original (0.5) and 1.0 vca_a0 = 0.5; @@ -342,15 +343,13 @@ lb302Synth::lb302Synth( InstrumentTrack * _instrumentTrack ) : db24Toggled(); sample_cnt = 0; - release_frame = 1<<24; + release_frame = 0; catch_frame = 0; catch_decay = 0; last_offset = 0; - new_freq = -1; - current_freq = -1; - delete_freq = -1; + new_freq = false; filterChanged(); @@ -425,7 +424,7 @@ void lb302Synth::filterChanged() void lb302Synth::db24Toggled() { vcf = vcfs[db24Toggle.value()]; - // These recalcFilter calls might suck + // These recalcFilter calls might suck recalcFilter(); } @@ -465,41 +464,41 @@ inline float GET_INC(float freq) { int lb302Synth::process(sampleFrame *outbuf, const int size) { + const float sampleRatio = 44100.f / engine::mixer()->processingSampleRate(); float w; float samp; // Hold on to the current VCF, and use it throughout this period lb302Filter *filter = vcf; - if( delete_freq == current_freq ) { - // Normal release - delete_freq = -1; + if( release_frame == 0 || ! m_playingNote ) + { vca_mode = 1; } - if( new_freq > 0.0f ) { + if( new_freq ) + { //printf(" playing new note..\n"); lb302Note note; note.vco_inc = GET_INC( true_freq ); - //printf("GET_INC %f %f %d\n", note.vco_inc, new_freq, vca_mode ); - ///**vco_detune*//engine::mixer()->processingSampleRate(); // TODO: Use actual sampling rate. - //printf("VCO_INC = %f\n", note.vco_inc); note.dead = deadToggle.value(); initNote(¬e); - //printf("%f %f, ", vco_inc, vco_c); - - current_freq = new_freq; - new_freq = -1.0f; - //printf("GOT_INC %f %f %d\n\n", note.vco_inc, new_freq, vca_mode ); - } + new_freq = false; + } + - // TODO: NORMAL RELEASE // vca_mode = 1; - for(int i=0;i= release_frame ) + { + vca_mode = 1; + } // update vcf if(vcf_envpos >= ENVINC) { @@ -508,9 +507,9 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) vcf_envpos = 0; if (vco_slide) { - vco_inc=vco_slidebase-vco_slide; + vco_inc = vco_slidebase - vco_slide; // Calculate coeff from dec_knob on knob change. - vco_slide*= 0.9+(slide_dec_knob.value()*0.0999); // TODO: Adjust for Hz and ENVINC + vco_slide -= vco_slide * ( 0.1f - slide_dec_knob.value() * 0.0999f ) * sampleRatio; // TODO: Adjust for ENVINC } } @@ -523,17 +522,10 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) // update vco vco_c += vco_inc; - + if(vco_c > 0.5) vco_c -= 1.0; - /*LB303 - if (catch_decay > 0) { - if (catch_decay < decay_frames) { - catch_decay++; - } - }*/ - switch(int(rint(wave_shape.value()))) { case 0: vco_shape = SAWTOOTH; break; case 1: vco_shape = TRIANGLE; break; @@ -543,6 +535,10 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) case 5: vco_shape = SINE; break; case 6: vco_shape = EXPONENTIAL; break; case 7: vco_shape = WHITE_NOISE; break; + case 8: vco_shape = BL_SAWTOOTH; break; + case 9: vco_shape = BL_SQUARE; break; + case 10: vco_shape = BL_TRIANGLE; break; + case 11: vco_shape = BL_MOOG; break; default: vco_shape = SAWTOOTH; break; } @@ -568,7 +564,7 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) break; case MOOG: // Maybe the fall should be exponential/sinsoidal instead of quadric. - // [-0.5, 0]: Rise, [0,0.25]: Slope down, [0.25,0.5]: Low + // [-0.5, 0]: Rise, [0,0.25]: Slope down, [0.25,0.5]: Low vco_k = (vco_c*2.0)+0.5; if (vco_k>1.0) { vco_k = -0.5 ; @@ -577,7 +573,7 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) w = 2.0*(vco_k-0.5)-1.0; vco_k = 0.5 - sqrtf(1.0-(w*w)); } - vco_k *= 2.0; // MOOG wave gets filtered away + vco_k *= 2.0; // MOOG wave gets filtered away break; case SINE: @@ -592,6 +588,22 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) case WHITE_NOISE: vco_k = 0.5 * Oscillator::noiseSample( vco_c ); break; + + case BL_SAWTOOTH: + vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLSaw ) * 0.5f; + break; + + case BL_SQUARE: + vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLSquare ) * 0.5f; + break; + + case BL_TRIANGLE: + vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLTriangle ) * 0.5f; + break; + + case BL_MOOG: + vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLMoog ); + break; } //vca_a = 0.5; @@ -600,8 +612,8 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) //samp = vcf->process(vco_k)*2.0*vca_a; //samp = vcf->process(vco_k)*2.0; samp = filter->process(vco_k) * vca_a; - //printf("%f %d\n", vco_c, sample_cnt); - + //printf("%f %d\n", vco_c, sample_cnt); + //samp = vco_k * vca_a; @@ -609,7 +621,7 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) { // vca_a = 0; } - + #else //samp = vco_k*vca_a; #endif @@ -619,21 +631,15 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) */ //LB302 samp *= (float)(decay_frames - catch_decay)/(float)decay_frames; - for(int c=0; c=release_frame) { - vca_mode=1; - } - */ - // Handle Envelope if(vca_mode==0) { vca_a+=(vca_a0-vca_a)*vca_attack; - if(sample_cnt>=0.5*engine::mixer()->processingSampleRate()) + if(sample_cnt>=0.5*engine::mixer()->processingSampleRate()) vca_mode = 2; } else if(vca_mode == 1) { @@ -661,7 +667,7 @@ void lb302Synth::initNote( lb302Note *n) catch_decay = 0; vco_inc = n->vco_inc; - + // Always reset vca on non-dead notes, and // Only reset vca on decaying(decayed) and never-played if(n->dead == 0 || (vca_mode==1 || vca_mode==3)) { @@ -675,8 +681,32 @@ void lb302Synth::initNote( lb302Note *n) vca_mode = 2; } + initSlide(); + + // Slide-from note, save inc for next note + if (slideToggle.value()) { + vco_slideinc = vco_inc; // May need to equal vco_slidebase+vco_slide if last note slid + } + + + recalcFilter(); + + if(n->dead ==0){ + // Swap next two blocks?? + vcf->playNote(); + // Ensure envelope is recalculated + vcf_envpos = ENVINC; + + // Double Check + //vca_mode = 0; + //vca_a = 0.0; + } +} + + +void lb302Synth::initSlide() +{ // Initiate Slide - // TODO: Break out into function, should be called again on detuneChanged if (vco_slideinc) { //printf(" sliding\n"); vco_slide = vco_inc-vco_slideinc; // Slide amount @@ -686,71 +716,55 @@ void lb302Synth::initNote( lb302Note *n) else { vco_slide = 0; } - // End break-out - - // Slide-from note, save inc for next note - if (slideToggle.value()) { - vco_slideinc = vco_inc; // May need to equal vco_slidebase+vco_slide if last note slid - } - - - recalcFilter(); - - if(n->dead ==0){ - // Swap next two blocks?? - vcf->playNote(); - // Ensure envelope is recalculated - vcf_envpos = ENVINC; - - // Double Check - //vca_mode = 0; - //vca_a = 0.0; - } } void lb302Synth::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ) { - //fpp_t framesPerPeriod = engine::mixer()->framesPerPeriod(); - - if( _n->isMasterNote() ) + if( _n->isMasterNote() || ( _n->hasParent() && _n->isReleased() ) ) { return; } - // Currently have release/decay disabled - // Start the release decay if this is the first release period. - //if (_n->released() && catch_decay == 0) - // catch_decay = 1; - - bool decay_note = false; - - release_frame = _n->framesLeft() - desiredReleaseFrames(); + // sort notes: new notes to the end + m_notesMutex.lock(); + if( _n->totalFramesPlayed() == 0 ) + { + m_notes.append( _n ); + } + else + { + m_notes.prepend( _n ); + } + m_notesMutex.unlock(); + + release_frame = qMax( release_frame, _n->framesLeft() + _n->offset() ); +} - //LB303 if ( _n->totalFramesPlayed() <= 0 ) { - // This code is obsolete, hence the "if false" - // Existing note. Allow it to decay. - if(deadToggle.value() == 0 && decay_note) { - - /* lb302Note note; - note.vco_inc = _n->frequency()*vco_detune/engine::mixer()->processingSampleRate(); // TODO: Use actual sampling rate. - note.dead = deadToggle.value(); - initNote(¬e); - vca_mode=0; - */ - - } +void lb302Synth::processNote( NotePlayHandle * _n ) +{ /// Start a new note. - else if( _n->totalFramesPlayed() == 0 ) { - new_freq = _n->unpitchedFrequency(); - true_freq = _n->frequency(); + if( _n->m_pluginData != this ) + { + m_playingNote = _n; + new_freq = true; _n->m_pluginData = this; } + + if( ! m_playingNote && ! _n->isReleased() && release_frame > 0 ) + { + m_playingNote = _n; + if ( slideToggle.value() ) + { + vco_slideinc = GET_INC( _n->frequency() ); + } + } // Check for slide - if( _n->unpitchedFrequency() == current_freq ) { + if( m_playingNote == _n ) + { true_freq = _n->frequency(); if( slideToggle.value() ) { @@ -760,22 +774,22 @@ void lb302Synth::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ) vco_inc = GET_INC( true_freq ); } } - - //LB303 } - - } void lb302Synth::play( sampleFrame * _working_buffer ) { - //printf("."); + while( ! m_notes.isEmpty() ) + { + processNote( m_notes.takeFirst() ); + }; + const fpp_t frames = engine::mixer()->framesPerPeriod(); - process( _working_buffer, frames); - instrumentTrack()->processAudioBuffer( _working_buffer, frames, - NULL ); + process( _working_buffer, frames ); + instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL ); + release_frame = 0; } @@ -783,9 +797,9 @@ void lb302Synth::play( sampleFrame * _working_buffer ) void lb302Synth::deleteNotePluginData( NotePlayHandle * _n ) { //printf("GONE\n"); - if( _n->unpitchedFrequency() == current_freq ) + if( m_playingNote == _n ) { - delete_freq = current_freq; + m_playingNote = NULL; } } @@ -831,7 +845,7 @@ lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) : m_deadToggle->move( 10, 220 ); m_db24Toggle = new ledCheckBox( "", this ); - m_db24Toggle->setWhatsThis( + m_db24Toggle->setWhatsThis( tr( "303-es-que, 24dB/octave, 3 pole filter" ) ); m_db24Toggle->move( 10, 150); @@ -888,8 +902,8 @@ lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) : "round_square_wave_inactive" ) ); toolTip::add( roundSqrWaveBtn, tr( "Click here for a square-wave with a rounded end." ) ); - - pixmapButton * moogWaveBtn = + + pixmapButton * moogWaveBtn = new pixmapButton( this, tr( "Moog wave" ) ); moogWaveBtn->move( waveBtnX+(16*4), waveBtnY ); moogWaveBtn->setActiveGraphic( @@ -929,6 +943,47 @@ lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) : toolTip::add( whiteNoiseWaveBtn, tr( "Click here for white-noise." ) ); + pixmapButton * blSawWaveBtn = + new pixmapButton( this, tr( "Bandlimited saw wave" ) ); + blSawWaveBtn->move( waveBtnX+(16*9)-8, waveBtnY ); + blSawWaveBtn->setActiveGraphic( + embed::getIconPixmap( "saw_wave_active" ) ); + blSawWaveBtn->setInactiveGraphic( + embed::getIconPixmap( "saw_wave_inactive" ) ); + toolTip::add( blSawWaveBtn, + tr( "Click here for bandlimited saw wave." ) ); + + pixmapButton * blSquareWaveBtn = + new pixmapButton( this, tr( "Bandlimited square wave" ) ); + blSquareWaveBtn->move( waveBtnX+(16*10)-8, waveBtnY ); + blSquareWaveBtn->setActiveGraphic( + embed::getIconPixmap( "square_wave_active" ) ); + blSquareWaveBtn->setInactiveGraphic( + embed::getIconPixmap( "square_wave_inactive" ) ); + toolTip::add( blSquareWaveBtn, + tr( "Click here for bandlimited square wave." ) ); + + pixmapButton * blTriangleWaveBtn = + new pixmapButton( this, tr( "Bandlimited triangle wave" ) ); + blTriangleWaveBtn->move( waveBtnX+(16*11)-8, waveBtnY ); + blTriangleWaveBtn->setActiveGraphic( + embed::getIconPixmap( "triangle_wave_active" ) ); + blTriangleWaveBtn->setInactiveGraphic( + embed::getIconPixmap( "triangle_wave_inactive" ) ); + toolTip::add( blTriangleWaveBtn, + tr( "Click here for bandlimited triangle wave." ) ); + + pixmapButton * blMoogWaveBtn = + new pixmapButton( this, tr( "Bandlimited moog saw wave" ) ); + blMoogWaveBtn->move( waveBtnX+(16*12)-8, waveBtnY ); + blMoogWaveBtn->setActiveGraphic( + embed::getIconPixmap( "moog_saw_wave_active" ) ); + blMoogWaveBtn->setInactiveGraphic( + embed::getIconPixmap( "moog_saw_wave_inactive" ) ); + toolTip::add( blMoogWaveBtn, + tr( "Click here for bandlimited moog saw wave." ) ); + + m_waveBtnGrp = new automatableButtonGroup( this ); m_waveBtnGrp->addButton( sawWaveBtn ); m_waveBtnGrp->addButton( triangleWaveBtn ); @@ -938,6 +993,10 @@ lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) : m_waveBtnGrp->addButton( sinWaveBtn ); m_waveBtnGrp->addButton( exponentialWaveBtn ); m_waveBtnGrp->addButton( whiteNoiseWaveBtn ); + m_waveBtnGrp->addButton( blSawWaveBtn ); + m_waveBtnGrp->addButton( blSquareWaveBtn ); + m_waveBtnGrp->addButton( blTriangleWaveBtn ); + m_waveBtnGrp->addButton( blMoogWaveBtn ); setAutoFillBackground( true ); QPalette pal; @@ -955,7 +1014,7 @@ lb302SynthView::~lb302SynthView() void lb302SynthView::modelChanged() { lb302Synth * syn = castModel(); - + m_vcfCutKnob->setModel( &syn->vcf_cut_knob ); m_vcfResKnob->setModel( &syn->vcf_res_knob ); m_vcfDecKnob->setModel( &syn->vcf_dec_knob ); @@ -964,7 +1023,7 @@ void lb302SynthView::modelChanged() m_distKnob->setModel( &syn->dist_knob ); m_waveBtnGrp->setModel( &syn->wave_shape ); - + m_slideToggle->setModel( &syn->slideToggle ); m_accentToggle->setModel( &syn->accentToggle ); m_deadToggle->setModel( &syn->deadToggle ); diff --git a/plugins/lb302/lb302.h b/plugins/lb302/lb302.h index b909b2710..2777e7fa5 100644 --- a/plugins/lb302/lb302.h +++ b/plugins/lb302/lb302.h @@ -3,12 +3,12 @@ * emulate the Roland TB303 bass synth * * Copyright (c) 2006-2008 Paul Giblock - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * lb302FilterIIR2 is based on the gsyn filter code by Andy Sloane. - * - * lb302Filter3Pole is based on the TB303 instrument written by + * + * lb302Filter3Pole is based on the TB303 instrument written by * Josep M Comajuncosas for the CSounds library * * This program is free software; you can redistribute it and/or @@ -29,8 +29,8 @@ */ -#ifndef _LB302_H_ -#define _LB302_H_ +#ifndef LB302_H_ +#define LB302_H_ #include "DspEffectLibrary.h" #include "Instrument.h" @@ -38,6 +38,8 @@ #include "led_checkbox.h" #include "knob.h" #include "Mixer.h" +#include "NotePlayHandle.h" +#include static const int NUM_FILTERS = 2; @@ -67,12 +69,12 @@ class lb302Filter virtual void playNote(); protected: - lb302FilterKnobState *fs; + lb302FilterKnobState *fs; // Filter Decay float vcf_c0; // c0=e1 on retrigger; c0*=ed every sample; cutoff=e0+c0 float vcf_e0, // e0 and e1 for interpolation - vcf_e1; + vcf_e1; float vcf_rescoeff; // Resonance coefficient [0.30,9.54] }; @@ -87,13 +89,13 @@ class lb302FilterIIR2 : public lb302Filter virtual float process(const float& samp); protected: - float vcf_d1, // d1 and d2 are added back into the sample with + float vcf_d1, // d1 and d2 are added back into the sample with vcf_d2; // vcf_a and b as coefficients. IIR2 resonance // loop. // IIR2 Coefficients for mixing dry and delay. - float vcf_a, // Mixing coefficients for the final sound. - vcf_b, // + float vcf_a, // Mixing coefficients for the final sound. + vcf_b, // vcf_c; DspEffectLibrary::Distortion * m_dist; @@ -111,15 +113,15 @@ class lb302Filter3Pole : public lb302Filter virtual float process(const float& samp); protected: - float kfcn, - kp, - kp1, - kp1h, + float kfcn, + kp, + kp1, + kp1h, kres; - float ay1, - ay2, - aout, - lastin, + float ay1, + ay2, + aout, + lastin, value; }; @@ -164,9 +166,10 @@ public: virtual PluginView * instantiateView( QWidget * _parent ); private: + void processNote( NotePlayHandle * n ); void initNote(lb302Note *note); - + void initSlide(); private: FloatModel vcf_cut_knob; @@ -179,7 +182,7 @@ private: FloatModel dist_knob; IntModel wave_shape; FloatModel slide_dec_knob; - + BoolModel slideToggle; BoolModel accentToggle; BoolModel deadToggle; @@ -200,7 +203,8 @@ private: vco_slideinc, //* Slide base to use in next node. Nonzero=slide next note vco_slidebase; //* The base vco_inc while sliding. - enum vco_shape_t { SAWTOOTH, SQUARE, TRIANGLE, MOOG, ROUND_SQUARE, SINE, EXPONENTIAL, WHITE_NOISE }; + enum vco_shape_t { SAWTOOTH, SQUARE, TRIANGLE, MOOG, ROUND_SQUARE, SINE, EXPONENTIAL, WHITE_NOISE, + BL_SAWTOOTH, BL_SQUARE, BL_TRIANGLE, BL_MOOG }; vco_shape_t vco_shape; // Filters (just keep both loaded and switch) @@ -215,9 +219,9 @@ private: // More States int vcf_envpos; // Update counter. Updates when >= ENVINC - float vca_attack, // Amp attack + float vca_attack, // Amp attack vca_decay, // Amp decay - vca_a0, // Initial amplifier coefficient + vca_a0, // Initial amplifier coefficient vca_a; // Amplifier coefficient. // Envelope State @@ -231,9 +235,7 @@ private: int catch_frame; int catch_decay; - float new_freq; - float current_freq; - float delete_freq; + bool new_freq; float true_freq; void recalcFilter(); @@ -242,6 +244,9 @@ private: friend class lb302SynthView; + NotePlayHandle * m_playingNote; + NotePlayHandleList m_notes; + QMutex m_notesMutex; } ; @@ -254,7 +259,7 @@ public: private: virtual void modelChanged(); - + knob * m_vcfCutKnob; knob * m_vcfResKnob; knob * m_vcfDecKnob; @@ -263,7 +268,7 @@ private: knob * m_distKnob; knob * m_slideDecKnob; automatableButtonGroup * m_waveBtnGrp; - + ledCheckBox * m_slideToggle; ledCheckBox * m_accentToggle; ledCheckBox * m_deadToggle; diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index f38b58400..aa61187bd 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -89,7 +89,7 @@ MonstroSynth::MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph, m_lfo1_phase = 0.0f; m_lfo2_phase = 0.0f; - + m_lfo1_s = Oscillator::noiseSample( 0.0f ); m_lfo2_s = Oscillator::noiseSample( 0.0f ); @@ -103,15 +103,16 @@ MonstroSynth::MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph, m_invert2r = false; m_invert3l = false; m_invert3r = false; - + m_integrator = 0.5f - ( 0.5f - INTEGRATOR ) * 44100.0f / m_samplerate; - + m_counter2l = 0; m_counter2r = 0; m_counter3l = 0; m_counter3r = 0; m_counterMax = ( m_samplerate * 10 ) / 44100; - + + m_fmCorrection = 44100.f / m_samplerate * FM_AMOUNT; } @@ -127,32 +128,36 @@ MonstroSynth::~MonstroSynth() void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) { + float modtmp; // temp variable for freq modulation // macros for modulating with env/lfos #define modulatefreq( car, mod ) \ - if( mod##_e1 != 0.0f ) car = qBound( MIN_FREQ, car * powf( 2.0f, m_env1_buf[f] * mod##_e1 * 2.0f ), MAX_FREQ ); \ - if( mod##_e2 != 0.0f ) car = qBound( MIN_FREQ, car * powf( 2.0f, m_env2_buf[f] * mod##_e2 * 2.0f ), MAX_FREQ ); \ - if( mod##_l1 != 0.0f ) car = qBound( MIN_FREQ, car * powf( 2.0f, m_lfo1_buf[f] * mod##_l1 ), MAX_FREQ ); \ - if( mod##_l2 != 0.0f ) car = qBound( MIN_FREQ, car * powf( 2.0f, m_lfo2_buf[f] * mod##_l2 ), MAX_FREQ ); + modtmp = 0.0f; \ + if( mod##_e1 != 0.0f ) modtmp += m_env1_buf[f] * mod##_e1; \ + if( mod##_e2 != 0.0f ) modtmp += m_env2_buf[f] * mod##_e2; \ + if( mod##_l1 != 0.0f ) modtmp += m_lfo1_buf[f] * mod##_l1; \ + if( mod##_l2 != 0.0f ) modtmp += m_lfo2_buf[f] * mod##_l2; \ + car = qBound( MIN_FREQ, car * powf( 2.0f, modtmp ), MAX_FREQ ); #define modulateabs( car, mod ) \ - if( mod##_e1 != 0.0f ) car = qBound( 0.0f, car + mod##_e1 * m_env1_buf[f], 1.0f ); \ - if( mod##_e2 != 0.0f ) car = qBound( 0.0f, car + mod##_e2 * m_env2_buf[f], 1.0f ); \ - if( mod##_l1 != 0.0f ) car = qBound( 0.0f, car + mod##_l1 * 0.5f * m_lfo1_buf[f], 1.0f ); \ - if( mod##_l2 != 0.0f ) car = qBound( 0.0f, car + mod##_l2 * 0.5f * m_lfo2_buf[f], 1.0f ); + if( mod##_e1 != 0.0f ) car += m_env1_buf[f] * mod##_e1; \ + if( mod##_e2 != 0.0f ) car += m_env2_buf[f] * mod##_e2; \ + if( mod##_l1 != 0.0f ) car += m_lfo1_buf[f] * mod##_l1; \ + if( mod##_l2 != 0.0f ) car += m_lfo2_buf[f] * mod##_l2; #define modulatephs( car, mod ) \ - if( mod##_e1 != 0.0f ) car += qBound( -1.0f, ( mod##_e1 * m_env1_buf[f] ), 1.0f ); \ - if( mod##_e2 != 0.0f ) car += qBound( -1.0f, ( mod##_e2 * m_env2_buf[f] ), 1.0f ); \ - if( mod##_l1 != 0.0f ) car += ( mod##_l1 * 0.5f * m_lfo1_buf[f] ); \ - if( mod##_l2 != 0.0f ) car += ( mod##_l2 * 0.5f * m_lfo2_buf[f] ); + if( mod##_e1 != 0.0f ) car += m_env1_buf[f] * mod##_e1; \ + if( mod##_e2 != 0.0f ) car += m_env2_buf[f] * mod##_e2; \ + if( mod##_l1 != 0.0f ) car += m_lfo1_buf[f] * mod##_l1; \ + if( mod##_l2 != 0.0f ) car += m_lfo2_buf[f] * mod##_l2; #define modulatevol( car, mod ) \ - if( mod##_e1 > 0.0f ) car = qBound( -MODCLIP, car * ( 1.0f - mod##_e1 + mod##_e1 * m_env1_buf[f] ), MODCLIP ); \ - if( mod##_e1 < 0.0f ) car = qBound( -MODCLIP, car * ( 1.0f + mod##_e1 * m_env1_buf[f] ), MODCLIP ); \ - if( mod##_e2 > 0.0f ) car = qBound( -MODCLIP, car * ( 1.0f - mod##_e2 + mod##_e2 * m_env2_buf[f] ), MODCLIP ); \ - if( mod##_e2 < 0.0f ) car = qBound( -MODCLIP, car * ( 1.0f + mod##_e2 * m_env2_buf[f] ), MODCLIP ); \ - if( mod##_l1 != 0.0f ) car = qBound( -MODCLIP, car * ( 1.0f + mod##_l1 * m_lfo1_buf[f] ), MODCLIP ); \ - if( mod##_l2 != 0.0f ) car = qBound( -MODCLIP, car * ( 1.0f + mod##_l2 * m_lfo2_buf[f] ), MODCLIP ); + if( mod##_e1 > 0.0f ) car *= ( 1.0f - mod##_e1 + mod##_e1 * m_env1_buf[f] ); \ + if( mod##_e1 < 0.0f ) car *= ( 1.0f + mod##_e1 * m_env1_buf[f] ); \ + if( mod##_e2 > 0.0f ) car *= ( 1.0f - mod##_e2 + mod##_e2 * m_env2_buf[f] ); \ + if( mod##_e2 < 0.0f ) car *= ( 1.0f + mod##_e2 * m_env2_buf[f] ); \ + if( mod##_l1 != 0.0f ) car *= ( 1.0f + mod##_l1 * m_lfo1_buf[f] ); \ + if( mod##_l2 != 0.0f ) car *= ( 1.0f + mod##_l2 * m_lfo2_buf[f] ); \ + car = qBound( -MODCLIP, car, MODCLIP ); // pre-render env's and lfo's renderModulators( _frames ); @@ -162,24 +167,27 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) const float pw = ( m_parent->m_osc1Pw.value() / 100.0f ); const float o1pw_e1 = ( m_parent->m_pw1env1.value() ); const float o1pw_e2 = ( m_parent->m_pw1env2.value() ); - const float o1pw_l1 = ( m_parent->m_pw1lfo1.value() ); - const float o1pw_l2 = ( m_parent->m_pw1lfo2.value() ); + const float o1pw_l1 = ( m_parent->m_pw1lfo1.value() * 0.5f ); + const float o1pw_l2 = ( m_parent->m_pw1lfo2.value() * 0.5f ); + const bool o1pw_mod = o1pw_e1 != 0.0f || o1pw_e2 != 0.0f || o1pw_l1 != 0.0f || o1pw_l2 != 0.0f; // get phases const float o1lpo = m_parent->m_osc1l_po; const float o1rpo = m_parent->m_osc1r_po; const float o1p_e1 = ( m_parent->m_phs1env1.value() ); const float o1p_e2 = ( m_parent->m_phs1env2.value() ); - const float o1p_l1 = ( m_parent->m_phs1lfo1.value() ); - const float o1p_l2 = ( m_parent->m_phs1lfo2.value() ); + const float o1p_l1 = ( m_parent->m_phs1lfo1.value() * 0.5f ); + const float o1p_l2 = ( m_parent->m_phs1lfo2.value() * 0.5f ); + const bool o1p_mod = o1p_e1 != 0.0f || o1p_e2 != 0.0f || o1p_l1 != 0.0f || o1p_l2 != 0.0f; // get pitch const float o1lfb = ( m_parent->m_osc1l_freq * m_nph->frequency() ); const float o1rfb = ( m_parent->m_osc1r_freq * m_nph->frequency() ); - const float o1f_e1 = ( m_parent->m_pit1env1.value() ); - const float o1f_e2 = ( m_parent->m_pit1env2.value() ); + const float o1f_e1 = ( m_parent->m_pit1env1.value() * 2.0f ); + const float o1f_e2 = ( m_parent->m_pit1env2.value() * 2.0f ); const float o1f_l1 = ( m_parent->m_pit1lfo1.value() ); const float o1f_l2 = ( m_parent->m_pit1lfo2.value() ); + const bool o1f_mod = o1f_e1 != 0.0f || o1f_e2 != 0.0f || o1f_l1 != 0.0f || o1f_l2 != 0.0f; // get volumes const float o1lv = m_parent->m_osc1l_vol; @@ -188,6 +196,7 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) const float o1v_e2 = ( m_parent->m_vol1env2.value() ); const float o1v_l1 = ( m_parent->m_vol1lfo1.value() ); const float o1v_l2 = ( m_parent->m_vol1lfo2.value() ); + const bool o1v_mod = o1v_e1 != 0.0f || o1v_e2 != 0.0f || o1v_l1 != 0.0f || o1v_l2 != 0.0f; // update osc2 // get waveform @@ -198,25 +207,27 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) const float o2rpo = m_parent->m_osc2r_po; const float o2p_e1 = ( m_parent->m_phs2env1.value() ); const float o2p_e2 = ( m_parent->m_phs2env2.value() ); - const float o2p_l1 = ( m_parent->m_phs2lfo1.value() ); - const float o2p_l2 = ( m_parent->m_phs2lfo2.value() ); + const float o2p_l1 = ( m_parent->m_phs2lfo1.value() * 0.5f ); + const float o2p_l2 = ( m_parent->m_phs2lfo2.value() * 0.5f ); + const bool o2p_mod = o2p_e1 != 0.0f || o2p_e2 != 0.0f || o2p_l1 != 0.0f || o2p_l2 != 0.0f; // get pitch const float o2lfb = ( m_parent->m_osc2l_freq * m_nph->frequency() ); const float o2rfb = ( m_parent->m_osc2r_freq * m_nph->frequency() ); - const float o2f_e1 = ( m_parent->m_pit2env1.value() ); - const float o2f_e2 = ( m_parent->m_pit2env2.value() ); + const float o2f_e1 = ( m_parent->m_pit2env1.value() * 2.0f ); + const float o2f_e2 = ( m_parent->m_pit2env2.value() * 2.0f ); const float o2f_l1 = ( m_parent->m_pit2lfo1.value() ); const float o2f_l2 = ( m_parent->m_pit2lfo2.value() ); + const bool o2f_mod = o2f_e1 != 0.0f || o2f_e2 != 0.0f || o2f_l1 != 0.0f || o2f_l2 != 0.0f; // get volumes const float o2lv = m_parent->m_osc2l_vol; const float o2rv = m_parent->m_osc2r_vol; const float o2v_e1 = ( m_parent->m_vol2env1.value() ); const float o2v_e2 = ( m_parent->m_vol2env2.value() ); - const float o2v_l1 = ( m_parent->m_vol2lfo2.value() ); + const float o2v_l1 = ( m_parent->m_vol2lfo1.value() ); const float o2v_l2 = ( m_parent->m_vol2lfo2.value() ); - + const bool o2v_mod = o2v_e1 != 0.0f || o2v_e2 != 0.0f || o2v_l1 != 0.0f || o2v_l2 != 0.0f; // update osc3 @@ -229,15 +240,17 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) const float o3rpo = m_parent->m_osc3r_po; const float o3p_e1 = ( m_parent->m_phs3env1.value() ); const float o3p_e2 = ( m_parent->m_phs3env2.value() ); - const float o3p_l1 = ( m_parent->m_phs3lfo1.value() ); - const float o3p_l2 = ( m_parent->m_phs3lfo2.value() ); + const float o3p_l1 = ( m_parent->m_phs3lfo1.value() * 0.5f ); + const float o3p_l2 = ( m_parent->m_phs3lfo2.value() * 0.5f ); + const bool o3p_mod = o3p_e1 != 0.0f || o3p_e2 != 0.0f || o3p_l1 != 0.0f || o3p_l2 != 0.0f; // get pitch modulators const float o3fb = ( m_parent->m_osc3_freq * m_nph->frequency() ); - const float o3f_e1 = ( m_parent->m_pit3env1.value() ); - const float o3f_e2 = ( m_parent->m_pit3env2.value() ); + const float o3f_e1 = ( m_parent->m_pit3env1.value() * 2.0f ); + const float o3f_e2 = ( m_parent->m_pit3env2.value() * 2.0f ); const float o3f_l1 = ( m_parent->m_pit3lfo1.value() ); const float o3f_l2 = ( m_parent->m_pit3lfo2.value() ); + const bool o3f_mod = o3f_e1 != 0.0f || o3f_e2 != 0.0f || o3f_l1 != 0.0f || o3f_l2 != 0.0f; // get volumes const float o3lv = m_parent->m_osc3l_vol; @@ -246,13 +259,15 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) const float o3v_e2 = ( m_parent->m_vol3env2.value() ); const float o3v_l1 = ( m_parent->m_vol3lfo1.value() ); const float o3v_l2 = ( m_parent->m_vol3lfo2.value() ); + const bool o3v_mod = o3v_e1 != 0.0f || o3v_e2 != 0.0f || o3v_l1 != 0.0f || o3v_l2 != 0.0f; // get sub const float o3sub = ( m_parent->m_osc3Sub.value() + 100.0f ) / 200.0f; const float o3s_e1 = ( m_parent->m_sub3env1.value() ); const float o3s_e2 = ( m_parent->m_sub3env2.value() ); - const float o3s_l1 = ( m_parent->m_sub3lfo1.value() ); - const float o3s_l2 = ( m_parent->m_sub3lfo2.value() ); + const float o3s_l1 = ( m_parent->m_sub3lfo1.value() * 0.5f ); + const float o3s_l2 = ( m_parent->m_sub3lfo2.value() * 0.5f ); + const bool o3s_mod = o3s_e1 != 0.0f || o3s_e2 != 0.0f || o3s_l1 != 0.0f || o3s_l2 != 0.0f; //o2-o3 modulation @@ -274,7 +289,6 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // // /////////////////////////// - // declare working variables for for loop // phase manipulation vars - these can be reused by all oscs @@ -284,12 +298,12 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) float pd_r; float len_l; float len_r; - + // osc1 vars float o1l_f; float o1r_f; float o1l_p = m_osc1l_phase + o1lpo; // we add phase offset here so we don't have to do it every frame - float o1r_p = m_osc1r_phase + o1rpo; // then substract it again after loop... + float o1r_p = m_osc1r_phase + o1rpo; // then substract it again after loop... float o1_pw; // osc2 vars @@ -327,18 +341,27 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // calc and mod frequencies o1l_f = o1lfb; o1r_f = o1rfb; - modulatefreq( o1l_f, o1f ) - modulatefreq( o1r_f, o1f ) - + if( o1f_mod ) + { + modulatefreq( o1l_f, o1f ) + modulatefreq( o1r_f, o1f ) + } // calc and modulate pulse o1_pw = pw; - modulateabs( o1_pw, o1pw ) + if( o1pw_mod ) + { + modulateabs( o1_pw, o1pw ) + o1_pw = qBound( PW_MIN, o1_pw, PW_MAX ); + } // calc and modulate phase leftph = o1l_p; - rightph = o1r_p; - modulatephs( leftph, o1p ) - modulatephs( rightph, o1p ) + rightph = o1r_p; + if( o1p_mod ) + { + modulatephs( leftph, o1p ) + modulatephs( rightph, o1p ) + } // pulse wave osc sample_t O1L = ( absFraction( leftph ) < o1_pw ) ? 1.0f : -1.0f; @@ -395,7 +418,7 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) { if( O1L < m_osc1l_last ) { m_invert3l = !m_invert3l; m_counter3l = m_counterMax; } if( O1R < m_osc1r_last ) { m_invert3r = !m_invert3r; m_counter3r = m_counterMax; } - } + } } // update last before signal is touched @@ -412,8 +435,11 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // modulate volume O1L *= o1lv; O1R *= o1rv; - modulatevol( O1L, o1v ) - modulatevol( O1R, o1v ) + if( o1v_mod ) + { + modulatevol( O1L, o1v ) + modulatevol( O1R, o1v ) + } // update osc1 phase working variable o1l_p += 1.0f / ( static_cast( m_samplerate ) / o1l_f ); @@ -428,14 +454,20 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // calc and mod frequencies o2l_f = o2lfb; o2r_f = o2rfb; - modulatefreq( o2l_f, o2f ) - modulatefreq( o2r_f, o2f ) + if( o2f_mod ) + { + modulatefreq( o2l_f, o2f ) + modulatefreq( o2r_f, o2f ) + } // calc and modulate phase leftph = o2l_p; - rightph = o2r_p; - modulatephs( leftph, o2p ) - modulatephs( rightph, o2p ) + rightph = o2r_p; + if( o2p_mod ) + { + modulatephs( leftph, o2p ) + modulatephs( rightph, o2p ) + } leftph = absFraction( leftph ); rightph = absFraction( rightph ); @@ -456,8 +488,11 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // modulate volume O2L *= o2lv; O2R *= o2rv; - modulatevol( O2L, o2v ) - modulatevol( O2R, o2v ) + if( o2v_mod ) + { + modulatevol( O2L, o2v ) + modulatevol( O2R, o2v ) + } // reverse sync - invert waveforms when needed if( m_invert2l ) O2L *= -1.0; @@ -478,26 +513,25 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // calc and mod frequencies o3l_f = o3fb; o3r_f = o3fb; - modulatefreq( o3l_f, o3f ) - modulatefreq( o3r_f, o3f ) - // o2 modulation? - if( omod == MOD_FM ) + if( o3f_mod ) { - o3l_f = qBound( MIN_FREQ, o3l_f * powf( 2.0f, O2L ), MAX_FREQ ); - o3r_f = qBound( MIN_FREQ, o3r_f * powf( 2.0f, O2R ), MAX_FREQ ); + modulatefreq( o3l_f, o3f ) + modulatefreq( o3r_f, o3f ) } - // calc and modulate phase leftph = o3l_p; - rightph = o3r_p; - modulatephs( leftph, o3p ) - modulatephs( rightph, o3p ) - + rightph = o3r_p; + if( o3p_mod ) + { + modulatephs( leftph, o3p ) + modulatephs( rightph, o3p ) + } + // o2 modulation? if( omod == MOD_PM ) { - leftph += O2L/2; - rightph += O2R/2; + leftph += O2L * 0.5f; + rightph += O2R * 0.5f; } leftph = absFraction( leftph ); rightph = absFraction( rightph ); @@ -523,7 +557,11 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // calc and modulate sub sub = o3sub; - modulateabs( sub, o3s ) + if( o3s_mod ) + { + modulateabs( sub, o3s ) + sub = qBound( 0.0f, sub, 1.0f ); + } sample_t O3L = linearInterpolate( O3AL, O3BL, sub ); sample_t O3R = linearInterpolate( O3AR, O3BR, sub ); @@ -531,8 +569,11 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // modulate volume O3L *= o3lv; O3R *= o3rv; - modulatevol( O3L, o3v ) - modulatevol( O3R, o3v ) + if( o3v_mod ) + { + modulatevol( O3L, o3v ) + modulatevol( O3R, o3v ) + } // o2 modulation? if( omod == MOD_AM ) { @@ -547,8 +588,16 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // update osc3 phases m_ph3l_last = leftph; m_ph3r_last = rightph; - o3l_p += 1.0f / ( static_cast( m_samplerate ) / o3l_f ); - o3r_p += 1.0f / ( static_cast( m_samplerate ) / o3r_f ); + len_l = 1.0f / ( static_cast( m_samplerate ) / o3l_f ); + len_r = 1.0f / ( static_cast( m_samplerate ) / o3r_f ); + // handle FM as PM + if( omod == MOD_FM ) + { + len_l += O2L * m_fmCorrection; + len_r += O2R * m_fmCorrection; + } + o3l_p += len_l; + o3r_p += len_r; // integrator - very simple filter sample_t L = O1L + O3L + ( omod == MOD_MIX ? O2L : 0.0f ); @@ -560,7 +609,7 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) m_l_last = L; m_r_last = R; } - + // update phases m_osc1l_phase = absFraction( o1l_p - o1lpo ); m_osc1r_phase = absFraction( o1r_p - o1rpo ); @@ -568,7 +617,7 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) m_osc2r_phase = absFraction( o2r_p - o2rpo ); m_osc3l_phase = absFraction( o3l_p - o3lpo ); m_osc3r_phase = absFraction( o3r_p - o3rpo ); - + } @@ -712,7 +761,7 @@ void MonstroSynth::renderModulators( fpp_t _frames ) const f_cnt_t tm = t % static_cast( lfo1_r ); const float p = static_cast( tm ) / lfo1_r; if( tm == 0 ) - { + { m_lfo1_last = m_lfo1_s; m_lfo1_s = Oscillator::noiseSample( 0.0f ); } @@ -845,7 +894,7 @@ void MonstroSynth::renderModulators( fpp_t _frames ) const f_cnt_t tm = t % static_cast( lfo2_r ); const float p = static_cast( tm ) / lfo2_r; if( tm == 0 ) - { + { m_lfo2_last = m_lfo2_s; m_lfo2_s = Oscillator::noiseSample( 0.0f ); } @@ -959,7 +1008,7 @@ void MonstroSynth::renderModulators( fpp_t _frames ) { m_env2_buf[f] = s; m_env2_phase = qMin( 4.0f - env2_sus, m_env2_phase + m_parent->m_env2_dec ); - if( m_env1_phase == 4.0f ) m_env1_phase = 5.0f; // jump over release if sustain is zero - fix for clicking + if( m_env2_phase == 4.0f ) m_env2_phase = 5.0f; // jump over release if sustain is zero - fix for clicking } } else if( m_env2_phase < 5.0f ) // release phase @@ -998,7 +1047,7 @@ MonstroInstrument::MonstroInstrument( InstrumentTrack * _instrument_track ) : m_osc1Ftl( 0.0, -100.0, 100.0, 1.0, this, tr( "Osc 1 Fine detune left" ) ), m_osc1Ftr( 0.0, -100.0, 100.0, 1.0, this, tr( "Osc 1 Fine detune right" ) ), m_osc1Spo( 0.0, -180.0, 180.0, 0.1, this, tr( "Osc 1 Stereo phase offset" ) ), - m_osc1Pw( 50.0, 0.0, 100.0, 0.01, this, tr( "Osc 1 Pulse width" ) ), + m_osc1Pw( 50.0, PW_MIN, PW_MAX, 0.01, this, tr( "Osc 1 Pulse width" ) ), m_osc1SSR( false, this, tr( "Osc 1 Sync send on rise" ) ), m_osc1SSF( false, this, tr( "Osc 1 Sync send on fall" ) ), @@ -1161,7 +1210,7 @@ MonstroInstrument::MonstroInstrument( InstrumentTrack * _instrument_track ) : connect( &m_env2Dec, SIGNAL( dataChanged() ), this, SLOT( updateEnvelope2() ) ); connect( &m_env2Rel, SIGNAL( dataChanged() ), this, SLOT( updateEnvelope2() ) ); connect( &m_env2Slope, SIGNAL( dataChanged() ), this, SLOT( updateSlope2() ) ); - + // updateLFOAtts connect( &m_lfo1Att, SIGNAL( dataChanged() ), this, SLOT( updateLFOAtts() ) ); @@ -1183,6 +1232,8 @@ MonstroInstrument::MonstroInstrument( InstrumentTrack * _instrument_track ) : updatePO1(); updatePO2(); updatePO3(); + updateSlope1(); + updateSlope2(); } @@ -1206,7 +1257,7 @@ void MonstroInstrument::playNote( NotePlayHandle * _n, ms->renderOutput( frames, _working_buffer ); - applyRelease( _working_buffer, _n ); + //applyRelease( _working_buffer, _n ); // we have our own release instrumentTrack()->processAudioBuffer( _working_buffer, frames, _n ); } @@ -1461,7 +1512,7 @@ QString MonstroInstrument::nodeName() const f_cnt_t MonstroInstrument::desiredReleaseFrames() const { - return 64; + return qMax( 64, qMax( m_env1_relF, m_env2_relF ) ); } @@ -1590,14 +1641,14 @@ void MonstroInstrument::updateSamplerate() void MonstroInstrument::updateSlope1() { const float slope = m_env1Slope.value(); - m_slope1 = powf( 10.0f, slope * -1.0f ); + m_slope1 = powf( 10.0f, slope * -1.0f ); } void MonstroInstrument::updateSlope2() { const float slope = m_env2Slope.value(); - m_slope2 = powf( 10.0f, slope * -1.0f ); + m_slope2 = powf( 10.0f, slope * -1.0f ); } @@ -1842,7 +1893,7 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) maketinyled( m_osc3SyncHButton, 212, O3ROW - 3, "Hard sync oscillator 3" ) maketinyled( m_osc3SyncRButton, 191, O3ROW - 3, "Reverse sync oscillator 3" ) - + m_lfo1WaveBox = new comboBox( view ); m_lfo1WaveBox -> setGeometry( 2, LFOROW + 7, 42, 22 ); m_lfo1WaveBox->setFont( pointSize<8>( m_lfo1WaveBox->font() ) ); diff --git a/plugins/monstro/Monstro.h b/plugins/monstro/Monstro.h index 2b84a1678..4b2066c88 100644 --- a/plugins/monstro/Monstro.h +++ b/plugins/monstro/Monstro.h @@ -178,6 +178,11 @@ const float MAX_FREQ = 48000.0f; const float INTEGRATOR = 3.0f / 7.0f; +const float FM_AMOUNT = 0.25f; + +const float PW_MIN = 0.25f; +const float PW_MAX = 100.0f - PW_MIN; + class MonstroInstrument; class MonstroView; @@ -338,6 +343,8 @@ private: int m_counter3l; int m_counter3r; int m_counterMax; + + float m_fmCorrection; }; class MonstroInstrument : public Instrument diff --git a/plugins/monstro/artwork_mat.png b/plugins/monstro/artwork_mat.png index 1a4240b51..2f783c655 100644 Binary files a/plugins/monstro/artwork_mat.png and b/plugins/monstro/artwork_mat.png differ diff --git a/plugins/monstro/logo.png b/plugins/monstro/logo.png index aace6a3ce..435febc9d 100644 Binary files a/plugins/monstro/logo.png and b/plugins/monstro/logo.png differ diff --git a/plugins/opl2/opl2instrument.cpp b/plugins/opl2/opl2instrument.cpp index 4704f0147..6a169c964 100644 --- a/plugins/opl2/opl2instrument.cpp +++ b/plugins/opl2/opl2instrument.cpp @@ -283,7 +283,7 @@ int opl2instrument::pushVoice(int v) { return i; } -bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time ) +bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { emulatorMutex.lock(); int key, vel, voice, tmp_pb; diff --git a/plugins/opl2/opl2instrument.h b/plugins/opl2/opl2instrument.h index e95357807..e388b0672 100644 --- a/plugins/opl2/opl2instrument.h +++ b/plugins/opl2/opl2instrument.h @@ -53,7 +53,7 @@ public: return IsSingleStreamed | IsMidiBased; } - virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time ); + virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset = 0 ); virtual void play( sampleFrame * _working_buffer ); void saveSettings( QDomDocument & _doc, QDomElement & _this ); diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 4fba5c648..7ce0219fc 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -352,9 +352,9 @@ void sf2Instrument::openFile( const QString & _sf2File, bool updateTrackName ) delete[] sf2Ascii; - if( updateTrackName ) + if( updateTrackName || instrumentTrack()->displayName() == displayName() ) { - instrumentTrack()->setName( QFileInfo( _sf2File ).baseName() ); + instrumentTrack()->setName( QFileInfo( _sf2File ).baseName() ); } } @@ -542,7 +542,7 @@ void sf2Instrument::playNote( NotePlayHandle * _n, sampleFrame * ) { SF2PluginData * pluginData = new SF2PluginData; pluginData->midiNote = midiNote; - pluginData->lastPanning = -1; + pluginData->lastPanning = 0; pluginData->lastVelocity = 127; pluginData->fluidVoice = NULL; @@ -588,7 +588,7 @@ void sf2Instrument::playNote( NotePlayHandle * _n, sampleFrame * ) m_notesRunningMutex.unlock(); } - SF2PluginData * pluginData = static_cast( +/* SF2PluginData * pluginData = static_cast( _n->m_pluginData ); #ifdef SOMEONE_FIXED_PER_NOTE_PANNING if( pluginData->fluidVoice && @@ -620,7 +620,7 @@ void sf2Instrument::playNote( NotePlayHandle * _n, sampleFrame * ) m_synthMutex.unlock(); pluginData->lastVelocity = currentVelocity; - } + }*/ } diff --git a/plugins/sf2_player/sf2_player.h b/plugins/sf2_player/sf2_player.h index e27aa8a8a..728a717cc 100644 --- a/plugins/sf2_player/sf2_player.h +++ b/plugins/sf2_player/sf2_player.h @@ -24,8 +24,8 @@ */ -#ifndef _SF2_PLAYER_H -#define _SF2_PLAYER_H +#ifndef SF2_PLAYER_H +#define SF2_PLAYER_H #include @@ -79,7 +79,7 @@ public: virtual Flags flags() const { - return IsSingleStreamed | IsMidiBased; + return IsSingleStreamed; } virtual PluginView * instantiateView( QWidget * _parent ); diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 31a262771..8f41b36c9 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -237,9 +237,10 @@ void vestigeInstrument::loadFile( const QString & _file ) { m_pluginMutex.lock(); const bool set_ch_name = ( m_plugin != NULL && - instrumentTrack()->name() == m_plugin->name() ) || - instrumentTrack()->name() == - InstrumentTrack::tr( "Default preset" ); + instrumentTrack()->name() == m_plugin->name() ) || + instrumentTrack()->name() == InstrumentTrack::tr( "Default preset" ) || + instrumentTrack()->name() == displayName(); + m_pluginMutex.unlock(); if ( m_plugin != NULL ) @@ -310,12 +311,12 @@ void vestigeInstrument::play( sampleFrame * _buf ) -bool vestigeInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time ) +bool vestigeInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { m_pluginMutex.lock(); if( m_plugin != NULL ) { - m_plugin->processMidiEvent( event, time ); + m_plugin->processMidiEvent( event, offset ); } m_pluginMutex.unlock(); @@ -881,8 +882,9 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume m_vi->m_subWindow = engine::mainWindow()->workspace()->addSubWindow(new QMdiSubWindow, Qt::SubWindow | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); - m_vi->m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); - m_vi->m_subWindow->setFixedSize( 960, 300); + m_vi->m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::MinimumExpanding ); + m_vi->m_subWindow->setFixedWidth( 960 ); + m_vi->m_subWindow->setMinimumHeight( 300 ); m_vi->m_subWindow->setWidget(m_vi->m_scrollArea); m_vi->m_subWindow->setWindowTitle( m_vi->instrumentTrack()->name() + tr( " - VST plugin control" ) ); diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 8a5ce639e..8854e4369 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -68,7 +68,7 @@ public: return IsSingleStreamed | IsMidiBased; } - virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time ); + virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset = 0 ); virtual PluginView * instantiateView( QWidget * _parent ); diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index e088e0931..72af13771 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -153,8 +153,8 @@ void WatsynObject::renderOutput( fpp_t _frames ) const float xt = m_parent->m_xtalk.value(); if( xt > 0.0 ) { - B2_L += ( A1_L * xt ) / 100.0f; - B2_R += ( A1_R * xt ) / 100.0f; + B2_L += ( A1_L * xt ) * 0.01f; + B2_R += ( A1_R * xt ) * 0.01f; } // if phase mod, add to phases diff --git a/plugins/watsyn/Watsyn.h b/plugins/watsyn/Watsyn.h index e863f4991..3e0992144 100644 --- a/plugins/watsyn/Watsyn.h +++ b/plugins/watsyn/Watsyn.h @@ -183,17 +183,25 @@ private: inline void srccpy( float * _dst, float * _src ) { int err; + const int margin = 64; + + // copy to temp array + float * tmp = new float [ GRAPHLEN + margin ]; + memcpy( tmp, _src, sizeof( float ) * GRAPHLEN ); + memcpy( tmp + GRAPHLEN, _src, sizeof( float ) * margin ); SRC_STATE * src_state = src_new( SRC_SINC_FASTEST, 1, &err ); SRC_DATA src_data; - src_data.data_in = _src; - src_data.input_frames = GRAPHLEN; + src_data.data_in = tmp; + src_data.input_frames = GRAPHLEN + margin; src_data.data_out = _dst; src_data.output_frames = WAVELEN; src_data.src_ratio = static_cast( WAVERATIO ); - src_data.end_of_input = 1; + src_data.end_of_input = 0; err = src_process( src_state, &src_data ); if( err ) { qDebug( "Watsyn SRC error: %s", src_strerror( err ) ); } src_delete( src_state ); + + delete tmp; } // memcpy utilizing cubic interpolation diff --git a/plugins/watsyn/logo.png b/plugins/watsyn/logo.png index 3e77966ff..f18957b8d 100644 Binary files a/plugins/watsyn/logo.png and b/plugins/watsyn/logo.png differ diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 8eca9fdae..40c2737c7 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -343,7 +343,7 @@ void ZynAddSubFxInstrument::play( sampleFrame * _buf ) -bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time ) +bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { // do not forward external MIDI Control Change events if the according // LED is not checked diff --git a/plugins/zynaddsubfx/ZynAddSubFx.h b/plugins/zynaddsubfx/ZynAddSubFx.h index ad78b95b4..ac9cdf3cc 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.h +++ b/plugins/zynaddsubfx/ZynAddSubFx.h @@ -70,7 +70,7 @@ public: virtual void play( sampleFrame * _working_buffer ); - virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); + virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ); virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); virtual void loadSettings( const QDomElement & _this ); diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 81649be87..a7af69956 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -432,7 +432,7 @@ float AutomatableModel::fittedValue( float value, bool forceStep ) const void AutomatableModel::linkModel( AutomatableModel* model ) { - if( !m_linkedModels.contains( model ) ) + if( !m_linkedModels.contains( model ) && model != this ) { m_linkedModels.push_back( model ); m_hasLinkedModels = true; @@ -464,8 +464,8 @@ void AutomatableModel::unlinkModel( AutomatableModel* model ) void AutomatableModel::linkModels( AutomatableModel* model1, AutomatableModel* model2 ) { - model1->linkModel( model2 ); - model2->linkModel( model1 ); + model1->linkModel( model2 ); + model2->linkModel( model1 ); } diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 94025a389..c595a422e 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -35,6 +35,8 @@ #include "ProjectJournal.h" #include "bb_track_container.h" #include "song.h" +#include "text_float.h" +#include "embed.h" const float AutomationPattern::DEFAULT_MIN_VALUE = 0; @@ -96,8 +98,8 @@ void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup ) { if( *it == _obj ) { - // Already exists - // TODO: Maybe let the user know in some non-annoying way + textFloat::displayMessage( _obj->displayName(), tr( "Model is already connected " + "to this pattern." ), embed::getIconPixmap( "automation" ), 2000 ); return; } } diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 28e1697aa..8992d592a 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -683,18 +683,6 @@ void DataFile::upgrade() } - // new default colour for B&B tracks - QDomNodeList list = elementsByTagName( "bbtco" ); - for( int i = 0; !list.item( i ).isNull(); ++i ) - { - QDomElement el = list.item( i ).toElement(); - unsigned int rgb = el.attribute( "color" ).toUInt(); - if( rgb == qRgb( 64, 128, 255 ) ) - { - el.setAttribute( "color", bbTCO::defaultColor() ); - } - } - // Time-signature if ( !m_head.hasAttribute( "timesig_numerator" ) ) { diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 263b3df50..d3622a6eb 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -223,13 +223,13 @@ void FxMixer::deleteChannel(int index) } // delete all of this channel's sends and receives - for(int i=0; im_sends.size(); ++i) + while( ! m_fxChannels[index]->m_sends.isEmpty() ) { - deleteChannelSend(index, m_fxChannels[index]->m_sends[i]); + deleteChannelSend( index, m_fxChannels[index]->m_sends.first() ); } - for(int i=0; im_receives.size(); ++i) + while( ! m_fxChannels[index]->m_receives.isEmpty() ) { - deleteChannelSend(m_fxChannels[index]->m_receives[i], index); + deleteChannelSend( m_fxChannels[index]->m_receives.first(), index ); } for(int i=0; im_sends.push_back(toChannel); from->m_sendAmount.push_back(new FloatModel(amount, 0, 1, 0.001, NULL, @@ -364,7 +365,7 @@ void FxMixer::createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel, // add to to's receives m_fxChannels[toChannel]->m_receives.push_back(fromChannel); - + m_sendsMutex.unlock(); } @@ -375,7 +376,7 @@ void FxMixer::deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel) // delete the send FxChannel * from = m_fxChannels[fromChannel]; FxChannel * to = m_fxChannels[toChannel]; - + m_sendsMutex.lock(); // find and delete the send entry for(int i=0; im_sends.size(); ++i) { if( from->m_sends[i] == toChannel ) @@ -398,6 +399,7 @@ void FxMixer::deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel) break; } } + m_sendsMutex.unlock(); } @@ -496,6 +498,7 @@ void FxMixer::masterMix( sampleFrame * _buf ) // and add all channels to job list that have no dependencies // when the channel completes it will check its parent to see if it needs // to be processed. + m_sendsMutex.lock(); MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic ); addChannelLeaf( 0, _buf ); while( m_fxChannels[0]->state() != ThreadableJob::Done ) @@ -503,6 +506,7 @@ void FxMixer::masterMix( sampleFrame * _buf ) MixerWorkerThread::startAndWaitForJobs(); } //m_fxChannels[0]->doProcessing( NULL ); + m_sendsMutex.unlock(); // handle sample-exact data in master volume fader ValueBuffer * volBuf = m_fxChannels[0]->m_volumeModel.hasSampleExactData() @@ -566,9 +570,9 @@ void FxMixer::clearChannel(fx_ch_t index) if( index > 0) { // delete existing sends - for( int i=0; im_sends.size(); ++i) + while( ! ch->m_sends.isEmpty() ) { - deleteChannelSend(index, ch->m_sends[i]); + deleteChannelSend( index, ch->m_sends.first() ); } // add send to master @@ -576,11 +580,10 @@ void FxMixer::clearChannel(fx_ch_t index) } // delete receives - for( int i=0; im_receives.size(); ++i) + while( ! ch->m_receives.isEmpty() ) { - deleteChannelSend(ch->m_receives[i], index); + deleteChannelSend( ch->m_receives.first(), index ); } - } void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this ) diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index 7ffb4a3bb..5549a0d7e 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -235,7 +235,7 @@ void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n ) // time an audio-buffer is rendered... if( ( _n->origin() == NotePlayHandle::OriginArpeggio || ( _n->hasParent() == false && _n->instrumentTrack()->isArpeggioEnabled() == false ) ) && _n->totalFramesPlayed() == 0 && - m_chordsEnabledModel.value() == true ) + m_chordsEnabledModel.value() == true && ! _n->isReleased() ) { // then insert sub-notes for chord const int selected_chord = m_chordsModel.value(); diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 9c35ee852..c9fd9b83c 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -686,13 +686,13 @@ void Mixer::removePlayHandle( PlayHandle * _ph ) -void Mixer::removePlayHandles( track * _track ) +void Mixer::removePlayHandles( track * _track, bool removeIPHs ) { lock(); PlayHandleList::Iterator it = m_playHandles.begin(); while( it != m_playHandles.end() ) { - if( ( *it )->isFromTrack( _track ) ) + if( ( *it )->isFromTrack( _track ) && ( removeIPHs || ( *it )->type() != PlayHandle::TypeInstrumentPlayHandle ) ) { delete *it; it = m_playHandles.erase( it ); diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 9ad49de41..0a3107acd 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -61,13 +61,14 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, m_framesBeforeRelease( 0 ), m_releaseFramesToDo( 0 ), m_releaseFramesDone( 0 ), + m_scheduledNoteOff( -1 ), m_released( false ), m_hasParent( parent != NULL ), m_hadChildren( false ), m_muted( false ), m_bbTrack( NULL ), m_origTempo( engine::getSong()->getTempo() ), - m_origBaseNote( instrumentTrack->baseNoteModel()->value() ), + m_origBaseNote( instrumentTrack->baseNote() ), m_frequency( 0 ), m_unpitchedFrequency( 0 ), m_baseDetuning( NULL ), @@ -100,14 +101,15 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, m_instrumentTrack->midiNoteOn( *this ); } - if( !isMasterNote() || !instrumentTrack->isArpeggioEnabled() ) + if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) { const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity(); // send MidiNoteOn event m_instrumentTrack->processOutEvent( MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ), - MidiTime::fromFrames( offset(), engine::framesPerTick() ) ); + MidiTime::fromFrames( offset(), engine::framesPerTick() ), + offset() ); } } @@ -117,7 +119,14 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, NotePlayHandle::~NotePlayHandle() { noteOff( 0 ); - + if( m_scheduledNoteOff >= 0 ) // ensure that scheduled noteoffs get triggered if somehow the nph got destructed prematurely + { + m_instrumentTrack->processOutEvent( + MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ), + MidiTime::fromFrames( m_scheduledNoteOff, engine::framesPerTick() ), + m_scheduledNoteOff ); + } + if( hasParent() == false ) { delete m_baseDetuning; @@ -173,7 +182,7 @@ void NotePlayHandle::setPanning( panning_t panning ) int NotePlayHandle::midiKey() const { - return key() - m_origBaseNote + instrumentTrack()->baseNoteModel()->value(); + return key() - m_origBaseNote + instrumentTrack()->baseNote(); } @@ -181,6 +190,15 @@ int NotePlayHandle::midiKey() const void NotePlayHandle::play( sampleFrame * _working_buffer ) { + if( m_scheduledNoteOff >= 0 ) // always trigger scheduled noteoffs, because they're only scheduled if the note is released + { + m_instrumentTrack->processOutEvent( + MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ), + MidiTime::fromFrames( m_scheduledNoteOff, engine::framesPerTick() ), + m_scheduledNoteOff ); + m_scheduledNoteOff = -1; + } + if( m_muted ) { return; @@ -188,7 +206,7 @@ void NotePlayHandle::play( sampleFrame * _working_buffer ) if( m_released == false && instrumentTrack()->isSustainPedalPressed() == false && - m_totalFramesPlayed + engine::mixer()->framesPerPeriod() >= m_frames ) + m_totalFramesPlayed + engine::mixer()->framesPerPeriod() > m_frames ) { noteOff( m_frames - m_totalFramesPlayed ); } @@ -211,7 +229,7 @@ void NotePlayHandle::play( sampleFrame * _working_buffer ) // because we do not allow NotePlayHandle::isFinished() to be true // until all sub-notes are completely played and no new ones // are inserted by arpAndChordsTabWidget::processNote() - if( isMasterNote() ) + if( ! m_subNotes.isEmpty() ) { m_releaseFramesToDo = m_releaseFramesDone + 2 * engine::mixer()->framesPerPeriod(); } @@ -288,9 +306,9 @@ f_cnt_t NotePlayHandle::framesLeft() const { return m_framesBeforeRelease; } - else if( m_released && actualReleaseFramesToDo() >= m_releaseFramesDone ) + else if( m_released ) { - return m_framesBeforeRelease + actualReleaseFramesToDo() - m_releaseFramesDone; + return m_framesBeforeRelease + m_releaseFramesToDo - m_releaseFramesDone; } return m_frames+actualReleaseFramesToDo()-m_totalFramesPlayed; } @@ -329,14 +347,23 @@ void NotePlayHandle::noteOff( const f_cnt_t _s ) // then set some variables indicating release-state m_framesBeforeRelease = _s; - m_releaseFramesToDo = qMax( 0, m_instrumentTrack->m_soundShaping.releaseFrames() ); + m_releaseFramesToDo = qMax( 0, actualReleaseFramesToDo() ); - if( hasParent() || !instrumentTrack()->isArpeggioEnabled() ) + if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) { // send MidiNoteOff event - m_instrumentTrack->processOutEvent( - MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ), - MidiTime::fromFrames( m_framesBeforeRelease, engine::framesPerTick() ) ); + f_cnt_t realOffset = offset() + _s; // get actual frameoffset of release, in global time + if( realOffset < engine::mixer()->framesPerPeriod() ) // if release happens during this period, trigger midievent + { + m_instrumentTrack->processOutEvent( + MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ), + MidiTime::fromFrames( realOffset, engine::framesPerTick() ), + realOffset ); + } + else // if release flows over to next period, use m_scheduledNoteOff to trigger it later + { + m_scheduledNoteOff = realOffset - engine::mixer()->framesPerPeriod(); + } } // inform attached components about MIDI finished (used for recording in Piano Roll) diff --git a/src/core/ladspa_manager.cpp b/src/core/ladspa_manager.cpp index 4d78ebc5d..bd533fb87 100644 --- a/src/core/ladspa_manager.cpp +++ b/src/core/ladspa_manager.cpp @@ -46,10 +46,11 @@ ladspaManager::ladspaManager() ladspaDirectories.push_back( configManager::inst()->pluginDir() + "ladspa" ); #ifndef LMMS_BUILD_WIN32 ladspaDirectories.push_back( qApp->applicationDirPath() + '/' + LIB_DIR + "ladspa" ); - ladspaDirectories.push_back( "/usr/lib/lmms/ladspa" ); - ladspaDirectories.push_back( "/usr/local/lib/lmms/ladspa" ); ladspaDirectories.push_back( "/usr/lib/ladspa" ); + ladspaDirectories.push_back( "/usr/lib64/ladspa" ); ladspaDirectories.push_back( "/usr/local/lib/ladspa" ); + ladspaDirectories.push_back( "/usr/local/lib64/ladspa" ); + ladspaDirectories.push_back( "/Library/Audio/Plug-Ins/LADSPA" ); #endif for( QStringList::iterator it = ladspaDirectories.begin(); diff --git a/src/core/midi/MidiController.cpp b/src/core/midi/MidiController.cpp index b6e3f44dc..042429b49 100644 --- a/src/core/midi/MidiController.cpp +++ b/src/core/midi/MidiController.cpp @@ -81,7 +81,7 @@ void MidiController::updateName() -void MidiController::processInEvent( const MidiEvent& event, const MidiTime& time ) +void MidiController::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { unsigned char controllerNum; switch( event.type() ) diff --git a/src/core/song.cpp b/src/core/song.cpp index 735bfdba4..961bcd9d7 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -1201,12 +1201,28 @@ void song::exportProject(bool multiExport) efd.setAcceptMode( FileDialog::AcceptSave ); - if( efd.exec() == QDialog::Accepted && - !efd.selectedFiles().isEmpty() && !efd.selectedFiles()[0].isEmpty() ) + if( efd.exec() == QDialog::Accepted && !efd.selectedFiles().isEmpty() && !efd.selectedFiles()[0].isEmpty() ) { - const QString export_file_name = efd.selectedFiles()[0]; - exportProjectDialog epd( export_file_name, - engine::mainWindow(), multiExport ); + QString suffix = ""; + if ( !multiExport ) + { + int stx = efd.selectedNameFilter().indexOf( "(*." ); + int etx = efd.selectedNameFilter().indexOf( ")" ); + + if ( stx > 0 && etx > stx ) + { + // Get first extension from selected dropdown. + // i.e. ".wav" from "WAV-File (*.wav), Dummy-File (*.dum)" + suffix = efd.selectedNameFilter().mid( stx + 2, etx - stx - 2 ).split( " " )[0].trimmed(); + if ( efd.selectedFiles()[0].endsWith( suffix ) ) + { + suffix = ""; + } + } + } + + const QString export_file_name = efd.selectedFiles()[0] + suffix; + exportProjectDialog epd( export_file_name, engine::mainWindow(), multiExport ); epd.exec(); } } diff --git a/src/core/track.cpp b/src/core/track.cpp index 664fd67a2..5de2a120a 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -998,14 +998,7 @@ bool trackContentObjectView::mouseMovedDistance( QMouseEvent * _me, int distance */ trackContentWidget::trackContentWidget( trackView * _parent ) : QWidget( _parent ), - m_trackView( _parent ), - m_darkerColor1( 0, 0, 0 ), - m_darkerColor2( 0, 0, 0 ), - m_darkerColor3( 0, 0, 0 ), - m_lighterColor1( 0, 0, 0 ), - m_lighterColor2( 0, 0, 0 ), - m_lighterColor3( 0, 0, 0 ), - m_gradMidPoint( 0.0f ) + m_trackView( _parent ) { setAcceptDrops( true ); @@ -1045,17 +1038,8 @@ void trackContentWidget::updateBackground() m_background = QPixmap( w * 2, height() ); QPainter pmp( &m_background ); - QLinearGradient grad( 0,0, 0, h ); - grad.setColorAt( 0.0, darkerColor1() ); - grad.setColorAt( gradMidPoint(), darkerColor2() ); - grad.setColorAt( 1.0, darkerColor3() ); - pmp.fillRect( 0, 0, w, h, grad ); - - QLinearGradient grad2( 0,0, 0, h ); - grad2.setColorAt( 0.0, lighterColor1() ); - grad2.setColorAt( gradMidPoint(), lighterColor2() ); - grad2.setColorAt( 1.0, lighterColor3() ); - pmp.fillRect( w, 0, w , h, grad2 ); + pmp.fillRect( 0, 0, w, h, darkerColor() ); + pmp.fillRect( w, 0, w , h, lighterColor() ); // draw lines pmp.setPen( QPen( QColor( 0, 0, 0, 160 ), 1 ) ); @@ -1534,61 +1518,20 @@ MidiTime trackContentWidget::endPosition( const MidiTime & _pos_start ) // qproperty access methods //! \brief CSS theming qproperty access method -QColor trackContentWidget::darkerColor1() const -{ return m_darkerColor1; } +QBrush trackContentWidget::darkerColor() const +{ return m_darkerColor; } //! \brief CSS theming qproperty access method -QColor trackContentWidget::darkerColor2() const -{ return m_darkerColor2; } +QBrush trackContentWidget::lighterColor() const +{ return m_lighterColor; } //! \brief CSS theming qproperty access method -QColor trackContentWidget::darkerColor3() const -{ return m_darkerColor3; } +void trackContentWidget::setDarkerColor( const QBrush & c ) +{ m_darkerColor = c; } //! \brief CSS theming qproperty access method -QColor trackContentWidget::lighterColor1() const -{ return m_lighterColor1; } - -//! \brief CSS theming qproperty access method -QColor trackContentWidget::lighterColor2() const -{ return m_lighterColor2; } - -//! \brief CSS theming qproperty access method -QColor trackContentWidget::lighterColor3() const -{ return m_lighterColor3; } - -//! \brief CSS theming qproperty access method -void trackContentWidget::setDarkerColor1( const QColor & _c ) -{ m_darkerColor1 = QColor( _c ); } - -//! \brief CSS theming qproperty access method -void trackContentWidget::setDarkerColor2( const QColor & _c ) -{ m_darkerColor2 = QColor( _c ); } - -//! \brief CSS theming qproperty access method -void trackContentWidget::setDarkerColor3( const QColor & _c ) -{ m_darkerColor3 = QColor( _c ); } - -//! \brief CSS theming qproperty access method -void trackContentWidget::setLighterColor1( const QColor & _c ) -{ m_lighterColor1 = QColor( _c ); } - -//! \brief CSS theming qproperty access method -void trackContentWidget::setLighterColor2( const QColor & _c ) -{ m_lighterColor2 = QColor( _c ); } - -//! \brief CSS theming qproperty access method -void trackContentWidget::setLighterColor3( const QColor & _c ) -{ m_lighterColor3 = QColor( _c ); } - -//! \brief CSS theming qproperty access method -float trackContentWidget::gradMidPoint() const -{ return m_gradMidPoint; } - -//! \brief CSS theming qproperty access method -void trackContentWidget::setGradMidPoint( float _g ) -{ m_gradMidPoint = _g; } - +void trackContentWidget::setLighterColor( const QBrush & c ) +{ m_lighterColor = c; } diff --git a/src/gui/AutomationEditor.cpp b/src/gui/AutomationEditor.cpp index 9c4536ca2..71abe18c1 100644 --- a/src/gui/AutomationEditor.cpp +++ b/src/gui/AutomationEditor.cpp @@ -1,6 +1,6 @@ /* * AutomationEditor.cpp - implementation of AutomationEditor which is used for - * actual setting of dynamic values + * actual setting of dynamic values * * Copyright (c) 2008-2014 Tobias Doerffel * Copyright (c) 2008-2013 Paul Giblock @@ -71,8 +71,6 @@ QPixmap * AutomationEditor::s_toolSelect = NULL; QPixmap * AutomationEditor::s_toolMove = NULL; -const QColor DRAGGABLE_PIN_COLOR = QColor( 0xFF, 0x00, 0x00 ); -const QColor DRAGGABLE_PIN_BORDER_COLOR = QColor( 0xFF, 0xFF, 0xFF ); AutomationEditor::AutomationEditor() : @@ -98,7 +96,11 @@ AutomationEditor::AutomationEditor() : m_y_delta( DEFAULT_Y_DELTA ), m_y_auto( TRUE ), m_editMode( DRAW ), - m_scrollBack( FALSE ) + m_scrollBack( FALSE ), + m_gridColor( 0,0,0 ), + m_graphColor(), + m_vertexColor( 0,0,0 ), + m_scaleColor() { connect( this, SIGNAL( currentPatternChanged() ), this, SLOT( updateAfterPatternChange() ), @@ -358,7 +360,7 @@ AutomationEditor::AutomationEditor() : m_zoomingYComboBox->setFixedSize( 80, 22 ); m_zoomingYModel.addItem( "Auto" ); - for( int i = 0; i < 6; ++i ) + for( int i = 0; i < 7; ++i ) { m_zoomingYModel.addItem( QString::number( 25 << i ) + "%" ); } @@ -377,15 +379,13 @@ AutomationEditor::AutomationEditor() : m_quantizeComboBox = new comboBox( m_toolBar ); m_quantizeComboBox->setFixedSize( 60, 22 ); - // TODO: leak - ComboBoxModel * quantize_model = new ComboBoxModel( /* this */ ); for( int i = 0; i < 7; ++i ) { - quantize_model->addItem( "1/" + QString::number( 1 << i ) ); + m_quantizeModel.addItem( "1/" + QString::number( 1 << i ) ); } - quantize_model->setValue( quantize_model->findText( "1/16" ) ); + m_quantizeModel.setValue( m_quantizeModel.findText( "1/16" ) ); - m_quantizeComboBox->setModel( quantize_model ); + m_quantizeComboBox->setModel( &m_quantizeModel ); tb_layout->addSpacing( 5 ); @@ -456,6 +456,7 @@ AutomationEditor::~AutomationEditor() { m_zoomingXModel.disconnect(); m_zoomingYModel.disconnect(); + m_quantizeModel.disconnect(); m_tensionModel->disconnect(); } @@ -502,6 +503,24 @@ void AutomationEditor::setPauseIcon( bool pause ) } } +// qproperty access methods + +QColor AutomationEditor::gridColor() const +{ return m_gridColor; } +QBrush AutomationEditor::graphColor() const +{ return m_graphColor; } +QColor AutomationEditor::vertexColor() const +{ return m_vertexColor; } +QBrush AutomationEditor::scaleColor() const +{ return m_scaleColor; } +void AutomationEditor::setGridColor( const QColor & c ) +{ m_gridColor = c; } +void AutomationEditor::setGraphColor( const QBrush & c ) +{ m_graphColor = c; } +void AutomationEditor::setVertexColor( const QColor & c ) +{ m_vertexColor = c; } +void AutomationEditor::setScaleColor( const QBrush & c ) +{ m_scaleColor = c; } @@ -1350,13 +1369,10 @@ inline void AutomationEditor::drawAutomationPoint( QPainter & p, timeMap::iterat { int x = xCoordOfTick( it.key() ); int y = yCoordOfLevel( it.value() ); - int outerRadius = qMin( 8, m_ppt/quantization() ); - int innerRadius = qMax( 0, outerRadius-2 ); - p.setBrush( QBrush( DRAGGABLE_PIN_BORDER_COLOR ) ); - p.drawEllipse( x-outerRadius/2, y-outerRadius/2, outerRadius, outerRadius ); - p.setBrush( QBrush( DRAGGABLE_PIN_COLOR ) ); - p.drawEllipse( x-innerRadius/2, y-innerRadius/2, innerRadius, innerRadius ); - p.setBrush( QBrush() ); + const int outerRadius = qBound( 2, ( m_ppt * quantization() ) / 576, 5 ); // man, getting this calculation right took forever + p.setPen( QPen( vertexColor().lighter( 200 ) ) ); + p.setBrush( QBrush( vertexColor() ) ); + p.drawEllipse( x - outerRadius, y - outerRadius, outerRadius * 2, outerRadius * 2 ); } @@ -1371,6 +1387,12 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) QPainter p( this ); style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this ); + // get foreground color + QColor fgColor = p.pen().brush().color(); + // get background color and fill background + QBrush bgColor = p.background(); + p.fillRect( 0, 0, width(), height(), bgColor ); + // set font-size to 8 p.setFont( pointSize<8>( p.font() ) ); @@ -1380,7 +1402,7 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) int grid_bottom = height() - SCROLLBAR_SIZE - 1; p.fillRect( 0, TOP_MARGIN, VALUES_WIDTH, height() - TOP_MARGIN, - QColor( 0x33, 0x33, 0x33 ) ); + scaleColor() ); // print value numbers int font_height = p.fontMetrics().height(); @@ -1397,11 +1419,12 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) { const QString & label = m_pattern->firstObject() ->displayValue( level[i] ); - p.setPen( QColor( 240, 240, 240 ) ); + p.setPen( QApplication::palette().color( QPalette::Active, + QPalette::Shadow ) ); p.drawText( 1, y[i] - font_height + 1, VALUES_WIDTH - 10, 2 * font_height, text_flags, label ); - p.setPen( QColor( 0, 0, 0 ) ); + p.setPen( fgColor ); p.drawText( 0, y[i] - font_height, VALUES_WIDTH - 10, 2 * font_height, text_flags, label ); @@ -1425,11 +1448,12 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) const QString & label = m_pattern->firstObject() ->displayValue( level ); y = yCoordOfLevel( level ); - p.setPen( QColor( 240, 240, 240 ) ); + p.setPen( QApplication::palette().color( QPalette::Active, + QPalette::Shadow ) ); p.drawText( 1, y - font_height + 1, VALUES_WIDTH - 10, 2 * font_height, text_flags, label ); - p.setPen( QColor( 0, 0, 0 ) ); + p.setPen( fgColor ); p.drawText( 0, y - font_height, VALUES_WIDTH - 10, 2 * font_height, text_flags, label ); @@ -1443,6 +1467,7 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) grid_height ); // draw vertical raster + QColor lineColor = QColor( gridColor() ); if( m_pattern ) { int tick, x; @@ -1454,38 +1479,42 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) // exotic denominators (e.g. 7/11 time), which are allowed ATM. // First quantization grid... for( tick = m_currentPosition - m_currentPosition % quantization(), - x = xCoordOfTick( tick ); - x<=width(); - tick += quantization(), x = xCoordOfTick( tick ) ) - { - p.setPen( QColor( 0x2F, 0x2F, 0x2F ) ); + x = xCoordOfTick( tick ); + x<=width(); + tick += quantization(), x = xCoordOfTick( tick ) ) + { + lineColor.setAlpha( 80 ); + p.setPen( lineColor ); p.drawLine( x, grid_bottom, x, x_line_end ); } - // Then beat grid - int ticksPerBeat = DefaultTicksPerTact / + // Then beat grid + int ticksPerBeat = DefaultTicksPerTact / engine::getSong()->getTimeSigModel().getDenominator(); for( tick = m_currentPosition - m_currentPosition % ticksPerBeat, - x = xCoordOfTick( tick ); - x<=width(); - tick += ticksPerBeat, x = xCoordOfTick( tick ) ) - { - p.setPen( QColor( 0x5F, 0x5F, 0x5F ) ); + x = xCoordOfTick( tick ); + x<=width(); + tick += ticksPerBeat, x = xCoordOfTick( tick ) ) + { + lineColor.setAlpha( 160 ); + p.setPen( lineColor ); p.drawLine( x, grid_bottom, x, x_line_end ); } // and finally bars for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerTact(), - x = xCoordOfTick( tick ); - x<=width(); - tick += MidiTime::ticksPerTact(), x = xCoordOfTick( tick ) ) + x = xCoordOfTick( tick ); + x<=width(); + tick += MidiTime::ticksPerTact(), x = xCoordOfTick( tick ) ) { - p.setPen( QColor( 0x7F, 0x7F, 0x7F ) ); + lineColor.setAlpha( 255 ); + p.setPen( lineColor ); p.drawLine( x, grid_bottom, x, x_line_end ); } - + /// \todo move this horizontal line drawing code into the same loop as the value ticks? if( m_y_auto ) { - QPen pen( QColor( 0x4F, 0x4F, 0x4F ) ); + lineColor.setAlpha( 160 ); + QPen pen( lineColor ); p.setPen( pen ); p.drawLine( VALUES_WIDTH, grid_bottom, width(), grid_bottom ); @@ -1506,11 +1535,13 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) y = yCoordOfLevel( (float)level ); if( level % 5 == 0 ) { - p.setPen( QColor( 0x4F, 0x4F, 0x4F ) ); + lineColor.setAlpha( 160 ); + p.setPen( lineColor ); } else { - p.setPen( QColor( 0x3F, 0x3F, 0x3F ) ); + lineColor.setAlpha( 80 ); + p.setPen( lineColor ); } // draw level line @@ -1547,8 +1578,7 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) //Don't bother doing/rendering anything if there is no automation points if( time_map.size() > 0 ) { - timeMap::iterator it = time_map.begin(); - p.setPen( QColor( 0xCF, 0xD9, 0xFF ) ); + timeMap::iterator it = time_map.begin(); while( it+1 != time_map.end() ) { // skip this section if it occurs completely before the @@ -1585,10 +1615,11 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) { is_selected = TRUE; } - + float *values = m_pattern->valuesAfter( it.key() ); for( int i = 0; i < (it+1).key() - it.key(); i++ ) { + drawLevelTick( p, it.key() + i, values[i], is_selected ); } @@ -1617,7 +1648,8 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) QFont f = p.font(); f.setBold( TRUE ); p.setFont( pointSize<14>( f ) ); - p.setPen( QColor( 74, 253, 133 ) ); + p.setPen( QApplication::palette().color( QPalette::Active, + QPalette::BrightText ) ); p.drawText( VALUES_WIDTH + 20, TOP_MARGIN + 40, width() - VALUES_WIDTH - 20 - SCROLLBAR_SIZE, grid_height - 40, Qt::TextWordWrap, @@ -1736,17 +1768,18 @@ void AutomationEditor::drawLevelTick( QPainter & _p, int _tick, float _level, rect_height = (int)( _level * m_y_delta ); } - QColor current_color( 0x9F, 0xAF, 0xFF ); - if( _is_selected == TRUE ) - { - current_color.setRgb( 0x00, 0x40, 0xC0 ); - } - _p.fillRect( x, y_start, rect_width, rect_height, current_color ); + QBrush currentColor = _is_selected + ? QBrush( QColor( 0x00, 0x40, 0xC0 ) ) + : graphColor(); + + _p.fillRect( x, y_start, rect_width, rect_height, currentColor ); } + else { printf("not in range\n"); } + } @@ -1798,26 +1831,49 @@ void AutomationEditor::resizeEvent( QResizeEvent * ) void AutomationEditor::wheelEvent( QWheelEvent * _we ) { _we->accept(); - if( _we->modifiers() & Qt::ControlModifier ) + if( _we->modifiers() & Qt::ControlModifier && _we->modifiers() & Qt::ShiftModifier ) { + int y = m_zoomingYModel.value(); if( _we->delta() > 0 ) { - m_ppt = qMin( m_ppt * 2, m_y_delta * - DEFAULT_STEPS_PER_TACT * 8 ); + y++; } - else if( m_ppt >= 72 ) + if( _we->delta() < 0 ) { - m_ppt /= 2; + y--; } - // update combobox with zooming-factor - m_zoomingXComboBox->model()->setValue( - m_zoomingXComboBox->model()->findText( QString::number( - qRound( m_ppt * 100 / - DEFAULT_PPT ) ) +"%" ) ); - // update timeline - m_timeLine->setPixelsPerTact( m_ppt ); + y = qBound( 0, y, m_zoomingYModel.size() - 1 ); + m_zoomingYModel.setValue( y ); + } + else if( _we->modifiers() & Qt::ControlModifier && _we->modifiers() & Qt::AltModifier ) + { + int q = m_quantizeModel.value(); + if( _we->delta() > 0 ) + { + q--; + } + if( _we->delta() < 0 ) + { + q++; + } + q = qBound( 0, q, m_quantizeModel.size() - 1 ); + m_quantizeModel.setValue( q ); update(); } + else if( _we->modifiers() & Qt::ControlModifier ) + { + int x = m_zoomingXModel.value(); + if( _we->delta() > 0 ) + { + x++; + } + if( _we->delta() < 0 ) + { + x--; + } + x = qBound( 0, x, m_zoomingXModel.size() - 1 ); + m_zoomingXModel.setValue( x ); + } else if( _we->modifiers() & Qt::ShiftModifier || _we->orientation() == Qt::Horizontal ) { diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index 7f0f22194..51c2ae397 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -391,14 +391,6 @@ void AutomationPatternView::dropEvent( QDropEvent * _de ) { engine::automationEditor()->setCurrentPattern( m_pat ); } - - //This is the only model that's just added to AutomationPattern. - if( m_pat->m_objects.size() == 1 ) - { - //scale the points to fit the new min. and max. value - this->scaleTimemapToFit( AutomationPattern::DEFAULT_MIN_VALUE, - AutomationPattern::DEFAULT_MAX_VALUE ); - } } else { diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 466807c4b..f55112e26 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -48,7 +47,6 @@ #include "song.h" #include "bb_track_container.h" - FxMixerView::FxMixerView() : QWidget(), ModelView( NULL, this ), @@ -77,10 +75,18 @@ FxMixerView::FxMixerView() : chLayout->setMargin( 0 ); m_channelAreaWidget->setLayout(chLayout); + // create rack layout before creating the first channel + m_racksWidget = new QWidget; + m_racksLayout = new QStackedLayout( m_racksWidget ); + m_racksLayout->setContentsMargins( 0, 0, 0, 0 ); + m_racksWidget->setLayout( m_racksLayout ); + // add master channel m_fxChannelViews.resize( m->numChannels() ); m_fxChannelViews[0] = new FxChannelView( this, this, 0 ); + m_racksLayout->addWidget( m_fxChannelViews[0]->m_rackView ); + FxChannelView * masterView = m_fxChannelViews[0]; ml->addWidget( masterView->m_fxLine, 0, Qt::AlignTop ); @@ -118,17 +124,15 @@ FxMixerView::FxMixerView() : ml->addWidget(channelArea); // show the add new effect channel button - QPushButton * newChannelBtn = new QPushButton("new", this ); - newChannelBtn->setFont(QFont("sans-serif", 10, 1, false)); - newChannelBtn->setFixedSize(fxLineSize); - connect( newChannelBtn, SIGNAL(clicked()), this, SLOT(addNewChannel())); + QPushButton * newChannelBtn = new QPushButton( embed::getIconPixmap( "new_channel" ), QString::null, this ); + newChannelBtn->setObjectName( "newChannelBtn" ); + newChannelBtn->setFixedSize( fxLineSize ); + connect( newChannelBtn, SIGNAL( clicked() ), this, SLOT( addNewChannel() ) ); ml->addWidget( newChannelBtn, 0, Qt::AlignTop ); - // Create EffectRack and set initial index to master channel - m_rackView = new EffectRackView( &m->m_fxChannels[0]->m_fxChain, this ); - m_rackView->setFixedSize( 245, fxLineSize.height() ); - ml->addWidget( m_rackView, 0, Qt::AlignTop ); + // add the stacked layout for the effect racks of fx channels + ml->addWidget( m_racksWidget, 0, Qt::AlignTop ); setCurrentFxLine( m_fxChannelViews[0]->m_fxLine ); @@ -170,7 +174,8 @@ void FxMixerView::addNewChannel() int newChannelIndex = mix->createChannel(); m_fxChannelViews.push_back(new FxChannelView(m_channelAreaWidget, this, newChannelIndex)); - chLayout->addWidget(m_fxChannelViews[newChannelIndex]->m_fxLine); + chLayout->addWidget( m_fxChannelViews[newChannelIndex]->m_fxLine ); + m_racksLayout->addWidget( m_fxChannelViews[newChannelIndex]->m_rackView ); updateFxLine(newChannelIndex); @@ -188,6 +193,7 @@ void FxMixerView::refreshDisplay() delete m_fxChannelViews[i]->m_muteBtn; delete m_fxChannelViews[i]->m_fxLine; delete m_fxChannelViews[i]; + m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView ); } m_channelAreaWidget->adjustSize(); @@ -197,6 +203,7 @@ void FxMixerView::refreshDisplay() { m_fxChannelViews[i] = new FxChannelView(m_channelAreaWidget, this, i); chLayout->addWidget(m_fxChannelViews[i]->m_fxLine); + m_racksLayout->addWidget( m_fxChannelViews[i]->m_rackView ); } // set selected fx line to 0 @@ -257,7 +264,7 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, FxMixer * m = engine::fxMixer(); m_fader = new fader( &m->effectChannel(_chIndex)->m_volumeModel, tr( "FX Fader %1" ).arg( _chIndex ), m_fxLine ); - m_fader->move( 15-m_fader->width()/2, + m_fader->move( 16-m_fader->width()/2, m_fxLine->height()- m_fader->height()-5 ); @@ -270,6 +277,10 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, m_muteBtn->setCheckable( true ); m_muteBtn->move( 9, m_fader->y()-16); toolTip::add( m_muteBtn, tr( "Mute this FX channel" ) ); + + // Create EffectRack for the channel + m_rackView = new EffectRackView( &m->effectChannel(_chIndex)->m_fxChain, _mv->m_racksWidget ); + m_rackView->setFixedSize( 245, FxLine::FxLineHeight ); } @@ -277,7 +288,7 @@ void FxMixerView::setCurrentFxLine( FxLine * _line ) { // select m_currentFxLine = _line; - m_rackView->setModel( &engine::fxMixer()->m_fxChannels[_line->channelIndex()]->m_fxChain ); + m_racksLayout->setCurrentWidget( m_fxChannelViews[ _line->channelIndex() ]->m_rackView ); // set up send knob for(int i = 0; i < m_fxChannelViews.size(); ++i) @@ -333,6 +344,9 @@ void FxMixerView::deleteChannel(int index) delete m_fxChannelViews[index]; m_channelAreaWidget->adjustSize(); + // delete the fx rack + m_racksLayout->removeWidget( m_fxChannelViews[index]->m_rackView ); + // make sure every channel knows what index it is for(int i=0; im_muteBtn; delete m_fxChannelViews[i]->m_fxLine; delete m_fxChannelViews[i]; + m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView ); // add it again - m_fxChannelViews[i] = new FxChannelView(m_channelAreaWidget, this, i); - chLayout->insertWidget(replaceIndex, m_fxChannelViews[i]->m_fxLine); + m_fxChannelViews[i] = new FxChannelView( m_channelAreaWidget, this, i ); + chLayout->insertWidget( replaceIndex, m_fxChannelViews[i]->m_fxLine ); + m_racksLayout->insertWidget( replaceIndex, m_fxChannelViews[i]->m_rackView ); } // keep selected channel @@ -449,8 +465,6 @@ void FxMixerView::setCurrentFxLine( int _line ) void FxMixerView::clear() { - m_rackView->clearViews(); - engine::fxMixer()->clear(); refreshDisplay(); diff --git a/src/gui/PianoRoll.cpp b/src/gui/PianoRoll.cpp index a4f3847a5..59a1cd488 100644 --- a/src/gui/PianoRoll.cpp +++ b/src/gui/PianoRoll.cpp @@ -172,7 +172,11 @@ PianoRoll::PianoRoll() : m_editMode( ModeDraw ), m_mouseDownLeft( false ), m_mouseDownRight( false ), - m_scrollBack( false ) + m_scrollBack( false ), + m_gridColor( 0, 0, 0 ), + m_noteModeColor( 0, 0, 0 ), + m_noteColor( 0, 0, 0 ), + m_barColor( 0, 0, 0 ) { // gui names of edit modes m_nemStr.push_back( tr( "Note Volume" ) ); @@ -832,10 +836,36 @@ void PianoRoll::setPauseIcon( bool pause ) } +/** \brief qproperty access implementation */ + +QColor PianoRoll::gridColor() const +{ return m_gridColor; } + +void PianoRoll::setGridColor( const QColor & c ) +{ m_gridColor = c; } + +QColor PianoRoll::noteModeColor() const +{ return m_noteModeColor; } + +void PianoRoll::setNoteModeColor( const QColor & c ) +{ m_noteModeColor = c; } + +QColor PianoRoll::noteColor() const +{ return m_noteColor; } + +void PianoRoll::setNoteColor( const QColor & c ) +{ m_noteColor = c; } + +QColor PianoRoll::barColor() const +{ return m_barColor; } + +void PianoRoll::setBarColor( const QColor & c ) +{ m_barColor = c; } + inline void PianoRoll::drawNoteRect( QPainter & _p, int _x, int _y, - int _width, note * _n ) + int _width, note * _n, const QColor & noteCol ) { ++_x; ++_y; @@ -846,9 +876,8 @@ inline void PianoRoll::drawNoteRect( QPainter & _p, int _x, int _y, _width = 2; } - int volVal = qMin( 255, (int) ( - ( (float)( _n->getVolume() - MinVolume ) ) / - ( (float)( MaxVolume - MinVolume ) ) * 255.0f) ); + int volVal = qMin( 255, 25 + (int) ( ( (float)( _n->getVolume() - MinVolume ) ) / + ( (float)( MaxVolume - MinVolume ) ) * 230.0f) ); float rightPercent = qMin( 1.0f, ( (float)( _n->getPanning() - PanningLeft ) ) / ( (float)( PanningRight - PanningLeft ) ) * 2.0f ); @@ -857,8 +886,7 @@ inline void PianoRoll::drawNoteRect( QPainter & _p, int _x, int _y, ( (float)( PanningRight - _n->getPanning() ) ) / ( (float)( PanningRight - PanningLeft ) ) * 2.0f ); - const QColor defaultNoteColor( 0x77, 0xC7, 0xD8 ); - QColor col = defaultNoteColor; + QColor col = QColor( noteCol ); if( _n->length() < 0 ) { @@ -894,13 +922,13 @@ inline void PianoRoll::drawNoteRect( QPainter & _p, int _x, int _y, _p.setPen( Qt::SolidLine ); _p.setBrush( Qt::NoBrush ); - col = defaultNoteColor; + col = QColor( noteCol ); _p.setPen( QColor::fromHsv( col.hue(), col.saturation(), qMin( 255, volVal*1.7f ) ) ); _p.drawLine( _x, _y, _x + _width, _y ); _p.drawLine( _x, _y, _x, _y + KEY_LINE_HEIGHT - 2 ); - col = defaultNoteColor; + col = QColor( noteCol ); _p.setPen( QColor::fromHsv( col.hue(), col.saturation(), volVal/1.7 ) ); _p.drawLine( _x + _width, _y, _x + _width, _y + KEY_LINE_HEIGHT - 2 ); _p.drawLine( _x, _y + KEY_LINE_HEIGHT - 2, _x + _width, @@ -908,7 +936,7 @@ inline void PianoRoll::drawNoteRect( QPainter & _p, int _x, int _y, // that little tab thing on the end hinting at the user // to resize the note - _p.setPen( defaultNoteColor.lighter( 200 ) ); + _p.setPen( noteCol.lighter( 200 ) ); if( _width > 2 ) { _p.drawLine( _x + _width - 3, _y + 2, _x + _width - 3, @@ -927,7 +955,7 @@ inline void PianoRoll::drawDetuningInfo( QPainter & _p, note * _n, int _x, int _y ) { int middle_y = _y + KEY_LINE_HEIGHT / 2; - _p.setPen( QColor( 0x99, 0xAF, 0xFF ) ); + _p.setPen( noteColor() ); int old_x = 0; int old_y = 0; @@ -2851,11 +2879,19 @@ static void printNoteHeights(QPainter& p, int bottom, int width, int startKey) void PianoRoll::paintEvent( QPaintEvent * _pe ) { + QColor horizCol = QColor( gridColor() ); + QColor vertCol = QColor( gridColor() ); + QStyleOption opt; opt.initFrom( this ); QPainter p( this ); style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this ); + QBrush bgColor = p.background(); + + // fill with bg color + p.fillRect( 0,0, width(), height(), bgColor ); + // set font-size to 8 p.setFont( pointSize<8>( p.font() ) ); @@ -2965,21 +3001,19 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) // label C-keys... if( static_cast( key % KeysPerOctave ) == Key_C ) { + const QString cLabel = "C" + QString::number( static_cast( key / KeysPerOctave ) ); p.setPen( QColor( 240, 240, 240 ) ); - p.drawText( C_KEY_LABEL_X + 1, y+14, "C" + - QString::number( static_cast( key / - KeysPerOctave ) ) ); + p.drawText( C_KEY_LABEL_X + 1, y+14, cLabel ); p.setPen( QColor( 0, 0, 0 ) ); - p.drawText( C_KEY_LABEL_X, y + 13, "C" + - QString::number( static_cast( key / - KeysPerOctave ) ) ); - p.setPen( QColor( 0x4F, 0x4F, 0x4F ) ); + p.drawText( C_KEY_LABEL_X, y + 13, cLabel ); + horizCol.setAlpha( 192 ); } else { - p.setPen( QColor( 0x3F, 0x3F, 0x3F ) ); + horizCol.setAlpha( 128 ); } // draw key-line + p.setPen( horizCol ); p.drawLine( WHITE_KEY_WIDTH, key_line_y, width(), key_line_y ); ++key; } @@ -3057,14 +3091,13 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) // erase the area below the piano, because there might be keys that // should be only half-visible p.fillRect( QRect( 0, keyAreaBottom(), - WHITE_KEY_WIDTH, noteEditBottom()-keyAreaBottom() ), - QColor( 0, 0, 0 ) ); + WHITE_KEY_WIDTH, noteEditBottom()-keyAreaBottom() ), bgColor ); // display note editing info QFont f = p.font(); f.setBold( false ); p.setFont( pointSize<10>( f ) ); - p.setPen( QColor( 255, 255, 255) ); + p.setPen( noteModeColor() ); p.drawText( QRect( 0, keyAreaBottom(), WHITE_KEY_WIDTH, noteEditBottom() - keyAreaBottom() ), Qt::AlignCenter | Qt::TextWordWrap, @@ -3107,17 +3140,19 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) // every tact-start needs to be a bright line if( tact_16th % spt == 0 ) { - p.setPen( QColor( 0x7F, 0x7F, 0x7F ) ); + p.setPen( gridColor() ); } // normal line else if( tact_16th % 4 == 0 ) { - p.setPen( QColor( 0x5F, 0x5F, 0x5F ) ); + vertCol.setAlpha( 160 ); + p.setPen( vertCol ); } // weak line else { - p.setPen( QColor( 0x3F, 0x3F, 0x3F ) ); + vertCol.setAlpha( 128 ); + p.setPen( vertCol ); } p.drawLine( (int)x, PR_TOP_MARGIN, (int)x, height() - @@ -3126,7 +3161,8 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) // extra 32nd's line if( show32nds ) { - p.setPen( QColor( 0x22, 0x22, 0x22 ) ); + vertCol.setAlpha( 80 ); + p.setPen( vertCol ); p.drawLine( (int)(x + pp16th/2) , PR_TOP_MARGIN, (int)(x + pp16th/2), height() - PR_BOTTOM_MARGIN ); @@ -3205,15 +3241,14 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) // note drawNoteRect( p, x + WHITE_KEY_WIDTH, y_base - key * KEY_LINE_HEIGHT, - note_width, *it ); + note_width, *it, noteColor() ); } // draw note editing stuff int editHandleTop = 0; if( m_noteEditMode == NoteEditVolume ) { - QColor color = QColor::fromHsv( 140, 221, - qMin(255, 60 + ( *it )->getVolume() ) ); + QColor color = barColor().lighter( 30 + ( ( *it )->getVolume() * 90 / MaxVolume ) ); if( ( *it )->selected() ) { color.setRgb( 0x00, 0x40, 0xC0 ); @@ -3231,7 +3266,7 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) } else if( m_noteEditMode == NoteEditPanning ) { - QColor color( 0x99, 0xAF, 0xFF ); + QColor color( noteColor() ); if( ( *it )->selected() ) { color.setRgb( 0x00, 0x40, 0xC0 ); @@ -3259,8 +3294,7 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) } } - p.setPen( QPen( QColor( 0x99, 0xAF, 0xFF ), - NE_LINE_WIDTH+2 ) ); + p.setPen( QPen( noteColor(), NE_LINE_WIDTH+2 ) ); p.drawPoints( editHandles ); } @@ -3269,7 +3303,8 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) QFont f = p.font(); f.setBold( true ); p.setFont( pointSize<14>( f ) ); - p.setPen( QColor( 0x4A, 0xFD, 0x85 ) ); + p.setPen( QApplication::palette().color( QPalette::Active, + QPalette::BrightText ) ); p.drawText( WHITE_KEY_WIDTH + 20, PR_TOP_MARGIN + 40, tr( "Please open a pattern by double-clicking " "on it!" ) ); @@ -3299,21 +3334,21 @@ void PianoRoll::paintEvent( QPaintEvent * _pe ) m_leftRightScroll->setPageStep( l ); } + // set alpha for horizontal lines + horizCol.setAlpha( 64 ); + // horizontal line for the key under the cursor if( validPattern() == true ) { int key_num = getKey( mapFromGlobal( QCursor::pos() ).y() ); p.fillRect( 10, keyAreaBottom() + 3 - KEY_LINE_HEIGHT * - ( key_num - m_startKey + 1 ), - width() - 10, KEY_LINE_HEIGHT - 7, - QColor( 64, 64, 64 ) ); + ( key_num - m_startKey + 1 ), width() - 10, KEY_LINE_HEIGHT - 7, horizCol ); } // bar to resize note edit area p.setClipRect( 0, 0, width(), height() ); p.fillRect( QRect( 0, keyAreaBottom(), - width()-PR_RIGHT_MARGIN, NOTE_EDIT_RESIZE_BAR ), - QColor( 64, 64, 64 ) ); + width()-PR_RIGHT_MARGIN, NOTE_EDIT_RESIZE_BAR ), horizCol ); const QPixmap * cursor = NULL; // draw current edit-mode-icon below the cursor @@ -3459,27 +3494,50 @@ void PianoRoll::wheelEvent( QWheelEvent * _we ) } } - // not in note edit area, so handle scrolling/zooming + // not in note edit area, so handle scrolling/zooming and quantization change else - if( _we->modifiers() & Qt::ControlModifier ) + if( _we->modifiers() & Qt::ControlModifier && _we->modifiers() & Qt::AltModifier ) { + int q = m_quantizeModel.value(); if( _we->delta() > 0 ) { - m_ppt = qMin( m_ppt * 2, KEY_LINE_HEIGHT * - DefaultStepsPerTact * 8 ); + q--; } - else if( m_ppt >= 72 ) + if( _we->delta() < 0 ) { - m_ppt /= 2; + q++; } + q = qBound( 0, q, m_quantizeModel.size() - 1 ); + m_quantizeModel.setValue( q ); + } + else if( _we->modifiers() & Qt::ControlModifier && _we->modifiers() & Qt::ShiftModifier ) + { + int l = m_noteLenModel.value(); + if( _we->delta() > 0 ) + { + l--; + } + if( _we->delta() < 0 ) + { + l++; + } + l = qBound( 0, l, m_noteLenModel.size() - 1 ); + m_noteLenModel.setValue( l ); + } + else if( _we->modifiers() & Qt::ControlModifier ) + { + int z = m_zoomingModel.value(); + if( _we->delta() > 0 ) + { + z++; + } + if( _we->delta() < 0 ) + { + z--; + } + z = qBound( 0, z, m_zoomingModel.size() - 1 ); // update combobox with zooming-factor - m_zoomingModel.setValue( - m_zoomingModel.findText( QString::number( - static_cast( m_ppt * 100 / - DEFAULT_PR_PPT ) ) +"%" ) ); - // update timeline - m_timeLine->setPixelsPerTact( m_ppt ); - update(); + m_zoomingModel.setValue( z ); } else if( _we->modifiers() & Qt::ShiftModifier || _we->orientation() == Qt::Horizontal ) @@ -4088,13 +4146,6 @@ void PianoRoll::zoomingChanged() void PianoRoll::quantizeChanged() { - if( m_quantizeModel.value() == 0 && - m_noteLenModel.value() == 0 ) - { - m_quantizeModel.setValue( m_quantizeModel.findText( "1/16" ) ); - return; - } - // Could be smarter update(); } @@ -4103,7 +4154,14 @@ int PianoRoll::quantization() const { if( m_quantizeModel.value() == 0 ) { - return newNoteLen(); + if( m_noteLenModel.value() > 0 ) + { + return newNoteLen(); + } + else + { + return DefaultTicksPerTact / 16; + } } return DefaultTicksPerTact / m_quantizeModel.currentText().right( m_quantizeModel.currentText().length() - diff --git a/src/gui/widgets/FxLine.cpp b/src/gui/widgets/FxLine.cpp index c200c1001..ac051d799 100644 --- a/src/gui/widgets/FxLine.cpp +++ b/src/gui/widgets/FxLine.cpp @@ -39,25 +39,25 @@ #include "gui_templates.h" #include "caption_menu.h" +const int FxLine::FxLineHeight = 287; FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex) : QWidget( _parent ), m_mv( _mv ), m_channelIndex( _channelIndex ) { - setFixedSize( 32, 287 ); + setFixedSize( 33, FxLineHeight ); setAttribute( Qt::WA_OpaquePaintEvent, true ); setCursor( QCursor( embed::getIconPixmap( "hand" ), 0, 0 ) ); // mixer sends knob m_sendKnob = new knob( knobBright_26, this, tr("Channel send amount") ); - m_sendKnob->move(3, 22); + m_sendKnob->move( 3, 22 ); m_sendKnob->setVisible(false); // send button indicator - m_sendBtn = new SendButtonIndicator(this, this, m_mv); - m_sendBtn->setPixmap(embed::getIconPixmap("mixer_send_off", 23, 16)); - m_sendBtn->move(4,4); + m_sendBtn = new SendButtonIndicator( this, this, m_mv ); + m_sendBtn->move( 2, 2 ); // channel number m_lcd = new LcdWidget( 2, this ); @@ -97,37 +97,34 @@ void FxLine::setChannelIndex(int index) { } -static void drawFxLine( QPainter* p, const QWidget *fxLine, const QString& name, bool isActive, bool sendToThis ) +static void drawFxLine( QPainter* p, const FxLine *fxLine, const QString& name, bool isActive, bool sendToThis ) { int width = fxLine->rect().width(); int height = fxLine->rect().height(); - QColor bg_color = QApplication::palette().color( QPalette::Active, - QPalette::Background ); QColor sh_color = QApplication::palette().color( QPalette::Active, QPalette::Shadow ); - QColor te_color = QApplication::palette().color( QPalette::Active, - QPalette::Text ); + QColor te_color = p->pen().brush().color(); QColor bt_color = QApplication::palette().color( QPalette::Active, QPalette::BrightText ); - p->fillRect( fxLine->rect(), isActive ? bg_color.lighter(130) : bg_color ); + p->fillRect( fxLine->rect(), isActive ? fxLine->backgroundActive() : p->background() ); - p->setPen( bg_color.darker(130) ); + p->setPen( QColor( 0, 0, 0, 75 ) ); p->drawRect( 0, 0, width-2, height-2 ); - p->setPen( bg_color.lighter(150) ); - p->drawRect( 1, 1, width-2, height-2 ); + p->setPen( QColor( 255, 255, 255, 75 ) ); + p->drawRect( 1, 1, width-3, height-3 ); - p->setPen( isActive ? sh_color : bg_color.darker(130) ); + p->setPen( isActive ? sh_color : QColor( 0, 0, 0, 50 ) ); p->drawRect( 0, 0, width-1, height-1 ); // draw the mixer send background if( sendToThis ) { - p->drawPixmap(2, 0, 28, 56, - embed::getIconPixmap("send_bg_arrow", 28, 56)); + p->drawPixmap( 3, 0, 28, 56, + embed::getIconPixmap("send_bg_arrow", 28, 56 ) ); } // draw the channel name @@ -241,5 +238,15 @@ void FxLine::displayHelp() whatsThis() ); } +QBrush FxLine::backgroundActive() const +{ + return m_backgroundActive; +} + +void FxLine::setBackgroundActive( const QBrush & c ) +{ + m_backgroundActive = c; +} + #include "moc_FxLine.cxx" diff --git a/src/gui/widgets/SendButtonIndicator.cpp b/src/gui/widgets/SendButtonIndicator.cpp index a932f136a..e77c0e965 100644 --- a/src/gui/widgets/SendButtonIndicator.cpp +++ b/src/gui/widgets/SendButtonIndicator.cpp @@ -4,19 +4,29 @@ #include "FxMixer.h" #include "Model.h" +QPixmap * SendButtonIndicator::s_qpmOff = NULL; +QPixmap * SendButtonIndicator::s_qpmOn = NULL; + SendButtonIndicator:: SendButtonIndicator( QWidget * _parent, FxLine * _owner, FxMixerView * _mv) : QLabel( _parent ), m_parent( _owner ), m_mv( _mv ) { - qpmOff = embed::getIconPixmap("mixer_send_off", 23, 16); - qpmOn = embed::getIconPixmap("mixer_send_on", 23, 16); - + if( ! s_qpmOff ) + { + s_qpmOff = new QPixmap( embed::getIconPixmap( "mixer_send_off", 29, 20 ) ); + } + + if( ! s_qpmOn ) + { + s_qpmOn = new QPixmap( embed::getIconPixmap( "mixer_send_on", 29, 20 ) ); + } + // don't do any initializing yet, because the FxMixerView and FxLine // that were passed to this constructor are not done with their constructors // yet. - + setPixmap( *s_qpmOff ); } void SendButtonIndicator::mousePressEvent( QMouseEvent * e ) @@ -49,5 +59,5 @@ FloatModel * SendButtonIndicator::getSendModel() void SendButtonIndicator::updateLightStatus() { - setPixmap( getSendModel() == NULL ? qpmOff : qpmOn ); + setPixmap( getSendModel() == NULL ? *s_qpmOff : *s_qpmOn ); } diff --git a/src/gui/widgets/fader.cpp b/src/gui/widgets/fader.cpp index f2dc4c5fd..d12112f82 100644 --- a/src/gui/widgets/fader.cpp +++ b/src/gui/widgets/fader.cpp @@ -60,7 +60,9 @@ textFloat * fader::s_textFloat = NULL; - +QPixmap * fader::s_back = NULL; +QPixmap * fader::s_leds = NULL; +QPixmap * fader::s_knob = NULL; fader::fader( FloatModel * _model, const QString & _name, QWidget * _parent ) : QWidget( _parent ), @@ -72,18 +74,30 @@ fader::fader( FloatModel * _model, const QString & _name, QWidget * _parent ) : m_persistentPeak_R( 0.0 ), m_fMinPeak( 0.01f ), m_fMaxPeak( 1.1 ), - m_back( embed::getIconPixmap( "fader_background" ) ), - m_leds( embed::getIconPixmap( "fader_leds" ) ), - m_knob( embed::getIconPixmap( "fader_knob" ) ), m_moveStartPoint( -1 ), - m_startValue( 0 ) + m_startValue( 0 ), + m_peakGreen( 0, 0, 0 ), + m_peakRed( 0, 0, 0 ) { if( s_textFloat == NULL ) { s_textFloat = new textFloat; } + if( ! s_back ) + { + s_back = new QPixmap( embed::getIconPixmap( "fader_background" ) ); + } + if( ! s_leds ) + { + s_leds = new QPixmap( embed::getIconPixmap( "fader_leds" ) ); + } + if( ! s_knob ) + { + s_knob = new QPixmap( embed::getIconPixmap( "fader_knob" ) ); + } + setWindowTitle( _name ); - setAttribute( Qt::WA_OpaquePaintEvent, true ); + setAttribute( Qt::WA_OpaquePaintEvent, false ); setMinimumSize( 23, 116 ); setMaximumSize( 23, 116); resize( 23, 116 ); @@ -116,7 +130,7 @@ void fader::mouseMoveEvent( QMouseEvent *mouseEvent ) { int dy = m_moveStartPoint - mouseEvent->globalY(); - float delta = dy * ( m_model->maxValue() - m_model->minValue() ) / (float) ( height() - m_knob.height() ); + float delta = dy * ( m_model->maxValue() - m_model->minValue() ) / (float) ( height() - ( *s_knob ).height() ); model()->setValue( m_startValue + delta ); @@ -132,7 +146,7 @@ void fader::mousePressEvent( QMouseEvent* mouseEvent ) if( mouseEvent->button() == Qt::LeftButton && ! ( mouseEvent->modifiers() & Qt::ControlModifier ) ) { - if( mouseEvent->y() >= knobPosY() - m_knob.height() && mouseEvent->y() < knobPosY() ) + if( mouseEvent->y() >= knobPosY() - ( *s_knob ).height() && mouseEvent->y() < knobPosY() ) { updateTextFloat(); s_textFloat->show(); @@ -260,7 +274,7 @@ void fader::updateTextFloat() { s_textFloat->setText( QString("Volume: %1 %").arg( m_model->value() * 100 ) ); } - s_textFloat->moveGlobal( this, QPoint( width() - m_knob.width() - 5, knobPosY() - 46 ) ); + s_textFloat->moveGlobal( this, QPoint( width() - ( *s_knob ).width() - 5, knobPosY() - 46 ) ); } @@ -277,8 +291,7 @@ void fader::paintEvent( QPaintEvent * ev) QPainter painter(this); // background -// painter.drawPixmap( rect(), m_back, QRect( 0, 0, 23, 116 ) ); - painter.drawPixmap( ev->rect(), m_back, ev->rect() ); + painter.drawPixmap( ev->rect(), *s_back, ev->rect() ); // peak leds @@ -286,28 +299,50 @@ void fader::paintEvent( QPaintEvent * ev) int peak_L = calculateDisplayPeak( m_fPeakValue_L - m_fMinPeak ); int persistentPeak_L = qMax( 3, calculateDisplayPeak( m_persistentPeak_L - m_fMinPeak ) ); - painter.drawPixmap( QRect( 0, peak_L, 11, 116 - peak_L ), m_leds, QRect( 0, peak_L, 11, 116 - peak_L ) ); + painter.drawPixmap( QRect( 0, peak_L, 11, 116 - peak_L ), *s_leds, QRect( 0, peak_L, 11, 116 - peak_L ) ); if( m_persistentPeak_L > 0.05 ) { - painter.fillRect( QRect( 2, persistentPeak_L, 7, 1 ), (m_persistentPeak_L < 1.0 )? QColor( 74, 253, 133) : QColor( 255, 100, 100)); + painter.fillRect( QRect( 2, persistentPeak_L, 7, 1 ), ( m_persistentPeak_L < 1.0 ) + ? peakGreen() + : peakRed() ); } int peak_R = calculateDisplayPeak( m_fPeakValue_R - m_fMinPeak ); int persistentPeak_R = qMax( 3, calculateDisplayPeak( m_persistentPeak_R - m_fMinPeak ) ); - painter.drawPixmap( QRect( 11, peak_R, 11, 116 - peak_R ), m_leds, QRect( 11, peak_R, 11, 116 - peak_R ) ); + painter.drawPixmap( QRect( 11, peak_R, 11, 116 - peak_R ), *s_leds, QRect( 11, peak_R, 11, 116 - peak_R ) ); if( m_persistentPeak_R > 0.05 ) { - painter.fillRect( QRect( 14, persistentPeak_R, 7, 1 ), (m_persistentPeak_R < 1.0 )? QColor( 74, 253, 133) : QColor( 255, 100, 100)); + painter.fillRect( QRect( 14, persistentPeak_R, 7, 1 ), ( m_persistentPeak_R < 1.0 ) + ? peakGreen() + : peakRed() ); } // knob - painter.drawPixmap( 0, knobPosY() - m_knob.height(), m_knob ); + painter.drawPixmap( 0, knobPosY() - ( *s_knob ).height(), *s_knob ); } +QColor fader::peakGreen() const +{ + return m_peakGreen; +} +QColor fader::peakRed() const +{ + return m_peakRed; +} + +void fader::setPeakGreen( const QColor & c ) +{ + m_peakGreen = c; +} + +void fader::setPeakRed( const QColor & c ) +{ + m_peakRed = c; +} #include "moc_fader.cxx" diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 1b30c56c6..b9e1e21b1 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -135,12 +135,17 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) : } +int InstrumentTrack::baseNote() const +{ + return m_baseNoteModel.value() - engine::getSong()->masterPitch(); +} + InstrumentTrack::~InstrumentTrack() { - // kill all running notes - silenceAllNotes(); + // kill all running notes and the iph + silenceAllNotes( true ); // now we're save deleting the instrument delete m_instrument; @@ -232,10 +237,9 @@ MidiEvent InstrumentTrack::applyMasterKey( const MidiEvent& event ) -void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& time ) +void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { engine::mixer()->lock(); - bool eventHandled = false; switch( event.type() ) @@ -335,7 +339,7 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti break; } - if( eventHandled == false && instrument()->handleMidiEvent( event, time ) == false ) + if( eventHandled == false && instrument()->handleMidiEvent( event, time, offset ) == false ) { qWarning( "InstrumentTrack: unhandled MIDI event %d", event.type() ); } @@ -346,7 +350,7 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti -void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& time ) +void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { // do nothing if we do not have an instrument instance (e.g. when loading settings) if( m_instrument == NULL ) @@ -366,10 +370,10 @@ void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& t { if( m_runningMidiNotes[key] > 0 ) { - m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time ); + m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset ); } ++m_runningMidiNotes[key]; - m_instrument->handleMidiEvent( MidiEvent( MidiNoteOn, midiPort()->realOutputChannel(), key, event.velocity() ), time ); + m_instrument->handleMidiEvent( MidiEvent( MidiNoteOn, midiPort()->realOutputChannel(), key, event.velocity() ), time, offset ); emit newNote(); } @@ -381,12 +385,12 @@ void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& t if( key >= 0 && key < NumKeys && --m_runningMidiNotes[key] <= 0 ) { m_runningMidiNotes[key] = qMax( 0, m_runningMidiNotes[key] ); - m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time ); + m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset ); } break; default: - m_instrument->handleMidiEvent( transposedEvent, time ); + m_instrument->handleMidiEvent( transposedEvent, time, offset ); break; } @@ -397,7 +401,7 @@ void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& t -void InstrumentTrack::silenceAllNotes() +void InstrumentTrack::silenceAllNotes( bool removeIPH ) { engine::mixer()->lock(); for( int i = 0; i < NumKeys; ++i ) @@ -408,7 +412,7 @@ void InstrumentTrack::silenceAllNotes() // invalidate all NotePlayHandles linked to this track m_processHandles.clear(); - engine::mixer()->removePlayHandles( this ); + engine::mixer()->removePlayHandles( this, removeIPH ); engine::mixer()->unlock(); } @@ -537,7 +541,7 @@ void InstrumentTrack::updatePitchRange() int InstrumentTrack::masterKey( int _midi_key ) const { - int key = m_baseNoteModel.value() - engine::getSong()->masterPitch(); + int key = baseNote(); return tLimit( _midi_key - ( key - DefaultKey ), 0, NumKeys ); } @@ -695,7 +699,7 @@ void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement ) { - silenceAllNotes(); + silenceAllNotes( true ); engine::mixer()->lock(); @@ -771,7 +775,7 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement Instrument * InstrumentTrack::loadInstrument( const QString & _plugin_name ) { - silenceAllNotes(); + silenceAllNotes( true ); engine::mixer()->lock(); delete m_instrument; @@ -1323,6 +1327,7 @@ void InstrumentTrackWindow::modelChanged() m_pitchKnob->setModel( &m_track->m_pitchModel ); m_pitchRangeSpinBox->setModel( &m_track->m_pitchRangeModel ); m_pitchKnob->show(); + m_pitchRangeSpinBox->show(); } else { diff --git a/src/tracks/bb_track.cpp b/src/tracks/bb_track.cpp index 15bace3fc..01703b990 100644 --- a/src/tracks/bb_track.cpp +++ b/src/tracks/bb_track.cpp @@ -46,9 +46,10 @@ bbTrack::infoMap bbTrack::s_infoMap; -bbTCO::bbTCO( track * _track, unsigned int _color ) : +bbTCO::bbTCO( track * _track ) : trackContentObject( _track ), - m_color( _color > 0 ? _color : defaultColor() ) + m_color( 128, 128, 128 ), + m_useStyleColor( true ) { tact_t t = engine::getBBTrackContainer()->lengthOfBB( bbTrackIndex() ); if( t > 0 ) @@ -69,41 +70,73 @@ bbTCO::~bbTCO() -void bbTCO::saveSettings( QDomDocument & _doc, QDomElement & _this ) +void bbTCO::saveSettings( QDomDocument & doc, QDomElement & element ) { - _this.setAttribute( "name", name() ); - if( _this.parentNode().nodeName() == "clipboard" ) + element.setAttribute( "name", name() ); + if( element.parentNode().nodeName() == "clipboard" ) { - _this.setAttribute( "pos", -1 ); + element.setAttribute( "pos", -1 ); } else { - _this.setAttribute( "pos", startPosition() ); + element.setAttribute( "pos", startPosition() ); + } + element.setAttribute( "len", length() ); + element.setAttribute( "muted", isMuted() ); + element.setAttribute( "color", color() ); + + if( m_useStyleColor ) + { + element.setAttribute( "usestyle", 1 ); + } + else + { + element.setAttribute( "usestyle", 0 ); } - _this.setAttribute( "len", length() ); - _this.setAttribute( "muted", isMuted() ); - _this.setAttribute( "color", m_color ); } -void bbTCO::loadSettings( const QDomElement & _this ) +void bbTCO::loadSettings( const QDomElement & element ) { - setName( _this.attribute( "name" ) ); - if( _this.attribute( "pos" ).toInt() >= 0 ) + setName( element.attribute( "name" ) ); + if( element.attribute( "pos" ).toInt() >= 0 ) { - movePosition( _this.attribute( "pos" ).toInt() ); + movePosition( element.attribute( "pos" ).toInt() ); } - changeLength( _this.attribute( "len" ).toInt() ); - if( _this.attribute( "muted" ).toInt() != isMuted() ) + changeLength( element.attribute( "len" ).toInt() ); + if( element.attribute( "muted" ).toInt() != isMuted() ) { toggleMute(); } - if( _this.attribute( "color" ).toUInt() != 0 ) + if( element.hasAttribute( "color" ) ) { - m_color = _this.attribute( "color" ).toUInt(); + setColor( QColor( element.attribute( "color" ).toUInt() ) ); + } + + if( element.hasAttribute( "usestyle" ) ) + { + if( element.attribute( "usestyle" ).toUInt() == 1 ) + { + m_useStyleColor = true; + } + else + { + m_useStyleColor = false; + } + } + else + { + if( m_color.rgb() == qRgb( 128, 182, 175 ) || m_color.rgb() == qRgb( 64, 128, 255 ) ) // old or older default color + { + m_useStyleColor = true; + } + else + { + m_useStyleColor = false; + } } } @@ -163,6 +196,8 @@ void bbTCOView::constructContextMenu( QMenu * _cm ) this, SLOT( changeName() ) ); _cm->addAction( embed::getIconPixmap( "colorize" ), tr( "Change color" ), this, SLOT( changeColor() ) ); + _cm->addAction( embed::getIconPixmap( "colorize" ), + tr( "Reset color to default" ), this, SLOT( resetColor() ) ); } @@ -178,7 +213,12 @@ void bbTCOView::mouseDoubleClickEvent( QMouseEvent * ) void bbTCOView::paintEvent( QPaintEvent * ) { - QColor col( m_bbTCO->m_color ); + QPainter p( this ); + + QColor col = m_bbTCO->m_useStyleColor + ? p.pen().brush().color() + : m_bbTCO->colorObj(); + if( m_bbTCO->getTrack()->isMuted() || m_bbTCO->isMuted() ) { col = QColor( 160, 160, 160 ); @@ -188,7 +228,6 @@ void bbTCOView::paintEvent( QPaintEvent * ) col = QColor( qMax( col.red() - 128, 0 ), qMax( col.green() - 128, 0 ), 255 ); } - QPainter p( this ); QLinearGradient lingrad( 0, 0, 0, height() ); lingrad.setColorAt( 0, col.light( 130 ) ); @@ -263,8 +302,8 @@ void bbTCOView::changeName() void bbTCOView::changeColor() { - QColor _new_color = QColorDialog::getColor( m_bbTCO->m_color ); - if( !_new_color.isValid() ) + QColor new_color = QColorDialog::getColor( m_bbTCO->m_color ); + if( ! new_color.isValid() ) { return; } @@ -279,34 +318,48 @@ void bbTCOView::changeColor() bbTCOView * bb_tcov = dynamic_cast( *it ); if( bb_tcov ) { - bb_tcov->setColor( _new_color ); + bb_tcov->setColor( new_color ); } } } else { - setColor( _new_color ); + setColor( new_color ); } } - - -void bbTCOView::setColor( QColor _new_color ) +/** \brief Makes the BB pattern use the colour defined in the stylesheet */ +void bbTCOView::resetColor() { - if( _new_color.rgb() != m_bbTCO->m_color ) + if( ! m_bbTCO->m_useStyleColor ) { - m_bbTCO->m_color = _new_color.rgb(); + m_bbTCO->m_useStyleColor = true; engine::getSong()->setModified(); update(); } + bbTrack::clearLastTCOColor(); +} + + + +void bbTCOView::setColor( QColor new_color ) +{ + if( new_color.rgb() != m_bbTCO->color() ) + { + m_bbTCO->setColor( new_color ); + m_bbTCO->m_useStyleColor = false; + engine::getSong()->setModified(); + update(); + } + bbTrack::setLastTCOColor( new_color ); } - +QColor * bbTrack::s_lastTCOColor = NULL; bbTrack::bbTrack( TrackContainer* tc ) : track( BBTrack, tc ) @@ -404,24 +457,18 @@ trackView * bbTrack::createView( TrackContainerView* tcv ) trackContentObject * bbTrack::createTCO( const MidiTime & _pos ) { - // if we're creating a new bbTCO, we colorize it according to the - // previous bbTCO, so we have to get all TCOs from 0 to _pos and - // pickup the last and take the color if it - tcoVector tcos; - getTCOsInRange( tcos, 0, _pos ); - if( tcos.size() > 0 && dynamic_cast( tcos.back() ) != NULL ) + bbTCO * bbtco = new bbTCO( this ); + if( s_lastTCOColor ) { - return new bbTCO( this, dynamic_cast( tcos.back() )->color() ); - + bbtco->setColor( *s_lastTCOColor ); + bbtco->setUseStyleColor( false ); } - return new bbTCO( this ); + return bbtco; } - - void bbTrack::saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _this ) {