diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-06-11 11:55:13 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-06-11 16:11:07 +0300 |
commit | 0767f95a63959e156c302520db7fbf480159abe0 (patch) | |
tree | e4f416474ae320156e9e35b1d25d2b8300ad628e /source/blender/blenkernel/intern/sound.c | |
parent | 3a6f6c87e051edd3e98c92428980a52bafd7abf0 (diff) |
Sound: Fix queries of sound info
A lot of areas were querying sound information directly using audio handle
which does not exist on an original sound IDs.
This change basically makes it so it's possible to query information about
given sound ID, without worrying about whether it's loaded or not: if it is
needed to load it first it happens automatically (no automatically-opened
handles are left behind though).
While this seems a bit extreme to open files on such queries it is still
better than the old situation when all sound handles were opened on file
load, no matter if it's needed or not. Besides, none of the changed code
paths are performance critical, just handful of tools.
Fixes T65696: Sequencer fails to create a new sound sequence strip via Python
Fixes T65656: Audio strip - SHIFT K crashes Blender
Reviewers: brecht
Reviewed By: brecht
Subscribers: ISS
Maniphest Tasks: T65696, T65656
Differential Revision: https://developer.blender.org/D5061
Diffstat (limited to 'source/blender/blenkernel/intern/sound.c')
-rw-r--r-- | source/blender/blenkernel/intern/sound.c | 120 |
1 files changed, 79 insertions, 41 deletions
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 029fea5c300..927a45accca 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -145,6 +145,24 @@ bSound *BKE_sound_new_file_exists(Main *bmain, const char *filepath) return BKE_sound_new_file_exists_ex(bmain, filepath, NULL); } +static void sound_free_audio(bSound *sound) +{ +#ifdef WITH_AUDASPACE + if (sound->handle) { + AUD_Sound_free(sound->handle); + sound->handle = NULL; + sound->playback_handle = NULL; + } + + if (sound->cache) { + AUD_Sound_free(sound->cache); + sound->cache = NULL; + } +#else + UNUSED_VARS(sound); +#endif /* WITH_AUDASPACE */ +} + /** Free (or release) any data used by this sound (does not free the sound itself). */ void BKE_sound_free(bSound *sound) { @@ -155,7 +173,7 @@ void BKE_sound_free(bSound *sound) sound->packedfile = NULL; } - BKE_sound_free_audio(sound); + sound_free_audio(sound); BKE_sound_free_waveform(sound); if (sound->spinlock) { @@ -165,24 +183,6 @@ void BKE_sound_free(bSound *sound) } } -void BKE_sound_free_audio(bSound *sound) -{ -#ifdef WITH_AUDASPACE - if (sound->handle) { - AUD_Sound_free(sound->handle); - sound->handle = NULL; - sound->playback_handle = NULL; - } - - if (sound->cache) { - AUD_Sound_free(sound->cache); - sound->cache = NULL; - } -#else - UNUSED_VARS(sound); -#endif /* WITH_AUDASPACE */ -} - /** * Only copy internal data of Sound ID from source * to already allocated/initialized destination. @@ -412,13 +412,7 @@ void BKE_sound_delete_cache(bSound *sound) } } -void BKE_sound_load(Main *bmain, bSound *sound) -{ - sound_verify_evaluated_id(&sound->id); - BKE_sound_load_audio(bmain, sound); -} - -void BKE_sound_load_audio(Main *bmain, bSound *sound) +static void sound_load_audio(Main *bmain, bSound *sound) { if (sound->cache) { @@ -492,6 +486,12 @@ void BKE_sound_load_audio(Main *bmain, bSound *sound) } } +void BKE_sound_load(Main *bmain, bSound *sound) +{ + sound_verify_evaluated_id(&sound->id); + sound_load_audio(bmain, sound); +} + AUD_Device *BKE_sound_mixdown(Scene *scene, AUD_DeviceSpecs specs, int start, float volume) { sound_verify_evaluated_id(&scene->id); @@ -560,7 +560,7 @@ void BKE_sound_mute_scene(Scene *scene, int muted) } } -void BKE_sound_update_fps(Scene *scene) +void BKE_sound_update_fps(Main *bmain, Scene *scene) { sound_verify_evaluated_id(&scene->id); @@ -568,7 +568,7 @@ void BKE_sound_update_fps(Scene *scene) AUD_Sequence_setFPS(scene->sound_scene, FPS); } - BKE_sequencer_refresh_sound_length(scene); + BKE_sequencer_refresh_sound_length(bmain, scene); } void BKE_sound_update_scene_listener(Scene *scene) @@ -895,11 +895,15 @@ 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) +void BKE_sound_read_waveform(Main *bmain, bSound *sound, short *stop) { + bool need_close_audio_handles = false; + if (sound->playback_handle == NULL) { + /* TOOD(sergey): Make it fully independent audio handle. */ + sound_load_audio(bmain, sound); + need_close_audio_handles = true; + } + AUD_SoundInfo info = AUD_getInfo(sound->playback_handle); SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform"); @@ -936,6 +940,10 @@ void BKE_sound_read_waveform(bSound *sound, short *stop) sound->waveform = waveform; sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING; BLI_spin_unlock(sound->spinlock); + + if (need_close_audio_handles) { + sound_free_audio(sound); + } } static void sound_update_base(Scene *scene, Object *object, void *new_set) @@ -1047,12 +1055,16 @@ void *BKE_sound_get_factory(void *sound) return ((bSound *)sound)->playback_handle; } -/* stupid wrapper because AUD_C-API.h includes Python.h which makesrna doesn't like */ -float BKE_sound_get_length(bSound *sound) +float BKE_sound_get_length(Main *bmain, bSound *sound) { - sound_verify_evaluated_id(&sound->id); - AUD_SoundInfo info = AUD_getInfo(sound->playback_handle); - + if (sound->playback_handle != NULL) { + AUD_SoundInfo info = AUD_getInfo(sound->playback_handle); + return info.length; + } + SoundInfo info; + if (!BKE_sound_info_get(bmain, sound, &info)) { + return 0.0f; + } return info.length; } @@ -1065,6 +1077,29 @@ char **BKE_sound_get_device_names(void) return audio_device_names; } +static bool sound_info_from_playback_handle(void *playback_handle, SoundInfo *sound_info) +{ + if (playback_handle == NULL) { + return false; + } + AUD_SoundInfo info = AUD_getInfo(playback_handle); + sound_info->specs.channels = (eSoundChannels)info.specs.channels; + sound_info->length = info.length; + return true; +} + +bool BKE_sound_info_get(struct Main *main, struct bSound *sound, SoundInfo *sound_info) +{ + if (sound->playback_handle != NULL) { + return sound_info_from_playback_handle(sound->playback_handle, sound_info); + } + /* TOOD(sergey): Make it fully independent audio handle. */ + sound_load_audio(main, sound); + const bool result = sound_info_from_playback_handle(sound->playback_handle, sound_info); + sound_free_audio(sound); + return result; +} + #else /* WITH_AUDASPACE */ # include "BLI_utildefines.h" @@ -1162,7 +1197,7 @@ int BKE_sound_scene_playing(Scene *UNUSED(scene)) { return -1; } -void BKE_sound_read_waveform(bSound *sound, short *stop) +void BKE_sound_read_waveform(Main *bmain, bSound *sound, short *stop) { UNUSED_VARS(sound, stop); } @@ -1184,7 +1219,7 @@ void BKE_sound_update_scene_sound(void *UNUSED(handle), bSound *UNUSED(sound)) void BKE_sound_update_scene_listener(Scene *UNUSED(scene)) { } -void BKE_sound_update_fps(Scene *UNUSED(scene)) +void BKE_sound_update_fps(Main *UNUSED(bmain), Scene *UNUSED(scene)) { } void BKE_sound_set_scene_sound_volume(void *UNUSED(handle), @@ -1203,7 +1238,7 @@ void BKE_sound_set_scene_sound_pitch(void *UNUSED(handle), char UNUSED(animated)) { } -float BKE_sound_get_length(bSound *UNUSED(sound)) +float BKE_sound_get_length(struct Main *UNUSED(bmain), bSound *UNUSED(sound)) { return 0; } @@ -1217,8 +1252,11 @@ void BKE_sound_free_waveform(bSound *UNUSED(sound)) { } -void BKE_sound_load_audio(Main *UNUSED(bmain), bSound *UNUSED(sound)) +bool BKE_sound_info_get(struct Main *UNUSED(main), + struct bSound *UNUSED(sound), + SoundInfo *UNUSED(sound_info)) { + return false; } #endif /* WITH_AUDASPACE */ |