sf2_player.cpp 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172
  1. /*
  2. * sf2_player.cpp - a soundfont2 player using fluidSynth
  3. *
  4. * Copyright (c) 2008 Paul Giblock <drfaygo/at/gmail/dot/com>
  5. * Copyright (c) 2009-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
  6. *
  7. * This file is part of LMMS - https://lmms.io
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2 of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public
  20. * License along with this program (see COPYING); if not, write to the
  21. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  22. * Boston, MA 02110-1301 USA.
  23. *
  24. */
  25. #include <QDebug>
  26. #include <QLayout>
  27. #include <QLabel>
  28. #include <QDomDocument>
  29. #include "ConfigManager.h"
  30. #include "FileDialog.h"
  31. #include "sf2_player.h"
  32. #include "Engine.h"
  33. #include "InstrumentTrack.h"
  34. #include "InstrumentPlayHandle.h"
  35. #include "Mixer.h"
  36. #include "NotePlayHandle.h"
  37. #include "Knob.h"
  38. #include "SampleBuffer.h"
  39. #include "Song.h"
  40. #include "patches_dialog.h"
  41. #include "ToolTip.h"
  42. #include "LcdSpinBox.h"
  43. #include "embed.cpp"
  44. extern "C"
  45. {
  46. Plugin::Descriptor PLUGIN_EXPORT sf2player_plugin_descriptor =
  47. {
  48. STRINGIFY( PLUGIN_NAME ),
  49. "Sf2 Player",
  50. QT_TRANSLATE_NOOP( "pluginBrowser", "Player for SoundFont files" ),
  51. "Paul Giblock <drfaygo/at/gmail/dot/com>",
  52. 0x0100,
  53. Plugin::Instrument,
  54. new PluginPixmapLoader( "logo" ),
  55. "sf2",
  56. NULL
  57. } ;
  58. }
  59. struct SF2PluginData
  60. {
  61. int midiNote;
  62. int lastPanning;
  63. float lastVelocity;
  64. fluid_voice_t * fluidVoice;
  65. bool isNew;
  66. f_cnt_t offset;
  67. bool noteOffSent;
  68. } ;
  69. // Static map of current sfonts
  70. QMap<QString, sf2Font*> sf2Instrument::s_fonts;
  71. QMutex sf2Instrument::s_fontsMutex;
  72. sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) :
  73. Instrument( _instrument_track, &sf2player_plugin_descriptor ),
  74. m_srcState( NULL ),
  75. m_font( NULL ),
  76. m_fontId( 0 ),
  77. m_filename( "" ),
  78. m_lastMidiPitch( -1 ),
  79. m_lastMidiPitchRange( -1 ),
  80. m_channel( 1 ),
  81. m_bankNum( 0, 0, 999, this, tr("Bank") ),
  82. m_patchNum( 0, 0, 127, this, tr("Patch") ),
  83. m_gain( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Gain" ) ),
  84. m_reverbOn( false, this, tr( "Reverb" ) ),
  85. m_reverbRoomSize( FLUID_REVERB_DEFAULT_ROOMSIZE, 0, 1.0, 0.01f, this, tr( "Reverb Roomsize" ) ),
  86. m_reverbDamping( FLUID_REVERB_DEFAULT_DAMP, 0, 1.0, 0.01, this, tr( "Reverb Damping" ) ),
  87. m_reverbWidth( FLUID_REVERB_DEFAULT_WIDTH, 0, 1.0, 0.01f, this, tr( "Reverb Width" ) ),
  88. m_reverbLevel( FLUID_REVERB_DEFAULT_LEVEL, 0, 1.0, 0.01f, this, tr( "Reverb Level" ) ),
  89. m_chorusOn( false, this, tr( "Chorus" ) ),
  90. m_chorusNum( FLUID_CHORUS_DEFAULT_N, 0, 10.0, 1.0, this, tr( "Chorus Lines" ) ),
  91. m_chorusLevel( FLUID_CHORUS_DEFAULT_LEVEL, 0, 10.0, 0.01, this, tr( "Chorus Level" ) ),
  92. m_chorusSpeed( FLUID_CHORUS_DEFAULT_SPEED, 0.29, 5.0, 0.01, this, tr( "Chorus Speed" ) ),
  93. m_chorusDepth( FLUID_CHORUS_DEFAULT_DEPTH, 0, 46.0, 0.05, this, tr( "Chorus Depth" ) )
  94. {
  95. for( int i = 0; i < 128; ++i )
  96. {
  97. m_notesRunning[i] = 0;
  98. }
  99. #if QT_VERSION_CHECK(FLUIDSYNTH_VERSION_MAJOR, FLUIDSYNTH_VERSION_MINOR, FLUIDSYNTH_VERSION_MICRO) >= QT_VERSION_CHECK(1,1,9)
  100. // Deactivate all audio drivers in fluidsynth
  101. const char *none[] = { NULL };
  102. fluid_audio_driver_register( none );
  103. #endif
  104. m_settings = new_fluid_settings();
  105. //fluid_settings_setint( m_settings, (char *) "audio.period-size", engine::mixer()->framesPerPeriod() );
  106. // This is just our starting instance of synth. It is recreated
  107. // everytime we load a new soundfont.
  108. m_synth = new_fluid_synth( m_settings );
  109. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  110. // Get the default values from the setting
  111. double settingVal;
  112. fluid_settings_getnum_default(m_settings, "synth.reverb.room-size", &settingVal);
  113. m_reverbRoomSize.setInitValue(settingVal);
  114. fluid_settings_getnum_default(m_settings, "synth.reverb.damping", &settingVal);
  115. m_reverbDamping.setInitValue(settingVal);
  116. fluid_settings_getnum_default(m_settings, "synth.reverb.width", &settingVal);
  117. m_reverbWidth.setInitValue(settingVal);
  118. fluid_settings_getnum_default(m_settings, "synth.reverb.level", &settingVal);
  119. m_reverbLevel.setInitValue(settingVal);
  120. fluid_settings_getnum_default(m_settings, "synth.chorus.nr", &settingVal);
  121. m_chorusNum.setInitValue(settingVal);
  122. fluid_settings_getnum_default(m_settings, "synth.chorus.level", &settingVal);
  123. m_chorusLevel.setInitValue(settingVal);
  124. fluid_settings_getnum_default(m_settings, "synth.chorus.speed", &settingVal);
  125. m_chorusSpeed.setInitValue(settingVal);
  126. fluid_settings_getnum_default(m_settings, "synth.chorus.depth", &settingVal);
  127. m_chorusDepth.setInitValue(settingVal);
  128. #endif
  129. loadFile( ConfigManager::inst()->defaultSoundfont() );
  130. updateSampleRate();
  131. updateReverbOn();
  132. updateReverb();
  133. updateChorusOn();
  134. updateChorus();
  135. updateGain();
  136. connect( &m_bankNum, SIGNAL( dataChanged() ), this, SLOT( updatePatch() ) );
  137. connect( &m_patchNum, SIGNAL( dataChanged() ), this, SLOT( updatePatch() ) );
  138. connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateSampleRate() ) );
  139. // Gain
  140. connect( &m_gain, SIGNAL( dataChanged() ), this, SLOT( updateGain() ) );
  141. // Reverb
  142. connect( &m_reverbOn, SIGNAL( dataChanged() ), this, SLOT( updateReverbOn() ) );
  143. connect( &m_reverbRoomSize, SIGNAL( dataChanged() ), this, SLOT( updateReverb() ) );
  144. connect( &m_reverbDamping, SIGNAL( dataChanged() ), this, SLOT( updateReverb() ) );
  145. connect( &m_reverbWidth, SIGNAL( dataChanged() ), this, SLOT( updateReverb() ) );
  146. connect( &m_reverbLevel, SIGNAL( dataChanged() ), this, SLOT( updateReverb() ) );
  147. // Chorus
  148. connect( &m_chorusOn, SIGNAL( dataChanged() ), this, SLOT( updateChorusOn() ) );
  149. connect( &m_chorusNum, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
  150. connect( &m_chorusLevel, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
  151. connect( &m_chorusSpeed, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
  152. connect( &m_chorusDepth, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
  153. InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrument_track );
  154. Engine::mixer()->addPlayHandle( iph );
  155. }
  156. sf2Instrument::~sf2Instrument()
  157. {
  158. Engine::mixer()->removePlayHandlesOfTypes( instrumentTrack(),
  159. PlayHandle::TypeNotePlayHandle
  160. | PlayHandle::TypeInstrumentPlayHandle );
  161. freeFont();
  162. delete_fluid_synth( m_synth );
  163. delete_fluid_settings( m_settings );
  164. if( m_srcState != NULL )
  165. {
  166. src_delete( m_srcState );
  167. }
  168. }
  169. void sf2Instrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
  170. {
  171. _this.setAttribute( "src", m_filename );
  172. m_patchNum.saveSettings( _doc, _this, "patch" );
  173. m_bankNum.saveSettings( _doc, _this, "bank" );
  174. m_gain.saveSettings( _doc, _this, "gain" );
  175. m_reverbOn.saveSettings( _doc, _this, "reverbOn" );
  176. m_reverbRoomSize.saveSettings( _doc, _this, "reverbRoomSize" );
  177. m_reverbDamping.saveSettings( _doc, _this, "reverbDamping" );
  178. m_reverbWidth.saveSettings( _doc, _this, "reverbWidth" );
  179. m_reverbLevel.saveSettings( _doc, _this, "reverbLevel" );
  180. m_chorusOn.saveSettings( _doc, _this, "chorusOn" );
  181. m_chorusNum.saveSettings( _doc, _this, "chorusNum" );
  182. m_chorusLevel.saveSettings( _doc, _this, "chorusLevel" );
  183. m_chorusSpeed.saveSettings( _doc, _this, "chorusSpeed" );
  184. m_chorusDepth.saveSettings( _doc, _this, "chorusDepth" );
  185. }
  186. void sf2Instrument::loadSettings( const QDomElement & _this )
  187. {
  188. openFile( _this.attribute( "src" ), false );
  189. m_patchNum.loadSettings( _this, "patch" );
  190. m_bankNum.loadSettings( _this, "bank" );
  191. m_gain.loadSettings( _this, "gain" );
  192. m_reverbOn.loadSettings( _this, "reverbOn" );
  193. m_reverbRoomSize.loadSettings( _this, "reverbRoomSize" );
  194. m_reverbDamping.loadSettings( _this, "reverbDamping" );
  195. m_reverbWidth.loadSettings( _this, "reverbWidth" );
  196. m_reverbLevel.loadSettings( _this, "reverbLevel" );
  197. m_chorusOn.loadSettings( _this, "chorusOn" );
  198. m_chorusNum.loadSettings( _this, "chorusNum" );
  199. m_chorusLevel.loadSettings( _this, "chorusLevel" );
  200. m_chorusSpeed.loadSettings( _this, "chorusSpeed" );
  201. m_chorusDepth.loadSettings( _this, "chorusDepth" );
  202. updatePatch();
  203. updateGain();
  204. }
  205. void sf2Instrument::loadFile( const QString & _file )
  206. {
  207. if( !_file.isEmpty() && QFileInfo( _file ).exists() )
  208. {
  209. openFile( _file, false );
  210. updatePatch();
  211. // for some reason we've to call that, otherwise preview of a
  212. // soundfont for the first time fails
  213. updateSampleRate();
  214. }
  215. }
  216. AutomatableModel * sf2Instrument::childModel( const QString & _modelName )
  217. {
  218. if( _modelName == "bank" )
  219. {
  220. return &m_bankNum;
  221. }
  222. else if( _modelName == "patch" )
  223. {
  224. return &m_patchNum;
  225. }
  226. qCritical() << "requested unknown model " << _modelName;
  227. return NULL;
  228. }
  229. QString sf2Instrument::nodeName() const
  230. {
  231. return sf2player_plugin_descriptor.name;
  232. }
  233. void sf2Instrument::freeFont()
  234. {
  235. m_synthMutex.lock();
  236. if ( m_font != NULL )
  237. {
  238. s_fontsMutex.lock();
  239. --(m_font->refCount);
  240. // No more references
  241. if( m_font->refCount <= 0 )
  242. {
  243. qDebug() << "Really deleting " << m_filename;
  244. fluid_synth_sfunload( m_synth, m_fontId, true );
  245. s_fonts.remove( m_filename );
  246. delete m_font;
  247. }
  248. // Just remove our reference
  249. else
  250. {
  251. qDebug() << "un-referencing " << m_filename;
  252. fluid_synth_remove_sfont( m_synth, m_font->fluidFont );
  253. }
  254. s_fontsMutex.unlock();
  255. m_font = NULL;
  256. }
  257. m_synthMutex.unlock();
  258. }
  259. void sf2Instrument::openFile( const QString & _sf2File, bool updateTrackName )
  260. {
  261. emit fileLoading();
  262. // Used for loading file
  263. char * sf2Ascii = qstrdup( qPrintable( SampleBuffer::tryToMakeAbsolute( _sf2File ) ) );
  264. QString relativePath = SampleBuffer::tryToMakeRelative( _sf2File );
  265. // free reference to soundfont if one is selected
  266. freeFont();
  267. m_synthMutex.lock();
  268. s_fontsMutex.lock();
  269. // Increment Reference
  270. if( s_fonts.contains( relativePath ) )
  271. {
  272. qDebug() << "Using existing reference to " << relativePath;
  273. m_font = s_fonts[ relativePath ];
  274. m_font->refCount++;
  275. m_fontId = fluid_synth_add_sfont( m_synth, m_font->fluidFont );
  276. }
  277. // Add to map, if doesn't exist.
  278. else
  279. {
  280. m_fontId = fluid_synth_sfload( m_synth, sf2Ascii, true );
  281. if( fluid_synth_sfcount( m_synth ) > 0 )
  282. {
  283. // Grab this sf from the top of the stack and add to list
  284. m_font = new sf2Font( fluid_synth_get_sfont( m_synth, 0 ) );
  285. s_fonts.insert( relativePath, m_font );
  286. }
  287. else
  288. {
  289. collectErrorForUI( sf2Instrument::tr( "A soundfont %1 could not be loaded." ).arg( QFileInfo( _sf2File ).baseName() ) );
  290. // TODO: Why is the filename missing when the file does not exist?
  291. }
  292. }
  293. s_fontsMutex.unlock();
  294. m_synthMutex.unlock();
  295. if( m_fontId >= 0 )
  296. {
  297. // Don't reset patch/bank, so that it isn't cleared when
  298. // someone resolves a missing file
  299. //m_patchNum.setValue( 0 );
  300. //m_bankNum.setValue( 0 );
  301. m_filename = relativePath;
  302. emit fileChanged();
  303. }
  304. delete[] sf2Ascii;
  305. if( updateTrackName || instrumentTrack()->displayName() == displayName() )
  306. {
  307. instrumentTrack()->setName( QFileInfo( _sf2File ).baseName() );
  308. }
  309. }
  310. void sf2Instrument::updatePatch()
  311. {
  312. if( m_bankNum.value() >= 0 && m_patchNum.value() >= 0 )
  313. {
  314. fluid_synth_program_select( m_synth, m_channel, m_fontId,
  315. m_bankNum.value(), m_patchNum.value() );
  316. }
  317. }
  318. QString sf2Instrument::getCurrentPatchName()
  319. {
  320. int iBankSelected = m_bankNum.value();
  321. int iProgSelected = m_patchNum.value();
  322. // For all soundfonts (in reversed stack order) fill the available programs...
  323. int cSoundFonts = ::fluid_synth_sfcount( m_synth );
  324. for( int i = 0; i < cSoundFonts; i++ )
  325. {
  326. fluid_sfont_t *pSoundFont = fluid_synth_get_sfont( m_synth, i );
  327. if ( pSoundFont )
  328. {
  329. #ifdef CONFIG_FLUID_BANK_OFFSET
  330. int iBankOffset =
  331. fluid_synth_get_bank_offset(
  332. m_synth, fluid_sfont_get_id(pSoundFont) );
  333. #endif
  334. fluid_sfont_iteration_start( pSoundFont );
  335. #if FLUIDSYNTH_VERSION_MAJOR < 2
  336. fluid_preset_t preset;
  337. fluid_preset_t *pCurPreset = &preset;
  338. #else
  339. fluid_preset_t *pCurPreset;
  340. #endif
  341. while ((pCurPreset = fluid_sfont_iteration_next_wrapper(pSoundFont, pCurPreset)))
  342. {
  343. int iBank = fluid_preset_get_banknum( pCurPreset );
  344. #ifdef CONFIG_FLUID_BANK_OFFSET
  345. iBank += iBankOffset;
  346. #endif
  347. int iProg = fluid_preset_get_num( pCurPreset );
  348. if( iBank == iBankSelected && iProg ==
  349. iProgSelected )
  350. {
  351. return fluid_preset_get_name( pCurPreset );
  352. }
  353. }
  354. }
  355. }
  356. return "";
  357. }
  358. void sf2Instrument::updateGain()
  359. {
  360. fluid_synth_set_gain( m_synth, m_gain.value() );
  361. }
  362. void sf2Instrument::updateReverbOn()
  363. {
  364. fluid_synth_set_reverb_on( m_synth, m_reverbOn.value() ? 1 : 0 );
  365. }
  366. void sf2Instrument::updateReverb()
  367. {
  368. fluid_synth_set_reverb( m_synth, m_reverbRoomSize.value(),
  369. m_reverbDamping.value(), m_reverbWidth.value(),
  370. m_reverbLevel.value() );
  371. }
  372. void sf2Instrument::updateChorusOn()
  373. {
  374. fluid_synth_set_chorus_on( m_synth, m_chorusOn.value() ? 1 : 0 );
  375. }
  376. void sf2Instrument::updateChorus()
  377. {
  378. fluid_synth_set_chorus( m_synth, static_cast<int>( m_chorusNum.value() ),
  379. m_chorusLevel.value(), m_chorusSpeed.value(),
  380. m_chorusDepth.value(), 0 );
  381. }
  382. void sf2Instrument::updateSampleRate()
  383. {
  384. double tempRate;
  385. // Set & get, returns the true sample rate
  386. fluid_settings_setnum( m_settings, (char *) "synth.sample-rate", Engine::mixer()->processingSampleRate() );
  387. fluid_settings_getnum( m_settings, (char *) "synth.sample-rate", &tempRate );
  388. m_internalSampleRate = static_cast<int>( tempRate );
  389. if( m_font )
  390. {
  391. // Now, delete the old one and replace
  392. m_synthMutex.lock();
  393. fluid_synth_remove_sfont( m_synth, m_font->fluidFont );
  394. delete_fluid_synth( m_synth );
  395. // New synth
  396. m_synth = new_fluid_synth( m_settings );
  397. m_fontId = fluid_synth_add_sfont( m_synth, m_font->fluidFont );
  398. m_synthMutex.unlock();
  399. // synth program change (set bank and patch)
  400. updatePatch();
  401. }
  402. else
  403. {
  404. // Recreate synth with no soundfonts
  405. m_synthMutex.lock();
  406. delete_fluid_synth( m_synth );
  407. m_synth = new_fluid_synth( m_settings );
  408. m_synthMutex.unlock();
  409. }
  410. m_synthMutex.lock();
  411. if( Engine::mixer()->currentQualitySettings().interpolation >=
  412. Mixer::qualitySettings::Interpolation_SincFastest )
  413. {
  414. fluid_synth_set_interp_method( m_synth, -1, FLUID_INTERP_7THORDER );
  415. }
  416. else
  417. {
  418. fluid_synth_set_interp_method( m_synth, -1, FLUID_INTERP_DEFAULT );
  419. }
  420. m_synthMutex.unlock();
  421. if( m_internalSampleRate < Engine::mixer()->processingSampleRate() )
  422. {
  423. m_synthMutex.lock();
  424. if( m_srcState != NULL )
  425. {
  426. src_delete( m_srcState );
  427. }
  428. int error;
  429. m_srcState = src_new( Engine::mixer()->currentQualitySettings().libsrcInterpolation(), DEFAULT_CHANNELS, &error );
  430. if( m_srcState == NULL || error )
  431. {
  432. qCritical( "error while creating libsamplerate data structure in Sf2Instrument::updateSampleRate()" );
  433. }
  434. m_synthMutex.unlock();
  435. }
  436. updateReverb();
  437. updateChorus();
  438. updateReverbOn();
  439. updateChorusOn();
  440. updateGain();
  441. // Reset last MIDI pitch properties, which will be set to the correct values
  442. // upon playing the next note
  443. m_lastMidiPitch = -1;
  444. m_lastMidiPitchRange = -1;
  445. }
  446. void sf2Instrument::playNote( NotePlayHandle * _n, sampleFrame * )
  447. {
  448. if( _n->isMasterNote() || ( _n->hasParent() && _n->isReleased() ) )
  449. {
  450. return;
  451. }
  452. const f_cnt_t tfp = _n->totalFramesPlayed();
  453. if( tfp == 0 )
  454. {
  455. const float LOG440 = 2.643452676f;
  456. int midiNote = (int)floor( 12.0 * ( log2( _n->unpitchedFrequency() ) - LOG440 ) - 4.0 );
  457. // out of range?
  458. if( midiNote <= 0 || midiNote >= 128 )
  459. {
  460. return;
  461. }
  462. const int baseVelocity = instrumentTrack()->midiPort()->baseVelocity();
  463. SF2PluginData * pluginData = new SF2PluginData;
  464. pluginData->midiNote = midiNote;
  465. pluginData->lastPanning = 0;
  466. pluginData->lastVelocity = _n->midiVelocity( baseVelocity );
  467. pluginData->fluidVoice = NULL;
  468. pluginData->isNew = true;
  469. pluginData->offset = _n->offset();
  470. pluginData->noteOffSent = false;
  471. _n->m_pluginData = pluginData;
  472. // insert the nph to the playing notes vector
  473. m_playingNotesMutex.lock();
  474. m_playingNotes.append( _n );
  475. m_playingNotesMutex.unlock();
  476. }
  477. else if( _n->isReleased() && ! _n->instrumentTrack()->isSustainPedalPressed() ) // note is released during this period
  478. {
  479. SF2PluginData * pluginData = static_cast<SF2PluginData *>( _n->m_pluginData );
  480. pluginData->offset = _n->framesBeforeRelease();
  481. pluginData->isNew = false;
  482. m_playingNotesMutex.lock();
  483. m_playingNotes.append( _n );
  484. m_playingNotesMutex.unlock();
  485. }
  486. }
  487. void sf2Instrument::noteOn( SF2PluginData * n )
  488. {
  489. m_synthMutex.lock();
  490. // get list of current voice IDs so we can easily spot the new
  491. // voice after the fluid_synth_noteon() call
  492. const int poly = fluid_synth_get_polyphony( m_synth );
  493. fluid_voice_t * voices[poly];
  494. unsigned int id[poly];
  495. fluid_synth_get_voicelist( m_synth, voices, poly, -1 );
  496. for( int i = 0; i < poly; ++i )
  497. {
  498. id[i] = 0;
  499. }
  500. for( int i = 0; i < poly && voices[i]; ++i )
  501. {
  502. id[i] = fluid_voice_get_id( voices[i] );
  503. }
  504. fluid_synth_noteon( m_synth, m_channel, n->midiNote, n->lastVelocity );
  505. // get new voice and save it
  506. fluid_synth_get_voicelist( m_synth, voices, poly, -1 );
  507. for( int i = 0; i < poly && voices[i]; ++i )
  508. {
  509. const unsigned int newID = fluid_voice_get_id( voices[i] );
  510. if( id[i] != newID || newID == 0 )
  511. {
  512. n->fluidVoice = voices[i];
  513. break;
  514. }
  515. }
  516. m_synthMutex.unlock();
  517. m_notesRunningMutex.lock();
  518. ++m_notesRunning[ n->midiNote ];
  519. m_notesRunningMutex.unlock();
  520. }
  521. void sf2Instrument::noteOff( SF2PluginData * n )
  522. {
  523. n->noteOffSent = true;
  524. m_notesRunningMutex.lock();
  525. const int notes = --m_notesRunning[n->midiNote];
  526. m_notesRunningMutex.unlock();
  527. if( notes <= 0 )
  528. {
  529. m_synthMutex.lock();
  530. fluid_synth_noteoff( m_synth, m_channel, n->midiNote );
  531. m_synthMutex.unlock();
  532. }
  533. }
  534. void sf2Instrument::play( sampleFrame * _working_buffer )
  535. {
  536. const fpp_t frames = Engine::mixer()->framesPerPeriod();
  537. // set midi pitch for this period
  538. const int currentMidiPitch = instrumentTrack()->midiPitch();
  539. if( m_lastMidiPitch != currentMidiPitch )
  540. {
  541. m_lastMidiPitch = currentMidiPitch;
  542. m_synthMutex.lock();
  543. fluid_synth_pitch_bend( m_synth, m_channel, m_lastMidiPitch );
  544. m_synthMutex.unlock();
  545. }
  546. const int currentMidiPitchRange = instrumentTrack()->midiPitchRange();
  547. if( m_lastMidiPitchRange != currentMidiPitchRange )
  548. {
  549. m_lastMidiPitchRange = currentMidiPitchRange;
  550. m_synthMutex.lock();
  551. fluid_synth_pitch_wheel_sens( m_synth, m_channel, m_lastMidiPitchRange );
  552. m_synthMutex.unlock();
  553. }
  554. // if we have no new noteons/noteoffs, just render a period and call it a day
  555. if( m_playingNotes.isEmpty() )
  556. {
  557. renderFrames( frames, _working_buffer );
  558. instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL );
  559. return;
  560. }
  561. // processing loop
  562. // go through noteplayhandles in processing order
  563. f_cnt_t currentFrame = 0;
  564. while( ! m_playingNotes.isEmpty() )
  565. {
  566. // find the note with lowest offset
  567. NotePlayHandle * currentNote = m_playingNotes[0];
  568. for( int i = 1; i < m_playingNotes.size(); ++i )
  569. {
  570. SF2PluginData * currentData = static_cast<SF2PluginData *>( currentNote->m_pluginData );
  571. SF2PluginData * iData = static_cast<SF2PluginData *>( m_playingNotes[i]->m_pluginData );
  572. if( currentData->offset > iData->offset )
  573. {
  574. currentNote = m_playingNotes[i];
  575. }
  576. }
  577. // process the current note:
  578. // first see if we're synced in frame count
  579. SF2PluginData * currentData = static_cast<SF2PluginData *>( currentNote->m_pluginData );
  580. if( currentData->offset > currentFrame )
  581. {
  582. renderFrames( currentData->offset - currentFrame, _working_buffer + currentFrame );
  583. currentFrame = currentData->offset;
  584. }
  585. if( currentData->isNew )
  586. {
  587. noteOn( currentData );
  588. if( currentNote->isReleased() ) // if the note is released during the same period, we have to process it again for noteoff
  589. {
  590. currentData->isNew = false;
  591. currentData->offset = currentNote->framesBeforeRelease();
  592. }
  593. else // otherwise remove the handle
  594. {
  595. m_playingNotesMutex.lock();
  596. m_playingNotes.remove( m_playingNotes.indexOf( currentNote ) );
  597. m_playingNotesMutex.unlock();
  598. }
  599. }
  600. else
  601. {
  602. noteOff( currentData );
  603. m_playingNotesMutex.lock();
  604. m_playingNotes.remove( m_playingNotes.indexOf( currentNote ) );
  605. m_playingNotesMutex.unlock();
  606. }
  607. }
  608. if( currentFrame < frames )
  609. {
  610. renderFrames( frames - currentFrame, _working_buffer + currentFrame );
  611. }
  612. instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL );
  613. }
  614. void sf2Instrument::renderFrames( f_cnt_t frames, sampleFrame * buf )
  615. {
  616. m_synthMutex.lock();
  617. if( m_internalSampleRate < Engine::mixer()->processingSampleRate() &&
  618. m_srcState != NULL )
  619. {
  620. const fpp_t f = frames * m_internalSampleRate / Engine::mixer()->processingSampleRate();
  621. #ifdef __GNUC__
  622. sampleFrame tmp[f];
  623. #else
  624. sampleFrame * tmp = new sampleFrame[f];
  625. #endif
  626. fluid_synth_write_float( m_synth, f, tmp, 0, 2, tmp, 1, 2 );
  627. SRC_DATA src_data;
  628. src_data.data_in = (float *)tmp;
  629. src_data.data_out = (float *)buf;
  630. src_data.input_frames = f;
  631. src_data.output_frames = frames;
  632. src_data.src_ratio = (double) frames / f;
  633. src_data.end_of_input = 0;
  634. int error = src_process( m_srcState, &src_data );
  635. #ifndef __GNUC__
  636. delete[] tmp;
  637. #endif
  638. if( error )
  639. {
  640. qCritical( "sf2Instrument: error while resampling: %s", src_strerror( error ) );
  641. }
  642. if( src_data.output_frames_gen > frames )
  643. {
  644. qCritical( "sf2Instrument: not enough frames: %ld / %d", src_data.output_frames_gen, frames );
  645. }
  646. }
  647. else
  648. {
  649. fluid_synth_write_float( m_synth, frames, buf, 0, 2, buf, 1, 2 );
  650. }
  651. m_synthMutex.unlock();
  652. }
  653. void sf2Instrument::deleteNotePluginData( NotePlayHandle * _n )
  654. {
  655. SF2PluginData * pluginData = static_cast<SF2PluginData *>( _n->m_pluginData );
  656. if( ! pluginData->noteOffSent ) // if we for some reason haven't noteoffed the note before it gets deleted,
  657. // do it here
  658. {
  659. noteOff( pluginData );
  660. m_playingNotesMutex.lock();
  661. if( m_playingNotes.indexOf( _n ) >= 0 )
  662. {
  663. m_playingNotes.remove( m_playingNotes.indexOf( _n ) );
  664. }
  665. m_playingNotesMutex.unlock();
  666. }
  667. delete pluginData;
  668. }
  669. PluginView * sf2Instrument::instantiateView( QWidget * _parent )
  670. {
  671. return new sf2InstrumentView( this, _parent );
  672. }
  673. class sf2Knob : public Knob
  674. {
  675. public:
  676. sf2Knob( QWidget * _parent ) :
  677. Knob( knobStyled, _parent )
  678. {
  679. setFixedSize( 31, 38 );
  680. }
  681. };
  682. sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _parent ) :
  683. InstrumentView( _instrument, _parent )
  684. {
  685. // QVBoxLayout * vl = new QVBoxLayout( this );
  686. // QHBoxLayout * hl = new QHBoxLayout();
  687. sf2Instrument* k = castModel<sf2Instrument>();
  688. connect( &k->m_bankNum, SIGNAL( dataChanged() ), this, SLOT( updatePatchName() ) );
  689. connect( &k->m_patchNum, SIGNAL( dataChanged() ), this, SLOT( updatePatchName() ) );
  690. // File Button
  691. m_fileDialogButton = new PixmapButton( this );
  692. m_fileDialogButton->setCursor( QCursor( Qt::PointingHandCursor ) );
  693. m_fileDialogButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileselect_on" ) );
  694. m_fileDialogButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileselect_off" ) );
  695. m_fileDialogButton->move( 217, 107 );
  696. connect( m_fileDialogButton, SIGNAL( clicked() ), this, SLOT( showFileDialog() ) );
  697. ToolTip::add( m_fileDialogButton, tr( "Open other SoundFont file" ) );
  698. m_fileDialogButton->setWhatsThis( tr( "Click here to open another SF2 file" ) );
  699. // Patch Button
  700. m_patchDialogButton = new PixmapButton( this );
  701. m_patchDialogButton->setCursor( QCursor( Qt::PointingHandCursor ) );
  702. m_patchDialogButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "patches_on" ) );
  703. m_patchDialogButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "patches_off" ) );
  704. m_patchDialogButton->setEnabled( false );
  705. m_patchDialogButton->move( 217, 125 );
  706. connect( m_patchDialogButton, SIGNAL( clicked() ), this, SLOT( showPatchDialog() ) );
  707. ToolTip::add( m_patchDialogButton, tr( "Choose the patch" ) );
  708. // LCDs
  709. m_bankNumLcd = new LcdSpinBox( 3, "21pink", this );
  710. m_bankNumLcd->move(131, 62);
  711. // m_bankNumLcd->addTextForValue( -1, "---" );
  712. // m_bankNumLcd->setEnabled( false );
  713. m_patchNumLcd = new LcdSpinBox( 3, "21pink", this );
  714. m_patchNumLcd->move(190, 62);
  715. // m_patchNumLcd->addTextForValue( -1, "---" );
  716. // m_patchNumLcd->setEnabled( false );
  717. /*hl->addWidget( m_fileDialogButton );
  718. hl->addWidget( m_bankNumLcd );
  719. hl->addWidget( m_patchNumLcd );
  720. hl->addWidget( m_patchDialogButton );
  721. vl->addLayout( hl );*/
  722. // Next row
  723. //hl = new QHBoxLayout();
  724. m_filenameLabel = new QLabel( this );
  725. m_filenameLabel->setGeometry( 58, 109, 156, 11 );
  726. m_patchLabel = new QLabel( this );
  727. m_patchLabel->setGeometry( 58, 127, 156, 11 );
  728. //hl->addWidget( m_filenameLabel );
  729. // vl->addLayout( hl );
  730. // Gain
  731. m_gainKnob = new sf2Knob( this );
  732. m_gainKnob->setHintText( tr("Gain"), "" );
  733. m_gainKnob->move( 86, 55 );
  734. // vl->addWidget( m_gainKnob );
  735. // Reverb
  736. // hl = new QHBoxLayout();
  737. m_reverbButton = new PixmapButton( this );
  738. m_reverbButton->setCheckable( true );
  739. m_reverbButton->move( 14, 180 );
  740. m_reverbButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "reverb_on" ) );
  741. m_reverbButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "reverb_off" ) );
  742. ToolTip::add( m_reverbButton, tr( "Apply reverb (if supported)" ) );
  743. m_reverbButton->setWhatsThis(
  744. tr( "This button enables the reverb effect. "
  745. "This is useful for cool effects, but only works on "
  746. "files that support it." ) );
  747. m_reverbRoomSizeKnob = new sf2Knob( this );
  748. m_reverbRoomSizeKnob->setHintText( tr("Reverb Roomsize:"), "" );
  749. m_reverbRoomSizeKnob->move( 93, 160 );
  750. m_reverbDampingKnob = new sf2Knob( this );
  751. m_reverbDampingKnob->setHintText( tr("Reverb Damping:"), "" );
  752. m_reverbDampingKnob->move( 130, 160 );
  753. m_reverbWidthKnob = new sf2Knob( this );
  754. m_reverbWidthKnob->setHintText( tr("Reverb Width:"), "" );
  755. m_reverbWidthKnob->move( 167, 160 );
  756. m_reverbLevelKnob = new sf2Knob( this );
  757. m_reverbLevelKnob->setHintText( tr("Reverb Level:"), "" );
  758. m_reverbLevelKnob->move( 204, 160 );
  759. /* hl->addWidget( m_reverbOnLed );
  760. hl->addWidget( m_reverbRoomSizeKnob );
  761. hl->addWidget( m_reverbDampingKnob );
  762. hl->addWidget( m_reverbWidthKnob );
  763. hl->addWidget( m_reverbLevelKnob );
  764. vl->addLayout( hl );
  765. */
  766. // Chorus
  767. // hl = new QHBoxLayout();
  768. m_chorusButton = new PixmapButton( this );
  769. m_chorusButton->setCheckable( true );
  770. m_chorusButton->move( 14, 226 );
  771. m_chorusButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "chorus_on" ) );
  772. m_chorusButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "chorus_off" ) );
  773. ToolTip::add( m_chorusButton, tr( "Apply chorus (if supported)" ) );
  774. m_chorusButton->setWhatsThis(
  775. tr( "This button enables the chorus effect. "
  776. "This is useful for cool echo effects, but only works on "
  777. "files that support it." ) );
  778. m_chorusNumKnob = new sf2Knob( this );
  779. m_chorusNumKnob->setHintText( tr("Chorus Lines:"), "" );
  780. m_chorusNumKnob->move( 93, 206 );
  781. m_chorusLevelKnob = new sf2Knob( this );
  782. m_chorusLevelKnob->setHintText( tr("Chorus Level:"), "" );
  783. m_chorusLevelKnob->move( 130 , 206 );
  784. m_chorusSpeedKnob = new sf2Knob( this );
  785. m_chorusSpeedKnob->setHintText( tr("Chorus Speed:"), "" );
  786. m_chorusSpeedKnob->move( 167 , 206 );
  787. m_chorusDepthKnob = new sf2Knob( this );
  788. m_chorusDepthKnob->setHintText( tr("Chorus Depth:"), "" );
  789. m_chorusDepthKnob->move( 204 , 206 );
  790. /*
  791. hl->addWidget( m_chorusOnLed );
  792. hl->addWidget( m_chorusNumKnob);
  793. hl->addWidget( m_chorusLevelKnob);
  794. hl->addWidget( m_chorusSpeedKnob);
  795. hl->addWidget( m_chorusDepthKnob);
  796. vl->addLayout( hl );
  797. */
  798. setAutoFillBackground( true );
  799. QPalette pal;
  800. pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
  801. setPalette( pal );
  802. updateFilename();
  803. }
  804. sf2InstrumentView::~sf2InstrumentView()
  805. {
  806. }
  807. void sf2InstrumentView::modelChanged()
  808. {
  809. sf2Instrument * k = castModel<sf2Instrument>();
  810. m_bankNumLcd->setModel( &k->m_bankNum );
  811. m_patchNumLcd->setModel( &k->m_patchNum );
  812. m_gainKnob->setModel( &k->m_gain );
  813. m_reverbButton->setModel( &k->m_reverbOn );
  814. m_reverbRoomSizeKnob->setModel( &k->m_reverbRoomSize );
  815. m_reverbDampingKnob->setModel( &k->m_reverbDamping );
  816. m_reverbWidthKnob->setModel( &k->m_reverbWidth );
  817. m_reverbLevelKnob->setModel( &k->m_reverbLevel );
  818. m_chorusButton->setModel( &k->m_chorusOn );
  819. m_chorusNumKnob->setModel( &k->m_chorusNum );
  820. m_chorusLevelKnob->setModel( &k->m_chorusLevel );
  821. m_chorusSpeedKnob->setModel( &k->m_chorusSpeed );
  822. m_chorusDepthKnob->setModel( &k->m_chorusDepth );
  823. connect( k, SIGNAL( fileChanged() ), this, SLOT( updateFilename() ) );
  824. connect( k, SIGNAL( fileLoading() ), this, SLOT( invalidateFile() ) );
  825. updateFilename();
  826. }
  827. void sf2InstrumentView::updateFilename()
  828. {
  829. sf2Instrument * i = castModel<sf2Instrument>();
  830. QFontMetrics fm( m_filenameLabel->font() );
  831. QString file = i->m_filename.endsWith( ".sf2", Qt::CaseInsensitive ) ?
  832. i->m_filename.left( i->m_filename.length() - 4 ) :
  833. i->m_filename;
  834. m_filenameLabel->setText( fm.elidedText( file, Qt::ElideLeft, m_filenameLabel->width() ) );
  835. // i->m_filename + "\nPatch: TODO" );
  836. m_patchDialogButton->setEnabled( !i->m_filename.isEmpty() );
  837. updatePatchName();
  838. update();
  839. }
  840. void sf2InstrumentView::updatePatchName()
  841. {
  842. sf2Instrument * i = castModel<sf2Instrument>();
  843. QFontMetrics fm( font() );
  844. QString patch = i->getCurrentPatchName();
  845. m_patchLabel->setText( fm.elidedText( patch, Qt::ElideLeft, m_patchLabel->width() ) );
  846. update();
  847. }
  848. void sf2InstrumentView::invalidateFile()
  849. {
  850. m_patchDialogButton->setEnabled( false );
  851. }
  852. void sf2InstrumentView::showFileDialog()
  853. {
  854. sf2Instrument * k = castModel<sf2Instrument>();
  855. FileDialog ofd( NULL, tr( "Open SoundFont file" ) );
  856. ofd.setFileMode( FileDialog::ExistingFiles );
  857. QStringList types;
  858. types << tr( "SoundFont2 Files (*.sf2)" );
  859. ofd.setNameFilters( types );
  860. if( k->m_filename != "" )
  861. {
  862. QString f = SampleBuffer::tryToMakeAbsolute( k->m_filename );
  863. ofd.setDirectory( QFileInfo( f ).absolutePath() );
  864. ofd.selectFile( QFileInfo( f ).fileName() );
  865. }
  866. else
  867. {
  868. ofd.setDirectory( ConfigManager::inst()->sf2Dir() );
  869. }
  870. m_fileDialogButton->setEnabled( false );
  871. if( ofd.exec() == QDialog::Accepted && !ofd.selectedFiles().isEmpty() )
  872. {
  873. QString f = ofd.selectedFiles()[0];
  874. if( f != "" )
  875. {
  876. k->openFile( f );
  877. Engine::getSong()->setModified();
  878. }
  879. }
  880. m_fileDialogButton->setEnabled( true );
  881. }
  882. void sf2InstrumentView::showPatchDialog()
  883. {
  884. sf2Instrument * k = castModel<sf2Instrument>();
  885. patchesDialog pd( this );
  886. pd.setup( k->m_synth, 1, k->instrumentTrack()->name(), &k->m_bankNum, &k->m_patchNum, m_patchLabel );
  887. pd.exec();
  888. }
  889. extern "C"
  890. {
  891. // necessary for getting instance out of shared lib
  892. Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data )
  893. {
  894. return new sf2Instrument( static_cast<InstrumentTrack *>( _data ) );
  895. }
  896. }