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.

cmSdb.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #ifndef cmSdb_h
  2. #define cmSdb_h
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. /*( { file_desc:"Musical instrument sample database manager and synthetic sequence generator." kw:[audio] }
  7. The CSV file used to initialize a SDB object has the following column syntax.
  8. Column Name Type Description
  9. ------ -------- ----- -----------------------------------------------------
  10. 1 uuid uint Unique integer identifier for this event
  11. 2 baseUuid uint uuid of channel 0 for this event
  12. 3 chIdx uint Channel index (stereo: 1=left 2=right)
  13. 4 obi uint Outer onset sample index into 'afn'.
  14. 5 ibi uint Inner onset sample index into 'afn'.
  15. 6 iei uint Inner offset sample index into 'afn'.
  16. 7 oei uint Outer offset sample index into 'afn'.
  17. 8 src text Source label for this event (e.g. mcgill, ui )
  18. 9 midi uint MIDI pitch number or -1 if the sample is not pitched
  19. 10 instr text Instrument label.
  20. 11 srate uint Sample rate of audio file reference by 'afn'.
  21. 10 chCnt uint Count of channels for this event.
  22. * notes text 0 or more free form double quoted text notes.
  23. * afn text File name of the audio file this event occurs in.
  24. Notes:
  25. #. Each event represents a mono audio signal. If the event is drawn
  26. from a multi-channel audio file then the 'chCnt' field will be
  27. greater than one. If 'chCnt' is greater than one then the associated
  28. samples can be found by collecting all events that share the
  29. same 'baseUuid'.
  30. #. There may be zero or more columns of 'notes'. If there are no
  31. notes then the 'afn' field is in column 11.
  32. #. The index values (chIdx,obi,ibi,iei,oei) as stored in the CSV file
  33. are 1 based. These values are decreased by 1 by the cmSdb CSV reader
  34. so that their cmSdb value is zero based. See cmSdbLoad().
  35. */
  36. enum
  37. {
  38. kOkSdbRC,
  39. kLHeapFailSdbRC,
  40. kCsvFailSdbRC,
  41. kFileSysFailSdbRC,
  42. kAudioFileFailSdbRC,
  43. kSyntaxErrSdbRC,
  44. kInvalidRspIdxSdbRC,
  45. kInvalidSeqIdxSdbRC,
  46. kChPairNotFoundSdbRC,
  47. kRspEvtNotFoundSdbRC,
  48. kAssertFailSdbRC,
  49. kInvalidArgSdbRC
  50. };
  51. typedef cmHandle_t cmSdbH_t;
  52. typedef cmHandle_t cmSdbResponseH_t;
  53. typedef cmHandle_t cmSdbSeqH_t;
  54. typedef cmRC_t cmSdbRC_t;
  55. extern cmSdbH_t cmSdbNullHandle;
  56. extern cmSdbResponseH_t cmSdbResponseNullHandle;
  57. extern cmSdbSeqH_t cmSdbSeqNullHandle;
  58. typedef struct
  59. {
  60. unsigned uuid; // unique id of this sample
  61. unsigned baseUuid; // uuid of channel 0
  62. unsigned chIdx; // channel index (0=left,1=right)
  63. unsigned obi; // outer onset
  64. unsigned ibi; // inner onset
  65. unsigned iei; // inner offset
  66. unsigned oei; // outer offset
  67. unsigned midi; // MIDI pitch or -1 for unpitched instruments
  68. unsigned srate; // sample rate
  69. unsigned chCnt; // source channel count
  70. const cmChar_t* src; // sample source (e.g. mcgill, ui )
  71. const cmChar_t* instr; // instrument label
  72. const cmChar_t* afn; // audio file name
  73. const cmChar_t** notesV; // NULL terminated list of terms describing the event.
  74. } cmSdbEvent_t;
  75. // Create an SDB object. If 'csvFn' is non-NULL then an internal call is made to cmSdbLoad().
  76. cmSdbRC_t cmSdbCreate( cmCtx_t* ctx, cmSdbH_t* hp, const cmChar_t* csvFn, const cmChar_t* audioDir );
  77. // Release an SDB object previously created via cmSdbCreate().
  78. cmSdbRC_t cmSdbDestroy( cmSdbH_t* hp );
  79. bool cmSdbIsValid( cmSdbH_t h );
  80. // Iinitialze the internal database from the CSV file 'csvFn'.
  81. cmSdbRC_t cmSdbLoad( cmSdbH_t h, const cmChar_t* csvFn, const cmChar_t* audioDir );
  82. // Time align all channel pairs by setting the onset times to
  83. // the minimum time among all the pairs and the offset times to
  84. // the maximum among all the pairs. This function is applied to all
  85. // the events contained in the sample database.
  86. cmSdbRC_t cmSdbSyncChPairs( cmSdbH_t h );
  87. // Given a sample event unique id return a pointer to the associated record.
  88. const cmSdbEvent_t* cmSdbEvent( cmSdbH_t h, unsigned uuid );
  89. //================================================================================================
  90. // Query Related functions
  91. //
  92. // Select a set of events from the sample database.
  93. //
  94. // The possible selection criteria are:
  95. // sample rate
  96. // instrument label
  97. // source label
  98. // notes labels
  99. // event duration
  100. //
  101. // In order to match an event all active criteria
  102. // must match. In other words the match implies a
  103. // logical AND operation on each match criteria.
  104. // Each of the criteria can be made inactive by
  105. // specifying particular key values.
  106. // sample rate = 0
  107. // instrument label = NULL
  108. // source label = NULL
  109. // notes labels = NULL
  110. // event duration = minDurSec=0 maxDurSec=0
  111. //
  112. // For the text array arguments (instrV,srcV,notesV)
  113. // each element of the array is a key which is attempts to
  114. // match the associated field in each event record.
  115. // By default a match is triggered if the key text is identical to the
  116. // event field text. The match algorithm can be modified by
  117. // specifying a '*' as the first character in the key field.
  118. // In this case a the key need only be a substring of the
  119. // event field to trigger a match. For example "*viol"
  120. // will return events that match both "violin" and "viola".
  121. //
  122. // To specify a mismatch as a successful match
  123. // (i.e. to return events which do not match the key text)
  124. // prefix the key with a '!' character.
  125. //
  126. // Note that it is legal to specify both '!' and '*'. In
  127. // which case a match will be triggered by fields where
  128. // the key text is not a substring of the field text.
  129. //
  130. // pitchV[] contains an array of pitch values to match.
  131. // The last value in pitchV[] must be kInvalidMidiPitch.
  132. // If pitchV == NULL then all pitches match. Note that
  133. // to match non-pitched instruments set set one element
  134. // of pitchV[] to -1.
  135. //
  136. // The application should release all query response handles
  137. // returned from this function via a call to cmSdbResponseFree().
  138. // cmSdbDestroy() will automatically release any response
  139. // handles not previously release by cmSdbReponseFree().
  140. cmSdbRC_t cmSdbSelect(
  141. cmSdbH_t h,
  142. double srate, // event sample rate or 0 to ignore
  143. const cmChar_t** instrV, // array of instrument labels to match
  144. const cmChar_t** srcV, // array of 'src' labels to match
  145. const cmChar_t** notesV, // array of text 'notes' to match
  146. const unsigned* pitchV, // array of pitches terminated w/ kInvalidMidiPitch
  147. double minDurSec, // min event duration
  148. double maxDurSec, // max event duration or 0 to ignore
  149. unsigned minChCnt, // min ch cnt or 0 to ignore
  150. cmSdbResponseH_t* rhp );
  151. // Given the event 'ep' locate the channel pairs associated with that event.
  152. // The response handle returned from this function must be released
  153. // by a call to cmSdbResponseFree().
  154. cmSdbRC_t cmSdbSelectChPairs( cmSdbH_t h, const cmSdbEvent_t* ep, cmSdbResponseH_t* rhp );
  155. // Return the count of events in a query response.
  156. unsigned cmSdbResponseCount( cmSdbResponseH_t rh );
  157. // Return the event at 'index' in from a query response.
  158. // Legal 'index' range: 0<=index<=cmSdbResponseCount().
  159. const cmSdbEvent_t* cmSdbResponseEvent( cmSdbResponseH_t rh, unsigned index );
  160. // Return true if the 'rh' is a non-NULL query response handle.
  161. bool cmSdbResponseIsValid( cmSdbResponseH_t rh );
  162. // Release the resource held by a query response.
  163. cmSdbRC_t cmSdbResponseFree( cmSdbResponseH_t* rhp );
  164. void cmSdbResponsePrint( cmSdbResponseH_t rh, cmRpt_t* rpt );
  165. //================================================================================================
  166. // Sequence Related functions
  167. //
  168. typedef struct
  169. {
  170. unsigned uuid; // uuid of sample data base envent.
  171. double begSec; // Event start time in seconds.
  172. double durSec; // Event duration in seconds.
  173. double gain; // Event amplitude scaling factor.
  174. unsigned outChIdx; // Output channel index.
  175. } cmSdbSeqEvent_t;
  176. // Generate a random sequence of events with a programmable
  177. // density of events per second.
  178. //
  179. // 'minEvtPerSec' and 'maxEvtPerSec' specify the min and max count of events
  180. // which may be initiated per second.
  181. //
  182. // The application should release all sequence handles
  183. // returned from this function via a call to cmSdbSeqFree().
  184. // cmSdbDestroy() will automatically release any sequence
  185. // handles not previously release by cmSdbSeqFree().
  186. //
  187. // Note that the event selection is done with replacement.
  188. // The same event may therefore be selected more than
  189. // once.
  190. cmSdbRC_t cmSdbSeqRand(
  191. cmSdbResponseH_t rh,
  192. unsigned seqDurSecs,
  193. unsigned seqChCnt,
  194. unsigned minEvtPerSec,
  195. unsigned maxEvtPerSec,
  196. cmSdbSeqH_t* shp );
  197. // Generate a sequence of serial events w/ gapSec seconds
  198. // between each event. Events longer than 'maxEvtDurSec'
  199. // seconds are truncated to 'maxEvtDurSec'.
  200. cmSdbRC_t cmSdbSeqSerial(
  201. cmSdbResponseH_t rh,
  202. unsigned seqChCnt,
  203. double gapSec,
  204. double maxEvtDurSec,
  205. cmSdbSeqH_t* shp );
  206. // Generate a chord sequence by randomly selecting one event
  207. // from each response handle.
  208. cmSdbRC_t cmSdbSeqChord(
  209. cmSdbResponseH_t* rhp, // one rhp[rn] query resonse per chord note
  210. unsigned rn, // count of response handles in rhp[].
  211. unsigned seqChCnt, // output sequence channel count
  212. unsigned maxEvtDurSec, // maximum event duration or 0 to prevent truncation
  213. cmSdbSeqH_t* shp );
  214. // Release a sequence.
  215. cmSdbRC_t cmSdbSeqFree( cmSdbSeqH_t* shp );
  216. // Return the count of sequence events.
  217. unsigned cmSdbSeqCount( cmSdbSeqH_t sh );
  218. // Return a pointer to a specified cmSdbSeqEvent_t record.
  219. // where 0 <= index < cmSdbSeqCount(sh)
  220. const cmSdbSeqEvent_t* cmSdbSeqEvent( cmSdbSeqH_t sh, unsigned index );
  221. // Given a seqence index return the associate cmSdbEvent_t.
  222. const cmSdbEvent_t* cmSdbSeqSdbEvent( cmSdbSeqH_t sh, unsigned index );
  223. // Return the total duration of the sequence in seconds.
  224. double cmSdbSeqDurSeconds( cmSdbSeqH_t sh );
  225. // Return the sample rate of the first event in the sequence that
  226. // has a non-zero sample rate. There is no guarantee that all
  227. // of the other events in the sequence have the same sample rate
  228. // unless this was enforced by the query response that the
  229. // sequence was generated from.
  230. double cmSdbSeqSampleRate( cmSdbSeqH_t sh );
  231. // Generate an audio from a sequence and return it in
  232. // a signal vector.
  233. cmSdbRC_t cmSdbSeqToAudio(
  234. cmSdbSeqH_t sh,
  235. unsigned decayMs, // decay rate for truncated events
  236. double noiseDb, // (-70.0) pad signal with white noise to avoid digital silence
  237. double evtNormFact, // normalize each sample event by normFact / abs(max(x[])) or 0 to skip normalization
  238. cmSample_t** signalRef, // *signalRef[*sigSmpCntRef * sh.chCnt] returned audio signal
  239. unsigned* sigSmpCntRef ); // count of frames in *signalRef
  240. // Generate an audio file from a sequence vector.
  241. cmSdbRC_t cmSdbSeqToAudioFn(
  242. cmSdbSeqH_t sh,
  243. unsigned decayMs, // decay rate for truncated events
  244. double noiseDb, // (-70.0) pad signal with white noise to avoid digital silence
  245. double evtNormFact, // normalize each sample event by normFact / abs(max(x[])) or 0 to skip normalization
  246. double normFact, // total signal norm factor or 0.0 to skip normalization
  247. const cmChar_t* fn, // write the output signal to this audio file
  248. unsigned bitsPerSample // audio file bits per sample
  249. );
  250. // Print a sequence event listing.
  251. void cmSdbSeqPrint( cmSdbSeqH_t sh, cmRpt_t* rpt );
  252. cmSdbRC_t cmSdbTest( cmCtx_t* ctx );
  253. //)
  254. #ifdef __cplusplus
  255. }
  256. #endif
  257. #endif