From f4154da68f3299194783dfab5efa29874f2ac6c9 Mon Sep 17 00:00:00 2001 From: Danny McRae Date: Fri, 8 Sep 2006 14:25:04 +0000 Subject: [PATCH] initial support for STK git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@392 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 19 + configure.in | 20 + include/config_mgr.h | 11 + include/setup_dialog.h | 11 +- plugins/Makefile.am | 6 +- plugins/stk/Makefile.am | 1 + plugins/stk/mallets/Makefile.am | 34 ++ plugins/stk/mallets/artwork.png | Bin 0 -> 17211 bytes plugins/stk/mallets/logo.png | Bin 0 -> 6971 bytes plugins/stk/mallets/mallets.cpp | 658 ++++++++++++++++++++++++++++++++ plugins/stk/mallets/mallets.h | 180 +++++++++ src/core/config_mgr.cpp | 29 +- src/core/setup_dialog.cpp | 69 ++++ 13 files changed, 1032 insertions(+), 6 deletions(-) create mode 100644 plugins/stk/Makefile.am create mode 100644 plugins/stk/mallets/Makefile.am create mode 100644 plugins/stk/mallets/artwork.png create mode 100644 plugins/stk/mallets/logo.png create mode 100644 plugins/stk/mallets/mallets.cpp create mode 100644 plugins/stk/mallets/mallets.h diff --git a/ChangeLog b/ChangeLog index 6a43c9fb8..432f51235 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2006-09-08 Danny McRae + * configure.in: + * plugins/Makefile.am: + * plugins/stk/Makefile.am: + began work on supporting STK instruments + + * plugins/stk/mallets/Makefile.am: + * plugins/stk/mallets/artwork.png: + * plugins/stk/mallets/logo.png: + * plugins/stk/mallets/mallets.h: + * plugins/stk/mallets/mallets.cpp: + added mallets instrument + + * include/config_mgr.h: + * src/core/config_mgr.cpp: + * include/setup_dialog.h: + * src/core/setup_dialog.cpp: + added STK rawwave to directory selector + 2006-09-03 Thomas Girard * src/core/file_browser.cpp: diff --git a/configure.in b/configure.in index 3b8392b2b..a39605346 100644 --- a/configure.in +++ b/configure.in @@ -214,6 +214,24 @@ if test ! -z "$HAVE_LADSPA_H" ; then fi #AM_CONDITIONAL(HAVE_LADSPA_H, test ! -z "$HAVE_LADSPA_H") + +# check for STK +AC_ARG_WITH(stk, + AS_HELP_STRING([--with-stk], [enable support for STK plugins]), [ with_stk=yes ], [ with_stk=no ]) +AH_TEMPLATE(HAVE_STK_H, [Define to 1 if you have the header file.]) +#if test "x$with_stk" = "xyes" ; then +# AC_CHECK_HEADER(stk/Stk.h, HAVE_STK_H="true") +# AC_CHECK_LIB([stk], [], HAVE_STK="true", HAVE_STK_H="") +#fi +if test "x$with_stk" = "xyes" ; then + HAVE_STK_H="true" +fi +if test ! -z "$HAVE_STK_H" ; then + AC_DEFINE(HAVE_STK_H) +fi +AM_CONDITIONAL(STK_SUPPORT, test ! -z "$HAVE_STK_H") + + # check for vorbis-lib AC_ARG_WITH(vorbis, AS_HELP_STRING([--without-vorbis], @@ -484,6 +502,8 @@ AC_CONFIG_FILES([Makefile plugins/midi_import/Makefile plugins/organic/Makefile plugins/plucked_string_synth/Makefile + plugins/stk/Makefile + plugins/stk/mallets/Makefile plugins/triple_oscillator/Makefile plugins/vestige/Makefile plugins/vibed/Makefile diff --git a/include/config_mgr.h b/include/config_mgr.h index 9ba0ea34f..5c5f96221 100644 --- a/include/config_mgr.h +++ b/include/config_mgr.h @@ -166,6 +166,13 @@ public: } #endif +#ifdef HAVE_STK_H + const QString & stkDir( void ) const + { + return( m_stkDir ); + } +#endif + const QString & value( const QString & _class, const QString & _attribute ) const; void setValue( const QString & _class, const QString & _attribute, @@ -181,6 +188,7 @@ public slots: void setArtworkDir( const QString & _ad ); void setFLDir( const QString & _fd ); void setLADSPADir( const QString & _fd ); + void setSTKDir( const QString & _fd ); protected slots: @@ -222,6 +230,9 @@ private: #ifdef LADSPA_SUPPORT QString m_ladDir; #endif +#ifdef HAVE_STK_H + QString m_stkDir; +#endif typedef vvector > stringPairVector; typedef QMap settingsMap; diff --git a/include/setup_dialog.h b/include/setup_dialog.h index 234bdd2d4..362db7c4e 100644 --- a/include/setup_dialog.h +++ b/include/setup_dialog.h @@ -85,7 +85,8 @@ private slots: void setArtworkDir( const QString & _ad ); void setFLDir( const QString & _fd ); void setLADSPADir( const QString & _fd ); - + void setSTKDir( const QString & _fd ); + // audio settings widget void audioInterfaceChanged( const QString & _driver ); void displayAudioHelp( void ); @@ -107,7 +108,7 @@ private slots: void openArtworkDir( void ); void openFLDir( void ); void openLADSPADir( void ); - + void openSTKDir( void ); void toggleDisableChActInd( bool _disabled ); void toggleManualChPiano( bool _enabled ); @@ -135,6 +136,9 @@ private: #ifdef LADSPA_SUPPORT QLineEdit * m_ladLineEdit; #endif +#ifdef HAVE_STK_H + QLineEdit * m_stkLineEdit; +#endif QString m_workingDir; QString m_vstDir; @@ -143,6 +147,9 @@ private: #ifdef LADSPA_SUPPORT QString m_ladDir; #endif +#ifdef HAVE_STK_H + QString m_stkDir; +#endif bool m_disableChActInd; bool m_manualChPiano; diff --git a/plugins/Makefile.am b/plugins/Makefile.am index deaf18444..d0ceedd34 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -2,5 +2,9 @@ if VST_SUPPORT VESTIGE_SUBDIR=vestige endif -SUBDIRS = audio_file_processor bit_invader flp_import midi_import organic plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR) vibed +if STK_SUPPORT +STK_DIR=stk +endif + +SUBDIRS = audio_file_processor bit_invader flp_import midi_import organic plucked_string_synth $(STK_DIR) triple_oscillator $(VESTIGE_SUBDIR) vibed diff --git a/plugins/stk/Makefile.am b/plugins/stk/Makefile.am new file mode 100644 index 000000000..c615d3acf --- /dev/null +++ b/plugins/stk/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = mallets \ No newline at end of file diff --git a/plugins/stk/mallets/Makefile.am b/plugins/stk/mallets/Makefile.am new file mode 100644 index 000000000..03b386a60 --- /dev/null +++ b/plugins/stk/mallets/Makefile.am @@ -0,0 +1,34 @@ +AUTOMAKE_OPTIONS = foreign 1.4 + + +INCLUDES = -I/usr/include/stk -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I. + + +AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="malletsstk" + + +%.moc: ./%.h + $(MOC) -o $@ $< + + +MOC_FILES = ./mallets.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= libmalletsstk.la + +libmalletsstk_la_SOURCES = mallets.cpp mallets.h +libmalletsstk_la_LDFLAGS = -L/usr/lib -lstk + +$(libmalletsstk_la_SOURCES): ./embedded_resources.h diff --git a/plugins/stk/mallets/artwork.png b/plugins/stk/mallets/artwork.png new file mode 100644 index 0000000000000000000000000000000000000000..ed24a16b153056e662c1d1254e16941b5e0861c4 GIT binary patch literal 17211 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 literal 0 HcmV?d00001 diff --git a/plugins/stk/mallets/logo.png b/plugins/stk/mallets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c9a8a04514b1f193ced5139fa81254ac405c0f4c GIT binary patch literal 6971 zcmV-B8^q*^P)8|>c%)c^n*$w@>( zRA}C9nRl3;S9#`t=e+G}GvCZNy=z7z$&zf@mSih3E?{iH#+0zx5ZWe$uwluSO(A6y z5;iyq3l7O<31m|!4(*CD31Ez|<0@P3k}TQkqfwh)zTVz?p8aE-U6N~`KhL?Y_dU;f z?&qBQzK{CCLwEouU(CwieEN42$no-L?)L0fq8@){F#g~#&g2fPd&zU{{^aACH2|W; zJ}HcCi<3&M9=mOsMayNW($Cq(3jET<=k1_pOg*b_Hvqp-d@SjB^hzl{^fvRRXIe=j z0;~b+3WQ(%(=Y3>ZHda{pm!K4FQ8I3dVCT~cf$H2O50HAM|eFfg{rKOJo!jxpuY4k zctIQ5b!e8LRfh*Id`fRmzh=L0_W?&LCHwLEaB_C*waH}9j}Qapz)IGaT$Cso$=m@= zo8d)Q_Ix(S%G*6jZmOtOy-7Nq5%t#ZIImq8G#Aca7w=g7j*N|CY!4Cv*Mp8cDi&zA zQLQRU3`|d>3WHebZm5@0N+a1$us|}Mfc!)PUpa`od>NhZK)E*d%rWdO%S`2M_I9S( zo+Q-k5q_mbFxth%c8rxos6viLZyx_lXouJ;>CY17L-Eg!cD2KSo**41NrL*h0ZKZe~ifaxDZk4$3m@1nO4<7L3Iej? z@)N2^334)a} z-atT@l+fMR&XXj-H6vI%&#rdm&>y9-6y&7%mSNk z*~6g=MY>Zd)~y0&xy9gEA4|{Aklr!CsZ&L!r-wLq@FY{$Z=w0{Hz{qO#yNPNOkWR; zOAA<0i#TaP(8je2E})|a_nW^wrP^5J(BdKpMh5Ae1 zI;jr4)aJo2K84(I1BZX_T}Zo&U@aoLSfqH*_qaKXXy5&I&R(3M&_6}IS54t8_za8+P<{A8(leKFjc}*saP`t0>9r!}>?y>4@p+W*6Pf_J9p9U)vl_;# zað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 + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#include "qt3support.h" + +#ifdef QT4 + +#include + +#else + +#include + +#endif + +#include "BandedWG.h" +#include "ModalBar.h" +#include "TubeBell.h" + +#include "mallets.h" +#include "instrument_track.h" +#include "note_play_handle.h" +#include "templates.h" +#include "knob.h" + +#undef SINGLE_SOURCE_COMPILE +#include "embed.cpp" + + +extern "C" +{ + +plugin::descriptor malletsstk_plugin_descriptor = +{ + STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ), + "Mallets", + QT_TRANSLATE_NOOP( "pluginBrowser", + "Tuneful things to bang on" ), + "Danny McRae ", + 0x0100, + plugin::INSTRUMENT, + new QPixmap( PLUGIN_NAME::getIconPixmap( "logo" ) ) +} ; + +} + + +mallets::mallets( instrumentTrack * _channel_track ) : + instrument( _channel_track, &malletsstk_plugin_descriptor ) +{ + m_modalBarWidget = setupModalBarControls( this, _channel_track ); + setWidgetBackground( m_modalBarWidget, "artwork" ); + + m_tubeBellWidget = setupTubeBellControls( this, _channel_track ); + setWidgetBackground( m_tubeBellWidget, "artwork" ); + m_tubeBellWidget->hide(); + + m_bandedWGWidget = setupBandedWGControls( this, _channel_track ); + setWidgetBackground( m_bandedWGWidget, "artwork" ); + m_bandedWGWidget->hide(); + + m_presets = setupPresets( this, _channel_track ); + + m_spread = new knob( knobBright_26, this, tr( "Spread" ), + eng(), _channel_track ); + m_spread->setLabel( tr( "Spread" ) ); + m_spread->setRange( 0, 255, 1 ); + m_spread->setInitValue( 0 ); + m_spread->move( 178, 173 ); + m_spread->setHintText( tr( "Spread:" ) + " ", "" ); + + m_buffer = bufferAllocator::alloc( + eng()->getMixer()->framesPerAudioBuffer() ); +} + + + + +mallets::~mallets() +{ + bufferAllocator::free( m_buffer ); +} + + + + +void mallets::setWidgetBackground( QWidget * _widget, const QString & _pic ) +{ +#ifdef QT4 + _widget->setAutoFillBackground( TRUE ); + _widget->QPalette pal; + _widget->pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( + _pic ) ); + _widget->setPalette( pal ); +#else + _widget->setErasePixmap( PLUGIN_NAME::getIconPixmap( _pic ) ); +#endif +} + + + + +QWidget * mallets::setupModalBarControls( QWidget * _parent, track * _track ) +{ + QWidget * widget = new QWidget( _parent, "ModalBar" ); + widget->setFixedSize( 250, 250 ); + + m_hardness = new knob( knobBright_26, widget, tr( "Hardness" ), + eng(), _track ); + m_hardness->setLabel( tr( "Hardness" ) ); + m_hardness->setRange( 0.0, 128.0, 0.1 ); + m_hardness->setInitValue( 64.0 ); + m_hardness->move( 145, 24 ); + m_hardness->setHintText( tr( "Hardness:" ) + " ", "" ); + + m_position = new knob( knobBright_26, widget, tr( "Position" ), + eng(), _track ); + m_position->setLabel( tr( "Position" ) ); + m_position->setRange( 0.0, 128.0, 0.1 ); + m_position->setInitValue( 64.0 ); + m_position->move( 195, 24 ); + m_position->setHintText( tr( "Position:" ) + " ", "" ); + + m_vibratoGain = new knob( knobBright_26, widget, tr( "Vibrato Gain" ), + eng(), _track ); + m_vibratoGain->setLabel( tr( "Vib Gain" ) ); + m_vibratoGain->setRange( 0.0, 128.0, 0.1 ); + m_vibratoGain->setInitValue( 64.0 ); + m_vibratoGain->move( 56, 86 ); + m_vibratoGain->setHintText( tr( "Vib Gain:" ) + " ", "" ); + + m_vibratoFreq = new knob( knobBright_26, widget, tr( "Vibrato Freq" ), + eng(), _track ); + m_vibratoFreq->setLabel( tr( "Vib Freq" ) ); + m_vibratoFreq->setRange( 0.0, 128.0, 0.1 ); + m_vibratoFreq->setInitValue( 64.0 ); + m_vibratoFreq->move( 117, 86 ); + m_vibratoFreq->setHintText( tr( "Vib Freq:" ) + " ", "" ); + + m_stick = new knob( knobBright_26, widget, tr( "Stick Mix" ), + eng(), _track ); + m_stick->setLabel( tr( "Stick Mix" ) ); + m_stick->setRange( 0.0, 128.0, 0.1 ); + m_stick->setInitValue( 64.0 ); + m_stick->move( 178, 86 ); + m_stick->setHintText( tr( "Stick Mix:" ) + " ", "" ); + + return( widget ); +} + + + + +QWidget * mallets::setupTubeBellControls( QWidget * _parent, track * _track ) +{ + QWidget * widget = new QWidget( _parent, "TubeBellWidget" ); + widget->setFixedSize( 250, 250 ); + + m_modulator = new knob( knobBright_26, widget, tr( "Modulator" ), + eng(), _track ); + m_modulator->setLabel( tr( "Modulator" ) ); + m_modulator->setRange( 0.0, 128.0, 0.1 ); + m_modulator->setInitValue( 100.0 ); + m_modulator->move( 145, 24 ); + m_modulator->setHintText( tr( "Modulator:" ) + " ", "" ); + + m_crossfade = new knob( knobBright_26, widget, tr( "Crossfade" ), + eng(), _track ); + m_crossfade->setLabel( tr( "Crossfade" ) ); + m_crossfade->setRange( 0.0, 128.0, 0.1 ); + m_crossfade->setInitValue( 0.0 ); + m_crossfade->move( 195, 24 ); + m_crossfade->setHintText( tr( "Crossfade:" ) + " ", "" ); + + m_lfoSpeed = new knob( knobBright_26, widget, tr( "LFO Speed" ), + eng(), _track ); + m_lfoSpeed->setLabel( tr( "LFO Speed" ) ); + m_lfoSpeed->setRange( 0.0, 128.0, 0.1 ); + m_lfoSpeed->setInitValue( 20.0 ); + m_lfoSpeed->move( 56, 86 ); + m_lfoSpeed->setHintText( tr( "LFO Speed:" ) + " ", "" ); + + m_lfoDepth = new knob( knobBright_26, widget, tr( "LFO Depth" ), + eng(), _track ); + m_lfoDepth->setLabel( tr( "LFO Depth" ) ); + m_lfoDepth->setRange( 0.0, 128.0, 0.1 ); + m_lfoDepth->setInitValue( 10.0 ); + m_lfoDepth->move( 117, 86 ); + m_lfoDepth->setHintText( tr( "LFO Depth:" ) + " ", "" ); + + m_adsr = new knob( knobBright_26, widget, tr( "ADSR" ), + eng(), _track ); + m_adsr->setLabel( tr( "ADSR" ) ); + m_adsr->setRange( 0.0, 128.0, 0.1 ); + m_adsr->setInitValue( 0.0 ); + m_adsr->move( 178, 86 ); + m_adsr->setHintText( tr( "ADSR:" ) + " ", "" ); + + return( widget ); +} + + + + +QWidget * mallets::setupBandedWGControls( QWidget * _parent, track * _track ) +{ + // BandedWG + QWidget * widget = new QWidget( _parent, "BandedWGWidget" ); + widget->setFixedSize( 250, 250 ); + + m_strike = new ledCheckBox( tr( "Bowed" ), widget, tr( "Bowed" ), + eng(), _track ); + m_strike->move( 165, 30 ); + + m_pressure = new knob( knobBright_26, widget, tr( "Pressure" ), + eng(), _track ); + m_pressure->setLabel( tr( "Pressure" ) ); + m_pressure->setRange( 0.0, 128.0, 0.1 ); + m_pressure->setInitValue( 64.0 ); + m_pressure->move( 56, 86 ); + m_pressure->setHintText( tr( "Pressure:" ) + " ", "" ); + + m_motion = new knob( knobBright_26, widget, tr( "Motion" ), + eng(), _track ); + m_motion->setLabel( tr( "Motion" ) ); + m_motion->setRange( 0.0, 128.0, 0.1 ); + m_motion->setInitValue( 64.0 ); + m_motion->move( 117, 86 ); + m_motion->setHintText( tr( "Motion:" ) + " ", "" ); + + m_velocity = new knob( knobBright_26, widget, tr( "Speed" ), + eng(), _track ); + m_velocity->setLabel( tr( "Speed" ) ); + m_velocity->setRange( 0.0, 128.0, 0.1 ); + m_velocity->setInitValue( 74.5 ); + m_velocity->move( 178, 86 ); + m_velocity->setHintText( tr( "Speed:" ) + " ", "" ); + + m_vibrato = new knob( knobBright_26, widget, tr( "Vibrato" ), + eng(), _track ); + m_vibrato->setLabel( tr( "Vibrato" ) ); + m_vibrato->setRange( 0.0, 128.0, 0.1 ); + m_vibrato->setInitValue( 64.0 ); + m_vibrato->move( 178, 129 ); + m_vibrato->setHintText( tr( "Vibrato:" ) + " ", "" ); + + return( widget ); +} + + + + +comboBox * mallets::setupPresets( QWidget * _parent, track * _track ) +{ + comboBox * presets = new comboBox( _parent, tr( "Instrument" ), + eng(), _track ); + presets->setGeometry( 64, 157, 99, 22 ); + presets->setFont( pointSize<8>( presets->font() ) ); + + connect( presets, SIGNAL( valueChanged( int ) ), + _parent, SLOT( changePreset( int ) ) ); + + // ModalBar + presets->addItem( tr( "Marimba" ) ); + m_scalers.append( 4.0 ); + presets->addItem( tr( "Vibraphone" ) ); + m_scalers.append( 4.0 ); + presets->addItem( tr( "Agogo" ) ); + m_scalers.append( 5.0 ); + presets->addItem( tr( "Wood1" ) ); + m_scalers.append( 4.0 ); + presets->addItem( tr( "Reso" ) ); + m_scalers.append( 2.5 ); + presets->addItem( tr( "Wood2" ) ); + m_scalers.append( 5.0 ); + presets->addItem( tr( "Beats" ) ); + m_scalers.append( 20.0 ); + presets->addItem( tr( "Two Fixed" ) ); + m_scalers.append( 5.0 ); + presets->addItem( tr( "Clump" ) ); + m_scalers.append( 4.0 ); + + // TubeBell + presets->addItem( tr( "Tubular Bells" ) ); + m_scalers.append( 1.8 ); + + // BandedWG + presets->addItem( tr( "Uniform Bar" ) ); + m_scalers.append( 25.0 ); + presets->addItem( tr( "Tuned Bar" ) ); + m_scalers.append( 10.0 ); + presets->addItem( tr( "Glass" ) ); + m_scalers.append( 16.0 ); + presets->addItem( tr( "Tibetan Bowl" ) ); + m_scalers.append( 7.0 ); + + return( presets ); +} + + + + +void mallets::saveSettings( QDomDocument & _doc, QDomElement & _this ) +{ + // ModalBar + m_hardness->saveSettings( _doc, _this, "hardness" ); + m_position->saveSettings( _doc, _this, "position" ); + m_vibratoGain->saveSettings( _doc, _this, "vib_gain" ); + m_vibratoFreq->saveSettings( _doc, _this, "vib_freq" ); + m_stick->saveSettings( _doc, _this, "stick_mix" ); + + // TubeBell + m_modulator->saveSettings( _doc, _this, "modulator" ); + m_crossfade->saveSettings( _doc, _this, "crossfade" ); + m_lfoSpeed->saveSettings( _doc, _this, "lfo_speed" ); + m_lfoDepth->saveSettings( _doc, _this, "lfo_depth" ); + m_adsr->saveSettings( _doc, _this, "adsr" ); + + // BandedWG + m_pressure->saveSettings( _doc, _this, "pressure" ); + m_motion->saveSettings( _doc, _this, "motion" ); + m_vibrato->saveSettings( _doc, _this, "vibrato" ); + m_velocity->saveSettings( _doc, _this, "velocity" ); + m_strike->saveSettings( _doc, _this, "strike" ); + + m_presets->saveSettings( _doc, _this, "preset" ); + m_spread->saveSettings( _doc, _this, "spread" ); +} + + + + +void mallets::loadSettings( const QDomElement & _this ) +{ + // ModalBar + m_hardness->loadSettings( _this, "hardness" ); + m_position->loadSettings( _this, "position" ); + m_vibratoGain->loadSettings( _this, "vib_gain" ); + m_vibratoFreq->loadSettings( _this, "vib_freq" ); + m_stick->loadSettings( _this, "stick_mix" ); + + // TubeBell + m_modulator->loadSettings( _this, "modulator" ); + m_crossfade->loadSettings( _this, "crossfade" ); + m_lfoSpeed->loadSettings( _this, "lfo_speed" ); + m_lfoDepth->loadSettings( _this, "lfo_depth" ); + m_adsr->loadSettings( _this, "adsr" ); + + // BandedWG + m_pressure->loadSettings( _this, "pressure" ); + m_motion->loadSettings( _this, "motion" ); + m_vibrato->loadSettings( _this, "vibrato" ); + m_velocity->loadSettings( _this, "velocity" ); + m_strike->loadSettings( _this, "strike" ); + + m_presets->loadSettings( _this, "preset" ); + m_spread->loadSettings( _this, "spread" ); +} + + + + +QString mallets::nodeName( void ) const +{ + return( malletsstk_plugin_descriptor.name ); +} + + + + +void mallets::playNote( notePlayHandle * _n ) +{ + int p = m_presets->value(); + + float freq = getInstrumentTrack()->frequency( _n ); + if ( _n->totalFramesPlayed() == 0 ) + { + float vel = static_cast( _n->getVolume() ) / 100.0f; + + if( p < 9 ) + { + _n->m_pluginData = new malletsSynth( + freq, + vel, + m_vibratoGain->value(), + m_hardness->value(), + m_position->value(), + m_stick->value(), + m_vibratoFreq->value(), + p, + (Uint8) m_spread->value(), + eng()->getMixer()->sampleRate() ); + } + else if( p == 9 ) + { + _n->m_pluginData = new malletsSynth( + freq, + vel, + p, + m_lfoDepth->value(), + m_modulator->value(), + m_crossfade->value(), + m_lfoSpeed->value(), + m_adsr->value(), + (Uint8) m_spread->value(), + eng()->getMixer()->sampleRate() ); + } + else + { + _n->m_pluginData = new malletsSynth( + freq, + vel, + m_pressure->value(), + m_motion->value(), + m_vibrato->value(), + p - 10, + m_strike->value() * 128.0, + m_velocity->value(), + (Uint8) m_spread->value(), + eng()->getMixer()->sampleRate() ); + } + } + + const Uint32 frames = eng()->getMixer()->framesPerAudioBuffer(); + + malletsSynth * ps = static_cast( _n->m_pluginData ); + sample_t add_scale = 0.0f; + if( p == 10 ) + { + add_scale = + static_cast( m_strike->value() ) * freq * 2.5f; + } + for( Uint32 frame = 0; frame < frames; ++frame ) + { + const sample_t left = ps->nextSampleLeft() * + ( m_scalers[m_presets->value()] + add_scale ); + const sample_t right = ps->nextSampleRight() * + ( m_scalers[m_presets->value()] + add_scale ); + for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS / 2; ++chnl ) + { + m_buffer[frame][chnl * DEFAULT_CHANNELS / 2] = left; + m_buffer[frame][( chnl + 1 ) * DEFAULT_CHANNELS / 2] = + right; + } + } + + getInstrumentTrack()->processAudioBuffer( m_buffer, frames, _n ); +} + + + + +void mallets::deleteNotePluginData( notePlayHandle * _n ) +{ + delete static_cast( _n->m_pluginData ); +} + + + + +void mallets::changePreset( int _preset ) +{ + if( _preset < 9 ) + { + m_tubeBellWidget->hide(); + m_bandedWGWidget->hide(); + m_modalBarWidget->show(); + } + else if( _preset == 9 ) + { + m_modalBarWidget->hide(); + m_bandedWGWidget->hide(); + m_tubeBellWidget->show(); + } + else + { + m_modalBarWidget->hide(); + m_tubeBellWidget->hide(); + m_bandedWGWidget->show(); + } +} + + + +// ModalBar +malletsSynth::malletsSynth( const StkFloat _pitch, + const StkFloat _velocity, + const StkFloat _control1, + const StkFloat _control2, + const StkFloat _control4, + const StkFloat _control8, + const StkFloat _control11, + const int _control16, + const Uint8 _delay, + const sample_rate_t _sample_rate ) +{ + try + { + Stk::setSampleRate( _sample_rate ); + Stk::setRawwavePath( configManager::inst()->stkDir() ); + + m_voice = new ModalBar(); + + m_voice->controlChange( 1, _control1 ); + m_voice->controlChange( 2, _control2 ); + m_voice->controlChange( 4, _control4 ); + m_voice->controlChange( 8, _control8 ); + m_voice->controlChange( 11, _control11 ); + m_voice->controlChange( 16, _control16 ); + m_voice->controlChange( 128, 128.0f ); + + m_voice->noteOn( _pitch, _velocity ); + } + catch( ... ) + { + m_voice = NULL; + } + + m_delay = bufferAllocator::alloc( 256 ); + m_delayRead = 0; + m_delayWrite = _delay; + for( Uint16 i = 0; i < 256; i++ ) + { + m_delay[i] = 0.0; + } +} + + + + +// TubeBell +malletsSynth::malletsSynth( const StkFloat _pitch, + const StkFloat _velocity, + const int _preset, + const StkFloat _control1, + const StkFloat _control2, + const StkFloat _control4, + const StkFloat _control11, + const StkFloat _control128, + const Uint8 _delay, + const sample_rate_t _sample_rate ) +{ + try + { + Stk::setSampleRate( _sample_rate ); + Stk::setRawwavePath( configManager::inst()->stkDir() ); + + m_voice = new TubeBell(); + + m_voice->controlChange( 1, _control1 ); + m_voice->controlChange( 2, _control2 ); + m_voice->controlChange( 4, _control4 ); + m_voice->controlChange( 11, _control11 ); + m_voice->controlChange( 128, _control128 ); + + m_voice->noteOn( _pitch, _velocity ); + } + catch( ... ) + { + m_voice = NULL; + } + + m_delay = bufferAllocator::alloc( 256 ); + m_delayRead = 0; + m_delayWrite = _delay; + for( Uint16 i = 0; i < 256; i++ ) + { + m_delay[i] = 0.0; + } +} + + + + +// BandedWG +malletsSynth::malletsSynth( const StkFloat _pitch, + const StkFloat _velocity, + const StkFloat _control2, + const StkFloat _control4, + const StkFloat _control11, + const int _control16, + const StkFloat _control64, + const StkFloat _control128, + const Uint8 _delay, + const sample_rate_t _sample_rate ) +{ + try + { + Stk::setSampleRate( _sample_rate ); + Stk::setRawwavePath( configManager::inst()->stkDir() ); + + m_voice = new BandedWG(); + + m_voice->controlChange( 1, 128.0 ); + m_voice->controlChange( 2, _control2 ); + m_voice->controlChange( 4, _control4 ); + m_voice->controlChange( 11, _control11 ); + m_voice->controlChange( 16, _control16 ); + m_voice->controlChange( 64, _control64 ); + m_voice->controlChange( 128, _control128 ); + + m_voice->noteOn( _pitch, _velocity ); + } + catch( ... ) + { + m_voice = NULL; + } + + m_delay = bufferAllocator::alloc( 256 ); + m_delayRead = 0; + m_delayWrite = _delay; + for( Uint16 i = 0; i < 256; i++ ) + { + m_delay[i] = 0.0; + } +} + + + + +extern "C" +{ + +// neccessary for getting instance out of shared lib +plugin * lmms_plugin_main( void * _data ) +{ + return( new mallets( static_cast( _data ) ) ); +} + + +} + + +#include "mallets.moc" + + diff --git a/plugins/stk/mallets/mallets.h b/plugins/stk/mallets/mallets.h new file mode 100644 index 000000000..a9586ef92 --- /dev/null +++ b/plugins/stk/mallets/mallets.h @@ -0,0 +1,180 @@ +/* + * mallets.h - tuned instruments that one would bang upon + * + * Copyright (c) 2006 Danny McRae + * + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef _MALLET_H +#define _MALLET_H + +#include "Instrmnt.h" + +#include "instrument.h" +#include "combobox.h" +#include "led_checkbox.h" +#include "track.h" +#include "buffer_allocator.h" + +class knob; +class notePlayHandle; + + +class malletsSynth +{ +public: + // ModalBar + malletsSynth( const StkFloat _pitch, + const StkFloat _velocity, + const StkFloat _control1, + const StkFloat _control2, + const StkFloat _control4, + const StkFloat _control8, + const StkFloat _control11, + const int _control16, + const Uint8 _delay, + const sample_rate_t _sample_rate ); + + // TubeBell + malletsSynth( const StkFloat _pitch, + const StkFloat _velocity, + const int _preset, + const StkFloat _control1, + const StkFloat _control2, + const StkFloat _control4, + const StkFloat _control11, + const StkFloat _control128, + const Uint8 _delay, + const sample_rate_t _sample_rate ); + + // BandedWG + malletsSynth( const StkFloat _pitch, + const StkFloat _velocity, + const StkFloat _control2, + const StkFloat _control4, + const StkFloat _control11, + const int _control16, + const StkFloat _control64, + const StkFloat _control128, + const Uint8 _delay, + const sample_rate_t _sample_rate ); + + inline ~malletsSynth( void ) + { + m_voice->noteOff( 0.0 ); + bufferAllocator::free( m_delay ); + delete m_voice; + } + + inline sample_t nextSampleLeft( void ) + { + if( m_voice == NULL ) + { + return( 0.0f ); + } + else + { + StkFloat s = m_voice->tick(); + m_delay[m_delayWrite] = s; + m_delayWrite++; + m_delayWrite %= 256; + return( s ); + } + } + + inline sample_t nextSampleRight( void ) + { + StkFloat s = m_delay[m_delayRead]; + m_delayRead++; + m_delayRead %= 256; + return( s ); + } + + +protected: + Instrmnt * m_voice; + + StkFloat * m_delay; + Uint8 m_delayRead; + Uint8 m_delayWrite; +}; + + + + +class mallets : public instrument +{ + Q_OBJECT +public: + mallets( instrumentTrack * _channel_track ); + virtual ~mallets(); + + 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; + +public slots: + void changePreset( int _preset ); + +private: + void setWidgetBackground( QWidget * _widget, const QString & _pic ); + QWidget * setupModalBarControls( QWidget * _parent, track * _track ); + QWidget * setupTubeBellControls( QWidget * _parent, track * _track ); + QWidget * setupBandedWGControls( QWidget * _parent, track * _track ); + comboBox * setupPresets( QWidget * _parent, track * _track ); + + QWidget * m_modalBarWidget; + knob * m_hardness; + knob * m_position; + knob * m_vibratoGain; + knob * m_vibratoFreq; + knob * m_stick; + + QWidget * m_tubeBellWidget; + knob * m_modulator; + knob * m_crossfade; + knob * m_lfoSpeed; + knob * m_lfoDepth; + knob * m_adsr; + + QWidget * m_bandedWGWidget; + knob * m_pressure; + knob * m_motion; + knob * m_vibrato; + knob * m_velocity; + ledCheckBox * m_strike; + + comboBox * m_presets; + knob * m_spread; + + vvector m_scalers; + sampleFrame * m_buffer; +}; + + +#endif diff --git a/src/core/config_mgr.cpp b/src/core/config_mgr.cpp index 924c6836c..6c9bfceac 100644 --- a/src/core/config_mgr.cpp +++ b/src/core/config_mgr.cpp @@ -576,6 +576,16 @@ void configManager::setLADSPADir( const QString & _fd ) +void configManager::setSTKDir( const QString & _fd ) +{ +#ifdef HAVE_STK_H + m_stkDir = _fd; +#endif +} + + + + void configManager::accept( void ) { if( m_workingDir.right( 1 ) != "/" ) @@ -848,6 +858,9 @@ bool configManager::loadConfigFile( void ) #ifdef LADSPA_SUPPORT m_ladDir = value( "paths", "laddir" ); #endif +#ifdef HAVE_STK_H + m_stkDir = value( "paths", "stkdir" ); +#endif if( m_vstDir == "" ) { @@ -861,9 +874,16 @@ bool configManager::loadConfigFile( void ) #ifdef LADSPA_SUPPORT if( m_ladDir == "" ) - { - m_ladDir = "/usr/lib/ladspa/:/usr/local/lib/ladspa/"; - } +{ + m_ladDir = "/usr/lib/ladspa/:/usr/local/lib/ladspa/"; +} +#endif + +#ifdef HAVE_STK_H + if( m_stkDir == "" ) +{ + m_stkDir = "/usr/share/stk/rawwaves/"; +} #endif if( root.isElement() ) @@ -915,6 +935,9 @@ void configManager::saveConfigFile( void ) #ifdef LADSPA_SUPPORT setValue( "paths", "laddir", m_ladDir ); #endif +#ifdef HAVE_STK_H + setValue( "paths", "stkdir", m_stkDir ); +#endif QDomDocument doc( "lmms-config-file" ); diff --git a/src/core/setup_dialog.cpp b/src/core/setup_dialog.cpp index 1dadd2c63..eea02ad3e 100644 --- a/src/core/setup_dialog.cpp +++ b/src/core/setup_dialog.cpp @@ -119,6 +119,9 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) : m_flDir( configManager::inst()->flDir() ), #ifdef LADSPA_SUPPORT m_ladDir( configManager::inst()->ladspaDir() ), +#endif +#ifdef HAVE_STK_H + m_stkDir( configManager::inst()->stkDir() ), #endif m_disableChActInd( configManager::inst()->value( "ui", "disablechannelactivityindicators" ).toInt() ), @@ -144,7 +147,11 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) : QWidget * ws = new QWidget( settings ); #ifdef LADSPA_SUPPORT +#ifdef HAVE_STK_H + ws->setFixedSize( 360, 412 ); +#else ws->setFixedSize( 360, 356 ); +#endif #else ws->setFixedSize( 360, 300 ); #endif @@ -263,7 +270,11 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) : QWidget * directories = new QWidget( ws ); #ifdef LADSPA_SUPPORT +#ifdef HAVE_STK_H + directories->setFixedSize( 360, 362 ); +#else directories->setFixedSize( 360, 316 ); +#endif #else directories->setFixedSize( 360, 260 ); #endif @@ -368,6 +379,26 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) : SLOT( openLADSPADir() ) ); #endif +#ifdef HAVE_STK_H + // STK-dir + tabWidget * stk_tw = new tabWidget( tr( + "STK rawwave directory" ).toUpper(), + directories ); + stk_tw->setFixedHeight( 56 ); + + m_stkLineEdit = new QLineEdit( m_stkDir, stk_tw ); + m_stkLineEdit->setGeometry( 10, 20, 300, 16 ); + connect( m_stkLineEdit, SIGNAL( textChanged( const QString & ) ), this, + SLOT( setSTKDir( const QString & ) ) ); + + QPushButton * stkdir_select_btn = new QPushButton( + embed::getIconPixmap( "project_open", 16, 16 ), + "", stk_tw ); + stkdir_select_btn->setFixedSize( 24, 24 ); + stkdir_select_btn->move( 320, 20 ); + connect( stkdir_select_btn, SIGNAL( clicked() ), this, + SLOT( openSTKDir() ) ); +#endif dir_layout->addWidget( lmms_wd_tw ); dir_layout->addSpacing( 10 ); @@ -380,6 +411,10 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) : dir_layout->addSpacing( 10 ); dir_layout->addWidget( lad_tw ); #endif +#ifdef HAVE_STK_H + dir_layout->addSpacing( 10 ); + dir_layout->addWidget( stk_tw ); +#endif dir_layout->addStretch(); @@ -694,6 +729,9 @@ void setupDialog::accept( void ) #ifdef LADSPA_SUPPORT configManager::inst()->setLADSPADir( m_ladDir ); #endif +#ifdef HAVE_STK_H + configManager::inst()->setSTKDir( m_stkDir ); +#endif // tell all audio-settings-widget to save their settings for( aswMap::iterator it = m_audioIfaceSetupWidgets.begin(); @@ -974,6 +1012,27 @@ void setupDialog::openLADSPADir( void ) +void setupDialog::openSTKDir( void ) +{ +#ifdef HAVE_STK_H +#ifdef QT4 + QString new_dir = QFileDialog::getExistingDirectory( this, + tr( "Choose STK rawwave directory" ), + m_ladDir ); +#else + QString new_dir = QFileDialog::getExistingDirectory( m_ladDir, 0, 0, + tr( "Choose STK rawwave directory" ), TRUE ); +#endif + if( new_dir != QString::null ) + { + m_stkLineEdit->setText( new_dir ); + } +#endif +} + + + + void setupDialog::setFLDir( const QString & _fd ) { m_flDir = _fd; @@ -992,6 +1051,16 @@ void setupDialog::setLADSPADir( const QString & _fd ) +void setupDialog::setSTKDir( const QString & _fd ) +{ +#ifdef HAVE_STK_H + m_stkDir = _fd; +#endif +} + + + + void setupDialog::audioInterfaceChanged( const QString & _iface ) { for( aswMap::iterator it = m_audioIfaceSetupWidgets.begin();