Advertisement
Kitomas

kit_acodec.h as of 2023-9-28

Sep 29th, 2023
616
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.74 KB | None | 0 0
  1. /**
  2.  * \file kit_acodec.h
  3.  * \brief Header file for KIT SDL2's Audio Codec module
  4.  */
  5. #ifndef _KIT_ACODEC_H
  6. #define _KIT_ACODEC_H
  7. #ifndef _KIT_SDL2_ACODEC_H
  8. #define _KIT_SDL2_ACODEC_H
  9. //todo: add acodecQOARead at some point
  10.  
  11.  
  12. #include "./kit_core.h" //includes SDL2/SDL.h
  13.  
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17.  
  18.  
  19.  
  20.  
  21. /* ++++++++++++++++++++ */
  22. /* +kit_sdl2_acodecPCM+ */
  23. /* ++++++++++++++++++++ */
  24.  
  25. //using the extension ".kpm" is preferred
  26.  //when saving kit_acodecPCM to a file
  27. #define KPCM_MAGIC (0x4D43506B) //= "kPCM"
  28.  
  29.  
  30.  
  31. /**
  32.  * \brief Stereo Uint8 samples
  33.  */
  34. typedef struct kit_acodecPCM_U_8S {
  35.   Uint8 l; ///< \brief Left audio channel
  36.   Uint8 r; ///< \brief Right audio channel
  37. } kit_acodecPCM_U_8S;
  38.  
  39. /**
  40.  * \brief Stereo Sint16 samples
  41.  */
  42. typedef struct kit_acodecPCM_I16S {
  43.   Sint16 l; ///< \brief Left audio channel
  44.   Sint16 r; ///< \brief Right audio channel
  45. } kit_acodecPCM_I16S;
  46.  
  47. /**
  48.  * \brief Stereo Sint32 samples
  49.  */
  50. typedef struct kit_acodecPCM_I32S {
  51.   Sint32 l; ///< \brief Left audio channel
  52.   Sint32 r; ///< \brief Right audio channel
  53. } kit_acodecPCM_I32S;
  54.  
  55. /**
  56.  * \brief Stereo float samples
  57.  */
  58. typedef struct kit_acodecPCM_F32S {
  59.   float l; ///< \brief Left audio channel
  60.   float r; ///< \brief Right audio channel
  61. } kit_acodecPCM_F32S;
  62.  
  63.  
  64. /**
  65.  * \brief A union of supported sample formats
  66.  */
  67. typedef union kit_acodecPCMSamples {
  68.   void*  data; ///< \brief Generic pointer
  69.   Uint8*  u_8; ///< \brief Mono Uint8 Samples
  70.   Sint16* i16; ///< \brief Mono Sint16 Samples
  71.   Sint32* i32; ///< \brief Mono Sint32 Samples
  72.   float*  f32; ///< \brief Mono float Samples
  73.   kit_acodecPCM_U_8S* u_8s; ///< \brief Stereo Uint8 samples
  74.   kit_acodecPCM_I16S* i16s; ///< \brief Stereo Sint16 samples
  75.   kit_acodecPCM_I32S* i32s; ///< \brief Stereo Sint32 samples
  76.   kit_acodecPCM_F32S* f32s; ///< \brief Stereo float samples
  77. } kit_acodecPCMSamples;
  78.  
  79.  
  80. /**
  81.  * \brief The struct that contains info about a PCM audio stream. \n
  82.  *        When saved as a file (usually as ".kpm"), the header's size will be 72 (0x48).
  83.  */
  84. typedef struct kit_acodecPCM {
  85.   Uint32           magic; ///< \brief (0x00) = 0x4D43506B = "kPCM" (no null terminator)
  86.   SDL_AudioFormat format; ///< \brief (0x04) The data format of the stream
  87.   Uint16      headerSize; ///< \brief (0x06) = sizeof(kit_acodecPCM)
  88.   Uint64        dataSize; ///< \brief (0x08) The size of the PCM buffer, in bytes
  89.   Uint64       loopStart; ///< \brief (0x10) Which sample to loop back to
  90.   Uint64         loopEnd; ///< \brief (0x18) Which sample to restart the loop on
  91.   Uint64      numSamples; ///< \brief (0x20) The number of sample frames in the stream
  92.   Uint32      sampleRate; ///< \brief (0x28) The stream's sample rate, in Hz
  93.   Uint32         bitRate; ///< \brief (0x2C) The audio's bit rate per second
  94.   Uint16       loopCount; ///< \brief (0x30) # of times to loop audio (65535 for infinite loop)
  95.   Uint16        channels; ///< \brief (0x32) # of interlaced channels in the stream (L&R for stereo)
  96.   Uint8     bitRemainder; ///< \brief (0x34) = bitsPerSample%8
  97.   Uint8        userflags; ///< \brief (0x35) User-defined (is just padding otherwise)
  98.   Uint16       uservalue; ///< \brief (0x36) User-defined (is just padding otherwise)
  99.   //while userdata and data are technically included in a .kpm file,
  100.    //they should appear as 0 within that file
  101.   void*         userdata; ///< \brief (0x38) User-defined pointer
  102.   union {
  103.     void*  data; ///< \brief = (void*)pcm_struct_pointer + pcm_struct_pointer->headerSize
  104.     Uint8*  u_8; ///< \brief Mono Uint8 Samples
  105.     Sint16* i16; ///< \brief Mono Sint16 Samples
  106.     Sint32* i32; ///< \brief Mono Sint32 Samples
  107.     float*  f32; ///< \brief Mono float Samples
  108.     kit_acodecPCM_U_8S* u_8s; ///< \brief Stereo Uint8 samples
  109.     kit_acodecPCM_I16S* i16s; ///< \brief Stereo Sint16 samples
  110.     kit_acodecPCM_I32S* i32s; ///< \brief Stereo Sint32 samples
  111.     kit_acodecPCM_F32S* f32s; ///< \brief Stereo float samples
  112.   }; ///< \brief (0x40) Sample data (PCM data should be contiguous with the struct itself)
  113. } kit_acodecPCM;
  114.  
  115.  
  116.  
  117. /**
  118.  * Destroy a kit_acodecPCM stream
  119.  * \param[in,out] pcm_p A pointer to the kit_acodecPCM* to be destroyed (before being set to NULL)
  120.  * \return 0 on success, or -1 on error (call SDL_GetError() for more info)
  121.  *
  122.  * \sa kit_acodecPCMCreate
  123.  * \sa kit_acodecPCMCopy
  124.  */
  125. extern int kit_acodecPCMDestroy(kit_acodecPCM** pcm_p);
  126.  
  127. /**
  128.  * Destroy a kit_acodecPCM stream
  129.  * \param[in] format The data type of the stream
  130.  * \param[in] channels The number of interlaced channels in the stream
  131.  * \param[in] sampleRate The desired sample rate, in hertz
  132.  * \param[in] numSamples The number of sample frames in the stream
  133.  * \return A pointer to the newly-created pcm stream, or NULL on error (call SDL_GetError() for more info)
  134.  *
  135.  * \sa kit_acodecPCMDestroy
  136.  * \sa kit_acodecPCMCopy
  137.  */
  138. extern kit_acodecPCM* kit_acodecPCMCreate(SDL_AudioFormat format, Uint16 channels,
  139.                                           Uint32 sampleRate, Uint64 numSamples);
  140.  
  141. /**
  142.  * Create a duplicate of a kit_acodecPCM stream
  143.  * \param[in] pcm A pointer to the kit_acodecPCM stream to be copied
  144.  * \return A pointer to a newly-copied kit_acodecPCM stream,
  145.  *         or NULL on error (call SDL_GetError() for more info)
  146.  *
  147.  * \sa kit_acodecPCMDestroy
  148.  * \sa kit_acodecPCMCreate
  149.  */
  150. extern kit_acodecPCM* kit_acodecPCMCopy(kit_acodecPCM* pcm);
  151.  
  152.  
  153. /**
  154.  * Read kit_acodecPCM data from a pcm file (usually with a ".kpm" file extension)
  155.  * \param[in] filePath The name of the file to read from
  156.  * \return A pointer to a kit_acodecPCM struct that contains the audio data,
  157.  *         or NULL on error (call SDL_GetError() for more info)
  158.  *
  159.  * \sa kit_acodecPCMWrite
  160.  */
  161. extern kit_acodecPCM* kit_acodecPCMRead(const char* filePath);
  162.  
  163. /**
  164.  * Save kit_acodecPCM data to a pcm file (usually with a ".kpm" file extension)
  165.  * \param[in] pcm A pointer to a kit_acodecPCM struct that contains the audio data
  166.  * \param[in] filePath The name of the file to write to
  167.  * \return 0 on success, or -1 on error (call SDL_GetError() for more info)
  168.  *
  169.  * \sa kit_acodecPCMRead
  170.  */
  171. extern int kit_acodecPCMWrite(kit_acodecPCM* pcm, const char* filePath);
  172.  
  173.  
  174. /**
  175.  * Change the number of sample frames in a kit_acodecPCM stream
  176.  * \param[in,out] pcm_p A pointer to the kit_acodecPCM* to be resized
  177.  * \param[in] numSamples The amount of sample frames to resize the stream to
  178.  * \return 0 on success, or -1 on error (call SDL_GetError() for more info)
  179.  */
  180. extern int kit_acodecPCMSetNumSamples(kit_acodecPCM** pcm_p, Uint64 numSamples);
  181.  
  182. /**
  183.  * Create a copy of a kit_acodecPCM stream, converted to either mono or stereo
  184.  * \param[in] pcm A pointer to the input kit_acodecPCM stream
  185.  * \param[in] toStereo Whether to convert to stereo, or convert to mono
  186.  * \return A pointer to a kit_acodecPCM struct that contains the converted stream,
  187.  *         or NULL on error (call SDL_GetError() for more info)
  188.  *
  189.  * \remark Accepted formats are AUDIO_U8, AUDIO_S16, AUDIO_S32, and AUDIO_F32. \n
  190.  * \remark (Trying to use a stream with > 2 channels is not allowed!)
  191.  */
  192. extern kit_acodecPCM* kit_acodecPCMConvertStereo(kit_acodecPCM* pcm, SDL_bool toStereo);
  193.  
  194. /**
  195.  * Create a copy of a kit_acodecPCM stream, under a new sample format
  196.  * \param[in] pcm A pointer to the input kit_acodecPCM stream
  197.  * \param[in] format The sample format to convert to
  198.  * \return A pointer to a kit_acodecPCM struct that contains the converted stream,
  199.  *         or NULL on error (call SDL_GetError() for more info)
  200.  *
  201.  * \remark Accepted formats are AUDIO_U8, AUDIO_S16, AUDIO_S32, and AUDIO_F32.
  202.  * \remark (Also, conversions from AUDIO_S32 will have a quantization error of up to 64!)
  203.  */
  204. extern kit_acodecPCM* kit_acodecPCMConvertFormat(kit_acodecPCM* pcm, SDL_AudioFormat format);
  205.  
  206. /**
  207.  * Create a copy of a kit_acodecPCM stream, under a new sample rate
  208.  * \param[in] pcm A pointer to the input kit_acodecPCM stream
  209.  * \param[in] sampleRate The sample rate to convert to
  210.  * \param[in] linearInterpolation A boolean of whether to use linear interpolation
  211.  *            during sample rate conversion (nearest-neighbor is used otherwise)
  212.  * \return A pointer to a kit_acodecPCM struct that contains the converted stream,
  213.  *         or NULL on error (call SDL_GetError() for more info)
  214.  *
  215.  * \remark Accepted formats are AUDIO_U8, AUDIO_S16, AUDIO_S32, and AUDIO_F32.
  216.  */
  217. extern kit_acodecPCM* kit_acodecPCMResample(kit_acodecPCM* pcm, Uint32 sampleRate,
  218.                                             SDL_bool linearInterpolation);
  219.  
  220. /* -------------------- */
  221. /* -kit_sdl2_acodecPCM- */
  222. /* -------------------- */
  223.  
  224.  
  225.  
  226.  
  227. /* ++++++++++++++++++++ */
  228. /* +kit_sdl2_acodecWAV+ */
  229. /* ++++++++++++++++++++ */
  230.  
  231. /**
  232.  * Load kit_acodecPCM data from a ".wav" file
  233.  * \param[in] filePath The name of the wav file to load
  234.  * \return A pointer to a kit_acodecPCM struct that contains the audio data,
  235.  *         or NULL on error (call SDL_GetError() for more info)
  236.  *
  237.  * \remark Supported sample formats are: Uint8, Sint16, Sint32, and float
  238.  * \sa kit_acodecPCM
  239.  * \sa kit_acodecWAVWrite
  240.  */
  241. extern kit_acodecPCM* kit_acodecWAVRead(const char* filePath);
  242.  
  243. /**
  244.  * Save kit_acodecPCM data to a ".wav" file
  245.  * \param[in] pcm A pointer to a kit_acodecPCM struct that contains the audio data
  246.  * \param[in] filePath The name of the wav file to write to
  247.  * \return 0 on success, or -1 on failure; call SDL_GetError() for details
  248.  *
  249.  * \sa kit_acodecPCM
  250.  * \sa kit_acodecWAVRead
  251.  */
  252. extern int kit_acodecWAVWrite(kit_acodecPCM* pcm, const char* filePath);
  253.  
  254. /* -------------------- */
  255. /* -kit_sdl2_acodecWAV- */
  256. /* -------------------- */
  257.  
  258.  
  259.  
  260.  
  261. /* ++++++++++++++++++++ */
  262. /* +kit_sdl2_acodecFDM+ */
  263. /* ++++++++++++++++++++ */
  264.  
  265. #define FDM_MAGIC_NUMBER 0x4D44466B
  266. typedef struct kit_acodecFDMHeader { //(".kfd")
  267.   union {
  268.     char      s[4]; //="kFDM"
  269.     Uint32       n; //=0x4D44466B
  270.   } /*-----*/ magic;
  271.   Uint16 headerSize; //headerSize includes headerSize itself, and magic
  272.   Uint16       type; //type 0 = static delta, static history
  273.   Uint64   dataSize;
  274.   Uint64 numSamples;
  275.   Uint64  loopStart;
  276.   Uint64    loopEnd;
  277.   float       delta; //% of change, relative to HALF range; 0.0 -> 2.0
  278.   Uint8   loopCount; //255 (-1) for inf. loop
  279.   Uint8   remainder; //=numSamples%8
  280.   Uint8  historyLen; //number of samples in filter; 0 -> 63
  281.   Uint8    channels;
  282. } kit_acodecFDMHeader;
  283.  
  284.  
  285.  
  286. extern kit_acodecPCM* kit_acodecFDMRead(const char* filePath);
  287.  
  288. extern int kit_acodecFDMWrite(const char* fileName, kit_acodecPCM* pcm,
  289.                               Uint8 historyLen, Uint8 iterations);
  290.  
  291. /* -------------------- */
  292. /* -kit_sdl2_acodecFDM- */
  293. /* -------------------- */
  294.  
  295.  
  296.  
  297.  
  298. /* +++++++++++++++++ */
  299. /* +kit_sdl2_acodec+ */
  300. /* +++++++++++++++++ */
  301.  
  302. extern const SDL_bool kit_acodecIsDebug;
  303.  
  304.  
  305.  
  306. /**
  307.  * Load kit_acodecPCM data from a valid audio file
  308.  * \param[in] filePath The name of the file to load from
  309.  * \param[in] format The target data type to convert to (0 to keep original data type)
  310.  * \param[in] sampleRate The target sample rate to resample to (0 to keep original sample rate)
  311.  * \param[in] linearInterpolation 'Use linear interpolation if resampling?' (nearest-neighbor otherwise)
  312.  * \return A pointer to a kit_acodecPCM struct that contains the audio data,
  313.  *         or NULL on error (call SDL_GetError() for more info)
  314.  *
  315.  * \remark Supported file formats are: "kPCM" (.kpm), "kFDM" (.kfd), and "WAVE" (.wav)
  316.  */
  317. extern kit_acodecPCM* kit_acodecLoadAudio(const char* filePath, SDL_AudioFormat format,
  318.                                           Uint32 sampleRate, SDL_bool linearInterpolation);
  319.  
  320. /* ----------------- */
  321. /* -kit_sdl2_acodec- */
  322. /* ----------------- */
  323.  
  324.  
  325.  
  326.  
  327. #ifdef __cplusplus
  328. }
  329. #endif
  330.  
  331. #endif /* _KIT_SDL2_ACODEC_H */
  332. #endif /* _KIT_ACODEC_H */
  333.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement