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.

250 lines
5.4KB

  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 "../Timeline.H"
  19. #include "../Transport.H" // for .rolling
  20. #include "../Track.H"
  21. #include "Record_DS.H"
  22. #include "Playback_DS.H"
  23. #include "util/Thread.H"
  24. /** Initiate recording for all armed tracks */
  25. bool
  26. Timeline::record ( void )
  27. {
  28. /* FIXME: right place for this? */
  29. transport->recording = true;
  30. Loggable::block_start();
  31. nframes_t frame = transport->frame;
  32. DMESSAGE( "Going to record starting at frame %lu", (unsigned long)frame );
  33. for ( int i = tracks->children(); i-- ; )
  34. {
  35. Track *t = (Track*)tracks->child( i );
  36. if ( t->armed() && t->record_ds )
  37. t->record_ds->start( frame );
  38. }
  39. deactivate();
  40. return true;
  41. }
  42. /** stop recording for all armed tracks */
  43. void
  44. Timeline::stop ( void )
  45. {
  46. nframes_t frame = transport->frame;
  47. for ( int i = tracks->children(); i-- ; )
  48. {
  49. Track *t = (Track*)tracks->child( i );
  50. if ( t->armed() && t->record_ds )
  51. t->record_ds->stop( frame );
  52. }
  53. Loggable::block_end();
  54. activate();
  55. transport->recording = false;
  56. }
  57. /**********/
  58. /* Engine */
  59. /**********/
  60. /** call process() on each track header */
  61. nframes_t
  62. Timeline::process ( nframes_t nframes )
  63. {
  64. for ( int i = tracks->children(); i-- ; )
  65. {
  66. Track *t = (Track*)tracks->child( i );
  67. t->process_output( nframes );
  68. }
  69. for ( int i = tracks->children(); i-- ; )
  70. {
  71. Track *t = (Track*)tracks->child( i );
  72. t->process_input( nframes );
  73. }
  74. /* FIXME: BOGUS */
  75. return nframes;
  76. }
  77. void
  78. Timeline::seek ( nframes_t frame )
  79. {
  80. THREAD_ASSERT( RT );
  81. for ( int i = tracks->children(); i-- ; )
  82. {
  83. Track *t = (Track*)tracks->child( i );
  84. t->seek( frame );
  85. }
  86. }
  87. /* THREAD: RT (non-RT) */
  88. void
  89. Timeline::resize_buffers ( nframes_t nframes )
  90. {
  91. for ( int i = tracks->children(); i-- ; )
  92. {
  93. Track *t = (Track*)tracks->child( i );
  94. t->resize_buffers( nframes );
  95. }
  96. }
  97. int
  98. Timeline::seek_pending ( void )
  99. {
  100. THREAD_ASSERT( RT );
  101. int r = 0;
  102. for ( int i = tracks->children(); i-- ; )
  103. {
  104. Track *t = (Track*)tracks->child( i );
  105. if ( t->playback_ds )
  106. r += t->playback_ds->buffer_percent() < 50;
  107. }
  108. return r;
  109. }
  110. /* FIXME: shouldn't these belong to the engine? */
  111. int
  112. Timeline::total_input_buffer_percent ( void )
  113. {
  114. int r = 0;
  115. int cnt = 0;
  116. for ( int i = tracks->children(); i-- ; )
  117. {
  118. Track *t = (Track*)tracks->child( i );
  119. if ( t->record_ds )
  120. {
  121. ++cnt;
  122. r += t->record_ds->buffer_percent();
  123. }
  124. }
  125. if ( ! cnt )
  126. return 0;
  127. return r / cnt;
  128. }
  129. int
  130. Timeline::total_output_buffer_percent ( void )
  131. {
  132. int r = 0;
  133. int cnt = 0;
  134. for ( int i = tracks->children(); i-- ; )
  135. {
  136. Track *t = (Track*)tracks->child( i );
  137. if ( t->playback_ds )
  138. {
  139. ++cnt;
  140. r += t->playback_ds->buffer_percent();
  141. }
  142. }
  143. if ( ! cnt )
  144. return 0;
  145. return r / cnt;
  146. }
  147. /** wait for I/O threads to fill their buffers */
  148. void
  149. Timeline::wait_for_buffers ( void )
  150. {
  151. while ( total_output_buffer_percent() + total_input_buffer_percent() < 200 )
  152. usleep( 5000 );
  153. }
  154. int
  155. Timeline::total_playback_xruns ( void )
  156. {
  157. int r = 0;
  158. for ( int i = tracks->children(); i-- ; )
  159. {
  160. Track *t = (Track*)tracks->child( i );
  161. if ( t->playback_ds )
  162. r += t->playback_ds->xruns();
  163. }
  164. return r;
  165. }
  166. int
  167. Timeline::total_capture_xruns ( void )
  168. {
  169. int r = 0;
  170. for ( int i = tracks->children(); i-- ; )
  171. {
  172. Track *t = (Track*)tracks->child( i );
  173. if ( t->record_ds )
  174. r += t->record_ds->xruns();
  175. }
  176. return r;
  177. }
  178. #include "Engine.H"
  179. extern Engine *engine;
  180. nframes_t
  181. Timeline::total_output_latency ( void ) const
  182. {
  183. /* Due to flaws in the JACK latency reporting API, we cannot
  184. * reliably account for software latency. Using the system latency
  185. * is the best we can do here. */
  186. return engine->system_latency();
  187. }