Sebastian Vater a écrit :

-- 

Best regards,
                   :-) Basty/CDGS (-:

diff --git a/libavsequencer/player.c b/libavsequencer/player.c
index eb1e63e..6011a2e 100644
--- a/libavsequencer/player.c
+++ b/libavsequencer/player.c
@@ -3276,3 +3276,1025 @@ USE_ENVELOPE(arpeggio) {
 USE_ENVELOPE(resonance) {
     return (AVSequencerPlayerEnvelope *) &(player_channel->resonance_env);
 }
+
+static void run_effects ( AVSequencerContext *avctx, AVSequencerModule *module, AVSequencerSong *song, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel ) {
+    AVSequencerTrack *track;
+
+    if ((track = player_host_channel->track) && player_host_channel->effect) {
+        AVSequencerTrackEffect *track_fx;
+        AVSequencerTrackData *track_data = track->data + player_host_channel->row;
+        uint32_t fx                      = -1;
+
+        while ((++fx < track_data->effects) && ((track_fx = track_data->effects_data[fx]))) {
+            AVSequencerEffectsTable *fx_lut;
+            void (*check_func)( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel, uint16_t *fx_byte, uint16_t *data_word, uint16_t *flags );
+            uint16_t fx_byte, data_word, flags;
+            uint8_t channel_ctrl_type;
+
+            if (player_host_channel->effect == track_fx)
+                break;
+
+            fx_byte   = track_fx->command;
+            fx_lut    = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + fx_byte;
+            data_word = track_fx->data;
+            flags     = fx_lut->flags;
+
+            if ((check_func = fx_lut->check_fx_func)) {
+                check_func ( avctx, player_host_channel, player_channel, channel, &fx_byte, &data_word, &flags );
+
+                fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + fx_byte;
+            }
+
+            if (flags & AVSEQ_EFFECTS_TABLE_FLAG_EXEC_WHOLE_ROW)
+                continue;
+
+            flags = player_host_channel->exec_fx;
+
+            if (!(player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_EXEC_FX))
+                flags = fx_lut->std_exec_tick;
+
+            if (flags != player_host_channel->tempo_counter)
+                continue;
+
+            if (player_host_channel->effects_used[(fx_byte >> 3)] & (1 << (7 - (fx_byte & 7))))
+                continue;
+
+            fx_lut->effect_func ( avctx, player_host_channel, player_channel, channel, fx_byte, data_word );
+
+            if ((channel_ctrl_type = player_host_channel->ch_control_type)) {
+                if (player_host_channel->ch_control_affect & fx_lut->and_mask_ctrl) {
+                    AVSequencerPlayerHostChannel *new_player_host_channel;
+                    AVSequencerPlayerChannel *new_player_channel;
+                    uint16_t ctrl_fx_byte, ctrl_data_word, ctrl_flags, ctrl_channel;
+
+                    switch (channel_ctrl_type) {
+                    case CH_CTRL_NORMAL :
+                        if ((ctrl_channel = player_host_channel->ch_control_channel) != channel) {
+                            new_player_host_channel = song->channel_data + ctrl_channel;
+                            new_player_channel      = module->channel_data + new_player_host_channel->virtual_channel;
+                            ctrl_fx_byte            = fx_byte;
+                            ctrl_data_word          = data_word;
+                            ctrl_flags              = flags;
+
+                            if ((check_func = fx_lut->check_fx_func)) {
+                                check_func ( avctx, player_host_channel, player_channel, channel, &ctrl_fx_byte, &ctrl_data_word, &ctrl_flags );
+
+                                fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + ctrl_fx_byte;
+                            }
+
+                            fx_lut->effect_func ( avctx, new_player_host_channel, new_player_channel, ctrl_channel, ctrl_fx_byte, ctrl_data_word );
+                        }
+
+                        break;
+                    case CH_CTRL_MULTI :
+                        ctrl_channel = 0;
+
+                        do {
+                            if ((ctrl_channel != channel) && (player_host_channel->control_channels[(ctrl_channel >> 3)] & (1 << (7 - (ctrl_channel & 7))))) {
+                                new_player_host_channel = song->channel_data + ctrl_channel;
+                                new_player_channel      = module->channel_data + new_player_host_channel->virtual_channel;
+
+                                ctrl_fx_byte   = fx_byte;
+                                ctrl_data_word = data_word;
+                                ctrl_flags     = flags;
+
+                                if ((check_func = fx_lut->check_fx_func)) {
+                                    check_func ( avctx, player_host_channel, player_channel, channel, &ctrl_fx_byte, &ctrl_data_word, &ctrl_flags );
+
+                                    fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + ctrl_fx_byte;
+                                }
+
+                                fx_lut->effect_func ( avctx, new_player_host_channel, new_player_channel, ctrl_channel, ctrl_fx_byte, ctrl_data_word );
+                            }
+                        } while (++ctrl_channel < song->channels);
+
+                        break;
+                    default :
+                        ctrl_channel = 0;
+
+                        do {
+                            if (ctrl_channel != channel) {
+                                new_player_host_channel = song->channel_data + ctrl_channel;
+                                new_player_channel      = module->channel_data + new_player_host_channel->virtual_channel;
+                                ctrl_fx_byte            = fx_byte;
+                                ctrl_data_word          = data_word;
+                                ctrl_flags              = flags;
+
+                                if ((check_func = fx_lut->check_fx_func)) {
+                                    check_func ( avctx, player_host_channel, player_channel, channel, &ctrl_fx_byte, &ctrl_data_word, &ctrl_flags );
+
+                                    fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + ctrl_fx_byte;
+                                }
+
+                                fx_lut->effect_func ( avctx, new_player_host_channel, new_player_channel, ctrl_channel, ctrl_fx_byte, ctrl_data_word );
+                            }
+                        } while (++ctrl_channel < song->channels);
+
+                        break;
+                    }
+                }
+            }
+        }
+
+        fx = -1;
+
+        while ((++fx < track_data->effects) && ((track_fx = track_data->effects_data[fx]))) {
+            AVSequencerEffectsTable *fx_lut;
+            void (*check_func)( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel, uint16_t *fx_byte, uint16_t *data_word, uint16_t *flags );
+            uint16_t fx_byte, data_word, flags;
+            uint8_t channel_ctrl_type;
+
+            if (player_host_channel->effect == track_fx)
+                break;
+
+            fx_byte   = track_fx->command;
+            fx_lut    = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + fx_byte;
+            data_word = track_fx->data;
+            flags     = fx_lut->flags;
+
+            if ((check_func = fx_lut->check_fx_func)) {
+                check_func ( avctx, player_host_channel, player_channel, channel, &fx_byte, &data_word, &flags );
+
+                fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + fx_byte;
+            }
+
+            if (!(flags & AVSEQ_EFFECTS_TABLE_FLAG_EXEC_WHOLE_ROW))
+                continue;
+
+            flags = player_host_channel->exec_fx;
+
+            if (!(player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_EXEC_FX))
+                flags = fx_lut->std_exec_tick;
+
+            if (player_host_channel->tempo_counter < flags)
+                continue;
+
+            if (player_host_channel->effects_used[(fx_byte >> 3)] & (1 << (7 - (fx_byte & 7))))
+                continue;
+
+            fx_lut->effect_func ( avctx, player_host_channel, player_channel, channel, fx_byte, data_word );
+
+            if ((channel_ctrl_type = player_host_channel->ch_control_type)) {
+                if (player_host_channel->ch_control_affect & fx_lut->and_mask_ctrl) {
+                    AVSequencerPlayerHostChannel *new_player_host_channel;
+                    AVSequencerPlayerChannel *new_player_channel;
+                    uint16_t ctrl_fx_byte, ctrl_data_word, ctrl_flags, ctrl_channel;
+
+                    switch (channel_ctrl_type) {
+                    case CH_CTRL_NORMAL :
+                        if ((ctrl_channel = player_host_channel->ch_control_channel) != channel) {
+                            new_player_host_channel = song->channel_data + ctrl_channel;
+                            new_player_channel      = module->channel_data + new_player_host_channel->virtual_channel;
+                            ctrl_fx_byte            = fx_byte;
+                            ctrl_data_word          = data_word;
+                            ctrl_flags              = flags;
+
+                            if ((check_func = fx_lut->check_fx_func)) {
+                                check_func ( avctx, player_host_channel, player_channel, channel, &ctrl_fx_byte, &ctrl_data_word, &ctrl_flags );
+
+                                fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + ctrl_fx_byte;
+                            }
+
+                            if (new_player_host_channel->effects_used[(ctrl_fx_byte >> 3)] & (1 << (7 - (ctrl_fx_byte & 7))))
+                                continue;
+
+                            fx_lut->effect_func ( avctx, new_player_host_channel, new_player_channel, ctrl_channel, ctrl_fx_byte, ctrl_data_word );
+                        }
+
+                        break;
+                    case CH_CTRL_MULTI :
+                        ctrl_channel = 0;
+
+                        do {
+                            if ((ctrl_channel != channel) && (player_host_channel->control_channels[(ctrl_channel >> 3)] & (1 << (7 - (ctrl_channel & 7))))) {
+                                new_player_host_channel = song->channel_data + ctrl_channel;
+                                new_player_channel      = module->channel_data + new_player_host_channel->virtual_channel;
+                                ctrl_fx_byte            = fx_byte;
+                                ctrl_data_word          = data_word;
+                                ctrl_flags              = flags;
+
+                                if ((check_func = fx_lut->check_fx_func)) {
+                                    check_func ( avctx, player_host_channel, player_channel, channel, &ctrl_fx_byte, &ctrl_data_word, &ctrl_flags );
+
+                                    fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + ctrl_fx_byte;
+                                }
+
+                                if (new_player_host_channel->effects_used[(ctrl_fx_byte >> 3)] & (1 << (7 - (ctrl_fx_byte & 7))))
+                                    continue;
+
+                                fx_lut->effect_func ( avctx, new_player_host_channel, new_player_channel, ctrl_channel, ctrl_fx_byte, ctrl_data_word );
+                            }
+                        } while (++ctrl_channel < song->channels);
+
+                        break;
+                    default :
+                        ctrl_channel = 0;
+
+                        do {
+                            if (ctrl_channel != channel) {
+                                new_player_host_channel = song->channel_data + ctrl_channel;
+                                new_player_channel      = module->channel_data + new_player_host_channel->virtual_channel;
+                                ctrl_fx_byte            = fx_byte;
+                                ctrl_data_word          = data_word;
+                                ctrl_flags              = flags;
+
+                                if ((check_func = fx_lut->check_fx_func)) {
+                                    check_func ( avctx, player_host_channel, player_channel, channel, &ctrl_fx_byte, &ctrl_data_word, &ctrl_flags );
+
+                                    fx_lut = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + ctrl_fx_byte;
+                                }
+
+                                if (new_player_host_channel->effects_used[(ctrl_fx_byte >> 3)] & (1 << (7 - (ctrl_fx_byte & 7))))
+                                    continue;
+
+                                fx_lut->effect_func ( avctx, new_player_host_channel, new_player_channel, ctrl_channel, ctrl_fx_byte, ctrl_data_word );
+                            }
+                        } while (++ctrl_channel < song->channels);
+
+                        break;
+                    }
+                }
+            }
+        }
+    }
+}
+
+static uint32_t linear_slide_up ( AVSequencerContext *avctx, AVSequencerPlayerChannel *player_channel, uint32_t frequency, uint32_t slide_value ) {
+    uint32_t linear_slide_div  = slide_value / 3072;
+    uint32_t linear_slide_mod  = slide_value % 3072;
+    uint32_t linear_multiplier = (0x10000 + (avctx->linear_frequency_lut ? avctx->linear_frequency_lut[linear_slide_mod] : linear_frequency_lut[linear_slide_mod)) << linear_slide_div;
+    uint64_t slide_frequency   = ((uint64_t) linear_multiplier * frequency) >> 16;
+
+    if (slide_frequency > 0xFFFFFFFF)
+        slide_frequency = -1;
+
+    return (player_channel->frequency = slide_frequency);
+}
+
+static uint32_t amiga_slide_up ( AVSequencerPlayerChannel *player_channel, uint32_t frequency, uint32_t slide_value ) {
+    uint32_t period = AVSEQ_SLIDE_CONST / frequency;
+
+    if (period <= slide_value)
+        return 1;
+
+    period -= slide_value;
+
+    return (player_channel->frequency = (AVSEQ_SLIDE_CONST / period));
+}
+
+static uint32_t linear_slide_down ( AVSequencerContext *avctx, AVSequencerPlayerChannel *player_channel, uint32_t frequency, uint32_t slide_value ) {
+    uint32_t linear_slide_div  = slide_value / 3072;
+    uint32_t linear_slide_mod  = slide_value % 3072;
+    uint32_t linear_multiplier = 0x10000;
+
+    if (!(linear_slide_mod))
+        linear_multiplier <<= 1;
+
+    linear_multiplier += (avctx->linear_frequency_lut ? avctx->linear_frequency_lut[-linear_slide_mod + 3072] : linear_frequency_lut[-linear_slide_mod + 3072);
+
+    return (player_channel->frequency = ((uint64_t) linear_multiplier * frequency) >> (17 + linear_slide_div));
+}
+
+static uint32_t amiga_slide_down ( AVSequencerPlayerChannel *player_channel, uint32_t frequency, uint32_t slide_value ) {
+    uint32_t period = AVSEQ_SLIDE_CONST / frequency;
+    uint32_t new_frequency;
+
+    period += slide_value;
+
+    if (period < slide_value)
+        return 0;
+
+    new_frequency = AVSEQ_SLIDE_CONST / period;
+
+    if (frequency == new_frequency) {
+        if (!(new_frequency--))
+            new_frequency = 0;
+    }
+
+    return (player_channel->frequency = new_frequency);
+}
+
+static void portamento_slide_up ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint32_t data_word, uint32_t carry_add, uint32_t portamento_shift, uint16_t channel ) {
+    if (player_channel->host_channel == channel) {
+        uint32_t portamento_slide_value;
+        uint8_t portamento_sub_slide_value = data_word;
+
+        if ((portamento_slide_value = (data_word & 0xFFFFFF00) >> portamento_shift)) {
+            player_host_channel->sub_slide += portamento_sub_slide_value;
+
+            if (player_host_channel->sub_slide < portamento_sub_slide_value)
+                portamento_slide_value += carry_add;
+
+            if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_LINEAR_FREQ)
+                linear_slide_up ( avctx, player_channel, player_channel->frequency, portamento_slide_value );
+            else
+                amiga_slide_up ( player_channel, player_channel->frequency, portamento_slide_value );
+        }
+    }
+}
+
+static void portamento_slide_down ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint32_t data_word, uint32_t carry_add, uint32_t portamento_shift, uint16_t channel ) {
+    if (player_channel->host_channel == channel) {
+        uint32_t portamento_slide_value;
+        uint8_t portamento_sub_slide_value = data_word;
+
+        if ((int32_t) data_word < 0) {
+            portamento_slide_up ( avctx, player_host_channel, player_channel, -data_word, carry_add, portamento_shift, channel );
+
+            return;
+        }
+
+        if ((portamento_slide_value = ( data_word & 0xFFFFFF00 ) >> portamento_shift)) {
+            if (player_host_channel->sub_slide < portamento_sub_slide_value) {
+                portamento_slide_value += carry_add;
+
+                if (portamento_slide_value < carry_add)
+                    portamento_slide_value = -1;
+            }
+
+            player_host_channel->sub_slide -= portamento_sub_slide_value;
+
+            if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_LINEAR_FREQ)
+                linear_slide_down ( avctx, player_channel, player_channel->frequency, portamento_slide_value );
+            else
+                amiga_slide_down ( player_channel, player_channel->frequency, portamento_slide_value );
+        }
+    }
+}
+
+static void portamento_up_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v0, v1, v3, v4, v5, v8;
+
+    v0 = player_host_channel->fine_porta_up;
+    v1 = player_host_channel->fine_porta_down;
+    v3 = player_host_channel->porta_up_once;
+    v4 = player_host_channel->porta_down_once;
+    v5 = player_host_channel->fine_porta_up_once;
+    v8 = player_host_channel->fine_porta_down_once;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+        v0 = data_word;
+        v3 = data_word;
+        v5 = data_word;
+    }
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_SLIDES)) {
+        player_host_channel->porta_down = data_word;
+        v1 = v0;
+        v4 = v3;
+        v8 = v5;
+    }
+
+    player_host_channel->porta_up             = data_word;
+    player_host_channel->fine_porta_up        = v0;
+    player_host_channel->fine_porta_down      = v1;
+    player_host_channel->porta_up_once        = v3;
+    player_host_channel->porta_down_once      = v4;
+    player_host_channel->fine_porta_up_once   = v5;
+    player_host_channel->fine_porta_down_once = v8;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_TONE_PORTA) {
+        v1 = player_host_channel->fine_tone_porta;
+        v4 = player_host_channel->tone_porta_once;
+        v8 = player_host_channel->fine_tone_porta_once;
+
+        if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+            v1 = v0;
+            v4 = v3;
+            v8 = v5;
+        }
+
+        player_host_channel->tone_porta           = data_word;
+        player_host_channel->fine_tone_porta      = v1;
+        player_host_channel->tone_porta_once      = v4;
+        player_host_channel->fine_tone_porta_once = v8;
+    }
+}
+
+static void portamento_down_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word )
+{
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v0, v1, v3, v4, v5, v8;
+
+    v0 = player_host_channel->fine_porta_up;
+    v1 = player_host_channel->fine_porta_down;
+    v3 = player_host_channel->porta_up_once;
+    v4 = player_host_channel->porta_down_once;
+    v5 = player_host_channel->fine_porta_up_once;
+    v8 = player_host_channel->fine_porta_down_once;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+        v1 = data_word;
+        v4 = data_word;
+        v8 = data_word;
+    }
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_SLIDES)) {
+        player_host_channel->porta_up = data_word;
+        v0 = v1;
+        v3 = v4;
+        v5 = v8;
+    }
+
+    player_host_channel->porta_down           = data_word;
+    player_host_channel->fine_porta_up        = v0;
+    player_host_channel->fine_porta_down      = v1;
+    player_host_channel->porta_up_once        = v3;
+    player_host_channel->porta_down_once      = v4;
+    player_host_channel->fine_porta_up_once   = v5;
+    player_host_channel->fine_porta_down_once = v8;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_TONE_PORTA) {
+        v0 = player_host_channel->fine_tone_porta;
+        v3 = player_host_channel->tone_porta_once;
+        v5 = player_host_channel->fine_tone_porta_once;
+
+        if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+            v0 = v1;
+            v3 = v4;
+            v5 = v8;
+        }
+
+        player_host_channel->tone_porta           = data_word;
+        player_host_channel->fine_tone_porta      = v0;
+        player_host_channel->tone_porta_once      = v3;
+        player_host_channel->fine_tone_porta_once = v5;
+    }
+}
+
+static void portamento_up_once_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v0, v1, v3, v4, v5, v8;
+
+    v0 = player_host_channel->porta_up;
+    v1 = player_host_channel->porta_down;
+    v3 = player_host_channel->fine_porta_up;
+    v4 = player_host_channel->fine_porta_down;
+    v5 = player_host_channel->fine_porta_up_once;
+    v8 = player_host_channel->fine_porta_down_once;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+        v0 = data_word;
+        v3 = data_word;
+        v5 = data_word;
+    }
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_SLIDES)) {
+        player_host_channel->porta_down_once = data_word;
+        v1 = v0;
+        v4 = v3;
+        v8 = v5;
+    }
+
+    player_host_channel->porta_up_once        = data_word;
+    player_host_channel->porta_up             = v0;
+    player_host_channel->porta_down           = v1;
+    player_host_channel->fine_porta_up        = v3;
+    player_host_channel->fine_porta_down      = v4;
+    player_host_channel->fine_porta_up_once   = v5;
+    player_host_channel->fine_porta_down_once = v8;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_TONE_PORTA) {
+        v1 = player_host_channel->tone_porta;
+        v4 = player_host_channel->fine_tone_porta;
+        v8 = player_host_channel->fine_tone_porta_once;
+
+        if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+            v1 = v0;
+            v4 = v3;
+            v8 = v5;
+        }
+
+        player_host_channel->tone_porta           = v1;
+        player_host_channel->fine_tone_porta      = v4;
+        player_host_channel->tone_porta_once      = data_word;
+        player_host_channel->fine_tone_porta_once = v8;
+    }
+}
+
+static void portamento_down_once_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v0, v1, v3, v4, v5, v8;
+
+    v0 = player_host_channel->porta_up;
+    v1 = player_host_channel->porta_down;
+    v3 = player_host_channel->fine_porta_up;
+    v4 = player_host_channel->fine_porta_down;
+    v5 = player_host_channel->fine_porta_up_once;
+    v8 = player_host_channel->fine_porta_down_once;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+        v1 = data_word;
+        v4 = data_word;
+        v8 = data_word;
+    }
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_SLIDES)) {
+        player_host_channel->porta_up_once = data_word;
+        v0 = v1;
+        v3 = v4;
+        v5 = v8;
+    }
+
+    player_host_channel->porta_down_once      = data_word;
+    player_host_channel->porta_up             = v0;
+    player_host_channel->porta_down           = v1;
+    player_host_channel->fine_porta_up        = v3;
+    player_host_channel->fine_porta_down      = v4;
+    player_host_channel->fine_porta_up_once   = v5;
+    player_host_channel->fine_porta_down_once = v8;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_TONE_PORTA) {
+        v0 = player_host_channel->tone_porta;
+        v3 = player_host_channel->fine_tone_porta;
+        v5 = player_host_channel->fine_tone_porta_once;
+
+        if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_SLIDES) {
+            v0 = v1;
+            v3 = v4;
+            v5 = v8;
+        }
+
+        player_host_channel->tone_porta           = v0;
+        player_host_channel->fine_tone_porta      = v3;
+        player_host_channel->tone_porta_once      = data_word;
+        player_host_channel->fine_tone_porta_once = v5;
+    }
+}
+
+static void do_vibrato ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel, uint16_t vibrato_rate, int16_t vibrato_depth ) {
+    int32_t vibrato_slide_value;
+
+    if (!vibrato_depth)
+        vibrato_depth = player_host_channel->vibrato_depth;
+
+    player_host_channel->vibrato_depth = vibrato_depth;
+
+    vibrato_slide_value = ((-vibrato_depth * run_envelope ( avctx, (AVSequencerPlayerEnvelope *) &(player_host_channel->vibrato_env), vibrato_rate, 0 )) >> (7 - 2)) << 8;
+
+    if (player_channel->host_channel == channel) {
+        uint32_t old_frequency     = player_channel->frequency;
+        player_channel->frequency -= player_host_channel->vibrato_slide;
+
+        portamento_slide_down ( avctx, player_host_channel, player_channel, vibrato_slide_value, 1, 8, channel );
+
+        player_host_channel->vibrato_slide -= old_frequency - player_channel->frequency;
+    }
+}
+
+static uint32_t check_old_volume ( AVSequencerContext *avctx, AVSequencerPlayerChannel *player_channel, uint16_t *data_word, uint16_t channel ) {
+    AVSequencerSong *song;
+
+    if (channel != player_channel->host_channel)
+        return 0;
+
+    song = avctx->player_song;
+
+    if (song->compat_flags & AVSEQ_SONG_COMPAT_FLAG_OLD_VOLUMES) {
+        if (*data_word < 0x4000)
+            *data_word = ((*data_word & 0xFF00) << 2) | (*data_word & 0xFF);
+        else
+            *data_word = 0xFFFF;
+    }
+
+    return 1;
+}
+
+static void do_volume_slide ( AVSequencerContext *avctx, AVSequencerPlayerChannel *player_channel, uint16_t data_word, uint16_t channel ) {
+    if (check_old_volume ( avctx, player_channel, &data_word, channel)) {
+        uint16_t slide_volume = (player_channel->volume << 8U) + player_channel->sub_vol;
+
+        if ((slide_volume += data_word) < data_word)
+            slide_volume = 0xFFFF;
+
+        player_channel->volume  = slide_volume >> 8;
+        player_channel->sub_vol = slide_volume;
+    }
+}
+
+static void do_volume_slide_down ( AVSequencerContext *avctx, AVSequencerPlayerChannel *player_channel, uint16_t data_word, uint16_t channel ) {
+    if (check_old_volume ( avctx, player_channel, &data_word, channel )) {
+        uint16_t slide_volume = (player_channel->volume << 8) + player_channel->sub_vol;
+
+        if (slide_volume < data_word)
+            data_word = slide_volume;
+
+        slide_volume -= data_word;
+
+        player_channel->volume  = slide_volume >> 8;
+        player_channel->sub_vol = slide_volume;
+    }
+}
+
+static void volume_slide_up_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v3, v4, v5;
+
+    v3 = player_host_channel->vol_slide_down;
+    v4 = player_host_channel->fine_vol_slide_up;
+    v5 = player_host_channel->fine_vol_slide_down;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_VOLUME_SLIDES)
+        v4 = data_word;
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_VOLUME_SLIDES)) {
+        v3 = data_word;
+        v5 = v4;
+    }
+
+    player_host_channel->vol_slide_up        = data_word;
+    player_host_channel->vol_slide_down      = v3;
+    player_host_channel->fine_vol_slide_up   = v4;
+    player_host_channel->fine_vol_slide_down = v5;
+}
+
+static void volume_slide_down_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v0, v3, v4;
+
+    v0 = player_host_channel->vol_slide_up;
+    v3 = player_host_channel->fine_vol_slide_up;
+    v4 = player_host_channel->fine_vol_slide_down;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_VOLUME_SLIDES)
+        v4 = data_word;
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_VOLUME_SLIDES)) {
+        v0 = data_word;
+        v3 = v4;
+    }
+
+    player_host_channel->vol_slide_up        = v0;
+    player_host_channel->vol_slide_down      = data_word;
+    player_host_channel->fine_vol_slide_up   = v3;
+    player_host_channel->fine_vol_slide_down = v4;
+}
+
+static void fine_volume_slide_up_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v0, v1, v4;
+
+    v0 = player_host_channel->vol_slide_up;
+    v1 = player_host_channel->vol_slide_down;
+    v4 = player_host_channel->fine_vol_slide_down;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_VOLUME_SLIDES)
+        v0 = data_word;
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_VOLUME_SLIDES)) {
+        v1 = v0;
+        v4 = data_word;
+    }
+
+    player_host_channel->vol_slide_up        = v0;
+    player_host_channel->vol_slide_down      = v1;
+    player_host_channel->fine_vol_slide_up   = data_word;
+    player_host_channel->fine_vol_slide_down = v4;
+}
+
+static void fine_volume_slide_down_ok ( AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    AVSequencerTrack *track = player_host_channel->track;
+    uint16_t v0, v1, v3;
+
+    v0 = player_host_channel->vol_slide_up;
+    v1 = player_host_channel->vol_slide_down;
+    v3 = player_host_channel->fine_vol_slide_up;
+
+    if (track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_VOLUME_SLIDES)
+        v1 = data_word;
+
+    if (!(track->compat_flags & AVSEQ_TRACK_COMPAT_FLAG_OP_VOLUME_SLIDES)) {
+        v0 = v1;
+        v3 = data_word;
+    }
+
+    player_host_channel->vol_slide_up        = v0;
+    player_host_channel->vol_slide_down      = v1;
+    player_host_channel->fine_vol_slide_up   = data_word;
+    player_host_channel->fine_vol_slide_down = v3;
+}
+
+static uint32_t check_old_track_volume ( AVSequencerContext *avctx, uint16_t *data_word ) {
+    AVSequencerSong *song = avctx->player_song;
+
+    if (song->compat_flags & AVSEQ_SONG_COMPAT_FLAG_OLD_VOLUMES) {
+        if (*data_word < 0x4000)
+            *data_word = ((*data_word & 0xFF00) << 2) | (*data_word & 0xFF);
+        else
+            *data_word = 0xFFFF;
+    }
+
+    return 1;
+}
+
+static void do_track_volume_slide ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    if (check_old_track_volume ( avctx, &data_word )) {
+        uint16_t track_volume = (player_host_channel->track_volume << 8) + player_host_channel->track_sub_vol;
+
+        if ((track_volume += data_word) < data_word)
+            track_volume = 0xFFFF;
+
+        player_host_channel->track_volume  = track_volume >> 8;
+        player_host_channel->track_sub_vol = track_volume;
+    }
+}
+
+static void do_track_volume_slide_down ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    if (check_old_track_volume ( avctx, &data_word )) {
+        uint16_t track_volume = (player_host_channel->track_volume << 8) + player_host_channel->track_sub_vol;
+
+        if (track_volume < data_word)
+            data_word = track_volume;
+
+        track_volume                      -= data_word;
+        player_host_channel->track_volume  = track_volume >> 8;
+        player_host_channel->track_sub_vol = track_volume;
+    }
+}
+
+static void do_panning_slide ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t data_word, uint16_t channel ) {
+    if (player_channel->host_channel == channel) {
+        uint16_t panning = (player_channel->panning << 8) + player_channel->sub_pan;
+
+        if (panning < data_word)
+            data_word = panning;
+
+        panning -= data_word;
+
+        player_host_channel->track_panning = player_channel->panning = panning >> 8;
+        player_host_channel->track_sub_pan = player_channel->sub_pan = panning;
+    } else {
+        uint16_t track_panning = (player_host_channel->track_panning << 8) + player_host_channel->track_sub_pan;
+
+        if (track_panning < data_word)
+            data_word = track_panning;
+
+        track_panning                     -= data_word;
+        player_host_channel->track_panning = track_panning >> 8;
+        player_host_channel->track_sub_pan = track_panning;
+    }
+
+    player_host_channel->track_note_pan     = player_host_channel->track_panning;
+    player_host_channel->track_note_sub_pan = player_host_channel->track_sub_pan;
+}
+
+static void do_panning_slide_right ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t data_word, uint16_t channel ) {
+    if (player_channel->host_channel == channel) {
+        uint16_t panning = (player_channel->panning << 8) + player_channel->sub_pan;
+
+        if ((panning += data_word) < data_word)
+            panning = 0xFFFF;
+
+        player_host_channel->track_panning = player_channel->panning = panning >> 8;
+        player_host_channel->track_sub_pan = player_channel->sub_pan = panning;
+    } else {
+        uint16_t track_panning = (player_host_channel->track_panning << 8) + player_host_channel->track_sub_pan;
+
+        if ((track_panning += data_word) < data_word)
+            track_panning = 0xFFFF;
+
+        player_host_channel->track_panning = track_panning >> 8U;
+        player_host_channel->track_sub_pan = track_panning;
+    }
+
+    player_host_channel->track_note_pan     = player_host_channel->track_panning;
+    player_host_channel->track_note_sub_pan = player_host_channel->track_sub_pan;
+}
+
+static void do_track_panning_slide ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    uint16_t channel_panning = (player_host_channel->channel_panning << 8) + player_host_channel->channel_sub_pan;
+
+    if (channel_panning < data_word)
+        data_word = channel_panning;
+
+    channel_panning -= data_word;
+
+    player_host_channel->channel_panning = channel_panning >> 8;
+    player_host_channel->channel_sub_pan = channel_panning;
+}
+
+static void do_track_panning_slide_right ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, uint16_t data_word ) {
+    uint16_t channel_panning = (player_host_channel->channel_panning << 8) + player_host_channel->channel_sub_pan;
+
+    if ((channel_panning += data_word) < data_word)
+        channel_panning = 0xFFFF;
+
+    player_host_channel->channel_panning = channel_panning >> 8;
+    player_host_channel->channel_sub_pan = channel_panning;
+}
+
+static uint32_t check_surround_track_panning ( AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel, uint8_t channel_ctrl_byte ) {
+    if (player_channel->host_channel == channel) {
+        if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_AFFECT_CHAN_PAN)
+            return 1;
+
+        if (channel_ctrl_byte)
+            player_channel->flags |= AVSEQ_PLAYER_CHANNEL_FLAG_SMP_SUR_PAN;
+        else
+            player_channel->flags &= ~AVSEQ_PLAYER_CHANNEL_FLAG_SMP_SUR_PAN;
+    } else if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_AFFECT_CHAN_PAN) {
+        player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TRACK_SUR_PAN;
+
+        if (channel_ctrl_byte)
+            player_host_channel->flags |= AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TRACK_SUR_PAN;
+    }
+
+    return 0;
+}
+
+static uint16_t *get_speed_address ( AVSequencerSong *song, uint16_t speed_type, uint16_t *speed_min_value, uint16_t *speed_max_value ) {
+    AVSequencerPlayerGlobals *player_globals = song->global_data;
+    uint16_t *speed_adr = NULL;
+
+    switch (speed_type & 0x07) {
+    case 0x00 :
+        *speed_min_value = song->bpm_speed_min;
+        *speed_max_value = song->bpm_speed_max;
+
+        speed_adr = (uint16_t *) &(player_globals->bpm_speed);
+
+        break;
+    case 0x01 :
+        *speed_min_value = song->bpm_tempo_min;
+        *speed_max_value = song->bpm_tempo_max;
+
+        speed_adr = (uint16_t *) &(player_globals->bpm_tempo);
+
+        break;
+    case 0x02 :
+        *speed_min_value = song->spd_min;
+        *speed_max_value = song->spd_max;
+
+        speed_adr = (uint16_t *) &(player_globals->spd_speed);
+
+        break;
+    case 0x07 :
+        *speed_min_value = 1;
+        *speed_max_value = 0xFFFF;
+
+        speed_adr = (uint16_t *) &(player_globals->speed_mul);
+
+        break;
+    }
+
+    return speed_adr;
+}
+
+static void speed_val_ok ( AVSequencerContext *avctx, uint16_t *speed_adr, uint16_t speed_value, uint8_t speed_type, uint16_t speed_min_value, uint16_t speed_max_value ) {
+    AVSequencerPlayerGlobals *player_globals = avctx->player_song->global_data;
+
+    if (speed_value < speed_min_value)
+        speed_value = speed_min_value;
+
+    if (speed_value > speed_max_value)
+        speed_value = speed_max_value;
+
+    if ((speed_type & 0x07) == 0x07) {
+        player_globals->speed_mul = speed_value >> 8;
+        player_globals->speed_div = speed_value;
+    } else {
+        *speed_adr = speed_value;
+    }
+
+    if (!((player_globals->speed_type = speed_type) & 0x08)) {
+        AVSequencerMixerData *mixer = avctx->player_mixer_data;
+        uint64_t tempo = 0;
+        uint8_t speed_multiplier;
+
+        switch (speed_type & 0x07) {
+        case 0x00 :
+            player_globals->flags &= ~AVSEQ_PLAYER_GLOBALS_FLAG_SPD_TIMING;
+
+            break;
+        case 0x02 :
+            player_globals->flags |= AVSEQ_PLAYER_GLOBALS_FLAG_SPD_TIMING;
+
+            break;
+        }
+
+        if (player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_SPD_TIMING) {
+            if (player_globals->spd_speed > 10) {
+                tempo = (uint32_t) 989156 * player_globals->spd_speed;
+
+                if ((speed_multiplier = player_globals->speed_mul))
+                    tempo *= speed_multiplier;
+
+                if ((speed_multiplier = player_globals->speed_div))
+                    tempo /= speed_multiplier;
+            } else {
+                tempo = (avctx->old_st_lut ? avctx->old_st_lut[player_globals->spd_speed] : old_st_lut[player_globals->spd_speed]);
+            }
+        } else {
+            tempo = (player_globals->bpm_speed) * (player_globals->bpm_tempo) << 16;
+
+            if ((speed_multiplier = player_globals->speed_mul))
+                tempo *= speed_multiplier;
+
+            if ((speed_multiplier = player_globals->speed_div))
+                tempo /= speed_multiplier;
+        }
+
+        player_globals->tempo = tempo;
+        tempo                *= player_globals->relative_speed;
+        tempo               >>= 16;
+
+        mixer_set_tempo ( mixer, tempo, mixer->mixctx );
+    }
+}
+
+static void do_speed_slide ( AVSequencerContext *avctx, uint16_t data_word ) {
+    AVSequencerSong *song = avctx->player_song;
+    AVSequencerPlayerGlobals *player_globals = song->global_data;
+    uint16_t *speed_ptr;
+    uint16_t speed_min_value, speed_max_value;
+
+    if ((speed_ptr = get_speed_address ( song, player_globals->speed_type, &speed_min_value, &speed_max_value ))) {
+        uint16_t speed_value;
+
+        if ((player_globals->speed_type & 0x07) == 0x07)
+            speed_value = (player_globals->speed_mul << 8) + player_globals->speed_div;
+        else
+            speed_value = *speed_ptr;
+
+        if ((speed_value += data_word) < data_word)
+            speed_value = 0xFFFF;
+
+        speed_val_ok ( avctx, speed_ptr, speed_value, player_globals->speed_type, speed_min_value, speed_max_value );
+    }
+}
+
+static void do_speed_slide_slower ( AVSequencerContext *avctx, uint16_t data_word )
+{
+    AVSequencerSong *song = avctx->player_song;
+    AVSequencerPlayerGlobals *player_globals = song->global_data;
+    uint16_t *speed_ptr;
+    uint16_t speed_min_value, speed_max_value;
+
+    if ((speed_ptr = get_speed_address ( song, player_globals->speed_type, &speed_min_value, &speed_max_value ))) {
+        uint16_t speed_value;
+
+        if ((player_globals->speed_type & 0x07) == 0x07)
+            speed_value = (player_globals->speed_mul << 8) + player_globals->speed_div;
+        else
+            speed_value = *speed_ptr;
+
+        if (speed_value < data_word)
+            data_word = speed_value;
+
+        speed_value -= data_word;
+
+        speed_val_ok ( avctx, speed_ptr, speed_value, player_globals->speed_type, speed_min_value, speed_max_value );
+    }
+}
+
+static void do_global_volume_slide ( AVSequencerContext *avctx, AVSequencerPlayerGlobals *player_globals, uint16_t data_word ) {
+    if (check_old_track_volume ( avctx, &data_word )) {
+        uint16_t global_volume = (player_globals->global_volume << 8) + player_globals->global_sub_volume;
+
+        if ((global_volume += data_word) < data_word)
+            global_volume = 0xFFFF;
+
+        player_globals->global_volume     = global_volume >> 8;
+        player_globals->global_sub_volume = global_volume;
+    }
+}
+
+static void do_global_volume_slide_down ( AVSequencerContext *avctx, AVSequencerPlayerGlobals *player_globals, uint16_t data_word ) {
+    if (check_old_track_volume ( avctx, &data_word )) {
+        uint16_t global_volume = (player_globals->global_volume << 8) + player_globals->global_sub_volume;
+
+        if (global_volume < data_word)
+            data_word = global_volume;
+
+        global_volume -= data_word;
+
+        player_globals->global_volume     = global_volume >> 8;
+        player_globals->global_sub_volume = global_volume;
+    }
+}
+
+static void do_global_panning_slide ( AVSequencerPlayerGlobals *player_globals, uint16_t data_word ) {
+    uint16_t global_panning = (player_globals->global_panning << 8) + player_globals->global_sub_panning;
+
+    player_globals->flags &= ~AVSEQ_PLAYER_GLOBALS_FLAG_SURROUND;
+
+    if ((global_panning += data_word) < data_word)
+        global_panning = 0xFFFF;
+
+    player_globals->global_panning     = global_panning >> 8;
+    player_globals->global_sub_panning = global_panning;
+}
+
+static void do_global_panning_slide_right ( AVSequencerPlayerGlobals *player_globals, uint16_t data_word ) {
+    uint16_t global_panning = (player_globals->global_panning << 8) + player_globals->global_sub_panning;
+
+    player_globals->flags &= ~AVSEQ_PLAYER_GLOBALS_FLAG_SURROUND;
+
+    if (global_panning < data_word)
+        data_word = global_panning;
+
+    global_panning                    -= data_word;
+    player_globals->global_panning     = global_panning >> 8;
+    player_globals->global_sub_panning = global_panning;
+}
_______________________________________________
FFmpeg-soc mailing list
FFmpeg-soc@mplayerhq.hu
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to