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_sound.h14
-rw-r--r--source/blender/blenkernel/intern/scene.c26
-rw-r--r--source/blender/blenkernel/intern/sequencer.c22
-rw-r--r--source/blender/blenkernel/intern/sound.c253
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc5
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc4
-rw-r--r--source/blender/editors/animation/anim_ops.c6
-rw-r--r--source/blender/editors/screen/screen_ops.c9
-rw-r--r--source/blender/editors/sound/CMakeLists.txt1
-rw-r--r--source/blender/editors/sound/sound_ops.c55
-rw-r--r--source/blender/makesdna/DNA_ID.h8
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c6
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c28
15 files changed, 272 insertions, 173 deletions
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index d95be9fde97..0c1ab2cc4c3 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -71,12 +71,17 @@ void BKE_sound_cache(struct bSound *sound);
void BKE_sound_delete_cache(struct bSound *sound);
-void BKE_sound_reset_pointers(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,
@@ -88,7 +93,7 @@ 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_pointers(struct Scene *scene);
+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);
@@ -154,6 +159,11 @@ 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);
+
/* Evaluation. */
struct Depsgraph;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 14e011fca3b..733e76fef2d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -309,7 +309,7 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
flag_subdata);
}
- BKE_sound_reset_scene_pointers(sce_dst);
+ BKE_sound_reset_scene_runtime(sce_dst);
/* Copy sequencer, this is local data! */
if (sce_src->ed) {
@@ -399,7 +399,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
sce_copy->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
}
- BKE_sound_reset_scene_pointers(sce_copy);
+ BKE_sound_reset_scene_runtime(sce_copy);
/* grease pencil */
sce_copy->gpd = NULL;
@@ -779,7 +779,7 @@ void BKE_scene_init(Scene *sce)
srv = sce->r.views.last;
BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
- BKE_sound_reset_scene_pointers(sce);
+ BKE_sound_reset_scene_runtime(sce);
/* color management */
colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER);
@@ -1509,7 +1509,7 @@ 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_input_scene(depsgraph);
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
BKE_sound_ensure_scene(scene);
BKE_sound_update_scene(bmain, scene);
}
@@ -2398,23 +2398,17 @@ void BKE_scene_cursor_quat_to_rot(View3DCursor *cursor, const float quat[4], boo
void BKE_scene_eval_sequencer_sequences(Depsgraph *depsgraph, Scene *scene)
{
DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene);
- /* TODO(sergey): For now we keep sound handlers in an original IDs, but it
- * should really be moved to an evaluated one. */
- if (!DEG_is_active(depsgraph)) {
- return;
- }
- Scene *scene_orig = (Scene *)DEG_get_original_id(&scene->id);
- if (scene_orig->ed == NULL) {
+ if (scene->ed == NULL) {
return;
}
- BKE_sound_ensure_scene(scene_orig);
+ BKE_sound_ensure_scene(scene);
Sequence *seq;
- SEQ_BEGIN (scene_orig->ed, seq) {
+ SEQ_BEGIN (scene->ed, seq) {
if (seq->sound != NULL && seq->scene_sound == NULL) {
- seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene_orig, seq);
+ seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
}
}
SEQ_END;
- BKE_sequencer_update_muting(scene_orig->ed);
- BKE_sequencer_update_sound_bounds_all(scene_orig);
+ 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 f593713b79c..74541c13c4f 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);
}
}
@@ -5491,17 +5488,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;
@@ -5526,8 +5524,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);
@@ -5536,6 +5533,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
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 18093173f7c..9e5fb3dac63 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>
@@ -64,6 +65,28 @@ 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;
@@ -80,7 +103,7 @@ 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);
+ BKE_sound_reset_runtime(sound);
return sound;
}
@@ -128,6 +151,17 @@ void BKE_sound_free(bSound *sound)
sound->packedfile = NULL;
}
+ BKE_sound_free_audio(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);
@@ -143,11 +177,6 @@ void BKE_sound_free(bSound *sound)
BKE_sound_free_waveform(sound);
#endif /* WITH_AUDASPACE */
- if (sound->spinlock) {
- BLI_spin_end(sound->spinlock);
- MEM_freeN(sound->spinlock);
- sound->spinlock = NULL;
- }
}
/**
@@ -160,7 +189,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))
@@ -180,8 +209,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)
@@ -194,31 +222,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
@@ -370,6 +382,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);
@@ -396,44 +410,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)
+{
- BKE_sound_free_waveform(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);
/* 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;
@@ -450,32 +470,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_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_CACHING) {
+ sound->cache = AUD_Sound_cache(sound->handle);
+ }
- if (sound->cache) {
- sound->playback_handle = sound->cache;
- }
- else {
- sound->playback_handle = sound->handle;
- }
+ 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;
@@ -508,6 +530,8 @@ void BKE_sound_destroy_scene(Scene *scene)
void BKE_sound_reset_scene_specs(Scene *scene)
{
+ sound_verify_evaluated_id(&scene->id);
+
AUD_Specs specs;
specs.channels = AUD_Device_getChannels(sound_device);
@@ -518,6 +542,7 @@ void BKE_sound_reset_scene_specs(Scene *scene)
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);
}
@@ -525,6 +550,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);
}
@@ -534,6 +561,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);
@@ -542,6 +571,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,
@@ -565,6 +595,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;
@@ -604,12 +635,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,
@@ -631,6 +664,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,
@@ -656,6 +690,8 @@ void BKE_sound_set_scene_sound_pan(void *handle, float pan, char 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) {
@@ -665,6 +701,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);
}
@@ -678,6 +716,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);
@@ -720,6 +760,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;
@@ -751,9 +793,10 @@ void BKE_sound_seek_scene(Main *bmain, Scene *scene)
}
}
- if (scene->audio.flag & AUDIO_SCRUB && !animation_playing) {
+ Scene *scene_orig = (Scene *)DEG_get_original_id(&scene->id);
+ if (scene_orig->audio.flag & AUDIO_SCRUB && !animation_playing) {
AUD_Handle_setPosition(scene->playback_handle, cur_time);
- if (scene->audio.flag & AUDIO_SYNC) {
+ if (scene_orig->audio.flag & AUDIO_SYNC) {
AUD_seekSynchronizer(scene->playback_handle, cur_time);
}
AUD_Handle_resume(scene->playback_handle);
@@ -769,7 +812,7 @@ void BKE_sound_seek_scene(Main *bmain, Scene *scene)
}
}
else {
- if (scene->audio.flag & AUDIO_SYNC) {
+ if (scene_orig->audio.flag & AUDIO_SYNC) {
AUD_seekSynchronizer(scene->playback_handle, cur_time);
}
else {
@@ -784,6 +827,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;
@@ -802,6 +847,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;
@@ -834,6 +881,8 @@ void BKE_sound_free_waveform(bSound *sound)
void BKE_sound_read_waveform(bSound *sound, short *stop)
{
+ sound_verify_evaluated_id(&sound->id);
+
AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
@@ -880,11 +929,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;
@@ -947,6 +999,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;
@@ -956,7 +1010,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) {
@@ -993,6 +1048,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;
@@ -1157,7 +1213,7 @@ char **BKE_sound_get_device_names(void)
#endif /* WITH_AUDASPACE */
-void BKE_sound_reset_scene_pointers(Scene *scene)
+void BKE_sound_reset_scene_runtime(Scene *scene)
{
scene->sound_scene = NULL;
scene->playback_handle = NULL;
@@ -1173,7 +1229,7 @@ void BKE_sound_ensure_scene(struct Scene *scene)
BKE_sound_create_scene(scene);
}
-void BKE_sound_reset_pointers(bSound *sound)
+void BKE_sound_reset_runtime(bSound *sound)
{
sound->cache = NULL;
sound->playback_handle = NULL;
@@ -1187,14 +1243,39 @@ void BKE_sound_ensure_loaded(Main *bmain, bSound *sound)
BKE_sound_load(bmain, sound);
}
-void BKE_sound_evaluate(Depsgraph *depsgraph, Main *bmain, bSound *sound)
+void BKE_sound_jack_sync_callback_set(SoundJackSyncCallback callback)
{
- DEG_debug_print_eval(depsgraph, __func__, sound->id.name, sound);
- /* TODO(sergey): For now we keep sound handlers in an original IDs, but it
- * should really be moved to an evaluated one. */
- if (!DEG_is_active(depsgraph)) {
+#if defined(WITH_AUDASPACE) && defined(WITH_JACK)
+ sound_jack_sync_callback = callback;
+#else
+ (void)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;
}
- bSound *sound_orig = (bSound *)DEG_get_original_id(&sound->id);
- BKE_sound_ensure_loaded(bmain, sound_orig);
+
+ 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);
+ }
+#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 3326e2c02dc..9661fd0bc61 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6678,7 +6678,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_reset_scene_pointers(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);
@@ -8423,7 +8423,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_reset_pointers(sound);
+ BKE_sound_reset_runtime(sound);
sound->id.tag &= ~LIB_TAG_NEED_LINK;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 8fef35570fe..64772dcc64b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -2391,6 +2391,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/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index d8e895364ca..f7d7b76cb69 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -218,9 +218,6 @@ void depsgraph_tag_to_component_opcode(const ID *id,
case ID_RECALC_SEQUENCER:
*component_type = NodeType::SEQUENCER;
break;
- case ID_RECALC_AUDIO_JUMP:
- *component_type = NodeType::AUDIO;
- break;
case ID_RECALC_ALL:
case ID_RECALC_PSYS_ALL:
BLI_assert(!"Should not happen");
@@ -623,8 +620,6 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
return "EDITORS";
case ID_RECALC_SEQUENCER:
return "SEQUENCER";
- case ID_RECALC_AUDIO_JUMP:
- return "AUDIO_JUMP";
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 6d5714d5606..bb4300e5330 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
@@ -1516,9 +1516,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/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 45bb8f3b11e..f95429fd47c 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -52,6 +52,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 +91,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 +116,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
FRAMENUMBER_MIN_CLAMP(CFRA);
/* do updates */
- BKE_sound_seek_scene(bmain, scene);
+ BKE_sound_seek_scene(CTX_data_main(C), DEG_get_evaluated_scene(CTX_data_depsgraph(C)));
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 a87660d2cb7..e35a2679b8f 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"
@@ -2832,7 +2833,8 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
areas_do_frame_follow(C, true);
- BKE_sound_seek_scene(bmain, scene);
+ /* TODO(sergey): Make more reusable. */
+ BKE_sound_seek_scene(bmain, DEG_get_evaluated_scene(CTX_data_depsgraph(C)));
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -4523,11 +4525,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);
}
@@ -4536,7 +4539,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 25c05e2d1d0..8ac49e447fe 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/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 42ee4e9a6c8..14b3d97cef4 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
@@ -608,10 +606,6 @@ typedef enum IDRecalcFlag {
* Use this tag with a scene ID which owns the sequences. */
ID_RECALC_SEQUENCER = (1 << 14),
- /* Frame changed in a way that caused audio jump.
- * Use this on a scene ID. */
- ID_RECALC_AUDIO_JUMP = (1 << 15),
-
/***************************************************************************
* 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/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 13b6260e2b9..a13b28b7853 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"
/* Motion in pixels allowed before we don't consider single/double click,
* or detect the start of a tweak event. */
@@ -3090,10 +3091,12 @@ void wm_event_do_handlers(bContext *C)
wm_event_free_all(win);
}
else {
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *scene = WM_window_get_active_scene(win);
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
if (scene) {
- int is_playing_sound = BKE_sound_scene_playing(scene);
+ const int is_playing_sound = BKE_sound_scene_playing(scene_eval);
if (is_playing_sound != -1) {
bool is_playing_screen;
@@ -3113,7 +3116,6 @@ 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);
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 97ba9190351..5529aec1aa5 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -64,6 +64,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"
@@ -122,6 +124,7 @@
#include "COM_compositor.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "DRW_engine.h"
@@ -194,6 +197,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)
{
@@ -201,6 +228,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();