libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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