opl2instrument.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. /*
  2. * OPL2 FM synth
  3. *
  4. * Copyright (c) 2014 Raine M. Ekman <raine/at/iki/fi>
  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. // TODO:
  25. // - Better voice allocation: long releases get cut short :(
  26. // - RT safety = get rid of mutex = make emulator code thread-safe
  27. // - Extras:
  28. // - double release: first release is in effect until noteoff (heard if percussive sound),
  29. // second is switched in just before key bit cleared (is this useful???)
  30. // - Unison: 2,3,4, or 9 voices with configurable spread?
  31. // - Portamento (needs mono mode?)
  32. // - Pre-bend/post-bend in poly mode could use portamento speed?
  33. #include "opl2instrument.h"
  34. #include "mididata.h"
  35. #include "debug.h"
  36. #include "Instrument.h"
  37. #include "Engine.h"
  38. #include "InstrumentPlayHandle.h"
  39. #include "InstrumentTrack.h"
  40. #include "Mixer.h"
  41. #include <QDomDocument>
  42. #include <QFile>
  43. #include <QFileInfo>
  44. #include <QByteArray>
  45. #include "opl.h"
  46. #include "temuopl.h"
  47. #include "embed.cpp"
  48. #include "math.h"
  49. #include "debug.h"
  50. #include "Knob.h"
  51. #include "LcdSpinBox.h"
  52. #include "PixmapButton.h"
  53. #include "ToolTip.h"
  54. extern "C"
  55. {
  56. Plugin::Descriptor PLUGIN_EXPORT OPL2_plugin_descriptor =
  57. {
  58. STRINGIFY( PLUGIN_NAME ),
  59. "OpulenZ",
  60. QT_TRANSLATE_NOOP( "pluginBrowser",
  61. "2-operator FM Synth" ),
  62. "Raine M. Ekman <raine/at/iki/fi>",
  63. 0x0100,
  64. Plugin::Instrument,
  65. new PluginPixmapLoader( "logo" ),
  66. "sbi",
  67. NULL
  68. };
  69. // necessary for getting instance out of shared lib
  70. Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data )
  71. {
  72. return( new opl2instrument( static_cast<InstrumentTrack *>( _data ) ) );
  73. }
  74. }
  75. // I'd much rather do without a mutex, but it looks like
  76. // the emulator code isn't really ready for threads
  77. QMutex opl2instrument::emulatorMutex;
  78. // Weird ordering of voice parameters
  79. const unsigned int adlib_opadd[OPL2_VOICES] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12};
  80. opl2instrument::opl2instrument( InstrumentTrack * _instrument_track ) :
  81. Instrument( _instrument_track, &OPL2_plugin_descriptor ),
  82. m_patchModel( 0, 0, 127, this, tr( "Patch" ) ),
  83. op1_a_mdl(14.0, 0.0, 15.0, 1.0, this, tr( "Op 1 Attack" ) ),
  84. op1_d_mdl(14.0, 0.0, 15.0, 1.0, this, tr( "Op 1 Decay" ) ),
  85. op1_s_mdl(3.0, 0.0, 15.0, 1.0, this, tr( "Op 1 Sustain" ) ),
  86. op1_r_mdl(10.0, 0.0, 15.0, 1.0, this, tr( "Op 1 Release" ) ),
  87. op1_lvl_mdl(62.0, 0.0, 63.0, 1.0, this, tr( "Op 1 Level" ) ),
  88. op1_scale_mdl(0.0, 0.0, 3.0, 1.0, this, tr( "Op 1 Level Scaling" ) ),
  89. op1_mul_mdl(0.0, 0.0, 15.0, 1.0, this, tr( "Op 1 Frequency Multiple" ) ),
  90. feedback_mdl(0.0, 0.0, 7.0, 1.0, this, tr( "Op 1 Feedback" ) ),
  91. op1_ksr_mdl(false, this, tr( "Op 1 Key Scaling Rate" ) ),
  92. op1_perc_mdl(false, this, tr( "Op 1 Percussive Envelope" ) ),
  93. op1_trem_mdl(true, this, tr( "Op 1 Tremolo" ) ),
  94. op1_vib_mdl(false, this, tr( "Op 1 Vibrato" ) ),
  95. op1_w0_mdl( ),
  96. op1_w1_mdl( ),
  97. op1_w2_mdl( ),
  98. op1_w3_mdl( ),
  99. op1_waveform_mdl(0,0,3,this, tr( "Op 1 Waveform" ) ),
  100. op2_a_mdl(1.0, 0.0, 15.0, 1.0, this, tr( "Op 2 Attack" ) ),
  101. op2_d_mdl(3.0, 0.0, 15.0, 1.0, this, tr( "Op 2 Decay" ) ),
  102. op2_s_mdl(14.0, 0.0, 15.0, 1.0, this, tr( "Op 2 Sustain" ) ),
  103. op2_r_mdl(12.0, 0.0, 15.0, 1.0, this, tr( "Op 2 Release" ) ),
  104. op2_lvl_mdl(63.0, 0.0, 63.0, 1.0, this, tr( "Op 2 Level" ) ),
  105. op2_scale_mdl(0.0, 0.0, 3.0, 1.0, this, tr( "Op 2 Level Scaling" ) ),
  106. op2_mul_mdl(1.0, 0.0, 15.0, 1.0, this, tr( "Op 2 Frequency Multiple" ) ),
  107. op2_ksr_mdl(false, this, tr( "Op 2 Key Scaling Rate" ) ),
  108. op2_perc_mdl(false, this, tr( "Op 2 Percussive Envelope" ) ),
  109. op2_trem_mdl(false, this, tr( "Op 2 Tremolo" ) ),
  110. op2_vib_mdl(true, this, tr( "Op 2 Vibrato" ) ),
  111. op2_w0_mdl( ),
  112. op2_w1_mdl( ),
  113. op2_w2_mdl( ),
  114. op2_w3_mdl( ),
  115. op2_waveform_mdl(0,0,3,this, tr( "Op 2 Waveform" ) ),
  116. fm_mdl(true, this, tr( "FM" ) ),
  117. vib_depth_mdl(false, this, tr( "Vibrato Depth" ) ),
  118. trem_depth_mdl(false, this, tr( "Tremolo Depth" ) )
  119. {
  120. // Create an emulator - samplerate, 16 bit, mono
  121. emulatorMutex.lock();
  122. theEmulator = new CTemuopl(Engine::mixer()->processingSampleRate(), true, false);
  123. theEmulator->init();
  124. // Enable waveform selection
  125. theEmulator->write(0x01,0x20);
  126. emulatorMutex.unlock();
  127. //Initialize voice values
  128. // voiceNote[0] = 0;
  129. // voiceLRU[0] = 0;
  130. for(int i=0; i<OPL2_VOICES; ++i) {
  131. voiceNote[i] = OPL2_VOICE_FREE;
  132. voiceLRU[i] = i;
  133. }
  134. storedname = displayName();
  135. updatePatch();
  136. // Can the buffer size change suddenly? I bet that would break lots of stuff
  137. frameCount = Engine::mixer()->framesPerPeriod();
  138. renderbuffer = new short[frameCount];
  139. // Some kind of sane defaults
  140. pitchbend = 0;
  141. pitchBendRange = 100; // cents
  142. RPNcoarse = RPNfine = 255;
  143. tuneEqual(69, 440);
  144. connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
  145. this, SLOT( reloadEmulator() ) );
  146. // Connect knobs
  147. // This one's for testing...
  148. connect( &m_patchModel, SIGNAL( dataChanged() ), this, SLOT( loadGMPatch() ) );
  149. #define MOD_CON( model ) connect( &model, SIGNAL( dataChanged() ), this, SLOT( updatePatch() ) );
  150. MOD_CON( op1_a_mdl );
  151. MOD_CON( op1_d_mdl );
  152. MOD_CON( op1_s_mdl );
  153. MOD_CON( op1_r_mdl );
  154. MOD_CON( op1_lvl_mdl );
  155. MOD_CON( op1_scale_mdl );
  156. MOD_CON( op1_mul_mdl );
  157. MOD_CON( feedback_mdl );
  158. MOD_CON( op1_ksr_mdl );
  159. MOD_CON( op1_perc_mdl );
  160. MOD_CON( op1_trem_mdl );
  161. MOD_CON( op1_vib_mdl );
  162. MOD_CON( op1_w0_mdl );
  163. MOD_CON( op1_w1_mdl );
  164. MOD_CON( op1_w2_mdl );
  165. MOD_CON( op1_w3_mdl );
  166. MOD_CON( op1_waveform_mdl );
  167. MOD_CON( op2_a_mdl );
  168. MOD_CON( op2_d_mdl );
  169. MOD_CON( op2_s_mdl );
  170. MOD_CON( op2_r_mdl );
  171. MOD_CON( op2_lvl_mdl );
  172. MOD_CON( op2_scale_mdl );
  173. MOD_CON( op2_mul_mdl );
  174. MOD_CON( op2_ksr_mdl );
  175. MOD_CON( op2_perc_mdl );
  176. MOD_CON( op2_trem_mdl );
  177. MOD_CON( op2_vib_mdl );
  178. MOD_CON( op2_w0_mdl );
  179. MOD_CON( op2_w1_mdl );
  180. MOD_CON( op2_w2_mdl );
  181. MOD_CON( op2_w3_mdl );
  182. MOD_CON( op2_waveform_mdl );
  183. MOD_CON( fm_mdl );
  184. MOD_CON( vib_depth_mdl );
  185. MOD_CON( trem_depth_mdl );
  186. // Connect the plugin to the mixer...
  187. InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrument_track );
  188. Engine::mixer()->addPlayHandle( iph );
  189. }
  190. opl2instrument::~opl2instrument() {
  191. delete theEmulator;
  192. Engine::mixer()->removePlayHandlesOfTypes( instrumentTrack(),
  193. PlayHandle::TypeNotePlayHandle
  194. | PlayHandle::TypeInstrumentPlayHandle );
  195. delete [] renderbuffer;
  196. }
  197. // Samplerate changes when choosing oversampling, so this is more or less mandatory
  198. void opl2instrument::reloadEmulator() {
  199. delete theEmulator;
  200. emulatorMutex.lock();
  201. theEmulator = new CTemuopl(Engine::mixer()->processingSampleRate(), true, false);
  202. theEmulator->init();
  203. theEmulator->write(0x01,0x20);
  204. emulatorMutex.unlock();
  205. for(int i=0; i<OPL2_VOICES; ++i) {
  206. voiceNote[i] = OPL2_VOICE_FREE;
  207. voiceLRU[i] = i;
  208. }
  209. updatePatch();
  210. }
  211. // This shall only be called from code protected by the holy Mutex!
  212. void opl2instrument::setVoiceVelocity(int voice, int vel) {
  213. int vel_adjusted;
  214. // Velocity calculation, some kind of approximation
  215. // Only calculate for operator 1 if in adding mode, don't want to change timbre
  216. if( fm_mdl.value() == false ) {
  217. vel_adjusted = 63 - ( op1_lvl_mdl.value() * vel/127.0) ;
  218. } else {
  219. vel_adjusted = 63 - op1_lvl_mdl.value();
  220. }
  221. theEmulator->write(0x40+adlib_opadd[voice],
  222. ( (int)op1_scale_mdl.value() & 0x03 << 6) +
  223. ( vel_adjusted & 0x3f ) );
  224. vel_adjusted = 63 - ( op2_lvl_mdl.value() * vel/127.0 );
  225. // vel_adjusted = 63 - op2_lvl_mdl.value();
  226. theEmulator->write(0x43+adlib_opadd[voice],
  227. ( (int)op2_scale_mdl.value() & 0x03 << 6) +
  228. ( vel_adjusted & 0x3f ) );
  229. }
  230. // Pop least recently used voice
  231. int opl2instrument::popVoice() {
  232. int tmp = voiceLRU[0];
  233. for( int i=0; i<OPL2_VOICES-1; ++i) {
  234. voiceLRU[i] = voiceLRU[i+1];
  235. }
  236. voiceLRU[OPL2_VOICES-1] = OPL2_NO_VOICE;
  237. #ifdef false
  238. printf("<-- %d %d %d %d %d %d %d %d %d \n", voiceLRU[0],voiceLRU[1],voiceLRU[2],
  239. voiceLRU[3],voiceLRU[4],voiceLRU[5],voiceLRU[6],voiceLRU[7],voiceLRU[8]);
  240. #endif
  241. return tmp;
  242. }
  243. // Push voice into first free slot
  244. int opl2instrument::pushVoice(int v) {
  245. int i;
  246. assert(voiceLRU[OPL2_VOICES-1]==OPL2_NO_VOICE);
  247. for(i=OPL2_VOICES-1; i>0; --i) {
  248. if( voiceLRU[i-1] != OPL2_NO_VOICE ) {
  249. break;
  250. }
  251. }
  252. voiceLRU[i] = v;
  253. #ifdef false
  254. printf("%d %d %d %d %d %d %d %d %d <-- \n", voiceLRU[0],voiceLRU[1],voiceLRU[2],
  255. voiceLRU[3],voiceLRU[4],voiceLRU[5],voiceLRU[6],voiceLRU[7],voiceLRU[8]);
  256. #endif
  257. return i;
  258. }
  259. bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
  260. {
  261. emulatorMutex.lock();
  262. int key, vel, voice, tmp_pb;
  263. switch(event.type()) {
  264. case MidiNoteOn:
  265. // to get us in line with MIDI(?)
  266. key = event.key() +12;
  267. vel = event.velocity();
  268. voice = popVoice();
  269. if( voice != OPL2_NO_VOICE ) {
  270. // Turn voice on, NB! the frequencies are straight by voice number,
  271. // not by the adlib_opadd table!
  272. theEmulator->write(0xA0+voice, fnums[key] & 0xff);
  273. theEmulator->write(0xB0+voice, 32 + ((fnums[key] & 0x1f00) >> 8) );
  274. setVoiceVelocity(voice, vel);
  275. voiceNote[voice] = key;
  276. velocities[key] = vel;
  277. }
  278. break;
  279. case MidiNoteOff:
  280. key = event.key() +12;
  281. for(voice=0; voice<OPL2_VOICES; ++voice) {
  282. if( voiceNote[voice] == key ) {
  283. theEmulator->write(0xA0+voice, fnums[key] & 0xff);
  284. theEmulator->write(0xB0+voice, (fnums[key] & 0x1f00) >> 8 );
  285. voiceNote[voice] |= OPL2_VOICE_FREE;
  286. pushVoice(voice);
  287. }
  288. }
  289. velocities[key] = 0;
  290. break;
  291. case MidiKeyPressure:
  292. key = event.key() +12;
  293. vel = event.velocity();
  294. if( velocities[key] != 0) {
  295. velocities[key] = vel;
  296. }
  297. for(voice=0; voice<OPL2_VOICES; ++voice) {
  298. if(voiceNote[voice] == key) {
  299. setVoiceVelocity(voice, vel);
  300. }
  301. }
  302. break;
  303. case MidiPitchBend:
  304. // Update fnumber table
  305. // Neutral = 8192, full downbend = 0, full upbend = 16383
  306. tmp_pb = ( event.pitchBend()-8192 ) * pitchBendRange / 8192;
  307. if( tmp_pb != pitchbend ) {
  308. pitchbend = tmp_pb;
  309. tuneEqual(69, 440.0);
  310. }
  311. // Update pitch of all voices (also released ones)
  312. for( int v=0; v<OPL2_VOICES; ++v ) {
  313. int vn = (voiceNote[v] & ~OPL2_VOICE_FREE); // remove the flag bit
  314. int playing = (voiceNote[v] & OPL2_VOICE_FREE) == 0; // just the flag bit
  315. theEmulator->write(0xA0+v, fnums[vn] & 0xff);
  316. theEmulator->write(0xB0+v, (playing ? 32 : 0) + ((fnums[vn] & 0x1f00) >> 8) );
  317. }
  318. break;
  319. case MidiControlChange:
  320. switch (event.controllerNumber()) {
  321. case MidiControllerRegisteredParameterNumberLSB:
  322. RPNfine = event.controllerValue();
  323. break;
  324. case MidiControllerRegisteredParameterNumberMSB:
  325. RPNcoarse = event.controllerValue();
  326. break;
  327. case MidiControllerDataEntry:
  328. if( (RPNcoarse << 8) + RPNfine == MidiPitchBendSensitivityRPN) {
  329. pitchBendRange = event.controllerValue() * 100;
  330. }
  331. break;
  332. default:
  333. #ifdef LMMS_DEBUG
  334. printf("Midi CC %02x %02x\n", event.controllerNumber(), event.controllerValue() );
  335. #endif
  336. break;
  337. }
  338. break;
  339. default:
  340. #ifdef LMMS_DEBUG
  341. printf("Midi event type %d\n",event.type());
  342. #endif
  343. break;
  344. }
  345. emulatorMutex.unlock();
  346. return true;
  347. }
  348. QString opl2instrument::nodeName() const
  349. {
  350. return( OPL2_plugin_descriptor.name );
  351. }
  352. PluginView * opl2instrument::instantiateView( QWidget * _parent )
  353. {
  354. return( new opl2instrumentView( this, _parent ) );
  355. }
  356. void opl2instrument::play( sampleFrame * _working_buffer )
  357. {
  358. emulatorMutex.lock();
  359. theEmulator->update(renderbuffer, frameCount);
  360. for( fpp_t frame = 0; frame < frameCount; ++frame )
  361. {
  362. sample_t s = float(renderbuffer[frame]) / 8192.0;
  363. for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch )
  364. {
  365. _working_buffer[frame][ch] = s;
  366. }
  367. }
  368. emulatorMutex.unlock();
  369. // Throw the data to the track...
  370. instrumentTrack()->processAudioBuffer( _working_buffer, frameCount, NULL );
  371. }
  372. void opl2instrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
  373. {
  374. op1_a_mdl.saveSettings( _doc, _this, "op1_a" );
  375. op1_d_mdl.saveSettings( _doc, _this, "op1_d" );
  376. op1_s_mdl.saveSettings( _doc, _this, "op1_s" );
  377. op1_r_mdl.saveSettings( _doc, _this, "op1_r" );
  378. op1_lvl_mdl.saveSettings( _doc, _this, "op1_lvl" );
  379. op1_scale_mdl.saveSettings( _doc, _this, "op1_scale" );
  380. op1_mul_mdl.saveSettings( _doc, _this, "op1_mul" );
  381. feedback_mdl.saveSettings( _doc, _this, "feedback" );
  382. op1_ksr_mdl.saveSettings( _doc, _this, "op1_ksr" );
  383. op1_perc_mdl.saveSettings( _doc, _this, "op1_perc" );
  384. op1_trem_mdl.saveSettings( _doc, _this, "op1_trem" );
  385. op1_vib_mdl.saveSettings( _doc, _this, "op1_vib" );
  386. op1_waveform_mdl.saveSettings( _doc, _this, "op1_waveform" );
  387. op2_a_mdl.saveSettings( _doc, _this, "op2_a" );
  388. op2_d_mdl.saveSettings( _doc, _this, "op2_d" );
  389. op2_s_mdl.saveSettings( _doc, _this, "op2_s" );
  390. op2_r_mdl.saveSettings( _doc, _this, "op2_r" );
  391. op2_lvl_mdl.saveSettings( _doc, _this, "op2_lvl" );
  392. op2_scale_mdl.saveSettings( _doc, _this, "op2_scale" );
  393. op2_mul_mdl.saveSettings( _doc, _this, "op2_mul" );
  394. op2_ksr_mdl.saveSettings( _doc, _this, "op2_ksr" );
  395. op2_perc_mdl.saveSettings( _doc, _this, "op2_perc" );
  396. op2_trem_mdl.saveSettings( _doc, _this, "op2_trem" );
  397. op2_vib_mdl.saveSettings( _doc, _this, "op2_vib" );
  398. op2_waveform_mdl.saveSettings( _doc, _this, "op2_waveform" );
  399. fm_mdl.saveSettings( _doc, _this, "fm" );
  400. vib_depth_mdl.saveSettings( _doc, _this, "vib_depth" );
  401. trem_depth_mdl.saveSettings( _doc, _this, "trem_depth" );
  402. }
  403. void opl2instrument::loadSettings( const QDomElement & _this )
  404. {
  405. op1_a_mdl.loadSettings( _this, "op1_a" );
  406. op1_d_mdl.loadSettings( _this, "op1_d" );
  407. op1_s_mdl.loadSettings( _this, "op1_s" );
  408. op1_r_mdl.loadSettings( _this, "op1_r" );
  409. op1_lvl_mdl.loadSettings( _this, "op1_lvl" );
  410. op1_scale_mdl.loadSettings( _this, "op1_scale" );
  411. op1_mul_mdl.loadSettings( _this, "op1_mul" );
  412. feedback_mdl.loadSettings( _this, "feedback" );
  413. op1_ksr_mdl.loadSettings( _this, "op1_ksr" );
  414. op1_perc_mdl.loadSettings( _this, "op1_perc" );
  415. op1_trem_mdl.loadSettings( _this, "op1_trem" );
  416. op1_vib_mdl.loadSettings( _this, "op1_vib" );
  417. op1_waveform_mdl.loadSettings( _this, "op1_waveform" );
  418. op2_a_mdl.loadSettings( _this, "op2_a" );
  419. op2_d_mdl.loadSettings( _this, "op2_d" );
  420. op2_s_mdl.loadSettings( _this, "op2_s" );
  421. op2_r_mdl.loadSettings( _this, "op2_r" );
  422. op2_lvl_mdl.loadSettings( _this, "op2_lvl" );
  423. op2_scale_mdl.loadSettings( _this, "op2_scale" );
  424. op2_mul_mdl.loadSettings( _this, "op2_mul" );
  425. op2_ksr_mdl.loadSettings( _this, "op2_ksr" );
  426. op2_perc_mdl.loadSettings( _this, "op2_perc" );
  427. op2_trem_mdl.loadSettings( _this, "op2_trem" );
  428. op2_vib_mdl.loadSettings( _this, "op2_vib" );
  429. op2_waveform_mdl.loadSettings( _this, "op2_waveform" );
  430. fm_mdl.loadSettings( _this, "fm" );
  431. vib_depth_mdl.loadSettings( _this, "vib_depth" );
  432. trem_depth_mdl.loadSettings( _this, "trem_depth" );
  433. }
  434. // Load a patch into the emulator
  435. void opl2instrument::loadPatch(const unsigned char inst[14]) {
  436. emulatorMutex.lock();
  437. for(int v=0; v<OPL2_VOICES; ++v) {
  438. theEmulator->write(0x20+adlib_opadd[v],inst[0]); // op1 AM/VIB/EG/KSR/Multiplier
  439. theEmulator->write(0x23+adlib_opadd[v],inst[1]); // op2
  440. // theEmulator->write(0x40+adlib_opadd[v],inst[2]); // op1 KSL/Output Level - these are handled by noteon/aftertouch code
  441. // theEmulator->write(0x43+adlib_opadd[v],inst[3]); // op2
  442. theEmulator->write(0x60+adlib_opadd[v],inst[4]); // op1 A/D
  443. theEmulator->write(0x63+adlib_opadd[v],inst[5]); // op2
  444. theEmulator->write(0x80+adlib_opadd[v],inst[6]); // op1 S/R
  445. theEmulator->write(0x83+adlib_opadd[v],inst[7]); // op2
  446. theEmulator->write(0xe0+adlib_opadd[v],inst[8]); // op1 waveform
  447. theEmulator->write(0xe3+adlib_opadd[v],inst[9]); // op2
  448. theEmulator->write(0xc0+v,inst[10]); // feedback/algorithm
  449. }
  450. emulatorMutex.unlock();
  451. }
  452. void opl2instrument::tuneEqual(int center, float Hz) {
  453. float tmp;
  454. for(int n=0; n<128; ++n) {
  455. tmp = Hz*pow( 2.0, ( n - center ) * ( 1.0 / 12.0 ) + pitchbend * ( 1.0 / 1200.0 ) );
  456. fnums[n] = Hz2fnum( tmp );
  457. }
  458. }
  459. // Find suitable F number in lowest possible block
  460. int opl2instrument::Hz2fnum(float Hz) {
  461. for(int block=0; block<8; ++block) {
  462. unsigned int fnum = Hz * pow( 2.0, 20.0 - (double)block ) * ( 1.0 / 49716.0 );
  463. if(fnum<1023) {
  464. return fnum + (block << 10);
  465. }
  466. }
  467. return 0;
  468. }
  469. // Load one of the default patches
  470. void opl2instrument::loadGMPatch() {
  471. unsigned char *inst = midi_fm_instruments[m_patchModel.value()];
  472. loadPatch(inst);
  473. }
  474. // Update patch from the models to the chip emulation
  475. void opl2instrument::updatePatch() {
  476. unsigned char inst[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  477. inst[0] = ( op1_trem_mdl.value() ? 128 : 0 ) +
  478. ( op1_vib_mdl.value() ? 64 : 0 ) +
  479. ( op1_perc_mdl.value() ? 0 : 32 ) + // NB. This envelope mode is "perc", not "sus"
  480. ( op1_ksr_mdl.value() ? 16 : 0 ) +
  481. ((int)op1_mul_mdl.value() & 0x0f);
  482. inst[1] = ( op2_trem_mdl.value() ? 128 : 0 ) +
  483. ( op2_vib_mdl.value() ? 64 : 0 ) +
  484. ( op2_perc_mdl.value() ? 0 : 32 ) + // NB. This envelope mode is "perc", not "sus"
  485. ( op2_ksr_mdl.value() ? 16 : 0 ) +
  486. ((int)op2_mul_mdl.value() & 0x0f);
  487. inst[2] = ( ((int)op1_scale_mdl.value() & 0x03) << 6 ) +
  488. (63 - ( (int)op1_lvl_mdl.value() & 0x3f ) );
  489. inst[3] = ( ((int)op2_scale_mdl.value() & 0x03) << 6 ) +
  490. (63 - ( (int)op2_lvl_mdl.value() & 0x3f ) );
  491. inst[4] = ((15 - ((int)op1_a_mdl.value() & 0x0f ) ) << 4 )+
  492. (15 - ( (int)op1_d_mdl.value() & 0x0f ) );
  493. inst[5] = ((15 - ( (int)op2_a_mdl.value() & 0x0f ) ) << 4 )+
  494. (15 - ( (int)op2_d_mdl.value() & 0x0f ) );
  495. inst[6] = ((15 - ( (int)op1_s_mdl.value() & 0x0f ) ) << 4 ) +
  496. (15 - ( (int)op1_r_mdl.value() & 0x0f ) );
  497. inst[7] = ((15 - ( (int)op2_s_mdl.value() & 0x0f ) ) << 4 ) +
  498. (15 - ( (int)op2_r_mdl.value() & 0x0f ) );
  499. inst[8] = (int)op1_waveform_mdl.value() & 0x03;
  500. inst[9] = (int)op2_waveform_mdl.value() & 0x03;
  501. inst[10] = (fm_mdl.value() ? 0 : 1 ) +
  502. (((int)feedback_mdl.value() & 0x07 )<< 1);
  503. // These are always 0 in the list I had?
  504. inst[11] = 0;
  505. inst[12] = 0;
  506. inst[13] = 0;
  507. // Not part of the per-voice patch info
  508. theEmulator->write(0xBD, (trem_depth_mdl.value() ? 128 : 0 ) +
  509. (vib_depth_mdl.value() ? 64 : 0 ));
  510. // have to do this, as the level knobs might've changed
  511. for( int voice = 0; voice < OPL2_VOICES ; ++voice) {
  512. if(voiceNote[voice] && OPL2_VOICE_FREE == 0) {
  513. setVoiceVelocity(voice, velocities[voiceNote[voice]] );
  514. }
  515. }
  516. #ifdef false
  517. printf("UPD: %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
  518. inst[0], inst[1], inst[2], inst[3], inst[4],
  519. inst[5], inst[6], inst[7], inst[8], inst[9], inst[10]);
  520. #endif
  521. loadPatch(inst);
  522. }
  523. // Load an SBI file into the knob models
  524. void opl2instrument::loadFile( const QString& file ) {
  525. // http://cd.textfiles.com/soundsensations/SYNTH/SBINS/
  526. // http://cd.textfiles.com/soundsensations/SYNTH/SBI1198/1198SBI.ZIP
  527. if( !file.isEmpty() && QFileInfo( file ).exists() )
  528. {
  529. QFile sbifile(file);
  530. if (!sbifile.open(QIODevice::ReadOnly )) {
  531. printf("Can't open file\n");
  532. return;
  533. }
  534. QByteArray sbidata = sbifile.read(52);
  535. if( !sbidata.startsWith("SBI\0x1a") ) {
  536. printf("No SBI signature\n");
  537. return;
  538. }
  539. if( sbidata.size() != 52 ) {
  540. printf("SBI size error: expected 52, got %d\n",sbidata.size() );
  541. }
  542. // Minimum size of SBI if we ignore "reserved" bytes at end
  543. // https://courses.engr.illinois.edu/ece390/resources/sound/cmf.txt.html
  544. if( sbidata.size() < 47 ) {
  545. return;
  546. }
  547. QString sbiname = sbidata.mid(4, 32);
  548. // If user has changed track name... let's hope my logic is valid.
  549. if( sbiname.size() > 0 && instrumentTrack()->displayName() == storedname ) {
  550. instrumentTrack()->setName(sbiname);
  551. storedname = sbiname;
  552. }
  553. #ifdef false
  554. printf("SBI: %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
  555. (unsigned char)sbidata[36], (unsigned char)sbidata[37], (unsigned char)sbidata[38], (unsigned char)sbidata[39], (unsigned char)sbidata[40],
  556. (unsigned char)sbidata[41], (unsigned char)sbidata[42], (unsigned char)sbidata[43], (unsigned char)sbidata[44], (unsigned char)sbidata[45], (unsigned char)sbidata[46]);
  557. #endif
  558. // Modulator Sound Characteristic (Mult, KSR, EG, VIB, AM)
  559. op1_trem_mdl.setValue( (sbidata[36] & 0x80 ) == 0x80 ? true : false );
  560. op1_vib_mdl.setValue( (sbidata[36] & 0x40 ) == 0x40 ? true : false );
  561. op1_perc_mdl.setValue( (sbidata[36] & 0x20 ) == 0x20 ? false : true );
  562. op1_ksr_mdl.setValue( (sbidata[36] & 0x10 ) == 0x10 ? true : false );
  563. op1_mul_mdl.setValue( sbidata[36] & 0x0f );
  564. // Carrier Sound Characteristic
  565. op2_trem_mdl.setValue( (sbidata[37] & 0x80 ) == 0x80 ? true : false );
  566. op2_vib_mdl.setValue( (sbidata[37] & 0x40 ) == 0x40 ? true : false );
  567. op2_perc_mdl.setValue( (sbidata[37] & 0x20 ) == 0x20 ? false : true );
  568. op2_ksr_mdl.setValue( (sbidata[37] & 0x10 ) == 0x10 ? true : false );
  569. op2_mul_mdl.setValue( sbidata[37] & 0x0f );
  570. // Modulator Scaling/Output Level
  571. op1_scale_mdl.setValue( (sbidata[38] & 0xc0 ) >> 6 );
  572. op1_lvl_mdl.setValue( 63 - (sbidata[38] & 0x3f) );
  573. // Carrier Scaling/Output Level
  574. op2_scale_mdl.setValue( (sbidata[39] & 0xc0) >> 6 );
  575. op2_lvl_mdl.setValue( 63 - (sbidata[39] & 0x3f) );
  576. // Modulator Attack/Decay
  577. op1_a_mdl.setValue( 15 - ( ( sbidata[40] & 0xf0 ) >> 4 ) );
  578. op1_d_mdl.setValue( 15 - ( sbidata[40] & 0x0f ) );
  579. // Carrier Attack/Decay
  580. op2_a_mdl.setValue( 15 - ( ( sbidata[41] & 0xf0 ) >> 4 ) );
  581. op2_d_mdl.setValue( 15 - ( sbidata[41] & 0x0f ) );
  582. // Modulator Sustain/Release
  583. op1_s_mdl.setValue( 15 - ( ( sbidata[42] & 0xf0 ) >> 4 ) );
  584. op1_r_mdl.setValue( 15 - ( sbidata[42] & 0x0f ) );
  585. // Carrier Sustain/Release
  586. op2_s_mdl.setValue( 15 - ( ( sbidata[43] & 0xf0 ) >> 4 ) );
  587. op2_r_mdl.setValue( 15 - ( sbidata[43] & 0x0f ) );
  588. // Modulator Wave Select
  589. op1_waveform_mdl.setValue( sbidata[44] & 0x03 );
  590. // Carrier Wave Select
  591. op2_waveform_mdl.setValue( sbidata[45] & 0x03 );
  592. // Feedback/Connection
  593. fm_mdl.setValue( (sbidata[46] & 0x01) == 0x01 ? false : true );
  594. feedback_mdl.setValue( ( (sbidata[46] & 0x0e ) >> 1 ) );
  595. }
  596. }
  597. opl2instrumentView::opl2instrumentView( Instrument * _instrument,
  598. QWidget * _parent ) :
  599. InstrumentView( _instrument, _parent )
  600. {
  601. #define KNOB_GEN(knobname, hinttext, hintunit,xpos,ypos) \
  602. knobname = new Knob( knobStyled, this );\
  603. knobname->setHintText( tr(hinttext), hintunit );\
  604. knobname->setFixedSize(22,22);\
  605. knobname->setCenterPointX(11.0);\
  606. knobname->setCenterPointY(11.0);\
  607. knobname->setTotalAngle(270.0);\
  608. knobname->move(xpos,ypos);
  609. #define BUTTON_GEN(buttname, tooltip, xpos, ypos) \
  610. buttname = new PixmapButton( this, NULL );\
  611. buttname->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "opl2_led_on" ) );\
  612. buttname->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "opl2_led_off" ) );\
  613. buttname->setCheckable( true );\
  614. ToolTip::add( buttname, tr( tooltip ) );\
  615. buttname->move( xpos, ypos );
  616. #define WAVEBUTTON_GEN(buttname, tooltip, xpos, ypos, icon_on, icon_off, buttgroup) \
  617. buttname = new PixmapButton( this, NULL );\
  618. buttname->setActiveGraphic( PLUGIN_NAME::getIconPixmap( icon_on ) ); \
  619. buttname->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( icon_off ) ); \
  620. ToolTip::add( buttname, tr( tooltip ) );\
  621. buttname->move( xpos, ypos );\
  622. buttgroup->addButton(buttname);
  623. // OP1 knobs & buttons...
  624. KNOB_GEN(op1_a_kn, "Attack", "", 6, 48);
  625. KNOB_GEN(op1_d_kn, "Decay", "", 34, 48);
  626. KNOB_GEN(op1_s_kn, "Sustain", "", 62, 48);
  627. KNOB_GEN(op1_r_kn, "Release", "", 90, 48);
  628. KNOB_GEN(op1_lvl_kn, "Level", "", 166, 48);
  629. KNOB_GEN(op1_scale_kn, "Scale", "", 194, 48);
  630. KNOB_GEN(op1_mul_kn, "Frequency multiplier", "", 222, 48);
  631. BUTTON_GEN(op1_ksr_btn, "Keyboard scaling rate", 9, 87);
  632. BUTTON_GEN(op1_perc_btn, "Percussive envelope", 36, 87);
  633. BUTTON_GEN(op1_trem_btn, "Tremolo", 65, 87);
  634. BUTTON_GEN(op1_vib_btn, "Vibrato", 93, 87);
  635. KNOB_GEN(feedback_kn, "Feedback", "", 128, 48);
  636. op1_waveform = new automatableButtonGroup( this );
  637. WAVEBUTTON_GEN(op1_w0_btn,"Sine", 154, 86, "wave1_on", "wave1_off", op1_waveform);
  638. WAVEBUTTON_GEN(op1_w1_btn,"Half sine", 178, 86, "wave2_on", "wave2_off", op1_waveform);
  639. WAVEBUTTON_GEN(op1_w2_btn,"Absolute sine", 199, 86, "wave3_on", "wave3_off", op1_waveform);
  640. WAVEBUTTON_GEN(op1_w3_btn,"Quarter sine", 220, 86, "wave4_on", "wave4_off", op1_waveform);
  641. // And the same for OP2
  642. KNOB_GEN(op2_a_kn, "Attack", "", 6, 138);
  643. KNOB_GEN(op2_d_kn, "Decay", "", 34, 138);
  644. KNOB_GEN(op2_s_kn, "Sustain", "", 62, 138);
  645. KNOB_GEN(op2_r_kn, "Release", "", 90, 138);
  646. KNOB_GEN(op2_lvl_kn, "Level", "", 166, 138);
  647. KNOB_GEN(op2_scale_kn, "Scale", "", 194, 138);
  648. KNOB_GEN(op2_mul_kn, "Frequency multiplier", "", 222, 138);
  649. BUTTON_GEN(op2_ksr_btn, "Keyboard scaling rate", 9, 177);
  650. BUTTON_GEN(op2_perc_btn, "Percussive envelope", 36, 177);
  651. BUTTON_GEN(op2_trem_btn, "Tremolo", 65, 177);
  652. BUTTON_GEN(op2_vib_btn, "Vibrato", 93, 177);
  653. op2_waveform = new automatableButtonGroup( this );
  654. WAVEBUTTON_GEN(op2_w0_btn,"Sine", 154, 176, "wave1_on", "wave1_off", op2_waveform);
  655. WAVEBUTTON_GEN(op2_w1_btn,"Half sine", 178, 176, "wave2_on", "wave2_off", op2_waveform);
  656. WAVEBUTTON_GEN(op2_w2_btn,"Absolute sine", 199, 176, "wave3_on", "wave3_off", op2_waveform);
  657. WAVEBUTTON_GEN(op2_w3_btn,"Quarter Sine", 220, 176, "wave4_on", "wave4_off", op2_waveform);
  658. BUTTON_GEN(fm_btn, "FM", 9, 220);
  659. BUTTON_GEN(vib_depth_btn, "Vibrato depth", 65, 220);
  660. BUTTON_GEN(trem_depth_btn, "Tremolo depth", 93, 220);
  661. setAutoFillBackground( true );
  662. QPalette pal;
  663. pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap(
  664. "artwork" ) );
  665. setPalette( pal );
  666. }
  667. opl2instrumentView::~opl2instrumentView() {
  668. // Knobs are QWidgets and our children, so they're
  669. // destroyed automagically
  670. }
  671. // Returns text for time knob formatted nicely
  672. inline QString opl2instrumentView::knobHintHelper(float n) {
  673. if(n>1000) {
  674. return QString::number(n/1000, 'f', 0)+ " s";
  675. } else if(n>10) {
  676. return QString::number(n, 'f', 0)+ " ms";
  677. } else {
  678. return QString::number(n, 'f', 1)+ " ms";
  679. }
  680. }
  681. void opl2instrumentView::updateKnobHints()
  682. {
  683. // Envelope times in ms: t[0] = 0, t[n] = ( 1<<n ) * X, X = 0.11597 for A, 0.6311 for D/R
  684. // Here some rounding has been applied.
  685. const float attack_times[16] = {
  686. 0.0, 0.2, 0.4, 0.9, 1.8, 3.7, 7.4,
  687. 15.0, 30.0, 60.0, 120.0, 240.0, 480.0,
  688. 950.0, 1900.0, 3800.0
  689. };
  690. const float dr_times[16] = {
  691. 0.0, 1.2, 2.5, 5.0, 10.0, 20.0, 40.0,
  692. 80.0, 160.0, 320.0, 640.0, 1300.0, 2600.0,
  693. 5200.0, 10000.0, 20000.0
  694. };
  695. const int fmultipliers[16] = {
  696. -12, 0, 12, 19, 24, 28, 31, 34, 36, 38, 40, 40, 43, 43, 47, 47
  697. };
  698. opl2instrument * m = castModel<opl2instrument>();
  699. op1_a_kn->setHintText( tr( "Attack" ),
  700. " (" + knobHintHelper(attack_times[(int)m->op1_a_mdl.value()]) + ")");
  701. op2_a_kn->setHintText( tr( "Attack" ),
  702. " (" + knobHintHelper(attack_times[(int)m->op2_a_mdl.value()]) + ")");
  703. op1_d_kn->setHintText( tr( "Decay" ),
  704. " (" + knobHintHelper(dr_times[(int)m->op1_d_mdl.value()]) + ")");
  705. op2_d_kn->setHintText( tr( "Decay" ),
  706. " (" + knobHintHelper(dr_times[(int)m->op2_d_mdl.value()]) + ")");
  707. op1_r_kn->setHintText( tr( "Release" ),
  708. " (" + knobHintHelper(dr_times[(int)m->op1_r_mdl.value()]) + ")");
  709. op2_r_kn->setHintText( tr( "Release" ),
  710. " (" + knobHintHelper(dr_times[(int)m->op2_r_mdl.value()]) + ")");
  711. op1_mul_kn->setHintText( tr( "Frequency multiplier" ),
  712. " (" + QString::number(fmultipliers[(int)m->op1_mul_mdl.value()]) + " semitones)");
  713. op2_mul_kn->setHintText( tr( "Frequency multiplier" ),
  714. " (" + QString::number(fmultipliers[(int)m->op2_mul_mdl.value()]) + " semitones)");
  715. }
  716. void opl2instrumentView::modelChanged()
  717. {
  718. opl2instrument * m = castModel<opl2instrument>();
  719. // m_patch->setModel( &m->m_patchModel );
  720. op1_a_kn->setModel( &m->op1_a_mdl );
  721. op1_d_kn->setModel( &m->op1_d_mdl );
  722. op1_s_kn->setModel( &m->op1_s_mdl );
  723. op1_r_kn->setModel( &m->op1_r_mdl );
  724. op1_lvl_kn->setModel( &m->op1_lvl_mdl );
  725. op1_scale_kn->setModel( &m->op1_scale_mdl );
  726. op1_mul_kn->setModel( &m->op1_mul_mdl );
  727. feedback_kn->setModel( &m->feedback_mdl );
  728. op1_ksr_btn->setModel( &m->op1_ksr_mdl );
  729. op1_perc_btn->setModel( &m->op1_perc_mdl );
  730. op1_trem_btn->setModel( &m->op1_trem_mdl );
  731. op1_vib_btn->setModel( &m->op1_vib_mdl );
  732. op1_waveform->setModel( &m->op1_waveform_mdl );
  733. op2_a_kn->setModel( &m->op2_a_mdl );
  734. op2_d_kn->setModel( &m->op2_d_mdl );
  735. op2_s_kn->setModel( &m->op2_s_mdl );
  736. op2_r_kn->setModel( &m->op2_r_mdl );
  737. op2_lvl_kn->setModel( &m->op2_lvl_mdl );
  738. op2_scale_kn->setModel( &m->op2_scale_mdl );
  739. op2_mul_kn->setModel( &m->op2_mul_mdl );
  740. op2_ksr_btn->setModel( &m->op2_ksr_mdl );
  741. op2_perc_btn->setModel( &m->op2_perc_mdl );
  742. op2_trem_btn->setModel( &m->op2_trem_mdl );
  743. op2_vib_btn->setModel( &m->op2_vib_mdl );
  744. op2_waveform->setModel( &m->op2_waveform_mdl );
  745. fm_btn->setModel( &m->fm_mdl );
  746. vib_depth_btn->setModel( &m->vib_depth_mdl );
  747. trem_depth_btn->setModel( &m->trem_depth_mdl );
  748. // All knobs needing a user friendly unit
  749. connect( &m->op1_a_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  750. connect( &m->op2_a_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  751. connect( &m->op1_d_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  752. connect( &m->op2_d_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  753. connect( &m->op1_r_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  754. connect( &m->op2_r_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  755. connect( &m->op1_mul_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  756. connect( &m->op2_mul_mdl, SIGNAL( dataChanged() ), this, SLOT( updateKnobHints() ) );
  757. updateKnobHints();
  758. }