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