Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/sound.c')
-rw-r--r--source/blender/blenkernel/intern/sound.c293
1 files changed, 86 insertions, 207 deletions
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 1be59529cc7..7b451bd5a98 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -12,6 +12,7 @@
#include "BLI_blenlib.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_screen_types.h"
@@ -26,6 +27,9 @@
#include "BKE_context.h"
#include "BKE_library.h"
#include "BKE_packedFile.h"
+#include "BKE_fcurve.h"
+
+#include "RNA_access.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -107,7 +111,7 @@ struct bSound* sound_new_file(struct Main *main, char* filename)
sound_load(main, sound);
- if(!sound->handle)
+ if(!sound->playback_handle)
{
free_libblock(&main->sound, sound);
sound = NULL;
@@ -133,7 +137,7 @@ struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source)
sound_load(CTX_data_main(C), sound);
- if(!sound->handle)
+ if(!sound->playback_handle)
{
free_libblock(&CTX_data_main(C)->sound, sound);
sound = NULL;
@@ -159,7 +163,7 @@ struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, floa
sound_load(CTX_data_main(C), sound);
- if(!sound->handle)
+ if(!sound->playback_handle)
{
free_libblock(&CTX_data_main(C)->sound, sound);
sound = NULL;
@@ -175,8 +179,6 @@ void sound_delete(struct bContext *C, struct bSound* sound)
{
sound_free(sound);
- sound_unlink(C, sound);
-
free_libblock(&CTX_data_main(C)->sound, sound);
}
}
@@ -187,7 +189,7 @@ void sound_cache(struct bSound* sound, int ignore)
AUD_unload(sound->cache);
sound->cache = AUD_bufferSound(sound->handle);
- sound->changed++;
+ sound->playback_handle = sound->cache;
}
void sound_delete_cache(struct bSound* sound)
@@ -196,6 +198,7 @@ void sound_delete_cache(struct bSound* sound)
{
AUD_unload(sound->cache);
sound->cache = NULL;
+ sound->playback_handle = sound->handle;
}
}
@@ -207,6 +210,7 @@ void sound_load(struct Main *main, struct bSound* sound)
{
AUD_unload(sound->handle);
sound->handle = NULL;
+ sound->playback_handle = NULL;
}
// XXX unused currently
@@ -253,7 +257,10 @@ void sound_load(struct Main *main, struct bSound* sound)
break;
}
#endif
- sound->changed++;
+ if(sound->cache)
+ sound->playback_handle = sound->cache;
+ else
+ sound->playback_handle = sound->handle;
}
}
@@ -269,243 +276,115 @@ void sound_free(struct bSound* sound)
{
AUD_unload(sound->handle);
sound->handle = NULL;
+ sound->playback_handle = NULL;
}
}
-void sound_unlink(struct bContext *C, struct bSound* sound)
+static float sound_get_volume(Scene* scene, Sequence* sequence, float time)
{
- Scene *scene;
- SoundHandle *handle;
-
-// XXX unused currently
-#if 0
- bSound *snd;
- for(snd = CTX_data_main(C)->sound.first; snd; snd = snd->id.next)
- {
- if(snd->child_sound == sound)
- {
- snd->child_sound = NULL;
- if(snd->handle)
- {
- AUD_unload(sound->handle);
- snd->handle = NULL;
- }
-
- sound_unlink(C, snd);
- }
- }
-#endif
-
- for(scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next)
- {
- for(handle = scene->sound_handles.first; handle; handle = handle->next)
- {
- if(handle->source == sound)
- {
- handle->source = NULL;
- if(handle->handle)
- AUD_stop(handle->handle);
- }
- }
- }
+ struct FCurve* fcu = id_data_find_fcurve(scene, sequence, &RNA_Sequence, "volume", 0);
+ if(fcu)
+ return evaluate_fcurve(fcu, time * FPS);
+ else
+ return sequence->volume;
}
-struct SoundHandle* sound_new_handle(struct Scene *scene, struct bSound* sound, int startframe, int endframe, int frameskip)
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
{
- ListBase* handles = &scene->sound_handles;
+ AUD_Device* mixdown = AUD_openReadDevice(specs);
+
+ AUD_setDeviceVolume(mixdown, volume);
- SoundHandle* handle = MEM_callocN(sizeof(SoundHandle), "sound_handle");
- handle->source = sound;
- handle->startframe = startframe;
- handle->endframe = endframe;
- handle->frameskip = frameskip;
- handle->state = AUD_STATUS_INVALID;
- handle->volume = 1.0f;
+ AUD_playDevice(mixdown, scene->sound_scene, start / FPS);
- BLI_addtail(handles, handle);
+ return mixdown;
+}
- return handle;
+void sound_create_scene(struct Scene *scene)
+{
+ scene->sound_scene = AUD_createSequencer(scene, (AUD_volumeFunction)&sound_get_volume);
}
-void sound_delete_handle(struct Scene *scene, struct SoundHandle *handle)
+void sound_destroy_scene(struct Scene *scene)
{
- if(handle == NULL)
- return;
+ if(scene->sound_scene_handle)
+ AUD_stop(scene->sound_scene_handle);
+ if(scene->sound_scene)
+ AUD_destroySequencer(scene->sound_scene);
+}
- if(handle->handle)
- AUD_stop(handle->handle);
+void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
+{
+ return AUD_addSequencer(scene->sound_scene, &(sequence->sound->playback_handle), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
+}
- BLI_freelinkN(&scene->sound_handles, handle);
+void sound_remove_scene_sound(struct Scene *scene, void* handle)
+{
+ AUD_removeSequencer(scene->sound_scene, handle);
}
-void sound_stop_all(struct bContext *C)
+void sound_mute_scene_sound(struct Scene *scene, void* handle, char mute)
{
- SoundHandle *handle;
+ AUD_muteSequencer(scene->sound_scene, handle, mute);
+}
- for(handle = CTX_data_scene(C)->sound_handles.first; handle; handle = handle->next)
- {
- if(handle->state == AUD_STATUS_PLAYING)
- {
- AUD_pause(handle->handle);
- handle->state = AUD_STATUS_PAUSED;
- }
- }
+void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip)
+{
+ AUD_moveSequencer(scene->sound_scene, handle, startframe / FPS, endframe / FPS, frameskip / FPS);
}
-void sound_update_playing(struct bContext *C)
+void sound_start_play_scene(struct Scene *scene)
{
- SoundHandle *handle;
- Scene* scene = CTX_data_scene(C);
- int cfra = CFRA;
- float fps = FPS;
- int action;
+ AUD_Sound* sound;
+ sound = AUD_loopSound(scene->sound_scene);
+ scene->sound_scene_handle = AUD_play(sound, 1);
+ AUD_unload(sound);
+}
+void sound_play_scene(struct Scene *scene)
+{
AUD_lock();
- for(handle = scene->sound_handles.first; handle; handle = handle->next)
- {
- if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute || (scene->audio.flag & AUDIO_MUTE))
- {
- if(handle->state == AUD_STATUS_PLAYING)
- {
- AUD_pause(handle->handle);
- handle->state = AUD_STATUS_PAUSED;
- }
- }
- else
- {
- action = 0;
-
- if(handle->changed != handle->source->changed)
- {
- handle->changed = handle->source->changed;
- action = 3;
- if(handle->state != AUD_STATUS_INVALID)
- {
- AUD_stop(handle->handle);
- handle->state = AUD_STATUS_INVALID;
- }
- }
- else
- {
- if(handle->state != AUD_STATUS_PLAYING)
- action = 3;
- else
- {
- handle->state = AUD_getStatus(handle->handle);
- if(handle->state != AUD_STATUS_PLAYING)
- action = 3;
- else
- {
- float diff = AUD_getPosition(handle->handle) * fps - cfra + handle->startframe;
- if(diff < 0.0)
- diff = -diff;
- if(diff > FPS/2.0)
- {
- action = 2;
- }
- }
- }
- }
-
- AUD_setSoundVolume(handle->handle, handle->volume);
-
- if(action & 1)
- {
- if(handle->state == AUD_STATUS_INVALID)
- {
- if(handle->source && handle->source->handle)
- {
- AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, handle->frameskip / fps, (handle->frameskip + handle->endframe - handle->startframe)/fps);
- handle->handle = AUD_play(limiter, 1);
- AUD_unload(limiter);
- if(handle->handle)
- handle->state = AUD_STATUS_PLAYING;
- if(cfra == handle->startframe)
- action &= ~2;
- }
- }
- else
- if(AUD_resume(handle->handle))
- handle->state = AUD_STATUS_PLAYING;
- else
- handle->state = AUD_STATUS_INVALID;
- }
-
- if(action & 2)
- AUD_seek(handle->handle, (cfra - handle->startframe) / fps);
- }
- }
+ if(!scene->sound_scene_handle || AUD_getStatus(scene->sound_scene_handle) == AUD_STATUS_INVALID)
+ sound_start_play_scene(scene);
+
+ AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ AUD_setLoop(scene->sound_scene_handle, -1, -1);
+ AUD_resume(scene->sound_scene_handle);
AUD_unlock();
}
-void sound_scrub(struct bContext *C)
+void sound_stop_scene(struct Scene *scene)
{
- SoundHandle *handle;
- Scene* scene = CTX_data_scene(C);
- int cfra = CFRA;
- float fps = FPS;
-
- if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
- {
- AUD_lock();
-
- for(handle = scene->sound_handles.first; handle; handle = handle->next)
- {
- if(cfra >= handle->startframe && cfra < handle->endframe && !handle->mute)
- {
- if(handle->source && handle->source->handle)
- {
- int frameskip = handle->frameskip + cfra - handle->startframe;
- AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, frameskip / fps, (frameskip + 1)/fps);
- AUD_play(limiter, 0);
- AUD_unload(limiter);
- }
- }
- }
-
- AUD_unlock();
- }
+ AUD_pause(scene->sound_scene_handle);
}
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume)
+void sound_seek_scene(struct bContext *C)
{
- AUD_Device* mixdown = AUD_openReadDevice(specs);
- SoundHandle *handle;
- float fps = FPS;
- AUD_Sound *limiter, *delayer;
- int frameskip, s, e;
+ struct Scene *scene = CTX_data_scene(C);
- end++;
+ AUD_lock();
- AUD_setDeviceVolume(mixdown, volume);
+ if(!scene->sound_scene_handle || AUD_getStatus(scene->sound_scene_handle) == AUD_STATUS_INVALID)
+ {
+ sound_start_play_scene(scene);
+ AUD_pause(scene->sound_scene_handle);
+ }
- for(handle = scene->sound_handles.first; handle; handle = handle->next)
+ if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
{
- if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->handle)
- {
- frameskip = handle->frameskip;
- s = handle->startframe - start;
- e = handle->frameskip + AUD_MIN(handle->endframe, end) - handle->startframe;
-
- if(s < 0)
- {
- frameskip -= s;
- s = 0;
- }
-
- AUD_setSoundVolume(handle->handle, handle->volume);
-
- limiter = AUD_limitSound(handle->source->handle, frameskip / fps, e / fps);
- delayer = AUD_delaySound(limiter, s / fps);
-
- AUD_playDevice(mixdown, delayer);
-
- AUD_unload(delayer);
- AUD_unload(limiter);
- }
+ AUD_setLoop(scene->sound_scene_handle, -1, 1 / FPS);
+ AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ AUD_resume(scene->sound_scene_handle);
}
+ else
+ AUD_seek(scene->sound_scene_handle, CFRA / FPS);
- return mixdown;
+ AUD_unlock();
+}
+
+int sound_read_sound_buffer(bSound* sound, float* buffer, int length)
+{
+ AUD_readSound(sound->cache, buffer, length);
}