Advertisement
Kitomas

kit_kmixer.h as of 2023-10-20

Oct 20th, 2023 (edited)
760
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 28.80 KB | None | 0 0
  1. /**
  2.  * \file kit_kmixer.h
  3.  * \brief Header file for KIT SDL2's KMixer module
  4.  */
  5. #ifndef _KIT_KMIXER_H
  6. #define _KIT_KMIXER_H
  7. #ifndef _KIT_SDL2_KMIXER_H
  8. #define _KIT_SDL2_KMIXER_H
  9. //todo: fix bugs related to acodec pcm conversion (not directly a kmixer problem but w/e)
  10. /* todo: finish kmixerAsync:
  11.   (fix seamless looping of clips)
  12.  
  13.   StopTrack
  14.   StopAllTracks
  15.   GetTrackCount
  16.  
  17.   GetTrackPlaystate
  18.   GetTrackPosition
  19.  
  20.  
  21.   GetTrackPan
  22.   GetTrackVolumeLR
  23.   GetTrackVolumeL
  24.   GetTrackVolumeR
  25.  
  26.   GetTrackDeltaLR
  27.   GetTrackDeltaL
  28.   GetTrackDeltaR
  29.  
  30.   GetTrackSpeed
  31.   GetTrackDeltaS
  32.  
  33.  
  34.   SetTrackPan
  35.   SetTrackVolumeLR
  36.   SetTrackVolumeL
  37.   SetTrackVolumeR
  38.  
  39.   SetTrackDeltaLR
  40.   SetTrackDeltaL
  41.   SetTrackDeltaR
  42.  
  43.   SetTrackSpeed
  44.   SetTrackDeltaS
  45.  
  46.  
  47.  
  48.   GetMainPan
  49.   GetMainVolumeLR
  50.   GetMainVolumeL
  51.   GetMainVolumeR
  52.  
  53.   GetMainDeltaLR
  54.   GetMainDeltaL
  55.   GetMainDeltaR
  56.  
  57.  
  58.   SetMainPan
  59.   SetMainVolumeLR
  60.   SetMainVolumeL
  61.   SetMainVolumeR
  62.  
  63.   SetMainDeltaLR
  64.   SetMainDeltaL
  65.   SetMainDeltaR
  66. */
  67.  
  68.  
  69. #include "./kit_core.h" //includes SDL2/SDL.h
  70. #include "./_kit_acodecPCM.h" //contains PCM data stuff
  71.  
  72. #ifdef __cplusplus
  73. extern "C" {
  74. #endif
  75.  
  76.  
  77.  
  78.  
  79. /* +kit_kmixerDevice struct/union typedefs+ */
  80. typedef struct kit_kmixerDevice kit_kmixerDevice;
  81. /* -kit_kmixerDevice struct/union typedefs- */
  82.  
  83. /* +kit_kmixerVoice struct/union typedefs+ */
  84. typedef struct kit_kmixerVoiceSpec kit_kmixerVoiceSpec;
  85. /* -kit_kmixerVoice struct/union typedefs- */
  86.  
  87.  
  88.  
  89.  
  90. /* ++++++++++++ */
  91. /* +kit_kmixer+ */
  92. /* ++++++++++++ */
  93.  
  94. extern const SDL_bool kit_kmixerIsDebug;
  95.  
  96.  
  97.  
  98. /**
  99.  * Initialize kmixer
  100.  * \param[in] numDeviceThreads The maximum number of active threads a device can have. \n
  101.                                Negative values will use fractions of total core count (-2 for half, -3 for a third, etc.)
  102.  * \return 0 on success, >0 on warning, or <0 on error (call SDL_GetError() for more info)
  103.  *
  104.  * \remark Setting numDeviceThreads to 0 is treated the same as setting it to -1 (as many threads as there are CPU cores).
  105.  * \sa kit_kmixerQuit
  106.  */
  107. extern int kit_kmixerInit(int numDeviceThreads);
  108.  
  109. /**
  110.  * Shut down kmixer
  111.  * \return 0 on success, >0 on warning, <0 on error (call SDL_GetError() for more info)
  112.  *
  113.  * \sa kit_kmixerInit
  114.  */
  115. extern int kit_kmixerQuit();
  116.  
  117. /* ------------ */
  118. /* -kit_kmixer- */
  119. /* ------------ */
  120.  
  121.  
  122.  
  123.  
  124. /* ++++++++++++++++++ */
  125. /* +kit_kmixerDevice+ */
  126. /* ++++++++++++++++++ */
  127.  
  128. /**
  129.  * \brief This struct contains all info needed for a kmixer device and its voice chains
  130.  * \remark Every member of this struct has the "_" prefix,
  131.  *         which means they should be treated as read-only
  132.  */
  133. struct kit_kmixerDevice { //128B
  134.   union {
  135.     char             str[8]; ///< \brief String portion of struct ID ("kmxrDev\x00")
  136.     Uint64              num; ///< \brief Integer portion of struct ID (0x0076654472786D6B)
  137.   } /* ------------ */ _magic; ///< \brief Struct ID number; union of Uint64 and char[8]
  138.   SDL_AudioSpec         _spec; ///< \brief Audio specification of the device
  139.   SDL_mutex*            _lock; ///< \brief Mutex for device access (lock unnecessary for accessing some members)
  140.   kit_coreVector*    _threads; ///< \brief The device's thread list for voice processing
  141.   kit_coreVector* _threadData; ///< \brief List of data to be fed into the device threads
  142.   kit_coreVector*        _raw; ///< \brief 1D array of all registered voice structs
  143.   kit_coreVector*        _ord; ///< \brief 2D array of voice references (of raw), ordered by input chain stage
  144.   Uint64      _timeStampStart; ///< \brief The result of SDL_GetTicks64() at the start of the device callback
  145.   Uint64        _timeStampEnd; ///< \brief The result of SDL_GetTicks64() at the end of the device callback
  146.   float            _fadeDelta; ///< \brief The number to apply to _fadeVolume when applying fade ins/outs
  147.   float           _fadeVolume; ///< \brief Volume used for fade ins/outs
  148.   Uint32         _fadeInDelay; ///< \brief How many samples to write 0 to before fading in
  149.   Uint32           _lockCount; ///< \brief The number of threads currently locking the device
  150.   SDL_AudioDeviceID    _devID; ///< \brief The device ID number that SDL uses
  151.   SDL_bool           _playing; ///< \brief A boolean of whether the device is currently active
  152.   SDL_bool           _closing; ///< \brief Should only be set inside a call to kit_kmixerDeviceClose
  153.   SDL_bool           _fadeOut; ///< \brief Used internally for fade ins/outs
  154. };
  155.  
  156.  
  157.  
  158. /**
  159.  * Lock or unlock the mutex of a kit_kmixerAudioDevice
  160.  * \param[in] device The device to lock
  161.  * \param[in] lockState A boolean of whether to lock the device or unlock it
  162.  * \return 0 on success, 1 if device already unlocked, or <0 on error (call SDL_GetError() for more info).
  163.  *
  164.  * \remark Only lock a device as long as necessary, as locking the device's mutex
  165.  *         prevents kmixer from interacting with the device at all. \n
  166.  *         Also, locks are counted by reference, so every lock needs to be
  167.  *         paired with an unlock until the device can be fully unlocked.
  168.  */
  169. extern int kit_kmixerDeviceLock(kit_kmixerDevice* device, SDL_bool lockState);
  170.  
  171.  
  172. /**
  173.  * Play or pause a kit_kmixerAudioDevice
  174.  * \param[in] device The device to play or pause
  175.  * \param[in] playState A boolean of whether to play or pause the device
  176.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  177.  *
  178.  * \remark When unpausing a paused device, there is 490ms of silence, followed by 10ms of fade-in. \n
  179.  * \remark Conversely, when pausing a currently unpaused device, there's 10ms of fade-out.
  180.  * \sa kit_kmixerDeviceUnpauseAndWait
  181.  * \sa kit_kmixerDevicePauseAndWait
  182.  */
  183. extern int kit_kmixerDevicePlay(kit_kmixerDevice* device, SDL_bool playState);
  184.  
  185.  
  186. /**
  187.  * Close a kit_kmixerAudioDevice
  188.  * \param[in] device_p A pointer to the device to close
  189.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  190.  *
  191.  * \remark Do note that this will call the kit_kmixerVoiceRemoveCallback
  192.  *         of any voices destroyed during this operation.
  193.  * \sa kit_kmixerDeviceOpen
  194.  */
  195. extern int kit_kmixerDeviceClose(kit_kmixerDevice** device_p);
  196.  
  197. /**
  198.  * Open a kit_kmixerAudioDevice
  199.  * \param[in] deviceName A string given by SDL_GetAudioDeviceName
  200.  *            (NULL for most reasonable default device)
  201.  * \param[in] allowedChanges Any combination of
  202.  *            SDL_AUDIO_ALLOW_<FREQUENCY,FORMAT,CHANNELS,SAMPLES,ANY>_CHANGE, OR'd together
  203.  * \param[in] voiceSpecDesired The requested specification of the device and initial voice
  204.  * \param[out] voiceSpecObtained The real specification of the device/initial voice,
  205.  *             altered depending on allowedChange's flags
  206.  *
  207.  * \remark If the ".format" member of voiceSpecDesired is set to 0,
  208.  *         voice 1 will not be created (useful in some scenarios). \n
  209.  * \remark (Devices will start in a paused state!)
  210.  * \sa kit_kmixerDeviceClose
  211.  * \sa kit_kmixerDevicePlay
  212.  */
  213. extern kit_kmixerDevice* kit_kmixerDeviceOpen(const char* deviceName, int allowedChanges,
  214.                                               const kit_kmixerVoiceSpec* voiceSpecDesired,
  215.                                               kit_kmixerVoiceSpec* voiceSpecObtained);
  216.  
  217.  
  218. /**
  219.  * Unpause a device, halting the calling thread until device fade-in completes
  220.  * \param[in] device The device to unpause
  221.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  222.  *
  223.  * \sa kit_kmixerDevicePlay
  224.  * \sa kit_kmixerDevicePauseAndWait
  225.  */
  226. extern int kit_kmixerDeviceUnpauseAndWait(kit_kmixerDevice* device);
  227.  
  228. /**
  229.  * Pause a device, halting the calling thread until device fade-out completes
  230.  * \param[in] device The device to unpause
  231.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  232.  *
  233.  * \sa kit_kmixerDevicePlay
  234.  * \sa kit_kmixerDeviceUnpauseAndWait
  235.  */
  236. extern int kit_kmixerDevicePauseAndWait(kit_kmixerDevice* device);
  237.  
  238.  
  239. extern int kit_kmixerDevice_Test(); // debug
  240.  
  241. /* ------------------ */
  242. /* -kit_kmixerDevice- */
  243. /* ------------------ */
  244.  
  245.  
  246.  
  247.  
  248. /* +++++++++++++++++ */
  249. /* +kit_kmixerVoice+ */
  250. /* +++++++++++++++++ */
  251.  
  252. /**
  253.  * \name Print a kit_kmixerVoiceSpec (These should probably become inlines at some point)
  254.  */
  255. /** @{ */
  256. #define PRINT_VOICE_SPEC(_pref, _vspec) {                              \
  257.   kit_coreLog(_pref".remove   = %p",(_vspec).remove);                  \
  258.   kit_coreLog(_pref".callback = %p",(_vspec).callback);                \
  259.   kit_coreLog(_pref".userdata = %p",(_vspec).userdata);                \
  260.   kit_coreLog(_pref".freq     = %i",(_vspec).freq);                    \
  261.   kit_coreLog(_pref"._size    = %u",(_vspec)._size);                   \
  262.   kit_coreLog(_pref".stereo   = %s",boolstr[(_vspec).stereo]); \
  263.   kit_coreLog(_pref".samples  = %u",(_vspec).samples);                 \
  264.   kit_coreLog(_pref".format   = 0x%04X",(_vspec).format);              }
  265.  
  266. #define PRINT_VOICE_SPEC_P(_pref, _vspec_pointer) {                              \
  267.   kit_coreLog(_pref"->remove   = %p",(_vspec_pointer)->remove);                  \
  268.   kit_coreLog(_pref"->callback = %p",(_vspec_pointer)->callback);                \
  269.   kit_coreLog(_pref"->userdata = %p",(_vspec_pointer)->userdata);                \
  270.   kit_coreLog(_pref"->freq     = %i",(_vspec_pointer)->freq);                    \
  271.   kit_coreLog(_pref"->_size    = %u",(_vspec_pointer)->_size);                   \
  272.   kit_coreLog(_pref"->stereo   = %s",boolstr[(_vspec_pointer)->stereo]); \
  273.   kit_coreLog(_pref"->samples  = %u",(_vspec_pointer)->samples);                 \
  274.   kit_coreLog(_pref"->format   = 0x%04X",(_vspec_pointer)->format);              }
  275. /** @} */
  276.  
  277.  
  278.  
  279. /**
  280.  * PCM Audio Voice Callback
  281.  * This type of function is called when added as a voice to a KMixer audio device
  282.  * While each voice's callback is given its own threadpool task (and should be thread-safe),
  283.  * the overall speed is determined by device's slowest voice chain (processing-wise)
  284.  * The given audio buffer must be completely filled before returning
  285.  * \param[in] userdata A user-defined pointer passed to the voice callback
  286.  * \param[in] _stream  A pointer to the audio data buffer
  287.  * \param[in] size     The size of that buffer, in bytes
  288.  * \param[in] hasInput A boolean of whether _stream already contains input PCM data (useful for applying DSP effects)
  289.  *
  290.  * \remark The audio data buffer is not guaranteed to be zeroed out, even if hasInput is SDL_FALSE!
  291.  */
  292. typedef void (*kit_kmixerVoiceCallback) (void* userdata, void* _stream, int size, SDL_bool hasInput);
  293.  
  294.  
  295. /**
  296.  * Voice Destructor Callback
  297.  * This type of function is called when removing a voice, so userdata can be properly handled by the user.
  298.  * \param[in] userdata The user defined pointer to operate on.
  299.  *
  300.  * \remark Warning: unless kit_kmixerVoiceSpec.remove was set to NULL,
  301.  *         this will still be called, whether or not userdata is also NULL.
  302.  */
  303. typedef void (*kit_kmixerVoiceRemoveCallback) (void* userdata);
  304.  
  305.  
  306.  
  307. /**
  308.  * \brief The struct used when opening a kmixerDevice, as well as adding a voice to that device.
  309.  * \details When adding a voice, ".freq", and ".samples" are ignored, as that is tied to the device itself.
  310.  */
  311. struct kit_kmixerVoiceSpec { //40B
  312.   kit_kmixerVoiceRemoveCallback remove; ///< \brief A callback that should handle userdata in the event of voice removal (can be NULL)
  313.   kit_kmixerVoiceCallback callback; ///< \brief A callback that should either fill or modify its input stream
  314.   void*                   userdata; ///< \brief A user-defined pointer, passed to the callback (can be NULL)
  315.   Sint32                      freq; ///< \brief The PCM audio's sample rate, in Hz
  316.   Uint32                     _size; ///< \brief (internal; automatically calculated) The size of the audio buffer, in bytes
  317.   SDL_bool                  stereo; ///< \brief Stereo if SDL_TRUE, mono if SDL_FALSE
  318.   Uint16                   samples; ///< \brief The Audio buffer's length in sample FRAMES (total samples divided by channel count)
  319.   SDL_AudioFormat           format; ///< \brief Format can be one of AUDIO_<U8,S16,S32,F32>
  320. };
  321.  
  322.  
  323.  
  324. /**
  325.  * Remove a kmixer device's voice, as well as any input voices, recursively
  326.  * \param[in] device The device to remove a voice from
  327.  * \param[in] voiceID The ID number of the voice to remove
  328.  * \return 0 on success, -1 on error (call SDL_GetError() for more info)
  329.  *
  330.  * \remark The selected voice's kit_kmixerVoiceRemoveCallback will trigger
  331.  *         after the voice itself is mostly done being removed (if it isn't NULL) \n
  332.  * \remark Also, bit 31 of voiceID is reserved for detecting recursion, so don't set it.
  333.  * \sa kit_kmixerVoiceRemoveCallback
  334.  * \sa kit_kmixerVoiceAdd
  335.  * \sa kit_kmixerVoiceRedirect
  336.  */
  337. extern int kit_kmixerVoiceRemove(kit_kmixerDevice* device, Uint32 voiceID);
  338.  
  339. /**
  340.  * Add a voice to output to either a kmixer device or one of the device's voices
  341.  * \param[in] device The device to add a voice to
  342.  * \param[in] spec The specification for the voice
  343.  * \param[in] outputVoiceID The ID number of the output voice (0 for the device itself)
  344.  * \return The ID number of the newly-created voice, or 0 on error (call SDL_GetError() for more info)
  345.  *
  346.  * \sa kit_kmixerVoiceRemove
  347.  * \sa kit_kmixerVoiceRedirect
  348.  */
  349. extern Uint32 kit_kmixerVoiceAdd(kit_kmixerDevice* device, kit_kmixerVoiceSpec* spec,
  350.                                  Uint32 outputVoiceID);
  351.  
  352. /**
  353.  * Redirect the output of a voice
  354.  * \param[in] device The device to alter the voices of
  355.  * \param[in] inputVoiceID The voice to be redirected
  356.  * \param[in] outputVoiceID The new voice to output to (0 for the device itself)
  357.  * \return 0 on success, -1 on error (call SDL_GetError() for more info)
  358.  *
  359.  * \sa kit_kmixerVoiceRemove
  360.  * \sa kit_kmixerVoiceAdd
  361.  */
  362. extern int kit_kmixerVoiceRedirect(kit_kmixerDevice* device,
  363.                                    Uint32 inputVoiceID, Uint32 outputVoiceID);
  364.  
  365.  
  366. /**
  367.  * Get the number of inputs of a given voice
  368.  * \param[in] device The device access the voices of
  369.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  370.  * \return The total number of inputs, or -1 on error (call SDL_GetError() for more info)
  371.  *
  372.  * \sa kit_kmixerVoiceGetInputs
  373.  * \sa kit_kmixerVoiceGetOutput
  374.  */
  375. extern Uint32 kit_kmixerVoiceGetNumInputs(kit_kmixerDevice* device, Uint32 voiceID);
  376.  
  377. /**
  378.  * Create a deep copy of a voice's input list
  379.  * \param[in] device The device access the voices of
  380.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  381.  * \return A deep copy of voice's input list, or NULL on error (call SDL_GetError() for more info)
  382.  *
  383.  * \remark (Make sure to call kit_coreVectorDestroy after the returned vector is no longer used!)
  384.  * \sa kit_kmixerVoiceGetNumInputs
  385.  * \sa kit_kmixerVoiceGetOutput
  386.  */
  387. extern kit_coreVector* kit_kmixerVoiceGetInputs(kit_kmixerDevice* device, Uint32 voiceID);
  388.  
  389. /**
  390.  * Get the output voice ID of a given input voice
  391.  * \param[in] device The device access the voices of
  392.  * \param[in] voiceID The specific voice to query
  393.  * \return The output voice ID, or -1 on error (call SDL_GetError() for more info)
  394.  *
  395.  * \sa kit_kmixerVoiceGetNumInputs
  396.  * \sa kit_kmixerVoiceGetInputs
  397.  */
  398. extern Uint32 kit_kmixerVoiceGetOutput(kit_kmixerDevice* device, Uint32 voiceID);
  399.  
  400. /**
  401.  * Get the activity state of a given voice
  402.  * \param[in] device The device access the voices of
  403.  * \param[in] voiceID The specific voice to query
  404.  * \return A boolean of the if the voice is active or not, or -1 on error (call SDL_GetError() for more info)
  405.  *
  406.  * \sa kit_kmixerVoiceSetActive
  407.  * \sa kit_kmixerVoiceSetActiveChain
  408.  */
  409. extern int kit_kmixerVoiceGetActive(kit_kmixerDevice* device, Uint32 voiceID);
  410.  
  411. /**
  412.  * Set the activity state of a given voice
  413.  * \param[in] device The device access the voices of
  414.  * \param[in] voiceID The specific voice to query
  415.  * \param[in] isActive Whether to set the voice as active or not
  416.  * \return 0 on success, -1 on error (call SDL_GetError() for more info)
  417.  *
  418.  * \remark Deactivating a voice will stop the user callback from being called! \n
  419.  * \remark (Unlike SetActiveChain, de/activation of a voice doesn't apply to any of its input voices!)
  420.  * \sa kit_kmixerVoiceGetActive
  421.  * \sa kit_kmixerVoiceSetActiveChain
  422.  */
  423. extern int kit_kmixerVoiceSetActive(kit_kmixerDevice* device, Uint32 voiceID, SDL_bool isActive);
  424.  
  425. /**
  426.  * Set the activity state of a given voice, as well as any of its input voices (recursively)
  427.  * \param[in] device The device access the voices of
  428.  * \param[in] voiceID The specific voice to query
  429.  * \param[in] isActive Whether to set the voice as active or not
  430.  * \return 0 on success, -1 on error (call SDL_GetError() for more info)
  431.  *
  432.  * \remark Deactivating a voice will stop the user callback from being called!
  433.  * \sa kit_kmixerVoiceGetActive
  434.  * \sa kit_kmixerVoiceSetActive
  435.  */
  436. extern int kit_kmixerVoiceSetActiveChain(kit_kmixerDevice* device, Uint32 voiceID, SDL_bool isActive);
  437.  
  438.  
  439. /**
  440.  * Get the voice processing stage of a given voice
  441.  * \param[in] device The device access the voices of
  442.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  443.  * \return The voice's chain stage, or -1 on error (call SDL_GetError() for more info)
  444.  *
  445.  * \remark Voices are processed by order of highest stage to lowest. \n
  446.  *         For example, voice 0 is always on stage 0, whereas a voice that outputs to it will be on stage 1.
  447.  */
  448. extern Uint32 kit_kmixerVoiceGetChainStage(kit_kmixerDevice* device, Uint32 voiceID);
  449.  
  450.  
  451. /**
  452.  * Get the specification of a given voice
  453.  * \param[in] device The device access the voices of
  454.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  455.  * \return The voice's specification struct. ".format" will be 0 on error (call SDL_GetError() for more info)
  456.  *
  457.  * \sa kit_kmixerVoiceSetSpecRemove
  458.  * \sa kit_kmixerVoiceSetSpecCallback
  459.  * \sa kit_kmixerVoiceSetSpecUserdata
  460.  */
  461. extern kit_kmixerVoiceSpec kit_kmixerVoiceGetSpec(kit_kmixerDevice* device, Uint32 voiceID);
  462.  
  463. /**
  464.  * Set the kit_kmixerVoiceRemoveCallback of a given voice
  465.  * \param[in] device The device access the voices of
  466.  * \param[in] voiceID The specific voice to query
  467.  * \param[in] remove The new kit_kmixerVoiceRemoveCallback the voice should use (can be NULL)
  468.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  469.  *
  470.  * \sa kit_kmixerVoiceGetSpec
  471.  * \sa kit_kmixerVoiceSetSpecCallback
  472.  * \sa kit_kmixerVoiceSetSpecUserdata
  473.  */
  474. extern int kit_kmixerVoiceSetSpecRemove(kit_kmixerDevice* device, Uint32 voiceID,
  475.                                         kit_kmixerVoiceRemoveCallback remove);
  476.  
  477. /**
  478.  * Set the kit_kmixerVoiceCallback of a given voice
  479.  * \param[in] device The device access the voices of
  480.  * \param[in] voiceID The specific voice to query
  481.  * \param[in] callback The new kit_kmixerVoiceCallback the voice should use
  482.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  483.  *
  484.  * \sa kit_kmixerVoiceGetSpec
  485.  * \sa kit_kmixerVoiceSetSpecRemove
  486.  * \sa kit_kmixerVoiceSetSpecUserdata
  487.  */
  488. extern int kit_kmixerVoiceSetSpecCallback(kit_kmixerDevice* device, Uint32 voiceID,
  489.                                           kit_kmixerVoiceCallback callback);
  490.  
  491. /**
  492.  * Set the userdata pointer of a given voice
  493.  * \param[in] device The device access the voices of
  494.  * \param[in] voiceID The specific voice to query
  495.  * \param[in] userdata The new userdata pointer the voice should use (can be NULL)
  496.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  497.  *
  498.  * \sa kit_kmixerVoiceGetSpec
  499.  * \sa kit_kmixerVoiceSetSpecRemove
  500.  * \sa kit_kmixerVoiceSetSpecCallback
  501.  */
  502. extern int kit_kmixerVoiceSetSpecUserdata(kit_kmixerDevice* device, Uint32 voiceID, void* userdata);
  503.  
  504.  
  505. /**
  506.  * Get the left channel volume of a given voice (or total volume if voice is mono)
  507.  * \param[in] device The device access the voices of
  508.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  509.  * \return The voice's volume, or NAN on error (call SDL_GetError() for more info)
  510.  *
  511.  * \sa kit_kmixerVoiceGetVolR
  512.  * \sa kit_kmixerVoiceSetVolL
  513.  * \sa kit_kmixerVoiceSetVolR
  514.  * \sa kit_kmixerVoiceSetVolume
  515.  * \sa kit_kmixerVoiceSetPan
  516.  */
  517. extern float kit_kmixerVoiceGetVolL(kit_kmixerDevice* device, Uint32 voiceID);
  518.  
  519. /**
  520.  * Get the right channel volume of a given voice (or total volume if voice is mono)
  521.  * \param[in] device The device access the voices of
  522.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  523.  * \return The voice's volume, or NAN on error (call SDL_GetError() for more info)
  524.  *
  525.  * \sa kit_kmixerVoiceGetVolL
  526.  * \sa kit_kmixerVoiceSetVolL
  527.  * \sa kit_kmixerVoiceSetVolR
  528.  * \sa kit_kmixerVoiceSetVolume
  529.  * \sa kit_kmixerVoiceSetPan
  530.  */
  531. extern float kit_kmixerVoiceGetVolR(kit_kmixerDevice* device, Uint32 voiceID);
  532.  
  533. /**
  534.  * Set the left channel volume of a given voice (or total volume if voice is mono)
  535.  * \param[in] device The device access the voices of
  536.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  537.  * \param[in] volL The new volume to set the voice to (0.0f -> 1.0f)
  538.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  539.  *
  540.  * \remark If volL <0, volL will be MAX()'d to 0
  541.  * \sa kit_kmixerVoiceGetVolL
  542.  * \sa kit_kmixerVoiceGetVolR
  543.  * \sa kit_kmixerVoiceSetVolR
  544.  * \sa kit_kmixerVoiceSetVolume
  545.  * \sa kit_kmixerVoiceSetPan
  546.  */
  547. extern int kit_kmixerVoiceSetVolL(kit_kmixerDevice* device, Uint32 voiceID, float volL);
  548.  
  549. /**
  550.  * Set the right channel volume of a given voice (ignored if voice is mono)
  551.  * \param[in] device The device access the voices of
  552.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  553.  * \param[in] volR The new volume to set the voice to (0.0f -> 1.0f)
  554.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  555.  *
  556.  * \remark If the voice is stereo, but volR <0, volR will be set to volL
  557.  * \sa kit_kmixerVoiceGetVolL
  558.  * \sa kit_kmixerVoiceGetVolR
  559.  * \sa kit_kmixerVoiceSetVolL
  560.  * \sa kit_kmixerVoiceSetVolume
  561.  * \sa kit_kmixerVoiceSetPan
  562.  */
  563. extern int kit_kmixerVoiceSetVolR(kit_kmixerDevice* device, Uint32 voiceID, float volR);
  564.  
  565. /**
  566.  * Set both the left and right channel volumes of a given voice
  567.  * \param[in] device The device access the voices of
  568.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  569.  * \param[in] volL The new volume for the left channel (0.0f -> 1.0f)
  570.  * \param[in] volR The new volume for the right channel (0.0f -> 1.0f)
  571.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  572.  *
  573.  * \remark The same rules that apply to kit_kmixerVoiceSetVolL and kit_kmixerVoiceSetVolR apply here too.
  574.  * \sa kit_kmixerVoiceGetVolL
  575.  * \sa kit_kmixerVoiceGetVolR
  576.  * \sa kit_kmixerVoiceSetVolL
  577.  * \sa kit_kmixerVoiceSetVolR
  578.  * \sa kit_kmixerVoiceSetPan
  579.  */
  580. extern int kit_kmixerVoiceSetVolume(kit_kmixerDevice* device, Uint32 voiceID, float volL, float volR);
  581.  
  582. /**
  583.  * \param[in] device The device access the voices of
  584.  * \param[in] voiceID The specific voice to query (0 for the device itself)
  585.  * \param[in] pan The new pan setting for the voice, which alters volL and volR directly (-1.0f -> 1.0f)
  586.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  587.  *
  588.  * \remark For example, if pan = -0.6f, volL and volR would then be set to 1.0f and 0.4f respectively. \n
  589.  * \remark (This will overwrite any previous volume setting!)
  590.  * \sa kit_kmixerVoiceGetVolL
  591.  * \sa kit_kmixerVoiceGetVolR
  592.  * \sa kit_kmixerVoiceSetVolL
  593.  * \sa kit_kmixerVoiceSetVolR
  594.  * \sa kit_kmixerVoiceSetVolume
  595.  */
  596. extern int kit_kmixerVoiceSetPan(kit_kmixerDevice* device, Uint32 voiceID, float pan);
  597.  
  598.  
  599. /**
  600.  * Unlock the mutex of a given voice
  601.  * \param[in] device The device access the voices of
  602.  * \param[in] voiceID The specific voice to query
  603.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  604.  *
  605.  * \remark Only unlock a voice if it's actually been locked, as doing so might undo an important, internal lock!
  606.  * \sa kit_kmixerVoiceLock
  607.  */
  608. extern int kit_kmixerVoiceUnlock(kit_kmixerDevice* device, Uint32 voiceID);
  609.  
  610. /**
  611.  * Lock the mutex of a given voice
  612.  * \param[in] device The device access the voices of
  613.  * \param[in] voiceID The specific voice to query
  614.  * \return 0 on success, or <0 on error (call SDL_GetError() for more info)
  615.  *
  616.  * \remark If a voice is locked for too long, audio will halt entirely!
  617.  * \sa kit_kmixerVoiceUnlock
  618.  */
  619. extern int kit_kmixerVoiceLock(kit_kmixerDevice* device, Uint32 voiceID);
  620.  
  621.  
  622. extern int kit_kmixerVoice_Test(); //debug
  623.  
  624. extern void kit_kmixerVoicePrintRawOrd(kit_kmixerDevice* device); //debug
  625.  
  626. /* ----------------- */
  627. /* -kit_kmixerVoice- */
  628. /* ----------------- */
  629.  
  630.  
  631.  
  632.  
  633. /* +++++++++++++++++ */
  634. /* +kit_kmixerAsync+ */
  635. /* +++++++++++++++++ */
  636.  
  637. /**
  638.  * Add an asynchronous mixer voice (useful for playing sound effects)
  639.  * \param[in] device The device to add the voice to
  640.  * \param[in] linearInterpolation Whether to use linear interpolation or nearest-neighbor when resampling
  641.  * \param[in] stereo Whether to use stereo or mono for each track
  642.  * \param[in] outputVoiceID The voice to output to (0 for the device itself)
  643.  * \param[in] numTracks The maximum number of tracks that can play at once
  644.  * \return The index of the newly-created voice, or 0 on error (call SDL_GetError() for more info)
  645.  *
  646.  * \remark There is no AsyncRemove function. Instead, use VoiceRemove on the returned voice ID! \n
  647.  * \remark Also, the resulting VoiceSpec is that of the device, EXCEPT for stereo (and format, which will always be AUDIO_F32).
  648.  */
  649. extern Uint32 kit_kmixerAsyncAdd(kit_kmixerDevice* device,
  650.                                  SDL_bool linearInterpolation, SDL_bool stereo,
  651.                                  Uint32 outputVoiceID, Uint32 numTracks);
  652.  
  653.  
  654. /**
  655.  * Play a kit_acodecPCM audio clip asynchronously, with a custom pan, volume, and speed
  656.  * \param[in] device The device that contains the async voice
  657.  * \param[in] voiceID The async voice to query
  658.  * \param[in] pcm The audio clip to queue
  659.  * \param[in] pan The pan setting of the clip (-1.0f -> 1.0f)
  660.  * \param[in] volumeL The left channel's volume, or total volume if mono (>=0.0f)
  661.  * \param[in] volumeR The right channel's volume (>=0.0f; ignored if mono)
  662.  * \param[in] speedMultiplier The speed the clip should play at; 1 for 1x, 1.5 for 1.5x, etc.
  663.  * \return The track that clip was queued, -2 if no free track was found, or -1 on error (call SDL_GetError() for more info)
  664.  *
  665.  * \remark To check for a valid async voice, the first 4 bytes of *userdata are compared to 0x54414455 ("UDAT"). \n
  666.  *         This means that even if the voice is invalid, no error will occur if the check is true (so don't do that)!
  667.  * \sa kit_kmixerAsyncPlay
  668.  * \sa kit_kmixerAsyncPlayS
  669.  */
  670. Uint32 kit_kmixerAsyncPlayPVS(kit_kmixerDevice* device, Uint32 voiceID, kit_acodecPCM* pcm,
  671.                               float pan, float volumeL, float volumeR, float speedMultiplier);
  672.  
  673. /**
  674.  * Play a kit_acodecPCM audio clip asynchronously
  675.  * \param[in] device The device that contains the async voice
  676.  * \param[in] voiceID The async voice to query
  677.  * \param[in] pcm The audio clip to queue
  678.  * \return The track that clip was queued, -2 if no free track was found, or -1 on error (call SDL_GetError() for more info)
  679.  *
  680.  * \remark (refer to to kit_kmixerAsyncPlayPVS 's remark)
  681.  * \sa kit_kmixerAsyncPlayPVS
  682.  * \sa kit_kmixerAsyncPlayS
  683.  */
  684. static inline Uint32 kit_kmixerAsyncPlay(kit_kmixerDevice* device, Uint32 voiceID, kit_acodecPCM* pcm){
  685.   return kit_kmixerAsyncPlayPVS(device, voiceID, pcm, 0.0f, 1.0f,1.0f, 1.0f);
  686. }
  687.  
  688. /**
  689.  * Play a kit_acodecPCM audio clip asynchronously, with a custom speed
  690.  * \param[in] device The device that contains the async voice
  691.  * \param[in] voiceID The async voice to query
  692.  * \param[in] pcm The audio clip to queue
  693.  * \param[in] speedMultiplier The speed the clip should play at; 1 for 1x, 1.5 for 1.5x, etc.
  694.  * \return The track that clip was queued, -2 if no free track was found, or -1 on error (call SDL_GetError() for more info)
  695.  *
  696.  * \remark (refer to to kit_kmixerAsyncPlayPVS 's remark)
  697.  * \sa kit_kmixerAsyncPlayPVS
  698.  * \sa kit_kmixerAsyncPlay
  699.  */
  700. static inline Uint32 kit_kmixerAsyncPlayS(kit_kmixerDevice* device, Uint32 voiceID, kit_acodecPCM* pcm,
  701.                                           float speedMultiplier)
  702. {
  703.   return kit_kmixerAsyncPlayPVS(device, voiceID, pcm, 0.0f, 1.0f,1.0f, speedMultiplier);
  704. }
  705.  
  706.  
  707. /**
  708.  * Get the number of tracks actively playing audio clips
  709.  * \param[in] device The device that contains the async voice
  710.  * \param[in] voiceID The async voice to query
  711.  * \return The number of active tracks, or -1 on error (call SDL_GetError() for more info)
  712.  *
  713.  * \remark (refer to to kit_kmixerAsyncPlayPVS 's remark)
  714.  * \sa kit_kmixerAsyncPlayPVS
  715.  */
  716. Uint32 kit_kmixerAsyncGetActiveTracks(kit_kmixerDevice* device, Uint32 voiceID);
  717.  
  718. /* +++++++++++++++++ */
  719. /* +kit_kmixerAsync+ */
  720. /* +++++++++++++++++ */
  721.  
  722.  
  723.  
  724.  
  725. #ifdef __cplusplus
  726. }
  727. #endif
  728.  
  729. #endif /* _KIT_SDL2_KMIXER_H */
  730. #endif /* _KIT_KMIXER_H */
  731.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement