fundamental changes in plugin-architecture, added plugin-browser, bug-fixes - see ChangeLog for further details
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@18 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
141
ChangeLog
141
ChangeLog
@@ -1,3 +1,144 @@
|
||||
2005-10-19 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* plugins/vestige/vestige.h:
|
||||
* plugins/vestige/vestige.cpp:
|
||||
added possibility of opening plugins instead of hardcoding them ;-)
|
||||
|
||||
* include/track.h:
|
||||
renamed createTrack() and cloneTrack() to create() and clone()
|
||||
|
||||
* include/track_container.h:
|
||||
* src/core/track_container.cpp:
|
||||
receive drop-events -> add channel with instrument/preset
|
||||
|
||||
* src/audio/audio_jack.cpp:
|
||||
removed usleep() out of loop in audioJACK::writeBufferToDev() since it
|
||||
caused LMMS to hang e.g when removing a track
|
||||
|
||||
* src/core/plugin_browser.cpp:
|
||||
show hand-cursor if over a plugin-description-widget
|
||||
|
||||
* src/widgets/pixmap_button.cpp:
|
||||
if pixmap-button is set non-checkable, draw active-graphic if pressed
|
||||
down and inactive one in normal state
|
||||
|
||||
* include/lmms_main_win.h:
|
||||
* src/core/lmms_main_win.cpp:
|
||||
own workspace for making wheelEvent(...) is now obsolete -> removed
|
||||
|
||||
* include/track_container.h:
|
||||
* src/core/song_editor.cpp:
|
||||
* src/core/track_container.cpp:
|
||||
added own scroll-area for capturing special wheel-events where a
|
||||
modifier-key (shift, control etc.) is pressed
|
||||
|
||||
* src/core/song_editor.cpp:
|
||||
removed add-channel-button as it is obsolete after adding plugin-browser
|
||||
|
||||
* resources/:
|
||||
improved icons such as project_*.png and sample-track-related icons
|
||||
|
||||
2005-10-18 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* include/channel_track.h:
|
||||
* src/tracks/channel_track.cpp:
|
||||
- moved channelButton-implementation to channel_track.src
|
||||
- added support for receiving drop-events, which makes channel-track
|
||||
to load either the given instrument or the given preset
|
||||
|
||||
* src/core/plugin_browser.cpp:
|
||||
* include/plugin_browser.h:
|
||||
added cool plugin-browser, which displays all available instrument-
|
||||
plugins which are draggable to a channel-window/button
|
||||
|
||||
* include/string_pair_drag.h:
|
||||
* src/lib/string_pair_drag.cpp:
|
||||
added drag'n'drop-implementation for dragging string-pairs (key/value)
|
||||
which provides a standard-interface, although drag'n'drop has changed a
|
||||
lot in Qt 4
|
||||
|
||||
* src/widgets/crystal_button.cpp:
|
||||
made mouseMoveEvent()-method much more effective
|
||||
|
||||
* Makefile.am:
|
||||
* buildtools/Makefile.am:
|
||||
build buildtools in subdir instead of top-build-directory - solves
|
||||
dependendy problems with bin2res
|
||||
|
||||
* src/core/file_browser.cpp:
|
||||
do not depend on typeinfo of audioFileProcessor anymore by using
|
||||
new setParameter()-method
|
||||
|
||||
* include/plugin.h:
|
||||
added setParameter() and getParameter()-methods for making LMMS able to
|
||||
set parameters of a specific plugin without knowing anything about it
|
||||
|
||||
2005-10-17 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* buildtools/bin2res.cpp:
|
||||
* include/embed.h:
|
||||
* src/lib/embed.cpp:
|
||||
- declaration of embedded-data-descriptor is now located in embed.h and
|
||||
part of namespace embed
|
||||
- added support for local embedded-resources which is important for
|
||||
plugins containing their own images etc., so data and access-methods
|
||||
are stored into namespace PLUGIN_NAME
|
||||
|
||||
* include/plugin.h:
|
||||
* src/core/plugin.cpp:
|
||||
added logo-field to descriptor-structure and simplified method for
|
||||
getting descriptors of all plugins
|
||||
|
||||
* include/basic_filters.h:
|
||||
removed Moog-2-filter as it is only very CPU-intensive without any
|
||||
significant difference to sound of normal Moog-filter
|
||||
|
||||
2005-10-16 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* src/lib/ladspa_manager.cpp:
|
||||
skip not existing/unreadable directories when searching for plugins
|
||||
|
||||
* include/vestige.h:
|
||||
* src/plugins/vestige.cpp:
|
||||
make use of new instrument-play-handle
|
||||
|
||||
* include/channel_track.h:
|
||||
* src/core/browser.cpp:
|
||||
* src/core/song_editor.cpp:
|
||||
* src/midi/midi_file.cpp:
|
||||
* src/tracks/channel_track.cpp:
|
||||
renamed loadPlugin() to loadInstrument()
|
||||
|
||||
* include/config_mgr.h:
|
||||
* src/core/config_mgr.cpp:
|
||||
added pluginDir()-method
|
||||
|
||||
* include/instrument_play_handle.h:
|
||||
added another play-handle for playing instruments which do not
|
||||
produce sound for each note
|
||||
|
||||
* src/plugins/:
|
||||
renamed directory soundgenerators to plugins and modified all plugins
|
||||
for working with revised plugin-system
|
||||
|
||||
* include/instrument.h:
|
||||
* include/plugin.h:
|
||||
* src/core/instrument.cpp:
|
||||
* src/core/plugin.cpp:
|
||||
splitted code from instrument up into class plugin and class instrument
|
||||
and revised plugin-system
|
||||
|
||||
* include/instrument.h:
|
||||
* src/core/instrument.cpp:
|
||||
renamed files soundgenerator.* to instrument.* as well as class-name
|
||||
|
||||
2005-10-15 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* include/vestige.h:
|
||||
* src/soundgenerators/vestige.cpp:
|
||||
new plugin "VeSTige" for handling VST-plugins - VERY experimental,
|
||||
but at least, we get some sound out of these strange dll-files ;-)
|
||||
|
||||
2005-10-13 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* src/audio/audio_jack.cpp:
|
||||
|
||||
60
Makefile.am
60
Makefile.am
@@ -19,24 +19,23 @@ rpm: $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE).spec
|
||||
endif
|
||||
|
||||
|
||||
noinst_PROGRAMS= bin2res
|
||||
bin2res_SOURCES = buildtools/bin2res.cpp
|
||||
|
||||
SUBDIRS = artwork buildtools locale midi-maps plugins presets projects samples
|
||||
|
||||
|
||||
INCLUDES = -I$(srcdir)/include -I.
|
||||
bin_PROGRAMS = lmms
|
||||
|
||||
|
||||
|
||||
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS)
|
||||
|
||||
|
||||
%.moc: $(srcdir)/include/%.h
|
||||
$(MOC) -o $@ $<
|
||||
|
||||
|
||||
%.ts:
|
||||
$(LUPDATE) $(lmms_SOURCES) -ts locale/$@
|
||||
|
||||
$(LUPDATE) $(lmms_SOURCES) `find plugins/ -type f -name *.cpp` -ts locale/$@
|
||||
|
||||
%.qm: %.ts
|
||||
$(LRELEASE) $<
|
||||
|
||||
@@ -45,20 +44,18 @@ AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS)
|
||||
lmms_MOC = \
|
||||
./about_dialog.moc \
|
||||
./arp_and_chords_tab_widget.moc \
|
||||
./audio_file_processor.moc \
|
||||
./bb_editor.moc \
|
||||
./bb_track.moc \
|
||||
./browser.moc \
|
||||
./channel_track.moc \
|
||||
./config_mgr.moc \
|
||||
./crystal_button.moc \
|
||||
./envelope_and_lfo_widget.moc \
|
||||
./envelope_tab_widget.moc \
|
||||
./export_project_dialog.moc \
|
||||
./kmultitabbar.moc \
|
||||
./file_browser.moc \
|
||||
./group_box.moc \
|
||||
./kmultitabbar.moc \
|
||||
./knob.moc \
|
||||
./ladspa_sine_1063.moc \
|
||||
./lcd_spinbox.moc \
|
||||
./led_checkbox.moc \
|
||||
./lmms_main_win.moc \
|
||||
@@ -69,6 +66,7 @@ lmms_MOC = \
|
||||
./piano_roll.moc \
|
||||
./piano_widget.moc \
|
||||
./pixmap_button.moc \
|
||||
./plugin_browser.moc \
|
||||
./project_notes.moc \
|
||||
./rename_dialog.moc \
|
||||
./sample_buffer.moc \
|
||||
@@ -77,7 +75,6 @@ lmms_MOC = \
|
||||
./side_bar.moc \
|
||||
./side_bar_widget.moc \
|
||||
./song_editor.moc \
|
||||
./sound_generator.moc \
|
||||
./surround_area.moc \
|
||||
./tab_bar.moc \
|
||||
./tab_button.moc \
|
||||
@@ -86,7 +83,6 @@ lmms_MOC = \
|
||||
./timeline.moc \
|
||||
./track_container.moc \
|
||||
./track.moc \
|
||||
./triple_oscillator.moc \
|
||||
./visualization_widget.moc
|
||||
|
||||
|
||||
@@ -94,8 +90,8 @@ BUILT_SOURCES = $(lmms_MOC)
|
||||
|
||||
lmms_EMBEDDED_RESOURCES = $(wildcard $(srcdir)/resources/*png AUTHORS COPYING)
|
||||
|
||||
./embedded_resources.h: $(lmms_EMBEDDED_RESOURCES) bin2res
|
||||
$(top_builddir)/bin2res $(lmms_EMBEDDED_RESOURCES) > $@
|
||||
./embedded_resources.h: $(lmms_EMBEDDED_RESOURCES)
|
||||
$(top_builddir)/buildtools/bin2res $(lmms_EMBEDDED_RESOURCES) > $@
|
||||
|
||||
./embed.o: ./embedded_resources.h
|
||||
|
||||
@@ -113,11 +109,12 @@ lmms_SOURCES = \
|
||||
$(srcdir)/src/core/about_dialog.cpp \
|
||||
$(srcdir)/src/core/arp_and_chords_tab_widget.cpp \
|
||||
$(srcdir)/src/core/bb_editor.cpp \
|
||||
$(srcdir)/src/core/browser.cpp \
|
||||
$(srcdir)/src/core/config_mgr.cpp \
|
||||
$(srcdir)/src/core/envelope_and_lfo_widget.cpp \
|
||||
$(srcdir)/src/core/envelope_tab_widget.cpp \
|
||||
$(srcdir)/src/core/export_project_dialog.cpp \
|
||||
$(srcdir)/src/core/file_browser.cpp \
|
||||
$(srcdir)/src/core/instrument.cpp \
|
||||
$(srcdir)/src/core/lmms_main_win.cpp \
|
||||
$(srcdir)/src/core/main.cpp \
|
||||
$(srcdir)/src/core/mixer.cpp \
|
||||
@@ -126,11 +123,12 @@ lmms_SOURCES = \
|
||||
$(srcdir)/src/core/note_play_handle.cpp \
|
||||
$(srcdir)/src/core/piano_roll.cpp \
|
||||
$(srcdir)/src/core/piano_widget.cpp \
|
||||
$(srcdir)/src/core/plugin.cpp \
|
||||
$(srcdir)/src/core/plugin_browser.cpp \
|
||||
$(srcdir)/src/core/preset_preview_play_handle.cpp \
|
||||
$(srcdir)/src/core/sample_play_handle.cpp \
|
||||
$(srcdir)/src/core/setup_dialog.cpp \
|
||||
$(srcdir)/src/core/song_editor.cpp \
|
||||
$(srcdir)/src/core/sound_generator.cpp \
|
||||
$(srcdir)/src/core/track.cpp \
|
||||
$(srcdir)/src/core/track_container.cpp \
|
||||
$(srcdir)/src/core/surround_area.cpp \
|
||||
@@ -142,6 +140,7 @@ lmms_SOURCES = \
|
||||
$(srcdir)/src/lib/mmp.cpp \
|
||||
$(srcdir)/src/lib/oscillator.cpp \
|
||||
$(srcdir)/src/lib/sample_buffer.cpp \
|
||||
$(srcdir)/src/lib/string_pair_drag.cpp \
|
||||
$(srcdir)/src/midi/midi_alsa_raw.cpp \
|
||||
$(srcdir)/src/midi/midi_device.cpp \
|
||||
$(srcdir)/src/midi/midi_file.cpp \
|
||||
@@ -189,16 +188,14 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/volume.h \
|
||||
$(srcdir)/include/panning.h \
|
||||
$(srcdir)/include/song_editor.h \
|
||||
$(srcdir)/include/sound_generator.h \
|
||||
$(srcdir)/include/audio_file_processor.h \
|
||||
$(srcdir)/include/plugin.h \
|
||||
$(srcdir)/include/instrument.h \
|
||||
$(srcdir)/include/midi_time.h \
|
||||
$(srcdir)/include/bb_editor.h \
|
||||
$(srcdir)/include/piano_widget.h \
|
||||
$(srcdir)/include/effect_board.h \
|
||||
$(srcdir)/include/pixmap_button.h \
|
||||
$(srcdir)/include/triple_oscillator.h \
|
||||
$(srcdir)/include/settings.h \
|
||||
$(srcdir)/include/plucked_string_synth.h \
|
||||
$(srcdir)/include/rename_dialog.h \
|
||||
$(srcdir)/include/export_project_dialog.h \
|
||||
$(srcdir)/include/note_play_handle.h \
|
||||
@@ -214,7 +211,8 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/group_box.h \
|
||||
$(srcdir)/include/tab_widget.h \
|
||||
$(srcdir)/include/knob.h \
|
||||
$(srcdir)/include/browser.h \
|
||||
$(srcdir)/include/file_browser.h \
|
||||
$(srcdir)/include/plugin_browser.h \
|
||||
$(srcdir)/include/templates.h \
|
||||
$(srcdir)/include/gui_templates.h \
|
||||
$(srcdir)/include/surround_area.h \
|
||||
@@ -248,7 +246,6 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/preset_preview_play_handle.h \
|
||||
$(srcdir)/include/sample_play_handle.h \
|
||||
$(srcdir)/include/midi.h \
|
||||
$(srcdir)/include/midi_out.h \
|
||||
$(srcdir)/include/nstate_button.h \
|
||||
$(srcdir)/include/midi_dummy.h \
|
||||
$(srcdir)/include/midi_mapper.h \
|
||||
@@ -259,7 +256,10 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/text_float.h \
|
||||
$(srcdir)/include/tempo_sync_knob.h \
|
||||
$(srcdir)/include/setup_dialog.h \
|
||||
$(srcdir)/include/empty_sg_plugin.h \
|
||||
$(srcdir)/include/dummy_plugin.h \
|
||||
$(srcdir)/include/dummy_instrument.h \
|
||||
$(srcdir)/include/instrument_play_handle.h \
|
||||
$(srcdir)/include/string_pair_drag.h \
|
||||
$(srcdir)/include/ladspa_manager.h
|
||||
|
||||
|
||||
@@ -296,18 +296,6 @@ if HAVE_LIBSF
|
||||
LIB_SF_LDADD = -lsndfile
|
||||
endif
|
||||
|
||||
lmms_LDADD = $(QT_LDADD) $(LIB_SDL_LDADD) $(LIB_ASOUND_LDADD) $(LIB_JACK_LDADD) $(LIB_SDL_SOUND_LDADD) $(LIB_VORBIS_LDADD) $(LIB_SRC_LDADD) $(LIB_SF_LDADD) -laudiofileprocessor -ldl
|
||||
lmms_LDADD = $(QT_LDADD) $(LIB_SDL_LDADD) $(LIB_ASOUND_LDADD) $(LIB_JACK_LDADD) $(LIB_SDL_SOUND_LDADD) $(LIB_VORBIS_LDADD) $(LIB_SRC_LDADD) $(LIB_SF_LDADD) -lfst -ldl
|
||||
lmms_LDFLAGS = -rdynamic -rpath $(pkglibdir)
|
||||
|
||||
SUBDIRS = artwork locale midi-maps presets projects samples
|
||||
|
||||
|
||||
|
||||
pkglib_LTLIBRARIES= libaudiofileprocessor.la libsine1063oscillator.la libmidiout.la libpluckedstringsynth.la libtripleoscillator.la
|
||||
|
||||
|
||||
libaudiofileprocessor_la_SOURCES = src/soundgenerators/audio_file_processor.cpp
|
||||
libsine1063oscillator_la_SOURCES = src/soundgenerators/ladspa_sine_1063.cpp
|
||||
libmidiout_la_SOURCES = src/soundgenerators/midi_out.cpp
|
||||
libpluckedstringsynth_la_SOURCES = src/soundgenerators/plucked_string_synth.cpp
|
||||
libtripleoscillator_la_SOURCES = src/soundgenerators/triple_oscillator.cpp
|
||||
|
||||
29
README
29
README
@@ -1,4 +1,4 @@
|
||||
Linux MultiMedia Studio 0.1.2
|
||||
Linux MultiMedia Studio 0.1.1
|
||||
==============================
|
||||
|
||||
Copyright (c) 2004-2005 by Tobias Doerffel and others
|
||||
@@ -41,13 +41,13 @@ Requirements
|
||||
------------
|
||||
|
||||
The most important requirement is for sure a fast computer, so don't try to get
|
||||
LMMS working on a pentium I with 60 MHz... ;-) So you should have at least
|
||||
500 MHz, but for really enjoying LMMS less than 1 GHz makes no sense...
|
||||
(LMMS is currently developed on a PIII 450 MHz...!!)
|
||||
LMMS working on a pentium I with 60 MHz... ;-) Therefore you should have at
|
||||
least 500 MHz, but for really enjoying LMMS less than 1 GHz makes no sense...
|
||||
|
||||
|
||||
Required libraries are:
|
||||
|
||||
- Qt 3.2 or higher (tested up to 4.0.0) with devel-files
|
||||
- Qt 3.0 (3.2 recommended) or higher (tested up to 4.0.0) with devel-files
|
||||
|
||||
Optional, but strongly recommended:
|
||||
- libvorbis with devel-files
|
||||
@@ -57,6 +57,7 @@ Optional, but strongly recommended:
|
||||
- libsamplerate with devel-files
|
||||
- libsndfile with devel-files
|
||||
- JACK with devel-files
|
||||
- libfst + header-files from Steinberg SDK
|
||||
|
||||
For compiling you should have an up to date GCC with g++.
|
||||
LMMS has been (successfully) tested under Debian Sarge 3.1, Fedora Core 2-4,
|
||||
@@ -83,16 +84,16 @@ can be found at
|
||||
http://lmms.sourceforge.net
|
||||
|
||||
|
||||
Before coding a new big feature, please always post your idea and suggestions
|
||||
Details on development can be found at
|
||||
|
||||
http://lmms.sourceforge.net/development.php
|
||||
|
||||
or in the Wiki:
|
||||
|
||||
http://wiki.mindrules.net
|
||||
|
||||
Before coding a new big feature, please ALWAYS post your idea and suggestions
|
||||
about your feature and about the actual implementation to the
|
||||
LMMS-devel-mailinglist (lmms-devel@lists.sourceforge.net) and wait for replies!
|
||||
Maybe there're different ideas, improvements, hints or maybe your feature is
|
||||
not welcome/needed at the moment (but for sure this will be very seldom).
|
||||
|
||||
If you coded your feature, make sure, that it is running properly with the
|
||||
newest available version of LMMS and that it also runs with different
|
||||
configurations (e.g. disabled surround-support, missing package(s) etc.).
|
||||
Important is also, that you comment your source so that other people can fix
|
||||
bugs or improve your feature!
|
||||
|
||||
|
||||
|
||||
18
TODO
18
TODO
@@ -1,18 +1,20 @@
|
||||
- toolbar-redesign in song-editor, bb-editor and piano-roll!!!
|
||||
- addchannel-toolbutton -> popup-menu with available soundgenerator-plugins
|
||||
- complete toolbar-redesign in song-editor, bb-editor and piano-roll!!!
|
||||
- dnd everywhere: presets, samples (afp/sample-track), TCO's, knob-values
|
||||
- save/load parameters of VST-plugin
|
||||
- move VST-code into separate class which can use several backends (libfst, dssi-vst and vst-server) -> add libfst/dssi-vst/vstserver-check to configure.in
|
||||
- somehow avoid hidden plugin-descriptor-widgets if height of window is too small -> add scrollbar
|
||||
- use drawLineF() for drawing notes in pattern::paintEvent() in qt4-version
|
||||
- pattern freeze -> do not endless loop if looping-points are enabled
|
||||
- solve problem with knob-control-precision
|
||||
- built-in VST-support
|
||||
- proper dlclos()ing of sg-plugins
|
||||
- use own scrollview for capturing wheel-events
|
||||
- add note-len- and note-alignment-selectbox to piano-roll
|
||||
- only redraw region given by paint-event in pattern, bbTCO, sampleTCO etc.
|
||||
- make LMMS an ALSA-sequencer-client
|
||||
- use midi-maps
|
||||
- process program-/channel-change-events from MIDI-files
|
||||
- setup MIDI-channel and -program in MIDI-Out
|
||||
- pre-listen when opening sample with QFileDialog
|
||||
- level-meters in output-graph and channel-track
|
||||
- panning-editing in piano-roll
|
||||
- use midi-maps
|
||||
- process program-/channel-change-events from MIDI-files
|
||||
- setup MIDI-channel and -program in MIDI-Out
|
||||
- speed up painting of sampleTCO
|
||||
- save window-positions, -states and -sizes in files
|
||||
- solve problems with different keyboard-layouts when playing channel-track with pc-keyboard -> use tr()
|
||||
|
||||
5
buildtools/Makefile.am
Normal file
5
buildtools/Makefile.am
Normal file
@@ -0,0 +1,5 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
noinst_PROGRAMS= bin2res
|
||||
bin2res_SOURCES = bin2res.cpp
|
||||
|
||||
@@ -97,7 +97,7 @@ int main( int argc, char * * argv )
|
||||
e->cname = convertFileNameToCIdentifier( e->name );
|
||||
embedded_data.push_back( e );
|
||||
std::string s;
|
||||
std::cout << "static const unsigned char " << e->cname <<
|
||||
std::cout << "const unsigned char " << e->cname <<
|
||||
"_data[] = {";
|
||||
embedData( data, fsize, std::cout );
|
||||
std::cout << std::endl << "};" << std::endl << std::endl;
|
||||
@@ -106,7 +106,7 @@ int main( int argc, char * * argv )
|
||||
|
||||
if( embedded_data.size() > 0 )
|
||||
{
|
||||
std::cout << "static const unsigned char dummy_data[] ="
|
||||
std::cout << "const unsigned char dummy_data[] ="
|
||||
"{ 0x00 };" << std::endl << std::endl;
|
||||
embed * dummy = new embed;
|
||||
dummy->size = 1;
|
||||
@@ -114,14 +114,15 @@ int main( int argc, char * * argv )
|
||||
dummy->cname = convertFileNameToCIdentifier( "dummy" );
|
||||
embedded_data.push_back( dummy );
|
||||
|
||||
std::cout << "#include <string.h>" << std::endl;
|
||||
std::cout << "static struct embedDesc" << std::endl
|
||||
<< "{" << std::endl
|
||||
std::cout << "#include <string.h>" << std::endl << std::endl;
|
||||
std::cout << "#include \"embed.h\"" << std::endl << std::endl;
|
||||
std::cout << "embed::descriptor embed_vec[] = {" << std::endl;
|
||||
/* << "{" << std::endl
|
||||
<< " int size;" << std::endl
|
||||
<< " const unsigned char * data;" <<
|
||||
std::endl
|
||||
<< " const char * name;" << std::endl
|
||||
<< "} embed_vec[] = {" << std::endl;
|
||||
<< "} embed_vec[] = {" << std::endl;*/
|
||||
while( embedded_data.size() > 0 )
|
||||
{
|
||||
embed * e = embedded_data[0];
|
||||
@@ -133,9 +134,9 @@ int main( int argc, char * * argv )
|
||||
}
|
||||
std::cout << " { 0, 0, 0 }" << std::endl << "};" << std::endl
|
||||
<< std::endl
|
||||
<< "static const embedDesc & findEmbeddedData( "
|
||||
"const char * _name )" << std::endl
|
||||
<< "{" << std::endl
|
||||
<< "const embed::descriptor & "
|
||||
"findEmbeddedData( const char * _name )"
|
||||
<< std::endl << "{" << std::endl
|
||||
<< " for( int i = 0; embed_vec[i].data; "
|
||||
"i++ )" << std::endl
|
||||
<< " {" << std::endl
|
||||
|
||||
15
configure.in
15
configure.in
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.1.1-cvs20051013, tobydox@users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051013)
|
||||
AC_INIT(lmms, 0.1.1-cvs20051019, tobydox@users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051019)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
@@ -22,7 +22,7 @@ gw_CHECK_QT
|
||||
# checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS([fcntl.h memory.h string.h sys/ioctl.h unistd.h stdlib.h dlfcn.h])
|
||||
AC_CHECK_HEADERS([fcntl.h memory.h string.h sys/ioctl.h unistd.h stdlib.h dlfcn.h ladspa.h])
|
||||
|
||||
# checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
@@ -349,14 +349,23 @@ fi
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
artwork/Makefile
|
||||
buildtools/Makefile
|
||||
locale/Makefile
|
||||
midi-maps/Makefile
|
||||
plugins/Makefile
|
||||
plugins/audio_file_processor/Makefile
|
||||
plugins/ladspa_sine_1063/Makefile
|
||||
plugins/midi_out/Makefile
|
||||
plugins/plucked_string_synth/Makefile
|
||||
plugins/triple_oscillator/Makefile
|
||||
plugins/vestige/Makefile
|
||||
presets/Makefile
|
||||
presets/AudioFileProcessor/Makefile
|
||||
presets/MIDI-Out/Makefile
|
||||
presets/PluckedStringSynth/Makefile
|
||||
presets/Sine1063Oscillator/Makefile
|
||||
presets/TripleOscillator/Makefile
|
||||
presets/VeSTige/Makefile
|
||||
projects/Makefile
|
||||
projects/cool_songs/Makefile
|
||||
projects/covers/Makefile
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
private:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
int FASTCALL setHWParams( Uint32 _sample_rate, Uint32 _channels,
|
||||
snd_pcm_access_t _access );
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
void FASTCALL writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
Uint32 _src_sample_rate,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
inline Uint32 sampleRate( void ) const
|
||||
{
|
||||
@@ -104,12 +104,12 @@ public:
|
||||
protected:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output ) = 0;
|
||||
float _master_gain ) = 0;
|
||||
|
||||
// convert a given audio-buffer to a buffer in signed 16-bit samples
|
||||
// returns num of bytes in outbuf
|
||||
int FASTCALL convertToS16( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
float _master_output,
|
||||
float _master_gain,
|
||||
outputSampleType * _output_buffer,
|
||||
bool _convert_endian = FALSE );
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
private:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
bool startEncoding( void );
|
||||
void finishEncoding( void );
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
private:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
bool startEncoding( void );
|
||||
void finishEncoding( void );
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
private:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
void clearBuffer( void );
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
private:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
int m_audioFD;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
private:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
typedef vvector<QPair<sampleFrame *, Uint32> > bufferVector;
|
||||
bufferVector m_buffers;
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
private:
|
||||
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output );
|
||||
float _master_gain );
|
||||
|
||||
void clearBuffer( void );
|
||||
|
||||
|
||||
@@ -54,11 +54,9 @@ public:
|
||||
NOTCH,
|
||||
ALLPASS,
|
||||
MOOG,
|
||||
MOOG2,
|
||||
SIMPLE_FLT_CNT,
|
||||
DOUBLE_LOWPASS = 16+LOWPASS,
|
||||
DOUBLE_MOOG = 16+MOOG,
|
||||
DOUBLE_MOOG2 = 16+MOOG2
|
||||
DOUBLE_MOOG = 16+MOOG
|
||||
} ;
|
||||
|
||||
static inline filterTypes getFilterType( const int _idx )
|
||||
@@ -127,7 +125,7 @@ public:
|
||||
m_y4[_chnl] * ( 1.0f / 6.0f );
|
||||
break;
|
||||
}
|
||||
case MOOG2:
|
||||
/* case MOOG2:
|
||||
case DOUBLE_MOOG2:
|
||||
{
|
||||
const float x1 = ( _in0 - m_r *
|
||||
@@ -190,7 +188,7 @@ public:
|
||||
|
||||
out = m_oldx[_chnl];
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
default:
|
||||
// filter
|
||||
@@ -251,7 +249,7 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case DOUBLE_MOOG2:
|
||||
/* case DOUBLE_MOOG2:
|
||||
{
|
||||
if( m_subFilter == NULL )
|
||||
{
|
||||
@@ -276,7 +274,7 @@ public:
|
||||
kfcr * kf ) );
|
||||
m_r = 4 * _q * kacr;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
@@ -83,10 +83,10 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
void closeEvent( QCloseEvent * _ce );
|
||||
void keyPressEvent (QKeyEvent * _ke);
|
||||
void wheelEvent( QWheelEvent * _we );
|
||||
void resizeEvent( QResizeEvent * _re );
|
||||
virtual void closeEvent( QCloseEvent * _ce );
|
||||
virtual void keyPressEvent( QKeyEvent * _ke );
|
||||
virtual void resizeEvent( QResizeEvent * _re );
|
||||
|
||||
void updateBackground( void );
|
||||
|
||||
|
||||
|
||||
@@ -105,6 +105,11 @@ public:
|
||||
{
|
||||
return( m_lmmsDataDir + LOCALE_PATH );
|
||||
}
|
||||
const QString & pluginDir( void ) const
|
||||
{
|
||||
return( m_lmmsPluginDir );
|
||||
}
|
||||
|
||||
|
||||
const QString & value( const QString & _class,
|
||||
const QString & _attribute ) const;
|
||||
@@ -148,6 +153,7 @@ private:
|
||||
const QString m_lmmsRcFile;
|
||||
QString m_lmmsWorkingDir;
|
||||
QString m_lmmsDataDir;
|
||||
QString m_lmmsPluginDir;
|
||||
|
||||
typedef vvector<QPair<QString, QString> > stringPairVector;
|
||||
typedef QMap<QString, stringPairVector> settingsMap;
|
||||
|
||||
61
include/dummy_instrument.h
Normal file
61
include/dummy_instrument.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* dummy_instrument.h - instrument used as fallback if an instrument couldn't
|
||||
* be loaded
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _DUMMY_INSTRUMENT_H
|
||||
#define _DUMMY_INSTRUMENT_H
|
||||
|
||||
#include "instrument.h"
|
||||
|
||||
|
||||
class dummyInstrument : public instrument
|
||||
{
|
||||
public:
|
||||
inline dummyInstrument( channelTrack * _channel_track ) :
|
||||
instrument( _channel_track, "Dummy instrument" )
|
||||
{
|
||||
}
|
||||
|
||||
inline virtual ~dummyInstrument()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline virtual void saveSettings( QDomDocument &, QDomElement & )
|
||||
{
|
||||
}
|
||||
|
||||
inline virtual void loadSettings( const QDomElement & )
|
||||
{
|
||||
}
|
||||
|
||||
inline virtual QString nodeName( void ) const
|
||||
{
|
||||
return( "dummyinstrument" );
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
61
include/dummy_plugin.h
Normal file
61
include/dummy_plugin.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* dummy_plugin.h - empty plugin which is used as fallback if a plugin wasn't
|
||||
* found
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _DUMMY_PLUGIN_H
|
||||
#define _DUMMY_PLUGIN_H
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
|
||||
class dummyPlugin : public plugin
|
||||
{
|
||||
public:
|
||||
inline dummyPlugin( void ) :
|
||||
plugin( "Dummy plugin", plugin::UNDEFINED )
|
||||
{
|
||||
}
|
||||
|
||||
inline virtual ~dummyPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline virtual void saveSettings( QDomDocument &, QDomElement & )
|
||||
{
|
||||
}
|
||||
|
||||
inline virtual void loadSettings( const QDomElement & )
|
||||
{
|
||||
}
|
||||
|
||||
inline virtual QString nodeName( void ) const
|
||||
{
|
||||
return( "dummyplugin" );
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -42,10 +42,31 @@
|
||||
namespace embed
|
||||
{
|
||||
|
||||
struct descriptor
|
||||
{
|
||||
int size;
|
||||
const unsigned char * data;
|
||||
const char * name;
|
||||
} ;
|
||||
|
||||
|
||||
QPixmap getIconPixmap( const char * _name, int _w = -1, int _h = -1 );
|
||||
QString getText( const char * _name );
|
||||
void loadTranslation( const QString & _tname );
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef PLUGIN_NAME
|
||||
namespace PLUGIN_NAME
|
||||
{
|
||||
|
||||
QPixmap getIconPixmap( const char * _name, int _w = -1, int _h = -1 );
|
||||
QString getText( const char * _name );
|
||||
void loadTranslation( const QString & _tname );
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LADSPA_H
|
||||
|
||||
#define LADSPA_SUPPORT
|
||||
|
||||
#include <ladspa.h>
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
@@ -49,9 +55,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include <ladspa.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
||||
typedef QPair<QString, QString> ladspaKey;
|
||||
|
||||
/* ladspaManager provides a database of LADSPA plug-ins. Upon instantiation,
|
||||
@@ -188,7 +195,7 @@ public:
|
||||
|
||||
|
||||
/* The following methods are convenience functions for use during
|
||||
development. A real soundGenerator should use the getDescriptor()
|
||||
development. A real instrument should use the getDescriptor()
|
||||
method and implement the plug-in manipulations internally to avoid
|
||||
the overhead associated with QMap lookups. */
|
||||
|
||||
@@ -326,5 +333,7 @@ private:
|
||||
typedef QMap<ladspaKey, ladspaManagerDescription *> ladspaManagerMapType;
|
||||
ladspaManagerMapType m_ladspaManagerMap;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
class audioDevice;
|
||||
class midiDevice;
|
||||
class lmmsMainWin;
|
||||
class plugin;
|
||||
|
||||
|
||||
const int DEFAULT_BUFFER_SIZE = 512;
|
||||
@@ -174,7 +175,8 @@ public:
|
||||
m_playHandlesToRemove.push_back( _ph );
|
||||
}
|
||||
|
||||
void FASTCALL checkValidityOfPlayHandles( void );
|
||||
void checkValidityOfPlayHandles( void );
|
||||
|
||||
|
||||
|
||||
inline int sampleRate( void )
|
||||
@@ -319,7 +321,6 @@ private:
|
||||
volatile bool m_quit;
|
||||
|
||||
|
||||
|
||||
audioDevice * m_audioDev;
|
||||
audioDevice * m_oldAudioDev;
|
||||
QString m_audioDevName;
|
||||
|
||||
133
include/plugin.h
Normal file
133
include/plugin.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* plugin.h - class plugin, the base-class and generic interface for all plugins
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _PLUGIN_H
|
||||
#define _PLUGIN_H
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#else
|
||||
|
||||
#include <qstring.h>
|
||||
#include <qvaluevector.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "settings.h"
|
||||
#include "embed.h"
|
||||
|
||||
|
||||
#define STRINGIFY_PLUGIN_NAME(s) STR(s)
|
||||
#define STR(PN) #PN
|
||||
|
||||
|
||||
class QPixmap;
|
||||
|
||||
|
||||
class plugin : public settings
|
||||
{
|
||||
public:
|
||||
enum pluginTypes
|
||||
{
|
||||
INSTRUMENT, // instrument being used in channel-track
|
||||
EFFECT, // effect-plugin for effect-board
|
||||
IMPORT_FILTER, // filter for importing a file
|
||||
EXPORT_FILTER, // filter for exporting a file
|
||||
UNDEFINED = 255
|
||||
} ;
|
||||
|
||||
// descriptor holds information about a plugin - every external plugin
|
||||
// has to instantiate such a descriptor in an extern "C"-section so that
|
||||
// the plugin-loader is able to access information about the plugin
|
||||
struct descriptor
|
||||
{
|
||||
const char * name;
|
||||
const char * public_name;
|
||||
const char * description;
|
||||
const char * author;
|
||||
int version;
|
||||
pluginTypes type;
|
||||
embed::descriptor logo;
|
||||
} ;
|
||||
|
||||
// contructor of a plugin
|
||||
// _name: public name of plugin
|
||||
// _type: one of the plugin-types defined above
|
||||
plugin( const QString & _public_name, pluginTypes _type );
|
||||
virtual ~plugin();
|
||||
|
||||
// returns the name, the plugin passed to plugin-constructor
|
||||
inline const QString & publicName( void ) const
|
||||
{
|
||||
return( m_publicName );
|
||||
}
|
||||
|
||||
// return type
|
||||
inline pluginTypes type( void ) const
|
||||
{
|
||||
return( m_type );
|
||||
}
|
||||
|
||||
// plugins can overload this for making other classes able to change
|
||||
// settings of the plugin without knowing the actual class
|
||||
virtual void FASTCALL setParameter( const QString & _param,
|
||||
const QString & _value );
|
||||
|
||||
// plugins can overload this for making other classes able to query
|
||||
// settings of the plugin without knowing the actual class
|
||||
virtual QString FASTCALL getParameter( const QString & _param );
|
||||
|
||||
|
||||
// returns an instance of a plugin whose name matches to given one
|
||||
// if specified plugin couldn't be loaded, it creates a dummy-plugin
|
||||
static plugin * FASTCALL instantiate( const QString & _plugin_name,
|
||||
void * _data );
|
||||
|
||||
// fills given vector with descriptors for all available plugins
|
||||
static void FASTCALL getDescriptorsOfAvailPlugins(
|
||||
vvector<descriptor> & _plugin_descs );
|
||||
|
||||
private:
|
||||
const QString m_publicName;
|
||||
const pluginTypes m_type;
|
||||
|
||||
// pointer to instantiation-function in plugin
|
||||
typedef plugin * ( * instantiationHook )( void * );
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
96
include/plugin_browser.h
Normal file
96
include/plugin_browser.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* plugin_browser.h - include file for pluginBrowser
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _PLUGIN_BROWSER_H
|
||||
#define _PLUGIN_BROWSER_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QVector>
|
||||
#include <QPixmap>
|
||||
|
||||
#else
|
||||
|
||||
#include <qvaluevector.h>
|
||||
#include <qpixmap.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "side_bar_widget.h"
|
||||
#include "plugin.h"
|
||||
|
||||
|
||||
class trackContainer;
|
||||
|
||||
|
||||
class pluginBrowser : public sideBarWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
pluginBrowser( QWidget * _parent );
|
||||
virtual ~pluginBrowser();
|
||||
|
||||
|
||||
private:
|
||||
vvector<plugin::descriptor> m_pluginDescriptors;
|
||||
|
||||
QWidget * m_view;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
class pluginDescWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
pluginDescWidget( const plugin::descriptor & _pd, QWidget * _parent );
|
||||
virtual ~pluginDescWidget();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
virtual void mousePressEvent( QMouseEvent * _me );
|
||||
virtual void mouseMoveEvent( QMouseEvent * _me );
|
||||
virtual void mouseReleaseEvent( QMouseEvent * _me );
|
||||
|
||||
|
||||
private:
|
||||
const plugin::descriptor & m_pluginDescriptor;
|
||||
QPixmap m_logo;
|
||||
|
||||
bool m_mouseOver;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -48,7 +48,7 @@ class sideBarWidget : public QWidget
|
||||
public:
|
||||
sideBarWidget( const QString & _title, const QPixmap & _icon,
|
||||
QWidget * _parent );
|
||||
~sideBarWidget();
|
||||
virtual ~sideBarWidget();
|
||||
inline const QPixmap & icon( void ) const
|
||||
{
|
||||
return( m_icon );
|
||||
@@ -60,9 +60,9 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent * _pe );
|
||||
void resizeEvent( QResizeEvent * _re );
|
||||
inline void contextMenuEvent( QContextMenuEvent * )
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
virtual void resizeEvent( QResizeEvent * _re );
|
||||
inline virtual void contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,6 @@ protected:
|
||||
protected slots:
|
||||
void insertTact( void );
|
||||
void removeTact( void );
|
||||
void addChannelTrack( void );
|
||||
void addBBTrack( void );
|
||||
void addSampleTrack( void );
|
||||
void scrolled( int _new_pos );
|
||||
|
||||
64
include/string_pair_drag.h
Normal file
64
include/string_pair_drag.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* string_pair_drag.h - class stringPairDrag which provides general support
|
||||
* for drag'n'drop of string-pairs
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _STRING_PAIR_DRAG_H
|
||||
#define _STRING_PAIR_DRAG_H
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QDrag>
|
||||
|
||||
#else
|
||||
|
||||
#include <qdragobject.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class QPixmap;
|
||||
|
||||
|
||||
class stringPairDrag : public
|
||||
#ifdef QT4
|
||||
QDrag
|
||||
#else
|
||||
QStoredDrag
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
stringPairDrag( const QString & _key, const QString & _value,
|
||||
const QPixmap & _icon, QWidget * _w );
|
||||
~stringPairDrag();
|
||||
|
||||
static void processDragEnterEvent( QDragEnterEvent * _dee,
|
||||
const QString & _allowed_keys );
|
||||
static QString decodeKey( QDropEvent * _de );
|
||||
static QString decodeValue( QDropEvent * _de );
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -227,7 +227,7 @@ public:
|
||||
public slots:
|
||||
void changePosition( const midiTime & _new_pos = -1 );
|
||||
void cloneTrack( void );
|
||||
void deleteTrack( void );
|
||||
void removeTrack( void );
|
||||
void moveTrackUp( void );
|
||||
void moveTrackDown( void );
|
||||
void setMuted( bool _muted );
|
||||
@@ -271,11 +271,10 @@ public:
|
||||
|
||||
track( trackContainer * _tc );
|
||||
virtual ~track();
|
||||
static track * FASTCALL createTrack( trackTypes _tt,
|
||||
static track * FASTCALL create( trackTypes _tt, trackContainer * _tc );
|
||||
static track * FASTCALL create( const QDomElement & _this,
|
||||
trackContainer * _tc );
|
||||
static track * FASTCALL createTrack( const QDomElement & _this,
|
||||
trackContainer * _tc );
|
||||
static track * FASTCALL cloneTrack( track * _track );
|
||||
static track * FASTCALL clone( track * _track );
|
||||
|
||||
tact length( void ) const;
|
||||
|
||||
|
||||
@@ -93,10 +93,13 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent( QResizeEvent * );
|
||||
virtual void dragEnterEvent( QDragEnterEvent * _dee );
|
||||
virtual void dropEvent( QDropEvent * _de );
|
||||
|
||||
constTrackVector tracks( void ) const;
|
||||
trackVector tracks( void );
|
||||
|
||||
virtual void resizeEvent( QResizeEvent * );
|
||||
|
||||
midiTime m_currentPosition;
|
||||
|
||||
@@ -106,16 +109,33 @@ protected slots:
|
||||
|
||||
|
||||
private:
|
||||
QScrollArea * m_scrollArea;
|
||||
|
||||
class scrollArea : public QScrollArea
|
||||
{
|
||||
public:
|
||||
scrollArea( trackContainer * _parent );
|
||||
virtual ~scrollArea();
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent( QWheelEvent * _we );
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
scrollArea * m_scrollArea;
|
||||
typedef vvector<trackWidget *> trackWidgetVector;
|
||||
|
||||
trackWidgetVector m_trackWidgets;
|
||||
float m_ppt;
|
||||
|
||||
|
||||
friend class scrollArea;
|
||||
|
||||
|
||||
signals:
|
||||
void positionChanged( const midiTime & _pos );
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* volume.h - declaration of some constants and types, concerning the volume of a note
|
||||
* volume.h - declaration of some constants and types, concerning the volume
|
||||
* of a note
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
2
plugins/Makefile.am
Normal file
2
plugins/Makefile.am
Normal file
@@ -0,0 +1,2 @@
|
||||
SUBDIRS = audio_file_processor ladspa_sine_1063 midi_out plucked_string_synth triple_oscillator vestige
|
||||
|
||||
34
plugins/audio_file_processor/Makefile.am
Normal file
34
plugins/audio_file_processor/Makefile.am
Normal file
@@ -0,0 +1,34 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I.
|
||||
|
||||
|
||||
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="audiofileprocessor"
|
||||
|
||||
|
||||
%.moc: ./%.h
|
||||
$(MOC) -o $@ $<
|
||||
|
||||
|
||||
MOC_FILES = ./audio_file_processor.moc
|
||||
|
||||
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
|
||||
|
||||
EMBEDDED_RESOURCES = $(wildcard *png)
|
||||
|
||||
./embedded_resources.h: $(EMBEDDED_RESOURCES)
|
||||
$(top_builddir)/buildtools/bin2res $(EMBEDDED_RESOURCES) > $@
|
||||
|
||||
EXTRA_DIST = $(EMBEDDED_RESOURCES)
|
||||
|
||||
|
||||
CLEANFILES = $(MOC_FILES) ./embedded_resources.h
|
||||
|
||||
|
||||
|
||||
pkglib_LTLIBRARIES= libaudiofileprocessor.la
|
||||
|
||||
libaudiofileprocessor_la_SOURCES = audio_file_processor.cpp audio_file_processor.h
|
||||
|
||||
$(libaudiofileprocessor_la_SOURCES): ./embedded_resources.h
|
||||
BIN
plugins/audio_file_processor/artwork.png
Normal file
BIN
plugins/audio_file_processor/artwork.png
Normal file
Binary file not shown.
628
plugins/audio_file_processor/audio_file_processor.cpp
Normal file
628
plugins/audio_file_processor/audio_file_processor.cpp
Normal file
@@ -0,0 +1,628 @@
|
||||
/*
|
||||
* audio_file_processor.cpp - instrument for using audio-files
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QPainter>
|
||||
#include <QButtonGroup>
|
||||
#include <QBitmap>
|
||||
#include <Qt/QtXml>
|
||||
#include <QFileInfo>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpainter.h>
|
||||
#include <qbuttongroup.h>
|
||||
#include <qbitmap.h>
|
||||
#include <qdom.h>
|
||||
#include <qfileinfo.h>
|
||||
|
||||
#define isChecked isOn
|
||||
#define setChecked setOn
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "audio_file_processor.h"
|
||||
#include "song_editor.h"
|
||||
#include "channel_track.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "paths.h"
|
||||
#include "interpolation.h"
|
||||
#include "buffer_allocator.h"
|
||||
#include "pixmap_button.h"
|
||||
#include "knob.h"
|
||||
#include "tooltip.h"
|
||||
|
||||
#include "embed.cpp"
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
plugin::descriptor audiofileprocessor_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"AudioFileProcessor",
|
||||
QT_TRANSLATE_NOOP( "plugin",
|
||||
"simple sampler with various settings for "
|
||||
"using samples (e.g. drums) in a channel" ),
|
||||
"Tobias Doerffel <tobydox@users.sf.net>",
|
||||
0x0100,
|
||||
plugin::INSTRUMENT,
|
||||
PLUGIN_NAME::findEmbeddedData( "logo.png" )
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
QPixmap * audioFileProcessor::s_artwork = NULL;
|
||||
|
||||
|
||||
|
||||
audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) :
|
||||
instrument( _channel_track,
|
||||
audiofileprocessor_plugin_descriptor.public_name ),
|
||||
specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) ),
|
||||
m_sampleBuffer( "" ),
|
||||
m_drawMethod( sampleBuffer::LINE_CONNECT )
|
||||
{
|
||||
connect( &m_sampleBuffer, SIGNAL( sampleUpdated() ), this,
|
||||
SLOT( sampleUpdated() ) );
|
||||
|
||||
if( s_artwork == NULL )
|
||||
{
|
||||
s_artwork = new QPixmap( PLUGIN_NAME::getIconPixmap(
|
||||
"artwork" ) );
|
||||
}
|
||||
|
||||
|
||||
m_openAudioFileButton = new pixmapButton( this );
|
||||
m_openAudioFileButton->setCheckable( FALSE );
|
||||
m_openAudioFileButton->setCursor( QCursor( Qt::PointingHandCursor ) );
|
||||
m_openAudioFileButton->move( 200, 90 );
|
||||
m_openAudioFileButton->setActiveGraphic( embed::getIconPixmap(
|
||||
"project_open_down" ) );
|
||||
m_openAudioFileButton->setInactiveGraphic( embed::getIconPixmap(
|
||||
"project_open" ) );
|
||||
m_openAudioFileButton->setBgGraphic( getBackground(
|
||||
m_openAudioFileButton ) );
|
||||
connect( m_openAudioFileButton, SIGNAL( clicked() ), this,
|
||||
SLOT( openAudioFile() ) );
|
||||
toolTip::add( m_openAudioFileButton, tr( "Open other sample" ) );
|
||||
|
||||
#ifdef QT4
|
||||
m_openAudioFileButton->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_openAudioFileButton,
|
||||
#endif
|
||||
tr( "Click here, if you want to open another audio-file. After "
|
||||
"clicking on this button, a file-open-dialog appears "
|
||||
"and you can select your file. Settings like Looping-"
|
||||
"Mode, start- and end-point, amplify-value and so on "
|
||||
"are not reset, so please don't wonder if your sample "
|
||||
"doesn't sound like the original one..." ) );
|
||||
|
||||
m_reverseButton = new pixmapButton( this );
|
||||
m_reverseButton->move( 160, 124 );
|
||||
m_reverseButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"reverse_on" ) );
|
||||
m_reverseButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"reverse_off" ) );
|
||||
m_reverseButton->setBgGraphic( getBackground( m_reverseButton ) );
|
||||
connect( m_reverseButton, SIGNAL( toggled( bool ) ), this,
|
||||
SLOT( reverseBtnToggled( bool ) ) );
|
||||
toolTip::add( m_reverseButton, tr( "Reverse sample" ) );
|
||||
#ifdef QT4
|
||||
m_reverseButton->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_reverseButton,
|
||||
#endif
|
||||
tr( "If you enable this button, the whole sample is reversed. "
|
||||
"This is useful for cool effects, e.g. a reversed "
|
||||
"crash." ) );
|
||||
|
||||
m_loopButton = new pixmapButton( this );
|
||||
m_loopButton->move( 180, 124 );
|
||||
m_loopButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"loop_on" ) );
|
||||
m_loopButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"loop_off" ) );
|
||||
m_loopButton->setBgGraphic( getBackground( m_loopButton ) );
|
||||
toolTip::add( m_loopButton,
|
||||
tr( "Loop sample at start- and end-point" ) );
|
||||
#ifdef QT4
|
||||
m_loopButton->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_loopButton,
|
||||
#endif
|
||||
tr( "Here you can set, whether Looping-Mode is enabled. If "
|
||||
"enabled, AudioFileProcessor loops between start- and "
|
||||
"end-point of a sample until the whole note is played. "
|
||||
"This is useful for things like string- and choir-"
|
||||
"samples." ) );
|
||||
|
||||
m_ampKnob = new knob( knobDark_28, this, tr( "Amplify" ) );
|
||||
m_ampKnob->setRange( 0, 500, 1.0f );
|
||||
m_ampKnob->move( 6, 114 );
|
||||
m_ampKnob->setValue( 100.0f, TRUE );
|
||||
m_ampKnob->setHintText( tr( "Amplify:" )+" ", "%" );
|
||||
m_ampKnob->setLabel( tr( "AMP" ) );
|
||||
connect( m_ampKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
SLOT( ampKnobChanged( float ) ) );
|
||||
#ifdef QT4
|
||||
m_ampKnob->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_ampKnob,
|
||||
#endif
|
||||
tr( "With this knob you can set the amplify-ratio. When you "
|
||||
"set a value of 100% your sample isn't changed. "
|
||||
"Otherwise it will be amplified up or down (your "
|
||||
"actual sample-file isn't touched!)" ) );
|
||||
|
||||
m_startKnob = new knob( knobDark_28, this, tr( "Start of sample" ) );
|
||||
m_startKnob->setRange( 0, 1.0, 0.00001 );
|
||||
m_startKnob->move( 46, 114 );
|
||||
m_startKnob->setValue( 0.0, TRUE );
|
||||
m_startKnob->setHintText( tr( "Startpoint:" )+" ", "" );
|
||||
m_startKnob->setLabel( tr( "START" ) );
|
||||
connect( m_startKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
SLOT( startKnobChanged( float ) ) );
|
||||
#ifdef QT4
|
||||
m_startKnob->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_startKnob,
|
||||
#endif
|
||||
tr( "With this knob you can set the point where "
|
||||
"AudioFileProcessor should begin playing your sample. "
|
||||
"If you enable Looping-Mode, this is the point to "
|
||||
"which AudioFileProcessor returns if a note is longer "
|
||||
"than the sample between start- and end-point." ) );
|
||||
|
||||
m_endKnob = new knob( knobDark_28, this, tr( "End of sample" ) );
|
||||
m_endKnob->setRange( 0, 1.0, 0.00001 );
|
||||
m_endKnob->move( 84, 114 );
|
||||
m_endKnob->setValue( 1.0, TRUE );
|
||||
m_endKnob->setHintText( tr( "Endpoint:" )+" ", "" );
|
||||
m_endKnob->setLabel( tr( "END" ) );
|
||||
connect( m_endKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
SLOT( endKnobChanged( float ) ) );
|
||||
#ifdef QT4
|
||||
m_endKnob->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_endKnob,
|
||||
#endif
|
||||
tr( "With this knob you can set the point where "
|
||||
"AudioFileProcessor should stop playing your sample. "
|
||||
"If you enable Looping-Mode, this is the point where "
|
||||
"AudioFileProcessor returns if a note is longer than "
|
||||
"the sample between start- and end-point." ) );
|
||||
|
||||
m_viewLinesPB = new pixmapButton( this );
|
||||
m_viewLinesPB->move( 154, 158 );
|
||||
m_viewLinesPB->setBgGraphic( getBackground( m_viewLinesPB ) );
|
||||
if( m_drawMethod == sampleBuffer::LINE_CONNECT )
|
||||
{
|
||||
#ifdef QT4
|
||||
m_viewLinesPB->setChecked( TRUE );
|
||||
#else
|
||||
m_viewLinesPB->setOn( TRUE );
|
||||
#endif
|
||||
}
|
||||
connect( m_viewLinesPB, SIGNAL( toggled( bool ) ), this,
|
||||
SLOT( lineDrawBtnToggled( bool ) ) );
|
||||
#ifdef QT4
|
||||
m_viewLinesPB->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_viewLinesPB,
|
||||
#endif
|
||||
tr( "Activate this button, if your sample should be drawn "
|
||||
"with connected lines. This doesn't change the "
|
||||
"sound itself. It just gives you another view to your "
|
||||
"sample." ) );
|
||||
|
||||
m_viewDotsPB = new pixmapButton( this );
|
||||
m_viewDotsPB->move( 204, 158 );
|
||||
m_viewDotsPB->setBgGraphic( getBackground( m_viewDotsPB ) );
|
||||
if( m_drawMethod == sampleBuffer::DOTS )
|
||||
{
|
||||
#ifdef QT4
|
||||
m_viewDotsPB->setChecked( TRUE );
|
||||
#else
|
||||
m_viewDotsPB->setOn( TRUE );
|
||||
#endif
|
||||
}
|
||||
connect( m_viewDotsPB, SIGNAL( toggled( bool ) ), this,
|
||||
SLOT( dotDrawBtnToggled( bool ) ) );
|
||||
#ifdef QT4
|
||||
m_viewDotsPB->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_viewDotsPB,
|
||||
#endif
|
||||
tr( "Activate this button, if your sample should be drawn "
|
||||
"with dots. This doesn't change the sound itself. "
|
||||
"It just gives you another view to your sample." ) );
|
||||
|
||||
QButtonGroup * view_group = new QButtonGroup( this );
|
||||
view_group->addButton( m_viewLinesPB );
|
||||
view_group->addButton( m_viewDotsPB );
|
||||
view_group->setExclusive( TRUE );
|
||||
#ifndef QT4
|
||||
view_group->hide();
|
||||
|
||||
setBackgroundMode( Qt::NoBackground );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
audioFileProcessor::~audioFileProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent )
|
||||
{
|
||||
QDomElement afp_de = _doc.createElement( nodeName() );
|
||||
afp_de.setAttribute( "src", m_sampleBuffer.audioFile() );
|
||||
afp_de.setAttribute( "sframe", QString::number(
|
||||
m_sampleBuffer.startFrame() /
|
||||
(float)m_sampleBuffer.frames() ) );
|
||||
afp_de.setAttribute( "eframe", QString::number(
|
||||
m_sampleBuffer.endFrame() /
|
||||
(float)m_sampleBuffer.frames() ) );
|
||||
afp_de.setAttribute( "reversed", QString::number(
|
||||
m_reverseButton->isChecked() ) );
|
||||
afp_de.setAttribute( "looped", QString::number(
|
||||
m_loopButton->isChecked() ) );
|
||||
afp_de.setAttribute( "amp", QString::number( m_ampKnob->value() ) );
|
||||
_parent.appendChild( afp_de );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
setAudioFile( _this.attribute( "src" ) );
|
||||
setStartAndEndKnob( _this.attribute( "sframe" ).toFloat(),
|
||||
_this.attribute( "eframe" ).toFloat() );
|
||||
m_reverseButton->setChecked( _this.attribute( "reversed" ).toInt() );
|
||||
m_loopButton->setChecked( _this.attribute( "looped" ).toInt() );
|
||||
m_ampKnob->setValue( _this.attribute( "amp" ).toFloat() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString audioFileProcessor::nodeName( void ) const
|
||||
{
|
||||
return( audiofileprocessor_plugin_descriptor.name );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::setParameter( const QString & _param,
|
||||
const QString & _value )
|
||||
{
|
||||
if( _param == "audiofile" )
|
||||
{
|
||||
setAudioFile( _value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Uint32 audioFileProcessor::getBeatLen( notePlayHandle * _n ) const
|
||||
{
|
||||
const float freq_factor = BASE_FREQ /
|
||||
( getChannelTrack()->frequency( _n ) *
|
||||
DEFAULT_SAMPLE_RATE /
|
||||
mixer::inst()->sampleRate() );
|
||||
|
||||
return( static_cast<Uint32>( floorf( ( m_sampleBuffer.endFrame() -
|
||||
m_sampleBuffer.startFrame() ) *
|
||||
freq_factor ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::setAudioFile( const QString & _audio_file )
|
||||
{
|
||||
// is current channel-name equal to previous-filename??
|
||||
if( getChannelTrack()->name() ==
|
||||
QFileInfo( m_sampleBuffer.audioFile() ).fileName() ||
|
||||
m_sampleBuffer.audioFile() == "" )
|
||||
{
|
||||
// then set it to new one
|
||||
getChannelTrack()->setName( QFileInfo( _audio_file
|
||||
).fileName() );
|
||||
}
|
||||
// else we don't touch the channel-name, because the user named it self
|
||||
|
||||
m_sampleBuffer.setAudioFile( _audio_file );
|
||||
setStartAndEndKnob( 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::playNote( notePlayHandle * _n )
|
||||
{
|
||||
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
|
||||
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
|
||||
|
||||
// calculate frequency of note
|
||||
const float note_freq = getChannelTrack()->frequency( _n ) /
|
||||
( mixer::inst()->sampleRate() /
|
||||
DEFAULT_SAMPLE_RATE );
|
||||
|
||||
if( m_sampleBuffer.play( buf, _n->totalFramesPlayed(),
|
||||
frames, note_freq,
|
||||
m_loopButton->isChecked(),
|
||||
&_n->m_pluginData ) == TRUE )
|
||||
{
|
||||
getChannelTrack()->processAudioBuffer( buf, frames, _n );
|
||||
}
|
||||
bufferAllocator::free( buf );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::deleteNotePluginData( notePlayHandle * _n )
|
||||
{
|
||||
if( _n->m_pluginData != NULL )
|
||||
{
|
||||
m_sampleBuffer.deleteResamplingData( &_n->m_pluginData );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::paintEvent( QPaintEvent * )
|
||||
{
|
||||
#ifdef QT4
|
||||
QPainter p( this );
|
||||
#else
|
||||
QPixmap pm( rect().size() );
|
||||
pm.fill( this, rect().topLeft() );
|
||||
|
||||
QPainter p( &pm, this );
|
||||
#endif
|
||||
|
||||
p.drawPixmap( 0, 0, *s_artwork );
|
||||
|
||||
|
||||
QString file_name = "";
|
||||
Uint16 idx = m_sampleBuffer.audioFile().length();
|
||||
|
||||
p.setFont( pointSize<8>( p.font() ) );
|
||||
|
||||
QFontMetrics fm( font() );
|
||||
|
||||
// simple algorithm for creating a text from the filename that
|
||||
// matches in the white rectangle
|
||||
#ifdef QT4
|
||||
while( idx > 0 &&
|
||||
fm.size( Qt::TextSingleLine, file_name + "..." ).width() < 225 )
|
||||
#else
|
||||
while( idx > 0 &&
|
||||
fm.size( Qt::SingleLine, file_name + "..." ).width() < 225 )
|
||||
#endif
|
||||
{
|
||||
file_name = m_sampleBuffer.audioFile()[--idx] + file_name;
|
||||
}
|
||||
|
||||
if( idx > 0 )
|
||||
{
|
||||
file_name = "..." + file_name;
|
||||
}
|
||||
|
||||
p.setPen( QColor( 255, 255, 255 ) );
|
||||
p.drawText( 8, 84, file_name );
|
||||
|
||||
p.drawPixmap( 2, 172, m_graph );
|
||||
|
||||
|
||||
p.setPen( QColor( 0xFF, 0xAA, 0x00 ) );
|
||||
const QRect graph_rect( 4, 174, 241, 70 );
|
||||
const Uint32 frames = tMax( m_sampleBuffer.frames(),
|
||||
static_cast<Uint32>( 1 ) );
|
||||
const Uint16 start_frame_x = m_sampleBuffer.startFrame() *
|
||||
graph_rect.width() / frames;
|
||||
const Uint16 end_frame_x = m_sampleBuffer.endFrame() *
|
||||
( graph_rect.width() - 1 ) / frames;
|
||||
|
||||
p.drawLine( start_frame_x + graph_rect.x(), graph_rect.y(),
|
||||
start_frame_x + graph_rect.x(),
|
||||
graph_rect.height() + graph_rect.y() );
|
||||
p.drawLine( end_frame_x + graph_rect.x(), graph_rect.y(),
|
||||
end_frame_x + graph_rect.x(),
|
||||
graph_rect.height() + graph_rect.y() );
|
||||
|
||||
#ifndef QT4
|
||||
bitBlt( this, rect().topLeft(), &pm );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::sampleUpdated( void )
|
||||
{
|
||||
m_graph = QPixmap( 245, 75 );
|
||||
copyBlt( &m_graph, 0, 0, s_artwork, 2, 172, m_graph.width(),
|
||||
m_graph.height() );
|
||||
QPainter p( &m_graph );
|
||||
m_sampleBuffer.drawWaves( p, QRect( 2, 2, m_graph.width() - 4,
|
||||
m_graph.height() - 4 ),
|
||||
m_drawMethod );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::reverseBtnToggled( bool _on )
|
||||
{
|
||||
m_sampleBuffer.setReversed( _on );
|
||||
songEditor::inst()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::lineDrawBtnToggled( bool _on )
|
||||
{
|
||||
if( _on )
|
||||
{
|
||||
m_drawMethod = sampleBuffer::LINE_CONNECT;
|
||||
sampleUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::dotDrawBtnToggled( bool _on )
|
||||
{
|
||||
if( _on )
|
||||
{
|
||||
m_drawMethod = sampleBuffer::DOTS;
|
||||
sampleUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::ampKnobChanged( float _val )
|
||||
{
|
||||
m_sampleBuffer.setAmplification( _val/100.0f );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::setStartAndEndKnob( float _s, float _e )
|
||||
{
|
||||
// because the signal-handlers of valuechanges of start- and end-knob
|
||||
// do range checking, depending on value of the other knob, we have to
|
||||
// disconnect the signal-handlers, set then the values, connect again
|
||||
// and then let the changes take effect...
|
||||
m_startKnob->disconnect();
|
||||
m_endKnob->disconnect();
|
||||
m_startKnob->setValue( _s );
|
||||
m_endKnob->setValue( _e );
|
||||
connect( m_startKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
SLOT( startKnobChanged( float ) ) );
|
||||
connect( m_endKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
SLOT( endKnobChanged( float ) ) );
|
||||
m_startKnob->setValue( _s );
|
||||
m_endKnob->setValue( _e );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::startKnobChanged( float _new_value )
|
||||
{
|
||||
if( _new_value < m_endKnob->value() )
|
||||
{
|
||||
m_sampleBuffer.setStartFrame( static_cast<Uint32>( _new_value *
|
||||
m_sampleBuffer.frames() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_startKnob->setValue( m_endKnob->value() - 0.01 );
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::endKnobChanged( float _new_value )
|
||||
{
|
||||
if( _new_value > m_startKnob->value() )
|
||||
{
|
||||
m_sampleBuffer.setEndFrame( static_cast<Uint32>( _new_value *
|
||||
m_sampleBuffer.frames() ) - 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_endKnob->setValue( m_startKnob->value() + 0.01 );
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::openAudioFile( void )
|
||||
{
|
||||
QString af = m_sampleBuffer.openAudioFile();
|
||||
if( af != "" )
|
||||
{
|
||||
setAudioFile( af );
|
||||
songEditor::inst()->setModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// neccessary for getting instance out of shared lib
|
||||
plugin * lmms_plugin_main( void * _data )
|
||||
{
|
||||
return( new audioFileProcessor(
|
||||
static_cast<channelTrack *>( _data ) ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#undef isChecked
|
||||
#undef isOn
|
||||
|
||||
#include "audio_file_processor.moc"
|
||||
|
||||
116
plugins/audio_file_processor/audio_file_processor.h
Normal file
116
plugins/audio_file_processor/audio_file_processor.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* audio_file_processor.h - declaration of class audioFileProcessor
|
||||
* (instrument-plugin for using audio-files)
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _AUDIO_FILE_PROCESSOR_H
|
||||
#define _AUDIO_FILE_PROCESSOR_H
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpixmap.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "instrument.h"
|
||||
#include "sample_buffer.h"
|
||||
#include "spc_bg_hndl_widget.h"
|
||||
|
||||
|
||||
class knob;
|
||||
class pixmapButton;
|
||||
|
||||
|
||||
class audioFileProcessor : public instrument, public specialBgHandlingWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
audioFileProcessor( channelTrack * _channel_track );
|
||||
virtual ~audioFileProcessor();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
virtual void FASTCALL saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
virtual void FASTCALL loadSettings( const QDomElement & _this );
|
||||
|
||||
virtual void FASTCALL setParameter( const QString & _param,
|
||||
const QString & _value );
|
||||
|
||||
virtual QString nodeName( void ) const;
|
||||
|
||||
virtual Uint32 FASTCALL getBeatLen( notePlayHandle * _n ) const;
|
||||
|
||||
|
||||
public slots:
|
||||
void setAudioFile( const QString & _audio_file );
|
||||
|
||||
|
||||
protected slots:
|
||||
void openAudioFile( void );
|
||||
void reverseBtnToggled( bool _on );
|
||||
void ampKnobChanged( float _new_value );
|
||||
void startKnobChanged( float _new_value );
|
||||
void endKnobChanged( float _new_value );
|
||||
void lineDrawBtnToggled( bool _on );
|
||||
void dotDrawBtnToggled( bool _on );
|
||||
void sampleUpdated( void );
|
||||
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent * );
|
||||
|
||||
|
||||
private:
|
||||
static QPixmap * s_artwork;
|
||||
|
||||
|
||||
sampleBuffer m_sampleBuffer;
|
||||
|
||||
sampleBuffer::drawMethods m_drawMethod;
|
||||
|
||||
QPixmap m_graph;
|
||||
knob * m_ampKnob;
|
||||
knob * m_startKnob;
|
||||
knob * m_endKnob;
|
||||
pixmapButton * m_openAudioFileButton;
|
||||
pixmapButton * m_viewLinesPB;
|
||||
pixmapButton * m_viewDotsPB;
|
||||
pixmapButton * m_reverseButton;
|
||||
pixmapButton * m_loopButton;
|
||||
|
||||
|
||||
void updateSample( void );
|
||||
void FASTCALL setStartAndEndKnob( float _s, float _e );
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
BIN
plugins/audio_file_processor/logo.png
Normal file
BIN
plugins/audio_file_processor/logo.png
Normal file
Binary file not shown.
BIN
plugins/audio_file_processor/loop_off.png
Normal file
BIN
plugins/audio_file_processor/loop_off.png
Normal file
Binary file not shown.
BIN
plugins/audio_file_processor/loop_on.png
Normal file
BIN
plugins/audio_file_processor/loop_on.png
Normal file
Binary file not shown.
BIN
plugins/audio_file_processor/reverse_off.png
Normal file
BIN
plugins/audio_file_processor/reverse_off.png
Normal file
Binary file not shown.
BIN
plugins/audio_file_processor/reverse_on.png
Normal file
BIN
plugins/audio_file_processor/reverse_on.png
Normal file
Binary file not shown.
33
plugins/plucked_string_synth/Makefile.am
Normal file
33
plugins/plucked_string_synth/Makefile.am
Normal file
@@ -0,0 +1,33 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I.
|
||||
|
||||
|
||||
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="pluckedstringsynth"
|
||||
|
||||
|
||||
%.moc: ./%.h
|
||||
$(MOC) -o $@ $<
|
||||
|
||||
|
||||
MOC_FILES = ./plucked_string_synth.moc
|
||||
|
||||
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
|
||||
EMBEDDED_RESOURCES = $(wildcard *png)
|
||||
|
||||
./embedded_resources.h: $(EMBEDDED_RESOURCES)
|
||||
$(top_builddir)/buildtools/bin2res $(EMBEDDED_RESOURCES) > $@
|
||||
|
||||
EXTRA_DIST = $(EMBEDDED_RESOURCES)
|
||||
|
||||
|
||||
CLEANFILES = $(MOC_FILES) ./embedded_resources.h
|
||||
|
||||
|
||||
|
||||
pkglib_LTLIBRARIES= libpluckedstringsynth.la
|
||||
|
||||
libpluckedstringsynth_la_SOURCES = plucked_string_synth.cpp plucked_string_synth.h
|
||||
|
||||
$(libpluckedstringsynth_la_SOURCES): ./embedded_resources.h
|
||||
BIN
plugins/plucked_string_synth/artwork.png
Normal file
BIN
plugins/plucked_string_synth/artwork.png
Normal file
Binary file not shown.
BIN
plugins/plucked_string_synth/logo.png
Normal file
BIN
plugins/plucked_string_synth/logo.png
Normal file
Binary file not shown.
274
plugins/plucked_string_synth/plucked_string_synth.cpp
Normal file
274
plugins/plucked_string_synth/plucked_string_synth.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* plucked_string_synth.cpp - instrument which uses the Karplus-Strong-algorithm
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <Qt/QtXml>
|
||||
#include <QMap>
|
||||
|
||||
#else
|
||||
|
||||
#include <qdom.h>
|
||||
#include <qmap.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "plucked_string_synth.h"
|
||||
#include "channel_track.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "templates.h"
|
||||
#include "buffer_allocator.h"
|
||||
#include "knob.h"
|
||||
|
||||
#include "embed.cpp"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
plugin::descriptor pluckedstringsynth_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"PluckedStringSynth",
|
||||
QT_TRANSLATE_NOOP( "plugin",
|
||||
"cheap synthesis of guitar/harp-like sounds" ),
|
||||
"Tobias Doerffel <tobydox@users.sf.net>",
|
||||
0x0100,
|
||||
plugin::INSTRUMENT,
|
||||
PLUGIN_NAME::findEmbeddedData( "logo.png" )
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO: make this synth stereo for better better spacial (room) feeling and
|
||||
// add distortion
|
||||
|
||||
pluckedStringSynth::pluckedStringSynth( channelTrack * _channel_track ) :
|
||||
instrument( _channel_track,
|
||||
pluckedstringsynth_plugin_descriptor.public_name )
|
||||
{
|
||||
m_pickKnob = new knob( knobDark_28, this, tr( "Pick position" ) );
|
||||
m_pickKnob->setRange( 0.0f, 0.5f, 0.005f );
|
||||
m_pickKnob->setValue( 0.0f, TRUE );
|
||||
m_pickKnob->move( 86, 134 );
|
||||
m_pickKnob->setHintText( tr( "Pick position:" ) + " ", "" );
|
||||
|
||||
m_pickupKnob = new knob( knobDark_28, this, tr( "Pickup position" ) );
|
||||
m_pickupKnob->setRange( 0.0f, 0.5f, 0.005f );
|
||||
m_pickupKnob->setValue( 0.05f, TRUE );
|
||||
m_pickupKnob->move( 138, 134 );
|
||||
m_pickupKnob->setHintText( tr( "Pickup position:" ) + " ", "" );
|
||||
#ifdef QT4
|
||||
QPalette pal;
|
||||
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap(
|
||||
"artwork" ) );
|
||||
setPalette( pal );
|
||||
#else
|
||||
setErasePixmap( PLUGIN_NAME::getIconPixmap( "artwork" ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pluckedStringSynth::~pluckedStringSynth()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluckedStringSynth::saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent )
|
||||
{
|
||||
QDomElement pss_de = _doc.createElement( nodeName() );
|
||||
pss_de.setAttribute( "pick", QString::number( m_pickKnob->value() ) );
|
||||
pss_de.setAttribute( "pickup", QString::number(
|
||||
m_pickupKnob->value() ) );
|
||||
_parent.appendChild( pss_de );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluckedStringSynth::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_pickKnob->setValue( _this.attribute( "pick" ).toFloat() );
|
||||
m_pickupKnob->setValue( _this.attribute( "pickup" ).toFloat() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString pluckedStringSynth::nodeName( void ) const
|
||||
{
|
||||
return( pluckedstringsynth_plugin_descriptor.name );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluckedStringSynth::playNote( notePlayHandle * _n )
|
||||
{
|
||||
if ( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
float freq = getChannelTrack()->frequency( _n );
|
||||
_n->m_pluginData = new pluckSynth( freq, m_pickKnob->value(),
|
||||
m_pickupKnob->value() );
|
||||
}
|
||||
|
||||
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
|
||||
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
|
||||
|
||||
pluckSynth * ps = static_cast<pluckSynth *>( _n->m_pluginData );
|
||||
for( Uint32 frame = 0; frame < frames; ++frame )
|
||||
{
|
||||
const sampleType cur = ps->nextStringSample();
|
||||
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
|
||||
{
|
||||
buf[frame][chnl] = cur;
|
||||
}
|
||||
}
|
||||
|
||||
getChannelTrack()->processAudioBuffer( buf, frames, _n );
|
||||
|
||||
bufferAllocator::free( buf );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluckedStringSynth::deleteNotePluginData( notePlayHandle * _n )
|
||||
{
|
||||
delete static_cast<pluckSynth *>( _n->m_pluginData );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pluckSynth::delayLine * FASTCALL pluckSynth::initDelayLine( int _len )
|
||||
{
|
||||
delayLine * dl = new pluckSynth::delayLine[_len];
|
||||
dl->length = _len;
|
||||
if( _len > 0 )
|
||||
{
|
||||
dl->data = new sampleType[_len];
|
||||
}
|
||||
else
|
||||
{
|
||||
dl->data = NULL;
|
||||
}
|
||||
|
||||
dl->pointer = dl->data;
|
||||
dl->end = dl->data + _len - 1;
|
||||
|
||||
return( dl );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FASTCALL pluckSynth::freeDelayLine( delayLine * _dl )
|
||||
{
|
||||
if( _dl && _dl->data )
|
||||
{
|
||||
delete[] _dl->data;
|
||||
}
|
||||
|
||||
_dl->data = NULL;
|
||||
delete[] _dl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pluckSynth::pluckSynth( float _pitch, float _pick, float _pickup )
|
||||
{
|
||||
const float AMP = 1.5f;
|
||||
int rail_length = static_cast<int>( mixer::inst()->sampleRate() / 2 /
|
||||
_pitch ) + 1;
|
||||
// Round pick position to nearest spatial sample.
|
||||
// A pick position at x = 0 is not allowed.
|
||||
int pick_sample = static_cast<int>( tMax<float>( rail_length * _pick,
|
||||
1.0f ) );
|
||||
float initial_shape[rail_length];
|
||||
|
||||
m_upperRail = pluckSynth::initDelayLine( rail_length );
|
||||
m_lowerRail = pluckSynth::initDelayLine( rail_length );
|
||||
|
||||
//#define METALLIC_PLUCK
|
||||
#ifdef METALLIC_PLUCK
|
||||
for ( int i = 0; i < rail_length; i++ )
|
||||
{
|
||||
initial_shape[i] = rand() * AMP / RAND_MAX;
|
||||
}
|
||||
|
||||
initial_shape[pick_sample] = 0.5;
|
||||
initial_shape[pick_sample+1] = 0.5;
|
||||
|
||||
#else
|
||||
float upslope = AMP / pick_sample;
|
||||
const float downslope = AMP / ( rail_length - pick_sample - 1 );
|
||||
|
||||
for( int i = 0; i < pick_sample; i++ )
|
||||
{
|
||||
initial_shape[i] = upslope * i;
|
||||
}
|
||||
|
||||
for( int i = pick_sample; i < rail_length; i++ )
|
||||
{
|
||||
initial_shape[i] = downslope * ( rail_length - 1 - i );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initial conditions for the ideal plucked string.
|
||||
// "Past history" is measured backward from the end of the array.
|
||||
pluckSynth::setDelayLine( m_lowerRail, initial_shape, 0.5f );
|
||||
pluckSynth::setDelayLine( m_upperRail, initial_shape, 0.5f );
|
||||
|
||||
m_pickupLoc = static_cast<int>( _pickup * rail_length );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// neccessary for getting instance out of shared lib
|
||||
plugin * lmms_plugin_main( void * _data )
|
||||
{
|
||||
return( new pluckedStringSynth(
|
||||
static_cast<channelTrack *>( _data ) ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
216
plugins/plucked_string_synth/plucked_string_synth.h
Normal file
216
plugins/plucked_string_synth/plucked_string_synth.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* plucked_string_sytn.h - declaration of class pluckedStringSynth which
|
||||
* is a synth for plucked string-sounds
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _PLUCKED_STRING_SYNTH_H
|
||||
#define _PLUCKED_STRING_SYNTH_H
|
||||
|
||||
#include "instrument.h"
|
||||
|
||||
|
||||
class knob;
|
||||
class notePlayHandle;
|
||||
|
||||
|
||||
// the actual synth
|
||||
class pluckSynth
|
||||
{
|
||||
public:
|
||||
pluckSynth( float _pitch, float _pick, float _pickup );
|
||||
|
||||
inline ~pluckSynth( void )
|
||||
{
|
||||
pluckSynth::freeDelayLine( m_upperRail );
|
||||
pluckSynth::freeDelayLine( m_lowerRail );
|
||||
}
|
||||
|
||||
inline sampleType nextStringSample( void )
|
||||
{
|
||||
// Output at pickup position
|
||||
sampleType outsamp = rgDlAccess( m_upperRail, m_pickupLoc );
|
||||
outsamp += lgDlAccess( m_lowerRail, m_pickupLoc );
|
||||
|
||||
// Sample traveling into "bridge"
|
||||
sampleType ym0 = lgDlAccess( m_lowerRail, 1 );
|
||||
// Sample to "nut"
|
||||
sampleType ypM = rgDlAccess( m_upperRail,
|
||||
m_upperRail->length - 2 );
|
||||
|
||||
// String state update
|
||||
|
||||
// Decrement pointer and then update
|
||||
rgDlUpdate( m_upperRail, -bridgeReflection( ym0 ) );
|
||||
// Update and then increment pointer
|
||||
lgDlUpdate( m_lowerRail, -ypM );
|
||||
|
||||
return( outsamp );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
struct delayLine
|
||||
{
|
||||
sampleType * data;
|
||||
int length;
|
||||
sampleType * pointer;
|
||||
sampleType * end;
|
||||
} ;
|
||||
|
||||
delayLine * m_upperRail;
|
||||
delayLine * m_lowerRail;
|
||||
int m_pickupLoc;
|
||||
|
||||
static delayLine * FASTCALL initDelayLine( int _len );
|
||||
static void FASTCALL freeDelayLine( delayLine * _dl );
|
||||
static inline void setDelayLine( delayLine * _dl, float * _values,
|
||||
float _scale )
|
||||
{
|
||||
for( int i = 0; i < _dl->length; ++i )
|
||||
{
|
||||
_dl->data[i] = _scale * _values[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* lgDlUpdate(dl, insamp);
|
||||
* Places "nut-reflected" sample from upper delay-line into
|
||||
* current lower delay-line pointer position (which represents
|
||||
* x = 0 position). The pointer is then incremented (i.e. the
|
||||
* wave travels one sample to the left), turning the previous
|
||||
* position into an "effective" x = L position for the next
|
||||
* iteration. */
|
||||
static inline void lgDlUpdate( delayLine * _dl, sampleType _insamp )
|
||||
{
|
||||
register sampleType * ptr = _dl->pointer;
|
||||
*ptr = _insamp;
|
||||
++ptr;
|
||||
if( ptr > _dl->end )
|
||||
{
|
||||
ptr = _dl->data;
|
||||
}
|
||||
_dl->pointer = ptr;
|
||||
}
|
||||
|
||||
/* rgDlUpdate(dl, insamp);
|
||||
* Decrements current upper delay-line pointer position (i.e.
|
||||
* the wave travels one sample to the right), moving it to the
|
||||
* "effective" x = 0 position for the next iteration. The
|
||||
* "bridge-reflected" sample from lower delay-line is then placed
|
||||
* into this position. */
|
||||
static inline void rgDlUpdate( delayLine * _dl, sampleType _insamp )
|
||||
{
|
||||
register sampleType * ptr = _dl->pointer;
|
||||
--ptr;
|
||||
if( ptr < _dl->data )
|
||||
{
|
||||
ptr = _dl->end;
|
||||
}
|
||||
*ptr = _insamp;
|
||||
_dl->pointer = ptr;
|
||||
}
|
||||
|
||||
/* dlAccess(dl, position);
|
||||
* Returns sample "position" samples into delay-line's past.
|
||||
* Position "0" points to the most recently inserted sample. */
|
||||
static inline sampleType dlAccess( delayLine * _dl, int _position )
|
||||
{
|
||||
sampleType * outpos = _dl->pointer + _position;
|
||||
while( outpos < _dl->data )
|
||||
{
|
||||
outpos += _dl->length;
|
||||
}
|
||||
while( outpos > _dl->end )
|
||||
{
|
||||
outpos -= _dl->length;
|
||||
}
|
||||
return( *outpos );
|
||||
}
|
||||
|
||||
/*
|
||||
* Right-going delay line:
|
||||
* -->---->---->---
|
||||
* x=0
|
||||
* (pointer)
|
||||
* Left-going delay line:
|
||||
* --<----<----<---
|
||||
* x=0
|
||||
* (pointer)
|
||||
*/
|
||||
|
||||
/* rgDlAccess(dl, position);
|
||||
* Returns spatial sample at position "position", where position zero
|
||||
* is equal to the current upper delay-line pointer position (x = 0).
|
||||
* In a right-going delay-line, position increases to the right, and
|
||||
* delay increases to the right => left = past and right = future. */
|
||||
static inline sampleType rgDlAccess( delayLine * _dl, int _position )
|
||||
{
|
||||
return( dlAccess( _dl, _position ) );
|
||||
}
|
||||
|
||||
/* lgDlAccess(dl, position);
|
||||
* Returns spatial sample at position "position", where position zero
|
||||
* is equal to the current lower delay-line pointer position (x = 0).
|
||||
* In a left-going delay-line, position increases to the right, and
|
||||
* delay DEcreases to the right => left = future and right = past. */
|
||||
static inline sampleType lgDlAccess( delayLine * _dl, int _position )
|
||||
{
|
||||
return( dlAccess( _dl, _position ) );
|
||||
}
|
||||
|
||||
static inline sampleType bridgeReflection( sampleType _insamp )
|
||||
{
|
||||
static sampleType state = 0.0f; // filter memory
|
||||
// Implement a one-pole lowpass with feedback coefficient = 0.5
|
||||
return( state = state*0.5f + _insamp*0.5f );
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
class pluckedStringSynth : public instrument
|
||||
{
|
||||
public:
|
||||
pluckedStringSynth(channelTrack * _channel_track );
|
||||
virtual ~pluckedStringSynth();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
virtual void FASTCALL saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
virtual void FASTCALL loadSettings( const QDomElement & _this );
|
||||
|
||||
virtual QString nodeName( void ) const;
|
||||
|
||||
|
||||
private:
|
||||
knob * m_pickKnob;
|
||||
knob * m_pickupKnob;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
33
plugins/triple_oscillator/Makefile.am
Normal file
33
plugins/triple_oscillator/Makefile.am
Normal file
@@ -0,0 +1,33 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I.
|
||||
|
||||
|
||||
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="tripleoscillator"
|
||||
|
||||
|
||||
%.moc: ./%.h
|
||||
$(MOC) -o $@ $<
|
||||
|
||||
|
||||
MOC_FILES = ./triple_oscillator.moc
|
||||
|
||||
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
|
||||
EMBEDDED_RESOURCES = $(wildcard *png)
|
||||
|
||||
./embedded_resources.h: $(EMBEDDED_RESOURCES)
|
||||
$(top_builddir)/buildtools/bin2res $(EMBEDDED_RESOURCES) > $@
|
||||
|
||||
EXTRA_DIST = $(EMBEDDED_RESOURCES)
|
||||
|
||||
|
||||
CLEANFILES = $(MOC_FILES) ./embedded_resources.h
|
||||
|
||||
|
||||
|
||||
pkglib_LTLIBRARIES= libtripleoscillator.la
|
||||
|
||||
libtripleoscillator_la_SOURCES = triple_oscillator.cpp triple_oscillator.h
|
||||
|
||||
$(libtripleoscillator_la_SOURCES): ./embedded_resources.h
|
||||
BIN
plugins/triple_oscillator/am_active.png
Normal file
BIN
plugins/triple_oscillator/am_active.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/am_inactive.png
Normal file
BIN
plugins/triple_oscillator/am_inactive.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/artwork.png
Normal file
BIN
plugins/triple_oscillator/artwork.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/btn_mask.png
Normal file
BIN
plugins/triple_oscillator/btn_mask.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/fm_active.png
Normal file
BIN
plugins/triple_oscillator/fm_active.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/fm_inactive.png
Normal file
BIN
plugins/triple_oscillator/fm_inactive.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/logo.png
Normal file
BIN
plugins/triple_oscillator/logo.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/mix_active.png
Normal file
BIN
plugins/triple_oscillator/mix_active.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/mix_inactive.png
Normal file
BIN
plugins/triple_oscillator/mix_inactive.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/sync_active.png
Normal file
BIN
plugins/triple_oscillator/sync_active.png
Normal file
Binary file not shown.
BIN
plugins/triple_oscillator/sync_inactive.png
Normal file
BIN
plugins/triple_oscillator/sync_inactive.png
Normal file
Binary file not shown.
1222
plugins/triple_oscillator/triple_oscillator.cpp
Normal file
1222
plugins/triple_oscillator/triple_oscillator.cpp
Normal file
File diff suppressed because it is too large
Load Diff
167
plugins/triple_oscillator/triple_oscillator.h
Normal file
167
plugins/triple_oscillator/triple_oscillator.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* triple_oscillator.h - declaration of class tripleOscillator a powerful
|
||||
* instrument-plugin with 3 oscillators
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _TRIPLE_OSCILLATOR_H
|
||||
#define _TRIPLE_OSCILLATOR_H
|
||||
|
||||
|
||||
#include "instrument.h"
|
||||
#include "oscillator.h"
|
||||
#include "sample_buffer.h"
|
||||
|
||||
|
||||
class knob;
|
||||
class pixmapButton;
|
||||
class notePlayHandle;
|
||||
|
||||
|
||||
const int NUM_OF_OSCILLATORS = 3;
|
||||
|
||||
|
||||
class tripleOscillator : public instrument
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tripleOscillator( channelTrack * _channel ) FASTCALL;
|
||||
virtual ~tripleOscillator();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
virtual void FASTCALL saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
virtual void FASTCALL loadSettings( const QDomElement & _this );
|
||||
|
||||
virtual QString nodeName( void ) const;
|
||||
|
||||
|
||||
protected slots:
|
||||
// Slots for Osc 1
|
||||
void osc01SinWaveCh( bool _on );
|
||||
void osc01TriangleWaveCh( bool _on );
|
||||
void osc01SawWaveCh( bool _on );
|
||||
void osc01SquareWaveCh( bool _on );
|
||||
void osc01MoogSawWaveCh( bool _on );
|
||||
void osc01ExpWaveCh( bool _on );
|
||||
void osc01WhiteNoiseCh( bool _on );
|
||||
void osc01UserDefWaveCh( bool _on );
|
||||
void osc01UserDefWaveDblClick( void );
|
||||
|
||||
// Slots for Osc 2
|
||||
void osc02SinWaveCh( bool _on );
|
||||
void osc02TriangleWaveCh( bool _on );
|
||||
void osc02SawWaveCh( bool _on );
|
||||
void osc02SquareWaveCh( bool _on );
|
||||
void osc02MoogSawWaveCh( bool _on );
|
||||
void osc02ExpWaveCh( bool _on );
|
||||
void osc02WhiteNoiseCh( bool _on );
|
||||
void osc02UserDefWaveCh( bool _on );
|
||||
void osc02UserDefWaveDblClick( void );
|
||||
|
||||
// Slots for Osc 3
|
||||
void osc03SinWaveCh( bool _on );
|
||||
void osc03TriangleWaveCh( bool _on );
|
||||
void osc03SawWaveCh( bool _on );
|
||||
void osc03SquareWaveCh( bool _on );
|
||||
void osc03MoogSawWaveCh( bool _on );
|
||||
void osc03ExpWaveCh( bool _on );
|
||||
void osc03WhiteNoiseCh( bool _on );
|
||||
void osc03UserDefWaveCh( bool _on );
|
||||
void osc03UserDefWaveDblClick( void );
|
||||
|
||||
// modulation-type-button slots
|
||||
void fm1BtnToggled( bool _on );
|
||||
void am1BtnToggled( bool _on );
|
||||
void mix1BtnToggled( bool _on );
|
||||
void sync1BtnToggled( bool _on );
|
||||
|
||||
void fm2BtnToggled( bool _on );
|
||||
void am2BtnToggled( bool _on );
|
||||
void mix2BtnToggled( bool _on );
|
||||
void sync2BtnToggled( bool _on );
|
||||
|
||||
|
||||
private:
|
||||
channelTrack * m_channelTrack;
|
||||
|
||||
struct oscillatorData
|
||||
{
|
||||
oscillator::waveShapes waveShape;
|
||||
knob * volKnob;
|
||||
knob * panKnob;
|
||||
knob * coarseKnob;
|
||||
knob * fineLKnob;
|
||||
knob * fineRKnob;
|
||||
knob * phaseOffsetKnob;
|
||||
knob * stereoPhaseDetuningKnob;
|
||||
pixmapButton * sinWaveBtn;
|
||||
pixmapButton * triangleWaveBtn;
|
||||
pixmapButton * sawWaveBtn;
|
||||
pixmapButton * sqrWaveBtn;
|
||||
pixmapButton * moogSawWaveBtn;
|
||||
pixmapButton * expWaveBtn;
|
||||
pixmapButton * whiteNoiseWaveBtn;
|
||||
pixmapButton * usrWaveBtn;
|
||||
sampleBuffer m_sampleBuffer;
|
||||
} m_osc[NUM_OF_OSCILLATORS];
|
||||
|
||||
struct oscPtr
|
||||
{
|
||||
oscillator * oscLeft;
|
||||
oscillator * oscRight;
|
||||
} ;
|
||||
|
||||
|
||||
void FASTCALL doSinWaveBtn( oscillatorData * _osc );
|
||||
void FASTCALL doTriangleWaveBtn( oscillatorData * _osc );
|
||||
void FASTCALL doSawWaveBtn( oscillatorData * _osc );
|
||||
void FASTCALL doSqrWaveBtn( oscillatorData * _osc );
|
||||
void FASTCALL doMoogSawWaveBtn( oscillatorData * _osc );
|
||||
void FASTCALL doExpWaveBtn( oscillatorData * _osc );
|
||||
void FASTCALL doWhiteNoiseWaveBtn( oscillatorData * _osc );
|
||||
void FASTCALL doUsrWaveBtn( oscillatorData * _osc );
|
||||
pixmapButton * FASTCALL getModulationButton(
|
||||
oscillator::modulationAlgos _modulation_algo, int _n );
|
||||
void FASTCALL setModulationAlgo(
|
||||
oscillator::modulationAlgos _new_modulation_algo, int _n );
|
||||
oscillator::modulationAlgos FASTCALL getModulationAlgo( int _n );
|
||||
|
||||
|
||||
pixmapButton * m_fm1OscBtn;
|
||||
pixmapButton * m_am1OscBtn;
|
||||
pixmapButton * m_mix1OscBtn;
|
||||
pixmapButton * m_sync1OscBtn;
|
||||
pixmapButton * m_fm2OscBtn;
|
||||
pixmapButton * m_am2OscBtn;
|
||||
pixmapButton * m_mix2OscBtn;
|
||||
pixmapButton * m_sync2OscBtn;
|
||||
|
||||
oscillator::modulationAlgos m_modulationAlgo1;
|
||||
oscillator::modulationAlgos m_modulationAlgo2;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
35
plugins/vestige/Makefile.am
Normal file
35
plugins/vestige/Makefile.am
Normal file
@@ -0,0 +1,35 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I.
|
||||
|
||||
|
||||
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="vestige"
|
||||
|
||||
|
||||
%.moc: ./%.h
|
||||
$(MOC) -o $@ $<
|
||||
|
||||
|
||||
MOC_FILES = ./vestige.moc
|
||||
|
||||
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
|
||||
EMBEDDED_RESOURCES = $(wildcard *png)
|
||||
|
||||
./embedded_resources.h: $(EMBEDDED_RESOURCES)
|
||||
$(top_builddir)/buildtools/bin2res $(EMBEDDED_RESOURCES) > $@
|
||||
|
||||
EXTRA_DIST = $(EMBEDDED_RESOURCES)
|
||||
|
||||
|
||||
CLEANFILES = $(MOC_FILES) ./embedded_resources.h
|
||||
|
||||
|
||||
|
||||
pkglib_LTLIBRARIES= libvestige.la
|
||||
|
||||
libvestige_la_SOURCES = vestige.cpp vestige.h
|
||||
# libvestige_la_LIBADD = -lfst
|
||||
|
||||
$(libvestige_la_SOURCES): ./embedded_resources.h
|
||||
|
||||
BIN
plugins/vestige/artwork.png
Normal file
BIN
plugins/vestige/artwork.png
Normal file
Binary file not shown.
BIN
plugins/vestige/logo.png
Normal file
BIN
plugins/vestige/logo.png
Normal file
Binary file not shown.
860
plugins/vestige/vestige.cpp
Normal file
860
plugins/vestige/vestige.cpp
Normal file
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
* vestige.cpp - instrument-plugin for hosting VST-plugins
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <Qt/QtXml>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QCursor>
|
||||
|
||||
#else
|
||||
|
||||
#include <qdom.h>
|
||||
#include <qmessagebox.h>
|
||||
#include <qfiledialog.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qdir.h>
|
||||
#include <qcursor.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "vestige.h"
|
||||
#include "channel_track.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "buffer_allocator.h"
|
||||
#include "mixer.h"
|
||||
#include "song_editor.h"
|
||||
#include "instrument_play_handle.h"
|
||||
#include "pixmap_button.h"
|
||||
#include "tooltip.h"
|
||||
#include "spc_bg_hndl_widget.h"
|
||||
|
||||
|
||||
#include "embed.cpp"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
plugin::descriptor vestige_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"VeSTige",
|
||||
QT_TRANSLATE_NOOP( "plugin",
|
||||
"experimental VST-hoster for using VST-plugins "
|
||||
"within LMMS" ),
|
||||
"Tobias Doerffel <tobydox@users.sf.net>",
|
||||
0x0100,
|
||||
plugin::INSTRUMENT,
|
||||
PLUGIN_NAME::findEmbeddedData( "logo.png" )
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool vestigeInstrument::s_initialized = FALSE;
|
||||
bool vestigeInstrument::s_threadAdopted = FALSE;
|
||||
QPixmap * vestigeInstrument::s_artwork = NULL;
|
||||
|
||||
|
||||
vestigeInstrument::vestigeInstrument( channelTrack * _channel_track ) :
|
||||
instrument( _channel_track, vestige_plugin_descriptor.public_name ),
|
||||
specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) ),
|
||||
m_handle( NULL ),
|
||||
m_fst( NULL )
|
||||
{
|
||||
if( s_artwork == NULL )
|
||||
{
|
||||
s_artwork = new QPixmap( PLUGIN_NAME::getIconPixmap(
|
||||
"artwork" ) );
|
||||
}
|
||||
#ifdef QT4
|
||||
QPalette pal;
|
||||
pal.setBrush( backgroundRole(), *s_artwork);
|
||||
setPalette( pal );
|
||||
#else
|
||||
setErasePixmap( *s_artwork );
|
||||
#endif
|
||||
|
||||
m_openPluginButton = new pixmapButton( this );
|
||||
m_openPluginButton->setCheckable( FALSE );
|
||||
m_openPluginButton->setCursor( PointingHandCursor );
|
||||
m_openPluginButton->move( 200, 70 );
|
||||
m_openPluginButton->setActiveGraphic( embed::getIconPixmap(
|
||||
"project_open_down" ) );
|
||||
m_openPluginButton->setInactiveGraphic( embed::getIconPixmap(
|
||||
"project_open" ) );
|
||||
m_openPluginButton->setBgGraphic( getBackground(
|
||||
m_openPluginButton ) );
|
||||
connect( m_openPluginButton, SIGNAL( clicked() ), this,
|
||||
SLOT( openPlugin() ) );
|
||||
toolTip::add( m_openPluginButton, tr( "Open other VST-plugin" ) );
|
||||
|
||||
#ifdef QT4
|
||||
m_openPluginButton->setWhatsThis(
|
||||
#else
|
||||
QWhatsThis::add( m_openPluginButton,
|
||||
#endif
|
||||
tr( "Click here, if you want to open another VST-plugin. After "
|
||||
"clicking on this button, a file-open-dialog appears "
|
||||
"and you can select your file." ) );
|
||||
|
||||
if( s_initialized == FALSE )
|
||||
{
|
||||
if( fst_init( fst_signal_handler ) )
|
||||
{
|
||||
// TODO: message-box
|
||||
return;
|
||||
}
|
||||
s_initialized = TRUE;
|
||||
}
|
||||
// now we need a play-handle which cares for calling play()
|
||||
instrumentPlayHandle * iph = new instrumentPlayHandle( this );
|
||||
mixer::inst()->addPlayHandle( iph );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vestigeInstrument::~vestigeInstrument()
|
||||
{
|
||||
// this single call automates the rest of cleanup like trashing our
|
||||
// play-handle and so on
|
||||
invalidate();
|
||||
closePlugin();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent )
|
||||
{
|
||||
QDomElement vst_de = _doc.createElement( nodeName() );
|
||||
_parent.appendChild( vst_de );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString vestigeInstrument::nodeName( void ) const
|
||||
{
|
||||
return( vestige_plugin_descriptor.name );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::setParameter( const QString & _param,
|
||||
const QString & _value )
|
||||
{
|
||||
if( _param == "plugin" )
|
||||
{
|
||||
closePlugin();
|
||||
|
||||
m_plugin = _value;
|
||||
if( ( m_handle = fst_load(
|
||||
#ifdef QT4
|
||||
m_plugin.constData().toAscii()
|
||||
#else
|
||||
m_plugin.ascii()
|
||||
#endif
|
||||
) ) == NULL )
|
||||
{
|
||||
QMessageBox::information( this,
|
||||
tr( "Failed loading plugin" ),
|
||||
tr( "The VST-plugin %1 couldn't be "
|
||||
"loaded for some reason." ).arg(
|
||||
m_plugin ),
|
||||
QMessageBox::Ok );
|
||||
return;
|
||||
}
|
||||
if( ( m_fst = fst_instantiate( m_handle, hostCallback,
|
||||
this ) ) == NULL )
|
||||
{
|
||||
QMessageBox::information( this,
|
||||
tr( "Failed instantiating plugin" ),
|
||||
tr( "Couldn't create an instance of "
|
||||
"VST-plugin %1 for some "
|
||||
"reason." ).arg( m_plugin ),
|
||||
QMessageBox::Ok );
|
||||
fst_unload( m_handle );
|
||||
m_handle = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// set sample-rate and blocksize
|
||||
m_fst->plugin->dispatcher( m_fst->plugin, effSetSampleRate, 0,
|
||||
0, NULL, mixer::inst()->sampleRate() );
|
||||
m_fst->plugin->dispatcher( m_fst->plugin, effSetBlockSize, 0,
|
||||
mixer::inst()->framesPerAudioBuffer(),
|
||||
NULL, 0.0f );
|
||||
// set program to zero
|
||||
m_fst->plugin->dispatcher( m_fst->plugin, effSetProgram, 0, 0,
|
||||
NULL, 0.0f );
|
||||
// resume
|
||||
m_fst->plugin->dispatcher( m_fst->plugin, effMainsChanged, 0,
|
||||
1, NULL, 0.0f );
|
||||
/* if( fst_run_editor( m_fst ) )
|
||||
{
|
||||
printf( "VeSTige: cannot create editor\n" );
|
||||
}*/
|
||||
int vst_version = m_fst->plugin->dispatcher( m_fst->plugin,
|
||||
effGetVstVersion, 0, 0,
|
||||
NULL, 0.0f );
|
||||
if( vst_version < 2 )
|
||||
{
|
||||
QMessageBox::information( this,
|
||||
tr( "VST-plugin too old" ),
|
||||
tr( "The version of VST-plugin %1 "
|
||||
"is smaller than 2, which "
|
||||
"isn't supported." ).arg(
|
||||
m_plugin ),
|
||||
QMessageBox::Ok );
|
||||
return;
|
||||
}
|
||||
/* printf("WID:%d %d\n", (int)fst_get_XID( m_fst ),
|
||||
(int)QWidget::find( fst_get_XID( m_fst ) ) );*/
|
||||
|
||||
//printf("%d\n", m_fst->plugin->numParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::play( void )
|
||||
{
|
||||
// the very first time, we have to adopt fst-thread
|
||||
if( !s_threadAdopted )
|
||||
{
|
||||
fst_adopt_thread();
|
||||
s_threadAdopted = TRUE;
|
||||
}
|
||||
|
||||
if( m_handle == NULL || m_fst == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// first we gonna post all MIDI-events we enqueued so far
|
||||
if( m_midiEvents.size() )
|
||||
{
|
||||
// since MIDI-events are not received immediately, we have
|
||||
// to have them stored somewhere even after dispatcher-call,
|
||||
// so we create static copies of the data and post them
|
||||
static VstEvents events;
|
||||
static vvector<VstMidiEvent> cur_events;
|
||||
cur_events = m_midiEvents;
|
||||
m_midiEvents.clear();
|
||||
for( csize i = 0; i < cur_events.size(); ++i )
|
||||
{
|
||||
events.events[i] = (VstEvent *) &cur_events[i];
|
||||
}
|
||||
events.numEvents = cur_events.size();
|
||||
events.reserved = 0;
|
||||
m_fst->plugin->dispatcher( m_fst->plugin, effProcessEvents,
|
||||
0, 0, &events, 0.0f );
|
||||
}
|
||||
|
||||
// now we're ready to fetch sound from VST-plugin
|
||||
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
|
||||
|
||||
int ch_in = m_fst->plugin->numInputs;
|
||||
int ch_out = m_fst->plugin->numOutputs;
|
||||
float * ins[ch_in];
|
||||
float * outs[ch_out];
|
||||
for( int i = 0; i < ch_in; ++i )
|
||||
{
|
||||
ins[i] = bufferAllocator::alloc<float>( frames );
|
||||
}
|
||||
for( int i = 0; i < ch_out; ++i )
|
||||
{
|
||||
outs[i] = bufferAllocator::alloc<float>( frames );
|
||||
}
|
||||
|
||||
if( m_fst->plugin->flags & effFlagsCanReplacing )
|
||||
{
|
||||
m_fst->plugin->processReplacing( m_fst->plugin, ins, outs,
|
||||
frames );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("normal process\n");
|
||||
//mixer::inst()->clearAudioBuffer( buf, frames );
|
||||
m_fst->plugin->process( m_fst->plugin, ins, outs, frames );
|
||||
printf("normal process done\n");
|
||||
}
|
||||
|
||||
for( int i = 0; i < ch_in; ++i )
|
||||
{
|
||||
bufferAllocator::free( ins[i] );
|
||||
}
|
||||
|
||||
// got our data, now we just have to merge the 1/2 out-buffers
|
||||
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
|
||||
Uint8 chnls = tMax<Uint8>( ch_out, DEFAULT_CHANNELS );
|
||||
if( chnls != DEFAULT_CHANNELS )
|
||||
{
|
||||
mixer::inst()->clearAudioBuffer( buf, frames );
|
||||
}
|
||||
|
||||
for( Uint32 f = 0; f < frames; ++f )
|
||||
{
|
||||
for( Uint8 chnl = 0; chnl < chnls; ++chnl )
|
||||
{
|
||||
buf[f][chnl] = outs[chnl][f];
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < ch_out; ++i )
|
||||
{
|
||||
bufferAllocator::free( outs[i] );
|
||||
}
|
||||
|
||||
getChannelTrack()->processAudioBuffer( buf, frames, NULL );
|
||||
|
||||
bufferAllocator::free( buf );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::playNote( notePlayHandle * _n )
|
||||
{
|
||||
if( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
enqueueEvent( midiEvent( NOTE_ON, 0, _n->key(),
|
||||
_n->getVolume() ), _n->framesAhead() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::deleteNotePluginData( notePlayHandle * _n )
|
||||
{
|
||||
enqueueEvent( midiEvent( NOTE_OFF, 0, _n->key(), 0 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::openPlugin( void )
|
||||
{
|
||||
#ifdef QT4
|
||||
QFileDialog ofd( NULL, tr( "Open VST-plugin" ) );
|
||||
#else
|
||||
QFileDialog ofd( QString::null, QString::null, NULL, "", TRUE );
|
||||
ofd.setWindowTitle( tr( "Open VST-plugin" ) );
|
||||
#endif
|
||||
|
||||
QString dir;
|
||||
if( m_plugin != "" )
|
||||
{
|
||||
#ifdef QT4
|
||||
dir = QFileInfo( m_plugin ).absolutePath();
|
||||
#else
|
||||
dir = QFileInfo( m_plugin ).dirPath( TRUE );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = QDir::home().path();
|
||||
}
|
||||
// change dir to position of previously opened file
|
||||
ofd.setDirectory( dir );
|
||||
ofd.setFileMode( QFileDialog::ExistingFiles );
|
||||
|
||||
// set filters
|
||||
#ifdef QT4
|
||||
QStringList types;
|
||||
types << tr( "DLL-files (*.dll)" )
|
||||
<< tr( "EXE-files (*.exe)" )
|
||||
;
|
||||
ofd.setFilters( types );
|
||||
#else
|
||||
ofd.addFilter( tr( "DLL-files (*.dll)" ) );
|
||||
ofd.addFilter( tr( "EXE-files (*.exe)" ) );
|
||||
ofd.setSelectedFilter( tr( "DLL-files (*.dll)" ) );
|
||||
#endif
|
||||
if( m_plugin != "" )
|
||||
{
|
||||
// select previously opened file
|
||||
ofd.selectFile( QFileInfo( m_plugin ).fileName() );
|
||||
}
|
||||
|
||||
if ( ofd.exec () == QDialog::Accepted )
|
||||
{
|
||||
if( ofd.selectedFiles().isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
setParameter( "plugin", ofd.selectedFiles()[0] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::paintEvent( QPaintEvent * )
|
||||
{
|
||||
#ifdef QT4
|
||||
QPainter p( this );
|
||||
#else
|
||||
QPixmap pm( rect().size() );
|
||||
pm.fill( this, rect().topLeft() );
|
||||
|
||||
QPainter p( &pm, this );
|
||||
#endif
|
||||
|
||||
p.drawPixmap( 0, 0, *s_artwork );
|
||||
|
||||
QString plugin_name = ( m_handle != NULL && m_fst != NULL ) ?
|
||||
QString( m_handle->name ) + " " +
|
||||
QString::number( m_fst->plugin->dispatcher(
|
||||
m_fst->plugin,
|
||||
effGetVendorVersion,
|
||||
0, 0, NULL, 0.0f ) ):
|
||||
tr( "No VST-plugin loaded" );
|
||||
QFont f = p.font();
|
||||
f.setBold( TRUE );
|
||||
p.setFont( pointSize<10>( f ) );
|
||||
p.setPen( QColor( 0, 0, 0 ) );
|
||||
|
||||
p.drawText( 20, 80, plugin_name );
|
||||
|
||||
if( m_handle != NULL && m_fst != NULL )
|
||||
{
|
||||
p.setPen( QColor( 64, 128, 64 ) );
|
||||
f.setBold( FALSE );
|
||||
p.setFont( pointSize<8>( f ) );
|
||||
char buf[1024];
|
||||
m_fst->plugin->dispatcher( m_fst->plugin, effGetVendorString,
|
||||
0, 0, buf, 0 );
|
||||
p.drawText( 20, 94, tr( "by" ) + " " + QString( buf ) );
|
||||
}
|
||||
#ifndef QT4
|
||||
bitBlt( this, rect().topLeft(), &pm );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::closePlugin( void )
|
||||
{
|
||||
if( m_fst != NULL && m_handle != NULL )
|
||||
{
|
||||
//fst_destroy_editor( m_fst );
|
||||
printf( "closing VST-plugin" );
|
||||
fst_close( m_fst );
|
||||
printf( "unloading VST-plugin" );
|
||||
fst_unload( m_handle );
|
||||
m_fst = NULL;
|
||||
m_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::enqueueEvent( const midiEvent & _e,
|
||||
Uint32 _frames_ahead )
|
||||
{
|
||||
if( m_handle == NULL || m_fst == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VstMidiEvent event;
|
||||
|
||||
event.type = kVstMidiType;
|
||||
event.byteSize = 24;
|
||||
event.deltaFrames = _frames_ahead;
|
||||
event.flags = 0;
|
||||
event.detune = 0;
|
||||
event.noteLength = 0;
|
||||
event.noteOffset = 0;
|
||||
event.noteOffVelocity = 0;
|
||||
event.reserved1 = 0;
|
||||
event.reserved2 = 0;
|
||||
event.midiData[0] = _e.m_type + _e.m_channel;
|
||||
event.midiData[1] = _e.key();
|
||||
event.midiData[2] = _e.velocity();
|
||||
event.midiData[3] = 0;
|
||||
|
||||
m_midiEvents.push_back( event );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define DEBUG_CALLBACKS
|
||||
#ifdef DEBUG_CALLBACKS
|
||||
#define SHOW_CALLBACK printf
|
||||
#else
|
||||
#define SHOW_CALLBACK(...)
|
||||
#endif
|
||||
|
||||
long vestigeInstrument::hostCallback( AEffect * _effect, long _opcode,
|
||||
long _index, long _value, void * _ptr,
|
||||
float _opt )
|
||||
{
|
||||
static VstTimeInfo _timeInfo;
|
||||
|
||||
SHOW_CALLBACK( "host-callback, opcode = %d", (int) _opcode );
|
||||
|
||||
switch( _opcode )
|
||||
{
|
||||
case audioMasterAutomate:
|
||||
SHOW_CALLBACK( "amc: audioMasterAutomate\n" );
|
||||
// index, value, returns 0
|
||||
_effect->setParameter( _effect, _index, _opt );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterVersion:
|
||||
SHOW_CALLBACK( "amc: audioMasterVersion\n" );
|
||||
// vst version, currently 2 (0 for older)
|
||||
return( 2 );
|
||||
|
||||
case audioMasterCurrentId:
|
||||
SHOW_CALLBACK( "amc: audioMasterCurrentId\n" );
|
||||
// returns the unique id of a plug that's currently
|
||||
// loading
|
||||
return( 0 );
|
||||
|
||||
case audioMasterIdle:
|
||||
SHOW_CALLBACK ("amc: audioMasterIdle\n");
|
||||
// call application idle routine (this will
|
||||
// call effEditIdle for all open editors too)
|
||||
_effect->dispatcher( _effect, effEditIdle, 0, 0, NULL,
|
||||
0.0f );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterPinConnected:
|
||||
SHOW_CALLBACK( "amc: audioMasterPinConnected\n" );
|
||||
// inquire if an input or output is beeing connected;
|
||||
// index enumerates input or output counting from zero:
|
||||
// value is 0 for input and != 0 otherwise. note: the
|
||||
// return value is 0 for <true> such that older versions
|
||||
// will always return true.
|
||||
return( 1 );
|
||||
|
||||
case audioMasterWantMidi:
|
||||
SHOW_CALLBACK( "amc: audioMasterWantMidi\n" );
|
||||
// <value> is a filter which is currently ignored
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetTime:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetTime\n" );
|
||||
// returns const VstTimeInfo* (or 0 if not supported)
|
||||
// <value> should contain a mask indicating which
|
||||
// fields are required (see valid masks above), as some
|
||||
// items may require extensive conversions
|
||||
|
||||
memset( &_timeInfo, 0, sizeof( _timeInfo ) );
|
||||
|
||||
//tstate = jack_transport_query (jackvst->client, &jack_pos);
|
||||
_timeInfo.samplePos = 0;
|
||||
_timeInfo.sampleRate = mixer::inst()->sampleRate();
|
||||
_timeInfo.flags = 0;
|
||||
_timeInfo.tempo = songEditor::inst()->getBPM();
|
||||
_timeInfo.timeSigNumerator = 4;//(long) floor (jack_pos.beats_per_bar);
|
||||
_timeInfo.timeSigDenominator = 4;//(long) floor (jack_pos.beat_type);
|
||||
_timeInfo.flags |= (kVstBarsValid|kVstTempoValid);
|
||||
// if (tstate == JackTransportRolling) {
|
||||
_timeInfo.flags |= kVstTransportPlaying;
|
||||
// }
|
||||
|
||||
return( (long)&_timeInfo );
|
||||
|
||||
case audioMasterProcessEvents:
|
||||
SHOW_CALLBACK( "amc: audioMasterProcessEvents\n" );
|
||||
// VstEvents* in <ptr>
|
||||
return( 0 );
|
||||
|
||||
case audioMasterSetTime:
|
||||
SHOW_CALLBACK( "amc: audioMasterSetTime\n" );
|
||||
// VstTimenfo* in <ptr>, filter in <value>, not
|
||||
// supported
|
||||
|
||||
case audioMasterTempoAt:
|
||||
SHOW_CALLBACK( "amc: audioMasterTempoAt\n" );
|
||||
// returns tempo (in bpm * 10000) at sample frame
|
||||
// location passed in <value>
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetNumAutomatableParameters:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetNumAutomatable"
|
||||
"Parameters\n" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetParameterQuantization:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetParameter\n"
|
||||
"Quantization\n" );
|
||||
// returns the integer value for +1.0 representation,
|
||||
// or 1 if full single float precision is maintained
|
||||
// in automation. parameter index in <value> (-1: all,
|
||||
// any)
|
||||
return( 0 );
|
||||
|
||||
case audioMasterIOChanged:
|
||||
SHOW_CALLBACK( "amc: audioMasterIOChanged\n" );
|
||||
// numInputs and/or numOutputs has changed
|
||||
return( 0 );
|
||||
|
||||
case audioMasterNeedIdle:
|
||||
SHOW_CALLBACK( "amc: audioMasterNeedIdle\n" );
|
||||
// plug needs idle calls (outside its editor window)
|
||||
return( 0 );
|
||||
|
||||
case audioMasterSizeWindow:
|
||||
// TODO using lmms-main-window-size
|
||||
SHOW_CALLBACK( "amc: audioMasterSizeWindow\n" );
|
||||
// index: width, value: height
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetSampleRate:
|
||||
// TODO using mixer-call
|
||||
SHOW_CALLBACK( "amc: audioMasterGetSampleRate\n" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetBlockSize:
|
||||
// TODO using mixer-call
|
||||
SHOW_CALLBACK( "amc: audioMasterGetBlockSize\n" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetInputLatency:
|
||||
// TODO using mixer-call
|
||||
SHOW_CALLBACK( "amc: audioMasterGetInputLatency\n" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetOutputLatency:
|
||||
// TODO using mixer-call
|
||||
SHOW_CALLBACK( "amc: audioMasterGetOutputLatency\n" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetPreviousPlug:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetPreviousPlug\n" );
|
||||
// input pin in <value> (-1: first to come), returns
|
||||
// cEffect*
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetNextPlug:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetNextPlug\n" );
|
||||
// output pin in <value> (-1: first to come), returns
|
||||
// cEffect*
|
||||
return( 0 );
|
||||
|
||||
case audioMasterWillReplaceOrAccumulate:
|
||||
SHOW_CALLBACK( "amc: audioMasterWillReplaceOr"
|
||||
"Accumulate\n" );
|
||||
// returns: 0: not supported, 1: replace, 2: accumulate
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetCurrentProcessLevel:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetCurrentProcess"
|
||||
"Level\n" );
|
||||
// returns: 0: not supported,
|
||||
// 1: currently in user thread (gui)
|
||||
// 2: currently in audio thread (where process is
|
||||
// called)
|
||||
// 3: currently in 'sequencer' thread (midi, timer etc)
|
||||
// 4: currently offline processing and thus in user
|
||||
// thread
|
||||
// other: not defined, but probably pre-empting user
|
||||
// thread.
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetAutomationState:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetAutomationState\n" );
|
||||
// returns 0: not supported, 1: off, 2:read, 3:write,
|
||||
// 4:read/write offline
|
||||
return( 0 );
|
||||
|
||||
case audioMasterOfflineStart:
|
||||
SHOW_CALLBACK( "amc: audioMasterOfflineStart\n" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterOfflineRead:
|
||||
SHOW_CALLBACK( "amc: audioMasterOfflineRead\n" );
|
||||
// ptr points to offline structure, see below.
|
||||
// return 0: error, 1 ok
|
||||
return( 0 );
|
||||
|
||||
case audioMasterOfflineWrite:
|
||||
SHOW_CALLBACK( "amc: audioMasterOfflineWrite\n" );
|
||||
// same as read
|
||||
return( 0 );
|
||||
|
||||
case audioMasterOfflineGetCurrentPass:
|
||||
SHOW_CALLBACK( "amc: audioMasterOfflineGetCurrent"
|
||||
"Pass\n" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterOfflineGetCurrentMetaPass:
|
||||
SHOW_CALLBACK( "amc: audioMasterOfflineGetCurrentMeta"
|
||||
"Pass\n");
|
||||
return( 0 );
|
||||
|
||||
case audioMasterSetOutputSampleRate:
|
||||
SHOW_CALLBACK( "amc: audioMasterSetOutputSample"
|
||||
"Rate\n" );
|
||||
// for variable i/o, sample rate in <opt>
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetSpeakerArrangement:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetSpeaker"
|
||||
"Arrangement\n" );
|
||||
// (long)input in <value>, output in <ptr>
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetVendorString:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetVendorString\n" );
|
||||
// fills <ptr> with a string identifying the vendor
|
||||
// (max 64 char)
|
||||
strcpy( (char *) _ptr, "LAD");
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetProductString:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetProductString\n" );
|
||||
// fills <ptr> with a string with product name
|
||||
// (max 64 char)
|
||||
strcpy( (char *) _ptr, "VeSTige" );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetVendorVersion:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetVendorVersion\n" );
|
||||
// TODO
|
||||
// returns vendor-specific version
|
||||
return( 1000 );
|
||||
|
||||
case audioMasterVendorSpecific:
|
||||
SHOW_CALLBACK( "amc: audioMasterVendorSpecific\n" );
|
||||
// no definition, vendor specific handling
|
||||
return( 0 );
|
||||
|
||||
case audioMasterSetIcon:
|
||||
SHOW_CALLBACK( "amc: audioMasterSetIcon\n" );
|
||||
// TODO
|
||||
// void* in <ptr>, format not defined yet
|
||||
return( 0 );
|
||||
|
||||
case audioMasterCanDo:
|
||||
SHOW_CALLBACK( "amc: audioMasterCanDo\n" );
|
||||
// string in ptr, see below
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetLanguage:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetLanguage\n" );
|
||||
// TODO
|
||||
// see enum
|
||||
return( 0 );
|
||||
|
||||
case audioMasterOpenWindow:
|
||||
SHOW_CALLBACK( "amc: audioMasterOpenWindow\n" );
|
||||
// TODO
|
||||
// returns platform specific ptr
|
||||
return( 0 );
|
||||
|
||||
case audioMasterCloseWindow:
|
||||
SHOW_CALLBACK( "amc: audioMasterCloseWindow\n" );
|
||||
// TODO
|
||||
// close window, platform specific handle in <ptr>
|
||||
return( 0 );
|
||||
|
||||
case audioMasterGetDirectory:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetDirectory\n" );
|
||||
// TODO
|
||||
// get plug directory, FSSpec on MAC, else char*
|
||||
return( 0 );
|
||||
|
||||
case audioMasterUpdateDisplay:
|
||||
SHOW_CALLBACK( "amc: audioMasterUpdateDisplay\n" );
|
||||
// something has changed, update 'multi-fx' display
|
||||
_effect->dispatcher( _effect, effEditIdle, 0, 0, NULL,
|
||||
0.0f );
|
||||
return( 0 );
|
||||
|
||||
case audioMasterBeginEdit:
|
||||
SHOW_CALLBACK( "amc: audioMasterBeginEdit\n" );
|
||||
// begin of automation session (when mouse down),
|
||||
// parameter index in <index>
|
||||
return( 0 );
|
||||
|
||||
case audioMasterEndEdit:
|
||||
SHOW_CALLBACK( "amc: audioMasterEndEdit\n" );
|
||||
// end of automation session (when mouse up),
|
||||
// parameter index in <index>
|
||||
return( 0 );
|
||||
|
||||
case audioMasterOpenFileSelector:
|
||||
SHOW_CALLBACK( "amc: audioMasterOpenFileSelector\n" );
|
||||
// open a fileselector window with VstFileSelect*
|
||||
// in <ptr>
|
||||
return( 0 );
|
||||
|
||||
default:
|
||||
SHOW_CALLBACK( "VST master dispatcher: undefed: "
|
||||
"%d, %d\n", (int) _opcode,
|
||||
effKeysRequired );
|
||||
break;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// neccessary for getting instance out of shared lib
|
||||
plugin * lmms_plugin_main( void * _data )
|
||||
{
|
||||
return( new vestigeInstrument( static_cast<channelTrack *>( _data ) ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include "vestige.moc"
|
||||
|
||||
110
plugins/vestige/vestige.h
Normal file
110
plugins/vestige/vestige.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* vestige.h - instrument VeSTige for hosting VST-plugins
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 _VESTIGE_H
|
||||
#define _VESTIGE_H
|
||||
|
||||
#include "instrument.h"
|
||||
#include "midi.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#else
|
||||
|
||||
#include <qvector.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <fst.h>
|
||||
#include <vst/aeffectx.h>
|
||||
|
||||
#include "spc_bg_hndl_widget.h"
|
||||
|
||||
|
||||
class pixmapButton;
|
||||
class QPixmap;
|
||||
|
||||
|
||||
class vestigeInstrument : public instrument, public specialBgHandlingWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
vestigeInstrument( channelTrack * _channel_track );
|
||||
virtual ~vestigeInstrument();
|
||||
|
||||
virtual void play( void );
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
virtual void FASTCALL saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
virtual void FASTCALL loadSettings( const QDomElement & _this );
|
||||
|
||||
virtual QString nodeName( void ) const;
|
||||
|
||||
virtual void FASTCALL setParameter( const QString & _param,
|
||||
const QString & _value );
|
||||
|
||||
|
||||
protected slots:
|
||||
void openPlugin( void );
|
||||
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
|
||||
|
||||
private:
|
||||
void closePlugin( void );
|
||||
|
||||
void enqueueEvent( const midiEvent & _e, Uint32 _frames_ahead = 0 );
|
||||
|
||||
static long hostCallback( AEffect *, long, long, long, void *, float );
|
||||
|
||||
|
||||
static bool s_initialized;
|
||||
static bool s_threadAdopted;
|
||||
static QPixmap * s_artwork;
|
||||
|
||||
|
||||
FSTHandle * m_handle;
|
||||
FST * m_fst;
|
||||
|
||||
vvector<VstMidiEvent> m_midiEvents;
|
||||
|
||||
|
||||
pixmapButton * m_openPluginButton;
|
||||
|
||||
QString m_plugin;
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -175,13 +175,13 @@ int audioALSA::handleError( int _err )
|
||||
|
||||
|
||||
void audioALSA::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
float _master_output )
|
||||
float _master_gain )
|
||||
{
|
||||
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
|
||||
_frames * channels() );
|
||||
bufferAllocator::autoCleaner<> ac( outbuf );
|
||||
|
||||
convertToS16( _ab, _frames, _master_output, outbuf,
|
||||
convertToS16( _ab, _frames, _master_gain, outbuf,
|
||||
m_littleEndian != isLittleEndian() );
|
||||
|
||||
Uint32 frame = 0;
|
||||
|
||||
@@ -70,7 +70,7 @@ audioDevice::~audioDevice()
|
||||
|
||||
|
||||
void audioDevice::writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
Uint32 _src_sample_rate, float _master_output )
|
||||
Uint32 _src_sample_rate, float _master_gain )
|
||||
{
|
||||
// make sure, no other thread is accessing device
|
||||
lock();
|
||||
@@ -82,12 +82,12 @@ void audioDevice::writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
_frames * channels() );
|
||||
resample( _ab, _frames, temp, _src_sample_rate, m_sampleRate );
|
||||
writeBufferToDev( temp, _frames * m_sampleRate /
|
||||
_src_sample_rate, _master_output );
|
||||
_src_sample_rate, _master_gain );
|
||||
bufferAllocator::free( temp );
|
||||
}
|
||||
else
|
||||
{
|
||||
writeBufferToDev( _ab, _frames, _master_output );
|
||||
writeBufferToDev( _ab, _frames, _master_gain );
|
||||
}
|
||||
// release lock
|
||||
unlock();
|
||||
@@ -240,7 +240,7 @@ LP_FILTER_COEFFS[tap] * lp_hist[( oldest + tap ) % LP_FILTER_TAPS][chnl];
|
||||
|
||||
|
||||
int FASTCALL audioDevice::convertToS16( surroundSampleFrame * _ab,
|
||||
Uint32 _frames, float _master_output,
|
||||
Uint32 _frames, float _master_gain,
|
||||
outputSampleType * _output_buffer,
|
||||
bool _convert_endian )
|
||||
{
|
||||
@@ -251,7 +251,7 @@ int FASTCALL audioDevice::convertToS16( surroundSampleFrame * _ab,
|
||||
( _output_buffer + frame * channels() )[chnl] =
|
||||
static_cast<outputSampleType>(
|
||||
mixer::clip( _ab[frame][chnl] *
|
||||
_master_output ) *
|
||||
_master_gain ) *
|
||||
OUTPUT_SAMPLE_MULTIPLIER );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ bool audioFileOgg::startEncoding( void )
|
||||
|
||||
void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output )
|
||||
float _master_gain )
|
||||
{
|
||||
int eos = 0;
|
||||
|
||||
@@ -197,7 +197,7 @@ void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
|
||||
{
|
||||
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
|
||||
{
|
||||
buffer[chnl][frame] = _ab[frame][chnl] * _master_output;
|
||||
buffer[chnl][frame] = _ab[frame][chnl] * _master_gain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,11 +88,11 @@ bool audioFileWave::startEncoding( void )
|
||||
|
||||
void FASTCALL audioFileWave::writeBufferToDev( surroundSampleFrame * _ab,
|
||||
Uint32 _frames,
|
||||
float _master_output )
|
||||
float _master_gain )
|
||||
{
|
||||
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
|
||||
_frames * channels() );
|
||||
int bytes = convertToS16( _ab, _frames, _master_output, outbuf,
|
||||
int bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
|
||||
!isLittleEndian() );
|
||||
writeData( outbuf, bytes );
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ audioJACK::~audioJACK()
|
||||
|
||||
|
||||
void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
float _master_output )
|
||||
float _master_gain )
|
||||
{
|
||||
m_bufMutex.lock();
|
||||
|
||||
@@ -228,7 +228,7 @@ void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
_frames );
|
||||
for( Uint32 frame = 0; frame < _frames; ++frame )
|
||||
{
|
||||
buf[frame] = _ab[frame][chnl] * _master_output;
|
||||
buf[frame] = _ab[frame][chnl] * _master_gain;
|
||||
}
|
||||
bufset b = { buf, _frames } ;
|
||||
bufs.push_back( b );
|
||||
@@ -246,7 +246,10 @@ void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#ifdef HAVE_USLEEP
|
||||
// just wait and give cpu-time to other processes
|
||||
usleep( 200 );
|
||||
// tobydox 20051019: causes LMMS to hang up when locking
|
||||
// several other mutexes, so skip it
|
||||
//usleep( 200 );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -264,6 +267,8 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
|
||||
#endif
|
||||
jack_transport_state_t ts = jack_transport_query( _this->m_client,
|
||||
NULL );
|
||||
_this->m_bufMutex.lock();
|
||||
|
||||
if( ts != JackTransportRolling )
|
||||
{
|
||||
// always decrease frame-sync-var as we would do it if running
|
||||
@@ -276,6 +281,7 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
|
||||
{
|
||||
_this->m_frameSync = 0;
|
||||
}
|
||||
_this->m_bufMutex.unlock();
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@@ -289,7 +295,6 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
|
||||
_this->m_outputPorts[ch], _nframes );
|
||||
}
|
||||
|
||||
_this->m_bufMutex.lock();
|
||||
|
||||
jack_nframes_t done = 0;
|
||||
while( done < _nframes )
|
||||
|
||||
@@ -278,11 +278,11 @@ QString audioOSS::probeDevice( void )
|
||||
|
||||
|
||||
void audioOSS::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
float _master_output )
|
||||
float _master_gain )
|
||||
{
|
||||
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
|
||||
_frames * channels() );
|
||||
int bytes = convertToS16( _ab, _frames, _master_output, outbuf,
|
||||
int bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
|
||||
m_convertEndian );
|
||||
write( m_audioFD, outbuf, bytes );
|
||||
|
||||
|
||||
@@ -125,10 +125,10 @@ audioSDL::~audioSDL()
|
||||
|
||||
|
||||
void audioSDL::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
|
||||
float _master_output )
|
||||
float _master_gain )
|
||||
{
|
||||
m_bufMutex.lock();
|
||||
convertToS16( _ab, _frames, _master_output, m_buffer,
|
||||
convertToS16( _ab, _frames, _master_gain, m_buffer,
|
||||
m_convertEndian );
|
||||
m_bufMutex.unlock();
|
||||
// before returning make sure, callback was called, so we're synced
|
||||
|
||||
@@ -294,14 +294,6 @@ void bbEditor::keyPressEvent( QKeyEvent * _ke )
|
||||
|
||||
|
||||
|
||||
void bbEditor::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
lmmsMainWin::inst()->workspace()->wheelEvent( _we );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void bbEditor::resizeEvent( QResizeEvent * _re )
|
||||
{
|
||||
updateBackground();
|
||||
|
||||
@@ -163,10 +163,19 @@ configManager::configManager( void ) :
|
||||
m_lmmsDataDir( qApp->applicationDirPath().section( '/', 0, -2 ) +
|
||||
"/share/lmms/" ),
|
||||
#else
|
||||
// hardcode since qt 3.0 doesn't know something like
|
||||
// applicationDirPath and implmeneting own function would be senseless
|
||||
// since real support for qt 3.0 is senseless too ;-)
|
||||
// hardcode since qt < 3.2 doesn't know something like
|
||||
// applicationDirPath and implementing own function would be senseless
|
||||
// since real support for qt < 3.2 is senseless too ;-)
|
||||
m_lmmsDataDir( "/usr/share/lmms" ),
|
||||
#endif
|
||||
#if QT_VERSION >= 0x030200
|
||||
m_lmmsPluginDir( qApp->applicationDirPath().section( '/', 0, -2 ) +
|
||||
"/lib/lmms/" ),
|
||||
#else
|
||||
// hardcode since qt < 3.2 doesn't know something like
|
||||
// applicationDirPath and implementing own function would be senseless
|
||||
// since real support for qt < 3.2 is senseless too ;-)
|
||||
m_lmmsPluginDir( "/usr/lib/lmms" ),
|
||||
#endif
|
||||
m_currentPage( 0 )
|
||||
{
|
||||
|
||||
@@ -153,10 +153,7 @@ envelopeTabWidget::envelopeTabWidget( channelTrack * _channel_track,
|
||||
m_filterComboBox->addItem( tr( "Notch" ) );
|
||||
m_filterComboBox->addItem( tr( "Allpass" ) );
|
||||
m_filterComboBox->addItem( tr( "Moog" ) );
|
||||
m_filterComboBox->addItem( tr( "Moog 2" ) );
|
||||
m_filterComboBox->addItem( tr( "2x LowPass" ) );
|
||||
m_filterComboBox->addItem( tr( "2x Moog" ) );
|
||||
m_filterComboBox->addItem( tr( "2x Moog 2" ) );
|
||||
|
||||
#ifdef QT4
|
||||
m_filterComboBox->setWhatsThis(
|
||||
|
||||
93
src/core/instrument.cpp
Normal file
93
src/core/instrument.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* instrument.cpp - base-class for all instrument-plugins (synths, samplers etc)
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 "instrument.h"
|
||||
#include "channel_track.h"
|
||||
#include "dummy_instrument.h"
|
||||
|
||||
|
||||
instrument::instrument( channelTrack * _channel_track, const QString & _name ) :
|
||||
QWidget( _channel_track->pluginParent() ),
|
||||
plugin( _name, INSTRUMENT ),
|
||||
m_channelTrack( _channel_track ),
|
||||
m_valid( TRUE )
|
||||
{
|
||||
setFixedSize( 250, 250 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
instrument::~instrument()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void instrument::play( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void instrument::playNote( notePlayHandle * )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void instrument::deleteNotePluginData( notePlayHandle * )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Uint32 instrument::beatLen( notePlayHandle * ) const
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
instrument * instrument::instantiate( const QString & _plugin_name,
|
||||
channelTrack * _channel_track )
|
||||
{
|
||||
plugin * p = plugin::instantiate( _plugin_name, _channel_track );
|
||||
// check whether instantiated plugin is an instrument
|
||||
if( dynamic_cast<instrument *>( p ) != NULL )
|
||||
{
|
||||
// everything ok, so return pointer
|
||||
return( dynamic_cast<instrument *>( p ) );
|
||||
}
|
||||
|
||||
// not quite... so delete plugin and return dummy instrument
|
||||
delete p;
|
||||
return( new dummyInstrument( _channel_track ) );
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ int main( int argc, char * * argv )
|
||||
e->show();
|
||||
e->exportBtnClicked();
|
||||
}
|
||||
|
||||
return( app.exec() );
|
||||
}
|
||||
|
||||
|
||||
@@ -211,27 +211,6 @@ void mixer::run( void )
|
||||
// while we're acting...
|
||||
m_safetySyncMutex.lock();
|
||||
|
||||
/* following code is faster but unstable since using iterators
|
||||
while deleting from vector is dangerous and often leads to
|
||||
undefined results...
|
||||
|
||||
playHandleVector::iterator it = m_playHandles.begin();
|
||||
while( it != m_playHandles.end() )
|
||||
{
|
||||
if( ( *it )->done() )
|
||||
{
|
||||
// delete all play-handles which have
|
||||
// played completely now
|
||||
delete *it;
|
||||
m_playHandles.erase( it );
|
||||
}
|
||||
else
|
||||
{
|
||||
// play all uncompletely-played play-handles...
|
||||
( *it )->play();
|
||||
++it;
|
||||
}
|
||||
}*/
|
||||
csize idx = 0;
|
||||
while( idx < m_playHandles.size() )
|
||||
{
|
||||
|
||||
175
src/core/plugin.cpp
Normal file
175
src/core/plugin.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* plugin.cpp - implemenation of plugin-class including plugin-loader
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
|
||||
#else
|
||||
|
||||
#include <qmessagebox.h>
|
||||
#include <qdir.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "plugin.h"
|
||||
#include "mixer.h"
|
||||
#include "config_mgr.h"
|
||||
#include "dummy_plugin.h"
|
||||
|
||||
|
||||
|
||||
plugin::plugin( const QString & _public_name, pluginTypes _type ) :
|
||||
settings(),
|
||||
m_publicName( _public_name ),
|
||||
m_type( _type )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
plugin::~plugin()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void plugin::setParameter( const QString &, const QString & )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString plugin::getParameter( const QString & )
|
||||
{
|
||||
return( "" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
plugin * plugin::instantiate( const QString & _plugin_name, void * _data )
|
||||
{
|
||||
#ifdef HAVE_DLFCN_H
|
||||
void * handle = dlopen( QString( "lib" + _plugin_name + ".so" ).
|
||||
#ifdef QT4
|
||||
toAscii().constData()
|
||||
#else
|
||||
ascii()
|
||||
#endif
|
||||
, RTLD_LAZY );
|
||||
if( handle == NULL )
|
||||
{
|
||||
QMessageBox::information( NULL,
|
||||
mixer::tr( "Plugin not found" ),
|
||||
mixer::tr( "The %1-plugin wasn't found!"
|
||||
).arg( _plugin_name ),
|
||||
QMessageBox::Ok |
|
||||
QMessageBox::Default );
|
||||
return( new dummyPlugin() );
|
||||
}
|
||||
dlerror();
|
||||
instantiationHook inst_hook = ( instantiationHook )( dlsym( handle,
|
||||
"lmms_plugin_main" ) );
|
||||
char * error = dlerror();
|
||||
if( error != NULL )
|
||||
{
|
||||
printf( "%s\n", error );
|
||||
QMessageBox::information( NULL,
|
||||
mixer::tr( "Error while loading plugin" ),
|
||||
mixer::tr( "Failed loading plugin \"%1\"!"
|
||||
).arg( _plugin_name ),
|
||||
QMessageBox::Ok |
|
||||
QMessageBox::Default );
|
||||
return( new dummyPlugin() );
|
||||
}
|
||||
plugin * inst = inst_hook( _data );
|
||||
//dlclose( handle );
|
||||
return( inst );
|
||||
#endif
|
||||
return( new dummyPlugin() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void plugin::getDescriptorsOfAvailPlugins( vvector<descriptor> & _plugin_descs )
|
||||
{
|
||||
QDir directory( configManager::inst()->pluginDir() );
|
||||
const QFileInfoList * list = directory.entryInfoList( "*.so" );
|
||||
if( list == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
for( QFileInfoList::iterator file = list->begin();
|
||||
file != list->end(); ++file )
|
||||
{
|
||||
void * handle = dlopen( ( *file )->absFilePath().latin1(),
|
||||
RTLD_LAZY );
|
||||
char * msg = dlerror();
|
||||
if( msg != NULL || handle == NULL )
|
||||
{
|
||||
printf( "plugin-loader: %s\n", msg );
|
||||
continue;
|
||||
}
|
||||
void * foo = dlsym( handle, "lmms_plugin_main" );
|
||||
msg = dlerror();
|
||||
if( msg != NULL || foo == NULL )
|
||||
{
|
||||
printf( "plugin-loader: %s\n", msg );
|
||||
continue;
|
||||
}
|
||||
QString desc_name = ( *file )->fileName().mid( 3 ).section(
|
||||
'.', 0, 0 ) + "_plugin_descriptor";
|
||||
descriptor * plugin_desc =
|
||||
(descriptor *) dlsym( handle, desc_name.ascii() );
|
||||
msg = dlerror();
|
||||
if( msg != NULL || plugin_desc == NULL )
|
||||
{
|
||||
printf( "plugin-loader: %s\n", msg );
|
||||
continue;
|
||||
}
|
||||
_plugin_descs.push_back( *plugin_desc );
|
||||
//dlclose( handle );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
248
src/core/plugin_browser.cpp
Normal file
248
src/core/plugin_browser.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* plugin_browser.cpp - implementation of the plugin-browser
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
/*#include <QScrollArea>*/
|
||||
#include <QCursor>
|
||||
|
||||
#else
|
||||
|
||||
#include <qlabel.h>
|
||||
#include <qpainter.h>
|
||||
/*#include <qscrollview.h>*/
|
||||
#include <qcursor.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "plugin_browser.h"
|
||||
#include "embed.h"
|
||||
#include "debug.h"
|
||||
#include "gui_templates.h"
|
||||
#include "string_pair_drag.h"
|
||||
|
||||
|
||||
|
||||
pluginBrowser::pluginBrowser( QWidget * _parent ) :
|
||||
sideBarWidget( tr( "Instrument plugins" ),
|
||||
embed::getIconPixmap( "plugins" ), _parent )
|
||||
{
|
||||
setWindowTitle( tr( "Plugin browser" ) );
|
||||
m_view = new QWidget( contentParent() );
|
||||
//m_view->setFrameShape( QFrame::NoFrame );
|
||||
|
||||
addContentWidget( m_view );
|
||||
|
||||
QVBoxLayout * view_layout = new QVBoxLayout( m_view, 5, 10 );
|
||||
|
||||
|
||||
QLabel * hint = new QLabel( tr( "You can drag an instrument-plugin "
|
||||
"into either the Song-Editor, the "
|
||||
"Beat+Bassline Editor or just into a "
|
||||
"channel-window or on the "
|
||||
"corresponding channel-button." ),
|
||||
m_view );
|
||||
hint->setFont( pointSize<8>( hint->font() ) );
|
||||
hint->setAlignment( hint->alignment() | WordBreak );
|
||||
view_layout->addWidget( hint );
|
||||
|
||||
plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors );
|
||||
|
||||
for( vvector<plugin::descriptor>::iterator it =
|
||||
m_pluginDescriptors.begin();
|
||||
it != m_pluginDescriptors.end(); ++it )
|
||||
{
|
||||
pluginDescWidget * p = new pluginDescWidget( *it, m_view );
|
||||
p->show();
|
||||
view_layout->addWidget( p );
|
||||
}
|
||||
view_layout->addStretch();
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pluginBrowser::~pluginBrowser()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pluginDescWidget::pluginDescWidget( const plugin::descriptor & _pd,
|
||||
QWidget * _parent ) :
|
||||
QWidget( _parent ),
|
||||
m_pluginDescriptor( _pd ),
|
||||
m_logo(),
|
||||
m_mouseOver( FALSE )
|
||||
{
|
||||
m_logo.loadFromData( _pd.logo.data, _pd.logo.size );
|
||||
setFixedHeight( 60 );
|
||||
setMouseTracking( TRUE );
|
||||
#ifndef QT4
|
||||
setBackgroundMode( Qt::NoBackground );
|
||||
#endif
|
||||
setCursor( PointingHandCursor );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pluginDescWidget::~pluginDescWidget()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluginDescWidget::paintEvent( QPaintEvent * )
|
||||
{
|
||||
QColor fill_color( 192, 192, 192 );
|
||||
if( m_mouseOver )
|
||||
{
|
||||
fill_color = QColor( 224, 224, 224 );
|
||||
}
|
||||
|
||||
#ifdef QT4
|
||||
QPainter p( this );
|
||||
p.fillRect( rect(), fill_color );
|
||||
#else
|
||||
// create pixmap for whole widget
|
||||
QPixmap pm( rect().size() );
|
||||
pm.fill( fill_color );
|
||||
|
||||
// and a painter for it
|
||||
QPainter p( &pm );
|
||||
#endif
|
||||
p.setPen( QColor( 64, 64, 64 ) );
|
||||
p.drawRect( rect() );
|
||||
p.drawPixmap( 4, 4, m_logo );
|
||||
|
||||
QFont f = pointSize<8>( p.font() );
|
||||
f.setBold( TRUE );
|
||||
p.setFont( f );
|
||||
p.drawText( 58, 14, m_pluginDescriptor.public_name );
|
||||
|
||||
f.setBold( FALSE );
|
||||
p.setFont( pointSize<7>( f ) );
|
||||
QStringList words = QStringList::split( ' ',
|
||||
plugin::tr( m_pluginDescriptor.description ) );
|
||||
for( QStringList::iterator it = words.begin(); it != words.end(); ++it )
|
||||
{
|
||||
if( ( *it ).contains( '-' ) )
|
||||
{
|
||||
QStringList splitted_word = QStringList::split( '-',
|
||||
*it );
|
||||
QStringList::iterator orig_it = it;
|
||||
for( QStringList::iterator it2 = splitted_word.begin();
|
||||
it2 != splitted_word.end(); ++it2 )
|
||||
{
|
||||
if( it2 == splitted_word.fromLast() )
|
||||
{
|
||||
words.insert( it, *it2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
words.insert( it, *it2 + "-" );
|
||||
++it;
|
||||
}
|
||||
}
|
||||
words.erase( orig_it );
|
||||
--it;
|
||||
}
|
||||
}
|
||||
|
||||
int y = 26;
|
||||
int avail_width = width() - 58 - 5;
|
||||
QString s;
|
||||
for( QStringList::iterator it = words.begin(); it != words.end(); ++it )
|
||||
{
|
||||
if( p.fontMetrics().width( s + *it + " " ) >= avail_width )
|
||||
{
|
||||
p.drawText( 58, y, s );
|
||||
y += 10;
|
||||
s = "";
|
||||
}
|
||||
s += *it;
|
||||
if( ( *it ).right( 1 ) != "-" )
|
||||
{
|
||||
s += " ";
|
||||
}
|
||||
}
|
||||
p.drawText( 58, y, s );
|
||||
|
||||
#ifndef QT4
|
||||
// blit drawn pixmap to actual widget
|
||||
bitBlt( this, rect().topLeft(), &pm );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluginDescWidget::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( _me->button() == Qt::LeftButton )
|
||||
{
|
||||
new stringPairDrag( "plugin", m_pluginDescriptor.name, m_logo,
|
||||
this );
|
||||
m_mouseOver = FALSE;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluginDescWidget::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
bool new_mouse_over = rect().contains( _me->pos() );
|
||||
if( new_mouse_over != m_mouseOver )
|
||||
{
|
||||
m_mouseOver = new_mouse_over;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pluginDescWidget::mouseReleaseEvent( QMouseEvent * _me )
|
||||
{
|
||||
mouseMoveEvent( _me );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "plugin_browser.moc"
|
||||
|
||||
@@ -115,7 +115,7 @@ presetPreviewPlayHandle::presetPreviewPlayHandle(
|
||||
multimediaProject mmp( _preset_file );
|
||||
if( s_globalChannelTrack == NULL )
|
||||
{
|
||||
track * t = track::createTrack( track::CHANNEL_TRACK,
|
||||
track * t = track::create( track::CHANNEL_TRACK,
|
||||
blindTrackContainer::inst() );
|
||||
s_globalChannelTrack = dynamic_cast<channelTrack *>( t );
|
||||
#ifdef LMMS_DEBUG
|
||||
|
||||
@@ -351,16 +351,6 @@ songEditor::songEditor() :
|
||||
/* edit_tb->setPaletteBackgroundPixmap( embed::getIconPixmap(
|
||||
"toolbar_bg" ) );
|
||||
edit_tb->setErasePixmap( embed::getIconPixmap( "toolbar_bg" ) );*/
|
||||
#ifdef QT4
|
||||
a = edit_tb->addAction( embed::getIconPixmap( "add_channel_track" ), "",
|
||||
this, SLOT( addChannelTrack() ) );
|
||||
a->setToolTip( tr( "Add channel-track" ) );
|
||||
#else
|
||||
m_addChannelTrackButton = new QToolButton( embed::getIconPixmap(
|
||||
"add_channel_track" ), "", "",
|
||||
this, SLOT( addChannelTrack() ),
|
||||
edit_tb );
|
||||
#endif
|
||||
#ifdef QT4
|
||||
a = edit_tb->addAction( embed::getIconPixmap( "add_bb_track" ), "",
|
||||
this, SLOT( addBBTrack() ) );
|
||||
@@ -414,7 +404,6 @@ songEditor::songEditor() :
|
||||
|
||||
toolTip::add( m_playButton, tr( "Play/pause song (Space)" ) );
|
||||
toolTip::add( m_stopButton, tr( "Stop playing song (Space)" ) );
|
||||
toolTip::add( m_addChannelTrackButton, tr( "Add channel-track" ) );
|
||||
toolTip::add( m_addBBTrackButton, tr( "Add beat/bassline" ) );
|
||||
toolTip::add( m_addSampleTrackButton, tr( "Add sample-track" ) );
|
||||
toolTip::add( m_insertTactButton, tr( "Insert tact at current tact "
|
||||
@@ -609,7 +598,6 @@ void songEditor::scrolled( int _new_pos )
|
||||
|
||||
void songEditor::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
_we->accept();
|
||||
if( m_controlPressed )
|
||||
{
|
||||
if( _we->delta() > 0 )
|
||||
@@ -636,6 +624,12 @@ void songEditor::wheelEvent( QWheelEvent * _we )
|
||||
m_leftRightScroll->setValue( m_leftRightScroll->value() -
|
||||
_we->delta() / 30 );
|
||||
}
|
||||
else
|
||||
{
|
||||
_we->ignore();
|
||||
return;
|
||||
}
|
||||
_we->accept();
|
||||
}
|
||||
|
||||
|
||||
@@ -1290,24 +1284,9 @@ void songEditor::removeTact( void )
|
||||
|
||||
|
||||
|
||||
void songEditor::addChannelTrack( void )
|
||||
{
|
||||
channelTrack * t = dynamic_cast< channelTrack * >(
|
||||
track::createTrack( track::CHANNEL_TRACK, this ) );
|
||||
#ifdef LMMS_DEBUG
|
||||
assert( t != NULL );
|
||||
#endif
|
||||
t->loadPlugin( "tripleoscillator" );
|
||||
t->toggledChannelButton( TRUE );
|
||||
t->show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void songEditor::addBBTrack( void )
|
||||
{
|
||||
track * t = track::createTrack( track::BB_TRACK, this );
|
||||
track * t = track::create( track::BB_TRACK, this );
|
||||
if( dynamic_cast<bbTrack *>( t ) != NULL )
|
||||
{
|
||||
dynamic_cast<bbTrack *>( t )->clickedTrackLabel();
|
||||
@@ -1319,7 +1298,7 @@ void songEditor::addBBTrack( void )
|
||||
|
||||
void songEditor::addSampleTrack( void )
|
||||
{
|
||||
(void) track::createTrack( track::SAMPLE_TRACK, this );
|
||||
(void) track::create( track::SAMPLE_TRACK, this );
|
||||
}
|
||||
|
||||
|
||||
@@ -1435,14 +1414,14 @@ void songEditor::createNewProject( void )
|
||||
clearProject();
|
||||
|
||||
track * t;
|
||||
t = track::createTrack( track::CHANNEL_TRACK, this );
|
||||
dynamic_cast< channelTrack * >( t )->loadPlugin(
|
||||
t = track::create( track::CHANNEL_TRACK, this );
|
||||
dynamic_cast< channelTrack * >( t )->loadInstrument(
|
||||
"tripleoscillator" );
|
||||
track::createTrack( track::SAMPLE_TRACK, this );
|
||||
t = track::createTrack( track::CHANNEL_TRACK, bbEditor::inst() );
|
||||
dynamic_cast< channelTrack * >( t )->loadPlugin(
|
||||
track::create( track::SAMPLE_TRACK, this );
|
||||
t = track::create( track::CHANNEL_TRACK, bbEditor::inst() );
|
||||
dynamic_cast< channelTrack * >( t )->loadInstrument(
|
||||
"tripleoscillator" );
|
||||
track::createTrack( track::BB_TRACK, this );
|
||||
track::create( track::BB_TRACK, this );
|
||||
|
||||
setBPM( DEFAULT_BPM );
|
||||
m_masterVolumeSlider->setValue( 100 );
|
||||
|
||||
@@ -607,10 +607,10 @@ trackWidget::trackWidget( track * _track, QWidget * _parent ) :
|
||||
"", &m_trackOperationsWidget );
|
||||
deltr_btn->setGeometry( 1, 1+TRACK_OP_BTN_HEIGHT, TRACK_OP_BTN_WIDTH,
|
||||
TRACK_OP_BTN_HEIGHT );
|
||||
connect( deltr_btn, SIGNAL( clicked() ), this, SLOT( deleteTrack() ) );
|
||||
connect( deltr_btn, SIGNAL( clicked() ), this, SLOT( removeTrack() ) );
|
||||
connect( deltr_btn, SIGNAL( clicked() ), deltr_btn,
|
||||
SLOT( clearFocus() ) );
|
||||
toolTip::add( deltr_btn, tr( "Delete this track" ) );
|
||||
toolTip::add( deltr_btn, tr( "Remove this track" ) );
|
||||
|
||||
QPushButton * muptr_btn = new QPushButton( embed::getIconPixmap(
|
||||
"arp_up_on", 12, 12 ),
|
||||
@@ -718,7 +718,7 @@ void trackWidget::cloneTrack( void )
|
||||
|
||||
|
||||
|
||||
void trackWidget::deleteTrack( void )
|
||||
void trackWidget::removeTrack( void )
|
||||
{
|
||||
m_track->getTrackContainer()->removeTrack( m_track );
|
||||
}
|
||||
@@ -873,7 +873,7 @@ track::~track()
|
||||
|
||||
|
||||
|
||||
track * FASTCALL track::createTrack( trackTypes _tt, trackContainer * _tc )
|
||||
track * FASTCALL track::create( trackTypes _tt, trackContainer * _tc )
|
||||
{
|
||||
switch( _tt )
|
||||
{
|
||||
@@ -891,10 +891,10 @@ track * FASTCALL track::createTrack( trackTypes _tt, trackContainer * _tc )
|
||||
|
||||
|
||||
|
||||
track * FASTCALL track::createTrack( const QDomElement & _this,
|
||||
track * FASTCALL track::create( const QDomElement & _this,
|
||||
trackContainer * _tc )
|
||||
{
|
||||
track * t = createTrack( static_cast<trackTypes>( _this.attribute(
|
||||
track * t = create( static_cast<trackTypes>( _this.attribute(
|
||||
"type" ).toInt() ), _tc );
|
||||
#ifdef LMMS_DEBUG
|
||||
assert( t != NULL );
|
||||
@@ -906,13 +906,13 @@ track * FASTCALL track::createTrack( const QDomElement & _this,
|
||||
|
||||
|
||||
|
||||
track * FASTCALL track::cloneTrack( track * _track )
|
||||
track * FASTCALL track::clone( track * _track )
|
||||
{
|
||||
QDomDocument doc;
|
||||
QDomElement parent = doc.createElement( "clone" );
|
||||
_track->saveSettings( doc, parent );
|
||||
QDomElement e = parent.firstChild().toElement();
|
||||
return( createTrack( e, _track->getTrackContainer() ) );
|
||||
return( create( e, _track->getTrackContainer() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
#include "lmms_main_win.h"
|
||||
#include "mixer.h"
|
||||
#include "song_editor.h"
|
||||
|
||||
#include "string_pair_drag.h"
|
||||
#include "channel_track.h"
|
||||
#include "mmp.h"
|
||||
|
||||
|
||||
|
||||
@@ -69,15 +71,9 @@ trackContainer::trackContainer() :
|
||||
lmmsMainWin::inst()->workspace()->addWindow( this );
|
||||
#endif
|
||||
|
||||
m_scrollArea = new QScrollArea( this );
|
||||
m_scrollArea->setFrameStyle( QFrame::NoFrame );
|
||||
m_scrollArea->setHorizontalScrollBarPolicy(
|
||||
#ifdef QT4
|
||||
Qt::ScrollBarAlwaysOff
|
||||
#else
|
||||
QScrollArea::AlwaysOff
|
||||
#endif
|
||||
);
|
||||
m_scrollArea = new scrollArea( this );
|
||||
|
||||
setAcceptDrops( TRUE );
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +153,7 @@ void trackContainer::loadSettings( const QDomElement & _this )
|
||||
|
||||
if( node.isElement() )
|
||||
{
|
||||
track::createTrack( node.toElement(), this );
|
||||
track::create( node.toElement(), this );
|
||||
}
|
||||
node = node.nextSibling();
|
||||
}
|
||||
@@ -176,7 +172,7 @@ void trackContainer::loadSettings( const QDomElement & _this )
|
||||
|
||||
void trackContainer::cloneTrack( track * _track )
|
||||
{
|
||||
track::cloneTrack( _track );
|
||||
track::clone( _track );
|
||||
}
|
||||
|
||||
|
||||
@@ -372,6 +368,41 @@ void trackContainer::resizeEvent( QResizeEvent * )
|
||||
|
||||
|
||||
|
||||
void trackContainer::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
{
|
||||
stringPairDrag::processDragEnterEvent( _dee, "preset,plugin" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void trackContainer::dropEvent( QDropEvent * _de )
|
||||
{
|
||||
QString type = stringPairDrag::decodeKey( _de );
|
||||
QString value = stringPairDrag::decodeValue( _de );
|
||||
if( type == "plugin" )
|
||||
{
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>(
|
||||
track::create( track::CHANNEL_TRACK,
|
||||
this ) );
|
||||
ct->loadInstrument( value );
|
||||
ct->toggledChannelButton( TRUE );
|
||||
}
|
||||
else if( type == "preset" )
|
||||
{
|
||||
multimediaProject mmp( value );
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>(
|
||||
track::create( track::CHANNEL_TRACK,
|
||||
this ) );
|
||||
ct->loadTrackSpecificSettings( mmp.content().firstChild().
|
||||
toElement() );
|
||||
ct->toggledChannelButton( TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void trackContainer::updateScrollArea( void )
|
||||
{
|
||||
m_scrollArea->resize( tMax( m_scrollArea->parentWidget()->width() -
|
||||
@@ -384,6 +415,45 @@ void trackContainer::updateScrollArea( void )
|
||||
|
||||
|
||||
|
||||
trackContainer::scrollArea::scrollArea( trackContainer * _parent ) :
|
||||
QScrollArea( _parent )
|
||||
{
|
||||
setFrameStyle( QFrame::NoFrame );
|
||||
setHorizontalScrollBarPolicy(
|
||||
#ifdef QT4
|
||||
Qt::ScrollBarAlwaysOff
|
||||
#else
|
||||
QScrollArea::AlwaysOff
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
trackContainer::scrollArea::~scrollArea()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void trackContainer::scrollArea::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
// always pass wheel-event to parent-widget (song-editor
|
||||
// bb-editor etc.) because they might want to use it for zooming
|
||||
// or scrolling left/right if a modifier-key is pressed, otherwise
|
||||
// they do not accept it and we pass it up to QScrollArea
|
||||
dynamic_cast<trackContainer *>( parentWidget() )->wheelEvent( _we );
|
||||
if( !_we->isAccepted() )
|
||||
{
|
||||
QScrollArea::wheelEvent( _we );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "track_container.moc"
|
||||
|
||||
#undef setValue
|
||||
|
||||
@@ -188,7 +188,7 @@ void * bufferAllocator::allocBytes( Uint32 _bytes )
|
||||
}
|
||||
|
||||
|
||||
// nothing so far, so we'll alloc a new (aligned) buf
|
||||
// got nothing so far, so we'll alloc a new (aligned) buf
|
||||
bufDesc d = { FALSE, new char[_bytes + BUFFER_ALIGN], NULL, _bytes, 0 };
|
||||
d.buf = (void *)( (size_t) d.origPtr + ( BUFFER_ALIGN -
|
||||
( (size_t) d.origPtr &
|
||||
|
||||
@@ -43,9 +43,15 @@
|
||||
#include "config_mgr.h"
|
||||
|
||||
|
||||
|
||||
#ifndef PLUGIN_NAME
|
||||
namespace embed
|
||||
#else
|
||||
namespace PLUGIN_NAME
|
||||
#endif
|
||||
{
|
||||
|
||||
|
||||
#include "embedded_resources.h"
|
||||
|
||||
|
||||
@@ -55,10 +61,10 @@ QPixmap getIconPixmap( const char * _name, int _w, int _h )
|
||||
{
|
||||
QString name = QString( _name ) + ".png";
|
||||
#ifdef QT4
|
||||
const embedDesc & e = findEmbeddedData(
|
||||
const embed::descriptor & e = findEmbeddedData(
|
||||
name.toAscii().constData() );
|
||||
#else
|
||||
const embedDesc & e = findEmbeddedData( name.ascii() );
|
||||
const embed::descriptor & e = findEmbeddedData( name.ascii() );
|
||||
#endif
|
||||
// not found?
|
||||
if( QString( e.name ) != name )
|
||||
@@ -88,13 +94,12 @@ QPixmap getIconPixmap( const char * _name, int _w, int _h )
|
||||
|
||||
QString getText( const char * _name )
|
||||
{
|
||||
const embedDesc & e = findEmbeddedData( _name );
|
||||
const embed::descriptor & e = findEmbeddedData( _name );
|
||||
return( QString::fromLatin1( (const char *) e.data, e.size ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void loadTranslation( const QString & _tname )
|
||||
{
|
||||
QTranslator * t = new QTranslator( 0 );
|
||||
@@ -103,9 +108,10 @@ void loadTranslation( const QString & _tname )
|
||||
#if QT_VERSION >= 0x030100
|
||||
|
||||
#ifdef QT4
|
||||
const embedDesc & e = findEmbeddedData( name.toAscii().constData() );
|
||||
const embed::descriptor & e = findEmbeddedData(
|
||||
name.toAscii().constData() );
|
||||
#else
|
||||
const embedDesc & e = findEmbeddedData( name.ascii() );
|
||||
const embed::descriptor & e = findEmbeddedData( name.ascii() );
|
||||
#endif
|
||||
// not found?
|
||||
if( QString( e.name ) != name )
|
||||
@@ -126,3 +132,4 @@ void loadTranslation( const QString & _tname )
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,26 +23,31 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "ladspa_manager.h"
|
||||
|
||||
#ifdef LADSPA_SUPPORT
|
||||
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QPair>
|
||||
|
||||
#else
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qpair.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <ladspa.h>
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#include "ladspa_manager.h"
|
||||
|
||||
|
||||
ladspaManager * ladspaManager::s_instanceOfMe = NULL;
|
||||
@@ -55,19 +60,25 @@ ladspaManager::ladspaManager( void )
|
||||
|
||||
// TODO Need to move the search path definition to the config file to have
|
||||
// more control over where it tries to find the plugins.
|
||||
QStringList ladspaDirectories = QStringList::split( QString( ":" ),
|
||||
QStringList ladspaDirectories = QStringList::split( ':',
|
||||
QString( getenv( "LADSPA_PATH" ) ) );
|
||||
// set default-directory if nothing is specified...
|
||||
if( ladspaDirectories.isEmpty() )
|
||||
{
|
||||
ladspaDirectories.push_back( "/usr/lib/ladspa" );
|
||||
ladspaDirectories.push_back( "/usr/local/lib/ladspa" );
|
||||
}
|
||||
for( QStringList::iterator it = ladspaDirectories.begin();
|
||||
it != ladspaDirectories.end(); ++it )
|
||||
{
|
||||
QDir directory( ( *it ) );
|
||||
const QFileInfoList * list = directory.entryInfoList();
|
||||
|
||||
// if directory doesn't exist or isn't readable, we get NULL which
|
||||
// would crash LMMS...
|
||||
if( list == NULL )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for( QFileInfoList::iterator file = list->begin();
|
||||
file != list->end(); ++file )
|
||||
{
|
||||
@@ -842,3 +853,6 @@ void FASTCALL ladspaManager::cleanup( const ladspaKey & _plugin,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
112
src/lib/string_pair_drag.cpp
Normal file
112
src/lib/string_pair_drag.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* string_pair_drag.cpp - class stringPairDrag which provides general support
|
||||
* for drag'n'drop of string-pairs
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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 "string_pair_drag.h"
|
||||
|
||||
|
||||
|
||||
stringPairDrag::stringPairDrag( const QString & _key, const QString & _value,
|
||||
const QPixmap & _icon, QWidget * _w ) :
|
||||
#ifdef QT4
|
||||
QDrag( _w )
|
||||
#else
|
||||
QStoredDrag( "lmms/stringpair", _w )
|
||||
#endif
|
||||
{
|
||||
setPixmap( _icon );
|
||||
QString txt = _key + ":" + _value;
|
||||
#ifdef QT4
|
||||
QMimeData * m = new QMimeData();
|
||||
m->setData( "lmms/stringpair", txt.toAscii() );
|
||||
setMimeData( m );
|
||||
start( /*Qt::CopyAction*/ Qt::IgnoreAction );
|
||||
#else
|
||||
setEncodedData( txt.utf8() );
|
||||
drag();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
stringPairDrag::~stringPairDrag()
|
||||
{
|
||||
// TODO: do we have to delete anything???
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void stringPairDrag::processDragEnterEvent( QDragEnterEvent * _dee,
|
||||
const QString & _allowed_keys )
|
||||
{
|
||||
#ifdef QT4
|
||||
if( !_dee->mimeData()->hasFormat( "lmms/stringpair" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
QString txt = _dee->mimeData()->data();
|
||||
#else
|
||||
QString txt = _dee->encodedData( "lmms/stringpair" );
|
||||
#endif
|
||||
bool accepted = QStringList::split( ',', _allowed_keys ).contains(
|
||||
txt.section( ':', 0, 0 ) );
|
||||
#ifdef QT4
|
||||
if( accepted )
|
||||
{
|
||||
_dee->acceptProposedAction();
|
||||
}
|
||||
#else
|
||||
_dee->accept( accepted );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString stringPairDrag::decodeKey( QDropEvent * _de )
|
||||
{
|
||||
#ifdef QT4
|
||||
return( QString( _de->mimeData()->data() ).section( ':', 0, 0 ) );
|
||||
#else
|
||||
return( QString( _de->encodedData( "lmms/stringpair" ) ).section(
|
||||
':', 0, 0 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString stringPairDrag::decodeValue( QDropEvent * _de )
|
||||
{
|
||||
#ifdef QT4
|
||||
return( QString( _de->mimeData()->data() ).section( ':', 1, 1 ) );
|
||||
#else
|
||||
return( QString( _de->encodedData( "lmms/stringpair" ) ).section(
|
||||
':', 1, 1 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpainter.h>
|
||||
@@ -87,9 +88,9 @@ void pixmapButton::paintEvent( QPaintEvent * )
|
||||
}
|
||||
|
||||
#ifdef QT4
|
||||
if( isChecked() )
|
||||
if( isChecked() || isDown() )
|
||||
#else
|
||||
if( isOn() )
|
||||
if( isOn() || isDown() )
|
||||
#endif
|
||||
{
|
||||
if( m_activePixmap != NULL )
|
||||
|
||||
Reference in New Issue
Block a user