2 * Adplug - Replayer for many OPL2/OPL3 audio file formats.
3 * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp@gmx.net>, et al.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * protrack.cpp - Generic Protracker Player
22 * This is a generic Protracker-based formats player. It offers all Protracker
23 * features, plus a good set of extensions to be compatible to other Protracker
24 * derivatives. It is derived from the former SA2 player. If you got a
25 * Protracker-like format, this is most certainly the player you want to use.
32 #define SPECIALARPLEN 256 // Standard length of special arpeggio lists
33 #define JUMPMARKER 0x80 // Orderlist jump marker
35 // SA2 compatible adlib note table
36 const unsigned short CmodPlayer::sa2_notetable[12] =
37 {340,363,385,408,432,458,485,514,544,577,611,647};
39 // SA2 compatible vibrato rate table
40 const unsigned char CmodPlayer::vibratotab[32] =
41 {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
43 /*** public methods *************************************/
45 CmodPlayer::CmodPlayer(Copl *newopl)
46 : CPlayer(newopl), inst(0), order(0), arplist(0), arpcmd(0), initspeed(6),
47 nop(0), activechan(0xffffffff), flags(Standard), curchip(opl->getchip()),
48 nrows(0), npats(0), nchans(0)
51 realloc_patterns(64, 64, 9);
52 realloc_instruments(250);
53 init_notetable(sa2_notetable);
56 CmodPlayer::~CmodPlayer()
61 bool CmodPlayer::update()
63 unsigned char pattbreak=0, donote, pattnr, chan, oplchan, info1,
64 info2, info, pattern_delay;
68 if(!speed) // song full stop
71 // effect handling (timer dependant)
72 for(chan = 0; chan < nchans; chan++) {
73 oplchan = set_opl_chip(chan);
75 if(arplist && arpcmd && inst[channel[chan].inst].arpstart) { // special arpeggio
76 if(channel[chan].arpspdcnt)
77 channel[chan].arpspdcnt--;
79 if(arpcmd[channel[chan].arppos] != 255) {
80 switch(arpcmd[channel[chan].arppos]) {
81 case 252: channel[chan].vol1 = arplist[channel[chan].arppos]; // set volume
82 if(channel[chan].vol1 > 63) // ?????
83 channel[chan].vol1 = 63;
84 channel[chan].vol2 = channel[chan].vol1;
87 case 253: channel[chan].key = 0; setfreq(chan); break; // release sustaining note
88 case 254: channel[chan].arppos = arplist[channel[chan].arppos]; break; // arpeggio loop
89 default: if(arpcmd[channel[chan].arppos]) {
90 if(arpcmd[channel[chan].arppos] / 10)
91 opl->write(0xe3 + op_table[oplchan], arpcmd[channel[chan].arppos] / 10 - 1);
92 if(arpcmd[channel[chan].arppos] % 10)
93 opl->write(0xe0 + op_table[oplchan], (arpcmd[channel[chan].arppos] % 10) - 1);
94 if(arpcmd[channel[chan].arppos] < 10) // ?????
95 opl->write(0xe0 + op_table[oplchan], arpcmd[channel[chan].arppos] - 1);
98 if(arpcmd[channel[chan].arppos] != 252) {
99 if(arplist[channel[chan].arppos] <= 96)
100 setnote(chan,channel[chan].note + arplist[channel[chan].arppos]);
101 if(arplist[channel[chan].arppos] >= 100)
102 setnote(chan,arplist[channel[chan].arppos] - 100);
104 setnote(chan,channel[chan].note);
106 if(arpcmd[channel[chan].arppos] != 255)
107 channel[chan].arppos++;
108 channel[chan].arpspdcnt = inst[channel[chan].inst].arpspeed - 1;
112 info1 = channel[chan].info1;
113 info2 = channel[chan].info2;
115 info = channel[chan].info1 * 10 + channel[chan].info2;
117 info = (channel[chan].info1 << 4) + channel[chan].info2;
118 switch(channel[chan].fx) {
119 case 0: if(info) { // arpeggio
120 if(channel[chan].trigger < 2)
121 channel[chan].trigger++;
123 channel[chan].trigger = 0;
124 switch(channel[chan].trigger) {
125 case 0: setnote(chan,channel[chan].note); break;
126 case 1: setnote(chan,channel[chan].note + info1); break;
127 case 2: setnote(chan,channel[chan].note + info2);
132 case 1: slide_up(chan,info); setfreq(chan); break; // slide up
133 case 2: slide_down(chan,info); setfreq(chan); break; // slide down
134 case 3: tone_portamento(chan,channel[chan].portainfo); break; // tone portamento
135 case 4: vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2); break; // vibrato
136 case 5: // tone portamento & volume slide
137 case 6: if(channel[chan].fx == 5) // vibrato & volume slide
138 tone_portamento(chan,channel[chan].portainfo);
140 vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2);
141 case 10: if(del % 4) // SA2 volume slide
146 vol_down(chan,info2);
149 case 14: if(info1 == 3) // retrig note
150 if(!(del % (info2+1)))
153 case 16: if(del % 4) // AMD volume slide
156 vol_up_alt(chan,info1);
158 vol_down_alt(chan,info2);
161 case 20: // RAD volume slide
163 vol_down_alt(chan,info);
165 vol_up_alt(chan,info - 50);
168 case 26: // volume slide
172 vol_down(chan,info2);
177 slide_up(chan,1); channel[chan].info1--;
180 slide_down(chan,1); channel[chan].info2--;
187 if(del) { // speed compensation
192 // arrangement handling
193 if(!resolve_order()) return !songend;
196 if(!rw) AdPlug_LogWrite("\nCmodPlayer::update(): Pattern: %d, Order: %d\n", pattnr, ord);
197 AdPlug_LogWrite("CmodPlayer::update():%3d|", rw);
202 for(chan = 0; chan < nchans; chan++) {
203 oplchan = set_opl_chip(chan);
205 if(!(activechan >> (31 - chan)) & 1) { // channel active?
206 AdPlug_LogWrite("N/A|");
209 if(!(track = trackord[pattnr][chan])) { // resolve track
210 AdPlug_LogWrite("------------|");
215 AdPlug_LogWrite("%3d%3d%2X%2X%2X|", tracks[track][row].note,
216 tracks[track][row].inst, tracks[track][row].command,
217 tracks[track][row].param1, tracks[track][row].param2);
220 if(tracks[track][row].inst) {
221 channel[chan].inst = tracks[track][row].inst - 1;
222 if (!(flags & Faust)) {
223 channel[chan].vol1 = 63 - (inst[channel[chan].inst].data[10] & 63);
224 channel[chan].vol2 = 63 - (inst[channel[chan].inst].data[9] & 63);
229 if(tracks[track][row].note && tracks[track][row].command != 3) { // no tone portamento
230 channel[chan].note = tracks[track][row].note;
231 setnote(chan,tracks[track][row].note);
232 channel[chan].nextfreq = channel[chan].freq;
233 channel[chan].nextoct = channel[chan].oct;
234 channel[chan].arppos = inst[channel[chan].inst].arpstart;
235 channel[chan].arpspdcnt = 0;
236 if(tracks[track][row].note != 127) // handle key off
239 channel[chan].fx = tracks[track][row].command;
240 channel[chan].info1 = tracks[track][row].param1;
241 channel[chan].info2 = tracks[track][row].param2;
246 // command handling (row dependant)
247 info1 = channel[chan].info1;
248 info2 = channel[chan].info2;
250 info = channel[chan].info1 * 10 + channel[chan].info2;
252 info = (channel[chan].info1 << 4) + channel[chan].info2;
253 switch(channel[chan].fx) {
254 case 3: // tone portamento
255 if(tracks[track][row].note) {
256 if(tracks[track][row].note < 13)
257 channel[chan].nextfreq = notetable[tracks[track][row].note - 1];
259 if(tracks[track][row].note % 12 > 0)
260 channel[chan].nextfreq = notetable[(tracks[track][row].note % 12) - 1];
262 channel[chan].nextfreq = notetable[11];
263 channel[chan].nextoct = (tracks[track][row].note - 1) / 12;
264 if(tracks[track][row].note == 127) { // handle key off
265 channel[chan].nextfreq = channel[chan].freq;
266 channel[chan].nextoct = channel[chan].oct;
269 if(info) // remember vars
270 channel[chan].portainfo = info;
273 case 4: // vibrato (remember vars)
275 channel[chan].vibinfo1 = info1;
276 channel[chan].vibinfo2 = info2;
280 case 7: tempo = info; break; // set tempo
282 case 8: channel[chan].key = 0; setfreq(chan); break; // release sustaining note
284 case 9: // set carrier/modulator volume
286 channel[chan].vol1 = info1 * 7;
288 channel[chan].vol2 = info2 * 7;
292 case 11: // position jump
293 pattbreak = 1; rw = 0; if(info < ord) songend = 1; ord = info; break;
295 case 12: // set volume
296 channel[chan].vol1 = info;
297 channel[chan].vol2 = info;
298 if(channel[chan].vol1 > 63)
299 channel[chan].vol1 = 63;
300 if(channel[chan].vol2 > 63)
301 channel[chan].vol2 = 63;
305 case 13: // pattern break
306 if(!pattbreak) { pattbreak = 1; rw = info; ord++; } break;
308 case 14: // extended command
310 case 0: // define cell-tremolo
315 opl->write(0xbd,regbd);
318 case 1: // define cell-vibrato
323 opl->write(0xbd,regbd);
326 case 4: // increase volume fine
327 vol_up_alt(chan,info2);
331 case 5: // decrease volume fine
332 vol_down_alt(chan,info2);
336 case 6: // manual slide up
337 slide_up(chan,info2);
341 case 7: // manual slide down
342 slide_down(chan,info2);
346 case 8: // pattern delay (rows)
347 pattern_delay = info2 * speed;
352 case 15: // SA2 set speed
361 case 17: // alternate set volume
362 channel[chan].vol1 = info;
363 if(channel[chan].vol1 > 63)
364 channel[chan].vol1 = 63;
365 if(inst[channel[chan].inst].data[0] & 1) {
366 channel[chan].vol2 = info;
367 if(channel[chan].vol2 > 63)
368 channel[chan].vol2 = 63;
374 case 18: // AMD set speed
375 if(info <= 31 && info > 0)
377 if(info > 31 || !info)
381 case 19: // RAD/A2M set speed
382 speed = (info ? info : info + 1);
385 case 21: // set modulator volume
387 channel[chan].vol2 = info;
389 channel[chan].vol2 = 63;
393 case 22: // set carrier volume
395 channel[chan].vol1 = info;
397 channel[chan].vol1 = 63;
401 case 23: // fine frequency slide up
406 case 24: // fine frequency slide down
407 slide_down(chan,info);
411 case 25: // set carrier/modulator waveform
413 opl->write(0xe3 + op_table[oplchan],info1);
415 opl->write(0xe0 + op_table[oplchan],info2);
418 case 27: // set chip tremolo/vibrato
427 opl->write(0xbd,regbd);
430 case 29: // pattern delay (frames)
431 pattern_delay = info;
436 // speed compensation
437 del = speed - 1 + pattern_delay;
439 if(!pattbreak) { // next row (only if no manual advance)
447 resolve_order(); // so we can report songend right away
448 AdPlug_LogWrite("\n");
452 unsigned char CmodPlayer::set_opl_chip(unsigned char chan)
454 * Sets OPL chip according to channel number. Channels 0-8 are on first chip,
455 * channels 9-17 are on second chip. Returns corresponding OPL channel
459 int newchip = chan < 9 ? 0 : 1;
461 if(newchip != curchip) {
462 opl->setchip(newchip);
469 bool CmodPlayer::resolve_order()
471 * Resolves current orderlist entry, checking for jumps and loops.
473 * Returns true on correct processing, false if immediate recursive loop
478 while(order[ord] >= JUMPMARKER) { // jump to order
479 unsigned long neword = order[ord] - JUMPMARKER;
481 if(neword <= ord) songend = 1;
482 if(neword == ord) return false;
493 void CmodPlayer::rewind(int subsong)
497 // Reset playing variables
498 songend = del = ord = rw = regbd = 0;
499 tempo = bpm; speed = initspeed;
501 // Reset channel data
502 memset(channel,0,sizeof(Channel)*nchans);
504 // Compute number of patterns, if needed
506 for(i=0;i<length;i++)
507 nop = (order[i] > nop ? order[i] : nop);
509 opl->init(); // Reset OPL chip
510 opl->write(1, 32); // Go to ym3812 mode
512 // Enable OPL3 extensions if flagged
520 // Enable tremolo/vibrato depth if flagged
521 if(flags & Tremolo) regbd |= 128;
522 if(flags & Vibrato) regbd |= 64;
523 if(regbd) opl->write(0xbd, regbd);
526 float CmodPlayer::getrefresh()
528 return (float) (tempo / 2.5);
531 void CmodPlayer::init_trackord()
535 for(i=0;i<npats*nchans;i++)
536 trackord[i / nchans][i % nchans] = i + 1;
539 bool CmodPlayer::init_specialarp()
541 arplist = new unsigned char[SPECIALARPLEN];
542 arpcmd = new unsigned char[SPECIALARPLEN];
547 void CmodPlayer::init_notetable(const unsigned short *newnotetable)
549 memcpy(notetable, newnotetable, 12 * 2);
552 bool CmodPlayer::realloc_order(unsigned long len)
554 if(order) delete [] order;
555 order = new unsigned char[len];
559 bool CmodPlayer::realloc_patterns(unsigned long pats, unsigned long rows, unsigned long chans)
565 // set new number of tracks, rows and channels
566 npats = pats; nrows = rows; nchans = chans;
568 // alloc new patterns
569 tracks = new Tracks *[pats * chans];
570 for(i=0;i<pats*chans;i++) tracks[i] = new Tracks[rows];
571 trackord = new unsigned short *[pats];
572 for(i=0;i<pats;i++) trackord[i] = new unsigned short[chans];
573 channel = new Channel[chans];
575 // initialize new patterns
576 for(i=0;i<pats*chans;i++) memset(tracks[i],0,sizeof(Tracks)*rows);
577 for(i=0;i<pats;i++) memset(trackord[i],0,chans*2);
582 void CmodPlayer::dealloc_patterns()
586 // dealloc everything previously allocated
587 if(npats && nrows && nchans) {
588 for(i=0;i<npats*nchans;i++) delete [] tracks[i];
590 for(i=0;i<npats;i++) delete [] trackord[i];
596 bool CmodPlayer::realloc_instruments(unsigned long len)
598 // dealloc previous instance, if any
599 if(inst) delete [] inst;
601 inst = new Instrument[len];
602 memset(inst,0,sizeof(Instrument)*len); // reset instruments
606 void CmodPlayer::dealloc()
608 if(inst) delete [] inst;
609 if(order) delete [] order;
610 if(arplist) delete [] arplist;
611 if(arpcmd) delete [] arpcmd;
615 /*** private methods *************************************/
617 void CmodPlayer::setvolume(unsigned char chan)
619 unsigned char oplchan = set_opl_chip(chan);
624 opl->write(0x40 + op_table[oplchan], 63-channel[chan].vol2 + (inst[channel[chan].inst].data[9] & 192));
625 opl->write(0x43 + op_table[oplchan], 63-channel[chan].vol1 + (inst[channel[chan].inst].data[10] & 192));
629 void CmodPlayer::setvolume_alt(unsigned char chan)
631 unsigned char oplchan = set_opl_chip(chan);
632 unsigned char ivol2 = inst[channel[chan].inst].data[9] & 63;
633 unsigned char ivol1 = inst[channel[chan].inst].data[10] & 63;
635 opl->write(0x40 + op_table[oplchan], (((63 - (channel[chan].vol2 & 63)) + ivol2) >> 1) + (inst[channel[chan].inst].data[9] & 192));
636 opl->write(0x43 + op_table[oplchan], (((63 - (channel[chan].vol1 & 63)) + ivol1) >> 1) + (inst[channel[chan].inst].data[10] & 192));
639 void CmodPlayer::setfreq(unsigned char chan)
641 unsigned char oplchan = set_opl_chip(chan);
643 opl->write(0xa0 + oplchan, channel[chan].freq & 255);
644 if(channel[chan].key)
645 opl->write(0xb0 + oplchan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2) | 32);
647 opl->write(0xb0 + oplchan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
650 void CmodPlayer::playnote(unsigned char chan)
652 unsigned char oplchan = set_opl_chip(chan);
653 unsigned char op = op_table[oplchan], insnr = channel[chan].inst;
655 if(!(flags & NoKeyOn))
656 opl->write(0xb0 + oplchan, 0); // stop old note
658 // set instrument data
659 opl->write(0x20 + op, inst[insnr].data[1]);
660 opl->write(0x23 + op, inst[insnr].data[2]);
661 opl->write(0x60 + op, inst[insnr].data[3]);
662 opl->write(0x63 + op, inst[insnr].data[4]);
663 opl->write(0x80 + op, inst[insnr].data[5]);
664 opl->write(0x83 + op, inst[insnr].data[6]);
665 opl->write(0xe0 + op, inst[insnr].data[7]);
666 opl->write(0xe3 + op, inst[insnr].data[8]);
667 opl->write(0xc0 + oplchan, inst[insnr].data[0]);
668 opl->write(0xbd, inst[insnr].misc); // set misc. register
670 // set frequency, volume & play
671 channel[chan].key = 1;
675 channel[chan].vol2 = 63;
676 channel[chan].vol1 = 63;
681 void CmodPlayer::setnote(unsigned char chan, int note)
684 if(note == 127) { // key off
685 channel[chan].key = 0;
693 channel[chan].freq = notetable[note - 1];
696 channel[chan].freq = notetable[(note % 12) - 1];
698 channel[chan].freq = notetable[11];
699 channel[chan].oct = (note - 1) / 12;
700 channel[chan].freq += inst[channel[chan].inst].slide; // apply pre-slide
703 void CmodPlayer::slide_down(unsigned char chan, int amount)
705 channel[chan].freq -= amount;
706 if(channel[chan].freq <= 342) {
707 if(channel[chan].oct) {
709 channel[chan].freq <<= 1;
711 channel[chan].freq = 342;
715 void CmodPlayer::slide_up(unsigned char chan, int amount)
717 channel[chan].freq += amount;
718 if(channel[chan].freq >= 686) {
719 if(channel[chan].oct < 7) {
721 channel[chan].freq >>= 1;
723 channel[chan].freq = 686;
727 void CmodPlayer::tone_portamento(unsigned char chan, unsigned char info)
729 if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
730 (channel[chan].nextoct << 10)) {
732 if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
733 (channel[chan].nextoct << 10)) {
734 channel[chan].freq = channel[chan].nextfreq;
735 channel[chan].oct = channel[chan].nextoct;
738 if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
739 (channel[chan].nextoct << 10)) {
740 slide_down(chan,info);
741 if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
742 (channel[chan].nextoct << 10)) {
743 channel[chan].freq = channel[chan].nextfreq;
744 channel[chan].oct = channel[chan].nextoct;
750 void CmodPlayer::vibrato(unsigned char chan, unsigned char speed, unsigned char depth)
760 for(i=0;i<speed;i++) {
761 channel[chan].trigger++;
762 while(channel[chan].trigger >= 64)
763 channel[chan].trigger -= 64;
764 if(channel[chan].trigger >= 16 && channel[chan].trigger < 48)
765 slide_down(chan,vibratotab[channel[chan].trigger - 16] / (16-depth));
766 if(channel[chan].trigger < 16)
767 slide_up(chan,vibratotab[channel[chan].trigger + 16] / (16-depth));
768 if(channel[chan].trigger >= 48)
769 slide_up(chan,vibratotab[channel[chan].trigger - 48] / (16-depth));
774 void CmodPlayer::vol_up(unsigned char chan, int amount)
776 if(channel[chan].vol1 + amount < 63)
777 channel[chan].vol1 += amount;
779 channel[chan].vol1 = 63;
781 if(channel[chan].vol2 + amount < 63)
782 channel[chan].vol2 += amount;
784 channel[chan].vol2 = 63;
787 void CmodPlayer::vol_down(unsigned char chan, int amount)
789 if(channel[chan].vol1 - amount > 0)
790 channel[chan].vol1 -= amount;
792 channel[chan].vol1 = 0;
794 if(channel[chan].vol2 - amount > 0)
795 channel[chan].vol2 -= amount;
797 channel[chan].vol2 = 0;
800 void CmodPlayer::vol_up_alt(unsigned char chan, int amount)
802 if(channel[chan].vol1 + amount < 63)
803 channel[chan].vol1 += amount;
805 channel[chan].vol1 = 63;
806 if(inst[channel[chan].inst].data[0] & 1) {
807 if(channel[chan].vol2 + amount < 63)
808 channel[chan].vol2 += amount;
810 channel[chan].vol2 = 63;
814 void CmodPlayer::vol_down_alt(unsigned char chan, int amount)
816 if(channel[chan].vol1 - amount > 0)
817 channel[chan].vol1 -= amount;
819 channel[chan].vol1 = 0;
820 if(inst[channel[chan].inst].data[0] & 1) {
821 if(channel[chan].vol2 - amount > 0)
822 channel[chan].vol2 -= amount;
824 channel[chan].vol2 = 0;