Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * \file kit_kmixer.h
- * \brief Header file for KIT SDL2's KMixer module
- */
- #ifndef _KIT_KMIXER_H
- #define _KIT_KMIXER_H
- #ifndef _KIT_SDL2_KMIXER_H
- #define _KIT_SDL2_KMIXER_H
- /* add these things at some point:
- kmixerFileLoadQOA
- kmixerFileLoadWAV
- kmixerFileLoadMUA
- (also, include save functions, and functions that just convert streams)
- */
- #include "./kit_core.h" //includes SDL2/SDL.h
- /* +kit_kmixerDevice struct/union typedefs+ */
- typedef struct kit_kmixerDevice kit_kmixerDevice;
- /* -kit_kmixerDevice struct/union typedefs- */
- /* +kit_kmixerVoice struct/union typedefs+ */
- typedef struct kit_kmixerVoiceSpec kit_kmixerVoiceSpec;
- /* -kit_kmixerVoice struct/union typedefs- */
- /* ++++++++++++ */
- /* +kit_kmixer+ */
- /* ++++++++++++ */
- extern int kit_kmixerInit(int deviceThreadPoolSize);
- extern int kit_kmixerQuit();
- /* ------------ */
- /* -kit_kmixer- */
- /* ------------ */
- /* ++++++++++++++++++ */
- /* +kit_kmixerDevice+ */
- /* ++++++++++++++++++ */
- /**
- * \brief This struct contains all info needed for a kmixer device and its voice chains
- * \remark Every member of this struct has the "_" prefix,
- * which means they should be treated as read-only
- */
- struct kit_kmixerDevice { //136B
- union {
- char str[8]; ///< \brief String portion of struct ID ("kmxrDev\x00")
- Uint64 num; ///< \brief Integer portion of struct ID (0x0076654472786D6B)
- } /* ---------- */ _magic; ///< \brief Struct ID number; union of Uint64 and char[8]
- SDL_AudioSpec _spec; ///< \brief Audio specification of the device
- SDL_mutex* _lock; ///< \brief Mutex for device access (lock unnecessary for accessing some members)
- struct {
- SDL_cond* cond; ///< \brief Used for signalling when a free spot is available in the pool
- kit_coreVector* queue; ///< \brief Circular buffer that contains currently queued voice tasks
- kit_coreVector* pool; ///< \brief The thread pool for voice tasks
- Uint32 qread, qwrite; ///< \brief Read/write headers for the queue buffer
- } /* --------- */ _thread; ///< \brief The device's thread pool voice task queue
- struct { //(the highest current voice chain stage is basically just ord.x)
- kit_coreVector* raw; ///< \brief 1D array of all registered voice structs
- kit_coreVector* ord; ///< \brief 2D array of voice references (of .raw), ordered by input chain stage
- kit_coreVector* chain; ///< \brief 1D array of the amount of voices on a given chain stage (.ord's y axis)
- } /* --------- */ _voices; ///< \brief The device's registered voices
- float _fadeMuliplier; ///< \brief the number to *= by when applying fade
- float _fadeVolume; ///< \brief Volume used for fade ins/outs
- Uint32 _fadeInDelay; ///< \brief How many samples
- Uint32 _lockCount; ///< \brief The number of threads currently locking the device
- SDL_AudioDeviceID _devID; ///< \brief The device ID number that SDL uses
- SDL_bool _playing; ///< \brief A boolean of whether the device is currently active
- SDL_bool _closing; ///< \brief Should only be set inside a call to kit_kmixerDeviceClose
- SDL_bool _fadeOut; ///< \brief Used internally for fade ins/outs
- };
- /**
- * Lock or unlock the mutex of a kit_kmixerAudioDevice
- * \param[in] device The device to lock
- * \param[in] lockState A boolean of whether to lock the device or unlock it
- * \return 0 on success, 1 if device already unlocked,
- * or a negative error code (call SDL_GetError() for more info).
- *
- * \remark Only lock a device as long as necessary, as locking the device's mutex
- * prevents kmixer from interacting with the device at all. \n
- * Also, locks are counted by reference, so every lock needs to be
- * paired with an unlock until the device can be fully unlocked.
- */
- extern int kit_kmixerDeviceLock(kit_kmixerDevice* device, SDL_bool lockState);
- /**
- * Play or pause a kit_kmixerAudioDevice
- * \param[in] device The device to play or pause
- * \param[in] playState A boolean of whether to play or pause the device
- * \return 0 on success, or a negative error code (call SDL_GetError() for more info)
- */
- extern int kit_kmixerDevicePlay(kit_kmixerDevice* device, SDL_bool playState);
- /**
- * Close a kit_kmixerAudioDevice
- * \param[in] device_p A pointer to the device to close
- * \return 0 on success, or a negative error code (call SDL_GetError() for more info)
- *
- * \remark Do note that this will call the kit_kmixerVoiceRemoveCallback
- * of any voices destroyed during this operation.
- * \sa kit_kmixerDeviceOpen
- */
- extern int kit_kmixerDeviceClose(kit_kmixerDevice** device_p);
- /**
- * Open a kit_kmixerAudioDevice
- * \param[in] deviceName A string given by SDL_GetAudioDeviceName
- * (NULL for most reasonable default device)
- * \param[in] allowedChanges Any combination of
- * SDL_AUDIO_ALLOW_<FREQUENCY,FORMAT,CHANNELS,SAMPLES,ANY>_CHANGE, OR'd together
- * \param[in] voiceSpecDesired The requested specification of the device and initial voice
- * \param[out] voiceSpecObtained The real specification of the device/initial voice,
- * altered depending on allowedChange's flags
- *
- * \remark If the ".format" member of voiceSpecDesired is set to 0,
- * voice 1 will not be created (useful in some scenarios). \n
- * \remark (Devices will start in a paused state!)
- * \sa kit_kmixerDeviceClose
- * \sa kit_kmixerDevicePlay
- */
- extern kit_kmixerDevice* kit_kmixerDeviceOpen(const char* deviceName, int allowedChanges,
- const kit_kmixerVoiceSpec* voiceSpecDesired,
- kit_kmixerVoiceSpec* voiceSpecObtained);
- extern int kit_kmixerDeviceTest(); // debug
- /* ------------------ */
- /* -kit_kmixerDevice- */
- /* ------------------ */
- /* +++++++++++++++++ */
- /* +kit_kmixerVoice+ */
- /* +++++++++++++++++ */
- /**
- * \name Print a kit_kmixerVoiceSpec
- */
- /** @{ */
- #define PRINT_VOICE_SPEC(_vspec) { \
- SDL_Log(".remove =%p",_vspec.remove); \
- SDL_Log(".callback=%p",_vspec.callback); \
- SDL_Log(".userdata=%p",_vspec.userdata); \
- SDL_Log(".freq =%i",_vspec.freq); \
- SDL_Log("._size =%u",_vspec._size); \
- SDL_Log(".stereo =%u",_vspec.stereo); \
- SDL_Log(".samples =%u",_vspec.samples); \
- SDL_Log(".format =%X",_vspec.format); }
- #define PRINT_VOICE_SPEC_P(_vspec_pointer) { \
- SDL_Log("->remove =%p",_vspec_pointer->remove); \
- SDL_Log("->callback=%p",_vspec_pointer->callback); \
- SDL_Log("->userdata=%p",_vspec_pointer->userdata); \
- SDL_Log("->freq =%i",_vspec_pointer->freq); \
- SDL_Log("->_size =%u",_vspec_pointer->_size); \
- SDL_Log("->stereo =%u",_vspec_pointer->stereo); \
- SDL_Log("->samples =%u",_vspec_pointer->samples); \
- SDL_Log("->format =%X",_vspec_pointer->format); }
- /** @} */
- /**
- * PCM Audio Voice Callback
- * This type of function is called when added as a voice to a KMixer audio device
- * While each voice's callback is given its own threadpool task (and should be thread-safe),
- * the overall speed is determined by device's slowest voice chain (processing-wise)
- * The given audio buffer must be completely filled before returning
- * \param[in] userdata A user-defined pointer passed to the voice callback
- * \param[in] _stream A pointer to the audio data buffer
- * \param[in] len The size of that buffer, in bytes
- * \param[in] hasInput A boolean of whether _stream already contains input PCM data (useful for applying DSP effects)
- *
- * \remark The audio data buffer is not guaranteed to be zeroed out, even if hasInput is SDL_FALSE
- */
- typedef void (*kit_kmixerVoiceCallback) (void* userdata, void* _stream, int len, SDL_bool hasInput);
- /**
- * Voice Destructor Callback
- * This type of function is called when removing a voice, so userdata can be properly handled by the user.
- * \param[in] userdata The user defined pointer to operate on.
- *
- * \remark Warning: unless kit_kmixerVoiceSpec.remove was set to NULL,
- * this will still be called, whether or not userdata is also NULL.
- */
- typedef void (*kit_kmixerVoiceRemoveCallback) (void* userdata);
- /**
- * \brief The struct used when opening a kmixerDevice, as well as adding a voice to that device.
- * \details When opening a device, the ".format" member is ignored, as samples are always floats internally. \n
- * Conversely, when adding a voice, ".freq", and ".samples" are ignored, \n
- * as that is tied to the device itself.
- */
- struct kit_kmixerVoiceSpec { //40B
- kit_kmixerVoiceRemoveCallback remove; ///< \brief A callback that should handle userdata in the event of voice removal
- kit_kmixerVoiceCallback callback; ///< \brief A callback that should either fill or modify its input stream (NULL to use kmixer's built-in asynchronous mixer)
- void* userdata; ///< \brief A user-defined pointer, passed to the callback (can be NULL)
- Sint32 freq; ///< \brief The PCM audio's sample rate, in Hz
- Uint32 _size; ///< \brief (internal; automatically calculated) The size of the audio buffer, in bytes
- SDL_bool stereo; ///< \brief Stereo if SDL_TRUE, mono if SDL_FALSE
- Uint16 samples; ///< \brief The Audio buffer's length in sample FRAMES (total samples divided by channel count)
- SDL_AudioFormat format; ///< \brief Format can be one of AUDIO_<U8,S16,S32,F32>
- };
- /**
- * Remove a kmixer device's voice, as well as any input voices, recursively
- * \param[in] device The device to remove a voice from
- * \param[in] voiceID The ID number of the voice to remove
- *
- * \return 0 on success, -1 on error (call SDL_GetError() for more info)
- * \remark The selected voice's kit_kmixerVoiceRemoveCallback will trigger
- * after the voice itself is mostly done being removed (if it isn't NULL) \n
- * \remark Also, bit 31 of voiceID is reserved for detecting recursion, so don't set it.
- * \sa kit_kmixerVoiceAdd
- * \sa kit_kmixerVoiceRemoveCallback
- */
- extern int kit_kmixerVoiceRemove(kit_kmixerDevice* device, Uint32 voiceID);
- /**
- * Add a voice to output to either a kmixer device or one of the device's voices
- * \param[in] device The device to add a voice to
- * \param[in] spec The specification for the voice
- * \param[in] outputVoiceID The ID number of the output voice (0 for the device itself)
- *
- * \return The ID number of the newly-created voice, or 0 on error (call SDL_GetError() for more info)
- * \sa kit_kmixerVoiceAdd
- */
- extern Uint32 kit_kmixerVoiceAdd(kit_kmixerDevice* device, kit_kmixerVoiceSpec* spec,
- Uint32 outputVoiceID);
- extern int kit_kmixerVoiceTest(); //debug
- /* ----------------- */
- /* -kit_kmixerVoice- */
- /* ----------------- */
- #endif /* _KIT_SDL2_KMIXER_H */
- #endif /* _KIT_KMIXER_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement