Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions src/modules/core/producer_timewarp.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* producer_timewarp.c -- modify speed and direction of a clip
* Copyright (C) 2015-2021 Meltytech, LLC
* Copyright (C) 2015-2026 Meltytech, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -34,6 +34,7 @@ typedef struct
mlt_profile clip_profile;
mlt_properties clip_parameters;
mlt_filter pitch_filter;
int pitch_wsola;
} private_data;

// Private Functions
Expand Down Expand Up @@ -89,6 +90,15 @@ static int producer_probe(mlt_producer parent)
return 1;
}

// "wsola" prefers the WSOLA filter for pitch compensation. Anything else,
// including no value, prefers rubberband. Either way, the other filter is used
// when the preferred one is not available.
static int use_wsola_pitch(mlt_properties producer_properties)
{
const char *method = mlt_properties_get(producer_properties, "warp_pitch_method");
return method && !strcmp(method, "wsola");
}

static int producer_get_audio(mlt_frame frame,
void **buffer,
mlt_audio_format *format,
Expand Down Expand Up @@ -169,11 +179,19 @@ static int producer_get_frame(mlt_producer producer, mlt_frame_ptr frame, int in
// Pitch compensation does not work well for speed *reduction* of 1/10th or less.
if (mlt_properties_get_int(producer_properties, "warp_pitch")
&& fabs(pdata->speed) >= 0.1) {
int wsola = use_wsola_pitch(producer_properties);
if (pdata->pitch_filter && pdata->pitch_wsola != wsola) {
mlt_filter_close(pdata->pitch_filter);
pdata->pitch_filter = NULL;
}
if (!pdata->pitch_filter) {
pdata->pitch_filter = mlt_factory_filter(mlt_service_profile(
MLT_PRODUCER_SERVICE(producer)),
"rbpitch",
NULL);
mlt_profile profile = mlt_service_profile(MLT_PRODUCER_SERVICE(producer));
const char *preferred = wsola ? "wsola" : "rbpitch";
const char *fallback = wsola ? "rbpitch" : "wsola";
pdata->pitch_filter = mlt_factory_filter(profile, preferred, NULL);
if (!pdata->pitch_filter)
pdata->pitch_filter = mlt_factory_filter(profile, fallback, NULL);
pdata->pitch_wsola = wsola;
}
if (pdata->pitch_filter) {
mlt_properties_set_double(MLT_FILTER_PROPERTIES(pdata->pitch_filter),
Expand Down
15 changes: 15 additions & 0 deletions src/modules/core/producer_timewarp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,21 @@ parameters:
mutable: no
default: 0

- identifier: warp_pitch_method
title: Pitch Compensation Method
type: string
description: >
The filter used to shift the pitch of the resampled audio when
Comment thread
bmatherly marked this conversation as resolved.
Resolved
warp_pitch is enabled: "rubberband" (filter rbpitch) or "wsola" (filter
wsola, which needs no external library). When it is not set, rubberband
is used if it is available and wsola otherwise. If the selected filter is
not available, the other one is used.
readonly: no
mutable: yes
values:
- rubberband
- wsola

- identifier: warp_speed
title: Warp Speed
type: float
Expand Down
10 changes: 10 additions & 0 deletions src/modules/plus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ add_library(mltplus MODULE
filter_text.c
filter_threshold.c
filter_timer.c
filter_wsola.cpp
interp.h
producer_blipflash.c
producer_count.c
producer_pgm.c
producer_subtitle.c
transition_affine.c
wsola/sinc_resampler.cpp
wsola/wsola_algorithm.cpp
)

file(GLOB YML "*.yml")
Expand Down Expand Up @@ -64,6 +67,12 @@ else()
target_compile_definitions(mltplus PRIVATE USE_INTERNAL_LIBEBUR128)
endif()

# Keep the floating point behavior of the Chromium original (no -ffast-math).
if(NOT MSVC)
set_source_files_properties(filter_wsola.cpp wsola/sinc_resampler.cpp wsola/wsola_algorithm.cpp
PROPERTIES COMPILE_OPTIONS -fno-fast-math)
endif()

set_target_properties(mltplus PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}")

install(TARGETS mltplus LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR})
Expand Down Expand Up @@ -94,6 +103,7 @@ install(FILES
filter_text.yml
filter_threshold.yml
filter_timer.yml
filter_wsola.yml
producer_blipflash.yml
producer_count.yml
producer_pgm.yml
Expand Down
7 changes: 7 additions & 0 deletions src/modules/plus/factory.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ extern mlt_filter filter_fft_init(mlt_profile profile,
char *arg);
#endif

extern mlt_filter filter_wsola_init(mlt_profile profile,
mlt_service_type type,
const char *id,
char *arg);

static mlt_properties metadata(mlt_service_type type, const char *id, void *data)
{
char file[PATH_MAX];
Expand Down Expand Up @@ -187,6 +192,7 @@ MLTPLUS_EXPORT MLT_REPOSITORY
MLT_REGISTER(mlt_service_filter_type, "text", filter_text_init);
MLT_REGISTER(mlt_service_filter_type, "threshold", filter_threshold_init);
MLT_REGISTER(mlt_service_filter_type, "timer", filter_timer_init);
MLT_REGISTER(mlt_service_filter_type, "wsola", filter_wsola_init);
MLT_REGISTER(mlt_service_producer_type, "blipflash", producer_blipflash_init);
MLT_REGISTER(mlt_service_producer_type, "count", producer_count_init);
MLT_REGISTER(mlt_service_producer_type, "pgm", producer_pgm_init);
Expand Down Expand Up @@ -252,6 +258,7 @@ MLTPLUS_EXPORT MLT_REPOSITORY
MLT_REGISTER_METADATA(mlt_service_filter_type, "text", metadata, "filter_text.yml");
MLT_REGISTER_METADATA(mlt_service_filter_type, "threshold", metadata, "filter_threshold.yml");
MLT_REGISTER_METADATA(mlt_service_filter_type, "timer", metadata, "filter_timer.yml");
MLT_REGISTER_METADATA(mlt_service_filter_type, "wsola", metadata, "filter_wsola.yml");
MLT_REGISTER_METADATA(mlt_service_producer_type,
"blipflash",
metadata,
Expand Down
Loading
Loading