Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1162 lines
25KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2008 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. #include "smf.H"
  19. #include "phrase.H"
  20. #include "pattern.H"
  21. smf::smf ( void )
  22. {
  23. _name = NULL;
  24. _pos = 0;
  25. _fp = NULL;
  26. _length = 0;
  27. _length_pos = 0;
  28. _num_tracks_pos = 0;
  29. _tracks = 0;
  30. _time = 0;
  31. _tally = 0;
  32. _cue = 0;
  33. _track = 0;
  34. }
  35. smf::~smf ( void )
  36. {
  37. /* fill in the number of tracks */
  38. if ( _num_tracks_pos )
  39. {
  40. fseek( _fp, _num_tracks_pos, SEEK_SET );
  41. write_short( _tracks );
  42. }
  43. if ( _fp )
  44. fclose( _fp );
  45. if ( _name )
  46. free( _name );
  47. }
  48. int
  49. smf::open ( const char *name, int mode )
  50. {
  51. _name = strdup( name );
  52. _mode = mode;
  53. _fp = fopen( _name, mode == smf::WRITE ? "w" : "r" );
  54. return _fp != NULL;
  55. }
  56. /*************************/
  57. /* Private bit twiddlers */
  58. /*************************/
  59. unsigned long
  60. smf::read_long ( void )
  61. {
  62. byte_t buf[4];
  63. unsigned long ret = 0;
  64. read_bytes( buf, 4 );
  65. ret += *(buf + 0) << 24;
  66. ret += *(buf + 1) << 16;
  67. ret += *(buf + 2) << 8;
  68. ret += *(buf + 3);
  69. return ret;
  70. }
  71. unsigned short
  72. smf::read_short ( void )
  73. {
  74. byte_t buf[2];
  75. unsigned short ret = 0;
  76. read_bytes( buf, 2 );
  77. ret += *(buf + 0) << 8;
  78. ret += *(buf + 1);
  79. return ret;
  80. }
  81. unsigned long
  82. smf::read_var ( void )
  83. {
  84. unsigned long ret = 0;
  85. unsigned char c;
  86. /* while bit #7 is set */
  87. while ( ( ( c = read_byte() ) & 0x80 ) != 0x00 )
  88. {
  89. /* shift ret 7 bits */
  90. ret <<= 7;
  91. /* add bits 0-6 */
  92. ret += c & 0x7F;
  93. }
  94. /* bit was clear */
  95. ret <<= 7;
  96. ret += c & 0x7F;
  97. return ret;
  98. }
  99. void
  100. smf::read_bytes ( void *p, int l )
  101. {
  102. fread( p, l, 1, _fp );
  103. _pos += l;
  104. }
  105. byte_t
  106. smf::read_byte ( void )
  107. {
  108. byte_t b;
  109. read_bytes( &b, 1 );
  110. return b;
  111. }
  112. void
  113. smf::write_var ( long var )
  114. {
  115. long buffer;
  116. buffer = var & 0x7F;
  117. /* we shift it right 7, if there is
  118. still set bits, encode into buffer
  119. in reverse order */
  120. while ( ( var >>= 7) )
  121. {
  122. buffer <<= 8;
  123. buffer |= ( var & 0x7F ) | 0x80;
  124. }
  125. for ( ;; )
  126. {
  127. write_byte( buffer );
  128. if ( buffer & 0x80 )
  129. buffer >>= 8;
  130. else
  131. break;
  132. }
  133. }
  134. void
  135. smf::write_long ( unsigned long x )
  136. {
  137. byte_t buf[4];
  138. buf[0] = ( x & 0xFF000000 ) >> 24;
  139. buf[1] = ( x & 0x00FF0000 ) >> 16;
  140. buf[2] = ( x & 0x0000FF00 ) >> 8;
  141. buf[3] = x & 0x000000FF;
  142. write_bytes( buf, 4 );
  143. }
  144. void
  145. smf::write_ascii ( const char *buf )
  146. {
  147. if ( strlen( buf ) != 4 )
  148. ASSERTION( "invalid MIDI value" );
  149. write_bytes( (void *)buf, 4 );
  150. }
  151. void
  152. smf::write_short ( unsigned short x )
  153. {
  154. byte_t buf[2];
  155. buf[0] = (x & 0xFF00 ) >> 8;
  156. buf[1] = x & 0x00FF;
  157. write_bytes( buf, 2 );
  158. }
  159. void
  160. smf::write_byte ( byte_t b )
  161. {
  162. write_bytes( &b, 1 );
  163. }
  164. void
  165. smf::write_bytes ( const void *p, size_t l )
  166. {
  167. fwrite( p, l, 1, _fp );
  168. _tally += l;
  169. }
  170. /*************************/
  171. /* Read and write tracks */
  172. /*************************/
  173. /* write event /e/ to the currently open file (should only be used in a track)
  174. if /cue/ is true, transform a notes-on/off into cue messages */
  175. void
  176. smf::write_event ( const midievent *e )
  177. {
  178. tick_t ts = e->timestamp();
  179. tick_t delta = ts - _time;
  180. _time = ts;
  181. write_var( delta );
  182. if ( _cue && (e->is_note_off() || e->is_note_on() ) )
  183. {
  184. /* begin cue message */
  185. write_byte( 0xF0 ); /* sysex */
  186. write_var( 7 ); /* length of this message */
  187. static byte_t data[] = { 0x7F, /* MTC */
  188. 0, /* id */
  189. 0x05 }; /* cue message */
  190. write_bytes( data, sizeof( data ) );
  191. write_byte( e->opcode() == event::NOTE_ON ? 0x05 : 0x06 );
  192. write_short( e->note() );
  193. /* terminate */
  194. write_byte( 0xF7 );
  195. _status = 0;
  196. }
  197. else
  198. {
  199. byte_t buf[4];
  200. int l = e->size();
  201. midievent me = *e;
  202. if ( me.opcode() == event::NOTE_OFF )
  203. {
  204. me.opcode( event::NOTE_ON );
  205. me.note_velocity( 0 );
  206. }
  207. me.raw( buf, l );
  208. /* write with running status */
  209. if ( buf[0] != _status )
  210. {
  211. write_bytes( buf, l );
  212. _status = buf[0];
  213. }
  214. else
  215. write_bytes( buf + 1, l - 1 );
  216. }
  217. }
  218. void
  219. smf::write_header ( int fmt )
  220. {
  221. write_ascii( "MThd" );
  222. write_long( 6 ); /* Always 6 bytes of header */
  223. _format = fmt;
  224. write_short( fmt ); /* format, SMF-0 for 1 track SMF-2 for more */
  225. _num_tracks_pos = ftell( _fp );
  226. _tracks = 0;
  227. write_short( 0xDEAF );
  228. write_short( PPQN );
  229. }
  230. /* start a new MIDI 'chunk', /id/ is 4 letters of ASCII */
  231. void
  232. smf::open_chunk ( const char *id )
  233. {
  234. if ( _length_pos )
  235. ASSERTION( "chunks cannot be nested!" );
  236. write_ascii( id );
  237. /* reset track length counter */
  238. _length_pos = ftell( _fp );
  239. write_long( 0xBEEFCAFE ); /* length, this has to be filled in at track end! */
  240. _tally = 0;
  241. _time = 0;
  242. }
  243. void
  244. smf::close_chunk ( void )
  245. {
  246. /* fill in track length */
  247. long here = ftell( _fp );
  248. fseek( _fp, _length_pos, SEEK_SET );
  249. write_long( _tally );
  250. fseek( _fp, here, SEEK_SET );
  251. /* cleanup */
  252. _length_pos = 0;
  253. _tally = 0;
  254. }
  255. void
  256. smf::open_track ( const char *name, int num )
  257. {
  258. open_chunk( "MTrk" );
  259. if ( _format == 2 && num >= 0 )
  260. write_meta_event ( smf::SEQUENCE, num );
  261. if ( name )
  262. write_meta_event ( smf::NAME, name );
  263. ++_tracks;
  264. _status = 0;
  265. // FIXME: write time signature here
  266. }
  267. void
  268. smf::close_track ( tick_t length )
  269. {
  270. /* end */
  271. write_meta_event( smf::END, length ? length - _time : 0 );
  272. _cue = 0;
  273. close_chunk();
  274. }
  275. void
  276. smf::write_meta_event ( byte_t type, int n )
  277. {
  278. write_var( type == smf::END ? n : 0 ); /* delta time */
  279. write_short( 0xFF00 + type );
  280. /* write length bytes */
  281. switch ( type )
  282. {
  283. case smf::TEMPO:
  284. write_byte( 3 );
  285. // FIXME:
  286. break;
  287. case smf::SEQUENCE:
  288. write_byte( 2 );
  289. write_short( n );
  290. break;
  291. case smf::CHANNEL:
  292. case smf::PORT:
  293. write_byte( 1 );
  294. write_byte( n );
  295. break;
  296. case smf::END:
  297. write_byte( 0x00 );
  298. break;
  299. case smf::PROPRIETARY:
  300. // length
  301. write_var( n );
  302. break;
  303. // FIXME: handle time sig, key sig, proprietary
  304. }
  305. _status = 0;
  306. }
  307. void
  308. smf::write_meta_event ( byte_t type, const char *s )
  309. {
  310. write_var( 0 );
  311. write_short( 0xFF00 + type );
  312. switch ( type )
  313. {
  314. case smf::TEXT:
  315. case smf::NAME:
  316. case smf::INSTRUMENT:
  317. case smf::COPYRIGHT:
  318. case smf::LYRIC:
  319. case smf::MARKER:
  320. case smf::CUEPOINT:
  321. {
  322. int l = strlen( s );
  323. write_var( l );
  324. write_bytes( s, l );
  325. break;
  326. }
  327. default:
  328. ASSERTION( "event type does not take text!" );
  329. break;
  330. }
  331. }
  332. /** write song gloabl info (only used on playlist track) */
  333. void
  334. smf::write_song_info ( int mode, int phrases, int patterns, const char *name, const char *notes )
  335. {
  336. write_meta_event( smf::PROPRIETARY, 5 + (4 * 2) /* length */ );
  337. write_ascii( "Non!" );
  338. write_byte( mode );
  339. write_long( phrases );
  340. write_long( patterns );
  341. if ( name )
  342. write_meta_event( smf::NAME, name );
  343. write_meta_event( smf::TEXT, ":: Created by the Non-Seqeuncer" );
  344. if ( notes )
  345. write_meta_event( smf::TEXT, notes );
  346. }
  347. void
  348. smf::write_phrase_info ( const phrase *p )
  349. {
  350. if ( p->notes() )
  351. write_meta_event( smf::TEXT, p->notes() );
  352. char *s = p->viewport.dump();
  353. char pat[156];
  354. snprintf( pat, sizeof( pat ), "Non: xywh=%s",
  355. s );
  356. free( s );
  357. write_meta_event( smf::PROPRIETARY, strlen( pat ) );
  358. write_bytes( pat, strlen( pat ) );
  359. }
  360. /** write proprietary pattern info meta event */
  361. void
  362. smf::write_pattern_info ( const pattern *p )
  363. {
  364. write_meta_event( smf::PORT, p->port() );
  365. char pat[256];
  366. snprintf( pat, sizeof( pat ), "%s: %s", p->mapping.type(), p->mapping.name() );
  367. write_meta_event( smf::INSTRUMENT, pat );
  368. if ( p->notes() )
  369. write_meta_event( smf::TEXT, p->notes() );
  370. char *s = p->viewport.dump();
  371. snprintf( pat, sizeof( pat ), "Non: xywh=%s, ppqn=%d, key=%d, note=%d, mode=%d",
  372. s, p->ppqn(), p->mapping.key(), p->note(), p->mode() );
  373. free( s );
  374. write_meta_event( smf::PROPRIETARY, strlen( pat ) );
  375. write_bytes( pat, strlen( pat ) );
  376. }
  377. /* turn on note->cue translation for this track */
  378. void
  379. smf::cue ( bool b )
  380. {
  381. _cue = b;
  382. }
  383. /**********/
  384. /* Reader */
  385. /**********/
  386. char *
  387. smf::read_text ( void )
  388. {
  389. int l = read_var();
  390. char *s = (char*) malloc( l + 1 );
  391. read_bytes( s, l );
  392. s[l] = '\0';
  393. return s;
  394. }
  395. int
  396. smf::read_header ( void )
  397. {
  398. char id[4];
  399. read_bytes( id, 4 );
  400. if ( strncmp( id, "MThd", 4 ) )
  401. return 0;
  402. if ( read_long() != 6 )
  403. return 0;
  404. _format = read_short();
  405. _tracks = read_short();
  406. _ppqn = read_short();
  407. _pos = 0;
  408. return 1;
  409. }
  410. void
  411. smf::home ( void )
  412. {
  413. fseek( _fp, 14, SEEK_SET );
  414. _track = 0;
  415. _pos = 0;
  416. _length = 0;
  417. }
  418. void
  419. smf::skip ( size_t l )
  420. {
  421. fseek( _fp, l, SEEK_CUR );
  422. _pos += l;
  423. }
  424. void
  425. smf::backup ( size_t l )
  426. {
  427. skip( 0 - l );
  428. }
  429. char *
  430. smf::read_track_name ( void )
  431. {
  432. int status;
  433. long where = 0;
  434. int num = 0;
  435. for ( num = 0; ; ++num )
  436. {
  437. where = _pos;
  438. read_var(); /* delta */
  439. status = read_byte();
  440. /* stop at first non meta-event */
  441. if ( status != midievent::META )
  442. break;
  443. int opcode = read_byte();
  444. switch ( opcode )
  445. {
  446. case smf::NAME:
  447. return read_text();
  448. case smf::TEXT:
  449. return read_text();
  450. default:
  451. skip( read_var() );
  452. }
  453. }
  454. backup( _pos - where );
  455. return NULL;
  456. }
  457. /** read next Cue Point event on track */
  458. char *
  459. smf::read_cue_point ( void )
  460. {
  461. read_var(); /* delta */
  462. int status = read_byte();
  463. if ( status != midievent::META )
  464. return NULL;
  465. int opcode = read_byte();
  466. if ( opcode != smf::CUEPOINT )
  467. return NULL;
  468. return read_text();
  469. }
  470. bool
  471. smf::read_song_info ( int * mode, int * phrases, int *patterns, char **name, char **notes )
  472. {
  473. int status;
  474. long where = 0;
  475. int num = 0;
  476. bool r = false;
  477. *notes = NULL;
  478. for ( num = 0; ; ++num )
  479. {
  480. where = _pos;
  481. read_var(); /* delta */
  482. status = read_byte();
  483. /* stop at first non meta-event */
  484. if ( status != midievent::META )
  485. break;
  486. int opcode = read_byte();
  487. switch ( opcode )
  488. {
  489. case smf::PROPRIETARY:
  490. {
  491. int len = read_var();
  492. if ( len < 5 + (2 * 4) )
  493. return false;
  494. char id[4];
  495. read_bytes( id, 4 );
  496. if ( strncmp( id, "Non!", 4 ) )
  497. return false;
  498. *mode = read_byte();
  499. *phrases = read_long();
  500. *patterns = read_long();
  501. r = true;
  502. break;
  503. }
  504. case smf::TEXT:
  505. {
  506. char *text = read_text();
  507. if ( ! strncmp( text, "::", 2 ) )
  508. free( text );
  509. else
  510. *notes = text;
  511. break;
  512. }
  513. case smf::NAME:
  514. *name = read_text();
  515. break;
  516. case smf::END:
  517. goto done;
  518. default:
  519. goto semidone;
  520. }
  521. }
  522. semidone:
  523. backup( _pos - where );
  524. done:
  525. return r;
  526. }
  527. bool
  528. smf::read_phrase_info ( phrase *p )
  529. {
  530. int status;
  531. long where = 0;
  532. int num = 0;
  533. for ( num = 0; ; ++num )
  534. {
  535. where = _pos;
  536. read_var(); /* delta */
  537. status = read_byte();
  538. /* stop at first non meta-event */
  539. if ( status != midievent::META )
  540. break;
  541. int opcode = read_byte();
  542. switch ( opcode )
  543. {
  544. case smf::SEQUENCE:
  545. /* currently, this is ignored */
  546. read_var();
  547. read_short();
  548. break;
  549. case smf::NAME:
  550. p->name( read_text() );
  551. MESSAGE( "Track name: %s", p->name() );
  552. break;
  553. case smf::INSTRUMENT:
  554. skip( read_var() );
  555. break;
  556. case smf::TEXT:
  557. p->notes( read_text() );
  558. break;
  559. case smf::PROPRIETARY:
  560. {
  561. int l = read_var();
  562. char *data = (char *) alloca( l ) + 1;
  563. read_bytes( data, l );
  564. data[l] = '\0';
  565. char *s;
  566. if ( 1 != sscanf( data, "Non: xywh=%a[0-9:]",
  567. &s ) )
  568. WARNING( "Invalid phrase info event" );
  569. else
  570. {
  571. p->viewport.read( s );
  572. free( s );
  573. }
  574. break;
  575. }
  576. case smf::END:
  577. /* Track ends before any non meta-events... */
  578. read_byte();
  579. goto done;
  580. default:
  581. int l = read_var();
  582. skip( l );
  583. WARNING( "skipping unrecognized meta event %02X", opcode );
  584. break;
  585. }
  586. }
  587. backup( _pos - where );
  588. done:
  589. return num ? p : NULL;
  590. }
  591. /** inform pattern /p/ from meta-events at the beginning of the
  592. current track */
  593. bool
  594. smf::read_pattern_info ( pattern *p )
  595. {
  596. int status;
  597. long where = 0;
  598. int num = 0;
  599. bool name_set = false;
  600. for ( num = 0; ; ++num )
  601. {
  602. where = _pos;
  603. read_var(); /* delta */
  604. status = read_byte();
  605. /* stop at first non meta-event */
  606. if ( status != midievent::META )
  607. break;
  608. int opcode = read_byte();
  609. switch ( opcode )
  610. {
  611. case smf::SEQUENCE:
  612. /* currently, this is ignored */
  613. read_var();
  614. read_short();
  615. break;
  616. case smf::NAME:
  617. p->name( read_text() );
  618. MESSAGE( "Track name: %s", p->name() );
  619. name_set = true;
  620. break;
  621. case smf::INSTRUMENT:
  622. {
  623. char *s = read_text();
  624. char pat[256];
  625. if ( 1 == sscanf( s, "Instrument: %[^\n]", pat ) )
  626. {
  627. if ( ! p->mapping.open( Mapping::INSTRUMENT, pat ) )
  628. {
  629. p->mapping.open( Mapping::SCALE, "Chromatic" );
  630. WARNING( "could not find instrument \"%s\"", pat );
  631. }
  632. }
  633. else
  634. if ( 1 == sscanf( s, "Scale: %[^\n]", pat ) )
  635. {
  636. if ( ! p->mapping.open( Mapping::SCALE, pat ) )
  637. {
  638. p->mapping.open( Mapping::SCALE, "Chromatic" );
  639. WARNING( "could not find scale \"%s\"", pat );
  640. }
  641. }
  642. break;
  643. }
  644. case smf::PORT:
  645. read_byte();
  646. p->port( read_byte() );
  647. break;
  648. case smf::TEXT:
  649. if ( ! name_set )
  650. {
  651. /* also accept TEXT event as name if no name was
  652. provided--this is found in a number of older MIDI
  653. files. */
  654. p->name( read_text() );
  655. name_set = true;
  656. }
  657. else
  658. p->notes( read_text() );
  659. break;
  660. case smf::PROPRIETARY:
  661. {
  662. int l = read_var();
  663. char *data = (char *) alloca( l ) + 1;
  664. read_bytes( data, l );
  665. data[l] = '\0';
  666. int ppqn, key, note, mode;
  667. char *s;
  668. if ( 5 != sscanf( data, "Non: xywh=%a[0-9:], ppqn=%d, key=%d, note=%d, mode=%d",
  669. &s, &ppqn, &key, &note, &mode ) )
  670. WARNING( "Invalid pattern info event" );
  671. else
  672. {
  673. p->viewport.read( s );
  674. free( s );
  675. p->ppqn( ppqn );
  676. if ( key > 0 )
  677. p->mapping.key( key );
  678. p->note( note );
  679. p->mode( mode );
  680. }
  681. break;
  682. }
  683. case smf::END:
  684. /* Track ends before any non meta-events... */
  685. read_byte();
  686. goto done;
  687. default:
  688. int l = read_var();
  689. skip( l );
  690. WARNING( "skipping unrecognized meta event %02X", opcode );
  691. break;
  692. }
  693. }
  694. backup( _pos - where );
  695. done:
  696. return num ? p : NULL;
  697. }
  698. int
  699. smf::next_track ( void )
  700. {
  701. /* first, skip to the end of the track we're on, if any */
  702. if ( _length )
  703. skip( _length - _pos );
  704. while ( ! feof( _fp ) && _track < _tracks )
  705. {
  706. char id[4];
  707. read_bytes( id, 4 );
  708. _length = read_long();
  709. if ( strncmp( id, "MTrk", 4 ) )
  710. {
  711. WARNING( "skipping unrecognized chunk \"%s\"", id );
  712. /* not a track chunk */
  713. skip( _length );
  714. continue;
  715. }
  716. _pos = 0;
  717. ++_track;
  718. return 1;
  719. }
  720. return _length = _pos = 0;
  721. }
  722. /** locate track number /n/ */
  723. bool
  724. smf::seek_track ( int n )
  725. {
  726. home();
  727. if ( n >= _tracks )
  728. return false;
  729. for ( int i = 0; next_track(); ++i )
  730. if ( i == n )
  731. break;
  732. return true;
  733. }
  734. char **
  735. smf::track_listing ( void )
  736. {
  737. if ( _pos != 0 )
  738. ASSERTION( "attempt to get track listing while in the middle of reading a track." );
  739. char **sa = (char**)malloc( sizeof( char* ) * (_tracks + 1) );
  740. int i;
  741. long where = ftell( _fp );
  742. for ( i = 0; next_track(); ++i )
  743. {
  744. sa[i] = read_track_name();
  745. sa[i] = sa[i] ? sa[i] : strdup( "<Unnamed>" );
  746. }
  747. sa[i] = NULL;
  748. /* go back to where we started */
  749. fseek( _fp, where, SEEK_SET );
  750. _pos = 0;
  751. return sa;
  752. }
  753. /* print track list for file /name/ */
  754. void
  755. smf::print_track_listing ( const char *name )
  756. {
  757. smf f;
  758. f.open( name, smf::READ );
  759. f.read_header();
  760. char **sa = f.track_listing();
  761. char *s;
  762. for ( int i = 0; (s = sa[i]); ++i )
  763. printf( "Track %3d: \"%s\"\n", i, s );
  764. }
  765. /** read all remaining events in current track and return them in a list */
  766. list <midievent> *
  767. smf::read_track_events ( tick_t *length )
  768. {
  769. list <midievent> *events = new list <midievent>;
  770. event e;
  771. *length = 0;
  772. byte_t oldstatus = -1;
  773. tick_t time = 0;
  774. tick_t tick = 0;
  775. tick_t delta;
  776. while ( _pos < _length )
  777. {
  778. byte_t data[3];
  779. delta = read_var();
  780. int status = read_byte();
  781. if ( ! (status & 0x80) )
  782. {
  783. backup( 1 );
  784. status = oldstatus;
  785. }
  786. else
  787. oldstatus = status;
  788. time += delta;
  789. tick = (time * PPQN) / _ppqn;
  790. e.timestamp( tick );
  791. int opcode = status & 0xF0;
  792. // e.status( opcode );
  793. e.status( status );
  794. switch ( opcode )
  795. {
  796. case event::NOTE_OFF:
  797. case event::NOTE_ON:
  798. case event::AFTERTOUCH:
  799. case event::CONTROL_CHANGE:
  800. case event::PITCH_WHEEL:
  801. read_bytes( data, 2 );
  802. /* handle note off, vel 0 */
  803. if ( opcode == event::NOTE_ON && 0 == data[1] )
  804. {
  805. e.opcode( event::NOTE_OFF );
  806. data[1] = 127;
  807. }
  808. e.data( data[0], data[1] );
  809. events->push_back( e );
  810. /* TODO: set MIDI channel here */
  811. break;
  812. case event::PROGRAM_CHANGE:
  813. case event::CHANNEL_PRESSURE:
  814. data[0] = read_byte();
  815. e.lsb( data[0] );
  816. events->push_back( e );
  817. break;
  818. case 0xF0:
  819. /* TODO: hanlde proprietary events? */
  820. if ( midievent::META != status )
  821. {
  822. if ( 0xF0 == status )
  823. {
  824. /* looks like a sysex */
  825. int l = read_var();
  826. if ( l < 4 )
  827. ASSERTION( "unrecognized message" );
  828. byte_t *data = (byte_t *) alloca( 4 );
  829. read_bytes( data, 4 );
  830. l -= 4;
  831. if ( data[0] == 0x7F &&
  832. data[2] == 0x05 )
  833. {
  834. /* looks like a cue message! */
  835. switch ( data[3] )
  836. {
  837. case 0x05:
  838. /* start */
  839. e.status( event::NOTE_ON );
  840. e.note( read_short() );
  841. events->push_back( e );
  842. l -= 2;
  843. break;
  844. case 0x06:
  845. /* stop */
  846. e.status( event::NOTE_OFF );
  847. e.note( read_short() );
  848. events->push_back( e );
  849. l -= 2;
  850. break;
  851. default:
  852. ASSERTION( "unrecognized cue message" );
  853. break;
  854. }
  855. }
  856. MESSAGE( "converting MIDI cue to note-on/off n: %d", e.note() );
  857. /* just in case */
  858. skip( l );
  859. }
  860. else
  861. {
  862. WARNING( "unrecognized opcode %02X", status );
  863. // FIXME: what now?
  864. }
  865. break;
  866. }
  867. opcode = read_byte();
  868. switch ( opcode )
  869. {
  870. case smf::END: /* track end */
  871. /* track extends until this event */
  872. *length = tick;
  873. if ( read_byte() )
  874. WARNING( "corrupt MIDI file in track end" );
  875. goto done;
  876. break;
  877. default:
  878. WARNING( "unhandled meta-event %02X", opcode );
  879. skip( read_var() );
  880. break;
  881. }
  882. }
  883. }
  884. done:
  885. return events;
  886. }
  887. /**************************/
  888. /* accessors (for reader) */
  889. /**************************/
  890. int
  891. smf::format ( void ) const
  892. {
  893. return _format;
  894. }
  895. int
  896. smf::tracks ( void ) const
  897. {
  898. return _tracks;
  899. }