123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- //| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org>
- //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
- #ifndef cmdIf_h
- #define cmdIf_h
-
- class Fl_Output;
-
-
- // This class allows the 'model' to run independently
- // from the user interface. This eliminates problems with
- // application unresponsiveness which would arise from
- // executing compute intensive operations from UI control or
- // menu callback functions. It also allows a progress
- // or status bar to be shown while the model operation
- // is in progress.
-
- // The class works by enqueueing all incoming commands
- // into a thread-safe queue. An internal worker thread
- // executes the commands in the order they are received
- // and thereby changes the state of the model.
-
- // The results of model changes are posted to a second
- // thread-safe queue. These responses are picked
- // up by the onIdle() member and dispatched to an
- // object with a cmIfRspdr interface. Note that because
- // the onIdle() function is called from the applications
- // idle handler the callbacks to the cmIfRspdr are
- // always in the application thread and can therefore
- // safely interact with any application data constructs.
-
- // All calls to this object and all callbacks from it,
- // therefore occur in the application thread.
-
-
- class cmdIfRspdr
- {
- public:
- virtual ~cmdIfRspdr(){}
- virtual void cmdIfShowStatusMsg( const char* msg ) = 0;
- virtual void cmdIfHideStatus() = 0;
- virtual void cmdIfErrorMsg( const char* msg ) = 0;
- virtual void cmdIfTimeLineMsg( const void* msg, unsigned msgByteCnt ) = 0;
- virtual void cmdIfAudioFileLoad( unsigned fileId ) = 0;
- virtual void cmdIfScoreMsg( const void* msg, unsigned msgByteCnt ) = 0;
-
- virtual void cmdIfOnTimeLineMarkerSelect( unsigned markerId ) = 0;
- virtual void cmdIfOnTimeLineMidiEvtSelect(unsigned midiEvtId ) = 0;
- virtual void cmdIfOnScoreBarSelect( unsigned scoreIndex ) = 0;
-
-
- };
-
- class cmdIf
- {
- public:
-
- typedef enum
- {
- kOkRC,
- kCmdFailRC,
- kCmdEnqueueFailRC
- } rc_t;
-
- cmdIf( cmCtx_t* ctx, cmdIfRspdr* rspdr, const cmChar_t* audioPath=NULL );
- virtual ~cmdIf();
-
- // Open a time line.
- rc_t open( const cmChar_t* fn );
-
- // Close the time line.
- rc_t close();
-
- // Time line interface
- const cmChar_t* tlFileName() const;
- const cmTlObj_t* tlObjIdToPtr( unsigned tlObjId ) const;
- const cmTlMidiFile_t* tlMidiFileObjPtr( const cmTlObj_t* op ) const;
- const cmTlAudioFile_t* tlAudioFileObjPtr( const cmTlObj_t* op ) const;
- const cmTlMidiEvt_t* tlMidiEvtObjPtr( const cmTlObj_t* op ) const;
- const cmTlAudioEvt_t* tlAudioEvtObjPtr( const cmTlObj_t* op ) const;
- const cmTlMarker_t* tlMarkerObjPtr( const cmTlObj_t* op ) const;
-
- const cmChar_t* scoreFileName() const;
- const cmScoreEvt_t* scoreEventIdToPtr( unsigned scEvtId ) const;
- const cmScoreSection_t* scoreSectionIdToPtr( unsigned scSectId ) const;
-
- // Make a time line sequence active.
- rc_t selectSequence( unsigned id );
-
- // Load an audio file into the audio file mgr.
- // If an audio file path was set via setAudioFilePath() then
- // the directories referenced by 'fn' will be replaced by
- // the previously set audio file path.
- rc_t audioFileLoad( const cmChar_t* fn, unsigned appFileId );
-
- // Return the audio file handle assigned to appFileId.
- cmAfmFileH_t audioFileHandle( unsigned appFileId );
-
- // Set the audio file location.
- void setAudioFilePath( const cmChar_t* path );
-
- // Assign a score file
- rc_t setScore( const cmChar_t* scoreFn );
-
- // Set the current score location
- void setScoreLocation( unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel );
-
- // Set the value of a score variable
- void setScoreVarValue( unsigned locIdx, unsigned varId, double value );
-
- // Set the performed dynamic level of a score event.
- void setScoreDynLevel( unsigned evtIdx, unsigned dynLvl );
-
- void onTimeLineMarkerSelected( unsigned markerTlId );
- void onTimeLineMidiEvtSelected( unsigned midiEvtTlId );
- void onScoreBarSelected( unsigned scoreIndex );
-
- // Generate or delete Audio/MIDI onset markers.
- rc_t generateOnsetMarks();
- rc_t deleteOnsetMarks();
-
- // True if the worker thread is running.
- bool isBusy() const;
-
- // Called by the application to dequeue messages via callbacks to
- // the cmdIfRspdr.
- void onIdle();
-
- void testStub();
-
- private:
-
- // Id's used by cmd_t
- typedef enum
- {
- kInvalidCmdId, // 0
- kOpenCmdId, // 1 app->thread
- kCloseCmdId, // 2 app->thread
- kSelectSeqCmdId, // 3 app->thread
- kAfLoadCmdId, // 4 app->thread and thread->app
- kScoreCmdId, // 5 app->thread
- kShowStatusCmdId, // 6 thread->app
- kHideStatusCmdId, // 7 thread->app
- kErrMsgCmdId, // 8 thread->app
- kTimeLineMsgCmdId, // 9 thread->app
- kScoreMsgCmdId, //10 thread->app
- kGenOnsetMarksCmdId,
- kDelOnsetMarksCmdId
-
- } cmdId_t;
-
- // Messages are passed between the app and the worker thread
- // and v.v. using this record format. Note that the u.msg
- // field is always dynamically allocated by _enqueue()
- // and must be released following the dequeue operation.
- typedef struct cmd_str
- {
- cmdId_t id; // cmdId
- unsigned byteCnt; // length of msg
- unsigned value; // msg value
-
- union
- {
- void* msg; // msg[byteCnt]
- char* string; // string[byteCnt]
- } u;
- } cmd_t;
-
- cmCtx_t* _ctx; //
- cmErr_t _err; //
- cmThreadH_t _thH; // worker thread
- cmTs1p1cH_t _cmdQueH; // app->model
- cmTs1p1cH_t _outQueH; // model->appl
- cmTlH_t _tlH; // time line handle
- cmAfmH_t _afmH; // audio file manager
- cmScH_t _scH; // score handle
- cmChar_t* _afPath; //
- cmdIfRspdr* _rspdr; //
- unsigned _curSeqId; // seqId of last selected sequence
-
-
- // Functions called from the app thread.
- rc_t _sendCmd( cmdId_t id, unsigned value=0, const char* str=NULL );
- void _releaseQue( cmTs1p1cH_t* queHPtr );
-
- // Functions called from the worker thread
- static bool _thFunc( void* arg );
- void _thDoOpen( const cmd_t* cmd );
- void _thDoClose( const cmd_t* cmd );
- void _thDoSelectSeq( const cmd_t* cmd );
- void _thDoAfLoad( const cmd_t* cmd );
- void _thDoScore( const cmd_t* cmd );
- void _thDoGenOnsetMarks( const cmd_t* cmd );
- void _thDoDelOnsetMarks( const cmd_t* cmd );
-
- //void _thErrorMsg( const char* fmt, va_list vl );
- void _thErrorMsg( const char* fmt, ... );
- //void _thStatusMsg( const char* fmt, va_list vl );
- void _thStatusMsg( const char* fmt, ... );
- void _thSendResponse( cmdId_t id, const char* str = NULL, unsigned value=0 );
- static void _thSendTimeLineMsg( void* arg, const void* msg, unsigned byteCnt );
- static void _thSendScoreMsg( void* arg, const void* msg, unsigned byteCnt );
-
- // Thread independent functions
- rc_t _enqueue( cmTs1p1cH_t qH, cmdId_t id, unsigned value, const void* msg, unsigned msgByteCnt );
-
-
- // Print context information for selected time line objects
- void _onTimeLineObjSelected( unsigned tlObjId );
-
- };
-
-
- #endif
|