    001
    002    package ibxm;
    003
    004    public class Channel {
    005        public int pattern_loop_row;
    006
    007        private Module module;
    008        private Instrument instrument;
    009        private Sample sample;
    010        private int[] global_volume, current_note;
    011        private boolean linear_periods, fast_volume_slides, key_on, silent;
    012        private int sample_idx, sample_frac, step, left_gain, right_gain;
    013        private int volume, panning, fine_tune, period, porta_period, key_add;
    014        private int tremolo_speed, tremolo_depth, tremolo_tick, tremolo_wave, tremolo_add;
    015        private int vibrato_speed, vibrato_depth, vibrato_tick, vibrato_wave, vibrato_add;
    016        private int volume_slide_param, portamento_param, retrig_param;
    017        private int volume_envelope_tick, panning_envelope_tick;
    018        private int effect_tick, trigger_tick, fade_out_volume, random_seed;
    019
    020        private int log_2_sampling_rate;
    021        private static final int LOG_2_29024 = LogTable.log_2( 29024 );
    022        private static final int LOG_2_8287 = LogTable.log_2( 8287 );
    023        private static final int LOG_2_8363 = LogTable.log_2( 8363 );
    024        private static final int LOG_2_1712 = LogTable.log_2( 1712 );
    025
    026        private static final int[] sine_table = new int[] {
    027              0, 24 ,  49,  74,  97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253,
    028            255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120,  97,  74,  49,  24
    029        };
    030
    031        public Channel( Module mod, int sampling_rate, int[] global_vol ) {
    032            module = mod;
    033            global_volume = global_vol;
    034            linear_periods = module.linear_periods;
    035            fast_volume_slides = module.fast_volume_slides;
    036            current_note = new int[ 5 ];
    037            log_2_sampling_rate = LogTable.log_2( sampling_rate );
    038        }
    039
    040        public void reset() {
    041            tremolo_speed = 0;
    042            tremolo_depth = 0;
    043            tremolo_wave = 0;
    044            vibrato_speed = 0;
    045            vibrato_depth = 0;
    046            vibrato_wave = 0;
    047            volume_slide_param = 0;
    048            portamento_param = 0;
    049            retrig_param = 0;
    050            random_seed = 0xABC123;
    051            instrument = module.get_instrument( 0 );
    052            row( 48, 256, 0, 0, 0 );
    053        }
    054
    055        public void resample( int[] mixing_buffer, int frame_offset, int frames, int quality ) {
    056            if( !silent ) {
    057                switch( quality ) {
    058                    default:
    059                        sample.resample_nearest( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames );
    060                        break;
    061                    case 1:
    062                        sample.resample_linear( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames );
    063                        break;
    064                    case 2:
    065                        sample.resample_sinc( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames );
    066                        break;
    067                }
    068            }
    069        }
    070
    071        public void update_sample_idx( int samples ) {
    072            sample_frac += step * samples;
    073            sample_idx += sample_frac >> IBXM.FP_SHIFT;
    074            sample_frac &= IBXM.FP_MASK;
    075        }
    076
    077        public void set_volume( int vol ) {
    078            if( vol < 0 ) {
    079                vol = 0;
    080            }
    081            if( vol > 64 ) {
    082                vol = 64;
    083            }
    084            volume = vol;
    085        }
    086
    087        public void set_panning( int pan ) {
    088            if( pan < 0 ) {
    089                pan = 0;
    090            }
    091            if( pan > 255 ) {
    092                pan = 255;
    093            }
    094            panning = pan;
    095        }
    096
    097        public void row( int key, int inst_idx, int volume_column, int effect, int effect_param ) {
    098            effect = effect & 0xFF;
    099            if( effect >= 0x30 ) {
    100                /* Effects above 0x30 are internal.*/
    101                effect = 0;
    102            }
    103            if( effect == 0x00 && effect_param != 0 ) {
    104                /* Arpeggio.*/
    105                effect = 0x40;
    106            }
    107            if( effect == 0x0E ) {
    108                /* Renumber 0x0Ex effect command.*/
    109                effect = 0x30 + ( ( effect_param & 0xF0 ) >> 4 );
    110                effect_param = effect_param & 0x0F;
    111            }
    112            if( effect == 0x21 ) {
    113                /* Renumber 0x21x effect command.*/
    114                effect = 0x40 + ( ( effect_param & 0xF0 ) >> 4 );
    115                effect_param = effect_param & 0x0F;
    116            }
    117            current_note[ 0 ] = key;
    118            current_note[ 1 ] = inst_idx;
    119            current_note[ 2 ] = volume_column;
    120            current_note[ 3 ] = effect;
    121            current_note[ 4 ] = effect_param;
    122            effect_tick = 0;
    123            trigger_tick += 1;
    124            update_envelopes();
    125            key_add = 0;
    126            vibrato_add = 0;
    127            tremolo_add = 0;
    128            if( ! ( effect == 0x3D && effect_param > 0 ) ) {
    129                /* Not note delay.*/
    130                trigger( key, inst_idx, volume_column, effect );
    131                /* Handle volume column.*/
    132                switch( volume_column & 0xF0 ) {
    133                    case 0x00:
    134                        /* Do nothing.*/
    135                        break;
    136                    case 0x60:
    137                        /* Volume slide down.*/
    138                        break;
    139                    case 0x70:
    140                        /* Volume slide up.*/
    141                        break;
    142                    case 0x80:
    143                        /* Fine volume slide down.*/
    144                        set_volume( volume - ( volume_column & 0x0F ) );
    145                        break;
    146                    case 0x90:
    147                        /* Fine volume slide up.*/
    148                        set_volume( volume + ( volume_column & 0x0F ) );
    149                        break;
    150                    case 0xA0:
    151                        /* Set vibrato speed.*/
    152                        set_vibrato_speed( volume_column & 0x0F );
    153                        break;
    154                    case 0xB0:
    155                        /* Vibrato.*/
    156                        set_vibrato_depth( volume_column & 0x0F );
    157                        vibrato();
    158                        break;
    159                    case 0xC0:
    160                        /* Set panning.*/
    161                        set_panning( ( volume_column & 0x0F ) << 4 );
    162                        break;
    163                    case 0xD0:
    164                        /* Panning slide left.*/
    165                        break;
    166                    case 0xE0:
    167                        /* Panning slide right.*/
    168                        break;
    169                    case 0xF0:
    170                        /* Tone portamento.*/
    171                        set_portamento_param( volume_column & 0x0F );
    172                        break;
    173                    default:
    174                        /* Set volume.*/
    175                        set_volume( volume_column - 0x10 );
    176                        break;
    177                }
    178            }
    179            if( instrument.vibrato_depth > 0 ) {
    180                auto_vibrato();
    181            }
    182            switch( effect ) {
    183                case 0x01:
    184                    /* Portmento Up.*/
    185                    set_portamento_param( effect_param );
    186                    portamento_up();
    187                    break;
    188                case 0x02:
    189                    /* Portamento Down.*/
    190                    set_portamento_param( effect_param );
    191                    portamento_down();
    192                    break;
    193                case 0x03:
    194                    /* Tone Portamento.*/
    195                    set_portamento_param( effect_param );
    196                    break;
    197                case 0x04:
    198                    /* Vibrato.*/
    199                    set_vibrato_speed( ( effect_param & 0xF0 ) >> 4 );
    200                    set_vibrato_depth( effect_param & 0x0F );
    201                    vibrato();
    202                    break;
    203                case 0x05:
    204                    /* Tone Portamento + Volume Slide.*/
    205                    set_volume_slide_param( effect_param );
    206                    volume_slide();
    207                    break;
    208                case 0x06:
    209                    /* Vibrato + Volume Slide.*/
    210                    set_volume_slide_param( effect_param );
    211                    vibrato();
    212                    volume_slide();
    213                    break;
    214                case 0x07:
    215                    /* Tremolo.*/
    216                    set_tremolo_speed( ( effect_param & 0xF0 ) >> 4 );
    217                    set_tremolo_depth( effect_param & 0x0F );
    218                    tremolo();
    219                    break;
    220                case 0x08:
    221                    /* Set Panning.*/
    222                    set_panning( effect_param );
    223                    break;
    224                case 0x09:
    225                    /* Set Sample Index.*/
    226                    set_sample_index( effect_param << 8 );
    227                    break;
    228                case 0x0A:
    229                    /* Volume Slide.*/
    230                    set_volume_slide_param( effect_param );
    231                    volume_slide();
    232                    break;
    233                case 0x0B:
    234                    /* Pattern Jump.*/
    235                    break;
    236                case 0x0C:
    237                    /* Set volume.*/
    238                    set_volume( effect_param );
    239                    break;
    240                case 0x0D:
    241                    /* Pattern Break.*/
    242                    break;
    243                case 0x0E:
    244                    /* Extended Commands (See 0x30-0x3F).*/
    245                    break;
    246                case 0x0F:
    247                    /* Set Speed/Tempo.*/
    248                    break;
    249                case 0x10:
    250                    /* Set Global Volume.*/
    251                    set_global_volume( effect_param );
    252                    break;
    253                case 0x11:
    254                    /* global Volume Slide.*/
    255                    set_volume_slide_param( effect_param );
    256                    break;
    257                case 0x14:
    258                    /* Key Off*/
    259                    if( effect_param == 0 ) {
    260                        key_on = false;
    261                    }
    262                    break;
    263                case 0x15:
    264                    /* Set Envelope Tick.*/
    265                    set_envelope_tick( effect_param );
    266                    break;
    267                case 0x19:
    268                    /* Panning Slide.*/
    269                    set_volume_slide_param( effect_param );
    270                    break;
    271                case 0x1B:
    272                    /* Retrig + Volume Slide.*/
    273                    set_retrig_param( effect_param );
    274                    retrig_volume_slide();
    275                    break;
    276                case 0x1D:
    277                    /* Tremor.*/
    278                    set_retrig_param( effect_param );
    279                    tremor();
    280                    break;
    281                case 0x24:
    282                    /* S3M Fine Vibrato.*/
    283                    set_vibrato_speed( ( effect_param & 0xF0 ) >> 4 );
    284                    set_vibrato_depth( effect_param & 0x0F );
    285                    fine_vibrato();
    286                    break;
    287                case 0x25:
    288                    /* S3M Set Speed.*/
    289                    break;
    290                case 0x30:
    291                    /* Amiga Set Filter.*/
    292                    break;
    293                case 0x31:
    294                    /* Fine Portamento Up.*/
    295                    set_portamento_param( 0xF0 | effect_param );
    296                    portamento_up();
    297                    break;
    298                case 0x32:
    299                    /* Fine Portamento Down.*/
    300                    set_portamento_param( 0xF0 | effect_param );
    301                    portamento_down();
    302                    break;
    303                case 0x33:
    304                    /* Set Glissando Mode.*/
    305                    break;
    306                case 0x34:
    307                    /* Set Vibrato Waveform.*/
    308                    set_vibrato_wave( effect_param );
    309                    break;
    310                case 0x35:
    311                    /* Set Fine Tune.*/
    312                    break;
    313                case 0x36:
    314                    /* Pattern Loop.*/
    315                    break;
    316                case 0x37:
    317                    /* Set Tremolo Waveform.*/
    318                    set_tremolo_wave( effect_param );
    319                    break;
    320                case 0x38:
    321                    /* Set Panning(Obsolete).*/
    322                    break;
    323                case 0x39:
    324                    /* Retrig.*/
    325                    set_retrig_param( effect_param );
    326                    break;
    327                case 0x3A:
    328                    /* Fine Volume Slide Up.*/
    329                    set_volume_slide_param( ( effect_param << 4 ) | 0x0F );
    330                    volume_slide();
    331                    break;
    332                case 0x3B:
    333                    /* Fine Volume Slide Down.*/
    334                    set_volume_slide_param( 0xF0 | effect_param );
    335                    volume_slide();
    336                    break;
    337                case 0x3C:
    338                    /* Note Cut.*/
    339                    if( effect_param == 0 ) {
    340                        set_volume( 0 );
    341                    }
    342                    break;
    343                case 0x3D:
    344                    /* Note Delay.*/
    345                    break;
    346                case 0x3E:
    347                    /* Pattern Delay.*/
    348                    break;
    349                case 0x3F:
    350                    /* Invert Loop.*/
    351                    break;
    352                case 0x40:
    353                    /* Arpeggio.*/
    354                    break;
    355                case 0x41:
    356                    /* Extra Fine Porta Up.*/
    357                    set_portamento_param( 0xE0 | effect_param );
    358                    portamento_up();
    359                    break;
    360                case 0x42:
    361                    /* Extra Fine Porta Down.*/
    362                    set_portamento_param( 0xE0 | effect_param );
    363                    portamento_down();
    364                    break;
    365            }
    366            calculate_amplitude();
    367            calculate_frequency();
    368        }
    369
    370        public void tick() {
    371            int volume_column, effect, effect_param;
    372            volume_column = current_note[ 2 ];
    373            effect = current_note[ 3 ];
    374            effect_param = current_note[ 4 ];
    375            effect_tick += 1;
    376            if( effect == 0x3D && effect_param == effect_tick ) {
    377                /* Note delay.*/
    378                row( current_note[ 0 ], current_note[ 1 ], volume_column, 0, 0 );
    379            } else {
    380                trigger_tick += 1;
    381                vibrato_tick += 1;
    382                tremolo_tick += 1;
    383                update_envelopes();
    384                key_add = 0;
    385                vibrato_add = 0;
    386                tremolo_add = 0;
    387                if( instrument.vibrato_depth > 0 ) {
    388                    auto_vibrato();
    389                }
    390                switch( volume_column & 0xF0 ) {
    391                    case 0x60:
    392                        /* Volume Slide Down.*/
    393                        set_volume( volume - ( volume_column & 0x0F ) );
    394                        break;
    395                    case 0x70:
    396                        /* Volume Slide Up.*/
    397                        set_volume( volume + ( volume_column & 0x0F ) );
    398                        break;
    399                    case 0xB0:
    400                        /* Vibrato.*/
    401                        vibrato();
    402                        break;
    403                    case 0xD0:
    404                        /* Panning Slide Left.*/
    405                        set_panning( panning - ( volume_column & 0x0F ) );
    406                        break;
    407                    case 0xE0:
    408                        /* Panning Slide Right.*/
    409                        set_panning( panning + ( volume_column & 0x0F ) );
    410                        break;
    411                    case 0xF0:
    412                        /* Tone Portamento.*/
    413                        tone_portamento();
    414                        break;
    415                }
    416                switch( effect ) {
    417                    case 0x01:
    418                        /* Portamento Up.*/
    419                        portamento_up();
    420                        break;
    421                    case 0x02:
    422                        /* Portamento Down.*/
    423                        portamento_down();
    424                        break;
    425                    case 0x03:
    426                        /* Tone Portamento.*/
    427                        tone_portamento();
    428                        break;
    429                    case 0x04:
    430                        /* Vibrato.*/
    431                        vibrato();
    432                        break;
    433                    case 0x05:
    434                        /* Tone Portamento + Volume Slide.*/
    435                        tone_portamento();
    436                        volume_slide();
    437                        break;
    438                    case 0x06:
    439                        /* Vibrato + Volume Slide */
    440                        vibrato();
    441                        volume_slide();
    442                        break;
    443                    case 0x07:
    444                        /* Tremolo.*/
    445                        tremolo();
    446                        break;
    447                    case 0x0A:
    448                        /* Volume Slide.*/
    449                        volume_slide();
    450                        break;
    451                    case 0x11:
    452                        /* Global Volume Slide.*/
    453                        global_volume_slide();
    454                        break;
    455                    case 0x14:
    456                        /* Key off.*/
    457                        if( effect_tick == effect_param ) {
    458                            key_on = false;
    459                        }
    460                        break;
    461                    case 0x19:
    462                        /* Panning Slide.*/
    463                        panning_slide();
    464                        break;
    465                    case 0x1B:
    466                        /* Retrig + Volume Slide.*/
    467                        retrig_volume_slide();
    468                        break;
    469                    case 0x1D:
    470                        /* Tremor.*/
    471                        tremor();
    472                        break;
    473                    case 0x24:
    474                        /* S3M Fine Vibrato.*/
    475                        fine_vibrato();
    476                        break;
    477                    case 0x39:
    478                        /* Retrig.*/
    479                        retrig_volume_slide();
    480                        break;
    481                    case 0x3C:
    482                        /* Note Cut.*/
    483                        if( effect_tick == effect_param ) {
    484                            set_volume( 0 );
    485                        }
    486                        break;
    487                    case 0x40:
    488                        /* Arpeggio.*/
    489                        switch( effect_tick % 3 ) {
    490                            case 1:
    491                                key_add = ( effect_param & 0xF0 ) >> 4;
    492                                break;
    493                            case 2:
    494                                key_add = effect_param & 0x0F;
    495                                break;
    496                        }
    497                        break;
    498                }
    499            }
    500            calculate_amplitude();
    501            calculate_frequency();
    502        }
    503
    504        private void set_vibrato_speed( int speed ) {
    505            if( speed > 0 ) {
    506                vibrato_speed = speed;
    507            }
    508        }
    509
    510        private void set_vibrato_depth( int depth ) {
    511            if( depth > 0 ) {
    512                vibrato_depth = depth;
    513            }
    514        }
    515
    516        private void set_vibrato_wave( int wave ) {
    517            if( wave < 0 || wave > 7 ) {
    518                wave = 0;
    519            }
    520            vibrato_wave = wave;
    521        }
    522
    523        private void set_tremolo_speed( int speed ) {
    524            if( speed > 0 ) {
    525                tremolo_speed = speed;
    526            }
    527        }
    528
    529        private void set_tremolo_depth( int depth ) {
    530            if( depth > 0 ) {
    531                tremolo_depth = depth;
    532            }
    533        }
    534
    535        private void set_tremolo_wave( int wave ) {
    536            if( wave < 0 || wave > 7 ) {
    537                wave = 0;
    538            }
    539            tremolo_wave = wave;
    540        }
    541
    542        private void vibrato() {
    543            int vibrato_phase;
    544            vibrato_phase = vibrato_tick * vibrato_speed;
    545            vibrato_add += waveform( vibrato_phase, vibrato_wave ) * vibrato_depth >> 5;
    546        }
    547
    548        private void fine_vibrato() {
    549            int vibrato_phase;
    550            vibrato_phase = vibrato_tick * vibrato_speed;
    551            vibrato_add += waveform( vibrato_phase, vibrato_wave ) * vibrato_depth >> 7;
    552        }
    553
    554        private void tremolo() {
    555            int tremolo_phase;
    556            tremolo_phase = tremolo_tick * tremolo_speed;
    557            tremolo_add += waveform( tremolo_phase, tremolo_wave ) * tremolo_depth >> 6;
    558        }
    559
    560        private void set_portamento_param( int param ) {
    561            if( param != 0 ) {
    562                portamento_param = param;
    563            }
    564        }
    565
    566        private void tone_portamento() {
    567            int new_period;
    568            if( porta_period < period ) {
    569                new_period = period - ( portamento_param << 2 );
    570                if( new_period < porta_period ) {
    571                    new_period = porta_period;
    572                }
    573                set_period( new_period );
    574            }
    575            if( porta_period > period ) {
    576                new_period = period + ( portamento_param << 2 );
    577                if( new_period > porta_period ) {
    578                    new_period = porta_period;
    579                }
    580                set_period( new_period );
    581            }
    582        }
    583
    584        private void portamento_up() {
    585            if( ( portamento_param & 0xF0 ) == 0xE0 ) {
    586                /* Extra-fine porta.*/
    587                if( effect_tick == 0 ) {
    588                    set_period( period - ( portamento_param & 0x0F ) );
    589                }
    590            } else if( ( portamento_param & 0xF0 ) == 0xF0 ) {
    591                /* Fine porta.*/
    592                if( effect_tick == 0 ) {
    593                    set_period( period - ( ( portamento_param & 0x0F ) << 2 ) );
    594                }
    595            } else {
    596                /* Normal porta.*/
    597                if( effect_tick > 0 ) {
    598                    set_period( period - ( portamento_param << 2 ) );
    599                }
    600            }
    601        }
    602
    603        private void portamento_down() {
    604            if( ( portamento_param & 0xF0 ) == 0xE0 ) {
    605                /* Extra-fine porta.*/
    606                if( effect_tick == 0 ) {
    607                    set_period( period + ( portamento_param & 0x0F ) );
    608                }
    609            } else if( ( portamento_param & 0xF0 ) == 0xF0 ) {
    610                /* Fine porta.*/
    611                if( effect_tick == 0 ) {
    612                    set_period( period + ( ( portamento_param & 0x0F ) << 2 ) );
    613                }
    614            } else {
    615                /* Normal porta.*/
    616                if( effect_tick > 0 ) {
    617                    set_period( period + ( portamento_param << 2 ) );
    618                }
    619            }
    620        }
    621
    622        private void set_period( int p ) {
    623            if( p < 32 ) {
    624                p = 32;
    625            }
    626            if( p > 32768 ) {
    627                p = 32768;
    628            }
    629            period = p;
    630        }
    631
    632        private void set_global_volume( int vol ) {
    633            if( vol < 0 ) {
    634                vol = 0;
    635            }
    636            if( vol > 64 ) {
    637                vol = 64;
    638            }
    639            global_volume[ 0 ] = vol;
    640        }
    641
    642        private void set_volume_slide_param( int param ) {
    643            if( param != 0 ) {
    644                volume_slide_param = param;
    645            }
    646        }
    647
    648        private void global_volume_slide() {
    649            int up, down;
    650            up = ( volume_slide_param & 0xF0 ) >> 4;
    651            down = volume_slide_param & 0x0F;
    652            set_global_volume( global_volume[ 0 ] + up - down );
    653        }
    654
    655        private void volume_slide() {
    656            int up, down;
    657            up = ( volume_slide_param & 0xF0 ) >> 4;
    658            down = volume_slide_param & 0x0F;
    659            if( down == 0x0F && up > 0 ) {
    660                /* Fine slide up.*/
    661                if( effect_tick == 0 ) {
    662                    set_volume( volume + up );
    663                }
    664            } else if( up == 0x0F && down > 0 ) {
    665                /* Fine slide down.*/
    666                if( effect_tick == 0 ) {
    667                    set_volume( volume - down );
    668                }
    669            } else {
    670                /* Normal slide.*/
    671                if( effect_tick > 0 || fast_volume_slides ) {
    672                    set_volume( volume + up - down );
    673                }
    674            }
    675        }
    676
    677        private void panning_slide() {
    678            int left, right;
    679            left = ( volume_slide_param & 0xF0 ) >> 4;
    680            right = volume_slide_param & 0x0F;
    681            set_panning( panning - left + right );
    682        }
    683
    684        private void set_retrig_param( int param ) {
    685            if( param != 0 ) {
    686                retrig_param = param;
    687            }
    688        }
    689
    690        private void tremor() {
    691            int on_ticks, cycle_length, cycle_index;
    692            on_ticks = ( ( retrig_param & 0xF0 ) >> 4 ) + 1;
    693            cycle_length = on_ticks + ( retrig_param & 0x0F ) + 1;
    694            cycle_index = trigger_tick % cycle_length;
    695            if( cycle_index >= on_ticks ) {
    696                tremolo_add = -64;
    697            }
    698        }
    699
    700        private void retrig_volume_slide() {
    701            int retrig_volume, retrig_tick;
    702            retrig_volume = ( retrig_param & 0xF0 ) >> 4;
    703            retrig_tick = retrig_param & 0x0F;
    704            if( retrig_tick > 0 && ( trigger_tick % retrig_tick ) == 0 ) {
    705                set_sample_index( 0 );
    706                switch( retrig_volume ) {
    707                    case 0x01:
    708                        set_volume( volume - 1 );
    709                        break;
    710                    case 0x02:
    711                        set_volume( volume - 2 );
    712                        break;
    713                    case 0x03:
    714                        set_volume( volume - 4 );
    715                        break;
    716                    case 0x04:
    717                        set_volume( volume - 8 );
    718                        break;
    719                    case 0x05:
    720                        set_volume( volume - 16 );
    721                        break;
    722                    case 0x06:
    723                        set_volume( volume - volume / 3 );
    724                        break;
    725                    case 0x07:
    726                        set_volume( volume / 2 );
    727                        break;
    728                    case 0x09:
    729                        set_volume( volume + 1 );
    730                        break;
    731                    case 0x0A:
    732                        set_volume( volume + 2 );
    733                        break;
    734                    case 0x0B:
    735                        set_volume( volume + 4 );
    736                        break;
    737                    case 0x0C:
    738                        set_volume( volume + 8 );
    739                        break;
    740                    case 0x0D:
    741                        set_volume( volume + 16 );
    742                        break;
    743                    case 0x0E:
    744                        set_volume( volume + volume / 2 );
    745                        break;
    746                    case 0x0F:
    747                        set_volume( volume * 2 );
    748                        break;
    749                }
    750            }
    751        }
    752
    753        private void set_sample_index( int index ) {
    754            if( index < 0 ) {
    755                index = 0;
    756            }
    757            sample_idx = index;
    758            sample_frac = 0;
    759        }
    760
    761        private void set_envelope_tick( int tick ) {
    762            volume_envelope_tick = tick;
    763            panning_envelope_tick = tick;
    764        }
    765
    766        private void trigger( int key, int instrument_idx, int volume_column, int effect ) {
    767            if( instrument_idx > 0 ) {
    768                instrument = module.get_instrument( instrument_idx );
    769                sample = instrument.get_sample_from_key( key );
    770                set_volume( sample.volume );
    771                if( sample.set_panning ) {
    772                    set_panning( sample.panning );
    773                }
    774                set_envelope_tick( 0 );
    775                fade_out_volume = 32768;
    776                key_on = true;
    777            }
    778            if( key > 0 ) {
    779                if( key < 97 ) {
    780                    porta_period = key_to_period( key );
    781                    if( effect != 0x03 && effect != 0x05 ) {
    782                        if( ( volume_column & 0xF0 ) != 0xF0 ) {
    783                            /* Not portamento.*/
    784                            trigger_tick = 0;
    785                            if( vibrato_wave < 4 ) {
    786                                vibrato_tick = 0;
    787                            }
    788                            if( tremolo_wave < 4 ) {
    789                                tremolo_tick = 0;
    790                            }
    791                            set_period( porta_period );
    792                            set_sample_index( 0 );
    793                        }
    794                    }
    795                } else {
    796                    /* Key off.*/
    797                    key_on = false;
    798                }
    799            }
    800        }
    801
    802        private void update_envelopes() {
    803            Envelope envelope;
    804            if( instrument.volume_envelope_active ) {
    805                if( !key_on ) {
    806                    fade_out_volume -= instrument.volume_fade_out & 0xFFFF;
    807                    if( fade_out_volume < 0 ) {
    808                        fade_out_volume = 0;
    809                    }
    810                }
    811                envelope = instrument.get_volume_envelope();
    812                volume_envelope_tick = envelope.next_tick( volume_envelope_tick, key_on );
    813            }
    814            if( instrument.panning_envelope_active ) {
    815                envelope = instrument.get_panning_envelope();
    816                panning_envelope_tick = envelope.next_tick( panning_envelope_tick, key_on );
    817            }
    818        }
    819
    820        private void auto_vibrato() {
    821            int sweep, depth, rate;
    822            sweep = instrument.vibrato_sweep & 0xFF;
    823            depth = instrument.vibrato_depth & 0x0F;
    824            rate = instrument.vibrato_rate & 0x3F;
    825            if( trigger_tick < sweep ) {
    826                depth = depth * trigger_tick / sweep;
    827            }
    828            vibrato_add += waveform( trigger_tick * rate, 0 ) * depth >> 9;
    829        }
    830
    831        private int waveform( int phase, int wform ) {
    832            int amplitude;
    833            amplitude = 0;
    834            switch( wform & 0x3 ) {
    835                case 0:
    836                    /* Sine. */
    837                    if( ( phase & 0x20 ) == 0 ) {
    838                        amplitude =  sine_table[ phase & 0x1F ];
    839                    } else {
    840                        amplitude = -sine_table[ phase & 0x1F ];
    841                    }
    842                    break;
    843                case 1:
    844                    /* Saw. */
    845                    if( ( phase & 0x20 ) == 0 ) {
    846                        amplitude =   ( phase & 0x1F ) << 3;
    847                    } else {
    848                        amplitude = ( ( phase & 0x1F ) << 3 ) - 255;
    849                    }
    850                    break;
    851                case 2:
    852                    /* Square. */
    853                    if( ( phase & 0x20 ) == 0 ) {
    854                        amplitude =  255;
    855                    } else {
    856                        amplitude = -255;
    857                    }
    858                    break;
    859                case 3:
    860                    /* Random. */
    861                    amplitude = ( random_seed >> 15 ) - 255;
    862                    random_seed = ( random_seed * 65 + 17 ) & 0xFFFFFF;
    863                    break;
    864            }
    865            return amplitude;
    866        }
    867
    868        private int key_to_period( int key ) {
    869            int octave, log_2_period, period_out;
    870            octave = ( key << IBXM.FP_SHIFT ) / 12 + sample.transpose;
    871            if( linear_periods ) {
    872                period_out = 7744 - ( octave * 768 >> IBXM.FP_SHIFT );
    873            } else {
    874                log_2_period = LOG_2_29024 - octave;
    875                period_out = LogTable.raise_2( log_2_period );
    876                period_out = period_out >> ( IBXM.FP_SHIFT - 1 );
    877                period_out = ( period_out >> 1 ) + ( period_out & 1 );
    878            }
    879            return period_out;
    880        }
    881
    882        private void calculate_amplitude() {
    883            int envelope_volume, tremolo_volume, amplitude;
    884            int envelope_panning, mixer_panning, panning_range;
    885            Envelope envelope;
    886            envelope_volume = 0;
    887            if( instrument.volume_envelope_active ) {
    888                envelope = instrument.get_volume_envelope();
    889                envelope_volume = envelope.calculate_ampl( volume_envelope_tick );
    890            } else {
    891                if( key_on ) {
    892                    envelope_volume = 64;
    893                }
    894            }
    895            tremolo_volume = volume + tremolo_add;
    896            if( tremolo_volume < 0 ) {
    897                tremolo_volume = 0;
    898            }
    899            if( tremolo_volume > 64 ) {
    900                tremolo_volume = 64;
    901            }
    902            amplitude = tremolo_volume << IBXM.FP_SHIFT - 6;
    903            amplitude = amplitude * envelope_volume >> 6;
    904            amplitude = amplitude * fade_out_volume >> 15;
    905            amplitude = amplitude * global_volume[ 0 ] >> 6;
    906            amplitude = amplitude * module.channel_gain >> IBXM.FP_SHIFT;
    907            silent = sample.has_finished( sample_idx );
    908            if( amplitude <= 0 ) {
    909                silent = true;
    910            } else {
    911                envelope_panning = 32;
    912                if( instrument.panning_envelope_active ) {
    913                    envelope = instrument.get_panning_envelope();
    914                    envelope_panning = envelope.calculate_ampl( panning_envelope_tick );
    915                }
    916                mixer_panning = ( panning & 0xFF ) << IBXM.FP_SHIFT - 8;
    917                panning_range = IBXM.FP_ONE - mixer_panning;
    918                if( panning_range > mixer_panning ) {
    919                    panning_range = mixer_panning;
    920                }
    921                mixer_panning = mixer_panning + ( panning_range * ( envelope_panning - 32 ) >> 5 );
    922                left_gain = amplitude * ( IBXM.FP_ONE - mixer_panning ) >> IBXM.FP_SHIFT;
    923                right_gain = amplitude * mixer_panning >> IBXM.FP_SHIFT;
    924            }
    925        }
    926
    927        private void calculate_frequency() {
    928            int vibrato_period, log_2_freq;
    929            vibrato_period = period + vibrato_add;
    930            if( vibrato_period < 32 ) {
    931                vibrato_period = 32;
    932            }
    933            if( vibrato_period > 32768 ) {
    934                vibrato_period = 32768;
    935            }
    936            if( linear_periods ) {
    937                log_2_freq = LOG_2_8363 + ( 4608 - vibrato_period << IBXM.FP_SHIFT ) / 768;
    938            } else {
    939                log_2_freq = module.pal ? LOG_2_8287 : LOG_2_8363;
    940                log_2_freq = log_2_freq + LOG_2_1712 - LogTable.log_2( vibrato_period );
    941            }
    942            log_2_freq += ( key_add << IBXM.FP_SHIFT ) / 12;
    943            step = LogTable.raise_2( log_2_freq - log_2_sampling_rate );
    944        }
    945    }
    946