3D Audio GSoC:
authorJoerg Mueller <nexyon@gmail.com>
Tue, 9 Aug 2011 08:38:14 +0000 (08:38 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Tue, 9 Aug 2011 08:38:14 +0000 (08:38 +0000)
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.

13 files changed:
intern/audaspace/FX/AUD_DoubleReader.cpp
intern/audaspace/FX/AUD_SuperposeReader.cpp
intern/audaspace/intern/AUD_AnimateableProperty.cpp
intern/audaspace/intern/AUD_LinearResampleReader.cpp
intern/audaspace/intern/AUD_ReadDevice.cpp
intern/audaspace/intern/AUD_Space.h
source/blender/blenkernel/BKE_sound.h
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/sound.c
source/blender/editors/object/object_add.c
source/blender/makesdna/DNA_anim_types.h

index e9882743d282029e8a4a3f33e65a8ea7f977cf00..178240fa23bc5d1038e7e8e03d8d4a0a67ab1c1c 100644 (file)
@@ -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
                        {
index a0dc12fea96e161b783b0f020199edc5e953a1a4..b332a854a5db0e7521aae8a1651403637cfa708b 100644 (file)
@@ -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);
index 03d2d3a5ea180b937e3be9b750d2f4f26e655017..adc71928efd2918d877417d2b17497803ae6eca5 100644 (file)
@@ -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++)
                {
index 96add9bca4d4e4ad83b5c01fea4185cbae7afb53..599be29f1d754e1b3eca90082f77c28bd48a38d3 100644 (file)
@@ -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;
index 24e92d22038bec80782767139c3302b4f9e4cd10..a1495b31ed051fcf995b14b3ff54846542811500 100644 (file)
@@ -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);
 }
 
index 4d0a06e37b280175d255167b2d632f1ef82d7ce9..9232864995b2628253be5b90ad159c0175cc311c 100644 (file)
@@ -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)
 
index 2cd006385e05d7a9fdfd4d14e9d301863a9b15f2..c36532ee4cc4d1abe09ccf50a8a22fc6c1843889 100644 (file)
@@ -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
index a3a4c5b555bf080b1971f13726f3ec424cb8f9fd..5f33059e117d7400cd2680891a8295c47884f57a 100644 (file)
@@ -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) {
                
index 8668168936bfb221d89f3f3496e8a6d988ff7345..c362f3eb2fee651e0e3492c03a8d969ced067628 100644 (file)
@@ -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);
index 74126fd57a12b8cf72c0b9e496bff1cdf7fb08fc..12e81e8296e26a2f5d1716b2bda6cdfb7c1a4926 100644 (file)
@@ -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 */
index 890fc114e68faa0dfb122143f230294f01500886..17df6ba23cbecb6559122279baad29952f67377d 100644 (file)
 #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;
index 97d109118d1fb70f75c159d439634ab13e36eb69..09ce2562e3b0574cad36fbd234e6be862bf9de4c 100644 (file)
@@ -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);
index 5a031e04fe492756902edb8834b01f236d673309..c0030cd0e5e560f3fabfe3c94d6180cda9309932 100644 (file)
@@ -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;