From fee7337249342c3d5a332358883af9afe961f38d Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Thu, 11 Aug 2011 11:41:24 +0000 Subject: 3D Audio GSoC: 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. --- intern/audaspace/FX/AUD_DoubleReader.cpp | 4 +-- intern/audaspace/FX/AUD_SuperposeReader.cpp | 2 +- intern/audaspace/intern/AUD_C-API.cpp | 18 ++++++++++ intern/audaspace/intern/AUD_C-API.h | 7 ++++ intern/audaspace/intern/AUD_JOSResampleReader.cpp | 2 +- intern/audaspace/intern/AUD_ReadDevice.cpp | 2 +- intern/audaspace/intern/AUD_SequencerHandle.cpp | 2 ++ .../startup/bl_ui/properties_data_speaker.py | 2 +- source/blender/blenkernel/intern/sound.c | 7 ++++ source/blender/editors/sound/sound_ops.c | 39 +++++++++++++++++++++- source/blender/makesdna/DNA_sound_types.h | 1 + source/blender/makesrna/intern/rna_sound.c | 9 +++-- 12 files changed, 86 insertions(+), 9 deletions(-) diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp index 178240fa23b..3b1d105954c 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.cpp +++ b/intern/audaspace/FX/AUD_DoubleReader.cpp @@ -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 diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp index b332a854a5d..c07b7a9febf 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(AUD_COMPARE_SPECS(specs, s2)) + 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_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 85a053238d0..e64ca1af9e7 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -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); diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index 2cd24551dd9..8e347c73675 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -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. diff --git a/intern/audaspace/intern/AUD_JOSResampleReader.cpp b/intern/audaspace/intern/AUD_JOSResampleReader.cpp index e7eefb30c54..fcd96c3959a 100644 --- a/intern/audaspace/intern/AUD_JOSResampleReader.cpp +++ b/intern/audaspace/intern/AUD_JOSResampleReader.cpp @@ -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 diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp index a1495b31ed0..8ab858901b9 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(AUD_COMPARE_SPECS(specs, m_specs.specs)) + if(!AUD_COMPARE_SPECS(specs, m_specs.specs)) setSpecs(specs); } diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/intern/audaspace/intern/AUD_SequencerHandle.cpp index 978439d3174..c9cf46ccdc3 100644 --- a/intern/audaspace/intern/AUD_SequencerHandle.cpp +++ b/intern/audaspace/intern/AUD_SequencerHandle.cpp @@ -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) diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py index 45f2fa5d1f7..fe9f798af0c 100644 --- a/release/scripts/startup/bl_ui/properties_data_speaker.py +++ b/release/scripts/startup/bl_ui/properties_data_speaker.py @@ -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() diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 1b09db84125..9c62b92a924 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -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); diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 31d22f9dd54..fb4355d0df7 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -79,6 +79,13 @@ /******************** 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); diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index d7546e84bbf..4f727b3586b 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -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*/ diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c index e78bc092040..b224b55c20c 100644 --- a/source/blender/makesrna/intern/rna_sound.c +++ b/source/blender/makesrna/intern/rna_sound.c @@ -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) -- cgit v1.2.3