mix.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. //
  20. // mix.h
  21. //
  22. // History:
  23. // 06/17/95 JMI Started.
  24. //
  25. // 06/26/97 JMI Started tracking history of this .h file.
  26. // Added optional constant playing of silence.
  27. //
  28. // 07/16/97 JRD Added volume members and volume parameters to Start.
  29. // Modified BlueCall to pass parameters to MixBuf.
  30. //
  31. // 07/17/97 JRD Removed Volume parameters, as they should be set
  32. // by the callback.
  33. //
  34. // 07/17/97 JRD Added Volume parameters, as they aren't always set
  35. // by the callback.
  36. //
  37. // 08/05/97 JMI Added IsPaused(), PauseChannel(), ResumeChannel(),
  38. // and IsChannelPaused().
  39. //
  40. // 10/30/97 JMI Added alternate version of SetMode() which allows more
  41. // detail as to bit depth quality of samples and mixing.
  42. //
  43. //////////////////////////////////////////////////////////////////////////////
  44. //
  45. // See CPP header comment for details.
  46. //
  47. //////////////////////////////////////////////////////////////////////////////
  48. #ifndef MIX_H
  49. #define MIX_H
  50. ///////////////////////////////////////////////////////////////////////////////
  51. // Headers.
  52. ///////////////////////////////////////////////////////////////////////////////
  53. #include "System.h"
  54. // If PATHS_IN_INCLUDES macro is defined, we can utilized relative
  55. // paths to a header file. In this case we generally go off of our
  56. // RSPiX root directory. System.h MUST be included before this macro
  57. // is evaluated. System.h is the header that, based on the current
  58. // platform (or more so in this case on the compiler), defines
  59. // PATHS_IN_INCLUDES. Blue.h includes system.h so you can include that
  60. // instead.
  61. #ifdef PATHS_IN_INCLUDES
  62. #include "ORANGE/CDT/List.h"
  63. #include "GREEN/Mix/MixBuf.h"
  64. #include "GREEN/SndFx/SndFx.h"
  65. #else
  66. #include "List.h"
  67. #include "MixBuf.h"
  68. #include "SndFx.h"
  69. #endif // PATHS_IN_INCLUDES
  70. ///////////////////////////////////////////////////////////////////////////////
  71. // Macros.
  72. ///////////////////////////////////////////////////////////////////////////////
  73. // Maximum number of buffers this class will use.
  74. #define MAX_BUFS 256
  75. ///////////////////////////////////////////////////////////////////////////////
  76. // Types.
  77. ///////////////////////////////////////////////////////////////////////////////
  78. // Forward declare class for handy-dandy typedef.
  79. class RMix;
  80. // Handy-dandy typedef.
  81. typedef RMix* PMIX;
  82. // Class definition.
  83. class RMix
  84. {
  85. public: // Enums and typedefs.
  86. typedef enum
  87. { // Mix messages (callback can receive in addition to blue messages).
  88. Suspended, // Channel has finished.
  89. Data // Channel needs new data.
  90. } Msg;
  91. typedef enum
  92. { // Mix states for ms_sState and GetState().
  93. Idle, // No mixing occurring.
  94. Processing // There are unfinished channels (i.e.,
  95. // either mixing is occurring or there
  96. // are channels that have data that is
  97. // still being played by Blue).
  98. } State;
  99. // Callback.
  100. typedef void* (*RMixCall)( Msg msg,
  101. void* pData,
  102. ULONG* pulBufSize,
  103. ULONG ulUser,
  104. UCHAR* pucVol1,
  105. UCHAR* pucVol2);
  106. public: // <Con|De>struction.
  107. // Default constructor.
  108. RMix();
  109. // Destructor.
  110. ~RMix();
  111. public: // Methods.
  112. /////////////////////////////////////////////////////////////////////////
  113. // API that affects a single channel.
  114. /////////////////////////////////////////////////////////////////////////
  115. // Open a mix channel.
  116. // Returns 0 on success.
  117. short OpenChannel(long lSampleRate,
  118. long lBitsPerSample,
  119. long lNumChannels);
  120. // Close a mix channel.
  121. // Returns 0 on success.
  122. short CloseChannel(void);
  123. // Start receiving callbacks to fill channel data.
  124. // Set the initial mix volumes
  125. // Returns 0 on success.
  126. short Start(RMixCall mcUser, ULONG ulUser,
  127. UCHAR ucVolume = 255, UCHAR ucVol2 = 255 );
  128. // Stop receiving callbacks to fill channel data.
  129. short Suspend(void); // Returns 0 on success.
  130. // Pause mix channel.
  131. void PauseChannel(void);
  132. // Resume mix channel.
  133. void ResumeChannel(void);
  134. // Check mix channel's paused status.
  135. short IsChannelPaused(void); // Returns TRUE, if sound output is paused; FALSE otherwise.
  136. // Set or clear (if psndfx is NULL) a RSndFx for this channel.
  137. void SetFx( // Returns nothing.
  138. RSndFx* psndfx) // FX for this channel. Clears current, if
  139. // NULL.
  140. {
  141. m_psndfx = psndfx;
  142. }
  143. /////////////////////////////////////////////////////////////////////////
  144. // API that affects all channels (static).
  145. /////////////////////////////////////////////////////////////////////////
  146. // Set the current audio mode.
  147. // This will cause any open channels to start playing.
  148. static short SetMode( // Returns 0 on success.
  149. long lSamplesPerSec, // Sample rate in samples per second.
  150. long lDevBitsPerSample, // Number of bits per sample for device.
  151. long lNumChannels, // Number of channels (1 == mono,2 == stereo).
  152. long lBufferTime, // Amount of time buffer spends in queue b4
  153. // being played.
  154. long lMaxBufferTime, // Maximum that lBufferTime can be set to
  155. // dynamically with RMix::SetBufferTime().
  156. long lMixBitsPerSample, // Bit depth at which samples will be mixed.
  157. long lSrcBitsPerSample); // Bit depth at which samples must be to be
  158. // mixed or 0 for no preference.
  159. // Set the current audio mode.
  160. // This will cause any open channels to start playing.
  161. static short SetMode( // Returns 0 on success.
  162. long lSamplesPerSec, // Sample rate in samples per second.
  163. long lBitsPerSample, // Number of bits per sample.
  164. long lNumChannels, // Number of channels (1 == mono,2 == stereo).
  165. long lBufferTime, // Amount of time buffer spends in queue b4
  166. // being played.
  167. long lMaxBufferTime) // Maximum that lBufferTime can be set to
  168. // dynamically with RMix::SetBufferTime().
  169. {
  170. return SetMode(
  171. lSamplesPerSec,
  172. lBitsPerSample,
  173. lNumChannels,
  174. lBufferTime,
  175. lMaxBufferTime,
  176. lBitsPerSample,
  177. lBitsPerSample);
  178. }
  179. // Kills the current audio mode.
  180. // This will cause any open channels to be closed stops Blue from
  181. // utilizing the sound audio device.
  182. static void KillMode(void);
  183. // Pause currently playing audio.
  184. // NOTE: Pause/Resume is implemented in levels by Blue.
  185. static short Pause(void); // Returns 0 on success.
  186. // Resume currently paused audio.
  187. // NOTE: Pause/Resume is implemented in levels by Blue.
  188. static short Resume(void); // Returns 0 on success.
  189. // Returns TRUE, if sound output is paused; FALSE otherwise.
  190. static short IsPaused(void); // Returns TRUE, if sound output is paused; FALSE otherwise.
  191. // Do stuff specific to RMix and the playing of audio through Blue.
  192. // This includes calling rspDoSound().
  193. static long Do(void); // Returns value returned by rspDoSound() that
  194. // indicates how much audio, in milliseconds,
  195. // was required to be queued.
  196. // Reset all current mix channels.
  197. static short Reset(void); // Returns 0 on success.
  198. // Suspends all current mix channels.
  199. static short SuspendAll(void); // Returns 0 on success.
  200. // Sets the maximum duration that can occur between calls
  201. // to rspDoSound.
  202. static void SetBufferTime(long lBufferTime)
  203. { ms_ulBufSize = 0; rspSetSoundOutBufferTime(lBufferTime); }
  204. // Set or clear (if psndfx is NULL) a RSndFx for all channels.
  205. static void SetGlobalFx( // Returns nothing.
  206. RSndFx* psndfx) // FX for all channels. Clears current, if
  207. // NULL.
  208. {
  209. ms_psndfx = psndfx;
  210. }
  211. // Enable or disable auto-pump feature which will keep silence pumping
  212. // through Blue's sound interface even when there are no channels to
  213. // mix. This, when enabled, keeps delays consistent and removes overhead,
  214. // if any, for starting Blue's sound stuff.
  215. static void SetAutoPump( // Returns nothing.
  216. short sAutoPump) // In: TRUE to auto-pump silence, FALSE othwerise.
  217. {
  218. ms_sKeepPumping = sAutoPump;
  219. }
  220. public: // Querries.
  221. /////////////////////////////////////////////////////////////////////////
  222. // API that affects a single channel.
  223. /////////////////////////////////////////////////////////////////////////
  224. // Returns TRUE if this mix channel is open; FALSE otherwise.
  225. short IsOpen(void) { return m_sOpen; }
  226. // Returns TRUE if this mix channel is active; FALSE otherwise.
  227. short IsActive(void) { return m_sActive; }
  228. // Returns the time for this RMix.
  229. long GetTime(void);
  230. // Returns the position for this RMix.
  231. long GetPos(void);
  232. /////////////////////////////////////////////////////////////////////////
  233. // API that affects all channels (static).
  234. /////////////////////////////////////////////////////////////////////////
  235. // Returns the current state for all RMixes.
  236. static State GetState() { return ms_sState; }
  237. // Gets the current mode of the sound output device.
  238. static short GetMode( // Returns 0 on success;
  239. // nonzero if no mode.
  240. long* plSamplesPerSec, // Sample rate in samples per second
  241. // returned here, if not NULL.
  242. long* plDevBitsPerSample = NULL, // Bits per sample of device,
  243. // returned here, if not NULL.
  244. long* plNumChannels = NULL, // Number of channels (1 == mono,
  245. // 2 == stereo) returned here,
  246. // if not NULL.
  247. long* plBufferTime = NULL, // Amount of time in ms to lead the
  248. // current play cursor returned here,
  249. // if not NULL. This could also be
  250. // described as the maximum amount of
  251. // time in ms that can occur between
  252. // calls to rspDoSound.
  253. long* plMaxBufferTime = NULL, // Maximum buffer time. This is the amt
  254. // that *plBufferTime can be increased to.
  255. // This is indicative of how much space
  256. // was/will-be allocated for the sound
  257. // output device on rspLockSoundOut.
  258. long* plMixBitsPerSample = NULL, // Bits per sample at which samples are
  259. // mixed, if not NULL.
  260. long* plSrcBitsPerSample = NULL);// Bits per sample at which samples must
  261. // be to be mixed (0 if no requirement),
  262. // if not NULL.
  263. protected: // Internal use.
  264. // Intialize members.
  265. void Init(void);
  266. // Called when all sound on a channel has finished.
  267. // Returns 0 on success.
  268. short ChannelFinished(void);
  269. // Implied this version of BlueCallStatic, called from BlueCallStatic.
  270. short BlueCall( // Returns FALSE when no data mixed.
  271. long lDataPos, // Position that this buffer represents in stream.
  272. PMIXBUF pmb); // Mix buffer to mix into.
  273. // Callbacks from Blue.
  274. static short BlueCallStatic( // Returns TRUE to continue mixing in this
  275. // buffer or FALSE to not mix this buffer.
  276. UCHAR* pucData,
  277. long lBufSize,
  278. long lDataPos,
  279. ULONG* pul_ppmixbuf);
  280. public: // members
  281. // Volume information is set from Start and RSND callbacks
  282. UCHAR m_ucVolume; // 0 - 255
  283. UCHAR m_ucSecondaryVolume; // 0 - 255
  284. protected: // Members.
  285. long m_lSampleRate; // Sample rate for audio playback/mix.
  286. long m_lBitsPerSample; // Sample size in bits.
  287. long m_lNumChannels; // Number of channels (mono or stereo).
  288. short m_sOpen; // TRUE if channel open; FALSE
  289. // otherwise.
  290. short m_sActive; // TRUE if channel active; FALSE
  291. // otherwise.
  292. short m_sSuspending; // TRUE if channel suspending; FALSE
  293. // otherwise.
  294. long m_lLastDataPos; // Last byte mixed into.
  295. RMixCall m_mcUser; // User callback.
  296. ULONG m_ulUser; // User value.
  297. UCHAR* m_pucData; // User data.
  298. ULONG m_ulAmount; // Amount of user data remaining.
  299. long m_lStartTime; // Audio time when first buffer entered
  300. // queue.
  301. long m_lStartPos; // Audio position when first buffer
  302. // enter queue.
  303. RSndFx* m_psndfx; // Pointer to an RSndFx.
  304. short m_sPauseLevel; // Current pause level.
  305. static RList<RMix> ms_listActive; // List of active channels.
  306. static short ms_sSetMode; // TRUE if we set Blue's sound
  307. // output mode.
  308. static State ms_sState; // Current state for all RMixes.
  309. static long ms_lCurPos; // Current play position
  310. // based on absolute start.
  311. static ULONG ms_ulBufSize; // The size to use when allocating
  312. // RMixBufs.
  313. static short ms_sReset; // Resets Blue and returns all
  314. // current user buffers.
  315. static RSndFx* ms_psndfx; // Pointer to a global RSndFx.
  316. static short ms_sKeepPumping; // Keep Blue pumped with silence
  317. // when no channels are playing,
  318. // if TRUE.
  319. static RMixBuf ms_mixbuf; // One and only mix buffer.
  320. };
  321. #endif // MIX_H
  322. ///////////////////////////////////////////////////////////////////////////////
  323. // EOF
  324. ///////////////////////////////////////////////////////////////////////////////