ref: aeac73410477e8b27294e2d035c1710948c95303
dir: /src/ft2_replayer.h/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "ft2_unicode.h"
#include "mixer/ft2_windowed_sinc.h"
enum
{
// voice flags
IS_Vol = 1, // set volume
IS_Period = 2, // set resampling rate
IS_NyTon = 4, // trigger new sample
IS_Pan = 8, // set panning
IS_QuickVol = 16, // 5ms volramp instead of tick ms
LOOP_DISABLED = 0,
LOOP_FORWARD = 1,
LOOP_PINGPONG = 2,
// tracker playback modes
PLAYMODE_IDLE = 0,
PLAYMODE_EDIT = 1,
PLAYMODE_SONG = 2,
PLAYMODE_PATT = 3,
PLAYMODE_RECSONG = 4,
PLAYMODE_RECPATT = 5,
// note cursor positions
CURSOR_NOTE = 0,
CURSOR_INST1 = 1,
CURSOR_INST2 = 2,
CURSOR_VOL1 = 3,
CURSOR_VOL2 = 4,
CURSOR_EFX0 = 5,
CURSOR_EFX1 = 6,
CURSOR_EFX2 = 7
};
// DO NOT TOUCH!
#define MIN_BPM 1
#define MAX_BPM 999
#define MAX_VOICES 32
#define TRACK_WIDTH (5 * MAX_VOICES)
#define MAX_NOTES ((12 * 10 * 16) + 16)
#define MAX_PATTERNS 256
#define MAX_PATT_LEN 256
#define MAX_INST 128
#define MAX_SMP_PER_INST 16
#define MAX_ORDERS 256
#define STD_ENV_SIZE ((6*2*12*2*2) + (6*8*2) + (6*5*2) + (6*2*2))
#define INSTR_HEADER_SIZE 263
#define INSTR_XI_HEADER_SIZE 298
#define MAX_SAMPLE_LEN 0x3FFFFFFF
#define PROG_NAME_STR "Fasttracker II clone"
/* Some of the following structs must be packed (e.g. not padded) since they
** are loaded directly into with fread and stuff.
*/
#ifdef _MSC_VER
#pragma pack(push)
#pragma pack(1)
#endif
typedef struct songHeaderTyp_t // DO NOT TOUCH!
{
char sig[17], name[21], progName[20];
uint16_t ver;
int32_t headerSize;
uint16_t len, repS, antChn, antPtn, antInstrs, flags, defTempo, defSpeed;
uint8_t songTab[256];
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
songHeaderTyp;
typedef struct patternHeaderTyp_t // DO NOT TOUCH!
{
int32_t patternHeaderSize;
uint8_t typ;
int16_t pattLen;
uint16_t dataLen;
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
patternHeaderTyp;
typedef struct songMODInstrHeaderTyp_t
{
char name[22];
uint16_t len;
uint8_t fine, vol;
uint16_t repS, repL;
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
songMODInstrHeaderTyp;
typedef struct songMOD15HeaderTyp_t
{
char name[20];
songMODInstrHeaderTyp instr[15];
uint8_t len, repS, songTab[128];
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
songMOD15HeaderTyp;
typedef struct songMOD31HeaderTyp_t
{
char name[20];
songMODInstrHeaderTyp instr[31];
uint8_t len, repS, songTab[128];
char sig[4];
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
songMOD31HeaderTyp;
typedef struct sampleHeaderTyp_t // DO NOT TOUCH!
{
int32_t len, repS, repL;
uint8_t vol;
int8_t fine;
uint8_t typ, pan;
int8_t relTon;
uint8_t nameLen;
char name[22];
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
sampleHeaderTyp;
typedef struct instrHeaderTyp_t // DO NOT TOUCH!
{
uint32_t instrSize;
char name[22];
uint8_t typ;
int16_t antSamp;
int32_t sampleSize;
uint8_t ta[96];
int16_t envVP[12][2], envPP[12][2];
uint8_t envVPAnt, envPPAnt;
uint8_t envVSust, envVRepS, envVRepE;
uint8_t envPSust, envPRepS, envPRepE;
uint8_t envVTyp, envPTyp;
uint8_t vibTyp, vibSweep, vibDepth, vibRate;
uint16_t fadeOut;
uint8_t midiOn, midiChannel;
int16_t midiProgram, midiBend;
int8_t mute;
uint8_t reserved[15];
sampleHeaderTyp samp[16];
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
instrHeaderTyp;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
typedef struct sampleTyp_t
{
char name[22+1];
bool fixed;
int8_t fine, relTon, *pek, *origPek;
uint8_t vol, typ, pan;
int32_t len, repS, repL;
// fix for resampling interpolation taps
int8_t leftEdgeTapSamples8[SINC_TAPS+SINC_LEFT_TAPS];
int16_t leftEdgeTapSamples16[SINC_TAPS+SINC_LEFT_TAPS];
int16_t fixedSmp[SINC_RIGHT_TAPS];
int32_t fixedPos;
} sampleTyp;
typedef struct instrTyp_t
{
bool midiOn, mute;
uint8_t midiChannel, ta[96];
uint8_t envVPAnt, envPPAnt;
uint8_t envVSust, envVRepS, envVRepE;
uint8_t envPSust, envPRepS, envPRepE;
uint8_t envVTyp, envPTyp;
uint8_t vibTyp, vibSweep, vibDepth, vibRate;
uint16_t fadeOut;
int16_t envVP[12][2], envPP[12][2], midiProgram, midiBend;
int16_t antSamp; // used by loader only
sampleTyp samp[16];
} instrTyp;
typedef struct stmTyp_t
{
bool envSustainActive, stOff, mute;
volatile uint8_t status, tmpStatus;
int8_t relTonNr, fineTune;
uint8_t sampleNr, instrNr, effTyp, eff, smpOffset, tremorSave, tremorPos;
uint8_t globVolSlideSpeed, panningSlideSpeed, waveCtrl, portaDir;
uint8_t glissFunk, vibPos, tremPos, vibSpeed, vibDepth, tremSpeed, tremDepth;
uint8_t pattPos, loopCnt, volSlideSpeed, fVolSlideUpSpeed, fVolSlideDownSpeed;
uint8_t fPortaUpSpeed, fPortaDownSpeed, ePortaUpSpeed, ePortaDownSpeed;
uint8_t portaUpSpeed, portaDownSpeed, retrigSpeed, retrigCnt, retrigVol;
uint8_t volKolVol, tonNr, envPPos, eVibPos, envVPos, realVol, oldVol, outVol;
uint8_t oldPan, outPan, finalPan;
int16_t midiPitch;
uint16_t outPeriod, realPeriod, finalPeriod, tonTyp, wantPeriod, portaSpeed;
uint16_t envVCnt, envPCnt, eVibAmp, eVibSweep;
uint16_t fadeOutAmp, fadeOutSpeed, midiVibDepth;
double dEnvVIPValue, dEnvPIPValue, dEnvVAmp, dEnvPAmp, dFinalVol;
int32_t oldFinalPeriod, smpStartPos;
sampleTyp *smpPtr;
instrTyp *instrPtr;
} stmTyp;
typedef struct songTyp_t
{
bool pBreakFlag, posJumpFlag, isModified;
char name[20+1], instrName[1+MAX_INST][22+1];
uint8_t curReplayerTimer, curReplayerPattPos, curReplayerSongPos, curReplayerPattNr; // used for audio/video sync queue
uint8_t pattDelTime, pattDelTime2, pBreakPos, songTab[MAX_ORDERS];
int16_t songPos, pattNr, pattPos, pattLen;
int32_t antChn;
uint16_t len, repS, speed, tempo, globVol, timer, ver, initialTempo;
uint64_t musicTime64;
} songTyp;
typedef struct tonTyp_t
{
uint8_t ton, instr, vol, effTyp, eff;
} tonTyp;
typedef struct syncedChannel_t // used for audio/video sync queue
{
bool envSustainActive;
int8_t fineTune, relTonNr;
uint8_t status, sampleNr, instrNr;
uint16_t finalPeriod;
int32_t smpStartPos;
double dFinalVol;
} syncedChannel_t;
void setNewSongPos(int32_t pos);
void resetReplayerState(void);
void fixSongName(void); // removes spaces from right side of song name
void fixSampleName(int16_t nr); // removes spaces from right side of ins/smp names
void calcReplayerVars(int32_t rate);
void tuneSample(sampleTyp *s, int32_t midCFreq);
void calcRevMixDeltaTable(void);
void calcReplayerLogTab(void);
double dPeriod2Hz(uint16_t period);
int64_t getMixerDelta(uint16_t period);
uint32_t getRevMixerDelta(uint16_t period);
int32_t getPianoKey(uint16_t period, int32_t finetune, int32_t relativeNote); // for piano in Instr. Ed.
bool allocateInstr(int16_t nr);
void freeInstr(int32_t nr);
void freeAllInstr(void);
void freeSample(int16_t nr, int16_t nr2);
void freeAllPatterns(void);
void updateChanNums(void);
bool setupReplayer(void);
void closeReplayer(void);
void resetMusic(void);
void startPlaying(int8_t mode, int16_t row);
void stopPlaying(void);
void stopVoices(void);
void setPos(int16_t songPos, int16_t pattPos, bool resetTimer);
void pauseMusic(void); // stops reading pattern data
void resumeMusic(void); // starts reading pattern data
void setSongModifiedFlag(void);
void removeSongModifiedFlag(void);
void playTone(uint8_t stmm, uint8_t inst, uint8_t ton, int8_t vol, uint16_t midiVibDepth, uint16_t midiPitch);
void playSample(uint8_t stmm, uint8_t inst, uint8_t smpNr, uint8_t ton, uint16_t midiVibDepth, uint16_t midiPitch);
void playRange(uint8_t stmm, uint8_t inst, uint8_t smpNr, uint8_t ton, uint16_t midiVibDepth, uint16_t midiPitch, int32_t offs, int32_t len);
void keyOff(stmTyp *ch);
void conv8BitSample(int8_t *p, int32_t len, bool stereo);
void conv16BitSample(int8_t *p, int32_t len, bool stereo);
void delta2Samp(int8_t *p, int32_t len, uint8_t typ);
void samp2Delta(int8_t *p, int32_t len, uint8_t typ);
void setPatternLen(uint16_t nr, int16_t len);
void setFrqTab(bool linear);
void tickReplayer(void); // periodically called from audio callback
void resetChannels(void);
bool patternEmpty(uint16_t nr);
int16_t getUsedSamples(int16_t nr);
int16_t getRealUsedSamples(int16_t nr);
void setStdEnvelope(instrTyp *ins, int16_t i, uint8_t typ);
void setNoEnvelope(instrTyp *ins);
void setSyncedReplayerVars(void);
void decSongPos(void);
void incSongPos(void);
void decCurIns(void);
void incCurIns(void);
void decCurSmp(void);
void incCurSmp(void);
void pbPlaySong(void);
void pbPlayPtn(void);
void pbRecSng(void);
void pbRecPtn(void);
// ft2_replayer.c
extern int8_t playMode;
extern bool songPlaying, audioPaused, musicPaused;
extern volatile bool replayerBusy;
extern const uint16_t *note2Period;
extern int16_t pattLens[MAX_PATTERNS];
extern stmTyp stm[MAX_VOICES];
extern songTyp song;
extern instrTyp *instr[132];
extern tonTyp *patt[MAX_PATTERNS];