Added a first version of the Sound F-Curve Modifier, not really usable yet, but you...
authorJoerg Mueller <nexyon@gmail.com>
Sun, 22 Nov 2009 12:10:45 +0000 (12:10 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Sun, 22 Nov 2009 12:10:45 +0000 (12:10 +0000)
source/blender/blenkernel/intern/fmodifier.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/fmodifier_ui.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/space_graph/graph_buttons.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/makesdna/DNA_anim_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_fcurve.c

index 5daa2ed1924e7bc43cd5649048de8326dc63b369..fba15075bdbbd3ecce04a737294e8ee749b61e96 100644 (file)
@@ -53,6 +53,8 @@
 #include "RNA_access.h"
 #include "RNA_types.h"
 
+#include "AUD_C-API.h"
+
 #ifndef DISABLE_PYTHON
 #include "BPY_extern.h" /* for BPY_pydriver_eval() */
 #endif
@@ -871,6 +873,91 @@ static FModifierTypeInfo FMI_LIMITS = {
        fcm_limits_evaluate /* evaluate */
 };
 
+/* Sound F-Curve Modifier  --------------------------- */
+
+static void fcm_sound_new_data (void *mdata)
+{
+       FMod_Sound *data= (FMod_Sound *)mdata;
+
+       /* defaults */
+       data->strength= 1.0f;
+       data->delay = 0.0f;
+       data->modification = FCM_SOUND_MODIF_REPLACE;
+       data->sound = NULL;
+}
+
+static void fcm_sound_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+       FMod_Sound *data= (FMod_Sound *)fcm->data;
+       float amplitude;
+
+       AUD_Device* device;
+       SoundHandle* handle;
+       AUD_Sound* limiter;
+       AUD_SoundInfo info;
+
+//     evaltime = FRA2TIME(evaltime);
+       evaltime -= data->delay;
+
+       if(evaltime < 0.0f || data->sound == NULL || data->sound->cache == NULL)
+               return;
+
+       info = AUD_getInfo(data->sound->cache);
+       info.specs.channels = 1;
+       info.specs.format = AUD_FORMAT_FLOAT32;
+       device = AUD_openReadDevice(info.specs);
+       limiter = AUD_limitSound(data->sound->cache, evaltime, evaltime + 1);
+       AUD_playDevice(device, limiter);
+       AUD_unload(limiter);
+       AUD_readDevice(device, &amplitude, 1);
+       AUD_closeReadDevice(device);
+
+       /* combine the amplitude with existing motion data */
+       switch (data->modification) {
+               case FCM_SOUND_MODIF_ADD:
+                       *cvalue= *cvalue + amplitude * data->strength;
+                       break;
+               case FCM_SOUND_MODIF_SUBTRACT:
+                       *cvalue= *cvalue - amplitude * data->strength;
+                       break;
+               case FCM_SOUND_MODIF_MULTIPLY:
+                       *cvalue= *cvalue * amplitude * data->strength;
+                       break;
+               case FCM_SOUND_MODIF_REPLACE:
+               default:
+                       *cvalue= *cvalue + amplitude * data->strength;
+                       break;
+       }
+}
+
+static float fcm_sound_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime)
+{
+       FMod_Sound *data= (FMod_Sound *)fcm->data;
+
+       /* check for the time delay */
+//     evaltime = FRA2TIME(evaltime);
+       if(evaltime < data->delay)
+               return data->delay;
+
+       /* modifier doesn't change time */
+       return evaltime;
+}
+
+static FModifierTypeInfo FMI_SOUND = {
+       FMODIFIER_TYPE_SOUND, /* type */
+       sizeof(FMod_Sound), /* size */
+       FMI_TYPE_REPLACE_VALUES, /* action type */
+       0, /* requirements */
+       "Sound", /* name */
+       "FMod_Sound", /* struct name */
+       NULL, /* free data */
+       NULL, /* copy data */
+       fcm_sound_new_data, /* new data */
+       NULL, /* verify */
+       fcm_sound_time, /* evaluate time */
+       fcm_sound_evaluate /* evaluate */
+};
+
 /* F-Curve Modifier API --------------------------- */
 /* All of the F-Curve Modifier api functions use FModifierTypeInfo structs to carry out
  * and operations that involve F-Curve modifier specific code.
@@ -892,6 +979,7 @@ static void fmods_init_typeinfo ()
        fmodifiersTypeInfo[6]=  NULL/*&FMI_FILTER*/;                    /* Filter F-Curve Modifier */  // XXX unimplemented
        fmodifiersTypeInfo[7]=  &FMI_PYTHON;                    /* Custom Python F-Curve Modifier */
        fmodifiersTypeInfo[8]=  &FMI_LIMITS;                    /* Limits F-Curve Modifier */
+       fmodifiersTypeInfo[9]=  &FMI_SOUND;                             /* Sound F-Curve Modifier */
 }
 
 /* This function should be used for getting the appropriate type-info when only
index 5dc7cdad8ed1ae9d6b6187e733f65bde63b72db0..b78dd008fe1c57d30561cfe5ad198371642d4cb8 100644 (file)
@@ -1694,6 +1694,12 @@ static void lib_link_fmodifiers(FileData *fd, ID *id, ListBase *list)
                                data->script = newlibadr(fd, id->lib, data->script);
                        }
                                break;
+                       case FMODIFIER_TYPE_SOUND:
+                       {
+                               FMod_Sound *data= (FMod_Sound *)fcm->data;
+                               data->sound = newlibadr(fd, id->lib, data->sound);
+                       }
+                               break;
                }
        }
 }
@@ -10440,6 +10446,13 @@ static void expand_fmodifiers(FileData *fd, Main *mainvar, ListBase *list)
                                expand_doit(fd, mainvar, data->script);
                        }
                                break;
+                       case FMODIFIER_TYPE_SOUND:
+                       {
+                               FMod_Sound *data= (FMod_Sound *)fcm->data;
+
+                               expand_doit(fd, mainvar, data->sound);
+                       }
+                               break;
                }
        }
 }
index 872722607ce92f54c664bd32a0b39b58520679d4..d055667f264b03ad45e11177333140868823314a 100644 (file)
@@ -247,7 +247,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
 
 /* --------------- */
 
-/* draw settings for noise modifier */
+/* draw settings for generator modifier */
 static void draw_modifier__fn_generator(uiLayout *layout, ID *id, FModifier *fcm, short width)
 {
        uiLayout *col;
@@ -327,6 +327,49 @@ static void draw_modifier__noise(uiLayout *layout, ID *id, FModifier *fcm, short
 
 /* --------------- */
 
+/* draw settings for sound modifier */
+static void draw_modifier__sound(const bContext *C, uiLayout *layout, ID *id, FModifier *fcm, short width)
+{
+       uiLayout *split, *col;
+       PointerRNA ptr;
+       FMod_Sound *data= (FMod_Sound *)fcm->data;
+
+       /* init the RNA-pointer */
+       RNA_pointer_create(id, &RNA_FModifierSound, fcm, &ptr);
+
+       /* sound */
+       uiTemplateID(layout, C, &ptr, "sound", NULL, "sound.open", NULL);
+
+       if(data->sound)
+       {
+               if(data->sound->cache)
+               {
+                       /* blending mode */
+                       uiItemR(layout, NULL, 0, &ptr, "modification", 0);
+
+                       /* split into 2 columns */
+                       split= uiLayoutSplit(layout, 0.5f);
+
+                       /* col 1 */
+                       col= uiLayoutColumn(split, 0);
+                       uiItemR(col, NULL, 0, &ptr, "strength", 0);
+
+                       /* col 2 */
+                       col= uiLayoutColumn(split, 0);
+                       uiItemR(col, NULL, 0, &ptr, "delay", 0);
+               }
+               else
+               {
+                       PointerRNA ptr2;
+                       RNA_id_pointer_create(data->sound, &ptr2);
+                       uiItemL(layout, "Sound must be cached.", ICON_ERROR);
+                       uiItemR(layout, NULL, 0, &ptr2, "caching", UI_ITEM_R_TOGGLE);
+               }
+       }
+}
+
+/* --------------- */
+
 #define BINARYSEARCH_FRAMEEQ_THRESH    0.0001
 
 /* Binary search algorithm for finding where to insert Envelope Data Point.
@@ -590,7 +633,7 @@ static void draw_modifier__limits(uiLayout *layout, ID *id, FModifier *fcm, shor
 /* --------------- */
 
 
-void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifiers, FModifier *fcm)
+void ANIM_uiTemplate_fmodifier_draw (const bContext *C, uiLayout *layout, ID *id, ListBase *modifiers, FModifier *fcm)
 {
        FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
        uiLayout *box, *row, *subrow;
@@ -665,11 +708,15 @@ void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifie
                        case FMODIFIER_TYPE_LIMITS: /* Limits */
                                draw_modifier__limits(box, id, fcm, width);
                                break;
-                       
+
                        case FMODIFIER_TYPE_NOISE: /* Noise */
                                draw_modifier__noise(box, id, fcm, width);
                                break;
-                       
+
+                       case FMODIFIER_TYPE_SOUND: /* Sound */
+                               draw_modifier__sound(C, box, id, fcm, width);
+                               break;
+
                        default: /* unknown type */
                                break;
                }
index 5c83d68536242ef244b08737504c5efcf7e3538d..9e6a757baa23bbe189176fe6cb99fa3c1cb1f9ee 100644 (file)
@@ -418,7 +418,7 @@ short ANIM_headerUI_standard_buttons(const struct bContext *C, struct bDopeSheet
 /* F-MODIFIER TOOLS */
 
 /* draw a given F-Modifier for some layout/UI-Block */
-void ANIM_uiTemplate_fmodifier_draw(struct uiLayout *layout, struct ID *id, ListBase *modifiers, struct FModifier *fcm);
+void ANIM_uiTemplate_fmodifier_draw(const struct bContext *C, struct uiLayout *layout, struct ID *id, ListBase *modifiers, struct FModifier *fcm);
 
 /* ************************************************* */
 /* ASSORTED TOOLS */
index abcc1315313be07a5e45f7c047ccb907371006f4..3e25a6e7c2906411e914850335ffc20d16c2a8e8 100644 (file)
@@ -450,7 +450,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa)
        for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
                col= uiLayoutColumn(pa->layout, 1);
                
-               ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm);
+               ANIM_uiTemplate_fmodifier_draw(C, col, ale->id, &fcu->modifiers, fcm);
        }
 
        MEM_freeN(ale);
index 6e5da38dd1048ad882e4d391ddf62f85c55a634f..205aff27be77380f867ee954f9945c84aa76388f 100644 (file)
@@ -434,7 +434,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa)
        for (fcm= strip->modifiers.first; fcm; fcm= fcm->next) {
                col= uiLayoutColumn(pa->layout, 1);
                
-               ANIM_uiTemplate_fmodifier_draw(col, strip_ptr.id.data, &strip->modifiers, fcm);
+               ANIM_uiTemplate_fmodifier_draw(C, col, strip_ptr.id.data, &strip->modifiers, fcm);
        }
 }
 
index 195d68d63ff19414773bbc1f5a9a2f804bb41869..c6330861fd2e546e418f337255399a6a9b7ed790 100644 (file)
@@ -36,6 +36,7 @@ extern "C" {
 #include "DNA_listBase.h"
 #include "DNA_action_types.h"
 #include "DNA_curve_types.h"
+#include "DNA_sound_types.h"
 
 /* ************************************************ */
 /* F-Curve DataTypes */
@@ -73,6 +74,7 @@ typedef enum eFModifier_Types {
        FMODIFIER_TYPE_FILTER,          /* unimplemented - for applying: fft, high/low pass filters, etc. */
        FMODIFIER_TYPE_PYTHON,  
        FMODIFIER_TYPE_LIMITS,
+       FMODIFIER_TYPE_SOUND,
        
        /* NOTE: all new modifiers must be added above this line */
        FMODIFIER_NUM_TYPES
@@ -230,6 +232,25 @@ typedef enum eFMod_Noise_Modifications {
        FCM_NOISE_MODIF_MULTIPLY,               /* Multiply the curve by noise */
 } eFMod_Noise_Modifications;
 
+/* sound modifier data */
+typedef struct FMod_Sound {
+       float strength;
+       float delay;
+
+       short modification;
+       short pad[3];
+
+       bSound *sound;
+} FMod_Sound;
+
+/* modification modes */
+typedef enum eFMod_Sound_Modifications {
+       FCM_SOUND_MODIF_REPLACE = 0,    /* Modify existing curve, matching it's shape */
+       FCM_SOUND_MODIF_ADD,                    /* Add amplitude to the curve */
+       FCM_SOUND_MODIF_SUBTRACT,               /* Subtract amplitude from the curve */
+       FCM_SOUND_MODIF_MULTIPLY,               /* Multiply the curve by amplitude */
+} eFMod_Sound_Modifications;
+
 /* Drivers -------------------------------------- */
 
 /* Driver Target 
index d60713aa817790f2c7b42d6738ae5622c88fad6e..f8d9b4d333b9ad5ac76a77ea9de446c8903dc9c4 100644 (file)
@@ -203,6 +203,7 @@ extern StructRNA RNA_FModifierGenerator;
 extern StructRNA RNA_FModifierLimits;
 extern StructRNA RNA_FModifierNoise;
 extern StructRNA RNA_FModifierPython;
+extern StructRNA RNA_FModifierSound;
 extern StructRNA RNA_FieldSettings;
 extern StructRNA RNA_FileSelectParams;
 extern StructRNA RNA_FloatProperty;
index c83781a518a9da2799fe2b14a07ea957e0846245..eaffdc2cf29c05af8179b10385fc9d3dd1320a39 100644 (file)
@@ -34,6 +34,7 @@
 #include "DNA_anim_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_sound_types.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -49,6 +50,7 @@ EnumPropertyItem fmodifier_type_items[] = {
        {FMODIFIER_TYPE_FILTER, "FILTER", 0, "Filter", ""},
        {FMODIFIER_TYPE_PYTHON, "PYTHON", 0, "Python", ""},
        {FMODIFIER_TYPE_LIMITS, "LIMITS", 0, "Limits", ""},
+       {FMODIFIER_TYPE_SOUND, "SOUND", 0, "Sound", ""},
        {0, NULL, 0, NULL, NULL}};
 
 #ifdef RNA_RUNTIME
@@ -76,6 +78,8 @@ static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr)
                        return &RNA_FModifierPython;
                case FMODIFIER_TYPE_LIMITS:
                        return &RNA_FModifierLimits;
+               case FMODIFIER_TYPE_SOUND:
+                       return &RNA_FModifierSound;
                default:
                        return &RNA_UnknownType;
        }
@@ -225,6 +229,11 @@ static int rna_FCurve_modifiers_remove(FCurve *fcu, bContext *C, int index)
        return remove_fmodifier_index(&fcu->modifiers, index);
 }
 
+static int rna_Sound_id_editable(PointerRNA *ptr)
+{
+       return PROP_EDITABLE;
+}
+
 #else
 
 static void rna_def_fmodifier_generator(BlenderRNA *brna)
@@ -533,6 +542,47 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna)
 }
 
 
+/* --------- */
+
+static void rna_def_fmodifier_sound(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       static EnumPropertyItem prop_modification_items[] = {
+               {FCM_SOUND_MODIF_REPLACE, "REPLACE", 0, "Replace", ""},
+               {FCM_SOUND_MODIF_ADD, "ADD", 0, "Add", ""},
+               {FCM_SOUND_MODIF_SUBTRACT, "SUBTRACT", 0, "Subtract", ""},
+               {FCM_SOUND_MODIF_MULTIPLY, "MULTIPLY", 0, "Multiply", ""},
+               {0, NULL, 0, NULL, NULL}};
+
+       srna= RNA_def_struct(brna, "FModifierSound", "FModifier");
+       RNA_def_struct_ui_text(srna, "Sound F-Modifier", "Modifies an F-Curve based on the amplitudes in a sound.");
+       RNA_def_struct_sdna_from(srna, "FMod_Sound", "data");
+
+       prop= RNA_def_property(srna, "modification", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, prop_modification_items);
+       RNA_def_property_ui_text(prop, "Modification", "Method of modifying the existing F-Curve.");
+       RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+       prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "strength");
+       RNA_def_property_ui_text(prop, "Strength", "Amplitude of the sound - the amount that it modifies the underlying curve");
+       RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+       prop= RNA_def_property(srna, "delay", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "delay");
+       RNA_def_property_ui_text(prop, "delay", "The delay before the sound curve modification should start");
+       RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+       prop= RNA_def_property(srna, "sound", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "Sound");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_editable_func(prop, "rna_Sound_id_editable");
+       RNA_def_property_ui_text(prop, "Sound", "Sound datablock used by this modifier.");
+
+}
+
 /* --------- */
 
 static void rna_def_fmodifier(BlenderRNA *brna)
@@ -850,6 +900,7 @@ void RNA_def_fcurve(BlenderRNA *brna)
        rna_def_fmodifier_python(brna);
        rna_def_fmodifier_limits(brna);
        rna_def_fmodifier_noise(brna);
+       rna_def_fmodifier_sound(brna);
 }