libcm is a C development framework with an emphasis on audio signal processing applications.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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 cmScore_h
  4. #define cmScore_h
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. //( { file_desc:"Object for managing musical score data." kw:[score]}
  9. enum
  10. {
  11. kOkScRC = cmOkRC,
  12. kCsvFailScRC,
  13. kSyntaxErrScRC,
  14. kInvalidIdxScRC,
  15. kTimeLineFailScRC,
  16. kInvalidDynRefCntScRC,
  17. kMidiFileFailScRC,
  18. kPedalInvalidScRC,
  19. kFileFailScRC
  20. };
  21. enum
  22. {
  23. kInvalidEvtScId = 0,
  24. kTimeSigEvtScId,
  25. kKeySigEvtScId,
  26. kTempoEvtScId,
  27. kTrackEvtScId,
  28. kTextEvtScId,
  29. kNameEvtScId,
  30. kEOTrackEvtScId,
  31. kCopyEvtScId,
  32. kBlankEvtScId,
  33. kBarEvtScId,
  34. kPgmEvtScId,
  35. kCtlEvtScId,
  36. kNonEvtScId,
  37. kPedalEvtScId
  38. };
  39. // Flags used by cmScoreEvt_t.flags
  40. enum
  41. {
  42. kEvenScFl = 0x001, // This note is marked for evenness measurement
  43. kDynScFl = 0x002, // This note is marked for dynamics measurement
  44. kTempoScFl = 0x004, // This note is marked for tempo measurement
  45. kSkipScFl = 0x008, // This isn't a real event (e.g. tied note) skip over it
  46. kGraceScFl = 0x010, // This is a grace note
  47. kInvalidScFl = 0x020, // This note has a calculated time
  48. kPedalDnScFl = 0x040, // This is a pedal down event (pitch holds the pedal id and durSecs holds the time the pedal will remain down.)
  49. kPedalUpScFl = 0x080 // This is a pedal up event (pitch holds the pedal id)
  50. };
  51. // Id's used by cmScoreSet_t.varId and as indexes into
  52. // cmScoreSection_t.vars[].
  53. enum
  54. {
  55. kInvalidVarScId, // 0
  56. kEvenVarScId, // 1
  57. kDynVarScId, // 2
  58. kTempoVarScId, // 3
  59. kScVarCnt
  60. };
  61. struct cmScoreLoc_str;
  62. struct cmScoreSet_str;
  63. // The score can be divided into arbitrary non-overlapping sections.
  64. typedef struct
  65. {
  66. const cmChar_t* label; // section label
  67. unsigned index; // index of this record in the internal section array
  68. struct cmScoreLoc_str* locPtr; // location where this section starts
  69. unsigned begEvtIndex; // score element index where this section starts
  70. unsigned setCnt; // Count of elements in setArray[]
  71. struct cmScoreSet_str** setArray; // Ptrs to sets which are applied to this section.
  72. double vars[ kScVarCnt ]; // Set to DBL_MAX by default.
  73. } cmScoreSection_t;
  74. typedef struct
  75. {
  76. unsigned type; // Event type
  77. double secs; // Time location in seconds
  78. double durSecs; // Duration in seconds
  79. unsigned index; // Index of this event in the event array.
  80. unsigned locIdx; // Index of the location containing this event
  81. cmMidiByte_t pitch; // MIDI pitch of this note or the MIDI pedal id of pedal down/up msg (64=sustain 65=sostenuto 66=soft)
  82. cmMidiByte_t vel; // MIDI velocity of this note
  83. unsigned flags; // Attribute flags for this event
  84. unsigned dynVal; // Dynamcis value pppp to ffff (1 to 11) for this note.
  85. double frac; // Note's time value for tempo and non-grace evenness notes.
  86. unsigned barNumb; // Bar id of the measure containing this event.
  87. unsigned barNoteIdx; // Index of this note in this bar
  88. unsigned csvRowNumb; // File row number (not index) from which this record originated
  89. unsigned perfSmpIdx; // Time this event was performed or cmInvalidIdx if the event was not performed.
  90. unsigned perfVel; // Velocity of the performed note or 0 if the note was not performed.
  91. unsigned perfDynLvl; // Index into dynamic level ref. array assoc'd with perfVel
  92. unsigned line; // Line number of this event in the score file.
  93. unsigned csvEventId; // EventId from CSV 'evt' column.
  94. } cmScoreEvt_t;
  95. // A 'set' is a collection of events that are grouped in time and all marked with a given attribute.
  96. // (e.g. eveness, tempo, dynamcs ... )
  97. typedef struct cmScoreSet_str
  98. {
  99. unsigned varId; // See kXXXVarScId flags above
  100. cmScoreEvt_t** eleArray; // Events that make up this set in time order
  101. unsigned eleCnt; //
  102. cmScoreSection_t** sectArray; // Sections this set will be applied to
  103. unsigned sectCnt; //
  104. unsigned* symArray; // symArray[sectCnt] - symbol name of all variables represented by this set (e.g '1a-e', '1b-e', '2-t', etc)
  105. unsigned* costSymArray; // costSymArray[sectCnt] - same as symbols in symArray[] with 'c' prepended to front
  106. bool doneFl;
  107. double value;
  108. struct cmScoreSet_str* llink; // cmScoreLoc_t setList link
  109. } cmScoreSet_t;
  110. typedef enum
  111. {
  112. kInvalidScMId,
  113. kRecdBegScMId,
  114. kRecdEndScMId,
  115. kFadeScMId,
  116. kPlayBegScMId,
  117. kPlayEndScMId
  118. } cmMarkScMId_t;
  119. // score markers
  120. typedef struct cmScoreMarker_str
  121. {
  122. cmMarkScMId_t markTypeId; // marker type
  123. unsigned labelSymId; // marker label
  124. struct cmScoreLoc_str* scoreLocPtr; // score location of the marker
  125. unsigned csvRowIdx; // score CSV file line assoc'd w/ this marker
  126. struct cmScoreMarker_str* link; // cmScoreLoc_t.markList links
  127. } cmScoreMarker_t;
  128. // All events which are simultaneous are collected into a single
  129. // cmScoreLoc_t record.
  130. typedef struct cmScoreLoc_str
  131. {
  132. unsigned index; // index of this location record
  133. double secs; // Time of this location
  134. unsigned evtCnt; // Count of events in evtArray[].
  135. cmScoreEvt_t** evtArray; // Events which occur at this time.
  136. unsigned barNumb; // Bar number this event is contained by.
  137. cmScoreSet_t* setList; // Set's which end on this time location (linked through cmScoreSet_t.llink)
  138. cmScoreSection_t* begSectPtr; // NULL if this location does not start a section
  139. cmScoreMarker_t* markList; // List of markers assigned to this location
  140. } cmScoreLoc_t;
  141. typedef void (*cmScCb_t)( void* arg, const void* data, unsigned byteCnt );
  142. typedef cmRC_t cmScRC_t;
  143. typedef cmHandle_t cmScH_t;
  144. extern cmScH_t cmScNullHandle;
  145. const cmChar_t* cmScEvtTypeIdToLabel( unsigned id );
  146. const cmChar_t* cmScDynIdToLabel( unsigned id );
  147. const cmChar_t* cmScStatusToOpString( unsigned id );
  148. // Initialize a score object from a CSV File generated from a score spreadsheet.
  149. // The dynRefArray[dynRefCnt] and cbFunc(cbArg) are optional if these
  150. // features are not used.
  151. // If provided the dynRefArray[] is copied into an internal array.
  152. // The physical array passed here therefore does not need to remain valid.
  153. // Set 'srate' to zero if the score will not be used to perform measurement calculations.
  154. // The symbol table is only necessary if valid symbols are to be assigned to the cmScoreSet_t.symArray[].
  155. cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg, cmSymTblH_t stH );
  156. cmScRC_t cmScoreFinalize( cmScH_t* hp );
  157. // Filename of last successfuly loaded score file.
  158. const cmChar_t* cmScoreFileName( cmScH_t h );
  159. // Sample rate as set in cmScoreInitialize()
  160. double cmScoreSampleRate( cmScH_t h );
  161. // Validate the score handle
  162. bool cmScoreIsValid( cmScH_t h );
  163. // Access the score data.
  164. unsigned cmScoreEvtCount( cmScH_t h );
  165. cmScoreEvt_t* cmScoreEvt( cmScH_t h, unsigned idx );
  166. // Given a bar number return the associated 'bar' event record.
  167. const cmScoreEvt_t* cmScoreBarEvt( cmScH_t h, unsigned barNumb );
  168. // Given a csvEventId return the associated event
  169. const cmScoreEvt_t* cmScoreIdToEvt( cmScH_t h, unsigned csvEventId );
  170. // Access section records
  171. unsigned cmScoreSectionCount( cmScH_t h );
  172. cmScoreSection_t* cmScoreSection( cmScH_t h, unsigned idx );
  173. // Access the score location data
  174. unsigned cmScoreLocCount( cmScH_t h );
  175. cmScoreLoc_t* cmScoreLoc( cmScH_t h, unsigned idx );
  176. void cmScorePrintLoc( cmScH_t h );
  177. // Return the location associated with a given score event.
  178. cmScoreLoc_t* cmScoreEvtLoc( cmScH_t h, const cmScoreEvt_t* evt );
  179. // Return the count of sets.
  180. unsigned cmScoreSetCount( cmScH_t h );
  181. unsigned cmScoreMarkerLabelCount( cmScH_t h );
  182. unsigned cmScoreMarkerLabelSymbolId( cmScH_t h, unsigned idx );
  183. const cmScoreMarker_t* cmScoreMarker( cmScH_t h, cmMarkScMId_t markMId, unsigned labelSymId );
  184. // Make callbacks for all events in the score. The callbacks
  185. // contain cmScMsg_t records serialized as a byte stream.
  186. // Use cmScoreDecode() to convert the byte string to a
  187. // cmScMsg_t record.
  188. cmScRC_t cmScoreSeqNotify( cmScH_t h );
  189. cmScRC_t cmScoreSeqNotifyCb( cmScH_t h, cmScCb_t cbFunc, void* cbArg );
  190. void cmScoreClearPerfInfo( cmScH_t h );
  191. // Assign 'smpIdx' and 'vel' to the event matching 'pitch' at 'locIdx'
  192. // but do not trigger any variable calculations. Return true if as a
  193. // result of this call all events assigned to 'locIdx' have been received
  194. // otherwise return false.
  195. bool cmScoreSetPerfEvent( cmScH_t h, unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel );
  196. // Assign 'smpIdx' and 'vel' to the event matching 'pitch' at 'locIdx'
  197. // but and trigger any variable calculations which may happen on, or before, 'locIdx'.
  198. void cmScoreExecPerfEvent( cmScH_t h, unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel );
  199. // Assign 'value' to the section at, or before, 'locIdx'.
  200. void cmScoreSetPerfValue( cmScH_t h, unsigned locIdx, unsigned varId, double value );
  201. // Set the performed dynamic level of a score event.
  202. void cmScoreSetPerfDynLevel( cmScH_t h, unsigned evtIdx, unsigned dynLvl );
  203. typedef enum
  204. {
  205. kInvalidMsgScId,
  206. kBeginMsgScId,
  207. kEventMsgScId,
  208. kSectionMsgScId,
  209. kEndMsgScId,
  210. kVarMsgScId,
  211. kDynMsgScId
  212. } cmScMsgTypeId_t;
  213. typedef struct
  214. {
  215. unsigned varId; // see kXXXVarScId from cmScoreSet_t.varId
  216. double value; // value of a variable
  217. } cmScMeas_t;
  218. typedef struct
  219. {
  220. unsigned evtIdx;
  221. unsigned dynLvl;
  222. } cmScDyn_t;
  223. typedef struct
  224. {
  225. cmScMsgTypeId_t typeId;
  226. union
  227. {
  228. cmScoreEvt_t evt; // only used when typeId == kEventMsgScId
  229. cmScMeas_t meas; // only used when typeId == kVarMsgScId
  230. cmScoreSection_t sect; // only used when typeId == kSectionMsgScId
  231. cmScDyn_t dyn; // only used when typeId == kDynLvlMsgScId
  232. } u;
  233. } cmScMsg_t;
  234. // Decode a serialized cmScMsg_t from a byte stream as passed to the
  235. // cmScCb_t function.
  236. cmScRC_t cmScoreDecode( const void* msg, unsigned msgByteCnt, cmScMsg_t* );
  237. void cmScorePrint( cmScH_t h, cmRpt_t* rpt );
  238. void cmScorePrintSets( cmScH_t h, cmRpt_t* rpt );
  239. // Generate a new score file from a MIDI file.
  240. cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn );
  241. // Print open the score file 'fn' and report the contents. This function
  242. // simply wraps calls to cmScoreInitialize() and cmScorePrint().
  243. void cmScoreReport( cmCtx_t* ctx, const cmChar_t* fn, const cmChar_t* outFn );
  244. void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
  245. //)
  246. #ifdef __cplusplus
  247. }
  248. #endif
  249. #endif