Programmable real-time audio signal processing application
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cmdIf.h 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #ifndef cmdIf_h
  4. #define cmdIf_h
  5. class Fl_Output;
  6. // This class allows the 'model' to run independently
  7. // from the user interface. This eliminates problems with
  8. // application unresponsiveness which would arise from
  9. // executing compute intensive operations from UI control or
  10. // menu callback functions. It also allows a progress
  11. // or status bar to be shown while the model operation
  12. // is in progress.
  13. // The class works by enqueueing all incoming commands
  14. // into a thread-safe queue. An internal worker thread
  15. // executes the commands in the order they are received
  16. // and thereby changes the state of the model.
  17. // The results of model changes are posted to a second
  18. // thread-safe queue. These responses are picked
  19. // up by the onIdle() member and dispatched to an
  20. // object with a cmIfRspdr interface. Note that because
  21. // the onIdle() function is called from the applications
  22. // idle handler the callbacks to the cmIfRspdr are
  23. // always in the application thread and can therefore
  24. // safely interact with any application data constructs.
  25. // All calls to this object and all callbacks from it,
  26. // therefore occur in the application thread.
  27. class cmdIfRspdr
  28. {
  29. public:
  30. virtual ~cmdIfRspdr(){}
  31. virtual void cmdIfShowStatusMsg( const char* msg ) = 0;
  32. virtual void cmdIfHideStatus() = 0;
  33. virtual void cmdIfErrorMsg( const char* msg ) = 0;
  34. virtual void cmdIfTimeLineMsg( const void* msg, unsigned msgByteCnt ) = 0;
  35. virtual void cmdIfAudioFileLoad( unsigned fileId ) = 0;
  36. virtual void cmdIfScoreMsg( const void* msg, unsigned msgByteCnt ) = 0;
  37. virtual void cmdIfOnTimeLineMarkerSelect( unsigned markerId ) = 0;
  38. virtual void cmdIfOnTimeLineMidiEvtSelect(unsigned midiEvtId ) = 0;
  39. virtual void cmdIfOnScoreBarSelect( unsigned scoreIndex ) = 0;
  40. };
  41. class cmdIf
  42. {
  43. public:
  44. typedef enum
  45. {
  46. kOkRC,
  47. kCmdFailRC,
  48. kCmdEnqueueFailRC
  49. } rc_t;
  50. cmdIf( cmCtx_t* ctx, cmdIfRspdr* rspdr, const cmChar_t* audioPath=NULL );
  51. virtual ~cmdIf();
  52. // Open a time line.
  53. rc_t open( const cmChar_t* fn );
  54. // Close the time line.
  55. rc_t close();
  56. // Time line interface
  57. const cmChar_t* tlFileName() const;
  58. const cmTlObj_t* tlObjIdToPtr( unsigned tlObjId ) const;
  59. const cmTlMidiFile_t* tlMidiFileObjPtr( const cmTlObj_t* op ) const;
  60. const cmTlAudioFile_t* tlAudioFileObjPtr( const cmTlObj_t* op ) const;
  61. const cmTlMidiEvt_t* tlMidiEvtObjPtr( const cmTlObj_t* op ) const;
  62. const cmTlAudioEvt_t* tlAudioEvtObjPtr( const cmTlObj_t* op ) const;
  63. const cmTlMarker_t* tlMarkerObjPtr( const cmTlObj_t* op ) const;
  64. const cmChar_t* scoreFileName() const;
  65. const cmScoreEvt_t* scoreEventIdToPtr( unsigned scEvtId ) const;
  66. const cmScoreSection_t* scoreSectionIdToPtr( unsigned scSectId ) const;
  67. // Make a time line sequence active.
  68. rc_t selectSequence( unsigned id );
  69. // Load an audio file into the audio file mgr.
  70. // If an audio file path was set via setAudioFilePath() then
  71. // the directories referenced by 'fn' will be replaced by
  72. // the previously set audio file path.
  73. rc_t audioFileLoad( const cmChar_t* fn, unsigned appFileId );
  74. // Return the audio file handle assigned to appFileId.
  75. cmAfmFileH_t audioFileHandle( unsigned appFileId );
  76. // Set the audio file location.
  77. void setAudioFilePath( const cmChar_t* path );
  78. // Assign a score file
  79. rc_t setScore( const cmChar_t* scoreFn );
  80. // Set the current score location
  81. void setScoreLocation( unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel );
  82. // Set the value of a score variable
  83. void setScoreVarValue( unsigned locIdx, unsigned varId, double value );
  84. // Set the performed dynamic level of a score event.
  85. void setScoreDynLevel( unsigned evtIdx, unsigned dynLvl );
  86. void onTimeLineMarkerSelected( unsigned markerTlId );
  87. void onTimeLineMidiEvtSelected( unsigned midiEvtTlId );
  88. void onScoreBarSelected( unsigned scoreIndex );
  89. // Generate or delete Audio/MIDI onset markers.
  90. rc_t generateOnsetMarks();
  91. rc_t deleteOnsetMarks();
  92. // True if the worker thread is running.
  93. bool isBusy() const;
  94. // Called by the application to dequeue messages via callbacks to
  95. // the cmdIfRspdr.
  96. void onIdle();
  97. void testStub();
  98. private:
  99. // Id's used by cmd_t
  100. typedef enum
  101. {
  102. kInvalidCmdId, // 0
  103. kOpenCmdId, // 1 app->thread
  104. kCloseCmdId, // 2 app->thread
  105. kSelectSeqCmdId, // 3 app->thread
  106. kAfLoadCmdId, // 4 app->thread and thread->app
  107. kScoreCmdId, // 5 app->thread
  108. kShowStatusCmdId, // 6 thread->app
  109. kHideStatusCmdId, // 7 thread->app
  110. kErrMsgCmdId, // 8 thread->app
  111. kTimeLineMsgCmdId, // 9 thread->app
  112. kScoreMsgCmdId, //10 thread->app
  113. kGenOnsetMarksCmdId,
  114. kDelOnsetMarksCmdId
  115. } cmdId_t;
  116. // Messages are passed between the app and the worker thread
  117. // and v.v. using this record format. Note that the u.msg
  118. // field is always dynamically allocated by _enqueue()
  119. // and must be released following the dequeue operation.
  120. typedef struct cmd_str
  121. {
  122. cmdId_t id; // cmdId
  123. unsigned byteCnt; // length of msg
  124. unsigned value; // msg value
  125. union
  126. {
  127. void* msg; // msg[byteCnt]
  128. char* string; // string[byteCnt]
  129. } u;
  130. } cmd_t;
  131. cmCtx_t* _ctx; //
  132. cmErr_t _err; //
  133. cmThreadH_t _thH; // worker thread
  134. cmTs1p1cH_t _cmdQueH; // app->model
  135. cmTs1p1cH_t _outQueH; // model->appl
  136. cmTlH_t _tlH; // time line handle
  137. cmAfmH_t _afmH; // audio file manager
  138. cmScH_t _scH; // score handle
  139. cmChar_t* _afPath; //
  140. cmdIfRspdr* _rspdr; //
  141. unsigned _curSeqId; // seqId of last selected sequence
  142. // Functions called from the app thread.
  143. rc_t _sendCmd( cmdId_t id, unsigned value=0, const char* str=NULL );
  144. void _releaseQue( cmTs1p1cH_t* queHPtr );
  145. // Functions called from the worker thread
  146. static bool _thFunc( void* arg );
  147. void _thDoOpen( const cmd_t* cmd );
  148. void _thDoClose( const cmd_t* cmd );
  149. void _thDoSelectSeq( const cmd_t* cmd );
  150. void _thDoAfLoad( const cmd_t* cmd );
  151. void _thDoScore( const cmd_t* cmd );
  152. void _thDoGenOnsetMarks( const cmd_t* cmd );
  153. void _thDoDelOnsetMarks( const cmd_t* cmd );
  154. //void _thErrorMsg( const char* fmt, va_list vl );
  155. void _thErrorMsg( const char* fmt, ... );
  156. //void _thStatusMsg( const char* fmt, va_list vl );
  157. void _thStatusMsg( const char* fmt, ... );
  158. void _thSendResponse( cmdId_t id, const char* str = NULL, unsigned value=0 );
  159. static void _thSendTimeLineMsg( void* arg, const void* msg, unsigned byteCnt );
  160. static void _thSendScoreMsg( void* arg, const void* msg, unsigned byteCnt );
  161. // Thread independent functions
  162. rc_t _enqueue( cmTs1p1cH_t qH, cmdId_t id, unsigned value, const void* msg, unsigned msgByteCnt );
  163. // Print context information for selected time line objects
  164. void _onTimeLineObjSelected( unsigned tlObjId );
  165. };
  166. #endif