VSE: Hook up sound subframe sliding to the VSE slip modal operator

Updates the slide operator to be able to do subframe adjustments of
audio strips. If you hold shift while sliding (the S shortcut), it will
start to do subframe adjustments. It is also possible to type in
fractional inputs while in modal mode. (IE start sliding then type 1.5)
This commit is contained in:
Sebastian Parborg
2024-06-19 13:36:47 +02:00
committed by Sebastian Parborg
parent fb6aaf3200
commit 7b25d1327e
5 changed files with 106 additions and 75 deletions

View File

@@ -466,6 +466,8 @@ void SEQUENCER_OT_snap(wmOperatorType *ot)
struct SlipData {
float init_mouseloc[2];
int previous_offset;
float previous_subframe_offset;
float subframe_restore;
Sequence **seq_array;
int num_seq;
bool slow;
@@ -522,7 +524,6 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
initNumInput(&data->num_input);
data->num_input.idx_max = 0;
data->num_input.val_flag[0] |= NUM_NO_FRACTION;
data->num_input.unit_sys = USER_UNIT_NONE;
data->num_input.unit_type[0] = 0;
@@ -542,7 +543,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
return OPERATOR_RUNNING_MODAL;
}
static void sequencer_slip_strips(Scene *scene, SlipData *data, int delta)
static void sequencer_slip_strips(Scene *scene, SlipData *data, int delta, float subframe_delta)
{
for (int i = data->num_seq - 1; i >= 0; i--) {
Sequence *seq = data->seq_array[i];
@@ -552,7 +553,7 @@ static void sequencer_slip_strips(Scene *scene, SlipData *data, int delta)
continue;
}
SEQ_time_slip_strip(scene, seq, delta);
SEQ_time_slip_strip(scene, seq, delta, subframe_delta);
}
for (int i = data->num_seq - 1; i >= 0; i--) {
@@ -592,7 +593,6 @@ static int sequencer_slip_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene);
int offset = RNA_int_get(op->ptr, "offset");
/* Count the amount of elements to trim. */
int num_seq = slip_count_sequences(ed->seqbasep);
@@ -608,8 +608,17 @@ static int sequencer_slip_exec(bContext *C, wmOperator *op)
slip_add_sequences(ed->seqbasep, data->seq_array);
float offset_fl = RNA_float_get(op->ptr, "offset");
int offset = round_fl_to_int(offset_fl);
float subframe_delta = 0.0f;
if (std::trunc(offset_fl) != offset_fl) {
/* Only apply subframe offsets if the input is not an integer. */
subframe_delta = offset_fl - offset;
}
sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_strips(scene, data, offset);
sequencer_slip_strips(scene, data, offset, subframe_delta);
MEM_freeN(data->seq_array);
MEM_freeN(data);
@@ -638,6 +647,37 @@ static void sequencer_slip_update_header(Scene *scene, ScrArea *area, SlipData *
ED_area_status_text(area, msg);
}
static void handle_number_input(
bContext *C, wmOperator *op, ScrArea *area, SlipData *data, Scene *scene)
{
float offset_fl;
applyNumInput(&data->num_input, &offset_fl);
int offset = round_fl_to_int(offset_fl);
const int delta_offset = sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_update_header(scene, area, data, offset);
RNA_float_set(op->ptr, "offset", offset_fl);
float subframe_delta = 0.0f;
if (data->subframe_restore != 0.0f) {
/* Always remove the previous subframe adjustments we have potentially made with the mouse
* input when the user starts enterning values by hand.
*/
subframe_delta = -data->subframe_restore;
data->subframe_restore = 0.0f;
}
if (std::trunc(offset_fl) != offset_fl) {
/* Only apply subframe offsets if the input is not an integer. */
subframe_delta = offset_fl - data->previous_subframe_offset - delta_offset;
data->subframe_restore += subframe_delta;
}
data->previous_subframe_offset = offset_fl;
sequencer_slip_strips(scene, data, delta_offset, subframe_delta);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
}
static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
@@ -648,19 +688,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
/* Modal numinput active, try to handle numeric inputs. */
if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) {
float offset_fl;
applyNumInput(&data->num_input, &offset_fl);
int offset = round_fl_to_int(offset_fl);
const int delta_offset = sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_update_header(scene, area, data, offset);
RNA_int_set(op->ptr, "offset", offset);
sequencer_slip_strips(scene, data, delta_offset);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
handle_number_input(C, op, area, data, scene);
return OPERATOR_RUNNING_MODAL;
}
@@ -669,7 +697,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
if (!has_numInput) {
float mouseloc[2];
int offset;
int mouse_x;
float mouse_x;
View2D *v2d = UI_view2d_fromcontext(C);
if (data->slow) {
@@ -683,14 +711,28 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
/* Choose the side based on which side of the current frame the mouse is. */
UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]);
offset = mouseloc[0] - data->init_mouseloc[0];
float offset_fl = mouseloc[0] - data->init_mouseloc[0];
offset = offset_fl;
const int delta_offset = sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_update_header(scene, area, data, offset);
RNA_int_set(op->ptr, "offset", offset);
sequencer_slip_strips(scene, data, delta_offset);
if (!data->slow) {
RNA_float_set(op->ptr, "offset", offset);
}
float subframe_delta = 0.0f;
if (data->slow) {
RNA_float_set(op->ptr, "offset", offset_fl);
subframe_delta = offset_fl - data->previous_subframe_offset - delta_offset;
data->subframe_restore += subframe_delta;
}
else if (data->subframe_restore != 0.0f) {
/* If we exit slow mode, make sure we undo the fractional adjustments we have done. */
subframe_delta = -data->subframe_restore;
data->subframe_restore = 0.0f;
}
data->previous_subframe_offset = offset_fl;
sequencer_slip_strips(scene, data, delta_offset, subframe_delta);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
}
@@ -713,8 +755,9 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
case EVT_ESCKEY:
case RIGHTMOUSE: {
int offset = RNA_int_get(op->ptr, "offset");
sequencer_slip_strips(scene, data, -offset);
int offset = data->previous_offset;
float subframe_delta = data->subframe_restore;
sequencer_slip_strips(scene, data, -offset, -subframe_delta);
MEM_freeN(data->seq_array);
MEM_freeN(data);
@@ -749,18 +792,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
/* Modal numinput inactive, try to handle numeric inputs. */
if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) {
float offset_fl;
applyNumInput(&data->num_input, &offset_fl);
int offset = round_fl_to_int(offset_fl);
const int delta_offset = sequencer_slip_apply_limits(scene, data, &offset);
sequencer_slip_update_header(scene, area, data, offset);
RNA_int_set(op->ptr, "offset", offset);
sequencer_slip_strips(scene, data, delta_offset);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
handle_number_input(C, op, area, data, scene);
}
return OPERATOR_RUNNING_MODAL;
@@ -782,15 +814,19 @@ void SEQUENCER_OT_slip(wmOperatorType *ot)
/* Flags. */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_int(ot->srna,
"offset",
0,
INT32_MIN,
INT32_MAX,
"Offset",
"Offset to the data of the strip",
INT32_MIN,
INT32_MAX);
/* Properties. */
PropertyRNA *prop;
prop = RNA_def_float(ot->srna,
"offset",
0,
-FLT_MAX,
FLT_MAX,
"Offset",
"Offset to the data of the strip",
-FLT_MAX,
FLT_MAX);
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, 0);
}
/** \} */

View File

@@ -192,34 +192,22 @@ static StripDrawContext strip_draw_context_get(TimelineDrawContext *ctx, Sequenc
strip_ctx.seq = seq;
strip_ctx.bottom = seq->machine + SEQ_STRIP_OFSBOTTOM;
strip_ctx.top = seq->machine + SEQ_STRIP_OFSTOP;
strip_ctx.content_start = SEQ_time_left_handle_frame_get(scene, seq);
strip_ctx.content_end = SEQ_time_right_handle_frame_get(scene, seq);
if (SEQ_time_has_left_still_frames(scene, seq)) {
strip_ctx.content_start = SEQ_time_start_frame_get(seq);
}
if (SEQ_time_has_right_still_frames(scene, seq)) {
strip_ctx.content_end = SEQ_time_content_end_frame_get(scene, seq);
}
strip_ctx.left_handle = SEQ_time_left_handle_frame_get(scene, seq);
strip_ctx.right_handle = SEQ_time_right_handle_frame_get(scene, seq);
strip_ctx.content_start = SEQ_time_start_frame_get(seq);
strip_ctx.content_end = SEQ_time_content_end_frame_get(scene, seq);
if (seq->type == SEQ_TYPE_SOUND_RAM && seq->sound != nullptr) {
/* Visualize subframe sound offsets */
const double sound_offset = seq->sound->offset_time + seq->sound_offset;
if (sound_offset >= 0.0f) {
strip_ctx.content_start += sound_offset * FPS;
}
else {
strip_ctx.content_end += sound_offset * FPS;
}
const double sound_offset = (seq->sound->offset_time + seq->sound_offset) * FPS;
strip_ctx.content_start += sound_offset;
strip_ctx.content_end += sound_offset;
}
/* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
strip_ctx.content_start = min_ff(strip_ctx.content_start,
SEQ_time_right_handle_frame_get(scene, seq));
strip_ctx.content_end = max_ff(strip_ctx.content_end,
SEQ_time_left_handle_frame_get(scene, seq));
/* Limit body to strip bounds. */
strip_ctx.content_start = min_ff(strip_ctx.content_start, strip_ctx.right_handle);
strip_ctx.content_end = max_ff(strip_ctx.content_end, strip_ctx.left_handle);
strip_ctx.left_handle = SEQ_time_left_handle_frame_get(scene, seq);
strip_ctx.right_handle = SEQ_time_right_handle_frame_get(scene, seq);
strip_ctx.strip_length = strip_ctx.right_handle - strip_ctx.left_handle;
strip_draw_context_set_text_overlay_visibility(ctx, &strip_ctx);

View File

@@ -3042,8 +3042,10 @@ static void rna_def_sound(BlenderRNA *brna)
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 3);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not meant to be animated */
RNA_def_property_ui_text(prop, "Sound Offset", "Sound offset in seconds");
// TODO do we need to create any extra translation stuff for this?
RNA_def_property_ui_text(
prop,
"Sound Offset",
"Offset of the sound from the beginning of the strip, expressed in seconds");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SOUND);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update");

View File

@@ -123,7 +123,7 @@ void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta);
/**
* Move contents of a strip without moving the strip handles.
*/
void SEQ_time_slip_strip(const Scene *scene, Sequence *seq, int delta);
void SEQ_time_slip_strip(const Scene *scene, Sequence *seq, int delta, float subframe_delta);
/**
* Get difference between scene and movie strip frame-rate.
*/

View File

@@ -575,8 +575,13 @@ void seq_time_translate_handles(const Scene *scene, Sequence *seq, const int off
SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq));
}
static void seq_time_slip_strip_ex(const Scene *scene, Sequence *seq, int delta, bool recursed)
static void seq_time_slip_strip_ex(
const Scene *scene, Sequence *seq, int delta, float subframe_delta, bool recursed)
{
if (seq->type == SEQ_TYPE_SOUND_RAM && subframe_delta != 0.0f) {
seq->sound_offset += subframe_delta / FPS;
}
if (delta == 0) {
return;
}
@@ -600,7 +605,7 @@ static void seq_time_slip_strip_ex(const Scene *scene, Sequence *seq, int delta,
return;
}
LISTBASE_FOREACH (Sequence *, seq_child, &seq->seqbase) {
seq_time_slip_strip_ex(scene, seq_child, delta, true);
seq_time_slip_strip_ex(scene, seq_child, delta, subframe_delta, true);
}
}
@@ -618,9 +623,9 @@ static void seq_time_slip_strip_ex(const Scene *scene, Sequence *seq, int delta,
seq_time_update_effects_strip_range(scene, effects);
}
void SEQ_time_slip_strip(const Scene *scene, Sequence *seq, int delta)
void SEQ_time_slip_strip(const Scene *scene, Sequence *seq, int delta, float subframe_delta)
{
seq_time_slip_strip_ex(scene, seq, delta, false);
seq_time_slip_strip_ex(scene, seq, delta, subframe_delta, false);
}
int SEQ_time_get_rounded_sound_offset(const Scene *scene, const Sequence *seq)