prime/include/musyx/musyx.h

834 lines
28 KiB
C

#ifndef _MUSYX_MUSYX
#define _MUSYX_MUSYX
#include "musyx/platform.h"
#include "musyx/version.h"
#include <math.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#if MUSY_TARGET == MUSY_TARGET_DOLPHIN
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed long s32;
typedef unsigned long u32;
typedef unsigned long long u64;
typedef float f32;
typedef double f64;
#elif MUSY_TARGET == MUSY_TARGET_PC
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef float f32;
typedef double f64;
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef bool8
typedef unsigned char bool8;
#endif
#ifndef __cplusplus
#if __STDC_VERSION__ <= 199901L
typedef unsigned long bool;
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#endif
#define SND_STUDIO_MAXNUM 8
#define SND_STUDIO_DEFAULT 0
#define SND_STUDIO_NONE 0xFF
#define SYNTH_MAX_VOICES 64
typedef u32 SND_SEQID;
typedef u32 SND_VOICEID;
typedef u32 SND_STREAMID;
typedef u16 SND_GROUPID;
typedef u16 SND_SONGID;
typedef u16 SND_FXID;
typedef enum {
SND_OUTPUTMODE_MONO = 0,
SND_OUTPUTMODE_STEREO,
SND_OUTPUTMODE_SURROUND
} SND_OUTPUTMODE;
typedef struct SND_PLAYBACKINFO {
u32 frq;
u8 stereo;
u8 bits;
s8 deviceName[256];
s8 versionText[256];
} SND_PLAYBACKINFO;
typedef struct SND_SEQVOLDEF {
u8 track;
u8 volGroup;
} SND_SEQVOLDEF;
#define SND_PLAYPARA_DEFAULT 0x00000000
#define SND_PLAYPARA_TRACKMUTE 0x00000001
#define SND_PLAYPARA_SPEED 0x00000002
#define SND_PLAYPARA_VOLUME 0x00000004
#define SND_PLAYPARA_SEQVOLDEF 0x00000008
#define SND_PLAYPARA_PAUSE 0x00000010
typedef struct SND_PLAYPARA {
u32 flags; // Enable features by using these flags
u32 trackMute[2]; // Initial mute settings
u16 speed; // Initial speed factor (0x100 = 1:1)
struct { // Start volume information
u16 time;
u8 target;
} volume;
u8 numSeqVolDef; // Number of non-standart volume group tracks
SND_SEQVOLDEF* seqVolDef; // List of tracks and the volume groups to be assigned to them
u8 numFaded; // Number of entries to the fade list
u8* faded; // Array of u8s containing the volume group IDs that should be affected by the initial
// volume setting (default will always be affected)
} SND_PLAYPARA;
#define SND_CROSSFADE_STOP 0 // Stop old song after fadedown
#define SND_CROSSFADE_PAUSE 1 // Pause old song after fadedown
#define SND_CROSSFADE_CONTINUE 2 // Continue previously paused song as new one
#define SND_CROSSFADE_START 0 // Start new song (no continue)
#define SND_CROSSFADE_SYNC 4 // Crossfade should start syncronized by sync-controller (104)
#define SND_CROSSFADE_PAUSENEW 8 // Pause new song before even starting it
#define SND_CROSSFADE_TRACKMUTE 16 // Use trackmute informtion
#define SND_CROSSFADE_SPEED 32 // Use speed informtion
#define SND_CROSSFADE_MUTE 64 // Old song continues playing & gets muted after fade down
#define SND_CROSSFADE_MUTENEW 128 // Mute new song after starting it
#define SND_CROSSFADE_DEFAULT 0
typedef struct SND_CROSSFADE {
SND_SEQID seqId1;
u16 time1;
SND_SEQID seqId2;
u16 time2;
void* arr2;
SND_GROUPID gid2;
SND_SONGID sid2;
u8 vol2;
u8 studio2;
u32 trackMute2[2]; // Mute bits (see sndMute())
u16 speed2; // Initial speed (of new song)
u8 flags;
} SND_CROSSFADE;
#define SND_ID_ERROR 0xFFFFFFFF // ID is invalid
#define SND_USERMUSIC_VOLGROUPS 0xFA
#define SND_USERFX_VOLGROUPS 0xFB
#define SND_USERALL_VOLGROUPS 0xFC
#define SND_MUSIC_VOLGROUPS 0xFD
#define SND_FX_VOLGROUPS 0xFE
#define SND_ALL_VOLGROUPS 0xFF
#define SND_MAX_USER_VOLGROUP 20
bool sndPushGroup(void* prj_data, SND_GROUPID gid, void* samples, void* sampdir, void* pool);
bool sndPopGroup(void);
void sndSetSampleDataUploadCallback(void* (*callback)(u32 offset, u32 bytes), u32 chunkSize);
typedef struct SND_HOOKS {
void* (*malloc)(size_t addr);
void (*free)(void* addr);
} SND_HOOKS;
void sndSetHooks(SND_HOOKS* hooks);
// Misc flags to influence the way the sound system works internally
// (support may vary from platform to platform)
#define SND_FLAGS_DEFAULT 0x00000000
#define SND_FLAGS_DEFAULT_STUDIO_DPL2 0x00000001 // Use DPL2 encoding for default studio
#define SND_FLAGS_EMITTERGROUPSUSEMAXVOICES \
0x00000002 // define this to enable usage of max. voices from FX table for emitter group start
// management
// Platform dependend flags : PC
#define SND_FLAGS_PC_USE_TIMER \
0x00000000 // Use timer driven update system (less performance hit, larger latency)
#define SND_FLAGS_PC_USE_THREAD \
0x00010000 // Use thread driven update system (larger performance hit, shorter latency)
#define SND_FLAGS_PC_USE_PRIMARY 0x00020000 // Use a primary sound buffer for mixing (Win95/98 only)
#define SND_FLAGS_PC_LATENCY0 0x00000000 // Latency values (see documentation)
#define SND_FLAGS_PC_LATENCY1 0x10000000
#define SND_FLAGS_PC_LATENCY2 0x20000000
#define SND_FLAGS_PC_LATENCY3 0x30000000
#define SND_FLAGS_PC_LATENCY4 0x40000000
#define SND_FLAGS_PC_LATENCY5 0x50000000
#define SND_FLAGS_PC_LATENCY6 0x60000000
#define SND_FLAGS_PC_LATENCY7 0x70000000
s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize);
void sndQuit(void);
bool sndIsInstalled(void);
bool sndIsIdle(void);
SND_PLAYBACKINFO* sndGetPlayBackInfo(void);
void sndSetMaxVoices(u8 music, u8 sfx);
void sndVolume(u8 volume, u16 time, u8 volGroup);
void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx);
void sndOutputMode(SND_OUTPUTMODE mode);
void sndSilence(void);
#define SND_PAUSEVOL_NORMAL 127
void sndPauseVolume(u8 mute_vol, u16 time, u8 volGroup);
#define SND_MIDICTRL_MODULATION 0x01
#define SND_MIDICTRL_VOLUME 0x07
#define SND_MIDICTRL_PANNING 0x0A
#define SND_MIDICTRL_PEDAL 0x40
#define SND_MIDICTRL_PORTAMENTO 0x41
#define SND_MIDICTRL_REVERB 0x5B
#define SND_MIDICTRL_CHORUS 0x5D
#define SND_MIDICTRL_PITCHBEND 0x80
#define SND_MIDICTRL_SPANNING 0x83
#define SND_MIDICTRL_DOPPLER 0x84
#define SND_SEQVOL_CONTINUE 0
#define SND_SEQVOL_STOP 1
#define SND_SEQVOL_PAUSE 2
#define SND_SEQVOL_MUTE 3
#define SND_SEQVOL_MODEMASK 0xF
#define SND_ID_ERROR 0xFFFFFFFF // ID is invalid
#define SND_MAX_SEQINSTANCES 8
#define SND_SEQ_ERROR_ID 0xFFFFFFFF
#define SND_SEQ_CROSSFADE_ID 0x80000000
#define SND_PAUSEVOL_NORMAL 127
#define SND_SEQVOL_CONTINUE 0
#define SND_SEQVOL_STOP 1
#define SND_SEQVOL_PAUSE 2
#define SND_SEQVOL_MUTE 3
#define sndSeqPlay(sgid, sid, arrfile, para) \
sndSeqPlayEx(sgid, sid, arrfile, para, SND_STUDIO_DEFAULT)
SND_SEQID sndSeqPlayEx(SND_GROUPID sgid, SND_SONGID sid, void* arrfile, SND_PLAYPARA* para,
u8 studio);
void sndSeqStop(SND_SEQID seqId);
void sndSeqPause(SND_SEQID seqId);
void sndSeqContinue(SND_SEQID seqId);
void sndSeqMute(SND_SEQID seqId, u32 mask1, u32 mask2);
void sndSeqSpeed(SND_SEQID seqId, u16 speed);
bool sndSeqLoop(SND_SEQID seqId, bool on);
bool sndSeqLoopEx(SND_SEQID seqId, u8 track, bool on);
u16 sndSeqGetLoopCnt(SND_SEQID seqId);
u16 sndSeqGetLoopCntEx(SND_SEQID seqId, u8 track);
bool sndSeqGetValid(SND_SEQID seqId);
u8 sndSeqGetMidiCtrl(SND_SEQID seqId, u8 channel, u8 ctrl);
u16 sndSeqGetMidiCtrl14(SND_SEQID seqId, u8 channel, u8 ctrl);
bool sndSeqSetMidiCtrl(SND_SEQID seqId, u8 channel, u8 ctrl, u8 value);
bool sndSeqSetMidiCtrl14(SND_SEQID seqId, u8 channel, u8 ctrl, u16 value);
void sndSeqVolume(u8 volume, u16 time, SND_SEQID seqId, u8 mode);
u8 sndSeqGetVolGroup(SND_SEQID seqId);
bool sndSeqAssignVolGroup2Track(SND_SEQID seqId, u8 track, u8 vGroup);
void sndSeqCrossFade(SND_CROSSFADE* ci, SND_SEQID* new_seqId);
bool sndSeqCrossFadeDone(SND_SEQID* new_seqId);
typedef struct SND_PARAMETER {
u8 ctrl;
union _paraData {
u8 value7;
u16 value14;
} paraData;
} SND_PARAMETER;
typedef struct SND_PARAMETER_INFO {
u8 numPara; // How many MIDI controller values (ID,value - value may be 8-bit or 16-bit!)
SND_PARAMETER* paraArray; // Parameter data...
} SND_PARAMETER_INFO;
#define SND_FX_DEFVOL 0xFF
#define SND_FX_DEFPAN 0xFF
#define sndFXStart(fid, vol, pan) sndFXStartEx(fid, vol, pan, SND_STUDIO_DEFAULT)
SND_VOICEID sndFXStartEx(SND_FXID fid, u8 vol, u8 pan, u8 studio);
SND_VOICEID sndFXStartPara(SND_FXID fid, u8 vol, u8 pan, u8 studio, u8 numPara, ...);
SND_VOICEID sndFXStartParaInfo(SND_FXID fid, u8 vol, u8 pan, u8 studio,
SND_PARAMETER_INFO* paraInfo);
SND_VOICEID sndFXCheck(SND_VOICEID vid);
bool sndFXKeyOff(SND_VOICEID vid);
bool sndFXCtrl(SND_VOICEID vid, u8 ctrl, u8 value);
bool sndFXCtrl14(SND_VOICEID vid, u8 ctrl, u16 value);
#define SND_MIDICTRL_MODULATION 0x01
#define SND_MIDICTRL_VOLUME 0x07
#define SND_MIDICTRL_PANNING 0x0A
#define SND_MIDICTRL_PEDAL 0x40
#define SND_MIDICTRL_PORTAMENTO 0x41
#define SND_MIDICTRL_REVERB 0x5B
#define SND_MIDICTRL_CHORUS 0x5D
#define SND_MIDICTRL_PITCHBEND 0x80
#define SND_MIDICTRL_SPANNING 0x83
#define SND_MIDICTRL_DOPPLER 0x84
#define sndFXPitchBend(vid, pb) sndFXCtrl14(vid, SND_MIDICTRL_PITCHBEND, pb)
#define sndFXModulation(vid, modu) sndFXCtrl14(vid, SND_MIDICTRL_MODULATION, modu)
#define sndFXDoppler(vid, doppler) sndFXCtrl14(vid, SND_MIDICTRL_DOPPLER, doppler)
#define sndFXReverb(vid, reverb) sndFXCtrl(vid, SND_MIDICTRL_REVERB, reverb)
#define sndFXChorus(vid, chorus) sndFXCtrl(vid, SND_MIDICTRL_CHORUS, chorus)
#define sndFXPedal(vid, pedal) sndFXCtrl(vid, SND_MIDICTRL_PEDAL, pedal)
#define sndFXVolume(vid, vol) sndFXCtrl(vid, SND_MIDICTRL_VOLUME, vol)
#define sndFXPanning(vid, pan) sndFXCtrl(vid, SND_MIDICTRL_PANNING, pan)
#define sndFXSurroundPanning(vid, span) sndFXCtrl(vid, SND_MIDICTRL_SPANNING, span)
bool sndFXAssignVolGroup2FXId(SND_FXID fid, u8 vGroup);
// --------------------------------------------------------
s32 sndReadFlag(u8 num);
s32 sndWriteFlag(u8 num, s32 value);
bool sndSendMessage(SND_VOICEID vid, s32 mesg);
void sndSetReceiveMessageCallback(void (*callback)(SND_VOICEID vid, s32 mesg));
// --------------------------------------------------------
// Flags
#define SND_STREAM_DEFAULT 0x00000000 // Default stream buffer (PCM16)
#define SND_STREAM_ADPCM 0x00000001 // ADPCM stream buffer
#define SND_STREAM_INACTIVE 0x00010000 // Allocate stream, but do not start it yet
#define SND_STREAM_MANUALARAMUPD 0x00020000 // Application will provide manual ARAM buffer updates
#define SND_STREAM_ADPCM_BLKBYTES 8 // Bytes per ADPCM block
#define SND_STREAM_ADPCM_BLKSIZE 14 // Samples per ADPCM block
// ADPCM info structure
typedef struct SND_ADPCMSTREAM_INFO {
s16 coefTab[8][2]; // Table of coef. pairs
} SND_ADPCMSTREAM_INFO;
#define sndStreamAlloc(prio, buffer, size, frq, vol, pan, span, fxvol, updateFunction, user) \
sndStreamAllocEx(prio, buffer, size, frq, vol, pan, span, fxvol, 0, SND_STUDIO_DEFAULT, \
SND_STREAM_DEFAULT, updateFunction, user, NULL)
SND_STREAMID sndStreamAllocEx(u8 prio, void* buffer, u32 samples, u32 frq, u8 vol, u8 pan, u8 span,
u8 auxa, u8 auxb, u8 studio, u32 flags,
u32 (*updateFunction)(void* buffer1, u32 len1, void* buffer2,
u32 len2, u32 user),
u32 user, SND_ADPCMSTREAM_INFO* adpcmInfo);
SND_STREAMID sndStreamAllocStereo(u8 prio, void* lBuffer, void* rBuffer, u32 samples, u32 frq,
u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb, u8 studio, u32 flags,
u32 (*updateFunction)(void* buffer1, u32 len1, void* buffer2,
u32 len2, u32 user),
u32 lUser, u32 rUser, SND_ADPCMSTREAM_INFO* adpcmInfoL,
SND_ADPCMSTREAM_INFO* adpcmInfoR);
u32 sndStreamAllocLength(u32 num, u32 flags);
void sndStreamFree(SND_STREAMID stid);
void sndStreamMixParameter(SND_STREAMID stid, u8 vol, u8 pan, u8 span, u8 fxvol);
void sndStreamMixParameterEx(SND_STREAMID stid, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb);
void sndStreamADPCMParameter(SND_STREAMID stid, SND_ADPCMSTREAM_INFO* adpcmInfo);
void sndStreamFrq(SND_STREAMID stid, u32 frq);
bool sndStreamActivate(SND_STREAMID stid);
void sndStreamDeactivate(SND_STREAMID stid);
void sndStreamARAMUpdate(SND_STREAMID stid, u32 off1, u32 len1, u32 off2, u32 len2);
u32 sndStreamCallbackFrq(u32 msTime);
// --------------------------------------------------------
#define SND_VIRTUALSAMPLE_DEFAULT 0x00000000
bool sndVirtualSampleAllocateBuffers(u8 numInstances, u32 numSamples, u32 flags);
void sndVirtualSampleFreeBuffers(void);
typedef u16 SND_VSID; // Virtual sample ID
typedef u16 SND_INSTID; // Virtual sample instance ID
typedef struct SND_VIRTUALSAMPLE_INFO {
SND_VSID smpID; // ID of sample to be streamed
SND_INSTID instID; // ID of this instance of the stream
union vsData {
struct vsUpdate { // Buffer update info
u32 off1;
u32 len1;
u32 off2;
u32 len2;
} update;
} data;
} SND_VIRTUALSAMPLE_INFO;
#define SND_VIRTUALSAMPLE_REASON_INIT 0 // Virtual sample just started playback
#define SND_VIRTUALSAMPLE_REASON_UPDATE 1 // Virtual sample is within stream buffer and needs data
#define SND_VIRTUALSAMPLE_REASON_STOP 2 // Virtual sample just has been stopped
#define SND_VIRTUALSAMPLE_REASON_ARAMDMADONE \
3 // Last ARAM update initiated for this virtual sample has finished
void sndVirtualSampleSetCallback(u32 (*callback)(u8 reason, const SND_VIRTUALSAMPLE_INFO* info));
void sndVirtualSampleARAMUpdate(SND_INSTID instID, void* base, u32 off1, u32 len1, u32 off2,
u32 len2);
void sndVirtualSampleEndPlayback(SND_INSTID instID, bool sampleEndedNormally);
#define SND_AUX_BLOCKSIZE 160 // Size of block passed to the AUX FX hanler (in samples)
#define SND_AUX_REASON_BUFFERUPDATE 0
#define SND_AUX_REASON_PARAMETERUPDATE 1
#define SND_MIDI_NONE 0xFF
#define SND_AUX_NUMPARAMETERS 4
typedef struct SND_AUX_INFO {
union SND_AUX_DATA {
struct SND_AUX_BUFFERUPDATE {
s32* left;
s32* right;
s32* surround;
} bufferUpdate;
struct SND_AUX_PARAMETERUPDATE {
u16 para[SND_AUX_NUMPARAMETERS];
} parameterUpdate;
} data;
} SND_AUX_INFO;
void sndSetAuxProcessingCallbacks(u8 studio,
void (*auxA)(u8 reason, SND_AUX_INFO* info, void* user),
void* userA, u8 midiA, SND_SEQID seqIDA,
void (*auxB)(u8 reason, SND_AUX_INFO* info, void* user),
void* userB, u8 midiB, SND_SEQID seqIDB);
#define SND_AUXA_PARAMETERS 0
#define SND_AUXB_PARAMETERS 1
void sndUpdateAuxParameter(u8 studio, u16 para[SND_AUX_NUMPARAMETERS], u8 auxBus);
typedef enum {
SND_STUDIO_TYPE_STD = 0,
SND_STUDIO_TYPE_DPL2,
SND_STUDIO_TYPE_RESERVED1,
SND_STUDIO_TYPE_RESERVED2
} SND_STUDIO_TYPE;
#define sndActivateStudio(studio, isMaster) \
sndActivateStudioEx(studio, isMaster, SND_STUDIO_TYPE_STD)
void sndActivateStudioEx(u8 studio, bool isMaster, SND_STUDIO_TYPE type);
void sndChangeStudioMasterMix(u8 studio, bool isMaster);
void sndDeactivateStudio(u8 studio);
void sndSetITDDefault(u8 studio, bool musicITD, bool sfxITD);
// Standard Quality Reverb AUX FX
typedef struct _SND_REVSTD_DELAYLINE {
s32 inPoint;
s32 outPoint;
s32 length;
f32* inputs;
f32 lastOutput;
} _SND_REVSTD_DELAYLINE;
typedef struct _SND_REVSTD_WORK {
_SND_REVSTD_DELAYLINE AP[6];
_SND_REVSTD_DELAYLINE C[6];
f32 allPassCoeff;
f32 combCoef[6];
f32 lpLastout[3];
f32 level;
f32 damping;
s32 preDelayTime;
f32* preDelayLine[3];
f32* preDelayPtr[3];
} _SND_REVSTD_WORK;
typedef struct SND_AUX_REVERBSTD {
_SND_REVSTD_WORK rv;
bool8 tempDisableFX;
f32 coloration;
f32 mix;
f32 time;
f32 damping;
f32 preDelay;
} SND_AUX_REVERBSTD;
typedef void (*SND_AUX_CALLBACK)(u8 reason, SND_AUX_INFO* info, void* user);
void sndAuxCallbackReverbSTD(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareReverbSTD(SND_AUX_REVERBSTD* rev);
bool sndAuxCallbackShutdownReverbSTD(SND_AUX_REVERBSTD* rev);
bool sndAuxCallbackUpdateSettingsReverbSTD(SND_AUX_REVERBSTD* rev);
// High Quality Reverb AUX FX
//
typedef struct _SND_REVHI_DELAYLINE {
s32 inPoint;
s32 outPoint;
s32 length;
f32* inputs;
f32 lastOutput;
} _SND_REVHI_DELAYLINE;
typedef struct _SND_REVHI_WORK {
_SND_REVHI_DELAYLINE AP[9];
_SND_REVHI_DELAYLINE C[9];
f32 allPassCoeff;
f32 combCoef[9];
f32 lpLastout[3];
f32 level;
f32 damping;
s32 preDelayTime;
f32 crosstalk;
f32* preDelayLine[3];
f32* preDelayPtr[3];
} _SND_REVHI_WORK;
typedef struct SND_AUX_REVERBHI {
_SND_REVHI_WORK rv;
bool8 tempDisableFX;
f32 coloration;
f32 mix;
f32 time;
f32 damping;
f32 preDelay;
f32 crosstalk;
} SND_AUX_REVERBHI;
void sndAuxCallbackReverbHI(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareReverbHI(SND_AUX_REVERBHI* rev);
bool sndAuxCallbackShutdownReverbHI(SND_AUX_REVERBHI* rev);
bool sndAuxCallbackUpdateSettingsReverbHI(SND_AUX_REVERBHI* rev);
// Delay AUX FX
//
typedef struct SND_AUX_DELAY {
u32 currentSize[3];
u32 currentPos[3];
u32 currentFeedback[3];
u32 currentOutput[3];
s32* left;
s32* right;
s32* sur;
// - - - - - - - - - - -
u32 delay[3]; // Delay buffer length in ms per channel
u32 feedback[3]; // Feedback volume in % per channel
u32 output[3]; // Output volume in % per channel
} SND_AUX_DELAY;
void sndAuxCallbackDelay(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareDelay(SND_AUX_DELAY* delay);
bool sndAuxCallbackShutdownDelay(SND_AUX_DELAY* delay);
bool sndAuxCallbackUpdateSettingsDelay(SND_AUX_DELAY* delay);
// Chorus AUX FX
typedef struct _SND_CHORUS_SRCINFO {
s32* dest;
s32* smpBase;
s32* old;
u32 posLo;
u32 posHi;
u32 pitchLo;
u32 pitchHi;
u32 trigger;
u32 target;
} _SND_CHORUS_SRCINFO;
#define _SND_CHORUS_NUM_BLOCKS 3
typedef struct _SND_CHORUS_WORK {
s32* lastLeft[_SND_CHORUS_NUM_BLOCKS];
s32* lastRight[_SND_CHORUS_NUM_BLOCKS];
s32* lastSur[_SND_CHORUS_NUM_BLOCKS];
u8 currentLast;
s32 oldLeft[4];
s32 oldRight[4];
s32 oldSur[4];
u32 currentPosLo;
u32 currentPosHi;
s32 pitchOffset;
u32 pitchOffsetPeriodCount;
u32 pitchOffsetPeriod;
_SND_CHORUS_SRCINFO src;
} _SND_CHORUS_WORK;
typedef struct SND_AUX_CHORUS {
_SND_CHORUS_WORK work;
u32 baseDelay; // Base delay of chorus effect in ms
u32 variation; // Variation of base delay in ms
u32 period; // Period of variational oscilation in ms
} SND_AUX_CHORUS;
void sndAuxCallbackChorus(u8 reason, SND_AUX_INFO* info, void* user);
bool sndAuxCallbackPrepareChorus(SND_AUX_CHORUS* ch);
bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch);
bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch);
// Studio linkage
typedef struct SND_STUDIO_INPUT {
u8 vol;
u8 volA;
u8 volB;
u8 srcStudio;
} SND_STUDIO_INPUT;
bool sndAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
bool sndRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc);
// 3D API
typedef struct SND_FVECTOR {
f32 x;
f32 y;
f32 z;
} SND_FVECTOR;
typedef struct SND_FMATRIX {
f32 m[3][3];
f32 t[3];
} SND_FMATRIX;
typedef struct SND_ROOM {
struct SND_ROOM* next;
struct SND_ROOM* prev;
u32 flags;
SND_FVECTOR pos; // World "position" of room
f32 distance; // Average distance to listeners (squared)
u8 studio;
void (*activateReverb)(u8 studio, void* para); // Callbacks to activate/deactivate "reverb" (AuxA)
void (*deActivateReverb)(u8 studio); // (NULL -> none)
void* user; // Pointer to user data (e.g. "reverb" parameters)
u32 curMVol; // Current master mix volume (7.16)
} SND_ROOM;
typedef struct SND_DOOR {
struct SND_DOOR* next;
struct SND_DOOR* prev;
SND_FVECTOR pos; // Position of door
f32 open; // State (0=closed, 1=open)
f32 dampen; // Dampening when closed (0=none, 1=full)
u8 fxVol; // FX mix volume of this door (0-127)
u8 destStudio; // When active: Studio the input is linked to
SND_ROOM* a; // Rooms to be linked
SND_ROOM* b;
u32 flags; // Flags
s16 filterCoef[4]; // Coefs of the 4 tab FIR filter (0x7FFF = 1.0)
SND_STUDIO_INPUT input; // Input info (when active)
} SND_DOOR;
#define SND_DOOR_A2B 0x00000000 // Door leads from A to B
#define SND_DOOR_B2A 0x00000001 // Door leads from B to A
#define SND_DOOR_DEFAULT SND_DOOR_A2B
typedef struct SND_LISTENER {
struct SND_LISTENER* next;
struct SND_LISTENER* prev;
SND_ROOM* room;
u32 flags;
SND_FVECTOR pos;
f32 volPosOff; // (reserved for future use)
SND_FVECTOR dir; // Speed in units/second
SND_FVECTOR heading;
SND_FVECTOR right;
SND_FVECTOR up;
SND_FMATRIX mat;
f32 surroundDisFront;
f32 surroundDisBack;
f32 soundSpeed;
f32 vol;
} SND_LISTENER;
#define SND_LISTENER_DEFAULT 0x00000000 // No special features are activated
#define SND_LISTENER_DOPPLERFX \
0x00000001 // Listener is supposed to be moving fast enough to display Dopller effects
typedef struct SND_EMITTER {
struct SND_EMITTER* next;
struct SND_EMITTER* prev;
SND_ROOM* room;
SND_PARAMETER_INFO* paraInfo;
u32 flags;
SND_FVECTOR pos;
SND_FVECTOR dir; // Speed in units/second
f32 maxDis;
f32 maxVol;
f32 minVol;
f32 volPush; // -1.0f = 1/square -> 0.0 = linear -> 1.0 = square
SND_VOICEID vid;
u32 group; // Group ID (by default FXID | 0x80000000) used to do volume priorities for continous
// emitters
SND_FXID fxid;
u8 studio;
u8 maxVoices; // Max. voices of the assigned FX
u16 VolLevelCnt; // Used during continous emitter allocation process
f32 fade; // Used to fade-in of continous emitters
} SND_EMITTER;
#define SND_EMITTER_DEFAULTKEY 0xFF
#define SND_EMITTER_DEFAULTVOL 0xFF
#define SND_EMITTER_DEFAULT 0x00000000 // No special features are activated
#define SND_EMITTER_CONTINOUS \
0x00000001 // Parameters should be updated over time (they will be set just once if not set)
#define SND_EMITTER_CONTINUOUS \
0x00000001 // Parameters should be updated over time (they will be set just once if not set)
#define SND_EMITTER_RESTARTABLE \
0x00000002 // If the used voice is reallocated, the sound should be restarted as soon as possible
#define SND_EMITTER_PAUSABLE \
0x00000004 // The sound may be stopped if it is no longer audible (and restarted if the above flag
// is set as soon as it's audibel again)
#define SND_EMITTER_DOPPLERFX \
0x00000008 // Emitter is supposed to be moving fast enough to display Doppler effects
#define SND_EMITTER_ITD \
0x00000010 // Enable ITD per default. The macro controlling the voice may still overwrite this
// setting
#define SND_EMITTER_HARDSTART \
0x00000020 // By default continous emitters are quickly faded in at startup to avoid pop sounds at
// restart. This disables this behavior
#define SND_EMITTER_NOSILENTSTART \
0x00000040 // Do not start emitter if the volume would be zero (it will be removed from the active
// list in this case)
//
// Setup / Change logical rooms
//
void sndSetup3DStudios(u8 first, u8 num);
bool sndAddRoom(SND_ROOM* room, SND_FVECTOR* pos, void (*activateReverb)(u8 studio, void* para),
void (*deActivateReverb)(u8 studio));
bool sndRemoveRoom(SND_ROOM* room);
bool sndUpdateRoom(SND_ROOM* room, SND_FVECTOR* pos);
bool sndAddDoor(SND_DOOR* door, SND_ROOM* a, SND_ROOM* b, SND_FVECTOR* pos, f32 dampen, f32 open,
u8 fxVol, s16 filterCoef[4], u32 flags);
bool sndRemoveDoor(SND_DOOR* door);
//
// Functions to add emitters to logical rooms
//
SND_VOICEID sndAddEmitter(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis, f32 comp,
u32 flags, SND_FXID fxid, u8 maxVol, u8 minVol, SND_ROOM* room);
SND_VOICEID sndAddEmitterEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis,
f32 comp, u32 flags, SND_FXID fxid, u16 groupid, u8 maxVol, u8 minVol,
SND_ROOM* room);
SND_VOICEID sndAddEmitterPara(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis,
f32 comp, u32 flags, SND_FXID fxid, u8 maxVol, u8 minVol,
SND_ROOM* room, SND_PARAMETER_INFO* para);
SND_VOICEID sndAddEmitterParaEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u16 groupid,
u8 maxVol, u8 minVol, SND_ROOM* room, SND_PARAMETER_INFO* para);
//
// Listener related functions
//
bool sndAddListener(SND_LISTENER* li, SND_FVECTOR* pos, SND_FVECTOR* dir, SND_FVECTOR* heading,
SND_FVECTOR* up, f32 front_sur, f32 back_sur, f32 soundSpeed, u32 flags, u8 vol,
SND_ROOM* room);
bool sndAddListenerEx(SND_LISTENER* li, SND_FVECTOR* pos, SND_FVECTOR* dir, SND_FVECTOR* heading,
SND_FVECTOR* up, f32 front_sur, f32 back_sur, f32 soundSpeed,
f32 volPosOffset, u32 flags, u8 vol, SND_ROOM* room);
bool sndUpdateListener(SND_LISTENER* li, SND_FVECTOR* pos, SND_FVECTOR* dir, SND_FVECTOR* heading,
SND_FVECTOR* up, u8 vol, SND_ROOM* room);
bool sndRemoveListener(SND_LISTENER* li);
//
// Functions to add emitters directly to a studio
//
SND_VOICEID sndAddEmitter2Studio(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis,
f32 comp, u32 flags, SND_FXID fxid, u8 maxVol, u8 minVol,
u8 studio);
SND_VOICEID sndAddEmitter2StudioEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u16 groupid,
u8 maxVol, u8 minVol, u8 studio);
SND_VOICEID sndAddEmitter2StudioPara(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u8 maxVol,
u8 minVol, u8 studio, SND_PARAMETER_INFO* para);
SND_VOICEID sndAddEmitter2StudioParaEx(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir,
f32 maxDis, f32 comp, u32 flags, SND_FXID fxid, u16 groupid,
u8 maxVol, u8 minVol, u8 studio, SND_PARAMETER_INFO* para);
//
// Maintain emitters
//
bool sndUpdateEmitter(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, u8 maxVol,
SND_ROOM* room);
bool sndRemoveEmitter(SND_EMITTER* em);
//
// Misc. 3D functions
//
bool sndCheckEmitter(SND_EMITTER* em);
SND_VOICEID sndEmitterVoiceID(SND_EMITTER* em);
typedef struct SND_3DINFO {
u8 vol;
u8 pan;
u8 span;
u16 doppler;
} SND_3DINFO;
void sndGet3DParameters(SND_3DINFO* info, SND_FVECTOR* pos, SND_FVECTOR* dir, f32 maxDis, f32 comp,
u8 maxVol, u8 minVol, SND_ROOM* room);
// ------------------------- Debug Functions -----------------------
u8 sndDbgGetActiveVoices(void);
void* sndConvert32BitSDIRTo64BitSDIR(void* sdir_int);
#ifdef __cplusplus
}
#endif
#endif // _MUSYX_MUSYX