sf2_player.cpp 31 KB

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