Blender V4.3
sequencer/intern/sound.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 * SPDX-FileCopyrightText: 2003-2009 Blender Authors
3 * SPDX-FileCopyrightText: 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later */
6
11#include <algorithm>
12#include <cmath>
13#include <cstring>
14
15#include "MEM_guardedalloc.h"
16
17#include "DNA_curve_types.h"
18#include "DNA_scene_types.h"
19#include "DNA_sequence_types.h"
20#include "DNA_sound_types.h"
21
22#include "BLI_listbase.h"
23#include "BLI_utildefines.h"
24
25#include "BKE_colortools.hh"
26#include "BKE_sound.h"
27
28#ifdef WITH_CONVOLUTION
29# include "AUD_Sound.h"
30#endif
31
32#include "SEQ_sound.hh"
33#include "SEQ_time.hh"
34
35#include "sequencer.hh"
36#include "strip_time.hh"
37
38/* Unlike _update_sound_ functions,
39 * these ones take info from audaspace to update sequence length! */
42
43#ifdef WITH_CONVOLUTION
44static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene, ListBase *seqbase)
45{
46 bool changed = false;
47
48 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
49 if (seq->type == SEQ_TYPE_META) {
50 if (sequencer_refresh_sound_length_recursive(bmain, scene, &seq->seqbase)) {
51 changed = true;
52 }
53 }
54 else if (seq->type == SEQ_TYPE_SOUND_RAM && seq->sound) {
55 SoundInfo info;
56 if (!BKE_sound_info_get(bmain, seq->sound, &info)) {
57 continue;
58 }
59
60 int old = seq->len;
61 float fac;
62
63 seq->len = std::max(1, int(round((info.length - seq->sound->offset_time) * FPS)));
64 fac = float(seq->len) / float(old);
65 old = seq->startofs;
66 seq->startofs *= fac;
67 seq->endofs *= fac;
68 seq->start += (old - seq->startofs); /* So that visual/"real" start frame does not change! */
69
70 changed = true;
71 }
72 }
73 return changed;
74}
75#endif
76
78{
79#ifdef WITH_CONVOLUTION
80 if (scene->ed) {
81 sequencer_refresh_sound_length_recursive(bmain, scene, &scene->ed->seqbase);
82 }
83#else
84 UNUSED_VARS(bmain, scene);
85#endif
86}
87
89{
90 Editing *ed = scene->ed;
91
92 if (ed) {
93 LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) {
94 if (seq->type == SEQ_TYPE_META) {
96 }
97 else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
98 SEQ_sound_update_bounds(scene, seq);
99 }
100 }
101 }
102}
103
105{
106 if (seq->type == SEQ_TYPE_SCENE) {
107 if (seq->scene && seq->scene_sound) {
108 /* We have to take into account start frame of the sequence's scene! */
109 int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra;
110
112 seq->scene_sound,
115 startofs,
116 0.0);
117 }
118 }
119 else {
121 }
122 /* mute is set in seq_update_muting_recursive */
123}
124
125static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound *sound)
126{
127 LISTBASE_FOREACH (Sequence *, seq, seqbasep) {
128 if (seq->type == SEQ_TYPE_META) {
129 seq_update_sound_recursive(scene, &seq->seqbase, sound);
130 }
131 else if (seq->type == SEQ_TYPE_SOUND_RAM) {
132 if (seq->scene_sound && sound == seq->sound) {
133 BKE_sound_update_scene_sound(seq->scene_sound, sound);
134 }
135 }
136 }
137}
138
139void SEQ_sound_update(Scene *scene, bSound *sound)
140{
141 if (scene->ed) {
142 seq_update_sound_recursive(scene, &scene->ed->seqbase, sound);
143 }
144}
145
146float SEQ_sound_pitch_get(const Scene *scene, const Sequence *seq)
147{
148 const Sequence *meta_parent = seq_sequence_lookup_meta_by_seq(scene, seq);
149 if (meta_parent != nullptr) {
150 return seq->speed_factor * SEQ_sound_pitch_get(scene, meta_parent);
151 }
152 return seq->speed_factor;
153}
154
156 float minX,
157 float maxX)
158{
159 EQCurveMappingData *eqcmd;
160
161 if (maxX < 0) {
163 }
164 if (minX < 0) {
165 minX = 0.0;
166 }
167 /* It's the same as #BKE_curvemapping_add, but changing the name. */
168 eqcmd = MEM_cnew<EQCurveMappingData>("Equalizer");
170 1, /* Total. */
171 minX,
172 -SOUND_EQUALIZER_DEFAULT_MAX_DB, /* Min x, y */
173 maxX,
174 SOUND_EQUALIZER_DEFAULT_MAX_DB, /* Max x, y */
176
178
179 rctf clipr;
180 clipr.xmin = minX;
181 clipr.xmax = maxX;
182 clipr.ymin = 0.0;
183 clipr.ymax = 0.0;
184
186
187 BLI_addtail(&semd->graphics, eqcmd);
188
189 return eqcmd;
190}
191
193{
195 if (number == 1) {
198 }
199 else if (number == 2) {
200 SEQ_sound_equalizer_add(semd, 30.0, 2000.0);
201 SEQ_sound_equalizer_add(semd, 2000.1, 20000.0);
202 }
203 else if (number == 3) {
204 SEQ_sound_equalizer_add(semd, 30.0, 1000.0);
205 SEQ_sound_equalizer_add(semd, 1000.1, 5000.0);
206 SEQ_sound_equalizer_add(semd, 5000.1, 20000.0);
207 }
208}
209
211 float min_freq,
212 float max_freq)
213{
214 if (min_freq < 0.0) {
215 return nullptr;
216 }
217 if (max_freq < 0.0) {
218 return nullptr;
219 }
220 if (max_freq <= min_freq) {
221 return nullptr;
222 }
223 return SEQ_sound_equalizer_add(semd, min_freq, max_freq);
224}
225
232
240
250
252{
255 EQCurveMappingData *eqcmd_n;
256
257 BLI_listbase_clear(&semd_target->graphics);
258
259 LISTBASE_FOREACH (EQCurveMappingData *, eqcmd, &semd->graphics) {
260 eqcmd_n = static_cast<EQCurveMappingData *>(MEM_dupallocN(eqcmd));
261 BKE_curvemapping_copy_data(&eqcmd_n->curve_mapping, &eqcmd->curve_mapping);
262
263 eqcmd_n->next = eqcmd_n->prev = nullptr;
264 BLI_addtail(&semd_target->graphics, eqcmd_n);
265 }
266}
267
269{
270#ifdef WITH_CONVOLUTION
271 UNUSED_VARS(seq);
272
274
275 /* No equalizer definition. */
276 if (BLI_listbase_is_empty(&semd->graphics)) {
277 return sound;
278 }
279
280 float *buf = (float *)MEM_callocN(sizeof(float) * SOUND_EQUALIZER_SIZE_DEFINITION,
281 "eqrecreator");
282
283 CurveMapping *eq_mapping;
284 CurveMap *cm;
285 float minX;
286 float maxX;
288
289 /* Visit all equalizer definitions. */
290 LISTBASE_FOREACH (EQCurveMappingData *, mapping, &semd->graphics) {
291 eq_mapping = &mapping->curve_mapping;
292 BKE_curvemapping_init(eq_mapping);
293 cm = eq_mapping->cm;
294 minX = eq_mapping->curr.xmin;
295 maxX = eq_mapping->curr.xmax;
296 int idx = int(ceil(minX / interval));
297 int i = idx;
298 for (; i * interval <= maxX && i < SOUND_EQUALIZER_SIZE_DEFINITION; i++) {
299 float freq = i * interval;
300 float val = BKE_curvemap_evaluateF(eq_mapping, cm, freq);
302 val = (val / fabs(val)) * SOUND_EQUALIZER_DEFAULT_MAX_DB;
303 buf[i] = val;
304 /* To soften lower limit, but not the first position which is the constant value */
305 if (i == idx && i > 2) {
306 buf[i - 1] = 0.5 * (buf[i] + buf[i - 1]);
307 }
308 }
309 /* To soften higher limit */
311 buf[i] = 0.5 * (buf[i] + buf[i - 1]);
312 }
313
314 AUD_Sound *equ = AUD_Sound_equalize(sound,
315 buf,
319
320 MEM_freeN(buf);
321
322 return equ;
323#else
324 UNUSED_VARS(seq, smd, sound);
325 return nullptr;
326#endif
327}
328
330{
331 for (int i = 0; workersSoundModifiers[i].type > 0; i++) {
332 if (workersSoundModifiers[i].type == type) {
333 return &workersSoundModifiers[i];
334 }
335 }
336 return nullptr;
337}
338
340{
341
342 if (!(smd->flag & SEQUENCE_MODIFIER_MUTE)) {
344 return smwi->recreator(seq, smd, sound);
345 }
346 return sound;
347}
void BKE_curvemapping_free_data(CurveMapping *cumap)
void BKE_curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy, short default_handle_type)
Definition colortools.cc:40
void BKE_curvemapping_init(CurveMapping *cumap)
void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
float BKE_curvemap_evaluateF(const CurveMapping *cumap, const CurveMap *cuma, float value)
void BKE_curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
bool BKE_sound_info_get(struct Main *main, struct bSound *sound, SoundInfo *sound_info)
void BKE_sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence)
void BKE_sound_move_scene_sound(const struct Scene *scene, void *handle, int startframe, int endframe, int frameskip, double audio_offset)
void BKE_sound_update_scene_sound(void *handle, struct bSound *sound)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
bool BLI_remlink_safe(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:153
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
#define UNUSED_VARS(...)
#define ELEM(...)
@ CURVE_PRESET_CONSTANT_MEDIAN
@ HD_AUTO_ANIM
#define FPS
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_META
@ SEQ_TYPE_SCENE
@ seqModifierType_SoundEqualizer
@ SEQUENCE_MODIFIER_MUTE
Read Guarded memory(de)allocation.
#define SOUND_EQUALIZER_DEFAULT_MAX_FREQ
Definition SEQ_sound.hh:24
#define SOUND_EQUALIZER_SIZE_CONVERSION
Definition SEQ_sound.hh:26
#define SOUND_EQUALIZER_SIZE_DEFINITION
Definition SEQ_sound.hh:27
#define SOUND_EQUALIZER_DEFAULT_MIN_FREQ
Definition SEQ_sound.hh:23
#define SOUND_EQUALIZER_DEFAULT_MAX_DB
Definition SEQ_sound.hh:25
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
T round(const T &a)
Sequence * seq_sequence_lookup_meta_by_seq(const Scene *scene, const Sequence *key)
EQCurveMappingData * SEQ_sound_equalizermodifier_add_graph(SoundEqualizerModifierData *semd, float min_freq, float max_freq)
static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound *sound)
void SEQ_sound_equalizermodifier_free(SequenceModifierData *smd)
void SEQ_sound_update_bounds_all(Scene *scene)
EQCurveMappingData * SEQ_sound_equalizer_add(SoundEqualizerModifierData *semd, float minX, float maxX)
void SEQ_sound_equalizermodifier_set_graphs(SoundEqualizerModifierData *semd, int number)
void * SEQ_sound_modifier_recreator(Sequence *seq, SequenceModifierData *smd, void *sound)
const SoundModifierWorkerInfo * SEQ_sound_modifier_worker_info_get(int type)
void SEQ_sound_update(Scene *scene, bSound *sound)
float SEQ_sound_pitch_get(const Scene *scene, const Sequence *seq)
void SEQ_sound_update_bounds(Scene *scene, Sequence *seq)
void SEQ_sound_equalizermodifier_init_data(SequenceModifierData *smd)
void * SEQ_sound_equalizermodifier_recreator(Sequence *seq, SequenceModifierData *smd, void *sound)
void SEQ_sound_equalizermodifier_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
void SEQ_sound_update_length(Main *bmain, Scene *scene)
const SoundModifierWorkerInfo workersSoundModifiers[]
void SEQ_sound_equalizermodifier_remove_graph(SoundEqualizerModifierData *semd, EQCurveMappingData *eqcmd)
void seq_update_sound_bounds_recursive(const Scene *scene, Sequence *metaseq)
int SEQ_time_left_handle_frame_get(const Scene *, const Sequence *seq)
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
CurveMap cm[4]
struct EQCurveMappingData * next
struct EQCurveMappingData * prev
struct CurveMapping curve_mapping
ListBase seqbase
struct RenderData r
struct Scene * scene
float length
Definition BKE_sound.h:85
void *(* recreator)(Sequence *seq, SequenceModifierData *smd, void *sound)
Definition SEQ_sound.hh:57
float xmax
float xmin
float ymax
float ymin