diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_sound.h | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 26 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 22 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sound.c | 253 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 4 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_relations.cc | 4 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_tag.cc | 5 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc | 4 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_ops.c | 6 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 9 | ||||
-rw-r--r-- | source/blender/editors/sound/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/sound/sound_ops.c | 55 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ID.h | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 28 |
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(); |