libcm is a C development framework with an emphasis on audio signal processing applications.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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