007/include/PR/libaudio.h

607 lines
22 KiB
C

#ifndef _ULTRA64_LIBAUDIO_H_
#define _ULTRA64_LIBAUDIO_H_
#include "abi.h"
/***********************************************************************
* misc defines
***********************************************************************/
typedef u8 ALPan;
/***********************************************************************
* Audio Library global routines
***********************************************************************/
typedef struct ALLink_s {
struct ALLink_s *next;
struct ALLink_s *prev;
} ALLink;
typedef s32 (*ALDMAproc)(s32 addr, s32 len, void *state);
typedef ALDMAproc (*ALDMANew)(void *state);
#define AL_FX_NONE 0
#define AL_FX_SMALLROOM 1
#define AL_FX_BIGROOM 2
#define AL_FX_CHORUS 3
#define AL_FX_FLANGE 4
#define AL_FX_ECHO 5
#define AL_FX_CUSTOM 6
typedef u8 ALFxId;
typedef s32 ALMicroTime;
typedef struct {
u8 *base;
u8 *current;
s32 len;
s32 count;
} ALHeap;
typedef struct {
s32 maxVVoices; /* obsolete */
s32 maxPVoices;
s32 maxUpdates;
s32 maxFXbusses;
void *dmaproc;
ALHeap *heap;
s32 outputRate;
ALFxId fxType;
s32 *params;
} ALSynConfig;
void alHeapInit(ALHeap *hp, u8 *base, s32 len);
void *alHeapDBAlloc(u8 *file, s32 line, ALHeap *hp, s32 num, s32 size);
#ifdef DEBUG
#define alHeapAlloc(hp, elem ,size) alHeapDBAlloc((u8 *) __FILE__,__LINE__,(hp),(elem),(size))
#else
#define alHeapAlloc(hp, elem ,size) alHeapDBAlloc(0, 0,(hp),(elem),(size))
#endif
/***********************************************************************
* data structures for sound banks
***********************************************************************/
typedef struct {
s32 order;
s32 npredictors;
s16 book[1]; /* Actually variable size. Must be 8-byte aligned */
} ALADPCMBook;
typedef struct {
u32 start;
u32 end;
u32 count;
ADPCM_STATE state;
} ALADPCMloop;
typedef struct {
u32 start;
u32 end;
u32 count;
} ALRawLoop;
typedef struct {
ALMicroTime attackTime;
ALMicroTime decayTime;
ALMicroTime releaseTime;
u8 attackVolume;
u8 decayVolume;
} ALEnvelope;
typedef struct {
u8 velocityMin;
u8 velocityMax;
u8 keyMin;
u8 keyMax;
u8 keyBase;
s8 detune;
} ALKeyMap;
typedef struct {
ALADPCMloop *loop;
ALADPCMBook *book;
} ALADPCMWaveInfo;
typedef struct {
ALRawLoop *loop;
} ALRAWWaveInfo;
typedef struct ALWaveTable_s {
u8 *base; /* ptr to start of wave data */
s32 len; /* length of data in bytes */
u8 type; /* compression type */
u8 flags; /* offset/address flags */
union {
ALADPCMWaveInfo adpcmWave;
ALRAWWaveInfo rawWave;
} waveInfo;
} ALWaveTable;
typedef struct ALSound_s {
ALEnvelope *envelope;
ALKeyMap *keyMap;
ALWaveTable *wavetable; /* offset to wavetable struct */
ALPan samplePan;
u8 sampleVolume;
u8 flags;
} ALSound;
typedef struct {
u8 volume; /* overall volume for this instrument */
ALPan pan; /* 0 = hard left, 127 = hard right */
u8 priority; /* voice priority for this instrument */
u8 flags;
u8 tremType; /* the type of tremelo osc. to use */
u8 tremRate; /* the rate of the tremelo osc. */
u8 tremDepth; /* the depth of the tremelo osc */
u8 tremDelay; /* the delay for the tremelo osc */
u8 vibType; /* the type of tremelo osc. to use */
u8 vibRate; /* the rate of the tremelo osc. */
u8 vibDepth; /* the depth of the tremelo osc */
u8 vibDelay; /* the delay for the tremelo osc */
s16 bendRange; /* pitch bend range in cents */
s16 soundCount; /* number of sounds in this array */
ALSound *soundArray[1];
} ALInstrument;
typedef struct ALBank_s {
s16 instCount; /* number of programs in this bank */
u8 flags;
u8 pad;
s32 sampleRate; /* e.g. 44100, 22050, etc... */
ALInstrument *percussion; /* default percussion for GM */
ALInstrument *instArray[1]; /* ARRAY of instruments */
} ALBank;
typedef struct { /* Note: sizeof won't be correct */
s16 revision; /* format revision of this file */
s16 bankCount; /* number of banks */
ALBank *bankArray[1]; /* ARRAY of bank offsets */
} ALBankFile;
void alBnkfNew(ALBankFile *f, u8 *table);
/***********************************************************************
* Synthesis driver stuff
***********************************************************************/
typedef ALMicroTime (*ALVoiceHandler)(void *);
typedef struct ALPlayer_s {
struct ALPlayer_s *next;
void *clientData; /* storage for client callback */
ALVoiceHandler handler; /* voice handler for player */
ALMicroTime callTime; /* usec requested callback */
s32 samplesLeft; /* usec remaining to callback */
} ALPlayer;
typedef struct ALVoice_s {
ALLink node;
struct PVoice_s *pvoice;
ALWaveTable *table;
void *clientPrivate;
s16 state;
s16 priority;
s16 fxBus;
s16 unityPitch;
} ALVoice;
typedef struct {
ALPlayer *head; /* client list head */
ALLink pFreeList; /* list of free physical voices */
ALLink pAllocList; /* list of allocated physical voices */
ALLink pLameList; /* list of voices ready to be freed */
s32 paramSamples;
s32 curSamples; /* samples from start of game */
ALDMANew dma;
ALHeap *heap;
struct ALParam_s *paramList;
struct ALMainBus_s *mainBus;
struct ALAuxBus_s *auxBus; /* ptr to array of aux bus structs */
struct ALFilter_s *outputFilter; /* last filter in the filter chain */
s32 numPVoices;
s32 maxAuxBusses;
s32 outputRate; /* output sample rate */
s32 maxOutSamples; /* Maximum samples rsp can generate
at one time at output rate */
} ALSynth;
/***********************************************************************
* Audio Library (AL) stuff
***********************************************************************/
typedef struct {
ALSynth drvr;
} ALGlobals;
/***********************************************************************
* Sequence Files
***********************************************************************/
/**
* Metadata for a sequence "file" entry / data content of single sequence.
* Based on original ALSeqData in n64devkit\ultra\usr\include\PR\libaudio.h.
*/
typedef struct
{
u8 *address;
u16 offset;
u16 len;
} ALSeqData;
/**
* Structure for storing collection of sequence metadatas.
* Based on original ALSeqFile in n64devkit\ultra\usr\include\PR\libaudio.h.
*/
typedef struct
{
/**
* number of sequences.
*/
u16 seqCount;
/**
* Unknown, maybe revision.
*/
u16 unk;
/**
* ARRAY of sequence info. This is a "dynamic" array, more space
* will be allocated from ALHeap at runtime.
*/
ALSeqData seqArray[1];
} ALSeqFile;
void alSeqFileNew(ALSeqFile *f, u8 *base);
/***********************************************************************
* Audio Library (AL) stuff
***********************************************************************/
typedef struct {
u8 *curPtr; /* ptr to the next event */
s32 lastTicks; /* sequence clock ticks (used by alSeqSetLoc) */
s32 curTicks; /* sequence clock ticks of next event (used by loop end test) */
s16 lastStatus; /* the last status msg */
} ALSeqMarker;
typedef struct {
s32 ticks; /* MIDI, Tempo and End events must start with ticks */
u8 status;
u8 byte1;
u8 byte2;
u32 duration;
} ALMIDIEvent;
typedef struct {
s32 ticks;
u8 status;
u8 type;
u8 len;
u8 byte1;
u8 byte2;
u8 byte3;
} ALTempoEvent;
typedef struct {
s32 ticks;
u8 status;
u8 type;
u8 len;
} ALEndEvent;
typedef struct {
struct ALVoice_s *voice;
} ALNoteEvent;
typedef struct {
struct ALVoice_s *voice;
ALMicroTime delta;
u8 vol;
} ALVolumeEvent;
typedef struct {
s16 vol;
} ALSeqpVolEvent;
typedef struct {
ALSeqMarker *start;
ALSeqMarker *end;
s32 count;
} ALSeqpLoopEvent;
typedef struct {
u8 chan;
u8 priority;
} ALSeqpPriorityEvent;
typedef struct {
void *seq; /* pointer to a seq (could be an ALSeq or an ALCSeq). */
} ALSeqpSeqEvent;
typedef struct {
ALBank *bank;
} ALSeqpBankEvent;
typedef struct {
struct ALVoiceState_s *vs;
void *oscState;
u8 chan;
} ALOscEvent;
typedef struct {
s16 type;
union {
ALMIDIEvent midi;
ALTempoEvent tempo;
ALEndEvent end;
ALNoteEvent note;
ALVolumeEvent vol;
ALSeqpLoopEvent loop;
ALSeqpVolEvent spvol;
ALSeqpPriorityEvent sppriority;
ALSeqpSeqEvent spseq;
ALSeqpBankEvent spbank;
ALOscEvent osc;
} msg;
} ALEvent;
typedef struct {
ALLink freeList;
ALLink allocList;
s32 eventCount;
} ALEventQueue;
typedef struct {
ALInstrument *instrument; /* instrument assigned to this chan */
s16 bendRange; /* pitch bend range in cents */
ALFxId fxId; /* type of fx assigned to this chan */
ALPan pan; /* overall pan for this chan */
u8 priority; /* priority for this chan */
u8 vol; /* current volume for this chan */
u8 fxmix; /* current fx mix for this chan */
u8 sustain; /* current sustain pedal state */
f32 pitchBend; /* current pitch bend val in cents */
} ALChanState;
typedef struct ALVoiceState_s {
struct ALVoiceState_s *next;/* MUST be first */
ALVoice voice;
ALSound *sound;
ALMicroTime envEndTime; /* time of envelope segment end */
f32 pitch; /* currect pitch ratio */
f32 vibrato; /* current value of the vibrato */
u8 envGain; /* current envelope gain */
u8 channel; /* channel assignment */
u8 key; /* note on key number */
u8 velocity; /* note on velocity */
u8 envPhase; /* what envelope phase */
u8 phase;
u8 tremelo; /* current value of the tremelo */
u8 flags; /* bit 0 tremelo flag
bit 1 vibrato flag */
} ALVoiceState;
typedef struct ALSeq_s {
u8 *base; /* ptr to start of sequence file */
u8 *trackStart; /* ptr to first MIDI event */
u8 *curPtr; /* ptr to next event to read */
s32 lastTicks; /* MIDI ticks for last event */
s32 len; /* length of sequence in bytes */
f32 qnpt; /* qrter notes / tick (1/division) */
s16 division; /* ticks per quarter note */
s16 lastStatus; /* for running status */
} ALSeq;
typedef struct {
u32 trackOffset[16];
u32 division;
} ALCMidiHdr;
typedef struct ALCSeq_s {
ALCMidiHdr *base; /* ptr to start of sequence file */
u32 validTracks; /* set of flags, showing valid tracks */
f32 qnpt; /* qrter notes / tick (1/division) */
u32 lastTicks; /* keep track of ticks incase app wants */
u32 lastDeltaTicks; /* number of delta ticks of last event */
u32 deltaFlag; /* flag: set if delta's not subtracted */
u8 *curLoc[16]; /* ptr to current track location, */
/* may point to next event, or may point */
/* to a backup code */
u8 *curBUPtr[16]; /* ptr to next event if in backup mode */
u8 curBULen[16]; /* if > 0, then in backup mode */
u8 lastStatus[16]; /* for running status */
u32 evtDeltaTicks[16]; /* delta time to next event */
} ALCSeq;
typedef struct {
u32 validTracks;
s32 lastTicks;
u32 lastDeltaTicks;
u8 *curLoc[16];
u8 *curBUPtr[16];
u8 curBULen[16];
u8 lastStatus[16];
u32 evtDeltaTicks[16];
} ALCSeqMarker;
typedef struct ALSeqpConfig_s {
s32 maxVoices; /* max number of voices to alloc */
s32 maxEvents; /* max internal events to support */
u8 maxChannels; /* max MIDI channels to support (16)*/
u8 debugFlags; /* control which error get reported */
ALHeap *heap; /* ptr to initialized heap */
void *initOsc;
void *updateOsc;
void *stopOsc;
} ALSeqpConfig;
typedef ALMicroTime (*ALOscInit)(void **oscState,f32 *initVal, u8 oscType,
u8 oscRate, u8 oscDepth, u8 oscDelay);
typedef ALMicroTime (*ALOscUpdate)(void *oscState, f32 *updateVal);
typedef void (*ALOscStop)(void *oscState);
typedef struct {
ALPlayer node; /* note: must be first in structure */
ALSynth *drvr; /* reference to the client driver */
ALSeq *target; /* current sequence */
ALMicroTime curTime;
ALBank *bank; /* current ALBank */
s32 uspt; /* microseconds per tick */
s32 nextDelta; /* microseconds to next callback */
s32 state;
u16 chanMask; /* active channels */
s16 vol; /* overall sequence volume */
u8 maxChannels; /* number of MIDI channels */
u8 debugFlags; /* control which error get reported */
ALEvent nextEvent;
ALEventQueue evtq;
ALMicroTime frameTime;
ALChanState *chanState; /* 16 channels for MIDI */
ALVoiceState *vAllocHead; /* list head for allocated voices */
ALVoiceState *vAllocTail; /* list tail for allocated voices */
ALVoiceState *vFreeList; /* list of free voice state structs */
ALOscInit initOsc;
ALOscUpdate updateOsc;
ALOscStop stopOsc;
ALSeqMarker *loopStart;
ALSeqMarker *loopEnd;
s32 loopCount; /* -1 = loop forever, 0 = no loop */
} ALSeqPlayer;
typedef struct {
ALPlayer node; /* note: must be first in structure */
ALSynth *drvr; /* reference to the client driver */
ALCSeq *target; /* current sequence */
ALMicroTime curTime;
ALBank *bank; /* current ALBank */
s32 uspt; /* microseconds per tick */
s32 nextDelta; /* microseconds to next callback */
s32 state;
u16 chanMask; /* active channels */
s16 vol; /* overall sequence volume */
u8 maxChannels; /* number of MIDI channels */
u8 debugFlags; /* control which error get reported */
ALEvent nextEvent;
ALEventQueue evtq;
ALMicroTime frameTime;
ALChanState *chanState; /* 16 channels for MIDI */
ALVoiceState *vAllocHead; /* list head for allocated voices */
ALVoiceState *vAllocTail; /* list tail for allocated voices */
ALVoiceState *vFreeList; /* list of free voice state structs */
ALOscInit initOsc;
ALOscUpdate updateOsc;
ALOscStop stopOsc;
} ALCSPlayer;
/*
* Sequence data representation routines
*/
void alSeqNew(ALSeq *seq, u8 *ptr, s32 len);
void alSeqNextEvent(ALSeq *seq, ALEvent *event);
s32 alSeqGetTicks(ALSeq *seq);
f32 alSeqTicksToSec(ALSeq *seq, s32 ticks, u32 tempo);
u32 alSeqSecToTicks(ALSeq *seq, f32 sec, u32 tempo);
void alSeqNewMarker(ALSeq *seq, ALSeqMarker *m, u32 ticks);
void alSeqSetLoc(ALSeq *seq, ALSeqMarker *marker);
void alSeqGetLoc(ALSeq *seq, ALSeqMarker *marker);
/*
* Compact Sequence data representation routines
*/
void alCSeqNew(ALCSeq *seq, u8 *ptr);
void alCSeqNextEvent(ALCSeq *seq,ALEvent *evt);
s32 alCSeqGetTicks(ALCSeq *seq);
f32 alCSeqTicksToSec(ALCSeq *seq, s32 ticks, u32 tempo);
u32 alCSeqSecToTicks(ALCSeq *seq, f32 sec, u32 tempo);
void alCSeqNewMarker(ALCSeq *seq, ALCSeqMarker *m, u32 ticks);
void alCSeqSetLoc(ALCSeq *seq, ALCSeqMarker *marker);
void alCSeqGetLoc(ALCSeq *seq, ALCSeqMarker *marker);
/*
* Sequence Player routines
*/
f32 alCents2Ratio(s32 cents);
void alSeqpNew(ALSeqPlayer *seqp, ALSeqpConfig *config);
void alSeqpDelete(ALSeqPlayer *seqp);
void alSeqpSetSeq(ALSeqPlayer *seqp, ALSeq *seq);
ALSeq *alSeqpGetSeq(ALSeqPlayer *seqp);
void alSeqpPlay(ALSeqPlayer *seqp);
void alSeqpStop(ALSeqPlayer *seqp);
s32 alSeqpGetState(ALSeqPlayer *seqp);
void alSeqpSetBank(ALSeqPlayer *seqp, ALBank *b);
void alSeqpSetTempo(ALSeqPlayer *seqp, s32 tempo);
s32 alSeqpGetTempo(ALSeqPlayer *seqp);
s16 alSeqpGetVol(ALSeqPlayer *seqp); /* Master volume control */
void alSeqpSetVol(ALSeqPlayer *seqp, s16 vol);
void alSeqpLoop(ALSeqPlayer *seqp, ALSeqMarker *start, ALSeqMarker *end, s32 count);
void alSeqpSetChlProgram(ALSeqPlayer *seqp, u8 chan, u8 prog);
s32 alSeqpGetChlProgram(ALSeqPlayer *seqp, u8 chan);
void alSeqpSetChlFXMix(ALSeqPlayer *seqp, u8 chan, u8 fxmix);
u8 alSeqpGetChlFXMix(ALSeqPlayer *seqp, u8 chan);
void alSeqpSetChlVol(ALSeqPlayer *seqp, u8 chan, u8 vol);
u8 alSeqpGetChlVol(ALSeqPlayer *seqp, u8 chan);
void alSeqpSetChlPan(ALSeqPlayer *seqp, u8 chan, ALPan pan);
ALPan alSeqpGetChlPan(ALSeqPlayer *seqp, u8 chan);
void alSeqpSetChlPriority(ALSeqPlayer *seqp, u8 chan, u8 priority);
u8 alSeqpGetChlPriority(ALSeqPlayer *seqp, u8 chan);
void alSeqpSendMidi(ALSeqPlayer *seqp, s32 ticks, u8 status, u8 byte1, u8 byte2);
/* Maintain backwards compatibility with old routine names. */
#define alSeqpSetProgram alSeqpSetChlProgram
#define alSeqpGetProgram alSeqpGetChlProgram
#define alSeqpSetFXMix alSeqpSetChlFXMix
#define alSeqpGetFXMix alSeqpGetChlFXMix
#define alSeqpSetPan alSeqpSetChlPan
#define alSeqpGetPan alSeqpGetChlPan
#define alSeqpSetChannelPriority alSeqpSetChlPriority
#define alSeqpGetChannelPriority alSeqpGetChlPriority
/*
* Compressed Sequence Player routines
*/
void alCSPNew(ALCSPlayer *seqp, ALSeqpConfig *config);
void alCSPDelete(ALCSPlayer *seqp);
void alCSPSetSeq(ALCSPlayer *seqp, ALCSeq *seq);
ALCSeq *alCSPGetSeq(ALCSPlayer *seqp);
void alCSPPlay(ALCSPlayer *seqp);
void alCSPStop(ALCSPlayer *seqp);
s32 alCSPGetState(ALCSPlayer *seqp);
void alCSPSetBank(ALCSPlayer *seqp, ALBank *b);
void alCSPSetTempo(ALCSPlayer *seqp, s32 tempo);
s32 alCSPGetTempo(ALCSPlayer *seqp);
s16 alCSPGetVol(ALCSPlayer *seqp);
void alCSPSetVol(ALCSPlayer *seqp, s16 vol);
void alCSPSetChlProgram(ALCSPlayer *seqp, u8 chan, u8 prog);
s32 alCSPGetChlProgram(ALCSPlayer *seqp, u8 chan);
void alCSPSetChlFXMix(ALCSPlayer *seqp, u8 chan, u8 fxmix);
u8 alCSPGetChlFXMix(ALCSPlayer *seqp, u8 chan);
void alCSPSetChlPan(ALCSPlayer *seqp, u8 chan, ALPan pan);
ALPan alCSPGetChlPan(ALCSPlayer *seqp, u8 chan);
void alCSPSetChlVol(ALCSPlayer *seqp, u8 chan, u8 vol);
u8 alCSPGetChlVol(ALCSPlayer *seqp, u8 chan);
void alCSPSetChlPriority(ALCSPlayer *seqp, u8 chan, u8 priority);
u8 alCSPGetChlPriority(ALCSPlayer *seqp, u8 chan);
void alCSPSendMidi(ALCSPlayer *seqp, s32 ticks, u8 status,
u8 byte1, u8 byte2);
/* Maintain backwards compatibility with old routine names. */
#define alCSPSetProgram alCSPSetChlProgram
#define alCSPGetProgram alCSPGetChlProgram
#define alCSPSetFXMix alCSPSetChlFXMix
#define alCSPGetFXMix alCSPGetChlFXMix
#define alCSPSetPan alCSPSetChlPan
#define alCSPGetPan alCSPGetChlPan
#define alCSPSetChannelPriority alCSPSetChlPriority
#define alCSPGetChannelPriority alCSPGetChlPriority
#endif