libs: Import code from upstream FAudio 21.10.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-10-21 11:45:51 +02:00
parent 5329da61ac
commit 6b45777121
34 changed files with 32264 additions and 0 deletions

26
configure vendored
View File

@ -711,6 +711,8 @@ JPEG_PE_LIBS
JPEG_PE_CFLAGS
GSM_PE_LIBS
GSM_PE_CFLAGS
FAUDIO_PE_LIBS
FAUDIO_PE_CFLAGS
EXCESS_PRECISION_CFLAGS
CROSSDEBUG
DELAYLOADFLAG
@ -1780,6 +1782,7 @@ enable_dmoguids
enable_dxerr8
enable_dxerr9
enable_dxguid
enable_faudio
enable_gsm
enable_jpeg
enable_jxr
@ -1926,6 +1929,8 @@ CPP
OBJC
OBJCFLAGS
OBJCPP
FAUDIO_PE_CFLAGS
FAUDIO_PE_LIBS
GSM_PE_CFLAGS
GSM_PE_LIBS
JPEG_PE_CFLAGS
@ -2708,6 +2713,11 @@ Some influential environment variables:
OBJC Objective C compiler command
OBJCFLAGS Objective C compiler flags
OBJCPP Objective C preprocessor
FAUDIO_PE_CFLAGS
C compiler flags for the PE faudio, overriding the bundled
version
FAUDIO_PE_LIBS
Linker flags for the PE faudio, overriding the bundled version
GSM_PE_CFLAGS
C compiler flags for the PE gsm, overriding the bundled version
GSM_PE_LIBS Linker flags for the PE gsm, overriding the bundled version
@ -10680,6 +10690,19 @@ esac
fi
if ${FAUDIO_PE_CFLAGS:+false} :; then :
FAUDIO_PE_CFLAGS="-I\$(top_srcdir)/libs/faudio/include"
else
enable_faudio=no
fi
if ${FAUDIO_PE_LIBS:+false} :; then :
FAUDIO_PE_LIBS="faudio mfplat mfreadwrite mfuuid propsys"
else
enable_faudio=no
fi
$as_echo "$as_me:${as_lineno-$LINENO}: faudio cflags: $FAUDIO_PE_CFLAGS" >&5
$as_echo "$as_me:${as_lineno-$LINENO}: faudio libs: $FAUDIO_PE_LIBS" >&5
if ${GSM_PE_CFLAGS:+false} :; then :
GSM_PE_CFLAGS="-I\$(top_srcdir)/libs/gsm/inc"
else
@ -18754,6 +18777,8 @@ QUICKTIME_LIBS = $QUICKTIME_LIBS
CARBON_LIBS = $CARBON_LIBS
METAL_LIBS = $METAL_LIBS
EXCESS_PRECISION_CFLAGS = $EXCESS_PRECISION_CFLAGS
FAUDIO_PE_CFLAGS = $FAUDIO_PE_CFLAGS
FAUDIO_PE_LIBS = $FAUDIO_PE_LIBS
GSM_PE_CFLAGS = $GSM_PE_CFLAGS
GSM_PE_LIBS = $GSM_PE_LIBS
JPEG_PE_CFLAGS = $JPEG_PE_CFLAGS
@ -20052,6 +20077,7 @@ wine_fn_config_makefile libs/dmoguids enable_dmoguids
wine_fn_config_makefile libs/dxerr8 enable_dxerr8
wine_fn_config_makefile libs/dxerr9 enable_dxerr9
wine_fn_config_makefile libs/dxguid enable_dxguid
wine_fn_config_makefile libs/faudio enable_faudio
wine_fn_config_makefile libs/gsm enable_gsm
wine_fn_config_makefile libs/jpeg enable_jpeg
wine_fn_config_makefile libs/jxr enable_jxr

View File

@ -1052,6 +1052,7 @@ WINE_NOTICE_WITH(mingw,[test "x$CROSSTARGET" = "x"],
dnl **** External libraries ****
WINE_EXTLIB_FLAGS(FAUDIO, faudio, "faudio mfplat mfreadwrite mfuuid propsys", "-I\$(top_srcdir)/libs/faudio/include")
WINE_EXTLIB_FLAGS(GSM, gsm, gsm, "-I\$(top_srcdir)/libs/gsm/inc")
WINE_EXTLIB_FLAGS(JPEG, jpeg, jpeg, "-I\$(top_srcdir)/libs/jpeg")
WINE_EXTLIB_FLAGS(JXR, jxr, jxr, "-I\$(top_srcdir)/libs/jxr/jxrgluelib -I\$(top_srcdir)/libs/jxr/image/sys")
@ -3670,6 +3671,7 @@ WINE_CONFIG_MAKEFILE(libs/dmoguids)
WINE_CONFIG_MAKEFILE(libs/dxerr8)
WINE_CONFIG_MAKEFILE(libs/dxerr9)
WINE_CONFIG_MAKEFILE(libs/dxguid)
WINE_CONFIG_MAKEFILE(libs/faudio)
WINE_CONFIG_MAKEFILE(libs/gsm)
WINE_CONFIG_MAKEFILE(libs/jpeg)
WINE_CONFIG_MAKEFILE(libs/jxr)

25
libs/faudio/LICENSE Normal file
View File

@ -0,0 +1,25 @@
/* 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>
*
*/

22
libs/faudio/Makefile.in Normal file
View File

@ -0,0 +1,22 @@
EXTLIB = libfaudio.a
EXTRAINCL = -I$(srcdir)/include
EXTRADEFS = -DFAUDIO_WIN32_PLATFORM -DHAVE_WMADEC
C_SRCS = \
src/F3DAudio.c \
src/FACT.c \
src/FACT3D.c \
src/FACT_internal.c \
src/FAPOBase.c \
src/FAPOFX.c \
src/FAPOFX_echo.c \
src/FAPOFX_eq.c \
src/FAPOFX_masteringlimiter.c \
src/FAPOFX_reverb.c \
src/FAudio.c \
src/FAudioFX_reverb.c \
src/FAudioFX_volumemeter.c \
src/FAudio_internal.c \
src/FAudio_internal_simd.c \
src/FAudio_operationset.c \
src/FAudio_platform_win32.c

View File

@ -0,0 +1,262 @@
/* 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/x3daudio/
*/
#ifndef F3DAUDIO_H
#define F3DAUDIO_H
#ifdef _WIN32
#define F3DAUDIOAPI
#else
#define F3DAUDIOAPI
#endif
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Constants */
#ifndef _SPEAKER_POSITIONS_
#define SPEAKER_FRONT_LEFT 0x00000001
#define SPEAKER_FRONT_RIGHT 0x00000002
#define SPEAKER_FRONT_CENTER 0x00000004
#define SPEAKER_LOW_FREQUENCY 0x00000008
#define SPEAKER_BACK_LEFT 0x00000010
#define SPEAKER_BACK_RIGHT 0x00000020
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080
#define SPEAKER_BACK_CENTER 0x00000100
#define SPEAKER_SIDE_LEFT 0x00000200
#define SPEAKER_SIDE_RIGHT 0x00000400
#define SPEAKER_TOP_CENTER 0x00000800
#define SPEAKER_TOP_FRONT_LEFT 0x00001000
#define SPEAKER_TOP_FRONT_CENTER 0x00002000
#define SPEAKER_TOP_FRONT_RIGHT 0x00004000
#define SPEAKER_TOP_BACK_LEFT 0x00008000
#define SPEAKER_TOP_BACK_CENTER 0x00010000
#define SPEAKER_TOP_BACK_RIGHT 0x00020000
#define _SPEAKER_POSITIONS_
#endif
#ifndef SPEAKER_MONO
#define SPEAKER_MONO SPEAKER_FRONT_CENTER
#define SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT)
#define SPEAKER_2POINT1 \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_LOW_FREQUENCY )
#define SPEAKER_SURROUND \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | \
SPEAKER_BACK_CENTER )
#define SPEAKER_QUAD \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_BACK_LEFT | \
SPEAKER_BACK_RIGHT )
#define SPEAKER_4POINT1 \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | \
SPEAKER_BACK_RIGHT )
#define SPEAKER_5POINT1 \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | \
SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | \
SPEAKER_BACK_RIGHT )
#define SPEAKER_7POINT1 \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | \
SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | \
SPEAKER_BACK_RIGHT | \
SPEAKER_FRONT_LEFT_OF_CENTER | \
SPEAKER_FRONT_RIGHT_OF_CENTER )
#define SPEAKER_5POINT1_SURROUND \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | \
SPEAKER_LOW_FREQUENCY | \
SPEAKER_SIDE_LEFT | \
SPEAKER_SIDE_RIGHT )
#define SPEAKER_7POINT1_SURROUND \
( SPEAKER_FRONT_LEFT | \
SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | \
SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | \
SPEAKER_BACK_RIGHT | \
SPEAKER_SIDE_LEFT | \
SPEAKER_SIDE_RIGHT )
#define SPEAKER_XBOX SPEAKER_5POINT1
#endif
#define F3DAUDIO_PI 3.141592654f
#define F3DAUDIO_2PI 6.283185307f
#define F3DAUDIO_CALCULATE_MATRIX 0x00000001
#define F3DAUDIO_CALCULATE_DELAY 0x00000002
#define F3DAUDIO_CALCULATE_LPF_DIRECT 0x00000004
#define F3DAUDIO_CALCULATE_LPF_REVERB 0x00000008
#define F3DAUDIO_CALCULATE_REVERB 0x00000010
#define F3DAUDIO_CALCULATE_DOPPLER 0x00000020
#define F3DAUDIO_CALCULATE_EMITTER_ANGLE 0x00000040
#define F3DAUDIO_CALCULATE_ZEROCENTER 0x00010000
#define F3DAUDIO_CALCULATE_REDIRECT_TO_LFE 0x00020000
/* Type Declarations */
#define F3DAUDIO_HANDLE_BYTESIZE 20
typedef uint8_t F3DAUDIO_HANDLE[F3DAUDIO_HANDLE_BYTESIZE];
/* Structures */
#pragma pack(push, 1)
typedef struct F3DAUDIO_VECTOR
{
float x;
float y;
float z;
} F3DAUDIO_VECTOR;
typedef struct F3DAUDIO_DISTANCE_CURVE_POINT
{
float Distance;
float DSPSetting;
} F3DAUDIO_DISTANCE_CURVE_POINT;
typedef struct F3DAUDIO_DISTANCE_CURVE
{
F3DAUDIO_DISTANCE_CURVE_POINT *pPoints;
uint32_t PointCount;
} F3DAUDIO_DISTANCE_CURVE;
typedef struct F3DAUDIO_CONE
{
float InnerAngle;
float OuterAngle;
float InnerVolume;
float OuterVolume;
float InnerLPF;
float OuterLPF;
float InnerReverb;
float OuterReverb;
} F3DAUDIO_CONE;
typedef struct F3DAUDIO_LISTENER
{
F3DAUDIO_VECTOR OrientFront;
F3DAUDIO_VECTOR OrientTop;
F3DAUDIO_VECTOR Position;
F3DAUDIO_VECTOR Velocity;
F3DAUDIO_CONE *pCone;
} F3DAUDIO_LISTENER;
typedef struct F3DAUDIO_EMITTER
{
F3DAUDIO_CONE *pCone;
F3DAUDIO_VECTOR OrientFront;
F3DAUDIO_VECTOR OrientTop;
F3DAUDIO_VECTOR Position;
F3DAUDIO_VECTOR Velocity;
float InnerRadius;
float InnerRadiusAngle;
uint32_t ChannelCount;
float ChannelRadius;
float *pChannelAzimuths;
F3DAUDIO_DISTANCE_CURVE *pVolumeCurve;
F3DAUDIO_DISTANCE_CURVE *pLFECurve;
F3DAUDIO_DISTANCE_CURVE *pLPFDirectCurve;
F3DAUDIO_DISTANCE_CURVE *pLPFReverbCurve;
F3DAUDIO_DISTANCE_CURVE *pReverbCurve;
float CurveDistanceScaler;
float DopplerScaler;
} F3DAUDIO_EMITTER;
#ifndef F3DAUDIO_DSP_SETTINGS_DECL
#define F3DAUDIO_DSP_SETTINGS_DECL
typedef struct F3DAUDIO_DSP_SETTINGS F3DAUDIO_DSP_SETTINGS;
#endif /* F3DAUDIO_DSP_SETTINGS_DECL */
struct F3DAUDIO_DSP_SETTINGS
{
float *pMatrixCoefficients;
float *pDelayTimes;
uint32_t SrcChannelCount;
uint32_t DstChannelCount;
float LPFDirectCoefficient;
float LPFReverbCoefficient;
float ReverbLevel;
float DopplerFactor;
float EmitterToListenerAngle;
float EmitterToListenerDistance;
float EmitterVelocityComponent;
float ListenerVelocityComponent;
};
#pragma pack(pop)
/* Functions */
F3DAUDIOAPI void F3DAudioInitialize(
uint32_t SpeakerChannelMask,
float SpeedOfSound,
F3DAUDIO_HANDLE Instance
);
F3DAUDIOAPI uint32_t F3DAudioInitialize8(
uint32_t SpeakerChannelMask,
float SpeedOfSound,
F3DAUDIO_HANDLE Instance
);
F3DAUDIOAPI void F3DAudioCalculate(
const F3DAUDIO_HANDLE Instance,
const F3DAUDIO_LISTENER *pListener,
const F3DAUDIO_EMITTER *pEmitter,
uint32_t Flags,
F3DAUDIO_DSP_SETTINGS *pDSPSettings
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* F3DAUDIO_H */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

814
libs/faudio/include/FACT.h Normal file
View File

@ -0,0 +1,814 @@
/* 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 you are expected to already know how
* XACT works if you are still using these APIs!
*/
#ifndef FACT_H
#define FACT_H
#include "FAudio.h"
#define FACTAPI FAUDIOAPI
#ifdef _WIN32
#define FACTCALL __stdcall
#else
#define FACTCALL
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Type Declarations */
typedef struct FACTAudioEngine FACTAudioEngine;
typedef struct FACTSoundBank FACTSoundBank;
typedef struct FACTWaveBank FACTWaveBank;
typedef struct FACTWave FACTWave;
typedef struct FACTCue FACTCue;
typedef struct FACTNotification FACTNotification;
typedef struct FACTRendererDetails
{
int16_t rendererID[0xFF]; /* Win32 wchar_t */
int16_t displayName[0xFF]; /* Win32 wchar_t */
int32_t defaultDevice;
} FACTRendererDetails;
typedef struct FACTOverlapped
{
void *Internal; /* ULONG_PTR */
void *InternalHigh; /* ULONG_PTR */
FAUDIONAMELESS union
{
FAUDIONAMELESS struct
{
uint32_t Offset;
uint32_t OffsetHigh;
};
void *Pointer;
};
void *hEvent;
} FACTOverlapped;
typedef int32_t (FACTCALL * FACTReadFileCallback)(
void *hFile,
void *buffer,
uint32_t nNumberOfBytesToRead,
uint32_t *lpNumberOfBytesRead,
FACTOverlapped *lpOverlapped
);
typedef int32_t (FACTCALL * FACTGetOverlappedResultCallback)(
void *hFile,
FACTOverlapped *lpOverlapped,
uint32_t *lpNumberOfBytesTransferred,
int32_t bWait
);
typedef struct FACTFileIOCallbacks
{
FACTReadFileCallback readFileCallback;
FACTGetOverlappedResultCallback getOverlappedResultCallback;
} FACTFileIOCallbacks;
typedef void (FACTCALL * FACTNotificationCallback)(
const FACTNotification *pNotification
);
/* FIXME: ABI bug! This should be pack(1) explicitly. Do not memcpy this! */
typedef struct FACTRuntimeParameters
{
uint32_t lookAheadTime;
void *pGlobalSettingsBuffer;
uint32_t globalSettingsBufferSize;
uint32_t globalSettingsFlags;
uint32_t globalSettingsAllocAttributes;
FACTFileIOCallbacks fileIOCallbacks;
FACTNotificationCallback fnNotificationCallback;
int16_t *pRendererID; /* Win32 wchar_t* */
FAudio *pXAudio2;
FAudioMasteringVoice *pMasteringVoice;
} FACTRuntimeParameters;
typedef struct FACTStreamingParameters
{
void *file;
uint32_t offset;
uint32_t flags;
uint16_t packetSize; /* Measured in DVD sectors, or 2048 bytes */
} FACTStreamingParameters;
#define FACT_WAVEBANK_TYPE_BUFFER 0x00000000
#define FACT_WAVEBANK_TYPE_STREAMING 0x00000001
#define FACT_WAVEBANK_TYPE_MASK 0x00000001
#define FACT_WAVEBANK_FLAGS_ENTRYNAMES 0x00010000
#define FACT_WAVEBANK_FLAGS_COMPACT 0x00020000
#define FACT_WAVEBANK_FLAGS_SYNC_DISABLED 0x00040000
#define FACT_WAVEBANK_FLAGS_SEEKTABLES 0x00080000
#define FACT_WAVEBANK_FLAGS_MASK 0x000F0000
typedef enum FACTWaveBankSegIdx
{
FACT_WAVEBANK_SEGIDX_BANKDATA = 0,
FACT_WAVEBANK_SEGIDX_ENTRYMETADATA,
FACT_WAVEBANK_SEGIDX_SEEKTABLES,
FACT_WAVEBANK_SEGIDX_ENTRYNAMES,
FACT_WAVEBANK_SEGIDX_ENTRYWAVEDATA,
FACT_WAVEBANK_SEGIDX_COUNT
} FACTWaveBankSegIdx;
#pragma pack(push, 1)
typedef struct FACTWaveBankRegion
{
uint32_t dwOffset;
uint32_t dwLength;
} FACTWaveBankRegion;
typedef struct FACTWaveBankSampleRegion
{
uint32_t dwStartSample;
uint32_t dwTotalSamples;
} FACTWaveBankSampleRegion;
typedef struct FACTWaveBankHeader
{
uint32_t dwSignature;
uint32_t dwVersion;
uint32_t dwHeaderVersion;
FACTWaveBankRegion Segments[FACT_WAVEBANK_SEGIDX_COUNT];
} FACTWaveBankHeader;
typedef union FACTWaveBankMiniWaveFormat
{
FAUDIONAMELESS struct
{
uint32_t wFormatTag : 2;
uint32_t nChannels : 3;
uint32_t nSamplesPerSec : 18;
uint32_t wBlockAlign : 8;
uint32_t wBitsPerSample : 1;
};
uint32_t dwValue;
} FACTWaveBankMiniWaveFormat;
typedef struct FACTWaveBankEntry
{
FAUDIONAMELESS union
{
FAUDIONAMELESS struct
{
uint32_t dwFlags : 4;
uint32_t Duration : 28;
};
uint32_t dwFlagsAndDuration;
};
FACTWaveBankMiniWaveFormat Format;
FACTWaveBankRegion PlayRegion;
FACTWaveBankSampleRegion LoopRegion;
} FACTWaveBankEntry;
typedef struct FACTWaveBankEntryCompact
{
uint32_t dwOffset : 21;
uint32_t dwLengthDeviation : 11;
} FACTWaveBankEntryCompact;
typedef struct FACTWaveBankData
{
uint32_t dwFlags;
uint32_t dwEntryCount;
char szBankName[64];
uint32_t dwEntryMetaDataElementSize;
uint32_t dwEntryNameElementSize;
uint32_t dwAlignment;
FACTWaveBankMiniWaveFormat CompactFormat;
uint64_t BuildTime;
} FACTWaveBankData;
#pragma pack(pop)
typedef struct FACTWaveProperties
{
char friendlyName[64];
FACTWaveBankMiniWaveFormat format;
uint32_t durationInSamples;
FACTWaveBankSampleRegion loopRegion;
int32_t streaming;
} FACTWaveProperties;
typedef struct FACTWaveInstanceProperties
{
FACTWaveProperties properties;
int32_t backgroundMusic;
} FACTWaveInstanceProperties;
typedef struct FACTCueProperties
{
char friendlyName[0xFF];
int32_t interactive;
uint16_t iaVariableIndex;
uint16_t numVariations;
uint8_t maxInstances;
uint8_t currentInstances;
} FACTCueProperties;
typedef struct FACTTrackProperties
{
uint32_t duration;
uint16_t numVariations;
uint8_t numChannels;
uint16_t waveVariation;
uint8_t loopCount;
} FACTTrackProperties;
typedef struct FACTVariationProperties
{
uint16_t index;
uint8_t weight;
float iaVariableMin;
float iaVariableMax;
int32_t linger;
} FACTVariationProperties;
typedef struct FACTSoundProperties
{
uint16_t category;
uint8_t priority;
int16_t pitch;
float volume;
uint16_t numTracks;
FACTTrackProperties arrTrackProperties[1];
} FACTSoundProperties;
typedef struct FACTSoundVariationProperties
{
FACTVariationProperties variationProperties;
FACTSoundProperties soundProperties;
} FACTSoundVariationProperties;
typedef struct FACTCueInstanceProperties
{
uint32_t allocAttributes;
FACTCueProperties cueProperties;
FACTSoundVariationProperties activeVariationProperties;
} FACTCueInstanceProperties;
#pragma pack(push, 1)
typedef struct FACTNotificationDescription
{
uint8_t type;
uint8_t flags;
FACTSoundBank *pSoundBank;
FACTWaveBank *pWaveBank;
FACTCue *pCue;
FACTWave *pWave;
uint16_t cueIndex;
uint16_t waveIndex;
void* pvContext;
} FACTNotificationDescription;
typedef struct FACTNotificationCue
{
uint16_t cueIndex;
FACTSoundBank *pSoundBank;
FACTCue *pCue;
} FACTNotificationCue;
typedef struct FACTNotificationMarker
{
uint16_t cueIndex;
FACTSoundBank *pSoundBank;
FACTCue *pCue;
uint32_t marker;
} FACTNotificationMarker;
typedef struct FACTNotificationSoundBank
{
FACTSoundBank *pSoundBank;
} FACTNotificationSoundBank;
typedef struct FACTNotificationWaveBank
{
FACTWaveBank *pWaveBank;
} FACTNotificationWaveBank;
typedef struct FACTNotificationVariable
{
uint16_t cueIndex;
FACTSoundBank *pSoundBank;
FACTCue *pCue;
uint16_t variableIndex;
float variableValue;
int32_t local;
} FACTNotificationVariable;
typedef struct FACTNotificationGUI
{
uint32_t reserved;
} FACTNotificationGUI;
typedef struct FACTNotificationWave
{
FACTWaveBank *pWaveBank;
uint16_t waveIndex;
uint16_t cueIndex;
FACTSoundBank *pSoundBank;
FACTCue *pCue;
FACTWave *pWave;
} FACTNotificationWave;
struct FACTNotification
{
uint8_t type;
int32_t timeStamp;
void *pvContext;
FAUDIONAMELESS union
{
FACTNotificationCue cue;
FACTNotificationMarker marker;
FACTNotificationSoundBank soundBank;
FACTNotificationWaveBank waveBank;
FACTNotificationVariable variable;
FACTNotificationGUI gui;
FACTNotificationWave wave;
};
};
#pragma pack(pop)
/* Constants */
#define FACT_CONTENT_VERSION 46
static const uint32_t FACT_FLAG_MANAGEDATA = 0x00000001;
static const uint32_t FACT_FLAG_STOP_RELEASE = 0x00000000;
static const uint32_t FACT_FLAG_STOP_IMMEDIATE = 0x00000001;
static const uint32_t FACT_FLAG_BACKGROUND_MUSIC = 0x00000002;
static const uint32_t FACT_FLAG_UNITS_MS = 0x00000004;
static const uint32_t FACT_FLAG_UNITS_SAMPLES = 0x00000008;
static const uint32_t FACT_STATE_CREATED = 0x00000001;
static const uint32_t FACT_STATE_PREPARING = 0x00000002;
static const uint32_t FACT_STATE_PREPARED = 0x00000004;
static const uint32_t FACT_STATE_PLAYING = 0x00000008;
static const uint32_t FACT_STATE_STOPPING = 0x00000010;
static const uint32_t FACT_STATE_STOPPED = 0x00000020;
static const uint32_t FACT_STATE_PAUSED = 0x00000040;
static const uint32_t FACT_STATE_INUSE = 0x00000080;
static const uint32_t FACT_STATE_PREPAREFAILED = 0x80000000;
static const int16_t FACTPITCH_MIN = -1200;
static const int16_t FACTPITCH_MAX = 1200;
static const int16_t FACTPITCH_MIN_TOTAL = -2400;
static const int16_t FACTPITCH_MAX_TOTAL = 2400;
static const float FACTVOLUME_MIN = 0.0f;
static const float FACTVOLUME_MAX = 16777216.0f;
static const uint16_t FACTINDEX_INVALID = 0xFFFF;
static const uint16_t FACTVARIABLEINDEX_INVALID = 0xFFFF;
static const uint16_t FACTCATEGORY_INVALID = 0xFFFF;
static const uint8_t FACTNOTIFICATIONTYPE_CUEPREPARED = 1;
static const uint8_t FACTNOTIFICATIONTYPE_CUEPLAY = 2;
static const uint8_t FACTNOTIFICATIONTYPE_CUESTOP = 3;
static const uint8_t FACTNOTIFICATIONTYPE_CUEDESTROYED = 4;
static const uint8_t FACTNOTIFICATIONTYPE_MARKER = 5;
static const uint8_t FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED = 6;
static const uint8_t FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED = 7;
static const uint8_t FACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED = 8;
static const uint8_t FACTNOTIFICATIONTYPE_GLOBALVARIABLECHANGED = 9;
static const uint8_t FACTNOTIFICATIONTYPE_GUICONNECTED = 10;
static const uint8_t FACTNOTIFICATIONTYPE_GUIDISCONNECTED = 11;
static const uint8_t FACTNOTIFICATIONTYPE_WAVEPREPARED = 12;
static const uint8_t FACTNOTIFICATIONTYPE_WAVEPLAY = 13;
static const uint8_t FACTNOTIFICATIONTYPE_WAVESTOP = 14;
static const uint8_t FACTNOTIFICATIONTYPE_WAVELOOPED = 15;
static const uint8_t FACTNOTIFICATIONTYPE_WAVEDESTROYED = 16;
static const uint8_t FACTNOTIFICATIONTYPE_WAVEBANKPREPARED = 17;
static const uint8_t FACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT = 18;
static const uint8_t FACT_FLAG_NOTIFICATION_PERSIST = 0x01;
#define FACT_ENGINE_LOOKAHEAD_DEFAULT 250
#define FACT_MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES 7
static const uint32_t aWMAAvgBytesPerSec[] =
{
12000,
24000,
4000,
6000,
8000,
20000,
2500
};
#define FACT_MAX_WMA_BLOCK_ALIGN_ENTRIES 17
static const uint32_t aWMABlockAlign[] =
{
929,
1487,
1280,
2230,
8917,
8192,
4459,
5945,
2304,
1536,
1485,
1008,
2731,
4096,
6827,
5462,
1280
};
/* AudioEngine Interface */
FACTAPI uint32_t FACTCreateEngine(
uint32_t dwCreationFlags,
FACTAudioEngine **ppEngine
);
/* See "extensions/CustomAllocatorEXT.txt" for more details. */
FACTAPI uint32_t FACTCreateEngineWithCustomAllocatorEXT(
uint32_t dwCreationFlags,
FACTAudioEngine **ppEngine,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
);
FACTAPI uint32_t FACTAudioEngine_AddRef(FACTAudioEngine *pEngine);
FACTAPI uint32_t FACTAudioEngine_Release(FACTAudioEngine *pEngine);
/* FIXME: QueryInterface? Or just ignore COM garbage... -flibit */
FACTAPI uint32_t FACTAudioEngine_GetRendererCount(
FACTAudioEngine *pEngine,
uint16_t *pnRendererCount
);
FACTAPI uint32_t FACTAudioEngine_GetRendererDetails(
FACTAudioEngine *pEngine,
uint16_t nRendererIndex,
FACTRendererDetails *pRendererDetails
);
FACTAPI uint32_t FACTAudioEngine_GetFinalMixFormat(
FACTAudioEngine *pEngine,
FAudioWaveFormatExtensible *pFinalMixFormat
);
FACTAPI uint32_t FACTAudioEngine_Initialize(
FACTAudioEngine *pEngine,
const FACTRuntimeParameters *pParams
);
FACTAPI uint32_t FACTAudioEngine_ShutDown(FACTAudioEngine *pEngine);
FACTAPI uint32_t FACTAudioEngine_DoWork(FACTAudioEngine *pEngine);
FACTAPI uint32_t FACTAudioEngine_CreateSoundBank(
FACTAudioEngine *pEngine,
const void *pvBuffer,
uint32_t dwSize,
uint32_t dwFlags,
uint32_t dwAllocAttributes,
FACTSoundBank **ppSoundBank
);
FACTAPI uint32_t FACTAudioEngine_CreateInMemoryWaveBank(
FACTAudioEngine *pEngine,
const void *pvBuffer,
uint32_t dwSize,
uint32_t dwFlags,
uint32_t dwAllocAttributes,
FACTWaveBank **ppWaveBank
);
FACTAPI uint32_t FACTAudioEngine_CreateStreamingWaveBank(
FACTAudioEngine *pEngine,
const FACTStreamingParameters *pParms,
FACTWaveBank **ppWaveBank
);
FACTAPI uint32_t FACTAudioEngine_PrepareWave(
FACTAudioEngine *pEngine,
uint32_t dwFlags,
const char *szWavePath,
uint32_t wStreamingPacketSize,
uint32_t dwAlignment,
uint32_t dwPlayOffset,
uint8_t nLoopCount,
FACTWave **ppWave
);
FACTAPI uint32_t FACTAudioEngine_PrepareInMemoryWave(
FACTAudioEngine *pEngine,
uint32_t dwFlags,
FACTWaveBankEntry entry,
uint32_t *pdwSeekTable, /* Optional! */
uint8_t *pbWaveData,
uint32_t dwPlayOffset,
uint8_t nLoopCount,
FACTWave **ppWave
);
FACTAPI uint32_t FACTAudioEngine_PrepareStreamingWave(
FACTAudioEngine *pEngine,
uint32_t dwFlags,
FACTWaveBankEntry entry,
FACTStreamingParameters streamingParams,
uint32_t dwAlignment,
uint32_t *pdwSeekTable, /* Optional! */
uint8_t *pbWaveData, /* ABI bug, do not use! */
uint32_t dwPlayOffset,
uint8_t nLoopCount,
FACTWave **ppWave
);
FACTAPI uint32_t FACTAudioEngine_RegisterNotification(
FACTAudioEngine *pEngine,
const FACTNotificationDescription *pNotificationDescription
);
FACTAPI uint32_t FACTAudioEngine_UnRegisterNotification(
FACTAudioEngine *pEngine,
const FACTNotificationDescription *pNotificationDescription
);
FACTAPI uint16_t FACTAudioEngine_GetCategory(
FACTAudioEngine *pEngine,
const char *szFriendlyName
);
FACTAPI uint32_t FACTAudioEngine_Stop(
FACTAudioEngine *pEngine,
uint16_t nCategory,
uint32_t dwFlags
);
FACTAPI uint32_t FACTAudioEngine_SetVolume(
FACTAudioEngine *pEngine,
uint16_t nCategory,
float volume
);
FACTAPI uint32_t FACTAudioEngine_Pause(
FACTAudioEngine *pEngine,
uint16_t nCategory,
int32_t fPause
);
FACTAPI uint16_t FACTAudioEngine_GetGlobalVariableIndex(
FACTAudioEngine *pEngine,
const char *szFriendlyName
);
FACTAPI uint32_t FACTAudioEngine_SetGlobalVariable(
FACTAudioEngine *pEngine,
uint16_t nIndex,
float nValue
);
FACTAPI uint32_t FACTAudioEngine_GetGlobalVariable(
FACTAudioEngine *pEngine,
uint16_t nIndex,
float *pnValue
);
/* SoundBank Interface */
FACTAPI uint16_t FACTSoundBank_GetCueIndex(
FACTSoundBank *pSoundBank,
const char *szFriendlyName
);
FACTAPI uint32_t FACTSoundBank_GetNumCues(
FACTSoundBank *pSoundBank,
uint16_t *pnNumCues
);
FACTAPI uint32_t FACTSoundBank_GetCueProperties(
FACTSoundBank *pSoundBank,
uint16_t nCueIndex,
FACTCueProperties *pProperties
);
FACTAPI uint32_t FACTSoundBank_Prepare(
FACTSoundBank *pSoundBank,
uint16_t nCueIndex,
uint32_t dwFlags,
int32_t timeOffset,
FACTCue** ppCue
);
FACTAPI uint32_t FACTSoundBank_Play(
FACTSoundBank *pSoundBank,
uint16_t nCueIndex,
uint32_t dwFlags,
int32_t timeOffset,
FACTCue** ppCue /* Optional! */
);
#ifndef F3DAUDIO_DSP_SETTINGS_DECL
#define F3DAUDIO_DSP_SETTINGS_DECL
typedef struct F3DAUDIO_DSP_SETTINGS F3DAUDIO_DSP_SETTINGS;
#endif /* F3DAUDIO_DSP_SETTINGS_DECL */
FACTAPI uint32_t FACTSoundBank_Play3D(
FACTSoundBank *pSoundBank,
uint16_t nCueIndex,
uint32_t dwFlags,
int32_t timeOffset,
F3DAUDIO_DSP_SETTINGS *pDSPSettings,
FACTCue** ppCue /* Optional! */
);
FACTAPI uint32_t FACTSoundBank_Stop(
FACTSoundBank *pSoundBank,
uint16_t nCueIndex,
uint32_t dwFlags
);
FACTAPI uint32_t FACTSoundBank_Destroy(FACTSoundBank *pSoundBank);
FACTAPI uint32_t FACTSoundBank_GetState(
FACTSoundBank *pSoundBank,
uint32_t *pdwState
);
/* WaveBank Interface */
FACTAPI uint32_t FACTWaveBank_Destroy(FACTWaveBank *pWaveBank);
FACTAPI uint32_t FACTWaveBank_GetState(
FACTWaveBank *pWaveBank,
uint32_t *pdwState
);
FACTAPI uint32_t FACTWaveBank_GetNumWaves(
FACTWaveBank *pWaveBank,
uint16_t *pnNumWaves
);
FACTAPI uint16_t FACTWaveBank_GetWaveIndex(
FACTWaveBank *pWaveBank,
const char *szFriendlyName
);
FACTAPI uint32_t FACTWaveBank_GetWaveProperties(
FACTWaveBank *pWaveBank,
uint16_t nWaveIndex,
FACTWaveProperties *pWaveProperties
);
FACTAPI uint32_t FACTWaveBank_Prepare(
FACTWaveBank *pWaveBank,
uint16_t nWaveIndex,
uint32_t dwFlags,
uint32_t dwPlayOffset,
uint8_t nLoopCount,
FACTWave **ppWave
);
FACTAPI uint32_t FACTWaveBank_Play(
FACTWaveBank *pWaveBank,
uint16_t nWaveIndex,
uint32_t dwFlags,
uint32_t dwPlayOffset,
uint8_t nLoopCount,
FACTWave **ppWave
);
FACTAPI uint32_t FACTWaveBank_Stop(
FACTWaveBank *pWaveBank,
uint16_t nWaveIndex,
uint32_t dwFlags
);
/* Wave Interface */
FACTAPI uint32_t FACTWave_Destroy(FACTWave *pWave);
FACTAPI uint32_t FACTWave_Play(FACTWave *pWave);
FACTAPI uint32_t FACTWave_Stop(FACTWave *pWave, uint32_t dwFlags);
FACTAPI uint32_t FACTWave_Pause(FACTWave *pWave, int32_t fPause);
FACTAPI uint32_t FACTWave_GetState(FACTWave *pWave, uint32_t *pdwState);
FACTAPI uint32_t FACTWave_SetPitch(FACTWave *pWave, int16_t pitch);
FACTAPI uint32_t FACTWave_SetVolume(FACTWave *pWave, float volume);
FACTAPI uint32_t FACTWave_SetMatrixCoefficients(
FACTWave *pWave,
uint32_t uSrcChannelCount,
uint32_t uDstChannelCount,
float *pMatrixCoefficients
);
FACTAPI uint32_t FACTWave_GetProperties(
FACTWave *pWave,
FACTWaveInstanceProperties *pProperties
);
/* Cue Interface */
FACTAPI uint32_t FACTCue_Destroy(FACTCue *pCue);
FACTAPI uint32_t FACTCue_Play(FACTCue *pCue);
FACTAPI uint32_t FACTCue_Stop(FACTCue *pCue, uint32_t dwFlags);
FACTAPI uint32_t FACTCue_GetState(FACTCue *pCue, uint32_t *pdwState);
FACTAPI uint32_t FACTCue_SetMatrixCoefficients(
FACTCue *pCue,
uint32_t uSrcChannelCount,
uint32_t uDstChannelCount,
float *pMatrixCoefficients
);
FACTAPI uint16_t FACTCue_GetVariableIndex(
FACTCue *pCue,
const char *szFriendlyName
);
FACTAPI uint32_t FACTCue_SetVariable(
FACTCue *pCue,
uint16_t nIndex,
float nValue
);
FACTAPI uint32_t FACTCue_GetVariable(
FACTCue *pCue,
uint16_t nIndex,
float *nValue
);
FACTAPI uint32_t FACTCue_Pause(FACTCue *pCue, int32_t fPause);
FACTAPI uint32_t FACTCue_GetProperties(
FACTCue *pCue,
FACTCueInstanceProperties **ppProperties
);
FACTAPI uint32_t FACTCue_SetOutputVoices(
FACTCue *pCue,
const FAudioVoiceSends *pSendList /* Optional! */
);
FACTAPI uint32_t FACTCue_SetOutputVoiceMatrix(
FACTCue *pCue,
const FAudioVoice *pDestinationVoice, /* Optional! */
uint32_t SourceChannels,
uint32_t DestinationChannels,
const float *pLevelMatrix /* SourceChannels * DestinationChannels */
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FACT_H */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

View File

@ -0,0 +1,127 @@
/* 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 you are expected to already know how
* XACT works if you are still using these APIs!
*/
#ifndef FACT3D_H
#define FACT3D_H
#include "F3DAudio.h"
#include "FACT.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Constants */
#define LEFT_AZIMUTH (3.0f * F3DAUDIO_PI / 2.0f)
#define RIGHT_AZIMUTH (F3DAUDIO_PI / 2.0f)
#define FRONT_LEFT_AZIMUTH (7.0f * F3DAUDIO_PI / 4.0f)
#define FRONT_RIGHT_AZIMUTH (F3DAUDIO_PI / 4.0f)
#define FRONT_CENTER_AZIMUTH 0.0f
#define LOW_FREQUENCY_AZIMUTH F3DAUDIO_2PI
#define BACK_LEFT_AZIMUTH (5.0f * F3DAUDIO_PI / 4.0f)
#define BACK_RIGHT_AZIMUTH (3.0f * F3DAUDIO_PI / 4.0f)
#define BACK_CENTER_AZIMUTH F3DAUDIO_PI
#define FRONT_LEFT_OF_CENTER_AZIMUTH (15.0f * F3DAUDIO_PI / 8.0f)
#define FRONT_RIGHT_OF_CENTER_AZIMUTH (F3DAUDIO_PI / 8.0f)
static const float aStereoLayout[] =
{
LEFT_AZIMUTH,
RIGHT_AZIMUTH
};
static const float a2Point1Layout[] =
{
LEFT_AZIMUTH,
RIGHT_AZIMUTH,
LOW_FREQUENCY_AZIMUTH
};
static const float aQuadLayout[] =
{
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH
};
static const float a4Point1Layout[] =
{
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
LOW_FREQUENCY_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH
};
static const float a5Point1Layout[] =
{
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
FRONT_CENTER_AZIMUTH,
LOW_FREQUENCY_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH
};
static const float a7Point1Layout[] =
{
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
FRONT_CENTER_AZIMUTH,
LOW_FREQUENCY_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH,
LEFT_AZIMUTH,
RIGHT_AZIMUTH
};
/* Functions */
FACTAPI uint32_t FACT3DInitialize(
FACTAudioEngine *pEngine,
F3DAUDIO_HANDLE F3DInstance
);
FACTAPI uint32_t FACT3DCalculate(
F3DAUDIO_HANDLE F3DInstance,
const F3DAUDIO_LISTENER *pListener,
F3DAUDIO_EMITTER *pEmitter,
F3DAUDIO_DSP_SETTINGS *pDSPSettings
);
FACTAPI uint32_t FACT3DApply(
F3DAUDIO_DSP_SETTINGS *pDSPSettings,
FACTCue *pCue
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FACT3D_H */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

207
libs/faudio/include/FAPO.h Normal file
View File

@ -0,0 +1,207 @@
/* 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: */

View File

@ -0,0 +1,264 @@
/* 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/xapobase/
*
* 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.
*
* To mimic the CXAPOParametersBase experience, initialize the object like this:
*
* extern FAPORegistrationProperties MyFAPOProperties;
* extern int32_t producer;
* typedef struct MyFAPOParams
* {
* uint32_t something;
* } MyFAPOParams;
* typedef struct MyFAPO
* {
* FAPOBase base;
* uint32_t somethingElse;
* } MyFAPO;
* void MyFAPO_Free(void* fapo)
* {
* MyFAPO *mine = (MyFAPO*) fapo;
* mine->base.pFree(mine->base.m_pParameterBlocks);
* mine->base.pFree(fapo);
* }
*
* MyFAPO *result = (MyFAPO*) SDL_malloc(sizeof(MyFAPO));
* uint8_t *params = (uint8_t*) SDL_malloc(sizeof(MyFAPOParams) * 3);
* CreateFAPOBase(
* &result->base,
* &MyFAPOProperties,
* params,
* sizeof(MyFAPOParams),
* producer
* );
* result->base.base.Initialize = (InitializeFunc) MyFAPO_Initialize;
* result->base.base.Process = (ProcessFunc) MyFAPO_Process;
* result->base.Destructor = MyFAPO_Free;
*/
#ifndef FAPOBASE_H
#define FAPOBASE_H
#include "FAPO.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Constants */
#define FAPOBASE_DEFAULT_FORMAT_TAG FAUDIO_FORMAT_IEEE_FLOAT
#define FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS FAPO_MIN_CHANNELS
#define FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS FAPO_MAX_CHANNELS
#define FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE FAPO_MIN_FRAMERATE
#define FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE FAPO_MAX_FRAMERATE
#define FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE 32
#define FAPOBASE_DEFAULT_FLAG ( \
FAPO_FLAG_CHANNELS_MUST_MATCH | \
FAPO_FLAG_FRAMERATE_MUST_MATCH | \
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH | \
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH | \
FAPO_FLAG_INPLACE_SUPPORTED \
)
#define FAPOBASE_DEFAULT_BUFFER_COUNT 1
/* FAPOBase Interface */
typedef struct FAPOBase FAPOBase;
typedef void (FAPOCALL * OnSetParametersFunc)(
FAPOBase *fapo,
const void* parameters,
uint32_t parametersSize
);
#pragma pack(push, 8)
struct FAPOBase
{
/* Base Classes/Interfaces */
FAPO base;
void (FAPOCALL *Destructor)(void*);
/* Public Virtual Functions */
OnSetParametersFunc OnSetParameters;
/* Private Variables */
const FAPORegistrationProperties *m_pRegistrationProperties;
void* m_pfnMatrixMixFunction;
float *m_pfl32MatrixCoefficients;
uint32_t m_nSrcFormatType;
uint8_t m_fIsScalarMatrix;
uint8_t m_fIsLocked;
uint8_t *m_pParameterBlocks;
uint8_t *m_pCurrentParameters;
uint8_t *m_pCurrentParametersInternal;
uint32_t m_uCurrentParametersIndex;
uint32_t m_uParameterBlockByteSize;
uint8_t m_fNewerResultsReady;
uint8_t m_fProducer;
/* Protected Variables */
int32_t m_lReferenceCount; /* LONG */
/* Allocator callbacks, NOT part of XAPOBase spec! */
FAudioMallocFunc pMalloc;
FAudioFreeFunc pFree;
FAudioReallocFunc pRealloc;
};
#pragma pack(pop)
FAPOAPI void CreateFAPOBase(
FAPOBase *fapo,
const FAPORegistrationProperties *pRegistrationProperties,
uint8_t *pParameterBlocks,
uint32_t uParameterBlockByteSize,
uint8_t fProducer
);
/* See "extensions/CustomAllocatorEXT.txt" for more information. */
FAPOAPI void CreateFAPOBaseWithCustomAllocatorEXT(
FAPOBase *fapo,
const FAPORegistrationProperties *pRegistrationProperties,
uint8_t *pParameterBlocks,
uint32_t uParameterBlockByteSize,
uint8_t fProducer,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
);
FAPOAPI int32_t FAPOBase_AddRef(FAPOBase *fapo);
FAPOAPI int32_t FAPOBase_Release(FAPOBase *fapo);
FAPOAPI uint32_t FAPOBase_GetRegistrationProperties(
FAPOBase *fapo,
FAPORegistrationProperties **ppRegistrationProperties
);
FAPOAPI uint32_t FAPOBase_IsInputFormatSupported(
FAPOBase *fapo,
const FAudioWaveFormatEx *pOutputFormat,
const FAudioWaveFormatEx *pRequestedInputFormat,
FAudioWaveFormatEx **ppSupportedInputFormat
);
FAPOAPI uint32_t FAPOBase_IsOutputFormatSupported(
FAPOBase *fapo,
const FAudioWaveFormatEx *pInputFormat,
const FAudioWaveFormatEx *pRequestedOutputFormat,
FAudioWaveFormatEx **ppSupportedOutputFormat
);
FAPOAPI uint32_t FAPOBase_Initialize(
FAPOBase *fapo,
const void* pData,
uint32_t DataByteSize
);
FAPOAPI void FAPOBase_Reset(FAPOBase *fapo);
FAPOAPI uint32_t FAPOBase_LockForProcess(
FAPOBase *fapo,
uint32_t InputLockedParameterCount,
const FAPOLockForProcessBufferParameters *pInputLockedParameters,
uint32_t OutputLockedParameterCount,
const FAPOLockForProcessBufferParameters *pOutputLockedParameters
);
FAPOAPI void FAPOBase_UnlockForProcess(FAPOBase *fapo);
FAPOAPI uint32_t FAPOBase_CalcInputFrames(
FAPOBase *fapo,
uint32_t OutputFrameCount
);
FAPOAPI uint32_t FAPOBase_CalcOutputFrames(
FAPOBase *fapo,
uint32_t InputFrameCount
);
FAPOAPI uint32_t FAPOBase_ValidateFormatDefault(
FAPOBase *fapo,
FAudioWaveFormatEx *pFormat,
uint8_t fOverwrite
);
FAPOAPI uint32_t FAPOBase_ValidateFormatPair(
FAPOBase *fapo,
const FAudioWaveFormatEx *pSupportedFormat,
FAudioWaveFormatEx *pRequestedFormat,
uint8_t fOverwrite
);
FAPOAPI void FAPOBase_ProcessThru(
FAPOBase *fapo,
void* pInputBuffer,
float *pOutputBuffer,
uint32_t FrameCount,
uint16_t InputChannelCount,
uint16_t OutputChannelCount,
uint8_t MixWithOutput
);
FAPOAPI void FAPOBase_SetParameters(
FAPOBase *fapo,
const void* pParameters,
uint32_t ParameterByteSize
);
FAPOAPI void FAPOBase_GetParameters(
FAPOBase *fapo,
void* pParameters,
uint32_t ParameterByteSize
);
FAPOAPI void FAPOBase_OnSetParameters(
FAPOBase *fapo,
const void* parameters,
uint32_t parametersSize
);
FAPOAPI uint8_t FAPOBase_ParametersChanged(FAPOBase *fapo);
FAPOAPI uint8_t* FAPOBase_BeginProcess(FAPOBase *fapo);
FAPOAPI void FAPOBase_EndProcess(FAPOBase *fapo);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FAPOBASE_H */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

View File

@ -0,0 +1,178 @@
/* 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>
*
*/
#ifndef FAPOFX_H
#define FAPOFX_H
#include "FAPO.h"
#define FAPOFXAPI FAUDIOAPI
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* GUIDs */
/* "Legacy" GUIDs are from XAPOFX <= 1.5. They were removed in XAudio 2.8 and later. */
extern const FAudioGUID FAPOFX_CLSID_FXEQ, FAPOFX_CLSID_FXEQ_LEGACY;
extern const FAudioGUID FAPOFX_CLSID_FXMasteringLimiter, FAPOFX_CLSID_FXMasteringLimiter_LEGACY;
extern const FAudioGUID FAPOFX_CLSID_FXReverb, FAPOFX_CLSID_FXReverb_LEGACY;
extern const FAudioGUID FAPOFX_CLSID_FXEcho, FAPOFX_CLSID_FXEcho_LEGACY;
/* Structures */
#pragma pack(push, 1)
/* See FAPOFXEQ_* constants below.
* FrequencyCenter is in Hz, Gain is amplitude ratio, Bandwidth is Q factor.
*/
typedef struct FAPOFXEQParameters
{
float FrequencyCenter0;
float Gain0;
float Bandwidth0;
float FrequencyCenter1;
float Gain1;
float Bandwidth1;
float FrequencyCenter2;
float Gain2;
float Bandwidth2;
float FrequencyCenter3;
float Gain3;
float Bandwidth3;
} FAPOFXEQParameters;
/* See FAPOFXMASTERINGLIMITER_* constants below. */
typedef struct FAPOFXMasteringLimiterParameters
{
uint32_t Release; /* In milliseconds */
uint32_t Loudness; /* In... uh, MSDN doesn't actually say what. */
} FAPOFXMasteringLimiterParameters;
/* See FAPOFXREVERB_* constants below.
* Both parameters are arbitrary and should be treated subjectively.
*/
typedef struct FAPOFXReverbParameters
{
float Diffusion;
float RoomSize;
} FAPOFXReverbParameters;
/* See FAPOFXECHO_* constants below. */
typedef struct FAPOFXEchoParameters
{
float WetDryMix; /* Percentage of processed signal vs original */
float Feedback; /* Percentage to feed back into input */
float Delay; /* In milliseconds */
} FAPOFXEchoParameters;
#pragma pack(pop)
/* Constants */
#define FAPOFXEQ_MIN_FRAMERATE 22000
#define FAPOFXEQ_MAX_FRAMERATE 48000
#define FAPOFXEQ_MIN_FREQUENCY_CENTER 20.0f
#define FAPOFXEQ_MAX_FREQUENCY_CENTER 20000.0f
#define FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_0 100.0f
#define FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_1 800.0f
#define FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_2 2000.0f
#define FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_3 10000.0f
#define FAPOFXEQ_MIN_GAIN 0.126f
#define FAPOFXEQ_MAX_GAIN 7.94f
#define FAPOFXEQ_DEFAULT_GAIN 1.0f
#define FAPOFXEQ_MIN_BANDWIDTH 0.1f
#define FAPOFXEQ_MAX_BANDWIDTH 2.0f
#define FAPOFXEQ_DEFAULT_BANDWIDTH 1.0f
#define FAPOFXMASTERINGLIMITER_MIN_RELEASE 1
#define FAPOFXMASTERINGLIMITER_MAX_RELEASE 20
#define FAPOFXMASTERINGLIMITER_DEFAULT_RELEASE 6
#define FAPOFXMASTERINGLIMITER_MIN_LOUDNESS 1
#define FAPOFXMASTERINGLIMITER_MAX_LOUDNESS 1800
#define FAPOFXMASTERINGLIMITER_DEFAULT_LOUDNESS 1000
#define FAPOFXREVERB_MIN_DIFFUSION 0.0f
#define FAPOFXREVERB_MAX_DIFFUSION 1.0f
#define FAPOFXREVERB_DEFAULT_DIFFUSION 0.9f
#define FAPOFXREVERB_MIN_ROOMSIZE 0.0001f
#define FAPOFXREVERB_MAX_ROOMSIZE 1.0f
#define FAPOFXREVERB_DEFAULT_ROOMSIZE 0.6f
#define FAPOFXECHO_MIN_WETDRYMIX 0.0f
#define FAPOFXECHO_MAX_WETDRYMIX 1.0f
#define FAPOFXECHO_DEFAULT_WETDRYMIX 0.5f
#define FAPOFXECHO_MIN_FEEDBACK 0.0f
#define FAPOFXECHO_MAX_FEEDBACK 1.0f
#define FAPOFXECHO_DEFAULT_FEEDBACK 0.5f
#define FAPOFXECHO_MIN_DELAY 1.0f
#define FAPOFXECHO_MAX_DELAY 2000.0f
#define FAPOFXECHO_DEFAULT_DELAY 500.0f
/* Functions */
/* Creates an effect from the pre-made FAPOFX effect library.
*
* clsid: A reference to one of the FAPOFX_CLSID_* GUIDs
* pEffect: Filled with the resulting FAPO object
* pInitData: Starting parameters, pass NULL to use the default values
* InitDataByteSize: Parameter struct size, pass 0 if pInitData is NULL
*
* Returns 0 on success.
*/
FAPOFXAPI uint32_t FAPOFX_CreateFX(
const FAudioGUID *clsid,
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize
);
/* See "extensions/CustomAllocatorEXT.txt" for more details. */
FAPOFXAPI uint32_t FAPOFX_CreateFXWithCustomAllocatorEXT(
const FAudioGUID *clsid,
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FAPOFX_H */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

1322
libs/faudio/include/FAudio.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,308 @@
/* 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/xaudio2fx/
*
* Note, however, that FAudio's Reverb implementation does NOT support the new
* parameters for XAudio 2.9's 7.1 Reverb effect!
*/
#ifndef FAUDIOFX_H
#define FAUDIOFX_H
#include "FAudio.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* GUIDs */
extern const FAudioGUID FAudioFX_CLSID_AudioVolumeMeter;
extern const FAudioGUID FAudioFX_CLSID_AudioReverb;
/* Structures */
#pragma pack(push, 1)
typedef struct FAudioFXVolumeMeterLevels
{
float *pPeakLevels;
float *pRMSLevels;
uint32_t ChannelCount;
} FAudioFXVolumeMeterLevels;
typedef struct FAudioFXReverbParameters
{
float WetDryMix;
uint32_t ReflectionsDelay;
uint8_t ReverbDelay;
uint8_t RearDelay;
uint8_t PositionLeft;
uint8_t PositionRight;
uint8_t PositionMatrixLeft;
uint8_t PositionMatrixRight;
uint8_t EarlyDiffusion;
uint8_t LateDiffusion;
uint8_t LowEQGain;
uint8_t LowEQCutoff;
uint8_t HighEQGain;
uint8_t HighEQCutoff;
float RoomFilterFreq;
float RoomFilterMain;
float RoomFilterHF;
float ReflectionsGain;
float ReverbGain;
float DecayTime;
float Density;
float RoomSize;
} FAudioFXReverbParameters;
typedef struct FAudioFXReverbParameters9
{
float WetDryMix;
uint32_t ReflectionsDelay;
uint8_t ReverbDelay;
uint8_t RearDelay;
uint8_t SideDelay;
uint8_t PositionLeft;
uint8_t PositionRight;
uint8_t PositionMatrixLeft;
uint8_t PositionMatrixRight;
uint8_t EarlyDiffusion;
uint8_t LateDiffusion;
uint8_t LowEQGain;
uint8_t LowEQCutoff;
uint8_t HighEQGain;
uint8_t HighEQCutoff;
float RoomFilterFreq;
float RoomFilterMain;
float RoomFilterHF;
float ReflectionsGain;
float ReverbGain;
float DecayTime;
float Density;
float RoomSize;
} FAudioFXReverbParameters9;
typedef struct FAudioFXReverbI3DL2Parameters
{
float WetDryMix;
int32_t Room;
int32_t RoomHF;
float RoomRolloffFactor;
float DecayTime;
float DecayHFRatio;
int32_t Reflections;
float ReflectionsDelay;
int32_t Reverb;
float ReverbDelay;
float Diffusion;
float Density;
float HFReference;
} FAudioFXReverbI3DL2Parameters;
#pragma pack(pop)
/* Constants */
#define FAUDIOFX_DEBUG 1
#define FAUDIOFX_REVERB_MIN_FRAMERATE 20000
#define FAUDIOFX_REVERB_MAX_FRAMERATE 48000
#define FAUDIOFX_REVERB_MIN_WET_DRY_MIX 0.0f
#define FAUDIOFX_REVERB_MIN_REFLECTIONS_DELAY 0
#define FAUDIOFX_REVERB_MIN_REVERB_DELAY 0
#define FAUDIOFX_REVERB_MIN_REAR_DELAY 0
#define FAUDIOFX_REVERB_MIN_7POINT1_SIDE_DELAY 0
#define FAUDIOFX_REVERB_MIN_7POINT1_REAR_DELAY 0
#define FAUDIOFX_REVERB_MIN_POSITION 0
#define FAUDIOFX_REVERB_MIN_DIFFUSION 0
#define FAUDIOFX_REVERB_MIN_LOW_EQ_GAIN 0
#define FAUDIOFX_REVERB_MIN_LOW_EQ_CUTOFF 0
#define FAUDIOFX_REVERB_MIN_HIGH_EQ_GAIN 0
#define FAUDIOFX_REVERB_MIN_HIGH_EQ_CUTOFF 0
#define FAUDIOFX_REVERB_MIN_ROOM_FILTER_FREQ 20.0f
#define FAUDIOFX_REVERB_MIN_ROOM_FILTER_MAIN -100.0f
#define FAUDIOFX_REVERB_MIN_ROOM_FILTER_HF -100.0f
#define FAUDIOFX_REVERB_MIN_REFLECTIONS_GAIN -100.0f
#define FAUDIOFX_REVERB_MIN_REVERB_GAIN -100.0f
#define FAUDIOFX_REVERB_MIN_DECAY_TIME 0.1f
#define FAUDIOFX_REVERB_MIN_DENSITY 0.0f
#define FAUDIOFX_REVERB_MIN_ROOM_SIZE 0.0f
#define FAUDIOFX_REVERB_MAX_WET_DRY_MIX 100.0f
#define FAUDIOFX_REVERB_MAX_REFLECTIONS_DELAY 300
#define FAUDIOFX_REVERB_MAX_REVERB_DELAY 85
#define FAUDIOFX_REVERB_MAX_REAR_DELAY 5
#define FAUDIOFX_REVERB_MAX_7POINT1_SIDE_DELAY 5
#define FAUDIOFX_REVERB_MAX_7POINT1_REAR_DELAY 20
#define FAUDIOFX_REVERB_MAX_POSITION 30
#define FAUDIOFX_REVERB_MAX_DIFFUSION 15
#define FAUDIOFX_REVERB_MAX_LOW_EQ_GAIN 12
#define FAUDIOFX_REVERB_MAX_LOW_EQ_CUTOFF 9
#define FAUDIOFX_REVERB_MAX_HIGH_EQ_GAIN 8
#define FAUDIOFX_REVERB_MAX_HIGH_EQ_CUTOFF 14
#define FAUDIOFX_REVERB_MAX_ROOM_FILTER_FREQ 20000.0f
#define FAUDIOFX_REVERB_MAX_ROOM_FILTER_MAIN 0.0f
#define FAUDIOFX_REVERB_MAX_ROOM_FILTER_HF 0.0f
#define FAUDIOFX_REVERB_MAX_REFLECTIONS_GAIN 20.0f
#define FAUDIOFX_REVERB_MAX_REVERB_GAIN 20.0f
#define FAUDIOFX_REVERB_MAX_DENSITY 100.0f
#define FAUDIOFX_REVERB_MAX_ROOM_SIZE 100.0f
#define FAUDIOFX_REVERB_DEFAULT_WET_DRY_MIX 100.0f
#define FAUDIOFX_REVERB_DEFAULT_REFLECTIONS_DELAY 5
#define FAUDIOFX_REVERB_DEFAULT_REVERB_DELAY 5
#define FAUDIOFX_REVERB_DEFAULT_REAR_DELAY 5
#define FAUDIOFX_REVERB_DEFAULT_7POINT1_SIDE_DELAY 5
#define FAUDIOFX_REVERB_DEFAULT_7POINT1_REAR_DELAY 20
#define FAUDIOFX_REVERB_DEFAULT_POSITION 6
#define FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX 27
#define FAUDIOFX_REVERB_DEFAULT_EARLY_DIFFUSION 8
#define FAUDIOFX_REVERB_DEFAULT_LATE_DIFFUSION 8
#define FAUDIOFX_REVERB_DEFAULT_LOW_EQ_GAIN 8
#define FAUDIOFX_REVERB_DEFAULT_LOW_EQ_CUTOFF 4
#define FAUDIOFX_REVERB_DEFAULT_HIGH_EQ_GAIN 8
#define FAUDIOFX_REVERB_DEFAULT_HIGH_EQ_CUTOFF 4
#define FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_FREQ 5000.0f
#define FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_MAIN 0.0f
#define FAUDIOFX_REVERB_DEFAULT_ROOM_FILTER_HF 0.0f
#define FAUDIOFX_REVERB_DEFAULT_REFLECTIONS_GAIN 0.0f
#define FAUDIOFX_REVERB_DEFAULT_REVERB_GAIN 0.0f
#define FAUDIOFX_REVERB_DEFAULT_DECAY_TIME 1.0f
#define FAUDIOFX_REVERB_DEFAULT_DENSITY 100.0f
#define FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE 100.0f
#define FAUDIOFX_I3DL2_PRESET_DEFAULT \
{100,-10000, 0,0.0f, 1.00f,0.50f,-10000,0.020f,-10000,0.040f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_GENERIC \
{100, -1000, -100,0.0f, 1.49f,0.83f, -2602,0.007f, 200,0.011f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_PADDEDCELL \
{100, -1000,-6000,0.0f, 0.17f,0.10f, -1204,0.001f, 207,0.002f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_ROOM \
{100, -1000, -454,0.0f, 0.40f,0.83f, -1646,0.002f, 53,0.003f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_BATHROOM \
{100, -1000,-1200,0.0f, 1.49f,0.54f, -370,0.007f, 1030,0.011f,100.0f, 60.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_LIVINGROOM \
{100, -1000,-6000,0.0f, 0.50f,0.10f, -1376,0.003f, -1104,0.004f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_STONEROOM \
{100, -1000, -300,0.0f, 2.31f,0.64f, -711,0.012f, 83,0.017f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_AUDITORIUM \
{100, -1000, -476,0.0f, 4.32f,0.59f, -789,0.020f, -289,0.030f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_CONCERTHALL \
{100, -1000, -500,0.0f, 3.92f,0.70f, -1230,0.020f, -2,0.029f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_CAVE \
{100, -1000, 0,0.0f, 2.91f,1.30f, -602,0.015f, -302,0.022f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_ARENA \
{100, -1000, -698,0.0f, 7.24f,0.33f, -1166,0.020f, 16,0.030f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_HANGAR \
{100, -1000,-1000,0.0f,10.05f,0.23f, -602,0.020f, 198,0.030f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_CARPETEDHALLWAY \
{100, -1000,-4000,0.0f, 0.30f,0.10f, -1831,0.002f, -1630,0.030f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_HALLWAY \
{100, -1000, -300,0.0f, 1.49f,0.59f, -1219,0.007f, 441,0.011f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_STONECORRIDOR \
{100, -1000, -237,0.0f, 2.70f,0.79f, -1214,0.013f, 395,0.020f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_ALLEY \
{100, -1000, -270,0.0f, 1.49f,0.86f, -1204,0.007f, -4,0.011f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_FOREST \
{100, -1000,-3300,0.0f, 1.49f,0.54f, -2560,0.162f, -613,0.088f, 79.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_CITY \
{100, -1000, -800,0.0f, 1.49f,0.67f, -2273,0.007f, -2217,0.011f, 50.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_MOUNTAINS \
{100, -1000,-2500,0.0f, 1.49f,0.21f, -2780,0.300f, -2014,0.100f, 27.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_QUARRY \
{100, -1000,-1000,0.0f, 1.49f,0.83f,-10000,0.061f, 500,0.025f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_PLAIN \
{100, -1000,-2000,0.0f, 1.49f,0.50f, -2466,0.179f, -2514,0.100f, 21.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_PARKINGLOT \
{100, -1000, 0,0.0f, 1.65f,1.50f, -1363,0.008f, -1153,0.012f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_SEWERPIPE \
{100, -1000,-1000,0.0f, 2.81f,0.14f, 429,0.014f, 648,0.021f, 80.0f, 60.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_UNDERWATER \
{100, -1000,-4000,0.0f, 1.49f,0.10f, -449,0.007f, 1700,0.011f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_SMALLROOM \
{100, -1000, -600,0.0f, 1.10f,0.83f, -400,0.005f, 500,0.010f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_MEDIUMROOM \
{100, -1000, -600,0.0f, 1.30f,0.83f, -1000,0.010f, -200,0.020f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_LARGEROOM \
{100, -1000, -600,0.0f, 1.50f,0.83f, -1600,0.020f, -1000,0.040f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_MEDIUMHALL \
{100, -1000, -600,0.0f, 1.80f,0.70f, -1300,0.015f, -800,0.030f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_LARGEHALL \
{100, -1000, -600,0.0f, 1.80f,0.70f, -2000,0.030f, -1400,0.060f,100.0f,100.0f,5000.0f}
#define FAUDIOFX_I3DL2_PRESET_PLATE \
{100, -1000, -200,0.0f, 1.30f,0.90f, 0,0.002f, 0,0.010f,100.0f, 75.0f,5000.0f}
/* Functions */
FAUDIOAPI uint32_t FAudioCreateVolumeMeter(FAPO** ppApo, uint32_t Flags);
FAUDIOAPI uint32_t FAudioCreateReverb(FAPO** ppApo, uint32_t Flags);
FAUDIOAPI uint32_t FAudioCreateReverb9(FAPO** ppApo, uint32_t Flags);
/* See "extensions/CustomAllocatorEXT.txt" for more information. */
FAUDIOAPI uint32_t FAudioCreateVolumeMeterWithCustomAllocatorEXT(
FAPO** ppApo,
uint32_t Flags,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
);
FAUDIOAPI uint32_t FAudioCreateReverbWithCustomAllocatorEXT(
FAPO** ppApo,
uint32_t Flags,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
);
FAUDIOAPI uint32_t FAudioCreateReverb9WithCustomAllocatorEXT(
FAPO** ppApo,
uint32_t Flags,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
);
FAUDIOAPI void ReverbConvertI3DL2ToNative(
const FAudioFXReverbI3DL2Parameters *pI3DL2,
FAudioFXReverbParameters *pNative
);
FAUDIOAPI void ReverbConvertI3DL2ToNative9(
const FAudioFXReverbI3DL2Parameters *pI3DL2,
FAudioFXReverbParameters9 *pNative,
int32_t sevenDotOneReverb
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FAUDIOFX_H */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

1563
libs/faudio/src/F3DAudio.c Normal file

File diff suppressed because it is too large Load Diff

3021
libs/faudio/src/FACT.c Normal file

File diff suppressed because it is too large Load Diff

172
libs/faudio/src/FACT3D.c Normal file
View File

@ -0,0 +1,172 @@
/* 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>
*
*/
#include "FACT3D.h"
uint32_t FACT3DInitialize(
FACTAudioEngine *pEngine,
F3DAUDIO_HANDLE F3DInstance
) {
float nSpeedOfSound;
FAudioWaveFormatExtensible wfxFinalMixFormat;
if (pEngine == NULL)
{
return 0;
}
FACTAudioEngine_GetGlobalVariable(
pEngine,
FACTAudioEngine_GetGlobalVariableIndex(
pEngine,
"SpeedOfSound"
),
&nSpeedOfSound
);
FACTAudioEngine_GetFinalMixFormat(
pEngine,
&wfxFinalMixFormat
);
F3DAudioInitialize(
wfxFinalMixFormat.dwChannelMask,
nSpeedOfSound,
F3DInstance
);
return 0;
}
uint32_t FACT3DCalculate(
F3DAUDIO_HANDLE F3DInstance,
const F3DAUDIO_LISTENER *pListener,
F3DAUDIO_EMITTER *pEmitter,
F3DAUDIO_DSP_SETTINGS *pDSPSettings
) {
static F3DAUDIO_DISTANCE_CURVE_POINT DefaultCurvePoints[2] =
{
{ 0.0f, 1.0f },
{ 1.0f, 1.0f }
};
static F3DAUDIO_DISTANCE_CURVE DefaultCurve =
{
(F3DAUDIO_DISTANCE_CURVE_POINT*) &DefaultCurvePoints[0], 2
};
if (pListener == NULL || pEmitter == NULL || pDSPSettings == NULL)
{
return 0;
}
if (pEmitter->ChannelCount > 1 && pEmitter->pChannelAzimuths == NULL)
{
pEmitter->ChannelRadius = 1.0f;
if (pEmitter->ChannelCount == 2)
{
pEmitter->pChannelAzimuths = (float*) &aStereoLayout[0];
}
else if (pEmitter->ChannelCount == 3)
{
pEmitter->pChannelAzimuths = (float*) &a2Point1Layout[0];
}
else if (pEmitter->ChannelCount == 4)
{
pEmitter->pChannelAzimuths = (float*) &aQuadLayout[0];
}
else if (pEmitter->ChannelCount == 5)
{
pEmitter->pChannelAzimuths = (float*) &a4Point1Layout[0];
}
else if (pEmitter->ChannelCount == 6)
{
pEmitter->pChannelAzimuths = (float*) &a5Point1Layout[0];
}
else if (pEmitter->ChannelCount == 8)
{
pEmitter->pChannelAzimuths = (float*) &a7Point1Layout[0];
}
else
{
return 0;
}
}
if (pEmitter->pVolumeCurve == NULL)
{
pEmitter->pVolumeCurve = &DefaultCurve;
}
if (pEmitter->pLFECurve == NULL)
{
pEmitter->pLFECurve = &DefaultCurve;
}
F3DAudioCalculate(
F3DInstance,
pListener,
pEmitter,
(
F3DAUDIO_CALCULATE_MATRIX |
F3DAUDIO_CALCULATE_DOPPLER |
F3DAUDIO_CALCULATE_EMITTER_ANGLE
),
pDSPSettings
);
return 0;
}
uint32_t FACT3DApply(
F3DAUDIO_DSP_SETTINGS *pDSPSettings,
FACTCue *pCue
) {
if (pDSPSettings == NULL || pCue == NULL)
{
return 0;
}
FACTCue_SetMatrixCoefficients(
pCue,
pDSPSettings->SrcChannelCount,
pDSPSettings->DstChannelCount,
pDSPSettings->pMatrixCoefficients
);
FACTCue_SetVariable(
pCue,
FACTCue_GetVariableIndex(pCue, "Distance"),
pDSPSettings->EmitterToListenerDistance
);
FACTCue_SetVariable(
pCue,
FACTCue_GetVariableIndex(pCue, "DopplerPitchScalar"),
pDSPSettings->DopplerFactor
);
FACTCue_SetVariable(
pCue,
FACTCue_GetVariableIndex(pCue, "OrientationAngle"),
pDSPSettings->EmitterToListenerAngle * (180.0f / F3DAUDIO_PI)
);
return 0;
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,644 @@
/* 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>
*
*/
#include "FACT.h"
#include "FACT3D.h"
#include "FAudio_internal.h"
/* Internal AudioEngine Types */
typedef struct FACTAudioCategory
{
uint8_t instanceLimit;
uint16_t fadeInMS;
uint16_t fadeOutMS;
uint8_t maxInstanceBehavior;
int16_t parentCategory;
float volume;
uint8_t visibility;
uint8_t instanceCount;
float currentVolume;
} FACTAudioCategory;
typedef struct FACTVariable
{
uint8_t accessibility;
float initialValue;
float minValue;
float maxValue;
} FACTVariable;
typedef struct FACTRPCPoint
{
float x;
float y;
uint8_t type;
} FACTRPCPoint;
typedef enum FACTRPCParameter
{
RPC_PARAMETER_VOLUME,
RPC_PARAMETER_PITCH,
RPC_PARAMETER_REVERBSEND,
RPC_PARAMETER_FILTERFREQUENCY,
RPC_PARAMETER_FILTERQFACTOR,
RPC_PARAMETER_COUNT /* If >=, DSP Parameter! */
} FACTRPCParameter;
typedef struct FACTRPC
{
uint16_t variable;
uint8_t pointCount;
uint16_t parameter;
FACTRPCPoint *points;
} FACTRPC;
typedef struct FACTDSPParameter
{
uint8_t type;
float value;
float minVal;
float maxVal;
uint16_t unknown;
} FACTDSPParameter;
typedef struct FACTDSPPreset
{
uint8_t accessibility;
uint16_t parameterCount;
FACTDSPParameter *parameters;
} FACTDSPPreset;
typedef enum FACTNoticationsFlags
{
NOTIFY_CUEPREPARED = 0x00000001,
NOTIFY_CUEPLAY = 0x00000002,
NOTIFY_CUESTOP = 0x00000004,
NOTIFY_CUEDESTROY = 0x00000008,
NOTIFY_MARKER = 0x00000010,
NOTIFY_SOUNDBANKDESTROY = 0x00000020,
NOTIFY_WAVEBANKDESTROY = 0x00000040,
NOTIFY_LOCALVARIABLECHANGED = 0x00000080,
NOTIFY_GLOBALVARIABLECHANGED = 0x00000100,
NOTIFY_GUICONNECTED = 0x00000200,
NOTIFY_GUIDISCONNECTED = 0x00000400,
NOTIFY_WAVEPREPARED = 0x00000800,
NOTIFY_WAVEPLAY = 0x00001000,
NOTIFY_WAVESTOP = 0x00002000,
NOTIFY_WAVELOOPED = 0x00004000,
NOTIFY_WAVEDESTROY = 0x00008000,
NOTIFY_WAVEBANKPREPARED = 0x00010000
} FACTNoticationsFlags;
/* Internal SoundBank Types */
typedef enum
{
FACTEVENT_STOP = 0,
FACTEVENT_PLAYWAVE = 1,
FACTEVENT_PLAYWAVETRACKVARIATION = 3,
FACTEVENT_PLAYWAVEEFFECTVARIATION = 4,
FACTEVENT_PLAYWAVETRACKEFFECTVARIATION = 6,
FACTEVENT_PITCH = 7,
FACTEVENT_VOLUME = 8,
FACTEVENT_MARKER = 9,
FACTEVENT_PITCHREPEATING = 16,
FACTEVENT_VOLUMEREPEATING = 17,
FACTEVENT_MARKERREPEATING = 18
} FACTEventType;
typedef struct FACTEvent
{
uint16_t type;
uint16_t timestamp;
uint16_t randomOffset;
FAUDIONAMELESS union
{
/* Play Wave Event */
struct
{
uint8_t flags;
uint8_t loopCount;
uint16_t position;
uint16_t angle;
/* Track Variation */
uint8_t isComplex;
FAUDIONAMELESS union
{
struct
{
uint16_t track;
uint8_t wavebank;
} simple;
struct
{
uint16_t variation;
uint16_t trackCount;
uint16_t *tracks;
uint8_t *wavebanks;
uint8_t *weights;
} complex;
};
/* Effect Variation */
int16_t minPitch;
int16_t maxPitch;
float minVolume;
float maxVolume;
float minFrequency;
float maxFrequency;
float minQFactor;
float maxQFactor;
uint16_t variationFlags;
} wave;
/* Set Pitch/Volume Event */
struct
{
uint8_t settings;
uint16_t repeats;
uint16_t frequency;
FAUDIONAMELESS union
{
struct
{
float initialValue;
float initialSlope;
float slopeDelta;
uint16_t duration;
} ramp;
struct
{
uint8_t flags;
float value1;
float value2;
} equation;
};
} value;
/* Stop Event */
struct
{
uint8_t flags;
} stop;
/* Marker Event */
struct
{
uint32_t marker;
uint16_t repeats;
uint16_t frequency;
} marker;
};
} FACTEvent;
typedef struct FACTTrack
{
uint32_t code;
float volume;
uint8_t filter;
uint8_t qfactor;
uint16_t frequency;
uint8_t rpcCodeCount;
uint32_t *rpcCodes;
uint8_t eventCount;
FACTEvent *events;
} FACTTrack;
typedef struct FACTSound
{
uint8_t flags;
uint16_t category;
float volume;
int16_t pitch;
uint8_t priority;
uint8_t trackCount;
uint8_t rpcCodeCount;
uint8_t dspCodeCount;
FACTTrack *tracks;
uint32_t *rpcCodes;
uint32_t *dspCodes;
} FACTSound;
typedef struct FACTCueData
{
uint8_t flags;
uint32_t sbCode;
uint32_t transitionOffset;
uint8_t instanceLimit;
uint16_t fadeInMS;
uint16_t fadeOutMS;
uint8_t maxInstanceBehavior;
uint8_t instanceCount;
} FACTCueData;
typedef struct FACTVariation
{
FAUDIONAMELESS union
{
struct
{
uint16_t track;
uint8_t wavebank;
} simple;
uint32_t soundCode;
};
float minWeight;
float maxWeight;
uint32_t linger;
} FACTVariation;
typedef struct FACTVariationTable
{
uint8_t flags;
int16_t variable;
uint8_t isComplex;
uint16_t entryCount;
FACTVariation *entries;
} FACTVariationTable;
typedef struct FACTTransition
{
int32_t soundCode;
uint32_t srcMarkerMin;
uint32_t srcMarkerMax;
uint32_t dstMarkerMin;
uint32_t dstMarkerMax;
uint16_t fadeIn;
uint16_t fadeOut;
uint16_t flags;
} FACTTransition;
typedef struct FACTTransitionTable
{
uint32_t entryCount;
FACTTransition *entries;
} FACTTransitionTable;
/* Internal WaveBank Types */
typedef struct FACTSeekTable
{
uint32_t entryCount;
uint32_t *entries;
} FACTSeekTable;
/* Internal Cue Types */
typedef struct FACTInstanceRPCData
{
float rpcVolume;
float rpcPitch;
float rpcReverbSend;
float rpcFilterFreq;
float rpcFilterQFactor;
} FACTInstanceRPCData;
typedef struct FACTEventInstance
{
uint32_t timestamp;
uint16_t loopCount;
uint8_t finished;
FAUDIONAMELESS union
{
float value;
uint32_t valuei;
};
} FACTEventInstance;
typedef struct FACTTrackInstance
{
/* Tracks which events have fired */
FACTEventInstance *events;
/* RPC instance data */
FACTInstanceRPCData rpcData;
/* SetPitch/SetVolume data */
float evtPitch;
float evtVolume;
/* Wave playback */
struct
{
FACTWave *wave;
float baseVolume;
int16_t basePitch;
float baseQFactor;
float baseFrequency;
} activeWave, upcomingWave;
FACTEvent *waveEvt;
FACTEventInstance *waveEvtInst;
} FACTTrackInstance;
typedef struct FACTSoundInstance
{
/* Base Sound reference */
FACTSound *sound;
/* Per-instance track information */
FACTTrackInstance *tracks;
/* RPC instance data */
FACTInstanceRPCData rpcData;
/* Fade data */
uint32_t fadeStart;
uint16_t fadeTarget;
uint8_t fadeType; /* In (1), Out (2), Release RPC (3) */
/* Engine references */
FACTCue *parentCue;
} FACTSoundInstance;
/* Internal Wave Types */
typedef struct FACTWaveCallback
{
FAudioVoiceCallback callback;
FACTWave *wave;
} FACTWaveCallback;
/* Public XACT Types */
struct FACTAudioEngine
{
uint32_t refcount;
FACTNotificationCallback notificationCallback;
FACTReadFileCallback pReadFile;
FACTGetOverlappedResultCallback pGetOverlappedResult;
uint16_t categoryCount;
uint16_t variableCount;
uint16_t rpcCount;
uint16_t dspPresetCount;
uint16_t dspParameterCount;
char **categoryNames;
char **variableNames;
uint32_t *rpcCodes;
uint32_t *dspPresetCodes;
FACTAudioCategory *categories;
FACTVariable *variables;
FACTRPC *rpcs;
FACTDSPPreset *dspPresets;
/* Engine references */
LinkedList *sbList;
LinkedList *wbList;
FAudioMutex sbLock;
FAudioMutex wbLock;
float *globalVariableValues;
/* FAudio references */
FAudio *audio;
FAudioMasteringVoice *master;
FAudioSubmixVoice *reverbVoice;
/* Engine thread */
FAudioThread apiThread;
FAudioMutex apiLock;
uint8_t initialized;
/* Allocator callbacks */
FAudioMallocFunc pMalloc;
FAudioFreeFunc pFree;
FAudioReallocFunc pRealloc;
/* Peristent Notifications */
FACTNoticationsFlags notifications;
void *cue_context;
void *sb_context;
void *wb_context;
void *wave_context;
/* Settings handle */
void *settings;
};
struct FACTSoundBank
{
/* Engine references */
FACTAudioEngine *parentEngine;
FACTCue *cueList;
uint8_t notifyOnDestroy;
void *usercontext;
/* Array sizes */
uint16_t cueCount;
uint8_t wavebankCount;
uint16_t soundCount;
uint16_t variationCount;
uint16_t transitionCount;
/* Strings, strings everywhere! */
char **wavebankNames;
char **cueNames;
/* Actual SoundBank information */
char *name;
FACTCueData *cues;
FACTSound *sounds;
uint32_t *soundCodes;
FACTVariationTable *variations;
uint32_t *variationCodes;
FACTTransitionTable *transitions;
uint32_t *transitionCodes;
};
struct FACTWaveBank
{
/* Engine references */
FACTAudioEngine *parentEngine;
LinkedList *waveList;
FAudioMutex waveLock;
uint8_t notifyOnDestroy;
void *usercontext;
/* Actual WaveBank information */
char *name;
uint32_t entryCount;
FACTWaveBankEntry *entries;
uint32_t *entryRefs;
FACTSeekTable *seekTables;
char *waveBankNames;
/* I/O information */
uint32_t packetSize;
uint16_t streaming;
uint8_t *packetBuffer;
uint32_t packetBufferLen;
void* io;
};
struct FACTWave
{
/* Engine references */
FACTWaveBank *parentBank;
FACTCue *parentCue;
uint16_t index;
uint8_t notifyOnDestroy;
void *usercontext;
/* Playback */
uint32_t state;
float volume;
int16_t pitch;
uint8_t loopCount;
/* Stream data */
uint32_t streamSize;
uint32_t streamOffset;
uint8_t *streamCache;
/* FAudio references */
uint16_t srcChannels;
FAudioSourceVoice *voice;
FACTWaveCallback callback;
};
struct FACTCue
{
/* Engine references */
FACTSoundBank *parentBank;
FACTCue *next;
uint8_t managed;
uint16_t index;
uint8_t notifyOnDestroy;
void *usercontext;
/* Sound data */
FACTCueData *data;
FAUDIONAMELESS union
{
FACTVariationTable *variation;
/* This is only used in scenarios where there is only one
* Sound; XACT does not generate variation tables for
* Cues with only one Sound.
*/
FACTSound *sound;
};
/* Instance data */
float *variableValues;
float interactive;
/* Playback */
uint32_t state;
FACTWave *simpleWave;
FACTSoundInstance *playingSound;
FACTVariation *playingVariation;
uint32_t maxRpcReleaseTime;
/* 3D Data */
uint8_t active3D;
uint32_t srcChannels;
uint32_t dstChannels;
float matrixCoefficients[2 * 8]; /* Stereo input, 7.1 output */
/* Timer */
uint32_t start;
uint32_t elapsed;
};
/* Internal functions */
void FACT_INTERNAL_GetNextWave(
FACTCue *cue,
FACTSound *sound,
FACTTrack *track,
FACTTrackInstance *trackInst,
FACTEvent *evt,
FACTEventInstance *evtInst
);
uint8_t FACT_INTERNAL_CreateSound(FACTCue *cue, uint16_t fadeInMS);
void FACT_INTERNAL_DestroySound(FACTSoundInstance *sound);
void FACT_INTERNAL_BeginFadeOut(FACTSoundInstance *sound, uint16_t fadeOutMS);
void FACT_INTERNAL_BeginReleaseRPC(FACTSoundInstance *sound, uint16_t releaseMS);
void FACT_INTERNAL_SendCueNotification(FACTCue *cue, FACTNoticationsFlags flag, uint8_t type);
/* RPC Helper Functions */
FACTRPC* FACT_INTERNAL_GetRPC(FACTAudioEngine *engine, uint32_t code);
/* FACT Thread */
int32_t FAUDIOCALL FACT_INTERNAL_APIThread(void* enginePtr);
/* FAudio callbacks */
void FACT_INTERNAL_OnBufferEnd(FAudioVoiceCallback *callback, void* pContext);
void FACT_INTERNAL_OnStreamEnd(FAudioVoiceCallback *callback);
/* FAudioIOStream functions */
int32_t FACTCALL FACT_INTERNAL_DefaultReadFile(
void *hFile,
void *buffer,
uint32_t nNumberOfBytesToRead,
uint32_t *lpNumberOfBytesRead,
FACTOverlapped *lpOverlapped
);
int32_t FACTCALL FACT_INTERNAL_DefaultGetOverlappedResult(
void *hFile,
FACTOverlapped *lpOverlapped,
uint32_t *lpNumberOfBytesTransferred,
int32_t bWait
);
/* Parsing functions */
uint32_t FACT_INTERNAL_ParseAudioEngine(
FACTAudioEngine *pEngine,
const FACTRuntimeParameters *pParams
);
uint32_t FACT_INTERNAL_ParseSoundBank(
FACTAudioEngine *pEngine,
const void *pvBuffer,
uint32_t dwSize,
FACTSoundBank **ppSoundBank
);
uint32_t FACT_INTERNAL_ParseWaveBank(
FACTAudioEngine *pEngine,
void* io,
uint32_t offset,
uint32_t packetSize,
FACTReadFileCallback pRead,
FACTGetOverlappedResultCallback pOverlap,
uint16_t isStreaming,
FACTWaveBank **ppWaveBank
);
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

451
libs/faudio/src/FAPOBase.c Normal file
View File

@ -0,0 +1,451 @@
/* 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>
*
*/
#include "FAPOBase.h"
#include "FAudio_internal.h"
/* FAPOBase Interface */
void CreateFAPOBase(
FAPOBase *fapo,
const FAPORegistrationProperties *pRegistrationProperties,
uint8_t *pParameterBlocks,
uint32_t uParameterBlockByteSize,
uint8_t fProducer
) {
CreateFAPOBaseWithCustomAllocatorEXT(
fapo,
pRegistrationProperties,
pParameterBlocks,
uParameterBlockByteSize,
fProducer,
FAudio_malloc,
FAudio_free,
FAudio_realloc
);
}
void CreateFAPOBaseWithCustomAllocatorEXT(
FAPOBase *fapo,
const FAPORegistrationProperties *pRegistrationProperties,
uint8_t *pParameterBlocks,
uint32_t uParameterBlockByteSize,
uint8_t fProducer,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
) {
/* Base Classes/Interfaces */
#define ASSIGN_VT(name) \
fapo->base.name = (name##Func) FAPOBase_##name;
ASSIGN_VT(AddRef)
ASSIGN_VT(Release)
ASSIGN_VT(GetRegistrationProperties)
ASSIGN_VT(IsInputFormatSupported)
ASSIGN_VT(IsOutputFormatSupported)
ASSIGN_VT(Initialize)
ASSIGN_VT(Reset)
ASSIGN_VT(LockForProcess)
ASSIGN_VT(UnlockForProcess)
ASSIGN_VT(CalcInputFrames)
ASSIGN_VT(CalcOutputFrames)
ASSIGN_VT(SetParameters)
ASSIGN_VT(GetParameters)
#undef ASSIGN_VT
/* Public Virtual Functions */
fapo->OnSetParameters = (OnSetParametersFunc)
FAPOBase_OnSetParameters;
/* Private Variables */
fapo->m_pRegistrationProperties = pRegistrationProperties; /* FIXME */
fapo->m_pfnMatrixMixFunction = NULL; /* FIXME */
fapo->m_pfl32MatrixCoefficients = NULL; /* FIXME */
fapo->m_nSrcFormatType = 0; /* FIXME */
fapo->m_fIsScalarMatrix = 0; /* FIXME: */
fapo->m_fIsLocked = 0;
fapo->m_pParameterBlocks = pParameterBlocks;
fapo->m_pCurrentParameters = pParameterBlocks;
fapo->m_pCurrentParametersInternal = pParameterBlocks;
fapo->m_uCurrentParametersIndex = 0;
fapo->m_uParameterBlockByteSize = uParameterBlockByteSize;
fapo->m_fNewerResultsReady = 0;
fapo->m_fProducer = fProducer;
/* Allocator Callbacks */
fapo->pMalloc = customMalloc;
fapo->pFree = customFree;
fapo->pRealloc = customRealloc;
/* Protected Variables */
fapo->m_lReferenceCount = 1;
}
int32_t FAPOBase_AddRef(FAPOBase *fapo)
{
fapo->m_lReferenceCount += 1;
return fapo->m_lReferenceCount;
}
int32_t FAPOBase_Release(FAPOBase *fapo)
{
fapo->m_lReferenceCount -= 1;
if (fapo->m_lReferenceCount == 0)
{
fapo->Destructor(fapo);
return 0;
}
return fapo->m_lReferenceCount;
}
uint32_t FAPOBase_GetRegistrationProperties(
FAPOBase *fapo,
FAPORegistrationProperties **ppRegistrationProperties
) {
*ppRegistrationProperties = (FAPORegistrationProperties*) fapo->pMalloc(
sizeof(FAPORegistrationProperties)
);
FAudio_memcpy(
*ppRegistrationProperties,
fapo->m_pRegistrationProperties,
sizeof(FAPORegistrationProperties)
);
return 0;
}
uint32_t FAPOBase_IsInputFormatSupported(
FAPOBase *fapo,
const FAudioWaveFormatEx *pOutputFormat,
const FAudioWaveFormatEx *pRequestedInputFormat,
FAudioWaveFormatEx **ppSupportedInputFormat
) {
if ( pRequestedInputFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
pRequestedInputFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
pRequestedInputFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
pRequestedInputFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
pRequestedInputFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
pRequestedInputFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
{
if (ppSupportedInputFormat != NULL)
{
(*ppSupportedInputFormat)->wFormatTag =
FAPOBASE_DEFAULT_FORMAT_TAG;
(*ppSupportedInputFormat)->nChannels = FAudio_clamp(
pRequestedInputFormat->nChannels,
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
);
(*ppSupportedInputFormat)->nSamplesPerSec = FAudio_clamp(
pRequestedInputFormat->nSamplesPerSec,
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
);
(*ppSupportedInputFormat)->wBitsPerSample =
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
}
return FAPO_E_FORMAT_UNSUPPORTED;
}
return 0;
}
uint32_t FAPOBase_IsOutputFormatSupported(
FAPOBase *fapo,
const FAudioWaveFormatEx *pInputFormat,
const FAudioWaveFormatEx *pRequestedOutputFormat,
FAudioWaveFormatEx **ppSupportedOutputFormat
) {
if ( pRequestedOutputFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
pRequestedOutputFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
pRequestedOutputFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
pRequestedOutputFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
pRequestedOutputFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
pRequestedOutputFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
{
if (ppSupportedOutputFormat != NULL)
{
(*ppSupportedOutputFormat)->wFormatTag =
FAPOBASE_DEFAULT_FORMAT_TAG;
(*ppSupportedOutputFormat)->nChannels = FAudio_clamp(
pRequestedOutputFormat->nChannels,
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
);
(*ppSupportedOutputFormat)->nSamplesPerSec = FAudio_clamp(
pRequestedOutputFormat->nSamplesPerSec,
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
);
(*ppSupportedOutputFormat)->wBitsPerSample =
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
}
return FAPO_E_FORMAT_UNSUPPORTED;
}
return 0;
}
uint32_t FAPOBase_Initialize(
FAPOBase *fapo,
const void* pData,
uint32_t DataByteSize
) {
return 0;
}
void FAPOBase_Reset(FAPOBase *fapo)
{
}
uint32_t FAPOBase_LockForProcess(
FAPOBase *fapo,
uint32_t InputLockedParameterCount,
const FAPOLockForProcessBufferParameters *pInputLockedParameters,
uint32_t OutputLockedParameterCount,
const FAPOLockForProcessBufferParameters *pOutputLockedParameters
) {
/* Verify parameter counts... */
if ( InputLockedParameterCount < fapo->m_pRegistrationProperties->MinInputBufferCount ||
InputLockedParameterCount > fapo->m_pRegistrationProperties->MaxInputBufferCount ||
OutputLockedParameterCount < fapo->m_pRegistrationProperties->MinOutputBufferCount ||
OutputLockedParameterCount > fapo->m_pRegistrationProperties->MaxOutputBufferCount )
{
return FAUDIO_E_INVALID_ARG;
}
/* Validate input/output formats */
#define VERIFY_FORMAT_FLAG(flag, prop) \
if ( (fapo->m_pRegistrationProperties->Flags & flag) && \
(pInputLockedParameters->pFormat->prop != pOutputLockedParameters->pFormat->prop) ) \
{ \
return FAUDIO_E_INVALID_ARG; \
}
VERIFY_FORMAT_FLAG(FAPO_FLAG_CHANNELS_MUST_MATCH, nChannels)
VERIFY_FORMAT_FLAG(FAPO_FLAG_FRAMERATE_MUST_MATCH, nSamplesPerSec)
VERIFY_FORMAT_FLAG(FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH, wBitsPerSample)
#undef VERIFY_FORMAT_FLAG
if ( (fapo->m_pRegistrationProperties->Flags & FAPO_FLAG_BUFFERCOUNT_MUST_MATCH) &&
(InputLockedParameterCount != OutputLockedParameterCount) )
{
return FAUDIO_E_INVALID_ARG;
}
fapo->m_fIsLocked = 1;
return 0;
}
void FAPOBase_UnlockForProcess(FAPOBase *fapo)
{
fapo->m_fIsLocked = 0;
}
uint32_t FAPOBase_CalcInputFrames(FAPOBase *fapo, uint32_t OutputFrameCount)
{
return OutputFrameCount;
}
uint32_t FAPOBase_CalcOutputFrames(FAPOBase *fapo, uint32_t InputFrameCount)
{
return InputFrameCount;
}
uint32_t FAPOBase_ValidateFormatDefault(
FAPOBase *fapo,
FAudioWaveFormatEx *pFormat,
uint8_t fOverwrite
) {
if ( pFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
pFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
pFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
pFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
pFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
pFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
{
if (fOverwrite)
{
pFormat->wFormatTag =
FAPOBASE_DEFAULT_FORMAT_TAG;
pFormat->nChannels = FAudio_clamp(
pFormat->nChannels,
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
);
pFormat->nSamplesPerSec = FAudio_clamp(
pFormat->nSamplesPerSec,
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
);
pFormat->wBitsPerSample =
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
}
return FAPO_E_FORMAT_UNSUPPORTED;
}
return 0;
}
uint32_t FAPOBase_ValidateFormatPair(
FAPOBase *fapo,
const FAudioWaveFormatEx *pSupportedFormat,
FAudioWaveFormatEx *pRequestedFormat,
uint8_t fOverwrite
) {
if ( pRequestedFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
pRequestedFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
pRequestedFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
pRequestedFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
pRequestedFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
pRequestedFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
{
if (fOverwrite)
{
pRequestedFormat->wFormatTag =
FAPOBASE_DEFAULT_FORMAT_TAG;
pRequestedFormat->nChannels = FAudio_clamp(
pRequestedFormat->nChannels,
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
);
pRequestedFormat->nSamplesPerSec = FAudio_clamp(
pRequestedFormat->nSamplesPerSec,
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
);
pRequestedFormat->wBitsPerSample =
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
}
return FAPO_E_FORMAT_UNSUPPORTED;
}
return 0;
}
void FAPOBase_ProcessThru(
FAPOBase *fapo,
void* pInputBuffer,
float *pOutputBuffer,
uint32_t FrameCount,
uint16_t InputChannelCount,
uint16_t OutputChannelCount,
uint8_t MixWithOutput
) {
uint32_t i, co, ci;
float *input = (float*) pInputBuffer;
if (MixWithOutput)
{
/* TODO: SSE */
for (i = 0; i < FrameCount; i += 1)
for (co = 0; co < OutputChannelCount; co += 1)
for (ci = 0; ci < InputChannelCount; ci += 1)
{
/* Add, don't overwrite! */
pOutputBuffer[i * OutputChannelCount + co] +=
input[i * InputChannelCount + ci];
}
}
else
{
/* TODO: SSE */
for (i = 0; i < FrameCount; i += 1)
for (co = 0; co < OutputChannelCount; co += 1)
for (ci = 0; ci < InputChannelCount; ci += 1)
{
/* Overwrite, don't add! */
pOutputBuffer[i * OutputChannelCount + co] =
input[i * InputChannelCount + ci];
}
}
}
void FAPOBase_SetParameters(
FAPOBase *fapo,
const void* pParameters,
uint32_t ParameterByteSize
) {
FAudio_assert(!fapo->m_fProducer);
/* User callback for validation */
fapo->OnSetParameters(
fapo,
pParameters,
ParameterByteSize
);
/* Increment parameter block index... */
fapo->m_uCurrentParametersIndex += 1;
if (fapo->m_uCurrentParametersIndex == 3)
{
fapo->m_uCurrentParametersIndex = 0;
}
fapo->m_pCurrentParametersInternal = fapo->m_pParameterBlocks + (
fapo->m_uParameterBlockByteSize *
fapo->m_uCurrentParametersIndex
);
/* Copy to what will eventually be the next parameter update */
FAudio_memcpy(
fapo->m_pCurrentParametersInternal,
pParameters,
ParameterByteSize
);
}
void FAPOBase_GetParameters(
FAPOBase *fapo,
void* pParameters,
uint32_t ParameterByteSize
) {
/* Copy what's current as of the last Process */
FAudio_memcpy(
pParameters,
fapo->m_pCurrentParameters,
ParameterByteSize
);
}
void FAPOBase_OnSetParameters(
FAPOBase *fapo,
const void* parameters,
uint32_t parametersSize
) {
}
uint8_t FAPOBase_ParametersChanged(FAPOBase *fapo)
{
/* Internal will get updated when SetParameters is called */
return fapo->m_pCurrentParametersInternal != fapo->m_pCurrentParameters;
}
uint8_t* FAPOBase_BeginProcess(FAPOBase *fapo)
{
/* Set the latest block as "current", this is what Process will use now */
fapo->m_pCurrentParameters = fapo->m_pCurrentParametersInternal;
return fapo->m_pCurrentParameters;
}
void FAPOBase_EndProcess(FAPOBase *fapo)
{
/* I'm 100% sure my parameter block increment is wrong... */
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

89
libs/faudio/src/FAPOFX.c Normal file
View File

@ -0,0 +1,89 @@
/* 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>
*
*/
#include "FAPOFX.h"
#include "FAudio_internal.h"
uint32_t FAPOFX_CreateFX(
const FAudioGUID *clsid,
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize
) {
return FAPOFX_CreateFXWithCustomAllocatorEXT(
clsid,
pEffect,
pInitData,
InitDataByteSize,
FAudio_malloc,
FAudio_free,
FAudio_realloc
);
}
uint32_t FAPOFX_CreateFXWithCustomAllocatorEXT(
const FAudioGUID *clsid,
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
) {
#define CHECK_AND_RETURN(effect) \
if (FAudio_memcmp(clsid, &FAPOFX_CLSID_FX##effect, sizeof(FAudioGUID)) == 0) \
{ \
return FAPOFXCreate##effect( \
pEffect, \
pInitData, \
InitDataByteSize, \
customMalloc, \
customFree, \
customRealloc, \
0 \
); \
} \
else if (FAudio_memcmp(clsid, &FAPOFX_CLSID_FX##effect##_LEGACY, sizeof(FAudioGUID)) == 0) \
{ \
return FAPOFXCreate##effect( \
pEffect, \
pInitData, \
InitDataByteSize, \
customMalloc, \
customFree, \
customRealloc, \
1 \
); \
}
CHECK_AND_RETURN(EQ)
CHECK_AND_RETURN(MasteringLimiter)
CHECK_AND_RETURN(Reverb)
CHECK_AND_RETURN(Echo)
#undef CHECK_AND_RETURN
return -1;
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

View File

@ -0,0 +1,248 @@
/* 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>
*
*/
#include "FAPOFX.h"
#include "FAudio_internal.h"
/* FXEcho FAPO Implementation */
const FAudioGUID FAPOFX_CLSID_FXEcho =
{
0x5039D740,
0xF736,
0x449A,
{
0x84,
0xD3,
0xA5,
0x62,
0x02,
0x55,
0x7B,
0x87
}
};
static FAPORegistrationProperties FXEchoProperties =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'E', 'c', 'h', 'o', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
const FAudioGUID FAPOFX_CLSID_FXEcho_LEGACY =
{
0xA90BC001,
0xE897,
0xE897,
{
0x74,
0x39,
0x43,
0x55,
0x00,
0x00,
0x00,
0x03
}
};
static FAPORegistrationProperties FXEchoProperties_LEGACY =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'E', 'c', 'h', 'o', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
typedef struct FAPOFXEcho
{
FAPOBase base;
/* TODO */
} FAPOFXEcho;
uint32_t FAPOFXEcho_Initialize(
FAPOFXEcho *fapo,
const void* pData,
uint32_t DataByteSize
) {
#define INITPARAMS(offset) \
FAudio_memcpy( \
fapo->base.m_pParameterBlocks + DataByteSize * offset, \
pData, \
DataByteSize \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
return 0;
}
void FAPOFXEcho_Process(
FAPOFXEcho *fapo,
uint32_t InputProcessParameterCount,
const FAPOProcessBufferParameters* pInputProcessParameters,
uint32_t OutputProcessParameterCount,
FAPOProcessBufferParameters* pOutputProcessParameters,
int32_t IsEnabled
) {
FAPOBase_BeginProcess(&fapo->base);
/* TODO */
FAPOBase_EndProcess(&fapo->base);
}
void FAPOFXEcho_Free(void* fapo)
{
FAPOFXEcho *echo = (FAPOFXEcho*) fapo;
echo->base.pFree(echo->base.m_pParameterBlocks);
echo->base.pFree(fapo);
}
/* Public API */
uint32_t FAPOFXCreateEcho(
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc,
uint8_t legacy
) {
const FAPOFXEchoParameters fxdefault =
{
FAPOFXECHO_DEFAULT_WETDRYMIX,
FAPOFXECHO_DEFAULT_FEEDBACK,
FAPOFXECHO_DEFAULT_DELAY
};
/* Allocate... */
FAPOFXEcho *result = (FAPOFXEcho*) customMalloc(
sizeof(FAPOFXEcho)
);
uint8_t *params = (uint8_t*) customMalloc(
sizeof(FAPOFXEchoParameters) * 3
);
if (pInitData == NULL)
{
FAudio_zero(params, sizeof(FAPOFXEchoParameters) * 3);
#define INITPARAMS(offset) \
FAudio_memcpy( \
params + sizeof(FAPOFXEchoParameters) * offset, \
&fxdefault, \
sizeof(FAPOFXEchoParameters) \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
}
else
{
FAudio_assert(InitDataByteSize == sizeof(FAPOFXEchoParameters));
FAudio_memcpy(params, pInitData, InitDataByteSize);
FAudio_memcpy(params + InitDataByteSize, pInitData, InitDataByteSize);
FAudio_memcpy(params + (InitDataByteSize * 2), pInitData, InitDataByteSize);
}
/* Initialize... */
FAudio_memcpy(
&FXEchoProperties_LEGACY.clsid,
&FAPOFX_CLSID_FXEcho_LEGACY,
sizeof(FAudioGUID)
);
FAudio_memcpy(
&FXEchoProperties.clsid,
&FAPOFX_CLSID_FXEcho,
sizeof(FAudioGUID)
);
CreateFAPOBaseWithCustomAllocatorEXT(
&result->base,
legacy ? &FXEchoProperties_LEGACY : &FXEchoProperties,
params,
sizeof(FAPOFXEchoParameters),
0,
customMalloc,
customFree,
customRealloc
);
/* Function table... */
result->base.base.Initialize = (InitializeFunc)
FAPOFXEcho_Initialize;
result->base.base.Process = (ProcessFunc)
FAPOFXEcho_Process;
result->base.Destructor = FAPOFXEcho_Free;
/* Finally. */
*pEffect = &result->base.base;
return 0;
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

257
libs/faudio/src/FAPOFX_eq.c Normal file
View File

@ -0,0 +1,257 @@
/* 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>
*
*/
#include "FAPOFX.h"
#include "FAudio_internal.h"
/* FXEQ FAPO Implementation */
const FAudioGUID FAPOFX_CLSID_FXEQ =
{
0xF5E01117,
0xD6C4,
0x485A,
{
0xA3,
0xF5,
0x69,
0x51,
0x96,
0xF3,
0xDB,
0xFA
}
};
static FAPORegistrationProperties FXEQProperties =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'E', 'Q', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
const FAudioGUID FAPOFX_CLSID_FXEQ_LEGACY =
{
0xA90BC001,
0xE897,
0xE897,
{
0x74,
0x39,
0x43,
0x55,
0x00,
0x00,
0x00,
0x00
}
};
static FAPORegistrationProperties FXEQProperties_LEGACY =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'E', 'Q', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
typedef struct FAPOFXEQ
{
FAPOBase base;
/* TODO */
} FAPOFXEQ;
uint32_t FAPOFXEQ_Initialize(
FAPOFXEQ *fapo,
const void* pData,
uint32_t DataByteSize
) {
#define INITPARAMS(offset) \
FAudio_memcpy( \
fapo->base.m_pParameterBlocks + DataByteSize * offset, \
pData, \
DataByteSize \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
return 0;
}
void FAPOFXEQ_Process(
FAPOFXEQ *fapo,
uint32_t InputProcessParameterCount,
const FAPOProcessBufferParameters* pInputProcessParameters,
uint32_t OutputProcessParameterCount,
FAPOProcessBufferParameters* pOutputProcessParameters,
int32_t IsEnabled
) {
FAPOBase_BeginProcess(&fapo->base);
/* TODO */
FAPOBase_EndProcess(&fapo->base);
}
void FAPOFXEQ_Free(void* fapo)
{
FAPOFXEQ *eq = (FAPOFXEQ*) fapo;
eq->base.pFree(eq->base.m_pParameterBlocks);
eq->base.pFree(fapo);
}
/* Public API */
uint32_t FAPOFXCreateEQ(
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc,
uint8_t legacy
) {
const FAPOFXEQParameters fxdefault =
{
FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_0,
FAPOFXEQ_DEFAULT_GAIN,
FAPOFXEQ_DEFAULT_BANDWIDTH,
FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_1,
FAPOFXEQ_DEFAULT_GAIN,
FAPOFXEQ_DEFAULT_BANDWIDTH,
FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_2,
FAPOFXEQ_DEFAULT_GAIN,
FAPOFXEQ_DEFAULT_BANDWIDTH,
FAPOFXEQ_DEFAULT_FREQUENCY_CENTER_3,
FAPOFXEQ_DEFAULT_GAIN,
FAPOFXEQ_DEFAULT_BANDWIDTH
};
/* Allocate... */
FAPOFXEQ *result = (FAPOFXEQ*) customMalloc(
sizeof(FAPOFXEQ)
);
uint8_t *params = (uint8_t*) customMalloc(
sizeof(FAPOFXEQParameters) * 3
);
if (pInitData == NULL)
{
FAudio_zero(params, sizeof(FAPOFXEQParameters) * 3);
#define INITPARAMS(offset) \
FAudio_memcpy( \
params + sizeof(FAPOFXEQParameters) * offset, \
&fxdefault, \
sizeof(FAPOFXEQParameters) \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
}
else
{
FAudio_assert(InitDataByteSize == sizeof(FAPOFXEQParameters));
FAudio_memcpy(params, pInitData, InitDataByteSize);
FAudio_memcpy(params + InitDataByteSize, pInitData, InitDataByteSize);
FAudio_memcpy(params + (InitDataByteSize * 2), pInitData, InitDataByteSize);
}
/* Initialize... */
FAudio_memcpy(
&FXEQProperties_LEGACY.clsid,
&FAPOFX_CLSID_FXEQ_LEGACY,
sizeof(FAudioGUID)
);
FAudio_memcpy(
&FXEQProperties.clsid,
&FAPOFX_CLSID_FXEQ,
sizeof(FAudioGUID)
);
CreateFAPOBaseWithCustomAllocatorEXT(
&result->base,
legacy ? &FXEQProperties_LEGACY : &FXEQProperties,
params,
sizeof(FAPOFXEQParameters),
0,
customMalloc,
customFree,
customRealloc
);
/* Function table... */
result->base.base.Initialize = (InitializeFunc)
FAPOFXEQ_Initialize;
result->base.base.Process = (ProcessFunc)
FAPOFXEQ_Process;
result->base.Destructor = FAPOFXEQ_Free;
/* Finally. */
*pEffect = &result->base.base;
return 0;
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

View File

@ -0,0 +1,247 @@
/* 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>
*
*/
#include "FAPOFX.h"
#include "FAudio_internal.h"
/* FXMasteringLimiter FAPO Implementation */
const FAudioGUID FAPOFX_CLSID_FXMasteringLimiter =
{
0xC4137916,
0x2BE1,
0x46FD,
{
0x85,
0x99,
0x44,
0x15,
0x36,
0xF4,
0x98,
0x56
}
};
static FAPORegistrationProperties FXMasteringLimiterProperties =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'M', 'a', 's', 't', 'e', 'r', 'i', 'n', 'g', 'L', 'i', 'm', 'i', 't', 'e', 'r', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
const FAudioGUID FAPOFX_CLSID_FXMasteringLimiter_LEGACY =
{
0xA90BC001,
0xE897,
0xE897,
{
0x74,
0x39,
0x43,
0x55,
0x00,
0x00,
0x00,
0x01
}
};
static FAPORegistrationProperties FXMasteringLimiterProperties_LEGACY =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'M', 'a', 's', 't', 'e', 'r', 'i', 'n', 'g', 'L', 'i', 'm', 'i', 't', 'e', 'r', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
typedef struct FAPOFXMasteringLimiter
{
FAPOBase base;
/* TODO */
} FAPOFXMasteringLimiter;
uint32_t FAPOFXMasteringLimiter_Initialize(
FAPOFXMasteringLimiter *fapo,
const void* pData,
uint32_t DataByteSize
) {
#define INITPARAMS(offset) \
FAudio_memcpy( \
fapo->base.m_pParameterBlocks + DataByteSize * offset, \
pData, \
DataByteSize \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
return 0;
}
void FAPOFXMasteringLimiter_Process(
FAPOFXMasteringLimiter *fapo,
uint32_t InputProcessParameterCount,
const FAPOProcessBufferParameters* pInputProcessParameters,
uint32_t OutputProcessParameterCount,
FAPOProcessBufferParameters* pOutputProcessParameters,
int32_t IsEnabled
) {
FAPOBase_BeginProcess(&fapo->base);
/* TODO */
FAPOBase_EndProcess(&fapo->base);
}
void FAPOFXMasteringLimiter_Free(void* fapo)
{
FAPOFXMasteringLimiter *limiter = (FAPOFXMasteringLimiter*) fapo;
limiter->base.pFree(limiter->base.m_pParameterBlocks);
limiter->base.pFree(fapo);
}
/* Public API */
uint32_t FAPOFXCreateMasteringLimiter(
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc,
uint8_t legacy
) {
const FAPOFXMasteringLimiterParameters fxdefault =
{
FAPOFXMASTERINGLIMITER_DEFAULT_RELEASE,
FAPOFXMASTERINGLIMITER_DEFAULT_LOUDNESS
};
/* Allocate... */
FAPOFXMasteringLimiter *result = (FAPOFXMasteringLimiter*) customMalloc(
sizeof(FAPOFXMasteringLimiter)
);
uint8_t *params = (uint8_t*) customMalloc(
sizeof(FAPOFXMasteringLimiterParameters) * 3
);
if (pInitData == NULL)
{
FAudio_zero(params, sizeof(FAPOFXMasteringLimiterParameters) * 3);
#define INITPARAMS(offset) \
FAudio_memcpy( \
params + sizeof(FAPOFXMasteringLimiterParameters) * offset, \
&fxdefault, \
sizeof(FAPOFXMasteringLimiterParameters) \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
}
else
{
FAudio_assert(InitDataByteSize == sizeof(FAPOFXMasteringLimiterParameters));
FAudio_memcpy(params, pInitData, InitDataByteSize);
FAudio_memcpy(params + InitDataByteSize, pInitData, InitDataByteSize);
FAudio_memcpy(params + (InitDataByteSize * 2), pInitData, InitDataByteSize);
}
/* Initialize... */
FAudio_memcpy(
&FXMasteringLimiterProperties_LEGACY.clsid,
&FAPOFX_CLSID_FXMasteringLimiter_LEGACY,
sizeof(FAudioGUID)
);
FAudio_memcpy(
&FXMasteringLimiterProperties.clsid,
&FAPOFX_CLSID_FXMasteringLimiter,
sizeof(FAudioGUID)
);
CreateFAPOBaseWithCustomAllocatorEXT(
&result->base,
legacy ? &FXMasteringLimiterProperties_LEGACY : &FXMasteringLimiterProperties,
params,
sizeof(FAPOFXMasteringLimiterParameters),
0,
customMalloc,
customFree,
customRealloc
);
/* Function table... */
result->base.base.Initialize = (InitializeFunc)
FAPOFXMasteringLimiter_Initialize;
result->base.base.Process = (ProcessFunc)
FAPOFXMasteringLimiter_Process;
result->base.Destructor = FAPOFXMasteringLimiter_Free;
/* Finally. */
*pEffect = &result->base.base;
return 0;
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

View File

@ -0,0 +1,247 @@
/* 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>
*
*/
#include "FAPOFX.h"
#include "FAudio_internal.h"
/* FXReverb FAPO Implementation */
const FAudioGUID FAPOFX_CLSID_FXReverb =
{
0x7D9ACA56,
0xCB68,
0x4807,
{
0xB6,
0x32,
0xB1,
0x37,
0x35,
0x2E,
0x85,
0x96
}
};
static FAPORegistrationProperties FXReverbProperties =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'R', 'e', 'v', 'e', 'r', 'b', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
const FAudioGUID FAPOFX_CLSID_FXReverb_LEGACY =
{
0xA90BC001,
0xE897,
0xE897,
{
0x74,
0x39,
0x43,
0x55,
0x00,
0x00,
0x00,
0x02
}
};
static FAPORegistrationProperties FXReverbProperties_LEGACY =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'F', 'X', 'R', 'e', 'v', 'e', 'r', 'b', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
typedef struct FAPOFXReverb
{
FAPOBase base;
/* TODO */
} FAPOFXReverb;
uint32_t FAPOFXReverb_Initialize(
FAPOFXReverb *fapo,
const void* pData,
uint32_t DataByteSize
) {
#define INITPARAMS(offset) \
FAudio_memcpy( \
fapo->base.m_pParameterBlocks + DataByteSize * offset, \
pData, \
DataByteSize \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
return 0;
}
void FAPOFXReverb_Process(
FAPOFXReverb *fapo,
uint32_t InputProcessParameterCount,
const FAPOProcessBufferParameters* pInputProcessParameters,
uint32_t OutputProcessParameterCount,
FAPOProcessBufferParameters* pOutputProcessParameters,
int32_t IsEnabled
) {
FAPOBase_BeginProcess(&fapo->base);
/* TODO */
FAPOBase_EndProcess(&fapo->base);
}
void FAPOFXReverb_Free(void* fapo)
{
FAPOFXReverb *reverb = (FAPOFXReverb*) fapo;
reverb->base.pFree(reverb->base.m_pParameterBlocks);
reverb->base.pFree(fapo);
}
/* Public API */
uint32_t FAPOFXCreateReverb(
FAPO **pEffect,
const void *pInitData,
uint32_t InitDataByteSize,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc,
uint8_t legacy
) {
const FAPOFXReverbParameters fxdefault =
{
FAPOFXREVERB_DEFAULT_DIFFUSION,
FAPOFXREVERB_DEFAULT_ROOMSIZE,
};
/* Allocate... */
FAPOFXReverb *result = (FAPOFXReverb*) customMalloc(
sizeof(FAPOFXReverb)
);
uint8_t *params = (uint8_t*) customMalloc(
sizeof(FAPOFXReverbParameters) * 3
);
if (pInitData == NULL)
{
FAudio_zero(params, sizeof(FAPOFXReverbParameters) * 3);
#define INITPARAMS(offset) \
FAudio_memcpy( \
params + sizeof(FAPOFXReverbParameters) * offset, \
&fxdefault, \
sizeof(FAPOFXReverbParameters) \
);
INITPARAMS(0)
INITPARAMS(1)
INITPARAMS(2)
#undef INITPARAMS
}
else
{
FAudio_assert(InitDataByteSize == sizeof(FAPOFXReverbParameters));
FAudio_memcpy(params, pInitData, InitDataByteSize);
FAudio_memcpy(params + InitDataByteSize, pInitData, InitDataByteSize);
FAudio_memcpy(params + (InitDataByteSize * 2), pInitData, InitDataByteSize);
}
/* Initialize... */
FAudio_memcpy(
&FXReverbProperties_LEGACY.clsid,
&FAPOFX_CLSID_FXReverb_LEGACY,
sizeof(FAudioGUID)
);
FAudio_memcpy(
&FXReverbProperties.clsid,
&FAPOFX_CLSID_FXReverb,
sizeof(FAudioGUID)
);
CreateFAPOBaseWithCustomAllocatorEXT(
&result->base,
legacy ? &FXReverbProperties_LEGACY : &FXReverbProperties,
params,
sizeof(FAPOFXReverbParameters),
0,
customMalloc,
customFree,
customRealloc
);
/* Function table... */
result->base.base.Initialize = (InitializeFunc)
FAPOFXReverb_Initialize;
result->base.base.Process = (ProcessFunc)
FAPOFXReverb_Process;
result->base.Destructor = FAPOFXReverb_Free;
/* Finally. */
*pEffect = &result->base.base;
return 0;
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

3201
libs/faudio/src/FAudio.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
/* 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>
*
*/
#include "FAudioFX.h"
#include "FAudio_internal.h"
/* Volume Meter FAPO Implementation */
const FAudioGUID FAudioFX_CLSID_AudioVolumeMeter = /* 2.7 */
{
0xCAC1105F,
0x619B,
0x4D04,
{
0x83,
0x1A,
0x44,
0xE1,
0xCB,
0xF1,
0x2D,
0x57
}
};
static FAPORegistrationProperties VolumeMeterProperties =
{
/* .clsid = */ {0},
/* .FriendlyName = */
{
'V', 'o', 'l', 'u', 'm', 'e', 'M', 'e', 't', 'e', 'r', '\0'
},
/*.CopyrightInfo = */
{
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
},
/*.MajorVersion = */ 0,
/*.MinorVersion = */ 0,
/*.Flags = */(
FAPO_FLAG_CHANNELS_MUST_MATCH |
FAPO_FLAG_FRAMERATE_MUST_MATCH |
FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
FAPO_FLAG_INPLACE_SUPPORTED |
FAPO_FLAG_INPLACE_REQUIRED
),
/*.MinInputBufferCount = */ 1,
/*.MaxInputBufferCount = */ 1,
/*.MinOutputBufferCount = */ 1,
/*.MaxOutputBufferCount =*/ 1
};
typedef struct FAudioFXVolumeMeter
{
FAPOBase base;
uint16_t channels;
} FAudioFXVolumeMeter;
uint32_t FAudioFXVolumeMeter_LockForProcess(
FAudioFXVolumeMeter *fapo,
uint32_t InputLockedParameterCount,
const FAPOLockForProcessBufferParameters *pInputLockedParameters,
uint32_t OutputLockedParameterCount,
const FAPOLockForProcessBufferParameters *pOutputLockedParameters
) {
FAudioFXVolumeMeterLevels *levels = (FAudioFXVolumeMeterLevels*)
fapo->base.m_pParameterBlocks;
/* Verify parameter counts... */
if ( InputLockedParameterCount < fapo->base.m_pRegistrationProperties->MinInputBufferCount ||
InputLockedParameterCount > fapo->base.m_pRegistrationProperties->MaxInputBufferCount ||
OutputLockedParameterCount < fapo->base.m_pRegistrationProperties->MinOutputBufferCount ||
OutputLockedParameterCount > fapo->base.m_pRegistrationProperties->MaxOutputBufferCount )
{
return FAUDIO_E_INVALID_ARG;
}
/* Validate input/output formats */
#define VERIFY_FORMAT_FLAG(flag, prop) \
if ( (fapo->base.m_pRegistrationProperties->Flags & flag) && \
(pInputLockedParameters->pFormat->prop != pOutputLockedParameters->pFormat->prop) ) \
{ \
return FAUDIO_E_INVALID_ARG; \
}
VERIFY_FORMAT_FLAG(FAPO_FLAG_CHANNELS_MUST_MATCH, nChannels)
VERIFY_FORMAT_FLAG(FAPO_FLAG_FRAMERATE_MUST_MATCH, nSamplesPerSec)
VERIFY_FORMAT_FLAG(FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH, wBitsPerSample)
#undef VERIFY_FORMAT_FLAG
if ( (fapo->base.m_pRegistrationProperties->Flags & FAPO_FLAG_BUFFERCOUNT_MUST_MATCH) &&
(InputLockedParameterCount != OutputLockedParameterCount) )
{
return FAUDIO_E_INVALID_ARG;
}
/* Allocate volume meter arrays */
fapo->channels = pInputLockedParameters->pFormat->nChannels;
levels[0].pPeakLevels = (float*) fapo->base.pMalloc(
fapo->channels * sizeof(float) * 6
);
FAudio_zero(levels[0].pPeakLevels, fapo->channels * sizeof(float) * 6);
levels[0].pRMSLevels = levels[0].pPeakLevels + fapo->channels;
levels[1].pPeakLevels = levels[0].pPeakLevels + (fapo->channels * 2);
levels[1].pRMSLevels = levels[0].pPeakLevels + (fapo->channels * 3);
levels[2].pPeakLevels = levels[0].pPeakLevels + (fapo->channels * 4);
levels[2].pRMSLevels = levels[0].pPeakLevels + (fapo->channels * 5);
fapo->base.m_fIsLocked = 1;
return 0;
}
void FAudioFXVolumeMeter_UnlockForProcess(FAudioFXVolumeMeter *fapo)
{
FAudioFXVolumeMeterLevels *levels = (FAudioFXVolumeMeterLevels*)
fapo->base.m_pParameterBlocks;
fapo->base.pFree(levels[0].pPeakLevels);
fapo->base.m_fIsLocked = 0;
}
void FAudioFXVolumeMeter_Process(
FAudioFXVolumeMeter *fapo,
uint32_t InputProcessParameterCount,
const FAPOProcessBufferParameters* pInputProcessParameters,
uint32_t OutputProcessParameterCount,
FAPOProcessBufferParameters* pOutputProcessParameters,
int32_t IsEnabled
) {
float peak;
float total;
float *buffer;
uint32_t i, j;
FAudioFXVolumeMeterLevels *levels = (FAudioFXVolumeMeterLevels*)
FAPOBase_BeginProcess(&fapo->base);
/* TODO: This could probably be SIMD-ified... */
for (i = 0; i < fapo->channels; i += 1)
{
peak = 0.0f;
total = 0.0f;
buffer = ((float*) pInputProcessParameters->pBuffer) + i;
for (j = 0; j < pInputProcessParameters->ValidFrameCount; j += 1, buffer += fapo->channels)
{
const float sampleAbs = FAudio_fabsf(*buffer);
if (sampleAbs > peak)
{
peak = sampleAbs;
}
total += (*buffer) * (*buffer);
}
levels->pPeakLevels[i] = peak;
levels->pRMSLevels[i] = FAudio_sqrtf(
total / pInputProcessParameters->ValidFrameCount
);
}
FAPOBase_EndProcess(&fapo->base);
}
void FAudioFXVolumeMeter_GetParameters(
FAudioFXVolumeMeter *fapo,
FAudioFXVolumeMeterLevels *pParameters,
uint32_t ParameterByteSize
) {
FAudioFXVolumeMeterLevels *levels = (FAudioFXVolumeMeterLevels*)
fapo->base.m_pCurrentParameters;
FAudio_assert(ParameterByteSize == sizeof(FAudioFXVolumeMeterLevels));
FAudio_assert(pParameters->ChannelCount == fapo->channels);
/* Copy what's current as of the last Process */
if (pParameters->pPeakLevels != NULL)
{
FAudio_memcpy(
pParameters->pPeakLevels,
levels->pPeakLevels,
fapo->channels * sizeof(float)
);
}
if (pParameters->pRMSLevels != NULL)
{
FAudio_memcpy(
pParameters->pRMSLevels,
levels->pRMSLevels,
fapo->channels * sizeof(float)
);
}
}
void FAudioFXVolumeMeter_Free(void* fapo)
{
FAudioFXVolumeMeter *volumemeter = (FAudioFXVolumeMeter*) fapo;
volumemeter->base.pFree(volumemeter->base.m_pParameterBlocks);
volumemeter->base.pFree(fapo);
}
/* Public API */
uint32_t FAudioCreateVolumeMeter(FAPO** ppApo, uint32_t Flags)
{
return FAudioCreateVolumeMeterWithCustomAllocatorEXT(
ppApo,
Flags,
FAudio_malloc,
FAudio_free,
FAudio_realloc
);
}
uint32_t FAudioCreateVolumeMeterWithCustomAllocatorEXT(
FAPO** ppApo,
uint32_t Flags,
FAudioMallocFunc customMalloc,
FAudioFreeFunc customFree,
FAudioReallocFunc customRealloc
) {
/* Allocate... */
FAudioFXVolumeMeter *result = (FAudioFXVolumeMeter*) customMalloc(
sizeof(FAudioFXVolumeMeter)
);
uint8_t *params = (uint8_t*) customMalloc(
sizeof(FAudioFXVolumeMeterLevels) * 3
);
FAudio_zero(params, sizeof(FAudioFXVolumeMeterLevels) * 3);
/* Initialize... */
FAudio_memcpy(
&VolumeMeterProperties.clsid,
&FAudioFX_CLSID_AudioVolumeMeter,
sizeof(FAudioGUID)
);
CreateFAPOBaseWithCustomAllocatorEXT(
&result->base,
&VolumeMeterProperties,
params,
sizeof(FAudioFXVolumeMeterLevels),
1,
customMalloc,
customFree,
customRealloc
);
/* Function table... */
result->base.base.LockForProcess = (LockForProcessFunc)
FAudioFXVolumeMeter_LockForProcess;
result->base.base.UnlockForProcess = (UnlockForProcessFunc)
FAudioFXVolumeMeter_UnlockForProcess;
result->base.base.Process = (ProcessFunc)
FAudioFXVolumeMeter_Process;
result->base.base.GetParameters = (GetParametersFunc)
FAudioFXVolumeMeter_GetParameters;
result->base.Destructor = FAudioFXVolumeMeter_Free;
/* Finally. */
*ppApo = &result->base.base;
return 0;
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,913 @@
/* 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>
*
*/
#include "FAudio.h"
#include "FAPOBase.h"
#include <stdarg.h>
#ifdef FAUDIO_WIN32_PLATFORM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <assert.h>
#include <inttypes.h>
#include <windef.h>
#include <winbase.h>
#define FAudio_malloc malloc
#define FAudio_realloc realloc
#define FAudio_free free
#define FAudio_alloca(x) alloca(x)
#define FAudio_dealloca(x) (void)(x)
#define FAudio_zero(ptr, size) memset(ptr, '\0', size)
#define FAudio_memset(ptr, val, size) memset(ptr, val, size)
#define FAudio_memcpy(dst, src, size) memcpy(dst, src, size)
#define FAudio_memmove(dst, src, size) memmove(dst, src, size)
#define FAudio_memcmp(ptr1, ptr2, size) memcmp(ptr1, ptr2, size)
#define FAudio_strlen(ptr) strlen(ptr)
#define FAudio_strcmp(str1, str2) strcmp(str1, str2)
#define FAudio_strncmp(str1, str2, size) strncmp(str1, str2, size)
#define FAudio_strlcpy(ptr1, ptr2, size) lstrcpynA(ptr1, ptr2, size)
#define FAudio_pow(x, y) pow(x, y)
#define FAudio_log(x) log(x)
#define FAudio_log10(x) log10(x)
#define FAudio_sin(x) sin(x)
#define FAudio_cos(x) cos(x)
#define FAudio_tan(x) tan(x)
#define FAudio_acos(x) acos(x)
#define FAudio_ceil(x) ceil(x)
#define FAudio_floor(x) floor(x)
#define FAudio_abs(x) abs(x)
#define FAudio_ldexp(v, e) ldexp(v, e)
#define FAudio_exp(x) exp(x)
#define FAudio_cosf(x) cosf(x)
#define FAudio_sinf(x) sinf(x)
#define FAudio_sqrtf(x) sqrtf(x)
#define FAudio_acosf(x) acosf(x)
#define FAudio_atan2f(y, x) atan2f(y, x)
#define FAudio_fabsf(x) fabsf(x)
#define FAudio_qsort qsort
#define FAudio_assert assert
#define FAudio_snprintf snprintf
#define FAudio_vsnprintf vsnprintf
#define FAudio_getenv getenv
#define FAudio_PRIu64 PRIu64
#define FAudio_PRIx64 PRIx64
extern void FAudio_Log(char const *msg);
/* FIXME: Assuming little-endian! */
#define FAudio_swap16LE(x) (x)
#define FAudio_swap16BE(x) \
((x >> 8) & 0x00FF) | \
((x << 8) & 0xFF00)
#define FAudio_swap32LE(x) (x)
#define FAudio_swap32BE(x) \
((x >> 24) & 0x000000FF) | \
((x >> 8) & 0x0000FF00) | \
((x << 8) & 0x00FF0000) | \
((x << 24) & 0xFF000000)
#define FAudio_swap64LE(x) (x)
#define FAudio_swap64BE(x) \
((x >> 32) & 0x00000000000000FF) | \
((x >> 24) & 0x000000000000FF00) | \
((x >> 16) & 0x0000000000FF0000) | \
((x >> 8) & 0x00000000FF000000) | \
((x << 8) & 0x000000FF00000000) | \
((x << 16) & 0x0000FF0000000000) | \
((x << 24) & 0x00FF000000000000) | \
((x << 32) & 0xFF00000000000000)
#else
#include <SDL_stdinc.h>
#include <SDL_assert.h>
#include <SDL_endian.h>
#include <SDL_log.h>
#define FAudio_malloc SDL_malloc
#define FAudio_realloc SDL_realloc
#define FAudio_free SDL_free
#define FAudio_alloca(x) SDL_stack_alloc(uint8_t, x)
#define FAudio_dealloca(x) SDL_stack_free(x)
#define FAudio_zero(ptr, size) SDL_memset(ptr, '\0', size)
#define FAudio_memset(ptr, val, size) SDL_memset(ptr, val, size)
#define FAudio_memcpy(dst, src, size) SDL_memcpy(dst, src, size)
#define FAudio_memmove(dst, src, size) SDL_memmove(dst, src, size)
#define FAudio_memcmp(ptr1, ptr2, size) SDL_memcmp(ptr1, ptr2, size)
#define FAudio_strlen(ptr) SDL_strlen(ptr)
#define FAudio_strcmp(str1, str2) SDL_strcmp(str1, str2)
#define FAudio_strncmp(str1, str2, size) SDL_strncmp(str1, str1, size)
#define FAudio_strlcpy(ptr1, ptr2, size) SDL_strlcpy(ptr1, ptr2, size)
#define FAudio_pow(x, y) SDL_pow(x, y)
#define FAudio_log(x) SDL_log(x)
#define FAudio_log10(x) SDL_log10(x)
#define FAudio_sin(x) SDL_sin(x)
#define FAudio_cos(x) SDL_cos(x)
#define FAudio_tan(x) SDL_tan(x)
#define FAudio_acos(x) SDL_acos(x)
#define FAudio_ceil(x) SDL_ceil(x)
#define FAudio_floor(x) SDL_floor(x)
#define FAudio_abs(x) SDL_abs(x)
#define FAudio_ldexp(v, e) SDL_scalbn(v, e)
#define FAudio_exp(x) SDL_exp(x)
#define FAudio_cosf(x) SDL_cosf(x)
#define FAudio_sinf(x) SDL_sinf(x)
#define FAudio_sqrtf(x) SDL_sqrtf(x)
#define FAudio_acosf(x) SDL_acosf(x)
#define FAudio_atan2f(y, x) SDL_atan2f(y, x)
#define FAudio_fabsf(x) SDL_fabsf(x)
#define FAudio_qsort SDL_qsort
#ifdef FAUDIO_LOG_ASSERTIONS
#define FAudio_assert(condition) \
{ \
static uint8_t logged = 0; \
if (!(condition) && !logged) \
{ \
SDL_Log("Assertion failed: %s", #condition); \
logged = 1; \
} \
}
#else
#define FAudio_assert SDL_assert
#endif
#define FAudio_snprintf SDL_snprintf
#define FAudio_vsnprintf SDL_vsnprintf
#define FAudio_Log(msg) SDL_Log("%s", msg)
#define FAudio_getenv SDL_getenv
#define FAudio_PRIu64 SDL_PRIu64
#define FAudio_PRIx64 SDL_PRIx64
#define FAudio_swap16LE(x) SDL_SwapLE16(x)
#define FAudio_swap16BE(x) SDL_SwapBE16(x)
#define FAudio_swap32LE(x) SDL_SwapLE32(x)
#define FAudio_swap32BE(x) SDL_SwapBE32(x)
#define FAudio_swap64LE(x) SDL_SwapLE64(x)
#define FAudio_swap64BE(x) SDL_SwapBE64(x)
#endif
/* Easy Macros */
#define FAudio_min(val1, val2) \
(val1 < val2 ? val1 : val2)
#define FAudio_max(val1, val2) \
(val1 > val2 ? val1 : val2)
#define FAudio_clamp(val, min, max) \
(val > max ? max : (val < min ? min : val))
/* Windows/Visual Studio cruft */
#ifdef _WIN32
#ifdef __cplusplus
/* C++ should have `inline`, but not `restrict` */
#define restrict
#else
#define inline __inline
#if defined(_MSC_VER)
#if (_MSC_VER >= 1700) /* VS2012+ */
#define restrict __restrict
#else /* VS2010- */
#define restrict
#endif
#else
#define restrict
#endif
#endif
#endif
/* C++ does not have restrict (though VS2012+ does have __restrict) */
#if defined(__cplusplus) && !defined(restrict)
#define restrict
#endif
/* Threading Types */
typedef void* FAudioThread;
typedef void* FAudioMutex;
typedef int32_t (FAUDIOCALL * FAudioThreadFunc)(void* data);
typedef enum FAudioThreadPriority
{
FAUDIO_THREAD_PRIORITY_LOW,
FAUDIO_THREAD_PRIORITY_NORMAL,
FAUDIO_THREAD_PRIORITY_HIGH,
} FAudioThreadPriority;
/* Linked Lists */
typedef struct LinkedList LinkedList;
struct LinkedList
{
void* entry;
LinkedList *next;
};
void LinkedList_AddEntry(
LinkedList **start,
void* toAdd,
FAudioMutex lock,
FAudioMallocFunc pMalloc
);
void LinkedList_PrependEntry(
LinkedList **start,
void* toAdd,
FAudioMutex lock,
FAudioMallocFunc pMalloc
);
void LinkedList_RemoveEntry(
LinkedList **start,
void* toRemove,
FAudioMutex lock,
FAudioFreeFunc pFree
);
/* Internal FAudio Types */
typedef enum FAudioVoiceType
{
FAUDIO_VOICE_SOURCE,
FAUDIO_VOICE_SUBMIX,
FAUDIO_VOICE_MASTER
} FAudioVoiceType;
typedef struct FAudioBufferEntry FAudioBufferEntry;
struct FAudioBufferEntry
{
FAudioBuffer buffer;
FAudioBufferWMA bufferWMA;
FAudioBufferEntry *next;
};
typedef void (FAUDIOCALL * FAudioDecodeCallback)(
FAudioVoice *voice,
FAudioBuffer *buffer, /* Buffer to decode */
float *decodeCache, /* Decode into here */
uint32_t samples /* Samples to decode */
);
typedef void (FAUDIOCALL * FAudioResampleCallback)(
float *restrict dCache,
float *restrict resampleCache,
uint64_t *resampleOffset,
uint64_t resampleStep,
uint64_t toResample,
uint8_t channels
);
typedef void (FAUDIOCALL * FAudioMixCallback)(
uint32_t toMix,
uint32_t srcChans,
uint32_t dstChans,
float *restrict srcData,
float *restrict dstData,
float *restrict coefficients
);
typedef float FAudioFilterState[4];
/* Operation Sets, original implementation by Tyler Glaiel */
typedef struct FAudio_OPERATIONSET_Operation FAudio_OPERATIONSET_Operation;
void FAudio_OPERATIONSET_Commit(FAudio *audio, uint32_t OperationSet);
void FAudio_OPERATIONSET_CommitAll(FAudio *audio);
void FAudio_OPERATIONSET_Execute(FAudio *audio);
void FAudio_OPERATIONSET_ClearAll(FAudio *audio);
void FAudio_OPERATIONSET_ClearAllForVoice(FAudioVoice *voice);
void FAudio_OPERATIONSET_QueueEnableEffect(
FAudioVoice *voice,
uint32_t EffectIndex,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueDisableEffect(
FAudioVoice *voice,
uint32_t EffectIndex,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueSetEffectParameters(
FAudioVoice *voice,
uint32_t EffectIndex,
const void *pParameters,
uint32_t ParametersByteSize,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueSetFilterParameters(
FAudioVoice *voice,
const FAudioFilterParameters *pParameters,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueSetOutputFilterParameters(
FAudioVoice *voice,
FAudioVoice *pDestinationVoice,
const FAudioFilterParameters *pParameters,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueSetVolume(
FAudioVoice *voice,
float Volume,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueSetChannelVolumes(
FAudioVoice *voice,
uint32_t Channels,
const float *pVolumes,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueSetOutputMatrix(
FAudioVoice *voice,
FAudioVoice *pDestinationVoice,
uint32_t SourceChannels,
uint32_t DestinationChannels,
const float *pLevelMatrix,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueStart(
FAudioSourceVoice *voice,
uint32_t Flags,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueStop(
FAudioSourceVoice *voice,
uint32_t Flags,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueExitLoop(
FAudioSourceVoice *voice,
uint32_t OperationSet
);
void FAudio_OPERATIONSET_QueueSetFrequencyRatio(
FAudioSourceVoice *voice,
float Ratio,
uint32_t OperationSet
);
/* Public FAudio Types */
struct FAudio
{
uint8_t version;
uint8_t active;
uint32_t refcount;
uint32_t initFlags;
uint32_t updateSize;
FAudioMasteringVoice *master;
LinkedList *sources;
LinkedList *submixes;
LinkedList *callbacks;
FAudioMutex sourceLock;
FAudioMutex submixLock;
FAudioMutex callbackLock;
FAudioMutex operationLock;
FAudioWaveFormatExtensible mixFormat;
FAudio_OPERATIONSET_Operation *queuedOperations;
FAudio_OPERATIONSET_Operation *committedOperations;
/* Used to prevent destroying an active voice */
FAudioSourceVoice *processingSource;
/* Temp storage for processing, interleaved PCM32F */
#define EXTRA_DECODE_PADDING 2
uint32_t decodeSamples;
uint32_t resampleSamples;
uint32_t effectChainSamples;
float *decodeCache;
float *resampleCache;
float *effectChainCache;
/* Allocator callbacks */
FAudioMallocFunc pMalloc;
FAudioFreeFunc pFree;
FAudioReallocFunc pRealloc;
/* EngineProcedureEXT */
void *clientEngineUser;
FAudioEngineProcedureEXT pClientEngineProc;
#ifndef FAUDIO_DISABLE_DEBUGCONFIGURATION
/* Debug Information */
FAudioDebugConfiguration debug;
#endif /* FAUDIO_DISABLE_DEBUGCONFIGURATION */
/* Platform opaque pointer */
void *platform;
};
struct FAudioVoice
{
FAudio *audio;
uint32_t flags;
FAudioVoiceType type;
FAudioVoiceSends sends;
float **sendCoefficients;
float **mixCoefficients;
FAudioMixCallback *sendMix;
FAudioFilterParameters *sendFilter;
FAudioFilterState **sendFilterState;
struct
{
FAPOBufferFlags state;
uint32_t count;
FAudioEffectDescriptor *desc;
void **parameters;
uint32_t *parameterSizes;
uint8_t *parameterUpdates;
uint8_t *inPlaceProcessing;
} effects;
FAudioFilterParameters filter;
FAudioFilterState *filterState;
FAudioMutex sendLock;
FAudioMutex effectLock;
FAudioMutex filterLock;
float volume;
float *channelVolume;
uint32_t outputChannels;
FAudioMutex volumeLock;
FAUDIONAMELESS union
{
struct
{
/* Sample storage */
uint32_t decodeSamples;
uint32_t resampleSamples;
/* Resampler */
float resampleFreq;
uint64_t resampleStep;
uint64_t resampleOffset;
uint64_t curBufferOffsetDec;
uint32_t curBufferOffset;
/* WMA decoding */
#ifdef HAVE_WMADEC
struct FAudioWMADEC *wmadec;
#endif /* HAVE_WMADEC*/
/* Read-only */
float maxFreqRatio;
FAudioWaveFormatEx *format;
FAudioDecodeCallback decode;
FAudioResampleCallback resample;
FAudioVoiceCallback *callback;
/* Dynamic */
uint8_t active;
float freqRatio;
uint8_t newBuffer;
uint64_t totalSamples;
FAudioBufferEntry *bufferList;
FAudioBufferEntry *flushList;
FAudioMutex bufferLock;
} src;
struct
{
/* Sample storage */
uint32_t inputSamples;
uint32_t outputSamples;
float *inputCache;
uint64_t resampleStep;
FAudioResampleCallback resample;
/* Read-only */
uint32_t inputChannels;
uint32_t inputSampleRate;
uint32_t processingStage;
} mix;
struct
{
/* Output stream, allocated by Platform */
float *output;
/* Needed when inputChannels != outputChannels */
float *effectCache;
/* Read-only */
uint32_t inputChannels;
uint32_t inputSampleRate;
} master;
};
};
/* Internal Functions */
void FAudio_INTERNAL_InsertSubmixSorted(
LinkedList **start,
FAudioSubmixVoice *toAdd,
FAudioMutex lock,
FAudioMallocFunc pMalloc
);
void FAudio_INTERNAL_UpdateEngine(FAudio *audio, float *output);
void FAudio_INTERNAL_ResizeDecodeCache(FAudio *audio, uint32_t size);
void FAudio_INTERNAL_AllocEffectChain(
FAudioVoice *voice,
const FAudioEffectChain *pEffectChain
);
void FAudio_INTERNAL_FreeEffectChain(FAudioVoice *voice);
uint32_t FAudio_INTERNAL_VoiceOutputFrequency(
FAudioVoice *voice,
const FAudioVoiceSends *pSendList
);
extern const float FAUDIO_INTERNAL_MATRIX_DEFAULTS[8][8][64];
/* Debug */
#ifdef FAUDIO_DISABLE_DEBUGCONFIGURATION
#define LOG_ERROR(engine, fmt, ...)
#define LOG_WARNING(engine, fmt, ...)
#define LOG_INFO(engine, fmt, ...)
#define LOG_DETAIL(engine, fmt, ...)
#define LOG_API_ENTER(engine)
#define LOG_API_EXIT(engine)
#define LOG_FUNC_ENTER(engine)
#define LOG_FUNC_EXIT(engine)
/* TODO: LOG_TIMING */
#define LOG_MUTEX_CREATE(engine, mutex)
#define LOG_MUTEX_DESTROY(engine, mutex)
#define LOG_MUTEX_LOCK(engine, mutex)
#define LOG_MUTEX_UNLOCK(engine, mutex)
/* TODO: LOG_MEMORY */
/* TODO: LOG_STREAMING */
#define LOG_FORMAT(engine, waveFormat)
#else
#if defined(_MSC_VER)
/* VC doesn't support __attribute__ at all, and there's no replacement for format. */
void WINAPIV FAudio_INTERNAL_debug(
FAudio *audio,
const char *file,
uint32_t line,
const char *func,
const char *fmt,
...
);
#if _MSC_VER <= 1700 /* <=2012 also doesn't support __func__ */
#define __func__ __FUNCTION__
#endif
#else
void WINAPIV FAudio_INTERNAL_debug(
FAudio *audio,
const char *file,
uint32_t line,
const char *func,
const char *fmt,
...
) __attribute__((format(printf,5,6)));
#endif
void FAudio_INTERNAL_debug_fmt(
FAudio *audio,
const char *file,
uint32_t line,
const char *func,
const FAudioWaveFormatEx *fmt
);
#define PRINT_DEBUG(engine, cond, type, fmt, ...) \
if (engine->debug.TraceMask & FAUDIO_LOG_##cond) \
{ \
FAudio_INTERNAL_debug( \
engine, \
__FILE__, \
__LINE__, \
__func__, \
type ": " fmt, \
__VA_ARGS__ \
); \
}
#define LOG_ERROR(engine, fmt, ...) PRINT_DEBUG(engine, ERRORS, "ERROR", fmt, __VA_ARGS__)
#define LOG_WARNING(engine, fmt, ...) PRINT_DEBUG(engine, WARNINGS, "WARNING", fmt, __VA_ARGS__)
#define LOG_INFO(engine, fmt, ...) PRINT_DEBUG(engine, INFO, "INFO", fmt, __VA_ARGS__)
#define LOG_DETAIL(engine, fmt, ...) PRINT_DEBUG(engine, DETAIL, "DETAIL", fmt, __VA_ARGS__)
#define LOG_API_ENTER(engine) PRINT_DEBUG(engine, API_CALLS, "API Enter", "%s", __func__)
#define LOG_API_EXIT(engine) PRINT_DEBUG(engine, API_CALLS, "API Exit", "%s", __func__)
#define LOG_FUNC_ENTER(engine) PRINT_DEBUG(engine, FUNC_CALLS, "FUNC Enter", "%s", __func__)
#define LOG_FUNC_EXIT(engine) PRINT_DEBUG(engine, FUNC_CALLS, "FUNC Exit", "%s", __func__)
/* TODO: LOG_TIMING */
#define LOG_MUTEX_CREATE(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Create", "%p", mutex)
#define LOG_MUTEX_DESTROY(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Destroy", "%p", mutex)
#define LOG_MUTEX_LOCK(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Lock", "%p", mutex)
#define LOG_MUTEX_UNLOCK(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Unlock", "%p", mutex)
/* TODO: LOG_MEMORY */
/* TODO: LOG_STREAMING */
#define LOG_FORMAT(engine, waveFormat) \
if (engine->debug.TraceMask & FAUDIO_LOG_INFO) \
{ \
FAudio_INTERNAL_debug_fmt( \
engine, \
__FILE__, \
__LINE__, \
__func__, \
waveFormat \
); \
}
#endif /* FAUDIO_DISABLE_DEBUGCONFIGURATION */
/* FAPOFX Creators */
#define CREATE_FAPOFX_FUNC(effect) \
extern uint32_t FAPOFXCreate##effect( \
FAPO **pEffect, \
const void *pInitData, \
uint32_t InitDataByteSize, \
FAudioMallocFunc customMalloc, \
FAudioFreeFunc customFree, \
FAudioReallocFunc customRealloc, \
uint8_t legacy \
);
CREATE_FAPOFX_FUNC(EQ)
CREATE_FAPOFX_FUNC(MasteringLimiter)
CREATE_FAPOFX_FUNC(Reverb)
CREATE_FAPOFX_FUNC(Echo)
#undef CREATE_FAPOFX_FUNC
/* SIMD Stuff */
/* Callbacks declared as functions (rather than function pointers) are
* scalar-only, for now. SIMD versions should be possible for these.
*/
extern void (*FAudio_INTERNAL_Convert_U8_To_F32)(
const uint8_t *restrict src,
float *restrict dst,
uint32_t len
);
extern void (*FAudio_INTERNAL_Convert_S16_To_F32)(
const int16_t *restrict src,
float *restrict dst,
uint32_t len
);
extern void (*FAudio_INTERNAL_Convert_S32_To_F32)(
const int32_t *restrict src,
float *restrict dst,
uint32_t len
);
extern FAudioResampleCallback FAudio_INTERNAL_ResampleMono;
extern FAudioResampleCallback FAudio_INTERNAL_ResampleStereo;
extern void FAudio_INTERNAL_ResampleGeneric(
float *restrict dCache,
float *restrict resampleCache,
uint64_t *resampleOffset,
uint64_t resampleStep,
uint64_t toResample,
uint8_t channels
);
extern void (*FAudio_INTERNAL_Amplify)(
float *output,
uint32_t totalSamples,
float volume
);
extern FAudioMixCallback FAudio_INTERNAL_Mix_Generic;
#define MIX_FUNC(type) \
extern void FAudio_INTERNAL_Mix_##type##_Scalar( \
uint32_t toMix, \
uint32_t srcChans, \
uint32_t dstChans, \
float *restrict srcData, \
float *restrict dstData, \
float *restrict coefficients \
);
MIX_FUNC(Generic)
MIX_FUNC(1in_1out)
MIX_FUNC(1in_2out)
MIX_FUNC(1in_6out)
MIX_FUNC(1in_8out)
MIX_FUNC(2in_1out)
MIX_FUNC(2in_2out)
MIX_FUNC(2in_6out)
MIX_FUNC(2in_8out)
#undef MIX_FUNC
void FAudio_INTERNAL_InitSIMDFunctions(uint8_t hasSSE2, uint8_t hasNEON);
/* Decoders */
#define DECODE_FUNC(type) \
extern void FAudio_INTERNAL_Decode##type( \
FAudioVoice *voice, \
FAudioBuffer *buffer, \
float *decodeCache, \
uint32_t samples \
);
DECODE_FUNC(PCM8)
DECODE_FUNC(PCM16)
DECODE_FUNC(PCM24)
DECODE_FUNC(PCM32)
DECODE_FUNC(PCM32F)
DECODE_FUNC(MonoMSADPCM)
DECODE_FUNC(StereoMSADPCM)
DECODE_FUNC(WMAERROR)
#undef DECODE_FUNC
/* WMA decoding */
#ifdef HAVE_WMADEC
uint32_t FAudio_WMADEC_init(FAudioSourceVoice *pSourceVoice, uint32_t type);
void FAudio_WMADEC_free(FAudioSourceVoice *voice);
void FAudio_WMADEC_end_buffer(FAudioSourceVoice *voice);
#endif /* HAVE_WMADEC */
/* Platform Functions */
void FAudio_PlatformAddRef(void);
void FAudio_PlatformRelease(void);
void FAudio_PlatformInit(
FAudio *audio,
uint32_t flags,
uint32_t deviceIndex,
FAudioWaveFormatExtensible *mixFormat,
uint32_t *updateSize,
void** platformDevice
);
void FAudio_PlatformQuit(void* platformDevice);
uint32_t FAudio_PlatformGetDeviceCount(void);
uint32_t FAudio_PlatformGetDeviceDetails(
uint32_t index,
FAudioDeviceDetails *details
);
/* Threading */
FAudioThread FAudio_PlatformCreateThread(
FAudioThreadFunc func,
const char *name,
void* data
);
void FAudio_PlatformWaitThread(FAudioThread thread, int32_t *retval);
void FAudio_PlatformThreadPriority(FAudioThreadPriority priority);
uint64_t FAudio_PlatformGetThreadID(void);
FAudioMutex FAudio_PlatformCreateMutex(void);
void FAudio_PlatformDestroyMutex(FAudioMutex mutex);
void FAudio_PlatformLockMutex(FAudioMutex mutex);
void FAudio_PlatformUnlockMutex(FAudioMutex mutex);
void FAudio_sleep(uint32_t ms);
/* Time */
uint32_t FAudio_timems(void);
/* WaveFormatExtensible Helpers */
static inline uint32_t GetMask(uint16_t channels)
{
if (channels == 1) return SPEAKER_MONO;
if (channels == 2) return SPEAKER_STEREO;
if (channels == 3) return SPEAKER_2POINT1;
if (channels == 4) return SPEAKER_QUAD;
if (channels == 5) return SPEAKER_4POINT1;
if (channels == 6) return SPEAKER_5POINT1;
if (channels == 8) return SPEAKER_7POINT1;
FAudio_assert(0 && "Unrecognized speaker layout!");
return 0;
}
static inline void WriteWaveFormatExtensible(
FAudioWaveFormatExtensible *fmt,
int channels,
int samplerate,
const FAudioGUID *subformat
) {
FAudio_assert(fmt != NULL);
fmt->Format.wBitsPerSample = 32;
fmt->Format.wFormatTag = FAUDIO_FORMAT_EXTENSIBLE;
fmt->Format.nChannels = channels;
fmt->Format.nSamplesPerSec = samplerate;
fmt->Format.nBlockAlign = (
fmt->Format.nChannels *
(fmt->Format.wBitsPerSample / 8)
);
fmt->Format.nAvgBytesPerSec = (
fmt->Format.nSamplesPerSec *
fmt->Format.nBlockAlign
);
fmt->Format.cbSize = sizeof(FAudioWaveFormatExtensible) - sizeof(FAudioWaveFormatEx);
fmt->Samples.wValidBitsPerSample = 32;
fmt->dwChannelMask = GetMask(fmt->Format.nChannels);
FAudio_memcpy(&fmt->SubFormat, subformat, sizeof(FAudioGUID));
}
/* Resampling */
/* Okay, so here's what all this fixed-point goo is for:
*
* Inevitably you're going to run into weird sample rates,
* both from WaveBank data and from pitch shifting changes.
*
* How we deal with this is by calculating a fixed "step"
* value that steps from sample to sample at the speed needed
* to get the correct output sample rate, and the offset
* is stored as separate integer and fraction values.
*
* This allows us to do weird fractional steps between samples,
* while at the same time not letting it drift off into death
* thanks to floating point madness.
*
* Steps are stored in fixed-point with 32 bits for the fraction:
*
* 00000000000000000000000000000000 00000000000000000000000000000000
* ^ Integer block (32) ^ Fraction block (32)
*
* For example, to get 1.5:
* 00000000000000000000000000000001 10000000000000000000000000000000
*
* The Integer block works exactly like you'd expect.
* The Fraction block is divided by the Integer's "One" value.
* So, the above Fraction represented visually...
* 1 << 31
* -------
* 1 << 32
* ... which, simplified, is...
* 1 << 0
* ------
* 1 << 1
* ... in other words, 1 / 2, or 0.5.
*/
#define FIXED_PRECISION 32
#define FIXED_ONE (1LL << FIXED_PRECISION)
/* Quick way to drop parts */
#define FIXED_FRACTION_MASK (FIXED_ONE - 1)
#define FIXED_INTEGER_MASK ~FIXED_FRACTION_MASK
/* Helper macros to convert fixed to float */
#define DOUBLE_TO_FIXED(dbl) \
((uint64_t) (dbl * FIXED_ONE + 0.5))
#define FIXED_TO_DOUBLE(fxd) ( \
(double) (fxd >> FIXED_PRECISION) + /* Integer part */ \
((fxd & FIXED_FRACTION_MASK) * (1.0 / FIXED_ONE)) /* Fraction part */ \
)
#define FIXED_TO_FLOAT(fxd) ( \
(float) (fxd >> FIXED_PRECISION) + /* Integer part */ \
((fxd & FIXED_FRACTION_MASK) * (1.0f / FIXED_ONE)) /* Fraction part */ \
)
#ifdef FAUDIO_DUMP_VOICES
/* File writing structure */
typedef size_t (FAUDIOCALL * FAudio_writefunc)(
void *data,
const void *src,
size_t size,
size_t count
);
typedef size_t (FAUDIOCALL * FAudio_sizefunc)(
void *data
);
typedef struct FAudioIOStreamOut
{
void *data;
FAudio_readfunc read;
FAudio_writefunc write;
FAudio_seekfunc seek;
FAudio_sizefunc size;
FAudio_closefunc close;
void *lock;
} FAudioIOStreamOut;
FAudioIOStreamOut* FAudio_fopen_out(const char *path, const char *mode);
void FAudio_close_out(FAudioIOStreamOut *io);
#endif /* FAUDIO_DUMP_VOICES */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,777 @@
/* 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>
*
*/
/* FAudio_operationset.c originally written by Tyler Glaiel */
#include "FAudio_internal.h"
/* Core OperationSet Types */
typedef enum FAudio_OPERATIONSET_Type
{
FAUDIOOP_ENABLEEFFECT,
FAUDIOOP_DISABLEEFFECT,
FAUDIOOP_SETEFFECTPARAMETERS,
FAUDIOOP_SETFILTERPARAMETERS,
FAUDIOOP_SETOUTPUTFILTERPARAMETERS,
FAUDIOOP_SETVOLUME,
FAUDIOOP_SETCHANNELVOLUMES,
FAUDIOOP_SETOUTPUTMATRIX,
FAUDIOOP_START,
FAUDIOOP_STOP,
FAUDIOOP_EXITLOOP,
FAUDIOOP_SETFREQUENCYRATIO
} FAudio_OPERATIONSET_Type;
struct FAudio_OPERATIONSET_Operation
{
FAudio_OPERATIONSET_Type Type;
uint32_t OperationSet;
FAudioVoice *Voice;
union
{
struct
{
uint32_t EffectIndex;
} EnableEffect;
struct
{
uint32_t EffectIndex;
} DisableEffect;
struct
{
uint32_t EffectIndex;
void *pParameters;
uint32_t ParametersByteSize;
} SetEffectParameters;
struct
{
FAudioFilterParameters Parameters;
} SetFilterParameters;
struct
{
FAudioVoice *pDestinationVoice;
FAudioFilterParameters Parameters;
} SetOutputFilterParameters;
struct
{
float Volume;
} SetVolume;
struct
{
uint32_t Channels;
float *pVolumes;
} SetChannelVolumes;
struct
{
FAudioVoice *pDestinationVoice;
uint32_t SourceChannels;
uint32_t DestinationChannels;
float *pLevelMatrix;
} SetOutputMatrix;
struct
{
uint32_t Flags;
} Start;
struct
{
uint32_t Flags;
} Stop;
/* No special data for ExitLoop
struct
{
} ExitLoop;
*/
struct
{
float Ratio;
} SetFrequencyRatio;
} Data;
FAudio_OPERATIONSET_Operation *next;
};
/* Used by both Commit and Clear routines */
static inline void DeleteOperation(
FAudio_OPERATIONSET_Operation *op,
FAudioFreeFunc pFree
) {
if (op->Type == FAUDIOOP_SETEFFECTPARAMETERS)
{
pFree(op->Data.SetEffectParameters.pParameters);
}
else if (op->Type == FAUDIOOP_SETCHANNELVOLUMES)
{
pFree(op->Data.SetChannelVolumes.pVolumes);
}
else if (op->Type == FAUDIOOP_SETOUTPUTMATRIX)
{
pFree(op->Data.SetOutputMatrix.pLevelMatrix);
}
pFree(op);
}
/* OperationSet Execution */
static inline void ExecuteOperation(FAudio_OPERATIONSET_Operation *op)
{
switch (op->Type)
{
case FAUDIOOP_ENABLEEFFECT:
FAudioVoice_EnableEffect(
op->Voice,
op->Data.EnableEffect.EffectIndex,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_DISABLEEFFECT:
FAudioVoice_DisableEffect(
op->Voice,
op->Data.DisableEffect.EffectIndex,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_SETEFFECTPARAMETERS:
FAudioVoice_SetEffectParameters(
op->Voice,
op->Data.SetEffectParameters.EffectIndex,
op->Data.SetEffectParameters.pParameters,
op->Data.SetEffectParameters.ParametersByteSize,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_SETFILTERPARAMETERS:
FAudioVoice_SetFilterParameters(
op->Voice,
&op->Data.SetFilterParameters.Parameters,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_SETOUTPUTFILTERPARAMETERS:
FAudioVoice_SetOutputFilterParameters(
op->Voice,
op->Data.SetOutputFilterParameters.pDestinationVoice,
&op->Data.SetOutputFilterParameters.Parameters,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_SETVOLUME:
FAudioVoice_SetVolume(
op->Voice,
op->Data.SetVolume.Volume,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_SETCHANNELVOLUMES:
FAudioVoice_SetChannelVolumes(
op->Voice,
op->Data.SetChannelVolumes.Channels,
op->Data.SetChannelVolumes.pVolumes,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_SETOUTPUTMATRIX:
FAudioVoice_SetOutputMatrix(
op->Voice,
op->Data.SetOutputMatrix.pDestinationVoice,
op->Data.SetOutputMatrix.SourceChannels,
op->Data.SetOutputMatrix.DestinationChannels,
op->Data.SetOutputMatrix.pLevelMatrix,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_START:
FAudioSourceVoice_Start(
op->Voice,
op->Data.Start.Flags,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_STOP:
FAudioSourceVoice_Stop(
op->Voice,
op->Data.Stop.Flags,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_EXITLOOP:
FAudioSourceVoice_ExitLoop(
op->Voice,
FAUDIO_COMMIT_NOW
);
break;
case FAUDIOOP_SETFREQUENCYRATIO:
FAudioSourceVoice_SetFrequencyRatio(
op->Voice,
op->Data.SetFrequencyRatio.Ratio,
FAUDIO_COMMIT_NOW
);
break;
default:
FAudio_assert(0 && "Unrecognized operation type!");
break;
}
}
void FAudio_OPERATIONSET_CommitAll(FAudio *audio)
{
FAudio_OPERATIONSET_Operation *op, *next, **committed_end;
FAudio_PlatformLockMutex(audio->operationLock);
LOG_MUTEX_LOCK(audio, audio->operationLock)
if (audio->queuedOperations == NULL)
{
FAudio_PlatformUnlockMutex(audio->operationLock);
LOG_MUTEX_UNLOCK(audio, audio->operationLock)
return;
}
committed_end = &audio->committedOperations;
while (*committed_end)
{
committed_end = &((*committed_end)->next);
}
op = audio->queuedOperations;
do
{
next = op->next;
*committed_end = op;
op->next = NULL;
committed_end = &op->next;
op = next;
} while (op != NULL);
audio->queuedOperations = NULL;
FAudio_PlatformUnlockMutex(audio->operationLock);
LOG_MUTEX_UNLOCK(audio, audio->operationLock)
}
void FAudio_OPERATIONSET_Commit(FAudio *audio, uint32_t OperationSet)
{
FAudio_OPERATIONSET_Operation *op, *next, *prev, **committed_end;
FAudio_PlatformLockMutex(audio->operationLock);
LOG_MUTEX_LOCK(audio, audio->operationLock)
if (audio->queuedOperations == NULL)
{
FAudio_PlatformUnlockMutex(audio->operationLock);
LOG_MUTEX_UNLOCK(audio, audio->operationLock)
return;
}
committed_end = &audio->committedOperations;
while (*committed_end)
{
committed_end = &((*committed_end)->next);
}
op = audio->queuedOperations;
prev = NULL;
do
{
next = op->next;
if (op->OperationSet == OperationSet)
{
if (prev == NULL) /* Start of linked list */
{
audio->queuedOperations = next;
}
else
{
prev->next = next;
}
*committed_end = op;
op->next = NULL;
committed_end = &op->next;
}
else
{
prev = op;
}
op = next;
} while (op != NULL);
FAudio_PlatformUnlockMutex(audio->operationLock);
LOG_MUTEX_UNLOCK(audio, audio->operationLock)
}
void FAudio_OPERATIONSET_Execute(FAudio *audio)
{
FAudio_OPERATIONSET_Operation *op, *next;
FAudio_PlatformLockMutex(audio->operationLock);
LOG_MUTEX_LOCK(audio, audio->operationLock)
op = audio->committedOperations;
while (op != NULL)
{
next = op->next;
ExecuteOperation(op);
DeleteOperation(op, audio->pFree);
op = next;
}
audio->committedOperations = NULL;
FAudio_PlatformUnlockMutex(audio->operationLock);
LOG_MUTEX_UNLOCK(audio, audio->operationLock)
}
/* OperationSet Compilation */
static inline FAudio_OPERATIONSET_Operation* QueueOperation(
FAudioVoice *voice,
FAudio_OPERATIONSET_Type type,
uint32_t operationSet
) {
FAudio_OPERATIONSET_Operation *latest;
FAudio_OPERATIONSET_Operation *newop = voice->audio->pMalloc(
sizeof(FAudio_OPERATIONSET_Operation)
);
newop->Type = type;
newop->Voice = voice;
newop->OperationSet = operationSet;
newop->next = NULL;
if (voice->audio->queuedOperations == NULL)
{
voice->audio->queuedOperations = newop;
}
else
{
latest = voice->audio->queuedOperations;
while (latest->next != NULL)
{
latest = latest->next;
}
latest->next = newop;
}
return newop;
}
void FAudio_OPERATIONSET_QueueEnableEffect(
FAudioVoice *voice,
uint32_t EffectIndex,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_ENABLEEFFECT,
OperationSet
);
op->Data.EnableEffect.EffectIndex = EffectIndex;
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueDisableEffect(
FAudioVoice *voice,
uint32_t EffectIndex,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_DISABLEEFFECT,
OperationSet
);
op->Data.DisableEffect.EffectIndex = EffectIndex;
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueSetEffectParameters(
FAudioVoice *voice,
uint32_t EffectIndex,
const void *pParameters,
uint32_t ParametersByteSize,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_SETEFFECTPARAMETERS,
OperationSet
);
op->Data.SetEffectParameters.EffectIndex = EffectIndex;
op->Data.SetEffectParameters.pParameters = voice->audio->pMalloc(
ParametersByteSize
);
FAudio_memcpy(
op->Data.SetEffectParameters.pParameters,
pParameters,
ParametersByteSize
);
op->Data.SetEffectParameters.ParametersByteSize = ParametersByteSize;
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueSetFilterParameters(
FAudioVoice *voice,
const FAudioFilterParameters *pParameters,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_SETFILTERPARAMETERS,
OperationSet
);
FAudio_memcpy(
&op->Data.SetFilterParameters.Parameters,
pParameters,
sizeof(FAudioFilterParameters)
);
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueSetOutputFilterParameters(
FAudioVoice *voice,
FAudioVoice *pDestinationVoice,
const FAudioFilterParameters *pParameters,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_SETOUTPUTFILTERPARAMETERS,
OperationSet
);
op->Data.SetOutputFilterParameters.pDestinationVoice = pDestinationVoice;
FAudio_memcpy(
&op->Data.SetOutputFilterParameters.Parameters,
pParameters,
sizeof(FAudioFilterParameters)
);
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueSetVolume(
FAudioVoice *voice,
float Volume,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_SETVOLUME,
OperationSet
);
op->Data.SetVolume.Volume = Volume;
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueSetChannelVolumes(
FAudioVoice *voice,
uint32_t Channels,
const float *pVolumes,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_SETCHANNELVOLUMES,
OperationSet
);
op->Data.SetChannelVolumes.Channels = Channels;
op->Data.SetChannelVolumes.pVolumes = voice->audio->pMalloc(
sizeof(float) * Channels
);
FAudio_memcpy(
op->Data.SetChannelVolumes.pVolumes,
pVolumes,
sizeof(float) * Channels
);
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueSetOutputMatrix(
FAudioVoice *voice,
FAudioVoice *pDestinationVoice,
uint32_t SourceChannels,
uint32_t DestinationChannels,
const float *pLevelMatrix,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_SETOUTPUTMATRIX,
OperationSet
);
op->Data.SetOutputMatrix.pDestinationVoice = pDestinationVoice;
op->Data.SetOutputMatrix.SourceChannels = SourceChannels;
op->Data.SetOutputMatrix.DestinationChannels = DestinationChannels;
op->Data.SetOutputMatrix.pLevelMatrix = voice->audio->pMalloc(
sizeof(float) * SourceChannels * DestinationChannels
);
FAudio_memcpy(
op->Data.SetOutputMatrix.pLevelMatrix,
pLevelMatrix,
sizeof(float) * SourceChannels * DestinationChannels
);
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueStart(
FAudioSourceVoice *voice,
uint32_t Flags,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_START,
OperationSet
);
op->Data.Start.Flags = Flags;
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueStop(
FAudioSourceVoice *voice,
uint32_t Flags,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_STOP,
OperationSet
);
op->Data.Stop.Flags = Flags;
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueExitLoop(
FAudioSourceVoice *voice,
uint32_t OperationSet
) {
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
QueueOperation(
voice,
FAUDIOOP_EXITLOOP,
OperationSet
);
/* No special data for ExitLoop */
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
void FAudio_OPERATIONSET_QueueSetFrequencyRatio(
FAudioSourceVoice *voice,
float Ratio,
uint32_t OperationSet
) {
FAudio_OPERATIONSET_Operation *op;
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
op = QueueOperation(
voice,
FAUDIOOP_SETFREQUENCYRATIO,
OperationSet
);
op->Data.SetFrequencyRatio.Ratio = Ratio;
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
/* Called when releasing the engine */
void FAudio_OPERATIONSET_ClearAll(FAudio *audio)
{
FAudio_OPERATIONSET_Operation *current, *next;
FAudio_PlatformLockMutex(audio->operationLock);
LOG_MUTEX_LOCK(audio, audio->operationLock)
current = audio->queuedOperations;
while (current != NULL)
{
next = current->next;
DeleteOperation(current, audio->pFree);
current = next;
}
audio->queuedOperations = NULL;
FAudio_PlatformUnlockMutex(audio->operationLock);
LOG_MUTEX_UNLOCK(audio, audio->operationLock)
}
/* Called when releasing a voice */
static inline void RemoveFromList(
FAudioVoice *voice,
FAudio_OPERATIONSET_Operation **list
) {
FAudio_OPERATIONSET_Operation *current, *next, *prev;
current = *list;
prev = NULL;
while (current != NULL)
{
const uint8_t baseVoice = (voice == current->Voice);
const uint8_t dstVoice = (
current->Type == FAUDIOOP_SETOUTPUTFILTERPARAMETERS &&
voice == current->Data.SetOutputFilterParameters.pDestinationVoice
) || (
current->Type == FAUDIOOP_SETOUTPUTMATRIX &&
voice == current->Data.SetOutputMatrix.pDestinationVoice
);
next = current->next;
if (baseVoice || dstVoice)
{
if (prev == NULL) /* Start of linked list */
{
*list = next;
}
else
{
prev->next = next;
}
DeleteOperation(current, voice->audio->pFree);
}
else
{
prev = current;
}
current = next;
}
}
void FAudio_OPERATIONSET_ClearAllForVoice(FAudioVoice *voice)
{
FAudio_PlatformLockMutex(voice->audio->operationLock);
LOG_MUTEX_LOCK(voice->audio, voice->audio->operationLock)
RemoveFromList(voice, &voice->audio->queuedOperations);
RemoveFromList(voice, &voice->audio->committedOperations);
FAudio_PlatformUnlockMutex(voice->audio->operationLock);
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->operationLock)
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
/* This was generated by making 8 sources and 8 submixes, then assigning each
* submix to each voice and dumping the output matrix. Terrible, but it worked!
*/
{
/* 1 x 1 */
{ 1.000000000f },
/* 1 x 2 */
{ 1.000000000f, 1.000000000f },
/* 1 x 3 */
{ 1.000000000f, 1.000000000f, 0.000000000f },
/* 1 x 4 */
{ 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f },
/* 1 x 5 */
{ 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 1 x 6 */
{ 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 1 x 7 */
{ 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 1 x 8 */
{ 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }
},
{
/* 2 x 1 */
{ 0.500000000f, 0.500000000f },
/* 2 x 2 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 2 x 3 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f },
/* 2 x 4 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 2 x 5 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 2 x 6 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 2 x 7 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 2 x 8 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }
},
{
/* 3 x 1 */
{ 0.333333343f, 0.333333343f, 0.333333343f },
/* 3 x 2 */
{ 0.800000012f, 0.000000000f, 0.200000003f, 0.000000000f, 0.800000012f, 0.200000003f },
/* 3 x 3 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 3 x 4 */
{ 0.888888896f, 0.000000000f, 0.111111112f, 0.000000000f, 0.888888896f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f },
/* 3 x 5 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 3 x 6 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 3 x 7 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 3 x 8 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }
},
{
/* 4 x 1 */
{ 0.250000000f, 0.250000000f, 0.250000000f, 0.250000000f },
/* 4 x 2 */
{ 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f },
/* 4 x 3 */
{ 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 4 x 4 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 4 x 5 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 4 x 6 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 4 x 7 */
{ 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f },
/* 4 x 8 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }
},
{
/* 5 x 1 */
{ 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f },
/* 5 x 2 */
{ 0.374222219f, 0.000000000f, 0.111111112f, 0.319111109f, 0.195555553f, 0.000000000f, 0.374222219f, 0.111111112f, 0.195555553f, 0.319111109f },
/* 5 x 3 */
{ 0.421000004f, 0.000000000f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.000000000f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f },
/* 5 x 4 */
{ 0.941176474f, 0.000000000f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.941176474f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.941176474f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.000000000f, 0.941176474f },
/* 5 x 5 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 5 x 6 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 5 x 7 */
{ 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f },
/* 5 x 8 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }
},
{
/* 6 x 1 */
{ 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f },
/* 6 x 2 */
{ 0.294545442f, 0.000000000f, 0.208181813f, 0.090909094f, 0.251818180f, 0.154545456f, 0.000000000f, 0.294545442f, 0.208181813f, 0.090909094f, 0.154545456f, 0.251818180f },
/* 6 x 3 */
{ 0.324000001f, 0.000000000f, 0.229000002f, 0.000000000f, 0.277000010f, 0.170000002f, 0.000000000f, 0.324000001f, 0.229000002f, 0.000000000f, 0.170000002f, 0.277000010f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f },
/* 6 x 4 */
{ 0.558095276f, 0.000000000f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.558095276f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.558095276f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.000000000f, 0.558095276f },
/* 6 x 5 */
{ 0.586000025f, 0.000000000f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f },
/* 6 x 6 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 6 x 7 */
{ 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f },
/* 6 x 8 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }
},
{
/* 7 x 1 */
{ 0.143142849f, 0.143142849f, 0.143142849f, 0.142857149f, 0.143142849f, 0.143142849f, 0.143142849f },
/* 7 x 2 */
{ 0.247384623f, 0.000000000f, 0.174461529f, 0.076923080f, 0.174461529f, 0.226153851f, 0.100615382f, 0.000000000f, 0.247384623f, 0.174461529f, 0.076923080f, 0.174461529f, 0.100615382f, 0.226153851f },
/* 7 x 3 */
{ 0.268000007f, 0.000000000f, 0.188999996f, 0.000000000f, 0.188999996f, 0.245000005f, 0.108999997f, 0.000000000f, 0.268000007f, 0.188999996f, 0.000000000f, 0.188999996f, 0.108999997f, 0.245000005f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 7 x 4 */
{ 0.463679999f, 0.000000000f, 0.327360004f, 0.040000003f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.463679999f, 0.327360004f, 0.040000003f, 0.000000000f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.431039989f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.000000000f, 0.431039989f },
/* 7 x 5 */
{ 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.000000000f, 0.449000001f },
/* 7 x 6 */
{ 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.568000019f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.000000000f, 0.568000019f },
/* 7 x 7 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f },
/* 7 x 8 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }
},
{
/* 8 x 1 */
{ 0.125125006f, 0.125125006f, 0.125125006f, 0.125000000f, 0.125125006f, 0.125125006f, 0.125125006f, 0.125125006f },
/* 8 x 2 */
{ 0.211866662f, 0.000000000f, 0.150266662f, 0.066666670f, 0.181066677f, 0.111066669f, 0.194133341f, 0.085866667f, 0.000000000f, 0.211866662f, 0.150266662f, 0.066666670f, 0.111066669f, 0.181066677f, 0.085866667f, 0.194133341f },
/* 8 x 3 */
{ 0.226999998f, 0.000000000f, 0.160999998f, 0.000000000f, 0.194000006f, 0.119000003f, 0.208000004f, 0.092000000f, 0.000000000f, 0.226999998f, 0.160999998f, 0.000000000f, 0.119000003f, 0.194000006f, 0.092000000f, 0.208000004f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f },
/* 8 x 4 */
{ 0.466344833f, 0.000000000f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.466344833f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.466344833f, 0.000000000f, 0.433517247f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.000000000f, 0.466344833f, 0.000000000f, 0.433517247f },
/* 8 x 5 */
{ 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f },
/* 8 x 6 */
{ 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f },
/* 8 x 7 */
{ 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.287999988f, 0.287999988f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f },
/* 8 x 8 */
{ 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }
}

406
libs/faudio/src/stb.h Normal file
View File

@ -0,0 +1,406 @@
/* stb.h - v2.32 - Sean's Tool Box -- public domain -- http://nothings.org/stb.h
no warranty is offered or implied; use this code at your own risk
This is a single header file with a bunch of useful utilities
for getting stuff done in C/C++.
Documentation: http://nothings.org/stb/stb_h.html
Unit tests: http://nothings.org/stb/stb.c
============================================================================
You MUST
#define STB_DEFINE
in EXACTLY _one_ C or C++ file that includes this header, BEFORE the
include, like this:
#define STB_DEFINE
#include "stb.h"
All other files should just #include "stb.h" without the #define.
============================================================================
Version History
2.32 stb_intcmprev, stb_uidict, fix random numbers on Linux
2.31 stb_ucharcmp
2.30 MinGW fix
2.29 attempt to fix use of swprintf()
2.28 various new functionality
2.27 test _WIN32 not WIN32 in STB_THREADS
2.26 various warning & bugfixes
2.25 various warning & bugfixes
2.24 various warning & bugfixes
2.23 fix 2.22
2.22 64-bit fixes from '!='; fix stb_sdict_copy() to have preferred name
2.21 utf-8 decoder rejects "overlong" encodings; attempted 64-bit improvements
2.20 fix to hash "copy" function--reported by someone with handle "!="
2.19 ???
2.18 stb_readdir_subdirs_mask
2.17 stb_cfg_dir
2.16 fix stb_bgio_, add stb_bgio_stat(); begin a streaming wrapper
2.15 upgraded hash table template to allow:
- aggregate keys (explicit comparison func for EMPTY and DEL keys)
- "static" implementations (so they can be culled if unused)
2.14 stb_mprintf
2.13 reduce identifiable strings in STB_NO_STB_STRINGS
2.12 fix STB_ONLY -- lots of uint32s, TRUE/FALSE things had crept in
2.11 fix bug in stb_dirtree_get() which caused "c://path" sorts of stuff
2.10 STB_F(), STB_I() inline constants (also KI,KU,KF,KD)
2.09 stb_box_face_vertex_axis_side
2.08 bugfix stb_trimwhite()
2.07 colored printing in windows (why are we in 1985?)
2.06 comparison functions are now functions-that-return-functions and
accept a struct-offset as a parameter (not thread-safe)
2.05 compile and pass tests under Linux (but no threads); thread cleanup
2.04 stb_cubic_bezier_1d, smoothstep, avoid dependency on registry
2.03 ?
2.02 remove integrated documentation
2.01 integrate various fixes; stb_force_uniprocessor
2.00 revised stb_dupe to use multiple hashes
1.99 stb_charcmp
1.98 stb_arr_deleten, stb_arr_insertn
1.97 fix stb_newell_normal()
1.96 stb_hash_number()
1.95 hack stb__rec_max; clean up recursion code to use new functions
1.94 stb_dirtree; rename stb_extra to stb_ptrmap
1.93 stb_sem_new() API cleanup (no blockflag-starts blocked; use 'extra')
1.92 stb_threadqueue--multi reader/writer queue, fixed size or resizeable
1.91 stb_bgio_* for reading disk asynchronously
1.90 stb_mutex uses CRITICAL_REGION; new stb_sync primitive for thread
joining; workqueue supports stb_sync instead of stb_semaphore
1.89 support ';' in constant-string wildcards; stb_mutex wrapper (can
implement with EnterCriticalRegion eventually)
1.88 portable threading API (only for win32 so far); worker thread queue
1.87 fix wildcard handling in stb_readdir_recursive
1.86 support ';' in wildcards
1.85 make stb_regex work with non-constant strings;
beginnings of stb_introspect()
1.84 (forgot to make notes)
1.83 whoops, stb_keep_if_different wasn't deleting the temp file
1.82 bring back stb_compress from stb_file.h for cmirror
1.81 various bugfixes, STB_FASTMALLOC_INIT inits FASTMALLOC in release
1.80 stb_readdir returns utf8; write own utf8-utf16 because lib was wrong
1.79 stb_write
1.78 calloc() support for malloc wrapper, STB_FASTMALLOC
1.77 STB_FASTMALLOC
1.76 STB_STUA - Lua-like language; (stb_image, stb_csample, stb_bilinear)
1.75 alloc/free array of blocks; stb_hheap bug; a few stb_ps_ funcs;
hash*getkey, hash*copy; stb_bitset; stb_strnicmp; bugfix stb_bst
1.74 stb_replaceinplace; use stdlib C function to convert utf8 to UTF-16
1.73 fix performance bug & leak in stb_ischar (C++ port lost a 'static')
1.72 remove stb_block, stb_block_manager, stb_decompress (to stb_file.h)
1.71 stb_trimwhite, stb_tokens_nested, etc.
1.70 back out 1.69 because it might problemize mixed builds; stb_filec()
1.69 (stb_file returns 'char *' in C++)
1.68 add a special 'tree root' data type for stb_bst; stb_arr_end
1.67 full C++ port. (stb_block_manager)
1.66 stb_newell_normal
1.65 stb_lex_item_wild -- allow wildcard items which MUST match entirely
1.64 stb_data
1.63 stb_log_name
1.62 stb_define_sort; C++ cleanup
1.61 stb_hash_fast -- Paul Hsieh's hash function (beats Bob Jenkins'?)
1.60 stb_delete_directory_recursive
1.59 stb_readdir_recursive
1.58 stb_bst variant with parent pointer for O(1) iteration, not O(log N)
1.57 replace LCG random with Mersenne Twister (found a public domain one)
1.56 stb_perfect_hash, stb_ischar, stb_regex
1.55 new stb_bst API allows multiple BSTs per node (e.g. secondary keys)
1.54 bugfix: stb_define_hash, stb_wildmatch, regexp
1.53 stb_define_hash; recoded stb_extra, stb_sdict use it
1.52 stb_rand_define, stb_bst, stb_reverse
1.51 fix 'stb_arr_setlen(NULL, 0)'
1.50 stb_wordwrap
1.49 minor improvements to enable the scripting language
1.48 better approach for stb_arr using stb_malloc; more invasive, clearer
1.47 stb_lex (lexes stb.h at 1.5ML/s on 3Ghz P4; 60/70% of optimal/flex)
1.46 stb_wrapper_*, STB_MALLOC_WRAPPER
1.45 lightly tested DFA acceleration of regexp searching
1.44 wildcard matching & searching; regexp matching & searching
1.43 stb_temp
1.42 allow stb_arr to use stb_malloc/realloc; note this is global
1.41 make it compile in C++; (disable stb_arr in C++)
1.40 stb_dupe tweak; stb_swap; stb_substr
1.39 stb_dupe; improve stb_file_max to be less stupid
1.38 stb_sha1_file: generate sha1 for file, even > 4GB
1.37 stb_file_max; partial support for utf8 filenames in Windows
1.36 remove STB__NO_PREFIX - poor interaction with IDE, not worth it
streamline stb_arr to make it separately publishable
1.35 bugfixes for stb_sdict, stb_malloc(0), stristr
1.34 (streaming interfaces for stb_compress)
1.33 stb_alloc; bug in stb_getopt; remove stb_overflow
1.32 (stb_compress returns, smaller&faster; encode window & 64-bit len)
1.31 stb_prefix_count
1.30 (STB__NO_PREFIX - remove stb_ prefixes for personal projects)
1.29 stb_fput_varlen64, etc.
1.28 stb_sha1
1.27 ?
1.26 stb_extra
1.25 ?
1.24 stb_copyfile
1.23 stb_readdir
1.22 ?
1.21 ?
1.20 ?
1.19 ?
1.18 ?
1.17 ?
1.16 ?
1.15 stb_fixpath, stb_splitpath, stb_strchr2
1.14 stb_arr
1.13 ?stb, stb_log, stb_fatal
1.12 ?stb_hash2
1.11 miniML
1.10 stb_crc32, stb_adler32
1.09 stb_sdict
1.08 stb_bitreverse, stb_ispow2, stb_big32
stb_fopen, stb_fput_varlen, stb_fput_ranged
stb_fcmp, stb_feq
1.07 (stb_encompress)
1.06 stb_compress
1.05 stb_tokens, (stb_hheap)
1.04 stb_rand
1.03 ?(s-strings)
1.02 ?stb_filelen, stb_tokens
1.01 stb_tolower
1.00 stb_hash, stb_intcmp
stb_file, stb_stringfile, stb_fgets
stb_prefix, stb_strlower, stb_strtok
stb_image
(stb_array), (stb_arena)
Parenthesized items have since been removed.
LICENSE
See end of file for license information.
CREDITS
Written by Sean Barrett.
Fixes:
Philipp Wiesemann
Robert Nix
r-lyeh
blackpawn
github:Mojofreem
Ryan Whitworth
Vincent Isambart
Mike Sartain
Eugene Opalev
Tim Sjostrand
github:infatum
Dave Butler (Croepha)
*/
#ifndef STB__INCLUDE_STB_H
#define STB__INCLUDE_STB_H
#define STB_VERSION 1
/* In addition to trimming out all the stuff FAudio does not use, we are also
* binding various stdlib functions stb.h uses to FAudio's stdlib.
* -flibit
*/
#ifndef FAUDIO_WIN32_PLATFORM
#ifdef memcpy /* Thanks Apple! */
#undef memcpy
#endif
#define memcpy FAudio_memcpy
#endif
//////////////////////////////////////////////////////////////////////////////
//
// Miscellany
//
STB_EXTERN void stb_swap(void *p, void *q, size_t sz);
#ifdef STB_DEFINE
typedef struct { char d[4]; } stb__4;
typedef struct { char d[8]; } stb__8;
// optimize the small cases, though you shouldn't be calling this for those!
void stb_swap(void *p, void *q, size_t sz)
{
char buffer[256];
if (p == q) return;
if (sz == 4) {
stb__4 temp = * ( stb__4 *) p;
* (stb__4 *) p = * ( stb__4 *) q;
* (stb__4 *) q = temp;
return;
} else if (sz == 8) {
stb__8 temp = * ( stb__8 *) p;
* (stb__8 *) p = * ( stb__8 *) q;
* (stb__8 *) q = temp;
return;
}
while (sz > sizeof(buffer)) {
stb_swap(p, q, sizeof(buffer));
p = (char *) p + sizeof(buffer);
q = (char *) q + sizeof(buffer);
sz -= sizeof(buffer);
}
memcpy(buffer, p , sz);
memcpy(p , q , sz);
memcpy(q , buffer, sz);
}
#endif
//////////////////////////////////////////////////////////////////////////////
//
// Random Numbers via Meresenne Twister or LCG
//
STB_EXTERN unsigned int stb_srandLCG(unsigned int seed);
STB_EXTERN unsigned int stb_randLCG(void);
STB_EXTERN void stb_srand(unsigned int seed);
STB_EXTERN unsigned int stb_rand(void);
STB_EXTERN double stb_frand(void);
#define stb_rand_define(x,y) \
\
unsigned int x(void) \
{ \
static unsigned int stb__rand = y; \
stb__rand = stb__rand * 2147001325 + 715136305; /* BCPL */ \
return 0x31415926 ^ ((stb__rand >> 16) + (stb__rand << 16)); \
}
#ifdef STB_DEFINE
static unsigned int stb__rand_seed=0;
unsigned int stb_srandLCG(unsigned int seed)
{
unsigned int previous = stb__rand_seed;
stb__rand_seed = seed;
return previous;
}
unsigned int stb_randLCG(void)
{
stb__rand_seed = stb__rand_seed * 2147001325 + 715136305; // BCPL generator
// shuffle non-random bits to the middle, and xor to decorrelate with seed
return 0x31415926 ^ ((stb__rand_seed >> 16) + (stb__rand_seed << 16));
}
// public domain Mersenne Twister by Michael Brundage
#define STB__MT_LEN 624
int stb__mt_index = STB__MT_LEN*sizeof(int)+1;
unsigned int stb__mt_buffer[STB__MT_LEN];
void stb_srand(unsigned int seed)
{
int i;
unsigned int old = stb_srandLCG(seed);
for (i = 0; i < STB__MT_LEN; i++)
stb__mt_buffer[i] = stb_randLCG();
stb_srandLCG(old);
stb__mt_index = STB__MT_LEN*sizeof(unsigned int);
}
#define STB__MT_IA 397
#define STB__MT_IB (STB__MT_LEN - STB__MT_IA)
#define STB__UPPER_MASK 0x80000000
#define STB__LOWER_MASK 0x7FFFFFFF
#define STB__MATRIX_A 0x9908B0DF
#define STB__TWIST(b,i,j) ((b)[i] & STB__UPPER_MASK) | ((b)[j] & STB__LOWER_MASK)
#define STB__MAGIC(s) (((s)&1)*STB__MATRIX_A)
unsigned int stb_rand()
{
unsigned int * b = stb__mt_buffer;
int idx = stb__mt_index;
unsigned int s,r;
int i;
if (idx >= STB__MT_LEN*sizeof(unsigned int)) {
if (idx > STB__MT_LEN*sizeof(unsigned int))
stb_srand(0);
idx = 0;
i = 0;
for (; i < STB__MT_IB; i++) {
s = STB__TWIST(b, i, i+1);
b[i] = b[i + STB__MT_IA] ^ (s >> 1) ^ STB__MAGIC(s);
}
for (; i < STB__MT_LEN-1; i++) {
s = STB__TWIST(b, i, i+1);
b[i] = b[i - STB__MT_IB] ^ (s >> 1) ^ STB__MAGIC(s);
}
s = STB__TWIST(b, STB__MT_LEN-1, 0);
b[STB__MT_LEN-1] = b[STB__MT_IA-1] ^ (s >> 1) ^ STB__MAGIC(s);
}
stb__mt_index = idx + sizeof(unsigned int);
r = *(unsigned int *)((unsigned char *)b + idx);
r ^= (r >> 11);
r ^= (r << 7) & 0x9D2C5680;
r ^= (r << 15) & 0xEFC60000;
r ^= (r >> 18);
return r;
}
double stb_frand(void)
{
return stb_rand() / ((double) (1 << 16) * (1 << 16));
}
#endif
#undef STB_EXTERN
#endif // STB_INCLUDE_STB_H
/*
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/

5572
libs/faudio/src/stb_vorbis.h Normal file

File diff suppressed because it is too large Load Diff