3D Audio GSoC:
authorJoerg Mueller <nexyon@gmail.com>
Thu, 11 Aug 2011 11:41:24 +0000 (11:41 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Thu, 11 Aug 2011 11:41:24 +0000 (11:41 +0000)
Adding a mono flag to mixdown non-mono sounds for 3D audio.

* Added mono sound loading.
* Bugfix: AUD_COMPARE_SPECS usage was wrong.
* Bugfix: JOS resampler = instead of ==.
* Bugfix: Change of a sound should apply settings in AUD_SequencerHandle.
* Bugfix: Memory leak when canceling open sound operator.

12 files changed:
intern/audaspace/FX/AUD_DoubleReader.cpp
intern/audaspace/FX/AUD_SuperposeReader.cpp
intern/audaspace/intern/AUD_C-API.cpp
intern/audaspace/intern/AUD_C-API.h
intern/audaspace/intern/AUD_JOSResampleReader.cpp
intern/audaspace/intern/AUD_ReadDevice.cpp
intern/audaspace/intern/AUD_SequencerHandle.cpp
release/scripts/startup/bl_ui/properties_data_speaker.py
source/blender/blenkernel/intern/sound.c
source/blender/editors/sound/sound_ops.c
source/blender/makesdna/DNA_sound_types.h
source/blender/makesrna/intern/rna_sound.c

index 178240fa23bc5d1038e7e8e03d8d4a0a67ab1c1c..3b1d105954c122c4fad7d7a03c29acfae7a97b3b 100644 (file)
@@ -98,13 +98,13 @@ void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer)
                        specs1 = m_reader1->getSpecs();
                        specs2 = m_reader2->getSpecs();
                        if(AUD_COMPARE_SPECS(specs1, specs2))
-                               length = len;
-                       else
                        {
                                int len2 = length - len;
                                m_reader2->read(len2, eos, buffer + specs1.channels * len);
                                length = len + len2;
                        }
+                       else
+                               length = len;
                }
        }
        else
index b332a854a5db0e7521aae8a1651403637cfa708b..c07b7a9febfb9f1b706e0abd2f11e3c434b9e6c5 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(AUD_COMPARE_SPECS(specs, s2))
+       if(!AUD_COMPARE_SPECS(specs, s2))
                AUD_THROW(AUD_ERROR_SPECS, specs_error);
 
        int samplesize = AUD_SAMPLE_SIZE(specs);
index 85a053238d02fd00ed9fe14af840d676e1b7d4cc..e64ca1af9e7659bf590467dc61ac88b3e4017235 100644 (file)
@@ -321,6 +321,24 @@ AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
        }
 }
 
+AUD_Sound* AUD_monoSound(AUD_Sound* sound)
+{
+       assert(sound);
+
+       try
+       {
+               AUD_DeviceSpecs specs;
+               specs.channels = AUD_CHANNELS_MONO;
+               specs.rate = AUD_RATE_INVALID;
+               specs.format = AUD_FORMAT_INVALID;
+               return new AUD_Sound(new AUD_ChannelMapperFactory(*sound, specs));
+       }
+       catch(AUD_Exception&)
+       {
+               return NULL;
+       }
+}
+
 AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
 {
        assert(sound);
index 2cd24551dd90f749e3db005e79d56088ce20610e..8e347c736755d565b515f8ae0b9b6397575790ab 100644 (file)
@@ -122,6 +122,13 @@ extern AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size);
  */
 extern AUD_Sound* AUD_bufferSound(AUD_Sound* sound);
 
+/**
+ * Rechannels the sound to be mono.
+ * \param sound The sound to rechannel.
+ * \return The mono sound.
+ */
+extern AUD_Sound* AUD_monoSound(AUD_Sound* sound);
+
 /**
  * Delays a sound.
  * \param sound The sound to dealy.
index e7eefb30c54fb6ffbbf9d74a4bf59ab09ed9b5f3..fcd96c3959a5010c3b230ef68a62b5ba54db7176 100644 (file)
@@ -306,7 +306,7 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
                m_n = m_cache_valid;
        }
 
-       eos = eos && ((m_n == m_cache_valid) || (length = 0));
+       eos = eos && ((m_n == m_cache_valid) || (length == 0));
 }
 
 // kaiser windowed (beta = 10) sinc lowpass with a cutt-off of 0.9
index a1495b31ed051fcf995b14b3ff54846542811500..8ab858901b925229fa48e4dd68eb975e5c0082a0 100644 (file)
@@ -70,7 +70,7 @@ bool AUD_ReadDevice::read(data_t* buffer, int length)
 
 void AUD_ReadDevice::changeSpecs(AUD_Specs specs)
 {
-       if(AUD_COMPARE_SPECS(specs, m_specs.specs))
+       if(!AUD_COMPARE_SPECS(specs, m_specs.specs))
                setSpecs(specs);
 }
 
index 978439d3174697babe3675231833e39c95ef4edf..c9cf46ccdc3f9457b722b702790a756c089f2568 100644 (file)
@@ -88,6 +88,8 @@ void AUD_SequencerHandle::update(float position, float frame)
                        }
 
                        m_sound_status = m_entry->m_sound_status;
+                       m_pos_status--;
+                       m_status--;
                }
 
                if(m_pos_status != m_entry->m_pos_status)
index 45f2fa5d1f74c890c18949f181df1d562607e043..fe9f798af0c0e078c6a569381c5fe8dc7835631c 100644 (file)
@@ -63,7 +63,7 @@ class DATA_PT_speaker(DataButtonsPanel, bpy.types.Panel):
 
         split = layout.split(percentage=0.75)
 
-        split.template_ID(speaker, "sound", open="sound.open")
+        split.template_ID(speaker, "sound", open="sound.open_mono")
         split.prop(speaker, "muted")
 
         split = layout.split()
index 1b09db841252a5e0f7b74069b329bb8c77c427bc..9c62b92a924362d9125095b46e39364f4fa2376c 100644 (file)
@@ -349,6 +349,13 @@ void sound_load(struct Main *bmain, struct bSound* sound)
                        break;
                }
 #endif
+               if(sound->flags & SOUND_FLAGS_MONO)
+               {
+                       void* handle = AUD_monoSound(sound->handle);
+                       AUD_unload(sound->handle);
+                       sound->handle = handle;
+               }
+
                if(sound->flags & SOUND_FLAGS_CACHING)
                {
                        sound->cache = AUD_bufferSound(sound->handle);
index 31d22f9dd545c7ec39721551cabd00ccd91e0540..fb4355d0df7ac389c04475c19643cd436e49b973 100644 (file)
 
 /******************** open sound operator ********************/
 
+static int open_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+       MEM_freeN(op->customdata);
+       op->customdata= NULL;
+       return OPERATOR_CANCELLED;
+}
+
 static void open_init(bContext *C, wmOperator *op)
 {
        PropertyPointerRNA *pprop;
@@ -95,9 +102,10 @@ static int open_exec(bContext *C, wmOperator *op)
        PropertyPointerRNA *pprop;
        PointerRNA idptr;
        AUD_SoundInfo info;
+       Main *bmain = CTX_data_main(C);
 
        RNA_string_get(op->ptr, "filepath", path);
-       sound = sound_new_file(CTX_data_main(C), path);
+       sound = sound_new_file(bmain, path);
 
        if(!op->customdata)
                open_init(C, op);
@@ -117,6 +125,11 @@ static int open_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        }
 
+       if(RNA_boolean_get(op->ptr, "mono")) {
+               sound->flags |= SOUND_FLAGS_MONO;
+               sound_load(bmain, sound);
+       }
+
        if (RNA_boolean_get(op->ptr, "cache")) {
                sound_cache(sound);
        }
@@ -172,6 +185,28 @@ void SOUND_OT_open(wmOperatorType *ot)
        /* api callbacks */
        ot->exec= open_exec;
        ot->invoke= open_invoke;
+       ot->cancel= open_cancel;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH);
+       RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
+       RNA_def_boolean(ot->srna, "mono", FALSE, "Mono", "Mixdown the sound to mono.");
+}
+
+void SOUND_OT_open_mono(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Open Sound Mono";
+       ot->description= "Load a sound file as mono";
+       ot->idname= "SOUND_OT_open_mono";
+
+       /* api callbacks */
+       ot->exec= open_exec;
+       ot->invoke= open_invoke;
+       ot->cancel= open_cancel;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -179,6 +214,7 @@ void SOUND_OT_open(wmOperatorType *ot)
        /* properties */
        WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH);
        RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
+       RNA_def_boolean(ot->srna, "mono", TRUE, "Mono", "Mixdown the sound to mono.");
 }
 
 /******************** mixdown operator ********************/
@@ -667,6 +703,7 @@ void SOUND_OT_bake_animation(wmOperatorType *ot)
 void ED_operatortypes_sound(void)
 {
        WM_operatortype_append(SOUND_OT_open);
+       WM_operatortype_append(SOUND_OT_open_mono);
        WM_operatortype_append(SOUND_OT_mixdown);
        WM_operatortype_append(SOUND_OT_pack);
        WM_operatortype_append(SOUND_OT_unpack);
index d7546e84bbfe76cf899d4aa25996331861d3746b..4f727b3586b406013c7d1b13c37a996ae58549df 100644 (file)
@@ -113,6 +113,7 @@ typedef enum eSound_Type {
 
 #define SOUND_FLAGS_3D                                 (1 << 3) /* deprecated! used for sound actuator loading */
 #define SOUND_FLAGS_CACHING                            (1 << 4)
+#define SOUND_FLAGS_MONO                               (1 << 5)
 
 /* to DNA_sound_types.h*/
 
index e78bc09204069bb594fe95f31afc0da4fc5a8a3f..b224b55c20cf2979685df7db621016100d633005 100644 (file)
@@ -41,7 +41,7 @@
 #include "BKE_sound.h"
 #include "BKE_context.h"
 
-static void rna_Sound_filepath_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_Sound_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
 {
        sound_load(bmain, (bSound*)ptr->data);
 }
@@ -83,7 +83,7 @@ static void rna_def_sound(BlenderRNA *brna)
        prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
        RNA_def_property_string_sdna(prop, NULL, "name");
        RNA_def_property_ui_text(prop, "File Path", "Sound sample file used by this Sound datablock");
-       RNA_def_property_update(prop, 0, "rna_Sound_filepath_update");
+       RNA_def_property_update(prop, 0, "rna_Sound_update");
 
        prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "packedfile");
@@ -93,6 +93,11 @@ static void rna_def_sound(BlenderRNA *brna)
        RNA_def_property_boolean_funcs(prop, "rna_Sound_caching_get", "rna_Sound_caching_set");
        RNA_def_property_ui_text(prop, "Caching", "The sound file is decoded and loaded into RAM");
        RNA_def_property_update(prop, 0, "rna_Sound_caching_update");
+
+       prop= RNA_def_property(srna, "mono", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flags", SOUND_FLAGS_MONO);
+       RNA_def_property_ui_text(prop, "Mono", "If the file contains multiple audio channels they are mixdown to a signle one.");
+       RNA_def_property_update(prop, 0, "rna_Sound_update");
 }
 
 void RNA_def_sound(BlenderRNA *brna)