363 lines
8.5 KiB
C
363 lines
8.5 KiB
C
#ifndef SYNTRAX_H
|
|
#define SYNTRAX_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
//----------------------------typedefs-------------------------
|
|
#ifndef NULL
|
|
#define NULL 0
|
|
#endif
|
|
typedef unsigned uint;
|
|
|
|
//----------------------------defines--------------------------
|
|
#define SE_NROFEFFECTS 18
|
|
#define SE_MAXCHANS 16
|
|
#define SE_NROFFINETUNESTEPS 16
|
|
|
|
#define SE_OVERLAP 100
|
|
|
|
#define BUFFERLENGTH 4096
|
|
#define CHANNELS 2
|
|
#define BITRATE 16
|
|
#define RESAMPLE_POINTS 4
|
|
|
|
//some constants for controlling stuff
|
|
//I've no idea what the abreviations stand for
|
|
#define SE_PM_SONG 0
|
|
#define SE_PM_PATTERN 1
|
|
|
|
|
|
//---------------------------structures------------------------
|
|
//player structs
|
|
//don't pack these
|
|
typedef struct
|
|
{
|
|
int wavelength;
|
|
int gainDelay;
|
|
int delta;
|
|
int freq;
|
|
int isSample;
|
|
int isPlayingBackward;
|
|
int smpLoopEnd;
|
|
int PPMXBYLQ; //unused
|
|
int gain;
|
|
const int16_t *waveBuff;
|
|
int hasBidiLoop;
|
|
int synthPos;
|
|
int gainRight;
|
|
int smpLoopStart;
|
|
int bkpSynthPos;
|
|
int sampPos;
|
|
int gainLeft;
|
|
int hasLoop;
|
|
int smpLength;
|
|
int gainDelayRight;
|
|
int gainDelayLeft;
|
|
int hasLooped;
|
|
void * resampler[2];
|
|
int last_delta;
|
|
} Voice;
|
|
|
|
typedef struct
|
|
{
|
|
int VMBNMTNBQU;
|
|
int TIPUANVVR;
|
|
double MDTMBBIQHRQ;
|
|
double YLKJB;
|
|
double DQVLFV;
|
|
int MFATTMREMVP;
|
|
double ILHG;
|
|
double RKF;
|
|
int SPYK;
|
|
int QOMCBTRPXF;
|
|
int ABJGHAUY;
|
|
} VoiceEffect;
|
|
|
|
typedef struct
|
|
{
|
|
int JOEEPJCI;
|
|
int BNWIGU;
|
|
int isPlayingBackward;
|
|
int ELPHLDR;
|
|
int panning;
|
|
int TVORFCC;
|
|
int EYRXAB; //rather unused
|
|
int UHYDBDDI;
|
|
int XESAWSO;
|
|
int hasBidiLoop;
|
|
int fmDelay;
|
|
int volume;
|
|
int ACKCWV;
|
|
int sampPos;
|
|
int insNum;
|
|
uint8_t EQMIWERPIF;
|
|
int freq;
|
|
int HFRLJCG;
|
|
int VNVJPDIWAJQ;
|
|
int hasLoop;
|
|
int LJHG;
|
|
const int16_t *sampleBuffer;
|
|
//SQUASH effect overflows into next buffer
|
|
//SE_MAXCHANS * 0x100 + 1 must be allocated
|
|
int16_t synthBuffers[SE_MAXCHANS][0x100];
|
|
int16_t OVERFLOW_DUMMY;
|
|
int smpLoopStart;
|
|
int smpLoopEnd;
|
|
int hasLooped;
|
|
VoiceEffect effects[4];
|
|
} TuneChannel;
|
|
|
|
|
|
//data structs
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t destWave;
|
|
uint32_t srcWave1;
|
|
uint32_t srcWave2;
|
|
uint32_t oscWave;
|
|
uint32_t variable1;
|
|
uint32_t variable2;
|
|
uint32_t fxSpeed;
|
|
uint32_t oscSpeed;
|
|
uint32_t effectType;
|
|
int8_t oscSelect;
|
|
int8_t resetEffect;
|
|
int16_t UNK00;
|
|
} InstrumentEffect;
|
|
|
|
typedef struct
|
|
{
|
|
int16_t version;
|
|
char name[33];
|
|
int16_t waveform;
|
|
int16_t wavelength;
|
|
int16_t masterVolume;
|
|
int16_t amWave;
|
|
int16_t amSpeed;
|
|
int16_t amLoopPoint;
|
|
int16_t finetune;
|
|
int16_t fmWave;
|
|
int16_t fmSpeed;
|
|
int16_t fmLoopPoint;
|
|
int16_t fmDelay;
|
|
int16_t arpIndex;
|
|
uint8_t m_ResetWave[SE_MAXCHANS];
|
|
int16_t panWave;
|
|
int16_t panSpeed;
|
|
int16_t panLoopPoint;
|
|
int16_t UNK00;
|
|
int16_t UNK01;
|
|
int16_t UNK02;
|
|
int16_t UNK03;
|
|
int16_t UNK04;
|
|
int16_t UNK05;
|
|
InstrumentEffect effects[4];
|
|
//why do we even need to store a full path?
|
|
//only filename appears to be used.
|
|
char smpFullImportPath[193];
|
|
uint32_t UNK06;
|
|
uint32_t UNK07;
|
|
uint32_t UNK08;
|
|
uint32_t UNK09;
|
|
uint32_t UNK0A;
|
|
uint32_t UNK0B;
|
|
uint32_t UNK0C;
|
|
uint32_t UNK0D;
|
|
uint32_t UNK0E;
|
|
uint32_t UNK0F;
|
|
uint32_t UNK10;
|
|
uint32_t UNK11;
|
|
int16_t UNK12;
|
|
int16_t shareSmpDataFromInstr; //0 is off
|
|
int16_t hasLoop;
|
|
int16_t hasBidiLoop;
|
|
uint32_t smpStartPoint;
|
|
uint32_t smpLoopPoint;
|
|
uint32_t smpEndPoint;
|
|
uint32_t hasSample;
|
|
uint32_t smpLength;
|
|
int16_t synthBuffers[SE_MAXCHANS][0x100];
|
|
} Instrument;
|
|
|
|
typedef struct
|
|
{
|
|
uint8_t note;
|
|
uint8_t dest;
|
|
uint8_t instr;
|
|
int8_t spd;
|
|
uint8_t command;
|
|
} Row;
|
|
|
|
typedef struct
|
|
{
|
|
uint16_t patIndex; //0 means empty
|
|
uint16_t patLen;
|
|
} Order;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t UNK00[16];
|
|
//UNK00 is used for something. No idea what.
|
|
//There is a sequence to the data in it.
|
|
//zeroing it out with hex editor doesn't seem to break stuff with Jaytrax
|
|
//it could as well be uninitialized memory
|
|
uint8_t mutedChans[SE_MAXCHANS];
|
|
uint32_t tempo;
|
|
uint32_t groove;
|
|
uint32_t startPosCoarse;
|
|
uint32_t startPosFine;
|
|
uint32_t endPosCoarse;
|
|
uint32_t endPosFine;
|
|
uint32_t loopPosCoarse;
|
|
uint32_t loopPosFine;
|
|
int16_t isLooping;
|
|
char m_Name[33];
|
|
int16_t channelNumber;
|
|
uint16_t delayTime;
|
|
uint8_t chanDelayAmt[SE_MAXCHANS];
|
|
int16_t amplification;
|
|
int16_t UNK01;
|
|
int16_t UNK02;
|
|
int16_t UNK03;
|
|
int16_t UNK04;
|
|
int16_t UNK05;
|
|
int16_t UNK06;
|
|
//if my eyes don't deceive me, this actually happens
|
|
//waste of space
|
|
Order orders[SE_MAXCHANS][0x100];
|
|
} Subsong;
|
|
|
|
typedef struct
|
|
{
|
|
uint16_t version;
|
|
uint16_t UNK00;
|
|
uint32_t patNum;
|
|
uint32_t subsongNum;
|
|
uint32_t instrNum;
|
|
uint32_t UNK01;
|
|
int16_t UNK02;
|
|
int16_t UNK03;
|
|
int16_t UNK04;
|
|
int16_t UNK05;
|
|
int16_t UNK06;
|
|
int16_t UNK07;
|
|
int16_t UNK08;
|
|
int16_t UNK09;
|
|
int16_t UNK0A;
|
|
int16_t UNK0B;
|
|
int16_t UNK0C;
|
|
int16_t UNK0D;
|
|
int16_t UNK0E;
|
|
int16_t UNK0F;
|
|
int16_t UNK10;
|
|
int16_t UNK11;
|
|
} SongHeader;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
SongHeader h;
|
|
int8_t arpTable[0x100];
|
|
|
|
Row *rows;
|
|
//we don't know what maximum pat name length should be
|
|
//in fact this is probably a buffer overflow target in Syntrax(app crashed on too long name, from UI);
|
|
uint32_t *patNameSizes;
|
|
char **patternNames;
|
|
Instrument *instruments;
|
|
Subsong *subsongs;
|
|
int16_t **samples;
|
|
} Song;
|
|
|
|
|
|
typedef struct Player
|
|
{
|
|
int16_t *silentBuffer;
|
|
uint8_t m_LastNotes[SE_MAXCHANS];
|
|
|
|
uint32_t *freqTable;
|
|
int16_t *dynamorphTable;
|
|
|
|
const Song *synSong;
|
|
TuneChannel *tuneChannels;
|
|
Voice *voices;
|
|
|
|
int SAMPLEFREQUENCY;
|
|
|
|
int samplesPerBeat;
|
|
int otherSamplesPerBeat;
|
|
int someCounter;
|
|
int channelNumber;
|
|
int sePmSong;
|
|
int16_t *overlapBuff;
|
|
int16_t *delayBufferR;
|
|
int16_t *delayBufferL;
|
|
|
|
int bkpDelayPos;
|
|
int delayPos;
|
|
int gainPos;
|
|
int overlapPos;
|
|
|
|
int ISWLKT;
|
|
int WDTECTE;
|
|
int PQV;
|
|
int AMVM;
|
|
int DONGS;
|
|
uint8_t posCoarse;
|
|
int AMYGPFQCHSW;
|
|
int posFine;
|
|
int8_t mutedChans[SE_MAXCHANS];
|
|
|
|
int selectedSubsong;
|
|
Subsong curSubsong;
|
|
|
|
//local pointers to song structures
|
|
const Row *rows;
|
|
const char ** patternNames;
|
|
Instrument *instruments;
|
|
const Subsong *subsongs;
|
|
const int8_t *arpTable;
|
|
const int16_t **samples;
|
|
|
|
uint bufflen;
|
|
|
|
uint loopCount;
|
|
} Player;
|
|
|
|
|
|
//---------------------------prototypes------------------------
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
Player * playerCreate(int sampleFrequency);
|
|
void playerDestroy(Player *);
|
|
|
|
int loadSong(Player *, const Song *);
|
|
void initSubsong(Player *, int num);
|
|
|
|
void mixChunk(Player *, int16_t *outBuff, uint playbackBufferSize);
|
|
|
|
void playInstrument(Player *, int chanNum, int instrNum, int note); //could be handy dandy
|
|
|
|
bool playerGetSongEnded(Player *);
|
|
uint playerGetLoopCount(Player *);
|
|
|
|
typedef struct _stmi
|
|
{
|
|
unsigned char coarse;
|
|
unsigned char fine;
|
|
unsigned char channelsPlaying;
|
|
const char *subsongName;
|
|
int selectedSubs;
|
|
int totalSubs;
|
|
} syntrax_info;
|
|
|
|
void playerGetInfo(Player *, syntrax_info *);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|