From 13249b925eda7752b65a36d8270a3af3bdc02981 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Tue, 9 Aug 2011 08:38:14 +0000 Subject: 3D Audio GSoC: Speaker objects fully functional! Minor changes: * Fixed three memory bugs found via valgrind. * Fixed bug with jack transport crashing after file loading. * Sound NLA Strips now start at CFRA instead of 0. --- intern/audaspace/FX/AUD_DoubleReader.cpp | 2 +- intern/audaspace/FX/AUD_SuperposeReader.cpp | 2 +- .../audaspace/intern/AUD_AnimateableProperty.cpp | 20 ++--- .../audaspace/intern/AUD_LinearResampleReader.cpp | 2 +- intern/audaspace/intern/AUD_ReadDevice.cpp | 2 +- intern/audaspace/intern/AUD_Space.h | 2 + source/blender/blenkernel/BKE_sound.h | 4 + source/blender/blenkernel/intern/blender.c | 3 + source/blender/blenkernel/intern/library.c | 2 +- source/blender/blenkernel/intern/scene.c | 3 + source/blender/blenkernel/intern/sound.c | 88 +++++++++++++++++++++- source/blender/editors/object/object_add.c | 3 + source/blender/makesdna/DNA_anim_types.h | 2 + 13 files changed, 116 insertions(+), 19 deletions(-) diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp index e9882743d28..178240fa23b 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.cpp +++ b/intern/audaspace/FX/AUD_DoubleReader.cpp @@ -97,7 +97,7 @@ void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer) AUD_Specs specs1, specs2; specs1 = m_reader1->getSpecs(); specs2 = m_reader2->getSpecs(); - if(memcmp(&specs1, &specs2, sizeof(AUD_Specs))) + if(AUD_COMPARE_SPECS(specs1, specs2)) length = len; else { diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp index a0dc12fea96..b332a854a5d 100644 --- a/intern/audaspace/FX/AUD_SuperposeReader.cpp +++ b/intern/audaspace/FX/AUD_SuperposeReader.cpp @@ -81,7 +81,7 @@ void AUD_SuperposeReader::read(int& length, bool& eos, sample_t* buffer) { AUD_Specs specs = m_reader1->getSpecs(); AUD_Specs s2 = m_reader2->getSpecs(); - if(memcmp(&specs, &s2, sizeof(AUD_Specs))) + if(AUD_COMPARE_SPECS(specs, s2)) AUD_THROW(AUD_ERROR_SPECS, specs_error); int samplesize = AUD_SAMPLE_SIZE(specs); diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.cpp b/intern/audaspace/intern/AUD_AnimateableProperty.cpp index 03d2d3a5ea1..adc71928efd 100644 --- a/intern/audaspace/intern/AUD_AnimateableProperty.cpp +++ b/intern/audaspace/intern/AUD_AnimateableProperty.cpp @@ -105,10 +105,10 @@ void AUD_AnimateableProperty::read(float position, float* out) return; } - float last = (getSize() / (sizeof(float) * m_count) - 1); + int last = getSize() / (sizeof(float) * m_count) - 1; float t = position - floor(position); - if(position > last) + if(position >= last) { position = last; t = 0; @@ -128,24 +128,18 @@ void AUD_AnimateableProperty::read(float position, float* out) float* p1 = getBuffer() + pos; float* p2; float* p3; + last *= m_count; if(pos == 0) p0 = p1; else p0 = p1 - m_count; - if(pos > last) - { - p3 = p2 = p1; - } + p2 = p1 + m_count; + if(pos + m_count == last) + p3 = p2; else - { - p2 = p1 + m_count; - if(pos + m_count > last) - p3 = p2; - else - p3 = p2 + m_count; - } + p3 = p2 + m_count; for(int i = 0; i < m_count; i++) { diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp index 96add9bca4d..599be29f1d7 100644 --- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp +++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp @@ -82,7 +82,7 @@ void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer) int samplesize = AUD_SAMPLE_SIZE(specs); int size = length; - float factor = float(m_rate) / float(m_reader->getSpecs().rate); + float factor = m_rate / m_reader->getSpecs().rate; float spos; sample_t low, high; eos = false; diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp index 24e92d22038..a1495b31ed0 100644 --- a/intern/audaspace/intern/AUD_ReadDevice.cpp +++ b/intern/audaspace/intern/AUD_ReadDevice.cpp @@ -70,7 +70,7 @@ bool AUD_ReadDevice::read(data_t* buffer, int length) void AUD_ReadDevice::changeSpecs(AUD_Specs specs) { - if(memcmp(&specs, &m_specs.specs, sizeof(specs))) + if(AUD_COMPARE_SPECS(specs, m_specs.specs)) setSpecs(specs); } diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h index 4d0a06e37b2..9232864995b 100644 --- a/intern/audaspace/intern/AUD_Space.h +++ b/intern/audaspace/intern/AUD_Space.h @@ -41,6 +41,8 @@ /// Throws a AUD_Exception with the provided error code. #define AUD_THROW(exception, errorstr) { AUD_Exception e; e.error = exception; e.str = errorstr; throw e; } +#define AUD_COMPARE_SPECS(s1, s2) ((s1.rate == s2.rate) && (s1.channels == s2.channels)) + /// Returns the bit for a channel mask. #define AUD_CHANNEL_BIT(channel) (0x01 << channel) diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index 2cd006385e0..c36532ee4cc 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -46,6 +46,8 @@ void sound_init_once(void); void sound_init(struct Main *main); +void sound_init_main(struct Main *bmain); + void sound_exit(void); void sound_force_device(int device); @@ -124,6 +126,8 @@ int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length, flo int sound_get_channels(struct bSound* sound); +void sound_update_scene(struct Main* bmain, struct Scene* scene); + void* sound_get_factory(void* sound); #endif diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index a3a4c5b555b..5f33059e117 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -82,6 +82,7 @@ #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_sequencer.h" +#include "BKE_sound.h" #include "BLO_undofile.h" @@ -247,6 +248,8 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath G.main= bfd->main; CTX_data_main_set(C, G.main); + + sound_init_main(G.main); if (bfd->user) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 8668168936b..c362f3eb2fe 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -533,7 +533,6 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[a++]= &(main->latt); lb[a++]= &(main->lamp); lb[a++]= &(main->camera); - lb[a++]= &(main->speaker); lb[a++]= &(main->text); lb[a++]= &(main->sound); @@ -541,6 +540,7 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[a++]= &(main->brush); lb[a++]= &(main->script); lb[a++]= &(main->particle); + lb[a++]= &(main->speaker); lb[a++]= &(main->world); lb[a++]= &(main->screen); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 74126fd57a1..12e81e8296e 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -966,6 +966,9 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen /* scene drivers... */ scene_update_drivers(bmain, scene); + + /* update sound system animation */ + sound_update_scene(bmain, scene); } /* this is called in main loop, doing tagged updates before redraw */ diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 890fc114e68..17df6ba23cb 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -13,13 +13,16 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_math.h" #include "DNA_anim_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" #include "DNA_packedFile_types.h" #include "DNA_screen_types.h" #include "DNA_sound_types.h" +#include "DNA_speaker_types.h" #ifdef WITH_AUDASPACE # include "AUD_C-API.h" @@ -175,7 +178,12 @@ void sound_init(struct Main *bmain) if(!AUD_init(device, specs, buffersize)) AUD_init(AUD_NULL_DEVICE, specs, buffersize); - + + sound_init_main(bmain); +} + +void sound_init_main(struct Main *bmain) +{ #ifdef WITH_JACK AUD_setSyncCallback(sound_sync_callback, bmain); #else @@ -617,6 +625,84 @@ int sound_get_channels(struct bSound* sound) return info.specs.channels; } +void sound_update_scene(struct Main* bmain, struct Scene* scene) +{ + Object* ob; + NlaTrack* track; + NlaStrip* strip; + Speaker* speaker; + + void* new_set = AUD_createSet(); + void* handle; + float quat[4]; + + for(ob = bmain->object.first; ob; ob = ob->id.next) + { + if(ob->type == OB_SPEAKER) + { + if(ob->adt) + { + 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) + { + speaker = (Speaker*)ob->data; + + if(AUD_removeSet(scene->speaker_handles, strip->speaker_handle)) + { + AUD_moveSequence(strip->speaker_handle, strip->start / FPS, -1, 0); + } + else + { + if(speaker && speaker->sound) + { + strip->speaker_handle = AUD_addSequence(scene->sound_scene, speaker->sound->playback_handle, strip->start / FPS, -1, 0); + AUD_setRelativeSequence(strip->speaker_handle, 0); + } + } + + if(strip->speaker_handle) + { + AUD_addSet(new_set, strip->speaker_handle); + AUD_updateSequenceData(strip->speaker_handle, speaker->volume_max, + speaker->volume_min, speaker->distance_max, + speaker->distance_reference, speaker->attenuation, + speaker->cone_angle_outer, speaker->cone_angle_inner, + speaker->cone_volume_outer); + + mat4_to_quat(quat, ob->obmat); + AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_LOCATION, CFRA, ob->obmat[3], 1); + AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_ORIENTATION, CFRA, quat, 1); + AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_VOLUME, CFRA, &speaker->volume, 1); + AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_PITCH, CFRA, &speaker->pitch, 1); + AUD_updateSequenceSound(strip->speaker_handle, speaker->sound->playback_handle); + AUD_muteSequence(strip->speaker_handle, ((strip->flag & NLASTRIP_FLAG_MUTED) != 0) || ((speaker->flag & SPK_MUTED) != 0)); + } + } + } + } + } + } + } + + while((handle = AUD_getSet(scene->speaker_handles))) + { + AUD_removeSequence(scene->sound_scene, handle); + } + + if(scene->camera) + { + mat4_to_quat(quat, scene->camera->obmat); + AUD_setSequencerAnimData(scene->sound_scene, AUD_AP_LOCATION, CFRA, scene->camera->obmat[3], 1); + AUD_setSequencerAnimData(scene->sound_scene, AUD_AP_ORIENTATION, CFRA, quat, 1); + } + + AUD_destroySet(scene->speaker_handles); + scene->speaker_handles = new_set; +} + void* sound_get_factory(void* sound) { return ((struct bSound*) sound)->playback_handle; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 97d109118d1..09ce2562e3b 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -774,6 +774,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) int enter_editmode; unsigned int layer; float loc[3], rot[3]; + Scene *scene = CTX_data_scene(C); object_add_generic_invoke_options(C, op); if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) @@ -789,6 +790,8 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) AnimData *adt = BKE_id_add_animdata(&ob->id); NlaTrack *nlt = add_nlatrack(adt, NULL); NlaStrip *strip = add_nla_soundstrip(CTX_data_scene(C), ob->data); + strip->start = CFRA; + strip->end += strip->start; /* hook them up */ BKE_nlatrack_add_strip(nlt, strip); diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 5a031e04fe4..c0030cd0e5e 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -585,6 +585,8 @@ typedef struct NlaStrip { short type; /* type of NLA strip */ + void *speaker_handle; /* handle for speaker objects */ + int flag; /* settings */ int pad2; } NlaStrip; -- cgit v1.2.3