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