2011-09-18 12:06:28 +00:00
|
|
|
/*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
#include <string.h>
|
2005-10-09 16:57:49 +00:00
|
|
|
#include <stdlib.h>
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.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
|
|
|
|
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_scene_types.h"
|
2010-02-07 23:41:17 +00:00
|
|
|
#include "DNA_sequence_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_packedFile_types.h"
|
2009-08-09 21:16:39 +00:00
|
|
|
#include "DNA_screen_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"
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2011-06-23 09:27:56 +00:00
|
|
|
#ifdef WITH_AUDASPACE
|
2017-08-18 08:24:12 +02:00
|
|
|
# include <AUD_Sound.h>
|
|
|
|
|
# include <AUD_Sequence.h>
|
|
|
|
|
# include <AUD_Handle.h>
|
|
|
|
|
# include <AUD_Special.h>
|
|
|
|
|
# include "../../../intern/audaspace/intern/AUD_Set.h"
|
2011-06-23 09:27:56 +00:00
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
#include "BKE_global.h"
|
|
|
|
|
#include "BKE_main.h"
|
|
|
|
|
#include "BKE_sound.h"
|
2009-08-09 21:16:39 +00:00
|
|
|
#include "BKE_library.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_packedFile.h"
|
2011-07-26 13:56:31 +00:00
|
|
|
#include "BKE_sequencer.h"
|
2011-08-30 07:57:55 +00:00
|
|
|
#include "BKE_scene.h"
|
2010-02-07 23:41:17 +00: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
|
|
|
|
2015-10-06 19:40:15 +11:00
|
|
|
bSound *BKE_sound_new_file(struct Main *bmain, const char *filepath)
|
2011-06-23 09:27:56 +00:00
|
|
|
{
|
2015-05-03 03:28:43 +10:00
|
|
|
bSound *sound;
|
2014-04-27 00:20:13 +10:00
|
|
|
const char *path;
|
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));
|
2011-06-23 09:27:56 +00:00
|
|
|
|
2018-06-05 15:10:33 +02:00
|
|
|
path = BKE_main_blendfile_path(bmain);
|
2011-06-23 09:27:56 +00:00
|
|
|
|
|
|
|
|
BLI_path_abs(str, path);
|
|
|
|
|
|
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);
|
2015-10-06 19:40:15 +11:00
|
|
|
BLI_strncpy(sound->name, 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
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_load(bmain, sound);
|
2011-06-23 09:27:56 +00:00
|
|
|
|
|
|
|
|
return sound;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-06 19:40:15 +11:00
|
|
|
bSound *BKE_sound_new_file_exists_ex(struct Main *bmain, const char *filepath, bool *r_exists)
|
|
|
|
|
{
|
|
|
|
|
bSound *sound;
|
|
|
|
|
char str[FILE_MAX], strtest[FILE_MAX];
|
|
|
|
|
|
|
|
|
|
BLI_strncpy(str, filepath, sizeof(str));
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_path_abs(str, BKE_main_blendfile_path(bmain));
|
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) {
|
2015-10-06 19:40:15 +11:00
|
|
|
BLI_strncpy(strtest, sound->name, sizeof(sound->name));
|
|
|
|
|
BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &sound->id));
|
|
|
|
|
|
|
|
|
|
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! */
|
2015-10-06 19:40:15 +11:00
|
|
|
if (r_exists)
|
|
|
|
|
*r_exists = true;
|
|
|
|
|
return sound;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r_exists)
|
|
|
|
|
*r_exists = false;
|
|
|
|
|
return BKE_sound_new_file(bmain, filepath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bSound *BKE_sound_new_file_exists(struct Main *bmain, const char *filepath)
|
|
|
|
|
{
|
|
|
|
|
return BKE_sound_new_file_exists_ex(bmain, filepath, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
ID-Remap - Step one: core work (cleanup and rework of generic ID datablock handling).
This commit changes a lot of how IDs are handled internally, especially the unlinking/freeing
processes. So far, this was very fuzy, to summarize cleanly deleting or replacing a datablock
was pretty much impossible, except for a few special cases.
Also, unlinking was handled by each datatype, in a rather messy and prone-to-errors way (quite
a few ID usages were missed or wrongly handled that way).
One of the main goal of id-remap branch was to cleanup this, and fatorize ID links handling
by using library_query utils to allow generic handling of those, which is now the case
(now, generic ID links handling is only "knwon" from readfile.c and library_query.c).
This commit also adds backends to allow live replacement and deletion of datablocks in Blender
(so-called 'remapping' process, where we replace all usages of a given ID pointer by a new one,
or NULL one in case of unlinking).
This will allow nice new features, like ability to easily reload or relocate libraries, real immediate
deletion of datablocks in blender, replacement of one datablock by another, etc.
Some of those are for next commits.
A word of warning: this commit is highly risky, because it affects potentially a lot in Blender core.
Though it was tested rather deeply, being totally impossible to check all possible ID usage cases,
it's likely there are some remaining issues and bugs in new code... Please report them! ;)
Review task: D2027 (https://developer.blender.org/D2027).
Reviewed by campbellbarton, thanks a bunch.
2016-06-22 17:29:38 +02:00
|
|
|
/** Free (or release) any data used by this sound (does not free the sound itself). */
|
2012-05-10 15:22:29 +00:00
|
|
|
void BKE_sound_free(bSound *sound)
|
2011-06-23 09:27:56 +00:00
|
|
|
{
|
ID-Remap - Step one: core work (cleanup and rework of generic ID datablock handling).
This commit changes a lot of how IDs are handled internally, especially the unlinking/freeing
processes. So far, this was very fuzy, to summarize cleanly deleting or replacing a datablock
was pretty much impossible, except for a few special cases.
Also, unlinking was handled by each datatype, in a rather messy and prone-to-errors way (quite
a few ID usages were missed or wrongly handled that way).
One of the main goal of id-remap branch was to cleanup this, and fatorize ID links handling
by using library_query utils to allow generic handling of those, which is now the case
(now, generic ID links handling is only "knwon" from readfile.c and library_query.c).
This commit also adds backends to allow live replacement and deletion of datablocks in Blender
(so-called 'remapping' process, where we replace all usages of a given ID pointer by a new one,
or NULL one in case of unlinking).
This will allow nice new features, like ability to easily reload or relocate libraries, real immediate
deletion of datablocks in blender, replacement of one datablock by another, etc.
Some of those are for next commits.
A word of warning: this commit is highly risky, because it affects potentially a lot in Blender core.
Though it was tested rather deeply, being totally impossible to check all possible ID usage cases,
it's likely there are some remaining issues and bugs in new code... Please report them! ;)
Review task: D2027 (https://developer.blender.org/D2027).
Reviewed by campbellbarton, thanks a bunch.
2016-06-22 17:29:38 +02:00
|
|
|
/* No animdata here. */
|
|
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
if (sound->packedfile) {
|
2011-06-23 09:27:56 +00:00
|
|
|
freePackedFile(sound->packedfile);
|
|
|
|
|
sound->packedfile = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_AUDASPACE
|
2012-04-28 06:31:57 +00:00
|
|
|
if (sound->handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sound_free(sound->handle);
|
2011-06-23 09:27:56 +00:00
|
|
|
sound->handle = NULL;
|
|
|
|
|
sound->playback_handle = NULL;
|
|
|
|
|
}
|
2011-06-23 17:30:56 +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);
|
2011-08-07 11:54:58 +00:00
|
|
|
sound->cache = NULL;
|
2011-06-23 17:30:56 +00:00
|
|
|
}
|
2011-08-09 14:10:32 +00:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_free_waveform(sound);
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2017-02-06 11:18:20 +01:00
|
|
|
#endif /* WITH_AUDASPACE */
|
2015-01-28 19:45:16 +01:00
|
|
|
if (sound->spinlock) {
|
|
|
|
|
BLI_spin_end(sound->spinlock);
|
|
|
|
|
MEM_freeN(sound->spinlock);
|
|
|
|
|
sound->spinlock = NULL;
|
2017-02-06 11:18:20 +01:00
|
|
|
}
|
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
|
|
|
/**
|
|
|
|
|
* Only copy internal data of Sound ID from source to already allocated/initialized destination.
|
2019-02-04 20:39:59 +01:00
|
|
|
* You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs.
|
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
|
|
|
*
|
|
|
|
|
* WARNING! This function will not handle ID user count!
|
|
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
|
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
|
|
|
*/
|
|
|
|
|
void BKE_sound_copy_data(Main *bmain, bSound *sound_dst, const bSound *UNUSED(sound_src), const int UNUSED(flag))
|
|
|
|
|
{
|
|
|
|
|
sound_dst->handle = NULL;
|
|
|
|
|
sound_dst->cache = NULL;
|
|
|
|
|
sound_dst->waveform = NULL;
|
|
|
|
|
sound_dst->playback_handle = NULL;
|
|
|
|
|
sound_dst->spinlock = NULL; /* Think this is OK? Otherwise, easy to create new spinlock here... */
|
|
|
|
|
|
|
|
|
|
/* Just to be sure, should not have any value actually after reading time. */
|
|
|
|
|
sound_dst->ipo = NULL;
|
|
|
|
|
sound_dst->newpackedfile = NULL;
|
|
|
|
|
|
|
|
|
|
if (sound_dst->packedfile) {
|
|
|
|
|
sound_dst->packedfile = dupPackedFile(sound_dst->packedfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize whole runtime (audaspace) stuff. */
|
|
|
|
|
BKE_sound_load(bmain, sound_dst);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-21 16:09:08 +02:00
|
|
|
void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
|
|
|
|
|
{
|
|
|
|
|
BKE_id_make_local_generic(bmain, &sound->id, true, lib_local);
|
|
|
|
|
}
|
|
|
|
|
|
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
|
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
|
|
|
{
|
2016-12-27 20:47:01 +01:00
|
|
|
// Ugly: Blender doesn't like it when the animation is played back during rendering
|
|
|
|
|
if (G.is_rendering)
|
|
|
|
|
return;
|
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
struct Main *bmain = (struct Main *)data;
|
|
|
|
|
struct Scene *scene;
|
2010-02-21 18:01:41 +00:00
|
|
|
|
2019-03-08 09:29:17 +11:00
|
|
|
scene = bmain->scenes.first;
|
2012-04-28 06:31:57 +00:00
|
|
|
while (scene) {
|
|
|
|
|
if (scene->audio.flag & AUDIO_SYNC) {
|
2012-02-23 02:17:50 +00:00
|
|
|
if (mode)
|
2015-03-26 13:19:33 +01:00
|
|
|
BKE_sound_play_scene(scene);
|
2010-02-21 18:01:41 +00:00
|
|
|
else
|
2015-03-26 13:19:33 +01:00
|
|
|
BKE_sound_stop_scene(scene);
|
2015-05-15 16:51:17 +02:00
|
|
|
if (scene->playback_handle)
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_setPosition(scene->playback_handle, time);
|
2010-02-21 18:01:41 +00:00
|
|
|
}
|
|
|
|
|
scene = scene->id.next;
|
|
|
|
|
}
|
|
|
|
|
}
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_init(struct 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();
|
|
|
|
|
|
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;
|
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;
|
|
|
|
|
|
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];
|
|
|
|
|
|
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
|
|
|
}
|
2015-07-24 15:44:17 +02:00
|
|
|
else
|
|
|
|
|
device_name = force_device;
|
2014-03-03 23:57:59 +01:00
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (buffersize < 128)
|
2014-03-04 13:44:15 +01:00
|
|
|
buffersize = 1024;
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (specs.rate < AUD_RATE_8000)
|
2015-12-27 16:33:54 +01:00
|
|
|
specs.rate = AUD_RATE_48000;
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (specs.format <= AUD_FORMAT_INVALID)
|
2009-08-09 21:16:39 +00:00
|
|
|
specs.format = AUD_FORMAT_S16;
|
|
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (specs.channels <= AUD_CHANNELS_INVALID)
|
2009-08-09 21:16:39 +00:00
|
|
|
specs.channels = AUD_CHANNELS_STEREO;
|
|
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
if (!(sound_device = AUD_init(device_name, specs, buffersize, "Blender")))
|
|
|
|
|
sound_device = AUD_init("Null", specs, buffersize, "Blender");
|
2011-08-09 08:38:14 +00:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_init_main(bmain);
|
2011-08-09 08:38:14 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_init_main(struct Main *bmain)
|
2011-08-09 08:38:14 +00:00
|
|
|
{
|
2010-02-21 19:54:18 +00:00
|
|
|
#ifdef WITH_JACK
|
2016-11-09 00:06:49 +01:00
|
|
|
if (sound_device)
|
|
|
|
|
AUD_setSynchronizerCallback(sound_sync_callback, bmain);
|
2010-10-17 06:38:56 +00:00
|
|
|
#else
|
|
|
|
|
(void)bmain; /* unused */
|
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();
|
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
|
|
|
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
|
2015-03-26 11:39:08 +01:00
|
|
|
bSound *BKE_sound_new_buffer(struct 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;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:39:08 +01:00
|
|
|
bSound *BKE_sound_new_limiter(struct 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
|
|
|
{
|
2011-08-07 11:54:58 +00:00
|
|
|
sound->flags |= SOUND_FLAGS_CACHING;
|
2012-02-23 02:17:50 +00:00
|
|
|
if (sound->cache)
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sound_free(sound->cache);
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
sound->cache = AUD_Sound_cache(sound->handle);
|
2012-02-23 02:17:50 +00:00
|
|
|
if (sound->cache)
|
2011-10-13 22:19:29 +00:00
|
|
|
sound->playback_handle = sound->cache;
|
|
|
|
|
else
|
|
|
|
|
sound->playback_handle = sound->handle;
|
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
|
|
|
{
|
2011-08-07 11:54:58 +00:00
|
|
|
sound->flags &= ~SOUND_FLAGS_CACHING;
|
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
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_load(struct Main *bmain, bSound *sound)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2012-04-28 06:31:57 +00:00
|
|
|
if (sound) {
|
|
|
|
|
if (sound->cache) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sound_free(sound->cache);
|
2011-08-07 11:54:58 +00:00
|
|
|
sound->cache = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
if (sound->handle) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sound_free(sound->handle);
|
2009-08-26 14:19:29 +00:00
|
|
|
sound->handle = NULL;
|
2010-02-07 23:41:17 +00:00
|
|
|
sound->playback_handle = NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
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
|
2012-04-28 06:31:57 +00:00
|
|
|
switch (sound->type)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
case SOUND_TYPE_FILE:
|
2009-08-26 14:19:29 +00:00
|
|
|
#endif
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
|
|
|
|
char fullpath[FILE_MAX];
|
|
|
|
|
|
|
|
|
|
/* load sound */
|
2012-05-06 15:15:33 +00:00
|
|
|
PackedFile *pf = sound->packedfile;
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* don't modify soundact->sound->name, only change a copy */
|
2009-08-09 21:16:39 +00:00
|
|
|
BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
|
2011-10-08 11:11:54 +00:00
|
|
|
BLI_path_abs(fullpath, ID_BLEND_PATH(bmain, &sound->id));
|
2009-08-09 21:16:39 +00:00
|
|
|
|
|
|
|
|
/* but we need a packed file then */
|
|
|
|
|
if (pf)
|
2014-11-13 00:33:28 +13:00
|
|
|
sound->handle = AUD_Sound_bufferFile((unsigned char *) pf->data, pf->size);
|
2009-08-09 21:16:39 +00:00
|
|
|
/* or else load it from disk */
|
|
|
|
|
else
|
2014-11-13 00:33:28 +13:00
|
|
|
sound->handle = AUD_Sound_file(fullpath);
|
2010-11-13 13:44:45 +00:00
|
|
|
}
|
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:
|
|
|
|
|
if (sound->child_sound && sound->child_sound->handle)
|
|
|
|
|
sound->handle = AUD_bufferSound(sound->child_sound->handle);
|
|
|
|
|
break;
|
|
|
|
|
case SOUND_TYPE_LIMITER:
|
|
|
|
|
if (sound->child_sound && sound->child_sound->handle)
|
|
|
|
|
sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
|
|
|
|
|
break;
|
2012-05-10 15:22:29 +00:00
|
|
|
}
|
2009-08-26 14:19:29 +00:00
|
|
|
#endif
|
2012-04-28 06:31:57 +00:00
|
|
|
if (sound->flags & SOUND_FLAGS_MONO) {
|
2014-11-13 00:33:28 +13:00
|
|
|
void *handle = AUD_Sound_rechannel(sound->handle, AUD_CHANNELS_MONO);
|
|
|
|
|
AUD_Sound_free(sound->handle);
|
2011-08-11 11:41:24 +00:00
|
|
|
sound->handle = handle;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
if (sound->flags & SOUND_FLAGS_CACHING) {
|
2014-11-13 00:33:28 +13:00
|
|
|
sound->cache = AUD_Sound_cache(sound->handle);
|
2011-08-07 11:54:58 +00:00
|
|
|
}
|
|
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (sound->cache)
|
2010-02-07 23:41:17 +00:00
|
|
|
sound->playback_handle = sound->cache;
|
|
|
|
|
else
|
|
|
|
|
sound->playback_handle = sound->handle;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_update_sequencer(bmain, sound);
|
2011-07-26 13:56:31 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:39:08 +01:00
|
|
|
AUD_Device *BKE_sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
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
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_create_scene(struct Scene *scene)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2012-05-09 15:54:22 +00:00
|
|
|
/* should be done in version patch, but this gets called before */
|
|
|
|
|
if (scene->r.frs_sec_base == 0)
|
|
|
|
|
scene->r.frs_sec_base = 1;
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_destroy_scene(struct 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_stop(scene->playback_handle);
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->sound_scrub_handle)
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_stop(scene->sound_scrub_handle);
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->sound_scene)
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_free(scene->sound_scene);
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->speaker_handles)
|
2011-08-03 09:25:40 +00:00
|
|
|
AUD_destroySet(scene->speaker_handles);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2017-01-06 18:18:20 +01:00
|
|
|
void BKE_sound_reset_scene_specs(struct Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
AUD_Specs specs;
|
|
|
|
|
|
|
|
|
|
specs.channels = AUD_Device_getChannels(sound_device);
|
|
|
|
|
specs.rate = AUD_Device_getRate(sound_device);
|
|
|
|
|
|
|
|
|
|
AUD_Sequence_setSpecs(scene->sound_scene, specs);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_mute_scene(struct Scene *scene, int muted)
|
2011-04-10 22:40:37 +00:00
|
|
|
{
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->sound_scene)
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_setMuted(scene->sound_scene, muted);
|
2011-04-10 22:40:37 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_update_fps(struct Scene *scene)
|
2011-07-26 13:56:31 +00:00
|
|
|
{
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->sound_scene)
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Sequence_setFPS(scene->sound_scene, FPS);
|
2013-08-20 19:50:31 +00:00
|
|
|
|
|
|
|
|
BKE_sequencer_refresh_sound_length(scene);
|
2011-07-26 13:56:31 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_update_scene_listener(struct Scene *scene)
|
2011-08-03 09:25:40 +00:00
|
|
|
{
|
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(struct Scene *scene, struct Sequence *sequence,
|
2014-04-15 10:59:42 +02:00
|
|
|
int startframe, int endframe, int frameskip)
|
2010-03-20 11:15:16 +00:00
|
|
|
{
|
2019-01-13 21:25:29 -08: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, frameskip / fps);
|
|
|
|
|
}
|
2010-03-21 15:40:36 +00:00
|
|
|
return NULL;
|
2010-03-20 11:15:16 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void *BKE_sound_scene_add_scene_sound_defaults(struct Scene *scene, struct 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,
|
2012-01-05 10:34:50 +00:00
|
|
|
sequence->startdisp, sequence->enddisp,
|
|
|
|
|
sequence->startofs + sequence->anim_startofs);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void *BKE_sound_add_scene_sound(struct Scene *scene, struct Sequence *sequence, int startframe, int endframe, int frameskip)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2018-12-21 16:50:59 +01:00
|
|
|
/* Happens when sequence's sound datablock was removed. */
|
|
|
|
|
if (sequence->sound == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2014-04-15 10:59:42 +02:00
|
|
|
const double fps = FPS;
|
2014-11-13 00:33:28 +13:00
|
|
|
void *handle = AUD_Sequence_add(scene->sound_scene, sequence->sound->playback_handle,
|
2014-04-15 10:59:42 +02:00
|
|
|
startframe / fps, endframe / fps, frameskip / fps);
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_SequenceEntry_setMuted(handle, (sequence->flag & SEQ_MUTE) != 0);
|
|
|
|
|
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_VOLUME, CFRA, &sequence->volume, 0);
|
|
|
|
|
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PITCH, CFRA, &sequence->pitch, 0);
|
|
|
|
|
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PANNING, CFRA, &sequence->pan, 0);
|
2011-08-07 11:54:58 +00:00
|
|
|
return handle;
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void *BKE_sound_add_scene_sound_defaults(struct Scene *scene, struct 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,
|
2018-12-21 16:49:55 +01:00
|
|
|
sequence->startdisp, sequence->enddisp,
|
|
|
|
|
sequence->startofs + sequence->anim_startofs);
|
2012-01-05 10:34:50 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_remove_scene_sound(struct 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
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_move_scene_sound(struct Scene *scene, void *handle, int startframe, int endframe, int frameskip)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2014-04-15 10:59:42 +02:00
|
|
|
const double fps = FPS;
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_SequenceEntry_move(handle, startframe / fps, endframe / fps, frameskip / fps);
|
2011-07-26 13:56:31 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence)
|
2012-01-05 10:34:50 +00:00
|
|
|
{
|
2012-01-05 22:14:38 +00:00
|
|
|
if (sequence->scene_sound) {
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_move_scene_sound(scene, sequence->scene_sound,
|
2012-01-05 22:14:38 +00:00
|
|
|
sequence->startdisp, sequence->enddisp,
|
|
|
|
|
sequence->startofs + sequence->anim_startofs);
|
|
|
|
|
}
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_set_scene_volume(struct 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
|
|
|
{
|
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
|
|
|
{
|
2016-01-08 11:05:39 +01:00
|
|
|
printf("%s\n", __func__);
|
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
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_update_sequencer(struct Main *main, bSound *sound)
|
2011-07-26 13:56:31 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
struct 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) {
|
2012-08-08 11:15:40 +00:00
|
|
|
BKE_sequencer_update_sound(scene, sound);
|
2012-02-23 02:17:50 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2011-02-13 10:52:18 +00:00
|
|
|
static void sound_start_play_scene(struct 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_stop(scene->playback_handle);
|
|
|
|
|
|
2017-01-06 18:18:20 +01:00
|
|
|
BKE_sound_reset_scene_specs(scene);
|
2011-06-21 20:39:41 +00:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
if ((scene->playback_handle = AUD_Device_play(sound_device, scene->sound_scene, 1)))
|
|
|
|
|
AUD_Handle_setLoopCount(scene->playback_handle, -1);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_play_scene(struct Scene *scene)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
2010-02-21 18:01:41 +00:00
|
|
|
AUD_Status status;
|
2014-04-15 10:59:42 +02:00
|
|
|
const float cur_time = (float)((double)CFRA / FPS);
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC)
|
2014-03-03 23:57:59 +01:00
|
|
|
AUD_playSynchronizer();
|
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
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_stop_scene(struct 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
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC)
|
2014-03-03 23:57:59 +01:00
|
|
|
AUD_stopSynchronizer();
|
2011-06-21 20:21:43 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_seek_scene(struct Main *bmain, struct Scene *scene)
|
2009-08-09 21:16:39 +00:00
|
|
|
{
|
2010-02-21 18:01:41 +00:00
|
|
|
AUD_Status status;
|
2011-09-05 19:34:27 +00:00
|
|
|
bScreen *screen;
|
|
|
|
|
int animation_playing;
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2014-04-15 10:59:42 +02:00
|
|
|
const float one_frame = (float)(1.0 / FPS);
|
|
|
|
|
const float cur_time = (float)((double)CFRA / FPS);
|
|
|
|
|
|
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
|
|
|
|
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);
|
2011-06-21 20:21:43 +00: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;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Handle_pause(scene->playback_handle);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2009-09-26 20:03:01 +00: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
|
|
|
}
|
|
|
|
|
}
|
2011-09-05 19:34:27 +00:00
|
|
|
|
2012-04-28 06:31:57 +00: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);
|
2012-04-28 06:31:57 +00: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 {
|
2014-04-15 10:59:42 +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
|
|
|
}
|
|
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_unlock(sound_device);
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
float BKE_sound_sync_scene(struct Scene *scene)
|
2010-02-19 12:20:29 +00:00
|
|
|
{
|
2016-12-27 20:47:01 +01:00
|
|
|
// Ugly: Blender doesn't like it when the animation is played back during rendering
|
|
|
|
|
if (G.is_rendering)
|
|
|
|
|
return NAN_FLT;
|
|
|
|
|
|
2015-05-15 16:51:17 +02:00
|
|
|
if (scene->playback_handle) {
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC)
|
2014-03-03 23:57:59 +01:00
|
|
|
return AUD_getSynchronizerPosition(scene->playback_handle);
|
2011-06-21 20:21:43 +00:00
|
|
|
else
|
2014-11-13 00:33:28 +13: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
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
int BKE_sound_scene_playing(struct Scene *scene)
|
2010-02-21 18:01:41 +00:00
|
|
|
{
|
2016-12-27 20:47:01 +01:00
|
|
|
// Ugly: Blender doesn't like it when the animation is played back during rendering
|
|
|
|
|
if (G.is_rendering)
|
|
|
|
|
return -1;
|
|
|
|
|
|
2012-02-23 02:17:50 +00:00
|
|
|
if (scene->audio.flag & AUDIO_SYNC)
|
2014-03-03 23:57:59 +01:00
|
|
|
return AUD_isSynchronizerPlaying();
|
2010-02-21 18:01:41 +00:00
|
|
|
else
|
|
|
|
|
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
|
|
|
}
|
2011-08-09 14:10:32 +00: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
|
|
|
}
|
|
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
void BKE_sound_read_waveform(bSound *sound, short *stop)
|
2010-02-07 23:41:17 +00:00
|
|
|
{
|
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");
|
2015-01-15 12:51:53 +01: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;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2011-08-09 14:10:32 +00:00
|
|
|
waveform->data = MEM_mallocN(length * sizeof(float) * 3, "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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_free_waveform(sound);
|
2018-06-17 17:05:51 +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);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2010-12-22 16:07:57 +00:00
|
|
|
|
2017-10-16 17:15:03 -02:00
|
|
|
static void sound_update_base(Scene *scene, Base *base, void *new_set)
|
2011-08-09 08:38:14 +00:00
|
|
|
{
|
2017-10-16 17:15:03 -02:00
|
|
|
Object *ob = base->object;
|
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];
|
|
|
|
|
|
|
|
|
|
if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ob->id.tag &= ~LIB_TAG_DOIT;
|
|
|
|
|
|
|
|
|
|
if ((ob->type != OB_SPEAKER) || !ob->adt) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (track = ob->adt->nla_tracks.first; track; track = track->next) {
|
|
|
|
|
for (strip = track->strips.first; strip; strip = strip->next) {
|
|
|
|
|
if (strip->type != NLASTRIP_TYPE_SOUND) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
speaker = (Speaker *)ob->data;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
mat4_to_quat(quat, ob->obmat);
|
|
|
|
|
AUD_SequenceEntry_setAnimationData(strip->speaker_handle, AUD_AP_LOCATION, CFRA, ob->obmat[3], 1);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_sound_update_scene(Main *bmain, Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
Base *base;
|
2012-05-06 15:15:33 +00:00
|
|
|
Scene *sce_it;
|
2011-08-09 08:38:14 +00:00
|
|
|
|
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];
|
|
|
|
|
|
2014-03-11 14:44:13 +11:00
|
|
|
/* cheap test to skip looping over all objects (no speakers is a common case) */
|
2019-03-08 09:29:17 +11:00
|
|
|
if (!BLI_listbase_is_empty(&bmain->speakers)) {
|
|
|
|
|
BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
|
2017-10-16 17:15:03 -02:00
|
|
|
|
2017-11-22 10:52:39 -02:00
|
|
|
for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
|
|
|
|
|
for (base = view_layer->object_bases.first; base; base = base->next) {
|
2017-10-16 17:15:03 -02:00
|
|
|
sound_update_base(scene, base, new_set);
|
2011-08-09 08:38:14 +00:00
|
|
|
}
|
|
|
|
|
}
|
2017-10-16 17:15:03 -02:00
|
|
|
|
|
|
|
|
for (SETLOOPER_SET_ONLY(scene, sce_it, base)) {
|
|
|
|
|
sound_update_base(scene, base, new_set);
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-09 08:38:14 +00: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
|
|
|
}
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
2012-05-10 15:10:51 +00:00
|
|
|
/* stupid wrapper because AUD_C-API.h includes Python.h which makesrna doesn't like */
|
2015-03-26 11:35:41 +01:00
|
|
|
float BKE_sound_get_length(bSound *sound)
|
2012-05-10 15:10:51 +00:00
|
|
|
{
|
|
|
|
|
AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
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) {}
|
|
|
|
|
void BKE_sound_init(struct Main *UNUSED(bmain)) {}
|
|
|
|
|
void BKE_sound_exit(void) {}
|
|
|
|
|
void BKE_sound_exit_once(void) {}
|
|
|
|
|
void BKE_sound_cache(struct bSound *UNUSED(sound)) {}
|
|
|
|
|
void BKE_sound_delete_cache(struct bSound *UNUSED(sound)) {}
|
|
|
|
|
void BKE_sound_load(struct Main *UNUSED(bmain), struct bSound *UNUSED(sound)) {}
|
|
|
|
|
void BKE_sound_create_scene(struct Scene *UNUSED(scene)) {}
|
|
|
|
|
void BKE_sound_destroy_scene(struct Scene *UNUSED(scene)) {}
|
2017-01-06 18:18:20 +01:00
|
|
|
void BKE_sound_reset_scene_specs(struct Scene *UNUSED(scene)) {}
|
2015-03-26 16:33:20 +05:00
|
|
|
void BKE_sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {}
|
|
|
|
|
void *BKE_sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence),
|
|
|
|
|
int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
|
|
|
|
|
void *BKE_sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene),
|
|
|
|
|
struct Sequence *UNUSED(sequence)) { return NULL; }
|
|
|
|
|
void *BKE_sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe),
|
|
|
|
|
int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
|
|
|
|
|
void *BKE_sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) { return NULL; }
|
|
|
|
|
void BKE_sound_remove_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle)) {}
|
|
|
|
|
void BKE_sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute)) {}
|
|
|
|
|
void BKE_sound_move_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle), int UNUSED(startframe),
|
|
|
|
|
int UNUSED(endframe), int UNUSED(frameskip)) {}
|
|
|
|
|
void BKE_sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {}
|
|
|
|
|
void BKE_sound_play_scene(struct Scene *UNUSED(scene)) {}
|
|
|
|
|
void BKE_sound_stop_scene(struct Scene *UNUSED(scene)) {}
|
|
|
|
|
void BKE_sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
|
|
|
|
|
float BKE_sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; }
|
|
|
|
|
int BKE_sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
|
|
|
|
|
void BKE_sound_read_waveform(struct bSound *sound, short *stop) { UNUSED_VARS(sound, stop); }
|
|
|
|
|
void BKE_sound_init_main(struct Main *UNUSED(bmain)) {}
|
|
|
|
|
void BKE_sound_set_cfra(int UNUSED(cfra)) {}
|
|
|
|
|
void BKE_sound_update_sequencer(struct Main *UNUSED(main), struct bSound *UNUSED(sound)) {}
|
|
|
|
|
void BKE_sound_update_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
|
|
|
|
|
void BKE_sound_update_scene_sound(void *UNUSED(handle), struct bSound *UNUSED(sound)) {}
|
|
|
|
|
void BKE_sound_update_scene_listener(struct Scene *UNUSED(scene)) {}
|
|
|
|
|
void BKE_sound_update_fps(struct Scene *UNUSED(scene)) {}
|
|
|
|
|
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)) {}
|
|
|
|
|
void BKE_sound_set_scene_volume(struct Scene *UNUSED(scene), float UNUSED(volume)) {}
|
|
|
|
|
void BKE_sound_set_scene_sound_pitch(void *UNUSED(handle), float UNUSED(pitch), char UNUSED(animated)) {}
|
|
|
|
|
float BKE_sound_get_length(struct bSound *UNUSED(sound)) { return 0; }
|
2017-08-18 18:16:13 +10:00
|
|
|
char **BKE_sound_get_device_names(void) { static char *names[1] = {NULL}; return names; }
|
|
|
|
|
|
2014-04-15 10:59:42 +02:00
|
|
|
#endif /* WITH_AUDASPACE */
|