Sebastian Vater a écrit :
--
Best regards,
:-) Basty/CDGS (-:
diff --git a/libavsequencer/player.c b/libavsequencer/player.c
index 98c99d4..0980b24 100644
--- a/libavsequencer/player.c
+++ b/libavsequencer/player.c
@@ -1035,3 +1035,587 @@ static const int32_t global_panning_slide_trigger_mask[4] = {
static const int8_t empty_waveform[256];
+void avseq_playback_handler ( AVSequencerContext *avctx ) {
+ AVSequencerModule *module;
+ AVSequencerSong *song;
+ AVSequencerPlayerGlobals *player_globals;
+ AVSequencerPlayerHostChannel *player_host_channel;
+ AVSequencerPlayerChannel *player_channel;
+ AVSequencerMixerData *mixer = avctx->player_mixer_data;
+ AVSequencerPlayerHook *player_hook;
+ uint16_t channel, virtual_channel;
+
+ if (!(module = avctx->player_module))
+ return;
+
+ channel = 0;
+ player_channel = module->channel_data;
+
+ do {
+ mixer_get_channel ( mixer, (AVSequencerMixerChannel *) &(player_channel->channel_data), channel, mixer->mixctx );
+
+ player_channel++;
+ } while (++channel < module->channels);
+
+ song = avctx->player_song;
+ player_globals = song->global_data;
+
+ if (player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_TRACE_MODE) {
+ if (!player_globals->trace_count--)
+ player_globals->trace_count = 0;
+
+ return;
+ }
+
+ player_hook = avctx->playback_hook;
+
+ if (player_hook && (player_hook->flags & AVSEQ_PLAYER_HOOK_FLAG_BEGINNING) &&
+ (((player_hook->flags & AVSEQ_PLAYER_HOOK_FLAG_SONG_END) &&
+ (player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_SONG_END)) ||
+ (!(player_hook->flags & AVSEQ_PLAYER_HOOK_FLAG_SONG_END))))
+ player_hook->hook_func ( avctx, module, song, player_hook->hook_data, player_hook->hook_len );
+
+ if (player_globals->play_type & AVSEQ_PLAYER_GLOBALS_PLAY_TYPE_SONG) {
+ uint32_t play_time_calc, play_time_advance, play_time_fraction;
+
+ play_time_calc = ((uint64_t) player_globals->tempo * player_globals->relative_speed) >> 16;
+ play_time_advance = 65536000 / play_time_calc;
+ play_time_fraction = ((uint64_t) (65536000 % play_time_calc) << 32) / play_time_calc;
+ player_globals->play_time_frac += play_time_fraction;
+
+ if (player_globals->play_time_frac < play_time_fraction)
+ play_time_advance++;
+
+ player_globals->play_time += play_time_advance;
+ play_time_calc = player_globals->tempo;
+ play_time_advance = 65536000 / play_time_calc;
+ play_time_fraction = ((uint64_t) (65536000 % play_time_calc) << 32) / play_time_calc;
+ player_globals->play_tics_frac += play_time_fraction;
+
+ if (player_globals->play_tics_frac < play_time_fraction)
+ play_time_advance++;
+
+ player_globals->play_tics += play_time_advance;
+ }
+
+ channel = 0;
+ player_host_channel = song->channel_data;
+
+ do {
+ player_channel = module->channel_data + player_host_channel->virtual_channel;
+
+ if ((player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_INSTRUMENT) &&
+ (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_SAMPLE)) {
+ AVSequencerTrack *old_track = player_host_channel->track;
+ AVSequencerTrackEffect *old_effect = player_host_channel->effect;
+ uint32_t old_tempo_counter = player_host_channel->tempo_counter;
+ uint16_t old_row = player_host_channel->row;
+
+ player_host_channel->flags &= ~(AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_INSTRUMENT|AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_SAMPLE);
+ player_host_channel->track = (AVSequencerTrack *) player_host_channel->instrument;
+ player_host_channel->effect = NULL;
+ player_host_channel->row = *(uint32_t *) &(player_host_channel->sample);
+ player_host_channel->instrument = NULL;
+ player_host_channel->sample = NULL;
+
+ get_effects ( avctx, module, song, player_host_channel, player_channel, channel );
+
+ player_host_channel->tempo_counter = player_host_channel->note_delay;
+
+ get_note ( avctx, module, song, player_host_channel, player_channel, channel );
+ run_effects ( avctx, module, song, player_host_channel, player_channel, channel );
+
+ player_host_channel->track = old_track;
+ player_host_channel->effect = old_effect;
+ player_host_channel->tempo_counter = old_tempo_counter;
+ player_host_channel->row = old_row;
+ }
+
+ if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_INSTRUMENT) {
+ uint16_t note = (uint8_t) player_host_channel->instr_note;
+
+ player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_INSTRUMENT;
+
+ if ((int16_t) note < 0) {
+ switch (note) {
+ case AVSEQ_TRACK_DATA_AVSEQ_TRACK_DATA_NOTE_FADE :
+ player_channel->flags |= AVSEQ_PLAYER_CHANNEL_FLAG_FADING;
+
+ break;
+ case AVSEQ_TRACK_DATA_AVSEQ_TRACK_DATA_NOTE_HOLD_DELAY :
+ break;
+ case AVSEQ_TRACK_DATA_AVSEQ_TRACK_DATA_NOTE_KEYOFF :
+ play_key_off ( player_channel );
+
+ break;
+ case AVSEQ_TRACK_DATA_AVSEQ_TRACK_DATA_NOTE_OFF :
+ player_channel->volume = 0;
+
+ break;
+ case AVSEQ_TRACK_DATA_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;
+ }
+ } else {
+ AVSequencerInstrument *instrument = player_host_channel->instrument;
+ AVSequencerSample *sample;
+ AVSequencerPlayerChannel *new_player_channel;
+
+ if ((new_player_channel = play_note ( avctx, module, instrument,
+ player_host_channel, player_channel,
+ note / AVSEQ_TRACK_DATA_NOTE_MAX,
+ note % AVSEQ_TRACK_DATA_NOTE_MAX, channel )))
+ player_channel = new_player_channel;
+
+ sample = player_host_channel->sample;
+ player_channel->volume = player_host_channel->sample_note;
+ player_channel->sub_vol = 0;
+
+ init_new_instrument ( avctx, song, player_host_channel, player_channel );
+ init_new_sample ( avctx, player_host_channel, player_channel );
+ }
+ }
+
+ if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_SAMPLE) {
+ AVSequencerInstrument *instrument;
+ AVSequencerSample *sample = player_host_channel->sample;
+ uint32_t frequency = *(uint32_t *) &(player_host_channel->instrument), i;
+ uint16_t virtual_channel;
+
+ player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SET_SAMPLE;
+ player_host_channel->dct = 0;
+ player_host_channel->nna = AVSEQ_PLAYER_HOST_CHANNEL_NNA_NOTE_CUT;
+ player_host_channel->finetune = sample->finetune;
+
+ 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_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_host_channel->instrument = NULL;
+ player_channel->sample = sample;
+ player_channel->frequency = frequency;
+ player_channel->volume = player_host_channel->instr_note;
+ player_channel->sub_vol = 0;
+ player_host_channel->instr_note = 0;
+
+ init_new_instrument ( avctx, song, player_host_channel, player_channel );
+
+ i = -1;
+
+ while (++i < module->instruments) {
+ uint16_t smp = -1;
+
+ if (!(instrument = module->instrument_list[i]))
+ continue;
+
+ while (++smp < instrument->samples) {
+ if (!(sample = instrument->sample_list[smp]))
+ continue;
+
+ if (sample == player_channel->sample) {
+ player_host_channel->instrument = instrument;
+
+ goto instrument_found;
+ }
+ }
+ }
+instrument_found:
+ player_channel->instrument = player_host_channel->instrument;
+
+ init_new_sample ( avctx, player_host_channel, player_channel );
+ }
+
+ if ((!(player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_NO_PROC_PATTERN)) && player_host_channel->tempo) {
+rescan_row:
+ process_row ( song, player_host_channel, player_channel, channel );
+ get_effects ( avctx, module, song, player_host_channel, player_channel, channel );
+
+ if (player_channel->host_channel == channel) {
+ if (!(player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_VIBRATO)) {
+ int32_t slide_value = player_host_channel->vibrato_slide;
+
+ player_host_channel->vibrato_slide = 0;
+ player_channel->frequency -= slide_value;
+ }
+
+ if (!(player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TREMOLO)) {
+ int16_t slide_value = player_host_channel->tremolo_slide;
+
+ player_host_channel->tremolo_slide = 0;
+
+ if ((slide_value = ( player_channel->volume - slide_value)) < 0)
+ slide_value = 0;
+
+ if ((uint16_t) slide_value >= 255)
+ slide_value = -1;
+
+ player_channel->volume = slide_value;
+ }
+ }
+
+ if (get_note ( avctx, module, song, player_host_channel, player_channel, channel))
+ goto rescan_row;
+ }
+
+ player_host_channel->virtual_channels = 0;
+ player_host_channel++;
+ } while (++channel < song->channels);
+
+ channel = 0;
+ player_host_channel = song->channel_data;
+
+ do {
+ if ((!(player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_NO_PROC_PATTERN)) && player_host_channel->tempo) {
+ player_channel = module->channel_data + player_host_channel->virtual_channel;
+
+ run_effects ( avctx, module, song, player_host_channel, player_channel, channel );
+ }
+
+ player_host_channel->virtual_channels = 0;
+ player_host_channel++;
+ } while (++channel < song->channels);
+
+ virtual_channel = 0;
+ channel = 0;
+ player_channel = module->channel_data;
+
+ do {
+ AVSequencerPlayerEnvelope *player_envelope;
+
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_ALLOCATED)
+ player_channel->channel_data.flags &= ~AVSEQ_MIXER_CHANNEL_FLAG_PLAY;
+
+ if (player_channel->channel_data.flags & AVSEQ_MIXER_CHANNEL_FLAG_PLAY) {
+ AVSequencerSample *sample;
+ uint32_t frequency, host_volume, virtual_volume;
+ uint32_t auto_vibrato_depth, auto_vibrato_count;
+ uint16_t flags, slide_envelope_value;
+ int16_t auto_vibrato_value, panning, abs_panning, panning_envelope_value;
+
+ player_host_channel = song->channel_data + player_channel->host_channel;
+ player_envelope = (AVSequencerPlayerEnvelope *) &(player_channel->vol_env);
+
+ if (player_envelope->tempo) {
+ uint16_t volume = run_envelope ( avctx, player_envelope, 1, 0x8000 );
+
+ if (!player_envelope->tempo) {
+ if (!(volume >> 8))
+ goto turn_note_off;
+
+ player_channel->flags |= AVSEQ_PLAYER_CHANNEL_FLAG_FADING;
+ }
+ }
+
+ run_envelope ( avctx, (AVSequencerPlayerEnvelope *) &(player_channel->pan_env), 1, 0 );
+ slide_envelope_value = run_envelope ( avctx, (AVSequencerPlayerEnvelope *) &(player_channel->slide_env), 1, 0 );
+
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_PORTA_SLIDE_ENV) {
+ uint32_t old_frequency = player_channel->frequency;
+
+ player_channel->frequency += player_channel->slide_env_freq;
+
+ if ((frequency = player_channel->frequency)) {
+ if ((int16_t) slide_envelope_value < 0) {
+ slide_envelope_value = -slide_envelope_value;
+
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_LINEAR_SLIDE_ENV)
+ frequency = linear_slide_down ( avctx, player_channel, frequency, slide_envelope_value );
+ else
+ frequency = amiga_slide_down ( player_channel, frequency, slide_envelope_value );
+ } else if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_LINEAR_SLIDE_ENV) {
+ frequency = linear_slide_up ( avctx, player_channel, frequency, slide_envelope_value );
+ } else {
+ frequency = amiga_slide_up ( player_channel, frequency, slide_envelope_value );
+ }
+
+ old_frequency -= frequency;
+
+ player_channel->slide_env_freq += old_frequency;
+ }
+ } else {
+ uint32_t *frequency_lut;
+ uint32_t frequency, next_frequency, slide_envelope_frequency, old_frequency;
+ int16_t octave, note;
+ int16_t slide_note = (int16_t) slide_envelope_value >> 8;
+ int16_t finetune = slide_envelope_value & 0xFF;
+
+ octave = slide_note / AVSEQ_TRACK_DATA_NOTE_MAX;
+ note = slide_note % AVSEQ_TRACK_DATA_NOTE_MAX;
+
+ if (note < 0) {
+ octave--;
+ note += AVSEQ_TRACK_DATA_NOTE_MAX;
+
+ finetune = -finetune;
+ }
+
+ 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) >> 8;
+
+ if ((int16_t) octave < 0) {
+ octave = -octave;
+ frequency >>= octave;
+ } else {
+ frequency <<= octave;
+ }
+
+ slide_envelope_frequency = player_channel->slide_env_freq;
+ old_frequency = player_channel->frequency;
+ slide_envelope_frequency += old_frequency;
+ player_channel->frequency = frequency = ((uint64_t) frequency * slide_envelope_frequency) >> 16;
+ player_channel->slide_env_freq += old_frequency - frequency;
+ }
+
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_FADING) {
+ int32_t fade_out = (uint32_t) player_channel->fade_out_count;
+
+ if ((fade_out -= player_channel->fade_out) <= 0)
+ goto turn_note_off;
+
+ player_channel->fade_out_count = fade_out;
+ }
+
+ auto_vibrato_value = run_envelope ( avctx, (AVSequencerPlayerEnvelope *) &(player_channel->auto_vib_env), player_channel->auto_vibrato_rate, 0 );
+ auto_vibrato_depth = player_channel->auto_vibrato_depth << 8;
+ auto_vibrato_count = player_channel->auto_vibrato_count + player_channel->auto_vibrato_sweep;
+
+ if (auto_vibrato_count > auto_vibrato_depth)
+ auto_vibrato_count = auto_vibrato_depth;
+
+ player_channel->auto_vibrato_count = auto_vibrato_count;
+
+ auto_vibrato_count >>= 8;
+
+ if ((auto_vibrato_value *= (int16_t) -auto_vibrato_count)) {
+ uint32_t old_frequency = player_channel->frequency;
+
+ auto_vibrato_value >>= 7 - 2;
+
+ player_channel->frequency -= player_channel->auto_vibrato_freq;
+
+ if ((frequency = player_channel->frequency)) {
+ if ((int16_t) auto_vibrato_value < 0) {
+ auto_vibrato_value = -auto_vibrato_value;
+
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_LINEAR_SLIDE_ENV)
+ frequency = linear_slide_up ( avctx, player_channel, frequency, auto_vibrato_value );
+ else
+ frequency = amiga_slide_up ( player_channel, frequency, auto_vibrato_value );
+ } else if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_LINEAR_SLIDE_ENV) {
+ frequency = linear_slide_down ( avctx, player_channel, frequency, auto_vibrato_value );
+ } else {
+ frequency = amiga_slide_down ( player_channel, frequency, auto_vibrato_value );
+ }
+
+ old_frequency -= frequency;
+
+ player_channel->auto_vibrato_freq -= old_frequency;
+ }
+ }
+
+ sample = player_channel->sample;
+
+ if (sample->synth) {
+ if (!(execute_synth ( avctx, player_host_channel, player_channel, channel, 0)))
+ goto turn_note_off;
+
+ if (!(execute_synth ( avctx, player_host_channel, player_channel, channel, 1)))
+ goto turn_note_off;
+
+ if (!(execute_synth ( avctx, player_host_channel, player_channel, channel, 2)))
+ goto turn_note_off;
+
+ if (!(execute_synth ( avctx, player_host_channel, player_channel, channel, 3)))
+ goto turn_note_off;
+ }
+
+ if (((!(player_channel->channel_data.data)) || (!(player_channel->channel_data.bits_per_sample))) && (player_channel->channel_data.flags & AVSEQ_MIXER_CHANNEL_FLAG_PLAY)) {
+ player_channel->channel_data.pos = 0;
+ player_channel->channel_data.len = (sizeof (empty_waveform) / sizeof (empty_waveform[0]));
+ player_channel->channel_data.data = (int16_t *) &(empty_waveform);
+ player_channel->channel_data.repeat_start = 0;
+ player_channel->channel_data.repeat_length = (sizeof (empty_waveform) / sizeof (empty_waveform[0]));
+ player_channel->channel_data.repeat_count = 0;
+ player_channel->channel_data.repeat_counted = 0;
+ player_channel->channel_data.bits_per_sample = (sizeof (empty_waveform[0]) * 8);
+ player_channel->channel_data.flags = AVSEQ_MIXER_CHANNEL_FLAG_LOOP|AVSEQ_MIXER_CHANNEL_FLAG_PLAY;
+ }
+
+ frequency = player_channel->frequency;
+
+ if (frequency < sample->rate_min)
+ frequency = sample->rate_min;
+
+ if (frequency > sample->rate_max)
+ frequency = sample->rate_max;
+
+ if (!(player_channel->frequency = frequency)) {
+turn_note_off:
+ player_channel->channel_data.flags = 0;
+
+ goto not_calculate_no_playing;
+ }
+
+ if (!(player_channel->channel_data.rate = ((uint64_t) frequency * player_globals->relative_pitch) >> 16))
+ goto turn_note_off;
+
+ if (!(song->compat_flags & AVSEQ_SONG_COMPAT_FLAG_GLOBAL_NEW_ONLY)) {
+ player_channel->global_volume = player_globals->global_volume;
+ player_channel->global_sub_vol = player_globals->global_sub_volume;
+ player_channel->global_panning = player_globals->global_panning;
+ player_channel->global_sub_pan = player_globals->global_sub_pan;
+ }
+
+ host_volume = player_channel->volume;
+
+ player_host_channel->virtual_channels++;
+ virtual_channel++;
+
+ if ((!(player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_BACKGROUND)) && (player_host_channel->virtual_channel == channel) && (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TREMOR_EXEC) && (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TREMOR_OFF))
+ host_volume = 0;
+
+ host_volume *= (uint16_t) player_host_channel->track_volume * (uint16_t) player_channel->instr_volume;
+ virtual_volume = (((uint16_t) player_channel->vol_env.value >> 8) * (uint16_t) player_channel->global_volume) * (uint16_t) player_channel->fade_out_count;
+ player_channel->channel_data.volume = player_channel->final_volume = ((uint64_t) host_volume * virtual_volume) / (255ULL*255ULL*255ULL*255ULL*65535ULL*255ULL);
+ flags = 0;
+ player_channel->flags &= ~AVSEQ_PLAYER_CHANNEL_FLAG_SURROUND;
+ player_channel->channel_data.flags &= ~AVSEQ_MIXER_CHANNEL_FLAG_SURROUND;
+
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_SMP_SUR_PAN)
+ flags = AVSEQ_MIXER_CHANNEL_FLAG_SURROUND;
+
+ panning = player_channel->panning;
+
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_TRACK_PAN) {
+ panning = player_host_channel->track_panning;
+ flags = 0;
+
+ if ((player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_TRACK_SUR_PAN) || (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_CHANNEL_SUR_PAN))
+ flags = AVSEQ_MIXER_CHANNEL_FLAG_SURROUND;
+ }
+
+ player_channel->flags |= flags;
+
+ if (!(song->flags & AVSEQ_SONG_FLAG_MONO))
+ player_channel->channel_data.flags |= flags;
+
+ if (panning == 255)
+ panning++;
+
+ panning_envelope_value = panning;
+
+ if ((int16_t) (panning = (128 - panning)) < 0)
+ panning = -panning;
+
+ abs_panning = 128 - panning;
+ panning = player_channel->pan_env.value >> 8;
+
+ if (panning == 127)
+ panning++;
+
+ panning = 128 - (((panning * abs_panning) >> 7) + panning_envelope_value);
+ abs_panning = (uint16_t) player_host_channel->channel_panning;
+
+ if (abs_panning == 255)
+ abs_panning++;
+
+ abs_panning -= 128;
+ panning_envelope_value = abs_panning = ((panning * abs_panning) >> 7) + 128;
+
+ if (panning_envelope_value > 255)
+ panning_envelope_value = 255;
+
+ player_channel->final_panning = panning_envelope_value;
+
+ panning = 128;
+
+ if (!(song->flags & AVSEQ_SONG_FLAG_MONO)) {
+ if (player_channel->flags & AVSEQ_PLAYER_CHANNEL_FLAG_GLOBAL_SUR_PAN)
+ player_channel->channel_data.flags |= AVSEQ_MIXER_CHANNEL_FLAG_SURROUND;
+
+ panning -= abs_panning;
+
+ abs_panning = (uint16_t) player_channel->global_panning;
+
+ if (abs_panning == 255)
+ abs_panning++;
+
+ abs_panning -= 128;
+ panning = ((panning * abs_panning) >> 7) + 128;
+
+ if (panning == 256)
+ panning--;
+ }
+
+ player_channel->channel_data.panning = panning;
+
+ mixer_set_channel_volume_panning_pitch ( mixer, (AVSequencerMixerChannel *) &(player_channel->channel_data), channel, mixer->mixctx );
+ }
+not_calculate_no_playing:
+ mixer_set_channel_position_repeat_flags ( mixer, (AVSequencerMixerChannel *) &(player_channel->channel_data), channel, mixer->mixctx );
+
+ player_channel++;
+ } while (++channel < module->channels);
+
+ player_globals->channels = virtual_channel;
+
+ if (virtual_channel > player_globals->max_channels)
+ player_globals->max_channels = virtual_channel;
+
+ channel = 0;
+ player_host_channel = song->channel_data;
+
+ do {
+ if (!(player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SONG_END))
+ goto check_song_end_done;
+
+ player_host_channel++;
+ } while (++channel < song->channels);
+
+ player_globals->flags |= AVSEQ_PLAYER_GLOBALS_FLAG_SONG_END;
+check_song_end_done:
+
+ if (player_hook && (!(player_hook->flags & AVSEQ_PLAYER_HOOK_FLAG_BEGINNING)) &&
+ (((player_hook->flags & AVSEQ_PLAYER_HOOK_FLAG_SONG_END) &&
+ (!(player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_SONG_END))) ||
+ (!(player_hook->flags & AVSEQ_PLAYER_HOOK_FLAG_SONG_END))))
+ player_hook->hook_func ( avctx, module, song, player_hook->hook_data, player_hook->hook_len );
+
+ if (player_globals->flags & AVSEQ_PLAYER_GLOBALS_FLAG_SONG_END) {
+ player_host_channel = song->channel_data;
+
+ if (player_host_channel->flags & AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SONG_END) {
+ AVSequencerOrderList *order_list = song->order_list;
+ channel = song->channels;
+
+ do {
+ AVSequencerOrderData *order_data;
+ uint32_t i = -1;
+
+ if (player_host_channel->tempo)
+ player_host_channel->flags &= ~AVSEQ_PLAYER_HOST_CHANNEL_FLAG_SONG_END;
+
+ while (i++ < order_list->orders) {
+ if ((order_data = order_list->order_data[i]) && (order_data != player_host_channel->order))
+ order_data->played = 0;
+ }
+
+ order_list++;
+ player_host_channel++;
+ } while (--channel);
+ }
+ }
+}
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc