diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 72 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 27 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sound.c | 311 |
3 files changed, 298 insertions, 112 deletions
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); +} |