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.

cmApBuf.h 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. //( {file_desc: "Thread safe audio buffer class." kw:[rt audio]}
  4. //
  5. // This file defines an audio buffer class which handles
  6. // buffering incoming (recording) and outgoing (playback)
  7. // samples in a thread-safe manner.
  8. //
  9. // Usage example and testing code:
  10. // See cmApBufTest() and cmAudioSysTest().
  11. // \snippet cmApBuf.c cmApBufExample
  12. //
  13. // Notes on channel flags:
  14. // Disabled channels: kChFl is cleared
  15. // cmApBufGet()
  16. // in - return NULL buffer pointers
  17. // out - return NULL buffer points
  18. //
  19. // cmApBufUpdate()
  20. // in - incoming samples are set to 0.
  21. // out - outgoing samples are set to 0.
  22. //
  23. // Muted channels: kMuteFl is set
  24. // cmApBufUpdate()
  25. // in - incoming samples are set to 0.
  26. // out - outgoing samples are set to 0.
  27. //
  28. // Tone channels: kToneFl is set
  29. // cmApBufUpdate()
  30. // in - incoming samples are filled with a 1k sine tone
  31. // out - outgoing samples are filled with a 1k sine tone
  32. //)
  33. #ifndef cmApBuf_h
  34. #define cmApBuf_h
  35. #ifdef __cplusplus
  36. extern "C" {
  37. #endif
  38. //(
  39. typedef cmRC_t cmAbRC_t; //< Result code type
  40. enum
  41. {
  42. kOkAbRC = 0
  43. };
  44. // Allocate and initialize an audio buffer.
  45. // devCnt - count of devices this buffer will handle.
  46. // meterMs - length of the meter buffers in milliseconds (automatically limit to the range:10 to 1000)
  47. cmAbRC_t cmApBufInitialize( unsigned devCnt, unsigned meterMs );
  48. // Deallocate and release any resource held by an audio buffer allocated via cmApBufInitialize().
  49. cmAbRC_t cmApBufFinalize();
  50. // Configure a buffer for a given device.
  51. cmAbRC_t cmApBufSetup(
  52. unsigned devIdx, //< device to setup
  53. double srate, //< device sample rate (only required for synthesizing the correct test-tone frequency)
  54. unsigned dspFrameCnt, //< dspFrameCnt - count of samples in channel buffers returned via cmApBufGet()
  55. unsigned cycleCnt, //< number of audio port cycles to store
  56. unsigned inChCnt, //< input channel count on this device
  57. unsigned inFramesPerCycle, //< maximum number of incoming sample frames on an audio port cycle
  58. unsigned outChCnt, //< output channel count on this device
  59. unsigned outFramesPerCycle, //< maximum number of outgoing sample frames in an audio port cycle
  60. int srateMult ); //< sample rate cvt (positive for upsample, negative for downsample)
  61. // Prime the buffer with 'audioCycleCnt' * outFramesPerCycle samples ready to be played
  62. cmAbRC_t cmApBufPrimeOutput( unsigned devIdx, unsigned audioCycleCnt );
  63. // Notify the audio buffer that a device is being enabled or disabled.
  64. void cmApBufOnPortEnable( unsigned devIdx, bool enabelFl );
  65. // This function is called asynchronously by the audio device driver to transfer incoming samples to the
  66. // the buffer and to send outgoing samples to the DAC. This function is
  67. // intended to be called from the audio port callback function (\see cmApCallbackPtr_t).
  68. // This function is thread-safe under the condition where the audio device uses
  69. // different threads for input and output.
  70. //
  71. // Enable Flag:
  72. // Input: If an input channel is disabled then the incoming samples are replaced with zeros.
  73. // Output: If an output channel is disabled then the packet samples are set to zeros.
  74. //
  75. // Tone Flag:
  76. // Input: If the tone flag is set on an input channel then the incoming samples are set to a sine tone.
  77. // Output: If the tone flag is set on an output channel then the packet samples are set to a sine tone.
  78. //
  79. // The enable flag has higher precedence than the tone flag therefore disabled channels
  80. // will be set to zero even if the tone flag is set.
  81. cmAbRC_t cmApBufUpdate(
  82. cmApAudioPacket_t* inPktArray, //< full audio packets from incoming audio (from ADC)
  83. unsigned inPktCnt, //< count of incoming audio packets
  84. cmApAudioPacket_t* outPktArray, //< empty audio packet for outgoing audio (to DAC)
  85. unsigned outPktCnt //< count of outgoing audio packets
  86. );
  87. // Channel flags
  88. enum
  89. {
  90. kInApFl = 0x01, //< Identify an input channel
  91. kOutApFl = 0x02, //< Identify an output channel
  92. kEnableApFl = 0x04, //< Set to enable a channel, Clear to disable.
  93. kChApFl = 0x08, //< Used to enable/disable a channel
  94. kMuteApFl = 0x10, //< Mute this channel
  95. kToneApFl = 0x20, //< Generate a tone on this channel
  96. kMeterApFl = 0x40, //< Turn meter's on/off
  97. kPassApFl = 0x80 //< Pass input channels throught to the output. Must use cmApBufGetIO() to implement this functionality.
  98. };
  99. // Return the meter window period as set by cmApBufInitialize()
  100. unsigned cmApBufMeterMs();
  101. // Set the meter update period. THis function limits the value to between 10 and 1000.
  102. void cmApBufSetMeterMs( unsigned meterMs );
  103. // Returns the channel count set via cmApBufSetup().
  104. unsigned cmApBufChannelCount( unsigned devIdx, unsigned flags );
  105. // Set chIdx to -1 to enable all channels on this device.
  106. // Set flags to {kInApFl | kOutApFl} | {kChApFl | kToneApFl | kMeterFl} | { kEnableApFl=on | 0=off }
  107. void cmApBufSetFlag( unsigned devIdx, unsigned chIdx, unsigned flags );
  108. // Return true if the the flags is set.
  109. bool cmApBufIsFlag( unsigned devIdx, unsigned chIdx, unsigned flags );
  110. // Set chIdx to -1 to enable all channels on this device.
  111. void cmApBufEnableChannel( unsigned devIdx, unsigned chIdx, unsigned flags );
  112. // Returns true if an input/output channel is enabled on the specified device.
  113. bool cmApBufIsChannelEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
  114. // Set the state of the tone generator on the specified channel.
  115. // Set chIdx to -1 to apply the change to all channels on this device.
  116. // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
  117. void cmApBufEnableTone( unsigned devIdx, unsigned chIdx, unsigned flags );
  118. // Returns true if an input/output tone is enabled on the specified device.
  119. bool cmApBufIsToneEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
  120. // Mute a specified channel.
  121. // Set chIdx to -1 to apply the change to all channels on this device.
  122. // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
  123. void cmApBufEnableMute( unsigned devIdx, unsigned chIdx, unsigned flags );
  124. // Returns true if an input/output channel is muted on the specified device.
  125. bool cmApBufIsMuteEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
  126. // Set the specified channel to pass through.
  127. // Set chIdx to -1 to apply the change to all channels on this device.
  128. // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
  129. void cmApBufEnablePass( unsigned devIdx, unsigned chIdx, unsigned flags );
  130. // Returns true if pass through is enabled on the specified channel.
  131. bool cmApBufIsPassEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
  132. // Turn meter data collection on and off.
  133. // Set chIdx to -1 to apply the change to all channels on this device.
  134. // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
  135. void cmApBufEnableMeter( unsigned devIdx, unsigned chIdx, unsigned flags );
  136. // Returns true if an input/output tone is enabled on the specified device.
  137. bool cmApBufIsMeterEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
  138. // Return the meter value for the requested channel.
  139. // Set flags to kInApFl | kOutApFl.
  140. cmApSample_t cmApBufMeter(unsigned devIdx, unsigned chIdx, unsigned flags );
  141. // Set chIdx to -1 to apply the gain to all channels on the specified device.
  142. void cmApBufSetGain( unsigned devIdx, unsigned chIdx, unsigned flags, double gain );
  143. // Return the current gain seting for the specified channel.
  144. double cmApBufGain( unsigned devIdx, unsigned chIdx, unsigned flags );
  145. // Get the meter and fault status of the channel input or output channel array of a device.
  146. // Set 'flags' to { kInApFl | kOutApFl }.
  147. // The returns value is the count of channels actually written to meterArray.
  148. // If 'faultCntPtr' is non-NULL then it is set to the faultCnt of the associated devices input or output buffer.
  149. unsigned cmApBufGetStatus( unsigned devIdx, unsigned flags, double* meterArray, unsigned meterCnt, unsigned* faultCntPtr );
  150. // Do all enabled input/output channels on this device have samples available?
  151. // 'flags' can be set to either or both kInApFl and kOutApFl
  152. bool cmApBufIsDeviceReady( unsigned devIdx, unsigned flags );
  153. // This function is called by the application to get full incoming sample buffers and
  154. // to fill empty outgoing sample buffers.
  155. // Upon return each element in bufArray[bufChCnt] holds a pointer to a buffer assoicated
  156. // with an audio channel or to NULL if the channel is disabled.
  157. // 'flags' can be set to kInApFl or kOutApFl but not both.
  158. // The buffers pointed to by bufArray[] each contain 'dspFrameCnt' samples. Where
  159. // 'dspFrameCnt' was set in the earlier call to cmApBufSetup() for this device.
  160. // (see cmApBufInitialize()).
  161. // Note that this function just returns audio information it does not
  162. // change any cmApBuf() internal states.
  163. void cmApBufGet( unsigned devIdx, unsigned flags, cmApSample_t* bufArray[], unsigned bufChCnt );
  164. // This function replaces calls to cmApBufGet() and implements pass-through and output
  165. // buffer zeroing:
  166. //
  167. // 1) cmApBufGet(in);
  168. // 2) cmApBufGet(out);
  169. // 3) Copy through channels marked for 'pass' and set the associated oBufArray[i] channel to NULL.
  170. // 4) Zero all other enabled output channels.
  171. //
  172. // Notes:
  173. // 1) The oBufArray[] channels that are disabled or marked for pass-through will
  174. // be set to NULL.
  175. // 2) The client is required to use this function to implement pass-through internally.
  176. // 3) This function just returns audio information it does not
  177. // change any cmApBuf() internal states.
  178. // 4) The timestamp pointers are optional.
  179. void cmApBufGetIO( unsigned iDevIdx, cmApSample_t* iBufArray[], unsigned iBufChCnt, cmTimeSpec_t* iTimeStampPtr,
  180. unsigned oDevIdx, cmApSample_t* oBufArray[], unsigned oBufChCnt, cmTimeSpec_t* oTimeStampPtr );
  181. // The application calls this function each time it completes processing of a bufArray[]
  182. // returned from cmApBufGet(). 'flags' can be set to either or both kInApFl and kOutApFl.
  183. // This function should only be called from the client thread.
  184. void cmApBufAdvance( unsigned devIdx, unsigned flags );
  185. // Copy all available samples incoming samples from an input device to an output device.
  186. // The source code for this example is a good example of how an application should use cmApBufGet()
  187. // and cmApBufAdvance().
  188. void cmApBufInputToOutput( unsigned inDevIdx, unsigned outDevIdx );
  189. // Print the current buffer state.
  190. void cmApBufReport( cmRpt_t* rpt );
  191. // Run a buffer usage simulation to test the class. cmAudioPortTest.c calls this function.
  192. void cmApBufTest( cmRpt_t* rpt );
  193. //)
  194. #ifdef __cplusplus
  195. }
  196. #endif
  197. #endif