1 #pragma once 2 3 #include <stdint.h> 4 #include <stdbool.h> 5 #include "ft2_unicode.h" 6 #include "mixer/ft2_windowed_sinc.h" 7 #include "ft2_cpu.h" 8 9 enum 10 { 11 // voice flags 12 IS_Vol = 1, // set volume 13 IS_Period = 2, // set resampling rate 14 IS_Trigger = 4, // trigger sample 15 IS_Pan = 8, // set panning 16 IS_QuickVol = 16, // 5ms volramp instead of tick ms 17 18 LOOP_DISABLED = 0, 19 LOOP_FORWARD = 1, 20 LOOP_PINGPONG = 2, 21 22 // tracker playback modes 23 PLAYMODE_IDLE = 0, 24 PLAYMODE_EDIT = 1, 25 PLAYMODE_SONG = 2, 26 PLAYMODE_PATT = 3, 27 PLAYMODE_RECSONG = 4, 28 PLAYMODE_RECPATT = 5, 29 30 // note cursor positions 31 CURSOR_NOTE = 0, 32 CURSOR_INST1 = 1, 33 CURSOR_INST2 = 2, 34 CURSOR_VOL1 = 3, 35 CURSOR_VOL2 = 4, 36 CURSOR_EFX0 = 5, 37 CURSOR_EFX1 = 6, 38 CURSOR_EFX2 = 7 39 }; 40 41 // do not touch these! 42 #define MIN_BPM 32 43 #define MAX_BPM 255 44 #define MAX_SPEED 31 45 #define MAX_CHANNELS 32 46 #define TRACK_WIDTH (5 * MAX_CHANNELS) 47 #define MAX_FRQ 32000 48 #define C4_FREQ 8363 49 #define NOTE_C4 (4*12) 50 #define NOTE_OFF 97 51 #define MAX_NOTES (10*12*16+16) 52 #define MAX_PATTERNS 256 53 #define MAX_PATT_LEN 256 54 #define MAX_INST 128 55 #define MAX_SMP_PER_INST 16 56 #define MAX_ORDERS 256 57 #define STD_ENV_SIZE ((6*2*12*2*2) + (6*8*2) + (6*5*2) + (6*2*2)) 58 #define INSTR_HEADER_SIZE 263 59 #define INSTR_XI_HEADER_SIZE 298 60 #define MAX_SAMPLE_LEN 0x3FFFFFFF 61 #define FT2_QUICKRAMP_SAMPLES 200 62 #define PROG_NAME_STR "Fasttracker II clone" 63 64 enum // sample flags 65 { 66 LOOP_OFF = 0, 67 LOOP_FWD = 1, 68 LOOP_BIDI = 2, 69 SAMPLE_16BIT = 16, 70 SAMPLE_STEREO = 32, 71 SAMPLE_ADPCM = 64, // not an existing flag, but used by loader 72 }; 73 74 enum // envelope flags 75 { 76 ENV_ENABLED = 1, 77 ENV_SUSTAIN = 2, 78 ENV_LOOP = 4 79 }; 80 81 #define GET_LOOPTYPE(smpFlags) ((smpFlags) & (LOOP_FWD | LOOP_BIDI)) 82 #define DISABLE_LOOP(smpFlags) ((smpFlags) &= ~(LOOP_FWD | LOOP_BIDI)) 83 #define SAMPLE_LENGTH_BYTES(smp) (smp->length << !!(smp->flags & SAMPLE_16BIT)) 84 #define FINETUNE_MOD2XM(f) (((uint8_t)(f) & 0x0F) << 4) 85 #define FINETUNE_XM2MOD(f) ((uint8_t)(f) >> 4) 86 87 /* Some of the following structs MUST be packed! 88 ** Please do NOT edit these structs unless you 89 ** absolutely know what you are doing! 90 */ 91 92 #ifdef _MSC_VER 93 #pragma pack(push) 94 #pragma pack(1) 95 #endif 96 typedef struct xmHdr_t 97 { 98 char ID[17], name[20], x1A, progName[20]; 99 uint16_t version; 100 int32_t headerSize; 101 uint16_t numOrders, songLoopStart, numChannels, numPatterns; 102 uint16_t numInstr, flags, speed, BPM; 103 uint8_t orders[256]; 104 } 105 #ifdef __GNUC__ 106 __attribute__ ((packed)) 107 #endif 108 xmHdr_t; 109 110 typedef struct xmPatHdr_t 111 { 112 int32_t headerSize; 113 uint8_t type; 114 int16_t numRows; 115 uint16_t dataSize; 116 } 117 #ifdef __GNUC__ 118 __attribute__ ((packed)) 119 #endif 120 xmPatHdr_t; 121 122 typedef struct modSmpHdr_t 123 { 124 char name[22]; 125 uint16_t length; 126 uint8_t finetune, volume; 127 uint16_t loopStart, loopLength; 128 } 129 #ifdef __GNUC__ 130 __attribute__ ((packed)) 131 #endif 132 modSmpHdr_t; 133 134 typedef struct modHdr_t 135 { 136 char name[20]; 137 modSmpHdr_t smp[31]; 138 uint8_t numOrders, songLoopStart, orders[128]; 139 char ID[4]; 140 } 141 #ifdef __GNUC__ 142 __attribute__ ((packed)) 143 #endif 144 modHdr_t; 145 146 typedef struct xmSmpHdr_t 147 { 148 uint32_t length, loopStart, loopLength; 149 uint8_t volume; 150 int8_t finetune; 151 uint8_t flags, panning; 152 int8_t relativeNote; 153 uint8_t nameLength; // only handled before saving (ignored under load) 154 char name[22]; 155 } 156 #ifdef __GNUC__ 157 __attribute__ ((packed)) 158 #endif 159 xmSmpHdr_t; 160 161 typedef struct xmInsHdr_t 162 { 163 uint32_t instrSize; 164 char name[22]; 165 uint8_t type; 166 int16_t numSamples; 167 int32_t sampleSize; 168 uint8_t note2SampleLUT[96]; 169 int16_t volEnvPoints[12][2], panEnvPoints[12][2]; 170 uint8_t volEnvLength, panEnvLength; 171 uint8_t volEnvSustain, volEnvLoopStart, volEnvLoopEnd; 172 uint8_t panEnvSustain, panEnvLoopStart, panEnvLoopEnd; 173 uint8_t volEnvFlags, panEnvFlags; 174 uint8_t vibType, vibSweep, vibDepth, vibRate; 175 uint16_t fadeout; 176 uint8_t midiOn, midiChannel; 177 int16_t midiProgram, midiBend; 178 int8_t mute; 179 uint8_t junk[15]; 180 xmSmpHdr_t smp[16]; 181 } 182 #ifdef __GNUC__ 183 __attribute__ ((packed)) 184 #endif 185 xmInsHdr_t; 186 187 typedef struct pattNote_t // must be packed! 188 { 189 uint8_t note, instr, vol, efx, efxData; 190 } 191 #ifdef __GNUC__ 192 __attribute__ ((packed)) 193 #endif 194 note_t; 195 196 typedef struct syncedChannel_t // used for audio/video sync queue (pack to save RAM) 197 { 198 uint8_t status, pianoNoteNum, smpNum, instrNum; 199 int32_t smpStartPos; 200 uint8_t scopeVolume; 201 uintCPUWord_t scopeDelta; 202 } 203 #ifdef __GNUC__ 204 __attribute__ ((packed)) 205 #endif 206 syncedChannel_t; 207 208 #ifdef _MSC_VER 209 #pragma pack(pop) 210 #endif 211 212 typedef struct sample_t 213 { 214 char name[22+1]; 215 bool isFixed; 216 int8_t finetune, relativeNote, *dataPtr, *origDataPtr; 217 uint8_t volume, flags, panning; 218 int32_t length, loopStart, loopLength; 219 220 // fix for resampling interpolation taps 221 int8_t leftEdgeTapSamples8[SINC_TAPS+SINC_LEFT_TAPS]; 222 int16_t leftEdgeTapSamples16[SINC_TAPS+SINC_LEFT_TAPS]; 223 int16_t fixedSmp[SINC_RIGHT_TAPS]; 224 int32_t fixedPos; 225 } sample_t; 226 227 typedef struct instr_t 228 { 229 bool midiOn, mute; 230 uint8_t midiChannel, note2SampleLUT[96]; 231 uint8_t volEnvLength, panEnvLength; 232 uint8_t volEnvSustain, volEnvLoopStart, volEnvLoopEnd; 233 uint8_t panEnvSustain, panEnvLoopStart, panEnvLoopEnd; 234 uint8_t volEnvFlags, panEnvFlags; 235 uint8_t vibType, vibSweep, vibDepth, vibRate; 236 uint16_t fadeout; 237 int16_t volEnvPoints[12][2], panEnvPoints[12][2], midiProgram, midiBend; 238 int16_t numSamples; // used by loader only 239 sample_t smp[16]; 240 } instr_t; 241 242 typedef struct channel_t 243 { 244 bool envSustainActive, channelOff, mute; 245 volatile uint8_t status, tmpStatus; 246 int8_t relativeNote, finetune; 247 uint8_t smpNum, instrNum, efxData, efx, smpOffset, tremorSave, tremorPos; 248 uint8_t globVolSlideSpeed, panningSlideSpeed, waveCtrl, portaDirection; 249 uint8_t glissFunk, vibPos, tremPos, vibSpeed, vibDepth, tremSpeed, tremDepth; 250 uint8_t jumpToRow, patLoopCounter, volSlideSpeed, fVolSlideUpSpeed, fVolSlideDownSpeed; 251 uint8_t fPortaUpSpeed, fPortaDownSpeed, ePortaUpSpeed, ePortaDownSpeed; 252 uint8_t portaUpSpeed, portaDownSpeed, retrigSpeed, retrigCnt, retrigVol; 253 uint8_t volColumnVol, noteNum, panEnvPos, eVibPos, volEnvPos, realVol, oldVol, outVol; 254 uint8_t oldPan, outPan, finalPan; 255 int16_t midiPitch; 256 uint16_t outPeriod, realPeriod, finalPeriod, noteData, wantPeriod, portaSpeed; 257 uint16_t volEnvTick, panEnvTick, eVibAmp, eVibSweep; 258 uint16_t fadeoutVol, fadeoutSpeed, midiVibDepth; 259 int32_t volEnvDelta, panEnvDelta, volEnvValue, panEnvValue; 260 int32_t oldFinalPeriod, smpStartPos; 261 262 float fFinalVol; // 0.0f .. 1.0f 263 264 sample_t *smpPtr; 265 instr_t *instrPtr; 266 } channel_t; 267 268 typedef struct song_t 269 { 270 bool pBreakFlag, posJumpFlag, isModified; 271 char name[20+1], instrName[1+MAX_INST][22+1]; 272 uint8_t curReplayerTick, curReplayerRow, curReplayerSongPos, curReplayerPattNum; // used for audio/video sync queue 273 uint8_t pattDelTime, pattDelTime2, pBreakPos, orders[MAX_ORDERS]; 274 int16_t songPos, pattNum, row, currNumRows; 275 uint16_t songLength, songLoopStart, BPM, speed, initialSpeed, globalVolume, tick; 276 int32_t numChannels; 277 uint64_t musicTime64; 278 } song_t; 279 280 double getSampleC4Rate(sample_t *s); 281 282 void setNewSongPos(int32_t pos); 283 void resetReplayerState(void); 284 285 void fixString(char *str, int32_t lastChrPos); // removes leading spaces and 0x1A chars 286 void fixSongName(void); 287 void fixInstrAndSampleNames(int16_t insNum); 288 289 void calcReplayerVars(int32_t rate); 290 291 // used on external sample load and during sample loading in some module formats 292 void tuneSample(sample_t *s, const int32_t midCFreq, bool linearPeriodsFlag); 293 294 void calcReplayerLogTab(void); // for linear period -> hz calculation 295 296 double dLinearPeriod2Hz(int32_t period); 297 double dAmigaPeriod2Hz(int32_t period); 298 double dPeriod2Hz(int32_t period); 299 300 int32_t getPianoKey(uint16_t period, int8_t finetune, int8_t relativeNote); // for piano in Instr. Ed. 301 302 bool allocateInstr(int16_t insNum); 303 void freeInstr(int32_t insNum); 304 void freeAllInstr(void); 305 void freeSample(int16_t insNum, int16_t smpNum); 306 307 void freeAllPatterns(void); 308 void updateChanNums(void); 309 bool setupReplayer(void); 310 void closeReplayer(void); 311 void resetMusic(void); 312 void startPlaying(int8_t mode, int16_t row); 313 void stopPlaying(void); 314 void stopVoices(void); 315 void setPos(int16_t songPos, int16_t row, bool resetTimer); 316 void pauseMusic(void); // stops reading pattern data 317 void resumeMusic(void); // starts reading pattern data 318 void setSongModifiedFlag(void); 319 void removeSongModifiedFlag(void); 320 void playTone(uint8_t chNum, uint8_t insNum, uint8_t note, int8_t vol, uint16_t midiVibDepth, uint16_t midiPitch); 321 void playSample(uint8_t chNum, uint8_t insNum, uint8_t smpNum, uint8_t note, uint16_t midiVibDepth, uint16_t midiPitch); 322 void playRange(uint8_t chNum, uint8_t insNum, uint8_t smpNum, uint8_t note, uint16_t midiVibDepth, uint16_t midiPitch, int32_t smpOffset, int32_t length); 323 void keyOff(channel_t *ch); 324 void conv8BitSample(int8_t *p, int32_t length, bool stereo); // changes sample sign 325 void conv16BitSample(int8_t *p, int32_t length, bool stereo); // changes sample sign 326 void delta2Samp(int8_t *p, int32_t length, uint8_t smpFlags); 327 void samp2Delta(int8_t *p, int32_t length, uint8_t smpFlags); 328 void setPatternLen(uint16_t pattNum, int16_t numRows); 329 void setFrequencyTable(bool linearPeriodsFlag); 330 void tickReplayer(void); // periodically called from audio callback 331 void resetChannels(void); 332 bool patternEmpty(uint16_t pattNum); 333 int16_t getUsedSamples(int16_t smpNum); 334 int16_t getRealUsedSamples(int16_t smpNum); 335 void setStdEnvelope(instr_t *ins, int16_t i, uint8_t type); 336 void setNoEnvelope(instr_t *ins); 337 void setSyncedReplayerVars(void); 338 void decSongPos(void); 339 void incSongPos(void); 340 void decCurIns(void); 341 void incCurIns(void); 342 void decCurSmp(void); 343 void incCurSmp(void); 344 void pbPlaySong(void); 345 void pbPlayPtn(void); 346 void pbRecSng(void); 347 void pbRecPtn(void); 348 349 // ft2_replayer.c 350 extern int8_t playMode; 351 extern bool songPlaying, audioPaused, musicPaused; 352 extern volatile bool replayerBusy; 353 extern const uint16_t *note2Period; 354 extern int16_t patternNumRows[MAX_PATTERNS]; 355 extern channel_t channel[MAX_CHANNELS]; 356 extern song_t song; 357 extern instr_t *instr[128+4]; 358 extern note_t *pattern[MAX_PATTERNS]; 359