Advertisement
Kitomas

kit_w32_audio.h with winmm

Jun 29th, 2023
971
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.28 KB | Source Code | 0 0
  1. //(compile with kernel32, ole32, and optionally winmm (define "KIT_AUDIO_USE_WINMM" to use waveIn/Out functionality)
  2. /**
  3.  * \file kit_w32_audio.h
  4.  * \brief Header file for KIT Win32's audio module
  5.  */
  6. //uncomment this if compiling kit_w32_audio.a, and want to use winmm
  7. #ifndef KIT_AUDIO_USE_WINMM
  8. #  define KIT_AUDIO_USE_WINMM
  9. #endif
  10.  
  11. #ifndef _KIT_W32_AUDIO_H
  12. #define _KIT_W32_AUDIO_H
  13. #  ifndef _KIT_AUDIO
  14. #  define _KIT_AUDIO
  15.  
  16.  
  17.  
  18. /* GENERAL */
  19. #include <stdint.h>
  20. #include <string.h>
  21. #include <windef.h>
  22. //(requires that winmm was linked when kit_w32_audio.a was compiled)
  23. #ifdef KIT_AUDIO_USE_WINMM
  24. #  include <mmsystem.h>
  25. #endif
  26. //WAVEFORMATEXTENSIBLE lives in mmreg.h, but i don't want
  27.  //to also include wingdi.h here just for BITMAPINFOHEADER
  28.  //TBD: check if mmreg.h is deprecated like winmm, as i'm pretty sure they're related
  29. #ifndef NOBITMAP
  30. #  define NOBITMAP
  31. #  include <mmreg.h>
  32. #  undef NOBITMAP
  33. #else
  34. #  include <mmreg.h>
  35. #endif
  36. //this provides CRITICAL_SECTION, which is a type of mutex object iirc
  37. #include <synchapi.h>
  38. //used for creating and managing threads
  39. #include <processthreadsapi.h>
  40. #include <combaseapi.h>
  41. #define _kit_audioMalloc(_type,_len) CoTaskMemAlloc(sizeof(_type)*(_len))
  42. #define _kit_audioFree(_ptr) CoTaskMemFree(_ptr)
  43. #define _kit_audioRealloc(_ptr,_type,_len) CoTaskMemRealloc(_ptr,sizeof(_type)*(_len))
  44.  
  45.  
  46. /**
  47.  * \name Audio Format Constants
  48.  */
  49. /** @{ */
  50. #define KIT_AUDIO_FMT_I8  (0x8007) ///< \brief signed  8-bit samples
  51. #define KIT_AUDIO_FMT_U8  (0x0007) ///< \brief unsigned  8-bit samples
  52.  
  53. #define KIT_AUDIO_FMT_I16LSB (0x800F) ///< \brief   signed 16-bit samples (little endian)
  54. #define KIT_AUDIO_FMT_U16LSB (0x000F) ///< \brief unsigned 16-bit samples (little endian)
  55. #define KIT_AUDIO_FMT_I32LSB (0x801F) ///< \brief   signed 32-bit samples (little endian)
  56. #define KIT_AUDIO_FMT_U32LSB (0x001F) ///< \brief unsigned 32-bit samples (little endian)
  57. #define KIT_AUDIO_FMT_F32LSB (0x811F) ///< \brief 32-bit float samples (little endian)
  58. #define KIT_AUDIO_FMT_F64LSB (0x813F) ///< \brief 64-bit float samples (little endian)
  59.  
  60. #define KIT_AUDIO_FMT_I16MSB (0x900F) ///< \brief   signed 16-bit samples (big endian)
  61. #define KIT_AUDIO_FMT_U16MSB (0x100F) ///< \brief unsigned 16-bit samples (big endian)
  62. #define KIT_AUDIO_FMT_I32MSB (0x901F) ///< \brief   signed 32-bit samples (big endian)
  63. #define KIT_AUDIO_FMT_U32MSB (0x101F) ///< \brief unsigned 32-bit samples (big endian)
  64. #define KIT_AUDIO_FMT_F32MSB (0x911F) ///< \brief 32-bit float samples (big endian)
  65. #define KIT_AUDIO_FMT_F64MSB (0x913F) ///< \brief 64-bit float samples (big endian)
  66.  
  67. #define KIT_AUDIO_FMT_I16 KIT_AUDIO_FMT_I16LSB
  68. #define KIT_AUDIO_FMT_U16 KIT_AUDIO_FMT_U16LSB
  69. #define KIT_AUDIO_FMT_I32 KIT_AUDIO_FMT_I32LSB
  70. #define KIT_AUDIO_FMT_U32 KIT_AUDIO_FMT_U32LSB
  71. #define KIT_AUDIO_FMT_F32 KIT_AUDIO_FMT_F32LSB
  72. #define KIT_AUDIO_FMT_F64 KIT_AUDIO_FMT_F64LSB
  73. /** @} */
  74.  
  75.  
  76. /**
  77.  * \name Audio Format Bitmasks & Macros
  78.  */
  79. /** @{ */ /* (the "M" in FMT_M means (bit)mask) */
  80. #define KIT_AUDIO_FMT_MBITSIZE (0x00FF)
  81. #define KIT_AUDIO_FMT_MFLOAT   (0x0100)
  82. #define KIT_AUDIO_FMT_MENDIAN  (0X1000)
  83. #define KIT_AUDIO_FMT_MSIGNED  (0x8000)
  84. #define KIT_AUDIO_FMT_BITSIZE(x)        ((x) & KIT_AUDIO_FMT_MBITSIZE)
  85. #define KIT_AUDIO_FMT_ISFLOAT(x)        ((x) & KIT_AUDIO_FMT_MFLOAT)
  86. #define KIT_AUDIO_FMT_ISBIGENDIAN(x)    ((x) & KIT_AUDIO_FMT_MENDIAN)
  87. #define KIT_AUDIO_FMT_ISSIGNED(x)       ((x) & KIT_AUDIO_FMT_MSIGNED)
  88. #define KIT_AUDIO_FMT_ISINT(x)          (!KIT_AUDIO_FMT_ISFLOAT(x))
  89. #define KIT_AUDIO_FMT_ISLITTLEENDIAN(x) (!KIT_AUDIO_FMT_ISBIGENDIAN(x))
  90. #define KIT_AUDIO_FMT_ISUNSIGNED(x)     (!KIT_AUDIO_FMT_ISSIGNED(x))
  91. /** @} */
  92.  
  93.  
  94. /**
  95.  * \name Audio Device Type Constants
  96.  */
  97. /** @{ */
  98. #define _KIT_AUDIO_DEVTYPE_BASE                               0
  99. #define KIT_AUDIO_DEVTYPE_WASAPIIN  (_KIT_AUDIO_DEVTYPE_BASE+1)
  100. #define KIT_AUDIO_DEVTYPE_WASAPIOUT (_KIT_AUDIO_DEVTYPE_BASE+2)
  101. #define KIT_AUDIO_DEVTYPE_WAVEIN    (_KIT_AUDIO_DEVTYPE_BASE+3)
  102. #define KIT_AUDIO_DEVTYPE_WAVEOUT   (_KIT_AUDIO_DEVTYPE_BASE+4)
  103. /** @} */
  104.  
  105.  
  106. /**
  107.  * \name Audio Device Type Macros
  108.  */
  109. /** @{ */
  110. #define KIT_AUDIO_IFNOTDEVICE(_device)\
  111.   if(_device               == NULL                  || \
  112.      _device->_magic.num   != 0x007665446F69647561     \
  113.   )
  114. #define KIT_AUDIO_IFDEVICEINVALID(_device,_type)\
  115.   if(_device               == NULL                  || \
  116.      _device->_magic.num   != 0x007665446F69647561  || \
  117.      _device->_device_type != _type                    \
  118.   )
  119. #define KIT_AUDIO_AUDITANDLOCK(_device,_type,_errorvalue)\
  120.   if(!kit_audioLockDevice(_device)  || \
  121.      _device->device_type != _type    \
  122.   ) return _errorvalue;
  123. #define KIT_AUDIO_LOCK(_device) \
  124.   EnterCriticalSection(&_device->_mutex);
  125. //assumes audit already happened
  126. #define KIT_AUDIO_UNLOCK(_device) \
  127.   LeaveCriticalSection(&_device->_mutex);
  128. #define _KIT_AUDIO_LOCKCALLBACKTHREAD(_device) \
  129.   EnterCriticalSection(&_device->_callback_mutex);
  130. #define _KIT_AUDIO_UNLOCKCALLBACKTHREAD(_device) \
  131.   LeaveCriticalSection(&_device->_callback_mutex);
  132. /** @} */
  133.  
  134.  
  135. /**
  136.  * Audio Format (FMT)
  137.  * \verbatim
  138.    Bit Layout is as follows:
  139.  
  140.    +----------------------sample is signed if set
  141.    |
  142.    |        +----------sample is bigendian if set
  143.    |        |
  144.    |        |           +--sample is float if set
  145.    |        |           |
  146.    |        |           |  +-sample bit size (-1)+
  147.    |        |           |  |                     |
  148.    15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
  149.    \endverbatim
  150.  */
  151. typedef uint16_t kit_audioFormat;
  152.  
  153.  
  154. /**
  155.  * PCM Audio Callback
  156.  * This type of function is called when an opened (and unpaused)
  157.  * audio device's audio buffer needs more PCM data.
  158.  * The given audio buffer must be completely filled before returning
  159.  * \param userdata A user-defined pointer passed to the callback, which
  160.  *                 is stored in the same kit_audioSpec as the callback itself
  161.  * \param stream   A pointer to the audio data buffer
  162.  * \param len      The length of that buffer in bytes
  163.  */
  164. typedef void (*kit_audioCallback) (void* userdata,  void* stream, unsigned int len);
  165.  
  166.  
  167. /**
  168.  * \brief This is the struct for an audio specification (something like a config but for a kit_audioDevice)
  169.  */
  170. typedef struct {
  171.   kit_audioCallback callback; ///< \brief Called when the audio buffer needs to be refilled
  172.   void*             userdata; ///< \brief User-defined pointer passed to callback
  173.   uint32_t         frequency; ///< \brief Sample rate of audio in Hz
  174.   uint32_t       buffer_size; ///< \brief Audio buffer length in bytes (automatically calculated)
  175.   uint16_t        buffer_len; ///< \brief Audio buffer length in samples (must a be power of 2)
  176.   uint16_t          channels; ///< \brief Number of audio channels (1=mono, 2=stereo, etc.)
  177.   kit_audioFormat     format; ///< \brief Audio data format information
  178.   uint16_t          _padding; //hopefully this works as intended
  179. } kit_audioSpec;
  180.  
  181.  
  182. /**
  183.  * \brief This is the struct used for both WASAPI in/out and waveIn/Out devices. \n
  184.  * Something of note is that most members of this struct have the "_" prefix,
  185.  * which states that they are private and most likely should not be interacted
  186.  * with or modified unless through kit_audio's interface.
  187.  *
  188.  * (While this struct uses an ID in the form of _magic, this type of ID
  189.  * is not present in every kind of 'kit_moduleName' struct.)
  190.  */
  191. typedef struct {
  192.   union {
  193.     char               str[8]; ///< \brief String portion of ID ("audioDev\x00")
  194.     uint64_t              num; ///< \brief Number portion of ID (0x007665446F69647561)
  195.   } /* -------------- */ _magic; ///< \brief Struct ID number; union of uint64_t and char[8]
  196.   WAVEFORMATEXTENSIBLE    _info; ///< \brief Used for some internal Win32 interactions
  197.   #ifdef KIT_AUDIO_USE_WINMM
  198.   WAVEHDR       _buffer_info[2]; ///< \brief Information related to output streams
  199.   #endif
  200.   CRITICAL_SECTION       _mutex; ///< \brief Used to stop callback from triggering if kit_audioLockDevice is called
  201.   CRITICAL_SECTION _callback_mutex; ///< \brief Used to lock access to _callback_thread specifically
  202.   kit_audioSpec             src; ///< \brief Audio format of input stream buffer
  203.   kit_audioSpec             cvt; ///< \brief Audio format of ConVerTed (output) stream
  204.   union {
  205.     HANDLE            _handle; ///< \brief Pointer handle of the device
  206.     #ifdef KIT_AUDIO_USE_WINMM
  207.     HWAVEIN    _handle_waveIn;
  208.     HWAVEOUT  _handle_waveOut;
  209.     #endif
  210.   };
  211.   HANDLE       _callback_thread; ///< \brief User-defined callback thread, which kit_audioWaveOutReset locks until completion for
  212.   void*              _buffer[2]; ///< \brief Output streams (while 0 is playing, 1 is being filled, and vice versa)
  213.   void*                 _stream; ///< \brief Points to the input stream data that is passed to _src.callback
  214.   float*                 volume; ///< \brief Volume multiplier for each audio channel (0.0 -> 1.0)
  215.   uint32_t     callback_timeout; ///< \brief Timeout for callback thread, in milliseconds (default of 10000)
  216.   uint16_t               status; ///< \brief Gives some info of the device's state
  217.   uint8_t              _playing; ///< \brief A boolean of whether the device is unpaused or not
  218.   uint8_t           _cvt_needed; ///< \brief A boolean of 'is format conversion needed?'
  219.   uint8_t           device_type; ///< \brief 1, 2, 3, 4  =  WASAPI in, WASAPI out, waveIn, waveOut
  220.   uint8_t                _which; ///< \brief Which output stream to fill with more audio data
  221.   uint16_t             _padding;
  222.   union {
  223.     #ifdef KIT_AUDIO_USE_WINMM
  224.     WAVEINCAPS    _waveInCaps; ///< \brief Capabilities of a waveIn device
  225.     WAVEOUTCAPS  _waveOutCaps; ///< \brief Capabilities of a waveOut device
  226.     #endif
  227.   }; /* --------------------- */ ///< \brief Capability specifications of a device
  228. } kit_audioDevice;
  229.  
  230.  
  231. /**
  232.  * \brief Lock the audio callback of a given device from being called
  233.  *        (useful for manipulating the device struct)
  234.  *
  235.  * \param device A pointer to the device
  236.  * \return A boolean of if the given pointer is an actual audio device
  237.  *
  238.  * \remark This activates a CRITICAL_SECTION mutex, so unlock as soon as possible
  239.  */
  240. static inline int kit_audioLockDevice(kit_audioDevice* device){
  241.   KIT_AUDIO_IFNOTDEVICE(device) return 0;
  242.   else { EnterCriticalSection(&device->_mutex); return 1; }
  243. }
  244.  
  245.  
  246. /**
  247.  * \brief Unlock the audio callback of a given device
  248.  *
  249.  * \param device A pointer to the device
  250.  * \return A boolean of if the given pointer is an actual audio device
  251.  */
  252. static inline int kit_audioUnlockDevice(kit_audioDevice* device){
  253.   KIT_AUDIO_IFNOTDEVICE(device) return 0;
  254.   else { LeaveCriticalSection(&device->_mutex); return 1; }
  255. }
  256.  
  257.  
  258. /**
  259.  * \brief Get the current playing state of a given device
  260.  *
  261.  * \param device A pointer to the device
  262.  * \return A boolean value of whether the device is currently unpaused or not
  263.  */
  264. static inline int kit_audioIsPlaying(kit_audioDevice* device){
  265.   if(!kit_audioLockDevice(device)) return 0;
  266.   int isPlaying=device->_playing;
  267.   KIT_AUDIO_UNLOCK(device);
  268.   return isPlaying;
  269. }
  270.  
  271.  
  272. /**
  273.  * \brief Set a device channel's volume multiplier (values should be 0.0 -> 1.0)
  274.  *
  275.  * \param device A pointer to the device
  276.  * \param volume New volume multiplier for selected channel
  277.  * \param channel Channel to assign new multiplier to
  278.  */
  279. static inline void kit_audioSetVolume(kit_audioDevice* device, float volume,uint32_t channel){
  280.   if(!kit_audioLockDevice(device)) return;
  281.   if(channel>=device->cvt.channels) return;
  282.   device->volume[channel]=volume;
  283.   KIT_AUDIO_UNLOCK(device);
  284. }
  285.  
  286.  
  287. /**
  288.  * \brief Set Stereo volume multiplier for device (values should be 0.0 -> 1.0)
  289.  *
  290.  * \param device A pointer to the device
  291.  * \param volL New volume multiplier for left channel (or just channel 0 if channels is equal to 1)
  292.  * \param volR New volume multiplier for right channel (ignored if channels is <2)
  293.  */
  294. static inline void kit_audioSetVolumeLR(kit_audioDevice* device, float volL,float volR){
  295.   if(!kit_audioLockDevice(device)) return;
  296.   device->volume[0]=volL;
  297.   if(device->cvt.channels>1) device->volume[1]=volR;
  298.   KIT_AUDIO_UNLOCK(device);
  299. }
  300.  
  301.  
  302.  
  303. /* WASAPI */
  304. /*//link against kernel32 and ole32
  305. #include <initguid.h>
  306. #include <mmdeviceapi.h>
  307. #include <audioclient.h>
  308. */
  309.  
  310.  
  311.  
  312. /* WINMM */
  313. #ifdef KIT_AUDIO_USE_WINMM
  314.  
  315.  
  316. //thread process that handles filling waveOut audio buffers
  317. extern DWORD WINAPI _kit_audioWaveOutFillBuffer(LPVOID device_void_ptr);
  318.  
  319.  
  320. //callback associated with a waveOut device
  321. extern void CALLBACK _kit_audioWaveOutProc(HWAVEOUT waveOutHandle, UINT message, DWORD_PTR instance,
  322.                                            DWORD_PTR param1, DWORD_PTR param2);
  323.  
  324.  
  325. //(remember to turn on static member extraction in doxygen config!)
  326. /**
  327.  * \brief Get the current number of waveOut devices
  328.  *
  329.  * \return The number of available waveOut devices, or NULL on error \n
  330.  *         A value of 0 either means none are present, or an error occurred
  331.  */
  332. static inline uint32_t kit_audioWaveOutGetNumDevs(){
  333.   return (uint32_t)waveOutGetNumDevs();
  334. }
  335.  
  336.  
  337. /**
  338.  * \brief Play/Pause a given waveOut device
  339.  *
  340.  * \param device A pointer to the device
  341.  * \param playState A boolean of whether to resume playing or pause the device
  342.  * \return Result of either waveOutRestart/waveOutPause (depending on if playState == 1 or not) \n
  343.  *         Possible return values:
  344.  * \verbatim
  345.    "MMSYSERR_NOERROR": No error occurred; success!
  346.    "MMSYSERR_INVALHANDLE": Specified device handle is invalid
  347.    "MMSYSERR_NODRIVER": No device driver is present
  348.    "MMSYSERR_NOMEM": Unable to allocate or lock memory.
  349.    "MMSYSERR_NOTSUPPORTED": Specified device is synchronous and does not support pausing
  350.    \endverbatim
  351.  * (MMSYSERR_INVALHANDLE can also be returned if "device" is not a waveOut device)
  352.  */
  353. extern uint32_t kit_audioWaveOutPlay(kit_audioDevice* device, int playState);
  354.  
  355.  
  356. //threading can be a pain, so this is on the backburner for now
  357. /* *
  358.  * \brief Stop playback of waveOut device, before setting current position to zero. \n
  359.  *        (This will immediately call the device's kit_audioCallback to initialize the buffer again!)
  360.  * \remark If the kit_audioCallback is already running, the thread calling kit_audioWaveOutReset
  361.  *         will lock until the callback has completed
  362.  *
  363.  * \param device A pointer to the device
  364.  * \return result of waveOutReset, or MMSYSERR_INVALHANDLE if "device" is not a waveOut device \n
  365.  *         Possible return values:
  366.  * \verbatim
  367.    "MMSYSERR_NOERROR": No error occurred; success!
  368.    "MMSYSERR_INVALHANDLE": Specified device handle is invalid
  369.    "MMSYSERR_NODRIVER": No device driver is present
  370.    "MMSYSERR_NOMEM": Unable to allocate or lock memory.
  371.    "MMSYSERR_NOTSUPPORTED": Specified device is synchronous and does not support pausing
  372.    \endverbatim
  373.  */
  374. //extern uint32_t kit_audioWaveOutReset(kit_audioDevice* device);//, uint32_t timeoutMilliseconds);
  375. /*
  376.  * \param timeoutMilliseconds Maximum wait time for callback thread to end. \n
  377.  *        -1 (or "INFINITE") to wait indefinitely, and 0 to use device's timeout (10000 by default)
  378. */
  379.  
  380.  
  381. /**
  382.  * \brief Open a waveOut device (device will be paused initially)
  383.  *
  384.  * \param desiredSpec The desired kit_audioSpec of the audio stream
  385.  * \param deviceID The ID number of the desired waveOut device (-1 to select default device)
  386.  * \param returnStatus A pointer to an int to be filled with a status code (ignored unless function returns NULL) \n
  387.  *        Possible returnStatus codes (all but 0 is considered an error):
  388.  * \verbatim
  389.     0: Device opened successfully; no error
  390.     1: CoTaskMemAlloc (equivalent to malloc) of device returned NULL
  391.     2: Callback in desiredSpec was NULL
  392.     3: Bad device ID (ID specified was out of range)
  393.     4: No device driver is present
  394.     5: Unable to allocate or lock memory while fetching device capabilities
  395.     6: Format of device capabilities empty for some reason (this shouldn't happen)
  396.     7: desiredSpec->buffer_len is equal to 0
  397.     8: desiredSpec->buffer_len is not a power of 2
  398.     9: desiredSpec->frequency (sample rate) is neither 11025, 22050, 44100, nor 96000
  399.    10: desiredSpec->channels is neither 1 nor 2
  400.    11: desiredSpec->format is neither U8 (unsigned 8-bit), I16 (signed 16-bit), nor F32 (32-bit float)
  401.    12: Device is incapable of 11.025kHz, mono, signed 8-bit
  402.    13: Device is incapable of 11.025kHz, mono, signed 16-bit
  403.    14: Device is incapable of 11.025kHz, stereo, signed 8-bit
  404.    15: Device is incapable of 11.025kHz, stereo, signed 16-bit
  405.    16: Device is incapable of 22.05kHz, mono, signed 8-bit
  406.    17: Device is incapable of 22.05kHz, mono, signed 16-bit
  407.    18: Device is incapable of 22.05kHz, stereo, signed 8-bit
  408.    19: Device is incapable of 22.05kHz, stereo, signed 16-bit
  409.    20: Device is incapable of 44.1kHz, mono, signed 8-bit
  410.    21: Device is incapable of 44.1kHz, mono, signed 16-bit
  411.    22: Device is incapable of 44.1kHz, stereo, signed 8-bit
  412.    23: Device is incapable of 44.1kHz, stereo, signed 16-bit
  413.    24: Device is incapable of 96kHz, mono, signed 8-bit
  414.    25: Device is incapable of 96kHz, mono, signed 16-bit
  415.    26: Device is incapable of 96kHz, stereo, signed 8-bit
  416.    27: Device is incapable of 96kHz, stereo, signed 16-bit
  417.    28: CoTaskMemAlloc of device->_stream returned NULL
  418.    29: CoTaskMemAlloc of device->_buffer0 returned NULL
  419.    30: CoTaskMemAlloc of device->_buffer1 returned NULL
  420.    31: CoTaskMemAlloc of device->_volume returned NULL
  421.    32: waveOutOpen returned error 'Specified resource is already allocated'
  422.    33: waveOutOpen returned error 'No device driver is present'
  423.    34: waveOutOpen returned error 'Unable to allocate or lock memory'
  424.    35: waveOutOpen returned error 'Attempted to open with an unsupported waveform-audio format'
  425.    36: waveOutOpen returned error 'Device is synchronous, but WAVE_ALLOWSYNC flag was not set'
  426.    \endverbatim
  427.  * \return A pointer to a kit_audioDevice struct, otherwise return NULL on failure
  428.  *
  429.  * \remark Audio might begin stuttering if the audio stream buffer is set too small. \n
  430.  *         For example, audio at 96kHz might stutter with a buffer size of 4096, but 8192 or 16384 should be safe usually.
  431.  *
  432.  * \sa kit_audioWaveOutGetNumDevs
  433.  * \sa kit_audioWaveOutPlay
  434.  */
  435. extern kit_audioDevice* kit_audioWaveOutOpen(kit_audioSpec* desiredSpec, uint32_t deviceID, int* returnStatus_ptr);
  436.  
  437.  
  438. /* *
  439.  * \brief Close a waveOut device
  440.  *
  441.  * \param device_p A pointer to the device's pointer
  442.  * \return 0 on success, positive value on failure. \n
  443.  *         Possible return codes:
  444.  * \verbatim
  445.    0: Device closed successfully; no error
  446.    1: device_p is NULL
  447.    2: *device_p is invalid (pointer is either NULL, or just not a waveOut audioDevice)
  448.    3: waveOutUnprepareHeader returned MMSYSERR_INVALHANDLE (Specified handle is invalid)
  449.    4: waveOutUnprepareHeader returned MMSYSERR_NODRIVER (No device driver is present)
  450.    5: waveOutUnprepareHeader returned MMSYSERR_NOMEM (Unable to allocate or lock memory)
  451.    6: waveOutUnprepareHeader returned WAVERR_STILLPLAYING (There are still buffers in the queue)
  452.    7: waveOutClose returned MMSYSERR_INVALHANDLE
  453.    8: waveOutClose returned MMSYSERR_NODRIVER
  454.    9: waveOutClose returned MMSYSERR_NOMEM
  455.    10: waveOutClose returned WAVERR_STILLPLAYING (There are still buffers in the queue)
  456.    \endverbatim
  457.  */
  458. //extern uint32_t kit_audioWaveOutClose(kit_audioDevice** device_p);
  459.  
  460.  
  461. #endif
  462.  
  463.  
  464.  
  465. #  endif
  466. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement