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

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