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.

146 lines
4.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 "Disk_Stream.H"
  19. #include "Track_Header.H"
  20. #include "Audio_Track.H"
  21. #include "Port.H"
  22. #include "Engine.H" // for locking.
  23. #include "dsp.h"
  24. /**********/
  25. /* Engine */
  26. /**********/
  27. /* A Disk_Stream uses a separate I/O thread to stream a track's
  28. regions from disk into a ringbuffer to be processed by the RT
  29. thread (or vice-versa). The I/O thread syncronizes access with the
  30. user thread via the Timeline mutex. The size of the buffer (in
  31. seconds) must be set before any Disk_Stream objects are created;
  32. that is, at startup time. The default is 5 seconds, which may or
  33. may not be excessive depending on various external factors. */
  34. /* FIXME: handle termination of IO thread in destructor */
  35. /* FIXME: deal with (jack) buffer size changes */
  36. /* FIXME: needs error handling everywhere! */
  37. /* TODO: handle capture too. For this to work with some kind of
  38. * punch-in/out system, I believe we'll have to always keep at least
  39. * one buffer's worth of input. We would need this anyway in order to
  40. * pass input through to output (software monitoring). What about
  41. * looped recording? */
  42. /* TODO: latency compensation? Does this really apply to us? (we're
  43. * not hosting plugins here) */
  44. /* TODO: read/write data from/to disk in larger chunks to avoid
  45. * excessive seeking. 256k is supposedly the sweetspot. */
  46. float Disk_Stream::seconds_to_buffer = 5.0f;
  47. // size_t Disk_Stream::disk_block_frames = 2048;
  48. Disk_Stream::Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) : _th( th )
  49. {
  50. _frame = 0;
  51. _thread = 0;
  52. _terminate = false;
  53. _pending_seek = -1;
  54. printf( "nframes %lu\n", nframes );
  55. _total_blocks = frame_rate * seconds_to_buffer / nframes;
  56. _nframes = nframes;
  57. size_t bufsize = _total_blocks * nframes * sizeof( sample_t );
  58. for ( int i = channels; i--; )
  59. _rb.push_back( jack_ringbuffer_create( bufsize ) );
  60. sem_init( &_blocks, 0, _total_blocks );
  61. // run();
  62. }
  63. Disk_Stream::~Disk_Stream ( )
  64. {
  65. /* stop the IO thread */
  66. _terminate = true;
  67. pthread_join( _thread, NULL );
  68. /* it isn't safe to do all this with the RT thread running */
  69. engine->lock();
  70. _th = NULL;
  71. sem_destroy( &_blocks );
  72. for ( int i = channels(); i--; )
  73. jack_ringbuffer_free( _rb[ i ] );
  74. engine->unlock();
  75. }
  76. Audio_Track *
  77. Disk_Stream::track ( void )
  78. {
  79. return (Audio_Track*)_th->track();
  80. }
  81. /** start Disk_Stream thread */
  82. void
  83. Disk_Stream::run ( void )
  84. {
  85. if ( pthread_create( &_thread, NULL, &Disk_Stream::disk_thread, this ) != 0 )
  86. /* error */;
  87. }
  88. /* to be called when the JACK buffer size changes. */
  89. void
  90. Disk_Stream::resize ( nframes_t nframes )
  91. {
  92. if ( nframes != _nframes )
  93. /* FIXME: to something here! */;
  94. }
  95. /* void */
  96. /* DIsk_Stream::shutdown ( void ) */
  97. /* { */
  98. /* pthread_join( &_thread, NULL ); */
  99. /* } */
  100. /* static wrapper */
  101. void *
  102. Disk_Stream::disk_thread ( void *arg )
  103. {
  104. ((Disk_Stream*)arg)->disk_thread();
  105. return NULL;
  106. }
  107. int
  108. Disk_Stream::buffer_percent ( void )
  109. {
  110. int n;
  111. sem_getvalue( &_blocks, &n );
  112. return 100 - (n * 100 / _total_blocks);
  113. }