text: /* FAudio - XAudio Reimplementation for FNA
   *
   * Copyright (c) 2011-2021 Ethan Lee, Luigi Auriemma, and the MonoGame Team
   *
   * This software is provided 'as-is', without any express or implied warranty.
   * In no event will the authors be held liable for any damages arising from
   * the use of this software.
   *
   * Permission is granted to anyone to use this software for any purpose,
   * including commercial applications, and to alter it and redistribute it
   * freely, subject to the following restrictions:
   *
   * 1. The origin of this software must not be misrepresented; you must not
   * claim that you wrote the original software. If you use this software in a
   * product, an acknowledgment in the product documentation would be
   * appreciated but is not required.
   *
   * 2. Altered source versions must be plainly marked as such, and must not be
   * misrepresented as being the original software.
   *
   * 3. This notice may not be removed or altered from any source distribution.
   *
   * Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
   *
   */
  
  /* This file has no documentation since the MSDN docs are still perfectly fine:
   * https://docs.microsoft.com/en-us/windows/desktop/api/xapo/
   *
   * Of course, the APIs aren't exactly the same since XAPO is super dependent on
   * C++. Instead, we use a struct full of functions to mimic a vtable.
   *
   * The only serious difference is that our FAPO (yes, really) always has the
   * Get/SetParameters function pointers, for simplicity. You can ignore these if
   * your effect does not have parameters, as they will never get called unless
   * it is explicitly requested by the application.
   */
  
  #ifndef FAPO_H
  #define FAPO_H
  
  #include "FAudio.h"
  
  #define FAPOAPI FAUDIOAPI
  #define FAPOCALL FAUDIOCALL
  
  #ifdef __cplusplus
  extern "C" {
  #endif /* __cplusplus */
  
  /* Enumerations */
  
  typedef enum FAPOBufferFlags
  {
  	FAPO_BUFFER_SILENT,
  	FAPO_BUFFER_VALID
  } FAPOBufferFlags;
  
  /* Structures */
  
  #pragma pack(push, 1)
  
  typedef struct FAPORegistrationProperties
  {
  	FAudioGUID clsid;
  	int16_t FriendlyName[256]; /* Win32 wchar_t */
  	int16_t CopyrightInfo[256]; /* Win32 wchar_t */
  	uint32_t MajorVersion;
  	uint32_t MinorVersion;
  	uint32_t Flags;
  	uint32_t MinInputBufferCount;
  	uint32_t MaxInputBufferCount;
  	uint32_t MinOutputBufferCount;
  	uint32_t MaxOutputBufferCount;
  } FAPORegistrationProperties;
  
  typedef struct FAPOLockForProcessBufferParameters
  {
  	const FAudioWaveFormatEx *pFormat;
  	uint32_t MaxFrameCount;
  } FAPOLockForProcessBufferParameters;
  
  typedef struct FAPOProcessBufferParameters
  {
  	void* pBuffer;
  	FAPOBufferFlags BufferFlags;
  	uint32_t ValidFrameCount;
  } FAPOProcessBufferParameters;
  
  #pragma pack(pop)
  
  /* Constants */
  
  #define FAPO_MIN_CHANNELS 1
  #define FAPO_MAX_CHANNELS 64
  
  #define FAPO_MIN_FRAMERATE 1000
  #define FAPO_MAX_FRAMERATE 200000
  
  #define FAPO_REGISTRATION_STRING_LENGTH 256
  
  #define FAPO_FLAG_CHANNELS_MUST_MATCH		0x00000001
  #define FAPO_FLAG_FRAMERATE_MUST_MATCH		0x00000002
  #define FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH	0x00000004
  #define FAPO_FLAG_BUFFERCOUNT_MUST_MATCH	0x00000008
  #define FAPO_FLAG_INPLACE_REQUIRED		0x00000020
  #define FAPO_FLAG_INPLACE_SUPPORTED		0x00000010
  
  /* FAPO Interface */
  
  #ifndef FAPO_DECL
  #define FAPO_DECL
  typedef struct FAPO FAPO;
  #endif /* FAPO_DECL */
  
  typedef int32_t (FAPOCALL * AddRefFunc)(
  	void *fapo
  );
  typedef int32_t (FAPOCALL * ReleaseFunc)(
  	void *fapo
  );
  typedef uint32_t (FAPOCALL * GetRegistrationPropertiesFunc)(
  	void* fapo,
  	FAPORegistrationProperties **ppRegistrationProperties
  );
  typedef uint32_t (FAPOCALL * IsInputFormatSupportedFunc)(
  	void* fapo,
  	const FAudioWaveFormatEx *pOutputFormat,
  	const FAudioWaveFormatEx *pRequestedInputFormat,
  	FAudioWaveFormatEx **ppSupportedInputFormat
  );
  typedef uint32_t (FAPOCALL * IsOutputFormatSupportedFunc)(
  	void* fapo,
  	const FAudioWaveFormatEx *pInputFormat,
  	const FAudioWaveFormatEx *pRequestedOutputFormat,
  	FAudioWaveFormatEx **ppSupportedOutputFormat
  );
  typedef uint32_t (FAPOCALL * InitializeFunc)(
  	void* fapo,
  	const void* pData,
  	uint32_t DataByteSize
  );
  typedef void (FAPOCALL * ResetFunc)(
  	void* fapo
  );
  typedef uint32_t (FAPOCALL * LockForProcessFunc)(
  	void* fapo,
  	uint32_t InputLockedParameterCount,
  	const FAPOLockForProcessBufferParameters *pInputLockedParameters,
  	uint32_t OutputLockedParameterCount,
  	const FAPOLockForProcessBufferParameters *pOutputLockedParameters
  );
  typedef void (FAPOCALL * UnlockForProcessFunc)(
  	void* fapo
  );
  typedef void (FAPOCALL * ProcessFunc)(
  	void* fapo,
  	uint32_t InputProcessParameterCount,
  	const FAPOProcessBufferParameters* pInputProcessParameters,
  	uint32_t OutputProcessParameterCount,
  	FAPOProcessBufferParameters* pOutputProcessParameters,
  	int32_t IsEnabled
  );
  typedef uint32_t (FAPOCALL * CalcInputFramesFunc)(
  	void* fapo,
  	uint32_t OutputFrameCount
  );
  typedef uint32_t (FAPOCALL * CalcOutputFramesFunc)(
  	void* fapo,
  	uint32_t InputFrameCount
  );
  typedef void (FAPOCALL * SetParametersFunc)(
  	void* fapo,
  	const void* pParameters,
  	uint32_t ParameterByteSize
  );
  typedef void (FAPOCALL * GetParametersFunc)(
  	void* fapo,
  	void* pParameters,
  	uint32_t ParameterByteSize
  );
  
  struct FAPO
  {
  	AddRefFunc AddRef;
  	ReleaseFunc Release;
  	GetRegistrationPropertiesFunc GetRegistrationProperties;
  	IsInputFormatSupportedFunc IsInputFormatSupported;
  	IsOutputFormatSupportedFunc IsOutputFormatSupported;
  	InitializeFunc Initialize;
  	ResetFunc Reset;
  	LockForProcessFunc LockForProcess;
  	UnlockForProcessFunc UnlockForProcess;
  	ProcessFunc Process;
  	CalcInputFramesFunc CalcInputFrames;
  	CalcOutputFramesFunc CalcOutputFrames;
  	SetParametersFunc SetParameters;
  	GetParametersFunc GetParameters;
  };
  
  #ifdef __cplusplus
  }
  #endif /* __cplusplus */
  
  #endif /* FAPO_H */
  
  /* vim: set noexpandtab shiftwidth=8 tabstop=8: */
  