carb/audio/IAudioPlayback.h
File members: carb/audio/IAudioPlayback.h
// Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#    define _USE_MATH_DEFINES
#endif
#include "../Interface.h"
#include "AudioTypes.h"
#include "IAudioData.h"
#include <math.h>
namespace carb
{
namespace audio
{
/******************************** typedefs, enums, & macros **************************************/
struct SpeakerDirection
{
    float leftRight = 0.0f;
    float frontBack = 0.0f;
    float topBottom = 0.0f;
};
typedef uint32_t SpeakerDirectionFlags;
struct SpeakerDirectionDesc
{
    SpeakerDirectionFlags flags = 0;
    SpeakerMode speakerMode;
    SpeakerDirection directions[kMaxChannels];
    void* ext = nullptr;
};
enum class StreamState
{
    eNormal,
    eCritical,
    eMore,
    eLess,
    eMuchLess,
};
struct Streamer
{
    void(CARB_ABI* acquireReference)(Streamer* self);
    void(CARB_ABI* releaseReference)(Streamer* self);
    bool(CARB_ABI* openStream)(Streamer* self, SoundFormat* format);
    StreamState(CARB_ABI* writeStreamData)(Streamer* self, const void* data, size_t bytes);
    void(CARB_ABI* closeStream)(Streamer* self);
};
typedef uint32_t OutputFlags;
constexpr OutputFlags fOutputFlagDevice = 0x00000001;
constexpr OutputFlags fOutputFlagStreamer = 0x00000002;
constexpr OutputFlags fOutputFlagAllowNoStreamers = 0x00000004;
constexpr OutputFlags fOutputFlagAvailableMask = 0xffffffff;
struct OutputDesc
{
    OutputFlags flags = 0;
    size_t deviceIndex = 0;
    SpeakerMode speakerMode = kSpeakerModeDefault;
    size_t frameRate = 0;
    size_t streamerCount = 0;
    Streamer** streamer = nullptr;
    void* ext = nullptr;
};
enum class ContextCallbackEvent
{
    eDeviceChange,
    eCycleStart,
    eCycleEnd,
};
typedef void(CARB_ABI* ContextCallback)(Context* context, ContextCallbackEvent event, void* data, void* userData);
typedef uint32_t PlaybackContextFlags;
constexpr PlaybackContextFlags fContextFlagCycleCallbacks = 0x00000001;
constexpr PlaybackContextFlags fContextFlagBaking = 0x00000002;
constexpr PlaybackContextFlags fContextFlagManualStop = 0x00000004;
constexpr PlaybackContextFlags fContextFlagDeviceChangeCallbacks = 0x00000008;
struct PlaybackContextDesc
{
    PlaybackContextFlags flags = 0;
    ContextCallback callback = nullptr;
    void* callbackContext = nullptr;
    size_t maxBuses = 0;
    OutputDesc output = {};
    const char* outputDisplayName = nullptr;
    void* ext = nullptr;
};
struct ContextCaps
{
    size_t maxBuses;
    SpeakerDirectionDesc speakerDirections;
    DeviceCaps selectedDevice;
    OutputDesc output;
    void* ext;
};
typedef uint32_t EntityAttributeFlags;
constexpr EntityAttributeFlags fEntityFlagPosition = 0x00000001;
constexpr EntityAttributeFlags fEntityFlagVelocity = 0x00000002;
constexpr EntityAttributeFlags fEntityFlagForward = 0x00000004;
constexpr EntityAttributeFlags fEntityFlagUp = 0x00000008;
constexpr EntityAttributeFlags fEntityFlagCone = 0x00000010;
constexpr EntityAttributeFlags fEntityFlagRolloff = 0x00000020;
constexpr EntityAttributeFlags fEntityFlagAll = fEntityFlagPosition | fEntityFlagVelocity | fEntityFlagForward |
                                                fEntityFlagUp | fEntityFlagCone | fEntityFlagRolloff;
constexpr EntityAttributeFlags fEntityFlagMakePerp = 0x80000000;
constexpr EntityAttributeFlags fEntityFlagNormalize = 0x40000000;
enum class RolloffType
{
    eInverse,
    eLinear,
    eLinearSquare,
};
struct RolloffCurve
{
    size_t pointCount;
    Float2* points;
};
struct RolloffDesc
{
    RolloffType type;
    float nearDistance;
    float farDistance;
    RolloffCurve* volume;
    RolloffCurve* lowFrequency;
    RolloffCurve* lowPassDirect;
    RolloffCurve* lowPassReverb;
    RolloffCurve* reverb;
    void* ext = nullptr;
};
struct DspValuePair
{
    float inner;
    float outer;
};
constexpr float kConeAngleOmnidirectional = (float)(2.0 * M_PI);
struct EntityCone
{
    float insideAngle;
    float outsideAngle;
    DspValuePair volume;
    DspValuePair lowPassFilter;
    DspValuePair reverb;
    void* ext = nullptr;
};
struct EntityAttributes
{
    EntityAttributeFlags flags;
    Float3 position;
    Float3 velocity;
    Float3 forward;
    Float3 up;
    EntityCone cone;
};
struct ListenerAttributes : EntityAttributes
{
    void* ext = nullptr;
};
struct EmitterAttributes : EntityAttributes
{
    RolloffDesc rolloff;
    void* ext = nullptr;
};
enum class VoiceCallbackType
{
    eSoundEnded,
    eEventPoint,
    eLoopPoint,
};
typedef AudioResult(CARB_ABI* VoiceCallback)(
    Voice* voice, VoiceCallbackType callbackType, SoundData* sound, void* data, void* context);
typedef uint32_t PlaybackModeFlags;
constexpr PlaybackModeFlags fPlaybackModeSpatial = 0x00000001;
constexpr PlaybackModeFlags fPlaybackModeListenerRelative = 0x00000002;
constexpr PlaybackModeFlags fPlaybackModeDistanceDelay = 0x00000004;
constexpr PlaybackModeFlags fPlaybackModeInterauralDelay = 0x00000008;
constexpr PlaybackModeFlags fPlaybackModeUseDoppler = 0x00000010;
constexpr PlaybackModeFlags fPlaybackModeUseReverb = 0x00000020;
constexpr PlaybackModeFlags fPlaybackModeUseFilters = 0x00000040;
constexpr PlaybackModeFlags fPlaybackModeMuted = 0x00000080;
constexpr PlaybackModeFlags fPlaybackModePaused = 0x00000100;
constexpr PlaybackModeFlags fPlaybackModeFadeIn = 0x00000200;
constexpr PlaybackModeFlags fPlaybackModeSimulatePosition = 0x00000400;
constexpr PlaybackModeFlags fPlaybackModeNoPositionSimulation = 0x00000800;
constexpr PlaybackModeFlags fPlaybackModeSpatialMixLevelMatrix = 0x00001000;
constexpr PlaybackModeFlags fPlaybackModeNoSpatialLowFrequencyEffect = 0x00002000;
constexpr PlaybackModeFlags fPlaybackModeStopOnSimulation = 0x00004000;
constexpr PlaybackModeFlags fPlaybackModeAvailableMask = 0x7fffffff;
constexpr PlaybackModeFlags fPlaybackModeDefaultUseDoppler = 0x40000000;
constexpr PlaybackModeFlags fPlaybackModeDefaultDistanceDelay = 0x20000000;
constexpr PlaybackModeFlags fPlaybackModeDefaultInterauralDelay = 0x10000000;
constexpr PlaybackModeFlags fPlaybackModeDefaultUseReverb = 0x08000000;
constexpr PlaybackModeFlags fPlaybackModeDefaultUseFilters = 0x04000000;
constexpr PlaybackModeFlags fPlaybackModeDefaultMask =
    fPlaybackModeDefaultUseDoppler | fPlaybackModeDefaultDistanceDelay | fPlaybackModeDefaultInterauralDelay |
    fPlaybackModeDefaultUseReverb | fPlaybackModeDefaultUseFilters;
constexpr size_t kPlaybackModeDefaultFlagCount = 10;
// FIXME: exhale can't handle this
#ifndef DOXYGEN_SHOULD_SKIP_THIS
constexpr PlaybackModeFlags getForceOffPlaybackModeFlags(PlaybackModeFlags flags)
{
    return (flags & fPlaybackModeDefaultMask) >> kPlaybackModeDefaultFlagCount;
}
constexpr PlaybackModeFlags getForceOnPlaybackModeFlags(PlaybackModeFlags flags)
{
    return (flags & fPlaybackModeDefaultMask) >> (kPlaybackModeDefaultFlagCount * 2);
}
#endif
typedef uint32_t VoiceParamFlags;
constexpr VoiceParamFlags fVoiceParamAll = static_cast<VoiceParamFlags>(~0);
constexpr VoiceParamFlags fVoiceParamPlaybackMode = 0x00000001;
constexpr VoiceParamFlags fVoiceParamVolume = 0x00000002;
constexpr VoiceParamFlags fVoiceParamMute = 0x00000004;
constexpr VoiceParamFlags fVoiceParamBalance = 0x00000008;
constexpr VoiceParamFlags fVoiceParamFrequencyRatio = 0x00000010;
constexpr VoiceParamFlags fVoiceParamPriority = 0x00000020;
constexpr VoiceParamFlags fVoiceParamPause = 0x00000040;
constexpr VoiceParamFlags fVoiceParamSpatialMixLevel = 0x00000080;
constexpr VoiceParamFlags fVoiceParamDopplerScale = 0x00000100;
constexpr VoiceParamFlags fVoiceParamOcclusionFactor = 0x00000200;
constexpr VoiceParamFlags fVoiceParamEmitter = 0x00000400;
constexpr VoiceParamFlags fVoiceParamMatrix = 0x00000800;
struct VoiceParams
{
    PlaybackModeFlags playbackMode;
    float volume;
    struct VoiceParamBalance
    {
        float pan;
        float fade;
    } balance;
    float frequencyRatio;
    int32_t priority;
    float spatialMixLevel;
    float dopplerScale;
    struct VoiceParamOcclusion
    {
        float direct;
        float reverb;
    } occlusion;
    EmitterAttributes emitter;
    const float* matrix;
    void* ext = nullptr;
};
using ContextParamFlags = uint32_t;
constexpr ContextParamFlags fContextParamAll = ~0u;
constexpr ContextParamFlags fContextParamSpeedOfSound = 0x00000001;
constexpr ContextParamFlags fContextParamWorldUnitScale = 0x00000002;
constexpr ContextParamFlags fContextParamListener = 0x00000004;
constexpr ContextParamFlags fContextParamDopplerScale = 0x00000008;
constexpr ContextParamFlags fContextParamVirtualizationThreshold = 0x00000010;
constexpr ContextParamFlags fContextParamSpatialFrequencyRatio = 0x00000020;
constexpr ContextParamFlags fContextParamNonSpatialFrequencyRatio = 0x00000040;
constexpr ContextParamFlags fContextParamMasterVolume = 0x00000080;
constexpr ContextParamFlags fContextParamSpatialVolume = 0x00000100;
constexpr ContextParamFlags fContextParamNonSpatialVolume = 0x00000200;
constexpr ContextParamFlags fContextParamDopplerLimit = 0x00000400;
constexpr ContextParamFlags fContextParamDefaultPlaybackMode = 0x00000800;
constexpr ContextParamFlags fContextParamFlags = 0x00001000;
constexpr ContextParamFlags fContextParamVideoLatency = 0x00002000;
constexpr ContextParamFlags fContextParamFlagValidateVoiceTable = 0x10000000;
constexpr float kDefaultSpeedOfSound = 340.f;
struct ContextParams
{
    float speedOfSound;
    float unitsPerMeter;
    float dopplerScale;
    float dopplerLimit;
    float virtualizationThreshold;
    float spatialFrequencyRatio;
    float nonSpatialFrequencyRatio;
    float masterVolume;
    float spatialVolume;
    float nonSpatialVolume;
    ListenerAttributes listener;
    PlaybackModeFlags defaultPlaybackMode;
    ContextParamFlags flags;
    void* ext = nullptr;
};
struct ContextParams2
{
    int64_t videoLatency = 0;
    int64_t videoLatencyTrim = 0;
    void* padding[32] = {};
    void* ext = nullptr;
};
constexpr size_t kLoopDescNoLoop = ~0ull;
struct LoopPointDesc
{
    const EventPoint* loopPoint = nullptr;
    size_t loopPointIndex = kLoopDescNoLoop;
    void* ext = nullptr;
};
typedef uint32_t PlayFlags;
constexpr PlayFlags fPlayFlagUseEventPoints = 0x00000001;
constexpr PlayFlags fPlayFlagRealtimeCallbacks = 0x00000002;
constexpr PlayFlags fPlayFlagMaxInstancesSimulate = 0x00000004;
constexpr PlayFlags fPlayFlagAvailableMask = 0x01ffffff;
struct PlaySoundDesc
{
    PlayFlags flags = 0;
    SoundData* sound;
    VoiceParamFlags validParams = 0;
    VoiceParams* params = nullptr;
    LoopPointDesc loopPoint = {};
    VoiceCallback callback = nullptr;
    void* callbackContext = nullptr;
    size_t playStart = 0;
    size_t playLength = 0;
    UnitType playUnits = UnitType::eFrames;
    void* ext = nullptr;
};
struct PlaySoundDesc2
{
    int64_t delayTime = 0;
    void* padding[32] = {};
    void* ext = nullptr;
};
/********************************** IAudioPlayback Interface **********************************/
struct IAudioPlayback
{
    CARB_PLUGIN_INTERFACE("carb::audio::IAudioPlayback", 1, 1)
    /************************ context and device management functions ****************************/
    size_t(CARB_ABI* getDeviceCount)();
    AudioResult(CARB_ABI* getDeviceCaps)(size_t deviceIndex, DeviceCaps* caps);
    Context*(CARB_ABI* createContext)(const PlaybackContextDesc* desc);
    AudioResult(CARB_ABI* destroyContext)(Context* context);
    const ContextCaps*(CARB_ABI* getContextCaps)(Context* context);
    void(CARB_ABI* setContextParameters)(Context* context, ContextParamFlags paramsToSet, const ContextParams* params);
    void(CARB_ABI* getContextParameters)(Context* context, ContextParamFlags paramsToGet, ContextParams* params);
    bool(CARB_ABI* setBusCount)(Context* ctx, size_t count);
    bool(CARB_ABI* setSpeakerDirections)(Context* context, const SpeakerDirectionDesc* desc);
    AudioResult(CARB_ABI* setOutput)(Context* context, const OutputDesc* desc);
    AudioResult(CARB_ABI* update)(Context* context);
    void(CARB_ABI* startProcessing)(Context* context);
    void(CARB_ABI* stopProcessing)(Context* context);
    /********************************** sound management functions *******************************/
    Voice*(CARB_ABI* playSound)(Context* context, const PlaySoundDesc* desc);
    void(CARB_ABI* stopVoice)(Voice* voice);
    /********************************** voice management functions *******************************/
    SoundData*(CARB_ABI* getPlayingSound)(Voice* voice);
    bool(CARB_ABI* isPlaying)(Voice* voice);
    bool(CARB_ABI* setLoopPoint)(Voice* voice, const LoopPointDesc* desc);
    size_t(CARB_ABI* getPlayCursor)(Voice* voice, UnitType type);
    void(CARB_ABI* setVoiceParameters)(Voice* voice, VoiceParamFlags paramsToSet, const VoiceParams* params);
    void(CARB_ABI* getVoiceParameters)(Voice* voice, VoiceParamFlags paramsToGet, VoiceParams* params);
    void(CARB_ABI* stopAllVoices)(Context* context);
};
} // namespace audio
} // namespace carb