Sebastian Vater a écrit :

-- 

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

diff --git a/libavsequencer/player.c b/libavsequencer/player.c
index 0980b24..330cc8e 100644
--- a/libavsequencer/player.c
+++ b/libavsequencer/player.c
@@ -26,6 +26,7 @@
 
 #include <stddef.h>
 #include <string.h>
+#include "avutil/intreadwrite.h"
 #include "avsequencer/avsequencer.h"
 #include "avsequencer/module.h"
 #include "avsequencer/song.h"
@@ -1619,3 +1620,598 @@ check_song_end_done:
         }
     }
 }
+
+static void process_row ( AVSequencerSong *song, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel ) {
+    uint32_t current_tick;
+    uint16_t counted = 0;
+
+    player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TREMOR_EXEC;
+    current_tick                = player_host_channel->tempo_counter;
+    current_tick++;
+
+    if (current_tick >= (player_host_channel->fine_pattern_delay + player_host_channel->tempo))
+        current_tick  = 0;
+
+    if (!(player_host_channel->tempo_counter = current_tick)) {
+        AVSequencerTrack *track;
+        AVSequencerOrderList *order_list;
+        AVSequencerOrderData *order_data;
+        AVSequencerPlayerGlobals *player_globals = song->global_data;
+        uint16_t pattern_delay, row, last_row, track_length;
+        uint32_t ord;
+
+        if (player_channel->host_channel == channel) {
+            uint32_t slide_value               = player_host_channel->arpeggio_freq;
+
+            player_host_channel->arpeggio_freq = 0;
+            player_channel->frequency         += slide_value;
+        }
+
+        player_host_channel->flags            &= ~(AVSEQ_PLAYER_HOST_CHANNEL_FLAG_EXEC_FX|AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TONE_PORTA|AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_TRANSPOSE|AVSEQ_PLAYER_HOST_CHANNEL_FLAG_VIBRATO|AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TREMOLO);
+
+        AV_WN64A(player_host_channel->effects_used, 0);
+        AV_WN64A(player_host_channel->effects_used + 8, 0);
+
+        player_host_channel->effect            = NULL;
+        player_host_channel->arpeggio_tick     = 0;
+        player_host_channel->note_delay        = 0;
+        player_host_channel->retrig_tick_count = 0;
+
+        if ((pattern_delay = player_host_channel->pattern_delay) && (pattern_delay > player_host_channel->pattern_delay_count++))
+            return;
+
+        player_host_channel->pattern_delay_count = 0;
+        player_host_channel->pattern_delay       = 0;
+        row                                      = player_host_channel->row;
+
+        if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_LOOP) {
+            player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_LOOP;
+            order_data                  = player_host_channel->order;
+            track                       = player_host_channel->track;
+
+            goto loop_to_row;
+        }
+
+        player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_LOOP_JMP;
+
+        if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_CHG_PATTERN) {
+            player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_CHG_PATTERN;
+            order_data                  = player_host_channel->order;
+
+            if ((player_host_channel->chg_pattern < song->tracks) && ((track = song->track_list[player_host_channel->chg_pattern]))) {
+                if (!(song->global_data->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_PATTERN))
+                    player_host_channel->track = track;
+
+                goto loop_to_row;
+            }
+        }
+
+        if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_BREAK)
+            goto get_new_pattern;
+
+        if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_BACKWARDS) {
+            if (!(row--))
+                goto get_new_pattern;
+        } else if (++row >= player_host_channel->max_row) {
+get_new_pattern:
+            order_list = (AVSequencerOrderList *) song->order_list + channel;
+            order_data = player_host_channel->order;
+ 
+            if (song->global_data->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_PATTERN) {
+                track = player_host_channel->track;
+
+                goto loop_to_row;
+            }
+
+            ord        = -1;
+
+            while (++ord < order_list->orders) {
+                if (order_data == order_list->order_data[ord])
+                    break;
+            }
+
+check_next_empty_order:
+            do {
+                ord++;
+
+                if ((ord >= order_list->orders) || (!(order_data = order_list->order_data[ord])))
+song_end_found:
+                    player_host_channel->flags |= AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SONG_END;
+                    order_list                  = (AVSequencerOrderList *) song->order_list + channel;
+
+                    if ((order_list->rep_start >= order_list->orders) || (!(order_data = order_list->order_data[order_list->rep_start]))) {
+disable_channel:
+                        player_host_channel->flags |= AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SONG_END;
+                        player_host_channel->tempo  = 0;
+
+                        return;
+                    }
+
+                    if (order_data->flags & (AVSEQ_ORDER_DATA_FLAG_END_ORDER|AVSEQ_ORDER_DATA_FLAG_END_SONG))
+                        goto disable_channel;
+
+                    row = 0;
+
+                    if (((player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_ONCE) && (order_data->flags & AVSEQ_ORDER_DATA_FLAG_NOT_IN_ONCE)) || ((!(player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_ONCE)) && (order_data->flags & AVSEQ_ORDER_DATA_FLAG_NOT_IN_REPEAT)))
+                        goto disable_channel;
+
+                    if ((track = order_data->track))
+                        break;
+                }
+
+                if (order_data->flags & AVSEQ_ORDER_DATA_FLAG_END_ORDER)
+                    goto song_end_found;
+
+                if (order_data->flags & AVSEQ_ORDER_DATA_FLAG_END_SONG) {
+                    if (player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_ONCE)
+                        goto disable_channel;
+
+                    goto song_end_found;
+                }
+            } while (((player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_ONCE) && (order_data->flags & AVSEQ_ORDER_DATA_FLAG_NOT_IN_ONCE)) || ((!(player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_ONCE)) && (order_data->flags & AVSEQ_ORDER_DATA_FLAG_NOT_IN_REPEAT)) || (!(track = order_data->track)));
+
+            player_host_channel->order = order_data;
+            player_host_channel->track = track;
+
+            if (player_host_channel->gosub_depth < order_data->played) {
+                player_host_channel->flags |= AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SONG_END;
+
+                if (player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_PLAY_ONCE)
+                    player_host_channel->tempo = 0;
+            }
+
+            order_data->played++;
+
+            player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_RESET;
+loop_to_row:
+            track_length = track->last_row;
+            row          = order_data->first_row;
+            last_row     = order_data->last_row;
+
+            if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_BREAK) {
+                player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_BREAK;
+                row                         = player_host_channel->break_row;
+
+                if (track_length < row)
+                    row = order_data->first_row;
+            }
+
+            if (track_length < row)
+                goto check_next_empty_order;
+
+            if (track_length < last_row)
+                last_row = track_length;
+
+            player_host_channel->max_row = last_row + 1;
+
+            if ((pattern_delay = order_data->tempo))
+                player_host_channel->tempo = pattern_delay;
+
+            if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_BACKWARDS)
+                row = last_row - row;
+        }
+
+        player_host_channel->row = row;
+
+        if ((uint8_t) ((player_host_channel->track->data) + row)->note == AVSEQ_TRACK_DATA_AVSEQ_TRACK_DATA_NOTE_END) {
+            if (++counted)
+                goto get_new_pattern;
+
+            goto disable_channel;
+        }
+    }
+}
+
+static void get_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)) {
+        AVSequencerTrackData *track_data = track->data;
+        AVSequencerTrackEffect *track_fx;
+        uint32_t fx;
+
+        if ((track_fx = player_host_channel->effect)) {
+            fx         = -1;
+
+            while (++fx < track_data->effects) {
+                if (track_data == track_data->effects_data[fx])
+                    break;
+            }
+        } else {
+            fx          = 0;
+            track_data += player_host_channel->row;
+        }
+
+        player_host_channel->effect = track_fx;
+
+        if ((fx < track_data->effects) && track_data->effects_data[fx]) {
+            for (;;) {
+                uint8_t fx_byte = track_fx->command;
+
+                if (fx_byte == AVSEQ_TRACK_EFFECT_CMD_EXECUTE_FX) {
+                    player_host_channel->flags  |= AVSEQ_PLAYER_HOST_CHANNEL_FLAG_EXEC_FX;
+                    player_host_channel->exec_fx = track_fx->data;
+
+                    if (player_host_channel->tempo_counter < player_host_channel->exec_fx)
+                        break;
+                }
+
+                fx++;
+
+                if ((fx >= track_data->effects) || (!(track_fx = track_data->effects_data[fx])))
+                    break;
+            }
+
+            if (player_host_channel->effect != track_fx) {
+                player_host_channel->effect = track_fx;
+
+                AV_WN64A(player_host_channel->effects_used, 0);
+                AV_WN64A(player_host_channel->effects_used + 8, 0);
+            }
+
+            track_data = track->data + player_host_channel->row;
+            fx         = -1;
+
+            while ((++fx < track_data->effects) && ((track_fx = track_data->effects_data[fx]))) {
+                AVSequencerEffectsTable *fx_lut;
+                void (*pre_fx_func)( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel, uint16_t data_word );
+                uint16_t fx_byte;
+
+                fx_byte = track_fx->command;
+                fx_lut  = (AVSequencerEffectsTable *) (avctx->effects_lut ? avctx->effects_lut : fx_lut) + fx_byte;
+
+                if ((pre_fx_func = fx_lut->pre_pattern_func))
+                    pre_fx_func ( avctx, player_host_channel, player_channel, channel, track_fx->data );
+            }
+        }
+    }
+}
+
+static uint32_t get_note ( AVSequencerContext *avctx, AVSequencerModule *module, AVSequencerSong *song, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t channel ) {
+    AVSequencerTrack *track;
+    AVSequencerTrackData *track_data;
+    AVSequencerInstrument *instrument;
+    AVSequencerPlayerChannel *new_player_channel;
+    uint32_t instr;
+    uint16_t octave_note;
+    uint8_t octave;
+    int8_t note;
+
+    if (player_host_channel->pattern_delay_count || (player_host_channel->tempo_counter != player_host_channel->note_delay) || (!(track = player_host_channel->track)))
+        return 0;
+
+    track_data = track->data + player_host_channel->row;
+
+    if (!(*(uint32_t *) &(track_data->octave)))
+        return 0;
+
+    octave_note = *(uint16_t *) &(track_data->octave);
+    octave      = track_data->octave;
+
+    if ((note = track_data->note) < 0) {
+        switch ((uint8_t) note) {
+        case AVSEQ_TRACK_DATA_NOTE_END :
+            if (!(player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_LOOP)) {
+                player_host_channel->flags    |= AVSEQ_PLAYER_HOST_CHANNEL_FLAG_PATTERN_BREAK;
+                player_host_channel->break_row = 0;
+            }
+
+            return 1;
+        case AVSEQ_TRACK_DATA_NOTE_FADE :
+            player_channel->flags |= AVSEQ_PLAYER_CHANNEL_FLAG_FADING;
+
+            break;
+        case AVSEQ_TRACK_DATA_NOTE_HOLD_DELAY :
+            break;
+        case AVSEQ_TRACK_DATA_NOTE_KEYOFF :
+            play_key_off ( player_channel );
+
+            break;
+        case AVSEQ_TRACK_DATA_NOTE_OFF :
+            player_channel->volume = 0;
+
+            break;
+        case AVSEQ_TRACK_DATA_NOTE_KILL :
+            player_host_channel->instrument = NULL;
+            player_host_channel->sample     = NULL;
+            player_host_channel->instr_note = 0;
+
+            if (player_channel->host_channel == channel)
+                player_channel->channel_data.flags = 0;
+
+            break;
+        }
+
+        return 0;
+    }
+
+    if ((instr = track_data->instrument)) {
+        AVSequencerSample *sample;
+
+        instr--;
+
+        if ((instr >= module->instruments) || (!(instrument = module->instrument_list[instr])))
+            return 0;
+
+        if (!(instrument->flags & AVSEQ_INSTRUMENT_FLAG_NO_INSTR_TRANSPOSE)) {
+            AVSequencerOrderData *order_data = player_host_channel->order;
+
+            if (order_data->instr_transpose) {
+                AVSequencerInstrument *instrument_scan;
+
+                instr += order_data->instr_transpose;
+
+                if ((instr < module->instruments) && ((instrument_scan = module->instrument_list[instr])))
+                    instrument = instrument_scan;
+            }
+        }
+
+        if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TONE_PORTA) {
+            player_host_channel->tone_porta_target_pitch = get_tone_pitch ( avctx, player_host_channel, player_channel, get_key_lut_note ( module, instrument, player_host_channel, octave, note ));
+
+            return 0;
+        }
+
+        if (octave_note) {
+            if ((new_player_channel = play_note ( avctx, module, instrument, player_host_channel, player_channel, octave, note, channel )))
+                player_channel = new_player_channel;
+
+            sample                  = player_host_channel->sample;
+            player_channel->volume  = sample->volume;
+            player_channel->sub_vol = sample->sub_volume;
+
+            init_new_instrument ( avctx, song, player_host_channel, player_channel );
+            init_new_sample ( avctx, player_host_channel, player_channel );
+        } else {
+            uint16_t note;
+
+            if (!instrument)
+                return 0;
+
+            if ((note = player_host_channel->instr_note)) {
+                if ((note = get_key_lut ( module, instrument, player_host_channel, note )) == 0x8000)
+                    return 0;
+
+                if ((player_channel->host_channel != channel) || (player_host_channel->instrument != instrument)) {
+                    if ((new_player_channel = play_note_got ( avctx, module, player_host_channel, player_channel, note, channel )))
+                        player_channel = new_player_channel;
+                }
+            } else {
+                note                             = get_key_lut ( module, instrument, player_host_channel, 1 );
+                player_host_channel->instr_note  = 0;
+                player_host_channel->sample_note = 0;
+
+                if ((new_player_channel = play_note_got ( avctx, module, player_host_channel, player_channel, note, channel )))
+                    player_channel = new_player_channel;
+
+                player_channel->flags |= AVSEQ_PLAYER_CHANNEL_FLAG_ALLOCATED;
+            }
+
+            sample                  = player_host_channel->sample;
+            player_channel->volume  = sample->volume;
+            player_channel->sub_vol = sample->sub_volume;
+
+            init_new_instrument ( avctx, song, player_host_channel, player_channel );
+
+            if (!(instrument->compat_flags & AVSEQ_INSTRUMENT_COMPAT_FLAG_LOCK_INSTR_WAVE))
+                init_new_sample ( avctx, player_host_channel, player_channel );
+        }
+    } else if ((instrument = player_host_channel->instrument) && module->instruments) {
+        if (!(instrument->flags & AVSEQ_INSTRUMENT_FLAG_NO_INSTR_TRANSPOSE)) {
+            AVSequencerOrderData *order_data = player_host_channel->order;
+
+            if (order_data->instr_transpose) {
+                AVSequencerInstrument *instrument_scan;
+
+                do {
+                    if (module->instrument_list[instr] == instrument)
+                        break;
+                while (++instr < module->instruments);
+
+                instr += order_data->instr_transpose;
+
+                if ((instr < module->instruments) && ((instrument_scan = module->instrument_list[instr])))
+                    instrument = instrument_scan;
+            }
+        }
+
+        if ((new_player_channel = play_note ( avctx, module, instrument, player_host_channel, player_channel, octave, note, channel ))) {
+            AVSequencerSample *sample = player_host_channel->sample;
+
+            new_player_channel->channel_data.pos = sample->start_offset;
+
+            if (sample->compat_flags & AVSEQ_SAMPLE_COMPAT_FLAG_VOLUME_ONLY) {
+                new_player_channel->volume  = player_channel->volume;
+                new_player_channel->sub_vol = player_channel->sub_vol;
+
+                init_new_instrument ( avctx, song, player_host_channel, new_player_channel );
+                init_new_sample ( avctx, player_host_channel, new_player_channel );
+            } else {
+                if (player_channel != new_player_channel) {
+                    memcpy ( &(new_player_channel->volume), &(player_channel->volume), (offsetof (AVSequencerPlayerChannel, instr_note) - offsetof (AVSequencerPlayerChannel, volume)));
+
+                    new_player_channel->host_channel = channel;
+                }
+
+                init_new_instrument ( avctx, song, player_host_channel, new_player_channel );
+                init_new_sample ( avctx, player_host_channel, new_player_channel );
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int16_t get_key_lut_note ( AVSequencerModule *module, AVSequencerInstrument *instrument, AVSequencerPlayerHostChannel *player_host_channel, uint16_t octave, uint16_t note ) {
+    return get_key_lut ( module, instrument, player_host_channel, (( octave * AVSEQ_TRACK_DATA_NOTE_MAX ) + note ));
+}
+
+static int16_t get_key_lut ( AVSequencerModule *module, AVSequencerInstrument *instrument, AVSequencerPlayerHostChannel *player_host_channel, uint16_t note ) {
+    AVSequencerKeyboard *keyboard;
+    AVSequencerSample *sample;
+    uint16_t smp = 1, i;
+    int8_t transpose;
+
+    if (!player_host_channel->instrument)
+        player_host_channel->nna = instrument->nna;
+
+    player_host_channel->instr_note  = note;
+    player_host_channel->sample_note = note;
+    player_host_channel->instrument  = instrument;
+
+    if (!(keyboard = (AVSequencerKeyboard *) instrument->keyboard_defs))
+        goto do_not_play_keyboard;
+
+    i                                = ++note;
+    note                             = ((uint16_t) (keyboard->key[i].octave & 0x7F) * AVSEQ_TRACK_DATA_NOTE_MAX) + keyboard->key[i].note;
+    player_host_channel->sample_note = note;
+
+    if ((smp = keyboard->key[i].sample)) {
+do_not_play_keyboard:
+        smp--;
+
+        if (!(instrument->compat_flags & AVSEQ_INSTRUMENT_COMPAT_FLAG_SEPARATE_SAMPLES)) {
+            if ((smp >= instrument->samples) || (!(sample = instrument->sample_list[smp])))
+                return 0x8000;
+        } else {
+            if ((smp >= module->instruments) || (!(instrument = module->instrument_list[smp])))
+                return 0x8000;
+
+            if (!instrument->samples || !(sample = instrument->sample_list[0]))
+                return 0x8000;
+        }
+    } else {
+        sample = player_host_channel->sample;
+
+        if ((instrument->compat_flags & AVSEQ_INSTRUMENT_COMPAT_FLAG_PREV_SAMPLE) || !sample)
+            return 0x8000;
+    }
+
+    player_host_channel->sample = sample;
+    transpose                   = sample->transpose;
+
+    if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_TRANSPOSE)
+        transpose = player_host_channel->transpose;
+
+    note += transpose;
+
+    if (!(instrument->flags & AVSEQ_INSTRUMENT_FLAG_NO_TRANSPOSE))
+        note += player_host_channel->order->transpose;
+
+    note += player_host_channel->track->transpose;
+
+    return note - 1;
+}
+
+static uint32_t get_tone_pitch ( AVSequencerContext *avctx, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, int16_t note ) {
+    AVSequencerSample *sample = player_host_channel->sample;
+    uint32_t *frequency_lut;
+    uint32_t frequency, next_frequency;
+    uint16_t octave;
+    int8_t finetune;
+
+    octave = note / AVSEQ_TRACK_DATA_NOTE_MAX;
+    note   = note % AVSEQ_TRACK_DATA_NOTE_MAX;
+
+    if (note < 0) {
+        octave--;
+
+        note += AVSEQ_TRACK_DATA_NOTE_MAX;
+    }
+
+    if ((finetune = player_host_channel->finetune) < 0) {
+        finetune += -0x80;
+
+        note--;
+    }
+
+    frequency_lut  = (avctx->frequency_lut ? avctx->frequency_lut : pitch_lut) + note + 1;
+    frequency      = *frequency_lut++;
+    next_frequency = *frequency_lut - frequency;
+    frequency     += (int32_t) (finetune * (int16_t) next_frequency) >> 7;
+
+    if ((int16_t) (octave -= 4) < 0) {
+        octave = -octave;
+
+        return ((uint64_t) frequency * sample->rate) >> (16 + octave);
+    } else {
+        frequency <<= octave;
+
+        return ((uint64_t) frequency * sample->rate) >> 16;
+    }
+}
+
+static AVSequencerPlayerChannel *play_note ( AVSequencerContext *avctx, AVSequencerModule *module, AVSequencerInstrument *instrument, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t octave, uint16_t note, uint32_t channel ) {
+    player_host_channel->flags |= AVSEQ_PLAYER_HOST_CHANNEL_FLAG_RETRIG_NOTE;
+
+    if ((note = get_key_lut_note ( module, instrument, player_host_channel, octave, note )) == 0x8000)
+        return NULL;
+
+    return play_note_got ( avctx, module, player_host_channel, player_channel, note, channel );
+}
+
+static AVSequencerPlayerChannel *play_note_got ( AVSequencerContext *avctx, AVSequencerModule *module, AVSequencerPlayerHostChannel *player_host_channel, AVSequencerPlayerChannel *player_channel, uint16_t note, uint32_t channel ) {
+    AVSequencerInstrument *instrument = player_host_channel->instrument;
+    AVSequencerSample *sample = player_host_channel->sample;
+    uint32_t note_swing, pitch_swing, frequency = 0;
+    uint32_t seed;
+    uint16_t virtual_channel;
+
+    player_host_channel->dct        = instrument->dct;
+    player_host_channel->dna        = instrument->dna;
+    note_swing                      = (instrument->note_swing << 1) + 1;
+    avctx->seed                     = seed = ((int32_t) avctx->seed * AVSEQ_RANDOM_CONST) + 1;
+    note_swing                      = ((uint64_t) seed * note_swing) >> 32;
+    note_swing                     -= instrument->note_swing;
+    note                           += note_swing;
+    player_host_channel->final_note = note;
+
+    player_host_channel->finetune   = sample->finetune;
+
+    if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_TRANSPOSE)
+        player_host_channel->finetune = player_host_channel->trans_finetune;
+
+    player_host_channel->prev_volume_env    = player_channel->vol_env.envelope;
+    player_host_channel->prev_panning_env   = player_channel->pan_env.envelope;
+    player_host_channel->prev_slide_env     = player_channel->slide_env.envelope;
+    player_host_channel->prev_auto_vib_env  = player_channel->auto_vib_env.envelope;
+    player_host_channel->prev_auto_trem_env = player_channel->auto_trem_env.envelope;
+    player_host_channel->prev_auto_pan_env  = player_channel->auto_pan_env.envelope;
+    player_host_channel->prev_resonacne_env = player_channel->resonance_env.envelope;
+
+    player_channel = trigger_nna ( module, player_host_channel, player_channel, channel, (uint16_t *) &virtual_channel );
+
+    player_channel->channel_data.pos     = sample->start_offset;
+    player_host_channel->virtual_channel = virtual_channel;
+    player_channel->host_channel         = channel;
+    player_channel->instrument           = instrument;
+    player_channel->sample               = sample;
+
+    if ((player_channel->instr_note = player_host_channel->instr_note)) {
+        int16_t final_note;
+
+        player_channel->sample_note = player_host_channel->sample_note;
+        player_channel->final_note  = final_note = player_host_channel->final_note;
+
+        frequency = get_tone_pitch ( avctx, player_host_channel, player_channel, final_note );
+    }
+
+    note_swing    = pitch_swing = ((uint64_t) frequency * instrument->pitch_swing) >> 16;
+    pitch_swing <<= 1;
+
+    if (pitch_swing < note_swing)
+        pitch_swing = 0xFFFFFFFE;
+
+    note_swing = pitch_swing++ >> 1;
+
+    avctx->seed  = seed = ((int32_t) avctx->seed * AVSEQ_RANDOM_CONST) + 1;
+    pitch_swing  = ((uint64_t) seed * pitch_swing) >> 32;
+    pitch_swing -= note_swing;
+
+    if ((int32_t) (frequency += pitch_swing) < 0)
+        frequency = 0;
+
+    player_channel->frequency = frequency;
+
+    return player_channel;
+}
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to