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.

1154 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 > 0;
  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. // FIXME: write time signature here
  265. }
  266. void
  267. smf::close_track ( tick_t length )
  268. {
  269. /* end */
  270. write_meta_event( smf::END, length ? length - _time : 0 );
  271. _cue = 0;
  272. close_chunk();
  273. }
  274. void
  275. smf::write_meta_event ( byte_t type, int n )
  276. {
  277. write_var( type == smf::END ? n : 0 ); /* delta time */
  278. write_short( 0xFF00 + type );
  279. /* write length bytes */
  280. switch ( type )
  281. {
  282. case smf::TEMPO:
  283. write_byte( 3 );
  284. // FIXME:
  285. break;
  286. case smf::SEQUENCE:
  287. write_byte( 2 );
  288. write_short( n );
  289. break;
  290. case smf::CHANNEL:
  291. case smf::PORT:
  292. write_byte( 1 );
  293. write_byte( n );
  294. break;
  295. case smf::END:
  296. write_byte( 0x00 );
  297. break;
  298. case smf::PROPRIETARY:
  299. // length
  300. write_var( n );
  301. break;
  302. // FIXME: handle time sig, key sig, proprietary
  303. }
  304. }
  305. void
  306. smf::write_meta_event ( byte_t type, const char *s )
  307. {
  308. write_var( 0 );
  309. write_short( 0xFF00 + type );
  310. switch ( type )
  311. {
  312. case smf::TEXT:
  313. case smf::NAME:
  314. case smf::INSTRUMENT:
  315. case smf::COPYRIGHT:
  316. case smf::LYRIC:
  317. case smf::MARKER:
  318. case smf::CUEPOINT:
  319. {
  320. int l = strlen( s );
  321. write_var( l );
  322. write_bytes( s, l );
  323. break;
  324. }
  325. default:
  326. ASSERTION( "event type does not take text!" );
  327. break;
  328. }
  329. }
  330. /** write song gloabl info (only used on playlist track) */
  331. void
  332. smf::write_song_info ( int mode, int phrases, int patterns, const char *name, const char *notes )
  333. {
  334. write_meta_event( smf::PROPRIETARY, 5 + (4 * 2) /* length */ );
  335. write_ascii( "Non!" );
  336. write_byte( mode );
  337. write_long( phrases );
  338. write_long( patterns );
  339. if ( name )
  340. write_meta_event( smf::NAME, name );
  341. write_meta_event( smf::TEXT, ":: Created by the Non-Seqeuncer" );
  342. if ( notes )
  343. write_meta_event( smf::TEXT, notes );
  344. }
  345. void
  346. smf::write_phrase_info ( const phrase *p )
  347. {
  348. if ( p->notes() )
  349. write_meta_event( smf::TEXT, p->notes() );
  350. char *s = p->viewport.dump();
  351. char pat[156];
  352. snprintf( pat, sizeof( pat ), "Non: xywh=%s",
  353. s );
  354. free( s );
  355. write_meta_event( smf::PROPRIETARY, strlen( pat ) );
  356. write_bytes( pat, strlen( pat ) );
  357. }
  358. /** write proprietary pattern info meta event */
  359. void
  360. smf::write_pattern_info ( const pattern *p )
  361. {
  362. write_meta_event( smf::PORT, p->port() );
  363. char pat[256];
  364. snprintf( pat, sizeof( pat ), "%s: %s", p->mapping.type(), p->mapping.name() );
  365. write_meta_event( smf::INSTRUMENT, pat );
  366. if ( p->notes() )
  367. write_meta_event( smf::TEXT, p->notes() );
  368. char *s = p->viewport.dump();
  369. snprintf( pat, sizeof( pat ), "Non: xywh=%s, ppqn=%d, key=%d, note=%d, mode=%d",
  370. s, p->ppqn(), p->mapping.key(), p->note(), p->mode() );
  371. free( s );
  372. write_meta_event( smf::PROPRIETARY, strlen( pat ) );
  373. write_bytes( pat, strlen( pat ) );
  374. }
  375. /* turn on note->cue translation for this track */
  376. void
  377. smf::cue ( bool b )
  378. {
  379. _cue = b;
  380. }
  381. /**********/
  382. /* Reader */
  383. /**********/
  384. char *
  385. smf::read_text ( void )
  386. {
  387. int l = read_var();
  388. char *s = (char*) malloc( l + 1 );
  389. read_bytes( s, l );
  390. s[l] = '\0';
  391. return s;
  392. }
  393. int
  394. smf::read_header ( void )
  395. {
  396. char id[4];
  397. read_bytes( id, 4 );
  398. if ( strncmp( id, "MThd", 4 ) )
  399. return 0;
  400. if ( read_long() != 6 )
  401. return 0;
  402. _format = read_short();
  403. _tracks = read_short();
  404. _ppqn = read_short();
  405. _pos = 0;
  406. return 1;
  407. }
  408. void
  409. smf::home ( void )
  410. {
  411. fseek( _fp, 14, SEEK_SET );
  412. _track = 0;
  413. _pos = 0;
  414. _length = 0;
  415. }
  416. void
  417. smf::skip ( size_t l )
  418. {
  419. fseek( _fp, l, SEEK_CUR );
  420. _pos += l;
  421. }
  422. void
  423. smf::backup ( size_t l )
  424. {
  425. skip( 0 - l );
  426. }
  427. char *
  428. smf::read_track_name ( void )
  429. {
  430. int status;
  431. long where = 0;
  432. int num = 0;
  433. for ( num = 0; ; ++num )
  434. {
  435. where = _pos;
  436. read_var(); /* delta */
  437. status = read_byte();
  438. /* stop at first non meta-event */
  439. if ( status != midievent::META )
  440. break;
  441. int opcode = read_byte();
  442. switch ( opcode )
  443. {
  444. case smf::NAME:
  445. return read_text();
  446. case smf::TEXT:
  447. return read_text();
  448. default:
  449. skip( read_var() );
  450. }
  451. }
  452. backup( _pos - where );
  453. return NULL;
  454. }
  455. /** read next Cue Point event on track */
  456. char *
  457. smf::read_cue_point ( void )
  458. {
  459. read_var(); /* delta */
  460. int status = read_byte();
  461. if ( status != midievent::META )
  462. return NULL;
  463. int opcode = read_byte();
  464. if ( opcode != smf::CUEPOINT )
  465. return NULL;
  466. return read_text();
  467. }
  468. bool
  469. smf::read_song_info ( int * mode, int * phrases, int *patterns, char **name, char **notes )
  470. {
  471. int status;
  472. long where = 0;
  473. int num = 0;
  474. bool r = false;
  475. *notes = NULL;
  476. for ( num = 0; ; ++num )
  477. {
  478. where = _pos;
  479. read_var(); /* delta */
  480. status = read_byte();
  481. /* stop at first non meta-event */
  482. if ( status != midievent::META )
  483. break;
  484. int opcode = read_byte();
  485. switch ( opcode )
  486. {
  487. case smf::PROPRIETARY:
  488. {
  489. int len = read_var();
  490. if ( len < 5 + (2 * 4) )
  491. return false;
  492. char id[4];
  493. read_bytes( id, 4 );
  494. if ( strncmp( id, "Non!", 4 ) )
  495. return false;
  496. *mode = read_byte();
  497. *phrases = read_long();
  498. *patterns = read_long();
  499. r = true;
  500. break;
  501. }
  502. case smf::TEXT:
  503. {
  504. char *text = read_text();
  505. if ( ! strncmp( text, "::", 2 ) )
  506. free( text );
  507. else
  508. *notes = text;
  509. break;
  510. }
  511. case smf::NAME:
  512. *name = read_text();
  513. break;
  514. case smf::END:
  515. goto done;
  516. default:
  517. goto semidone;
  518. }
  519. }
  520. semidone:
  521. backup( _pos - where );
  522. done:
  523. return r;
  524. }
  525. bool
  526. smf::read_phrase_info ( phrase *p )
  527. {
  528. int status;
  529. long where = 0;
  530. int num = 0;
  531. for ( num = 0; ; ++num )
  532. {
  533. where = _pos;
  534. read_var(); /* delta */
  535. status = read_byte();
  536. /* stop at first non meta-event */
  537. if ( status != midievent::META )
  538. break;
  539. int opcode = read_byte();
  540. switch ( opcode )
  541. {
  542. case smf::SEQUENCE:
  543. /* currently, this is ignored */
  544. read_var();
  545. read_short();
  546. break;
  547. case smf::NAME:
  548. p->name( read_text() );
  549. MESSAGE( "Track name: %s", p->name() );
  550. break;
  551. case smf::INSTRUMENT:
  552. skip( read_var() );
  553. break;
  554. case smf::TEXT:
  555. p->notes( read_text() );
  556. break;
  557. case smf::PROPRIETARY:
  558. {
  559. int l = read_var();
  560. char *data = (char *) alloca( l ) + 1;
  561. read_bytes( data, l );
  562. data[l] = '\0';
  563. char *s;
  564. if ( 1 != sscanf( data, "Non: xywh=%a[0-9:]",
  565. &s ) )
  566. WARNING( "Invalid phrase info event" );
  567. else
  568. {
  569. p->viewport.read( s );
  570. free( s );
  571. }
  572. break;
  573. }
  574. case smf::END:
  575. /* Track ends before any non meta-events... */
  576. read_byte();
  577. goto done;
  578. default:
  579. int l = read_var();
  580. skip( l );
  581. WARNING( "skipping unrecognized meta event %02X", opcode );
  582. break;
  583. }
  584. }
  585. backup( _pos - where );
  586. done:
  587. return num ? p : NULL;
  588. }
  589. /** inform pattern /p/ from meta-events at the beginning of the
  590. current track */
  591. bool
  592. smf::read_pattern_info ( pattern *p )
  593. {
  594. int status;
  595. long where = 0;
  596. int num = 0;
  597. bool name_set = false;
  598. for ( num = 0; ; ++num )
  599. {
  600. where = _pos;
  601. read_var(); /* delta */
  602. status = read_byte();
  603. /* stop at first non meta-event */
  604. if ( status != midievent::META )
  605. break;
  606. int opcode = read_byte();
  607. switch ( opcode )
  608. {
  609. case smf::SEQUENCE:
  610. /* currently, this is ignored */
  611. read_var();
  612. read_short();
  613. break;
  614. case smf::NAME:
  615. p->name( read_text() );
  616. MESSAGE( "Track name: %s", p->name() );
  617. name_set = true;
  618. break;
  619. case smf::INSTRUMENT:
  620. // FIXME: decode mapping;
  621. {
  622. char *s = read_text();
  623. char pat[256];
  624. if ( 1 == sscanf( s, "Instrument: %s", pat ) )
  625. {
  626. if ( ! p->mapping.open( Mapping::INSTRUMENT, pat ) )
  627. WARNING( "could not find instrument \"%s\"", pat );
  628. }
  629. else
  630. if ( 1 == sscanf( s, "Scale: %s", pat ) )
  631. {
  632. if ( ! p->mapping.open( Mapping::SCALE, pat ) )
  633. WARNING( "could not find scale \"%s\"", pat );
  634. }
  635. break;
  636. }
  637. case smf::PORT:
  638. read_byte();
  639. p->port( read_byte() );
  640. break;
  641. case smf::TEXT:
  642. if ( ! name_set )
  643. {
  644. /* also accept TEXT event as name if no name was
  645. provided--this is found in a number of older MIDI
  646. files. */
  647. p->name( read_text() );
  648. name_set = true;
  649. }
  650. else
  651. p->notes( read_text() );
  652. break;
  653. case smf::PROPRIETARY:
  654. {
  655. int l = read_var();
  656. char *data = (char *) alloca( l ) + 1;
  657. read_bytes( data, l );
  658. data[l] = '\0';
  659. int ppqn, key, note, mode;
  660. char *s;
  661. if ( 5 != sscanf( data, "Non: xywh=%a[0-9:], ppqn=%d, key=%d, note=%d, mode=%d",
  662. &s, &ppqn, &key, &note, &mode ) )
  663. WARNING( "Invalid pattern info event" );
  664. else
  665. {
  666. p->viewport.read( s );
  667. free( s );
  668. p->ppqn( ppqn );
  669. if ( key > 0 )
  670. p->mapping.key( key );
  671. p->note( note );
  672. p->mode( mode );
  673. }
  674. break;
  675. }
  676. case smf::END:
  677. /* Track ends before any non meta-events... */
  678. read_byte();
  679. goto done;
  680. default:
  681. int l = read_var();
  682. skip( l );
  683. WARNING( "skipping unrecognized meta event %02X", opcode );
  684. break;
  685. }
  686. }
  687. backup( _pos - where );
  688. done:
  689. return num ? p : NULL;
  690. }
  691. int
  692. smf::next_track ( void )
  693. {
  694. /* first, skip to the end of the track we're on, if any */
  695. if ( _length )
  696. skip( _length - _pos );
  697. while ( ! feof( _fp ) && _track < _tracks )
  698. {
  699. char id[4];
  700. read_bytes( id, 4 );
  701. _length = read_long();
  702. if ( strncmp( id, "MTrk", 4 ) )
  703. {
  704. WARNING( "skipping unrecognized chunk \"%s\"", id );
  705. /* not a track chunk */
  706. skip( _length );
  707. continue;
  708. }
  709. _pos = 0;
  710. ++_track;
  711. return 1;
  712. }
  713. return _length = _pos = 0;
  714. }
  715. /** locate track number /n/ */
  716. bool
  717. smf::seek_track ( int n )
  718. {
  719. home();
  720. if ( n >= _tracks )
  721. return false;
  722. for ( int i = 0; next_track(); ++i )
  723. if ( i == n )
  724. break;
  725. return true;
  726. }
  727. char **
  728. smf::track_listing ( void )
  729. {
  730. if ( _pos != 0 )
  731. ASSERTION( "attempt to get track listing while in the middle of reading a track." );
  732. char **sa = (char**)malloc( sizeof( char* ) * (_tracks + 1) );
  733. int i;
  734. long where = ftell( _fp );
  735. for ( i = 0; next_track(); ++i )
  736. {
  737. sa[i] = read_track_name();
  738. sa[i] = sa[i] ? sa[i] : strdup( "<Unnamed>" );
  739. }
  740. sa[i] = NULL;
  741. /* go back to where we started */
  742. fseek( _fp, where, SEEK_SET );
  743. _pos = 0;
  744. return sa;
  745. }
  746. /* print track list for file /name/ */
  747. void
  748. smf::print_track_listing ( const char *name )
  749. {
  750. smf f;
  751. f.open( name, smf::READ );
  752. f.read_header();
  753. char **sa = f.track_listing();
  754. char *s;
  755. for ( int i = 0; (s = sa[i]); ++i )
  756. printf( "Track %3d: \"%s\"\n", i, s );
  757. }
  758. /** read all remaining events in current track and return them in a list */
  759. list <midievent> *
  760. smf::read_track_events ( tick_t *length )
  761. {
  762. list <midievent> *events = new list <midievent>;
  763. event e;
  764. *length = 0;
  765. byte_t oldstatus = -1;
  766. tick_t time = 0;
  767. tick_t tick = 0;
  768. tick_t delta;
  769. while ( _pos < _length )
  770. {
  771. byte_t data[3];
  772. delta = read_var();
  773. int status = read_byte();
  774. if ( ! (status & 0x80) )
  775. {
  776. backup( 1 );
  777. status = oldstatus;
  778. }
  779. else
  780. oldstatus = status;
  781. time += delta;
  782. tick = (time * PPQN) / _ppqn;
  783. e.timestamp( tick );
  784. int opcode = status & 0xF0;
  785. // e.status( opcode );
  786. e.status( status );
  787. switch ( opcode )
  788. {
  789. case event::NOTE_OFF:
  790. case event::NOTE_ON:
  791. case event::AFTERTOUCH:
  792. case event::CONTROL_CHANGE:
  793. case event::PITCH_WHEEL:
  794. read_bytes( data, 2 );
  795. /* handle note off, vel 0 */
  796. if ( opcode == event::NOTE_ON && 0 == data[1] )
  797. {
  798. e.opcode( event::NOTE_OFF );
  799. data[1] = 127;
  800. }
  801. e.data( data[0], data[1] );
  802. events->push_back( e );
  803. /* TODO: set MIDI channel here */
  804. break;
  805. case event::PROGRAM_CHANGE:
  806. case event::CHANNEL_PRESSURE:
  807. data[0] = read_byte();
  808. e.lsb( data[0] );
  809. events->push_back( e );
  810. break;
  811. case 0xF0:
  812. /* TODO: hanlde proprietary events? */
  813. if ( midievent::META != status )
  814. {
  815. if ( 0xF0 == status )
  816. {
  817. /* looks like a sysex */
  818. int l = read_var();
  819. if ( l < 4 )
  820. ASSERTION( "unrecognized message" );
  821. byte_t *data = (byte_t *) alloca( 4 );
  822. read_bytes( data, 4 );
  823. l -= 4;
  824. if ( data[0] == 0x7F &&
  825. data[2] == 0x05 )
  826. {
  827. /* looks like a cue message! */
  828. switch ( data[3] )
  829. {
  830. case 0x05:
  831. /* start */
  832. e.status( event::NOTE_ON );
  833. e.note( read_short() );
  834. events->push_back( e );
  835. l -= 2;
  836. break;
  837. case 0x06:
  838. /* stop */
  839. e.status( event::NOTE_OFF );
  840. e.note( read_short() );
  841. events->push_back( e );
  842. l -= 2;
  843. break;
  844. default:
  845. ASSERTION( "unrecognized cue message" );
  846. break;
  847. }
  848. }
  849. MESSAGE( "converting MIDI cue to note-on/off n: %d", e.note() );
  850. /* just in case */
  851. skip( l );
  852. }
  853. else
  854. {
  855. WARNING( "unrecognized opcode %02X", status );
  856. // FIXME: what now?
  857. }
  858. break;
  859. }
  860. opcode = read_byte();
  861. switch ( opcode )
  862. {
  863. case smf::END: /* track end */
  864. /* track extends until this event */
  865. *length = tick;
  866. if ( read_byte() )
  867. WARNING( "corrupt MIDI file in track end" );
  868. goto done;
  869. break;
  870. default:
  871. WARNING( "unhandled meta-event %02X", opcode );
  872. skip( read_var() );
  873. break;
  874. }
  875. }
  876. }
  877. done:
  878. return events;
  879. }
  880. /**************************/
  881. /* accessors (for reader) */
  882. /**************************/
  883. int
  884. smf::format ( void ) const
  885. {
  886. return _format;
  887. }
  888. int
  889. smf::tracks ( void ) const
  890. {
  891. return _tracks;
  892. }