MidiImport.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /*
  2. * MidiImport.cpp - support for importing MIDI files
  3. *
  4. * Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
  5. *
  6. * This file is part of LMMS - https://lmms.io
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public
  19. * License along with this program (see COPYING); if not, write to the
  20. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA.
  22. *
  23. */
  24. #include <QDomDocument>
  25. #include <QDir>
  26. #include <QApplication>
  27. #include <QFile>
  28. #include <QMessageBox>
  29. #include <QProgressDialog>
  30. #include <sstream>
  31. #include "MidiImport.h"
  32. #include "TrackContainer.h"
  33. #include "InstrumentTrack.h"
  34. #include "AutomationTrack.h"
  35. #include "AutomationPattern.h"
  36. #include "ConfigManager.h"
  37. #include "Pattern.h"
  38. #include "Instrument.h"
  39. #include "GuiApplication.h"
  40. #include "MainWindow.h"
  41. #include "MidiTime.h"
  42. #include "debug.h"
  43. #include "Song.h"
  44. #include "embed.h"
  45. #include "plugin_export.h"
  46. #include "portsmf/allegro.h"
  47. #define makeID(_c0, _c1, _c2, _c3) \
  48. ( 0 | \
  49. ( ( _c0 ) | ( ( _c1 ) << 8 ) | ( ( _c2 ) << 16 ) | ( ( _c3 ) << 24 ) ) )
  50. extern "C"
  51. {
  52. Plugin::Descriptor PLUGIN_EXPORT midiimport_plugin_descriptor =
  53. {
  54. STRINGIFY( PLUGIN_NAME ),
  55. "MIDI Import",
  56. QT_TRANSLATE_NOOP( "pluginBrowser",
  57. "Filter for importing MIDI-files into LMMS" ),
  58. "Tobias Doerffel <tobydox/at/users/dot/sf/dot/net>",
  59. 0x0100,
  60. Plugin::ImportFilter,
  61. NULL,
  62. NULL,
  63. NULL
  64. } ;
  65. }
  66. MidiImport::MidiImport( const QString & _file ) :
  67. ImportFilter( _file, &midiimport_plugin_descriptor ),
  68. m_events(),
  69. m_timingDivision( 0 )
  70. {
  71. }
  72. MidiImport::~MidiImport()
  73. {
  74. }
  75. bool MidiImport::tryImport( TrackContainer* tc )
  76. {
  77. if( openFile() == false )
  78. {
  79. return false;
  80. }
  81. #ifdef LMMS_HAVE_FLUIDSYNTH
  82. if( gui != NULL &&
  83. ConfigManager::inst()->sf2File().isEmpty() )
  84. {
  85. QMessageBox::information( gui->mainWindow(),
  86. tr( "Setup incomplete" ),
  87. tr( "You have not set up a default soundfont in "
  88. "the settings dialog (Edit->Settings). "
  89. "Therefore no sound will be played back after "
  90. "importing this MIDI file. You should download "
  91. "a General MIDI soundfont, specify it in "
  92. "settings dialog and try again." ) );
  93. }
  94. #else
  95. if( gui )
  96. {
  97. QMessageBox::information( gui->mainWindow(),
  98. tr( "Setup incomplete" ),
  99. tr( "You did not compile LMMS with support for "
  100. "SoundFont2 player, which is used to add default "
  101. "sound to imported MIDI files. "
  102. "Therefore no sound will be played back after "
  103. "importing this MIDI file." ) );
  104. }
  105. #endif
  106. switch( readID() )
  107. {
  108. case makeID( 'M', 'T', 'h', 'd' ):
  109. printf( "MidiImport::tryImport(): found MThd\n");
  110. return readSMF( tc );
  111. case makeID( 'R', 'I', 'F', 'F' ):
  112. printf( "MidiImport::tryImport(): found RIFF\n");
  113. return readRIFF( tc );
  114. default:
  115. printf( "MidiImport::tryImport(): not a Standard MIDI "
  116. "file\n" );
  117. return false;
  118. }
  119. }
  120. class smfMidiCC
  121. {
  122. public:
  123. smfMidiCC() :
  124. at( NULL ),
  125. ap( NULL ),
  126. lastPos( 0 )
  127. { }
  128. AutomationTrack * at;
  129. AutomationPattern * ap;
  130. MidiTime lastPos;
  131. smfMidiCC & create( TrackContainer* tc, QString tn )
  132. {
  133. if( !at )
  134. {
  135. // Keep LMMS responsive, for now the import runs
  136. // in the main thread. This should probably be
  137. // removed if that ever changes.
  138. qApp->processEvents();
  139. at = dynamic_cast<AutomationTrack *>( Track::create( Track::AutomationTrack, tc ) );
  140. }
  141. if( tn != "") {
  142. at->setName( tn );
  143. }
  144. return *this;
  145. }
  146. void clear()
  147. {
  148. at = NULL;
  149. ap = NULL;
  150. lastPos = 0;
  151. }
  152. smfMidiCC & putValue( MidiTime time, AutomatableModel * objModel, float value )
  153. {
  154. if( !ap || time > lastPos + DefaultTicksPerBar )
  155. {
  156. MidiTime pPos = MidiTime( time.getBar(), 0 );
  157. ap = dynamic_cast<AutomationPattern*>(
  158. at->createTCO(0) );
  159. ap->movePosition( pPos );
  160. ap->addObject( objModel );
  161. }
  162. lastPos = time;
  163. time = time - ap->startPosition();
  164. ap->putValue( time, value, false );
  165. ap->changeLength( MidiTime( time.getBar() + 1, 0 ) );
  166. return *this;
  167. }
  168. };
  169. class smfMidiChannel
  170. {
  171. public:
  172. smfMidiChannel() :
  173. it( NULL ),
  174. p( NULL ),
  175. it_inst( NULL ),
  176. isSF2( false ),
  177. hasNotes( false ),
  178. lastEnd( 0 )
  179. { }
  180. InstrumentTrack * it;
  181. Pattern* p;
  182. Instrument * it_inst;
  183. bool isSF2;
  184. bool hasNotes;
  185. MidiTime lastEnd;
  186. QString trackName;
  187. smfMidiChannel * create( TrackContainer* tc, QString tn )
  188. {
  189. if( !it ) {
  190. // Keep LMMS responsive
  191. qApp->processEvents();
  192. it = dynamic_cast<InstrumentTrack *>( Track::create( Track::InstrumentTrack, tc ) );
  193. #ifdef LMMS_HAVE_FLUIDSYNTH
  194. it_inst = it->loadInstrument( "sf2player" );
  195. if( it_inst )
  196. {
  197. isSF2 = true;
  198. it_inst->loadFile( ConfigManager::inst()->sf2File() );
  199. it_inst->childModel( "bank" )->setValue( 0 );
  200. it_inst->childModel( "patch" )->setValue( 0 );
  201. }
  202. else
  203. {
  204. it_inst = it->loadInstrument( "patman" );
  205. }
  206. #else
  207. it_inst = it->loadInstrument( "patman" );
  208. #endif
  209. trackName = tn;
  210. if( trackName != "") {
  211. it->setName( tn );
  212. }
  213. lastEnd = 0;
  214. // General MIDI default
  215. it->pitchRangeModel()->setInitValue( 2 );
  216. }
  217. return this;
  218. }
  219. void addNote( Note & n )
  220. {
  221. if( !p || n.pos() > lastEnd + DefaultTicksPerBar )
  222. {
  223. MidiTime pPos = MidiTime( n.pos().getBar(), 0 );
  224. p = dynamic_cast<Pattern*>( it->createTCO( 0 ) );
  225. p->movePosition( pPos );
  226. }
  227. hasNotes = true;
  228. lastEnd = n.pos() + n.length();
  229. n.setPos( n.pos( p->startPosition() ) );
  230. p->addNote( n, false );
  231. }
  232. };
  233. bool MidiImport::readSMF( TrackContainer* tc )
  234. {
  235. const int preTrackSteps = 2;
  236. QProgressDialog pd( TrackContainer::tr( "Importing MIDI-file..." ),
  237. TrackContainer::tr( "Cancel" ), 0, preTrackSteps, gui->mainWindow() );
  238. pd.setWindowTitle( TrackContainer::tr( "Please wait..." ) );
  239. pd.setWindowModality(Qt::WindowModal);
  240. pd.setMinimumDuration( 0 );
  241. pd.setValue( 0 );
  242. std::stringstream stream;
  243. QByteArray arr = readAllData();
  244. stream.str(std::string(arr.constData(), arr.size()));
  245. Alg_seq_ptr seq = new Alg_seq(stream, true);
  246. seq->convert_to_beats();
  247. pd.setMaximum( seq->tracks() + preTrackSteps );
  248. pd.setValue( 1 );
  249. // 128 CC + Pitch Bend
  250. smfMidiCC ccs[129];
  251. smfMidiChannel chs[256];
  252. MeterModel & timeSigMM = Engine::getSong()->getTimeSigModel();
  253. AutomationTrack * nt = dynamic_cast<AutomationTrack*>(
  254. Track::create(Track::AutomationTrack, Engine::getSong()));
  255. nt->setName(tr("MIDI Time Signature Numerator"));
  256. AutomationTrack * dt = dynamic_cast<AutomationTrack*>(
  257. Track::create(Track::AutomationTrack, Engine::getSong()));
  258. dt->setName(tr("MIDI Time Signature Denominator"));
  259. AutomationPattern * timeSigNumeratorPat =
  260. new AutomationPattern(nt);
  261. timeSigNumeratorPat->setDisplayName(tr("Numerator"));
  262. timeSigNumeratorPat->addObject(&timeSigMM.numeratorModel());
  263. AutomationPattern * timeSigDenominatorPat =
  264. new AutomationPattern(dt);
  265. timeSigDenominatorPat->setDisplayName(tr("Denominator"));
  266. timeSigDenominatorPat->addObject(&timeSigMM.denominatorModel());
  267. // TODO: adjust these to Time.Sig changes
  268. double beatsPerBar = 4;
  269. double ticksPerBeat = DefaultTicksPerBar / beatsPerBar;
  270. // Time-sig changes
  271. Alg_time_sigs * timeSigs = &seq->time_sig;
  272. for( int s = 0; s < timeSigs->length(); ++s )
  273. {
  274. Alg_time_sig timeSig = (*timeSigs)[s];
  275. timeSigNumeratorPat->putValue(timeSig.beat * ticksPerBeat, timeSig.num);
  276. timeSigDenominatorPat->putValue(timeSig.beat * ticksPerBeat, timeSig.den);
  277. }
  278. // manually call otherwise the pattern shows being 1 bar
  279. timeSigNumeratorPat->updateLength();
  280. timeSigDenominatorPat->updateLength();
  281. pd.setValue( 2 );
  282. // Tempo stuff
  283. AutomationPattern * tap = tc->tempoAutomationPattern();
  284. if( tap )
  285. {
  286. tap->clear();
  287. Alg_time_map * timeMap = seq->get_time_map();
  288. Alg_beats & beats = timeMap->beats;
  289. for( int i = 0; i < beats.len - 1; i++ )
  290. {
  291. Alg_beat_ptr b = &(beats[i]);
  292. double tempo = ( beats[i + 1].beat - b->beat ) /
  293. ( beats[i + 1].time - beats[i].time );
  294. tap->putValue( b->beat * ticksPerBeat, tempo * 60.0 );
  295. }
  296. if( timeMap->last_tempo_flag )
  297. {
  298. Alg_beat_ptr b = &( beats[beats.len - 1] );
  299. tap->putValue( b->beat * ticksPerBeat, timeMap->last_tempo * 60.0 );
  300. }
  301. }
  302. // Update the tempo to avoid crash when playing a project imported
  303. // via the command line
  304. Engine::updateFramesPerTick();
  305. // Song events
  306. for( int e = 0; e < seq->length(); ++e )
  307. {
  308. Alg_event_ptr evt = (*seq)[e];
  309. if( evt->is_update() )
  310. {
  311. printf("Unhandled SONG update: %d %f %s\n",
  312. evt->get_type_code(), evt->time, evt->get_attribute() );
  313. }
  314. }
  315. // Tracks
  316. for( int t = 0; t < seq->tracks(); ++t )
  317. {
  318. QString trackName = QString( tr( "Track" ) + " %1" ).arg( t );
  319. Alg_track_ptr trk = seq->track( t );
  320. pd.setValue( t + preTrackSteps );
  321. for( int c = 0; c < 129; c++ )
  322. {
  323. ccs[c].clear();
  324. }
  325. // Now look at events
  326. for( int e = 0; e < trk->length(); ++e )
  327. {
  328. Alg_event_ptr evt = (*trk)[e];
  329. if( evt->chan == -1 )
  330. {
  331. bool handled = false;
  332. if( evt->is_update() )
  333. {
  334. QString attr = evt->get_attribute();
  335. if( attr == "tracknames" && evt->get_update_type() == 's' ) {
  336. trackName = evt->get_string_value();
  337. handled = true;
  338. }
  339. }
  340. if( !handled ) {
  341. // Write debug output
  342. printf("MISSING GLOBAL HANDLER\n");
  343. printf(" Chn: %d, Type Code: %d, Time: %f", (int) evt->chan,
  344. evt->get_type_code(), evt->time );
  345. if ( evt->is_update() )
  346. {
  347. printf( ", Update Type: %s", evt->get_attribute() );
  348. if ( evt->get_update_type() == 'a' )
  349. {
  350. printf( ", Atom: %s", evt->get_atom_value() );
  351. }
  352. }
  353. printf( "\n" );
  354. }
  355. }
  356. else if( evt->is_note() && evt->chan < 256 )
  357. {
  358. smfMidiChannel * ch = chs[evt->chan].create( tc, trackName );
  359. Alg_note_ptr noteEvt = dynamic_cast<Alg_note_ptr>( evt );
  360. int ticks = noteEvt->get_duration() * ticksPerBeat;
  361. Note n( (ticks < 1 ? 1 : ticks ),
  362. noteEvt->get_start_time() * ticksPerBeat,
  363. noteEvt->get_identifier() - 12,
  364. noteEvt->get_loud() * (200.f / 127.f)); // Map from MIDI velocity to LMMS volume
  365. ch->addNote( n );
  366. }
  367. else if( evt->is_update() )
  368. {
  369. smfMidiChannel * ch = chs[evt->chan].create( tc, trackName );
  370. double time = evt->time*ticksPerBeat;
  371. QString update( evt->get_attribute() );
  372. if( update == "programi" )
  373. {
  374. long prog = evt->get_integer_value();
  375. if( ch->isSF2 )
  376. {
  377. ch->it_inst->childModel( "bank" )->setValue( 0 );
  378. ch->it_inst->childModel( "patch" )->setValue( prog );
  379. }
  380. else {
  381. const QString num = QString::number( prog );
  382. const QString filter = QString().fill( '0', 3 - num.length() ) + num + "*.pat";
  383. const QString dir = "/usr/share/midi/"
  384. "freepats/Tone_000/";
  385. const QStringList files = QDir( dir ).
  386. entryList( QStringList( filter ) );
  387. if( ch->it_inst && !files.empty() )
  388. {
  389. ch->it_inst->loadFile( dir+files.front() );
  390. }
  391. }
  392. }
  393. else if( update.startsWith( "control" ) || update == "bendr" )
  394. {
  395. int ccid = update.mid( 7, update.length()-8 ).toInt();
  396. if( update == "bendr" )
  397. {
  398. ccid = 128;
  399. }
  400. if( ccid <= 128 )
  401. {
  402. double cc = evt->get_real_value();
  403. AutomatableModel * objModel = NULL;
  404. switch( ccid )
  405. {
  406. case 0:
  407. if( ch->isSF2 && ch->it_inst )
  408. {
  409. objModel = ch->it_inst->childModel( "bank" );
  410. printf("BANK SELECT %f %d\n", cc, (int)(cc*127.0));
  411. cc *= 127.0f;
  412. }
  413. break;
  414. case 7:
  415. objModel = ch->it->volumeModel();
  416. cc *= 100.0f;
  417. break;
  418. case 10:
  419. objModel = ch->it->panningModel();
  420. cc = cc * 200.f - 100.0f;
  421. break;
  422. case 128:
  423. objModel = ch->it->pitchModel();
  424. cc = cc * 100.0f;
  425. break;
  426. default:
  427. //TODO: something useful for other CCs
  428. break;
  429. }
  430. if( objModel )
  431. {
  432. if( time == 0 && objModel )
  433. {
  434. objModel->setInitValue( cc );
  435. }
  436. else
  437. {
  438. if( ccs[ccid].at == NULL ) {
  439. ccs[ccid].create( tc, trackName + " > " + (
  440. objModel != NULL ?
  441. objModel->displayName() :
  442. QString("CC %1").arg(ccid) ) );
  443. }
  444. ccs[ccid].putValue( time, objModel, cc );
  445. }
  446. }
  447. }
  448. }
  449. else {
  450. printf("Unhandled update: %d %d %f %s\n", (int) evt->chan,
  451. evt->get_type_code(), evt->time, evt->get_attribute() );
  452. }
  453. }
  454. }
  455. }
  456. delete seq;
  457. for( int c=0; c < 256; ++c )
  458. {
  459. if( !chs[c].hasNotes && chs[c].it )
  460. {
  461. printf(" Should remove empty track\n");
  462. // must delete trackView first - but where is it?
  463. //tc->removeTrack( chs[c].it );
  464. //it->deleteLater();
  465. }
  466. }
  467. // Set channel 10 to drums as per General MIDI's orders
  468. if( chs[9].hasNotes && chs[9].it_inst && chs[9].isSF2 )
  469. {
  470. // AFAIK, 128 should be the standard bank for drums in SF2.
  471. // If not, this has to be made configurable.
  472. chs[9].it_inst->childModel( "bank" )->setValue( 128 );
  473. chs[9].it_inst->childModel( "patch" )->setValue( 0 );
  474. }
  475. return true;
  476. }
  477. bool MidiImport::readRIFF( TrackContainer* tc )
  478. {
  479. // skip file length
  480. skip( 4 );
  481. // check file type ("RMID" = RIFF MIDI)
  482. if( readID() != makeID( 'R', 'M', 'I', 'D' ) )
  483. {
  484. invalid_format:
  485. qWarning( "MidiImport::readRIFF(): invalid file format" );
  486. return false;
  487. }
  488. // search for "data" chunk
  489. while( 1 )
  490. {
  491. const int id = readID();
  492. const int len = read32LE();
  493. if( file().atEnd() )
  494. {
  495. data_not_found:
  496. qWarning( "MidiImport::readRIFF(): data chunk not found" );
  497. return false;
  498. }
  499. if( id == makeID( 'd', 'a', 't', 'a' ) )
  500. {
  501. break;
  502. }
  503. if( len < 0 )
  504. {
  505. goto data_not_found;
  506. }
  507. skip( ( len + 1 ) & ~1 );
  508. }
  509. // the "data" chunk must contain data in SMF format
  510. if( readID() != makeID( 'M', 'T', 'h', 'd' ) )
  511. {
  512. goto invalid_format;
  513. }
  514. return readSMF( tc );
  515. }
  516. void MidiImport::error()
  517. {
  518. printf( "MidiImport::readTrack(): invalid MIDI data (offset %#x)\n",
  519. (unsigned int) file().pos() );
  520. }
  521. extern "C"
  522. {
  523. // necessary for getting instance out of shared lib
  524. PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
  525. {
  526. return new MidiImport( QString::fromUtf8(
  527. static_cast<const char *>( _data ) ) );
  528. }
  529. }