libcm is a C development framework with an emphasis on audio signal processing applications.
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.

cmTimeLine.h 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #ifndef cmTimeLine_h
  4. #define cmTimeLine_h
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. //( { file_desc:"Manage, save, and restore a time-line containing MIDI files, Audio files, Audio events, and arbitrary markers ." kw[seq] }
  9. typedef cmHandle_t cmTlH_t;
  10. typedef cmRC_t cmTlRC_t;
  11. enum
  12. {
  13. kOkTlRC = cmOkRC,
  14. kLHeapFailTlRC,
  15. kParseFailTlRC,
  16. kJsonFailTlRC,
  17. kDuplNameTlRC,
  18. kRefNotFoundTlRC,
  19. kAudioFileFailTlRC,
  20. kMidiFileFailTlRC,
  21. kTypeCvtFailTlRC,
  22. kUnknownRecdTypeTlRC,
  23. kFinalizeFailTlRC,
  24. kInvalidSeqIdTlRC,
  25. kOnsetFailTlRC,
  26. kAssertFailTlRC,
  27. kRptFileFailTlRC
  28. };
  29. typedef enum
  30. {
  31. kMidiFileTlId = 0x01,
  32. kMidiEvtTlId = 0x02,
  33. kAudioFileTlId = 0x03,
  34. kAudioEvtTlId = 0x04,
  35. kMarkerTlId = 0x05
  36. } cmTlObjTypeId_t;
  37. enum
  38. {
  39. kReservedTlFl = 0x01,
  40. kNoWriteTlFl = 0x02 // do not write this object in cmTimeLineWrite()
  41. };
  42. // marker types
  43. enum
  44. {
  45. kAudioMarkTlId,
  46. kAudioOnsetMarkTlId,
  47. kMidiOnsetMarkTlId
  48. };
  49. typedef void (*cmTlCb_t)( void* arg, const void* data, unsigned byteCnt );
  50. typedef struct cmTlObj_str
  51. {
  52. void* reserved; // pt's to _cmTlObj_t
  53. unsigned seqId; // sequence this object is assigned to
  54. const cmChar_t* name; // text name of this object
  55. unsigned uid; // generated unique id for this object
  56. cmTlObjTypeId_t typeId; // type of the object
  57. struct cmTlObj_str* ref; // time reference object
  58. int begSmpIdx; // start time of this object as an offset from the start time of the reference object
  59. unsigned durSmpCnt; // duration of this object
  60. int seqSmpIdx; // absolute start time of this object within the sequence
  61. const cmChar_t* text; // points to text assoc'd with this node (file name for audio/midi file, marker text)
  62. unsigned flags; // see kXXXTlFl
  63. void* userDataPtr; // user customizable data pointer
  64. } cmTlObj_t;
  65. typedef struct
  66. {
  67. cmTlObj_t obj;
  68. cmMidiFileH_t h;
  69. unsigned noteOnCnt;
  70. cmChar_t* fn;
  71. } cmTlMidiFile_t;
  72. // MIDI events generated from MIDI files reference the previous
  73. // MIDI event and the first event in the file references the
  74. // file object. The 'begSmpIdx' is therefore a delta value
  75. // from the previous event.
  76. typedef struct
  77. {
  78. cmTlObj_t obj; //
  79. unsigned midiFileObjId;
  80. const cmMidiTrackMsg_t* msg; // w/ dticks converted to samples
  81. } cmTlMidiEvt_t;
  82. typedef struct
  83. {
  84. cmTlObj_t obj;
  85. cmAudioFileH_t h;
  86. cmAudioFileInfo_t info;
  87. cmChar_t* fn;
  88. } cmTlAudioFile_t;
  89. typedef struct
  90. {
  91. cmTlObj_t obj;
  92. cmAudioFileH_t h;
  93. unsigned smpIdx;
  94. unsigned smpCnt;
  95. cmChar_t* text;
  96. } cmTlAudioEvt_t;
  97. typedef struct
  98. {
  99. cmTlObj_t obj;
  100. unsigned typeId; // marker type see kXXXMarkTlId above.
  101. const cmChar_t* text;
  102. unsigned bar; // measure (bar) in which this marker starts
  103. const cmChar_t* sectionStr; // the section in which this marker starts
  104. } cmTlMarker_t;
  105. extern cmTlH_t cmTimeLineNullHandle;
  106. //
  107. cmTlRC_t cmTimeLineInitialize( cmCtx_t* ctx, cmTlH_t* hp, cmTlCb_t cbFunc, void* cbArg, const cmChar_t* prefixPath );
  108. cmTlRC_t cmTimeLineInitializeFromFile( cmCtx_t* ctx, cmTlH_t* hp, cmTlCb_t cbFunc, void* cbArg, const cmChar_t* fn, const cmChar_t* prefixPath );
  109. const cmChar_t* cmTimeLineFileName( cmTlH_t h );
  110. const cmChar_t* cmTimeLinePrefixPath( cmTlH_t h );
  111. cmTlRC_t cmTimeLineFinalize( cmTlH_t* hp );
  112. bool cmTimeLineIsValid( cmTlH_t h );
  113. double cmTimeLineSampleRate( cmTlH_t h );
  114. // Convert global (sequence) time to a time relative to an object.
  115. int cmTimeLineSeqToLocalSampleIndex( int seqSmpIdx, cmTlObj_t* localObjPtr );
  116. // Given cmTlObj_t.uid return a pointer to the associated record.
  117. // seqId is optional (dflt:cmInvalidId)
  118. cmTlObj_t* cmTimeLineIdToObj( cmTlH_t h, unsigned seqId, unsigned uid );
  119. // Return the object following 'p' assigned to 'seqId'.
  120. // If 'p' is NULL then return the first object assigned to seqId.
  121. // If 'seqId' is set to cmInvalidId then return the next object on any seq.
  122. // If no objects follow 'p' on the specified sequence then return NULL.
  123. cmTlObj_t* cmTimeLineNextObj( cmTlH_t h, cmTlObj_t* p, unsigned seqId );
  124. // Same as cmTimeLineNextObj() but returns next object whose type matches 'typeId'.
  125. cmTlObj_t* cmTimeLineNextTypeObj( cmTlH_t h, cmTlObj_t* p, unsigned seqId, unsigned typeId );
  126. cmTlMidiFile_t* cmTlNextMidiFileObjPtr( cmTlH_t h, cmTlObj_t* op, unsigned seqId );
  127. cmTlAudioFile_t* cmTlNextAudioFileObjPtr( cmTlH_t h, cmTlObj_t* op, unsigned seqId );
  128. cmTlMidiEvt_t* cmTlNextMidiEvtObjPtr( cmTlH_t h, cmTlObj_t* op, unsigned seqId );
  129. cmTlAudioEvt_t* cmTlNextAudioEvtObjPtr( cmTlH_t h, cmTlObj_t* op, unsigned seqId );
  130. cmTlMarker_t* cmTlNextMarkerObjPtr( cmTlH_t h, cmTlObj_t* op, unsigned seqId );
  131. cmTlObj_t* cmTlIdToObjPtr( cmTlH_t h, unsigned uid );
  132. // Cast a genereic cmTlObj_t pointer to a specific type.
  133. cmTlMidiFile_t* cmTimeLineMidiFileObjPtr( cmTlH_t h, cmTlObj_t* op );
  134. cmTlAudioFile_t* cmTimeLineAudioFileObjPtr( cmTlH_t h, cmTlObj_t* op );
  135. cmTlMidiEvt_t* cmTimeLineMidiEvtObjPtr( cmTlH_t h, cmTlObj_t* op );
  136. cmTlAudioEvt_t* cmTimeLineAudioEvtObjPtr( cmTlH_t h, cmTlObj_t* op );
  137. cmTlMarker_t* cmTimeLineMarkerObjPtr( cmTlH_t h, cmTlObj_t* op );
  138. // Same as cmTimeLineXXXObjPtr() but does not generate an error when
  139. // 'op' does not point to the correct type. These function quietly
  140. // return NULL if the requested type does not match or 'op' == NULL.
  141. cmTlMidiFile_t* cmTlMidiFileObjPtr( cmTlH_t h, cmTlObj_t* op );
  142. cmTlAudioFile_t* cmTlAudioFileObjPtr( cmTlH_t h, cmTlObj_t* op );
  143. cmTlMidiEvt_t* cmTlMidiEvtObjPtr( cmTlH_t h, cmTlObj_t* op );
  144. cmTlAudioEvt_t* cmTlAudioEvtObjPtr( cmTlH_t h, cmTlObj_t* op );
  145. cmTlMarker_t* cmTlMarkerObjPtr( cmTlH_t h, cmTlObj_t* op );
  146. cmTlAudioFile_t* cmTimeLineFindAudioFile( cmTlH_t h, const cmChar_t* fn );
  147. cmTlMidiFile_t* cmTimeLineFindMidiFile( cmTlH_t h, const cmChar_t* fn );
  148. cmTlAudioFile_t* cmTimeLineAudioFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  149. cmTlMidiFile_t* cmTimeLineMidiFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  150. cmTlMidiEvt_t* cmTimeLineMidiEvtAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  151. cmTlMarker_t* cmTimeLineMarkerAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  152. cmTlAudioFile_t* cmTimeLineAudioFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  153. cmTlMidiFile_t* cmTimeLineMidiFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  154. cmTlMidiEvt_t* cmTimeLineMidiEvtAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  155. cmTlMarker_t* cmTimeLineMarkerAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
  156. cmTlMarker_t* cmTimeLineMarkerFind( cmTlH_t h, const cmChar_t* markText );
  157. // 'typeId' = kAudioFileTlId, kMidiFileTId, kMarkerTlId.
  158. // 'nameStr' and 'refObjNameStr' may be NULL.
  159. cmTlRC_t cmTimeLineInsert(
  160. cmTlH_t h,
  161. const cmChar_t* nameStr,
  162. unsigned typeId,
  163. const cmChar_t* fn_or_markerStr,
  164. int begSmpIdx,
  165. unsigned durSmpCnt,
  166. const cmChar_t* refObjNameStr,
  167. unsigned seqId );
  168. // See src/data/tl0.json for an example JSON file.
  169. cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn );
  170. // Return a count of sequences contained within this timeline.
  171. unsigned cmTimeLineSeqCount( cmTlH_t h );
  172. // Make notifications for all records belonging to the sequence.
  173. cmTlRC_t cmTimeLineSeqNotify( cmTlH_t h, unsigned seqId );
  174. // Create and make notification for audio/MIDI onset marks.
  175. cmTlRC_t cmTimeLineGenOnsetMarks( cmTlH_t h, unsigned seqId );
  176. cmTlRC_t cmTimeLineDeleteOnsetMarks( cmTlH_t h, unsigned seqId );
  177. cmTlRC_t cmTimeLineWrite( cmTlH_t h, const cmChar_t* fn );
  178. cmTlRC_t cmTimeLinePrint( cmTlH_t h, cmRpt_t* rpt );
  179. cmTlRC_t cmTimeLinePrintFn( cmCtx_t* ctx, const cmChar_t* tlFn, const cmChar_t* prefixPath, cmRpt_t* rpt );
  180. cmTlRC_t cmTimeLineReport( cmCtx_t* ctx, const cmChar_t* tlFn, const cmChar_t* prefixPath, const cmChar_t* rptFn );
  181. cmTlRC_t cmTimeLineTest( cmCtx_t* ctx, const cmChar_t* tlFn, const cmChar_t* prefixPath );
  182. // The time-line notifies listeners of initialization and finalization
  183. // events via calling a cmTlCbFunc_t function. The argument to this
  184. // function is a serialized cmTlUiMsg_t. The recipient of the callback
  185. // can extract information from this message using cmTimeLineDecode()
  186. // to form a cmTlUiMsg_t record. Note that all pointers internal to the
  187. // cmTlUiMsg_t point into the message buffer itself.
  188. // id's used to indicate the type of a serialized object
  189. typedef enum
  190. {
  191. kInvalidMsgTlId,
  192. kInitMsgTlId, // A a set of time-line objects is about to be transmitted
  193. kFinalMsgTlId, // A time-line object is being finalized.
  194. kDoneMsgTlId, // All the objects assoc'd with a time line seq-notify have been sent.
  195. kInsertMsgTlId, // A time-line object was inserted.
  196. } cmTlUiMsgTypeId_t;
  197. typedef struct
  198. {
  199. cmTlUiMsgTypeId_t msgId; // See cmTlUiMsgTypeId_t.
  200. unsigned objId; // Set to cmTlObj_t.uid
  201. unsigned seqId; // Sequence id
  202. double srate; // Only valid with kInitMsgTlId.
  203. unsigned seqCnt; // Only valid with kInitMsgTlId.
  204. } cmTlUiMsg_t;
  205. // Decode a serialized cmTlObj_t as passed to the cmTlCb_t listener
  206. // callback function.
  207. cmTlRC_t cmTimeLineDecode( const void* msg, unsigned msgByteCnt, cmTlUiMsg_t* uiMsg );
  208. //)
  209. #ifdef __cplusplus
  210. }
  211. #endif
  212. #endif