1 /*
2 * Schism Tracker - a cross-platform Impulse Tracker clone
3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5 * copyright (c) 2009 Storlek & Mrs. Brisby
6 * copyright (c) 2010-2012 Storlek
7 * URL: http://schismtracker.org/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "song.h"
25 #include "sndfile.h"
26 #include "snd_fm.h"
27 #include "snd_gm.h"
28 #include "cmixer.h"
29
30 #include "util.h" /* for clamp */
31
32 // Volume ramp length, in 1/10 ms
33 #define VOLUMERAMPLEN 146 // 1.46ms = 64 samples at 44.1kHz
34
35 // VU meter
36 #define VUMETER_DECAY 16
37
38 // SNDMIX: These are global flags for playback control
39 unsigned int max_voices = 32; // ITT it is 1994
40
41 // Mixing data initialized in
42 static unsigned int volume_ramp_samples = 64;
43 unsigned int global_vu_left = 0;
44 unsigned int global_vu_right = 0;
45 int32_t g_dry_rofs_vol = 0;
46 int32_t g_dry_lofs_vol = 0;
47
48 typedef uint32_t (* convert_t)(void *, int *, uint32_t, int *, int *);
49
50
51 // see also csf_midi_out_raw in effects.c
52 void (*csf_midi_out_note)(int chan, const song_note_t *m) = NULL;
53
54
55 // The volume we have here is in range 0..(63*255) (0..16065)
56 // We should keep that range, but convert it into a logarithmic
57 // one such that a change of 256*8 (2048) corresponds to a halving
58 // of the volume.
59 // logvolume = 2^(linvolume / (4096/8)) * (4096/64)
60 // However, because the resolution of MIDI volumes
61 // is merely 128 units, we can use a lookup table.
62 //
63 // In this table, each value signifies the minimum value
64 // that volume must be in order for the result to be
65 // that table index.
66 static const unsigned short GMvolTransition[128] =
67 {
68 0, 2031, 4039, 5214, 6048, 6694, 7222, 7669,
69 8056, 8397, 8702, 8978, 9230, 9462, 9677, 9877,
70 10064,10239,10405,10562,10710,10852,10986,11115,
71 11239,11357,11470,11580,11685,11787,11885,11980,
72 12072,12161,12248,12332,12413,12493,12570,12645,
73 12718,12790,12860,12928,12995,13060,13123,13186,
74 13247,13306,13365,13422,13479,13534,13588,13641,
75 13693,13745,13795,13844,13893,13941,13988,14034,
76 14080,14125,14169,14213,14256,14298,14340,14381,
77 14421,14461,14501,14540,14578,14616,14653,14690,
78 14727,14763,14798,14833,14868,14902,14936,14970,
79 15003,15035,15068,15100,15131,15163,15194,15224,
80 15255,15285,15315,15344,15373,15402,15430,15459,
81 15487,15514,15542,15569,15596,15623,15649,15675,
82 15701,15727,15753,15778,15803,15828,15853,15877,
83 15901,15925,15949,15973,15996,16020,16043,16065,
84 };
85
86
87 // We use binary search to find the right slot
88 // with at most 7 comparisons.
find_volume(unsigned short vol)89 static unsigned int find_volume(unsigned short vol)
90 {
91 unsigned int l = 0, r = 128;
92
93 while (l < r) {
94 unsigned int m = l + ((r - l) / 2);
95 unsigned short p = GMvolTransition[m];
96
97 if (p < vol)
98 l = m + 1;
99 else
100 r = m;
101 }
102
103 return l;
104 }
105
106
107 ////////////////////////////////////////////////////////////////////////////////////////////
108 //
109 // XXX * I prefixed these with `rn_' to avoid any namespace conflicts
110 // XXX Needs better naming!
111 // XXX * Keep inline?
112 // XXX * Get rid of the pointer passing where it is not needed
113 //
114
115
rn_tremor(song_voice_t * chan,int * vol)116 static inline void rn_tremor(song_voice_t *chan, int *vol)
117 {
118 if ((chan->cd_tremor & 192) == 128)
119 *vol = 0;
120
121 chan->flags |= CHN_FASTVOLRAMP;
122 }
123
124
rn_vibrato(song_t * csf,song_voice_t * chan,int frequency)125 static inline int rn_vibrato(song_t *csf, song_voice_t *chan, int frequency)
126 {
127 unsigned int vibpos = chan->vibrato_position & 0xFF;
128 int vdelta;
129 unsigned int vdepth;
130
131 switch (chan->vib_type) {
132 case VIB_SINE:
133 default:
134 vdelta = sine_table[vibpos];
135 break;
136 case VIB_RAMP_DOWN:
137 vdelta = ramp_down_table[vibpos];
138 break;
139 case VIB_SQUARE:
140 vdelta = square_table[vibpos];
141 break;
142 case VIB_RANDOM:
143 vdelta = 128 * ((double) rand() / RAND_MAX) - 64;
144 break;
145 }
146
147 if (csf->flags & SONG_ITOLDEFFECTS) {
148 vdepth = 5;
149 vdelta = -vdelta; // yes, IT does vibrato backwards in old-effects mode. try it.
150 } else {
151 vdepth = 6;
152 }
153 vdelta = (vdelta * (int)chan->vibrato_depth) >> vdepth;
154
155 frequency = csf_fx_do_freq_slide(csf->flags, frequency, vdelta, 0);
156
157 // handle on tick-N, or all ticks if not in old-effects mode
158 if (!(csf->flags & SONG_FIRSTTICK) || !(csf->flags & SONG_ITOLDEFFECTS)) {
159 chan->vibrato_position = (vibpos + 4 * chan->vibrato_speed) & 0xFF;
160 }
161
162 return frequency;
163 }
164
rn_sample_vibrato(song_t * csf,song_voice_t * chan,int frequency)165 static inline int rn_sample_vibrato(song_t *csf, song_voice_t *chan, int frequency)
166 {
167 unsigned int vibpos = chan->autovib_position & 0xFF;
168 int vdelta, adepth;
169 song_sample_t *pins = chan->ptr_sample;
170
171 /*
172 1) Mov AX, [SomeVariableNameRelatingToVibrato]
173 2) Add AL, Rate
174 3) AdC AH, 0
175 4) AH contains the depth of the vibrato as a fine-linear slide.
176 5) Mov [SomeVariableNameRelatingToVibrato], AX ; For the next cycle.
177 */
178
179 adepth = chan->autovib_depth; // (1)
180 adepth += pins->vib_rate & 0xff; // (2 & 3)
181 /* need this cast -- if adepth is unsigned, large autovib will crash the mixer (why? I don't know!)
182 but if vib_depth is changed to signed, that screws up other parts of the code. ugh. */
183 adepth = MIN(adepth, (int) (pins->vib_depth << 8));
184 chan->autovib_depth = adepth; // (5)
185 adepth >>= 8; // (4)
186
187 chan->autovib_position += pins->vib_speed;
188
189 switch(pins->vib_type) {
190 case VIB_SINE:
191 default:
192 vdelta = sine_table[vibpos];
193 break;
194 case VIB_RAMP_DOWN:
195 vdelta = ramp_down_table[vibpos];
196 break;
197 case VIB_SQUARE:
198 vdelta = square_table[vibpos];
199 break;
200 case VIB_RANDOM:
201 vdelta = 128 * ((double) rand() / RAND_MAX) - 64;
202 break;
203 }
204 vdelta = (vdelta * adepth) >> 6;
205
206 int l = abs(vdelta);
207
208 const uint32_t *linear_slide_table, *fine_linear_slide_table;
209 if (vdelta < 0) {
210 linear_slide_table = linear_slide_up_table;
211 fine_linear_slide_table = fine_linear_slide_up_table;
212 } else {
213 linear_slide_table = linear_slide_down_table;
214 fine_linear_slide_table = fine_linear_slide_down_table;
215 }
216
217 if(l < 16)
218 vdelta = _muldiv(frequency, fine_linear_slide_table[l], 0x10000) - frequency;
219 else
220 vdelta = _muldiv(frequency, linear_slide_table[l >> 2], 0x10000) - frequency;
221
222 return frequency - vdelta;
223 }
224
225
rn_process_envelope(song_voice_t * chan,int * nvol)226 static inline void rn_process_envelope(song_voice_t *chan, int *nvol)
227 {
228 song_instrument_t *penv = chan->ptr_instrument;
229 int vol = *nvol;
230
231 // Volume Envelope
232 if (chan->flags & CHN_VOLENV && penv->vol_env.nodes) {
233 int envpos = chan->vol_env_position;
234 unsigned int pt = penv->vol_env.nodes - 1;
235
236 for (unsigned int i = 0; i < (unsigned int)(penv->vol_env.nodes - 1); i++) {
237 if (envpos <= penv->vol_env.ticks[i]) {
238 pt = i;
239 break;
240 }
241 }
242
243 int x2 = penv->vol_env.ticks[pt];
244 int x1, envvol;
245
246 if (envpos >= x2) {
247 envvol = penv->vol_env.values[pt] << 2;
248 x1 = x2;
249 } else if (pt) {
250 envvol = penv->vol_env.values[pt-1] << 2;
251 x1 = penv->vol_env.ticks[pt-1];
252 } else {
253 envvol = 0;
254 x1 = 0;
255 }
256
257 if (envpos > x2)
258 envpos = x2;
259
260 if (x2 > x1 && envpos > x1) {
261 envvol += ((envpos - x1) * (((int)penv->vol_env.values[pt]<<2) - envvol)) / (x2 - x1);
262 }
263
264 envvol = CLAMP(envvol, 0, 256);
265 vol = (vol * envvol) >> 8;
266 }
267
268 // Panning Envelope
269 if ((chan->flags & CHN_PANENV) && (penv->pan_env.nodes)) {
270 int envpos = chan->pan_env_position;
271 unsigned int pt = penv->pan_env.nodes - 1;
272
273 for (unsigned int i=0; i<(unsigned int)(penv->pan_env.nodes-1); i++) {
274 if (envpos <= penv->pan_env.ticks[i]) {
275 pt = i;
276 break;
277 }
278 }
279
280 int x2 = penv->pan_env.ticks[pt], y2 = penv->pan_env.values[pt];
281 int x1, envpan;
282
283 if (envpos >= x2) {
284 envpan = y2;
285 x1 = x2;
286 } else if (pt) {
287 envpan = penv->pan_env.values[pt-1];
288 x1 = penv->pan_env.ticks[pt-1];
289 } else {
290 envpan = 128;
291 x1 = 0;
292 }
293
294 if (x2 > x1 && envpos > x1) {
295 envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1);
296 }
297
298 envpan = CLAMP(envpan, 0, 64);
299
300 int pan = chan->final_panning;
301
302 if (pan >= 128) {
303 pan += ((envpan - 32) * (256 - pan)) / 32;
304 } else {
305 pan += ((envpan - 32) * (pan)) / 32;
306 }
307
308 chan->final_panning = pan;
309 }
310
311 // FadeOut volume
312 if (chan->flags & CHN_NOTEFADE) {
313 unsigned int fadeout = penv->fadeout;
314
315 if (fadeout) {
316 chan->fadeout_volume -= fadeout << 1;
317
318 if (chan->fadeout_volume <= 0)
319 chan->fadeout_volume = 0;
320
321 vol = (vol * chan->fadeout_volume) >> 16;
322 } else if (!chan->fadeout_volume) {
323 vol = 0;
324 }
325 }
326
327 *nvol = vol;
328 }
329
330
rn_arpeggio(song_t * csf,song_voice_t * chan,int frequency)331 static inline int rn_arpeggio(song_t *csf, song_voice_t *chan, int frequency)
332 {
333 int a;
334
335 switch ((csf->current_speed - csf->tick_count) % 3) {
336 case 1:
337 a = chan->mem_arpeggio >> 4;
338 break;
339 case 2:
340 a = chan->mem_arpeggio & 0xf;
341 break;
342 default:
343 a = 0;
344 }
345
346 if (!a)
347 return frequency;
348
349 a = linear_slide_up_table[a * 16];
350 return _muldiv(frequency, a, 65536);
351 }
352
353
rn_pitch_filter_envelope(song_t * csf,song_voice_t * chan,int * nenvpitch,int * nfrequency)354 static inline void rn_pitch_filter_envelope(song_t *csf, song_voice_t *chan,
355 int *nenvpitch, int *nfrequency)
356 {
357 song_instrument_t *penv = chan->ptr_instrument;
358 int envpos = chan->pitch_env_position;
359 unsigned int pt = penv->pitch_env.nodes - 1;
360 int frequency = *nfrequency;
361 int envpitch = *nenvpitch;
362
363 for (unsigned int i = 0; i < (unsigned int)(penv->pitch_env.nodes - 1); i++) {
364 if (envpos <= penv->pitch_env.ticks[i]) {
365 pt = i;
366 break;
367 }
368 }
369
370 int x2 = penv->pitch_env.ticks[pt];
371 int x1;
372
373 if (envpos >= x2) {
374 envpitch = (((int)penv->pitch_env.values[pt]) - 32) * 8;
375 x1 = x2;
376 } else if (pt) {
377 envpitch = (((int)penv->pitch_env.values[pt - 1]) - 32) * 8;
378 x1 = penv->pitch_env.ticks[pt - 1];
379 } else {
380 envpitch = 0;
381 x1 = 0;
382 }
383
384 if (envpos > x2)
385 envpos = x2;
386
387 if (x2 > x1 && envpos > x1) {
388 int envpitchdest = (((int)penv->pitch_env.values[pt]) - 32) * 8;
389 envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1);
390 }
391
392 // clamp to -255/255?
393 envpitch = CLAMP(envpitch, -256, 256);
394
395 // Pitch Envelope
396 if (!(penv->flags & ENV_FILTER)) {
397 int l = abs(envpitch);
398
399 if (l > 255)
400 l = 255;
401
402 int ratio = (envpitch < 0 ? linear_slide_down_table : linear_slide_up_table)[l];
403 frequency = _muldiv(frequency, ratio, 0x10000);
404 }
405
406 *nfrequency = frequency;
407 *nenvpitch = envpitch;
408 }
409
410
_process_envelope(song_voice_t * chan,song_instrument_t * penv,song_envelope_t * envelope,int * position,uint32_t env_flag,uint32_t loop_flag,uint32_t sus_flag,uint32_t fade_flag)411 static inline void _process_envelope(song_voice_t *chan, song_instrument_t *penv, song_envelope_t *envelope,
412 int *position, uint32_t env_flag, uint32_t loop_flag, uint32_t sus_flag,
413 uint32_t fade_flag)
414 {
415 int start = 0, end = 0x7fffffff;
416
417 if (!(chan->flags & env_flag)) {
418 return;
419 }
420
421 (*position)++;
422
423 if ((penv->flags & sus_flag) && !(chan->flags & CHN_KEYOFF)) {
424 start = envelope->ticks[envelope->sustain_start];
425 end = envelope->ticks[envelope->sustain_end] + 1;
426 fade_flag = 0;
427 } else if (penv->flags & loop_flag) {
428 start = envelope->ticks[envelope->loop_start];
429 end = envelope->ticks[envelope->loop_end] + 1;
430 fade_flag = 0;
431 } else {
432 // End of envelope (?)
433 start = end = envelope->ticks[envelope->nodes - 1];
434 }
435 if (*position >= end) {
436 if (fade_flag && !envelope->values[envelope->nodes - 1]) {
437 chan->fadeout_volume = chan->final_volume = 0;
438 }
439 *position = start;
440 chan->flags |= fade_flag; // only relevant for volume envelope
441 }
442 }
443
rn_increment_env_pos(song_voice_t * chan)444 static inline void rn_increment_env_pos(song_voice_t *chan)
445 {
446 song_instrument_t *penv = chan->ptr_instrument;
447
448 _process_envelope(chan, penv, &penv->vol_env, &chan->vol_env_position,
449 CHN_VOLENV, ENV_VOLLOOP, ENV_VOLSUSTAIN, CHN_NOTEFADE);
450 _process_envelope(chan, penv, &penv->pan_env, &chan->pan_env_position,
451 CHN_PANENV, ENV_PANLOOP, ENV_PANSUSTAIN, 0);
452 _process_envelope(chan, penv, &penv->pitch_env, &chan->pitch_env_position,
453 CHN_PITCHENV, ENV_PITCHLOOP, ENV_PITCHSUSTAIN, 0);
454 }
455
456
rn_update_sample(song_t * csf,song_voice_t * chan,int nchan,int master_vol)457 static inline int rn_update_sample(song_t *csf, song_voice_t *chan, int nchan, int master_vol)
458 {
459 // Adjusting volumes
460 if (csf->mix_channels < 2 || (csf->flags & SONG_NOSTEREO)) {
461 chan->right_volume_new = (chan->final_volume * master_vol) >> 8;
462 chan->left_volume_new = chan->right_volume_new;
463 } else if ((chan->flags & CHN_SURROUND) && !(csf->mix_flags & SNDMIX_NOSURROUND)) {
464 chan->right_volume_new = (chan->final_volume * master_vol) >> 8;
465 chan->left_volume_new = -chan->right_volume_new;
466 } else {
467 int pan = ((int) chan->final_panning) - 128;
468 pan *= (int) csf->pan_separation;
469 pan /= 128;
470
471 if ((csf->flags & SONG_INSTRUMENTMODE)
472 && chan->ptr_instrument
473 && chan->ptr_instrument->midi_channel_mask > 0)
474 GM_Pan(nchan, pan);
475
476 pan += 128;
477 pan = CLAMP(pan, 0, 256);
478
479 if (csf->mix_flags & SNDMIX_REVERSESTEREO)
480 pan = 256 - pan;
481
482 int realvol = (chan->final_volume * master_vol) >> (8 - 1);
483
484 chan->left_volume_new = (realvol * pan) >> 8;
485 chan->right_volume_new = (realvol * (256 - pan)) >> 8;
486 }
487
488 // Clipping volumes
489 if (chan->right_volume_new > 0xFFFF)
490 chan->right_volume_new = 0xFFFF;
491
492 if (chan->left_volume_new > 0xFFFF)
493 chan->left_volume_new = 0xFFFF;
494
495 // Check IDO
496 if (csf->mix_flags & SNDMIX_NORESAMPLING) {
497 chan->flags &= ~(CHN_HQSRC);
498 chan->flags |= CHN_NOIDO;
499 } else {
500 chan->flags &= ~(CHN_NOIDO | CHN_HQSRC);
501
502 if (chan->increment == 0x10000) {
503 chan->flags |= CHN_NOIDO;
504 } else {
505 if (!(csf->mix_flags & SNDMIX_HQRESAMPLER) &&
506 !(csf->mix_flags & SNDMIX_ULTRAHQSRCMODE)) {
507 if (chan->increment >= 0xFF00)
508 chan->flags |= CHN_NOIDO;
509 }
510 }
511 }
512
513 chan->right_volume_new >>= MIXING_ATTENUATION;
514 chan->left_volume_new >>= MIXING_ATTENUATION;
515 chan->right_ramp =
516 chan->left_ramp = 0;
517
518 // Checking Ping-Pong Loops
519 if (chan->flags & CHN_PINGPONGFLAG)
520 chan->increment = -chan->increment;
521
522 if (chan->flags & CHN_MUTE) {
523 chan->left_volume = chan->right_volume = 0;
524 } else if (!(csf->mix_flags & SNDMIX_NORAMPING) &&
525 chan->flags & CHN_VOLUMERAMP &&
526 (chan->right_volume != chan->right_volume_new ||
527 chan->left_volume != chan->left_volume_new)) {
528 // Setting up volume ramp
529 int ramp_length = volume_ramp_samples;
530 int right_delta = ((chan->right_volume_new - chan->right_volume) << VOLUMERAMPPRECISION);
531 int left_delta = ((chan->left_volume_new - chan->left_volume) << VOLUMERAMPPRECISION);
532
533 if (csf->mix_flags & SNDMIX_HQRESAMPLER) {
534 if (chan->right_volume | chan->left_volume &&
535 chan->right_volume_new | chan->left_volume_new &&
536 !(chan->flags & CHN_FASTVOLRAMP)) {
537 ramp_length = csf->buffer_count;
538
539 int l = (1 << (VOLUMERAMPPRECISION - 1));
540 int r =(int) volume_ramp_samples;
541
542 ramp_length = CLAMP(ramp_length, l, r);
543 }
544 }
545
546 chan->right_ramp = right_delta / ramp_length;
547 chan->left_ramp = left_delta / ramp_length;
548 chan->right_volume = chan->right_volume_new - ((chan->right_ramp * ramp_length) >> VOLUMERAMPPRECISION);
549 chan->left_volume = chan->left_volume_new - ((chan->left_ramp * ramp_length) >> VOLUMERAMPPRECISION);
550
551 if (chan->right_ramp | chan->left_ramp) {
552 chan->ramp_length = ramp_length;
553 } else {
554 chan->flags &= ~CHN_VOLUMERAMP;
555 chan->right_volume = chan->right_volume_new;
556 chan->left_volume = chan->left_volume_new;
557 }
558 } else {
559 chan->flags &= ~CHN_VOLUMERAMP;
560 chan->right_volume = chan->right_volume_new;
561 chan->left_volume = chan->left_volume_new;
562 }
563
564 chan->right_ramp_volume = chan->right_volume << VOLUMERAMPPRECISION;
565 chan->left_ramp_volume = chan->left_volume << VOLUMERAMPPRECISION;
566
567 // Adding the channel in the channel list
568 csf->voice_mix[csf->num_voices++] = nchan;
569
570 if (csf->num_voices >= MAX_VOICES)
571 return 0;
572
573 return 1;
574 }
575
576
577 // XXX Rename this
578 //Ranges:
579 // chan_num = 0..63
580 // freq = frequency in Hertz
581 // vol = 0..16384
582 // chan->instrument_volume = 0..64 (corresponds to the sample global volume and instrument global volume)
rn_gen_key(song_t * csf,song_voice_t * chan,int chan_num,int freq,int vol)583 static inline void rn_gen_key(song_t *csf, song_voice_t *chan, int chan_num, int freq, int vol)
584 {
585 if (chan->flags & CHN_MUTE) {
586 // don't do anything
587 return;
588 } else if (csf->flags & SONG_INSTRUMENTMODE &&
589 chan->ptr_instrument &&
590 chan->ptr_instrument->midi_channel_mask > 0) {
591 MidiBendMode BendMode = MIDI_BEND_NORMAL;
592 /* TODO: If we're expecting a large bend exclusively
593 * in either direction, update BendMode to indicate so.
594 * This can be used to extend the range of MIDI pitch bending.
595 */
596
597 int volume = vol;
598
599 if ((chan->flags & CHN_ADLIB) && volume > 0) {
600 // find_volume translates volume from range 0..16384 to range 0..127. But why with that method?
601 volume = find_volume((unsigned short) volume) * chan->instrument_volume / 64;
602 } else {
603 // This gives a value in the range 0..127.
604 volume = volume * chan->instrument_volume / 8192;
605 }
606
607 GM_SetFreqAndVol(chan_num, freq, volume, BendMode, chan->flags & CHN_KEYOFF);
608 }
609 if (chan->flags & CHN_ADLIB) {
610 // Scaling is needed to get a frequency that matches with ST3 notes.
611 // 8363 is st3s middle C sample rate. 261.625 is the Hertz for middle C in a tempered scale (A4 = 440)
612 //Also, note that to be true to ST3, the frequencies should be quantized, like using the glissando control.
613
614 // OPL_Patch is called in csf_process_effects, from csf_read_note or csf_process_tick, before calling this method.
615 int oplmilliHertz = (long long int)freq*261625L/8363L;
616 OPL_HertzTouch(chan_num, oplmilliHertz, chan->flags & CHN_KEYOFF);
617
618 // ST32 ignores global & master volume in adlib mode, guess we should do the same -Bisqwit
619 // This gives a value in the range 0..63.
620 // log_appendf(2,"vol: %d, voiceinsvol: %d", vol , chan->instrument_volume);
621 OPL_Touch(chan_num, vol * chan->instrument_volume * 63 / (1 << 20));
622 if (csf->flags&SONG_NOSTEREO) {
623 OPL_Pan(chan_num, 128);
624 }
625 else {
626 OPL_Pan(chan_num, chan->final_panning);
627 }
628 }
629 }
630
631
update_vu_meter(song_voice_t * chan)632 static inline void update_vu_meter(song_voice_t *chan)
633 {
634 // Update VU-Meter (final_volume is 14-bit)
635 // TODO: missing background channels by doing it this way.
636 // need to use nMasterCh, add the vu meters for each physical voice, and bit shift.
637 uint32_t vutmp = chan->final_volume >> (14 - 8);
638 if (vutmp > 0xFF) vutmp = 0xFF;
639 if (chan->flags & CHN_ADLIB) {
640 if (chan->strike>2) { chan->vu_meter=(0xFF*chan->final_volume)>>14;}
641 // fake VU decay (intentionally similar to ST3)
642 if (chan->vu_meter > VUMETER_DECAY) {
643 chan->vu_meter -= VUMETER_DECAY;
644 } else {
645 chan->vu_meter = 0;
646 }
647 if (chan->vu_meter >= 0x100) {
648 chan->vu_meter = vutmp;
649 }
650 } else if (vutmp && chan->current_sample_data) {
651 // can't fake the funk
652 int n;
653 int pos = chan->position; // necessary on 64-bit systems (sometimes pos == -1, weird)
654 if (chan->flags & CHN_16BIT) {
655 const signed short *p = (signed short *)(chan->current_sample_data);
656 if (chan->flags & CHN_STEREO)
657 n = p[2 * pos];
658 else
659 n = p[pos];
660 n >>= 8;
661 } else {
662 const signed char *p = (signed char *)(chan->current_sample_data);
663 if (chan->flags & CHN_STEREO)
664 n = p[2 * pos];
665 else
666 n = p[pos];
667 }
668 if (n < 0)
669 n = -n;
670 vutmp *= n;
671 vutmp >>= 7; // 0..255
672 chan->vu_meter = vutmp;
673 } else {
674 chan->vu_meter = 0;
675 }
676 }
677
678 ////////////////////////////////////////////////////////////////////////////////////////////
679
csf_init_player(song_t * csf,int reset)680 int csf_init_player(song_t *csf, int reset)
681 {
682 if (max_voices > MAX_VOICES)
683 max_voices = MAX_VOICES;
684
685 csf->mix_frequency = CLAMP(csf->mix_frequency, 4000, MAX_SAMPLE_RATE);
686 volume_ramp_samples = (csf->mix_frequency * VOLUMERAMPLEN) / 100000;
687
688 if (volume_ramp_samples < 8)
689 volume_ramp_samples = 8;
690
691 if (csf->mix_flags & SNDMIX_NORAMPING)
692 volume_ramp_samples = 2;
693
694 g_dry_rofs_vol = g_dry_lofs_vol = 0;
695
696 if (reset) {
697 global_vu_left = 0;
698 global_vu_right = 0;
699 }
700
701 song_init_eq(reset, csf->mix_frequency);
702
703 // I don't know why, but this "if" makes it work at the desired sample rate instead of 4000.
704 // the "4000Hz" value comes from csf_reset, but I don't yet understand why the opl keeps that value, if
705 // each call to Fmdrv_Init generates a new opl.
706 if (csf->mix_frequency != 4000) {
707 Fmdrv_Init(csf->mix_frequency);
708 }
709 GM_Reset(0);
710 return 1;
711 }
712
713
csf_read(song_t * csf,void * v_buffer,unsigned int bufsize)714 unsigned int csf_read(song_t *csf, void * v_buffer, unsigned int bufsize)
715 {
716 uint8_t * buffer = (uint8_t *)v_buffer;
717 convert_t convert_func = clip_32_to_8;
718 int32_t vu_min[2];
719 int32_t vu_max[2];
720 unsigned int bufleft, max, sample_size, count, smpcount, mix_stat=0;
721
722 vu_min[0] = vu_min[1] = 0x7FFFFFFF;
723 vu_max[0] = vu_max[1] = -0x7FFFFFFF;
724
725
726 csf->mix_stat = 0;
727 sample_size = csf->mix_channels;
728
729 if (csf->mix_bits_per_sample == 16) { sample_size *= 2; convert_func = clip_32_to_16; }
730 else if (csf->mix_bits_per_sample == 24) { sample_size *= 3; convert_func = clip_32_to_24; }
731 else if (csf->mix_bits_per_sample == 32) { sample_size *= 4; convert_func = clip_32_to_32; }
732
733 max = bufsize / sample_size;
734
735 if (!max || !buffer) {
736 return 0;
737 }
738
739 bufleft = max;
740
741 if (csf->flags & SONG_ENDREACHED)
742 bufleft = 0; // skip the loop
743
744 while (bufleft > 0) {
745 // Update Channel Data
746
747 if (!csf->buffer_count) {
748 if (!(csf->mix_flags & SNDMIX_DIRECTTODISK))
749 csf->buffer_count = bufleft;
750
751 if (!csf_read_note(csf)) {
752 csf->flags |= SONG_ENDREACHED;
753
754 if (csf->stop_at_order > -1)
755 return 0; /* faster */
756
757 if (bufleft == max)
758 break;
759
760 if (!(csf->mix_flags & SNDMIX_DIRECTTODISK))
761 csf->buffer_count = bufleft;
762 }
763
764 if (!csf->buffer_count)
765 break;
766 }
767
768 count = csf->buffer_count;
769
770 if (count > MIXBUFFERSIZE)
771 count = MIXBUFFERSIZE;
772
773 if (count > bufleft)
774 count = bufleft;
775
776 if (!count)
777 break;
778
779 smpcount = count;
780
781 // Resetting sound buffer
782 stereo_fill(csf->mix_buffer, smpcount, &g_dry_rofs_vol, &g_dry_lofs_vol);
783
784 if (csf->mix_channels >= 2) {
785 smpcount *= 2;
786 csf->mix_stat += csf_create_stereo_mix(csf, count);
787 } else {
788 csf->mix_stat += csf_create_stereo_mix(csf, count);
789 mono_from_stereo(csf->mix_buffer, count);
790 }
791
792 // Handle eq
793 if (csf->mix_channels >= 2)
794 eq_stereo(csf, csf->mix_buffer, count);
795 else
796 eq_mono(csf, csf->mix_buffer, count);
797
798 mix_stat++;
799
800 if (csf->multi_write) {
801 /* multi doesn't actually write meaningful data into 'buffer', so we can use that
802 as temp space for converting */
803 for (unsigned int n = 0; n < 64; n++) {
804 if (csf->multi_write[n].used) {
805 unsigned int bytes = convert_func(buffer, csf->multi_write[n].buffer,
806 smpcount, vu_min, vu_max);
807 csf->multi_write[n].write(csf->multi_write[n].data, buffer, bytes);
808 } else {
809 csf->multi_write[n].silence(csf->multi_write[n].data,
810 smpcount * ((csf->mix_bits_per_sample + 7) / 8));
811 }
812 }
813 } else {
814 // Perform clipping + VU-Meter
815 buffer += convert_func(buffer, csf->mix_buffer, smpcount, vu_min, vu_max);
816 }
817
818 // Buffer ready
819 bufleft -= count;
820 csf->buffer_count -= count;
821 }
822
823 if (bufleft)
824 memset(buffer, (csf->mix_bits_per_sample == 8) ? 0x80 : 0, bufleft * sample_size);
825
826 // VU-Meter
827 //Reduce range to 8bits signed (-128 to 127).
828 vu_min[0] >>= 19;
829 vu_min[1] >>= 19;
830 vu_max[0] >>= 19;
831 vu_max[1] >>= 19;
832
833 if (vu_max[0] < vu_min[0])
834 vu_max[0] = vu_min[0];
835
836 if (vu_max[1] < vu_min[1])
837 vu_max[1] = vu_min[1];
838
839 global_vu_left = (unsigned int)(vu_max[0] - vu_min[0]);
840
841 global_vu_right = (unsigned int)(vu_max[1] - vu_min[1]);
842
843 if (mix_stat) {
844 csf->mix_stat += mix_stat - 1;
845 csf->mix_stat /= mix_stat;
846 }
847
848 return max - bufleft;
849 }
850
851
852
853 /////////////////////////////////////////////////////////////////////////////
854 // Handles navigation/effects
855
increment_order(song_t * csf)856 static int increment_order(song_t *csf)
857 {
858 csf->process_row = csf->break_row; /* [ProcessRow = BreakRow] */
859 csf->break_row = 0; /* [BreakRow = 0] */
860
861 /* some ugly copypasta, this should be less dumb */
862 if (csf->flags & SONG_PATTERNPLAYBACK) {
863 /* process_order is hijacked as a "playback initiated" flag -- otherwise repeat count
864 would be incremented as soon as pattern playback started. (this is a stupid hack) */
865 if (csf->process_order) {
866 if (++csf->repeat_count) {
867 if (UNLIKELY(csf->repeat_count < 0)) {
868 csf->repeat_count = 1; // it overflowed!
869 }
870 } else {
871 csf->process_row = PROCESS_NEXT_ORDER;
872 return 0;
873 }
874 } else {
875 csf->process_order = 1;
876 }
877 } else if (!(csf->flags & SONG_ORDERLOCKED)) {
878 /* [Increase ProcessOrder] */
879 /* [while Order[ProcessOrder] = 0xFEh, increase ProcessOrder] */
880 do {
881 csf->process_order++;
882 } while (csf->orderlist[csf->process_order] == ORDER_SKIP);
883
884 /* [if Order[ProcessOrder] = 0xFFh, ProcessOrder = 0] (... or just stop playing) */
885 if (csf->orderlist[csf->process_order] == ORDER_LAST) {
886 if (++csf->repeat_count) {
887 if (UNLIKELY(csf->repeat_count < 0)) {
888 csf->repeat_count = 1; // it overflowed!
889 }
890 } else {
891 csf->process_row = PROCESS_NEXT_ORDER;
892 return 0;
893 }
894
895 csf->process_order = 0;
896 while (csf->orderlist[csf->process_order] == ORDER_SKIP)
897 csf->process_order++;
898 }
899 if (csf->orderlist[csf->process_order] >= MAX_PATTERNS) {
900 // what the butt?
901 csf->process_row = PROCESS_NEXT_ORDER;
902 return 0;
903 }
904
905 /* [CurrentPattern = Order[ProcessOrder]] */
906 csf->current_order = csf->process_order;
907 csf->current_pattern = csf->orderlist[csf->process_order];
908 }
909
910 if (!csf->pattern_size[csf->current_pattern] || !csf->patterns[csf->current_pattern]) {
911 /* okay, this is wrong. allocate the pattern _NOW_ */
912 csf->patterns[csf->current_pattern] = csf_allocate_pattern(64);
913 csf->pattern_size[csf->current_pattern] = 64;
914 csf->pattern_alloc_size[csf->current_pattern] = 64;
915 }
916
917 if (csf->process_row >= csf->pattern_size[csf->current_pattern]) {
918 // Cxx to row beyond end of pattern: use 0 instead
919 csf->process_row = 0;
920 }
921
922 return 1;
923 }
924
925
csf_process_tick(song_t * csf)926 int csf_process_tick(song_t *csf)
927 {
928 csf->flags &= ~SONG_FIRSTTICK;
929 /* [Decrease tick counter. Is tick counter 0?] */
930 if (--csf->tick_count == 0) {
931 /* [-- Yes --] */
932
933 /* [Tick counter = Tick counter set (the current 'speed')] */
934 csf->tick_count = csf->current_speed;
935
936 /* [Decrease row counter. Is row counter 0?] */
937 if (--csf->row_count <= 0) {
938 /* [-- Yes --] */
939
940 /* [Row counter = 1]
941 this uses zero, in order to simplify SEx effect handling -- SEx has no effect if a
942 channel to its left has already set the delay value. thus we set the row counter
943 there to (value + 1) which is never zero, but 0 and 1 are fundamentally equivalent
944 as far as csf_process_tick is concerned. */
945 csf->row_count = 0;
946
947 /* [Increase ProcessRow. Is ProcessRow > NumberOfRows?] */
948 if (++csf->process_row >= csf->pattern_size[csf->current_pattern]) {
949 /* [-- Yes --] */
950
951 if (!increment_order(csf))
952 return 0;
953 } /* else [-- No --] */
954
955 /* [CurrentRow = ProcessRow] */
956 csf->row = csf->process_row;
957
958 /* [Update Pattern Variables]
959 (this is handled along with update effects) */
960 csf->flags |= SONG_FIRSTTICK;
961 } else {
962 /* [-- No --] */
963 /* Call update-effects for each channel. */
964 }
965
966
967 // Reset channel values
968 song_voice_t *chan = csf->voices;
969 song_note_t *m = csf->patterns[csf->current_pattern] + csf->row * MAX_CHANNELS;
970
971 for (unsigned int nchan=0; nchan<MAX_CHANNELS; chan++, nchan++, m++) {
972 // this is where we're going to spit out our midi
973 // commands... ALL WE DO is dump raw midi data to
974 // our super-secret "midi buffer"
975 // -mrsb
976 if (csf_midi_out_note)
977 csf_midi_out_note(nchan, m);
978
979 chan->row_note = m->note;
980
981 if (m->instrument)
982 chan->last_instrument = m->instrument;
983
984 chan->row_instr = m->instrument;
985 chan->row_voleffect = m->voleffect;
986 chan->row_volparam = m->volparam;
987 chan->row_effect = m->effect;
988 chan->row_param = m->param;
989
990 chan->left_volume = chan->left_volume_new;
991 chan->right_volume = chan->right_volume_new;
992 chan->flags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO);
993 chan->n_command = 0;
994 }
995
996 csf_process_effects(csf, 1);
997 } else {
998 /* [-- No --] */
999 /* [Update effects for each channel as required.] */
1000
1001 if (csf_midi_out_note) {
1002 song_note_t *m = csf->patterns[csf->current_pattern] + csf->row * MAX_CHANNELS;
1003
1004 for (unsigned int nchan=0; nchan<MAX_CHANNELS; nchan++, m++) {
1005 /* m==NULL allows schism to receive notification of SDx and Scx commands */
1006 csf_midi_out_note(nchan, NULL);
1007 }
1008 }
1009
1010 csf_process_effects(csf, 0);
1011 }
1012
1013 return 1;
1014 }
1015
1016 ////////////////////////////////////////////////////////////////////////////////////////////
1017 // Handles envelopes & mixer setup
1018
csf_read_note(song_t * csf)1019 int csf_read_note(song_t *csf)
1020 {
1021 song_voice_t *chan;
1022 unsigned int cn;
1023
1024 // Checking end of row ?
1025 if (csf->flags & SONG_PAUSED) {
1026 if (!csf->current_speed)
1027 csf->current_speed = csf->initial_speed ?: 6;
1028 if (!csf->current_tempo)
1029 csf->current_tempo = csf->initial_tempo ?: 125;
1030
1031 csf->flags &= ~SONG_FIRSTTICK;
1032
1033 if (--csf->tick_count == 0) {
1034 csf->tick_count = csf->current_speed;
1035 if (--csf->row_count <= 0) {
1036 csf->row_count = 0;
1037 //csf->flags |= SONG_FIRSTTICK;
1038 }
1039 // clear channel values (similar to csf_process_tick)
1040 for (cn = 0, chan = csf->voices; cn < MAX_CHANNELS; cn++, chan++) {
1041 chan->row_note = 0;
1042 chan->row_instr = 0;
1043 chan->row_voleffect = 0;
1044 chan->row_volparam = 0;
1045 chan->row_effect = 0;
1046 chan->row_param = 0;
1047 chan->n_command = 0;
1048 }
1049 }
1050 csf_process_effects(csf, 0);
1051 } else {
1052 if (!csf_process_tick(csf))
1053 return 0;
1054 }
1055
1056 ////////////////////////////////////////////////////////////////////////////////////
1057
1058 if (!csf->current_tempo)
1059 return 0;
1060
1061 csf->buffer_count = (csf->mix_frequency * 5 * csf->tempo_factor) / (csf->current_tempo << 8);
1062
1063 // chaseback hoo hah
1064 if (csf->stop_at_order > -1 && csf->stop_at_row > -1) {
1065 if (csf->stop_at_order <= (signed) csf->current_order &&
1066 csf->stop_at_row <= (signed) csf->row) {
1067 return 0;
1068 }
1069 }
1070
1071 ////////////////////////////////////////////////////////////////////////////////////
1072 // Update channels data
1073
1074 // Master Volume + Pre-Amplification / Attenuation setup
1075 uint32_t master_vol = csf->mixing_volume << 2; // yields maximum of 0x200
1076
1077 csf->num_voices = 0;
1078
1079 for (cn = 0, chan = csf->voices; cn < MAX_VOICES; cn++, chan++) {
1080 /*if(cn == 0 || cn == 1)
1081 fprintf(stderr, "considering channel %d (per %d, pos %d/%d, flags %X)\n",
1082 (int)cn, chan->frequency, chan->position, chan->length, chan->flags);*/
1083
1084 if (chan->flags & CHN_NOTEFADE &&
1085 !(chan->fadeout_volume | chan->right_volume | chan->left_volume)) {
1086 chan->length = 0;
1087 chan->rofs =
1088 chan->lofs = 0;
1089 continue;
1090 }
1091
1092 // Check for unused channel
1093 if (cn >= MAX_CHANNELS && !chan->length) {
1094 continue;
1095 }
1096
1097 // Reset channel data
1098 chan->increment = 0;
1099 chan->final_volume = 0;
1100 chan->final_panning = chan->panning + chan->pan_swing + chan->panbrello_delta;
1101 chan->ramp_length = 0;
1102
1103 // Calc Frequency
1104 if (chan->frequency && (chan->length || (chan->flags & CHN_ADLIB))) {
1105 int vol = chan->volume;
1106
1107 if (chan->flags & CHN_TREMOLO)
1108 vol += chan->tremolo_delta;
1109
1110 vol = CLAMP(vol, 0, 256);
1111
1112 // Tremor
1113 if (chan->n_command == FX_TREMOR)
1114 rn_tremor(chan, &vol);
1115
1116 // Clip volume
1117 vol = CLAMP(vol, 0, 0x100);
1118 vol <<= 6;
1119
1120 // Process Envelopes
1121 if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument) {
1122 rn_process_envelope(chan, &vol);
1123 } else {
1124 // No Envelope: key off => note cut
1125 // 1.41-: CHN_KEYOFF|CHN_NOTEFADE
1126 if (chan->flags & CHN_NOTEFADE) {
1127 chan->fadeout_volume = 0;
1128 vol = 0;
1129 }
1130 }
1131
1132 // vol is 14-bits
1133 if (vol) {
1134 // IMPORTANT: chan->final_volume is 14 bits !!!
1135 // -> _muldiv( 14+7, 6+6, 18); => RealVolume: 14-bit result (21+12-19)
1136 chan->final_volume = _muldiv
1137 (vol * csf->current_global_volume,
1138 chan->global_volume
1139 * CLAMP(chan->instrument_volume + chan->vol_swing, 0, 64),
1140 1 << 19);
1141 }
1142
1143 int frequency = chan->frequency;
1144
1145 if ((chan->flags & (CHN_GLISSANDO|CHN_PORTAMENTO)) == (CHN_GLISSANDO|CHN_PORTAMENTO)) {
1146 frequency = get_frequency_from_note(get_note_from_frequency(frequency, chan->c5speed), chan->c5speed);
1147 }
1148
1149 // Arpeggio ?
1150 if (chan->n_command == FX_ARPEGGIO)
1151 frequency = rn_arpeggio(csf, chan, frequency);
1152
1153 // Pitch/Filter Envelope
1154 int envpitch = 0;
1155
1156 if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument
1157 && (chan->flags & CHN_PITCHENV) && chan->ptr_instrument->pitch_env.nodes)
1158 rn_pitch_filter_envelope(csf, chan, &envpitch, &frequency);
1159
1160 // Vibrato
1161 if (chan->flags & CHN_VIBRATO)
1162 frequency = rn_vibrato(csf, chan, frequency);
1163
1164 // Sample Auto-Vibrato
1165 if (chan->ptr_sample && chan->ptr_sample->vib_depth) {
1166 frequency = rn_sample_vibrato(csf, chan, frequency);
1167 }
1168
1169 if (!(chan->flags & CHN_NOTEFADE))
1170 rn_gen_key(csf, chan, cn, frequency, vol);
1171
1172 // Filter Envelope: controls cutoff frequency
1173 if (chan && chan->ptr_instrument && chan->ptr_instrument->flags & ENV_FILTER) {
1174 setup_channel_filter(chan,
1175 !(chan->flags & CHN_FILTER), envpitch, csf->mix_frequency);
1176 }
1177
1178 chan->sample_freq = frequency;
1179
1180 unsigned int ninc = _muldiv(frequency, 0x10000, csf->mix_frequency);
1181
1182 if (ninc >= 0xFFB0 && ninc <= 0x10090)
1183 ninc = 0x10000;
1184
1185 if (csf->freq_factor != 128)
1186 ninc = (ninc * csf->freq_factor) >> 7;
1187
1188 if (ninc > 0xFF0000)
1189 ninc = 0xFF0000;
1190
1191 chan->increment = (ninc + 1) & ~3;
1192 }
1193
1194 // Increment envelope position
1195 if (csf->flags & SONG_INSTRUMENTMODE && chan->ptr_instrument)
1196 rn_increment_env_pos(chan);
1197
1198 chan->final_panning = CLAMP(chan->final_panning, 0, 256);
1199
1200 // Volume ramping
1201 chan->flags &= ~CHN_VOLUMERAMP;
1202
1203 if (chan->final_volume || chan->left_volume || chan->right_volume)
1204 chan->flags |= CHN_VOLUMERAMP;
1205
1206 if (chan->strike)
1207 chan->strike--;
1208
1209 // Check for too big increment
1210 if (((chan->increment >> 16) + 1) >= (int)(chan->loop_end - chan->loop_start))
1211 chan->flags &= ~CHN_LOOP;
1212
1213 chan->right_volume_new = chan->left_volume_new = 0;
1214 if (!(chan->length && chan->increment))
1215 chan->current_sample_data = NULL;
1216
1217 update_vu_meter(chan);
1218
1219 if (chan->current_sample_data) {
1220 if (!rn_update_sample(csf, chan, cn, master_vol))
1221 break;
1222 } else {
1223 // Note change but no sample
1224 //if (chan->vu_meter > 0xFF) chan->vu_meter = 0;
1225 chan->left_volume = chan->right_volume = 0;
1226 chan->length = 0;
1227 }
1228 }
1229
1230 // Checking Max Mix Channels reached: ordering by volume
1231 if (csf->num_voices >= max_voices && (!(csf->mix_flags & SNDMIX_DIRECTTODISK))) {
1232 for (unsigned int i = 0; i < csf->num_voices; i++) {
1233 unsigned int j = i;
1234
1235 while ((j + 1 < csf->num_voices) &&
1236 (csf->voices[csf->voice_mix[j]].final_volume
1237 < csf->voices[csf->voice_mix[j + 1]].final_volume))
1238 {
1239 unsigned int n = csf->voice_mix[j];
1240 csf->voice_mix[j] = csf->voice_mix[j + 1];
1241 csf->voice_mix[j + 1] = n;
1242 j++;
1243 }
1244 }
1245 }
1246
1247 return 1;
1248 }
1249
1250