2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
* Copyright 2001-2002 NaN Holding BV. All rights reserved. */
|
2011-09-18 12:06:28 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup bke
|
2011-02-27 20:40:57 +00:00
|
|
|
*/
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-10-09 16:57:49 +00:00
|
|
|
#include <stdlib.h>
|
2020-03-19 09:33:03 +01:00
|
|
|
#include <string.h>
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2019-06-07 15:54:22 +02:00
|
|
|
#include "BLI_iterator.h"
|
2011-08-09 08:38:14 +00:00
|
|
|
#include "BLI_math.h"
|
2014-11-24 18:18:35 +01:00
|
|
|
#include "BLI_threads.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2020-03-08 20:45:00 +01:00
|
|
|
#include "BLT_translation.h"
|
|
|
|
|
|
2020-09-11 11:52:25 +02:00
|
|
|
/* Allow using deprecated functionality for .blend file I/O. */
|
|
|
|
|
#define DNA_DEPRECATED_ALLOW
|
|
|
|
|
|
2010-02-08 23:07:53 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2011-08-09 08:38:14 +00:00
|
|
|
#include "DNA_object_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_packedFile_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_scene_types.h"
|
2009-08-09 21:16:39 +00:00
|
|
|
#include "DNA_screen_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_sequence_types.h"
|
2010-08-04 04:01:27 +00:00
|
|
|
#include "DNA_sound_types.h"
|
2011-08-09 08:38:14 +00:00
|
|
|
#include "DNA_speaker_types.h"
|
2019-06-04 16:52:48 +02:00
|
|
|
#include "DNA_windowmanager_types.h"
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2011-06-23 09:27:56 +00:00
|
|
|
#ifdef WITH_AUDASPACE
|
2020-03-19 09:33:03 +01:00
|
|
|
# include "../../../intern/audaspace/intern/AUD_Set.h"
|
2017-08-18 08:24:12 +02:00
|
|
|
# include <AUD_Handle.h>
|
2020-03-19 09:33:03 +01:00
|
|
|
# include <AUD_Sequence.h>
|
|
|
|
|
# include <AUD_Sound.h>
|
2017-08-18 08:24:12 +02:00
|
|
|
# include <AUD_Special.h>
|
2011-06-23 09:27:56 +00:00
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
|
Refactor BKE_bpath module.
The main goal of this refactor is to make BPath module use `IDTypeInfo`,
and move each ID-specific part of the `foreach_path` looper into their
own IDTypeInfo struct, using a new `foreach_path` callback.
Additionally, following improvements/cleanups are included:
* Attempt to get better, more consistent namings.
** In particular, move from `path_visitor` to more standard `foreach_path`.
* Update and extend documentation.
** API doc was moved to header, according to recent discussions on this
topic.
* Remove `BKE_bpath_relocate_visitor` from API, this is specific
callback that belongs in `lib_id.c` user code.
NOTE: This commit is expected to be 100% non-behavioral-change. This
implies that several potential further changes were only noted as
comments (like using a more generic solution for
`lib_id_library_local_paths`, addressing inconsistencies like path of
packed libraries always being skipped, regardless of the
`BKE_BPATH_FOREACH_PATH_SKIP_PACKED` `eBPathForeachFlag` flag value,
etc.).
NOTE: basic unittests were added to master already in
rBdcc500e5a265093bc9cc.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D13381
2021-11-29 14:20:58 +01:00
|
|
|
#include "BKE_bpath.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_global.h"
|
2020-03-08 20:45:00 +01:00
|
|
|
#include "BKE_idtype.h"
|
2020-02-10 12:58:59 +01:00
|
|
|
#include "BKE_lib_id.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_main.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_packedFile.h"
|
2011-08-30 07:57:55 +00:00
|
|
|
#include "BKE_scene.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_sound.h"
|
2010-02-07 23:41:17 +00:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
2019-06-07 10:58:51 +02:00
|
|
|
#include "DEG_depsgraph_query.h"
|
2019-06-04 16:52:48 +02:00
|
|
|
|
2020-09-11 11:52:25 +02:00
|
|
|
#include "BLO_read_write.h"
|
|
|
|
|
|
2020-11-01 21:03:31 +01:00
|
|
|
#include "SEQ_sequencer.h"
|
2020-12-19 06:44:57 +01:00
|
|
|
#include "SEQ_sound.h"
|
2022-06-02 01:39:40 +02:00
|
|
|
#include "SEQ_time.h"
|
2020-11-01 21:03:31 +01:00
|
|
|
|
2020-03-08 20:45:00 +01:00
|
|
|
static void sound_free_audio(bSound *sound);
|
|
|
|
|
|
|
|
|
|
static void sound_copy_data(Main *UNUSED(bmain),
|
|
|
|
|
ID *id_dst,
|
|
|
|
|
const ID *id_src,
|
|
|
|
|
const int UNUSED(flag))
|
|
|
|
|
{
|
|
|
|
|
bSound *sound_dst = (bSound *)id_dst;
|
|
|
|
|
const bSound *sound_src = (const bSound *)id_src;
|
|
|
|
|
|
|
|
|
|
sound_dst->handle = NULL;
|
|
|
|
|
sound_dst->cache = NULL;
|
|
|
|
|
sound_dst->waveform = NULL;
|
|
|
|
|
sound_dst->playback_handle = NULL;
|
|
|
|
|
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;
|
|
|
|
|
sound_dst->newpackedfile = NULL;
|
|
|
|
|
|
|
|
|
|
if (sound_src->packedfile != NULL) {
|
|
|
|
|
sound_dst->packedfile = BKE_packedfile_duplicate(sound_src->packedfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BKE_sound_reset_runtime(sound_dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sound_free_data(ID *id)
|
|
|
|
|
{
|
|
|
|
|
bSound *sound = (bSound *)id;
|
|
|
|
|
|
2022-03-10 11:32:48 +11:00
|
|
|
/* No animation-data here. */
|
2020-03-08 20:45:00 +01:00
|
|
|
|
|
|
|
|
if (sound->packedfile) {
|
|
|
|
|
BKE_packedfile_free(sound->packedfile);
|
|
|
|
|
sound->packedfile = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sound_free_audio(sound);
|
|
|
|
|
BKE_sound_free_waveform(sound);
|
|
|
|
|
|
|
|
|
|
if (sound->spinlock) {
|
|
|
|
|
BLI_spin_end(sound->spinlock);
|
|
|
|
|
MEM_freeN(sound->spinlock);
|
|
|
|
|
sound->spinlock = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 12:55:50 +02:00
|
|
|
static void sound_foreach_cache(ID *id,
|
|
|
|
|
IDTypeForeachCacheFunctionCallback function_callback,
|
|
|
|
|
void *user_data)
|
|
|
|
|
{
|
|
|
|
|
bSound *sound = (bSound *)id;
|
|
|
|
|
IDCacheKey key = {
|
|
|
|
|
.id_session_uuid = id->session_uuid,
|
|
|
|
|
.offset_in_ID = offsetof(bSound, waveform),
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-06 15:07:12 +02:00
|
|
|
function_callback(id, &key, &sound->waveform, 0, user_data);
|
2020-07-03 12:55:50 +02:00
|
|
|
}
|
|
|
|
|
|
Refactor BKE_bpath module.
The main goal of this refactor is to make BPath module use `IDTypeInfo`,
and move each ID-specific part of the `foreach_path` looper into their
own IDTypeInfo struct, using a new `foreach_path` callback.
Additionally, following improvements/cleanups are included:
* Attempt to get better, more consistent namings.
** In particular, move from `path_visitor` to more standard `foreach_path`.
* Update and extend documentation.
** API doc was moved to header, according to recent discussions on this
topic.
* Remove `BKE_bpath_relocate_visitor` from API, this is specific
callback that belongs in `lib_id.c` user code.
NOTE: This commit is expected to be 100% non-behavioral-change. This
implies that several potential further changes were only noted as
comments (like using a more generic solution for
`lib_id_library_local_paths`, addressing inconsistencies like path of
packed libraries always being skipped, regardless of the
`BKE_BPATH_FOREACH_PATH_SKIP_PACKED` `eBPathForeachFlag` flag value,
etc.).
NOTE: basic unittests were added to master already in
rBdcc500e5a265093bc9cc.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D13381
2021-11-29 14:20:58 +01:00
|
|
|
static void sound_foreach_path(ID *id, BPathForeachPathData *bpath_data)
|
|
|
|
|
{
|
|
|
|
|
bSound *sound = (bSound *)id;
|
|
|
|
|
if (sound->packedfile != NULL && (bpath_data->flag & BKE_BPATH_FOREACH_PATH_SKIP_PACKED) != 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIXME: This does not check for empty path... */
|
|
|
|
|
BKE_bpath_foreach_path_fixed_process(bpath_data, sound->filepath);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-11 11:52:25 +02:00
|
|
|
static void sound_blend_write(BlendWriter *writer, ID *id, const void *id_address)
|
|
|
|
|
{
|
|
|
|
|
bSound *sound = (bSound *)id;
|
2020-12-14 11:28:08 +01:00
|
|
|
const bool is_undo = BLO_write_is_undo(writer);
|
|
|
|
|
|
2021-08-19 11:13:55 +02:00
|
|
|
/* Clean up, important in undo case to reduce false detection of changed datablocks. */
|
|
|
|
|
sound->tags = 0;
|
|
|
|
|
sound->handle = NULL;
|
|
|
|
|
sound->playback_handle = NULL;
|
|
|
|
|
sound->spinlock = NULL;
|
2020-09-11 11:52:25 +02:00
|
|
|
|
2021-08-19 11:13:55 +02:00
|
|
|
/* Do not store packed files in case this is a library override ID. */
|
|
|
|
|
if (ID_IS_OVERRIDE_LIBRARY(sound) && !is_undo) {
|
|
|
|
|
sound->packedfile = NULL;
|
2020-09-11 11:52:25 +02:00
|
|
|
}
|
2021-08-19 11:13:55 +02:00
|
|
|
|
|
|
|
|
/* write LibData */
|
|
|
|
|
BLO_write_id_struct(writer, bSound, id_address, &sound->id);
|
|
|
|
|
BKE_id_blend_write(writer, &sound->id);
|
|
|
|
|
|
|
|
|
|
BKE_packedfile_blend_write(writer, sound->packedfile);
|
2020-09-11 11:52:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sound_blend_read_data(BlendDataReader *reader, ID *id)
|
|
|
|
|
{
|
|
|
|
|
bSound *sound = (bSound *)id;
|
|
|
|
|
sound->tags = 0;
|
|
|
|
|
sound->handle = NULL;
|
|
|
|
|
sound->playback_handle = NULL;
|
|
|
|
|
|
|
|
|
|
/* versioning stuff, if there was a cache, then we enable caching: */
|
|
|
|
|
if (sound->cache) {
|
|
|
|
|
sound->flags |= SOUND_FLAGS_CACHING;
|
|
|
|
|
sound->cache = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (BLO_read_data_is_undo(reader)) {
|
|
|
|
|
sound->tags |= SOUND_TAGS_WAVEFORM_NO_RELOAD;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
|
|
|
|
|
BLI_spin_init(sound->spinlock);
|
|
|
|
|
|
|
|
|
|
/* clear waveform loading flag */
|
|
|
|
|
sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
|
|
|
|
|
|
|
|
|
|
BKE_packedfile_blend_read(reader, &sound->packedfile);
|
|
|
|
|
BKE_packedfile_blend_read(reader, &sound->newpackedfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sound_blend_read_lib(BlendLibReader *reader, ID *id)
|
|
|
|
|
{
|
|
|
|
|
bSound *sound = (bSound *)id;
|
2021-06-23 12:05:40 +10:00
|
|
|
/* XXX: deprecated - old animation system. */
|
|
|
|
|
BLO_read_id_address(reader, sound->id.lib, &sound->ipo);
|
2020-09-11 11:52:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sound_blend_read_expand(BlendExpander *expander, ID *id)
|
|
|
|
|
{
|
|
|
|
|
bSound *snd = (bSound *)id;
|
|
|
|
|
BLO_expand(expander, snd->ipo); /* XXX deprecated - old animation system */
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-08 20:45:00 +01:00
|
|
|
IDTypeInfo IDType_ID_SO = {
|
|
|
|
|
.id_code = ID_SO,
|
|
|
|
|
.id_filter = FILTER_ID_SO,
|
|
|
|
|
.main_listbase_index = INDEX_ID_SO,
|
|
|
|
|
.struct_size = sizeof(bSound),
|
|
|
|
|
.name = "Sound",
|
|
|
|
|
.name_plural = "sounds",
|
|
|
|
|
.translation_context = BLT_I18NCONTEXT_ID_SOUND,
|
2021-09-17 16:22:29 +02:00
|
|
|
.flags = IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_APPEND_IS_REUSABLE,
|
2021-11-24 10:32:28 +01:00
|
|
|
.asset_type_info = NULL,
|
2020-03-08 20:45:00 +01:00
|
|
|
|
|
|
|
|
/* A fuzzy case, think NULLified content is OK here... */
|
|
|
|
|
.init_data = NULL,
|
|
|
|
|
.copy_data = sound_copy_data,
|
|
|
|
|
.free_data = sound_free_data,
|
|
|
|
|
.make_local = NULL,
|
2020-05-21 18:35:11 +02:00
|
|
|
.foreach_id = NULL,
|
2020-07-03 12:55:50 +02:00
|
|
|
.foreach_cache = sound_foreach_cache,
|
Refactor BKE_bpath module.
The main goal of this refactor is to make BPath module use `IDTypeInfo`,
and move each ID-specific part of the `foreach_path` looper into their
own IDTypeInfo struct, using a new `foreach_path` callback.
Additionally, following improvements/cleanups are included:
* Attempt to get better, more consistent namings.
** In particular, move from `path_visitor` to more standard `foreach_path`.
* Update and extend documentation.
** API doc was moved to header, according to recent discussions on this
topic.
* Remove `BKE_bpath_relocate_visitor` from API, this is specific
callback that belongs in `lib_id.c` user code.
NOTE: This commit is expected to be 100% non-behavioral-change. This
implies that several potential further changes were only noted as
comments (like using a more generic solution for
`lib_id_library_local_paths`, addressing inconsistencies like path of
packed libraries always being skipped, regardless of the
`BKE_BPATH_FOREACH_PATH_SKIP_PACKED` `eBPathForeachFlag` flag value,
etc.).
NOTE: basic unittests were added to master already in
rBdcc500e5a265093bc9cc.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D13381
2021-11-29 14:20:58 +01:00
|
|
|
.foreach_path = sound_foreach_path,
|
2021-02-25 10:17:31 +01:00
|
|
|
.owner_get = NULL,
|
2020-08-28 13:05:48 +02:00
|
|
|
|
2020-09-11 11:52:25 +02:00
|
|
|
.blend_write = sound_blend_write,
|
|
|
|
|
.blend_read_data = sound_blend_read_data,
|
|
|
|
|
.blend_read_lib = sound_blend_read_lib,
|
|
|
|
|
.blend_read_expand = sound_blend_read_expand,
|
2020-11-03 11:39:36 +01:00
|
|
|
|
|
|
|
|
.blend_read_undo_preserve = NULL,
|
2021-01-22 14:52:50 +01:00
|
|
|
|
|
|
|
|
.lib_override_apply_post = NULL,
|
2020-03-08 20:45:00 +01:00
|
|
|
};
|
|
|
|
|
|
2011-09-02 03:32:57 +00:00
|
|
|
#ifdef WITH_AUDASPACE
|
2015-07-24 15:44:17 +02:00
|
|
|
/* evil globals ;-) */
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
static int sound_cfra;
|
2015-07-29 10:43:32 +10:00
|
|
|
static char **audio_device_names = NULL;
|
2011-09-02 03:32:57 +00:00
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2020-03-13 17:27:11 +11:00
|
|
|
BLI_INLINE void sound_verify_evaluated_id(const ID *id)
|
2019-06-04 16:52:48 +02:00
|
|
|
{
|
|
|
|
|
UNUSED_VARS_NDEBUG(id);
|
|
|
|
|
/* This is a bit tricky and not quite reliable, but good enough check.
|
|
|
|
|
*
|
2019-06-12 09:04:10 +10:00
|
|
|
* We don't want audio system handles to be allocated on an original data-blocks, and only want
|
|
|
|
|
* them to be allocated on a data-blocks which are result of dependency graph evaluation.
|
2019-06-04 16:52:48 +02:00
|
|
|
*
|
2019-06-12 09:04:10 +10:00
|
|
|
* Data-blocks 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 data-blocks during its evaluation
|
2019-06-04 16:52:48 +02:00
|
|
|
* decides to re-allocate its nested one (for example, object evaluation could re-allocate mesh
|
2019-06-12 09:04:10 +10:00
|
|
|
* when evaluating modifier stack). Such data-blocks will have
|
|
|
|
|
* LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT tag set on them.
|
2019-06-04 16:52:48 +02:00
|
|
|
*
|
2019-06-12 09:04:10 +10:00
|
|
|
* Additionally, we also allow data-blocks outside of main database. Those can not be "original"
|
2019-06-04 16:52:48 +02:00
|
|
|
* and could be used as a temporary evaluated result during operations like baking.
|
|
|
|
|
*
|
2019-06-17 12:51:53 +10:00
|
|
|
* NOTE: We consider ID evaluated if ANY of those flags is set. We do NOT require ALL of them.
|
|
|
|
|
*/
|
2019-06-04 16:52:48 +02:00
|
|
|
BLI_assert(id->tag &
|
|
|
|
|
(LIB_TAG_COPIED_ON_WRITE | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_NO_MAIN));
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
|
2011-06-23 09:27:56 +00:00
|
|
|
{
|
2015-05-03 03:28:43 +10:00
|
|
|
bSound *sound;
|
2021-12-14 21:32:14 +11:00
|
|
|
const char *blendfile_path = BKE_main_blendfile_path(bmain);
|
2015-10-06 19:49:58 +11:00
|
|
|
char str[FILE_MAX];
|
2011-06-23 09:27:56 +00:00
|
|
|
|
2015-10-06 19:40:15 +11:00
|
|
|
BLI_strncpy(str, filepath, sizeof(str));
|
2021-12-14 21:32:14 +11:00
|
|
|
BLI_path_abs(str, blendfile_path);
|
2011-06-23 09:27:56 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
sound = BKE_libblock_alloc(bmain, ID_SO, BLI_path_basename(filepath), 0);
|
2020-06-23 09:54:14 +10:00
|
|
|
BLI_strncpy(sound->filepath, filepath, FILE_MAX);
|
2014-04-15 10:59:42 +02:00
|
|
|
/* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */
|
2011-06-23 09:27:56 +00:00
|
|
|
|
2022-05-19 20:58:55 +02:00
|
|
|
/* Extract sound specs for bSound */
|
|
|
|
|
SoundInfo info;
|
|
|
|
|
bool success = BKE_sound_info_get(bmain, sound, &info);
|
|
|
|
|
if (success) {
|
|
|
|
|
sound->samplerate = info.specs.samplerate;
|
|
|
|
|
sound->audio_channels = info.specs.channels;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
|
|
|
|
|
BLI_spin_init(sound->spinlock);
|
|
|
|
|
|
|
|
|
|
BKE_sound_reset_runtime(sound);
|
2011-06-23 09:27:56 +00:00
|
|
|
|
|
|
|
|
return sound;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
bSound *BKE_sound_new_file_exists_ex(Main *bmain, const char *filepath, bool *r_exists)
|
2015-10-06 19:40:15 +11:00
|
|
|
{
|
|
|
|
|
bSound *sound;
|
|
|
|
|
char str[FILE_MAX], strtest[FILE_MAX];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-06 19:40:15 +11:00
|
|
|
BLI_strncpy(str, filepath, sizeof(str));
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_path_abs(str, BKE_main_blendfile_path(bmain));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-06 19:40:15 +11:00
|
|
|
/* first search an identical filepath */
|
2019-03-08 09:29:17 +11:00
|
|
|
for (sound = bmain->sounds.first; sound; sound = sound->id.next) {
|
2020-06-23 09:54:14 +10:00
|
|
|
BLI_strncpy(strtest, sound->filepath, sizeof(sound->filepath));
|
2015-10-06 19:40:15 +11:00
|
|
|
BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &sound->id));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-06 19:40:15 +11:00
|
|
|
if (BLI_path_cmp(strtest, str) == 0) {
|
2015-11-09 19:47:10 +01:00
|
|
|
id_us_plus(&sound->id); /* officially should not, it doesn't link here! */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (r_exists) {
|
2015-10-06 19:40:15 +11:00
|
|
|
*r_exists = true;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2015-10-06 19:40:15 +11:00
|
|
|
return sound;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (r_exists) {
|
2015-10-06 19:40:15 +11:00
|
|
|
*r_exists = false;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2015-10-06 19:40:15 +11:00
|
|
|
return BKE_sound_new_file(bmain, filepath);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
bSound *BKE_sound_new_file_exists(Main *bmain, const char *filepath)
|
2015-10-06 19:40:15 +11:00
|
|
|
{
|
|
|
|
|
return BKE_sound_new_file_exists_ex(bmain, filepath, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 10:55:13 +02:00
|
|
|
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 */
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-23 09:27:56 +00:00
|
|
|
#ifdef WITH_AUDASPACE
|
|
|
|
|
|
2015-07-29 10:43:32 +10:00
|
|
|
static const char *force_device = NULL;
|
2011-07-13 17:24:33 +00:00
|
|
|
|
2010-03-08 20:08:04 +00:00
|
|
|
# ifdef WITH_JACK
|
2019-06-04 16:52:48 +02:00
|
|
|
static SoundJackSyncCallback sound_jack_sync_callback = NULL;
|
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
static void sound_sync_callback(void *data, int mode, float time)
|
2010-02-21 18:01:41 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
if (sound_jack_sync_callback == NULL) {
|
2016-12-27 20:47:01 +01:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
Main *bmain = (Main *)data;
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_jack_sync_callback(bmain, mode, time);
|
2010-02-21 18:01:41 +00:00
|
|
|
}
|
2010-03-08 20:08:04 +00:00
|
|
|
# endif
|
2010-02-21 18:01:41 +00:00
|
|
|
|
2015-07-24 15:44:17 +02:00
|
|
|
void BKE_sound_force_device(const char *device)
|
2009-12-07 20:39:57 +00:00
|
|
|
{
|
2010-01-30 21:04:51 +00:00
|
|
|
force_device = device;
|
2009-12-07 20:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_init_once(void)
|
2010-04-24 16:35:16 +00:00
|
|
|
{
|
|
|
|
|
AUD_initOnce();
|
2015-03-26 11:35:41 +01:00
|
|
|
atexit(BKE_sound_exit_once);
|
2010-04-24 16:35:16 +00:00
|
|
|
}
|
|
|
|
|
|
2017-09-18 16:05:16 +02:00
|
|
|
static AUD_Device *sound_device = NULL;
|
2014-11-13 00:33:28 +13:00
|
|
|
|
2015-07-29 10:43:32 +10:00
|
|
|
void *BKE_sound_get_device(void)
|
2014-11-13 00:33:28 +13:00
|
|
|
{
|
|
|
|
|
return sound_device;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_init(Main *bmain)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2017-09-18 16:05:16 +02:00
|
|
|
/* Make sure no instance of the sound system is running, otherwise we get leaks. */
|
|
|
|
|
BKE_sound_exit();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-01-01 05:09:30 +00:00
|
|
|
AUD_DeviceSpecs specs;
|
2009-08-26 08:09:29 +00:00
|
|
|
int device, buffersize;
|
2015-07-29 10:43:32 +10:00
|
|
|
const char *device_name;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-08-09 21:16:39 +00:00
|
|
|
device = U.audiodevice;
|
|
|
|
|
buffersize = U.mixbufsize;
|
|
|
|
|
specs.channels = U.audiochannels;
|
|
|
|
|
specs.format = U.audioformat;
|
|
|
|
|
specs.rate = U.audiorate;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-29 10:43:32 +10:00
|
|
|
if (force_device == NULL) {
|
2015-07-24 15:44:17 +02:00
|
|
|
int i;
|
2015-07-29 10:43:32 +10:00
|
|
|
char **names = BKE_sound_get_device_names();
|
2015-07-24 15:44:17 +02:00
|
|
|
device_name = names[0];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-29 10:43:32 +10:00
|
|
|
/* make sure device is within the bounds of the array */
|
|
|
|
|
for (i = 0; names[i]; i++) {
|
|
|
|
|
if (i == device) {
|
2015-07-24 15:44:17 +02:00
|
|
|
device_name = names[i];
|
2015-07-29 10:43:32 +10:00
|
|
|
}
|
|
|
|
|
}
|
2014-03-03 23:57:59 +01:00
|
|
|
}
|
2019-04-22 09:39:35 +10:00
|
|
|
else {
|
2015-07-24 15:44:17 +02:00
|
|
|
device_name = force_device;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (buffersize < 128) {
|
2014-03-04 13:44:15 +01:00
|
|
|
buffersize = 1024;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (specs.rate < AUD_RATE_8000) {
|
2015-12-27 16:33:54 +01:00
|
|
|
specs.rate = AUD_RATE_48000;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (specs.format <= AUD_FORMAT_INVALID) {
|
2009-08-09 21:16:39 +00:00
|
|
|
specs.format = AUD_FORMAT_S16;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (specs.channels <= AUD_CHANNELS_INVALID) {
|
2009-08-09 21:16:39 +00:00
|
|
|
specs.channels = AUD_CHANNELS_STEREO;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!(sound_device = AUD_init(device_name, specs, buffersize, "Blender"))) {
|
2021-03-16 23:45:49 +01:00
|
|
|
sound_device = AUD_init("None", specs, buffersize, "Blender");
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_init_main(bmain);
|
2011-08-09 08:38:14 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_init_main(Main *bmain)
|
2011-08-09 08:38:14 +00:00
|
|
|
{
|
2010-02-21 19:54:18 +00:00
|
|
|
# ifdef WITH_JACK
|
2019-04-22 09:39:35 +10:00
|
|
|
if (sound_device) {
|
2016-11-09 00:06:49 +01:00
|
|
|
AUD_setSynchronizerCallback(sound_sync_callback, bmain);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2010-10-17 06:38:56 +00:00
|
|
|
# else
|
2019-06-04 16:52:48 +02:00
|
|
|
UNUSED_VARS(bmain);
|
2010-02-21 19:54:18 +00:00
|
|
|
# endif
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_exit(void)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_exit(sound_device);
|
|
|
|
|
sound_device = NULL;
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_exit_once(void)
|
2013-03-27 07:19:54 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_exit(sound_device);
|
|
|
|
|
sound_device = NULL;
|
2013-03-27 07:19:54 +00:00
|
|
|
AUD_exitOnce();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-29 10:43:32 +10:00
|
|
|
if (audio_device_names != NULL) {
|
2015-07-24 15:44:17 +02:00
|
|
|
int i;
|
2015-07-29 10:43:32 +10:00
|
|
|
for (i = 0; audio_device_names[i]; i++) {
|
2015-07-24 15:44:17 +02:00
|
|
|
free(audio_device_names[i]);
|
2015-07-29 10:43:32 +10:00
|
|
|
}
|
2015-07-24 15:44:17 +02:00
|
|
|
free(audio_device_names);
|
|
|
|
|
audio_device_names = NULL;
|
|
|
|
|
}
|
2013-03-27 07:19:54 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-15 10:59:42 +02:00
|
|
|
/* XXX unused currently */
|
2009-08-09 21:16:39 +00:00
|
|
|
# if 0
|
2019-05-01 10:51:19 +02:00
|
|
|
bSound *BKE_sound_new_buffer(Main *bmain, bSound *source)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
bSound *sound = NULL;
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
char name[MAX_ID_NAME + 5];
|
2009-08-09 21:16:39 +00:00
|
|
|
strcpy(name, "buf_");
|
|
|
|
|
strcpy(name + 4, source->id.name);
|
|
|
|
|
|
2014-01-15 16:37:03 +01:00
|
|
|
sound = BKE_libblock_alloc(bmain, ID_SO, name);
|
2009-08-09 21:16:39 +00:00
|
|
|
|
|
|
|
|
sound->child_sound = source;
|
|
|
|
|
sound->type = SOUND_TYPE_BUFFER;
|
|
|
|
|
|
2011-09-05 19:34:27 +00:00
|
|
|
sound_load(bmain, sound);
|
2009-08-09 21:16:39 +00:00
|
|
|
|
|
|
|
|
return sound;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
bSound *BKE_sound_new_limiter(Main *bmain, bSound *source, float start, float end)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
bSound *sound = NULL;
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
char name[MAX_ID_NAME + 5];
|
2009-08-09 21:16:39 +00:00
|
|
|
strcpy(name, "lim_");
|
|
|
|
|
strcpy(name + 4, source->id.name);
|
|
|
|
|
|
2014-01-15 16:37:03 +01:00
|
|
|
sound = BKE_libblock_alloc(bmain, ID_SO, name);
|
2009-08-09 21:16:39 +00:00
|
|
|
|
|
|
|
|
sound->child_sound = source;
|
|
|
|
|
sound->start = start;
|
|
|
|
|
sound->end = end;
|
|
|
|
|
sound->type = SOUND_TYPE_LIMITER;
|
|
|
|
|
|
2011-09-05 19:34:27 +00:00
|
|
|
sound_load(bmain, sound);
|
2009-08-09 21:16:39 +00:00
|
|
|
|
|
|
|
|
return sound;
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_cache(bSound *sound)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&sound->id);
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (sound->cache) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sound_free(sound->cache);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
sound->cache = AUD_Sound_cache(sound->handle);
|
2019-04-22 09:39:35 +10:00
|
|
|
if (sound->cache) {
|
2011-10-13 22:19:29 +00:00
|
|
|
sound->playback_handle = sound->cache;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2011-10-13 22:19:29 +00:00
|
|
|
sound->playback_handle = sound->handle;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2009-08-26 18:20:17 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_delete_cache(bSound *sound)
|
2009-08-26 18:20:17 +00:00
|
|
|
{
|
2012-04-28 06:31:57 +00:00
|
|
|
if (sound->cache) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sound_free(sound->cache);
|
2009-08-26 18:20:17 +00:00
|
|
|
sound->cache = NULL;
|
2010-02-07 23:41:17 +00:00
|
|
|
sound->playback_handle = sound->handle;
|
2009-08-26 18:20:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2020-01-22 13:34:47 +01:00
|
|
|
static void sound_load_audio(Main *bmain, bSound *sound, bool free_waveform)
|
2019-06-04 16:52:48 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2019-05-02 14:31:33 +02:00
|
|
|
|
2020-01-22 13:34:47 +01:00
|
|
|
if (free_waveform) {
|
|
|
|
|
BKE_sound_free_waveform(sound);
|
|
|
|
|
}
|
2011-10-13 22:19:29 +00:00
|
|
|
|
2014-04-15 10:59:42 +02:00
|
|
|
/* XXX unused currently */
|
2009-08-26 14:19:29 +00:00
|
|
|
# if 0
|
2019-04-17 08:50:46 +02:00
|
|
|
switch (sound->type) {
|
2012-05-06 15:15:33 +00:00
|
|
|
case SOUND_TYPE_FILE:
|
2009-08-26 14:19:29 +00:00
|
|
|
# endif
|
2019-06-04 16:52:48 +02:00
|
|
|
{
|
|
|
|
|
char fullpath[FILE_MAX];
|
2019-04-17 09:34:15 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
/* load sound */
|
|
|
|
|
PackedFile *pf = sound->packedfile;
|
2019-04-17 09:34:15 +02:00
|
|
|
|
2020-06-23 09:54:14 +10:00
|
|
|
/* don't modify soundact->sound->filepath, only change a copy */
|
|
|
|
|
BLI_strncpy(fullpath, sound->filepath, sizeof(fullpath));
|
2019-06-04 16:52:48 +02:00
|
|
|
BLI_path_abs(fullpath, ID_BLEND_PATH(bmain, &sound->id));
|
2019-04-17 09:34:15 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
/* but we need a packed file then */
|
|
|
|
|
if (pf) {
|
|
|
|
|
sound->handle = AUD_Sound_bufferFile((unsigned char *)pf->data, pf->size);
|
2019-04-17 09:34:15 +02:00
|
|
|
}
|
2019-06-04 16:52:48 +02:00
|
|
|
else {
|
|
|
|
|
/* or else load it from disk */
|
|
|
|
|
sound->handle = AUD_Sound_file(fullpath);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-15 10:59:42 +02:00
|
|
|
/* XXX unused currently */
|
2009-08-26 14:19:29 +00:00
|
|
|
# if 0
|
2012-11-09 09:33:28 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SOUND_TYPE_BUFFER:
|
2019-04-22 09:39:35 +10:00
|
|
|
if (sound->child_sound && sound->child_sound->handle) {
|
2012-11-09 09:33:28 +00:00
|
|
|
sound->handle = AUD_bufferSound(sound->child_sound->handle);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-11-09 09:33:28 +00:00
|
|
|
break;
|
|
|
|
|
case SOUND_TYPE_LIMITER:
|
2019-04-22 09:39:35 +10:00
|
|
|
if (sound->child_sound && sound->child_sound->handle) {
|
2012-11-09 09:33:28 +00:00
|
|
|
sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-11-09 09:33:28 +00:00
|
|
|
break;
|
2012-05-10 15:22:29 +00:00
|
|
|
}
|
2009-08-26 14:19:29 +00:00
|
|
|
# endif
|
2019-06-04 16:52:48 +02:00
|
|
|
if (sound->flags & SOUND_FLAGS_MONO) {
|
|
|
|
|
void *handle = AUD_Sound_rechannel(sound->handle, AUD_CHANNELS_MONO);
|
|
|
|
|
AUD_Sound_free(sound->handle);
|
|
|
|
|
sound->handle = handle;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
if (sound->flags & SOUND_FLAGS_CACHING) {
|
|
|
|
|
sound->cache = AUD_Sound_cache(sound->handle);
|
|
|
|
|
}
|
2019-05-07 11:30:00 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
if (sound->cache) {
|
|
|
|
|
sound->playback_handle = sound->cache;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sound->playback_handle = sound->handle;
|
2019-04-17 09:34:15 +02:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2019-06-11 10:55:13 +02:00
|
|
|
void BKE_sound_load(Main *bmain, bSound *sound)
|
|
|
|
|
{
|
|
|
|
|
sound_verify_evaluated_id(&sound->id);
|
2020-01-22 13:34:47 +01:00
|
|
|
sound_load_audio(bmain, sound, true);
|
2019-06-11 10:55:13 +02:00
|
|
|
}
|
|
|
|
|
|
2020-03-13 17:27:11 +11:00
|
|
|
AUD_Device *BKE_sound_mixdown(const Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2011-08-15 21:50:09 +00:00
|
|
|
return AUD_openMixdownDevice(specs, scene->sound_scene, volume, start / FPS);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_create_scene(Scene *scene)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2012-05-09 15:54:22 +00:00
|
|
|
/* should be done in version patch, but this gets called before */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->r.frs_sec_base == 0) {
|
2012-05-09 15:54:22 +00:00
|
|
|
scene->r.frs_sec_base = 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
scene->sound_scene = AUD_Sequence_create(FPS, scene->audio.flag & AUDIO_MUTE);
|
|
|
|
|
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);
|
2015-05-15 16:51:17 +02:00
|
|
|
scene->playback_handle = NULL;
|
2011-06-21 20:21:43 +00:00
|
|
|
scene->sound_scrub_handle = NULL;
|
2011-08-03 09:25:40 +00:00
|
|
|
scene->speaker_handles = NULL;
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_destroy_scene(Scene *scene)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->playback_handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_stop(scene->playback_handle);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (scene->sound_scrub_handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_stop(scene->sound_scrub_handle);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (scene->speaker_handles) {
|
2019-06-07 22:29:52 +02:00
|
|
|
void *handle;
|
|
|
|
|
|
|
|
|
|
while ((handle = AUD_getSet(scene->speaker_handles))) {
|
|
|
|
|
AUD_Sequence_remove(scene->sound_scene, handle);
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-03 09:25:40 +00:00
|
|
|
AUD_destroySet(scene->speaker_handles);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-06-07 22:29:52 +02:00
|
|
|
if (scene->sound_scene) {
|
|
|
|
|
AUD_Sequence_free(scene->sound_scene);
|
|
|
|
|
}
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2020-03-28 09:14:07 +01:00
|
|
|
void BKE_sound_lock()
|
2020-03-23 09:33:02 +01:00
|
|
|
{
|
|
|
|
|
AUD_Device_lock(sound_device);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-28 09:14:07 +01:00
|
|
|
void BKE_sound_unlock()
|
2020-03-23 09:33:02 +01:00
|
|
|
{
|
|
|
|
|
AUD_Device_unlock(sound_device);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_reset_scene_specs(Scene *scene)
|
2017-01-06 18:18:20 +01:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
|
|
|
|
if (scene->sound_scene) {
|
|
|
|
|
AUD_Specs specs;
|
2017-01-06 18:18:20 +01:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
specs.channels = AUD_Device_getChannels(sound_device);
|
|
|
|
|
specs.rate = AUD_Device_getRate(sound_device);
|
2017-01-06 18:18:20 +01:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
AUD_Sequence_setSpecs(scene->sound_scene, specs);
|
|
|
|
|
}
|
2017-01-06 18:18:20 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_mute_scene(Scene *scene, int muted)
|
2011-04-10 22:40:37 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->sound_scene) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_setMuted(scene->sound_scene, muted);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-04-10 22:40:37 +00:00
|
|
|
}
|
|
|
|
|
|
2019-06-11 10:55:13 +02:00
|
|
|
void BKE_sound_update_fps(Main *bmain, Scene *scene)
|
2011-07-26 13:56:31 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->sound_scene) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_setFPS(scene->sound_scene, FPS);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-08-20 19:50:31 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sound_update_length(bmain, scene);
|
2011-07-26 13:56:31 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_update_scene_listener(Scene *scene)
|
2011-08-03 09:25:40 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
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);
|
2011-08-03 09:25:40 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void *BKE_sound_scene_add_scene_sound(
|
2019-05-01 10:51:19 +02:00
|
|
|
Scene *scene, Sequence *sequence, int startframe, int endframe, int frameskip)
|
2010-03-20 11:15:16 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2021-10-15 22:49:19 +02:00
|
|
|
if (sequence->scene && scene != sequence->scene) {
|
2014-04-15 10:59:42 +02:00
|
|
|
const double fps = FPS;
|
2014-11-13 00:33:28 +13:00
|
|
|
return AUD_Sequence_add(scene->sound_scene,
|
|
|
|
|
sequence->scene->sound_scene,
|
2014-04-15 10:59:42 +02:00
|
|
|
startframe / fps,
|
|
|
|
|
endframe / fps,
|
2021-10-15 22:49:19 +02:00
|
|
|
frameskip / fps);
|
2014-04-15 10:59:42 +02:00
|
|
|
}
|
2010-03-21 15:40:36 +00:00
|
|
|
return NULL;
|
2010-03-20 11:15:16 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void *BKE_sound_scene_add_scene_sound_defaults(Scene *scene, Sequence *sequence)
|
2012-01-05 10:34:50 +00:00
|
|
|
{
|
2015-03-26 11:35:41 +01:00
|
|
|
return BKE_sound_scene_add_scene_sound(scene,
|
|
|
|
|
sequence,
|
2022-06-02 01:39:40 +02:00
|
|
|
SEQ_time_left_handle_frame_get(sequence),
|
|
|
|
|
SEQ_time_right_handle_frame_get(sequence),
|
2012-01-05 10:34:50 +00:00
|
|
|
sequence->startofs + sequence->anim_startofs);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void *BKE_sound_add_scene_sound(
|
2019-05-01 10:51:19 +02:00
|
|
|
Scene *scene, Sequence *sequence, int startframe, int endframe, int frameskip)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2019-06-12 09:04:10 +10:00
|
|
|
/* Happens when sequence's sound data-block was removed. */
|
2018-12-21 16:50:59 +01:00
|
|
|
if (sequence->sound == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2019-06-07 11:27:34 +02:00
|
|
|
sound_verify_evaluated_id(&sequence->sound->id);
|
2014-04-15 10:59:42 +02:00
|
|
|
const double fps = FPS;
|
2022-03-08 13:15:41 +01:00
|
|
|
return AUD_Sequence_add(scene->sound_scene,
|
|
|
|
|
sequence->sound->playback_handle,
|
|
|
|
|
startframe / fps,
|
|
|
|
|
endframe / fps,
|
|
|
|
|
frameskip / fps + sequence->sound->offset_time);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void *BKE_sound_add_scene_sound_defaults(Scene *scene, Sequence *sequence)
|
2012-01-05 10:34:50 +00:00
|
|
|
{
|
2015-03-26 11:35:41 +01:00
|
|
|
return BKE_sound_add_scene_sound(scene,
|
|
|
|
|
sequence,
|
2022-06-02 01:39:40 +02:00
|
|
|
SEQ_time_left_handle_frame_get(sequence),
|
|
|
|
|
SEQ_time_right_handle_frame_get(sequence),
|
2018-12-21 16:49:55 +01:00
|
|
|
sequence->startofs + sequence->anim_startofs);
|
2012-01-05 10:34:50 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_remove_scene_sound(Scene *scene, void *handle)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_remove(scene->sound_scene, handle);
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_mute_scene_sound(void *handle, char mute)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_SequenceEntry_setMuted(handle, mute);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2022-06-02 01:39:40 +02:00
|
|
|
void BKE_sound_move_scene_sound(const Scene *scene,
|
|
|
|
|
void *handle,
|
|
|
|
|
int startframe,
|
|
|
|
|
int endframe,
|
|
|
|
|
int frameskip,
|
|
|
|
|
double audio_offset)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2014-04-15 10:59:42 +02:00
|
|
|
const double fps = FPS;
|
2021-07-06 19:48:06 +02:00
|
|
|
AUD_SequenceEntry_move(handle, startframe / fps, endframe / fps, frameskip / fps + audio_offset);
|
2011-07-26 13:56:31 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence)
|
2012-01-05 10:34:50 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2021-10-15 22:49:19 +02:00
|
|
|
if (sequence->scene_sound) {
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_move_scene_sound(scene,
|
|
|
|
|
sequence->scene_sound,
|
2022-06-02 01:39:40 +02:00
|
|
|
SEQ_time_left_handle_frame_get(sequence),
|
|
|
|
|
SEQ_time_right_handle_frame_get(sequence),
|
2021-07-06 19:48:06 +02:00
|
|
|
sequence->startofs + sequence->anim_startofs,
|
2021-10-15 22:49:19 +02:00
|
|
|
0.0);
|
2012-01-05 22:14:38 +00:00
|
|
|
}
|
2012-01-05 10:34:50 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_update_scene_sound(void *handle, bSound *sound)
|
2011-07-26 13:56:31 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_SequenceEntry_setSound(handle, sound->playback_handle);
|
2011-07-26 13:56:31 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_set_cfra(int cfra)
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
{
|
|
|
|
|
sound_cfra = cfra;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_set_scene_volume(Scene *scene, float volume)
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2019-10-22 17:30:43 -07:00
|
|
|
if (scene->sound_scene == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_setAnimationData(scene->sound_scene,
|
|
|
|
|
AUD_AP_VOLUME,
|
|
|
|
|
CFRA,
|
|
|
|
|
&volume,
|
2014-04-15 10:59:42 +02:00
|
|
|
(scene->audio.flag & AUDIO_VOLUME_ANIMATED) != 0);
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_set_scene_sound_volume(void *handle, float volume, char animated)
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_VOLUME, sound_cfra, &volume, animated);
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_set_scene_sound_pitch(void *handle, float pitch, char animated)
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PITCH, sound_cfra, &pitch, animated);
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_set_scene_sound_pan(void *handle, float pan, char animated)
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
{
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PANNING, sound_cfra, &pan, animated);
|
3D Audio GSoC:
Implemented basic audio animation.
* AnimatableProperty: Propper cache writing and spline interpolation for reading (the solution for stair steps in audio animation)
* Animatable properties so far are: volume, pitch, panning
* Users note: Changing the pitch of a sound results in wrong seeking, due to the resulting playback length difference.
* Users note: Panning only works for mono sources, values are in the range [-2..2], this basically controls the angle of the sound, 0 is front, -1 left, 1 right and 2 and -2 are back. Typical stereo panning only supports [-1..1].
* Disabled animation of audio related ffmpeg output parameters.
* Scene Audio Panel: 3D Listener settings also for Renderer, new Volume property (animatable!), Update/Bake buttons for animation problems, moved sampling rate and channel count here
2011-07-28 13:58:59 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_update_sequencer(Main *main, bSound *sound)
|
2011-07-26 13:56:31 +00:00
|
|
|
{
|
2021-07-15 18:23:28 +10:00
|
|
|
BLI_assert_msg(0, "is not supposed to be used, is weird function.");
|
2019-06-04 16:52:48 +02:00
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
Scene *scene;
|
2011-07-26 13:56:31 +00:00
|
|
|
|
2019-03-08 09:29:17 +11:00
|
|
|
for (scene = main->scenes.first; scene; scene = scene->id.next) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sound_update(scene, sound);
|
2012-02-23 02:17:50 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
static void sound_start_play_scene(Scene *scene)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->playback_handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_stop(scene->playback_handle);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2014-11-13 00:33:28 +13:00
|
|
|
|
2017-01-06 18:18:20 +01:00
|
|
|
BKE_sound_reset_scene_specs(scene);
|
2011-06-21 20:39:41 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if ((scene->playback_handle = AUD_Device_play(sound_device, scene->sound_scene, 1))) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_setLoopCount(scene->playback_handle, -1);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2020-05-03 15:25:52 +02:00
|
|
|
static double get_cur_time(Scene *scene)
|
2020-04-06 13:53:07 +02:00
|
|
|
{
|
|
|
|
|
/* We divide by the current framelen to take into account time remapping.
|
|
|
|
|
* Otherwise we will get the wrong starting time which will break A/V sync.
|
|
|
|
|
* See T74111 for further details. */
|
2020-05-03 15:25:52 +02:00
|
|
|
return FRA2TIME((CFRA + SUBFRA) / (double)scene->r.framelen);
|
2020-04-06 13:53:07 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_play_scene(Scene *scene)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2010-02-21 18:01:41 +00:00
|
|
|
AUD_Status status;
|
2020-05-03 15:25:52 +02:00
|
|
|
const double cur_time = get_cur_time(scene);
|
2014-04-15 10:59:42 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_lock(sound_device);
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
status = scene->playback_handle ? AUD_Handle_getStatus(scene->playback_handle) :
|
|
|
|
|
AUD_STATUS_INVALID;
|
2010-02-21 18:01:41 +00:00
|
|
|
|
2014-04-15 14:23:13 +02:00
|
|
|
if (status == AUD_STATUS_INVALID) {
|
2010-02-07 23:41:17 +00:00
|
|
|
sound_start_play_scene(scene);
|
|
|
|
|
|
2015-05-15 16:51:17 +02:00
|
|
|
if (!scene->playback_handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_unlock(sound_device);
|
2014-04-15 14:23:13 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2011-06-21 20:21:43 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
if (status != AUD_STATUS_PLAYING) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_setPosition(scene->playback_handle, cur_time);
|
|
|
|
|
AUD_Handle_resume(scene->playback_handle);
|
2010-02-21 18:01:41 +00:00
|
|
|
}
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC) {
|
2014-03-03 23:57:59 +01:00
|
|
|
AUD_playSynchronizer();
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_unlock(sound_device);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_stop_scene(Scene *scene)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2015-05-15 16:51:17 +02:00
|
|
|
if (scene->playback_handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_pause(scene->playback_handle);
|
2010-02-21 18:01:41 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC) {
|
2014-03-03 23:57:59 +01:00
|
|
|
AUD_stopSynchronizer();
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-06-21 20:21:43 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_seek_scene(Main *bmain, Scene *scene)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2010-02-21 18:01:41 +00:00
|
|
|
AUD_Status status;
|
2011-09-05 19:34:27 +00:00
|
|
|
bScreen *screen;
|
|
|
|
|
int animation_playing;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-03 15:25:52 +02:00
|
|
|
const double one_frame = 1.0 / FPS;
|
|
|
|
|
const double cur_time = FRA2TIME(CFRA);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_lock(sound_device);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
status = scene->playback_handle ? AUD_Handle_getStatus(scene->playback_handle) :
|
|
|
|
|
AUD_STATUS_INVALID;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
if (status == AUD_STATUS_INVALID) {
|
2010-02-07 23:41:17 +00:00
|
|
|
sound_start_play_scene(scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-05-15 16:51:17 +02:00
|
|
|
if (!scene->playback_handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_unlock(sound_device);
|
2011-06-21 20:21:43 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_pause(scene->playback_handle);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-09-05 19:34:27 +00:00
|
|
|
animation_playing = 0;
|
2019-03-08 09:29:17 +11:00
|
|
|
for (screen = bmain->screens.first; screen; screen = screen->id.next) {
|
2012-02-23 02:17:50 +00:00
|
|
|
if (screen->animtimer) {
|
2011-09-05 19:34:27 +00:00
|
|
|
animation_playing = 1;
|
2015-03-05 18:49:59 +01:00
|
|
|
break;
|
2012-02-23 02:17:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-06 12:46:14 +02:00
|
|
|
if (scene->audio.flag & AUDIO_SCRUB && !animation_playing) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_setPosition(scene->playback_handle, cur_time);
|
2019-05-06 12:46:14 +02:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC) {
|
2014-03-03 23:57:59 +01:00
|
|
|
AUD_seekSynchronizer(scene->playback_handle, cur_time);
|
2014-04-15 10:59:42 +02:00
|
|
|
}
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_resume(scene->playback_handle);
|
|
|
|
|
if (scene->sound_scrub_handle &&
|
|
|
|
|
AUD_Handle_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID) {
|
|
|
|
|
AUD_Handle_setPosition(scene->sound_scrub_handle, 0);
|
2014-04-15 10:59:42 +02:00
|
|
|
}
|
2012-03-06 18:40:15 +00:00
|
|
|
else {
|
2014-04-15 10:59:42 +02:00
|
|
|
if (scene->sound_scrub_handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_stop(scene->sound_scrub_handle);
|
2014-04-15 10:59:42 +02:00
|
|
|
}
|
2015-05-15 16:51:17 +02:00
|
|
|
scene->sound_scrub_handle = AUD_pauseAfter(scene->playback_handle, one_frame);
|
2011-06-21 20:21:43 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2012-03-06 18:40:15 +00:00
|
|
|
else {
|
2019-05-06 12:46:14 +02:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC) {
|
2014-03-03 23:57:59 +01:00
|
|
|
AUD_seekSynchronizer(scene->playback_handle, cur_time);
|
2014-04-15 10:59:42 +02:00
|
|
|
}
|
2012-03-06 18:40:15 +00:00
|
|
|
else {
|
2014-04-15 10:59:42 +02:00
|
|
|
if (status == AUD_STATUS_PLAYING) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_setPosition(scene->playback_handle, cur_time);
|
2014-04-15 10:59:42 +02:00
|
|
|
}
|
2010-02-21 18:01:41 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_unlock(sound_device);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
2020-05-03 15:25:52 +02:00
|
|
|
double BKE_sound_sync_scene(Scene *scene)
|
2010-02-19 12:20:29 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2016-12-27 20:47:01 +01:00
|
|
|
/* Ugly: Blender doesn't like it when the animation is played back during rendering */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (G.is_rendering) {
|
2016-12-27 20:47:01 +01:00
|
|
|
return NAN_FLT;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-05-15 16:51:17 +02:00
|
|
|
if (scene->playback_handle) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC) {
|
2014-03-03 23:57:59 +01:00
|
|
|
return AUD_getSynchronizerPosition(scene->playback_handle);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return AUD_Handle_getPosition(scene->playback_handle);
|
2011-06-21 20:21:43 +00:00
|
|
|
}
|
2011-10-14 07:56:33 +00:00
|
|
|
return NAN_FLT;
|
2010-02-21 18:01:41 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 10:51:19 +02:00
|
|
|
int BKE_sound_scene_playing(Scene *scene)
|
2010-02-21 18:01:41 +00:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2016-12-27 20:47:01 +01:00
|
|
|
/* Ugly: Blender doesn't like it when the animation is played back during rendering */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (G.is_rendering) {
|
2016-12-27 20:47:01 +01:00
|
|
|
return -1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-03-16 23:45:49 +01:00
|
|
|
/* In case of a "None" audio device, we have no playback information. */
|
2019-05-31 22:51:19 +10:00
|
|
|
if (AUD_Device_getRate(sound_device) == AUD_RATE_INVALID) {
|
2019-05-30 14:21:58 +02:00
|
|
|
return -1;
|
2019-05-31 22:51:19 +10:00
|
|
|
}
|
2019-05-30 14:21:58 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC) {
|
2014-03-03 23:57:59 +01:00
|
|
|
return AUD_isSynchronizerPlaying();
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return -1;
|
2010-02-19 12:20:29 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_free_waveform(bSound *sound)
|
2011-08-09 14:10:32 +00:00
|
|
|
{
|
2018-07-20 12:01:38 +02:00
|
|
|
if ((sound->tags & SOUND_TAGS_WAVEFORM_NO_RELOAD) == 0) {
|
|
|
|
|
SoundWaveform *waveform = sound->waveform;
|
|
|
|
|
if (waveform) {
|
|
|
|
|
if (waveform->data) {
|
|
|
|
|
MEM_freeN(waveform->data);
|
|
|
|
|
}
|
|
|
|
|
MEM_freeN(waveform);
|
2015-01-15 12:51:53 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-20 12:01:38 +02:00
|
|
|
sound->waveform = NULL;
|
|
|
|
|
}
|
|
|
|
|
/* This tag is only valid once. */
|
|
|
|
|
sound->tags &= ~SOUND_TAGS_WAVEFORM_NO_RELOAD;
|
2011-08-09 14:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
2019-06-11 10:55:13 +02:00
|
|
|
void BKE_sound_read_waveform(Main *bmain, bSound *sound, short *stop)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2019-06-11 10:55:13 +02:00
|
|
|
bool need_close_audio_handles = false;
|
|
|
|
|
if (sound->playback_handle == NULL) {
|
2019-08-01 13:53:25 +10:00
|
|
|
/* TODO(sergey): Make it fully independent audio handle. */
|
2020-01-22 13:34:47 +01:00
|
|
|
sound_load_audio(bmain, sound, true);
|
2019-06-11 10:55:13 +02:00
|
|
|
need_close_audio_handles = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-15 12:51:53 +01:00
|
|
|
AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
|
2015-01-24 03:10:23 +11:00
|
|
|
SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
if (info.length > 0) {
|
2011-08-09 14:10:32 +00:00
|
|
|
int length = info.length * SOUND_WAVE_SAMPLES_PER_SECOND;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-08 13:29:21 +10:00
|
|
|
waveform->data = MEM_mallocN(sizeof(float[3]) * length, "SoundWaveform.samples");
|
2014-11-24 18:18:35 +01:00
|
|
|
waveform->length = AUD_readSound(
|
|
|
|
|
sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND, stop);
|
2015-01-15 12:51:53 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Create an empty waveform here if the sound couldn't be
|
|
|
|
|
* read. This indicates that reading the waveform is "done",
|
|
|
|
|
* whereas just setting sound->waveform to NULL causes other
|
|
|
|
|
* code to think the waveform still needs to be created. */
|
|
|
|
|
waveform->data = NULL;
|
|
|
|
|
waveform->length = 0;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-01-15 12:51:53 +01:00
|
|
|
if (*stop) {
|
|
|
|
|
if (waveform->data) {
|
2014-11-24 18:18:35 +01:00
|
|
|
MEM_freeN(waveform->data);
|
|
|
|
|
}
|
2015-01-15 12:51:53 +01:00
|
|
|
MEM_freeN(waveform);
|
2015-01-28 19:45:16 +01:00
|
|
|
BLI_spin_lock(sound->spinlock);
|
2018-07-20 12:11:34 +02:00
|
|
|
sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
|
2015-01-28 19:45:16 +01:00
|
|
|
BLI_spin_unlock(sound->spinlock);
|
2015-01-15 12:51:53 +01:00
|
|
|
return;
|
2011-08-09 14:10:32 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_free_waveform(sound);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-01-28 19:45:16 +01:00
|
|
|
BLI_spin_lock(sound->spinlock);
|
2014-11-24 18:18:35 +01:00
|
|
|
sound->waveform = waveform;
|
2018-07-20 12:11:34 +02:00
|
|
|
sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
|
2015-01-28 19:45:16 +01:00
|
|
|
BLI_spin_unlock(sound->spinlock);
|
2019-06-11 10:55:13 +02:00
|
|
|
|
|
|
|
|
if (need_close_audio_handles) {
|
|
|
|
|
sound_free_audio(sound);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2010-12-22 16:07:57 +00:00
|
|
|
|
2019-06-07 15:54:22 +02:00
|
|
|
static void sound_update_base(Scene *scene, Object *object, void *new_set)
|
2011-08-09 08:38:14 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
NlaTrack *track;
|
|
|
|
|
NlaStrip *strip;
|
|
|
|
|
Speaker *speaker;
|
2017-10-16 17:15:03 -02:00
|
|
|
float quat[4];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
2019-06-07 15:54:22 +02:00
|
|
|
sound_verify_evaluated_id(&object->id);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-07 15:54:22 +02:00
|
|
|
if ((object->type != OB_SPEAKER) || !object->adt) {
|
2017-10-16 17:15:03 -02:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-07 15:54:22 +02:00
|
|
|
for (track = object->adt->nla_tracks.first; track; track = track->next) {
|
2017-10-16 17:15:03 -02:00
|
|
|
for (strip = track->strips.first; strip; strip = strip->next) {
|
|
|
|
|
if (strip->type != NLASTRIP_TYPE_SOUND) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-06-07 15:54:22 +02:00
|
|
|
speaker = (Speaker *)object->data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-10-16 17:15:03 -02:00
|
|
|
if (AUD_removeSet(scene->speaker_handles, strip->speaker_handle)) {
|
|
|
|
|
if (speaker->sound) {
|
|
|
|
|
AUD_SequenceEntry_move(strip->speaker_handle, (double)strip->start / FPS, FLT_MAX, 0);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
AUD_Sequence_remove(scene->sound_scene, strip->speaker_handle);
|
|
|
|
|
strip->speaker_handle = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-10-16 17:15:03 -02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (speaker->sound) {
|
|
|
|
|
strip->speaker_handle = AUD_Sequence_add(scene->sound_scene,
|
|
|
|
|
speaker->sound->playback_handle,
|
|
|
|
|
(double)strip->start / FPS,
|
|
|
|
|
FLT_MAX,
|
|
|
|
|
0);
|
|
|
|
|
AUD_SequenceEntry_setRelative(strip->speaker_handle, 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-10-16 17:15:03 -02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-10-16 17:15:03 -02:00
|
|
|
if (strip->speaker_handle) {
|
|
|
|
|
const bool mute = ((strip->flag & NLASTRIP_FLAG_MUTED) || (speaker->flag & SPK_MUTED));
|
|
|
|
|
AUD_addSet(new_set, strip->speaker_handle);
|
|
|
|
|
AUD_SequenceEntry_setVolumeMaximum(strip->speaker_handle, speaker->volume_max);
|
|
|
|
|
AUD_SequenceEntry_setVolumeMinimum(strip->speaker_handle, speaker->volume_min);
|
|
|
|
|
AUD_SequenceEntry_setDistanceMaximum(strip->speaker_handle, speaker->distance_max);
|
|
|
|
|
AUD_SequenceEntry_setDistanceReference(strip->speaker_handle, speaker->distance_reference);
|
|
|
|
|
AUD_SequenceEntry_setAttenuation(strip->speaker_handle, speaker->attenuation);
|
|
|
|
|
AUD_SequenceEntry_setConeAngleOuter(strip->speaker_handle, speaker->cone_angle_outer);
|
|
|
|
|
AUD_SequenceEntry_setConeAngleInner(strip->speaker_handle, speaker->cone_angle_inner);
|
|
|
|
|
AUD_SequenceEntry_setConeVolumeOuter(strip->speaker_handle, speaker->cone_volume_outer);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-07 15:54:22 +02:00
|
|
|
mat4_to_quat(quat, object->obmat);
|
2017-10-16 17:15:03 -02:00
|
|
|
AUD_SequenceEntry_setAnimationData(
|
2019-06-07 15:54:22 +02:00
|
|
|
strip->speaker_handle, AUD_AP_LOCATION, CFRA, object->obmat[3], 1);
|
2017-10-16 17:15:03 -02:00
|
|
|
AUD_SequenceEntry_setAnimationData(
|
|
|
|
|
strip->speaker_handle, AUD_AP_ORIENTATION, CFRA, quat, 1);
|
|
|
|
|
AUD_SequenceEntry_setAnimationData(
|
|
|
|
|
strip->speaker_handle, AUD_AP_VOLUME, CFRA, &speaker->volume, 1);
|
|
|
|
|
AUD_SequenceEntry_setAnimationData(
|
|
|
|
|
strip->speaker_handle, AUD_AP_PITCH, CFRA, &speaker->pitch, 1);
|
|
|
|
|
AUD_SequenceEntry_setSound(strip->speaker_handle, speaker->sound->playback_handle);
|
|
|
|
|
AUD_SequenceEntry_setMuted(strip->speaker_handle, mute);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-07 10:58:51 +02:00
|
|
|
void BKE_sound_update_scene(Depsgraph *depsgraph, Scene *scene)
|
2017-10-16 17:15:03 -02:00
|
|
|
{
|
2019-06-04 16:52:48 +02:00
|
|
|
sound_verify_evaluated_id(&scene->id);
|
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
void *new_set = AUD_createSet();
|
|
|
|
|
void *handle;
|
2011-08-09 08:38:14 +00:00
|
|
|
float quat[4];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-11 14:44:13 +11:00
|
|
|
/* cheap test to skip looping over all objects (no speakers is a common case) */
|
2019-06-07 10:58:51 +02:00
|
|
|
if (DEG_id_type_any_exists(depsgraph, ID_SPK)) {
|
2019-06-07 15:54:22 +02:00
|
|
|
DEG_OBJECT_ITER_BEGIN (depsgraph,
|
|
|
|
|
object,
|
|
|
|
|
(DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
|
|
|
|
|
DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY |
|
|
|
|
|
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET)) {
|
|
|
|
|
sound_update_base(scene, object, new_set);
|
2017-10-16 17:15:03 -02:00
|
|
|
}
|
2019-06-07 15:54:22 +02:00
|
|
|
DEG_OBJECT_ITER_END;
|
2011-08-09 08:38:14 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
while ((handle = AUD_getSet(scene->speaker_handles))) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_remove(scene->sound_scene, handle);
|
2011-08-09 08:38:14 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
if (scene->camera) {
|
2011-08-09 08:38:14 +00:00
|
|
|
mat4_to_quat(quat, scene->camera->obmat);
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_setAnimationData(
|
|
|
|
|
scene->sound_scene, AUD_AP_LOCATION, CFRA, scene->camera->obmat[3], 1);
|
|
|
|
|
AUD_Sequence_setAnimationData(scene->sound_scene, AUD_AP_ORIENTATION, CFRA, quat, 1);
|
2011-08-09 08:38:14 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-08-09 08:38:14 +00:00
|
|
|
AUD_destroySet(scene->speaker_handles);
|
|
|
|
|
scene->speaker_handles = new_set;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void *BKE_sound_get_factory(void *sound)
|
2011-06-05 22:06:29 +00:00
|
|
|
{
|
2014-04-15 10:59:42 +02:00
|
|
|
return ((bSound *)sound)->playback_handle;
|
2011-06-05 22:06:29 +00:00
|
|
|
}
|
2011-06-23 17:30:56 +00:00
|
|
|
|
2019-06-11 10:55:13 +02:00
|
|
|
float BKE_sound_get_length(Main *bmain, bSound *sound)
|
2012-05-10 15:10:51 +00:00
|
|
|
{
|
2019-06-11 10:55:13 +02:00
|
|
|
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;
|
|
|
|
|
}
|
2012-05-10 15:10:51 +00:00
|
|
|
return info.length;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-29 10:43:32 +10:00
|
|
|
char **BKE_sound_get_device_names(void)
|
2015-07-24 15:44:17 +02:00
|
|
|
{
|
2015-07-29 10:43:32 +10:00
|
|
|
if (audio_device_names == NULL) {
|
2015-07-24 15:44:17 +02:00
|
|
|
audio_device_names = AUD_getDeviceNames();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return audio_device_names;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 10:55:13 +02:00
|
|
|
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;
|
2022-05-19 20:58:55 +02:00
|
|
|
sound_info->specs.samplerate = info.specs.rate;
|
2019-06-11 10:55:13 +02:00
|
|
|
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);
|
|
|
|
|
}
|
2019-08-01 13:53:25 +10:00
|
|
|
/* TODO(sergey): Make it fully independent audio handle. */
|
2020-01-22 13:34:47 +01:00
|
|
|
/* Don't free waveforms during non-destructive queries.
|
|
|
|
|
* This causes unnecessary recalculation - see T69921 */
|
|
|
|
|
sound_load_audio(main, sound, false);
|
2019-06-11 10:55:13 +02:00
|
|
|
const bool result = sound_info_from_playback_handle(sound->playback_handle, sound_info);
|
|
|
|
|
sound_free_audio(sound);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-22 16:55:09 +02:00
|
|
|
bool BKE_sound_stream_info_get(struct Main *main,
|
|
|
|
|
const char *filepath,
|
|
|
|
|
int stream,
|
|
|
|
|
SoundStreamInfo *sound_info)
|
2021-08-30 22:36:02 +02:00
|
|
|
{
|
2021-12-14 21:32:14 +11:00
|
|
|
const char *blendfile_path = BKE_main_blendfile_path(main);
|
2021-08-30 22:36:02 +02:00
|
|
|
char str[FILE_MAX];
|
|
|
|
|
AUD_Sound *sound;
|
|
|
|
|
AUD_StreamInfo *stream_infos;
|
|
|
|
|
int stream_count;
|
|
|
|
|
|
|
|
|
|
BLI_strncpy(str, filepath, sizeof(str));
|
2021-12-14 21:32:14 +11:00
|
|
|
BLI_path_abs(str, blendfile_path);
|
2021-08-30 22:36:02 +02:00
|
|
|
|
|
|
|
|
sound = AUD_Sound_file(str);
|
|
|
|
|
if (!sound) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stream_count = AUD_Sound_getFileStreams(sound, &stream_infos);
|
|
|
|
|
|
|
|
|
|
AUD_Sound_free(sound);
|
|
|
|
|
|
|
|
|
|
if (!stream_infos) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((stream < 0) || (stream >= stream_count)) {
|
|
|
|
|
free(stream_infos);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sound_info->start = stream_infos[stream].start;
|
|
|
|
|
sound_info->duration = stream_infos[stream].duration;
|
|
|
|
|
|
|
|
|
|
free(stream_infos);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-15 10:59:42 +02:00
|
|
|
#else /* WITH_AUDASPACE */
|
2011-06-23 09:27:56 +00:00
|
|
|
|
|
|
|
|
# include "BLI_utildefines.h"
|
|
|
|
|
|
2015-07-28 14:52:21 +02:00
|
|
|
void BKE_sound_force_device(const char *UNUSED(device))
|
|
|
|
|
{
|
|
|
|
|
}
|
2015-03-26 16:33:20 +05:00
|
|
|
void BKE_sound_init_once(void)
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_init(Main *UNUSED(bmain))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void BKE_sound_exit(void)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void BKE_sound_exit_once(void)
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_cache(bSound *UNUSED(sound))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_delete_cache(bSound *UNUSED(sound))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_load(Main *UNUSED(bmain), bSound *UNUSED(sound))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_create_scene(Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_destroy_scene(Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2020-03-29 16:34:23 +11:00
|
|
|
void BKE_sound_lock(void)
|
2020-03-23 09:33:02 +01:00
|
|
|
{
|
|
|
|
|
}
|
2020-03-29 16:34:23 +11:00
|
|
|
void BKE_sound_unlock(void)
|
2020-03-23 09:33:02 +01:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_reset_scene_specs(Scene *UNUSED(scene))
|
2017-01-06 18:18:20 +01:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_mute_scene(Scene *UNUSED(scene), int UNUSED(muted))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void *BKE_sound_scene_add_scene_sound(Scene *UNUSED(scene),
|
|
|
|
|
Sequence *UNUSED(sequence),
|
2015-03-26 16:33:20 +05:00
|
|
|
int UNUSED(startframe),
|
|
|
|
|
int UNUSED(endframe),
|
|
|
|
|
int UNUSED(frameskip))
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void *BKE_sound_scene_add_scene_sound_defaults(Scene *UNUSED(scene), Sequence *UNUSED(sequence))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void *BKE_sound_add_scene_sound(Scene *UNUSED(scene),
|
|
|
|
|
Sequence *UNUSED(sequence),
|
2015-03-26 16:33:20 +05:00
|
|
|
int UNUSED(startframe),
|
|
|
|
|
int UNUSED(endframe),
|
|
|
|
|
int UNUSED(frameskip))
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void *BKE_sound_add_scene_sound_defaults(Scene *UNUSED(scene), Sequence *UNUSED(sequence))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_remove_scene_sound(Scene *UNUSED(scene), void *UNUSED(handle))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void BKE_sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute))
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
|
|
|
|
}
|
2022-06-02 01:39:40 +02:00
|
|
|
void BKE_sound_move_scene_sound(const Scene *UNUSED(scene),
|
2015-03-26 16:33:20 +05:00
|
|
|
void *UNUSED(handle),
|
|
|
|
|
int UNUSED(startframe),
|
|
|
|
|
int UNUSED(endframe),
|
2021-08-16 23:19:54 +10:00
|
|
|
int UNUSED(frameskip),
|
|
|
|
|
double UNUSED(audio_offset))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_move_scene_sound_defaults(Scene *UNUSED(scene), Sequence *UNUSED(sequence))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_play_scene(Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_stop_scene(Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_seek_scene(Main *UNUSED(bmain), Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2020-05-03 15:25:52 +02:00
|
|
|
double BKE_sound_sync_scene(Scene *UNUSED(scene))
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
2015-03-26 16:33:20 +05:00
|
|
|
return NAN_FLT;
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
int BKE_sound_scene_playing(Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2020-11-10 09:24:47 +11:00
|
|
|
void BKE_sound_read_waveform(Main *bmain,
|
|
|
|
|
bSound *sound,
|
|
|
|
|
/* NOLINTNEXTLINE: readability-non-const-parameter. */
|
|
|
|
|
short *stop)
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
2019-06-12 08:16:58 +10:00
|
|
|
UNUSED_VARS(sound, stop, bmain);
|
2015-03-26 16:33:20 +05:00
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_init_main(Main *UNUSED(bmain))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void BKE_sound_set_cfra(int UNUSED(cfra))
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_update_sequencer(Main *UNUSED(main), bSound *UNUSED(sound))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-06-07 10:58:51 +02:00
|
|
|
void BKE_sound_update_scene(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_update_scene_sound(void *UNUSED(handle), bSound *UNUSED(sound))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_update_scene_listener(Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
2019-06-11 10:55:13 +02:00
|
|
|
void BKE_sound_update_fps(Main *UNUSED(bmain), Scene *UNUSED(scene))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void BKE_sound_set_scene_sound_volume(void *UNUSED(handle),
|
|
|
|
|
float UNUSED(volume),
|
|
|
|
|
char UNUSED(animated))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void BKE_sound_set_scene_sound_pan(void *UNUSED(handle), float UNUSED(pan), char UNUSED(animated))
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-05-01 10:51:19 +02:00
|
|
|
void BKE_sound_set_scene_volume(Scene *UNUSED(scene), float UNUSED(volume))
|
2015-03-26 16:33:20 +05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
void BKE_sound_set_scene_sound_pitch(void *UNUSED(handle),
|
|
|
|
|
float UNUSED(pitch),
|
|
|
|
|
char UNUSED(animated))
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-06-11 10:55:13 +02:00
|
|
|
float BKE_sound_get_length(struct Main *UNUSED(bmain), bSound *UNUSED(sound))
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
2015-03-26 16:33:20 +05:00
|
|
|
return 0;
|
2017-08-18 18:16:13 +10:00
|
|
|
}
|
|
|
|
|
char **BKE_sound_get_device_names(void)
|
|
|
|
|
{
|
|
|
|
|
static char *names[1] = {NULL};
|
|
|
|
|
return names;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
void BKE_sound_free_waveform(bSound *UNUSED(sound))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 10:55:13 +02:00
|
|
|
bool BKE_sound_info_get(struct Main *UNUSED(main),
|
|
|
|
|
struct bSound *UNUSED(sound),
|
|
|
|
|
SoundInfo *UNUSED(sound_info))
|
2019-06-04 16:52:48 +02:00
|
|
|
{
|
2019-06-11 10:55:13 +02:00
|
|
|
return false;
|
2019-06-04 16:52:48 +02:00
|
|
|
}
|
|
|
|
|
|
2021-08-30 22:36:02 +02:00
|
|
|
bool BKE_sound_stream_info_get(struct Main *UNUSED(main),
|
|
|
|
|
const char *UNUSED(filepath),
|
|
|
|
|
int UNUSED(stream),
|
|
|
|
|
SoundStreamInfo *UNUSED(sound_info))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-15 10:59:42 +02:00
|
|
|
#endif /* WITH_AUDASPACE */
|
2019-06-04 16:52:48 +02:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-03 15:25:52 +02:00
|
|
|
void BKE_sound_jack_scene_update(Scene *scene, int mode, double time)
|
2019-06-04 16:52:48 +02:00
|
|
|
{
|
|
|
|
|
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);
|
2019-06-17 12:54:56 +02:00
|
|
|
if (sound->id.recalc & ID_RECALC_AUDIO) {
|
|
|
|
|
BKE_sound_load(bmain, sound);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-06-04 16:52:48 +02:00
|
|
|
BKE_sound_ensure_loaded(bmain, sound);
|
|
|
|
|
}
|