sound-equalizer #105613

Merged
Richard Antalik merged 18 commits from :sound-equalizer into main 2023-08-30 22:36:44 +02:00
22 changed files with 722 additions and 93 deletions

View File

@ -37,7 +37,18 @@ find_path(FFTW3_INCLUDE_DIR
include
)
find_library(FFTW3_LIBRARY
set(_FFTW3_LIBRARIES)
find_library(FFTW3_LIBRARY_F
NAMES
fftw3f
HINTS
${_fftw3_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
find_library(FFTW3_LIBRARY_D
NAMES
fftw3
HINTS
@ -46,17 +57,22 @@ find_library(FFTW3_LIBRARY
lib64 lib
)
list(APPEND _FFTW3_LIBRARIES "${FFTW3_LIBRARY_F}")
list(APPEND _FFTW3_LIBRARIES "${FFTW3_LIBRARY_D}")
# handle the QUIETLY and REQUIRED arguments and set FFTW3_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Fftw3 DEFAULT_MSG
FFTW3_LIBRARY FFTW3_INCLUDE_DIR)
_FFTW3_LIBRARIES FFTW3_INCLUDE_DIR)
if(FFTW3_FOUND)
set(FFTW3_LIBRARIES ${FFTW3_LIBRARY})
set(FFTW3_LIBRARIES ${_FFTW3_LIBRARIES})
set(FFTW3_INCLUDE_DIRS ${FFTW3_INCLUDE_DIR})
endif()
unset(_FFTW3_LIBRARIES)
mark_as_advanced(
FFTW3_INCLUDE_DIR
FFTW3_LIBRARY

View File

@ -7,7 +7,12 @@ set(SHARED_LIBRARY FALSE) # "Build Shared Library"
set(WITH_C TRUE) # "Build C Module"
set(WITH_DOCS FALSE) # "Build C++ HTML Documentation with Doxygen"
set(WITH_FFMPEG ${WITH_CODEC_FFMPEG}) # "Build With FFMPEG"
set(WITH_FFTW FALSE) # "Build With FFTW"
if(DEFINED WITH_FFTW3) # "Build With FFTW"
set(FFTW_FOUND TRUE)
set(WITH_FFTW ${WITH_FFTW3})
set(FFTW_INCLUDE_DIR ${FFTW3_INCLUDE_DIRS})
set(FFTW_LIBRARY ${FFTW3_LIBRARIES})
endif()
set(WITH_LIBSNDFILE ${WITH_CODEC_SNDFILE}) # "Build With LibSndFile"
set(SEPARATE_C FALSE) # "Build C Binding as separate library"
set(PLUGIN_COREAUDIO FALSE) # "Build CoreAudio Plugin"

View File

@ -962,7 +962,11 @@ class SEQUENCER_MT_strip(Menu):
if strip_type != 'SOUND':
layout.separator()
layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
layout.operator_menu_enum("sequencer.strip_video_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
else:
layout.separator()
layout.operator_menu_enum("sequencer.strip_sound_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if strip_type in {
@ -1103,17 +1107,19 @@ class SEQUENCER_MT_context_menu(Menu):
if strip_type != 'SOUND':
layout.separator()
layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
layout.operator_menu_enum("sequencer.strip_video_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if selected_sequences_count >= 2:
layout.separator()
col = layout.column()
col.menu("SEQUENCER_MT_add_transitions", text="Add Transition")
elif selected_sequences_count >= 2:
else:
layout.separator()
layout.operator("sequencer.crossfade_sounds", text="Crossfade Sounds")
layout.operator_menu_enum("sequencer.strip_sound_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if selected_sequences_count >= 2:
layout.separator()
layout.operator("sequencer.crossfade_sounds", text="Crossfade Sounds")
if selected_sequences_count >= 1:
col = layout.column()
@ -2503,8 +2509,13 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
strip = context.active_sequence_strip
ed = context.scene.sequence_editor
if strip.type == 'SOUND':
sound = strip.sound
else:
sound = None
layout.prop(strip, "use_linear_modifiers")
if sound is None:
layout.prop(strip, "use_linear_modifiers")
layout.operator_menu_enum("sequencer.strip_modifier_add", "type")
layout.operator("sequencer.strip_modifier_copy")
@ -2531,45 +2542,66 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
row.operator("sequencer.strip_modifier_remove", text="", icon='X', emboss=False).name = mod.name
if mod.show_expanded:
row = box.row()
row.prop(mod, "input_mask_type", expand=True)
if mod.input_mask_type == 'STRIP':
sequences_object = ed
if ed.meta_stack:
sequences_object = ed.meta_stack[-1]
box.prop_search(mod, "input_mask_strip", sequences_object, "sequences", text="Mask")
else:
box.prop(mod, "input_mask_id")
if sound is None:
row = box.row()
row.prop(mod, "mask_time", expand=True)
row.prop(mod, "input_mask_type", expand=True)
if mod.type == 'COLOR_BALANCE':
box.prop(mod, "color_multiply")
draw_color_balance(box, mod.color_balance)
elif mod.type == 'CURVES':
box.template_curve_mapping(mod, "curve_mapping", type='COLOR', show_tone=True)
elif mod.type == 'HUE_CORRECT':
box.template_curve_mapping(mod, "curve_mapping", type='HUE')
elif mod.type == 'BRIGHT_CONTRAST':
col = box.column()
col.prop(mod, "bright")
col.prop(mod, "contrast")
elif mod.type == 'WHITE_BALANCE':
col = box.column()
col.prop(mod, "white_value")
elif mod.type == 'TONEMAP':
col = box.column()
col.prop(mod, "tonemap_type")
if mod.tonemap_type == 'RD_PHOTORECEPTOR':
col.prop(mod, "intensity")
if mod.input_mask_type == 'STRIP':
sequences_object = ed
if ed.meta_stack:
sequences_object = ed.meta_stack[-1]
box.prop_search(mod, "input_mask_strip", sequences_object, "sequences", text="Mask")
else:
box.prop(mod, "input_mask_id")
row = box.row()
row.prop(mod, "mask_time", expand=True)
if mod.type == 'COLOR_BALANCE':
box.prop(mod, "color_multiply")
draw_color_balance(box, mod.color_balance)
elif mod.type == 'CURVES':
box.template_curve_mapping(mod, "curve_mapping", type='COLOR', show_tone=True)
elif mod.type == 'HUE_CORRECT':
box.template_curve_mapping(mod, "curve_mapping", type='HUE')
elif mod.type == 'BRIGHT_CONTRAST':
col = box.column()
col.prop(mod, "bright")
col.prop(mod, "contrast")
col.prop(mod, "adaptation")
col.prop(mod, "correction")
elif mod.tonemap_type == 'RH_SIMPLE':
col.prop(mod, "key")
col.prop(mod, "offset")
col.prop(mod, "gamma")
elif mod.type == 'WHITE_BALANCE':
col = box.column()
col.prop(mod, "white_value")
elif mod.type == 'TONEMAP':
col = box.column()
col.prop(mod, "tonemap_type")
if mod.tonemap_type == 'RD_PHOTORECEPTOR':
col.prop(mod, "intensity")
col.prop(mod, "contrast")
col.prop(mod, "adaptation")
col.prop(mod, "correction")
elif mod.tonemap_type == 'RH_SIMPLE':
col.prop(mod, "key")
col.prop(mod, "offset")
col.prop(mod, "gamma")
else:
if mod.type == 'SOUND_EQUALIZER':
eq_row = box.row()
# eq_graphs = eq_row.operator_menu_enum("sequencer.strip_modifier_equalizer_redefine", "graphs")
# eq_graphs.name = mod.name
flow = box.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
for i in range(len(mod.graphics)):
soundEq = mod.graphics[i]
col = flow.column()
box = col.box()
split = box.split(factor=0.4)
split.label(text = "{:.2f}".format(soundEq.curve_mapping.clip_min_x))
split.label(text = "Hz")
split.alignment = "RIGHT"
split.label(text = "{:.2f}".format(soundEq.curve_mapping.clip_max_x))
box.template_curve_mapping(soundEq, "curve_mapping",
type='NONE', levels=False, brush=True, use_negative_slope=True, show_tone=False)
second_row = col.row()
second_row.label(text = "dB")
second_row.alignment = "CENTER"
class SEQUENCER_PT_annotation(AnnotationDataPanel, SequencerButtonsPanel_Output, Panel):

View File

@ -24,8 +24,13 @@ struct ImBuf;
struct Scopes;
struct rctf;
void BKE_curvemapping_set_defaults(
struct CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy);
void BKE_curvemapping_set_defaults(struct CurveMapping *cumap,
int tot,
float minx,
float miny,
float maxx,
float maxy,
short default_handle_type);
struct CurveMapping *BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
void BKE_curvemapping_free_data(struct CurveMapping *cumap);
void BKE_curvemapping_free(struct CurveMapping *cumap);

View File

@ -127,6 +127,7 @@ void BKE_sound_update_scene_listener(struct Scene *scene);
void *BKE_sound_scene_add_scene_sound(
struct Scene *scene, struct Sequence *sequence, int startframe, int endframe, int frameskip);
void *BKE_sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence);
void *BKE_sound_add_scene_sound(
@ -145,8 +146,14 @@ void BKE_sound_move_scene_sound(const struct Scene *scene,
double audio_offset);
void BKE_sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence);
/* Join the Sequence with the structure in Audaspace, the second parameter is a bSound */
void BKE_sound_update_scene_sound(void *handle, struct bSound *sound);
/* Join the Sequence with the structure in Audaspace, the second parameter is the AUD_Sound created
* in Audaspace previously
*/
void BKE_sound_update_sequence_handle(void *handle, void *sound_handle);
void BKE_sound_set_cfra(int cfra);
void BKE_sound_set_scene_volume(struct Scene *scene, float volume);

View File

@ -776,7 +776,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INK);
@ -813,7 +813,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INKNOISE);
@ -850,7 +850,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_MARKER);
@ -886,12 +886,12 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_CHISEL_SENSIVITY);
custom_curve = brush->gpencil_settings->curve_strength;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_CHISEL_STRENGTH);

View File

@ -34,8 +34,13 @@
/* ***************** operations on full struct ************* */
void BKE_curvemapping_set_defaults(
CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy)
void BKE_curvemapping_set_defaults(CurveMapping *cumap,
int tot,
float minx,
float miny,
float maxx,
float maxy,
short default_handle_type)
{
int a;
float clipminx, clipminy, clipmaxx, clipmaxy;
@ -57,14 +62,23 @@ void BKE_curvemapping_set_defaults(
cumap->bwmul[0] = cumap->bwmul[1] = cumap->bwmul[2] = 1.0f;
for (a = 0; a < tot; a++) {
if (default_handle_type == HD_VECT) {
cumap->cm[a].default_handle_type = CUMA_HANDLE_VECTOR;
}
else if (default_handle_type == HD_AUTO_ANIM) {
cumap->cm[a].default_handle_type = CUMA_HANDLE_AUTO_ANIM;
}
cumap->cm[a].totpoint = 2;
cumap->cm[a].curve = static_cast<CurveMapPoint *>(
MEM_callocN(2 * sizeof(CurveMapPoint), "curve points"));
cumap->cm[a].curve[0].x = minx;
cumap->cm[a].curve[0].y = miny;
cumap->cm[a].curve[0].flag |= default_handle_type;
cumap->cm[a].curve[1].x = maxx;
cumap->cm[a].curve[1].y = maxy;
cumap->cm[a].curve[1].flag |= default_handle_type;
}
cumap->changed_timestamp = 0;
@ -76,7 +90,7 @@ CurveMapping *BKE_curvemapping_add(int tot, float minx, float miny, float maxx,
cumap = static_cast<CurveMapping *>(MEM_callocN(sizeof(CurveMapping), "new curvemap"));
BKE_curvemapping_set_defaults(cumap, tot, minx, miny, maxx, maxy);
BKE_curvemapping_set_defaults(cumap, tot, minx, miny, maxx, maxy, HD_AUTO);
return cumap;
}
@ -238,6 +252,7 @@ CurveMapPoint *BKE_curvemap_insert(CurveMap *cuma, float x, float y)
cmp[a].x = x;
cmp[a].y = y;
cmp[a].flag = CUMA_SELECT;
cmp[a].flag |= cuma->default_handle_type;
foundloc = true;
newcmp = &cmp[a];
}
@ -266,6 +281,7 @@ void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope
switch (preset) {
case CURVE_PRESET_LINE:
case CURVE_PRESET_CONSTANT_MEDIAN:
cuma->totpoint = 2;
break;
case CURVE_PRESET_SHARP:
@ -297,6 +313,10 @@ void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope
cuma->curve = static_cast<CurveMapPoint *>(
MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), "curve points"));
for (int i = 0; i < cuma->totpoint; i++) {
cuma->curve[i].flag = cuma->default_handle_type;
}
switch (preset) {
case CURVE_PRESET_LINE:
cuma->curve[0].x = clipr->xmin;
@ -304,10 +324,18 @@ void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope
cuma->curve[1].x = clipr->xmax;
cuma->curve[1].y = clipr->ymin;
if (slope == CURVEMAP_SLOPE_POS_NEG) {
cuma->curve[0].flag &= ~CUMA_HANDLE_AUTO_ANIM;
cuma->curve[1].flag &= ~CUMA_HANDLE_AUTO_ANIM;
cuma->curve[0].flag |= CUMA_HANDLE_VECTOR;
cuma->curve[1].flag |= CUMA_HANDLE_VECTOR;
}
break;
case CURVE_PRESET_CONSTANT_MEDIAN:
cuma->curve[0].x = clipr->xmin;
cuma->curve[0].y = (clipr->ymin + clipr->ymax) / 2.0f;
cuma->curve[1].x = clipr->xmax;
cuma->curve[1].y = (clipr->ymin + clipr->ymax) / 2.0f;
break;
case CURVE_PRESET_SHARP:
cuma->curve[0].x = 0;
cuma->curve[0].y = 1;

View File

@ -158,7 +158,7 @@ static void scene_init_data(ID *id)
STRNCPY(scene->r.bake.filepath, U.renderdir);
mblur_shutter_curve = &scene->r.mblur_shutter_curve;
BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
BKE_curvemapping_init(mblur_shutter_curve);
BKE_curvemap_reset(mblur_shutter_curve->cm,
&mblur_shutter_curve->clipr,

View File

@ -789,6 +789,11 @@ void BKE_sound_update_scene_sound(void *handle, bSound *sound)
AUD_SequenceEntry_setSound(handle, sound->playback_handle);
}
void BKE_sound_update_sequence_handle(void *handle, void *sound_handle)
{
AUD_SequenceEntry_setSound(handle, sound_handle);
}
void BKE_sound_set_cfra(int cfra)
{
sound_cfra = cfra;

View File

@ -999,7 +999,7 @@ void blo_do_versions_270(FileData *fd, Library * /*lib*/, Main *bmain)
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "CurveMapping", "mblur_shutter_curve")) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
CurveMapping *curve_mapping = &scene->r.mblur_shutter_curve;
BKE_curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
BKE_curvemapping_init(curve_mapping);
BKE_curvemap_reset(
curve_mapping->cm, &curve_mapping->clipr, CURVE_PRESET_MAX, CURVEMAP_SLOPE_POS_NEG);

View File

@ -279,6 +279,7 @@ void SEQUENCER_OT_strip_modifier_add(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_remove(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_move(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_copy(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_equalizer_redefine(struct wmOperatorType *ot);
/* `sequencer_view.cc` */

View File

@ -11,6 +11,8 @@
#include "DNA_scene_types.h"
#include "DEG_depsgraph.h"
#include "BKE_context.h"
#include "WM_api.hh"
@ -24,28 +26,13 @@
#include "SEQ_relations.h"
#include "SEQ_select.h"
#include "SEQ_sequencer.h"
#include "SEQ_sound.h"
/* Own include. */
#include "sequencer_intern.h"
/*********************** Add modifier operator *************************/
static bool strip_modifier_active_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene);
if (ed) {
Sequence *seq = SEQ_select_active_get(scene);
if (seq) {
return SEQ_sequence_supports_modifiers(seq);
}
}
return false;
}
static int strip_modifier_add_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@ -60,6 +47,21 @@ static int strip_modifier_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static const EnumPropertyItem *filter_modifiers_by_sequence_type(bContext *C,
PointerRNA * /* ptr */,
PropertyRNA * /* prop */,
bool * /* r_free */)
{
Scene *scene = CTX_data_scene(C);
Sequence *seq = SEQ_select_active_get(scene);
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM)) {
return rna_enum_sequence_sound_modifier_type_items;
}
else {
return rna_enum_sequence_video_modifier_type_items;
}
}
void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot)
{
PropertyRNA *prop;
@ -71,18 +73,17 @@ void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = strip_modifier_add_exec;
ot->poll = strip_modifier_active_poll;
/*
* No poll because a modifier can be applied to any kind of strip
*/
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_enum(ot->srna,
"type",
rna_enum_sequence_modifier_type_items,
seqModifierType_ColorBalance,
"Type",
"");
prop = RNA_def_enum(ot->srna, "type", rna_enum_dummy_NULL_items, 0, "Type", "");
RNA_def_enum_funcs(prop, filter_modifiers_by_sequence_type);
ot->prop = prop;
}
@ -105,7 +106,12 @@ static int strip_modifier_remove_exec(bContext *C, wmOperator *op)
BLI_remlink(&seq->modifiers, smd);
SEQ_modifier_free(smd);
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM)) {
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS | ID_RECALC_AUDIO);
}
else {
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@ -122,7 +128,9 @@ void SEQUENCER_OT_strip_modifier_remove(wmOperatorType *ot)
/* api callbacks */
ot->exec = strip_modifier_remove_exec;
ot->poll = strip_modifier_active_poll;
/*
* No poll is needed because all kind of strips can have their modifiers erased
*/
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@ -168,7 +176,13 @@ static int strip_modifier_move_exec(bContext *C, wmOperator *op)
}
}
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM)) {
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS | ID_RECALC_AUDIO);
}
else {
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@ -191,7 +205,10 @@ void SEQUENCER_OT_strip_modifier_move(wmOperatorType *ot)
/* api callbacks */
ot->exec = strip_modifier_move_exec;
ot->poll = strip_modifier_active_poll;
/*
* No poll is needed because all strips can have modifiers
*/
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@ -221,11 +238,19 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
int isSound = ELEM(seq->type, SEQ_TYPE_SOUND_RAM);
LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) {
if (seq_iter->flag & SELECT) {
if (seq_iter == seq) {
continue;
}
int seq_iter_is_sound = ELEM(seq_iter->type, SEQ_TYPE_SOUND_RAM);
/* If original is sound, only copy to "sound" strips
* If original is not sound, only copy to "not sound" strips
*/
if (isSound != seq_iter_is_sound)
continue;
if (type == SEQ_MODIFIER_COPY_REPLACE) {
if (seq_iter->modifiers.first) {
@ -245,7 +270,13 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op)
}
}
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM)) {
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS | ID_RECALC_AUDIO);
}
else {
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@ -271,7 +302,9 @@ void SEQUENCER_OT_strip_modifier_copy(wmOperatorType *ot)
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = strip_modifier_copy_exec;
ot->poll = strip_modifier_active_poll;
/*
* No poll is needed because all kind of strips can have modifier
*/
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@ -279,3 +312,60 @@ void SEQUENCER_OT_strip_modifier_copy(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", type_items, SEQ_MODIFIER_COPY_REPLACE, "Type", "");
}
static int strip_modifier_equalizer_redefine_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Sequence *seq = SEQ_select_active_get(scene);
SequenceModifierData *smd;
char name[MAX_NAME];
RNA_string_get(op->ptr, "name", name);
int number = RNA_enum_get(op->ptr, "graphs");
smd = SEQ_modifier_find_by_name(seq, name);
if (!smd) {
return OPERATOR_CANCELLED;
}
SEQ_sound_equalizermodifier_set_graphs((SoundEqualizerModifierData *)smd, number);
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
void SEQUENCER_OT_strip_modifier_equalizer_redefine(wmOperatorType *ot)
{
static const EnumPropertyItem enum_modifier_equalizer_presets_items[] = {
{1, "SIMPLE", 0, "Unique", "One unique graphical definition"},
{2, "DOUBLE", 0, "Double", "Graphical definition in 2 sections"},
{3, "TRIPLE", 0, "Triplet", "Graphical definition in 3 sections"},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop;
/* identifiers */
ot->name = "Redefine equalizer graphs";
ot->idname = "SEQUENCER_OT_strip_modifier_equalizer_redefine";
ot->description = "Redefine equalizer graphs";
/* api callbacks */
ot->exec = strip_modifier_equalizer_redefine_exec;
/*
* No poll because a modifier can be applied to any kind of strip
*/
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_enum(
ot->srna, "graphs", enum_modifier_equalizer_presets_items, 1, "Graphs", "Number of graphs");
ot->prop = prop;
prop = RNA_def_string(
ot->srna, "name", "Name", MAX_NAME, "Name", "Name of modifier to redefine");
RNA_def_property_flag(prop, PROP_HIDDEN);
}

View File

@ -104,6 +104,7 @@ void sequencer_operatortypes()
WM_operatortype_append(SEQUENCER_OT_strip_modifier_remove);
WM_operatortype_append(SEQUENCER_OT_strip_modifier_move);
WM_operatortype_append(SEQUENCER_OT_strip_modifier_copy);
WM_operatortype_append(SEQUENCER_OT_strip_modifier_equalizer_redefine);
/* sequencer_view.h */
WM_operatortype_append(SEQUENCER_OT_sample);

View File

@ -60,6 +60,8 @@ typedef struct CurveMap {
/** For RGB curves, pre-multiplied extrapolation vector. */
float premul_ext_in[2];
float premul_ext_out[2];
short default_handle_type;
char _pad[6];
} CurveMap;
typedef struct CurveMapping {
@ -107,6 +109,7 @@ typedef enum eCurveMappingPreset {
CURVE_PRESET_ROOT = 6,
CURVE_PRESET_GAUSS = 7,
CURVE_PRESET_BELL = 8,
CURVE_PRESET_CONSTANT_MEDIAN = 9,
} eCurveMappingPreset;
/** #CurveMapping.tone */

View File

@ -527,6 +527,21 @@ enum {
/** \} */
/** \name Sound Modifiers
* \{ */
typedef struct EQCurveMappingData {
struct EQCurveMappingData *next, *prev;
struct CurveMapping curve_mapping;
} EQCurveMappingData;
typedef struct SoundEqualizerModifierData {
SequenceModifierData modifier;
/* EQCurveMappingData */
ListBase graphics;
} SoundEqualizerModifierData;
/** \} */
/* -------------------------------------------------------------------- */
/** \name Scopes
* \{ */
@ -760,6 +775,7 @@ enum {
seqModifierType_Mask = 5,
seqModifierType_WhiteBalance = 6,
seqModifierType_Tonemap = 7,
seqModifierType_SoundEqualizer = 8,
/* Keep last. */
NUM_SEQUENCE_MODIFIER_TYPES,
};

View File

@ -45,6 +45,8 @@ DEF_ENUM(rna_enum_object_modifier_type_items)
DEF_ENUM(rna_enum_constraint_type_items)
DEF_ENUM(rna_enum_boidrule_type_items)
DEF_ENUM(rna_enum_sequence_modifier_type_items)
DEF_ENUM(rna_enum_sequence_video_modifier_type_items)
DEF_ENUM(rna_enum_sequence_sound_modifier_type_items)
DEF_ENUM(rna_enum_object_greasepencil_modifier_type_items)
DEF_ENUM(rna_enum_object_shaderfx_type_items)

View File

@ -72,7 +72,24 @@ const EnumPropertyItem rna_enum_sequence_modifier_type_items[] = {
{seqModifierType_Mask, "MASK", ICON_NONE, "Mask", ""},
{seqModifierType_Tonemap, "TONEMAP", ICON_NONE, "Tone Map", ""},
{seqModifierType_WhiteBalance, "WHITE_BALANCE", ICON_NONE, "White Balance", ""},
{0, nullptr, 0, nullptr, nullptr},
{seqModifierType_SoundEqualizer, "SOUND_EQUALIZER", ICON_NONE, "Sound Equalizer", ""},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_sequence_video_modifier_type_items[] = {
{seqModifierType_BrightContrast, "BRIGHT_CONTRAST", ICON_NONE, "Bright/Contrast", ""},
{seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""},
{seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""},
{seqModifierType_HueCorrect, "HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
{seqModifierType_Mask, "MASK", ICON_NONE, "Mask", ""},
{seqModifierType_Tonemap, "TONEMAP", ICON_NONE, "Tone Map", ""},
{seqModifierType_WhiteBalance, "WHITE_BALANCE", ICON_NONE, "White Balance", ""},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_sequence_sound_modifier_type_items[] = {
{seqModifierType_SoundEqualizer, "SOUND_EQUALIZER", ICON_NONE, "Equalizer", ""},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_strip_color_items[] = {
@ -1286,6 +1303,8 @@ static StructRNA *rna_SequenceModifier_refine(PointerRNA *ptr)
return &RNA_WhiteBalanceModifier;
case seqModifierType_Tonemap:
return &RNA_SequencerTonemapModifierData;
case seqModifierType_SoundEqualizer:
return &RNA_SoundEqualizerModifier;
default:
return &RNA_SequenceModifier;
}
@ -1344,14 +1363,34 @@ static void rna_SequenceModifier_name_set(PointerRNA *ptr, const char *value)
}
}
static void rna_SequenceModifier_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
static void rna_SequenceModifier_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
{
/* strip from other scenes could be modified, so using active scene is not reliable */
Scene *scene = (Scene *)ptr->owner_id;
Editing *ed = SEQ_editing_get(scene);
Sequence *seq = sequence_get_by_modifier(ed, static_cast<SequenceModifierData *>(ptr->data));
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS | ID_RECALC_AUDIO);
DEG_relations_tag_update(bmain);
}
else {
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
}
}
/*
* Update of Curve in an EQ Sound Modifier
*/
static void rna_SequenceModifier_EQCurveMapping_update(Main *bmain,
Scene * /*scene*/,
PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->owner_id;
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS | ID_RECALC_AUDIO);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
}
static bool rna_SequenceModifier_otherSequence_poll(PointerRNA *ptr, PointerRNA value)
@ -1554,6 +1593,23 @@ static char *rna_SeqTimelineChannel_path(const PointerRNA *ptr)
}
}
static EQCurveMappingData *rna_Sequence_SoundEqualizer_Curve_add(SoundEqualizerModifierData *semd,
bContext * /* C */,
float min_freq,
float max_freq)
{
EQCurveMappingData *eqcmd = SEQ_sound_equalizermodifier_add_graph(semd, min_freq, max_freq);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
return eqcmd;
}
static void rna_Sequence_SoundEqualizer_Curve_clear(SoundEqualizerModifierData *semd,
bContext * /* C */)
{
SEQ_sound_equalizermodifier_free((SequenceModifierData *)semd);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
}
#else
static void rna_def_strip_element(BlenderRNA *brna)
@ -3757,6 +3813,89 @@ static void rna_def_modifiers(BlenderRNA *brna)
rna_def_tonemap_modifier(brna);
}
static void rna_def_graphical_sound_equalizer(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
/* Define Sound EQ */
srna = RNA_def_struct(brna, "EQCurveMappingData", NULL);
RNA_def_struct_sdna(srna, "EQCurveMappingData");
RNA_def_struct_ui_text(srna, "EQCurveMappingData", "EQCurveMappingData");
prop = RNA_def_property(srna, "curve_mapping", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "curve_mapping");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_ui_text(prop, "Curve Mapping", "");
RNA_def_property_update(
prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_EQCurveMapping_update");
}
static void rna_def_sound_equalizer_modifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
srna = RNA_def_struct(brna, "SoundEqualizerModifier", "SequenceModifier");
RNA_def_struct_sdna(srna, "SoundEqualizerModifierData");
RNA_def_struct_ui_text(srna, "SoundEqualizerModifier", "Equalize audio");
/* Sound Equalizers*/
prop = RNA_def_property(srna, "graphics", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "EQCurveMappingData");
RNA_def_property_ui_text(
prop, "Graphical definition equalization", "Graphical definition equalization");
/* add band*/
func = RNA_def_function(srna, "new_graphic", "rna_Sequence_SoundEqualizer_Curve_add");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Add a new EQ band");
parm = RNA_def_float(func,
"min_freq",
SOUND_EQUALIZER_DEFAULT_MIN_FREQ,
0.0,
SOUND_EQUALIZER_DEFAULT_MAX_FREQ, /* Hard min and max */
"Minimum Frequency",
"Minimum Frequency",
0.0,
SOUND_EQUALIZER_DEFAULT_MAX_FREQ); /* Soft min and max */
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_float(func,
"max_freq",
SOUND_EQUALIZER_DEFAULT_MAX_FREQ,
0.0,
SOUND_EQUALIZER_DEFAULT_MAX_FREQ, /* Hard min and max */
"Maximum Frequency",
"Maximum Frequency",
0.0,
SOUND_EQUALIZER_DEFAULT_MAX_FREQ); /* Soft min and max */
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
/* return type */
parm = RNA_def_pointer(func,
"graphic_eqs",
"EQCurveMappingData",
"",
"Newly created graphical Equalizer definition");
RNA_def_function_return(func, parm);
/* clear all modifiers */
func = RNA_def_function(srna, "clear_soundeqs", "rna_Sequence_SoundEqualizer_Curve_clear");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func,
"Remove all graphical equalizers from the Equalizer modifier");
rna_def_graphical_sound_equalizer(brna);
}
static void rna_def_sound_modifiers(BlenderRNA *brna)
{
rna_def_sound_equalizer_modifier(brna);
}
void RNA_def_sequencer(BlenderRNA *brna)
{
rna_def_color_balance(brna);
@ -3782,6 +3921,7 @@ void RNA_def_sequencer(BlenderRNA *brna)
rna_def_effect(brna);
rna_def_effects(brna);
rna_def_modifiers(brna);
rna_def_sound_modifiers(brna);
}
#endif

View File

@ -101,6 +101,10 @@ if(WITH_AUDASPACE)
)
endif()
add_definitions(-DWITH_AUDASPACE)
if(WITH_FFTW3)
add_definitions(-DWITH_CONVOLUTION)
endif()
endif()
blender_add_lib(bf_sequencer "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@ -16,12 +16,51 @@ struct Main;
struct Scene;
struct Sequence;
struct bSound;
struct SequencerSoundEqualizer;
struct BlendWriter;
struct BlendDataReader;
struct ListBase;
struct SoundEqualizerModifierData;
#define SOUND_EQUALIZER_DEFAULT_MIN_FREQ 30.0
#define SOUND_EQUALIZER_DEFAULT_MAX_FREQ 20000.0
#define SOUND_EQUALIZER_DEFAULT_MAX_DB 35.0
#define SOUND_EQUALIZER_SIZE_CONVERSION 2048
#define SOUND_EQUALIZER_SIZE_DEFINITION 1000
void SEQ_sound_update_bounds_all(struct Scene *scene);
void SEQ_sound_update_bounds(struct Scene *scene, struct Sequence *seq);
void SEQ_sound_update(struct Scene *scene, struct bSound *sound);
void SEQ_sound_update_length(struct Main *bmain, struct Scene *scene);
float SEQ_sound_pitch_get(const struct Scene *scene, const struct Sequence *seq);
struct EQCurveMappingData *SEQ_sound_equalizer_add(struct SoundEqualizerModifierData *semd,
float minX,
float maxX);
void SEQ_sound_blend_write(struct BlendWriter *writer, struct ListBase *soundbase);
void SEQ_sound_blend_read_data(struct BlendDataReader *reader, struct ListBase *lb);
void *SEQ_sound_modifier_recreator(struct Sequence *seq,
struct SequenceModifierData *smd,
void *sound);
void SEQ_sound_equalizermodifier_init_data(struct SequenceModifierData *smd);
void SEQ_sound_equalizermodifier_free(struct SequenceModifierData *smd);
void SEQ_sound_equalizermodifier_copy_data(struct SequenceModifierData *target,
struct SequenceModifierData *smd);
void *SEQ_sound_equalizermodifier_recreator(struct Sequence *seq,
struct SequenceModifierData *smd,
void *sound);
void SEQ_sound_equalizermodifier_set_graphs(struct SoundEqualizerModifierData *semd, int number);
const struct SoundModifierWorkerInfo *SEQ_sound_modifier_worker_info_get(int type);
struct EQCurveMappingData *SEQ_sound_equalizermodifier_add_graph(
struct SoundEqualizerModifierData *semd, float min_freq, float max_freq);
void SEQ_sound_equalizermodifier_remove_graph(struct SoundEqualizerModifierData *semd,
struct EQCurveMappingData *gsed);
typedef struct SoundModifierWorkerInfo {
int type;
void *(*recreator)(struct Sequence *seq, struct SequenceModifierData *smd, void *sound);
} SoundModifierWorkerInfo;
#ifdef __cplusplus
}

View File

@ -30,6 +30,7 @@
#include "SEQ_modifier.h"
#include "SEQ_render.h"
#include "SEQ_sound.h"
#include "BLO_read_write.hh"
@ -741,7 +742,7 @@ static void curves_init_data(SequenceModifierData *smd)
{
CurvesModifierData *cmd = (CurvesModifierData *)smd;
BKE_curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
}
static void curves_free_data(SequenceModifierData *smd)
@ -860,7 +861,7 @@ static void hue_correct_init_data(SequenceModifierData *smd)
HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
int c;
BKE_curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
BKE_curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f, HD_AUTO);
hcmd->curve_mapping.preset = CURVE_PRESET_MID9;
for (c = 0; c < 3; c++) {
@ -1371,6 +1372,15 @@ static SequenceModifierTypeInfo seqModifier_Tonemap = {
/*apply*/ tonemapmodifier_apply,
};
static SequenceModifierTypeInfo seqModifier_SoundEqualizer = {
CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Equalizer"), /* name */
"SoundEqualizerModifierData", /* struct_name */
sizeof(SoundEqualizerModifierData), /* struct_size */
SEQ_sound_equalizermodifier_init_data, /* init_data */
SEQ_sound_equalizermodifier_free, /* free_data */
SEQ_sound_equalizermodifier_copy_data, /* copy_data */
NULL, /* apply */
};
/** \} */
/* -------------------------------------------------------------------- */
@ -1388,6 +1398,7 @@ static void sequence_modifier_type_info_init()
INIT_TYPE(Mask);
INIT_TYPE(WhiteBalance);
INIT_TYPE(Tonemap);
INIT_TYPE(SoundEqualizer);
#undef INIT_TYPE
}
@ -1591,6 +1602,13 @@ void SEQ_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
BKE_curvemapping_blend_write(writer, &hcmd->curve_mapping);
}
else if (smd->type == seqModifierType_SoundEqualizer) {
SoundEqualizerModifierData *semd = (SoundEqualizerModifierData *)smd;
LISTBASE_FOREACH (EQCurveMappingData *, eqcmd, &semd->graphics) {
BLO_write_struct_by_name(writer, "EQCurveMappingData", eqcmd);
BKE_curvemapping_blend_write(writer, &eqcmd->curve_mapping);
}
}
}
else {
BLO_write_struct(writer, SequenceModifierData, smd);
@ -1617,6 +1635,13 @@ void SEQ_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
BKE_curvemapping_blend_read(reader, &hcmd->curve_mapping);
}
else if (smd->type == seqModifierType_SoundEqualizer) {
SoundEqualizerModifierData *semd = (SoundEqualizerModifierData *)smd;
BLO_read_list(reader, &semd->graphics);
LISTBASE_FOREACH (EQCurveMappingData *, eqcmd, &semd->graphics) {
BKE_curvemapping_blend_read(reader, &eqcmd->curve_mapping);
}
}
}
}

View File

@ -918,6 +918,15 @@ static bool seq_update_seq_cb(Sequence *seq, void *user_data)
if (scene->id.recalc & ID_RECALC_AUDIO || seq->sound->id.recalc & ID_RECALC_AUDIO) {
BKE_sound_update_scene_sound(seq->scene_sound, seq->sound);
}
void *sound = seq->sound->playback_handle;
if (!BLI_listbase_is_empty(&seq->modifiers)) {
LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
sound = SEQ_sound_modifier_recreator(seq, smd, sound);
}
}
BKE_sound_update_sequence_handle(seq->scene_sound, sound);
}
BKE_sound_set_scene_sound_volume(
seq->scene_sound, seq->volume, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0);

View File

@ -9,7 +9,12 @@
*/
#include <cmath>
#include <math.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
@ -17,10 +22,15 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "BLO_read_write.hh"
#include "BKE_colortools.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "BKE_sound.h"
#include "AUD_Sound.h"
#include "SEQ_sound.h"
#include "SEQ_time.h"
@ -29,6 +39,9 @@
/* Unlike _update_sound_ functions,
* these ones take info from audaspace to update sequence length! */
const SoundModifierWorkerInfo workersSoundModifiers[] = {
{seqModifierType_SoundEqualizer, SEQ_sound_equalizermodifier_recreator}, {0, NULL}};
#ifdef WITH_AUDASPACE
static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene, ListBase *seqbase)
{
@ -140,3 +153,191 @@ float SEQ_sound_pitch_get(const Scene *scene, const Sequence *seq)
}
return seq->speed_factor;
}
struct EQCurveMappingData *SEQ_sound_equalizer_add(SoundEqualizerModifierData *semd,
float minX,
float maxX)
{
EQCurveMappingData *eqcmd;
if (maxX < 0)
maxX = SOUND_EQUALIZER_DEFAULT_MAX_FREQ;
if (minX < 0)
minX = 0.0;
/* It's the same as BKE_curvemapping_add , but changing the name */
eqcmd = MEM_cnew<EQCurveMappingData>("Equalizer");
BKE_curvemapping_set_defaults(&eqcmd->curve_mapping,
1, /* tot*/
minX,
-SOUND_EQUALIZER_DEFAULT_MAX_DB, /* Min x, y */
maxX,
SOUND_EQUALIZER_DEFAULT_MAX_DB, /* Max x, y */
HD_AUTO_ANIM);
eqcmd->curve_mapping.preset = CURVE_PRESET_CONSTANT_MEDIAN;
rctf clipr;
clipr.xmin = minX;
clipr.xmax = maxX;
clipr.ymin = 0.0;
clipr.ymax = 0.0;
BKE_curvemap_reset(&eqcmd->curve_mapping.cm[0], &clipr, CURVE_PRESET_CONSTANT_MEDIAN, 0);
BLI_addtail(&semd->graphics, eqcmd);
return eqcmd;
}
void SEQ_sound_equalizermodifier_set_graphs(struct SoundEqualizerModifierData *semd, int number)
{
SEQ_sound_equalizermodifier_free((SequenceModifierData *)semd);
if (number == 1) {
SEQ_sound_equalizer_add(
semd, SOUND_EQUALIZER_DEFAULT_MIN_FREQ, SOUND_EQUALIZER_DEFAULT_MAX_FREQ);
}
else if (number == 2) {
SEQ_sound_equalizer_add(semd, 30.0, 2000.0);
SEQ_sound_equalizer_add(semd, 2000.1, 20000.0);
}
else if (number == 3) {
SEQ_sound_equalizer_add(semd, 30.0, 1000.0);
SEQ_sound_equalizer_add(semd, 1000.1, 5000.0);
SEQ_sound_equalizer_add(semd, 5000.1, 20000.0);
}
}
EQCurveMappingData *SEQ_sound_equalizermodifier_add_graph(struct SoundEqualizerModifierData *semd,
float min_freq,
float max_freq)
{
if (min_freq < 0.0)
return NULL;
if (max_freq < 0.0)
return NULL;
if (max_freq <= min_freq)
return NULL;
return SEQ_sound_equalizer_add(semd, min_freq, max_freq);
}
void SEQ_sound_equalizermodifier_remove_graph(struct SoundEqualizerModifierData *semd,
struct EQCurveMappingData *eqcmd)
{
BLI_remlink_safe(&semd->graphics, eqcmd);
MEM_freeN(eqcmd);
}
void SEQ_sound_equalizermodifier_init_data(SequenceModifierData *smd)
{
SoundEqualizerModifierData *semd = (SoundEqualizerModifierData *)smd;
SEQ_sound_equalizer_add(
semd, SOUND_EQUALIZER_DEFAULT_MIN_FREQ, SOUND_EQUALIZER_DEFAULT_MAX_FREQ);
}
void SEQ_sound_equalizermodifier_free(SequenceModifierData *smd)
{
SoundEqualizerModifierData *semd = (SoundEqualizerModifierData *)smd;
LISTBASE_FOREACH_MUTABLE (EQCurveMappingData *, eqcmd, &semd->graphics) {
BKE_curvemapping_free_data(&eqcmd->curve_mapping);
MEM_freeN(eqcmd);
}
BLI_listbase_clear(&semd->graphics);
}
void SEQ_sound_equalizermodifier_copy_data(struct SequenceModifierData *target,
struct SequenceModifierData *smd)
{
SoundEqualizerModifierData *semd = (SoundEqualizerModifierData *)smd;
SoundEqualizerModifierData *semd_target = (SoundEqualizerModifierData *)target;
EQCurveMappingData *eqcmd_n;
BLI_listbase_clear(&semd_target->graphics);
LISTBASE_FOREACH (EQCurveMappingData *, eqcmd, &semd->graphics) {
eqcmd_n = static_cast<EQCurveMappingData *>(MEM_dupallocN(eqcmd));
BKE_curvemapping_copy_data(&eqcmd_n->curve_mapping, &eqcmd->curve_mapping);
eqcmd_n->next = eqcmd_n->prev = NULL;
BLI_addtail(&semd_target->graphics, eqcmd_n);
}
}
void *SEQ_sound_equalizermodifier_recreator(struct Sequence *seq,
struct SequenceModifierData *smd,
void *sound)
{
UNUSED_VARS(seq);
SoundEqualizerModifierData *semd = (SoundEqualizerModifierData *)smd;
// No Equalizer definition
if (BLI_listbase_is_empty(&semd->graphics)) {
return sound;
}
float *buf = (float *)MEM_callocN(sizeof(float) * SOUND_EQUALIZER_SIZE_DEFINITION,
"eqrecreator");
CurveMapping *eq_mapping;
CurveMap *cm;
float minX;
float maxX;
float interval = SOUND_EQUALIZER_DEFAULT_MAX_FREQ / (float)SOUND_EQUALIZER_SIZE_DEFINITION;
// Visit all equalizer definitions
LISTBASE_FOREACH (EQCurveMappingData *, mapping, &semd->graphics) {
eq_mapping = &mapping->curve_mapping;
BKE_curvemapping_init(eq_mapping);
cm = eq_mapping->cm;
minX = eq_mapping->curr.xmin;
maxX = eq_mapping->curr.xmax;
int idx = (int)ceil(minX / interval);
int i = idx;
for (; i * interval <= maxX && i < SOUND_EQUALIZER_SIZE_DEFINITION; i++) {
float freq = i * interval;
float val = BKE_curvemap_evaluateF(eq_mapping, cm, freq);
if (fabs(val) > SOUND_EQUALIZER_DEFAULT_MAX_DB)
val = (val / fabs(val)) * SOUND_EQUALIZER_DEFAULT_MAX_DB;
buf[i] = val;
/* To soften lower limit, but not the first position which is the constant value */
if (i == idx && i > 2) {
buf[i - 1] = 0.5 * (buf[i] + buf[i - 1]);
}
}
/* To soften higher limit */
if (i < SOUND_EQUALIZER_SIZE_DEFINITION)
buf[i] = 0.5 * (buf[i] + buf[i - 1]);
}
AUD_Sound *equ = AUD_Sound_equalize(sound,
buf,
SOUND_EQUALIZER_SIZE_DEFINITION,
SOUND_EQUALIZER_DEFAULT_MAX_FREQ,
SOUND_EQUALIZER_SIZE_CONVERSION);
MEM_freeN(buf);
return equ;
}
const struct SoundModifierWorkerInfo *SEQ_sound_modifier_worker_info_get(int type)
{
for (int i = 0; workersSoundModifiers[i].type > 0; i++) {
if (workersSoundModifiers[i].type == type)
return &workersSoundModifiers[i];
}
return NULL;
}
void *SEQ_sound_modifier_recreator(struct Sequence *seq,
struct SequenceModifierData *smd,
void *sound)
{
if (!(smd->flag & SEQUENCE_MODIFIER_MUTE)) {
const SoundModifierWorkerInfo *smwi = SEQ_sound_modifier_worker_info_get(smd->type);
return smwi->recreator(seq, smd, sound);
}
return sound;
}