vibed.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. /*
  2. * vibed.cpp - combination of PluckedStringSynth and BitInvader
  3. *
  4. * Copyright (c) 2006-2008 Danny McRae <khjklujn/at/yahoo/com>
  5. *
  6. * This file is part of LMMS - https://lmms.io
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public
  19. * License along with this program (see COPYING); if not, write to the
  20. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA.
  22. *
  23. */
  24. #include <QDomDocument>
  25. #include <QMap>
  26. #include "vibed.h"
  27. #include "Engine.h"
  28. #include "InstrumentTrack.h"
  29. #include "Mixer.h"
  30. #include "NotePlayHandle.h"
  31. #include "ToolTip.h"
  32. #include "base64.h"
  33. #include "CaptionMenu.h"
  34. #include "Oscillator.h"
  35. #include "string_container.h"
  36. #include "volume.h"
  37. #include "Song.h"
  38. #include "embed.h"
  39. #include "plugin_export.h"
  40. extern "C"
  41. {
  42. Plugin::Descriptor PLUGIN_EXPORT vibedstrings_plugin_descriptor =
  43. {
  44. STRINGIFY( PLUGIN_NAME ),
  45. "Vibed",
  46. QT_TRANSLATE_NOOP( "pluginBrowser",
  47. "Vibrating string modeler" ),
  48. "Danny McRae <khjklujn/at/yahoo/com>",
  49. 0x0100,
  50. Plugin::Instrument,
  51. new PluginPixmapLoader( "logo" ),
  52. NULL,
  53. NULL
  54. };
  55. }
  56. vibed::vibed( InstrumentTrack * _instrumentTrack ) :
  57. Instrument( _instrumentTrack, &vibedstrings_plugin_descriptor )
  58. {
  59. FloatModel * knob;
  60. BoolModel * led;
  61. nineButtonSelectorModel * harmonic;
  62. graphModel * graphTmp;
  63. for( int harm = 0; harm < 9; harm++ )
  64. {
  65. knob = new FloatModel( DefaultVolume, MinVolume, MaxVolume,
  66. 1.0f, this, tr( "String %1 volume" ).arg( harm+1 ) );
  67. m_volumeKnobs.append( knob );
  68. knob = new FloatModel( 0.0f, 0.0f, 0.05f, 0.001f, this,
  69. tr( "String %1 stiffness" ).arg( harm+1 ) );
  70. m_stiffnessKnobs.append( knob );
  71. knob = new FloatModel( 0.0f, 0.0f, 0.05f, 0.005f, this,
  72. tr( "Pick %1 position" ).arg( harm+1 ) );
  73. m_pickKnobs.append( knob );
  74. knob = new FloatModel( 0.05f, 0.0f, 0.05f, 0.005f, this,
  75. tr( "Pickup %1 position" ).arg( harm+1 ) );
  76. m_pickupKnobs.append( knob );
  77. knob = new FloatModel( 0.0f, -1.0f, 1.0f, 0.01f, this,
  78. tr( "String %1 panning" ).arg( harm+1 ) );
  79. m_panKnobs.append( knob );
  80. knob = new FloatModel( 0.0f, -0.1f, 0.1f, 0.001f, this,
  81. tr( "String %1 detune" ).arg( harm+1 ) );
  82. m_detuneKnobs.append( knob );
  83. knob = new FloatModel( 0.0f, 0.0f, 0.75f, 0.01f, this,
  84. tr( "String %1 fuzziness" ).arg( harm+1 ) );
  85. m_randomKnobs.append( knob );
  86. knob = new FloatModel( 1, 1, 16, 1, this,
  87. tr( "String %1 length" ).arg( harm+1 ) );
  88. m_lengthKnobs.append( knob );
  89. led = new BoolModel( false, this,
  90. tr( "Impulse %1" ).arg( harm+1 ) );
  91. m_impulses.append( led );
  92. led = new BoolModel( harm==0, this,
  93. tr( "String %1" ).arg( harm+1 ) );
  94. m_powerButtons.append( led );
  95. harmonic = new nineButtonSelectorModel( 2, 0, 8, this );
  96. m_harmonics.append( harmonic );
  97. graphTmp = new graphModel( -1.0, 1.0, __sampleLength, this );
  98. graphTmp->setWaveToSine();
  99. m_graphs.append( graphTmp );
  100. }
  101. }
  102. vibed::~vibed()
  103. {
  104. }
  105. void vibed::saveSettings( QDomDocument & _doc, QDomElement & _this )
  106. {
  107. QString name;
  108. // Save plugin version
  109. _this.setAttribute( "version", "0.1" );
  110. for( int i = 0; i < 9; i++ )
  111. {
  112. name = "active" + QString::number( i );
  113. _this.setAttribute( name, QString::number(
  114. m_powerButtons[i]->value() ) );
  115. if( m_powerButtons[i]->value() )
  116. {
  117. name = "volume" + QString::number( i );
  118. m_volumeKnobs[i]->saveSettings( _doc, _this, name );
  119. name = "stiffness" + QString::number( i );
  120. m_stiffnessKnobs[i]->saveSettings( _doc, _this, name );
  121. name = "pick" + QString::number( i );
  122. m_pickKnobs[i]->saveSettings( _doc, _this, name );
  123. name = "pickup" + QString::number( i );
  124. m_pickupKnobs[i]->saveSettings( _doc, _this, name );
  125. name = "octave" + QString::number( i );
  126. m_harmonics[i]->saveSettings( _doc, _this, name );
  127. name = "length" + QString::number( i );
  128. m_lengthKnobs[i]->saveSettings( _doc, _this, name );
  129. name = "pan" + QString::number( i );
  130. m_panKnobs[i]->saveSettings( _doc, _this, name );
  131. name = "detune" + QString::number( i );
  132. m_detuneKnobs[i]->saveSettings( _doc, _this, name );
  133. name = "slap" + QString::number( i );
  134. m_randomKnobs[i]->saveSettings( _doc, _this, name );
  135. name = "impulse" + QString::number( i );
  136. m_impulses[i]->saveSettings( _doc, _this, name );
  137. QString sampleString;
  138. base64::encode(
  139. (const char *)m_graphs[i]->samples(),
  140. __sampleLength * sizeof(float),
  141. sampleString );
  142. name = "graph" + QString::number( i );
  143. _this.setAttribute( name, sampleString );
  144. }
  145. }
  146. }
  147. void vibed::loadSettings( const QDomElement & _this )
  148. {
  149. QString name;
  150. for( int i = 0; i < 9; i++ )
  151. {
  152. name = "active" + QString::number( i );
  153. m_powerButtons[i]->setValue( _this.attribute( name ).toInt() );
  154. if( m_powerButtons[i]->value() &&
  155. _this.hasAttribute( "volume" + QString::number( i ) ) )
  156. {
  157. name = "volume" + QString::number( i );
  158. m_volumeKnobs[i]->loadSettings( _this, name );
  159. name = "stiffness" + QString::number( i );
  160. m_stiffnessKnobs[i]->loadSettings( _this, name );
  161. name = "pick" + QString::number( i );
  162. m_pickKnobs[i]->loadSettings( _this, name );
  163. name = "pickup" + QString::number( i );
  164. m_pickupKnobs[i]->loadSettings( _this, name );
  165. name = "octave" + QString::number( i );
  166. m_harmonics[i]->loadSettings( _this, name );
  167. name = "length" + QString::number( i );
  168. m_lengthKnobs[i]->loadSettings( _this, name );
  169. name = "pan" + QString::number( i );
  170. m_panKnobs[i]->loadSettings( _this, name );
  171. name = "detune" + QString::number( i );
  172. m_detuneKnobs[i]->loadSettings( _this, name );
  173. name = "slap" + QString::number( i );
  174. m_randomKnobs[i]->loadSettings( _this, name );
  175. name = "impulse" + QString::number( i );
  176. m_impulses[i]->loadSettings( _this, name );
  177. int size = 0;
  178. float * shp = 0;
  179. base64::decode( _this.attribute( "graph" +
  180. QString::number( i ) ),
  181. &shp,
  182. &size );
  183. // TODO: check whether size == 128 * sizeof( float ),
  184. // otherwise me might and up in a segfault
  185. m_graphs[i]->setSamples( shp );
  186. delete[] shp;
  187. // TODO: do one of the following to avoid
  188. // "uninitialized" wave-shape-buttongroup
  189. // - activate random-wave-shape-button here
  190. // - make wave-shape-buttons simple toggle-buttons
  191. // instead of checkable buttons
  192. // - save and restore selected wave-shape-button
  193. }
  194. }
  195. // update();
  196. }
  197. QString vibed::nodeName() const
  198. {
  199. return( vibedstrings_plugin_descriptor.name );
  200. }
  201. void vibed::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer )
  202. {
  203. if ( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL )
  204. {
  205. _n->m_pluginData = new stringContainer( _n->frequency(),
  206. Engine::mixer()->processingSampleRate(),
  207. __sampleLength );
  208. for( int i = 0; i < 9; ++i )
  209. {
  210. if( m_powerButtons[i]->value() )
  211. {
  212. static_cast<stringContainer*>(
  213. _n->m_pluginData )->addString(
  214. m_harmonics[i]->value(),
  215. m_pickKnobs[i]->value(),
  216. m_pickupKnobs[i]->value(),
  217. m_graphs[i]->samples(),
  218. m_randomKnobs[i]->value(),
  219. m_stiffnessKnobs[i]->value(),
  220. m_detuneKnobs[i]->value(),
  221. static_cast<int>(
  222. m_lengthKnobs[i]->value() ),
  223. m_impulses[i]->value(),
  224. i );
  225. }
  226. }
  227. }
  228. const fpp_t frames = _n->framesLeftForCurrentPeriod();
  229. const f_cnt_t offset = _n->noteOffset();
  230. stringContainer * ps = static_cast<stringContainer *>(
  231. _n->m_pluginData );
  232. for( fpp_t i = offset; i < frames + offset; ++i )
  233. {
  234. _working_buffer[i][0] = 0.0f;
  235. _working_buffer[i][1] = 0.0f;
  236. int s = 0;
  237. for( int string = 0; string < 9; ++string )
  238. {
  239. if( ps->exists( string ) )
  240. {
  241. // pan: 0 -> left, 1 -> right
  242. const float pan = ( m_panKnobs[string]->value() + 1 ) / 2.0f;
  243. const sample_t sample = ps->getStringSample( s ) * m_volumeKnobs[string]->value() / 100.0f;
  244. _working_buffer[i][0] += ( 1.0f - pan ) * sample;
  245. _working_buffer[i][1] += pan * sample;
  246. s++;
  247. }
  248. }
  249. }
  250. instrumentTrack()->processAudioBuffer( _working_buffer, frames + offset, _n );
  251. }
  252. void vibed::deleteNotePluginData( NotePlayHandle * _n )
  253. {
  254. delete static_cast<stringContainer *>( _n->m_pluginData );
  255. }
  256. PluginView * vibed::instantiateView( QWidget * _parent )
  257. {
  258. return( new vibedView( this, _parent ) );
  259. }
  260. vibedView::vibedView( Instrument * _instrument,
  261. QWidget * _parent ) :
  262. InstrumentViewFixedSize( _instrument, _parent )
  263. {
  264. setAutoFillBackground( true );
  265. QPalette pal;
  266. pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap(
  267. "artwork" ) );
  268. setPalette( pal );
  269. m_volumeKnob = new Knob( knobBright_26, this );
  270. m_volumeKnob->setVolumeKnob( true );
  271. m_volumeKnob->move( 103, 142 );
  272. m_volumeKnob->setHintText( tr( "String volume:" ), "" );
  273. m_stiffnessKnob = new Knob( knobBright_26, this );
  274. m_stiffnessKnob->move( 129, 142 );
  275. m_stiffnessKnob->setHintText( tr( "String stiffness:" )
  276. , "" );
  277. m_pickKnob = new Knob( knobBright_26, this );
  278. m_pickKnob->move( 153, 142 );
  279. m_pickKnob->setHintText( tr( "Pick position:" ), "" );
  280. m_pickupKnob = new Knob( knobBright_26, this );
  281. m_pickupKnob->move( 177, 142 );
  282. m_pickupKnob->setHintText( tr( "Pickup position:" )
  283. , "" );
  284. m_panKnob = new Knob( knobBright_26, this );
  285. m_panKnob->move( 105, 187 );
  286. m_panKnob->setHintText( tr( "String panning:" ), "" );
  287. m_detuneKnob = new Knob( knobBright_26, this );
  288. m_detuneKnob->move( 150, 187 );
  289. m_detuneKnob->setHintText( tr( "String detune:" ), "" );
  290. m_randomKnob = new Knob( knobBright_26, this );
  291. m_randomKnob->move( 194, 187 );
  292. m_randomKnob->setHintText( tr( "String fuzziness:" )
  293. , "" );
  294. m_lengthKnob = new Knob( knobBright_26, this );
  295. m_lengthKnob->move( 23, 193 );
  296. m_lengthKnob->setHintText( tr( "String length:" )
  297. , "" );
  298. m_impulse = new LedCheckBox( "", this );
  299. m_impulse->move( 23, 94 );
  300. ToolTip::add( m_impulse,
  301. tr( "Impulse" ) );
  302. m_harmonic = new nineButtonSelector(
  303. PLUGIN_NAME::getIconPixmap( "button_-2_on" ),
  304. PLUGIN_NAME::getIconPixmap( "button_-2_off" ),
  305. PLUGIN_NAME::getIconPixmap( "button_-1_on" ),
  306. PLUGIN_NAME::getIconPixmap( "button_-1_off" ),
  307. PLUGIN_NAME::getIconPixmap( "button_f_on" ),
  308. PLUGIN_NAME::getIconPixmap( "button_f_off" ),
  309. PLUGIN_NAME::getIconPixmap( "button_2_on" ),
  310. PLUGIN_NAME::getIconPixmap( "button_2_off" ),
  311. PLUGIN_NAME::getIconPixmap( "button_3_on" ),
  312. PLUGIN_NAME::getIconPixmap( "button_3_off" ),
  313. PLUGIN_NAME::getIconPixmap( "button_4_on" ),
  314. PLUGIN_NAME::getIconPixmap( "button_4_off" ),
  315. PLUGIN_NAME::getIconPixmap( "button_5_on" ),
  316. PLUGIN_NAME::getIconPixmap( "button_5_off" ),
  317. PLUGIN_NAME::getIconPixmap( "button_6_on" ),
  318. PLUGIN_NAME::getIconPixmap( "button_6_off" ),
  319. PLUGIN_NAME::getIconPixmap( "button_7_on" ),
  320. PLUGIN_NAME::getIconPixmap( "button_7_off" ),
  321. 2,
  322. 21, 127,
  323. this );
  324. m_harmonic->setWindowTitle( tr( "Octave" ) );
  325. m_stringSelector = new nineButtonSelector(
  326. PLUGIN_NAME::getIconPixmap( "button_1_on" ),
  327. PLUGIN_NAME::getIconPixmap( "button_1_off" ),
  328. PLUGIN_NAME::getIconPixmap( "button_2_on" ),
  329. PLUGIN_NAME::getIconPixmap( "button_2_off" ),
  330. PLUGIN_NAME::getIconPixmap( "button_3_on" ),
  331. PLUGIN_NAME::getIconPixmap( "button_3_off" ),
  332. PLUGIN_NAME::getIconPixmap( "button_4_on" ),
  333. PLUGIN_NAME::getIconPixmap( "button_4_off" ),
  334. PLUGIN_NAME::getIconPixmap( "button_5_on" ),
  335. PLUGIN_NAME::getIconPixmap( "button_5_off" ),
  336. PLUGIN_NAME::getIconPixmap( "button_6_on" ),
  337. PLUGIN_NAME::getIconPixmap( "button_6_off" ),
  338. PLUGIN_NAME::getIconPixmap( "button_7_on" ),
  339. PLUGIN_NAME::getIconPixmap( "button_7_off" ),
  340. PLUGIN_NAME::getIconPixmap( "button_8_on" ),
  341. PLUGIN_NAME::getIconPixmap( "button_8_off" ),
  342. PLUGIN_NAME::getIconPixmap( "button_9_on" ),
  343. PLUGIN_NAME::getIconPixmap( "button_9_off" ),
  344. 0,
  345. 21, 39,
  346. this);
  347. m_graph = new Graph( this );
  348. m_graph->setWindowTitle( tr( "Impulse Editor" ) );
  349. m_graph->setForeground( PLUGIN_NAME::getIconPixmap( "wavegraph4" ) );
  350. m_graph->move( 76, 21 );
  351. m_graph->resize(132, 104);
  352. m_power = new LedCheckBox( "", this, tr( "Enable waveform" ) );
  353. m_power->move( 212, 130 );
  354. ToolTip::add( m_power,
  355. tr( "Enable/disable string" ) );
  356. // String selector is not a part of the model
  357. m_stringSelector->setWindowTitle( tr( "String" ) );
  358. connect( m_stringSelector, SIGNAL( nineButtonSelection( int ) ),
  359. this, SLOT( showString( int ) ) );
  360. showString( 0 );
  361. m_sinWaveBtn = new PixmapButton( this, tr( "Sine wave" ) );
  362. m_sinWaveBtn->move( 212, 24 );
  363. m_sinWaveBtn->setActiveGraphic( embed::getIconPixmap(
  364. "sin_wave_active" ) );
  365. m_sinWaveBtn->setInactiveGraphic( embed::getIconPixmap(
  366. "sin_wave_inactive" ) );
  367. ToolTip::add( m_sinWaveBtn,
  368. tr( "Sine wave" ) );
  369. connect( m_sinWaveBtn, SIGNAL (clicked () ),
  370. this, SLOT ( sinWaveClicked() ) );
  371. m_triangleWaveBtn = new PixmapButton( this, tr( "Triangle wave" ) );
  372. m_triangleWaveBtn->move( 212, 41 );
  373. m_triangleWaveBtn->setActiveGraphic(
  374. embed::getIconPixmap( "triangle_wave_active" ) );
  375. m_triangleWaveBtn->setInactiveGraphic(
  376. embed::getIconPixmap( "triangle_wave_inactive" ) );
  377. ToolTip::add( m_triangleWaveBtn,
  378. tr( "Triangle wave" ) );
  379. connect( m_triangleWaveBtn, SIGNAL ( clicked () ),
  380. this, SLOT ( triangleWaveClicked( ) ) );
  381. m_sawWaveBtn = new PixmapButton( this, tr( "Saw wave" ) );
  382. m_sawWaveBtn->move( 212, 58 );
  383. m_sawWaveBtn->setActiveGraphic( embed::getIconPixmap(
  384. "saw_wave_active" ) );
  385. m_sawWaveBtn->setInactiveGraphic( embed::getIconPixmap(
  386. "saw_wave_inactive" ) );
  387. ToolTip::add( m_sawWaveBtn,
  388. tr( "Saw wave" ) );
  389. connect( m_sawWaveBtn, SIGNAL (clicked () ),
  390. this, SLOT ( sawWaveClicked() ) );
  391. m_sqrWaveBtn = new PixmapButton( this, tr( "Square wave" ) );
  392. m_sqrWaveBtn->move( 212, 75 );
  393. m_sqrWaveBtn->setActiveGraphic( embed::getIconPixmap(
  394. "square_wave_active" ) );
  395. m_sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
  396. "square_wave_inactive" ) );
  397. ToolTip::add( m_sqrWaveBtn,
  398. tr( "Square wave" ) );
  399. connect( m_sqrWaveBtn, SIGNAL ( clicked () ),
  400. this, SLOT ( sqrWaveClicked() ) );
  401. m_whiteNoiseWaveBtn = new PixmapButton( this, tr( "White noise" ) );
  402. m_whiteNoiseWaveBtn->move( 212, 92 );
  403. m_whiteNoiseWaveBtn->setActiveGraphic(
  404. embed::getIconPixmap( "white_noise_wave_active" ) );
  405. m_whiteNoiseWaveBtn->setInactiveGraphic(
  406. embed::getIconPixmap( "white_noise_wave_inactive" ) );
  407. ToolTip::add( m_whiteNoiseWaveBtn,
  408. tr( "White noise" ) );
  409. connect( m_whiteNoiseWaveBtn, SIGNAL ( clicked () ),
  410. this, SLOT ( noiseWaveClicked() ) );
  411. m_usrWaveBtn = new PixmapButton( this, tr( "User-defined wave" ) );
  412. m_usrWaveBtn->move( 212, 109 );
  413. m_usrWaveBtn->setActiveGraphic( embed::getIconPixmap(
  414. "usr_wave_active" ) );
  415. m_usrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
  416. "usr_wave_inactive" ) );
  417. ToolTip::add( m_usrWaveBtn,
  418. tr( "User-defined wave" ) );
  419. connect( m_usrWaveBtn, SIGNAL ( clicked () ),
  420. this, SLOT ( usrWaveClicked() ) );
  421. m_smoothBtn = new PixmapButton( this, tr( "Smooth waveform" ) );
  422. m_smoothBtn->move( 79, 129 );
  423. m_smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
  424. "smooth_active" ) );
  425. m_smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
  426. "smooth_inactive" ) );
  427. m_smoothBtn->setChecked( false );
  428. ToolTip::add( m_smoothBtn,
  429. tr( "Smooth waveform" ) );
  430. connect( m_smoothBtn, SIGNAL ( clicked () ),
  431. this, SLOT ( smoothClicked() ) );
  432. m_normalizeBtn = new PixmapButton( this, tr( "Normalize waveform" ) );
  433. m_normalizeBtn->move( 96, 129 );
  434. m_normalizeBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
  435. "normalize_active" ) );
  436. m_normalizeBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
  437. "normalize_inactive" ) );
  438. m_normalizeBtn->setChecked( false );
  439. ToolTip::add( m_normalizeBtn,
  440. tr( "Normalize waveform" ) );
  441. connect( m_normalizeBtn, SIGNAL ( clicked () ),
  442. this, SLOT ( normalizeClicked() ) );
  443. }
  444. void vibedView::modelChanged()
  445. {
  446. showString( 0 );
  447. }
  448. void vibedView::showString( int _string )
  449. {
  450. vibed * v = castModel<vibed>();
  451. m_pickKnob->setModel( v->m_pickKnobs[_string] );
  452. m_pickupKnob->setModel( v->m_pickupKnobs[_string] );
  453. m_stiffnessKnob->setModel( v->m_stiffnessKnobs[_string] );
  454. m_volumeKnob->setModel( v->m_volumeKnobs[_string] );
  455. m_panKnob->setModel( v->m_panKnobs[_string] );
  456. m_detuneKnob->setModel( v->m_detuneKnobs[_string] );
  457. m_randomKnob->setModel( v->m_randomKnobs[_string] );
  458. m_lengthKnob->setModel( v->m_lengthKnobs[_string] );
  459. m_graph->setModel( v->m_graphs[_string] );
  460. m_impulse->setModel( v->m_impulses[_string] );
  461. m_harmonic->setModel( v->m_harmonics[_string] );
  462. m_power->setModel( v->m_powerButtons[_string] );
  463. }
  464. void vibedView::sinWaveClicked()
  465. {
  466. m_graph->model()->setWaveToSine();
  467. Engine::getSong()->setModified();
  468. }
  469. void vibedView::triangleWaveClicked()
  470. {
  471. m_graph->model()->setWaveToTriangle();
  472. Engine::getSong()->setModified();
  473. }
  474. void vibedView::sawWaveClicked()
  475. {
  476. m_graph->model()->setWaveToSaw();
  477. Engine::getSong()->setModified();
  478. }
  479. void vibedView::sqrWaveClicked()
  480. {
  481. m_graph->model()->setWaveToSquare();
  482. Engine::getSong()->setModified();
  483. }
  484. void vibedView::noiseWaveClicked()
  485. {
  486. m_graph->model()->setWaveToNoise();
  487. Engine::getSong()->setModified();
  488. }
  489. void vibedView::usrWaveClicked()
  490. {
  491. QString fileName = m_graph->model()->setWaveToUser();
  492. ToolTip::add( m_usrWaveBtn, fileName );
  493. Engine::getSong()->setModified();
  494. }
  495. void vibedView::smoothClicked()
  496. {
  497. m_graph->model()->smooth();
  498. Engine::getSong()->setModified();
  499. }
  500. void vibedView::normalizeClicked()
  501. {
  502. m_graph->model()->normalize();
  503. Engine::getSong()->setModified();
  504. }
  505. void vibedView::contextMenuEvent( QContextMenuEvent * )
  506. {
  507. CaptionMenu contextMenu( model()->displayName(), this );
  508. contextMenu.exec( QCursor::pos() );
  509. }
  510. extern "C"
  511. {
  512. // necessary for getting instance out of shared lib
  513. PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
  514. {
  515. return( new vibed( static_cast<InstrumentTrack *>( m ) ) );
  516. }
  517. }