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.5KB

  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. /** return true if any playback stream's buffer is less than 50% full */
  98. bool
  99. Timeline::seek_pending ( void )
  100. {
  101. // THREAD_ASSERT( RT );
  102. for ( int i = tracks->children(); i-- ; )
  103. {
  104. Track *t = (Track*)tracks->child( i );
  105. if ( t->playback_ds )
  106. if ( t->playback_ds->buffer_percent() < 50 )
  107. return true;
  108. }
  109. return false;
  110. }
  111. /* FIXME: shouldn't these belong to the engine? */
  112. int
  113. Timeline::total_input_buffer_percent ( void )
  114. {
  115. int r = 0;
  116. int cnt = 0;
  117. for ( int i = tracks->children(); i-- ; )
  118. {
  119. Track *t = (Track*)tracks->child( i );
  120. if ( t->record_ds )
  121. {
  122. ++cnt;
  123. r += t->record_ds->buffer_percent();
  124. }
  125. }
  126. if ( ! cnt )
  127. return 0;
  128. return r / cnt;
  129. }
  130. int
  131. Timeline::total_output_buffer_percent ( void )
  132. {
  133. int r = 0;
  134. int cnt = 0;
  135. for ( int i = tracks->children(); i-- ; )
  136. {
  137. Track *t = (Track*)tracks->child( i );
  138. if ( t->playback_ds )
  139. {
  140. ++cnt;
  141. r += t->playback_ds->buffer_percent();
  142. }
  143. }
  144. if ( ! cnt )
  145. return 0;
  146. return r / cnt;
  147. }
  148. /** wait for I/O threads to fill their buffers */
  149. void
  150. Timeline::wait_for_buffers ( void )
  151. {
  152. while ( total_output_buffer_percent() + total_input_buffer_percent() < 200 )
  153. usleep( 5000 );
  154. }
  155. int
  156. Timeline::total_playback_xruns ( void )
  157. {
  158. int r = 0;
  159. for ( int i = tracks->children(); i-- ; )
  160. {
  161. Track *t = (Track*)tracks->child( i );
  162. if ( t->playback_ds )
  163. r += t->playback_ds->xruns();
  164. }
  165. return r;
  166. }
  167. int
  168. Timeline::total_capture_xruns ( void )
  169. {
  170. int r = 0;
  171. for ( int i = tracks->children(); i-- ; )
  172. {
  173. Track *t = (Track*)tracks->child( i );
  174. if ( t->record_ds )
  175. r += t->record_ds->xruns();
  176. }
  177. return r;
  178. }
  179. #include "Engine.H"
  180. extern Engine *engine;
  181. nframes_t
  182. Timeline::total_output_latency ( void ) const
  183. {
  184. /* Due to flaws in the JACK latency reporting API, we cannot
  185. * reliably account for software latency. Using the system latency
  186. * is the best we can do here. */
  187. return engine->system_latency();
  188. }