You've already forked hackerlibultra
mirror of
https://github.com/HackerN64/hackerlibultra.git
synced 2026-01-21 10:37:53 -08:00
* set build options * remove COMPARE and MDOERN_* switches * remove tools makefile * AR patching is gone too since we want a fullly decomped version * AR is modern * remove cwd changes * edit my own tool to fix compile errors * compile files generated with my own tool instead of the originals * inline modern_gcc makefile * port mips toolchain detection logic * add util.mk for find-command * remove forced AR order and strip/mdebug removal commands * add -mabi=32 to as flags * formatting changes * add clang format files * formatting changes * make libgultra CI work * install mips gcc too * add format check tools * Add formatting to CI * Add CI (#4) * make libgultra CI work * install mips gcc too * remove make setup --------- Co-authored-by: someone2639 <someone2639@gmail.com> * we don't use clang-tidy * use 120 width for formatting * a * address clang-tidy messing up * test * align consecutive macros and declarations * only align macros for now * SpaceAfterCStyleCast: false * format headers too * remove cast space switch because its false by default * pointers on left * AlignConsecutiveBitFields: true * install clang-format and clang-tidy on gh actions * and clang-tools * show diff in format check tool * make CI work --------- Co-authored-by: someone2639 <someone2639@gmail.com> 🙏
935 lines
31 KiB
C
935 lines
31 KiB
C
/*====================================================================
|
|
* libaudio.h
|
|
*
|
|
* Copyright 1993, Silicon Graphics, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
|
|
* Inc.; the contents of this file may not be disclosed to third
|
|
* parties, copied or duplicated in any form, in whole or in part,
|
|
* without the prior written permission of Silicon Graphics, Inc.
|
|
*
|
|
* RESTRICTED RIGHTS LEGEND:
|
|
* Use, duplication or disclosure by the Government is subject to
|
|
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights
|
|
* in Technical Data and Computer Software clause at DFARS
|
|
* 252.227-7013, and/or in similar or successor clauses in the FAR,
|
|
* DOD or NASA FAR Supplement. Unpublished - rights reserved under the
|
|
* Copyright Laws of the United States.
|
|
*====================================================================*/
|
|
|
|
/**************************************************************************
|
|
*
|
|
* $Revision: 1.173 $
|
|
* $Date: 1997/12/01 12:42:21 $
|
|
* $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/libaudio.h,v $
|
|
*
|
|
**************************************************************************/
|
|
|
|
#ifndef __LIB_AUDIO__
|
|
#define __LIB_AUDIO__
|
|
|
|
#ifdef _LANGUAGE_C_PLUS_PLUS
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <PR/ultratypes.h>
|
|
#include <PR/mbi.h>
|
|
|
|
/***********************************************************************
|
|
* misc defines
|
|
***********************************************************************/
|
|
#ifndef _EMULATOR
|
|
#ifdef AUD_PROFILE
|
|
|
|
#define PROFILE_AUD(num, cnt, max, min) \
|
|
{ \
|
|
u32 currCnt = osGetCount(); \
|
|
currCnt -= lastCnt[cnt_index]; \
|
|
cnt_index--; \
|
|
cnt += currCnt; \
|
|
num++; \
|
|
\
|
|
if (currCnt > max) \
|
|
max = currCnt; \
|
|
if (currCnt < min) \
|
|
min = currCnt; \
|
|
}
|
|
|
|
#endif /* AUD_PROFILE */
|
|
#endif /* EMULATOR */
|
|
|
|
#ifndef NULL
|
|
#define NULL 0
|
|
#endif
|
|
|
|
#define AL_FX_BUFFER_SIZE 8192
|
|
#define AL_FRAME_INIT -1
|
|
#define AL_USEC_PER_FRAME 16000
|
|
#define AL_MAX_PRIORITY 127
|
|
#define AL_GAIN_CHANGE_TIME 1000
|
|
|
|
typedef s32 ALMicroTime;
|
|
typedef u8 ALPan;
|
|
|
|
#define AL_PAN_CENTER 64
|
|
#define AL_PAN_LEFT 0
|
|
#define AL_PAN_RIGHT 127
|
|
#define AL_VOL_FULL 127
|
|
#define AL_KEY_MIN 0
|
|
#define AL_KEY_MAX 127
|
|
#define AL_DEFAULT_FXMIX 0
|
|
#define AL_SUSTAIN 63
|
|
|
|
/***********************************************************************
|
|
* Error handling
|
|
***********************************************************************/
|
|
|
|
#ifdef _DEBUG
|
|
#define ALFailIf(condition, error) \
|
|
if (condition) { \
|
|
__osError(error, 0); \
|
|
return; \
|
|
}
|
|
|
|
#else
|
|
#define ALFailIf(condition, error) \
|
|
if (condition) { \
|
|
return; \
|
|
}
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#define ALFlagFailIf(condition, flag, error) \
|
|
if (condition) { \
|
|
if (flag) \
|
|
__osError(error, 0); \
|
|
return; \
|
|
}
|
|
|
|
#else
|
|
#define ALFlagFailIf(condition, flag, error) \
|
|
if (condition) { \
|
|
return; \
|
|
}
|
|
#endif
|
|
|
|
/***********************************************************************
|
|
* Audio Library global routines
|
|
***********************************************************************/
|
|
typedef struct ALLink_s {
|
|
struct ALLink_s* next;
|
|
struct ALLink_s* prev;
|
|
} ALLink;
|
|
|
|
void alUnlink(ALLink* element);
|
|
void alLink(ALLink* element, ALLink* after);
|
|
|
|
typedef s32 (*ALDMAproc)(s32 addr, s32 len, void* state);
|
|
typedef ALDMAproc (*ALDMANew)(void* state);
|
|
|
|
void alCopy(void* src, void* dest, s32 len);
|
|
|
|
typedef struct {
|
|
u8* base;
|
|
u8* cur;
|
|
s32 len;
|
|
s32 count;
|
|
} ALHeap;
|
|
|
|
#define AL_HEAP_DEBUG 1
|
|
#define AL_HEAP_MAGIC 0x20736a73
|
|
#define AL_HEAP_INIT 0
|
|
|
|
void alHeapInit(ALHeap* hp, u8* base, s32 len);
|
|
void* alHeapDBAlloc(u8* file, s32 line, ALHeap* hp, s32 num, s32 size);
|
|
s32 alHeapCheck(ALHeap* hp);
|
|
|
|
#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
|
|
|
|
/***********************************************************************
|
|
* FX Stuff
|
|
***********************************************************************/
|
|
#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 void* ALFxRef;
|
|
|
|
/***********************************************************************
|
|
* data structures for sound banks
|
|
***********************************************************************/
|
|
|
|
#define AL_BANK_VERSION 0x4231 /* 'B1' */
|
|
|
|
/* Possible wavetable types */
|
|
enum { AL_ADPCM_WAVE = 0, AL_RAW16_WAVE };
|
|
|
|
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);
|
|
|
|
/***********************************************************************
|
|
* Sequence Files
|
|
***********************************************************************/
|
|
#define AL_SEQBANK_VERSION 'S1'
|
|
|
|
typedef struct {
|
|
u8* offset;
|
|
s32 len;
|
|
} ALSeqData;
|
|
|
|
typedef struct { /* Note: sizeof won't be correct */
|
|
s16 revision; /* format revision of this file */
|
|
s16 seqCount; /* number of sequences */
|
|
ALSeqData seqArray[1]; /* ARRAY of sequence info */
|
|
} ALSeqFile;
|
|
|
|
void alSeqFileNew(ALSeqFile* f, u8* base);
|
|
|
|
/***********************************************************************
|
|
* Synthesis driver stuff
|
|
***********************************************************************/
|
|
typedef ALMicroTime (*ALVoiceHandler)(void*);
|
|
|
|
typedef struct {
|
|
s32 maxVVoices; /* obsolete */
|
|
s32 maxPVoices;
|
|
s32 maxUpdates;
|
|
s32 maxFXbusses;
|
|
void* dmaproc;
|
|
ALHeap* heap;
|
|
s32 outputRate; /* output sample rate */
|
|
ALFxId fxType;
|
|
s32* params;
|
|
} ALSynConfig;
|
|
|
|
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 ALVoiceConfig_s {
|
|
s16 priority; /* voice priority */
|
|
s16 fxBus; /* bus assignment */
|
|
u8 unityPitch; /* unity pitch flag */
|
|
} ALVoiceConfig;
|
|
|
|
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;
|
|
|
|
void alSynNew(ALSynth* s, ALSynConfig* config);
|
|
void alSynDelete(ALSynth* s);
|
|
|
|
void alSynAddPlayer(ALSynth* s, ALPlayer* client);
|
|
void alSynRemovePlayer(ALSynth* s, ALPlayer* client);
|
|
|
|
s32 alSynAllocVoice(ALSynth* s, ALVoice* v, ALVoiceConfig* vc);
|
|
void alSynFreeVoice(ALSynth* s, ALVoice* voice);
|
|
|
|
void alSynStartVoice(ALSynth* s, ALVoice* voice, ALWaveTable* w);
|
|
void alSynStartVoiceParams(ALSynth* s, ALVoice* voice, ALWaveTable* w, f32 pitch, s16 vol, ALPan pan, u8 fxmix,
|
|
ALMicroTime t);
|
|
void alSynStopVoice(ALSynth* s, ALVoice* voice);
|
|
|
|
void alSynSetVol(ALSynth* s, ALVoice* v, s16 vol, ALMicroTime delta);
|
|
void alSynSetPitch(ALSynth* s, ALVoice* voice, f32 ratio);
|
|
void alSynSetPan(ALSynth* s, ALVoice* voice, ALPan pan);
|
|
void alSynSetFXMix(ALSynth* s, ALVoice* voice, u8 fxmix);
|
|
void alSynSetPriority(ALSynth* s, ALVoice* voice, s16 priority);
|
|
s16 alSynGetPriority(ALSynth* s, ALVoice* voice);
|
|
|
|
ALFxRef* alSynAllocFX(ALSynth* s, s16 bus, ALSynConfig* c, ALHeap* hp);
|
|
ALFxRef alSynGetFXRef(ALSynth* s, s16 bus, s16 index);
|
|
void alSynFreeFX(ALSynth* s, ALFxRef* fx);
|
|
void alSynSetFXParam(ALSynth* s, ALFxRef fx, s16 paramID, void* param);
|
|
|
|
/***********************************************************************
|
|
* Audio Library (AL) stuff
|
|
***********************************************************************/
|
|
typedef struct {
|
|
ALSynth drvr;
|
|
} ALGlobals;
|
|
|
|
extern ALGlobals* alGlobals;
|
|
|
|
void alInit(ALGlobals* glob, ALSynConfig* c);
|
|
void alClose(ALGlobals* glob);
|
|
|
|
Acmd* alAudioFrame(Acmd* cmdList, s32* cmdLen, s16* outBuf, s32 outLen);
|
|
|
|
/***********************************************************************
|
|
* Sequence Player stuff
|
|
***********************************************************************/
|
|
|
|
/*
|
|
* Play states
|
|
*/
|
|
#define AL_STOPPED 0
|
|
#define AL_PLAYING 1
|
|
#define AL_STOPPING 2
|
|
|
|
#define AL_DEFAULT_PRIORITY 5
|
|
#define AL_DEFAULT_VOICE 0
|
|
#define AL_MAX_CHANNELS 16
|
|
|
|
/*
|
|
* Audio Library event type definitions
|
|
*/
|
|
enum ALMsg {
|
|
AL_SEQ_REF_EVT, /* Reference to a pending event in the sequence. */
|
|
AL_SEQ_MIDI_EVT,
|
|
AL_SEQP_MIDI_EVT,
|
|
AL_TEMPO_EVT,
|
|
AL_SEQ_END_EVT,
|
|
AL_NOTE_END_EVT,
|
|
AL_SEQP_ENV_EVT,
|
|
AL_SEQP_META_EVT,
|
|
AL_SEQP_PROG_EVT,
|
|
AL_SEQP_API_EVT,
|
|
AL_SEQP_VOL_EVT,
|
|
AL_SEQP_LOOP_EVT,
|
|
AL_SEQP_PRIORITY_EVT,
|
|
AL_SEQP_SEQ_EVT,
|
|
AL_SEQP_BANK_EVT,
|
|
AL_SEQP_PLAY_EVT,
|
|
AL_SEQP_STOP_EVT,
|
|
AL_SEQP_STOPPING_EVT,
|
|
AL_TRACK_END,
|
|
AL_CSP_LOOPSTART,
|
|
AL_CSP_LOOPEND,
|
|
AL_CSP_NOTEOFF_EVT,
|
|
AL_TREM_OSC_EVT,
|
|
AL_VIB_OSC_EVT
|
|
};
|
|
|
|
/*
|
|
* Midi event definitions
|
|
*/
|
|
#define AL_EVTQ_END 0x7fffffff
|
|
|
|
enum AL_MIDIstatus {
|
|
/* For distinguishing channel number from status */
|
|
AL_MIDI_ChannelMask = 0x0F,
|
|
AL_MIDI_StatusMask = 0xF0,
|
|
|
|
/* Channel voice messages */
|
|
AL_MIDI_ChannelVoice = 0x80,
|
|
AL_MIDI_NoteOff = 0x80,
|
|
AL_MIDI_NoteOn = 0x90,
|
|
AL_MIDI_PolyKeyPressure = 0xA0,
|
|
AL_MIDI_ControlChange = 0xB0,
|
|
AL_MIDI_ChannelModeSelect = 0xB0,
|
|
AL_MIDI_ProgramChange = 0xC0,
|
|
AL_MIDI_ChannelPressure = 0xD0,
|
|
AL_MIDI_PitchBendChange = 0xE0,
|
|
|
|
/* System messages */
|
|
AL_MIDI_SysEx = 0xF0, /* System Exclusive */
|
|
|
|
/* System common */
|
|
AL_MIDI_SystemCommon = 0xF1,
|
|
AL_MIDI_TimeCodeQuarterFrame = 0xF1,
|
|
AL_MIDI_SongPositionPointer = 0xF2,
|
|
AL_MIDI_SongSelect = 0xF3,
|
|
AL_MIDI_Undefined1 = 0xF4,
|
|
AL_MIDI_Undefined2 = 0xF5,
|
|
AL_MIDI_TuneRequest = 0xF6,
|
|
AL_MIDI_EOX = 0xF7, /* End of System Exclusive */
|
|
|
|
/* System real time */
|
|
AL_MIDI_SystemRealTime = 0xF8,
|
|
AL_MIDI_TimingClock = 0xF8,
|
|
AL_MIDI_Undefined3 = 0xF9,
|
|
AL_MIDI_Start = 0xFA,
|
|
AL_MIDI_Continue = 0xFB,
|
|
AL_MIDI_Stop = 0xFC,
|
|
AL_MIDI_Undefined4 = 0xFD,
|
|
AL_MIDI_ActiveSensing = 0xFE,
|
|
AL_MIDI_SystemReset = 0xFF,
|
|
AL_MIDI_Meta = 0xFF /* MIDI Files only */
|
|
};
|
|
|
|
enum AL_MIDIctrl {
|
|
AL_MIDI_VOLUME_CTRL = 0x07,
|
|
AL_MIDI_PAN_CTRL = 0x0A,
|
|
AL_MIDI_PRIORITY_CTRL = 0x10, /* use general purpose controller for priority */
|
|
AL_MIDI_FX_CTRL_0 = 0x14,
|
|
AL_MIDI_FX_CTRL_1 = 0x15,
|
|
AL_MIDI_FX_CTRL_2 = 0x16,
|
|
AL_MIDI_FX_CTRL_3 = 0x17,
|
|
AL_MIDI_FX_CTRL_4 = 0x18,
|
|
AL_MIDI_FX_CTRL_5 = 0x19,
|
|
AL_MIDI_FX_CTRL_6 = 0x1A,
|
|
AL_MIDI_FX_CTRL_7 = 0x1B,
|
|
AL_MIDI_FX_CTRL_8 = 0x1C,
|
|
AL_MIDI_FX_CTRL_9 = 0x1D,
|
|
AL_MIDI_SUSTAIN_CTRL = 0x40,
|
|
AL_MIDI_FX1_CTRL = 0x5B,
|
|
AL_MIDI_FX3_CTRL = 0x5D
|
|
};
|
|
|
|
enum AL_MIDImeta { AL_MIDI_META_TEMPO = 0x51, AL_MIDI_META_EOT = 0x2f };
|
|
|
|
#define AL_CMIDI_BLOCK_CODE 0xFE
|
|
#define AL_CMIDI_LOOPSTART_CODE 0x2E
|
|
#define AL_CMIDI_LOOPEND_CODE 0x2D
|
|
#define AL_CMIDI_CNTRL_LOOPSTART 102
|
|
#define AL_CMIDI_CNTRL_LOOPEND 103
|
|
#define AL_CMIDI_CNTRL_LOOPCOUNT_SM 104
|
|
#define AL_CMIDI_CNTRL_LOOPCOUNT_BIG 105
|
|
|
|
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 node;
|
|
ALMicroTime delta;
|
|
ALEvent evt;
|
|
} ALEventListItem;
|
|
|
|
typedef struct {
|
|
ALLink freeList;
|
|
ALLink allocList;
|
|
s32 eventCount;
|
|
} ALEventQueue;
|
|
|
|
void alEvtqNew(ALEventQueue* evtq, ALEventListItem* items, s32 itemCount);
|
|
ALMicroTime alEvtqNextEvent(ALEventQueue* evtq, ALEvent* evt);
|
|
void alEvtqPostEvent(ALEventQueue* evtq, ALEvent* evt, ALMicroTime delta);
|
|
void alEvtqFlush(ALEventQueue* evtq);
|
|
void alEvtqFlushType(ALEventQueue* evtq, s16 type);
|
|
|
|
#define AL_PHASE_ATTACK 0
|
|
#define AL_PHASE_NOTEON 0
|
|
#define AL_PHASE_DECAY 1
|
|
#define AL_PHASE_SUSTAIN 2
|
|
#define AL_PHASE_RELEASE 3
|
|
#define AL_PHASE_SUSTREL 4
|
|
|
|
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 {
|
|
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 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;
|
|
|
|
#define NO_SOUND_ERR_MASK 0x01
|
|
#define NOTE_OFF_ERR_MASK 0x02
|
|
#define NO_VOICE_ERR_MASK 0x04
|
|
|
|
typedef struct {
|
|
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
|
|
|
|
/***********************************************************************
|
|
* Sound Player stuff
|
|
***********************************************************************/
|
|
|
|
typedef struct {
|
|
s32 maxSounds;
|
|
s32 maxEvents;
|
|
ALHeap* heap;
|
|
} ALSndpConfig;
|
|
|
|
typedef struct {
|
|
ALPlayer node; /* note: must be first in structure */
|
|
ALEventQueue evtq;
|
|
ALEvent nextEvent;
|
|
ALSynth* drvr; /* reference to the client driver */
|
|
s32 target;
|
|
void* sndState;
|
|
s32 maxSounds;
|
|
ALMicroTime frameTime;
|
|
ALMicroTime nextDelta; /* microseconds to next callback */
|
|
ALMicroTime curTime;
|
|
} ALSndPlayer;
|
|
|
|
typedef s16 ALSndId;
|
|
|
|
void alSndpNew(ALSndPlayer* sndp, ALSndpConfig* c);
|
|
void alSndpDelete(ALSndPlayer* sndp);
|
|
|
|
ALSndId alSndpAllocate(ALSndPlayer* sndp, ALSound* sound);
|
|
void alSndpDeallocate(ALSndPlayer* sndp, ALSndId id);
|
|
|
|
void alSndpSetSound(ALSndPlayer* sndp, ALSndId id);
|
|
ALSndId alSndpGetSound(ALSndPlayer* sndp);
|
|
|
|
void alSndpPlay(ALSndPlayer* sndp);
|
|
void alSndpPlayAt(ALSndPlayer* sndp, ALMicroTime delta);
|
|
void alSndpStop(ALSndPlayer* sndp);
|
|
|
|
void alSndpSetVol(ALSndPlayer* sndp, s16 vol);
|
|
void alSndpSetPitch(ALSndPlayer* sndp, f32 pitch);
|
|
void alSndpSetPan(ALSndPlayer* sndp, ALPan pan);
|
|
void alSndpSetPriority(ALSndPlayer* sndp, ALSndId id, u8 priority);
|
|
|
|
void alSndpSetFXMix(ALSndPlayer* sndp, u8 mix);
|
|
s32 alSndpGetState(ALSndPlayer* sndp);
|
|
|
|
#ifndef _FINALROM
|
|
void alParseAbiCL(Acmd* cmdList, u32 nbytes);
|
|
#endif
|
|
#ifdef _LANGUAGE_C_PLUS_PLUS
|
|
}
|
|
#endif
|
|
|
|
#endif /* !__LIB_AUDIO__ */
|