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.

856 lines
14KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2007-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 "grid.H"
  19. #include "common.h"
  20. #include "canvas.H"
  21. #include "non.H"
  22. #include "smf.H"
  23. Grid::Grid ( void )
  24. {
  25. _name = NULL;
  26. _notes = NULL;
  27. _number = 0;
  28. _height = 0;
  29. _rd = new data;
  30. _rw = NULL;
  31. // we need to initialize it here.
  32. data *d = (data *)_rd;
  33. _mode = 0;
  34. _locked = 0;
  35. d->length = 0;
  36. _bpb = 4;
  37. _ppqn = 1;
  38. viewport.h = 32;
  39. viewport.w = 32;
  40. viewport.x = 0;
  41. viewport.y = 0;
  42. _playing = false;
  43. _suspend_update = false;
  44. _start = _end = _index = 0;
  45. }
  46. Grid::~Grid ( void )
  47. {
  48. DMESSAGE( "deleting grid" );
  49. if ( _name )
  50. free( _name );
  51. if ( _notes )
  52. free( _notes );
  53. if ( _rw )
  54. delete _rw;
  55. if ( _rd )
  56. delete _rd;
  57. }
  58. /* copy constructor */
  59. Grid::Grid ( const Grid &rhs ) : sigc::trackable()
  60. {
  61. _rd = new data( *rhs._rd );
  62. _rw = NULL;
  63. _name = rhs._name ? strdup( rhs._name ) : NULL;
  64. _notes = rhs._notes ? strdup( rhs._notes ) : NULL;
  65. _number = rhs._number;
  66. _height = rhs._height;
  67. _mode = 0;
  68. _locked = 0;
  69. _playing = false;
  70. _index = 0;
  71. _start = 0;
  72. _end = 0;
  73. _bpb = rhs._bpb;
  74. _ppqn = rhs._ppqn;
  75. viewport = rhs.viewport;
  76. }
  77. void
  78. Grid::lock ( void )
  79. {
  80. if ( ! _locked++ )
  81. _rw = new data( *_rd );
  82. }
  83. void
  84. Grid::unlock ( void )
  85. {
  86. if ( 0 == --_locked )
  87. {
  88. _history.push_back( const_cast<data *>( _rd ) );
  89. if ( _history.size() > MAX_UNDO + 1 )
  90. {
  91. data *d = _history.front();
  92. delete d;
  93. _history.pop_front();
  94. }
  95. // swap the copy back in (atomically).
  96. _rd = (const data *)_rw;
  97. _rw = NULL;
  98. if ( ! _suspend_update )
  99. signal_events_change();
  100. }
  101. }
  102. event *
  103. Grid::_event ( int x, int y, bool write ) const
  104. {
  105. const data *d = const_cast< data * >(_rd);
  106. const event_list *r = write ? &_rw->events : &d->events;
  107. if ( r->empty() || x_to_ts( x ) > _rd->length )
  108. return NULL;
  109. int note = y_to_note( y );
  110. tick_t xt = x_to_ts( x );
  111. for ( event *e = r->first(); e; e = e->next() )
  112. {
  113. if ( ! e->is_note_on() )
  114. continue;
  115. if ( e->note() != note )
  116. continue;
  117. unsigned long ts = e->timestamp();
  118. unsigned long l = 0;
  119. if ( e->linked() )
  120. l = e->link()->timestamp() - ts;
  121. else
  122. WARNING( "found unlinked event... event list is corrupt." );
  123. if ( xt >= ts && xt < ts + l )
  124. // this is a little nasty
  125. return const_cast<event *>(e);
  126. }
  127. return NULL;
  128. }
  129. bool
  130. Grid::_delete ( int x, int y )
  131. {
  132. event *e = _event ( x, y, true );
  133. if ( e )
  134. {
  135. if ( e->linked() )
  136. _rw->events.remove( e->link() );
  137. _rw->events.remove( e );
  138. return true;
  139. }
  140. return false;
  141. }
  142. bool
  143. Grid::_get ( struct dash *d, int x, int y ) const
  144. {
  145. event *e = _event ( x, y, false );
  146. if ( e )
  147. {
  148. tick_t ts = e->timestamp();
  149. tick_t l = 0;
  150. if ( e->linked() )
  151. l = e->link()->timestamp() - ts;
  152. else
  153. WARNING( "Found unlinked note on" );
  154. d->timestamp = ts_to_x( ts );
  155. d->length = ts_to_x( l );
  156. d->color = e->note_velocity();
  157. return true;
  158. }
  159. return false;
  160. }
  161. void
  162. Grid::clear ( void )
  163. {
  164. lock();
  165. _rw->events.clear();
  166. unlock();
  167. }
  168. int
  169. Grid::get ( struct dash *d, int x, int y ) const
  170. {
  171. return _get( d, x, y );
  172. }
  173. void
  174. Grid::del ( int x, int y )
  175. {
  176. lock();
  177. _delete( x, y );
  178. unlock();
  179. }
  180. int
  181. Grid::next_note_x ( int x ) const
  182. {
  183. for ( const event *e = _rd->events.first(); e; e = e->next() )
  184. if ( e->is_note_on() && (ts_to_x( e->timestamp() ) > (uint)x ) )
  185. return ts_to_x( e->timestamp() );
  186. return 0;
  187. }
  188. int
  189. Grid::prev_note_x ( int x ) const
  190. {
  191. for ( const event *e = _rd->events.last(); e; e = e->prev() )
  192. if ( e->is_note_on() && (ts_to_x( e->timestamp() ) < (uint)x) )
  193. return ts_to_x( e->timestamp() );
  194. return 0;
  195. }
  196. void
  197. Grid::_fix_length ( void )
  198. {
  199. tick_t beats = (unsigned long)(_rw->length / PPQN);
  200. tick_t rem = (unsigned long)_rw->length % PPQN;
  201. _rw->length = (rem ? (beats + 1) : beats) * PPQN;
  202. }
  203. /** Trim the length of the grid to the last event */
  204. void
  205. Grid::trim ( void )
  206. {
  207. lock();
  208. event *e = _rw->events.last();
  209. if ( e )
  210. {
  211. tick_t ts = e->timestamp();
  212. _rw->length = ts;
  213. _fix_length();
  214. }
  215. unlock();
  216. }
  217. void
  218. Grid::fit ( void )
  219. {
  220. int hi, lo;
  221. _rd->events.hi_lo_note( &hi, &lo );
  222. viewport.h = abs( hi - lo ) + 1;
  223. viewport.y = note_to_y( hi );
  224. }
  225. /** Expand the length of the grid to the last event */
  226. void
  227. Grid::expand ( void )
  228. {
  229. lock();
  230. event *e = _rw->events.last();
  231. if ( e )
  232. {
  233. tick_t ts = e->timestamp();
  234. _rw->length = ts > _rw->length ? ts : _rw->length;
  235. _fix_length();
  236. }
  237. unlock();
  238. }
  239. void
  240. Grid::put ( int x, int y, tick_t l )
  241. {
  242. int xl = ts_to_x( l );
  243. tick_t ts = x_to_ts( x );
  244. event *on = new event;
  245. event *off = new event;
  246. struct dash d;
  247. // Don't allow overlap (Why not?)
  248. if ( get( &d, x, y ) || get( &d, x + xl - 1, y ) )
  249. return;
  250. DMESSAGE( "put %d,%d", x, y );
  251. lock();
  252. int note = y_to_note( y );
  253. on->status( event::NOTE_ON );
  254. on->note( note );
  255. on->timestamp( ts );
  256. on->note_velocity( 64 );
  257. on->link( off );
  258. off->status( event::NOTE_OFF );
  259. off->note( note );
  260. off->timestamp( ts + l );
  261. off->note_velocity( 64 );
  262. off->link( on );
  263. _rw->events.insert( on );
  264. _rw->events.insert( off );
  265. expand();
  266. unlock();
  267. }
  268. // void
  269. // pattern::move ( int x, int y, int nx )
  270. // {
  271. // event *e = _event( x, y, false );
  272. // if ( e )
  273. // e->timestamp( nx );
  274. // }
  275. void
  276. Grid::move ( int x, int y, int nx, int ny )
  277. {
  278. lock();
  279. event *e = _event( x, y, true );
  280. if ( e )
  281. {
  282. DMESSAGE( "moving note" );
  283. event *on = e,
  284. *off = e->link();
  285. _rw->events.unlink( on );
  286. _rw->events.unlink( off );
  287. on->note( y_to_note( ny ) );
  288. tick_t l = on->note_duration();
  289. on->timestamp( x_to_ts( ny ) );
  290. on->note_duration( l );
  291. _rw->events.insert( off );
  292. _rw->events.insert( on );
  293. }
  294. unlock();
  295. }
  296. void
  297. Grid::adj_velocity ( int x, int y, int n )
  298. {
  299. lock();
  300. event *e = _event( x, y, true );
  301. if ( e )
  302. {
  303. DMESSAGE( "adjusting velocity" );
  304. {
  305. int v = e->note_velocity();
  306. v += n;
  307. if ( v > 127 )
  308. v = 127;
  309. e->note_velocity( v > 0 ? v : 1 );
  310. }
  311. }
  312. unlock();
  313. }
  314. void
  315. Grid::adj_duration ( int x, int y, int l )
  316. {
  317. lock();
  318. event *e = _event( x, y, true );
  319. if ( e )
  320. {
  321. DMESSAGE( "adjusting duration" );
  322. {
  323. int v = ts_to_x( e->note_duration() );
  324. v += l;
  325. e->note_duration( x_to_ts( v > 0 ? v : 1 ) );
  326. _rw->events.sort( e->link() );
  327. }
  328. }
  329. unlock();
  330. }
  331. void
  332. Grid::toggle_select ( int x, int y )
  333. {
  334. lock();
  335. event *e = _event( x, y, true );
  336. if ( e )
  337. {
  338. if ( e->selected() )
  339. e->deselect();
  340. else
  341. e->select();
  342. }
  343. unlock();
  344. }
  345. /** insert /l/ ticks of time after /x/ */
  346. void
  347. Grid::insert_time ( int l, int r )
  348. {
  349. tick_t start = x_to_ts( l );
  350. tick_t end = x_to_ts( r );
  351. lock();
  352. _rw->events.insert_time( start, end - start );
  353. expand();
  354. unlock();
  355. }
  356. /** select all events in range (notes straddling the border will also be selected */
  357. void
  358. Grid::select ( int l, int r )
  359. {
  360. tick_t start = x_to_ts( l );
  361. tick_t end = x_to_ts( r );
  362. lock();
  363. _rw->events.select( start, end );
  364. unlock();
  365. }
  366. /** select all (note) events in rectangle */
  367. void
  368. Grid::select ( int l, int r, int t, int b )
  369. {
  370. tick_t start = x_to_ts( l );
  371. tick_t end = x_to_ts( r );
  372. lock();
  373. _rw->events.select( start, end, y_to_note( t) , y_to_note( b ) );
  374. unlock();
  375. }
  376. /** delete events from /x/ to /l/, compressing time. */
  377. void
  378. Grid::delete_time ( int l, int r )
  379. {
  380. tick_t start = x_to_ts( l );
  381. tick_t end = x_to_ts( r );
  382. lock();
  383. _rw->events.delete_time( start, end );
  384. unlock();
  385. }
  386. void
  387. Grid::select_none ( void )
  388. {
  389. lock();
  390. _rw->events.select_none();
  391. unlock();
  392. }
  393. void
  394. Grid::invert_selection ( void )
  395. {
  396. lock();
  397. _rw->events.invert_selection();
  398. unlock();
  399. }
  400. void
  401. Grid::delete_selected ( void )
  402. {
  403. lock();
  404. _rw->events.remove_selected();
  405. unlock();
  406. }
  407. void
  408. Grid::move_selected ( int l )
  409. {
  410. long o = x_to_ts( abs( l ) );
  411. if ( l < 0 )
  412. o = 0 - o;
  413. lock();
  414. // MESSAGE( "moving by %ld", o );
  415. _rw->events.move_selected( o );
  416. unlock();
  417. }
  418. void
  419. Grid::crop ( int l, int r )
  420. {
  421. lock();
  422. if ( (uint)r < ts_to_x( _rw->length ) )
  423. delete_time( r, ts_to_x( _rw->length ) );
  424. if ( l > 0 )
  425. delete_time( 0, l );
  426. trim();
  427. unlock();
  428. }
  429. void
  430. Grid::crop ( int l, int r, int t, int b )
  431. {
  432. lock();
  433. _rw->events.push_selection();
  434. select( l, r, t, b );
  435. _rw->events.invert_selection();
  436. _rw->events.remove_selected();
  437. _rw->events.pop_selection();
  438. crop( l, r );
  439. unlock();
  440. }
  441. void
  442. Grid::_relink ( void )
  443. {
  444. _rw->events.relink();
  445. }
  446. /* Dump the event list -- used by pattern / phrase dumppers */
  447. void
  448. Grid::dump ( smf *f, int channel ) const
  449. {
  450. data *d = const_cast<data *>(_rd);
  451. midievent me;
  452. for ( event *e = d->events.first(); e; e = e->next() )
  453. {
  454. me = *e;
  455. me.channel( channel );
  456. f->write_event( &me );
  457. }
  458. }
  459. void
  460. Grid::print ( void ) const
  461. {
  462. data *d = const_cast<data *>(_rd);
  463. for ( event *e = d->events.first(); e; e = e->next() )
  464. e->print();
  465. }
  466. void
  467. Grid::draw ( Canvas *c, int bx, int by, int bw, int bh )
  468. {
  469. c->clear();
  470. tick_t start = x_to_ts( bx );
  471. tick_t end = x_to_ts( bx + bw );
  472. data *d = const_cast< data *>( _rd );
  473. for ( event *e = d->events.first(); e; e = e->next() )
  474. {
  475. if ( ! e->is_note_on() )
  476. continue;
  477. tick_t ts = e->timestamp();
  478. ASSERT( e->link(), "found a non-linked note" );
  479. tick_t tse = e->link()->timestamp();
  480. // if ( ts >= start && ts <= end )
  481. if ( tse >= start && ts <= end )
  482. c->draw_dash( ts_to_x( ts ), note_to_y( e->note() ), ts_to_x( tse - ts ),
  483. draw_shape(), e->note_velocity(), e->selected() );
  484. }
  485. c->flip();
  486. }
  487. /*******************************************/
  488. /* Generic accessors -- boy C++ is verbose */
  489. /*******************************************/
  490. /** Returns the index (playhead) for this grid */
  491. tick_t
  492. Grid::index ( void ) const
  493. {
  494. /* FIXME: considering the type of tick_t, we really need some kind
  495. of locking here to insure that this thread doesn't read _index
  496. while the RT thread is writing it. */
  497. return _index;
  498. }
  499. bool
  500. Grid::playing ( void ) const
  501. {
  502. return _playing;
  503. }
  504. int
  505. Grid::height ( void ) const
  506. {
  507. return _height;
  508. }
  509. void
  510. Grid::height ( int h )
  511. {
  512. _height = h;
  513. }
  514. tick_t
  515. Grid::length ( void ) const
  516. {
  517. return _rd->length;
  518. }
  519. void
  520. Grid::length ( tick_t l )
  521. {
  522. lock();
  523. _rw->length = l;
  524. unlock();
  525. }
  526. int
  527. Grid::bars ( void ) const
  528. {
  529. return ts_to_x( _rd->length ) / (_ppqn * _bpb);
  530. }
  531. int
  532. Grid::beats ( void ) const
  533. {
  534. return ts_to_x( _rd->length ) / _ppqn;
  535. }
  536. int
  537. Grid::division ( void ) const
  538. {
  539. return _bpb * _ppqn;
  540. }
  541. int
  542. Grid::subdivision ( void ) const
  543. {
  544. return _ppqn;
  545. }
  546. int
  547. Grid::ppqn ( void ) const
  548. {
  549. return _ppqn;
  550. }
  551. /** set grid resolution to /n/, where 0 is 1/4 note, 1 is 1/8 note 2 is 1/16 note, etc. */
  552. void
  553. Grid::resolution ( unsigned int n )
  554. {
  555. if ( n < 4 )
  556. ASSERTION( "bad resolution: %d", n );
  557. _ppqn = n / 4;
  558. DMESSAGE( "%d setting resolution to %d", n, _ppqn );
  559. signal_events_change();
  560. signal_settings_change();
  561. }
  562. int
  563. Grid::resolution ( void ) const
  564. {
  565. return _ppqn * 4;
  566. }
  567. int
  568. Grid::number ( void ) const
  569. {
  570. return _number;
  571. }
  572. void
  573. Grid::name ( char *s )
  574. {
  575. if ( _name ) free ( _name );
  576. _name = s;
  577. signal_settings_change();
  578. }
  579. const char *
  580. Grid::name ( void ) const
  581. {
  582. return _name;
  583. }
  584. void
  585. Grid::notes ( char *s )
  586. {
  587. if ( _notes ) free ( _notes );
  588. _notes = s;
  589. signal_settings_change();
  590. }
  591. char *
  592. Grid::notes ( void ) const
  593. {
  594. return _notes;
  595. }
  596. void
  597. Grid::mode ( int m )
  598. {
  599. _mode = m;
  600. /* can't do this in RT thread, sorry. */
  601. /// signal_settings_change();
  602. }
  603. int
  604. Grid::mode ( void ) const
  605. {
  606. return _mode;
  607. }
  608. /** return a pointer to a copy of grid's event list in raw form */
  609. event_list *
  610. Grid::events ( void ) const
  611. {
  612. data * d = const_cast< data * >( _rd );
  613. return new event_list( d->events );
  614. }
  615. /** replace event list with a copy of /el/ */
  616. void
  617. Grid::events ( const event_list * el )
  618. {
  619. lock();
  620. _rw->events = *el;
  621. unlock();
  622. }