Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h3
-rw-r--r--source/blender/blenkernel/BKE_scene.h8
-rw-r--r--source/blender/blenkernel/BKE_sound.h21
-rw-r--r--source/blender/blenkernel/intern/scene.c72
-rw-r--r--source/blender/blenkernel/intern/sequencer.c27
-rw-r--r--source/blender/blenkernel/intern/sound.c311
-rw-r--r--source/blender/blenloader/intern/readfile.c20
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc37
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc35
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc11
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc13
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc22
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc244
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc3
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h6
-rw-r--r--source/blender/editors/animation/anim_ops.c7
-rw-r--r--source/blender/editors/screen/screen_ops.c25
-rw-r--r--source/blender/editors/sound/CMakeLists.txt1
-rw-r--r--source/blender/editors/sound/sound_ops.c55
-rw-r--r--source/blender/editors/space_clip/clip_ops.c4
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c3
-rw-r--r--source/blender/editors/space_graph/graph_ops.c6
-rw-r--r--source/blender/editors/space_image/image_ops.c3
-rw-r--r--source/blender/editors/space_sequencer/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c13
-rw-r--r--source/blender/editors/space_sequencer/sequencer_preview.c4
-rw-r--r--source/blender/editors/transform/transform_generics.c2
-rw-r--r--source/blender/makesdna/DNA_ID.h14
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_scene.c30
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c46
-rw-r--r--source/blender/render/intern/source/pipeline.c12
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c22
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c28
44 files changed, 887 insertions, 279 deletions
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 43ee284a201..9425f396bc5 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -116,7 +116,8 @@ bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip,
struct MovieClipUser *user,
struct ImBuf *ibuf);
-/* Evaluation. */
+/* Dependency graph evaluation. */
+
void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, struct MovieClip *clip);
void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, struct MovieClip *clip);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 0dcb109240c..f90429aaebe 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -246,6 +246,14 @@ void BKE_scene_cursor_from_mat4(struct View3DCursor *cursor,
const float mat[4][4],
bool use_compat);
+/* Dependency graph evaluation. */
+
+/* Evaluate parts of sequences which needs to be done as a part of a dependency graph evaluation.
+ * This does NOT include actual rendering of the strips, but rather makes them up-to-date for
+ * animation playback and makes them ready for the sequencer's rendering pipeline to render them.
+ */
+void BKE_scene_eval_sequencer_sequences(struct Depsgraph *depsgraph, struct Scene *scene);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 91e23d35f0e..8d17380592e 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -32,6 +32,7 @@
struct Main;
struct Sequence;
struct bSound;
+struct Depsgraph;
typedef struct SoundWaveform {
int length;
@@ -71,10 +72,17 @@ void BKE_sound_cache(struct bSound *sound);
void BKE_sound_delete_cache(struct bSound *sound);
+void BKE_sound_reset_runtime(struct bSound *sound);
void BKE_sound_load(struct Main *main, struct bSound *sound);
+void BKE_sound_ensure_loaded(struct Main *bmain, struct bSound *sound);
void BKE_sound_free(struct bSound *sound);
+/* Is used by sequencer to temporarily load audio to access information about channels and
+ * duration. */
+void BKE_sound_load_audio(struct Main *main, struct bSound *sound);
+void BKE_sound_free_audio(struct bSound *sound);
+
void BKE_sound_copy_data(struct Main *bmain,
struct bSound *sound_dst,
const struct bSound *sound_src,
@@ -86,7 +94,9 @@ void BKE_sound_make_local(struct Main *bmain, struct bSound *sound, const bool l
AUD_Device *BKE_sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
#endif
+void BKE_sound_reset_scene_runtime(struct Scene *scene);
void BKE_sound_create_scene(struct Scene *scene);
+void BKE_sound_ensure_scene(struct Scene *scene);
void BKE_sound_destroy_scene(struct Scene *scene);
@@ -150,4 +160,15 @@ float BKE_sound_get_length(struct bSound *sound);
char **BKE_sound_get_device_names(void);
+typedef void (*SoundJackSyncCallback)(struct Main *bmain, int mode, float time);
+
+void BKE_sound_jack_sync_callback_set(SoundJackSyncCallback callback);
+void BKE_sound_jack_scene_update(struct Scene *scene, int mode, float time);
+
+/* Dependency graph evaluation. */
+
+struct Depsgraph;
+
+void BKE_sound_evaluate(struct Depsgraph *depsgraph, struct Main *bmain, struct bSound *sound);
+
#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d17990d4bee..9fcbf209cba 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -37,6 +37,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_sound_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
@@ -308,8 +309,7 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
flag_subdata);
}
- /* before scene copy */
- BKE_sound_create_scene(sce_dst);
+ BKE_sound_reset_scene_runtime(sce_dst);
/* Copy sequencer, this is local data! */
if (sce_src->ed) {
@@ -399,8 +399,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
sce_copy->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
}
- /* before scene copy */
- BKE_sound_create_scene(sce_copy);
+ BKE_sound_reset_scene_runtime(sce_copy);
/* grease pencil */
sce_copy->gpd = NULL;
@@ -779,7 +778,7 @@ void BKE_scene_init(Scene *sce)
srv = sce->r.views.last;
BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
- BKE_sound_create_scene(sce);
+ BKE_sound_reset_scene_runtime(sce);
/* color management */
colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER);
@@ -1507,6 +1506,30 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
}
}
+static void scene_update_sound(Depsgraph *depsgraph, Main *bmain)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ const int recalc = scene->id.recalc;
+ BKE_sound_ensure_scene(scene);
+ if (recalc & ID_RECALC_AUDIO_SEEK) {
+ BKE_sound_seek_scene(bmain, scene);
+ }
+ if (recalc & ID_RECALC_AUDIO_FPS) {
+ BKE_sound_update_fps(scene);
+ }
+ if (recalc & ID_RECALC_AUDIO_VOLUME) {
+ BKE_sound_set_scene_volume(scene, scene->audio.volume);
+ }
+ if (recalc & ID_RECALC_AUDIO_MUTE) {
+ const bool is_mute = (scene->audio.flag & AUDIO_MUTE);
+ BKE_sound_mute_scene(scene, is_mute);
+ }
+ if (recalc & ID_RECALC_AUDIO_LISTENER) {
+ BKE_sound_update_scene_listener(scene);
+ }
+ BKE_sound_update_scene(bmain, scene);
+}
+
/* TODO(sergey): This actually should become view_layer_graph or so.
* Same applies to update_for_newframe.
*
@@ -1542,10 +1565,9 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
* by depgraph or manual, no layer check here, gets correct flushed.
*/
DEG_evaluate_on_refresh(depsgraph);
- /* Update sound system animation (TODO, move to depsgraph). */
- BKE_sound_update_scene(bmain, scene);
-
- /* Notify python about depsgraph update */
+ /* Update sound system. */
+ scene_update_sound(depsgraph, bmain);
+ /* Notify python about depsgraph update. */
if (run_callbacks) {
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_DEPSGRAPH_UPDATE_POST);
}
@@ -1590,8 +1612,8 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
* by depgraph or manual, no layer check here, gets correct flushed.
*/
DEG_evaluate_on_framechange(bmain, depsgraph, ctime);
- /* Update sound system animation (TODO, move to depsgraph). */
- BKE_sound_update_scene(bmain, scene);
+ /* Update sound system animation. */
+ scene_update_sound(depsgraph, bmain);
/* Notify editors and python about recalc. */
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_FRAME_CHANGE_POST);
/* Inform editors about possible changes. */
@@ -2420,3 +2442,31 @@ void BKE_scene_cursor_from_mat4(View3DCursor *cursor, const float mat[4][4], boo
}
/** \} */
+
+/* Dependency graph evaluation. */
+
+void BKE_scene_eval_sequencer_sequences(Depsgraph *depsgraph, Scene *scene)
+{
+ DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene);
+ if (scene->ed == NULL) {
+ return;
+ }
+ BKE_sound_ensure_scene(scene);
+ Sequence *seq;
+ SEQ_BEGIN (scene->ed, seq) {
+ if (seq->sound != NULL && seq->scene_sound == NULL) {
+ seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
+ }
+ if (seq->scene_sound) {
+ BKE_sound_set_scene_sound_volume(
+ seq->scene_sound, seq->volume, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0);
+ BKE_sound_set_scene_sound_pitch(
+ seq->scene_sound, seq->pitch, (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0);
+ BKE_sound_set_scene_sound_pan(
+ seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0);
+ }
+ }
+ SEQ_END;
+ BKE_sequencer_update_muting(scene->ed);
+ BKE_sequencer_update_sound_bounds_all(scene);
+}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index ec8a2520461..171635cc6b5 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -808,10 +808,7 @@ void BKE_sequence_calc_disp(Scene *scene, Sequence *seq)
seq->handsize = (float)((seq->enddisp - seq->startdisp) / 25);
}
- if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
- BKE_sequencer_update_sound_bounds(scene, seq);
- }
- else if (seq->type == SEQ_TYPE_META) {
+ if (seq->type == SEQ_TYPE_META) {
seq_update_sound_bounds_recursive(scene, seq);
}
}
@@ -5505,17 +5502,18 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
Strip *strip;
StripElem *se;
- AUD_SoundInfo info;
-
sound = BKE_sound_new_file(bmain, seq_load->path); /* handles relative paths */
+ /* Load the original sound, so we can access number of channels and length information.
+ * We free the sound handle on the original bSound datablock before existing this function, it is
+ * to be allocated on an evaluated version after this. */
+ BKE_sound_load_audio(bmain, sound);
+ AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
if (sound->playback_handle == NULL) {
BKE_id_free(bmain, sound);
return NULL;
}
- info = AUD_getInfo(sound->playback_handle);
-
if (info.specs.channels == AUD_CHANNELS_INVALID) {
BKE_id_free(bmain, sound);
return NULL;
@@ -5537,8 +5535,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
- seq->scene_sound = BKE_sound_add_scene_sound(
- scene, seq, seq_load->start_frame, seq_load->start_frame + seq->len, 0);
+ seq->scene_sound = NULL;
BKE_sequence_calc_disp(scene, seq);
@@ -5547,6 +5544,11 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
seq_load_apply(bmain, scene, seq, seq_load);
+ BKE_sound_free_audio(sound);
+
+ /* TODO(sergey): Shall we tag here or in the oeprator? */
+ DEG_relations_tag_update(bmain);
+
return seq;
}
#else // WITH_AUDASPACE
@@ -5755,10 +5757,7 @@ static Sequence *seq_dupli(const Scene *scene_src,
}
else if (seq->type == SEQ_TYPE_SOUND_RAM) {
seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
- if (seq->scene_sound) {
- seqn->scene_sound = BKE_sound_add_scene_sound_defaults(scene_dst, seqn);
- }
-
+ seqn->scene_sound = NULL;
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)seqn->sound);
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 0cd51766078..13aedf60cd0 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -38,6 +38,7 @@
#include "DNA_screen_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
+#include "DNA_windowmanager_types.h"
#ifdef WITH_AUDASPACE
# include <AUD_Sound.h>
@@ -55,12 +56,36 @@
#include "BKE_sequencer.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph.h"
+
#ifdef WITH_AUDASPACE
/* evil globals ;-) */
static int sound_cfra;
static char **audio_device_names = NULL;
#endif
+BLI_INLINE void sound_verify_evaluated_id(ID *id)
+{
+ UNUSED_VARS_NDEBUG(id);
+ /* This is a bit tricky and not quite reliable, but good enough check.
+ *
+ * We don't want audio system handles to be allocated on amn original datablocks, and only want
+ * them to be allocated on a datablocks which are result of dependency graph evaluation.
+ *
+ * Datablocks which are covered by a copy-on-write system of dependency graph will have
+ * LIB_TAG_COPIED_ON_WRITE tag set on them. But if some of datablocks during its evaluation
+ * decides to re-allocate it's nested one (for example, object evaluation could re-allocate mesh
+ * when evaluating modifier stack). Such datablocks will have LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT
+ * tag set on them.
+ *
+ * Additionally, we also allow datablocks outside of main database. Those can not be "original"
+ * and could be used as a temporary evaluated result during operations like baking.
+ *
+ * NOTE: We conder ID evaluated if ANY of those flags is set. We do NOT require ALL of them. */
+ BLI_assert(id->tag &
+ (LIB_TAG_COPIED_ON_WRITE | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_NO_MAIN));
+}
+
bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
{
bSound *sound;
@@ -77,7 +102,10 @@ bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
BLI_strncpy(sound->name, filepath, FILE_MAX);
/* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */
- BKE_sound_load(bmain, sound);
+ sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound->spinlock);
+
+ BKE_sound_reset_runtime(sound);
return sound;
}
@@ -125,6 +153,18 @@ void BKE_sound_free(bSound *sound)
sound->packedfile = NULL;
}
+ BKE_sound_free_audio(sound);
+ BKE_sound_free_waveform(sound);
+
+ if (sound->spinlock) {
+ BLI_spin_end(sound->spinlock);
+ MEM_freeN(sound->spinlock);
+ sound->spinlock = NULL;
+ }
+}
+
+void BKE_sound_free_audio(bSound *sound)
+{
#ifdef WITH_AUDASPACE
if (sound->handle) {
AUD_Sound_free(sound->handle);
@@ -136,15 +176,9 @@ void BKE_sound_free(bSound *sound)
AUD_Sound_free(sound->cache);
sound->cache = NULL;
}
-
- BKE_sound_free_waveform(sound);
-
+#else
+ UNUSED_VARS(sound);
#endif /* WITH_AUDASPACE */
- if (sound->spinlock) {
- BLI_spin_end(sound->spinlock);
- MEM_freeN(sound->spinlock);
- sound->spinlock = NULL;
- }
}
/**
@@ -157,7 +191,7 @@ void BKE_sound_free(bSound *sound)
*
* \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
-void BKE_sound_copy_data(Main *bmain,
+void BKE_sound_copy_data(Main *UNUSED(bmain),
bSound *sound_dst,
const bSound *UNUSED(sound_src),
const int UNUSED(flag))
@@ -166,8 +200,8 @@ void BKE_sound_copy_data(Main *bmain,
sound_dst->cache = NULL;
sound_dst->waveform = NULL;
sound_dst->playback_handle = NULL;
- sound_dst->spinlock =
- NULL; /* Think this is OK? Otherwise, easy to create new spinlock here... */
+ sound_dst->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound_dst->spinlock);
/* Just to be sure, should not have any value actually after reading time. */
sound_dst->ipo = NULL;
@@ -177,8 +211,7 @@ void BKE_sound_copy_data(Main *bmain,
sound_dst->packedfile = dupPackedFile(sound_dst->packedfile);
}
- /* Initialize whole runtime (audaspace) stuff. */
- BKE_sound_load(bmain, sound_dst);
+ BKE_sound_reset_runtime(sound_dst);
}
void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
@@ -191,31 +224,15 @@ void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
static const char *force_device = NULL;
# ifdef WITH_JACK
+static SoundJackSyncCallback sound_jack_sync_callback = NULL;
+
static void sound_sync_callback(void *data, int mode, float time)
{
- // Ugly: Blender doesn't like it when the animation is played back during rendering
- if (G.is_rendering) {
+ if (sound_jack_sync_callback == NULL) {
return;
}
-
Main *bmain = (Main *)data;
- Scene *scene;
-
- scene = bmain->scenes.first;
- while (scene) {
- if (scene->audio.flag & AUDIO_SYNC) {
- if (mode) {
- BKE_sound_play_scene(scene);
- }
- else {
- BKE_sound_stop_scene(scene);
- }
- if (scene->playback_handle) {
- AUD_Handle_setPosition(scene->playback_handle, time);
- }
- }
- scene = scene->id.next;
- }
+ sound_jack_sync_callback(bmain, mode, time);
}
# endif
@@ -298,7 +315,7 @@ void BKE_sound_init_main(Main *bmain)
AUD_setSynchronizerCallback(sound_sync_callback, bmain);
}
# else
- (void)bmain; /* unused */
+ UNUSED_VARS(bmain);
# endif
}
@@ -367,6 +384,8 @@ bSound *BKE_sound_new_limiter(Main *bmain, bSound *source, float start, float en
void BKE_sound_cache(bSound *sound)
{
+ sound_verify_evaluated_id(&sound->id);
+
sound->flags |= SOUND_FLAGS_CACHING;
if (sound->cache) {
AUD_Sound_free(sound->cache);
@@ -393,44 +412,50 @@ void BKE_sound_delete_cache(bSound *sound)
void BKE_sound_load(Main *bmain, bSound *sound)
{
- if (sound) {
- if (sound->cache) {
- AUD_Sound_free(sound->cache);
- sound->cache = NULL;
- }
+ sound_verify_evaluated_id(&sound->id);
+ BKE_sound_load_audio(bmain, sound);
+}
- if (sound->handle) {
- AUD_Sound_free(sound->handle);
- sound->handle = NULL;
- sound->playback_handle = NULL;
- }
+void BKE_sound_load_audio(Main *bmain, bSound *sound)
+{
+
+ if (sound->cache) {
+ AUD_Sound_free(sound->cache);
+ sound->cache = NULL;
+ }
+
+ if (sound->handle) {
+ AUD_Sound_free(sound->handle);
+ sound->handle = NULL;
+ sound->playback_handle = NULL;
+ }
- BKE_sound_free_waveform(sound);
+ BKE_sound_free_waveform(sound);
/* XXX unused currently */
# if 0
switch (sound->type) {
case SOUND_TYPE_FILE:
# endif
- {
- char fullpath[FILE_MAX];
+ {
+ char fullpath[FILE_MAX];
- /* load sound */
- PackedFile *pf = sound->packedfile;
+ /* load sound */
+ PackedFile *pf = sound->packedfile;
- /* don't modify soundact->sound->name, only change a copy */
- BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
- BLI_path_abs(fullpath, ID_BLEND_PATH(bmain, &sound->id));
+ /* don't modify soundact->sound->name, only change a copy */
+ BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
+ BLI_path_abs(fullpath, ID_BLEND_PATH(bmain, &sound->id));
- /* but we need a packed file then */
- if (pf) {
- sound->handle = AUD_Sound_bufferFile((unsigned char *)pf->data, pf->size);
- }
- else {
- /* or else load it from disk */
- sound->handle = AUD_Sound_file(fullpath);
- }
+ /* but we need a packed file then */
+ if (pf) {
+ sound->handle = AUD_Sound_bufferFile((unsigned char *)pf->data, pf->size);
}
+ else {
+ /* or else load it from disk */
+ sound->handle = AUD_Sound_file(fullpath);
+ }
+ }
/* XXX unused currently */
# if 0
break;
@@ -447,34 +472,34 @@ void BKE_sound_load(Main *bmain, bSound *sound)
break;
}
# endif
- if (sound->flags & SOUND_FLAGS_MONO) {
- void *handle = AUD_Sound_rechannel(sound->handle, AUD_CHANNELS_MONO);
- AUD_Sound_free(sound->handle);
- sound->handle = handle;
- }
-
- if (sound->flags & SOUND_FLAGS_CACHING) {
- sound->cache = AUD_Sound_cache(sound->handle);
- }
+ if (sound->flags & SOUND_FLAGS_MONO) {
+ void *handle = AUD_Sound_rechannel(sound->handle, AUD_CHANNELS_MONO);
+ AUD_Sound_free(sound->handle);
+ sound->handle = handle;
+ }
- if (sound->cache) {
- sound->playback_handle = sound->cache;
- }
- else {
- sound->playback_handle = sound->handle;
- }
+ if (sound->flags & SOUND_FLAGS_CACHING) {
+ sound->cache = AUD_Sound_cache(sound->handle);
+ }
- BKE_sound_update_sequencer(bmain, sound);
+ if (sound->cache) {
+ sound->playback_handle = sound->cache;
+ }
+ else {
+ sound->playback_handle = sound->handle;
}
}
AUD_Device *BKE_sound_mixdown(Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
{
+ sound_verify_evaluated_id(&scene->id);
return AUD_openMixdownDevice(specs, scene->sound_scene, volume, start / FPS);
}
void BKE_sound_create_scene(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
/* should be done in version patch, but this gets called before */
if (scene->r.frs_sec_base == 0) {
scene->r.frs_sec_base = 1;
@@ -507,16 +532,21 @@ void BKE_sound_destroy_scene(Scene *scene)
void BKE_sound_reset_scene_specs(Scene *scene)
{
- AUD_Specs specs;
+ sound_verify_evaluated_id(&scene->id);
+
+ if (scene->sound_scene) {
+ AUD_Specs specs;
- specs.channels = AUD_Device_getChannels(sound_device);
- specs.rate = AUD_Device_getRate(sound_device);
+ specs.channels = AUD_Device_getChannels(sound_device);
+ specs.rate = AUD_Device_getRate(sound_device);
- AUD_Sequence_setSpecs(scene->sound_scene, specs);
+ AUD_Sequence_setSpecs(scene->sound_scene, specs);
+ }
}
void BKE_sound_mute_scene(Scene *scene, int muted)
{
+ sound_verify_evaluated_id(&scene->id);
if (scene->sound_scene) {
AUD_Sequence_setMuted(scene->sound_scene, muted);
}
@@ -524,6 +554,8 @@ void BKE_sound_mute_scene(Scene *scene, int muted)
void BKE_sound_update_fps(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
if (scene->sound_scene) {
AUD_Sequence_setFPS(scene->sound_scene, FPS);
}
@@ -533,6 +565,8 @@ void BKE_sound_update_fps(Scene *scene)
void BKE_sound_update_scene_listener(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
AUD_Sequence_setSpeedOfSound(scene->sound_scene, scene->audio.speed_of_sound);
AUD_Sequence_setDopplerFactor(scene->sound_scene, scene->audio.doppler_factor);
AUD_Sequence_setDistanceModel(scene->sound_scene, scene->audio.distance_model);
@@ -541,6 +575,7 @@ void BKE_sound_update_scene_listener(Scene *scene)
void *BKE_sound_scene_add_scene_sound(
Scene *scene, Sequence *sequence, int startframe, int endframe, int frameskip)
{
+ sound_verify_evaluated_id(&scene->id);
if (sequence->scene && scene != sequence->scene) {
const double fps = FPS;
return AUD_Sequence_add(scene->sound_scene,
@@ -564,6 +599,7 @@ void *BKE_sound_scene_add_scene_sound_defaults(Scene *scene, Sequence *sequence)
void *BKE_sound_add_scene_sound(
Scene *scene, Sequence *sequence, int startframe, int endframe, int frameskip)
{
+ sound_verify_evaluated_id(&scene->id);
/* Happens when sequence's sound datablock was removed. */
if (sequence->sound == NULL) {
return NULL;
@@ -603,12 +639,14 @@ void BKE_sound_mute_scene_sound(void *handle, char mute)
void BKE_sound_move_scene_sound(
Scene *scene, void *handle, int startframe, int endframe, int frameskip)
{
+ sound_verify_evaluated_id(&scene->id);
const double fps = FPS;
AUD_SequenceEntry_move(handle, startframe / fps, endframe / fps, frameskip / fps);
}
void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence)
{
+ sound_verify_evaluated_id(&scene->id);
if (sequence->scene_sound) {
BKE_sound_move_scene_sound(scene,
sequence->scene_sound,
@@ -630,6 +668,7 @@ void BKE_sound_set_cfra(int cfra)
void BKE_sound_set_scene_volume(Scene *scene, float volume)
{
+ sound_verify_evaluated_id(&scene->id);
AUD_Sequence_setAnimationData(scene->sound_scene,
AUD_AP_VOLUME,
CFRA,
@@ -649,12 +688,13 @@ void BKE_sound_set_scene_sound_pitch(void *handle, float pitch, char animated)
void BKE_sound_set_scene_sound_pan(void *handle, float pan, char animated)
{
- printf("%s\n", __func__);
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PANNING, sound_cfra, &pan, animated);
}
void BKE_sound_update_sequencer(Main *main, bSound *sound)
{
+ BLI_assert(!"is not supposed to be used, is weird function.");
+
Scene *scene;
for (scene = main->scenes.first; scene; scene = scene->id.next) {
@@ -664,6 +704,8 @@ void BKE_sound_update_sequencer(Main *main, bSound *sound)
static void sound_start_play_scene(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
if (scene->playback_handle) {
AUD_Handle_stop(scene->playback_handle);
}
@@ -677,6 +719,8 @@ static void sound_start_play_scene(Scene *scene)
void BKE_sound_play_scene(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
AUD_Status status;
const float cur_time = (float)((double)CFRA / FPS);
@@ -719,6 +763,8 @@ void BKE_sound_stop_scene(Scene *scene)
void BKE_sound_seek_scene(Main *bmain, Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
AUD_Status status;
bScreen *screen;
int animation_playing;
@@ -783,6 +829,8 @@ void BKE_sound_seek_scene(Main *bmain, Scene *scene)
float BKE_sound_sync_scene(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
// Ugly: Blender doesn't like it when the animation is played back during rendering
if (G.is_rendering) {
return NAN_FLT;
@@ -801,6 +849,8 @@ float BKE_sound_sync_scene(Scene *scene)
int BKE_sound_scene_playing(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
// Ugly: Blender doesn't like it when the animation is played back during rendering
if (G.is_rendering) {
return -1;
@@ -836,6 +886,9 @@ void BKE_sound_free_waveform(bSound *sound)
sound->tags &= ~SOUND_TAGS_WAVEFORM_NO_RELOAD;
}
+/* TODO(sergey): Consider mamakinging this function fully autonomous, as in, not require having
+ * an existing playback handle. That would make it easy to read waveforms, which doesn't seem to
+ * be affected by evaluated scene (waveworm comes from file). */
void BKE_sound_read_waveform(bSound *sound, short *stop)
{
AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
@@ -884,11 +937,14 @@ static void sound_update_base(Scene *scene, Base *base, void *new_set)
Speaker *speaker;
float quat[4];
- if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- return;
- }
+ sound_verify_evaluated_id(&scene->id);
+ sound_verify_evaluated_id(&ob->id);
- ob->id.tag &= ~LIB_TAG_DOIT;
+ // TODO(sergey): Bring the test back, or make it a part of dependency graph update.
+ // if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
+ // return;
+ // }
+ // ob->id.tag &= ~LIB_TAG_DOIT;
if ((ob->type != OB_SPEAKER) || !ob->adt) {
return;
@@ -951,6 +1007,8 @@ static void sound_update_base(Scene *scene, Base *base, void *new_set)
void BKE_sound_update_scene(Main *bmain, Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
Base *base;
Scene *sce_it;
@@ -960,7 +1018,8 @@ void BKE_sound_update_scene(Main *bmain, Scene *scene)
/* cheap test to skip looping over all objects (no speakers is a common case) */
if (!BLI_listbase_is_empty(&bmain->speakers)) {
- BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
+ // TODO(sergey): Bring the test back, or make it a part of dependency graph update.
+ // BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
for (ViewLayer *view_layer = scene->view_layers.first; view_layer;
view_layer = view_layer->next) {
@@ -997,6 +1056,7 @@ void *BKE_sound_get_factory(void *sound)
/* stupid wrapper because AUD_C-API.h includes Python.h which makesrna doesn't like */
float BKE_sound_get_length(bSound *sound)
{
+ sound_verify_evaluated_id(&sound->id);
AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
return info.length;
@@ -1159,4 +1219,81 @@ char **BKE_sound_get_device_names(void)
return names;
}
+void BKE_sound_free_waveform(bSound *UNUSED(sound))
+{
+}
+
+void BKE_sound_load_audio(Main *UNUSED(bmain), bSound *UNUSED(sound))
+{
+}
+
#endif /* WITH_AUDASPACE */
+
+void BKE_sound_reset_scene_runtime(Scene *scene)
+{
+ scene->sound_scene = NULL;
+ scene->playback_handle = NULL;
+ scene->sound_scrub_handle = NULL;
+ scene->speaker_handles = NULL;
+}
+
+void BKE_sound_ensure_scene(struct Scene *scene)
+{
+ if (scene->sound_scene != NULL) {
+ return;
+ }
+ BKE_sound_create_scene(scene);
+}
+
+void BKE_sound_reset_runtime(bSound *sound)
+{
+ sound->cache = NULL;
+ sound->playback_handle = NULL;
+}
+
+void BKE_sound_ensure_loaded(Main *bmain, bSound *sound)
+{
+ if (sound->cache != NULL) {
+ return;
+ }
+ BKE_sound_load(bmain, sound);
+}
+
+void BKE_sound_jack_sync_callback_set(SoundJackSyncCallback callback)
+{
+#if defined(WITH_AUDASPACE) && defined(WITH_JACK)
+ sound_jack_sync_callback = callback;
+#else
+ UNUSED_VARS(callback);
+#endif
+}
+
+void BKE_sound_jack_scene_update(Scene *scene, int mode, float time)
+{
+ sound_verify_evaluated_id(&scene->id);
+
+ /* Ugly: Blender doesn't like it when the animation is played back during rendering. */
+ if (G.is_rendering) {
+ return;
+ }
+
+ if (mode) {
+ BKE_sound_play_scene(scene);
+ }
+ else {
+ BKE_sound_stop_scene(scene);
+ }
+#ifdef WITH_AUDASPACE
+ if (scene->playback_handle != NULL) {
+ AUD_Handle_setPosition(scene->playback_handle, time);
+ }
+#else
+ UNUSED_VARS(time);
+#endif
+}
+
+void BKE_sound_evaluate(Depsgraph *depsgraph, Main *bmain, bSound *sound)
+{
+ DEG_debug_print_eval(depsgraph, __func__, sound->id.name, sound);
+ BKE_sound_ensure_loaded(bmain, sound);
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 32f0d35cd53..a4bdf02c838 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6462,9 +6462,7 @@ static void lib_link_scene(FileData *fd, Main *main)
seq->scene_sound = NULL;
if (seq->scene) {
seq->scene = newlibadr(fd, sce->id.lib, seq->scene);
- if (seq->scene) {
- seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(sce, seq);
- }
+ seq->scene_sound = NULL;
}
if (seq->clip) {
seq->clip = newlibadr_us(fd, sce->id.lib, seq->clip);
@@ -6485,7 +6483,7 @@ static void lib_link_scene(FileData *fd, Main *main)
}
if (seq->sound) {
id_us_plus_no_lib((ID *)seq->sound);
- seq->scene_sound = BKE_sound_add_scene_sound_defaults(sce, seq);
+ seq->scene_sound = NULL;
}
}
if (seq->type == SEQ_TYPE_TEXT) {
@@ -6504,9 +6502,6 @@ static void lib_link_scene(FileData *fd, Main *main)
}
}
- BKE_sequencer_update_muting(sce->ed);
- BKE_sequencer_update_sound_bounds_all(sce);
-
/* rigidbody world relies on it's linked collections */
if (sce->rigidbody_world) {
RigidBodyWorld *rbw = sce->rigidbody_world;
@@ -6685,7 +6680,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask));
memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal));
- BKE_sound_create_scene(sce);
+ BKE_sound_reset_scene_runtime(sce);
/* set users to one by default, not in lib-link, this will increase it for compo nodes */
id_us_ensure_real(&sce->id);
@@ -8395,10 +8390,9 @@ static void direct_link_sound(FileData *fd, bSound *sound)
sound->waveform = NULL;
}
- if (sound->spinlock) {
- sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
- BLI_spin_init(sound->spinlock);
- }
+ sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound->spinlock);
+
/* clear waveform loading flag */
sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
@@ -8415,7 +8409,7 @@ static void lib_link_sound(FileData *fd, Main *main)
sound->ipo = newlibadr_us(
fd, sound->id.lib, sound->ipo); // XXX deprecated - old animation system
- BKE_sound_load(main, sound);
+ BKE_sound_reset_runtime(sound);
sound->id.tag &= ~LIB_TAG_NEED_LINK;
}
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 48a62a69f30..cc6c5e7282a 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -85,6 +85,16 @@ void DEG_get_customdata_mask_for_object(const struct Depsgraph *graph,
* one. Assert will happen if it's not. */
struct Scene *DEG_get_evaluated_scene(const struct Depsgraph *graph);
+/* Similar to DEG_get_evaluated_scene(), but allows to access non-fully evaluated pointer without
+ * causing asserts or crashes. Works the following way:
+ * - If the scene was never evaluated NULL returned.
+ * - Otherwise the last known state of the scene is returned.
+ *
+ * Use in exceptional case if it's absolutely must to.
+ *
+ * Allows to pass depsgraph == NULL, wil lreturn NULL in that case. */
+struct Scene *DEG_get_evaluated_scene_if_exists(const struct Depsgraph *graph);
+
/* Get view layer at its evaluated state.
* This is a shortcut for accessing active view layer from evaluated scene. */
struct ViewLayer *DEG_get_evaluated_view_layer(const struct Depsgraph *graph);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 93e5dd14ae0..9bdc815518d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -58,6 +58,7 @@ extern "C" {
#include "DNA_lightprobe_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
#include "DNA_texture_types.h"
@@ -89,6 +90,8 @@ extern "C" {
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
+#include "BKE_scene.h"
+#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
@@ -1564,12 +1567,42 @@ void DepsgraphNodeBuilder::build_sound(bSound *sound)
if (built_map_.checkIsBuiltAndTag(sound)) {
return;
}
- /* Placeholder so we can add relations and tag ID node for update. */
- add_operation_node(&sound->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
+ add_id_node(&sound->id);
+ bSound *sound_cow = get_cow_datablock(sound);
+ add_operation_node(&sound->id,
+ NodeType::AUDIO,
+ OperationCode::SOUND_EVAL,
+ function_bind(BKE_sound_evaluate, _1, bmain_, sound_cow));
build_animdata(&sound->id);
build_parameters(&sound->id);
}
+void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
+{
+ if (scene->ed == NULL) {
+ return;
+ }
+ Scene *scene_cow = get_cow_datablock(scene_);
+ add_operation_node(&scene->id,
+ NodeType::SEQUENCER,
+ OperationCode::SEQUENCES_EVAL,
+ function_bind(BKE_scene_eval_sequencer_sequences, _1, scene_cow));
+ /* Make sure data for sequences is in the graph. */
+ Sequence *seq;
+ SEQ_BEGIN (scene->ed, seq) {
+ if (seq->sound != NULL) {
+ build_sound(seq->sound);
+ }
+ /* TODO(sergey): Movie clip, scene, camera, mask. */
+ }
+ SEQ_END;
+}
+
+void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)
+{
+ add_operation_node(&scene->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
+}
+
/* **** ID traversal callbacks functions **** */
void DepsgraphNodeBuilder::modifier_walk(void *user_data,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index c3a04a9ad88..896854870de 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -212,6 +212,8 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
void build_lightprobe(LightProbe *probe);
void build_speaker(Speaker *speaker);
void build_sound(bSound *sound);
+ void build_scene_sequencer(Scene *scene);
+ void build_scene_audio(Scene *scene);
/* Per-ID information about what was already in the dependency graph.
* Allows to re-use certain values, to speed up following evaluation. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
index 64f841d56fc..ef73de517e8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
@@ -31,13 +31,19 @@ void DepsgraphNodeBuilder::build_scene_render(Scene *scene)
{
scene_ = scene;
const bool build_compositor = (scene->r.scemode & R_DOCOMP);
+ const bool build_sequencer = (scene->r.scemode & R_DOSEQ);
IDNode *id_node = add_id_node(&scene->id);
id_node->linked_state = DEG_ID_LINKED_DIRECTLY;
add_time_source();
+ build_animdata(&scene->id);
build_scene_parameters(scene);
+ build_scene_audio(scene);
if (build_compositor) {
build_scene_compositor(scene);
}
+ if (build_sequencer) {
+ build_scene_sequencer(scene);
+ }
}
void DepsgraphNodeBuilder::build_scene_parameters(Scene *scene)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 4e3fdfc6c19..2f6b8c0ba6b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -146,6 +146,11 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
build_collection(NULL, fls->group);
}
}
+ /* Sequencer. */
+ if (linked_state == DEG_ID_LINKED_DIRECTLY) {
+ build_scene_audio(scene);
+ build_scene_sequencer(scene);
+ }
/* Collections. */
add_operation_node(
&scene->id,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 54d5223497e..a1f8c59f936 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -58,6 +58,7 @@ extern "C" {
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
#include "DNA_texture_types.h"
@@ -84,6 +85,7 @@ extern "C" {
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
+#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_shrinkwrap.h"
#include "BKE_sound.h"
@@ -2324,6 +2326,35 @@ void DepsgraphRelationBuilder::build_sound(bSound *sound)
build_parameters(&sound->id);
}
+void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
+{
+ if (scene->ed == NULL) {
+ return;
+ }
+ /* Make sure dependencies from sequences data goes to the sequencer evaluation. */
+ ComponentKey sequencer_key(&scene->id, NodeType::SEQUENCER);
+ Sequence *seq;
+ bool has_audio_strips = false;
+ SEQ_BEGIN (scene->ed, seq) {
+ if (seq->sound != NULL) {
+ build_sound(seq->sound);
+ ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO);
+ add_relation(sound_key, sequencer_key, "Sound -> Sequencer");
+ has_audio_strips = true;
+ }
+ /* TODO(sergey): Movie clip, scene, camera, mask. */
+ }
+ SEQ_END;
+ if (has_audio_strips) {
+ ComponentKey scene_audio_key(&scene->id, NodeType::AUDIO);
+ add_relation(sequencer_key, scene_audio_key, "Sequencer -> Audio");
+ }
+}
+
+void DepsgraphRelationBuilder::build_scene_audio(Scene * /*scene*/)
+{
+}
+
void DepsgraphRelationBuilder::build_copy_on_write_relations()
{
for (IDNode *id_node : graph_->id_nodes) {
@@ -2387,6 +2418,10 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
(id_type == ID_CF && comp_node->type == NodeType::CACHE)) {
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
}
+ /* TODO(sergey): Needs better solution for this. */
+ if (id_type == ID_SO) {
+ rel_flag &= ~RELATION_FLAG_NO_FLUSH;
+ }
/* Notes on exceptions:
* - Parameters component is where drivers are living. Changing any
* of the (custom) properties in the original datablock (even the
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 7d302092119..55295c8b075 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -41,6 +41,7 @@
#include "intern/builder/deg_builder_rna.h"
#include "intern/depsgraph.h"
#include "intern/node/deg_node.h"
+#include "intern/node/deg_node_id.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_operation.h"
@@ -200,7 +201,9 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
void build_scene_compositor(Scene *scene);
void build_layer_collections(ListBase *lb);
- void build_view_layer(Scene *scene, ViewLayer *view_layer);
+ void build_view_layer(Scene *scene,
+ ViewLayer *view_layer,
+ eDepsNode_LinkedState_Type linked_state);
void build_collection(LayerCollection *from_layer_collection,
Object *object,
Collection *collection);
@@ -270,6 +273,8 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
void build_lightprobe(LightProbe *probe);
void build_speaker(Speaker *speaker);
void build_sound(bSound *sound);
+ void build_scene_sequencer(Scene *scene);
+ void build_scene_audio(Scene *scene);
void build_nested_datablock(ID *owner, ID *id);
void build_nested_nodetree(ID *owner, bNodeTree *ntree);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
index 26bb1bd3d2a..46e8b8e7acc 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
@@ -31,10 +31,16 @@ void DepsgraphRelationBuilder::build_scene_render(Scene *scene)
{
scene_ = scene;
const bool build_compositor = (scene->r.scemode & R_DOCOMP);
+ const bool build_sequencer = (scene->r.scemode & R_DOSEQ);
build_scene_parameters(scene);
+ build_animdata(&scene->id);
+ build_scene_audio(scene);
if (build_compositor) {
build_scene_compositor(scene);
}
+ if (build_sequencer) {
+ build_scene_sequencer(scene);
+ }
}
void DepsgraphRelationBuilder::build_scene_parameters(Scene *scene)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index b832473bde9..4c55e4a137a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -75,7 +75,9 @@ void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
}
}
-void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_layer)
+void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
+ ViewLayer *view_layer,
+ eDepsNode_LinkedState_Type linked_state)
{
/* Setup currently building context. */
scene_ = scene;
@@ -132,10 +134,15 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
&scene->id, NodeType::LAYER_COLLECTIONS, OperationCode::VIEW_LAYER_EVAL);
OperationKey scene_eval_key(&scene->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL);
add_relation(scene_view_layer_key, scene_eval_key, "View Layer -> Scene Eval");
+ /* Sequencer. */
+ if (linked_state == DEG_ID_LINKED_DIRECTLY) {
+ build_scene_audio(scene);
+ build_scene_sequencer(scene);
+ }
/* Build all set scenes. */
if (scene->set != NULL) {
ViewLayer *set_view_layer = BKE_view_layer_default_render(scene->set);
- build_view_layer(scene->set, set_view_layer);
+ build_view_layer(scene->set, set_view_layer, DEG_ID_LINKED_VIA_SET);
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 403c9cfc778..b7efdc0fa3f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -329,10 +329,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
return node_identifier;
}
else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
- const Sequence *seq = static_cast<Sequence *>(ptr->data);
/* Sequencer strip */
node_identifier.type = NodeType::SEQUENCER;
- node_identifier.component_name = seq->name;
return node_identifier;
}
else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index cf1ebccc6c6..bfb0a2aade4 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -272,7 +272,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
/* Hook up relationships between operations - to determine evaluation order. */
DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
relation_builder.begin_build();
- relation_builder.build_view_layer(scene, view_layer);
+ relation_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY);
relation_builder.build_copy_on_write_relations();
/* Finalize building. */
graph_build_finalize_common(deg_graph, bmain);
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 0345f294860..865da20e6fd 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -160,6 +160,19 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph)
return scene_cow;
}
+Scene *DEG_get_evaluated_scene_if_exists(const Depsgraph *graph)
+{
+ if (graph == NULL) {
+ return NULL;
+ }
+ const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
+ Scene *scene_cow = deg_graph->scene_cow;
+ if (scene_cow == NULL || !DEG::deg_copy_on_write_is_expanded(&scene_cow->id)) {
+ return NULL;
+ }
+ return scene_cow;
+}
+
ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph)
{
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index c2cc15460d1..9f48dd2b47e 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -215,6 +215,16 @@ void depsgraph_tag_to_component_opcode(const ID *id,
/* There is no such node in depsgraph, this tag is to be handled
* separately. */
break;
+ case ID_RECALC_SEQUENCER_STRIPS:
+ *component_type = NodeType::SEQUENCER;
+ break;
+ case ID_RECALC_AUDIO_SEEK:
+ case ID_RECALC_AUDIO_FPS:
+ case ID_RECALC_AUDIO_VOLUME:
+ case ID_RECALC_AUDIO_MUTE:
+ case ID_RECALC_AUDIO_LISTENER:
+ *component_type = NodeType::AUDIO;
+ break;
case ID_RECALC_ALL:
case ID_RECALC_PSYS_ALL:
BLI_assert(!"Should not happen");
@@ -633,6 +643,18 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
return "POINT_CACHE";
case ID_RECALC_EDITORS:
return "EDITORS";
+ case ID_RECALC_SEQUENCER_STRIPS:
+ return "SEQUENCER_STRIPS";
+ case ID_RECALC_AUDIO_SEEK:
+ return "AUDIO_SEEK";
+ case ID_RECALC_AUDIO_FPS:
+ return "AUDIO_FPS";
+ case ID_RECALC_AUDIO_VOLUME:
+ return "AUDIO_VOLUME";
+ case ID_RECALC_AUDIO_MUTE:
+ return "AUDIO_MUTE";
+ case ID_RECALC_AUDIO_LISTENER:
+ return "AUDIO_LISTENER";
case ID_RECALC_ALL:
return "ALL";
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 4bc05bc9185..ef2862ab387 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -59,6 +59,8 @@ extern "C" {
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
+#include "DNA_sound_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
@@ -84,6 +86,8 @@ extern "C" {
#include "BKE_library_query.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_sequencer.h"
+#include "BKE_sound.h"
}
#include "intern/depsgraph.h"
@@ -467,6 +471,25 @@ void scene_setup_view_layers_after_remap(const Depsgraph *depsgraph,
* Still not an excuse to have those. */
}
+void update_sequence_orig_pointers(const ListBase *sequences_orig, ListBase *sequences_cow)
+{
+ Sequence *sequence_orig = reinterpret_cast<Sequence *>(sequences_orig->first);
+ Sequence *sequence_cow = reinterpret_cast<Sequence *>(sequences_cow->first);
+ while (sequence_orig != NULL) {
+ update_sequence_orig_pointers(&sequence_orig->seqbase, &sequence_cow->seqbase);
+ sequence_cow->orig_sequence = sequence_orig;
+ sequence_cow = sequence_cow->next;
+ sequence_orig = sequence_orig->next;
+ }
+}
+
+void update_scene_orig_pointers(const Scene *scene_orig, Scene *scene_cow)
+{
+ if (scene_orig->ed != NULL) {
+ update_sequence_orig_pointers(&scene_orig->ed->seqbase, &scene_cow->ed->seqbase);
+ }
+}
+
/* Check whether given ID is expanded or still a shallow copy. */
BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
{
@@ -751,6 +774,7 @@ void update_id_after_copy(const Depsgraph *depsgraph,
scene_cow->toolsettings = scene_orig->toolsettings;
scene_cow->eevee.light_cache = scene_orig->eevee.light_cache;
scene_setup_view_layers_after_remap(depsgraph, id_node, reinterpret_cast<Scene *>(id_cow));
+ update_scene_orig_pointers(scene_orig, scene_cow);
break;
}
default:
@@ -881,6 +905,205 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
namespace {
+/* Backup of sequencer strips runtime data. */
+
+/* Backup of a single strip. */
+class SequenceBackup {
+ public:
+ SequenceBackup()
+ {
+ reset();
+ }
+
+ inline void reset()
+ {
+ scene_sound = NULL;
+ }
+
+ void init_from_sequence(Sequence *sequence)
+ {
+ scene_sound = sequence->scene_sound;
+
+ sequence->scene_sound = NULL;
+ }
+
+ void restore_to_sequence(Sequence *sequence)
+ {
+ sequence->scene_sound = scene_sound;
+ reset();
+ }
+
+ inline bool isEmpty() const
+ {
+ return (scene_sound == NULL);
+ }
+
+ void *scene_sound;
+};
+
+class SequencerBackup {
+ public:
+ SequencerBackup();
+
+ void init_from_scene(Scene *scene);
+ void restore_to_scene(Scene *scene);
+
+ typedef map<Sequence *, SequenceBackup> SequencesBackupMap;
+ SequencesBackupMap sequences_backup;
+};
+
+SequencerBackup::SequencerBackup()
+{
+}
+
+void SequencerBackup::init_from_scene(Scene *scene)
+{
+ Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ SequenceBackup sequence_backup;
+ sequence_backup.init_from_sequence(sequence);
+ if (!sequence_backup.isEmpty()) {
+ sequences_backup.insert(make_pair(sequence->orig_sequence, sequence_backup));
+ }
+ }
+ SEQ_END;
+}
+
+void SequencerBackup::restore_to_scene(Scene *scene)
+{
+ Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ SequencesBackupMap::iterator it = sequences_backup.find(sequence->orig_sequence);
+ if (it == sequences_backup.end()) {
+ continue;
+ }
+ SequenceBackup &sequence_backup = it->second;
+ sequence_backup.restore_to_sequence(sequence);
+ }
+ SEQ_END;
+ /* Cleanup audio while the scene is still known. */
+ for (SequencesBackupMap::value_type &it : sequences_backup) {
+ SequenceBackup &sequence_backup = it.second;
+ if (sequence_backup.scene_sound != NULL) {
+ BKE_sound_remove_scene_sound(scene, sequence_backup.scene_sound);
+ }
+ }
+}
+
+/* Backup of scene runtime data. */
+
+class SceneBackup {
+ public:
+ SceneBackup();
+
+ void reset();
+
+ void init_from_scene(Scene *scene);
+ void restore_to_scene(Scene *scene);
+
+ /* Sound/audio related pointers of the scene itself.
+ *
+ * NOTE: Scene can not disappear after relations update, because otherwise the entire dependency
+ * graph will be gone. This means we don't need to compare original scene pointer, or worry about
+ * freeing those if they cant' be restorted: we just copy them over to a new scene. */
+ void *sound_scene;
+ void *playback_handle;
+ void *sound_scrub_handle;
+ void *speaker_handles;
+
+ SequencerBackup sequencer_backup;
+};
+
+SceneBackup::SceneBackup()
+{
+ reset();
+}
+
+void SceneBackup::reset()
+{
+ sound_scene = NULL;
+ playback_handle = NULL;
+ sound_scrub_handle = NULL;
+ speaker_handles = NULL;
+}
+
+void SceneBackup::init_from_scene(Scene *scene)
+{
+ sound_scene = scene->sound_scene;
+ playback_handle = scene->playback_handle;
+ sound_scrub_handle = scene->sound_scrub_handle;
+ speaker_handles = scene->speaker_handles;
+
+ /* Clear pointers stored in the scene, so they are not freed when copied-on-written datablock
+ * is freed for re-allocation. */
+ scene->sound_scene = NULL;
+ scene->playback_handle = NULL;
+ scene->sound_scrub_handle = NULL;
+ scene->speaker_handles = NULL;
+
+ sequencer_backup.init_from_scene(scene);
+}
+
+void SceneBackup::restore_to_scene(Scene *scene)
+{
+ scene->sound_scene = sound_scene;
+ scene->playback_handle = playback_handle;
+ scene->sound_scrub_handle = sound_scrub_handle;
+ scene->speaker_handles = speaker_handles;
+
+ sequencer_backup.restore_to_scene(scene);
+
+ reset();
+}
+
+/* Backup of sound datablocks runtime data. */
+
+class SoundBackup {
+ public:
+ SoundBackup();
+
+ void reset();
+
+ void init_from_sound(bSound *sound);
+ void restore_to_sound(bSound *sound);
+
+ void *cache;
+ void *waveform;
+ void *playback_handle;
+};
+
+SoundBackup::SoundBackup()
+{
+ reset();
+}
+
+void SoundBackup::reset()
+{
+ cache = NULL;
+ waveform = NULL;
+ playback_handle = NULL;
+}
+
+void SoundBackup::init_from_sound(bSound *sound)
+{
+ cache = sound->cache;
+ waveform = sound->waveform;
+ playback_handle = sound->playback_handle;
+
+ sound->cache = NULL;
+ sound->waveform = NULL;
+ sound->playback_handle = NULL;
+}
+
+void SoundBackup::restore_to_sound(bSound *sound)
+{
+ sound->cache = cache;
+ sound->waveform = waveform;
+ sound->playback_handle = playback_handle;
+
+ reset();
+}
+
/* Identifier used to match modifiers to backup/restore their runtime data.
* Identification is happening using original modifier data pointer and the
* modifier type.
@@ -921,7 +1144,8 @@ typedef map<ModifierDataBackupID, void *> ModifierRuntimeDataBackup;
/* Storage for backed up pose channel runtime data. */
typedef map<bPoseChannel *, bPoseChannel_Runtime> PoseChannelRuntimeDataBackup;
-struct ObjectRuntimeBackup {
+class ObjectRuntimeBackup {
+ public:
ObjectRuntimeBackup() : base_flag(0), base_local_view_bits(0)
{
/* TODO(sergey): Use something like BKE_object_runtime_reset(). */
@@ -1099,6 +1323,8 @@ class RuntimeBackup {
/* Restore fields to the given ID. */
void restore_to_id(ID *id);
+ SceneBackup scene_backup;
+ SoundBackup sound_backup;
ObjectRuntimeBackup object_backup;
DrawDataList drawdata_backup;
DrawDataList *drawdata_ptr;
@@ -1114,6 +1340,12 @@ void RuntimeBackup::init_from_id(ID *id)
case ID_OB:
object_backup.init_from_object(reinterpret_cast<Object *>(id));
break;
+ case ID_SCE:
+ scene_backup.init_from_scene(reinterpret_cast<Scene *>(id));
+ break;
+ case ID_SO:
+ sound_backup.init_from_sound(reinterpret_cast<bSound *>(id));
+ break;
default:
break;
}
@@ -1133,6 +1365,12 @@ void RuntimeBackup::restore_to_id(ID *id)
case ID_OB:
object_backup.restore_to_object(reinterpret_cast<Object *>(id));
break;
+ case ID_SCE:
+ scene_backup.restore_to_scene(reinterpret_cast<Scene *>(id));
+ break;
+ case ID_SO:
+ sound_backup.restore_to_sound(reinterpret_cast<bSound *>(id));
+ break;
default:
break;
}
@@ -1321,9 +1559,7 @@ bool deg_copy_on_write_is_expanded(const ID *id_cow)
bool deg_copy_on_write_is_needed(const ID *id_orig)
{
const ID_Type id_type = GS(id_orig->name);
- /* TODO(sergey): Make Sound copyable. It is here only because the code for dependency graph is
- * being work in progress. */
- return !ELEM(id_type, ID_IM, ID_SO);
+ return !ELEM(id_type, ID_IM);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 62a61675bcc..09a761d282f 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -185,6 +185,9 @@ const char *operationCodeAsString(OperationCode opcode)
/* Generic datablock. */
case OperationCode::GENERIC_DATABLOCK_UPDATE:
return "GENERIC_DATABLOCK_UPDATE";
+ /* Sequencer. */
+ case OperationCode::SEQUENCES_EVAL:
+ return "SEQUENCES_EVAL";
/* instancing/duplication. */
case OperationCode::DUPLI:
return "DUPLI";
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index ab6242a6196..8fc565cfa77 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -185,12 +185,16 @@ enum class OperationCode {
/* Images. -------------------------------------------------------------- */
IMAGE_ANIMATION,
- /* Synchronization clips. ----------------------------------------------- */
+ /* Synchronization. ----------------------------------------------------- */
SYNCHRONIZE_TO_ORIGINAL,
/* Generic datablock ---------------------------------------------------- */
GENERIC_DATABLOCK_UPDATE,
+ /* Sequencer. ----------------------------------------------------------- */
+
+ SEQUENCES_EVAL,
+
/* Duplication/instancing system. --------------------------------------- */
DUPLI,
};
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index abec3563d0c..9e3f91bc971 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -36,7 +36,6 @@
#include "BKE_sequencer.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_sound.h"
#include "BKE_scene.h"
#include "UI_view2d.h"
@@ -52,6 +51,9 @@
#include "ED_sequencer.h"
#include "ED_util.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
#include "anim_intern.h"
/* ********************** frame change operator ***************************/
@@ -88,7 +90,6 @@ static bool change_frame_poll(bContext *C)
/* Set the new frame number */
static void change_frame_apply(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
float frame = RNA_float_get(op->ptr, "frame");
bool do_snap = RNA_boolean_get(op->ptr, "snap");
@@ -114,7 +115,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
FRAMENUMBER_MIN_CLAMP(CFRA);
/* do updates */
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 7c03ba889a7..b3cbeca7317 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -67,6 +67,7 @@
#include "WM_types.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@@ -2740,7 +2741,6 @@ static void areas_do_frame_follow(bContext *C, bool middle)
/* function to be called outside UI context, or for redo */
static int frame_offset_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
int delta;
@@ -2752,7 +2752,7 @@ static int frame_offset_exec(bContext *C, wmOperator *op)
areas_do_frame_follow(C, false);
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -2784,7 +2784,6 @@ static void SCREEN_OT_frame_offset(wmOperatorType *ot)
/* function to be called outside UI context, or for redo */
static int frame_jump_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
wmTimer *animtimer = CTX_wm_screen(C)->animtimer;
@@ -2814,7 +2813,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
areas_do_frame_follow(C, true);
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -2847,7 +2846,6 @@ static void SCREEN_OT_frame_jump(wmOperatorType *ot)
/* function to be called outside UI context, or for redo */
static int keyframe_jump_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
bDopeSheet ads = {NULL};
@@ -2930,7 +2928,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
else {
areas_do_frame_follow(C, true);
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -2963,7 +2961,6 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
/* function to be called outside UI context, or for redo */
static int marker_jump_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
TimeMarker *marker;
int closest = CFRA;
@@ -2997,7 +2994,7 @@ static int marker_jump_exec(bContext *C, wmOperator *op)
areas_do_frame_follow(C, true);
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -4206,7 +4203,8 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
if (screen->animtimer && screen->animtimer == event->customdata) {
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
wmWindowManager *wm = CTX_wm_manager(C);
@@ -4227,7 +4225,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
}
if ((scene->audio.flag & AUDIO_SYNC) && (sad->flag & ANIMPLAY_FLAG_REVERSE) == false &&
- isfinite(time = BKE_sound_sync_scene(scene))) {
+ isfinite(time = BKE_sound_sync_scene(scene_eval))) {
double newfra = (double)time * FPS;
/* give some space here to avoid jumps */
@@ -4320,7 +4318,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
}
if (sad->flag & ANIMPLAY_FLAG_JUMPED) {
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
#ifdef PROFILE_AUDIO_SYNCH
old_frame = CFRA;
#endif
@@ -4442,11 +4440,12 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
{
bScreen *screen = CTX_wm_screen(C);
Scene *scene = CTX_data_scene(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(CTX_data_depsgraph(C));
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
/* stop playback now */
ED_screen_animation_timer(C, 0, 0, 0, 0);
- BKE_sound_stop_scene(scene);
+ BKE_sound_stop_scene(scene_eval);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -4455,7 +4454,7 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
int refresh = SPACE_ACTION;
if (mode == 1) { /* XXX only play audio forwards!? */
- BKE_sound_play_scene(scene);
+ BKE_sound_play_scene(scene_eval);
}
ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode);
diff --git a/source/blender/editors/sound/CMakeLists.txt b/source/blender/editors/sound/CMakeLists.txt
index c2a88041a85..7f4b5a45aa3 100644
--- a/source/blender/editors/sound/CMakeLists.txt
+++ b/source/blender/editors/sound/CMakeLists.txt
@@ -19,6 +19,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../depsgraph
../../makesdna
../../makesrna
../../windowmanager
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 381173999c4..30ddd8c7d33 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -62,6 +62,8 @@
# include <AUD_Special.h>
#endif
+#include "DEG_depsgraph_query.h"
+
#include "ED_sound.h"
#include "ED_util.h"
@@ -88,7 +90,6 @@ static int sound_open_exec(bContext *C, wmOperator *op)
bSound *sound;
PropertyPointerRNA *pprop;
PointerRNA idptr;
- AUD_SoundInfo info;
Main *bmain = CTX_data_main(C);
RNA_string_get(op->ptr, "filepath", path);
@@ -98,29 +99,8 @@ static int sound_open_exec(bContext *C, wmOperator *op)
sound_open_init(C, op);
}
- if (sound->playback_handle == NULL) {
- if (op->customdata) {
- MEM_freeN(op->customdata);
- }
- BKE_id_free(bmain, sound);
- BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
- return OPERATOR_CANCELLED;
- }
-
- info = AUD_getInfo(sound->playback_handle);
-
- if (info.specs.channels == AUD_CHANNELS_INVALID) {
- BKE_id_free(bmain, sound);
- if (op->customdata) {
- MEM_freeN(op->customdata);
- }
- BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
- return OPERATOR_CANCELLED;
- }
-
if (RNA_boolean_get(op->ptr, "mono")) {
sound->flags |= SOUND_FLAGS_MONO;
- BKE_sound_load(bmain, sound);
}
if (RNA_boolean_get(op->ptr, "cache")) {
@@ -140,6 +120,8 @@ static int sound_open_exec(bContext *C, wmOperator *op)
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
+ DEG_relations_tag_update(bmain);
+
MEM_freeN(op->customdata);
return OPERATOR_FINISHED;
}
@@ -361,8 +343,9 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
#ifdef WITH_AUDASPACE
char path[FILE_MAX];
char filename[FILE_MAX];
- Scene *scene;
- Main *bmain;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ Main *bmain = CTX_data_main(C);
int split;
int bitrate, accuracy;
@@ -380,18 +363,20 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
container = RNA_enum_get(op->ptr, "container");
codec = RNA_enum_get(op->ptr, "codec");
split = RNA_boolean_get(op->ptr, "split_channels");
- scene = CTX_data_scene(C);
- bmain = CTX_data_main(C);
- specs.channels = scene->r.ffcodecdata.audio_channels;
- specs.rate = scene->r.ffcodecdata.audio_mixrate;
+ specs.channels = scene_eval->r.ffcodecdata.audio_channels;
+ specs.rate = scene_eval->r.ffcodecdata.audio_mixrate;
BLI_strncpy(filename, path, sizeof(filename));
BLI_path_abs(filename, BKE_main_blendfile_path(bmain));
+ const double fps = (((double)scene_eval->r.frs_sec) / (double)scene_eval->r.frs_sec_base);
+ const int start_frame = scene_eval->r.sfra;
+ const int end_frame = scene_eval->r.efra;
+
if (split) {
- result = AUD_mixdown_per_channel(scene->sound_scene,
- SFRA * specs.rate / FPS,
- (EFRA - SFRA + 1) * specs.rate / FPS,
+ result = AUD_mixdown_per_channel(scene_eval->sound_scene,
+ start_frame * specs.rate / fps,
+ (end_frame - start_frame + 1) * specs.rate / fps,
accuracy,
filename,
specs,
@@ -400,9 +385,9 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
bitrate);
}
else {
- result = AUD_mixdown(scene->sound_scene,
- SFRA * specs.rate / FPS,
- (EFRA - SFRA + 1) * specs.rate / FPS,
+ result = AUD_mixdown(scene_eval->sound_scene,
+ start_frame * specs.rate / fps,
+ (end_frame - start_frame + 1) * specs.rate / fps,
accuracy,
filename,
specs,
@@ -411,7 +396,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
bitrate);
}
- BKE_sound_reset_scene_specs(scene);
+ BKE_sound_reset_scene_specs(scene_eval);
if (result) {
BKE_report(op->reports, RPT_ERROR, result);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index ba40b8bfaae..83d8133a99e 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -52,7 +52,6 @@
#include "BKE_main.h"
#include "BKE_movieclip.h"
#include "BKE_report.h"
-#include "BKE_sound.h"
#include "BKE_tracking.h"
#include "WM_api.h"
@@ -74,6 +73,7 @@
#include "PIL_time.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "clip_intern.h" // own include
@@ -999,7 +999,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
SUBFRA = 0.0f;
/* do updates */
- BKE_sound_seek_scene(CTX_data_main(C), scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index c19b0583a5c..2de01e0b7ec 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -35,7 +35,6 @@
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
#include "BKE_report.h"
-#include "BKE_sound.h"
#include "DEG_depsgraph.h"
@@ -1356,7 +1355,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
if (CFRA != sc->user.framenr) {
CFRA = sc->user.framenr;
- BKE_sound_seek_scene(CTX_data_main(C), scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 3450ca5a431..c9dc9803105 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -33,7 +33,6 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_sound.h"
#include "UI_view2d.h"
@@ -49,6 +48,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -74,7 +75,6 @@ static bool graphview_cursor_poll(bContext *C)
/* Set the new frame number */
static void graphview_cursor_apply(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SpaceGraph *sipo = CTX_wm_space_graph(C);
/* this isn't technically "frame", but it'll do... */
@@ -105,7 +105,7 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op)
}
SUBFRA = 0.0f;
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
}
/* set the cursor value */
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 9ef646e6c71..3789b6d7a6d 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -61,7 +61,6 @@
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_screen.h"
-#include "BKE_sound.h"
#include "BKE_scene.h"
#include "DEG_depsgraph.h"
@@ -3608,7 +3607,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
SUBFRA = 0.0f;
/* do updates */
- BKE_sound_seek_scene(CTX_data_main(C), scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt
index 4668a9cef90..d57be0c85c3 100644
--- a/source/blender/editors/space_sequencer/CMakeLists.txt
+++ b/source/blender/editors/space_sequencer/CMakeLists.txt
@@ -21,6 +21,7 @@ set(INC
../../blenlib
../../blentranslation
../../gpu
+ ../../depsgraph
../../imbuf
../../makesdna
../../makesrna
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index db6cc1af31e..190c2edf30c 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -64,6 +64,8 @@
# include <AUD_Sequence.h>
#endif
+#include "DEG_depsgraph.h"
+
/* own include */
#include "sequencer_intern.h"
@@ -351,6 +353,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -433,6 +436,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -515,6 +519,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -627,8 +632,8 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
}
BKE_sequencer_sort(scene);
- BKE_sequencer_update_muting(ed);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -956,6 +961,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
MEM_freeN(op->customdata);
}
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -1105,6 +1111,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
* it was NOT called in blender 2.4x, but wont hurt */
BKE_sequencer_sort(scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index b9b310cf922..6197a7bd559 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -260,11 +260,6 @@ static void drawseqwave(View2D *v2d,
return;
}
- if (!sound->spinlock) {
- sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
- BLI_spin_init(sound->spinlock);
- }
-
BLI_spin_lock(sound->spinlock);
if (!sound->waveform) {
if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index ed7205328eb..038ab0cc7cd 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -64,6 +64,8 @@
#include "UI_view2d.h"
#include "UI_interface.h"
+#include "DEG_depsgraph.h"
+
/* own include */
#include "sequencer_intern.h"
@@ -1809,7 +1811,7 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op)
}
}
- BKE_sequencer_update_muting(ed);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -1860,7 +1862,7 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op)
}
}
- BKE_sequencer_update_muting(ed);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -2370,6 +2372,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
ms = ms->prev;
}
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -2625,7 +2628,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
MEM_freeN(ms);
}
- BKE_sequencer_update_muting(ed);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -2686,7 +2689,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
BKE_sequence_base_shuffle(ed->seqbasep, seqm, scene);
}
- BKE_sequencer_update_muting(ed);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm);
@@ -2773,7 +2776,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
}
BKE_sequencer_sort(scene);
- BKE_sequencer_update_muting(ed);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c
index 546c2a8a9f0..8a4e8c007f7 100644
--- a/source/blender/editors/space_sequencer/sequencer_preview.c
+++ b/source/blender/editors/space_sequencer/sequencer_preview.c
@@ -50,6 +50,7 @@ typedef struct PreviewJob {
typedef struct PreviewJobAudio {
struct PreviewJobAudio *next, *prev;
+ struct Main *bmain;
bSound *sound;
int lr; /* sample left or right */
int startframe;
@@ -79,7 +80,9 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p
PreviewJobAudio *preview_next;
bSound *sound = previewjb->sound;
+ BKE_sound_load_audio(previewjb->bmain, sound);
BKE_sound_read_waveform(sound, stop);
+ BKE_sound_free_audio(sound);
if (*stop || G.is_break) {
BLI_mutex_lock(pj->mutex);
@@ -153,6 +156,7 @@ void sequencer_preview_add_sound(const bContext *C, Sequence *seq)
/* attempt to lock mutex of job here */
+ audiojob->bmain = CTX_data_main(C);
audiojob->sound = seq->sound;
BLI_mutex_lock(pj->mutex);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 6a9c6856a03..0a361d0d09e 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1183,6 +1183,8 @@ static void recalcData_sequencer(TransInfo *t)
seq_prev = seq;
}
+ DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
+
flushTransSeq(t);
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 5a666653043..139cb298710 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -448,9 +448,7 @@ typedef enum ID_Type {
/* No copy-on-write for these types.
* Keep in sync with check_datablocks_copy_on_writable and deg_copy_on_write_is_needed */
-/* TODO(sergey): Make Sound copyable. It is here only because the code for dependency graph is
- * being work in progress. */
-#define ID_TYPE_IS_COW(_id_type) (!ELEM(_id_type, ID_BR, ID_LS, ID_PAL, ID_IM, ID_SO))
+#define ID_TYPE_IS_COW(_id_type) (!ELEM(_id_type, ID_BR, ID_LS, ID_PAL, ID_IM))
#ifdef GS
# undef GS
@@ -604,6 +602,16 @@ typedef enum IDRecalcFlag {
*/
ID_RECALC_COPY_ON_WRITE = (1 << 13),
+ /* Sequences in the sequencer did change.
+ * Use this tag with a scene ID which owns the sequences. */
+ ID_RECALC_SEQUENCER_STRIPS = (1 << 14),
+
+ ID_RECALC_AUDIO_SEEK = (1 << 15),
+ ID_RECALC_AUDIO_FPS = (1 << 16),
+ ID_RECALC_AUDIO_VOLUME = (1 << 17),
+ ID_RECALC_AUDIO_MUTE = (1 << 18),
+ ID_RECALC_AUDIO_LISTENER = (1 << 19),
+
/***************************************************************************
* Pseudonyms, to have more semantic meaning in the actual code without
* using too much low-level and implementation specific tags. */
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index c21fa2ba64e..5240de4aff9 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -232,6 +232,9 @@ typedef struct Sequence {
int cache_flag;
int _pad2[3];
+
+ struct Sequence *orig_sequence;
+ void *_pad3;
} Sequence;
typedef struct MetaStack {
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index f101a29ec22..0f0d057845e 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -669,7 +669,6 @@ const EnumPropertyItem rna_enum_transform_orientation_items[] = {
# include "BKE_pointcache.h"
# include "BKE_scene.h"
# include "BKE_mesh.h"
-# include "BKE_sound.h"
# include "BKE_screen.h"
# include "BKE_sequencer.h"
# include "BKE_animsys.h"
@@ -819,23 +818,17 @@ static void rna_Scene_camera_update(Main *bmain, Scene *UNUSED(scene_unused), Po
static void rna_Scene_fps_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
- BKE_sound_update_fps(scene);
- BKE_sequencer_update_sound_bounds_all(scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_FPS | ID_RECALC_SEQUENCER_STRIPS);
}
static void rna_Scene_listener_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
- BKE_sound_update_scene_listener(scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_LISTENER);
}
-static void rna_Scene_volume_set(PointerRNA *ptr, float value)
+static void rna_Scene_volume_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
- Scene *scene = (Scene *)(ptr->data);
-
- scene->audio.volume = value;
- if (scene->sound_scene) {
- BKE_sound_set_scene_volume(scene, value);
- }
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_VOLUME);
}
static const char *rna_Scene_statistics_string_get(Scene *scene,
@@ -962,10 +955,12 @@ static void rna_Scene_show_subframe_update(Main *UNUSED(bmain),
scene->r.subframe = 0.0f;
}
-static void rna_Scene_frame_update(Main *bmain, Scene *UNUSED(current_scene), PointerRNA *ptr)
+static void rna_Scene_frame_update(Main *UNUSED(bmain),
+ Scene *UNUSED(current_scene),
+ PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->id.data;
- BKE_sound_seek_scene(bmain, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
WM_main_add_notifier(NC_SCENE | ND_FRAME, scene);
}
@@ -1825,8 +1820,11 @@ static void rna_Scene_use_audio_set(PointerRNA *ptr, bool value)
else {
scene->audio.flag &= ~AUDIO_MUTE;
}
+}
- BKE_sound_mute_scene(scene, value);
+static void rna_Scene_use_audio_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+{
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_MUTE);
}
static int rna_Scene_sync_mode_get(PointerRNA *ptr)
@@ -7420,7 +7418,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Scene_use_audio_get", "rna_Scene_use_audio_set");
RNA_def_property_ui_text(
prop, "Audio Muted", "Play back of audio from Sequence Editor will be muted");
- RNA_def_property_update(prop, NC_SCENE, NULL);
+ RNA_def_property_update(prop, NC_SCENE, "rna_Scene_use_audio_update");
# if 0 /* XXX: Is this actually needed? */
prop = RNA_def_property(srna, "use_audio_sync", PROP_BOOLEAN, PROP_NONE);
@@ -7467,7 +7465,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Volume", "Audio volume");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SOUND);
RNA_def_property_update(prop, NC_SCENE, NULL);
- RNA_def_property_float_funcs(prop, NULL, "rna_Scene_volume_set", NULL);
+ RNA_def_property_update(prop, NC_SCENE, "rna_Scene_volume_update");
/* Statistics */
func = RNA_def_function(srna, "statistics", "rna_Scene_statistics_string_get");
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 29a06eeabf2..3915c989614 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -75,6 +75,8 @@ const EnumPropertyItem rna_enum_sequence_modifier_type_items[] = {
# include "WM_api.h"
+# include "DEG_depsgraph.h"
+
# include "IMB_imbuf.h"
typedef struct SequenceSearchData {
@@ -727,37 +729,9 @@ static int rna_Sequence_proxy_filepath_length(PointerRNA *ptr)
return strlen(path);
}
-static void rna_Sequence_volume_set(PointerRNA *ptr, float value)
-{
- Sequence *seq = (Sequence *)(ptr->data);
-
- seq->volume = value;
- if (seq->scene_sound) {
- BKE_sound_set_scene_sound_volume(
- seq->scene_sound, value, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0);
- }
-}
-
-static void rna_Sequence_pitch_set(PointerRNA *ptr, float value)
-{
- Sequence *seq = (Sequence *)(ptr->data);
-
- seq->pitch = value;
- if (seq->scene_sound) {
- BKE_sound_set_scene_sound_pitch(
- seq->scene_sound, value, (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0);
- }
-}
-
-static void rna_Sequence_pan_set(PointerRNA *ptr, float value)
+static void rna_Sequence_audio_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
- Sequence *seq = (Sequence *)(ptr->data);
-
- seq->pan = value;
- if (seq->scene_sound) {
- BKE_sound_set_scene_sound_pan(
- seq->scene_sound, value, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0);
- }
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
}
static int rna_Sequence_input_count_get(PointerRNA *ptr)
@@ -801,9 +775,8 @@ static void rna_Sequence_reopen_files_update(Main *bmain, Scene *UNUSED(scene),
static void rna_Sequence_mute_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- BKE_sequencer_update_muting(ed);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
}
static void rna_Sequence_filepath_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -2392,23 +2365,20 @@ static void rna_def_sound(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Volume", "Playback volume of the sound");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SOUND);
- RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_volume_set", NULL);
- RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update");
prop = RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pitch");
RNA_def_property_range(prop, 0.1f, 10.0f);
RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SOUND);
- RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_pitch_set", NULL);
- RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update");
prop = RNA_def_property(srna, "pan", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pan");
RNA_def_property_range(prop, -2.0f, 2.0f);
RNA_def_property_ui_text(prop, "Pan", "Playback panning of the sound (only for Mono sources)");
- RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_pan_set", NULL);
- RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update");
prop = RNA_def_property(srna, "show_waveform", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_AUDIO_DRAW_WAVEFORM);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 6bde162f507..2e27ec81bd0 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2537,8 +2537,14 @@ void RE_RenderAnim(Render *re,
re->movie_ctx_arr[i] = mh->context_create();
- if (!mh->start_movie(
- re->movie_ctx_arr[i], scene, &re->r, width, height, re->reports, false, suffix)) {
+ if (!mh->start_movie(re->movie_ctx_arr[i],
+ re->pipeline_scene_eval,
+ &re->r,
+ width,
+ height,
+ re->reports,
+ false,
+ suffix)) {
is_error = true;
break;
}
@@ -2744,7 +2750,7 @@ void RE_RenderAnim(Render *re,
BLI_callback_exec(
re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
- BKE_sound_reset_scene_specs(scene);
+ BKE_sound_reset_scene_specs(re->pipeline_scene_eval);
RE_CleanAfterRender(re);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index f688f520572..952382c2e36 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -86,6 +86,7 @@
#include "RNA_enum_types.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
static void wm_notifier_clear(wmNotifier *note);
static void update_tablet_data(wmWindow *win, wmEvent *event);
@@ -3154,13 +3155,17 @@ void wm_event_do_handlers(bContext *C)
else {
Scene *scene = WM_window_get_active_scene(win);
- if (scene) {
- int is_playing_sound = BKE_sound_scene_playing(scene);
+ CTX_wm_window_set(C, win);
+ CTX_data_scene_set(C, scene);
+
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene_eval = DEG_get_evaluated_scene_if_exists(depsgraph);
+
+ if (scene_eval) {
+ const int is_playing_sound = BKE_sound_scene_playing(scene_eval);
if (is_playing_sound != -1) {
bool is_playing_screen;
- CTX_wm_window_set(C, win);
- CTX_data_scene_set(C, scene);
is_playing_screen = (ED_screen_animation_playing(wm) != NULL);
@@ -3175,18 +3180,17 @@ void wm_event_do_handlers(bContext *C)
int ncfra = time * (float)FPS + 0.5f;
if (ncfra != scene->r.cfra) {
scene->r.cfra = ncfra;
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
ED_update_for_newframe(CTX_data_main(C), depsgraph);
WM_event_add_notifier(C, NC_WINDOW, NULL);
}
}
}
-
- CTX_data_scene_set(C, NULL);
- CTX_wm_screen_set(C, NULL);
- CTX_wm_window_set(C, NULL);
}
}
+
+ CTX_data_scene_set(C, NULL);
+ CTX_wm_screen_set(C, NULL);
+ CTX_wm_window_set(C, NULL);
}
while ((event = win->queue.first)) {
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index bbaaab01b18..7e54afcb9aa 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -65,6 +65,8 @@
#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_screen.h"
+#include "BKE_scene.h"
+#include "BKE_sound.h"
#include "BKE_keyconfig.h"
#include "BKE_addon.h"
@@ -123,6 +125,7 @@
#include "COM_compositor.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "DRW_engine.h"
@@ -195,6 +198,30 @@ void WM_init_opengl(Main *bmain)
opengl_is_init = true;
}
+static void sound_jack_sync_callback(Main *bmain, int mode, float time)
+{
+ /* Ugly: Blender doesn't like it when the animation is played back during rendering. */
+ if (G.is_rendering) {
+ return;
+ }
+
+ wmWindowManager *wm = bmain->wm.first;
+
+ for (wmWindow *window = wm->windows.first; window != NULL; window = window->next) {
+ Scene *scene = WM_window_get_active_scene(window);
+ if ((scene->audio.flag & AUDIO_SYNC) == 0) {
+ continue;
+ }
+ ViewLayer *view_layer = WM_window_get_active_view_layer(window);
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
+ if (depsgraph == NULL) {
+ continue;
+ }
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ BKE_sound_jack_scene_update(scene_eval, mode, time);
+ }
+}
+
/* only called once, for startup */
void WM_init(bContext *C, int argc, const char **argv)
{
@@ -202,6 +229,7 @@ void WM_init(bContext *C, int argc, const char **argv)
if (!G.background) {
wm_ghost_init(C); /* note: it assigns C to ghost! */
wm_init_cursor_data();
+ BKE_sound_jack_sync_callback_set(sound_jack_sync_callback);
}
GHOST_CreateSystemPaths();