flp-import-basics and MIDI-tab-widget-extension
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@113 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
16
ChangeLog
16
ChangeLog
@@ -1,7 +1,21 @@
|
||||
2005-03-28 Danny McRae <khjklujn/at/yahoo/dot/com>
|
||||
* lib/sample_buffer.cpp:
|
||||
|
||||
* src/lib/sample_buffer.cpp:
|
||||
corrected miscalculation of buffer size in resample
|
||||
|
||||
2006-03-27 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/flp_import/:
|
||||
skeleton for FLP-import-filter and some first code (doesn't work yet)
|
||||
|
||||
* include/midi.h:
|
||||
* include/midi_port.h:
|
||||
* include/midi_tab_widget.h:
|
||||
* src/core/midi_tab_widget.cpp:
|
||||
* src/midi/midi_port.cpp:
|
||||
support for default-velocity for MIDI-in and/or -out-events - useful
|
||||
when recording with constant velocity
|
||||
|
||||
2005-03-26 Danny McRae <khjklujn/at/yahoo/dot/com>
|
||||
|
||||
* plugins/vibed/:
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.1.4-cvs20060326, tobydox/at/users/dot/sourceforge/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.4-cvs20060326)
|
||||
AC_INIT(lmms, 0.1.4-cvs20060327, tobydox/at/users/dot/sourceforge/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.4-cvs20060327)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
@@ -465,6 +465,7 @@ AC_CONFIG_FILES([Makefile
|
||||
plugins/Makefile
|
||||
plugins/audio_file_processor/Makefile
|
||||
plugins/bit_invader/Makefile
|
||||
plugins/flp_import/Makefile
|
||||
plugins/midi_import/Makefile
|
||||
plugins/organic/Makefile
|
||||
plugins/plucked_string_synth/Makefile
|
||||
|
||||
Binary file not shown.
@@ -671,7 +671,6 @@ http://lmms.sourceforge.net</translation>
|
||||
</context>
|
||||
<context>
|
||||
<name>bbTrack</name>
|
||||
<message>
|
||||
<message>
|
||||
<source>Beat/Baseline %1</source>
|
||||
<translation>Beat/Baseline %1</translation>
|
||||
@@ -724,87 +723,87 @@ http://lmms.sourceforge.net</translation>
|
||||
<name>channelTrack</name>
|
||||
<message>
|
||||
<source>With this knob you can set the volume of the opened channel.</source>
|
||||
<translation>Mit diesem Knopf können Sie die Lautstärke des geöffneten Kanals ändern.</translation>
|
||||
<translation type="obsolete">Mit diesem Knopf können Sie die Lautstärke des geöffneten Kanals ändern.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Within this rectangle you can set the position where the channel should be audible. You should have a soundcard supporting at least surround 4.0 for enjoying this feature.</source>
|
||||
<translation>Innerhalb dieses Rechtecks können Sie die Position setzen, an der dieser Kanal zu hören sein soll. Um dieses Feature sinnvoll zu nutzen, sollten Sie eine Soundkarte haben, die mindestens Surround 4.0 unterstützt.</translation>
|
||||
<translation type="obsolete">Innerhalb dieses Rechtecks können Sie die Position setzen, an der dieser Kanal zu hören sein soll. Um dieses Feature sinnvoll zu nutzen, sollten Sie eine Soundkarte haben, die mindestens Surround 4.0 unterstützt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save current channel settings in a preset-file</source>
|
||||
<translation>Aktuelle Kanal-Einstellungen in einer Preset-Datei speichern</translation>
|
||||
<translation type="obsolete">Aktuelle Kanal-Einstellungen in einer Preset-Datei speichern</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channel volume</source>
|
||||
<translation>Kanal Lautstärke</translation>
|
||||
<translation type="obsolete">Kanal Lautstärke</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channel volume:</source>
|
||||
<translation>Kanal Lautstärke:</translation>
|
||||
<translation type="obsolete">Kanal Lautstärke:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channel-Settings-File (*.cs.xml)</source>
|
||||
<translation>Channel-Settings-Datei (*.cs.xml)</translation>
|
||||
<translation type="obsolete">Channel-Settings-Datei (*.cs.xml)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save channel-settings in file</source>
|
||||
<translation>Kanal-Einstellungen in Datei speichern</translation>
|
||||
<translation type="obsolete">Kanal-Einstellungen in Datei speichern</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VOLUME</source>
|
||||
<translation>LAUTSTÄRKE</translation>
|
||||
<translation type="obsolete">LAUTSTÄRKE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FX CHNL</source>
|
||||
<translation>FX KANAL</translation>
|
||||
<translation type="obsolete">FX KANAL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ENV/LFO/FILTER</source>
|
||||
<translation>HÜLLK./LFO/FILTER</translation>
|
||||
<translation type="obsolete">HÜLLK./LFO/FILTER</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ARP/CHORD</source>
|
||||
<translation>ARP/AKK.</translation>
|
||||
<translation type="obsolete">ARP/AKK.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here, if you want to save current channel settings in a preset-file. Later you can load this preset by double-clicking it in the preset-browser.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie die aktuellen Kanal-Einstellungen in einer Preset-Datei speichern wollen. Spätern können Sie dieses Preset laden, indem Sie es im Preset-Browser doppelt anklicken.</translation>
|
||||
<translation type="obsolete">Klicken Sie hier, wenn Sie die aktuellen Kanal-Einstellungen in einer Preset-Datei speichern wollen. Spätern können Sie dieses Preset laden, indem Sie es im Preset-Browser doppelt anklicken.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VOL</source>
|
||||
<translation>LAUT</translation>
|
||||
<translation type="obsolete">LAUT</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GENERAL SETTINGS</source>
|
||||
<translation>GRUNDLEGENDE EINSTELLUNGEN</translation>
|
||||
<translation type="obsolete">GRUNDLEGENDE EINSTELLUNGEN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI</source>
|
||||
<translation>MIDI</translation>
|
||||
<translation type="obsolete">MIDI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLUGIN</source>
|
||||
<translation>PLUGIN</translation>
|
||||
<translation type="obsolete">PLUGIN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>unnamed_channel</source>
|
||||
<translation>Unbenannter_Kanal</translation>
|
||||
<translation type="obsolete">Unbenannter_Kanal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Default</source>
|
||||
<translation>Default</translation>
|
||||
<translation type="obsolete">Default</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI input/output</source>
|
||||
<translation>MIDI-Eingabe/Ausgabe</translation>
|
||||
<translation type="obsolete">MIDI-Eingabe/Ausgabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI input</source>
|
||||
<translation>MIDI-Eingabe</translation>
|
||||
<translation type="obsolete">MIDI-Eingabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI output</source>
|
||||
<translation>MIDI-Ausgabe</translation>
|
||||
<translation type="obsolete">MIDI-Ausgabe</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -1194,7 +1193,7 @@ installiert sind. Soll der Einrichtungsassistent jetzt gestartet werden?</transl
|
||||
</message>
|
||||
<message>
|
||||
<source>Here you can select the built-in filter you want to use in this channel. Filters are very important for changing the characteristics of a sound.</source>
|
||||
<translation>Hier können Sie den eingebauten Filter wählen, den Sie in diesem Kanal verwenden wollen. Filter sind sehr wichtig, um den Charakter eines Klangs zu ändern.</translation>
|
||||
<translation type="obsolete">Hier können Sie den eingebauten Filter wählen, den Sie in diesem Kanal verwenden wollen. Filter sind sehr wichtig, um den Charakter eines Klangs zu ändern.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hz</source>
|
||||
@@ -1252,6 +1251,10 @@ installiert sind. Soll der Einrichtungsassistent jetzt gestartet werden?</transl
|
||||
<source>TARGET</source>
|
||||
<translation>ZIEL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Here you can select the built-in filter you want to use for this instrument-track. Filters are very important for changing the characteristics of a sound.</source>
|
||||
<translation>Hier können Sie den eingebauten Filter wählen, den Sie in dieser Instrument-Spur nutzen wollen. Filter sind sehr wichtig, um die Charakteristik eines Klangs zu verändern.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>exportProjectDialog</name>
|
||||
@@ -1332,15 +1335,161 @@ Stellen Sie sicher, dass Sie Schreibzugriff auf die gewählte Datei/Gerät haben
|
||||
</message>
|
||||
<message>
|
||||
<source>Send to active channel</source>
|
||||
<translation>An aktiven Kanal senden</translation>
|
||||
<translation type="obsolete">An aktiven Kanal senden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in new channel/Song-Editor</source>
|
||||
<translation>In neuem Kanal im Song-Editor öffnen</translation>
|
||||
<translation type="obsolete">In neuem Kanal im Song-Editor öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in new channel/B+B Editor</source>
|
||||
<translation>In neuem Kanal im B+B Editor öffnen</translation>
|
||||
<translation type="obsolete">In neuem Kanal im B+B Editor öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send to active instrument-track</source>
|
||||
<translation>An aktive Instrument-Spur senden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in new instrument-track/Song-Editor</source>
|
||||
<translation>In neuer Instrument-Spur im Song-Editor öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in new instrument-track/B+B Editor</source>
|
||||
<translation>In neuer Instrument-Spur im B+B Editor öffnen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>impulseEditor</name>
|
||||
<message>
|
||||
<source>Draw your own waveform here by dragging your mouse onto this graph</source>
|
||||
<translation>Zeichnen Sie eigene Wellenformen, indem Sie die Maus über den Graph ziehen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here if you want a sine-wave for current oscillator.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie eine Sinus-Schwingung für den aktuellen Oszillator haben wollen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here if you want a triangle-wave for current oscillator.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie eine Dreiecks-Schwingung für den aktuellen Oszillator haben wollen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here if you want a saw-wave for current oscillator.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie eine Sägezahn-Schwingung für den aktuellen Oszillator haben wollen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here if you want a square-wave for current oscillator.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie eine Rechteck-Schwingung für den aktuellen Oszillator haben wollen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here if you want a white-noise for current oscillator.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie weißes Rauschen für den aktuellen Oszillator haben wollen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here if you want a user-defined wave-shape for current oscillator.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie eine selbst definierte Wellenform für den aktuellen Oszillator haben wollen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here to smooth waveform.</source>
|
||||
<translation>Klicken Sie hier, um die Wellenform zu glätten.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here to normalize waveform.</source>
|
||||
<translation>Hier klicken, um die Wellenform zu normalisieren.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here to enable/disable waveform.</source>
|
||||
<translation>Hier klicken, um die Wellenform zu aktivieren/deaktiveren.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Help</source>
|
||||
<translation>&Hilfe</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>instrumentTrack</name>
|
||||
<message>
|
||||
<source>With this knob you can set the volume of the opened channel.</source>
|
||||
<translation>Mit diesem Knopf können Sie die Lautstärke des geöffneten Kanals ändern.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Within this rectangle you can set the position where the channel should be audible. You should have a soundcard supporting at least surround 4.0 for enjoying this feature.</source>
|
||||
<translation>Innerhalb dieses Rechtecks können Sie die Position setzen, an der dieser Kanal zu hören sein soll. Um dieses Feature sinnvoll zu nutzen, sollten Sie eine Soundkarte haben, die mindestens Surround 4.0 unterstützt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>unnamed_channel</source>
|
||||
<translation>Unbenannter_Kanal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channel volume</source>
|
||||
<translation>Kanal Lautstärke</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channel volume:</source>
|
||||
<translation>Kanal Lautstärke:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VOL</source>
|
||||
<translation>LAUT</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI input/output</source>
|
||||
<translation>MIDI-Eingabe/Ausgabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GENERAL SETTINGS</source>
|
||||
<translation>GRUNDLEGENDE EINSTELLUNGEN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VOLUME</source>
|
||||
<translation>LAUTSTÄRKE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FX CHNL</source>
|
||||
<translation>FX KANAL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save current channel settings in a preset-file</source>
|
||||
<translation>Aktuelle Kanal-Einstellungen in einer Preset-Datei speichern</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click here, if you want to save current channel settings in a preset-file. Later you can load this preset by double-clicking it in the preset-browser.</source>
|
||||
<translation>Klicken Sie hier, wenn Sie die aktuellen Kanal-Einstellungen in einer Preset-Datei speichern wollen. Spätern können Sie dieses Preset laden, indem Sie es im Preset-Browser doppelt anklicken.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Default</source>
|
||||
<translation>Default</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ENV/LFO/FILTER</source>
|
||||
<translation>HÜLLK./LFO/FILTER</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ARP/CHORD</source>
|
||||
<translation>ARP/AKKORD</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI</source>
|
||||
<translation>MIDI</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI input</source>
|
||||
<translation>MIDI-Eingabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MIDI output</source>
|
||||
<translation>MIDI-Ausgabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save channel-settings in file</source>
|
||||
<translation>Kanal-Einstellungen in Datei speichern</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channel-Settings-File (*.cs.xml)</source>
|
||||
<translation>Channel-Settings-Datei (*.cs.xml)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLUGIN</source>
|
||||
<translation>PLUGIN</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -1561,6 +1710,18 @@ Bitte besuchen Sie http://wiki.mindrules.net für Dokumentationen über LMMS.</t
|
||||
<source>By pressing this button, you can show or hide the Beat+Baseline Editor. The Beat+Baseline Editor is needed for creating beats, opening, adding and removing channels, cutting, copying and pasting beat- and baseline-patterns and other things like that.</source>
|
||||
<translation>Durch das Drücken dieses Knopfes wird der Beat+Baseline Editor ein- oder ausgeblendet. Der Beat+Baseline Editor ist nötig, um Beats zu erstellen, Kanale zu öffnen, hinzuzufügen und zu entfernen sowie um Baseline-Patterns auszuschneiden, zu kopieren und einzufügen usw.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Edit</source>
|
||||
<translation>&Bearbeiten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Undo</source>
|
||||
<translation>Rückgängig</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Redo</source>
|
||||
<translation>Wiederherstellen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>midiClient</name>
|
||||
@@ -1633,6 +1794,13 @@ Bitte besuchen Sie http://wiki.mindrules.net für Dokumentationen über LMMS.</t
|
||||
<translation>Alle Bilder (*.png *.jpg *.jpeg *.gif *.bmp)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>nineButtonSelector</name>
|
||||
<message>
|
||||
<source>&Help</source>
|
||||
<translation>&Hilfe</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>organicInstrument</name>
|
||||
<message>
|
||||
@@ -1902,7 +2070,7 @@ Lautstärke eines Steps kann mit Mausrad geändert werden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>simple sampler with various settings for using samples (e.g. drums) in a channel</source>
|
||||
<translation>Einfacher Sampler mit verschiedenen Einstellungen zum Benutzen von Samples (z.B. Drums) in einem Kanal</translation>
|
||||
<translation type="obsolete">Einfacher Sampler mit verschiedenen Einstellungen zum Benutzen von Samples (z.B. Drums) in einem Kanal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VST-host for using VST(i)-plugins within LMMS</source>
|
||||
@@ -1924,6 +2092,18 @@ Lautstärke eines Steps kann mit Mausrad geändert werden</translation>
|
||||
<source>Additive Synthesizer for organ-like sounds</source>
|
||||
<translation>Additiver Synthesizer für orgelähnliche Klänge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Vibrating string modeler</source>
|
||||
<translation>Modellierung einer schwingenden Saite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Filter for importing MIDI-files into LMMS</source>
|
||||
<translation>Filter, um MIDI-Dateien in LMMS zu importieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>simple sampler with various settings for using samples (e.g. drums) in an instrument-track</source>
|
||||
<translation>Einfacher Sampler mit verschiedenen Einstellungen zur Nutzung von Samples (z.B. Drums) in einer Instrument-Spur</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>projectNotes</name>
|
||||
@@ -2589,24 +2769,44 @@ Bitte stellen Sie sicher, dass Sie Schreibrechte auf diese Datei besitzen und ve
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open file</source>
|
||||
<translation>Konnte Datei nicht öffnen</translation>
|
||||
<translation type="obsolete">Konnte Datei nicht öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open file %1 for reading.
|
||||
Please make sure you have read-permission to the file and the directory containing the file and try again!</source>
|
||||
<translation>Die Datei %1 konnte nicht zum Lesen geöffnet werden.
|
||||
<translation type="obsolete">Die Datei %1 konnte nicht zum Lesen geöffnet werden.
|
||||
Bitte stellen Sie sicher, dass Sie Leserechte auf die Datei und auf das Verzeichnis, das diese Datei beinhaltet, haben und versuchen es erneut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open file %1 for writing.
|
||||
Please make sure you have write-permission to the file and the directory containing the file and try again!</source>
|
||||
<translation>Die Datei %1 konnte nicht zum Schreiben geöffnet werden.
|
||||
<translation type="obsolete">Die Datei %1 konnte nicht zum Schreiben geöffnet werden.
|
||||
Bitte stellen Sie sicher, dass Sie Schreibrechte auf diese Datei und das Verzeichnis, das diese Datei enthält, besitzen und versuchen es erneut!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Importing MIDI-file...</source>
|
||||
<translation>Importiere MIDI-Datei...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Couldn't import file</source>
|
||||
<translation>Konnte Datei nicht importieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Couldn't find a filter for importing file %1.
|
||||
You should convert this file into a format supported by LMMS using another software. </source>
|
||||
<translation>Konnte keinen Filter finden, um die Datei %1 zu importieren.
|
||||
Sie sollten diese Datei mit Hilfe einer anderen Software in ein Format konvertieren, das von LMMS unterstützt wird.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Couldn't open file</source>
|
||||
<translation>Konnte Datei nicht öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>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!</source>
|
||||
<translation>Konnte Datei %1 nicht zum Lesen öffnen.
|
||||
Bitte stellen Sie sicher, dass Sie Lese-Rechte auf diese Datei sowie das Verzeichnis besitzen und probieren es erneut!</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>trackContentObject</name>
|
||||
@@ -2908,6 +3108,165 @@ Wenn es mit anderer VST-software unter Linux funktioniert, kontaktieren Sie bitt
|
||||
<translation>Alle Noten ausschalten</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>vibed</name>
|
||||
<message>
|
||||
<source>The waveform editor provides control over the initial state or impulse that is used to start the string vibrating. The buttons to the right of the graph will initialize the waveform to the selected type. The '?' button will load a waveform from a file--only the first 128 samples will be loaded.
|
||||
|
||||
The waveform can also be drawn in the graph.
|
||||
|
||||
The 'S' button will smooth the waveform.
|
||||
|
||||
The 'N' button will normalize the waveform.</source>
|
||||
<translation>Der Wellenform-Editor ermöglicht die Kontrolle über die Grundstellung oder den Impuls, der genutzt wird, um die Saite zum Schwingen zu bringen. Die Buttons rechts des Graphes initialisieren die Wellenform mit dem gewünschten Typ. Der '?'-Button lässt Sie eine Wellenform aus einer Datei laden - allerdings werden nur die ersten 128 Samples geladen.
|
||||
|
||||
Die Wellenform kann ebenfalls in dem Graph gezeichnet werden.
|
||||
|
||||
Der 'S'-Button glättet die Wellenform.
|
||||
|
||||
Der 'N'-Button normalisiert die Wellenform.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Volume</source>
|
||||
<translation>Lautstärke</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Volume:</source>
|
||||
<translation>Lautstärke:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The 'V' knob sets the volume of the selected string.</source>
|
||||
<translation>Der 'V'-Knopf setzt die Lautstärke der gewählten Saite.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>String stiffness</source>
|
||||
<translation>Härte der Saite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>String stiffness:</source>
|
||||
<translation>Härte der Saite:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The 'S' knob sets the stiffness of the selected string. The stiffness of the string affects how long the string will ring out. The lower the setting, the longer the string will ring.</source>
|
||||
<translation>Der 'S'-Knopf setzt die Härte der gewählten Saite. Die Härte der Saite beeinflusst deren Ausklang-Dauer. Je kleiner die Einstellung, desto länger klingt die Saite aus.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pick position</source>
|
||||
<translation>Zupf-Position</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pick position:</source>
|
||||
<translation>Zupf-Position:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The 'P' knob sets the position where the selected string will be 'picked'. The lower the setting the closer the pick is to the bridge.</source>
|
||||
<translation>Der 'P'-Knopf bestimmt die Position, an der die Saite angezupft wird. Je kleiner die Einstellung, desto näher wird am Steg gezupft.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pickup position</source>
|
||||
<translation>Abnehmer-Position</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pickup position:</source>
|
||||
<translation>Abnehmer-Position:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The 'PU' knob sets the position where the vibrations will be monitored for the selected string. The lower the setting, the closer the pickup is to the bridge.</source>
|
||||
<translation>Der 'PU'-Knopf bestimmt die Position, an der die Schwingungen an der gewählten Saite abgenommen werden. Je kleiner die Einstellung, desto näher ist der Abnehmer am Steg.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pan</source>
|
||||
<translation>Balance</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pan:</source>
|
||||
<translation>Balance:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The Pan knob determines the location of the selected string in the stereo field.</source>
|
||||
<translation>Der Balance-Knopf bestimmt den Ort der gewählten Saite im Stereo-Raum.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Detune</source>
|
||||
<translation>Verstimmung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Detune:</source>
|
||||
<translation>Verstimmung:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The Detune knob modifies the pitch of the selected string. Settings less than zero will cause the string to sound flat. Settings greater than zero will cause the string to sound sharp.</source>
|
||||
<translation>Der Verstimmungs-Knopf verändert die Tonhöhe der gewählten Saite. Einstellungen kleiner als 0 lassen die Saite flacher klingen, während Werte über 0 zu einem eher scharfen Klang führen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Fuzziness</source>
|
||||
<translation>Unschärfe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Fuzziness:</source>
|
||||
<translation>Unschärfe:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The Slap knob adds a bit of fuzz to the selected string which is most apparent during the attack, though it can also be used to make the string sound more 'metallic'.</source>
|
||||
<translation>Der Unschärfe-Knopf fügt dem Klang der Saite etwas 'Fuzz' hinzu, welcher hauptsächlich während des Anschlages zum Tragen kommt, wenngleich er auch genutzt werden kann, um den Klang etwas metallischer zu gestalten.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Length</source>
|
||||
<translation>Länge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Length:</source>
|
||||
<translation>Länge:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The Length knob sets the length of the selected string. Longer strings will both ring longer and sound brighter, however, they will also eat up more CPU cycles.</source>
|
||||
<translation>Der Länge-Knopf bestimmt die Länge der gewählten Saite. Längere Saiten klingen länger und klingen heller, wobei sie gleichzeitig auch mehr CPU-Leistung fressen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Impulse or initial state</source>
|
||||
<translation>Impuls oder Grundstellung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The 'Imp' selector determines whether the waveform in the graph is to be treated as an impulse imparted to the string by the pick or the initial state of the string.</source>
|
||||
<translation>Mit dem 'Imp'-Knopf legen Sie fest, ob die Wellenform in diesem Graph als Impuls zum Anzupfen der Saite oder als Grundstellung für die Saite genutzt werden soll.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The Octave selector is used to choose which harmonic of the note the string will ring at. For example, '-2' means the string will ring two octaves below the fundamental, 'F' means the string will ring at the fundamental, and '6' means the string will ring six octaves above the fundamental.</source>
|
||||
<translation>Mit dem Oktaven-Wähler kann der Oktavenversatz gegenüber der Note verändert werden. So meint beispielsweise eine Einstellung von '-2', dass die Saite zwei Oktaven unterhalb des Grundtons ('F') schwingen wird und '6' dementsprechend 6 Oktaven über dem Grundton.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The String selector is used to choose which string the controls are editting. A Vibed instrument can contain up to nine independently vibrating strings. The LED in the lower right corner of the waveform editor indicates whether the selected string is active.</source>
|
||||
<translation>Der Saiten-Wähler bestimmt die derzeit bearbeitete Saite. Ein Vibed-Instrument kann aus bis zu neun voneinander unabhängig schwingenden Saiten bestehen. Die LED in der Ecke rechts unterhalb der Wellenform gibt an, ob die gewählte Saite aktiv ist.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Vibed models up to nine independently vibrating strings. The 'String' selector allows you to choose which string is being edited. The 'Imp' selector chooses whether the graph represents an impulse or the initial state of the string. The 'Octave' selector chooses which harmonic the string should vibrate at.
|
||||
|
||||
The graph allows you to control the initial state or impulse used to set the string in motion.
|
||||
|
||||
The 'V' knob controls the volume. The 'S' knob controls the string's stiffness. The 'P' knob controls the pick position. The 'PU' knob controls the pickup position.
|
||||
|
||||
'Pan' and 'Detune' hopefully don't need explanation. The 'Slap' knob adds a bit of fuzz to the sound of the string.
|
||||
|
||||
The 'Length' knob controls the length of the string.
|
||||
|
||||
The LED in the lower right corner of the waveform editor determines whether the string is active in the current instrument.</source>
|
||||
<translation>Vibed modelliert bis zu 9 unabhängige schwingende Saiten. Der Saiten-Wähler ermöglicht die Wahl der gerade aktiven Saite. Der 'Imp'-Knopf bestimmt, ob der Graph einen Impuls oder die Grundstellung der Saite repräsentiert. Der Oktaven-Wähler gibt den Oktavenversatz der Saite gegenüber dem Grundton an.
|
||||
|
||||
Der Graph ermöglicht die Kontrolle über die Grundstellung der Saite oder den Impuls, der zum Anzupfen der Saite genutzt wird.
|
||||
|
||||
Der 'V'-Knopf bestimmt die Lautstärke. Mit dem 'S'-Knopf wird die Härte der Saite eingestellt. Der 'P'-Knopf beeinflusst den Ort, an dem die Saite angezupft wird, während der 'PU'-Knopf die Position des Abnehmers bestimmt.
|
||||
|
||||
'Balance' und 'Verstimmung' bedürfen hoffentlich keiner Erklärung. Der Unschärfe-Knopf fügt dem Klang der Saite etwas 'Fuzz' hinzu.
|
||||
|
||||
Der Länge-Knopf bestimmt die Länge der Saite.
|
||||
|
||||
Die LED rechts unterhalb der Wellenform gibt an, ob die Saite aktiviert ist.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Help</source>
|
||||
<translation>&Hilfe</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>visualizationWidget</name>
|
||||
<message>
|
||||
|
||||
@@ -190,7 +190,8 @@ public:
|
||||
|
||||
enum fileTypes
|
||||
{
|
||||
PROJECT_FILE, PRESET_FILE, SAMPLE_FILE, MIDI_FILE, UNKNOWN
|
||||
PROJECT_FILE, PRESET_FILE, SAMPLE_FILE, MIDI_FILE, FLP_FILE,
|
||||
UNKNOWN
|
||||
} ;
|
||||
|
||||
inline fileTypes type( void )
|
||||
@@ -207,6 +208,7 @@ private:
|
||||
static QPixmap * s_presetFilePixmap;
|
||||
static QPixmap * s_sampleFilePixmap;
|
||||
static QPixmap * s_midiFilePixmap;
|
||||
static QPixmap * s_flpFilePixmap;
|
||||
static QPixmap * s_unknownFilePixmap;
|
||||
|
||||
QPixmap * m_pix;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* midi.h - constants, structs etc. concerning MIDI
|
||||
*
|
||||
* Copyright (c) 2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -86,11 +86,23 @@ struct midiEvent
|
||||
{
|
||||
m_data.m_sysExDataLen = _data_len;
|
||||
}
|
||||
|
||||
inline Uint16 key( void ) const
|
||||
{
|
||||
return( m_data.m_param[0] );
|
||||
}
|
||||
inline Uint32 velocity( void ) const
|
||||
|
||||
inline Uint16 & key( void )
|
||||
{
|
||||
return( m_data.m_param[0] );
|
||||
}
|
||||
|
||||
inline Uint16 velocity( void ) const
|
||||
{
|
||||
return( m_data.m_param[1] );
|
||||
}
|
||||
|
||||
inline Uint16 & velocity( void )
|
||||
{
|
||||
return( m_data.m_param[1] );
|
||||
}
|
||||
|
||||
@@ -93,6 +93,11 @@ public:
|
||||
m_inputChannel = _chnl;
|
||||
}
|
||||
|
||||
inline void enableDefaultVelocityForInEvents( const bool _on )
|
||||
{
|
||||
m_defaultVelocityForInEventsEnabled = _on;
|
||||
}
|
||||
|
||||
inline Sint8 outputChannel( void ) const
|
||||
{
|
||||
return( m_outputChannel );
|
||||
@@ -103,6 +108,12 @@ public:
|
||||
m_outputChannel = _chnl;
|
||||
}
|
||||
|
||||
inline void enableDefaultVelocityForOutEvents( const bool _on )
|
||||
{
|
||||
m_defaultVelocityForOutEventsEnabled = _on;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FASTCALL processInEvent( const midiEvent & _me,
|
||||
const midiTime & _time );
|
||||
@@ -117,6 +128,8 @@ private:
|
||||
modes m_mode;
|
||||
Sint8 m_inputChannel;
|
||||
Sint8 m_outputChannel;
|
||||
bool m_defaultVelocityForInEventsEnabled;
|
||||
bool m_defaultVelocityForOutEventsEnabled;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ public slots:
|
||||
protected slots:
|
||||
void inputChannelChanged( int );
|
||||
void outputChannelChanged( int );
|
||||
void defaultVelInChanged( bool );
|
||||
void defaultVelOutChanged( bool );
|
||||
void readablePortsChanged( void );
|
||||
void writeablePortsChanged( void );
|
||||
void activatedReadablePort( QAction * _item );
|
||||
@@ -99,6 +101,8 @@ private:
|
||||
lcdSpinBox * m_outputChannelSpinBox;
|
||||
ledCheckBox * m_receiveCheckBox;
|
||||
ledCheckBox * m_sendCheckBox;
|
||||
ledCheckBox * m_defaultVelocityInCheckBox;
|
||||
ledCheckBox * m_defaultVelocityOutCheckBox;
|
||||
|
||||
QMenu * m_readablePorts;
|
||||
QMenu * m_writeablePorts;
|
||||
|
||||
@@ -2,5 +2,5 @@ if VST_SUPPORT
|
||||
VESTIGE_SUBDIR=vestige
|
||||
endif
|
||||
|
||||
SUBDIRS = audio_file_processor bit_invader midi_import organic plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR) vibed
|
||||
SUBDIRS = audio_file_processor bit_invader flp_import midi_import organic plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR) vibed
|
||||
|
||||
|
||||
12
plugins/flp_import/Makefile.am
Normal file
12
plugins/flp_import/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I.
|
||||
|
||||
|
||||
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="flpimport"
|
||||
|
||||
|
||||
pkglib_LTLIBRARIES= libflpimport.la
|
||||
|
||||
libflpimport_la_SOURCES = flp_import.cpp flp_import.h
|
||||
644
plugins/flp_import/flp_import.cpp
Normal file
644
plugins/flp_import/flp_import.cpp
Normal file
@@ -0,0 +1,644 @@
|
||||
/*
|
||||
* flp_import.cpp - support for importing FLP-files
|
||||
*
|
||||
* Copyright (c) 2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* This file partly contains code from Fluidsynth, Peter Hanappe
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "flp_import.h"
|
||||
|
||||
/*
|
||||
|
||||
|
||||
The FruityLoops
|
||||
FLP
|
||||
file format explained
|
||||
|
||||
(v 2.7.x)
|
||||
|
||||
(BETA)
|
||||
|
||||
|
||||
Introduction:
|
||||
|
||||
Here I will try to explain the FLP file format, which is the FruityLoops loop / song format. Visit www.fruityloops.com to get more info about FruityLoops.
|
||||
|
||||
First you've got to understand that FruityLoops keeps growing, so does the FLP format. Fortunately it has been designed for it... While I made some mistakes during its evolution, the format still remains updatable.
|
||||
Normally anything made out of this document will be able to process future loop files, although of course you will miss newly added features.
|
||||
|
||||
Not sure what this document could be useful for, but if you ever use it to make something, send it to me!
|
||||
Also if you'd like me to update this file (it's not complete yet), feel free to mail me.
|
||||
|
||||
(2/09/99) Didier Dambrin (gol)
|
||||
gol@fruityloops.com
|
||||
|
||||
|
||||
|
||||
How it works:
|
||||
|
||||
Don't expect the FLP format to be a big chunk full of ordered parameters, like most trackers file formats. It had to evolute, so I chose the 'events' way.
|
||||
You should see it a bit like MIDI / AIFF files. It's just a succession of events. Once you've understand how to process the file to retrieve these events, the only thing you'll need is the list of events available!
|
||||
|
||||
It's better, since once you've made the piece of code to get the events, you won't bother with the format anymore. Also you will just ignore any event you don't know (yet) about.
|
||||
|
||||
Please note that the format *does not* respect the AIFF standard, although I tried to keep the chunks system similar.
|
||||
|
||||
Although the program has been coded in Pascal, I'll do my best to use C++ declarations, so everyone will understand. DWORD is 4 bytes, WORD is 2 bytes.
|
||||
|
||||
|
||||
|
||||
Retrieving the events:
|
||||
|
||||
I said it looks like a MIDI file, but it's not a MIDI file.
|
||||
|
||||
First, you'll have to get & check the HEADER chunk, to be sure it's a FLP file.
|
||||
The header is similar to the format of a MIDI file header:
|
||||
|
||||
DWORD ChunkID 4 chars which are the letters 'FLhd' for 'FruityLoops header'
|
||||
DWORD Length The length of this chunk, like in MIDI files. Should be 6 because of the 3 WORDS below...
|
||||
WORD Format Set to 0 for full songs.
|
||||
WORD nChannels The total number of channels (not really used).
|
||||
WORD BeatDiv Pulses per quarter of the song.
|
||||
|
||||
Most of this chunk is not used, it's just that I tried (as a start) to respect the proper MIDI header :)
|
||||
|
||||
|
||||
Then you'll encounter the DATA chunk, which is in fact the last chunk, the one containing all the events.
|
||||
|
||||
DWORD ChunkID 4 chars which are the letters 'FLdt' for 'FruityLoops data'
|
||||
DWORD Length The length of this chunk WITHOUT these 2 DWORDS (that is minus 4*2 bytes), like in MIDI files.
|
||||
|
||||
|
||||
The whole data chunk is a succession of EVENTS, which I'm going to explain...
|
||||
To retrieve an event, first you read a byte (the event ID). According to this byte, the size of the event data varies:
|
||||
0..63 The data after this byte is a BYTE (signed or unsigned, depending on the ID).
|
||||
64..127 The data after this byte is a WORD.
|
||||
128..191 The data after this byte is a DWORD.
|
||||
192..255 The data after this byte is a variable-length block of data (a text for example).
|
||||
|
||||
That makes 64 BYTE events, 64 WORD events, 64 DWORD events & 64 TEXT events. The purpose of this split is of course to keep the file size small.
|
||||
So you get the event ID & then you read the number of bytes according to this ID. Whether you process the event or not isn't important. What is important is that you can jump correctly to the next event if you skip it.
|
||||
|
||||
|
||||
For TEXT (variable-length) events, you still have to read the size of the event, which is coded in the next byte(s) a bit like in MIDI files (but not stupidly inverted). After the size is the actual data, which you can process or skip.
|
||||
To get the size of the event, you've got to read bytes until the last one, which has bit 7 off (the purpose of this compression is to reduce the file size again).
|
||||
|
||||
Start with a DWORD Size = 0. You're going to reconstruct the size by getting packs of 7 bits:
|
||||
1. Get a byte.
|
||||
2. Add the first 7 bits of this byte to Size.
|
||||
3. Check bit 7 (the last bit) of this byte. If it's on, go back to 1. to process the next byte.
|
||||
|
||||
To resume, if Size < 128 then it will occupy only 1 byte, else if Size < 16384 it will occupy only 2 bytes & so on...
|
||||
|
||||
|
||||
So globally, you open the file, check the header, point to the data chunk & retrieve / filter all the events. Easy(?)
|
||||
Now let's get to the events...
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "track_container.h"
|
||||
#include "instrument_track.h"
|
||||
#include "pattern.h"
|
||||
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <Qt/QtXml>
|
||||
#include <QApplication>
|
||||
#include <QProgressDialog>
|
||||
|
||||
#else
|
||||
|
||||
#include <qdom.h>
|
||||
#include <qapplication.h>
|
||||
#include <qprogressdialog.h>
|
||||
|
||||
#define pos at
|
||||
#define setValue setProgress
|
||||
|
||||
#endif
|
||||
|
||||
#define makeID(_c0, _c1, _c2, _c3) \
|
||||
( ( _c0 ) | ( ( _c1 ) << 8 ) | ( ( _c2 ) << 16 ) | ( ( _c3 ) << 24 ) )
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
plugin::descriptor flpimport_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"FLP Import",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"Filter for importing FL Studio projects into LMMS" ),
|
||||
"Tobias Doerffel <tobydox/at/users/dot/sf/dot/net>",
|
||||
0x0100,
|
||||
plugin::IMPORT_FILTER,
|
||||
new QPixmap()
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
flpImport::flpImport( const QString & _file ) :
|
||||
importFilter( _file, &flpimport_plugin_descriptor, NULL )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
flpImport::~flpImport()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool flpImport::tryImport( trackContainer * _tc )
|
||||
{
|
||||
if( openFile() == FALSE )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if( readID() != makeID( 'F', 'L', 'h', 'd' ) )
|
||||
{
|
||||
printf( "flpImport::tryImport(): not a valid FL project\n" );
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
const int header_len = readInt( 4 );
|
||||
printf("%d\n", header_len );
|
||||
if( header_len != 6 )
|
||||
{
|
||||
invalid_format:
|
||||
printf( "flpImport::tryImport(): invalid file format\n" );
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
const int type = readInt( 2 );
|
||||
if( type != 0 )
|
||||
{
|
||||
printf( "flpImport::tryImport(): type %d format is not "
|
||||
"supported\n", type );
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
const int num_channels = readInt( 2 );
|
||||
if( num_channels < 1 || num_channels > 1000 )
|
||||
{
|
||||
printf( "flpImport::tryImport(): invalid number of channels "
|
||||
"(%d)\n", num_channels );
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
printf( "channels: %d\n", num_channels );
|
||||
|
||||
const int ppq = readInt( 2 );
|
||||
if( ppq < 0 )
|
||||
{
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
#ifdef QT4
|
||||
QProgressDialog pd( trackContainer::tr( "Importing FLP-file..." ),
|
||||
trackContainer::tr( "Cancel" ), 0, num_channels );
|
||||
#else
|
||||
QProgressDialog pd( trackContainer::tr( "Importing FLP-file..." ),
|
||||
trackContainer::tr( "Cancel" ), num_channels,
|
||||
0, 0, TRUE );
|
||||
#endif
|
||||
pd.setWindowTitle( trackContainer::tr( "Please wait..." ) );
|
||||
pd.show();
|
||||
|
||||
bool valid = FALSE;
|
||||
|
||||
// search for FLdt chunk
|
||||
while( 1 )
|
||||
{
|
||||
Sint32 id = readID();
|
||||
const int len = readInt( 4 );
|
||||
if( file().atEnd() )
|
||||
{
|
||||
printf( "flpImport::tryImport(): unexpected "
|
||||
"end of file\n" );
|
||||
return( FALSE );
|
||||
}
|
||||
if( len < 0 || len >= 0x10000000 )
|
||||
{
|
||||
printf( "flpImport::tryImport(): invalid "
|
||||
"chunk length %d\n", len );
|
||||
return( FALSE );
|
||||
}
|
||||
if( id == makeID( 'F', 'L', 'd', 't' ) )
|
||||
{
|
||||
valid = TRUE;
|
||||
break;
|
||||
}
|
||||
skip( len );
|
||||
}
|
||||
|
||||
if( valid == FALSE )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
instrumentTrack * it = NULL;
|
||||
pattern * p = NULL;
|
||||
int pat_cnt = 0;
|
||||
|
||||
|
||||
// read channels
|
||||
for( int i = 0; i < num_channels; ++i )
|
||||
{
|
||||
pd.setValue( i );
|
||||
#ifdef QT4
|
||||
qApp->processEvents( QEventLoop::AllEvents, 100 );
|
||||
#else
|
||||
qApp->processEvents( 100 );
|
||||
#endif
|
||||
|
||||
if( pd.wasCanceled() )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
flpEvents ev = static_cast<flpEvents>( readByte() );
|
||||
Uint32 data = readByte();
|
||||
|
||||
if( ev >= FLP_Word && ev < FLP_Text )
|
||||
{
|
||||
data = ( data << 8 ) + readByte();
|
||||
}
|
||||
|
||||
if( ev >= FLP_Int && ev < FLP_Text )
|
||||
{
|
||||
data = ( data << 8 ) + readByte();
|
||||
data = ( data << 8 ) + readByte();
|
||||
}
|
||||
|
||||
/*For TEXT (variable-length) events, you still have to read the size of the event, which is coded in the next byte(s) a bit like in MIDI files (but not stupidly inverted). After the size is the actual data, which you can process or skip.
|
||||
To get the size of the event, you've got to read bytes until the last one, which has bit 7 off (the purpose of this compression is to reduce the file size again).
|
||||
|
||||
Start with a DWORD Size = 0. You're going to reconstruct the size by getting packs of 7 bits:
|
||||
1. Get a byte.
|
||||
2. Add the first 7 bits of this byte to Size.
|
||||
3. Check bit 7 (the last bit) of this byte. If it's on, go back to 1. to process the next byte.
|
||||
|
||||
To resume, if Size < 128 then it will occupy only 1 byte, else if Size < 16384 it will occupy only 2 bytes & so on...
|
||||
*/
|
||||
|
||||
if( ev >= FLP_Text )
|
||||
{
|
||||
int read_so_far = 2;
|
||||
Uint32 len = data & 0x7F;
|
||||
while( data & 0x80 )
|
||||
{
|
||||
data = readByte();
|
||||
len = ( len << 7 ) | ( data & 0x7F );
|
||||
++read_so_far;
|
||||
}
|
||||
skip( len - read_so_far );
|
||||
continue;
|
||||
}
|
||||
|
||||
switch( ev )
|
||||
{
|
||||
case FLP_NoteOn:
|
||||
// data = pos how to handle?
|
||||
break;
|
||||
|
||||
case FLP_NewChan:
|
||||
m_events.clear();
|
||||
pat_cnt = 0;
|
||||
|
||||
it = dynamic_cast<instrumentTrack *>(
|
||||
track::create( track::CHANNEL_TRACK, _tc ) );
|
||||
assert( it != NULL );
|
||||
it->loadInstrument( "tripleoscillator" );
|
||||
it->toggledInstrumentTrackButton( FALSE );
|
||||
|
||||
continue;
|
||||
|
||||
case FLP_NewPat:
|
||||
p = dynamic_cast<pattern *>( it->createTCO(
|
||||
pat_cnt ) );
|
||||
assert( p != NULL );
|
||||
it->addTCO( p );
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "handling of FLP-event %d not "
|
||||
"implemented yet.", ev );
|
||||
break;
|
||||
}
|
||||
/*
|
||||
// now create new channel-track for reading track
|
||||
instrumentTrack * ct = dynamic_cast<instrumentTrack *>(
|
||||
track::create(
|
||||
track::CHANNEL_TRACK,
|
||||
_tc ) );
|
||||
#ifdef LMMS_DEBUG
|
||||
assert( ct != NULL );
|
||||
#endif
|
||||
// TODO: setup program, channel etc.
|
||||
ct->loadInstrument( "tripleoscillator" );
|
||||
ct->toggledInstrumentTrackButton( FALSE );
|
||||
|
||||
// now create pattern to store notes in
|
||||
pattern * p = dynamic_cast<pattern *>( ct->createTCO( 0 ) );
|
||||
#ifdef LMMS_DEBUG
|
||||
assert( p != NULL );
|
||||
#endif
|
||||
ct->addTCO( p );
|
||||
|
||||
// init keys
|
||||
int keys[NOTES_PER_OCTAVE * OCTAVES][2];
|
||||
for( int j = 0; j < NOTES_PER_OCTAVE * OCTAVES; ++j )
|
||||
{
|
||||
keys[j][0] = -1;
|
||||
}
|
||||
|
||||
// now process every event
|
||||
for( eventVector::const_iterator it = m_events.begin();
|
||||
it != m_events.end(); ++it )
|
||||
{
|
||||
const int tick = it->first;
|
||||
const midiEvent & ev = it->second;
|
||||
switch( ev.m_type )
|
||||
{
|
||||
case NOTE_ON:
|
||||
if( ev.key() >=
|
||||
NOTES_PER_OCTAVE * OCTAVES )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( ev.velocity() > 0 )
|
||||
{
|
||||
keys[ev.key()][0] = tick;
|
||||
keys[ev.key()][1] =
|
||||
ev.velocity();
|
||||
break;
|
||||
}
|
||||
|
||||
case NOTE_OFF:
|
||||
if( ev.key() <
|
||||
NOTES_PER_OCTAVE * OCTAVES &&
|
||||
keys[ev.key()][0] >= 0 )
|
||||
{
|
||||
note n( eng(),
|
||||
midiTime( ( tick - keys[ev.key()][0] ) / 10 ),
|
||||
midiTime( keys[ev.key()][0] / 10 ),
|
||||
(tones)( ev.key() % NOTES_PER_OCTAVE ),
|
||||
(octaves)( ev.key() / NOTES_PER_OCTAVE ),
|
||||
keys[ev.key()][1] * 100 / 128 );
|
||||
p->addNote( n );
|
||||
keys[ev.key()][0] = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// printf( "Unhandled event: %#x\n",
|
||||
// ev.m_type );
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
bool FASTCALL flpImport::readTrack( int _track_end )
|
||||
{
|
||||
int tick = 0;
|
||||
unsigned char last_cmd = 0;
|
||||
// unsigned char port = 0;
|
||||
|
||||
m_events.clear();
|
||||
// the current file position is after the track ID and length
|
||||
while( (int) file().pos() < _track_end )
|
||||
{
|
||||
unsigned char cmd;
|
||||
int len;
|
||||
|
||||
int delta_ticks = readVar();
|
||||
if( delta_ticks < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
tick += delta_ticks;
|
||||
|
||||
int c = readByte();
|
||||
if( c < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
if( c & 0x80 )
|
||||
{
|
||||
// have command
|
||||
cmd = c;
|
||||
if( cmd < 0xf0 )
|
||||
{
|
||||
last_cmd = cmd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// running status
|
||||
ungetChar( c );
|
||||
cmd = last_cmd;
|
||||
if( !cmd )
|
||||
{
|
||||
error();
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
switch( cmd & 0xF0 )
|
||||
{
|
||||
// channel msg with 2 parameter bytes
|
||||
case NOTE_OFF:
|
||||
case NOTE_ON:
|
||||
case KEY_PRESSURE:
|
||||
case CONTROL_CHANGE:
|
||||
case PITCH_BEND:
|
||||
{
|
||||
int data1 = readByte() & 0x7F;
|
||||
int data2 = readByte() & 0x7F;
|
||||
m_events.push_back( qMakePair( tick,
|
||||
midiEvent( static_cast<midiEventTypes>(
|
||||
cmd & 0xF0 ),
|
||||
cmd & 0x0F,
|
||||
data1,
|
||||
data2 ) ) );
|
||||
break;
|
||||
}
|
||||
// channel msg with 1 parameter byte
|
||||
case PROGRAM_CHANGE:
|
||||
case CHANNEL_PRESSURE:
|
||||
m_events.push_back( qMakePair( tick,
|
||||
midiEvent( static_cast<midiEventTypes>(
|
||||
cmd & 0xF0 ),
|
||||
cmd & 0x0F,
|
||||
readByte() & 0x7F ) ) );
|
||||
break;
|
||||
|
||||
case MIDI_SYSEX:
|
||||
switch( cmd )
|
||||
{
|
||||
case MIDI_SYSEX:
|
||||
case MIDI_EOX:
|
||||
{
|
||||
len = readVar();
|
||||
if( len < 0 )
|
||||
{
|
||||
error();
|
||||
return( FALSE );
|
||||
}
|
||||
if( cmd == MIDI_SYSEX )
|
||||
{
|
||||
++len;
|
||||
}
|
||||
char * data = new char[len];
|
||||
if( cmd == MIDI_SYSEX )
|
||||
{
|
||||
data[0] = MIDI_SYSEX;
|
||||
}
|
||||
for( ; c < len; ++c )
|
||||
{
|
||||
data[c] = readByte();
|
||||
}
|
||||
m_events.push_back(
|
||||
qMakePair( tick,
|
||||
midiEvent( MIDI_SYSEX, data, len ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case MIDI_META_EVENT:
|
||||
c = readByte();
|
||||
len = readVar();
|
||||
/* if( len < 0 )
|
||||
{
|
||||
error();
|
||||
return( FALSE );
|
||||
}*/
|
||||
switch( c )
|
||||
{
|
||||
case 0x21: // port number
|
||||
if( len < 1 )
|
||||
{
|
||||
error();
|
||||
return( FALSE );
|
||||
}
|
||||
/* port = readByte() %
|
||||
port_count;
|
||||
skip( len - 1 );*/
|
||||
skip( len );
|
||||
break;
|
||||
|
||||
case 0x2F: // end of track
|
||||
//track->end_tick = tick;
|
||||
skip( _track_end -
|
||||
file().pos() );
|
||||
return( TRUE );
|
||||
|
||||
case 0x51: // tempo
|
||||
if( len < 3 )
|
||||
{
|
||||
error();
|
||||
return( FALSE );
|
||||
}
|
||||
if( m_smpteTiming )
|
||||
{
|
||||
// SMPTE timing
|
||||
// doesnt change
|
||||
skip( len );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* event = new_event(track, 0);
|
||||
event->type = SND_SEQ_EVENT_TEMPO;
|
||||
event->port = port;
|
||||
event->tick = tick;
|
||||
event->data.tempo = read_byte() << 16;
|
||||
event->data.tempo |= read_byte() << 8;
|
||||
event->data.tempo |= read_byte();
|
||||
skip( len -3 );*/
|
||||
skip( len );
|
||||
}
|
||||
break;
|
||||
|
||||
default:// ignore all other
|
||||
// meta events
|
||||
skip( len );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: // invalid Fx command
|
||||
error();
|
||||
return( FALSE );
|
||||
}
|
||||
break;
|
||||
|
||||
default: // cannot happen
|
||||
error();
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
error();
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
|
||||
void flpImport::error( void )
|
||||
{
|
||||
printf( "flpImport::readTrack(): invalid MIDI data (offset %#x)\n",
|
||||
(unsigned int) file().pos() );
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// neccessary for getting instance out of shared lib
|
||||
plugin * lmms_plugin_main( void * _data )
|
||||
{
|
||||
return( new flpImport( static_cast<const char *>( _data ) ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#undef pos
|
||||
#undef setValue
|
||||
247
plugins/flp_import/flp_import.h
Executable file
247
plugins/flp_import/flp_import.h
Executable file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* flp_import.h - support for importing FLP-files
|
||||
*
|
||||
* Copyright (c) 2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FLP_IMPORT_H
|
||||
#define _FLP_IMPORT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QString>
|
||||
#include <QPair>
|
||||
#include <QVector>
|
||||
|
||||
#else
|
||||
|
||||
#include <qstring.h>
|
||||
#include <qpair.h>
|
||||
#include <qvaluevector.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "midi.h"
|
||||
#include "import_filter.h"
|
||||
|
||||
|
||||
enum flpEvents
|
||||
{
|
||||
// BYTE EVENTS
|
||||
FLP_Byte = 0,
|
||||
FLP_Enabled = 0,
|
||||
FLP_NoteOn = 1, //+pos (byte)
|
||||
FLP_Vol = 2,
|
||||
FLP_Pan = 3,
|
||||
FLP_MIDIChan = 4,
|
||||
FLP_MIDINote = 5,
|
||||
FLP_MIDIPatch = 6,
|
||||
FLP_MIDIBank = 7,
|
||||
FLP_LoopActive = 9,
|
||||
FLP_ShowInfo = 10,
|
||||
FLP_Shuffle = 11,
|
||||
FLP_MainVol = 12,
|
||||
FLP_Stretch = 13, // old byte version
|
||||
FLP_Pitchable = 14,
|
||||
FLP_Zipped = 15,
|
||||
FLP_Delay_Flags = 16,
|
||||
FLP_PatLength = 17,
|
||||
FLP_BlockLength = 18,
|
||||
FLP_UseLoopPoints = 19,
|
||||
FLP_LoopType = 20,
|
||||
FLP_ChanType = 21,
|
||||
FLP_MixSliceNum = 22,
|
||||
|
||||
// WORD EVENTS
|
||||
FLP_Word = 64,
|
||||
FLP_NewChan = FLP_Word,
|
||||
FLP_NewPat = FLP_Word + 1, //+PatNum (word)
|
||||
FLP_Tempo = FLP_Word + 2,
|
||||
FLP_CurrentPatNum = FLP_Word + 3,
|
||||
FLP_PatData = FLP_Word + 4,
|
||||
FLP_FX = FLP_Word + 5,
|
||||
FLP_Fade_Stereo = FLP_Word + 6,
|
||||
FLP_CutOff = FLP_Word + 7,
|
||||
FLP_DotVol = FLP_Word + 8,
|
||||
FLP_DotPan = FLP_Word + 9,
|
||||
FLP_PreAmp = FLP_Word + 10,
|
||||
FLP_Decay = FLP_Word + 11,
|
||||
FLP_Attack = FLP_Word + 12,
|
||||
FLP_DotNote = FLP_Word + 13,
|
||||
FLP_DotPitch = FLP_Word + 14,
|
||||
FLP_DotMix = FLP_Word + 15,
|
||||
FLP_MainPitch = FLP_Word + 16,
|
||||
FLP_RandChan = FLP_Word + 17,
|
||||
FLP_MixChan = FLP_Word + 18,
|
||||
FLP_Resonance = FLP_Word + 19,
|
||||
FLP_LoopBar = FLP_Word + 20,
|
||||
FLP_StDel = FLP_Word + 21,
|
||||
FLP_FX3 = FLP_Word + 22,
|
||||
FLP_DotReso = FLP_Word + 23,
|
||||
FLP_DotCutOff = FLP_Word + 24,
|
||||
FLP_ShiftDelay = FLP_Word + 25,
|
||||
FLP_LoopEndBar = FLP_Word + 26,
|
||||
FLP_Dot = FLP_Word + 27,
|
||||
FLP_DotShift = FLP_Word + 28,
|
||||
|
||||
// DWORD EVENTS
|
||||
FLP_Int = 128,
|
||||
FLP_Color = FLP_Int,
|
||||
FLP_PlayListItem = FLP_Int + 1, //+Pos (word) +PatNum (word)
|
||||
FLP_Echo = FLP_Int + 2,
|
||||
FLP_FXSine = FLP_Int + 3,
|
||||
FLP_CutCutBy = FLP_Int + 4,
|
||||
FLP_WindowH = FLP_Int + 5,
|
||||
FLP_MiddleNote = FLP_Int + 7,
|
||||
FLP_Reserved = FLP_Int + 8, // may contain an invalid version info
|
||||
FLP_MainResoCutOff = FLP_Int + 9,
|
||||
FLP_DelayReso = FLP_Int + 10,
|
||||
FLP_Reverb = FLP_Int + 11,
|
||||
FLP_IntStretch = FLP_Int + 12,
|
||||
FLP_SSNote = FLP_Int + 13,
|
||||
FLP_FineTune = FLP_Int + 14,
|
||||
|
||||
// TEXT EVENTS
|
||||
FLP_Undef = 192, //+Size (var length)
|
||||
FLP_Text = FLP_Undef, //+Size (var length)+Text
|
||||
// (Null Term. String)
|
||||
FLP_Text_ChanName = FLP_Text, // name for the current channel
|
||||
FLP_Text_PatName = FLP_Text + 1, // name for the current pattern
|
||||
FLP_Text_Title = FLP_Text + 2, // title of the loop
|
||||
FLP_Text_Comment = FLP_Text + 3, // old comments in text format.
|
||||
// Not used anymore
|
||||
FLP_Text_SampleFileName = FLP_Text + 4, // filename for the sample in
|
||||
// the current channel, stored
|
||||
// as relative path
|
||||
FLP_Text_URL = FLP_Text + 5,
|
||||
FLP_Text_CommentRTF = FLP_Text + 6, // new comments in Rich Text
|
||||
// format
|
||||
FLP_Version = FLP_Text + 7,
|
||||
FLP_Text_PluginName = FLP_Text + 9, // plugin file name
|
||||
// (without path)
|
||||
|
||||
FLP_MIDICtrls = FLP_Text + 16,
|
||||
FLP_Delay = FLP_Text + 17,
|
||||
FLP_TS404Params = FLP_Text + 18,
|
||||
FLP_DelayLine = FLP_Text + 19,
|
||||
FLP_NewPlugin = FLP_Text + 20,
|
||||
FLP_PluginParams = FLP_Text + 21,
|
||||
FLP_ChanParams = FLP_Text + 23,// block of various channel
|
||||
// params (can grow)
|
||||
|
||||
FLP_CmdCount
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class flpImport : public importFilter
|
||||
{
|
||||
public:
|
||||
flpImport( const QString & _file );
|
||||
virtual ~flpImport();
|
||||
|
||||
|
||||
private:
|
||||
virtual bool tryImport( trackContainer * _tc );
|
||||
|
||||
inline int readInt( int _bytes )
|
||||
{
|
||||
int c, value = 0;
|
||||
do
|
||||
{
|
||||
c = readByte();
|
||||
if( c == -1 )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
value = ( value << 8 ) | c;
|
||||
} while( --_bytes );
|
||||
return( value );
|
||||
}
|
||||
|
||||
inline Sint32 read32LE( void )
|
||||
{
|
||||
int value = readByte();
|
||||
value |= readByte() << 8;
|
||||
value |= readByte() << 16;
|
||||
value |= readByte() << 24;
|
||||
return( value );
|
||||
}
|
||||
/* inline int readVar( void )
|
||||
{
|
||||
int c = readByte();
|
||||
int value = c & 0x7f;
|
||||
if( c & 0x80 )
|
||||
{
|
||||
c = readByte();
|
||||
value = ( value << 7 ) | ( c & 0x7f );
|
||||
if( c & 0x80 )
|
||||
{
|
||||
c = readByte();
|
||||
value = ( value << 7 ) | ( c & 0x7f );
|
||||
if( c & 0x80 )
|
||||
{
|
||||
c = readByte();
|
||||
value = ( value << 7 ) | c;
|
||||
if( c & 0x80 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return( !file().atEnd() ? value : -1 );
|
||||
}*/
|
||||
|
||||
inline Sint32 readID( void )
|
||||
{
|
||||
return( read32LE() );
|
||||
}
|
||||
|
||||
inline void skip( int _bytes )
|
||||
{
|
||||
while( _bytes > 0 )
|
||||
{
|
||||
readByte();
|
||||
--_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef vvector<QPair<int, midiEvent> > eventVector;
|
||||
eventVector m_events;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -101,8 +101,8 @@ bool midiImport::tryImport( trackContainer * _tc )
|
||||
return( readRIFF( _tc ) );
|
||||
|
||||
default:
|
||||
printf( "midiImport::importToTrackContainer(): not a "
|
||||
"Standard MIDI file\n" );
|
||||
printf( "midiImport::tryImport(): not a Standard MIDI "
|
||||
"file\n" );
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* midi_import_filter.h - support for importing MIDI-files
|
||||
* midi_import.h - support for importing MIDI-files
|
||||
*
|
||||
* Copyright (c) 2005-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
|
||||
Binary file not shown.
@@ -376,13 +376,14 @@ void listView::contentsMouseDoubleClickEvent( QMouseEvent * _me )
|
||||
multimediaProject mmp( f->fullName() );
|
||||
track * t = track::create( track::CHANNEL_TRACK,
|
||||
eng()->getBBEditor() );
|
||||
instrumentTrack * ct = dynamic_cast<instrumentTrack *>( t );
|
||||
if( ct != NULL )
|
||||
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
|
||||
t );
|
||||
if( it != NULL )
|
||||
{
|
||||
ct->loadTrackSpecificSettings( mmp.content().
|
||||
it->loadTrackSpecificSettings( mmp.content().
|
||||
firstChild().
|
||||
toElement() );
|
||||
ct->toggledInstrumentTrackButton( TRUE );
|
||||
it->toggledInstrumentTrackButton( TRUE );
|
||||
}
|
||||
}
|
||||
else if( f->type() == fileItem::PROJECT_FILE )
|
||||
@@ -425,7 +426,8 @@ void listView::contentsMousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( m_previewPlayHandle != NULL )
|
||||
{
|
||||
eng()->getMixer()->removePlayHandle( m_previewPlayHandle );
|
||||
eng()->getMixer()->removePlayHandle(
|
||||
m_previewPlayHandle );
|
||||
m_previewPlayHandle = NULL;
|
||||
}
|
||||
if( f->type() == fileItem::SAMPLE_FILE )
|
||||
@@ -704,6 +706,7 @@ QPixmap * fileItem::s_projectFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_presetFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_sampleFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_midiFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_flpFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_unknownFilePixmap = NULL;
|
||||
|
||||
|
||||
@@ -759,6 +762,12 @@ void fileItem::initPixmapStuff( void )
|
||||
"midi_file", 16, 16 ) );
|
||||
}
|
||||
|
||||
if( s_flpFilePixmap == NULL )
|
||||
{
|
||||
s_flpFilePixmap = new QPixmap( embed::getIconPixmap(
|
||||
"midi_file", 16, 16 ) );
|
||||
}
|
||||
|
||||
if( s_unknownFilePixmap == NULL )
|
||||
{
|
||||
s_unknownFilePixmap = new QPixmap( embed::getIconPixmap(
|
||||
@@ -771,6 +780,7 @@ void fileItem::initPixmapStuff( void )
|
||||
case PRESET_FILE: m_pix = s_presetFilePixmap; break;
|
||||
case SAMPLE_FILE: m_pix = s_sampleFilePixmap; break;
|
||||
case MIDI_FILE: m_pix = s_midiFilePixmap; break;
|
||||
case FLP_FILE: m_pix = s_flpFilePixmap; break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
m_pix = s_unknownFilePixmap;
|
||||
@@ -823,6 +833,10 @@ void fileItem::determineFileType( void )
|
||||
{
|
||||
m_type = MIDI_FILE;
|
||||
}
|
||||
else if( ext == "flp" )
|
||||
{
|
||||
m_type = FLP_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = UNKNOWN;
|
||||
|
||||
@@ -110,7 +110,7 @@ void importFilter::import( const QString & _file_to_import,
|
||||
"importing file %1.\n"
|
||||
"You should convert this file "
|
||||
"into a format supported by "
|
||||
"LMMS using another software. "
|
||||
"LMMS using another software."
|
||||
).arg( _file_to_import ),
|
||||
QMessageBox::Ok,
|
||||
QMessageBox::NoButton );
|
||||
|
||||
@@ -127,7 +127,7 @@ mainWindow::mainWindow( engine * _engine ) :
|
||||
QString wdir = configManager::inst()->workingDir();
|
||||
side_bar->appendTab( new pluginBrowser( splitter, eng() ), ++id );
|
||||
side_bar->appendTab( new fileBrowser( wdir+"projects",
|
||||
"*.mmp *.xml *.mid",
|
||||
"*.mmp *.xml *.mid *.flp",
|
||||
tr( "My projects" ),
|
||||
embed::getIconPixmap( "project_file" ),
|
||||
splitter, eng() ),
|
||||
|
||||
@@ -71,7 +71,7 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track,
|
||||
{
|
||||
m_setupTabWidget = new tabWidget( tr( "MIDI-SETUP FOR THIS CHANNEL" ),
|
||||
this );
|
||||
m_setupTabWidget->setGeometry( 4, 5, 238, 160 );
|
||||
m_setupTabWidget->setGeometry( 4, 5, 238, 200 );
|
||||
|
||||
|
||||
m_inputChannelSpinBox = new lcdSpinBox( 0, MIDI_CHANNEL_COUNT, 3,
|
||||
@@ -89,7 +89,7 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track,
|
||||
m_outputChannelSpinBox->setValue( m_midiPort->outputChannel() + 1 );
|
||||
//m_outputChannelSpinBox->addTextForValue( 0, "---" );
|
||||
m_outputChannelSpinBox->setLabel( tr( "CHANNEL" ) );
|
||||
m_outputChannelSpinBox->move( 28, 112 );
|
||||
m_outputChannelSpinBox->move( 28, 132 );
|
||||
connect( m_outputChannelSpinBox, SIGNAL( valueChanged( int ) ),
|
||||
this, SLOT( outputChannelChanged( int ) ) );
|
||||
outputChannelChanged( m_outputChannelSpinBox->value() );
|
||||
@@ -103,15 +103,29 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track,
|
||||
connect( m_receiveCheckBox, SIGNAL( toggled( bool ) ),
|
||||
m_inputChannelSpinBox, SLOT( setEnabled( bool ) ) );
|
||||
|
||||
m_defaultVelocityInCheckBox = new ledCheckBox( tr( "Default velocity "
|
||||
"for all input-events" ),
|
||||
m_setupTabWidget, eng() );
|
||||
m_defaultVelocityInCheckBox->move( 28, 84 );
|
||||
connect( m_defaultVelocityInCheckBox, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( defaultVelInChanged( bool ) ) );
|
||||
|
||||
|
||||
m_sendCheckBox = new ledCheckBox( tr( "Send MIDI-events" ),
|
||||
m_setupTabWidget, eng() );
|
||||
m_sendCheckBox->move( 10, 94 );
|
||||
m_sendCheckBox->move( 10, 114 );
|
||||
connect( m_sendCheckBox, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( midiPortModeToggled( bool ) ) );
|
||||
connect( m_sendCheckBox, SIGNAL( toggled( bool ) ),
|
||||
m_outputChannelSpinBox, SLOT( setEnabled( bool ) ) );
|
||||
|
||||
m_defaultVelocityOutCheckBox = new ledCheckBox( tr( "Default velocity "
|
||||
"for all output-events" ),
|
||||
m_setupTabWidget, eng() );
|
||||
m_defaultVelocityOutCheckBox->move( 28, 164 );
|
||||
connect( m_defaultVelocityOutCheckBox, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( defaultVelOutChanged( bool ) ) );
|
||||
|
||||
|
||||
const midiPort::modes m = m_midiPort->mode();
|
||||
m_receiveCheckBox->setChecked( m == midiPort::INPUT ||
|
||||
@@ -168,7 +182,7 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track,
|
||||
wp_btn->setText( tr( "MIDI-devices to send MIDI-events "
|
||||
"to" ) );
|
||||
wp_btn->setIcon( embed::getIconPixmap( "midi_out" ) );
|
||||
wp_btn->setGeometry( 186, 94, 40, 40 );
|
||||
wp_btn->setGeometry( 186, 114, 40, 40 );
|
||||
wp_btn->setMenu( m_writeablePorts );
|
||||
#ifdef QT4
|
||||
wp_btn->setPopupMode( QToolButton::InstantPopup );
|
||||
@@ -199,6 +213,10 @@ void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
_this.setAttribute( "outputchannel", m_outputChannelSpinBox->value() );
|
||||
_this.setAttribute( "receive", m_receiveCheckBox->isChecked() );
|
||||
_this.setAttribute( "send", m_sendCheckBox->isChecked() );
|
||||
_this.setAttribute( "defvelin",
|
||||
m_defaultVelocityInCheckBox->isChecked() );
|
||||
_this.setAttribute( "defvelout",
|
||||
m_defaultVelocityOutCheckBox->isChecked() );
|
||||
|
||||
if( m_readablePorts != NULL && m_receiveCheckBox->isChecked() == TRUE )
|
||||
{
|
||||
@@ -274,6 +292,10 @@ void midiTabWidget::loadSettings( const QDomElement & _this )
|
||||
).toInt() );
|
||||
m_receiveCheckBox->setChecked( _this.attribute( "receive" ).toInt() );
|
||||
m_sendCheckBox->setChecked( _this.attribute( "send" ).toInt() );
|
||||
m_defaultVelocityInCheckBox->setChecked(
|
||||
_this.attribute( "defvelin" ).toInt() );
|
||||
m_defaultVelocityOutCheckBox->setChecked(
|
||||
_this.attribute( "defvelout" ).toInt() );
|
||||
|
||||
// restore connections
|
||||
|
||||
@@ -359,6 +381,22 @@ void midiTabWidget::outputChannelChanged( int _new_chnl )
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::defaultVelInChanged( bool _on )
|
||||
{
|
||||
m_midiPort->enableDefaultVelocityForInEvents( _on );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::defaultVelOutChanged( bool _on )
|
||||
{
|
||||
m_midiPort->enableDefaultVelocityForOutEvents( _on );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::midiPortModeToggled( bool )
|
||||
{
|
||||
// this small lookup-table makes everything easier
|
||||
|
||||
@@ -1599,10 +1599,10 @@ bool FASTCALL songEditor::saveProjectAs( const QString & _file_name )
|
||||
void songEditor::importProject( void )
|
||||
{
|
||||
#ifdef QT4
|
||||
QFileDialog ofd( this, tr( "Import file" ), "",
|
||||
tr( "MIDI-files (*.mid)" ) );
|
||||
QFileDialog ofd( this, tr( "Import file" ), ""/*,
|
||||
tr( "MIDI-files (*.mid)" )*/ );
|
||||
#else
|
||||
QFileDialog ofd( QString::null, tr( "MIDI-files (*.mid)" ),
|
||||
QFileDialog ofd( QString::null,/* tr( "MIDI-files (*.mid)" )*/ QString::null,
|
||||
this, "", TRUE );
|
||||
ofd.setWindowTitle( tr( "Import file" ) );
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* midi_port.cpp - abstraction of MIDI-ports which are part of LMMS's MIDI-
|
||||
* sequencing system
|
||||
*
|
||||
* Copyright (c) 2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "midi_port.h"
|
||||
#include "midi_client.h"
|
||||
#include "volume.h"
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +39,9 @@ midiPort::midiPort( midiClient * _mc, midiEventProcessor * _mep,
|
||||
m_name( _name ),
|
||||
m_mode( _mode ),
|
||||
m_inputChannel( -1 ),
|
||||
m_outputChannel( -1 )
|
||||
m_outputChannel( -1 ),
|
||||
m_defaultVelocityForInEventsEnabled( FALSE ),
|
||||
m_defaultVelocityForOutEventsEnabled( FALSE )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,7 +79,13 @@ void midiPort::processInEvent( const midiEvent & _me, const midiTime & _time )
|
||||
if( ( mode() == INPUT || mode() == DUPLEX ) &&
|
||||
( inputChannel() == _me.m_channel || inputChannel() == -1 ) )
|
||||
{
|
||||
m_midiEventProcessor->processInEvent( _me, _time );
|
||||
midiEvent ev = _me;
|
||||
if( m_defaultVelocityForInEventsEnabled == TRUE &&
|
||||
_me.velocity() > 0 )
|
||||
{
|
||||
ev.velocity() = DEFAULT_VOLUME;
|
||||
}
|
||||
m_midiEventProcessor->processInEvent( ev, _time );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +98,13 @@ void midiPort::processOutEvent( const midiEvent & _me, const midiTime & _time )
|
||||
if( ( mode() == OUTPUT || mode() == DUPLEX ) &&
|
||||
( outputChannel() == _me.m_channel && outputChannel() != -1 ) )
|
||||
{
|
||||
m_midiClient->processOutEvent( _me, _time, this );
|
||||
midiEvent ev = _me;
|
||||
if( m_defaultVelocityForOutEventsEnabled == TRUE &&
|
||||
_me.velocity() > 0 )
|
||||
{
|
||||
ev.velocity() = DEFAULT_VOLUME;
|
||||
}
|
||||
m_midiClient->processOutEvent( ev, _time, this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user