Files: 91e07c37ef88e4b9783f5a51c82e0e614f615a64 / src / syntrax / syntrax.c
20557 bytesRaw
1 | |
2 | |
3 | |
4 | |
5 | |
6 | void advanceTick() |
7 | { |
8 | int i; |
9 | ABH(); |
10 | |
11 | for (i = 0; i < channelNumber; i++) { |
12 | channelSomething(i); |
13 | Voice *v = voices[i]; |
14 | if (tuneChannels[i].insNum != -1) { |
15 | channelSomethingElse(i); |
16 | instrEffect(i); |
17 | } |
18 | } |
19 | } |
20 | |
21 | void mixChunk(int16_t *outBuff, uint playbackBufferSize) |
22 | { |
23 | |
24 | int i, j; |
25 | uint sampleNum; |
26 | int amp, smp, pos:int; |
27 | int16_t audioMainR, audioMainL; |
28 | int16_t audioDelayR, audioDelayL; |
29 | uint otherDelayTime; |
30 | Voice *v |
31 | TuneChannel *tc; |
32 | |
33 | //We just don't know! |
34 | uint dword_6632774C = 0; |
35 | |
36 | if ( channelNumber > 0 ) |
37 | { |
38 | if ( playbackBufferSize & 1) playbackBufferSize--; |
39 | if ( playbackBufferSize <= 0 ) return; |
40 | |
41 | while ( playbackBufferSize > 0 ) |
42 | { |
43 | if ( otherSamplesPerBeat >= playbackBufferSize ) |
44 | { |
45 | otherSamplesPerBeat = otherSamplesPerBeat - playbackBufferSize; |
46 | sampleNum = playbackBufferSize; |
47 | } |
48 | else |
49 | { |
50 | sampleNum = otherSamplesPerBeat; |
51 | otherSamplesPerBeat = samplesPerBeat * SAMPLEFREQUENCY / 44100; |
52 | } |
53 | playbackBufferSize -= sampleNum; |
54 | |
55 | for (i=0; i < channelNumber; ++i ) |
56 | { |
57 | v = voices[i]; tc = tuneChannels[i]; |
58 | |
59 | int insNum = tc.insNum; |
60 | if ( insNum == -1 ) |
61 | { |
62 | v.waveBuff = silentBuffer; |
63 | v.isSample = 0; |
64 | } |
65 | else if ( !tc.sampleBuffer ) |
66 | { |
67 | int waveNum = instruments[insNum].waveform; |
68 | v.wavelength = (instruments[insNum].wavelength << 8) - 1; |
69 | v.waveBuff = tc.synthBuffers[waveNum]; |
70 | v.isSample = 0; |
71 | } |
72 | else |
73 | { |
74 | v.waveBuff = tc.sampleBuffer; |
75 | v.sampPos = tc.sampPos; |
76 | v.smpLoopStart = tc.smpLoopStart; |
77 | v.smpLoopEnd = tc.smpLoopEnd; |
78 | v.hasLoop = tc.hasLoop; |
79 | v.hasBidiLoop = tc.hasBidiLoop; |
80 | v.isPlayingBackward = tc.isPlayingBackward; |
81 | v.hasLooped = tc.hasLooped; |
82 | v.isSample = 1; |
83 | } |
84 | |
85 | if ( tc.freq < 10 ) |
86 | tc.freq = 10; |
87 | |
88 | v.gain = (tc.volume + 10000) / 39; |
89 | v.delta = (tc.freq << 8) / SAMPLEFREQUENCY; |
90 | |
91 | if ( v.gain > 0x100 ) |
92 | v.gain = 0x100; |
93 | if ( tc.panning ) |
94 | { |
95 | if ( tc.panning <= 0 ) |
96 | { |
97 | v.gainRight = 0x100; |
98 | v.gainLeft = 0x100 + tc.panning; |
99 | } |
100 | else |
101 | { |
102 | v.gainLeft = 0x100; |
103 | v.gainRight = 0x100 - tc.panning; |
104 | } |
105 | } |
106 | else |
107 | { |
108 | v.gainRight = 0x100; |
109 | v.gainLeft = 0x100; |
110 | } |
111 | if ( dword_6632774C ) |
112 | { |
113 | //v.gainDelay = word_6632B9F4[i]; |
114 | } |
115 | else |
116 | { |
117 | v.gainDelay = curSubsong.chanDelayAmt[i]; |
118 | } |
119 | v.gainRight = (v.gain * v.gainRight) >> 8; |
120 | v.gainLeft = (v.gain * v.gainLeft) >> 8; |
121 | v.gainDelayRight = (v.gainDelay * v.gainRight) >> 8; |
122 | v.gainDelayLeft = (v.gainDelay * v.gainLeft) >> 8; |
123 | } |
124 | if ( dword_6632774C ) |
125 | { |
126 | //amp = word_6632B964; |
127 | //otherDelayTime = word_6632BB24; |
128 | } |
129 | else |
130 | { |
131 | amp = curSubsong.amplification; |
132 | otherDelayTime = curSubsong.delayTime / (44100 / SAMPLEFREQUENCY); |
133 | } |
134 | if ( outBuff ) |
135 | { |
136 | if ( sampleNum > 0 ) |
137 | { |
138 | for(i = 0; i < sampleNum; i++) |
139 | { |
140 | audioMainR = 0; |
141 | audioMainL = 0; |
142 | audioDelayR = 0; |
143 | audioDelayL = 0; |
144 | if ( channelNumber > 0 ) |
145 | { |
146 | for (j = 0; j < channelNumber; ++j) |
147 | { |
148 | v = voices[j]; |
149 | if ( v.isSample == 1 ) |
150 | { |
151 | if ( v.sampPos != -1 ) |
152 | { |
153 | //interpolation |
154 | //smp = intp.interpSamp(v); |
155 | smp = v.waveBuff[v.sampPos>>8]; |
156 | |
157 | audioMainR += (smp * v.gainRight) >> 8; |
158 | audioMainL += (smp * v.gainLeft) >> 8; |
159 | audioDelayR += (smp * v.gainDelayRight) >> 8; |
160 | audioDelayL += (smp * v.gainDelayLeft) >> 8; |
161 | if ( v.isPlayingBackward ) |
162 | { |
163 | v.sampPos -= v.delta; |
164 | if ( v.sampPos <= v.smpLoopStart ) |
165 | { |
166 | v.isPlayingBackward = 0; |
167 | v.sampPos += v.delta; |
168 | } |
169 | } |
170 | else |
171 | { |
172 | v.sampPos += v.delta; |
173 | if ( v.sampPos >= v.smpLoopEnd ) |
174 | { |
175 | if ( v.hasLoop ) |
176 | { |
177 | v.hasLooped = 1; |
178 | if ( v.hasBidiLoop ) |
179 | { |
180 | v.isPlayingBackward = 1; |
181 | v.sampPos -= v.delta; |
182 | } |
183 | else |
184 | { |
185 | v.sampPos += v.smpLoopStart - v.smpLoopEnd; |
186 | } |
187 | } |
188 | else |
189 | { |
190 | v.sampPos = -1; |
191 | } |
192 | } |
193 | } |
194 | } |
195 | } |
196 | else |
197 | { |
198 | //interpolation |
199 | //smp = intp.interpSynt(v); |
200 | smp = v.waveBuff[v.synthPos>>8]; |
201 | |
202 | audioMainR += (smp * v.gainRight) >> 8; |
203 | audioMainL += (smp * v.gainLeft) >> 8; |
204 | audioDelayR += (smp * v.gainDelayRight) >> 8; |
205 | audioDelayL += (smp * v.gainDelayLeft) >> 8; |
206 | v.synthPos += v.delta; |
207 | v.synthPos &= v.wavelength; |
208 | } |
209 | } |
210 | } |
211 | |
212 | audioMainL = (delayBufferL[delayPos] + audioMainL / channelNumber) / 2; |
213 | audioMainR = (delayBufferR[delayPos] + audioMainR / channelNumber) / 2; |
214 | audioMainR = audioMainR * amp / 100; |
215 | audioMainL = audioMainL * amp / 100; |
216 | //clip audio |
217 | if ( audioMainR < -32760 ) audioMainR = -32760; |
218 | if ( audioMainR > 32760 ) audioMainR = 32760; |
219 | if ( audioMainL < -32760 ) audioMainL = -32760; |
220 | if ( audioMainL > 32760 ) audioMainL = 32760; |
221 | |
222 | //interleaved buffer |
223 | if ( overlapPos < SE_OVERLAP ) |
224 | { |
225 | audioMainR = overlapPos * audioMainR / 100; |
226 | audioMainR += (SE_OVERLAP - overlapPos) * overlapBuff[overlapPos*2] / 100; |
227 | audioMainL = overlapPos * audioMainL / 100; |
228 | audioMainL += (SE_OVERLAP - overlapPos) * overlapBuff[overlapPos*2+1] / 100; |
229 | ++overlapPos; |
230 | } |
231 | |
232 | //output |
233 | *outbuff++ = audioMainR; |
234 | *outbuff++ = audioMainL; |
235 | |
236 | delayBufferL[delayPos] = (((audioDelayL / channelNumber) + delayBufferL[delayPos]) / 2); |
237 | delayBufferR[delayPos] = (((audioDelayR / channelNumber) + delayBufferR[delayPos]) / 2); |
238 | delayPos = ++delayPos % otherDelayTime; |
239 | } |
240 | } |
241 | } |
242 | |
243 | if ( channelNumber > 0 ) |
244 | { |
245 | for (i = 0; i < channelNumber; ++i) |
246 | { |
247 | v = voices[i]; tc = tuneChannels[i]; |
248 | if ( v.isSample ) |
249 | { |
250 | tc.sampPos = v.sampPos; |
251 | tc.isPlayingBackward = v.isPlayingBackward; |
252 | tc.hasLooped = v.hasLooped; |
253 | } |
254 | } |
255 | } |
256 | if ( otherSamplesPerBeat == (samplesPerBeat * SAMPLEFREQUENCY) / 44100 ) |
257 | { |
258 | bkpDelayPos = delayPos; |
259 | for (i = 0; i < channelNumber; i++) voices[i].bkpSynthPos = voices[i].synthPos; |
260 | |
261 | overlapPos = 0; |
262 | if ( outBuff ) |
263 | { |
264 | for (i = 0; i < SE_OVERLAP; i++) |
265 | { |
266 | audioMainR = 0; |
267 | audioMainL = 0; |
268 | audioDelayR = 0; |
269 | audioDelayL = 0; |
270 | if ( channelNumber > 0 ) |
271 | { |
272 | for (j = 0; j < channelNumber; j++) |
273 | { |
274 | v = voices[j]; |
275 | if ( v.isSample == 1 ) |
276 | { |
277 | if ( v.sampPos != -1 ) |
278 | { |
279 | //interpolation |
280 | //smp = intp.interpSamp(v); |
281 | smp = v.waveBuff[v.sampPos>>8]; |
282 | |
283 | audioMainR += (smp * v.gainRight) >> 8; |
284 | audioMainL += (smp * v.gainLeft) >> 8; |
285 | audioDelayR += (smp * v.gainDelayRight) >> 8; |
286 | audioDelayL += (smp * v.gainDelayLeft) >> 8; |
287 | if ( v.isPlayingBackward ) |
288 | { |
289 | v.sampPos -= v.delta; |
290 | if ( v.sampPos <= v.smpLoopStart ) |
291 | { |
292 | v.isPlayingBackward = 0; |
293 | v.sampPos += v.delta; |
294 | } |
295 | } |
296 | else |
297 | { |
298 | v.sampPos += v.delta; |
299 | if ( v.sampPos >= v.smpLoopEnd ) |
300 | { |
301 | if ( v.hasLoop ) |
302 | { |
303 | v.hasLooped = 1; |
304 | if ( v.hasBidiLoop ) |
305 | { |
306 | v.isPlayingBackward = 1; |
307 | v.sampPos -= v.delta; |
308 | } |
309 | else |
310 | { |
311 | v.sampPos += v.smpLoopStart - v.smpLoopEnd; |
312 | } |
313 | } |
314 | else |
315 | { |
316 | v.sampPos = -1; |
317 | } |
318 | } |
319 | } |
320 | } |
321 | } |
322 | else |
323 | { |
324 | //interpolation |
325 | //smp = intp.interpSynt(v); |
326 | smp = v.waveBuff[v.synthPos>>8]; |
327 | |
328 | audioMainR += (smp * v.gainRight) >> 8; |
329 | audioMainL += (smp * v.gainLeft) >> 8; |
330 | audioDelayR += (smp * v.gainDelayRight) >> 8; |
331 | audioDelayL += (smp * v.gainDelayLeft) >> 8; |
332 | v.synthPos += v.delta; |
333 | v.synthPos &= v.wavelength; |
334 | } |
335 | } |
336 | } |
337 | |
338 | audioMainL = (delayBufferL[delayPos] + audioMainL / channelNumber) / 2; |
339 | audioMainR = (delayBufferR[delayPos] + audioMainR / channelNumber) / 2; |
340 | audioMainR = audioMainR * amp / 100; |
341 | audioMainL = audioMainL * amp / 100; |
342 | //clip audio |
343 | if ( audioMainR < -32760 ) audioMainR = -32760; |
344 | if ( audioMainR > 32760 ) audioMainR = 32760; |
345 | if ( audioMainL < -32760 ) audioMainL = -32760; |
346 | if ( audioMainL > 32760 ) audioMainL = 32760; |
347 | |
348 | overlapBuff[i * 2] = audioMainR; |
349 | overlapBuff[i*2+1] = audioMainL; |
350 | |
351 | delayPos = ++delayPos % otherDelayTime; |
352 | } |
353 | } |
354 | delayPos = bkpDelayPos; |
355 | for (i = 0; i < channelNumber; i++) voices[i].synthPos = voices[i].bkpSynthPos; |
356 | |
357 | //dword_66327200 = 2 * sampleNum; |
358 | advanceTick(); |
359 | } |
360 | } |
361 | return; |
362 | } |
363 | if ( playbackBufferSize <= 0 ) return; |
364 | //blank write to playback buffer |
365 | memset(outbuff, 0, playbackBufferSize * 2); |
366 | } |
367 | |
368 | void pausePlay(void) |
369 | { |
370 | isPaused = 1; |
371 | } |
372 | |
373 | void resumePlay(void) |
374 | { |
375 | isPaused = 0; |
376 | } |
377 | |
378 | void reset(void) |
379 | { |
380 | int i, j; |
381 | |
382 | //dem assumptions |
383 | if (delayBufferL && delayBufferR){ |
384 | memset(delayBufferL, 0, 65536); |
385 | memset(delayBufferR, 0, 65536); |
386 | } |
387 | if (tuneChannels){ |
388 | |
389 | for (i = 0; i < SE_MAXCHANS; i++) { |
390 | TuneChannel *tc: = tuneChannels[i]; |
391 | |
392 | tc.EQMIWERPIF = 0; |
393 | tc.LJHG = 0; |
394 | tc.insNum = -1; |
395 | tc.HFRLJCG = 0; |
396 | tc.ACKCWV = 0; |
397 | tc.ELPHLDR = 0; |
398 | tc.TVORFCC = 0; |
399 | tc.freq = 0; |
400 | tc.BNWIGU = 0; |
401 | tc.UHYDBDDI = 0; |
402 | tc.XESAWSO = 0; |
403 | tc.JOEEPJCI = 0; |
404 | tc.fmDelay = 0; |
405 | tc.sampleBuffer = null; |
406 | tc.smpLoopEnd = 0; |
407 | //tuneChan.smpLength = 0; |
408 | tc.sampPos = 0; |
409 | tc.EYRXAB = 0; |
410 | tc.volume = 0; |
411 | tc.panning = 0; |
412 | tc.VNVJPDIWAJQ = 0; |
413 | tc.smpLoopStart = 0; |
414 | tc.hasLoop = 0; |
415 | tc.hasBidiLoop = 0; |
416 | tc.isPlayingBackward = 0; |
417 | tc.hasLooped = 0; |
418 | |
419 | for (j = 0; j < 4; j++) { |
420 | VoiceEffect *voiceEffect = tc.effects[j]; |
421 | |
422 | voiceEffect.QOMCBTRPXF = 0; |
423 | voiceEffect.TIPUANVVR = 0; |
424 | voiceEffect.MFATTMREMVP = 0; |
425 | voiceEffect.MDTMBBIQHRQ = 0; |
426 | voiceEffect.RKF = 0; |
427 | voiceEffect.DQVLFV = 0; |
428 | voiceEffect.ILHG = 0; |
429 | voiceEffect.YLKJB = 0; |
430 | voiceEffect.VMBNMTNBQU = 0; |
431 | voiceEffect.ABJGHAUY = 0; |
432 | voiceEffect.SPYK = 0; |
433 | |
434 | } |
435 | |
436 | memset(tc.synthBuffers, 0, 0x100 * SE_MAXCHANS + 1); |
437 | } |
438 | } |
439 | } |
440 | |
441 | void newSong(void) |
442 | { |
443 | var _local1:int; |
444 | var i:int; |
445 | var j:int; |
446 | var _local4:Order; |
447 | var _local6:Vector.<Order>; |
448 | var _local7:Row; |
449 | |
450 | reset(); |
451 | AMYGPFQCHSW = 1; |
452 | selectedSubsong = 0; |
453 | WDTECTE = 8; |
454 | AMVM = 0x0100; |
455 | synSong.h.subsongNum = 1; |
456 | synSong.h.version = 3457; |
457 | subsongs = new Vector.<Subsong>(); |
458 | subsongs.push(new Subsong()); |
459 | var subs0:Subsong = subsongs[0]; |
460 | curSubsong = subsongs[selectedSubsong]; |
461 | |
462 | subs0.tempo = 120; |
463 | subs0.groove = 0; |
464 | subs0.startPosCoarse = 0; |
465 | subs0.startPosFine = 0; |
466 | subs0.loopPosCoarse = 0; |
467 | subs0.loopPosFine = 0; |
468 | subs0.endPosCoarse = 1; |
469 | subs0.endPosFine = 0; |
470 | subs0.channelNumber = 4; |
471 | subs0.delayTime = 0x8000; |
472 | subs0.amplification = 400; |
473 | subs0.chanDelayAmt = new Vector.<int>(SE_MAXCHANS, true); |
474 | |
475 | subs0.m_Name = "Empty"; |
476 | subs0.mutedChans = new Vector.<int>(SE_MAXCHANS, true); |
477 | |
478 | |
479 | subs0.orders = Tools.malloc_2DVector(Order, SE_MAXCHANS, 0x0100, true, true); |
480 | for (i = 0; i < SE_MAXCHANS; i++) { |
481 | _local6 = subs0.orders[i]; |
482 | for (j = 0; j < 0x0100; j++) { |
483 | _local6[j].patIndex = 0; |
484 | _local6[j].patLen = 0; |
485 | } |
486 | } |
487 | |
488 | synSong.h.patNum = 2; |
489 | synSong.rows = Tools.malloc_1DVector(Row, 64 * synSong.h.patNum); |
490 | |
491 | for (i = 0; i < (64 * synSong.h.patNum); i++) { |
492 | rows[i].dest = 0; |
493 | rows[i].note = 0; |
494 | rows[i].instr = 0; |
495 | rows[i].command = 0; |
496 | rows[i].spd = 0; |
497 | |
498 | } |
499 | patternNames = new Vector.<String>(); |
500 | patternNames.push("Empty"); |
501 | patternNames.push("Pat1"); |
502 | synSong.h.instrNum = 1; |
503 | synSong.instruments = new Vector.<Instrument>(); |
504 | synSong.instruments.push(new Instrument()); |
505 | |
506 | mutedChans = new Vector.<int>(SE_MAXCHANS, true); |
507 | } |
Built with git-ssb-web