Mercurial > audlegacy
changeset 1507:0c5fdcf3f947 trunk
[svn] - incomplete stuff
line wrap: on
line diff
--- a/ChangeLog Sat Aug 05 23:43:14 2006 -0700 +++ b/ChangeLog Sun Aug 06 01:53:29 2006 -0700 @@ -1,3 +1,12 @@ +2006-08-06 06:43:14 +0000 Stephen Sokolow <deitarion@gmail.com> + revision [1926] + Fix the test for whether a notification is necessary + + + Changes: Modified: + +3 -3 trunk/Plugins/General/notify/notify.c + + 2006-08-06 05:55:11 +0000 William Pitcock <nenolod@nenolod.net> revision [1924] - fix!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/Makefile Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,44 @@ +include ../../../../mk/rules.mk +include ../../../../mk/objective.mk + +OBJECTIVE_LIBS_NOINST = libparanormal.a + +OBJECT_CFLAGS = $(GTK_CFLAGS) +OBJECT_LIBS = $(GTK_LIBS) + +CFLAGS += -fPIC -DPIC -Wall -g -I../../../.. $(OBJECT_CFLAGS) $(XML_CFLAGS) -I.. +LIBADD = -lm $(OBJECT_LIBS) $(XML_LIBS) + +SOURCES = \ + pnactuator.c \ + pnactuatorfactory.c \ + pnactuatorlist.c \ + pnaudiodata.c \ + pnblur.c \ + pnbooleanoption.c \ + pnbuiltins.c \ + pncontainer.c \ + pncpu.c \ + pndisplacement.c \ + pndistortion.c \ + pnerror.c \ + pnflip.c \ + pnfloatoption.c \ + pnimage.c \ + pnimagecontext.c \ + pninit.c \ + pnintegeroption.c \ + pnlistoption.c \ + pnobject.c \ + pnoption.c \ + pnrotozoom.c \ + pnscope.c \ + pnscript.c \ + pnscriptparser.y \ + pnstringoption.c \ + pnsymboltable.c \ + pntestactuator.c \ + pnuserobject.c \ + pnvis.c + +OBJECTS = ${SOURCES:.c=.o}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pn.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,55 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_H__ +#define __PN_H__ + +#include "pnactuator.h" +#include "pnactuatorfactory.h" +#include "pnactuatorlist.h" +#include "pnaudiodata.h" +#include "pnblur.h" +#include "pnbooleanoption.h" +#include "pnbuiltins.h" +#include "pncontainer.h" +#include "pncpu.h" +#include "pndisplacement.h" +#include "pndistortion.h" +#include "pnerror.h" +#include "pnflip.h" +#include "pnfloatoption.h" +#include "pngtk.h" +#include "pnimage.h" +#include "pnimagecontext.h" +#include "pninit.h" +#include "pnintegeroption.h" +#include "pnlistoption.h" +#include "pnobject.h" +#include "pnoption.h" +#include "pnoptionwidget.h" +#include "pnrotozoom.h" +#include "pnscope.h" +#include "pnscript.h" +#include "pnstringoption.h" +#include "pnsymboltable.h" +#include "pntestactuator.h" +#include "pnuserobject.h" +#include "pnvis.h" +#include "pnxml.h" + +#endif /* __PN_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnactuator.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,312 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <glib.h> +#include "pnactuator.h" +#include "pnerror.h" + +static void pn_actuator_class_init (PnActuatorClass *class); +static void pn_actuator_init (PnActuator *actuator, + PnActuatorClass *class); + +/* GObject signals */ +static void pn_actuator_finalize (GObject *gobject); + +/* PnObject signals */ +static void pn_actuator_destroy (PnObject *object); + +/* PnUserObject methods */ +static void pn_actuator_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_actuator_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static PnUserObjectClass *parent_class = NULL; + +GType +pn_actuator_get_type (void) +{ + static GType actuator_type = 0; + + if (! actuator_type) + { + static const GTypeInfo actuator_info = + { + sizeof (PnActuatorClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_actuator_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnActuator), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_actuator_init + }; + + /* FIXME: should this be dynamic? */ + actuator_type = g_type_register_static (PN_TYPE_USER_OBJECT, + "PnActuator", + &actuator_info, + G_TYPE_FLAG_ABSTRACT); + } + return actuator_type; +} + +static void +pn_actuator_class_init (PnActuatorClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + + /* GObject signals */ + gobject_class->finalize = pn_actuator_finalize; + + /* PnObject signals */ + object_class->destroy = pn_actuator_destroy; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_actuator_save_thyself; + user_object_class->load_thyself = pn_actuator_load_thyself; +} + +static void +pn_actuator_init (PnActuator *actuator, PnActuatorClass *class) +{ + actuator->options = g_array_new (FALSE, FALSE, sizeof (PnOption *)); +} + +static void +pn_actuator_destroy (PnObject *object) +{ + PnActuator *actuator = (PnActuator *) object; + gint i; + + for (i=0; i < actuator->options->len; i++) + pn_object_unref (g_array_index (actuator->options, PnObject *, i)); +} + +static void +pn_actuator_finalize (GObject *gobject) +{ + PnActuator *actuator = (PnActuator *) gobject; + + g_array_free (actuator->options, FALSE); + + if (G_OBJECT_CLASS (parent_class)->finalize) + G_OBJECT_CLASS (parent_class)->finalize (gobject); +} + +static void +pn_actuator_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnActuator *actuator; + gint i; + xmlNodePtr options_node, option_node; + PnOption *option; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_ACTUATOR (user_object)); + g_return_if_fail (node != NULL); + + actuator = (PnActuator *) user_object; + + options_node = xmlNewChild (node, NULL, "Options", NULL); + + /* Save all the options */ + for (i=0; i < actuator->options->len; i++) + { + option = g_array_index (actuator->options, PnOption *, i); + option_node = xmlNewChild (options_node, NULL, "BUG", NULL); + pn_user_object_save_thyself (PN_USER_OBJECT (option), option_node); + } + + if (parent_class->save_thyself) + parent_class->save_thyself (user_object, node); +} + +static void +pn_actuator_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnActuator *actuator; + xmlNodePtr options_node, option_node; + PnOption *option; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_ACTUATOR (user_object)); + g_return_if_fail (node != NULL); + + actuator = (PnActuator *) user_object; + + /* FIXME: should these 'xmlChildrenNode' be 'xmlRootNode'? */ + + /* find the 'options' node */ + for (options_node = node->xmlChildrenNode; options_node; options_node = options_node->next) + if (g_strcasecmp (options_node->name, "Options") == 0) + break; + + /* load each of the options */ + if (options_node) + { + for (option_node = options_node->xmlChildrenNode; option_node; option_node = option_node->next) + { + option = pn_actuator_get_option_by_name (actuator, option_node->name); + if (option) + pn_user_object_load_thyself (PN_USER_OBJECT (option), option_node); + else + pn_error ("unknown actuator option ecountered in actuator \"%s\": %s", + node->name, + option_node->name); + } + } + + if (parent_class->load_thyself) + parent_class->load_thyself (user_object, node); +} + +/** + * pn_actuator_add_option + * @actuator: a #PnActuator + * @option: the #PnOption to add + * + * Adds a #PnOption to the actuator. + */ +void +pn_actuator_add_option (PnActuator *actuator, PnOption *option) +{ + g_return_if_fail (actuator != NULL); + g_return_if_fail (PN_IS_ACTUATOR (actuator)); + g_return_if_fail (option != NULL); + g_return_if_fail (PN_IS_OPTION (option)); + g_return_if_fail (! pn_actuator_get_option_by_name (actuator, PN_USER_OBJECT_NAME (option))); + + g_array_append_val (actuator->options, option); + pn_object_ref (PN_OBJECT (option)); + pn_object_sink (PN_OBJECT (option)); + pn_user_object_set_owner (PN_USER_OBJECT (option), PN_USER_OBJECT (actuator)); +} + +/** + * pn_actuator_get_option_by_index + * @actuator: a #PnActuator + * @index: the index of the option to retrieve + * + * Retrieves a #PnOption associated with the actuator based on + * the index of the option. Indices start at 0 and are determined + * by the order in which the options were added. + * + * Returns: The #PnOption at index @index + */ +PnOption* +pn_actuator_get_option_by_index (PnActuator *actuator, guint index) +{ + g_return_val_if_fail (actuator != NULL, NULL); + g_return_val_if_fail (PN_IS_ACTUATOR (actuator), NULL); + g_return_val_if_fail (index < actuator->options->len, NULL); + + return g_array_index (actuator->options, PnOption *, index); +} + +/** + * pn_actuator_get_option_by_name + * @actuator: a #PnActuator + * @name: the name of the option to retrieve + * + * Retrieves the first #PnOption associated with the actuator + * based on the name of the option. + * + * Returns: The first #PnOption with the name @name + */ +PnOption* +pn_actuator_get_option_by_name (PnActuator *actuator, const gchar *name) +{ + gint i; + PnOption *option; + + g_return_val_if_fail (actuator != NULL, NULL); + g_return_val_if_fail (PN_IS_ACTUATOR (actuator), NULL); + g_return_val_if_fail (name != NULL, NULL); + + for (i=0; i < actuator->options->len; i++) + { + option = g_array_index (actuator->options, PnOption *, i); + if (g_strcasecmp (pn_user_object_get_name (PN_USER_OBJECT (option)), name) == 0) + return option; + } + + return NULL; +} + +/** + * pn_actuator_prepare + * @actuator: a #PnActuator + * @image: the #PnImage for which the actuator should prepare + * + * Prepares an actuator to act upon a given #PnImage. + */ +void +pn_actuator_prepare (PnActuator *actuator, PnImage *image) +{ + PnActuatorClass *class; + + g_return_if_fail (actuator != NULL); + g_return_if_fail (PN_IS_ACTUATOR (actuator)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + class = PN_ACTUATOR_GET_CLASS (actuator); + + if (class->prepare) + class->prepare (actuator, image); +} + +/** + * pn_actuator_execute + * @actuator: a #PnActuator + * @image: the #PnImage to act upon + * @audio_data: the #PnAudioData to use when basing effects on sound + * + * Causes the actuator to perform its function on @image. The pn_actuator_prepare() + * *MUST* have previously been called with the same @actuator and @image arguments. + */ +void +pn_actuator_execute (PnActuator *actuator, PnImage *image, PnAudioData *audio_data) +{ + PnActuatorClass *class; + + g_return_if_fail (actuator != NULL); + g_return_if_fail (PN_IS_ACTUATOR (actuator)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); +/* g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); */ + + class = PN_ACTUATOR_GET_CLASS (actuator); + + if (class->execute) + class->execute (actuator, image, audio_data); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnactuator.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,91 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_ACTUATOR_H__ +#define __PN_ACTUATOR_H__ + +#include <glib.h> +#include "pnuserobject.h" +#include "pnoption.h" +#include "pnimage.h" +#include "pnaudiodata.h" + + +G_BEGIN_DECLS + + +enum +{ + PN_ACTUATOR_OPT_LAST = 0 +}; + +#define PN_TYPE_ACTUATOR (pn_actuator_get_type ()) +#define PN_ACTUATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_ACTUATOR, PnActuator)) +#define PN_ACTUATOR_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_ACTUATOR, PnActuatorClass)) +#define PN_IS_ACTUATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_ACTUATOR)) +#define PN_IS_ACTUATOR_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_ACTUATOR)) +#define PN_ACTUATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_ACTUATOR, PnActuatorClass)) + +typedef struct _PnActuator PnActuator; +typedef struct _PnActuatorClass PnActuatorClass; + +typedef void (*PnActuatorPrepFunc) (PnActuator *actuator, + PnImage *image); +typedef void (*PnActuatorExecFunc) (PnActuator *actuator, + PnImage *image, + PnAudioData *audio_data); + +struct _PnActuator +{ + PnUserObject parent; + + GArray *options; +}; + +struct _PnActuatorClass +{ + PnUserObjectClass parent_class; + + void (* prepare) (PnActuator *actuator, + PnImage *image); + void (* execute) (PnActuator *actuator, + PnImage *image, + PnAudioData *audio_data); +}; + +/* Creators */ +GType pn_actuator_get_type (void); + +/* Accessors */ +void pn_actuator_add_option (PnActuator *actuator, + PnOption *option); +PnOption *pn_actuator_get_option_by_index (PnActuator *actuator, + guint index); +PnOption *pn_actuator_get_option_by_name (PnActuator *actuator, + const gchar *name); +/* Actions */ +void pn_actuator_prepare (PnActuator *actuator, + PnImage *image); +void pn_actuator_execute (PnActuator *actuator, + PnImage *image, + PnAudioData *audio_data); + + + + +#endif /* __PN_ACTUATOR_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnactuatorfactory.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,109 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <glib.h> +#include "pnactuatorfactory.h" + +static gboolean pn_actuator_factory_initialized = FALSE; +static GHashTable *actuator_hash; + +void +pn_actuator_factory_init (void) +{ + if (pn_actuator_factory_initialized == TRUE) + return; + + /* FIXME: This should be done this way, but to avoid mixing glib version calls + * when linked to both versions, we need to use functions that are in both + * versions. + * + * uncomment this when glib-1.2 is no longer linked to by things like XMMS + */ +/* actuator_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); */ + actuator_hash = g_hash_table_new (g_str_hash, g_str_equal); + + pn_actuator_factory_initialized = TRUE; +} + +void +pn_actuator_factory_register_actuator (const gchar *name, GType type) +{ + gchar *dup_name; + GType *dup_type; + + g_return_if_fail (pn_actuator_factory_initialized == TRUE); + g_return_if_fail (name != NULL); + g_return_if_fail (g_type_is_a (type, PN_TYPE_ACTUATOR)); + +/* if (pn_actuator_factory_is_registered (name)) */ +/* return; */ + + dup_name = g_strdup (name); + dup_type = g_new (GType, 1); + *dup_type = type; + + g_hash_table_insert (actuator_hash, dup_name, dup_type); +} + +void +pn_actuator_factory_unregister_actuator (const gchar *name) +{ + g_return_if_fail (pn_actuator_factory_initialized == TRUE); + g_return_if_fail (name != NULL); + + g_hash_table_remove (actuator_hash, name); +} + +gboolean +pn_actuator_factory_is_registered (const gchar *name) +{ + g_return_val_if_fail (pn_actuator_factory_initialized == TRUE, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + return (g_hash_table_lookup (actuator_hash, name) != NULL); +} + +PnActuator* +pn_actuator_factory_new_actuator (const gchar *name) +{ + GType *type; + g_return_val_if_fail (pn_actuator_factory_initialized == TRUE, NULL); + g_return_val_if_fail (name != NULL, NULL); + + type = (GType *) g_hash_table_lookup (actuator_hash, name); + if (! type) + return NULL; + + return (PnActuator *) g_object_new (*type, NULL); +} + +PnActuator* +pn_actuator_factory_new_actuator_from_xml (xmlNodePtr node) +{ + PnActuator *actuator; + + actuator = pn_actuator_factory_new_actuator (node->name); + if (! actuator) + return NULL; + + pn_user_object_load_thyself (PN_USER_OBJECT (actuator), node); + + return actuator; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnactuatorfactory.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,33 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_ACTUATOR_FACTORY_H__ +#define __PN_ACTUATOR_FACTORY_H__ + +#include "pnactuator.h" + +void pn_actuator_factory_init (void); +void pn_actuator_factory_register_actuator (const gchar *name, + GType type); +void pn_actuator_factory_unregister_actuator (const gchar *name); +gboolean pn_actuator_factory_is_registered (const gchar *name); +PnActuator *pn_actuator_factory_new_actuator (const gchar *name); +PnActuator *pn_actuator_factory_new_actuator_from_xml (xmlNodePtr node); + + +#endif /* __PN_ACTUATOR_FACTORY_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnactuatorlist.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,120 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glib.h> +#include "pnactuatorlist.h" + +static void pn_actuator_list_class_init (PnActuatorListClass *class); +static void pn_actuator_list_init (PnActuatorList *actuator_list, + PnActuatorListClass *class); +/* PnActuator methods */ +static void pn_actuator_list_execute (PnActuatorList *actuator_list, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_actuator_list_get_type (void) +{ + static GType actuator_list_type = 0; + + if (! actuator_list_type) + { + static const GTypeInfo actuator_list_info = + { + sizeof (PnActuatorListClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_actuator_list_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnActuatorList), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_actuator_list_init + }; + + /* FIXME: should this be dynamic? */ + actuator_list_type = g_type_register_static (PN_TYPE_CONTAINER, + "PnActuatorList", + &actuator_list_info, + 0); + } + return actuator_list_type; +} + +static void +pn_actuator_list_class_init (PnActuatorListClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnActuator methods */ + actuator_class->execute = (PnActuatorExecFunc) pn_actuator_list_execute; +} + +static void +pn_actuator_list_init (PnActuatorList *actuator_list, PnActuatorListClass *class) +{ + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (actuator_list), "Container.Actuator_List"); + pn_user_object_set_description (PN_USER_OBJECT (actuator_list), + "A container that executes all its actuators sequentially"); +} + +static void +pn_actuator_list_execute (PnActuatorList *actuator_list, PnImage *image, + PnAudioData *audio_data) +{ + guint i; + GArray *actuators; + + g_return_if_fail (actuator_list != NULL); + g_return_if_fail (PN_IS_ACTUATOR_LIST (actuator_list)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + + actuators = ((PnContainer *) (actuator_list))->actuators;; + + for (i=0; i<actuators->len; i++) + pn_actuator_execute (g_array_index (actuators, PnActuator *, i), image, audio_data); + + if (PN_ACTUATOR_CLASS (parent_class)->execute) + PN_ACTUATOR_CLASS (parent_class)->execute(PN_ACTUATOR (actuator_list), image, audio_data); +} + +/** + * pn_actuator_list_new + * + * Creates a new #PnActuatorList. + * + * Returns: The new #PnActuatorList. + */ +PnActuatorList* +pn_actuator_list_new (void) +{ + return (PnActuatorList *) g_object_new (PN_TYPE_ACTUATOR_LIST, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnactuatorlist.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,59 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_ACTUATOR_LIST_H__ +#define __PN_ACTUATOR_LIST_H__ + +#include "pncontainer.h" + + +G_BEGIN_DECLS + + +enum +{ + PN_ACTUATOR_LIST_OPT_LAST = PN_CONTAINER_OPT_LAST +}; + +#define PN_TYPE_ACTUATOR_LIST (pn_actuator_list_get_type ()) +#define PN_ACTUATOR_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_ACTUATOR_LIST, PnActuatorList)) +#define PN_ACTUATOR_LIST_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_ACTUATOR_LIST, PnActuatorListClass)) +#define PN_IS_ACTUATOR_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_ACTUATOR_LIST)) +#define PN_IS_ACTUATOR_LIST_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_ACTUATOR_LIST)) +#define PN_ACTUATOR_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_ACTUATOR_LIST, PnActuatorListClass)) + +#define PN_ACTUATOR_LIST_ACTUATORS(obj) (PN_ACTUATOR_LIST (obj)->actuators) + +typedef struct _PnActuatorList PnActuatorList; +typedef struct _PnActuatorListClass PnActuatorListClass; + +struct _PnActuatorList +{ + PnContainer parent; +}; + +struct _PnActuatorListClass +{ + PnContainerClass parent_class; +}; + +/* Creators */ +GType pn_actuator_list_get_type (void); +PnActuatorList *pn_actuator_list_new (void); + +#endif /* __PN_ACTUATOR_LIST_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnaudiodata.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,292 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <math.h> + +#include <config.h> +#include "pnaudiodata.h" + +/* Initialization */ +static void pn_audio_data_class_init (PnAudioDataClass *class); +static void pn_audio_data_init (PnAudioData *audio_data, + PnAudioDataClass *class); + +static GObjectClass *parent_class = NULL; + +GType +pn_audio_data_get_type (void) +{ + static GType audio_data_type = 0; + + if (! audio_data_type) + { + static const GTypeInfo audio_data_info = + { + sizeof (PnAudioDataClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_audio_data_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnAudioData), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_audio_data_init + }; + + /* FIXME: should this be dynamic? */ + audio_data_type = g_type_register_static (PN_TYPE_OBJECT, + "PnAudioData", + &audio_data_info, + 0); + } + return audio_data_type; +} + +static void +pn_audio_data_class_init (PnAudioDataClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + + parent_class = g_type_class_peek_parent (class); +} + +static void +pn_audio_data_init (PnAudioData *audio_data, PnAudioDataClass *class) +{ + audio_data->stereo = TRUE; + + /* Initialize with a 1-sample and 1-band pcm_ and freq_data, respecitvely */ + audio_data->pcm_samples = 1; + audio_data->pcm_data[0] = g_new0 (gfloat, 1); + audio_data->pcm_data[1] = g_new0 (gfloat, 1); + audio_data->pcm_data[2] = g_new0 (gfloat, 1); + + audio_data->freq_bands = 1; + audio_data->freq_data[0] = g_new0 (gfloat, 1); + audio_data->freq_data[1] = g_new0 (gfloat, 1); + audio_data->freq_data[2] = g_new0 (gfloat, 1); +} + +/** + * pn_audio_data_new + * + * Creates a new #PnAudioData object. + * + * Returns: The new #PnAudioData object + */ +PnAudioData* +pn_audio_data_new (void) +{ + return (PnAudioData *) g_object_new (PN_TYPE_AUDIO_DATA, NULL); +} + +/** + * pn_audio_data_set_stereo + * @audio_data: a #PnAudioData + * @stereo: TRUE or FALSE + * + * Sets whether @audio_data will use stereo audio data. If + * stereo is %FALSE, each channel buffer points to the same memory + * location; otherwise they are separate buffers. + */ +void +pn_audio_data_set_stereo (PnAudioData *audio_data, gboolean stereo) +{ + gboolean changed; + + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + + changed = audio_data->stereo == stereo ? TRUE : FALSE; + audio_data->stereo = stereo; + + if (changed) + { + pn_audio_data_set_pcm_samples (audio_data, audio_data->pcm_samples); + pn_audio_data_set_freq_bands (audio_data, audio_data->freq_bands); + } +} + +/** + * pn_audio_data_get_stereo + * @audio_data: a #PnAudioData + * + * Retrieves the whether or not @audio_data contains stereo audio data + * + * Returns: %TRUE if it contains stereo data, %FALSE otherwise + */ +gboolean +pn_audio_data_get_stereo (PnAudioData *audio_data) +{ + g_return_val_if_fail (audio_data != NULL, FALSE); + g_return_val_if_fail (PN_IS_AUDIO_DATA (audio_data), FALSE); + + return audio_data->stereo; +} + +/** + * pn_audio_data_set_pcm_samples + * @audio_data: a #PnAudioData + * @samples: the number of samples + * + * Sets the number of samples that @audio_data's pcm data + * contains. + */ +void +pn_audio_data_set_pcm_samples (PnAudioData *audio_data, guint samples) +{ + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + g_return_if_fail (samples > 0); + + if (audio_data->pcm_data[0]) + { + g_free (audio_data->pcm_data[0]); + if (audio_data->stereo) + { + g_free (audio_data->pcm_data[1]); + g_free (audio_data->pcm_data[2]); + } + } + + audio_data->pcm_samples = samples; + audio_data->pcm_data[0] = g_new0 (gfloat, samples); + if (audio_data->stereo) + { + audio_data->pcm_data[1] = g_new0 (gfloat, samples); + audio_data->pcm_data[2] = g_new0 (gfloat, samples); + } + else + audio_data->pcm_data[1] = audio_data->pcm_data[2] = audio_data->pcm_data[0]; +} + +/** + * pn_audio_data_get_pcm_samples + * @audio_data: a #PnAudioData + * + * Retrieves the number of samples that @audio_data's pcm data + * contains + * + * Returns: The number of samples + */ +guint +pn_audio_data_get_pcm_samples (PnAudioData *audio_data) +{ + g_return_val_if_fail (audio_data != NULL, 0); + g_return_val_if_fail (PN_IS_AUDIO_DATA (audio_data), 0); + + return audio_data->pcm_samples; +} + +/** + * pn_audio_data_set_freq_bands + * @audio_data: a #PnAudioData + * @bands: the number of bands + * + * Sets the number of bands that @audio_data's frequency data + * contains. + */ +void +pn_audio_data_set_freq_bands (PnAudioData *audio_data, guint bands) +{ + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + g_return_if_fail (bands > 0); + + + if (audio_data->freq_data[0]) + { + g_free (audio_data->freq_data[0]); + if (audio_data->stereo) + { + g_free (audio_data->freq_data[1]); + g_free (audio_data->freq_data[2]); + } + } + + audio_data->freq_bands = bands; + audio_data->freq_data[0] = g_new0 (gfloat, bands); + if (audio_data->stereo) + { + audio_data->freq_data[1] = g_new0 (gfloat, bands); + audio_data->freq_data[2] = g_new0 (gfloat, bands); + } + else + audio_data->freq_data[1] = audio_data->freq_data[2] = audio_data->freq_data[0]; +} + +/** + * pn_audio_data_get_freq_bands + * @audio_data: a #PnAudioData + * + * Retrieves the number of bands that @audio_data's frequency data + * contains + * + * Returns: The number of bands + */ +guint +pn_audio_data_get_freq_bands (PnAudioData *audio_data) +{ + g_return_val_if_fail (audio_data != NULL, 0); + g_return_val_if_fail (PN_IS_AUDIO_DATA (audio_data), 0); + + return audio_data->freq_bands; +} + +/** + * pn_audio_data_get_volume + * @audio_data: a #PnAudioData + * + * Retrieves the volume level (from 0.0 to 1.0) of the audio frame + * contained within a #PnAudioData object. + * + * Returns: The volume level + */ +gfloat +pn_audio_data_get_volume (PnAudioData *audio_data) +{ + g_return_val_if_fail (audio_data != NULL, 0.0); + g_return_val_if_fail (PN_IS_AUDIO_DATA (audio_data), 0.0); + + return audio_data->volume; +} + +/** + * pn_audio_data_update + * @audio_data: a #PnAudioData + * + * Updates the information about the audio data frame in a #PnAudioData. + * This function should be called after all updates to pcm_data or freq_data. + */ +void +pn_audio_data_update (PnAudioData *audio_data) +{ + guint i; + + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + + /* Get the volume */ + audio_data->volume = 0.0; + for (i=0; i<audio_data->pcm_samples; i++) + audio_data->volume = MAX (audio_data->volume, fabs (audio_data->pcm_data[PN_CHANNEL_LEFT][i])); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnaudiodata.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,101 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_AUDIO_DATA_H__ +#define __PN_AUDIO_DATA_H__ + +#include "pnobject.h" + + +G_BEGIN_DECLS + +typedef enum +{ + PN_CHANNEL_LEFT, + PN_CHANNEL_CENTER, + PN_CHANNEL_RIGHT +} PnAudioDataChannels; + +#define PN_TYPE_AUDIO_DATA (pn_audio_data_get_type ()) +#define PN_AUDIO_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_AUDIO_DATA, PnAudioData)) +#define PN_AUDIO_DATA_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_AUDIO_DATA, PnAudioDataClass)) +#define PN_IS_AUDIO_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_AUDIO_DATA)) +#define PN_IS_AUDIO_DATA_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_AUDIO_DATA)) +#define PN_AUDIO_DATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_AUDIO_DATA, PnAudioDataClass)) +#define PN_AUDIO_DATA_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +#define PN_AUDIO_DATA_CLASS_NAME(class) (g_type_name (PN_AUDIO_DATA_CLASS_TYPE (class))) + +#define PN_AUDIO_DATA_PCM_SAMPLES(obj) (PN_AUDIO_DATA (obj)->pcm_samples) +#define PN_AUDIO_DATA_PCM_DATA(obj,ch) (PN_AUDIO_DATA (obj)->pcm_data[ch]) +#define PN_AUDIO_DATA_FREQ_BANDS(obj) (PN_AUDIO_DATA (obj)->freq_bands) +#define PN_AUDIO_DATA_FREQ_DATA(obj,ch) (PN_AUDIO_DATA (obj)->freq_data[ch]) + +typedef struct _PnAudioData PnAudioData; +typedef struct _PnAudioDataClass PnAudioDataClass; + +struct _PnAudioData +{ + PnObject parent; + + /*< public >*/ + + /* PCM and frequency data are floats in the range of 0 to 1 */ + + /* PCM Data */ + guint pcm_samples; /* read-only */ + gfloat *pcm_data[3]; /* read-write */ + + /* Frequency Data */ + guint freq_bands; /* read-only */ + gfloat *freq_data[3]; /* read-write */ + + /*< private >*/ + /* If this is TRUE, each channel is separate, otherwise they all point + * to the same buffer. Default is TRUE. + */ + gboolean stereo; + + /* Overall volume of the audio frame */ + gfloat volume; +}; + +struct _PnAudioDataClass +{ + PnObjectClass parent_class; +}; + +/* Creators */ +GType pn_audio_data_get_type (void); +PnAudioData *pn_audio_data_new (void); + +/* Accessors */ +void pn_audio_data_set_stereo (PnAudioData *audio_data, + gboolean stereo); +gboolean pn_audio_data_get_stereo (PnAudioData *audio_data); +void pn_audio_data_set_pcm_samples (PnAudioData *audio_data, + guint samples); +guint pn_audio_data_get_pcm_samples (PnAudioData *audio_data); +void pn_audio_data_set_freq_bands (PnAudioData *audio_data, + guint bands); +guint pn_audio_data_get_freq_bands (PnAudioData *audio_data); +gfloat pn_audio_data_get_volume (PnAudioData *audio_data); + +/* Actions */ +void pn_audio_data_update (PnAudioData *audio_data); + +#endif /* __PN_AUDIO_DATA_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnblur.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,338 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glib.h> +#include "pnblur.h" +#include "pncpu.h" + +static void pn_blur_class_init (PnBlurClass *class); +static void pn_blur_init (PnBlur *blur, + PnBlurClass *class); + +/* PnActuator methods */ +static void pn_blur_execute (PnBlur *blur, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_blur_get_type (void) +{ + static GType blur_type = 0; + + if (! blur_type) + { + static const GTypeInfo blur_info = + { + sizeof (PnBlurClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_blur_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnBlur), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_blur_init + }; + + /* FIXME: should this be dynamic? */ + blur_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnBlur", + &blur_info, + 0); + } + return blur_type; +} + +static void +pn_blur_class_init (PnBlurClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnActuator methods */ + actuator_class->execute = (PnActuatorExecFunc) pn_blur_execute; +} + +static void +pn_blur_init (PnBlur *blur, PnBlurClass *class) +{ + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (blur), "Transform.Blur"); + pn_user_object_set_description (PN_USER_OBJECT (blur), + "Blur the image"); +} + +static inline void +pn_blur_execute_medium (PnImage *image) +{ + register PnColor *src_left; + PnColor *src_top, *src_bot, *src_right; + PnColor *dest, *dest_last; + guint width, width_m1, total_width, height, height_m1; + register guint red_sum, green_sum, blue_sum; + guint i = 0; + + width = pn_image_get_width (image); + width_m1 = width - 1; + total_width = pn_image_get_pitch (image)>>2; + height = pn_image_get_height (image); + height_m1 = height - 1; + + dest = pn_image_get_transform_buffer (image); + src_left = pn_image_get_image_buffer (image) - 1; + src_right = src_left + 2; + src_top = (src_left - total_width) + 1; + src_bot = (src_left + total_width) + 1; + + src_top += total_width; + src_bot += total_width; + src_left += total_width; + src_right += total_width; + dest += total_width; + + dest_last = pn_image_get_transform_buffer (image) + (total_width * (height-1)); + while (dest < dest_last) + { + for (i=0; i < width; i++) + { + /* Top pixel */ + red_sum = src_top->red; + green_sum = src_top->green; + blue_sum = src_top->blue; + + /* Bottom pixel */ + red_sum += src_bot->red; + green_sum += src_bot->green; + blue_sum += src_bot->blue; + + /* Left pixel */ + if (i != 0) + { + red_sum += src_left->red; + green_sum += src_left->green; + blue_sum += src_left->blue; + } + else + { + red_sum += (src_left+1)->red; + green_sum += (src_left+1)->green; + blue_sum += (src_left+1)->blue; + } + + /* Right pixel */ + if (i != width_m1) + { + red_sum += src_right->red; + green_sum += src_right->green; + blue_sum += src_right->blue; + } + else + { + red_sum += (src_left+1)->red; + green_sum += (src_left+1)->green; + blue_sum += (src_left+1)->blue; + } + + src_left++; + src_right++; + src_top++; + src_bot++; + + /* red_sum *= 3; */ + /* green_sum *= 3; */ + /* blue_sum *= 3; */ + + /* Center pixel */ + red_sum += src_left->red << 2; + green_sum += src_left->green << 2; + blue_sum += src_left->blue << 2; + + dest->red = (guchar)(red_sum >> 3); + dest->green = (guchar)(green_sum >> 3); + dest->blue = (guchar)(blue_sum >> 3); + dest++; + } + src_left += total_width - width; + src_right += total_width - width; + src_bot += total_width - width; + src_top += total_width - width; + dest += total_width - width; + } +} + +#ifdef PN_USE_MMX +static void +pn_blur_execute_medium_mmx (PnImage *image) +{ + guint width, pitch; + PnColor *src, *dest, *dest_last; + + width = pn_image_get_width (image); + pitch = pn_image_get_pitch (image); + + src = pn_image_get_image_buffer (image) - 1; + dest = pn_image_get_transform_buffer (image) + (pitch>>2); + dest_last = dest + ((pitch>>2) * (pn_image_get_height (image) - 2)); + + /* + * ecx = x counter + */ + + /* + * src X X X + * X X X X + * X X X X + */ + + /* + * X X X X + * X dest X X + * X X X X + */ + + /* + * %0 = src + * %1 = dest + * %2 = pitch + * %3 = width + * %4 = dest_last + */ + + /* + * mm0 = left dest pixel sum + * mm1 = right dest pixel sum + * mm6 = unpacked leftmost source pixel + * mm7 = 0 + */ + + __asm__ __volatile__ ( + "movl %3,%%ecx\n\t" /* start with x = 0 */ + + "pxor %%mm7,%%mm7\n\t" /* set up the zero mmx register used + * in unpacking + */ + + "pxor %%mm6,%%mm6\n\t" /* start with the leftmost pixel = zero */ + + + "10:\n\t" /* begin the inner loop */ + + "movq 4(%0),%%mm0\n\t" /* load and unpack the top and bottom */ + "movq 4(%0,%2,2),%%mm2\n\t" /* row of pixels */ + "movq %%mm0,%%mm1\n\t" + "movq %%mm2,%%mm3\n\t" + "punpcklbw %%mm7,%%mm0\n\t" /* tops */ + "punpckhbw %%mm7,%%mm1\n\t" + "punpcklbw %%mm7,%%mm2\n\t" /* bottoms */ + "punpckhbw %%mm7,%%mm3\n\t" + + "paddw %%mm2,%%mm0\n\t" /* add the two top & bottom pixels */ + "paddw %%mm3,%%mm1\n\t" + + "paddw %%mm6,%%mm0\n\t" /* add the left pixel */ + + "movq 4(%0,%2),%%mm2\n\t" /* load and unpack the two center pixels */ + "movq %%mm2,%%mm3\n\t" + "punpcklbw %%mm7,%%mm2\n\t" /* used as quadruple-weighted center pixels */ + "punpckhbw %%mm7,%%mm3\n\t" + + "movq %%mm3,%%mm6\n\t" /* save the unpacked right-center pixel + * for the next iteration's leftmost pixel + */ + + "cmpl $1,%%ecx\n\t" /* make sure the right-center pixel is on + * the image + */ + "je 20f\n\t" + + "movd 12(%0,%2),%%mm5\n\t" /* load and unpack the right pixel */ + "punpcklbw %%mm7,%%mm5\n\t" + "paddw %%mm5,%%mm1\n\t" /* add the right pixel */ + + "paddw %%mm3,%%mm0\n\t" /* add the center pixels as adjecent pixels */ + "paddw %%mm2,%%mm1\n\t" + "20:\n\t" + + "psllw $2,%%mm2\n\t" /* multiply the center pixels by 4 */ + "psllw $2,%%mm3\n\t" + + /* multiply the sums (mm0 and mm1) by 3 for the heavy blur here */ + + "paddw %%mm2,%%mm0\n\t" /* add the center pixels as center pixels */ + "paddw %%mm3,%%mm1\n\t" + + "psrlw $3,%%mm0\n\t" /* normalize the values - should be 4 for */ + "psrlw $3,%%mm1\n\t" /* heavy blur */ + + "packuswb %%mm1,%%mm0\n\t" /* repack it all and write it */ + "movq %%mm0,(%1)\n\t" + + "addl $8,%0\n\t" /* advance the pointers */ + "addl $8,%1\n\t" + + "subl $2,%%ecx\n\t" /* decrement inverse x counter */ + "jg 10b\n\t" + + "movl %3,%%ecx\n\t" /* start a new line */ + "pxor %%mm6,%%mm6\n\t" + + "cmpl %1,%4\n\t" /* if we're all done then stop */ + "jg 10b\n\t" + + "emms" /* all done! */ + : /* no outputs */ + : "r" (src), "r" (dest), "r" (pitch), "r" (width), "m" (dest_last) + : "ecx" + ); +} +#endif /* USE_MMX */ + +static void +pn_blur_execute (PnBlur *blur, PnImage *image, PnAudioData *audio_data) +{ + g_return_if_fail (blur != NULL); + g_return_if_fail (PN_IS_BLUR (blur)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + +#ifdef PN_USE_MMX + if (pn_cpu_get_caps () & PN_CPU_CAP_MMX) + pn_blur_execute_medium_mmx (image); + else +#endif /* USE_MMX */ + pn_blur_execute_medium (image); + + pn_image_apply_transform (image); +} + +PnBlur* +pn_blur_new (void) +{ + return (PnBlur *) g_object_new (PN_TYPE_BLUR, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnblur.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,56 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_BLUR_H__ +#define __PN_BLUR_H__ + +#include "pnactuator.h" + +G_BEGIN_DECLS + + +enum +{ + PN_BLUR_OPT_LAST = PN_ACTUATOR_OPT_LAST +}; + +#define PN_TYPE_BLUR (pn_blur_get_type ()) +#define PN_BLUR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_BLUR, PnBlur)) +#define PN_BLUR_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_BLUR, PnBlurClass)) +#define PN_IS_BLUR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_BLUR)) +#define PN_IS_BLUR_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_BLUR)) +#define PN_BLUR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_BLUR, PnBlurClass)) + +typedef struct _PnBlur PnBlur; +typedef struct _PnBlurClass PnBlurClass; + +struct _PnBlur +{ + PnActuator parent; +}; + +struct _PnBlurClass +{ + PnActuatorClass parent_class; +}; + +/* Creators */ +GType pn_blur_get_type (void); +PnBlur *pn_blur_new (void); + +#endif /* __PN_BLUR_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnbooleanoption.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,190 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <ctype.h> +#include <glib.h> +#include "pnbooleanoption.h" +#include "pnxml.h" +#include "pnerror.h" + +static void pn_boolean_option_class_init (PnBooleanOptionClass *class); + +/* PnUserObject methods */ +static void pn_boolean_option_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_boolean_option_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static PnUserObjectClass *parent_class = NULL; + +GType +pn_boolean_option_get_type (void) +{ + static GType boolean_option_type = 0; + + if (! boolean_option_type) + { + static const GTypeInfo boolean_option_info = + { + sizeof (PnBooleanOptionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_boolean_option_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnBooleanOption), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + + /* FIXME: should this be dynamic? */ + boolean_option_type = g_type_register_static (PN_TYPE_OPTION, + "PnBooleanOption", + &boolean_option_info, + 0); + } + return boolean_option_type; +} + +static void +pn_boolean_option_class_init (PnBooleanOptionClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnOptionClass *option_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + option_class = (PnOptionClass *) class; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_boolean_option_save_thyself; + user_object_class->load_thyself = pn_boolean_option_load_thyself; + + /* PnOption methods */ + /* FIXME: this needs to be uncommented when the widget is done */ +/* option_class->widget_type = PN_TYPE_BOOLEAN_OPTION_WIDGET; */ +} + +static void +pn_boolean_option_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnBooleanOption *boolean_option; + xmlNodePtr value_node; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_BOOLEAN_OPTION (user_object)); + g_return_if_fail (node != NULL); + + boolean_option = (PnBooleanOption *) user_object; + + value_node = xmlNewChild (node, NULL, "Value", NULL); + + if (boolean_option->value) + xmlNodeSetContent (value_node, "True"); + else + xmlNodeSetContent (value_node, "False"); + + if (parent_class->save_thyself) + parent_class->save_thyself (user_object, node); +} + +static void +pn_boolean_option_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnBooleanOption *boolean_option; + xmlNodePtr boolean_option_node; + gchar *val_str; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_BOOLEAN_OPTION (user_object)); + g_return_if_fail (node != NULL); + + boolean_option = (PnBooleanOption *) user_object; + + /* find the node for this class */ + for (boolean_option_node = node->xmlChildrenNode; + boolean_option_node; + boolean_option_node = boolean_option_node->next) + if (g_strcasecmp (boolean_option_node->name, "Value") == 0) + break; + if (! boolean_option_node) + { + pn_error ("unable to load a PnBooleanOption from xml node \"%s\"", node->name); + return; + } + + val_str = xmlNodeGetContent (boolean_option_node); + if (! val_str) + goto done; + + while (isspace (*val_str)) + val_str++; + + if (g_strncasecmp (val_str, "True", 4) == 0) + boolean_option->value = TRUE; + else if (g_strncasecmp (val_str, "False", 5) == 0) + boolean_option->value = FALSE; + else + { + pn_error ("invalid boolean option value encountered at xml node \"%s\"", node->name); + return; + } + + done: + if (parent_class->load_thyself) + parent_class->load_thyself (user_object, node); +} + +PnBooleanOption* +pn_boolean_option_new (const gchar *name, const gchar *desc) +{ + PnBooleanOption *boolean_option; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (desc != NULL, NULL); + + boolean_option = (PnBooleanOption *) g_object_new (PN_TYPE_BOOLEAN_OPTION, NULL); + + pn_user_object_set_name (PN_USER_OBJECT (boolean_option), name); + pn_user_object_set_description (PN_USER_OBJECT (boolean_option), desc); + + return boolean_option; +} + +void +pn_boolean_option_set_value (PnBooleanOption *boolean_option, gboolean value) +{ + g_return_if_fail (boolean_option != NULL); + g_return_if_fail (PN_IS_BOOLEAN_OPTION (boolean_option)); + + boolean_option->value = value; +} + +gboolean +pn_boolean_option_get_value (PnBooleanOption *boolean_option) +{ + g_return_val_if_fail (boolean_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_BOOLEAN_OPTION (boolean_option), FALSE); + + return boolean_option->value; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnbooleanoption.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,60 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_BOOLEAN_OPTION_H__ +#define __PN_BOOLEAN_OPTION_H__ + +#include "pnoption.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_BOOLEAN_OPTION (pn_boolean_option_get_type ()) +#define PN_BOOLEAN_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_BOOLEAN_OPTION, PnBooleanOption)) +#define PN_BOOLEAN_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_BOOLEAN_OPTION, PnBooleanOptionClass)) +#define PN_IS_BOOLEAN_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_BOOLEAN_OPTION)) +#define PN_IS_BOOLEAN_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_BOOLEAN_OPTION)) +#define PN_BOOLEAN_OPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_BOOLEAN_OPTION, PnBooleanOptionClass)) + +typedef struct _PnBooleanOption PnBooleanOption; +typedef struct _PnBooleanOptionClass PnBooleanOptionClass; + +struct _PnBooleanOption +{ + PnOption parent; + + gboolean value; +}; + +struct _PnBooleanOptionClass +{ + PnOptionClass parent_class; +}; + +/* Creators */ +GType pn_boolean_option_get_type (void); +PnBooleanOption *pn_boolean_option_new (const gchar *name, + const gchar *desc); + +/* Accessors */ +void pn_boolean_option_set_value (PnBooleanOption *boolean_option, + gboolean value); +gboolean pn_boolean_option_get_value (PnBooleanOption *boolean_option); + +#endif /* __PN_BOOLEAN_OPTION_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnbuiltins.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,44 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include "pnactuatorfactory.h" + +#include "pnactuatorlist.h" +#include "pnblur.h" +#include "pndisplacement.h" +#include "pndistortion.h" +#include "pnflip.h" +#include "pnimagecontext.h" +#include "pnrotozoom.h" +#include "pnscope.h" + +/* This NEEDS to be kept in sync with ALL the actuators */ +void +pn_builtins_register (void) +{ + pn_actuator_factory_register_actuator ("Container.Actuator_List", PN_TYPE_ACTUATOR_LIST); + pn_actuator_factory_register_actuator ("Transform.Blur", PN_TYPE_BLUR); + pn_actuator_factory_register_actuator ("Transform.Displacement", PN_TYPE_DISPLACEMENT); + pn_actuator_factory_register_actuator ("Transform.Distortion", PN_TYPE_DISTORTION); + pn_actuator_factory_register_actuator ("Transform.Flip", PN_TYPE_FLIP); + pn_actuator_factory_register_actuator ("Container.Image_Context", PN_TYPE_IMAGE_CONTEXT); + pn_actuator_factory_register_actuator ("Transform.Roto_Zoom", PN_TYPE_ROTO_ZOOM); + pn_actuator_factory_register_actuator ("Render.Scope", PN_TYPE_SCOPE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnbuiltins.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,32 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_BUILTINS_H__ +#define __PN_BUILTINS_H__ + + +G_BEGIN_DECLS + + +void pn_builtins_register (void); + + + + + +#endif /* __PN_BUILTINS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pncontainer.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,300 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glib.h> +#include "pncontainer.h" +#include "pnactuatorfactory.h" +#include "pnerror.h" +#include "pnxml.h" + +static void pn_container_class_init (PnContainerClass *class); +static void pn_container_init (PnContainer *container, + PnContainerClass *class); +/* PnObject methods */ +static void pn_container_destroy (PnObject *object); + +/* PnUserObject methods */ +static void pn_container_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_container_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +/* PnActuator methods */ +static void pn_container_prepare (PnContainer *container, + PnImage *image); + +/* PnContainer methods */ +static gboolean pn_container_real_add_actuator (PnContainer *container, + PnActuator *actuator, + gint position); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_container_get_type (void) +{ + static GType container_type = 0; + + if (! container_type) + { + static const GTypeInfo container_info = + { + sizeof (PnContainerClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_container_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnContainer), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_container_init + }; + + /* FIXME: should this be dynamic? */ + container_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnContainer", + &container_info, + G_TYPE_FLAG_ABSTRACT); + } + return container_type; +} + +static void +pn_container_class_init (PnContainerClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnObject signals */ + object_class->destroy = pn_container_destroy; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_container_save_thyself; + user_object_class->load_thyself = pn_container_load_thyself; + + /* PnActuator methods */ + actuator_class->prepare = (PnActuatorPrepFunc) pn_container_prepare; + + /* PnContainer methods */ + class->add_actuator = pn_container_real_add_actuator; +} + +static void +pn_container_init (PnContainer *container, PnContainerClass *class) +{ + container->actuators = g_array_new (FALSE, FALSE, sizeof (PnActuator *)); +} + +static void +pn_container_destroy (PnObject *object) +{ + PnContainer *container; + + g_return_if_fail (object != NULL); + g_return_if_fail (PN_IS_CONTAINER (object)); + + container = (PnContainer *) object; + + pn_container_remove_all_actuators (container); +} + +static void +pn_container_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnContainer *container; + PnActuator *actuator; + xmlNodePtr actuators_node, actuator_node; + guint i; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_CONTAINER (user_object)); + g_return_if_fail (node != NULL); + + container = (PnContainer *) user_object; + + actuators_node = xmlNewChild (node, NULL, "Actuators", NULL); + + /* Save the actuators */ + for (i=0; i<container->actuators->len; i++) + { + actuator = g_array_index (container->actuators, PnActuator *, i); + actuator_node = xmlNewChild (actuators_node, NULL, "BUG", NULL); + pn_user_object_save_thyself (PN_USER_OBJECT (actuator), actuator_node); + } + + if (PN_USER_OBJECT_CLASS (parent_class)->save_thyself) + PN_USER_OBJECT_CLASS (parent_class)->save_thyself (user_object, node); +} + +static void +pn_container_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnContainer *container; + xmlNodePtr actuators_node, actuator_node; + PnActuator *actuator; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_CONTAINER (user_object)); + g_return_if_fail (node != NULL); + + container = (PnContainer *) user_object; + + /* FIXME: should these 'xmlChildrenNode' be 'xmlRootNode'? */ + + /* find the 'actuators' node */ + for (actuators_node = node->xmlChildrenNode; actuators_node; actuators_node = actuators_node->next) + if (g_strcasecmp (actuators_node->name, "Actuators") == 0) + break; + + /* load each of the actuators */ + if (actuators_node) + { + for (actuator_node = actuators_node->xmlChildrenNode; actuator_node; actuator_node = actuator_node->next) + { + actuator = pn_actuator_factory_new_actuator_from_xml (actuator_node); + if (actuator) + /* FIXME: Should this be pn_container_real_add_actuator? */ + pn_container_add_actuator (container, actuator, PN_POSITION_TAIL); + else + pn_error ("unknown actuator ecountered in container \"%s\": %s", + node->name, + actuator_node->name); + } + } + + if (PN_USER_OBJECT_CLASS (parent_class)->load_thyself) + PN_USER_OBJECT_CLASS (parent_class)->load_thyself (user_object, node); +} + +static void +pn_container_prepare (PnContainer *container, PnImage *image) +{ + guint i; + + g_return_if_fail (container != NULL); + g_return_if_fail (PN_IS_CONTAINER (container)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + for (i=0; i<container->actuators->len; i++) + pn_actuator_prepare (g_array_index (container->actuators, PnActuator *, i), image); +} + +static gboolean +pn_container_real_add_actuator (PnContainer *container, PnActuator *actuator, gint position) +{ + g_return_val_if_fail (container != NULL, FALSE); + g_return_val_if_fail (PN_IS_CONTAINER (container), FALSE); + g_return_val_if_fail (actuator != NULL, FALSE); + g_return_val_if_fail (PN_IS_ACTUATOR (actuator), FALSE); + g_return_val_if_fail (position >= PN_POSITION_TAIL, FALSE); + + if (position == PN_POSITION_TAIL || position >= container->actuators->len) + position = container->actuators->len; + + /* Just pass it on to the GArray insert function */ + g_array_insert_val (container->actuators, position, actuator); + + pn_object_ref (PN_OBJECT (actuator)); + pn_object_sink (PN_OBJECT (actuator)); + + return TRUE; +} + +/** + * pn_container_add_actuator + * @container: a #PnContainer + * @actuator: the #PnActuator to add + * @position: the position at which to add the actuator + * + * Adds @actuator to @container. @position is the zero-based index + * in the list of actuators that the newly added actuator should have, + * or it can be the value %PN_POSITION_HEAD or %PN_POSITION_TAIL. + * + * Returns: %TRUE on success; %FALSE on failure + */ +gboolean +pn_container_add_actuator (PnContainer *container, PnActuator *actuator, gint position) +{ + g_return_val_if_fail (container != NULL, FALSE); + g_return_val_if_fail (PN_IS_CONTAINER (container), FALSE); + g_return_val_if_fail (actuator != NULL, FALSE); + g_return_val_if_fail (PN_IS_ACTUATOR (actuator), FALSE); + g_return_val_if_fail (position >= PN_POSITION_TAIL, FALSE); + + if (PN_CONTAINER_GET_CLASS (container)->add_actuator) + return PN_CONTAINER_GET_CLASS (container)->add_actuator (container, actuator, position); + else + return FALSE; +} + +/** + * pn_container_remove_actuator + * @container: a #PnContainer + * @actuator: the #PnActuator to remove + * + * Removes the first occurence of @actuator in @container's list + * of contained actuators. + */ +/* FIXME: what is the most convenient way to remove actuators? */ +/* Note: Only removes the first one in the array */ +void +pn_container_remove_actuator (PnContainer *container, PnActuator *actuator) +{ + guint i; + + g_return_if_fail (container != NULL); + g_return_if_fail (PN_IS_CONTAINER (container)); + g_return_if_fail (actuator != NULL); + g_return_if_fail (PN_IS_ACTUATOR (actuator)); + + for (i=0; i<container->actuators->len; i++) + if (g_array_index (container->actuators, PnActuator *, i) == actuator) + { + g_array_remove_index (container->actuators, i); + pn_object_unref (PN_OBJECT (actuator)); + return; + } +} + +/** + * pn_container_remove_all_actuators + * @container: a #PnContainer + * + * Removes all actuators from @container's list of contained actuators. + */ +void +pn_container_remove_all_actuators (PnContainer *container) +{ + guint i; + + g_return_if_fail (container != NULL); + g_return_if_fail (PN_IS_CONTAINER (container)); + + for (i=0; i<container->actuators->len; i++) + pn_object_unref (g_array_index (container->actuators, PnObject *, i)); + + g_array_set_size (container->actuators, 0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pncontainer.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,82 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_CONTAINER_H__ +#define __PN_CONTAINER_H__ + +#include "pnactuator.h" + + +G_BEGIN_DECLS + + +enum +{ + PN_CONTAINER_OPT_LAST = PN_ACTUATOR_OPT_LAST +}; + +typedef enum +{ + PN_POSITION_TAIL = -1, + PN_POSITION_HEAD = 0 +} PnContainerPosition; + +#define PN_TYPE_CONTAINER (pn_container_get_type ()) +#define PN_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_CONTAINER, PnContainer)) +#define PN_CONTAINER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_CONTAINER, PnContainerClass)) +#define PN_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_CONTAINER)) +#define PN_IS_CONTAINER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_CONTAINER)) +#define PN_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_CONTAINER, PnContainerClass)) + +#define PN_CONTAINER_ACTUATORS(obj) (PN_CONTAINER (obj)->actuators) + +typedef struct _PnContainer PnContainer; +typedef struct _PnContainerClass PnContainerClass; + +struct _PnContainer +{ + PnActuator parent; + + GArray *actuators; /* read-only */ +}; + +struct _PnContainerClass +{ + PnActuatorClass parent_class; + + gboolean (* add_actuator) (PnContainer *container, + PnActuator *actuator, + gint position); +}; + +/* Creators */ +GType pn_container_get_type (void); + +/* Actions */ +gboolean pn_container_add_actuator (PnContainer *container, + PnActuator *actuator, + gint position); +void pn_container_remove_actuator (PnContainer *container, + PnActuator *actuator); +void pn_container_remove_all_actuators (PnContainer *container); + + + + + +#endif /* __PN_CONTAINER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pncpu.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,95 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <glib.h> +#include "pncpu.h" + +static guint cpu_caps = 0; +static gboolean pn_cpu_ready = FALSE; + +#if defined PN_USE_CPU_IA32 +#define pn_cpu_init_arch pn_cpu_init_ia32 +void +pn_cpu_init_ia32 (void) +{ + gboolean AMD = FALSE; + guint eax, ebx, ecx, edx; + + /* GCC won't acknowledge the fact that I'm clobbering ebx, so just save it */ +#define CPUID __asm__ __volatile__ ("pushl %%ebx\n\tcpuid\n\tmovl %%ebx,%1\n\tpopl %%ebx" \ + :"+a"(eax),"=r"(ebx),"=c"(ecx),"=d"(edx)::"ebx"); + + eax = 0; + CPUID; + + AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); + + eax = 1; + CPUID; + + if (edx & (1 << 23)) + cpu_caps |= PN_CPU_CAP_MMX; + + if (edx & (1 << 25)) + { + cpu_caps |= PN_CPU_CAP_MMXEXT; + cpu_caps |= PN_CPU_CAP_SSE; + } + + eax = 0x80000000; + CPUID; + + if (eax >= 0x80000001) + { + eax = 0x80000001; + CPUID; + + if (edx & (1 << 31)) + cpu_caps |= PN_CPU_CAP_3DNOW; + if (AMD && (edx & (1 << 22))) + cpu_caps |= PN_CPU_CAP_MMXEXT; + } +#undef CPUID +} +#else /* Architecture */ +void +pn_cpu_init_arch (void) +{ +} +#endif /* Architecture */ + +void +pn_cpu_init (void) +{ + if (pn_cpu_ready) + return; + + pn_cpu_init_arch (); + + pn_cpu_ready = TRUE; +} + +guint +pn_cpu_get_caps (void) +{ + pn_cpu_init (); + + return cpu_caps; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pncpu.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,33 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_CPU_H__ +#define __PN_CPU_H__ + +typedef enum +{ + PN_CPU_CAP_MMX = (1<<0), + PN_CPU_CAP_MMXEXT = (1<<1), + PN_CPU_CAP_SSE = (1<<2), + PN_CPU_CAP_3DNOW = (1<<3) +} PnCPUCaps; + +void pn_cpu_init (void); +guint pn_cpu_get_caps (void); + +#endif /* __PN_CPU_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pndisplacement.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,423 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <math.h> +#include <glib.h> +#include "pndisplacement.h" +#include "pnbooleanoption.h" +#include "pnstringoption.h" +#include "pncpu.h" + +enum +{ + PN_PIXEL_DISPLACEMENT_NO_PIXEL = 0xffffffff +}; + +static void pn_displacement_class_init (PnDisplacementClass *class); +static void pn_displacement_init (PnDisplacement *displacement, + PnDisplacementClass *class); +/* PnObject signals */ +static void pn_displacement_destroy (PnObject *object); + +/* PnActuator methods */ +static void pn_displacement_prepare (PnDisplacement *displacement, + PnImage *image); +static void pn_displacement_execute (PnDisplacement *displacement, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_displacement_get_type (void) +{ + static GType displacement_type = 0; + + if (! displacement_type) + { + static const GTypeInfo displacement_info = + { + sizeof (PnDisplacementClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_displacement_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnDisplacement), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_displacement_init + }; + + /* FIXME: should this be dynamic? */ + displacement_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnDisplacement", + &displacement_info, + 0); + } + return displacement_type; +} + +static void +pn_displacement_class_init (PnDisplacementClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnObject signals */ + object_class->destroy = pn_displacement_destroy; + + /* PnActuator methods */ + actuator_class->prepare = (PnActuatorPrepFunc) pn_displacement_prepare; + actuator_class->execute = (PnActuatorExecFunc) pn_displacement_execute; +} + +static void +pn_displacement_init (PnDisplacement *displacement, PnDisplacementClass *class) +{ + PnStringOption *init_script_opt, *frame_script_opt; + + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (displacement), "Transform.Displacement"); + pn_user_object_set_description (PN_USER_OBJECT (displacement), + "Displaces the image"); + + /* Set up the options */ + init_script_opt = pn_string_option_new ("init_script", "The initialization script"); + frame_script_opt = pn_string_option_new ("frame_script", "The per-frame script"); + + pn_actuator_add_option (PN_ACTUATOR (displacement), PN_OPTION (init_script_opt)); + pn_actuator_add_option (PN_ACTUATOR (displacement), PN_OPTION (frame_script_opt)); + + /* Create the script objects and symbol table */ + displacement->init_script = pn_script_new (); + pn_object_ref (PN_OBJECT (displacement->init_script)); + pn_object_sink (PN_OBJECT (displacement->init_script)); + displacement->frame_script = pn_script_new (); + pn_object_ref (PN_OBJECT (displacement->frame_script)); + pn_object_sink (PN_OBJECT (displacement->frame_script)); + displacement->symbol_table = pn_symbol_table_new (); + pn_object_ref (PN_OBJECT (displacement->symbol_table)); + pn_object_sink (PN_OBJECT (displacement->symbol_table)); + + /* Get the variables from the symbol table */ + displacement->x_var = pn_symbol_table_ref_variable_by_name (displacement->symbol_table, "x"); + displacement->y_var = pn_symbol_table_ref_variable_by_name (displacement->symbol_table, "y"); + displacement->volume_var = pn_symbol_table_ref_variable_by_name (displacement->symbol_table, "volume"); +} + +static void +pn_displacement_destroy (PnObject *object) +{ + PnDisplacement *displacement; + + displacement = (PnDisplacement *) object; + + pn_object_unref (PN_OBJECT (displacement->init_script)); + pn_object_unref (PN_OBJECT (displacement->frame_script)); + pn_object_unref (PN_OBJECT (displacement->symbol_table)); +} + +/* FIXME: optimize this */ +static void +pn_displacement_prepare (PnDisplacement *displacement, PnImage *image) +{ + PnStringOption *init_script_opt, *frame_script_opt; + + g_return_if_fail (displacement != NULL); + g_return_if_fail (PN_IS_DISPLACEMENT (displacement)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + /* Parse the script strings */ + init_script_opt = + (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (displacement), + PN_DISPLACEMENT_OPT_INIT_SCRIPT); + frame_script_opt = + (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (displacement), + PN_DISPLACEMENT_OPT_FRAME_SCRIPT); + + pn_script_parse_string (displacement->init_script, displacement->symbol_table, + pn_string_option_get_value (init_script_opt)); + pn_script_parse_string (displacement->frame_script, displacement->symbol_table, + pn_string_option_get_value (frame_script_opt)); + + /* Set up 0 displacement */ + PN_VARIABLE_VALUE (displacement->x_var) = 0.0; + PN_VARIABLE_VALUE (displacement->y_var) = 0.0; + + /* Run the init script */ + pn_script_execute (displacement->init_script); + + if (PN_ACTUATOR_CLASS (parent_class)->prepare) + PN_ACTUATOR_CLASS (parent_class)->prepare (PN_ACTUATOR (displacement), image); +} + +static void +pn_displacement_exec (PnImage *image, gint offset, guint nw, guint ne, guint sw, guint se, + gint startx, gint starty, gint endx, gint endy) +{ + gint i, j, width, height, stride; + PnColor *src, *dest, zero = {0,0,0,0}; + guint r, g, b; + + width = pn_image_get_width (image); + height = pn_image_get_height (image); + stride = pn_image_get_pitch (image) >> 2; + + src = pn_image_get_image_buffer (image); + dest = pn_image_get_transform_buffer (image); + + for (j=0; j<height; j++) + for (i=0; i<width; i++) + { + if (i < startx || i >= endx + || j < starty || j >= endy) + dest[j * stride + i] = zero; + else + { + r = src[(j * stride + i) + offset].red * nw; + g = src[(j * stride + i) + offset].green * nw; + b = src[(j * stride + i) + offset].blue * nw; + + r += src[(j * stride + (i + 1)) + offset].red * ne; + g += src[(j * stride + (i + 1)) + offset].green * ne; + b += src[(j * stride + (i + 1)) + offset].blue * ne; + + r += src[((j + 1) * stride + i) + offset].red * sw; + g += src[((j + 1) * stride + i) + offset].green * sw; + b += src[((j + 1) * stride + i) + offset].blue * sw; + + r += src[((j + 1) * stride + (i + 1)) + offset].red * se; + g += src[((j + 1) * stride + (i + 1)) + offset].green * se; + b += src[((j + 1) * stride + (i + 1)) + offset].blue * se; + + dest[j * stride + i].red = r >> 7; + dest[j * stride + i].green = g >> 7; + dest[j * stride + i].blue = b >> 7; + } + } +} + +#ifdef PN_USE_MMX +static void +pn_displacement_exec_mmx (PnImage *image, gint offset, guint nw, guint ne, guint sw, guint se, + gint startx, gint starty, gint endx, gint endy) +{ + PnColor *src, *dest, *endptr; + gint width, height, stride, i; + guint64 upnw; /* a place to store the unpacked se weight */ + + width = pn_image_get_width (image); + height = pn_image_get_height (image); + stride = pn_image_get_pitch (image) >> 2; + + src = pn_image_get_image_buffer (image); + dest = pn_image_get_transform_buffer (image); + + memset (dest, 0, pn_image_get_pitch (image) * starty); + for (i=MAX(starty, 0); i<endy; i++) + { + memset (dest + i * stride, 0, startx * sizeof (PnColor)); + memset (dest + i * stride + endx, 0, (width - endx) * sizeof (PnColor)); + } + memset (dest + endy * stride, 0, (height - endy) * pn_image_get_pitch (image)); + + src += (starty * stride) + offset; + endptr = src + endx; + src += startx; + dest += (starty * stride) + startx; + + __asm__ __volatile__ ( + /* Unpack the weights */ + "pxor %%mm7,%%mm7\n\t" /* zero mm7 for unpacking */ + "movd %8,%%mm4\n\t" /* load the weights */ + "punpcklbw %%mm7,%%mm4\n\t" /* unpack the weights to words */ + "movq %%mm4,%%mm6\n\t" /* copy the weights for separate expansion */ + "punpcklwd %%mm4,%%mm4\n\t" /* expand the top weights */ + "punpckhwd %%mm6,%%mm6\n\t" /* expand the bottom weights */ + "movq %%mm4,%%mm5\n\t" /* copy the top pixels for separate expansion */ + "movq %%mm6,%%mm7\n\t" /* copy the bottom pixels for separate expansion */ + "punpckldq %%mm4,%%mm4\n\t" /* expand the NW weight */ + "punpckhdq %%mm5,%%mm5\n\t" /* expand the NE weight */ + "punpckldq %%mm6,%%mm6\n\t" /* expand the SW weight */ + "punpckhdq %%mm7,%%mm7\n\t" /* expand the SE weight */ + "movq %%mm7,%4\n\t" /* save the SE weight so we can use mm7 as 0 */ + "pxor %%mm7,%%mm7\n\t" /* re-zero mm7 */ + + "10:\n\t" + + /* zero mm7 for unpacking */ + "pxor %%mm7,%%mm7\n\t" + + /* load & unpack the pixels */ + "movd (%0),%%mm0\n\t" + "punpcklbw %%mm7,%%mm0\n\t" + "movd 4(%0),%%mm1\n\t" + "punpcklbw %%mm7,%%mm1\n\t" + "movd (%0,%5),%%mm2\n\t" + "punpcklbw %%mm7,%%mm2\n\t" + "movd 4(%0,%5),%%mm3\n\t" + "punpcklbw %%mm7,%%mm3\n\t" + + /* reload the unpacked se weight */ + "movq %4,%%mm7\n\t" + + /* weight each pixel */ + "pmullw %%mm4,%%mm0\n\t" + "pmullw %%mm5,%%mm1\n\t" + "pmullw %%mm6,%%mm2\n\t" + "pmullw %%mm7,%%mm3\n\t" + + /* add up the weighted pixels */ + "paddw %%mm1,%%mm0\n\t" + "paddw %%mm2,%%mm0\n\t" + "paddw %%mm3,%%mm0\n\t" + + /* normalize the resulting pixel, pack it, and write it */ + "psrlw $7,%%mm0\n\t" + "packuswb %%mm0,%%mm0\n\t" + "movd %%mm0,(%1)\n\t" + + /* advance the pointers */ + "addl $4,%0\n\t" + "addl $4,%1\n\t" + + /* see if we're done with this line */ + "cmpl %3,%0\n\t" + "jl 10b\n\t" + + /* advance the pointers */ + "addl %7,%0\n\t" + "addl %7,%1\n\t" + "addl %5,%3\n\t" + + /* see if we're done */ + "incl %2\n\t" + "cmpl %6,%2\n\t" + "jl 10b\n\t" + + "emms\n\t" + + : /* no outputs */ + : "r" (src), /* 0 */ + "r" (dest), /* 1 */ + "r" (starty), /* 2 */ + "m" (endptr), /* 3 */ + "m" (upnw), /* 4 */ + "r" (pn_image_get_pitch (image)), /* 5 */ + "r" (endy), /* 6 */ + "rm" (((stride - endx) + startx) * sizeof (PnColor)), /* 7 */ + "rm" ((guint32)((se << 24) | (sw << 16) | (ne << 8) | nw ))); /* 8 */ +} +#endif /* PN_USE_MMX */ + +static void +pn_displacement_execute (PnDisplacement *displacement, PnImage *image, PnAudioData *audio_data) +{ + g_return_if_fail (displacement != NULL); + g_return_if_fail (PN_IS_DISPLACEMENT (displacement)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + + /* set up the volume in-script variable */ + PN_VARIABLE_VALUE (displacement->volume_var) = pn_audio_data_get_volume (audio_data); + + /* run the frame scipt */ + pn_script_execute (displacement->frame_script); + + if (fabs (PN_VARIABLE_VALUE (displacement->x_var)) <= 2.0 + && fabs (PN_VARIABLE_VALUE (displacement->y_var)) <= 2.0) + { + guint nw, ne, sw, se; + gint startx, starty, endx, endy; + gint offset; + gdouble x, y, xfrac, yfrac; + + x = -PN_VARIABLE_VALUE (displacement->x_var) * (pn_image_get_width (image) >> 1); + y = PN_VARIABLE_VALUE (displacement->y_var) * (pn_image_get_height (image) >> 1); + + xfrac = modf (x, &x); + yfrac = modf (y, &y); + + if (x < 0.0 || xfrac < 0.0) + { + x--; + xfrac++; + } + if (y < 0.0 || yfrac < 0.0) + { + y--; + yfrac++; + } + + se = xfrac * yfrac * 128.0; + sw = (1.0 - xfrac) * yfrac * 128.0; + ne = xfrac * (1.0 - yfrac) * 128.0; + nw = 128 - (se + sw + ne); + + offset = (y * (pn_image_get_pitch (image) >> 2)) + x; + + startx = -x; + starty = -y; + endx = pn_image_get_width (image) - (x+1); + endy = pn_image_get_height (image) - (y+1); + + startx = MAX (startx, 0); + starty = MAX (starty, 0); + endx = MIN (endx, pn_image_get_width (image)); + endy = MIN (endy, pn_image_get_height (image)); + + /* I'm too lazy to special case the rightmost & bottommost pixels */ + if (endx == pn_image_get_width (image)) + endx--; + if (endy == pn_image_get_height (image)) + endy--; + +#ifdef PN_USE_MMX + if (pn_cpu_get_caps () & PN_CPU_CAP_MMX) + pn_displacement_exec_mmx (image, offset, nw, ne, sw, se, startx, starty, endx, endy); + else +#endif /* PN_USE_MMX */ + pn_displacement_exec (image, offset, nw, ne, sw, se, startx, starty, endx, endy); + } + else + memset (pn_image_get_transform_buffer (image), 0, + pn_image_get_pitch (image) * pn_image_get_height (image)); + + pn_image_apply_transform (image); + + if (PN_ACTUATOR_CLASS (parent_class)->execute) + PN_ACTUATOR_CLASS (parent_class)->execute (PN_ACTUATOR (displacement), image, audio_data); +} + +PnDisplacement* +pn_displacement_new (void) +{ + return (PnDisplacement *) g_object_new (PN_TYPE_DISPLACEMENT, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pndisplacement.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,71 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_DISPLACEMENT_H__ +#define __PN_DISPLACEMENT_H__ + +#include "pnactuator.h" +#include "pnscript.h" +#include "pnsymboltable.h" + + +G_BEGIN_DECLS + + +enum +{ + PN_DISPLACEMENT_OPT_INIT_SCRIPT = PN_ACTUATOR_OPT_LAST, + PN_DISPLACEMENT_OPT_FRAME_SCRIPT, + PN_DISPLACEMENT_OPT_LAST +}; + +#define PN_TYPE_DISPLACEMENT (pn_displacement_get_type ()) +#define PN_DISPLACEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_DISPLACEMENT, PnDisplacement)) +#define PN_DISPLACEMENT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_DISPLACEMENT, PnDisplacementClass)) +#define PN_IS_DISPLACEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_DISPLACEMENT)) +#define PN_IS_DISPLACEMENT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_DISPLACEMENT)) +#define PN_DISPLACEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_DISPLACEMENT, PnDisplacementClass)) + +typedef struct _PnDisplacement PnDisplacement; +typedef struct _PnDisplacementClass PnDisplacementClass; + +struct _PnDisplacement +{ + PnActuator parent; + + /* The script objects */ + PnScript *init_script; + PnScript *frame_script; + PnSymbolTable *symbol_table; + + /* The in-script variables */ + PnVariable *x_var; + PnVariable *y_var; + PnVariable *volume_var; +}; + +struct _PnDisplacementClass +{ + PnActuatorClass parent_class; +}; + +/* Creators */ +GType pn_displacement_get_type (void); +PnDisplacement *pn_displacement_new (void); + +#endif /* __PN_DISPLACEMENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pndistortion.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,440 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <math.h> +#include <glib.h> +#include "pndistortion.h" +#include "pnbooleanoption.h" +#include "pnstringoption.h" +#include "pncpu.h" + +enum +{ + PN_PIXEL_DISTORTION_NO_PIXEL = 0xffffffff +}; + +static void pn_distortion_class_init (PnDistortionClass *class); +static void pn_distortion_init (PnDistortion *distortion, + PnDistortionClass *class); +/* GObject methods */ +static void pn_distortion_finalize (GObject *gobject); + +/* PnObject signals */ +static void pn_distortion_destroy (PnObject *object); + +/* PnActuator methods */ +static void pn_distortion_prepare (PnDistortion *distortion, + PnImage *image); +static void pn_distortion_execute (PnDistortion *distortion, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_distortion_get_type (void) +{ + static GType distortion_type = 0; + + if (! distortion_type) + { + static const GTypeInfo distortion_info = + { + sizeof (PnDistortionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_distortion_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnDistortion), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_distortion_init + }; + + /* FIXME: should this be dynamic? */ + distortion_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnDistortion", + &distortion_info, + 0); + } + return distortion_type; +} + +static void +pn_distortion_class_init (PnDistortionClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* GObject methods */ + gobject_class->finalize = pn_distortion_finalize; + + /* PnObject signals */ + object_class->destroy = pn_distortion_destroy; + + /* PnActuator methods */ + actuator_class->prepare = (PnActuatorPrepFunc) pn_distortion_prepare; + actuator_class->execute = (PnActuatorExecFunc) pn_distortion_execute; +} + +static void +pn_distortion_init (PnDistortion *distortion, PnDistortionClass *class) +{ + PnBooleanOption *polar_coords_opt; + PnStringOption *distortion_script_opt; + + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (distortion), "Transform.Distortion"); + pn_user_object_set_description (PN_USER_OBJECT (distortion), + "Perform a distortion on all the points in the image"); + + /* Set up the options */ + polar_coords_opt = pn_boolean_option_new ("polar_coords", "Whether or not to use polar coordinates " + "in the distortion script"); + distortion_script_opt = pn_string_option_new ("distortion_script", "A script specifying the " + "distortion to be done at each point"); + + pn_actuator_add_option (PN_ACTUATOR (distortion), PN_OPTION (polar_coords_opt)); + pn_actuator_add_option (PN_ACTUATOR (distortion), PN_OPTION (distortion_script_opt)); + + /* Create the script object and symbol table */ + distortion->distortion_script = pn_script_new (); + pn_object_ref (PN_OBJECT (distortion->distortion_script)); + pn_object_sink (PN_OBJECT (distortion->distortion_script)); + distortion->symbol_table = pn_symbol_table_new (); + pn_object_ref (PN_OBJECT (distortion->symbol_table)); + pn_object_sink (PN_OBJECT (distortion->symbol_table)); + + /* Get the variables from the symbol table */ + distortion->x_var = pn_symbol_table_ref_variable_by_name (distortion->symbol_table, "x"); + distortion->y_var = pn_symbol_table_ref_variable_by_name (distortion->symbol_table, "y"); + distortion->r_var = pn_symbol_table_ref_variable_by_name (distortion->symbol_table, "r"); + distortion->theta_var = pn_symbol_table_ref_variable_by_name (distortion->symbol_table, "theta"); + distortion->intensity_var = pn_symbol_table_ref_variable_by_name (distortion->symbol_table, "intensity"); +} + +static void +pn_distortion_finalize (GObject *gobject) +{ + PnDistortion *distortion; + + distortion = (PnDistortion *) gobject; + + if (distortion->map) + g_free (distortion->map); + + if (G_OBJECT_CLASS (parent_class)->finalize) + G_OBJECT_CLASS (parent_class)->finalize (gobject); +} + +static void +pn_distortion_destroy (PnObject *object) +{ + PnDistortion *distortion; + + distortion = (PnDistortion *) object; + + pn_object_unref (PN_OBJECT (distortion->distortion_script)); + pn_object_unref (PN_OBJECT (distortion->symbol_table)); +} + +/* FIXME: optimize this */ +static void +pn_distortion_prepare (PnDistortion *distortion, PnImage *image) +{ + PnBooleanOption *polar_coords_opt; + PnStringOption *distortion_script_opt; + gboolean polar; + guint width, stride, height; + guint i, j; + gdouble half_width, neg_half_height; + gdouble xfrac, yfrac; + gdouble x, y; + + g_return_if_fail (distortion != NULL); + g_return_if_fail (PN_IS_DISTORTION (distortion)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + /* Parse the script strings */ + distortion_script_opt = + (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (distortion), + PN_DISTORTION_OPT_DISTORTION_SCRIPT); + + pn_script_parse_string (distortion->distortion_script, + distortion->symbol_table, + pn_string_option_get_value (distortion_script_opt)); + + /* Set up the new pixel distortion map */ + if (distortion->map) + g_free (distortion->map); + + polar_coords_opt = + (PnBooleanOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (distortion), + PN_DISTORTION_OPT_POLAR_COORDS); + polar = pn_boolean_option_get_value (polar_coords_opt); + width = pn_image_get_width (image); + stride = pn_image_get_pitch (image) >> 2; + height = pn_image_get_height (image); + + half_width = (((gdouble) width) - 1.0) * 0.5; + neg_half_height = (((gdouble) height) - 1.0) * -0.5; + + distortion->map = g_new (PnPixelDistortion, width * height); + + for (j=0; j < height; j++) + for (i=0; i < width; i++) + { + PN_VARIABLE_VALUE (distortion->x_var) = (((gdouble) i) / half_width) - 1.0; + PN_VARIABLE_VALUE (distortion->y_var) = (((gdouble) j) / neg_half_height) + 1.0; + PN_VARIABLE_VALUE (distortion->r_var) = + sqrt ((PN_VARIABLE_VALUE (distortion->x_var) * PN_VARIABLE_VALUE (distortion->x_var)) + + (PN_VARIABLE_VALUE (distortion->y_var) * PN_VARIABLE_VALUE (distortion->y_var))); + if (PN_VARIABLE_VALUE (distortion->r_var) != 0) + { + PN_VARIABLE_VALUE (distortion->theta_var) = acos (PN_VARIABLE_VALUE (distortion->x_var) + / PN_VARIABLE_VALUE (distortion->r_var)); + if (PN_VARIABLE_VALUE (distortion->y_var) < 0) + PN_VARIABLE_VALUE (distortion->theta_var) = 2.0 * G_PI + - PN_VARIABLE_VALUE (distortion->theta_var); + } + else + PN_VARIABLE_VALUE (distortion->theta_var) = 0.0; + PN_VARIABLE_VALUE (distortion->intensity_var) = 1.0; + + pn_script_execute (distortion->distortion_script); + + if (polar) + { + PN_VARIABLE_VALUE (distortion->x_var) = PN_VARIABLE_VALUE (distortion->r_var) + * cos (PN_VARIABLE_VALUE (distortion->theta_var)); + PN_VARIABLE_VALUE (distortion->y_var) = PN_VARIABLE_VALUE (distortion->r_var) + * sin (PN_VARIABLE_VALUE (distortion->theta_var)); + } + + if (PN_VARIABLE_VALUE (distortion->x_var) <= 1.0 + && PN_VARIABLE_VALUE (distortion->x_var) >= -1.0 + && PN_VARIABLE_VALUE (distortion->y_var) <= 1.0 + && PN_VARIABLE_VALUE (distortion->y_var) >= -1.0) + { + x = (PN_VARIABLE_VALUE (distortion->x_var) + 1.0) * half_width; + xfrac = modf (x, &x); + yfrac = modf ((PN_VARIABLE_VALUE (distortion->y_var) - 1.0) * neg_half_height, &y); + + distortion->map[i + (j * width)].offset = ((guint) x) + (((guint) y) * stride); + + PN_VARIABLE_VALUE (distortion->intensity_var) = + CLAMP (PN_VARIABLE_VALUE (distortion->intensity_var), 0.0, 1.0); + + distortion->map[i + (j * width)].se = xfrac * yfrac * 128.0 * + PN_VARIABLE_VALUE (distortion->intensity_var); + distortion->map[i + (j * width)].sw = (1.0 - xfrac) * yfrac * 128.0 * + PN_VARIABLE_VALUE (distortion->intensity_var); + distortion->map[i + (j * width)].ne = xfrac * (1.0 - yfrac) * 128.0 * + PN_VARIABLE_VALUE (distortion->intensity_var); + distortion->map[i + (j * width)].nw = (128.0 * PN_VARIABLE_VALUE (distortion->intensity_var)) + - (distortion->map[i + (j * width)].se + + distortion->map[i + (j * width)].sw + + distortion->map[i + (j * width)].ne); + } + else + distortion->map[i + (j * stride)].offset = PN_PIXEL_DISTORTION_NO_PIXEL; + } + + if (parent_class->prepare) + parent_class->prepare (PN_ACTUATOR (distortion), image); +} + +static inline void +pn_distortion_translate (PnDistortion *distortion, PnImage *image) +{ + register PnPixelDistortion *pixtrans; + register PnColor *src; + PnColor *dest, *src_start; + guint i, j; + guint width, stride, height; + register guint red_sum, green_sum, blue_sum; + + pixtrans = distortion->map; + src_start = pn_image_get_image_buffer (image); + dest = pn_image_get_transform_buffer (image); + + width = pn_image_get_width (image); + stride = pn_image_get_pitch (image) >> 2; + height = pn_image_get_height (image); + + for (j=0; j < height; j++) + { + for (i=0; i < width; i++) + { + if (pixtrans->offset != PN_PIXEL_DISTORTION_NO_PIXEL) + { + src = src_start + pixtrans->offset; + + red_sum = src->red * pixtrans->nw; + green_sum = src->green * pixtrans->nw; + blue_sum = src->blue * pixtrans->nw; + + src++; + + red_sum += src->red * pixtrans->ne; + green_sum += src->green * pixtrans->ne; + blue_sum += src->blue * pixtrans->ne; + + src += stride; + + red_sum += src->red * pixtrans->se; + green_sum += src->green * pixtrans->se; + blue_sum += src->blue * pixtrans->se; + + src--; + + red_sum += src->red * pixtrans->sw; + green_sum += src->green * pixtrans->sw; + blue_sum += src->blue * pixtrans->sw; + + dest->red = (guchar) (red_sum >> 7); + dest->green = (guchar) (green_sum >> 7); + dest->blue = (guchar) (blue_sum >> 7); + } + else + *((gulong *)dest) = 0; + + pixtrans++; + dest++; + } + dest += stride - width; + } +} + +#ifdef PN_USE_MMX +static inline void +pn_distortion_translate_mmx (PnDistortion *distortion, PnImage *image) +{ + __asm__ __volatile__ ( + ".align 16\n" /* The start of the loop */ + "10:\n\t" + + "pxor %%mm7,%%mm7\n\t" /* zero the reg for unpacking */ + + "movd (%0,%2,4),%%mm0\n\t" /* load the NW pixel */ + "movd 4(%0,%2,4),%%mm1\n\t" /* load the NE pixel */ + "addl %6,%2\n\t" /* advance the offset to the next line */ + "movd (%0,%2,4),%%mm2\n\t" /* load the SW pixel */ + "movd 4(%0,%2,4),%%mm3\n\t" /* load the SE pixel */ + + "punpcklbw %%mm7,%%mm0\n\t" /* unpack the NW pixel */ + "punpcklbw %%mm7,%%mm1\n\t" /* unpack the NE pixel */ + "punpcklbw %%mm7,%%mm2\n\t" /* unpack the SW pixel */ + "punpcklbw %%mm7,%%mm3\n\t" /* unpack the SE pixel */ + + "movd 4(%4),%%mm4\n\t" /* load the weights */ + "punpcklbw %%mm7,%%mm4\n\t" /* unpack the weights to words */ + "movq %%mm4,%%mm6\n\t" /* copy the weights for separate expansion */ + "punpcklwd %%mm4,%%mm4\n\t" /* expand the top weights */ + "punpckhwd %%mm6,%%mm6\n\t" /* expand the bottom weights */ + "movq %%mm4,%%mm5\n\t" /* copy the top pixels for separate expansion */ + "movq %%mm6,%%mm7\n\t" /* copy the bottom pixels for separate expansion */ + "punpckldq %%mm4,%%mm4\n\t" /* expand the NW weight */ + "punpckhdq %%mm5,%%mm5\n\t" /* expand the NE weight */ + "punpckldq %%mm6,%%mm6\n\t" /* expand the SW weight */ + "punpckhdq %%mm7,%%mm7\n\t" /* expand the SE weight */ + + "pmullw %%mm4,%%mm0\n\t" /* weight the NW pixel */ + "pmullw %%mm5,%%mm1\n\t" /* weight the NE pixel */ + "pmullw %%mm6,%%mm2\n\t" /* weight the SW pixel */ + "pmullw %%mm7,%%mm3\n\t" /* weight the SE pixel */ + + "paddusw %%mm1,%%mm0\n\t" /* sum up the weighted pixels */ + "paddusw %%mm2,%%mm0\n\t" + "paddusw %%mm3,%%mm0\n\t" + + "addl $4,%1\n\t" /* advance the dest pointer */ + + "psrlw $7,%%mm0\n\t" /* divide the sums by 128 */ + "packuswb %%mm0,%%mm0\n\t" /* pack up the resulting pixel */ + "movd %%mm0,(%1)\n\t" /* write the pixel */ + + + "addl $8,%4\n\t" /* advance the map pointer */ + "movl (%4),%2\n\t" /* load the next offset */ + + "dec %3\n\t" /* advance the inverse column counter */ + "jg 10b\n\t" + + "shll $2,%5\n\t" /* get the width/stride in bytes */ + "shll $2,%6\n\t" + "addl %6,%1\n\t" /* add (stride - width) to the dest */ + "subl %5,%1\n\t" + "shrl $2,%5\n\t" /* revert width/stride to pixels */ + "shrl $2,%6\n\t" + "movl %5,%3\n\t" /* reset the inverse column counter */ + + "cmpl %7,%1\n\t" /* see if we're done */ + "jl 10b\n\t" + + "emms\n\t" + : + : + "r" (pn_image_get_image_buffer (image)), + "r" (pn_image_get_transform_buffer (image) - 1), + "r" (distortion->map->offset), + "r" (pn_image_get_width (image)), + "r" (distortion->map), + "m" (pn_image_get_width (image)), + "m" (pn_image_get_pitch (image) >> 2), + "m" (pn_image_get_transform_buffer (image) + + ((pn_image_get_pitch (image) >> 2) * (pn_image_get_height (image) - 1)))); +} +#endif /* PN_USE_MMX */ + +static void +pn_distortion_execute (PnDistortion *distortion, PnImage *image, PnAudioData *audio_data) +{ + g_return_if_fail (distortion != NULL); + g_return_if_fail (PN_IS_DISTORTION (distortion)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + +#ifdef PN_USE_MMX + if (pn_cpu_get_caps () & PN_CPU_CAP_MMX) + pn_distortion_translate_mmx (distortion, image); + else +#endif /* PN_USE_MMX */ + pn_distortion_translate (distortion, image); + + pn_image_apply_transform (image); +} + +PnDistortion* +pn_distortion_new (void) +{ + return (PnDistortion *) g_object_new (PN_TYPE_DISTORTION, NULL); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pndistortion.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,85 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_DISTORTION_H__ +#define __PN_DISTORTION_H__ + +#include "pnactuator.h" +#include "pnscript.h" +#include "pnsymboltable.h" + + +G_BEGIN_DECLS + + +enum +{ + PN_DISTORTION_OPT_POLAR_COORDS = PN_ACTUATOR_OPT_LAST, + PN_DISTORTION_OPT_DISTORTION_SCRIPT, + PN_DISTORTION_OPT_LAST +}; + +#define PN_TYPE_DISTORTION (pn_distortion_get_type ()) +#define PN_DISTORTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_DISTORTION, PnDistortion)) +#define PN_DISTORTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_DISTORTION, PnDistortionClass)) +#define PN_IS_DISTORTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_DISTORTION)) +#define PN_IS_DISTORTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_DISTORTION)) +#define PN_DISTORTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_DISTORTION, PnDistortionClass)) + +typedef struct _PnPixelDistortion PnPixelDistortion; +typedef struct _PnDistortion PnDistortion; +typedef struct _PnDistortionClass PnDistortionClass; + +struct _PnPixelDistortion +{ + guint offset; + guchar nw; /* northwest weight */ + guchar ne; /* northeast weight */ + guchar sw; /* southwest weight */ + guchar se; /* southeast weight */ +}; + +struct _PnDistortion +{ + PnActuator parent; + + /* The script objects */ + PnScript *distortion_script; + PnSymbolTable *symbol_table; + + /* The in-script variables */ + PnVariable *x_var; + PnVariable *y_var; + PnVariable *r_var; + PnVariable *theta_var; + PnVariable *intensity_var; + + /* Distortion map */ + PnPixelDistortion *map; +}; + +struct _PnDistortionClass +{ + PnActuatorClass parent_class; +}; + +/* Creators */ +GType pn_distortion_get_type (void); +PnDistortion *pn_distortion_new (void); + +#endif /* __PN_DISTORTION_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnerror.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,64 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <stdarg.h> +#include <glib.h> +#include "pnerror.h" + +static void pn_error_default_handler (const gchar *str); + +static PnErrorFunc error_func = pn_error_default_handler; + +static void +pn_error_default_handler (const gchar *str) +{ + g_log ("paranormal", G_LOG_LEVEL_WARNING, str); +} + +PnErrorFunc +pn_error_set_handler (PnErrorFunc func) +{ + PnErrorFunc old_func = error_func; + + if (! func) + error_func = pn_error_default_handler; + else + error_func = func; + + return old_func; +} + +void +pn_error (const gchar *fmt, ...) +{ + va_list ap; + gchar *str; + + g_return_if_fail (fmt != NULL); + + va_start (ap, fmt); + str = g_strdup_vprintf (fmt, ap); + va_end (ap); + + error_func (str); + + g_free (str); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnerror.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,30 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_ERROR_H__ +#define __PN_ERROR_H__ + +typedef void (* PnErrorFunc) (const gchar *str); + +/* Accessors */ +PnErrorFunc pn_error_set_handler (PnErrorFunc func); + +/* Actions */ +void pn_error (const gchar *fmt, + ...); +#endif /* __PN_ERROR_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnflip.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,436 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glib.h> +#include "pnflip.h" +#include "pnbooleanoption.h" +#include "pnlistoption.h" +#include "pncpu.h" + +enum +{ + PN_FLIP_DIRECTION_HORIZONTAL, + PN_FLIP_DIRECTION_VERTICAL +}; + +static void pn_flip_class_init (PnFlipClass *class); +static void pn_flip_init (PnFlip *flip, + PnFlipClass *class); +/* PnActuator methods */ +static void pn_flip_execute (PnFlip *flip, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_flip_get_type (void) +{ + static GType flip_type = 0; + + if (! flip_type) + { + static const GTypeInfo flip_info = + { + sizeof (PnFlipClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_flip_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnFlip), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_flip_init + }; + + /* FIXME: should this be dynamic? */ + flip_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnFlip", + &flip_info, + 0); + } + return flip_type; +} + +static void +pn_flip_class_init (PnFlipClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnActuator methods */ + actuator_class->execute = (PnActuatorExecFunc) pn_flip_execute; +} + +static void +pn_flip_init (PnFlip *flip, PnFlipClass *class) +{ + PnBooleanOption *blend_opt; + PnListOption *direction_opt; + + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (flip), "Transform.Flip"); + pn_user_object_set_description (PN_USER_OBJECT (flip), + "Flip the image"); + + /* Set up the options */ + blend_opt = pn_boolean_option_new ("blend", "Blend the flipped image with the original"); + direction_opt = pn_list_option_new ("direction", "The direction in which the image will be flipped"); + + pn_list_option_add_item (direction_opt, "Horizontal"); + pn_list_option_add_item (direction_opt, "Vertical"); + + pn_actuator_add_option (PN_ACTUATOR (flip), PN_OPTION (blend_opt)); + pn_actuator_add_option (PN_ACTUATOR (flip), PN_OPTION (direction_opt)); +} + +static void +pn_flip_execute_horizontal (PnImage *image) +{ + register guint i, j, tmp; + register guint32 *src, *dest; + guint width, height, stride; + + width = pn_image_get_width (image); + height = pn_image_get_height (image); + stride = pn_image_get_pitch (image) >> 2; + + src = (guint32 *) pn_image_get_image_buffer (image); + dest = (guint32 *) pn_image_get_transform_buffer (image); + + for (j=0; j<height; j++) + { + for (i=0; i<width >> 1; i++) + { + tmp = src[j * stride + i]; + dest[j * stride + i] = src[j * stride + (width - (i + 1))]; + dest[j * stride + (width - (i + 1))] = tmp; + } + if (width & 0x1) + dest[j * stride + i] = src [j * stride + i]; + } +} + +static void +pn_flip_execute_horizontal_blend (PnImage *image) +{ + register guint i, j; + register PnColor *src, *dest; + guint width, height, stride; + guint r, g, b; + + width = pn_image_get_width (image); + height = pn_image_get_height (image); + stride = pn_image_get_pitch (image) >> 2; + + src = pn_image_get_image_buffer (image); + dest = pn_image_get_transform_buffer (image); + + for (j=0; j<height; j++) + { + for (i=0; i<width >> 1; i++) + { + r = src[j * stride + i].red + src[j * stride + (width - (i + 1))].red; + g = src[j * stride + i].green + src[j * stride + (width - (i + 1))].green; + b = src[j * stride + i].blue + src[j * stride + (width - (i + 1))].blue; + + r >>= 1; + g >>= 1; + b >>= 1; + + dest[j * stride + i].red = dest[j * stride + (width - (i + 1))].red = r; + dest[j * stride + i].green = dest[j * stride + (width - (i + 1))].green = g; + dest[j * stride + i].blue = dest[j * stride + (width - (i + 1))].blue = b; + } + if (width & 0x1) + ((guint32 *) dest)[j * stride + i] = + ((guint32 *) src)[j * stride + i]; + } +} + +#ifdef PN_USE_MMX +static void +pn_flip_execute_horizontal_blend_mmx (PnImage *image) +{ + /* + * 0: src + * 1: dest + * 2: left index + * 3: right index + * 4: inverse line counter + * 5; half width + * 6: width + * 7: pitch + */ + + __asm__ __volatile__ ( + "pxor %%mm7,%%mm7\n\t" /* Zero mm7 */ + + "10:\n\t" + + "movd (%0, %2, 4), %%mm0\n\t" /* Load the two pixels */ + "movd (%0, %3, 4), %%mm1\n\t" + + "punpcklbw %%mm7, %%mm0\n\t" /* Unpack the pixels */ + "punpcklbw %%mm7, %%mm1\n\t" + + "paddw %%mm1, %%mm0\n\t" /* Average the pixels */ + "psrlw $1, %%mm0\n\t" + + "packuswb %%mm7, %%mm0\n\t" /* Pack 'er up & write it*/ + "movd %%mm0, (%1, %2, 4)\n\t" + "movd %%mm0, (%1, %3, 4)\n\t" + + "incl %3\n\t" /* Advance the indexes & see if we're */ + "decl %2\n\t" /* done with this line */ + "jge 10b\n\t" + + "movl %5, %2\n\t" /* Reset the indexes */ + "movl %5, %3\n\t" + "decl %2\n\t" + + "testl $0x1, %6\n\t" /* Do the stuff for an odd width */ + "jz 20f\n\t" + "movd (%0, %3, 4), %%mm0\n\t" + "movd %%mm0, (%1, %3, 4)\n\t" + "incl %3\n\t" + + "20:\n\t" + + "addl %7, %0\n\t" /* Advance the line pointers */ + "addl %7, %1\n\t" + + "decl %4\n\t" /* See if we're done */ + "jnz 10b\n\t" + + "emms" + : /* no outputs */ + : "r" (pn_image_get_image_buffer (image)), + "r" (pn_image_get_transform_buffer (image)), + "r" ((pn_image_get_width (image) >> 1) - 1), + "r" ((pn_image_get_width (image) >> 1) + (pn_image_get_width (image) & 0x1 ? 1 : 0)), + "rm" (pn_image_get_height (image)), + "rm" (pn_image_get_width (image) >> 1), + "rm" (pn_image_get_width (image)), + "rm" (pn_image_get_pitch (image)) + ); +} +#endif /* PN_USE_MMX */ + +static void +pn_flip_execute_vertical (PnImage *image) +{ + register guint i, j, tmp; + register guint32 *src, *dest; + guint width, height, stride; + + width = pn_image_get_width (image); + height = pn_image_get_height (image); + stride = pn_image_get_pitch (image) >> 2; + + src = (guint32 *) pn_image_get_image_buffer (image); + dest = (guint32 *) pn_image_get_transform_buffer (image); + + for (j=0; j<height >> 1; j++) + { + for (i=0; i<width; i++) + { + tmp = src[j * stride + i]; + dest[j * stride + i] = src[(height - (j + 1)) * stride + i]; + dest[(height - (j + 1)) * stride + i] = tmp; + } + if (height & 0x1) + dest[j * stride + i] = src [j * stride + i]; + } +} + +static void +pn_flip_execute_vertical_blend (PnImage *image) +{ + register guint i, j; + register PnColor *src, *dest; + guint width, height, stride; + guint r, g, b; + + width = pn_image_get_width (image); + height = pn_image_get_height (image); + stride = pn_image_get_pitch (image) >> 2; + + src = pn_image_get_image_buffer (image); + dest = pn_image_get_transform_buffer (image); + + for (j=0; j<height >> 1; j++) + { + for (i=0; i<width; i++) + { + r = src[j * stride + i].red + src[(height - (j + 1)) * stride + i].red; + g = src[j * stride + i].green + src[(height - (j + 1)) * stride + i].green; + b = src[j * stride + i].blue + src[(height - (j + 1)) * stride + i].blue; + + r >>= 1; + g >>= 1; + b >>= 1; + + dest[j * stride + i].red = dest[(height - (j + 1)) * stride + i].red = r; + dest[j * stride + i].green = dest[(height - (j + 1)) * stride + i].green = g; + dest[j * stride + i].blue = dest[(height - (j + 1)) * stride + i].blue = b; + } + if (height & 0x1) + ((guint32 *) dest)[j * stride + i] = + ((guint32 *) src)[j * stride + i]; + } +} + +#ifdef PN_USE_MMX +static void +pn_flip_execute_vertical_blend_mmx (PnImage *image) +{ + PnColor *src, *dest; + guint pitch, width, height; + + src = pn_image_get_image_buffer (image); + dest = pn_image_get_transform_buffer (image); + pitch = pn_image_get_pitch (image); + width = pn_image_get_width (image); + height = pn_image_get_height (image); + + /* + * 0: tsrc + * 1: bsrc + * 2: tdest + * 3: bdest + * 4: i + * 5: (half stride) - 1 + * 6: pitch + * 7: src + */ + + __asm__ __volatile__ ( + "pxor %%mm7,%%mm7\n\t" /* Zero mm7 */ + + "movl %5,%4\n\t" /* Do this so gcc doesn't make %4 and + * %5 the same register + */ + + "10:\n\t" + + "movq (%0, %4, 8),%%mm0\n\t" /* Read the pixels */ + "movq (%1, %4, 8),%%mm2\n\t" + "movq %%mm0,%%mm1\n\t" + "movq %%mm2,%%mm3\n\t" + + "punpcklbw %%mm7,%%mm0\n\t" /* Unpack the pixels */ + "punpckhbw %%mm7,%%mm1\n\t" + "punpcklbw %%mm7,%%mm2\n\t" + "punpckhbw %%mm7,%%mm3\n\t" + + "paddw %%mm2,%%mm0\n\t" /* Average the pixels */ + "paddw %%mm3,%%mm1\n\t" + "psrlw $1,%%mm0\n\t" + "psrlw $1,%%mm1\n\t" + + "packuswb %%mm1,%%mm0\n\t" /* Pack & write the pixels */ + "movq %%mm0,(%2,%4,8)\n\t" + "movq %%mm0,(%3,%4,8)\n\t" + + "decl %4\n\t" /* See if we're done */ + "jns 10b\n\t" + + "movl %5,%4\n\t" /* Reset the x-counter */ + + "subl %6,%0\n\t" /* Advance the pointers */ + "addl %6,%1\n\t" + "subl %6,%2\n\t" + "addl %6,%3\n\t" + + "cmpl %7,%0\n\t" /* See if we're done */ + "jge 10b\n\t" + + "emms" + : /* no outputs */ + : "r" (src + (pitch >> 2) * ((height >> 1) - 1)), + "r" (src + (pitch >> 2) * ((height >> 1) + (height & 0x1 ? 1 : 0))), + "r" (dest + (pitch >> 2) * ((height >> 1) - 1)), + "r" (dest + (pitch >> 2) * ((height >> 1) + (height & 0x1 ? 1 : 0))), + "r" (0), + "rm" ((pitch >> 3) - 1), + "rm" (pitch), + "rm" (src) + ); +} +#endif /* PN_USE_MMX */ + +static void +pn_flip_execute (PnFlip *flip, PnImage *image, PnAudioData *audio_data) +{ + PnBooleanOption *blend_opt; + PnListOption *direction_opt; + + g_return_if_fail (flip != NULL); + g_return_if_fail (PN_IS_FLIP (flip)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + + blend_opt = (PnBooleanOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (flip), PN_FLIP_OPT_BLEND); + direction_opt = (PnListOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (flip), PN_FLIP_OPT_DIRECTION); + + switch (pn_list_option_get_index (direction_opt)) + { + case PN_FLIP_DIRECTION_HORIZONTAL: + if (pn_boolean_option_get_value (blend_opt)) +#ifdef PN_USE_MMX + if (pn_cpu_get_caps () & PN_CPU_CAP_MMX) + pn_flip_execute_horizontal_blend_mmx (image); + else +#endif /* PN_USE_MMX */ + pn_flip_execute_horizontal_blend (image); + else + pn_flip_execute_horizontal (image); + break; + case PN_FLIP_DIRECTION_VERTICAL: + if (pn_boolean_option_get_value (blend_opt)) +#ifdef PN_USE_MMX + if (pn_cpu_get_caps () & PN_CPU_CAP_MMX) + pn_flip_execute_vertical_blend_mmx (image); + else +#endif /* PN_USE_MMX */ + pn_flip_execute_vertical_blend (image); + else + pn_flip_execute_vertical (image); + break; + } + + pn_image_apply_transform (image); +} + +PnFlip* +pn_flip_new (void) +{ + return (PnFlip *) g_object_new (PN_TYPE_FLIP, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnflip.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,61 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_FLIP_H__ +#define __PN_FLIP_H__ + +#include "pnactuator.h" +#include "pnscript.h" +#include "pnsymboltable.h" + + +G_BEGIN_DECLS + +enum +{ + PN_FLIP_OPT_BLEND = PN_ACTUATOR_OPT_LAST, + PN_FLIP_OPT_DIRECTION, + PN_FLIP_OPT_LAST +}; + +#define PN_TYPE_FLIP (pn_flip_get_type ()) +#define PN_FLIP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_FLIP, PnFlip)) +#define PN_FLIP_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_FLIP, PnFlipClass)) +#define PN_IS_FLIP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_FLIP)) +#define PN_IS_FLIP_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_FLIP)) +#define PN_FLIP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_FLIP, PnFlipClass)) + +typedef struct _PnPixelFlip PnPixelFlip; +typedef struct _PnFlip PnFlip; +typedef struct _PnFlipClass PnFlipClass; + +struct _PnFlip +{ + PnActuator parent; +}; + +struct _PnFlipClass +{ + PnActuatorClass parent_class; +}; + +/* Creators */ +GType pn_flip_get_type (void); +PnFlip *pn_flip_new (void); + +#endif /* __PN_FLIP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnfloatoption.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,243 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <stdlib.h> +#include <limits.h> +#include <glib.h> +#include "pnfloatoption.h" +#include "pnxml.h" +#include "pnerror.h" + +static void pn_float_option_class_init (PnFloatOptionClass *class); +static void pn_float_option_init (PnFloatOption *float_option, + PnFloatOptionClass *class); + +/* PnUserObject methods */ +static void pn_float_option_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_float_option_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static PnUserObjectClass *parent_class = NULL; + +GType +pn_float_option_get_type (void) +{ + static GType float_option_type = 0; + + if (! float_option_type) + { + static const GTypeInfo float_option_info = + { + sizeof (PnFloatOptionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_float_option_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnFloatOption), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_float_option_init + }; + + /* FIXME: should this be dynamic? */ + float_option_type = g_type_register_static (PN_TYPE_OPTION, + "PnFloatOption", + &float_option_info, + 0); + } + return float_option_type; +} + +static void +pn_float_option_class_init (PnFloatOptionClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnOptionClass *option_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + option_class = (PnOptionClass *) class; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_float_option_save_thyself; + user_object_class->load_thyself = pn_float_option_load_thyself; + + /* PnOption methods */ + /* FIXME: this needs to be uncommented when the widget is done */ +/* option_class->widget_type = PN_TYPE_FLOAT_OPTION_WIDGET; */ +} + +static void +pn_float_option_init (PnFloatOption *float_option, + PnFloatOptionClass *class) +{ + float_option->min = INT_MIN; + float_option->max = INT_MAX; +} + +static void +pn_float_option_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnFloatOption *float_option; + xmlNodePtr value_node; + gchar str[16]; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_FLOAT_OPTION (user_object)); + g_return_if_fail (node != NULL); + + float_option = (PnFloatOption *) user_object; + + value_node = xmlNewChild (node, NULL, "Value", NULL); + sprintf (str, "%f", float_option->value); + xmlNodeSetContent (value_node, str); + + if (parent_class->save_thyself) + parent_class->save_thyself (user_object, node); +} + +static void +pn_float_option_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnFloatOption *float_option; + xmlNodePtr float_option_node; + gchar *val_str; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_FLOAT_OPTION (user_object)); + g_return_if_fail (node != NULL); + + float_option = (PnFloatOption *) user_object; + + /* find the node for this class */ + for (float_option_node = node->xmlChildrenNode; + float_option_node; + float_option_node = float_option_node->next) + if (g_strcasecmp (float_option_node->name, "Value") == 0) + break; + if (! float_option_node) + { + pn_error ("unable to load a PnFloatOption from xml node \"%s\"", node->name); + return; + } + + val_str = xmlNodeGetContent (float_option_node); + + if (val_str) + pn_float_option_set_value (float_option, strtod (val_str, NULL)); + else + { + pn_error ("invalid float option value encountered at xml node \"%s\"", node->name); + return; + } + + if (parent_class->load_thyself) + parent_class->load_thyself (user_object, node); +} + +PnFloatOption* +pn_float_option_new (const gchar *name, const gchar *desc) +{ + PnFloatOption *float_option; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (desc != NULL, NULL); + + float_option = (PnFloatOption *) g_object_new (PN_TYPE_FLOAT_OPTION, NULL); + + pn_user_object_set_name (PN_USER_OBJECT (float_option), name); + pn_user_object_set_description (PN_USER_OBJECT (float_option), desc); + + return float_option; +} + +void +pn_float_option_set_value (PnFloatOption *float_option, gfloat value) +{ + g_return_if_fail (float_option != NULL); + g_return_if_fail (PN_IS_FLOAT_OPTION (float_option)); + + float_option->value = CLAMP (value, float_option->min, float_option->max); +} + +gfloat +pn_float_option_get_value (PnFloatOption *float_option) +{ + g_return_val_if_fail (float_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_FLOAT_OPTION (float_option), FALSE); + + return float_option->value; +} + +void +pn_float_option_set_min (PnFloatOption *float_option, gfloat min) +{ + g_return_if_fail (float_option != NULL); + g_return_if_fail (PN_IS_FLOAT_OPTION (float_option)); + + if (min > float_option->max) + { + float_option->min = float_option->max; + float_option->max = min; + } + else + float_option->min = min; + + pn_float_option_set_value (float_option, float_option->value); +} + +gfloat +pn_float_option_get_min (PnFloatOption *float_option) +{ + g_return_val_if_fail (float_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_FLOAT_OPTION (float_option), FALSE); + + return float_option->min; +} + +void +pn_float_option_set_max (PnFloatOption *float_option, gfloat max) +{ + g_return_if_fail (float_option != NULL); + g_return_if_fail (PN_IS_FLOAT_OPTION (float_option)); + + if (max < float_option->min) + { + float_option->max = float_option->min; + float_option->min = max; + } + else + float_option->max = max; + + pn_float_option_set_value (float_option, float_option->value); +} + +gfloat +pn_float_option_get_max (PnFloatOption *float_option) +{ + g_return_val_if_fail (float_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_FLOAT_OPTION (float_option), FALSE); + + return float_option->max; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnfloatoption.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,73 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_FLOAT_OPTION_H__ +#define __PN_FLOAT_OPTION_H__ + +#include "pnoption.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_FLOAT_OPTION (pn_float_option_get_type ()) +#define PN_FLOAT_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_FLOAT_OPTION, PnFloatOption)) +#define PN_FLOAT_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_FLOAT_OPTION, PnFloatOptionClass)) +#define PN_IS_FLOAT_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_FLOAT_OPTION)) +#define PN_IS_FLOAT_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_FLOAT_OPTION)) +#define PN_FLOAT_OPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_FLOAT_OPTION, PnFloatOptionClass)) + +typedef struct _PnFloatOption PnFloatOption; +typedef struct _PnFloatOptionClass PnFloatOptionClass; + +struct _PnFloatOption +{ + PnOption parent; + + gfloat value; + gfloat min; + gfloat max; +}; + +struct _PnFloatOptionClass +{ + PnOptionClass parent_class; +}; + +/* Creators */ +GType pn_float_option_get_type (void); +PnFloatOption *pn_float_option_new (const gchar *name, + const gchar *desc); + +/* Accessors */ +void pn_float_option_set_value (PnFloatOption *float_option, + gfloat value); +gfloat pn_float_option_get_value (PnFloatOption *float_option); +void pn_float_option_set_min (PnFloatOption *float_option, + gfloat min); +gfloat pn_float_option_get_min (PnFloatOption *float_option); +void pn_float_option_set_max (PnFloatOption *float_option, + gfloat max); +gfloat pn_float_option_get_max (PnFloatOption *float_option); + + + + + + +#endif /* __PN_FLOAT_OPTION_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pngtk.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,29 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_GTK_H__ +#define __PN_GTK_H__ + +/* FIXME: Take this out */ +#define PN_NO_GTK + +#ifndef PN_NO_GTK +#include <gtk/gtk.h> +#endif /* PN_NO_GTK */ + +#endif /* __PN_GTK_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnimage.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,683 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <glib.h> +#include "pnimage.h" +#include "pnerror.h" +#include "pncpu.h" + +static void pn_image_class_init (PnImageClass *class); +static void pn_image_init (PnImage *image, + PnImageClass *class); + +/* GObject signals */ +static void pn_image_finalize (GObject *gobject); + +static PnObjectClass *parent_class = NULL; + +const gchar *pn_image_blend_mode_strings[] = +{ + "Ignore", + "Replace", + "50/50" +}; +const guint pn_image_blend_mode_count = 3; + +GType +pn_image_get_type (void) +{ + static GType image_type = 0; + + if (! image_type) + { + static const GTypeInfo image_info = + { + sizeof (PnImageClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_image_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnImage), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_image_init + }; + + /* FIXME: should this be dynamic? */ + image_type = g_type_register_static (PN_TYPE_OBJECT, + "PnImage", + &image_info, + 0); + } + return image_type; +} + +static void +pn_image_class_init (PnImageClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + + /* GObject signals */ + gobject_class->finalize = pn_image_finalize; +} + +static void +pn_image_init (PnImage *image, PnImageClass *class) +{ + image->render_mode = PN_BLEND_MODE_REPLACE; + image->transform_mode = PN_BLEND_MODE_REPLACE; +} + +static void +pn_image_finalize (GObject *gobject) +{ + PnImage *image; + + image = (PnImage *) gobject; + + if (image->image_buffer) + g_free (image->image_buffer); + + if (image->transform_buffer) + g_free (image->transform_buffer); +} + +/** + * pn_image_new + * + * Creates a new #PnImage object + * + * Returns: The new #PnImage object + */ +PnImage* +pn_image_new (void) +{ + return (PnImage *) g_object_new (PN_TYPE_IMAGE, NULL); +} + +/** + * pn_image_new_width_size + * @width: the width of the new image + * @height: the hight of the new image + * + * Creates a new #PnImage object with the given dimensions + * + * Returns: The new #PnImage object + */ +PnImage* +pn_image_new_with_size (guint width, guint height) +{ + PnImage *image; + + image = (PnImage *) g_object_new (PN_TYPE_IMAGE, NULL); + + pn_image_set_size (image, width, height); + + return image; +} + +/** + * pn_image_set_size + * @image: a #PnImage + * @width: the new width of the image + * @height: the new height of the image + * + * Sets the size of the image contained in a #PnImage object + */ +void +pn_image_set_size (PnImage *image, guint width, guint height) +{ + guint pitch; + + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (width > 0 && height > 0); + + pitch = width * sizeof (PnColor); + + /* Align each row to 8 bytes */ + if (pitch & 0x00000007) + pitch = (pitch & 0xfffffff8) + 8; + + if (image->image_buffer) + g_free (image->image_buffer); + + if (image->transform_buffer) + g_free (image->transform_buffer); + + image->pitch = pitch; + image->width = width; + image->height = height; + image->image_buffer = g_malloc0 (pitch * height); + image->transform_buffer = g_malloc0 (pitch * height); +} + +/** + * pn_image_get_width + * @image: a #PnImage + * + * Gets the width of a #PnImage + * + * Returns: The width of the image + */ +guint +pn_image_get_width (PnImage *image) +{ + g_return_val_if_fail (image != NULL, 0); + g_return_val_if_fail (PN_IS_IMAGE (image), 0); + + return image->width; +} + +/** + * pn_image_get_height + * @image: a #PnImage + * + * Gets the height of a #PnImage + * + * Returns: The height of the image + */ +guint +pn_image_get_height (PnImage *image) +{ + g_return_val_if_fail (image != NULL, 0); + g_return_val_if_fail (PN_IS_IMAGE (image), 0); + + return image->height; +} + +/** + * pn_image_get_pitch + * @image: a #PnImage + * + * Gets the pitch (width in bytes) of a #PnImage + * + * Returns: The pitch of the image + */ +guint +pn_image_get_pitch (PnImage *image) +{ + g_return_val_if_fail (image != NULL, 0); + g_return_val_if_fail (PN_IS_IMAGE (image), 0); + + return image->pitch; +} + +/** + * pn_image_set_render_mode + * @image: a #PnImage + * @render_mode: the blend mode to use + * + * Sets the blend mode to be used by render functions. The + * render functions are pn_image_render_pixel(), + * pn_image_render_pixel_by_offset(), and pn_image_render_line(). + */ +void +pn_image_set_render_mode (PnImage *image, PnBlendMode render_mode) +{ + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (render_mode < PN_BLEND_MODE_LAST); + + image->render_mode = render_mode; +} + +/** + * pn_image_set_transform_mode + * @image: a #PnImage + * @transform_mode: the blend mode to use + * + * Sets the blend mode to be used by pn_image_apply_transform(). + */ +void +pn_image_set_transform_mode (PnImage *image, PnBlendMode transform_mode) +{ + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (transform_mode < PN_BLEND_MODE_LAST); + + image->transform_mode = transform_mode; +} + +/** + * pn_image_get_image_buffer + * @image: a #PnImage + * + * Retrieves the image buffer (the 'front buffer') of a #PnImage. + * + * Returns: A pointer to the image buffer + */ +PnColor* +pn_image_get_image_buffer (PnImage *image) +{ + g_return_val_if_fail (image != NULL, NULL); + g_return_val_if_fail (PN_IS_IMAGE (image), NULL); + + return image->image_buffer; +} + +/** + * pn_image_get_transform_buffer + * @image: a #PnImage + * + * Retrieves the transform buffer (the 'back buffer') of a #PnImage. + * The transform buffer should only be used internally by transform + * actuators. *EVERY* pixel in the transform buffer *MUST* be set. + * The transform buffer can be 'copied' to the image buffer using + * pn_image_apply_transform(). + * + * Returns: A pointer to the transform buffer + */ +PnColor* +pn_image_get_transform_buffer (PnImage *image) +{ + g_return_val_if_fail (image != NULL, NULL); + g_return_val_if_fail (PN_IS_IMAGE (image), NULL); + + return image->transform_buffer; +} + +/** + * pn_image_render_pixel + * @image: a #PnImage + * @x: the x coordinate (left being 0) + * @y: the y coordinate (top being 0) + * @color: the color + * + * Renders a pixel to the image buffer of a #PnImage. pn_image_set_render_mode() + * can be used to set the blend mode that is used by this function. + */ +void +pn_image_render_pixel (PnImage *image, guint x, guint y, PnColor color) +{ + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (image->image_buffer != NULL); + + if (x > image->width || y > image->height) + return; + + switch (image->render_mode) + { + case PN_BLEND_MODE_LAST: break; + case PN_BLEND_MODE_IGNORE: + break; + + case PN_BLEND_MODE_REPLACE: + image->image_buffer[(y * (image->pitch>>2)) + x] = color; + break; + + case PN_BLEND_MODE_5050: + image->image_buffer[(y * (image->pitch>>2)) + x].red = + (image->image_buffer[(y * (image->pitch>>2)) + x].red + color.red) >> 1; + image->image_buffer[(y * (image->pitch>>2)) + x].green = + (image->image_buffer[(y * (image->pitch>>2)) + x].green + color.green) >> 1; + image->image_buffer[(y * (image->pitch>>2)) + x].blue = + (image->image_buffer[(y * (image->pitch>>2)) + x].blue + color.blue) >> 1; + break; + } +} + +/** + * pn_image_render_pixel_by_offset + * @image: a #PnImage + * @offset: the pixel offset (0 being the top left) NOTE: Use (pitch>>2) rather + * than width + * @color: the color + * + * Renders a pixel to the image buffer of a #PnImage based on a pixel offset rather than + * rectangular coordinates. This function should be used if there is a more optimum way + * to calculate the offset than multiplying at every pixel. pn_image_set_render_mode() + * can be used to set the blend mode that is used by this function. + */ +void +pn_image_render_pixel_by_offset (PnImage *image, guint offset, PnColor color) +{ + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (image->image_buffer != NULL); + + if (offset > (image->pitch>>2) * image->height) + return; + + switch (image->render_mode) + { + case PN_BLEND_MODE_LAST: break; + case PN_BLEND_MODE_IGNORE: + break; + + case PN_BLEND_MODE_REPLACE: + image->image_buffer[offset] = color; + break; + + case PN_BLEND_MODE_5050: + image->image_buffer[offset].red = + (image->image_buffer[offset].red + color.red) >> 1; + image->image_buffer[offset].green = + (image->image_buffer[offset].green + color.green) >> 1; + image->image_buffer[offset].blue = + (image->image_buffer[offset].blue + color.blue) >> 1; + break; + } +} + +/* FIXME: Add clipping to this */ +/** + * pn_image_render_line + * @image: a #PnImage + * @x0: the x coordinate of the first point + * @y0: the y coordinate of the first point + * @x1: the x coordinate of the second point + * @y1: the y coordinate of the second point + * @color: the color + * + * Renders a line from (x0,y0) to (x1,y1) to the image buffer of a #PnImage. + * Currently ***NO CLIPPING IS CURRENTLY DONE!!!*** + */ +void +pn_image_render_line (PnImage *image, guint _x0, guint _y0, guint _x1, guint _y1, PnColor color) +{ + gint x0 = _x0; + gint y0 = _y0; + gint x1 = _x1; + gint y1 = _y1; + + gint dy = y1 - y0; + gint dx = x1 - x0; + gint stepx, stepy; + gint fraction; + + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (image->image_buffer != NULL); + + if (dy < 0) + { + dy = -dy; + stepy = -(image->pitch>>2); + } + else + { + stepy = image->pitch>>2; + } + if (dx < 0) + { + dx = -dx; + stepx = -1; + } + else + { + stepx = 1; + } + dy <<= 1; + dx <<= 1; + + y0 *= image->pitch>>2; + y1 *= image->pitch>>2; + pn_image_render_pixel_by_offset(image, x0+y0, color); + if (dx > dy) + { + fraction = dy - (dx >> 1); + while (x0 != x1) + { + if (fraction >= 0) + { + y0 += stepy; + fraction -= dx; + } + x0 += stepx; + fraction += dy; + pn_image_render_pixel_by_offset (image, x0+y0, color); + } + } + else + { + fraction = dx - (dy >> 1); + while (y0 != y1) + { + if (fraction >= 0) + { + x0 += stepx; + fraction -= dy; + } + y0 += stepy; + fraction += dx; + pn_image_render_pixel_by_offset (image, x0+y0, color); + } + } +} + +static void +pn_image_bufcopy_5050 (PnColor *dest, PnColor *src, guint bufsize) +{ + register guint i; + register PnColor *d, *s; + + d = dest; + s = src; + + for (i=0; i<bufsize; i++) + { + d->red = (s->red + d->red) >> 1; + d->green = (s->green + d->green) >> 1; + d->blue = (s->blue + d->blue) >> 1; + d++; + s++; + } +} + +#ifdef PN_USE_MMX +static void +pn_image_bufcopy_5050_mmx (PnColor *dest, PnColor *src, guint bufsize) +{ + __asm__ __volatile__ ( + "pxor %%mm7,%%mm7\n\t" /* zero mm7 */ + + "10:\n\t" /* The start of the loop */ + + "movq (%0),%%mm0\n\t" /* Read the pixels */ + "movq (%1),%%mm2\n\t" + "movq %%mm0,%%mm1\n\t" + "movq %%mm2,%%mm3\n\t" + + "punpcklbw %%mm7,%%mm0\n\t" /* Unpack the pixels */ + "punpckhbw %%mm7,%%mm1\n\t" + "punpcklbw %%mm7,%%mm2\n\t" + "punpckhbw %%mm7,%%mm3\n\t" + + "paddw %%mm2,%%mm0\n\t" /* Add the pixels */ + "paddw %%mm3,%%mm1\n\t" + + "psrlw $1,%%mm0\n\t" /* Divide the pixels by 2 */ + "psrlw $1,%%mm1\n\t" + + "packuswb %%mm1,%%mm0\n\t" /* Pack it up & write it */ + "movq %%mm0,(%0)\n\t" + + "addl $8,%0\n\t" /* Advance the pointers */ + "addl $8,%1\n\t" + + "decl %2\n\t" /* See if we're done */ + "jnz 10b\n\t" + + "emms" + : /* no outputs */ + : "r" (dest), "r" (src), "r" (bufsize >> 1) + ); +} + +/* FIXME: Should this be in a separate #define PN_USE_MMXEXT ? */ +static void +pn_image_bufcopy_5050_mmxext (PnColor *dest, PnColor *src, guint bufsize) +{ + + + __asm__ __volatile__ ( + "10:\n\t" /* The non-unrolled loop */ + + "decl %2\n\t" /* See if we're done */ + "js 20f\n\t" + + "movq (%0),%%mm0\n\t" /* Read the pixels */ + "movq (%1),%%mm1\n\t" + "pavgb %%mm1,%%mm0\n\t" /* Average the pixels */ + + "movq %%mm0,(%0)\n\t" /* Write the pixels */ + + "addl $8,%0\n\t" /* Advance the pointers */ + "addl $8,%1\n\t" + + "20:\n\t" /* The unrolled loop */ + + "decl %3\n\t" /* See if we're done */ + "js 30f\n\t" + + /* First 2 pixels */ + "movq (%0),%%mm0\n\t" /* Read the pixels */ + "movq (%1),%%mm1\n\t" + "pavgb %%mm1,%%mm0\n\t" /* Average the pixels */ + + /* Second 2 pixels */ + "movq 8(%0),%%mm2\n\t" /* Read the pixels */ + "movq 8(%1),%%mm3\n\t" + "pavgb %%mm3,%%mm2\n\t" /* Average the pixels */ + + /* Third 2 pixels */ + "movq 16(%0),%%mm4\n\t" /* Read the pixels */ + "movq 16(%1),%%mm5\n\t" + "pavgb %%mm5,%%mm4\n\t" /* Average the pixels */ + + /* Fourth 2 pixels */ + "movq 24(%0),%%mm6\n\t" /* Read the pixels */ + "movq 24(%1),%%mm7\n\t" + "pavgb %%mm7,%%mm6\n\t" /* Average the pixels */ + + /* Write them all */ + "movq %%mm0,(%0)\n\t" + "movq %%mm2,8(%0)\n\t" + "movq %%mm4,16(%0)\n\t" + "movq %%mm6,24(%0)\n\t" + + "addl $32,%0\n\t" /* Advance the pointers */ + "addl $32,%1\n\t" + + "jmp 20b\n\t" /* And again */ + + "30:\n\t" + + "emms" + : /* no outputs */ + : "r" (dest), "r" (src), "r" ((bufsize >> 1) & 0x3), "r" (bufsize >> 3) + ); +} + +#endif /* PN_USE_MMX */ + +/** + * pn_image_apply_transform + * @image: a #PnImage + * + * Renders the transform buffer onto the image buffer. + * pn_image_set_transform_mode() may be used to set the blend mode that is + * used by this function. + */ +void +pn_image_apply_transform (PnImage *image) +{ + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + switch (image->transform_mode) + { + case PN_BLEND_MODE_LAST: + case PN_BLEND_MODE_IGNORE: + return; + + case PN_BLEND_MODE_REPLACE: + { + PnColor *tmp = image->image_buffer; + image->image_buffer = image->transform_buffer; + image->transform_buffer = tmp; + } + break; + + case PN_BLEND_MODE_5050: +#ifdef PN_USE_MMX + if (pn_cpu_get_caps () & PN_CPU_CAP_MMXEXT) + pn_image_bufcopy_5050_mmxext (image->image_buffer, image->transform_buffer, + image->height * (image->pitch >> 2)); + else if (pn_cpu_get_caps () & PN_CPU_CAP_MMX) + pn_image_bufcopy_5050_mmx (image->image_buffer, image->transform_buffer, + image->height * (image->pitch >> 2)); + else +#endif /* PN_USE_MMX */ + pn_image_bufcopy_5050 (image->image_buffer, image->transform_buffer, + image->height * (image->pitch >> 2)); + break; + } +} + +/** + * pn_image_render_image + * @image: a #PnImage + * @src: the source image + * @blend_mode: the blend mode to use + * + * Renders the image buffer of @src onto the image buffer of an image. + */ +void +pn_image_render_image (PnImage *image, PnImage *src, PnBlendMode blend_mode) +{ + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (src != NULL); + g_return_if_fail (PN_IS_IMAGE (src)); + g_return_if_fail (blend_mode < PN_BLEND_MODE_LAST); + g_return_if_fail (image->width == src->width); + g_return_if_fail (image->height == src->height); + + switch (blend_mode) + { + case PN_BLEND_MODE_LAST: + case PN_BLEND_MODE_IGNORE: + return; + + case PN_BLEND_MODE_REPLACE: + memcpy (image->image_buffer, src->image_buffer, image->height * (image->pitch >> 2) * sizeof (PnColor)); + break; + + case PN_BLEND_MODE_5050: +#ifdef PN_USE_MMX + if (pn_cpu_get_caps () & PN_CPU_CAP_MMXEXT) + pn_image_bufcopy_5050_mmxext (image->image_buffer, src->image_buffer, + image->height * (image->pitch >> 2)); + else if (pn_cpu_get_caps () & PN_CPU_CAP_MMX) + pn_image_bufcopy_5050_mmx (image->image_buffer, src->image_buffer, image->height * (image->pitch >> 2)); + else +#endif /* PN_USE_MMX */ + pn_image_bufcopy_5050 (image->image_buffer, src->image_buffer, image->height * (image->pitch >> 2)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnimage.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,136 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_IMAGE_H__ +#define __PN_IMAGE_H__ + +#include <glib.h> +#include "pnobject.h" + +G_BEGIN_DECLS + +typedef enum +{ + PN_BLEND_MODE_IGNORE, /* Ignore the source image */ + PN_BLEND_MODE_REPLACE, /* Replace the destination image with the source */ + PN_BLEND_MODE_5050, /* Use the mean of the source and destination images */ + PN_BLEND_MODE_LAST /* INVALID */ +} PnBlendMode; +extern const gchar *pn_image_blend_mode_strings[]; +extern const guint pn_image_blend_mode_count; + +#define PN_TYPE_IMAGE (pn_image_get_type ()) +#define PN_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_IMAGE, PnImage)) +#define PN_IMAGE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_IMAGE, PnImageClass)) +#define PN_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_IMAGE)) +#define PN_IS_IMAGE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_IMAGE)) +#define PN_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_IMAGE, PnImageClass)) + +/* Member access macros */ +#define PN_IMAGE_PITCH(obj) (PN_IMAGE (obj)->pitch) +#define PN_IMAGE_WIDTH(obj) (PN_IMAGE (obj)->width) +#define PN_IMAGE_HEIGHT(obj) (PN_IMAGE (obj)->height) +#define PN_IMAGE_IMAGE_BUF(obj) (PN_IMAGE (obj)->image_buffer) +#define PN_IMAGE_XFORM_BUF(obj) (PN_IMAGE (obj)->transform_buffer) + +/* This is to help with passing just the PnImage part of a + * PnImage (e.g. to assembly code) + */ +#define PN_IMAGE_START(obj) (G_STRUCT_MEMBER_P (obj, G_STRUCT_OFFSET (PnImage, pitch))) + +typedef struct _PnColor PnColor; + +struct _PnColor +{ + guint8 red; + guint8 green; + guint8 blue; + guint8 unused; +}; + +typedef struct _PnImage PnImage; +typedef struct _PnImageClass PnImageClass; + +struct _PnImage +{ + PnObject parent; + + /* The width of the image buffers in bytes */ + guint pitch; + + /* The dimensions of the valid image area in pixels */ + guint width; + guint height; + + /* The pixel bleding modes to be used when rendering individual + * pixels and when applying the transform buffer to the + * image buffer + */ + PnBlendMode render_mode; + PnBlendMode transform_mode; + + /* The pixel buffers */ + PnColor *image_buffer; + PnColor *transform_buffer; +}; + +struct _PnImageClass +{ + PnObjectClass parent_class; +}; + +/* Creators */ +GType pn_image_get_type (void); +PnImage *pn_image_new (void); +PnImage *pn_image_new_with_size (guint width, + guint height); + +/* Accessors */ +void pn_image_set_size (PnImage *image, + guint width, + guint height); +guint pn_image_get_width (PnImage *image); +guint pn_image_get_height (PnImage *image); +guint pn_image_get_pitch (PnImage *image); +void pn_image_set_render_mode (PnImage *image, + PnBlendMode render_mode); +void pn_image_set_transform_mode (PnImage *image, + PnBlendMode transform_mode); +PnColor *pn_image_get_image_buffer (PnImage *image); +PnColor *pn_image_get_transform_buffer (PnImage *image); + +/* Actions */ +void pn_image_render_pixel (PnImage *image, + guint x, + guint y, + PnColor color); +void pn_image_render_pixel_by_offset (PnImage *image, + guint offset, + PnColor color); +void pn_image_render_line (PnImage *image, + guint x0, + guint y0, + guint x1, + guint y1, + PnColor color); +void pn_image_apply_transform (PnImage *image); +void pn_image_render_image (PnImage *image, + PnImage *src, + PnBlendMode blend_mode); + +#endif /* __PN_IMAGE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnimagecontext.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,188 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glib.h> +#include "pnimagecontext.h" +#include "pnlistoption.h" + +static void pn_image_context_class_init (PnImageContextClass *class); +static void pn_image_context_init (PnImageContext *image_context, + PnImageContextClass *class); +/* GObject methods */ +static void pn_image_context_finalize (GObject *gobject); + +/* PnActuator methods */ +static void pn_image_context_prepare (PnImageContext *image_context, + PnImage *image); +static void pn_image_context_execute (PnImageContext *image_context, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_image_context_get_type (void) +{ + static GType image_context_type = 0; + + if (! image_context_type) + { + static const GTypeInfo image_context_info = + { + sizeof (PnImageContextClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_image_context_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnImageContext), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_image_context_init + }; + + /* FIXME: should this be dynamic? */ + image_context_type = g_type_register_static (PN_TYPE_CONTAINER, + "PnImageContext", + &image_context_info, + 0); + } + return image_context_type; +} + +static void +pn_image_context_class_init (PnImageContextClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* GObject methods */ + gobject_class->finalize = pn_image_context_finalize; + + /* PnActuator methods */ + actuator_class->prepare = (PnActuatorPrepFunc) pn_image_context_prepare; + actuator_class->execute = (PnActuatorExecFunc) pn_image_context_execute; +} + +static void +pn_image_context_finalize (GObject *gobject) +{ + PnImageContext *image_context; + + image_context = (PnImageContext *) gobject; + + if (image_context->image) + pn_object_unref (PN_OBJECT (image_context->image)); +} + +static void +pn_image_context_init (PnImageContext *image_context, PnImageContextClass *class) +{ + PnListOption *input_mode_opt, *output_mode_opt; + guint i; + + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (image_context), "Container.Image_Context"); + pn_user_object_set_description (PN_USER_OBJECT (image_context), + "A container that executes all its actuators sequentially"); + + /* Set up the options */ + input_mode_opt = pn_list_option_new ("input_mode", "The blend mode to be used when getting the image " + "from the parent context"); + output_mode_opt = pn_list_option_new ("output_mode", "The blend mode to be used when writing the image " + "to the parent context"); + + for (i=0; i<pn_image_blend_mode_count; i++) + { + pn_list_option_add_item (input_mode_opt, pn_image_blend_mode_strings[i]); + pn_list_option_add_item (output_mode_opt, pn_image_blend_mode_strings[i]); + } + + pn_list_option_set_index (input_mode_opt, 0); /* default mode: Ignore */ + pn_list_option_set_index (output_mode_opt, 1); /* default mode: Replace */ + + pn_actuator_add_option (PN_ACTUATOR (image_context), PN_OPTION (input_mode_opt)); + pn_actuator_add_option (PN_ACTUATOR (image_context), PN_OPTION (output_mode_opt)); + + /* Create the new image */ + image_context->image = pn_image_new (); + pn_object_ref (PN_OBJECT (image_context->image)); + pn_object_sink (PN_OBJECT (image_context->image)); +} + +static void +pn_image_context_prepare (PnImageContext *image_context, PnImage *image) +{ + g_return_if_fail (image_context != NULL); + g_return_if_fail (PN_IS_IMAGE_CONTEXT (image_context)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + pn_image_set_size (image_context->image, pn_image_get_width (image), pn_image_get_height (image)); + + if (PN_ACTUATOR_CLASS (parent_class)->prepare) + PN_ACTUATOR_CLASS (parent_class)->prepare (PN_ACTUATOR (image_context), image); +} + +static void +pn_image_context_execute (PnImageContext *image_context, PnImage *image, + PnAudioData *audio_data) +{ + guint i; + GArray *actuators; + PnListOption *input_mode_opt, *output_mode_opt; + + g_return_if_fail (image_context != NULL); + g_return_if_fail (PN_IS_IMAGE_CONTEXT (image_context)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + + actuators = ((PnContainer *) (image_context))->actuators;; + + input_mode_opt = (PnListOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (image_context), + PN_IMAGE_CONTEXT_OPT_INPUT_MODE); + output_mode_opt = (PnListOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (image_context), + PN_IMAGE_CONTEXT_OPT_OUTPUT_MODE); + + /* Get the image from the parent context */ + pn_image_render_image (image_context->image, image, (PnBlendMode) pn_list_option_get_index (input_mode_opt)); + + for (i=0; i<actuators->len; i++) + pn_actuator_execute (g_array_index (actuators, PnActuator *, i), image_context->image, audio_data); + + /* Write the image to the parent context */ + pn_image_render_image (image, image_context->image, (PnBlendMode) pn_list_option_get_index (output_mode_opt)); + + if (PN_ACTUATOR_CLASS (parent_class)->execute) + PN_ACTUATOR_CLASS (parent_class)->execute(PN_ACTUATOR (image_context), image, audio_data); +} + +PnImageContext* +pn_image_context_new (void) +{ + return (PnImageContext *) g_object_new (PN_TYPE_IMAGE_CONTEXT, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnimagecontext.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,61 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_IMAGE_CONTEXT_H__ +#define __PN_IMAGE_CONTEXT_H__ + +#include "pncontainer.h" + +G_BEGIN_DECLS + +enum +{ + PN_IMAGE_CONTEXT_OPT_INPUT_MODE = PN_CONTAINER_OPT_LAST, + PN_IMAGE_CONTEXT_OPT_OUTPUT_MODE, + PN_IMAGE_CONTEXT_OPT_LAST +}; + +#define PN_TYPE_IMAGE_CONTEXT (pn_image_context_get_type ()) +#define PN_IMAGE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_IMAGE_CONTEXT, PnImageContext)) +#define PN_IMAGE_CONTEXT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_IMAGE_CONTEXT, PnImageContextClass)) +#define PN_IS_IMAGE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_IMAGE_CONTEXT)) +#define PN_IS_IMAGE_CONTEXT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_IMAGE_CONTEXT)) +#define PN_IMAGE_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_IMAGE_CONTEXT, PnImageContextClass)) + +#define PN_IMAGE_CONTEXT_ACTUATORS(obj) (PN_IMAGE_CONTEXT (obj)->actuators) + +typedef struct _PnImageContext PnImageContext; +typedef struct _PnImageContextClass PnImageContextClass; + +struct _PnImageContext +{ + PnContainer parent; + + PnImage *image; +}; + +struct _PnImageContextClass +{ + PnContainerClass parent_class; +}; + +/* Creators */ +GType pn_image_context_get_type (void); +PnImageContext *pn_image_context_new (void); + +#endif /* __PN_IMAGE_CONTEXT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pninit.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,43 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <glib.h> +#include "pninit.h" +#include "pncpu.h" +#include "pnactuatorfactory.h" +#include "pnbuiltins.h" + +guint pn_major_version = 1; +guint pn_minor_version = 2; +guint pn_micro_version = 0; + +static gboolean pn_ready = FALSE; + +void +pn_init (void) +{ + if (pn_ready) + return; + + g_type_init (); + pn_cpu_init (); + pn_actuator_factory_init (); + pn_builtins_register (); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pninit.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,30 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_INIT_H__ +#define __PN_INIT_H__ + +#include <glib.h> + +extern guint pn_major_version; +extern guint pn_minor_version; +extern guint pn_micro_version; + +void pn_init (void); + +#endif /* __PN_INIT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnintegeroption.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,243 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <stdlib.h> +#include <limits.h> +#include <glib.h> +#include "pnintegeroption.h" +#include "pnxml.h" +#include "pnerror.h" + +static void pn_integer_option_class_init (PnIntegerOptionClass *class); +static void pn_integer_option_init (PnIntegerOption *integer_option, + PnIntegerOptionClass *class); + +/* PnUserObject methods */ +static void pn_integer_option_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_integer_option_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static PnUserObjectClass *parent_class = NULL; + +GType +pn_integer_option_get_type (void) +{ + static GType integer_option_type = 0; + + if (! integer_option_type) + { + static const GTypeInfo integer_option_info = + { + sizeof (PnIntegerOptionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_integer_option_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnIntegerOption), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_integer_option_init + }; + + /* FIXME: should this be dynamic? */ + integer_option_type = g_type_register_static (PN_TYPE_OPTION, + "PnIntegerOption", + &integer_option_info, + 0); + } + return integer_option_type; +} + +static void +pn_integer_option_class_init (PnIntegerOptionClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnOptionClass *option_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + option_class = (PnOptionClass *) class; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_integer_option_save_thyself; + user_object_class->load_thyself = pn_integer_option_load_thyself; + + /* PnOption methods */ + /* FIXME: this needs to be uncommented when the widget is done */ +/* option_class->widget_type = PN_TYPE_INTEGER_OPTION_WIDGET; */ +} + +static void +pn_integer_option_init (PnIntegerOption *integer_option, + PnIntegerOptionClass *class) +{ + integer_option->min = INT_MIN; + integer_option->max = INT_MAX; +} + +static void +pn_integer_option_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnIntegerOption *integer_option; + xmlNodePtr value_node; + gchar str[16]; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_INTEGER_OPTION (user_object)); + g_return_if_fail (node != NULL); + + integer_option = (PnIntegerOption *) user_object; + + value_node = xmlNewChild (node, NULL, "Value", NULL); + sprintf (str, "%i", integer_option->value); + xmlNodeSetContent (value_node, str); + + if (parent_class->save_thyself) + parent_class->save_thyself (user_object, node); +} + +static void +pn_integer_option_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnIntegerOption *integer_option; + xmlNodePtr integer_option_node; + gchar *val_str; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_INTEGER_OPTION (user_object)); + g_return_if_fail (node != NULL); + + integer_option = (PnIntegerOption *) user_object; + + /* find the node for this class */ + for (integer_option_node = node->xmlChildrenNode; + integer_option_node; + integer_option_node = integer_option_node->next) + if (g_strcasecmp (integer_option_node->name, "Value") == 0) + break; + if (! integer_option_node) + { + pn_error ("unable to load a PnIntegerOption from xml node \"%s\"", node->name); + return; + } + + val_str = xmlNodeGetContent (integer_option_node); + + if (val_str) + pn_integer_option_set_value (integer_option, strtol (val_str, NULL, 0)); + else + { + pn_error ("invalid integer option value encountered at xml node \"%s\"", node->name); + return; + } + + if (parent_class->load_thyself) + parent_class->load_thyself (user_object, node); +} + +PnIntegerOption* +pn_integer_option_new (const gchar *name, const gchar *desc) +{ + PnIntegerOption *integer_option; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (desc != NULL, NULL); + + integer_option = (PnIntegerOption *) g_object_new (PN_TYPE_INTEGER_OPTION, NULL); + + pn_user_object_set_name (PN_USER_OBJECT (integer_option), name); + pn_user_object_set_description (PN_USER_OBJECT (integer_option), desc); + + return integer_option; +} + +void +pn_integer_option_set_value (PnIntegerOption *integer_option, gint value) +{ + g_return_if_fail (integer_option != NULL); + g_return_if_fail (PN_IS_INTEGER_OPTION (integer_option)); + + integer_option->value = CLAMP (value, integer_option->min, integer_option->max); +} + +gint +pn_integer_option_get_value (PnIntegerOption *integer_option) +{ + g_return_val_if_fail (integer_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_INTEGER_OPTION (integer_option), FALSE); + + return integer_option->value; +} + +void +pn_integer_option_set_min (PnIntegerOption *integer_option, gint min) +{ + g_return_if_fail (integer_option != NULL); + g_return_if_fail (PN_IS_INTEGER_OPTION (integer_option)); + + if (min > integer_option->max) + { + integer_option->min = integer_option->max; + integer_option->max = min; + } + else + integer_option->min = min; + + pn_integer_option_set_value (integer_option, integer_option->value); +} + +gint +pn_integer_option_get_min (PnIntegerOption *integer_option) +{ + g_return_val_if_fail (integer_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_INTEGER_OPTION (integer_option), FALSE); + + return integer_option->min; +} + +void +pn_integer_option_set_max (PnIntegerOption *integer_option, gint max) +{ + g_return_if_fail (integer_option != NULL); + g_return_if_fail (PN_IS_INTEGER_OPTION (integer_option)); + + if (max < integer_option->min) + { + integer_option->max = integer_option->min; + integer_option->min = max; + } + else + integer_option->max = max; + + pn_integer_option_set_value (integer_option, integer_option->value); +} + +gint +pn_integer_option_get_max (PnIntegerOption *integer_option) +{ + g_return_val_if_fail (integer_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_INTEGER_OPTION (integer_option), FALSE); + + return integer_option->max; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnintegeroption.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,73 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_INTEGER_OPTION_H__ +#define __PN_INTEGER_OPTION_H__ + +#include "pnoption.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_INTEGER_OPTION (pn_integer_option_get_type ()) +#define PN_INTEGER_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_INTEGER_OPTION, PnIntegerOption)) +#define PN_INTEGER_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_INTEGER_OPTION, PnIntegerOptionClass)) +#define PN_IS_INTEGER_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_INTEGER_OPTION)) +#define PN_IS_INTEGER_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_INTEGER_OPTION)) +#define PN_INTEGER_OPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_INTEGER_OPTION, PnIntegerOptionClass)) + +typedef struct _PnIntegerOption PnIntegerOption; +typedef struct _PnIntegerOptionClass PnIntegerOptionClass; + +struct _PnIntegerOption +{ + PnOption parent; + + gint value; + gint min; + gint max; +}; + +struct _PnIntegerOptionClass +{ + PnOptionClass parent_class; +}; + +/* Creators */ +GType pn_integer_option_get_type (void); +PnIntegerOption *pn_integer_option_new (const gchar *name, + const gchar *desc); + +/* Accessors */ +void pn_integer_option_set_value (PnIntegerOption *integer_option, + gint value); +gint pn_integer_option_get_value (PnIntegerOption *integer_option); +void pn_integer_option_set_min (PnIntegerOption *integer_option, + gint min); +gint pn_integer_option_get_min (PnIntegerOption *integer_option); +void pn_integer_option_set_max (PnIntegerOption *integer_option, + gint max); +gint pn_integer_option_get_max (PnIntegerOption *integer_option); + + + + + + +#endif /* __PN_INTEGER_OPTION_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnlistoption.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,207 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <ctype.h> +#include <glib.h> +#include "pnlistoption.h" +#include "pnxml.h" +#include "pnerror.h" + +static void pn_list_option_class_init (PnListOptionClass *class); +static void pn_list_option_init (PnListOption *list_option, + PnListOptionClass *class); + +/* PnUserObject methods */ +static void pn_list_option_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_list_option_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static PnUserObjectClass *parent_class = NULL; + +GType +pn_list_option_get_type (void) +{ + static GType list_option_type = 0; + + if (! list_option_type) + { + static const GTypeInfo list_option_info = + { + sizeof (PnListOptionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_list_option_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnListOption), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_list_option_init + }; + + /* FIXME: should this be dynamic? */ + list_option_type = g_type_register_static (PN_TYPE_OPTION, + "PnListOption", + &list_option_info, + 0); + } + return list_option_type; +} + +static void +pn_list_option_class_init (PnListOptionClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnOptionClass *option_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + option_class = (PnOptionClass *) class; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_list_option_save_thyself; + user_object_class->load_thyself = pn_list_option_load_thyself; + + /* PnOption methods */ + /* FIXME: this needs to be uncommented when the widget is done */ +/* option_class->widget_type = PN_TYPE_LIST_OPTION_WIDGET; */ +} + +static void +pn_list_option_init (PnListOption *list_option, PnListOptionClass *class) +{ + list_option->items = g_array_new (FALSE, FALSE, sizeof (const gchar *)); + list_option->index = -1; +} + +static void +pn_list_option_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnListOption *list_option; + xmlNodePtr value_node; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_LIST_OPTION (user_object)); + g_return_if_fail (node != NULL); + + list_option = (PnListOption *) user_object; + + value_node = xmlNewChild (node, NULL, "Value", NULL); + xmlNodeSetContent (value_node, g_array_index (list_option->items, const gchar *, list_option->index)); + + if (parent_class->save_thyself) + parent_class->save_thyself (user_object, node); +} + +static void +pn_list_option_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnListOption *list_option; + xmlNodePtr list_option_node; + gchar *val_str; + guint i; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_LIST_OPTION (user_object)); + g_return_if_fail (node != NULL); + + list_option = (PnListOption *) user_object; + + /* find the node for this class */ + for (list_option_node = node->xmlChildrenNode; + list_option_node; + list_option_node = list_option_node->next) + if (g_strcasecmp (list_option_node->name, "Value") == 0) + break; + if (! list_option_node) + { + pn_error ("unable to load a PnListOption from xml node \"%s\"", node->name); + return; + } + + val_str = xmlNodeGetContent (list_option_node); + if (! val_str) + goto done; + + for (i=0; i < list_option->items->len; i++) + if (g_strcasecmp (val_str, g_array_index (list_option->items, const gchar *, i)) == 0) + { + list_option->index = i; + goto done; + } + + pn_error ("invalid list option value encountered at xml node \"%s\"", node->name); + return; + + done: + if (parent_class->load_thyself) + parent_class->load_thyself (user_object, node); +} + +PnListOption* +pn_list_option_new (const gchar *name, const gchar *desc) +{ + PnListOption *list_option; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (desc != NULL, NULL); + + list_option = (PnListOption *) g_object_new (PN_TYPE_LIST_OPTION, NULL); + + pn_user_object_set_name (PN_USER_OBJECT (list_option), name); + pn_user_object_set_description (PN_USER_OBJECT (list_option), desc); + + return list_option; +} + +void +pn_list_option_add_item (PnListOption *list_option, const gchar *item) +{ + g_return_if_fail (list_option != NULL); + g_return_if_fail (PN_IS_LIST_OPTION (list_option)); + g_return_if_fail (item != NULL); + + g_array_append_val (list_option->items, item); + + if (list_option->index < 0) + list_option->index = 0; +} + +void +pn_list_option_set_index (PnListOption *list_option, guint index) +{ + g_return_if_fail (list_option != NULL); + g_return_if_fail (PN_IS_LIST_OPTION (list_option)); + g_return_if_fail (index < list_option->items->len); + + list_option->index = index; +} + +gint +pn_list_option_get_index (PnListOption *list_option) +{ + g_return_val_if_fail (list_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_LIST_OPTION (list_option), FALSE); + + return list_option->index; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnlistoption.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,61 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_LIST_OPTION_H__ +#define __PN_LIST_OPTION_H__ + +#include "pnoption.h" + +G_BEGIN_DECLS + +#define PN_TYPE_LIST_OPTION (pn_list_option_get_type ()) +#define PN_LIST_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_LIST_OPTION, PnListOption)) +#define PN_LIST_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_LIST_OPTION, PnListOptionClass)) +#define PN_IS_LIST_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_LIST_OPTION)) +#define PN_IS_LIST_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_LIST_OPTION)) +#define PN_LIST_OPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_LIST_OPTION, PnListOptionClass)) + +typedef struct _PnListOption PnListOption; +typedef struct _PnListOptionClass PnListOptionClass; + +struct _PnListOption +{ + PnOption parent; + + GArray *items; + gint index; +}; + +struct _PnListOptionClass +{ + PnOptionClass parent_class; +}; + +/* Creators */ +GType pn_list_option_get_type (void); +PnListOption *pn_list_option_new (const gchar *name, + const gchar *desc); + +/* Accessors */ +void pn_list_option_add_item (PnListOption *list_option, + const gchar *item); +void pn_list_option_set_index (PnListOption *list_option, + guint index); +gint pn_list_option_get_index (PnListOption *list_option); + +#endif /* __PN_LIST_OPTION_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnobject.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,210 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include "pnobject.h" + +enum +{ + DESTROY, + LAST_SIGNAL +}; + +/* Initialization */ +static void pn_object_class_init (PnObjectClass *class); +static void pn_object_init (PnObject *object, + PnObjectClass *class); + +/* GObject signals */ +static void pn_object_finalize (GObject *gobject); +static void pn_object_dispose (GObject *gobject); + +/* PnObject signals */ +static void pn_object_real_destroy (PnObject *object); + +static GObjectClass *parent_class = NULL; +static guint object_signals[LAST_SIGNAL] = { 0 }; + +GType +pn_object_get_type (void) +{ + static GType object_type = 0; + + if (! object_type) + { + static const GTypeInfo object_info = + { + sizeof (PnObjectClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_object_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnObject), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_object_init + }; + + /* FIXME: should this be dynamic? */ + object_type = g_type_register_static (G_TYPE_OBJECT, + "PnObject", + &object_info, + G_TYPE_FLAG_ABSTRACT); + } + return object_type; +} + +static void +pn_object_class_init (PnObjectClass *class) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class->dispose = pn_object_dispose; + gobject_class->finalize = pn_object_finalize; + + class->destroy = pn_object_real_destroy; + + object_signals[DESTROY] = + g_signal_new ("destroy", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + G_STRUCT_OFFSET (PnObjectClass, destroy), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +pn_object_init (PnObject *object, PnObjectClass *class) +{ + object->flags = PN_FLOATING; +} + +void +pn_object_destroy (PnObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (PN_IS_OBJECT (object)); + + if (!PN_OBJECT_DESTROYED (object)) + { + /* need to hold a reference count around all class method + * invocations. + */ + g_object_run_dispose (G_OBJECT (object)); + } +} + +static void +pn_object_dispose (GObject *gobject) +{ + PnObject *object = PN_OBJECT (gobject); + + /* guard against reinvocations during + * destruction with the PN_DESTROYED flag. + */ + if (!PN_OBJECT_DESTROYED (object)) + { + PN_OBJECT_SET_FLAGS (object, PN_DESTROYED); + + g_signal_emit (object, object_signals[DESTROY], 0); + + PN_OBJECT_UNSET_FLAGS (object, PN_DESTROYED); + } + + G_OBJECT_CLASS (parent_class)->dispose (gobject); +} + +static void +pn_object_real_destroy (PnObject *object) +{ + g_signal_handlers_destroy (G_OBJECT (object)); +} + +static void +pn_object_finalize (GObject *gobject) +{ + PnObject *object; + + object = PN_OBJECT (gobject); + + G_OBJECT_CLASS (parent_class)->finalize (gobject); +} + +/** + * pn_object_sink + * @object: a #PnObject + * + * Removes floating reference on an object. Any newly created object has + * a refcount of 1 and is FLOATING. This function should be used when + * creating a new object to symbolically 'take ownership of' the object. + */ +void +pn_object_sink (PnObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (PN_IS_OBJECT (object)); + + if (PN_OBJECT_FLOATING (object)) + { + PN_OBJECT_UNSET_FLAGS (object, PN_FLOATING); + pn_object_unref (object); + } +} + +/** + * pn_object_ref + * @object: a #PnObject + * + * Increments the reference count on an object + * + * Returns: A pointer to the object + */ +PnObject* +pn_object_ref (PnObject *object) +{ + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (PN_IS_OBJECT (object), NULL); + + g_object_ref ((GObject*) object); + + return object; +} + +/** + * pn_object_unref + * @object: a #PnObject + * + * Decrements the reference count on an object. If the object's reference + * count becomes 0, the object is freed from memory. + */ +void +pn_object_unref (PnObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (PN_IS_OBJECT (object)); + + g_object_unref ((GObject*) object); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnobject.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,91 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_OBJECT_H__ +#define __PN_OBJECT_H__ + +#include <config.h> + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define PN_TYPE_OBJECT (pn_object_get_type ()) +#define PN_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_OBJECT, PnObject)) +#define PN_OBJECT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_OBJECT, PnObjectClass)) +#define PN_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_OBJECT)) +#define PN_IS_OBJECT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_OBJECT)) +#define PN_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_OBJECT, PnObjectClass)) +#define PN_OBJECT_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +#define PN_OBJECT_CLASS_NAME(class) (g_type_name (PN_OBJECT_CLASS_TYPE (class))) + +#define PN_OBJECT_TYPE(obj) (G_TYPE_FROM_INSTANCE (obj)) +#define PN_OBJECT_TYPE_NAME(obj) (g_type_name (PN_OBJECT_TYPE (obj))) + +typedef enum +{ + PN_DESTROYED = 1 << 0, + PN_FLOATING = 1 << 1, + PN_RESERVED_1 = 1 << 2, + PN_RESERVED_2 = 1 << 3 +} PnObjectFlags; + +#define PN_OBJECT_FLAGS(obj) (PN_OBJECT (obj)->flags) +#define PN_OBJECT_DESTROYED(obj) ((PN_OBJECT_FLAGS (obj) & PN_DESTROYED) != 0) +#define PN_OBJECT_FLOATING(obj) ((PN_OBJECT_FLAGS (obj) & PN_FLOATING) != 0) +#define PN_OBJECT_CONNECTED(obj) ((PN_OBJECT_FLAGS (obj) & PN_CONNECTED) != 0) + +#define PN_OBJECT_SET_FLAGS(obj,flag) G_STMT_START{ (PN_OBJECT_FLAGS (obj) |= (flag)); }G_STMT_END +#define PN_OBJECT_UNSET_FLAGS(obj,flag) G_STMT_START{ (PN_OBJECT_FLAGS (obj) &= ~(flag)); }G_STMT_END + +typedef struct _PnObject PnObject; +typedef struct _PnObjectClass PnObjectClass; + +struct _PnObject +{ + GObject parent; + + /* Only the first four bits are used, so derived classes can use this + * for their own flags + */ + guint32 flags; +}; + +struct _PnObjectClass +{ + GObjectClass parent_class; + + /* if a class overrides this then it MUST call its superclass' + * implimentation + */ + void (*destroy) (PnObject *object); +}; + +/* Creators */ +GType pn_object_get_type (void); + +/* Referencing */ +PnObject* pn_object_ref (PnObject *object); +void pn_object_unref (PnObject *object); +void pn_object_sink (PnObject *object); + +/* Destruction */ +void pn_object_destroy (PnObject *object); + +#endif /* __PN_OBJECT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnoption.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,112 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <glib.h> +#include "pnoption.h" + +static void pn_option_class_init (PnOptionClass *class); +static void pn_option_init (PnOption *option, + PnOptionClass *class); + +/* GObject signals */ +static void pn_option_finalize (GObject *gobject); + +static PnUserObjectClass *parent_class = NULL; + +GType +pn_option_get_type (void) +{ + static GType option_type = 0; + + if (! option_type) + { + static const GTypeInfo option_info = + { + sizeof (PnOptionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_option_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnOption), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_option_init + }; + + /* FIXME: should this be dynamic? */ + option_type = g_type_register_static (PN_TYPE_USER_OBJECT, + "PnOption", + &option_info, + G_TYPE_FLAG_ABSTRACT); + } + return option_type; +} + +static void +pn_option_class_init (PnOptionClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + + /* GObject signals */ + gobject_class->finalize = pn_option_finalize; +} + +static void +pn_option_init (PnOption *option, PnOptionClass *class) +{ +} + +static void +pn_option_finalize (GObject *gobject) +{ + PnOption *option; + + option = (PnOption *) gobject; + + if (G_OBJECT_CLASS (parent_class)->finalize) + (* G_OBJECT_CLASS (parent_class)->finalize) (gobject); +} + +PnOptionWidget* +pn_option_new_widget (PnOption *option) +{ + PnOptionClass *class; + + g_return_val_if_fail (option != NULL, NULL); + g_return_val_if_fail (PN_IS_OPTION (option), NULL); + + class = PN_OPTION_GET_CLASS (option); + +#ifndef PN_NO_GTK + if (class->widget_type) + return PN_OPTION_WIDGET (g_object_new (class->widget_type, NULL)); +#endif /* PN_NO_GTK */ + + return NULL; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnoption.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,59 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_OPTION_H__ +#define __PN_OPTION_H__ + +#include "pnuserobject.h" +#include "pnoptionwidget.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_OPTION (pn_option_get_type ()) +#define PN_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_OPTION, PnOption)) +#define PN_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_OPTION, PnOptionClass)) +#define PN_IS_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_OPTION)) +#define PN_IS_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_OPTION)) +#define PN_OPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_OPTION, PnOptionClass)) + +typedef struct _PnOption PnOption; +typedef struct _PnOptionClass PnOptionClass; + +struct _PnOption +{ + PnUserObject parent; +}; + +struct _PnOptionClass +{ + PnUserObjectClass parent_class; + + GType widget_type; +}; + +/* Creators */ +GType pn_option_get_type (void); +PnOptionWidget *pn_option_new_widget (PnOption *option); + + + + + +#endif /* __PN_OPTION_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnoptionwidget.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,26 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_OPTION_WIDGET_H__ +#define __PN_OPTION_WIDGET_H__ + +#include "pngtk.h" + +#define PnOptionWidget gpointer + +#endif /* __PN_OPTION_WIDGET_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnrotozoom.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,339 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <math.h> + +#include <glib.h> +#include "pnrotozoom.h" +#include "pnstringoption.h" +#include "pnscript.h" +#include "pnsymboltable.h" +#include "pncpu.h" + +static void pn_roto_zoom_class_init (PnRotoZoomClass *class); +static void pn_roto_zoom_init (PnRotoZoom *roto_zoom, + PnRotoZoomClass *class); + +/* PnObject signals */ +static void pn_roto_zoom_destroy (PnObject *object); + +/* PnActuator methods */ +static void pn_roto_zoom_prepare (PnRotoZoom *roto_zoom, + PnImage *image); +static void pn_roto_zoom_execute (PnRotoZoom *roto_zoom, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_roto_zoom_get_type (void) +{ + static GType roto_zoom_type = 0; + + if (! roto_zoom_type) + { + static const GTypeInfo roto_zoom_info = + { + sizeof (PnRotoZoomClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_roto_zoom_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnRotoZoom), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_roto_zoom_init + }; + + /* FIXME: should this be dynamic? */ + roto_zoom_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnRotoZoom", + &roto_zoom_info, + 0); + } + return roto_zoom_type; +} + +static void +pn_roto_zoom_class_init (PnRotoZoomClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnObject signals */ + object_class->destroy = pn_roto_zoom_destroy; + + /* PnActuator methods */ + actuator_class->prepare = (PnActuatorPrepFunc) pn_roto_zoom_prepare; + actuator_class->execute = (PnActuatorExecFunc) pn_roto_zoom_execute; +} + +static void +pn_roto_zoom_init (PnRotoZoom *roto_zoom, PnRotoZoomClass *class) +{ + PnStringOption *init_script_opt, *frame_script_opt; + + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (roto_zoom), "Transform.Roto_Zoom"); + pn_user_object_set_description (PN_USER_OBJECT (roto_zoom), + "Rotate and zoom the image"); + + /* Set up the options */ + init_script_opt = pn_string_option_new ("init_script", "The initialization script"); + frame_script_opt = pn_string_option_new ("frame_script", "The per-frame script"); + + pn_actuator_add_option (PN_ACTUATOR (roto_zoom), PN_OPTION (init_script_opt)); + pn_actuator_add_option (PN_ACTUATOR (roto_zoom), PN_OPTION (frame_script_opt)); + + /* Create the script objects and symbol table */ + roto_zoom->init_script = pn_script_new (); + pn_object_ref (PN_OBJECT (roto_zoom->init_script)); + pn_object_sink (PN_OBJECT (roto_zoom->init_script)); + roto_zoom->frame_script = pn_script_new (); + pn_object_ref (PN_OBJECT (roto_zoom->frame_script)); + pn_object_sink (PN_OBJECT (roto_zoom->frame_script)); + roto_zoom->symbol_table = pn_symbol_table_new (); + pn_object_ref (PN_OBJECT (roto_zoom->symbol_table)); + pn_object_sink (PN_OBJECT (roto_zoom->symbol_table)); + + /* Get the variables from the symbol table */ + roto_zoom->zoom_var = pn_symbol_table_ref_variable_by_name (roto_zoom->symbol_table, "zoom"); + roto_zoom->theta_var = pn_symbol_table_ref_variable_by_name (roto_zoom->symbol_table, "theta"); + roto_zoom->volume_var = pn_symbol_table_ref_variable_by_name (roto_zoom->symbol_table, "volume"); +} + +static void +pn_roto_zoom_destroy (PnObject *object) +{ + PnRotoZoom *roto_zoom; + + roto_zoom = (PnRotoZoom *) object; + + pn_object_unref (PN_OBJECT (roto_zoom->init_script)); + pn_object_unref (PN_OBJECT (roto_zoom->frame_script)); + pn_object_unref (PN_OBJECT (roto_zoom->symbol_table)); +} + +static void +pn_roto_zoom_prepare (PnRotoZoom *roto_zoom, PnImage *image) +{ + PnStringOption *init_script_opt, *frame_script_opt; + + g_return_if_fail (roto_zoom != NULL); + g_return_if_fail (PN_IS_ROTO_ZOOM (roto_zoom)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + /* Parse the script strings */ + init_script_opt = + (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (roto_zoom), + PN_ROTO_ZOOM_OPT_INIT_SCRIPT); + frame_script_opt = + (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (roto_zoom), + PN_ROTO_ZOOM_OPT_FRAME_SCRIPT); + + pn_script_parse_string (roto_zoom->init_script, roto_zoom->symbol_table, + pn_string_option_get_value (init_script_opt)); + pn_script_parse_string (roto_zoom->frame_script, roto_zoom->symbol_table, + pn_string_option_get_value (frame_script_opt)); + + /* Set up in-script vars for no rotozooming */ + PN_VARIABLE_VALUE (roto_zoom->zoom_var) = 1.0; + PN_VARIABLE_VALUE (roto_zoom->theta_var) = 0.0; + + /* Run the init script */ + pn_script_execute (roto_zoom->init_script); + + if (PN_ACTUATOR_CLASS (parent_class)->prepare) + PN_ACTUATOR_CLASS (parent_class)->prepare (PN_ACTUATOR (roto_zoom), image); +} + +static void +pn_roto_zoom_execute (PnRotoZoom *roto_zoom, PnImage *image, PnAudioData *audio_data) +{ + gint width, height, stride; + gdouble ax, ay, bx, by, cx, cy; + gint xdx, xdy, ydx, ydy; + gint xx, xy, yx, yy; + gint i, j; + gdouble zoom, theta, r; + + PnColor *src, *dest; + + g_return_if_fail (roto_zoom != NULL); + g_return_if_fail (PN_IS_ROTO_ZOOM (roto_zoom)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + + width = pn_image_get_width (image); + height = pn_image_get_height (image); + stride = pn_image_get_pitch (image) >> 2; + src = pn_image_get_image_buffer (image); + dest = pn_image_get_transform_buffer (image); + + /* set up the volume in-script variable */ + PN_VARIABLE_VALUE (roto_zoom->volume_var) = pn_audio_data_get_volume (audio_data); + + /* run the frame scipt */ + pn_script_execute (roto_zoom->frame_script); + + /* get the in-script variable values */ + zoom = PN_VARIABLE_VALUE (roto_zoom->zoom_var); + theta = PN_VARIABLE_VALUE (roto_zoom->theta_var); + + if (zoom == 0.0) + return; + + r = G_SQRT2 / zoom; + + ax = r * cos ((G_PI * .75) + theta); + ay = r * sin ((G_PI * .75) + theta); + bx = r * cos ((G_PI * .25) + theta); + by = r * sin ((G_PI * .25) + theta); + cx = r * cos ((G_PI * 1.25) + theta); + cy = r * sin ((G_PI * 1.25) + theta); + +/* fprintf (stderr, "ax: %f, ay: %f\n", ax, ay); */ +/* fprintf (stderr, "bx: %f, by: %f\n", bx, by); */ +/* fprintf (stderr, "cx: %f, cy: %f\n", cx, cy); */ + + ax = ((width-1)<<8) * ((ax + 1) * .5); + ay = ((height-1)<<8) * ((-ay + 1) * .5); + bx = ((width-1)<<8) * ((bx + 1) * .5); + by = ((height-1)<<8) * ((-by + 1) * .5); + cx = ((width-1)<<8) * ((cx + 1) * .5); + cy = ((height-1)<<8) * ((-cy + 1) * .5); + +/* fprintf (stderr, "ax': %f, ay': %f\n", ax, ay); */ +/* fprintf (stderr, "bx': %f, by': %f\n", bx, by); */ +/* fprintf (stderr, "cx': %f, cy': %f\n", cx, cy); */ + + xdx = (bx - ax) / (width-1); + xdy = (by - ay) / (width-1); + ydx = (cx - ax) / (height-1); + ydy = (cy - ay) / (height-1); + +/* fprintf (stderr, "xdx: %i, xdy: %i\n", xdx, xdy); */ +/* fprintf (stderr, "ydx: %i, ydy: %i\n", ydx, ydy); */ + + yx = ax; + yy = ay; + + for (j=0; j<height; j++) + { + while (yx < 0) yx += width<<8; + while (yy < 0) yy += height<<8; + while (yx >= width<<8) yx -= width<<8; + while (yy >= height<<8) yy -= height<<8; + + xx = yx; + xy = yy; + + for (i=0; i<width; i++) + { + guint r, g, b, offset; + guint xfrac, yfrac; + + while (xx < 0) xx += width<<8; + while (xy < 0) xy += height<<8; + while (xx >= width<<8) xx -= width<<8; + while (xy >= height<<8) xy -= height<<8; + + offset = (xy >> 8) * stride + (xx >> 8); + xfrac = xx & 0xff; + yfrac = xy & 0xff; + + r = src[offset].red * (256 - xfrac) * (256 - yfrac); + g = src[offset].green * (256 - xfrac) * (256 - yfrac); + b = src[offset].blue * (256 - xfrac) * (256 - yfrac); + + if (xx >> 8 < width-1) + { + r += src[offset+1].red * xfrac * (256 - yfrac); + g += src[offset+1].green * xfrac * (256 - yfrac); + b += src[offset+1].blue * xfrac * (256 - yfrac); + } + else + { + r += src[(xy>>8) * stride].red * xfrac * (256 - yfrac); + g += src[(xy>>8) * stride].green * xfrac * (256 - yfrac); + b += src[(xy>>8) * stride].blue * xfrac * (256 - yfrac); + } + + if (xy >> 8 < height-1) + { + r += src[offset+stride].red * (256 - xfrac) * yfrac; + g += src[offset+stride].green * (256 - xfrac) * yfrac; + b += src[offset+stride].blue * (256 - xfrac) * yfrac; + } + else + { + r += src[xx>>8].red * (256 - xfrac) * yfrac; + g += src[xx>>8].green * (256 - xfrac) * yfrac; + b += src[xx>>8].blue * (256 - xfrac) * yfrac; + } + + if (xx >> 8 < width-1 && xy >> 8 < height-1) + { + r += src[offset+stride+1].red * xfrac * yfrac; + g += src[offset+stride+1].green * xfrac * yfrac; + b += src[offset+stride+1].blue * xfrac * yfrac; + } + else + { + r += src[0].red * xfrac * yfrac; + g += src[0].green * xfrac * yfrac; + b += src[0].blue * xfrac * yfrac; + } + + dest[j * stride + i].red = r >> 16; + dest[j * stride + i].green = g >> 16; + dest[j * stride + i].blue = b >> 16; + + xx += xdx; + xy += xdy; + } + + yx += ydx; + yy += ydy; + } + +/* fprintf (stderr, "xx: %i, xy: %i\n", xx, xy); */ + + pn_image_apply_transform (image); + + if (PN_ACTUATOR_CLASS (parent_class)->execute != NULL) + PN_ACTUATOR_CLASS (parent_class)->execute (PN_ACTUATOR (roto_zoom), image, audio_data); +} + +PnRotoZoom* +pn_roto_zoom_new (void) +{ + return (PnRotoZoom *) g_object_new (PN_TYPE_ROTO_ZOOM, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnrotozoom.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,70 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_ROTO_ZOOM_H__ +#define __PN_ROTO_ZOOM_H__ + +#include "pnactuator.h" +#include "pnscript.h" +#include "pnsymboltable.h" + +G_BEGIN_DECLS + + +enum +{ + PN_ROTO_ZOOM_OPT_INIT_SCRIPT = PN_ACTUATOR_OPT_LAST, + PN_ROTO_ZOOM_OPT_FRAME_SCRIPT, + PN_ROTO_ZOOM_OPT_LAST +}; + +#define PN_TYPE_ROTO_ZOOM (pn_roto_zoom_get_type ()) +#define PN_ROTO_ZOOM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_ROTO_ZOOM, PnRotoZoom)) +#define PN_ROTO_ZOOM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_ROTO_ZOOM, PnRotoZoomClass)) +#define PN_IS_ROTO_ZOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_ROTO_ZOOM)) +#define PN_IS_ROTO_ZOOM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_ROTO_ZOOM)) +#define PN_ROTO_ZOOM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_ROTO_ZOOM, PnRotoZoomClass)) + +typedef struct _PnRotoZoom PnRotoZoom; +typedef struct _PnRotoZoomClass PnRotoZoomClass; + +struct _PnRotoZoom +{ + PnActuator parent; + + /* The script objects */ + PnScript *init_script; + PnScript *frame_script; + PnSymbolTable *symbol_table; + + /* The in-script variables */ + PnVariable *zoom_var; + PnVariable *theta_var; + PnVariable *volume_var; +}; + +struct _PnRotoZoomClass +{ + PnActuatorClass parent_class; +}; + +/* Creators */ +GType pn_roto_zoom_get_type (void); +PnRotoZoom *pn_roto_zoom_new (void); + +#endif /* __PN_ROTO_ZOOM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnscope.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,316 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <math.h> +#include <glib.h> +#include "pnscope.h" +#include "pnlistoption.h" +#include "pnstringoption.h" + +enum +{ + PN_SCOPE_DRAW_METHOD_DOTS = 0, + PN_SCOPE_DRAW_METHOD_LINES +}; + +static void pn_scope_class_init (PnScopeClass *class); +static void pn_scope_init (PnScope *scope, + PnScopeClass *class); +/* PnObject signals */ +static void pn_scope_destroy (PnObject *object); + +/* PnActuator methods */ +static void pn_scope_prepare (PnScope *scope, + PnImage *image); +static void pn_scope_execute (PnScope *scope, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_scope_get_type (void) +{ + static GType scope_type = 0; + + if (! scope_type) + { + static const GTypeInfo scope_info = + { + sizeof (PnScopeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_scope_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnScope), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_scope_init + }; + + /* FIXME: should this be dynamic? */ + scope_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnScope", + &scope_info, + 0); + } + return scope_type; +} + +static void +pn_scope_class_init (PnScopeClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnObject signals */ + object_class->destroy = pn_scope_destroy; + + /* PnActuator methods */ + actuator_class->prepare = (PnActuatorPrepFunc) pn_scope_prepare; + actuator_class->execute = (PnActuatorExecFunc) pn_scope_execute; +} + +static void +pn_scope_init (PnScope *scope, PnScopeClass *class) +{ + PnListOption *draw_method_opt; + PnStringOption *init_script_opt; + PnStringOption *frame_script_opt; + PnStringOption *sample_script_opt; + + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (scope), "Render.Scope"); + pn_user_object_set_description (PN_USER_OBJECT (scope), + "A test scope actuator"); + + /* Set up the options */ + draw_method_opt = pn_list_option_new ("draw_method", "The way the points will be drawn"); + init_script_opt = pn_string_option_new ("init_script", "The initialization script"); + frame_script_opt = pn_string_option_new ("frame_script", "The per-frame script"); + sample_script_opt = pn_string_option_new ("sample_script", "The per-sample script"); + + pn_list_option_add_item (draw_method_opt, "Dots"); + pn_list_option_add_item (draw_method_opt, "Lines"); + + pn_actuator_add_option (PN_ACTUATOR (scope), PN_OPTION (draw_method_opt)); + pn_actuator_add_option (PN_ACTUATOR (scope), PN_OPTION (init_script_opt)); + pn_actuator_add_option (PN_ACTUATOR (scope), PN_OPTION (frame_script_opt)); + pn_actuator_add_option (PN_ACTUATOR (scope), PN_OPTION (sample_script_opt)); + + /* Create the script objects and symbol table */ + scope->init_script = pn_script_new (); + pn_object_ref (PN_OBJECT (scope->init_script)); + pn_object_sink (PN_OBJECT (scope->init_script)); + scope->frame_script = pn_script_new (); + pn_object_ref (PN_OBJECT (scope->frame_script)); + pn_object_sink (PN_OBJECT (scope->frame_script)); + scope->sample_script = pn_script_new (); + pn_object_ref (PN_OBJECT (scope->sample_script)); + pn_object_sink (PN_OBJECT (scope->sample_script)); + scope->symbol_table = pn_symbol_table_new (); + pn_object_ref (PN_OBJECT (scope->symbol_table)); + pn_object_sink (PN_OBJECT (scope->symbol_table)); + + /* Get the variables from the symbol table */ + scope->samples_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "samples"); + scope->width_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "width"); + scope->height_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "height"); + scope->x_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "x"); + scope->y_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "y"); + scope->iteration_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "iteration"); + scope->value_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "value"); + scope->red_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "red"); + scope->green_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "green"); + scope->blue_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "blue"); + scope->volume_var = pn_symbol_table_ref_variable_by_name (scope->symbol_table, "volume"); + + PN_VARIABLE_VALUE (scope->samples_var) = 0.0; + PN_VARIABLE_VALUE (scope->red_var) = 1.0; + PN_VARIABLE_VALUE (scope->green_var) = 1.0; + PN_VARIABLE_VALUE (scope->blue_var) = 1.0; +} + +static void +pn_scope_destroy (PnObject *object) +{ + PnScope *scope; + + scope = (PnScope *) object; + + pn_object_unref (PN_OBJECT (scope->init_script)); + pn_object_unref (PN_OBJECT (scope->frame_script)); + pn_object_unref (PN_OBJECT (scope->sample_script)); + pn_object_unref (PN_OBJECT (scope->symbol_table)); +} + +static void +pn_scope_prepare (PnScope *scope, PnImage *image) +{ + PnStringOption *init_script_opt; + PnStringOption *frame_script_opt; + PnStringOption *sample_script_opt; + + g_return_if_fail (scope != NULL); + g_return_if_fail (PN_IS_SCOPE (scope)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + /* Parse the script strings */ + init_script_opt = (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (scope), + PN_SCOPE_OPT_INIT_SCRIPT); + frame_script_opt = (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (scope), + PN_SCOPE_OPT_FRAME_SCRIPT); + sample_script_opt = (PnStringOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (scope), + PN_SCOPE_OPT_SAMPLE_SCRIPT); + + pn_script_parse_string (scope->init_script, + scope->symbol_table, + pn_string_option_get_value (init_script_opt)); + pn_script_parse_string (scope->frame_script, + scope->symbol_table, + pn_string_option_get_value (frame_script_opt)); + pn_script_parse_string (scope->sample_script, + scope->symbol_table, + pn_string_option_get_value (sample_script_opt)); + + /* Set up the width and height in-script variables */ + PN_VARIABLE_VALUE (scope->width_var) = pn_image_get_width (image); + PN_VARIABLE_VALUE (scope->height_var) = pn_image_get_height (image); + + /* Run the init script */ + pn_script_execute (scope->init_script); + + if (parent_class->prepare) + parent_class->prepare (PN_ACTUATOR (scope), image); +} + +static void +pn_scope_execute (PnScope *scope, PnImage *image, PnAudioData *audio_data) +{ + gdouble i, samples; + gdouble half_width, neg_half_height, increment = 0.0; + PnColor color = { 255, 255, 255 }; + guint last_x = 0, last_y = 0, x, y; + PnListOption *draw_method_opt; + gboolean use_lines; + + g_return_if_fail (scope != NULL); + g_return_if_fail (PN_IS_SCOPE (scope)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); + g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); + + half_width = (((gdouble) pn_image_get_width (image)) - 1.0) * 0.5; + neg_half_height = (((gdouble) pn_image_get_height (image)) - 1.0) * -0.5; + + draw_method_opt = (PnListOption *) pn_actuator_get_option_by_index (PN_ACTUATOR (scope), + PN_SCOPE_OPT_DRAW_METHOD); + use_lines = pn_list_option_get_index (draw_method_opt) == PN_SCOPE_DRAW_METHOD_LINES; + + /* Set the volume in-script variable */ + PN_VARIABLE_VALUE (scope->volume_var) = pn_audio_data_get_volume (audio_data); + + /* Run the frame script */ + pn_script_execute (scope->frame_script); + + /* Go through and draw each sample-point */ + samples = PN_VARIABLE_VALUE (scope->samples_var); + if (samples > 1) + { + increment = 1 / (samples - 1); + PN_VARIABLE_VALUE (scope->iteration_var) = -increment; + } + else if (samples > 0) + { + increment = 0; + PN_VARIABLE_VALUE (scope->iteration_var) = 0.0; + } + for (i=0; i < samples; i++) + { + /* Set up the in-script variables */ + PN_VARIABLE_VALUE (scope->x_var) = 2.0; + PN_VARIABLE_VALUE (scope->y_var) = 2.0; + PN_VARIABLE_VALUE (scope->iteration_var) += increment; + + /* FIXME: This should be done in PnAudioData */ + /* Interpolate the sample value */ + { + gdouble sample, bias; + guint lsamp, usamp; + + sample = (gdouble)PN_AUDIO_DATA_PCM_SAMPLES(audio_data) + * (gdouble)PN_VARIABLE_VALUE (scope->iteration_var); + + lsamp = (guint) sample; + if (lsamp != sample) + { + usamp = lsamp + 1; + + bias = sample - (gdouble) lsamp; + + PN_VARIABLE_VALUE (scope->value_var) = + (PN_AUDIO_DATA_PCM_DATA(audio_data, PN_CHANNEL_LEFT)[lsamp] * (1 - bias)) + + (PN_AUDIO_DATA_PCM_DATA(audio_data, PN_CHANNEL_LEFT)[lsamp] * bias); + } + else + PN_VARIABLE_VALUE (scope->value_var) = + PN_AUDIO_DATA_PCM_DATA (audio_data, PN_CHANNEL_LEFT)[lsamp]; + } + + /* Run the sample script */ + pn_script_execute (scope->sample_script); + + /* Get the color */ + color.red = CLAMP (PN_VARIABLE_VALUE (scope->red_var), 0.0, 1.0) * 255.0; + color.green = CLAMP (PN_VARIABLE_VALUE (scope->green_var), 0.0, 1.0) * 255.0; + color.blue = CLAMP (PN_VARIABLE_VALUE (scope->blue_var), 0.0, 1.0) * 255.0; + + /* Render the point */ + x = rint ((PN_VARIABLE_VALUE (scope->x_var) + 1.0) * ((gdouble) half_width )); + y = rint ((PN_VARIABLE_VALUE (scope->y_var) - 1.0) * ((gdouble) neg_half_height)); + + if (use_lines) + { + if (i > 0) + pn_image_render_line (image, last_x, last_y, x, y, color); + + last_x = x; + last_y = y; + } + else + pn_image_render_pixel (image, x, y, color); + } + + if (parent_class->execute) + parent_class->execute (PN_ACTUATOR (scope), image, audio_data); +} + +PnScope* +pn_scope_new (void) +{ + return (PnScope *) g_object_new (PN_TYPE_SCOPE, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnscope.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,86 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_SCOPE_H__ +#define __PN_SCOPE_H__ + +#include "pnactuator.h" +#include "pnscript.h" +#include "pnsymboltable.h" + + +G_BEGIN_DECLS + + +enum +{ + PN_SCOPE_OPT_DRAW_METHOD = PN_ACTUATOR_OPT_LAST, + PN_SCOPE_OPT_INIT_SCRIPT, + PN_SCOPE_OPT_FRAME_SCRIPT, + PN_SCOPE_OPT_SAMPLE_SCRIPT, + PN_SCOPE_OPT_LAST +}; + +#define PN_TYPE_SCOPE (pn_scope_get_type ()) +#define PN_SCOPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_SCOPE, PnScope)) +#define PN_SCOPE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_SCOPE, PnScopeClass)) +#define PN_IS_SCOPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_SCOPE)) +#define PN_IS_SCOPE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_SCOPE)) +#define PN_SCOPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_SCOPE, PnScopeClass)) + +typedef struct _PnScope PnScope; +typedef struct _PnScopeClass PnScopeClass; + +struct _PnScope +{ + PnActuator parent; + + /* The script objects */ + PnScript *init_script; + PnScript *frame_script; + PnScript *sample_script; + PnSymbolTable *symbol_table; + + /* The in-script variables */ + PnVariable *samples_var; + PnVariable *width_var; + PnVariable *height_var; + PnVariable *x_var; + PnVariable *y_var; + PnVariable *iteration_var; + PnVariable *value_var; + PnVariable *red_var; + PnVariable *green_var; + PnVariable *blue_var; + PnVariable *volume_var; +}; + +struct _PnScopeClass +{ + PnActuatorClass parent_class; +}; + +/* Creators */ +GType pn_scope_get_type (void); +PnScope *pn_scope_new (void); + + + + + +#endif /* __PN_SCOPE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnscript.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,278 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <math.h> +#include "pnscript.h" + +/* Initialization */ +static void pn_script_class_init (PnScriptClass *class); + +/* Internal parser */ +gboolean pn_script_internal_parse_string (PnScript *script, + const gchar *string); + +static GObjectClass *parent_class = NULL; + +GType +pn_script_get_type (void) +{ + static GType script_type = 0; + + if (! script_type) + { + static const GTypeInfo script_info = + { + sizeof (PnScriptClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_script_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnScript), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + + /* FIXME: should this be dynamic? */ + script_type = g_type_register_static (PN_TYPE_OBJECT, + "PnScript", + &script_info, + 0); + } + return script_type; +} + +static void +pn_script_class_init (PnScriptClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + + parent_class = g_type_class_peek_parent (class); +} + +static void +pn_script_unref_variables (PnScript *script) +{ + g_return_if_fail (script != NULL); + g_return_if_fail (PN_IS_SCRIPT (script)); + + if (script->code && script->symbol_table) + { + guint *op; + + for (op = script->code; *op != PN_OP_END; op++) + switch (*op) + { + case PN_OP_PUSHC: + op++; + break; + + case PN_OP_PUSHV: + pn_symbol_table_unref_variable (script->symbol_table, PN_VARIABLE (*(++op))); + break; + + case PN_OP_SET: + pn_symbol_table_unref_variable (script->symbol_table, PN_VARIABLE (*(++op))); + break; + } + } +} + +/** + * pn_script_new + * + * Creates a new #PnScript object. + * + * Returns: The newly created #PnScript object + */ +PnScript* +pn_script_new (void) +{ + return (PnScript *) g_object_new (PN_TYPE_SCRIPT, NULL); +} + +/** + * pn_script_parse_string + * @script: A #PnScript + * @symbol_table: the #PnSymbolTable to associate with the script + * @string: a string containing the script + * + * Parses a script, compiling it to a bytecode that is stored within the script object. + * All in-script variables within the script are added to the specified symbol table (if + * they are not already in it). If errors are encountered while parsing the script, + * they are output using pn_error(). + * + * Returns: %TRUE on success; %FALSE otherwise + */ +gboolean +pn_script_parse_string (PnScript *script, PnSymbolTable *symbol_table, const gchar *string) +{ + g_return_val_if_fail (script != NULL, FALSE); + g_return_val_if_fail (PN_IS_SCRIPT (script), FALSE); + g_return_val_if_fail (symbol_table != NULL, FALSE); + g_return_val_if_fail (PN_IS_SYMBOL_TABLE (symbol_table), FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + /* Make sure if it's the same symbol table, we don't destroy it */ + pn_object_ref (PN_OBJECT (symbol_table)); + pn_object_sink (PN_OBJECT (symbol_table)); + + /* get rid of the old script */ + if (script->symbol_table) + { + pn_script_unref_variables (script); + pn_object_unref (PN_OBJECT (script->symbol_table)); + } + if (script->stack) + { + g_free (script->stack); + script->stack = NULL; + } + if (script->code) + { + g_free (script->code); + script->code = NULL; + } + if (script->constant_table) + { + g_free (script->constant_table); + script->constant_table = NULL; + } + + /* Set our new symbol table */ + script->symbol_table = symbol_table; + + return pn_script_internal_parse_string (script, string); +} + +/** + * pn_script_execute + * @script: a #PnScript + * + * Executes a script, updating all variabes in the associated symbol + * table as the script dictates. + */ +void +pn_script_execute (PnScript *script) +{ + guint *op; + gdouble stack[64]; + guint stack_top = 0; + + g_return_if_fail (script != NULL); + g_return_if_fail (PN_IS_SCRIPT (script)); + + if (! script->code) + return; + + for (op = script->code; *op != PN_OP_END; op++) + switch (*op) + { +#define PUSH(f) stack[stack_top++] = f; +#define POP stack_top--; +#define POPV (stack[--stack_top]) +#define PEEK (stack[stack_top-1]) +#define PEEKN(n) (stack[stack_top-n]) + case PN_OP_PUSHC: + case PN_OP_PUSHV: + PUSH (* (gdouble *)(*(++op))); + break; + + case PN_OP_POP: + POP; + break; + + case PN_OP_SET: + *(gdouble *)(*(++op)) = PEEK; + break; + + case PN_OP_ADD: + PEEKN (2) += POPV; + break; + + case PN_OP_SUB: + PEEKN (2) -= POPV; + break; + + case PN_OP_MUL: + PEEKN (2) *= POPV; + break; + + case PN_OP_DIV: + if (PEEK != 0) + PEEKN (2) /= PEEK; + else + PEEK = 0; + POP; + break; + + case PN_OP_NEG: + PEEK = -PEEK; + break; + + case PN_OP_POW: + PEEKN (2) = pow (PEEKN (2), PEEK); + POP; + break; + + case PN_OP_ABS: + PEEK = ABS (PEEK); + break; + + case PN_OP_MAX: + PEEKN (2) = MAX (PEEK, PEEKN (2)); + POP; + break; + + case PN_OP_MIN: + PEEKN (2) = MIN (PEEK, PEEKN (2)); + POP; + break; + + case PN_OP_SIN: + PEEK = sin (PEEK); + break; + + case PN_OP_COS: + PEEK = cos (PEEK); + break; + + case PN_OP_TAN: + PEEK = tan (PEEK); + break; + + case PN_OP_ASIN: + PEEK = asin (PEEK); + break; + + case PN_OP_ACOS: + PEEK = acos (PEEK); + break; + + case PN_OP_ATAN: + PEEK = atan (PEEK); + break; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnscript.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,102 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_SCRIPT_H__ +#define __PN_SCRIPT_H__ + +#include "pnobject.h" +#include "pnsymboltable.h" + + +G_BEGIN_DECLS + + +/* Opcodes */ +enum +{ + PN_OP_NOP, + PN_OP_END, + PN_OP_PUSHV, /* Push a variable */ + PN_OP_PUSHC, /* Push a constant */ + PN_OP_POP, + PN_OP_SET, + /* Arithmetic operators */ + PN_OP_ADD, + PN_OP_SUB, + PN_OP_MUL, + PN_OP_DIV, + PN_OP_NEG, + PN_OP_POW, + /* Functions */ + PN_OP_ABS, + PN_OP_MAX, + PN_OP_MIN, + PN_OP_SIN, + PN_OP_COS, + PN_OP_TAN, + PN_OP_ASIN, + PN_OP_ACOS, + PN_OP_ATAN, + PN_OP_LAST +}; + +#define PN_TYPE_SCRIPT (pn_script_get_type ()) +#define PN_SCRIPT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_SCRIPT, PnScript)) +#define PN_SCRIPT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_SCRIPT, PnScriptClass)) +#define PN_IS_SCRIPT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_SCRIPT)) +#define PN_IS_SCRIPT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_SCRIPT)) +#define PN_SCRIPT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_SCRIPT, PnScriptClass)) +#define PN_SCRIPT_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +#define PN_SCRIPT_CLASS_NAME(class) (g_type_name (PN_SCRIPT_CLASS_TYPE (class))) + +typedef struct _PnScript PnScript; +typedef struct _PnScriptClass PnScriptClass; + +struct _PnScript +{ + PnObject parent; + + /* The symbol table that is being used by the current code */ + PnSymbolTable *symbol_table; + + /* The table of constants used by the script */ + gdouble *constant_table; + + /* The byte-compiled code */ + guint32 *code; + + /* The script stack used during script execution */ + gdouble *stack; +}; + +struct _PnScriptClass +{ + PnObjectClass parent_class; +}; + +/* Creators */ +GType pn_script_get_type (void); +PnScript *pn_script_new (void); + +/* Actions */ +gboolean pn_script_parse_string (PnScript *script, + PnSymbolTable *symbol_table, + const gchar *string); +void pn_script_execute (PnScript *script); + +#endif /* __PN_SCRIPT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnscriptparser.y Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,551 @@ +%{ +#define yymaxdepth pn_script_parser_maxdepth +#define yyparse pn_script_parser_parse +#define yylex pn_script_parser_lex +#define yyerror pn_script_parser_error +#define yylval pn_script_parser_lval +#define yychar pn_script_parser_char +#define yydebug pn_script_parser_debug +#define yypact pn_script_parser_pact +#define yyr1 pn_script_parser_r1 +#define yyr2 pn_script_parser_r2 +#define yydef pn_script_parser_def +#define yychk pn_script_parser_chk +#define yypgo pn_script_parser_pgo +#define yyact pn_script_parser_act +#define yyexca pn_script_parser_exca +#define yyerrflag pn_script_parser_errflag +#define ynerrs pn_script_parser_nerrs +#define yyps pn_script_parser_ps +#define yypv pn_script_parser_pv +#define yys pn_script_parser_s +#define yy_yys pn_script_parser_yys +#define yystate pn_script_parser_state +#define yytmp pn_script_parser_tmp +#define yyv pn_script_parser_v +#define yy_yyv pn_script_parser_yyv +#define yyval pn_script_parser_val +#define yylloc pn_script_parser_lloc +#define yyreds pn_script_parser_reds +#define yytoks pn_script_parser_toks +#define yylhs pn_script_parser_yylhs +#define yylen pn_script_parser_yylen +#define yydefred pn_script_parser_yydefred +#define yydgoto pn_script_parser_yydgoto +#define yysindex pn_script_parser_yysindex +#define yyrindex pn_script_parser_yyrindex +#define yygindex pn_script_parser_yygindex +#define yytable pn_script_parser_yytable +#define yycheck pn_script_parser_yycheck +#define yyname pn_script_parser_yyname +#define yyrule pn_script_parser_yyrule + +#include <ctype.h> +#include <stdlib.h> +#include <glib.h> +#include <pn/pnscript.h> + +/* define this to dump the parser output to stdout */ +/* #define PN_PRINT_OPS 1 */ + +int yyerror (char *s); +int yylex (void); + +static gboolean parse_failed; + +/* Are we on the size-determining pass? */ +static gboolean size_pass; + +/* Used during the size pass to determine the size of the constant table */ +static GArray *temp_constant_table = NULL; + +/* The code size */ +static guint code_size; + +/* The current code byte */ +static guint *code_ptr; + +/* Input variables used during parsing */ +static PnScript *parse_script; +static const gchar *parse_string; +%} + +%union { + gdouble *constant; + PnVariable *variable; +} + +%token <constant> CONSTANT +%token <variable> VARIABLE +/* Functions */ +%token ABS_FUNC +%token MAX_FUNC +%token MIN_FUNC +%token SIN_FUNC +%token COS_FUNC +%token TAN_FUNC +%token ASIN_FUNC +%token ACOS_FUNC +%token ATAN_FUNC + + +%right '=' +%left '-' '+' +%left '*' '/' +%left NEG +%right '^' + +%% + +script + : /* empty */ + | script statement + ; + +statement + : equation ';' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_POP; + +#ifdef PN_PRINT_OPS + g_print ("POP\n"); +#endif /* PN_PRINT_OPS */ + } + } + ; + +equation + : VARIABLE '=' expression + { + if (size_pass) + code_size += sizeof (guint) + sizeof (gdouble *); + else + { + *code_ptr++ = PN_OP_SET; + *code_ptr++ = (guint) $1; + +#ifdef PN_PRINT_OPS + g_print ("SET %s\n", $1->name); +#endif /* PN_PRINT_OPS */ + } + } + +expression + : CONSTANT + { + if (size_pass) + code_size += sizeof (guint) + sizeof (gdouble *); + else + { + *code_ptr++ = PN_OP_PUSHC; + *code_ptr++ = GPOINTER_TO_UINT ($1); + +#ifdef PN_PRINT_OPS + g_print ("PUSHC %f\n", *$1); +#endif /* PN_PRINT_OPS */ + } + } + | VARIABLE + { + if (size_pass) + code_size += sizeof (guint) + sizeof (gdouble *); + else + { + *code_ptr++ = PN_OP_PUSHV; + *code_ptr++ = (guint) $1; + +#ifdef PN_PRINT_OPS + g_print ("PUSHV %s\n", $1->name); +#endif /* PN_PRINT_OPS */ + } + } + | equation + | ABS_FUNC '(' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_ABS; +#ifdef PN_PRINT_OPS + g_print ("ABS\n"); +#endif /* PN_PRINT_OPS */ + } + } + | MAX_FUNC '(' expression ',' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_MAX; +#ifdef PN_PRINT_OPS + g_print ("MAX\n"); +#endif /* PN_PRINT_OPS */ + } + } + | MIN_FUNC '(' expression ',' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_MIN; + +#ifdef PN_PRINT_OPS + g_print ("MIN\n"); +#endif /* PN_PRINT_OPS */ + } + + } + | SIN_FUNC '(' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_SIN; + +#ifdef PN_PRINT_OPS + g_print ("SIN\n"); +#endif /* PN_PRINT_OPS */ + } + + } + | COS_FUNC '(' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_COS; + +#ifdef PN_PRINT_OPS + g_print ("COS\n"); +#endif /* PN_PRINT_OPS */ + } + + } + | TAN_FUNC '(' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_TAN; + +#ifdef PN_PRINT_OPS + g_print ("TAN\n"); +#endif /* PN_PRINT_OPS */ + } + + } + | ASIN_FUNC '(' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_ASIN; + +#ifdef PN_PRINT_OPS + g_print ("ASIN\n"); +#endif /* PN_PRINT_OPS */ + } + + } + | ACOS_FUNC '(' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_ACOS; + +#ifdef PN_PRINT_OPS + g_print ("ACOS\n"); +#endif /* PN_PRINT_OPS */ + } + + } + | ATAN_FUNC '(' expression ')' + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_ATAN; + +#ifdef PN_PRINT_OPS + g_print ("ATAN\n"); +#endif /* PN_PRINT_OPS */ + } + + } + | expression '+' expression + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_ADD; + +#ifdef PN_PRINT_OPS + g_print ("ADD\n"); +#endif /* PN_PRINT_OPS */ + } + } + | expression '-' expression + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_SUB; +#ifdef PN_PRINT_OPS + g_print ("SUB\n"); +#endif /* PN_PRINT_OPS */ + } + } + | expression '*' expression + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_MUL; + +#ifdef PN_PRINT_OPS + g_print ("MUL\n"); +#endif /* PN_PRINT_OPS */ + } + } + | expression '/' expression + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_DIV; + +#ifdef PN_PRINT_OPS + g_print ("DIV\n"); +#endif /* PN_PRINT_OPS */ + } + } + | '-' expression %prec NEG + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_NEG; + +#ifdef PN_PRINT_OPS + g_print ("NEG\n"); +#endif /* PN_PRINT_OPS */ + } + } + | expression '^' expression + { + if (size_pass) + code_size += sizeof (guint); + else + { + *code_ptr++ = PN_OP_POW; + +#ifdef PN_PRINT_OPS + g_print ("POW\n"); +#endif /* PN_PRINT_OPS */ + } + } + | '(' expression ')' + ; + +%% + +static gdouble +get_named_constant_value (const gchar *name) +{ + if (g_strcasecmp (name, "pi") == 0) + return G_PI; + + /* This is a failure, so don't make a "zero" :) */ + return 0.0; +} + +static guint +get_function_token_type (const gchar *name) +{ + if (g_strcasecmp (name, "abs") == 0) + return ABS_FUNC; + if (g_strcasecmp (name, "max") == 0) + return MAX_FUNC; + if (g_strcasecmp (name, "min") == 0) + return MIN_FUNC; + if (g_strcasecmp (name, "sin") == 0) + return SIN_FUNC; + if (g_strcasecmp (name, "cos") == 0) + return COS_FUNC; + if (g_strcasecmp (name, "tan") == 0) + return TAN_FUNC; + if (g_strcasecmp (name, "asin") == 0) + return ASIN_FUNC; + if (g_strcasecmp (name, "acos") == 0) + return ACOS_FUNC; + if (g_strcasecmp (name, "atan") == 0) + return ATAN_FUNC; + + return 0; +} + +static gdouble* +get_constant_ptr (gdouble value) +{ + guint i; + + if (size_pass) + { + for (i=0; i<temp_constant_table->len; i++) + if (g_array_index (temp_constant_table, gdouble, i) == value) + return (gdouble *) TRUE; + + /* Add a constant */ + g_array_append_val (temp_constant_table, value); + return (gdouble *) TRUE; + } + else + { + for (i=0; i<temp_constant_table->len; i++) + if (parse_script->constant_table[i] == value) + return &parse_script->constant_table[i]; + + return NULL; /* This should never be reached */ + } +} + +int +yylex (void) +{ + /* Skip whitespaces */ + while (isspace (*parse_string)) parse_string++; + + /* Handle the end of the string */ + if (*parse_string == '\0') + return 0; + + /* Handle unnamed (numeric) constants */ + if (*parse_string == '.' || isdigit (*parse_string)) + { + gdouble value; + + value = strtod (parse_string, (char **) &parse_string); + yylval.constant = get_constant_ptr (value); + + return CONSTANT; + } + + /* Handle alphanumeric symbols */ + if (isalpha (*parse_string)) + { + const gchar *symbol_start = parse_string; + guint function_token; + gchar *symbol_name; + + while (isalnum (*parse_string) || *parse_string == '_') parse_string++; + + symbol_name = g_strndup (symbol_start, parse_string - symbol_start); + + /* Handle a named constant (e.g. 'pi') */ + if (get_named_constant_value (symbol_name)) + { + yylval.constant = get_constant_ptr (get_named_constant_value (symbol_name)); + + g_free (symbol_name); + + return CONSTANT; + } + + /* Handle a function (e.g. 'max') */ + if ((function_token = get_function_token_type (symbol_name))) + { + g_free (symbol_name); + + return function_token; + } + + /* Handle a variable */ + if (! size_pass) + yylval.variable = pn_symbol_table_ref_variable_by_name (parse_script->symbol_table, + symbol_name); + + g_free (symbol_name); + + return VARIABLE; + } + + /* Handle a single-character symbol (or invalid tokens) */ + return *parse_string++; +} + +int +yyerror (char *s) +{ + parse_failed = TRUE; + + return 0; +} + +gboolean +pn_script_internal_parse_string (PnScript *script, const gchar *string) +{ + guint i; + + g_return_val_if_fail (script != NULL, FALSE); + g_return_val_if_fail (PN_IS_SCRIPT (script), FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + /* Make a new temp constant table if needed */ + if (! temp_constant_table) + temp_constant_table = g_array_new (FALSE, FALSE, sizeof (gdouble)); + + parse_failed = FALSE; + + parse_script = script; + parse_string = string; + + /* First determine the code size */ + size_pass = TRUE; + code_size = 0; + yyparse (); + + if (parse_failed) + return FALSE; + + if (code_size == 0) + return TRUE; + + /* Now generate the real code */ + size_pass = FALSE; + parse_string = string; + script->code = g_malloc (code_size); + script->constant_table = g_malloc (temp_constant_table->len * sizeof (gdouble)); + for (i=0; i<temp_constant_table->len; i++) + script->constant_table[i] = g_array_index (temp_constant_table, gdouble, i); + code_ptr = script->code; + yyparse (); + g_array_set_size (temp_constant_table, 0); + + /* Terminate the script, replacing the last POP with an END */ + *(code_ptr-1) = PN_OP_END; + +#ifdef PN_PRINT_OPS + g_print ("END\n"); +#endif /* PN_PRINT_OPS */ + + return TRUE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnstringoption.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,185 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <ctype.h> +#include <glib.h> +#include "pnstringoption.h" +#include "pnxml.h" +#include "pnerror.h" + +static void pn_string_option_class_init (PnStringOptionClass *class); +static void pn_string_option_init (PnStringOption *string_option, + PnStringOptionClass *class); + +/* PnUserObject methods */ +static void pn_string_option_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_string_option_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static PnUserObjectClass *parent_class = NULL; +static gchar * const empty_string = ""; + +GType +pn_string_option_get_type (void) +{ + static GType string_option_type = 0; + + if (! string_option_type) + { + static const GTypeInfo string_option_info = + { + sizeof (PnStringOptionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_string_option_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnStringOption), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_string_option_init + }; + + /* FIXME: should this be dynamic? */ + string_option_type = g_type_register_static (PN_TYPE_OPTION, + "PnStringOption", + &string_option_info, + 0); + } + return string_option_type; +} + +static void +pn_string_option_class_init (PnStringOptionClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnOptionClass *option_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + option_class = (PnOptionClass *) class; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_string_option_save_thyself; + user_object_class->load_thyself = pn_string_option_load_thyself; + + /* PnOption methods */ + /* FIXME: this needs to be uncommented when the widget is done */ +/* option_class->widget_type = PN_TYPE_STRING_OPTION_WIDGET; */ +} + +static void +pn_string_option_init (PnStringOption *string_option, PnStringOptionClass *class) +{ + string_option->value = empty_string; +} + +static void +pn_string_option_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnStringOption *string_option; + xmlNodePtr value_node; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_STRING_OPTION (user_object)); + g_return_if_fail (node != NULL); + + string_option = (PnStringOption *) user_object; + value_node = xmlNewChild (node, NULL, "Value", NULL); + xmlNodeSetContent (value_node, string_option->value); + + if (parent_class->save_thyself) + parent_class->save_thyself (user_object, node); +} + +static void +pn_string_option_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnStringOption *string_option; + xmlNodePtr string_option_node; + gchar *val_str; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_STRING_OPTION (user_object)); + g_return_if_fail (node != NULL); + + string_option = (PnStringOption *) user_object; + + for (string_option_node = node->xmlChildrenNode; + string_option_node; + string_option_node = string_option_node->next) + if (g_strcasecmp (string_option_node->name, "Value") == 0) + break; + if (! string_option_node) + { + pn_error ("unable to load a PnStringOption from xml node \"%s\"", node->name); + return; + } + + val_str = xmlNodeGetContent (string_option_node); + if (val_str) + pn_string_option_set_value (string_option, val_str); + else + pn_string_option_set_value (string_option, empty_string); + + if (parent_class->load_thyself) + parent_class->load_thyself (user_object, node); +} + +PnStringOption* +pn_string_option_new (const gchar *name, const gchar *desc) +{ + PnStringOption *string_option; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (desc != NULL, NULL); + + string_option = (PnStringOption *) g_object_new (PN_TYPE_STRING_OPTION, NULL); + + pn_user_object_set_name (PN_USER_OBJECT (string_option), name); + pn_user_object_set_description (PN_USER_OBJECT (string_option), desc); + + return string_option; +} + +void +pn_string_option_set_value (PnStringOption *string_option, const gchar *value) +{ + g_return_if_fail (string_option != NULL); + g_return_if_fail (PN_IS_STRING_OPTION (string_option)); + g_return_if_fail (value != NULL); + + if (string_option->value && string_option->value != empty_string) + g_free (string_option->value); + + string_option->value = g_strdup (value); +} + +gchar* +pn_string_option_get_value (PnStringOption *string_option) +{ + g_return_val_if_fail (string_option != NULL, FALSE); + g_return_val_if_fail (PN_IS_STRING_OPTION (string_option), FALSE); + + return string_option->value; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnstringoption.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,64 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_STRING_OPTION_H__ +#define __PN_STRING_OPTION_H__ + +#include "pnoption.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_STRING_OPTION (pn_string_option_get_type ()) +#define PN_STRING_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_STRING_OPTION, PnStringOption)) +#define PN_STRING_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_STRING_OPTION, PnStringOptionClass)) +#define PN_IS_STRING_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_STRING_OPTION)) +#define PN_IS_STRING_OPTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_STRING_OPTION)) +#define PN_STRING_OPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_STRING_OPTION, PnStringOptionClass)) + +typedef struct _PnStringOption PnStringOption; +typedef struct _PnStringOptionClass PnStringOptionClass; + +struct _PnStringOption +{ + PnOption parent; + + gchar *value; +}; + +struct _PnStringOptionClass +{ + PnOptionClass parent_class; +}; + +/* Creators */ +GType pn_string_option_get_type (void); +PnStringOption *pn_string_option_new (const gchar *name, + const gchar *desc); + +/* Accessors */ +void pn_string_option_set_value (PnStringOption *string_option, + const gchar *value); +gchar *pn_string_option_get_value (PnStringOption *string_option); + + + + + +#endif /* __PN_STRING_OPTION_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnsymboltable.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,168 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include "pnsymboltable.h" + +/* Initialization */ +static void pn_symbol_table_class_init (PnSymbolTableClass *class); + +static GObjectClass *parent_class = NULL; + + + +GType +pn_symbol_table_get_type (void) +{ + static GType symbol_table_type = 0; + + if (! symbol_table_type) + { + static const GTypeInfo symbol_table_info = + { + sizeof (PnSymbolTableClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_symbol_table_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnSymbolTable), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + + /* FIXME: should this be dynamic? */ + symbol_table_type = g_type_register_static (PN_TYPE_OBJECT, + "PnSymbolTable", + &symbol_table_info, + 0); + } + return symbol_table_type; +} + +static void +pn_symbol_table_class_init (PnSymbolTableClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + + parent_class = g_type_class_peek_parent (class); +} + +/** + * pn_symbol_table_new + * + * Creates a new #PnSymbolTable object. + * + * Returns: The newly created #PnSymbolTable object + */ +PnSymbolTable* +pn_symbol_table_new (void) +{ + return (PnSymbolTable *) g_object_new (PN_TYPE_SYMBOL_TABLE, NULL); +} + +/** + * pn_symbol_table_ref_variable_by_name + * @symbol_table: a #PnSymbolTable + * @name: the name a an in-script variable + * + * Retrieves an in-script variable contained within a symbol table and increments the + * variable's reference count. If the variable is not yet in the symbol table, it is + * added (with a value of 0.0). + * + * Returns: A pointer to the variable object + */ +PnVariable* +pn_symbol_table_ref_variable_by_name (PnSymbolTable *symbol_table, const gchar *name) +{ + GList *cur; + PnVariable *variable; + + g_return_val_if_fail (symbol_table != NULL, NULL); + g_return_val_if_fail (PN_IS_SYMBOL_TABLE (symbol_table), NULL); + g_return_val_if_fail (name != NULL, NULL); + + /* If the variable already exists, return it */ + for (cur = symbol_table->variables; cur; cur = cur->next) + if (g_strcasecmp (PN_VARIABLE (cur->data)->name, name) == 0) + { + PN_VARIABLE (cur->data)->refs++; + return PN_VARIABLE (cur->data); + } + + /* We need to make a new variable */ + variable = g_new (PnVariable, 1); + variable->value = 0.0; + variable->name = g_strdup (name); + variable->refs = 1; + + /* Add the variable to the list */ + symbol_table->variables = g_list_prepend (symbol_table->variables, variable); + + return variable; +} + +/** + * pn_symbol_table_ref_variable + * @symbol_table: a #PnSymbolTable + * @variable: an in-script variable belonging to @symbol_table + * + * Increments the reference count of an in-script variable contained within + * a symbol table. + */ +void +pn_symbol_table_ref_variable (PnSymbolTable *symbol_table, PnVariable *variable) +{ + g_return_if_fail (symbol_table != NULL); + g_return_if_fail (PN_IS_SYMBOL_TABLE (symbol_table)); + g_return_if_fail (variable != NULL); + + /* FIXME: Check to ensure the variable belongs to the symtab */ + + variable->refs++; +} + +/** + * pn_symbol_table_unref_variable + * @symbol_table: a #PnSymbolTable + * @variable: an in-script variable belonging to @symbol_table + * + * Decrements the reference count of an in-script variable. If the reference + * count becomes 0, the variable is freed from memory. + */ +void +pn_symbol_table_unref_variable (PnSymbolTable *symbol_table, PnVariable *variable) +{ + g_return_if_fail (symbol_table != NULL); + g_return_if_fail (PN_IS_SYMBOL_TABLE (symbol_table)); + g_return_if_fail (variable != NULL); + + variable->refs--; + + if (variable->refs <= 0) + { + g_free (variable->name); + g_free (variable); + symbol_table->variables = g_list_remove (symbol_table->variables, variable); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnsymboltable.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,83 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_SYMBOL_TABLE_H__ +#define __PN_SYMBOL_TABLE_H__ + +#include "pnobject.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_SYMBOL_TABLE (pn_symbol_table_get_type ()) +#define PN_SYMBOL_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_SYMBOL_TABLE, PnSymbolTable)) +#define PN_SYMBOL_TABLE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_SYMBOL_TABLE, PnSymbolTableClass)) +#define PN_IS_SYMBOL_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_SYMBOL_TABLE)) +#define PN_IS_SYMBOL_TABLE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_SYMBOL_TABLE)) +#define PN_SYMBOL_TABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_SYMBOL_TABLE, PnSymbolTableClass)) +#define PN_SYMBOL_TABLE_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +#define PN_SYMBOL_TABLE_CLASS_NAME(class) (g_type_name (PN_SYMBOL_TABLE_CLASS_TYPE (class))) + +#define PN_VARIABLE(var) ((PnVariable *) var) +#define PN_VARIABLE_VALUE(var) (PN_VARIABLE (var)->value) +#define PN_VARIABLE_NAME(var) (PN_VARIABLE (var)->name) + +typedef struct _PnVariable PnVariable; +typedef struct _PnSymbolTable PnSymbolTable; +typedef struct _PnSymbolTableClass PnSymbolTableClass; + +struct _PnVariable +{ + /*< public >*/ + gdouble value; /* read-write */ + gchar *name; /* read-only */ + + /*< private >*/ + guint refs; +}; + +struct _PnSymbolTable +{ + PnObject parent; + + GList *variables; +}; + +struct _PnSymbolTableClass +{ + PnObjectClass parent_class; +}; + +/* Creators */ +GType pn_symbol_table_get_type (void); +PnSymbolTable *pn_symbol_table_new (void); + +/* Accessors */ +PnVariable *pn_symbol_table_ref_variable_by_name (PnSymbolTable *symbol_table, + const gchar *name); +void pn_symbol_table_ref_variable (PnSymbolTable *symbol_table, + PnVariable *variable); +void pn_symbol_table_unref_variable (PnSymbolTable *symbol_table, + PnVariable *variable); + + + + + +#endif /* __PN_SYMBOL_TABLE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pntestactuator.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,180 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glib.h> +#include "pntestactuator.h" +#include "pnbooleanoption.h" +#include "pnintegeroption.h" +#include "pnfloatoption.h" +#include "pnstringoption.h" +#include "pnerror.h" + +static void pn_test_actuator_class_init (PnTestActuatorClass *class); +static void pn_test_actuator_init (PnTestActuator *test_actuator, + PnTestActuatorClass *class); +/* PnActuator methods */ +static void pn_test_actuator_prepare (PnTestActuator *test_actuator, + PnImage *image); +static void pn_test_actuator_execute (PnTestActuator *test_actuator, + PnImage *image, + PnAudioData *audio_data); + +static PnActuatorClass *parent_class = NULL; + +GType +pn_test_actuator_get_type (void) +{ + static GType test_actuator_type = 0; + + if (! test_actuator_type) + { + static const GTypeInfo test_actuator_info = + { + sizeof (PnTestActuatorClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_test_actuator_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnTestActuator), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_test_actuator_init + }; + + /* FIXME: should this be dynamic? */ + test_actuator_type = g_type_register_static (PN_TYPE_ACTUATOR, + "PnTestActuator", + &test_actuator_info, + 0); + } + return test_actuator_type; +} + +static void +pn_test_actuator_class_init (PnTestActuatorClass *class) +{ + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + PnActuatorClass *actuator_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + actuator_class = (PnActuatorClass *) class; + + /* PnActuator methods */ + actuator_class->prepare = (PnActuatorPrepFunc) pn_test_actuator_prepare; + actuator_class->execute = (PnActuatorExecFunc) pn_test_actuator_execute; +} + +static void +pn_test_actuator_init (PnTestActuator *test_actuator, PnTestActuatorClass *class) +{ + PnBooleanOption *test_bool_opt; + PnIntegerOption *test_int_opt; + PnFloatOption *test_float_opt; + PnStringOption *test_str_opt; + + /* Set up the name and description */ + pn_user_object_set_name (PN_USER_OBJECT (test_actuator), "Test.Test"); + pn_user_object_set_description (PN_USER_OBJECT (test_actuator), + "An actuator to test the functionality of the PnActuator base class"); + + /* Set up the options */ + test_bool_opt = pn_boolean_option_new ("test_boolean_option", "A boolean test option"); + pn_boolean_option_set_value (test_bool_opt, TRUE); + + test_int_opt = pn_integer_option_new ("test_integer_option", "An integer test option"); + pn_integer_option_set_value (test_int_opt, 32); + pn_integer_option_set_min (test_int_opt, 16); + pn_integer_option_set_max (test_int_opt, 64); + + test_float_opt = pn_float_option_new ("test_float_option", "A float test option"); + pn_float_option_set_value (test_float_opt, 0.7); + pn_float_option_set_min (test_float_opt, 0.0); + pn_float_option_set_max (test_float_opt, 1.0); + + test_str_opt = pn_string_option_new ("test_string_option", "A string test option"); + + pn_actuator_add_option (PN_ACTUATOR (test_actuator), PN_OPTION (test_bool_opt)); + pn_actuator_add_option (PN_ACTUATOR (test_actuator), PN_OPTION (test_int_opt)); + pn_actuator_add_option (PN_ACTUATOR (test_actuator), PN_OPTION (test_float_opt)); + pn_actuator_add_option (PN_ACTUATOR (test_actuator), PN_OPTION (test_str_opt)); +} + +static void +pn_test_actuator_prepare (PnTestActuator *test_actuator, PnImage *image) +{ + g_return_if_fail (test_actuator != NULL); + g_return_if_fail (PN_IS_TEST_ACTUATOR (test_actuator)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + + pn_error ("pn_test_actuator_prepare called"); +} + +static void +pn_test_actuator_execute (PnTestActuator *test_actuator, PnImage *image, + PnAudioData *audio_data) +{ + PnOption *test_bool_opt, *test_int_opt, *test_float_opt, *test_str_opt; + PnColor color = { 0, 0, 0, 0 }; + guint i; + + g_return_if_fail (test_actuator != NULL); + g_return_if_fail (PN_IS_TEST_ACTUATOR (test_actuator)); + g_return_if_fail (image != NULL); + g_return_if_fail (PN_IS_IMAGE (image)); + g_return_if_fail (audio_data != NULL); +/* g_return_if_fail (PN_IS_AUDIO_DATA (audio_data)); */ + + test_bool_opt = pn_actuator_get_option_by_index (PN_ACTUATOR (test_actuator), + PN_TEST_ACTUATOR_OPT_TEST_BOOL); + test_int_opt = pn_actuator_get_option_by_index (PN_ACTUATOR (test_actuator), + PN_TEST_ACTUATOR_OPT_TEST_INT); + test_float_opt = pn_actuator_get_option_by_index (PN_ACTUATOR (test_actuator), + PN_TEST_ACTUATOR_OPT_TEST_FLOAT); + test_str_opt = pn_actuator_get_option_by_index (PN_ACTUATOR (test_actuator), + PN_TEST_ACTUATOR_OPT_TEST_STR); + +/* printf ("pn_test_actuator_execute: %s = %d\n", */ +/* pn_user_object_get_name (PN_USER_OBJECT (test_bool_opt)), */ +/* pn_boolean_option_get_value (PN_BOOLEAN_OPTION (test_bool_opt))); */ +/* printf ("pn_test_actuator_execute: %s = %d\n", */ +/* pn_user_object_get_name (PN_USER_OBJECT (test_int_opt)), */ +/* pn_integer_option_get_value (PN_INTEGER_OPTION (test_int_opt))); */ +/* printf ("pn_test_actuator_execute: %s = %f\n", */ +/* pn_user_object_get_name (PN_USER_OBJECT (test_float_opt)), */ +/* pn_float_option_get_value (PN_FLOAT_OPTION (test_float_opt))); */ +/* printf ("pn_test_actuator_execute: %s = \"%s\"\n", */ +/* pn_user_object_get_name (PN_USER_OBJECT (test_str_opt)), */ +/* pn_string_option_get_value (PN_STRING_OPTION (test_str_opt))); */ + + for (i=0; i<pn_image_get_width (image) * 64; i++) + { + color.red = i % 256; + pn_image_render_pixel_by_offset (image, i, color); + } +} + +PnTestActuator* +pn_test_actuator_new (void) +{ + return (PnTestActuator *) g_object_new (PN_TYPE_TEST_ACTUATOR, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pntestactuator.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,61 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_TEST_ACTUATOR_H__ +#define __PN_TEST_ACTUATOR_H__ + +#include "pnactuator.h" + + +G_BEGIN_DECLS + + +enum +{ + PN_TEST_ACTUATOR_OPT_TEST_BOOL = PN_ACTUATOR_OPT_LAST, + PN_TEST_ACTUATOR_OPT_TEST_INT, + PN_TEST_ACTUATOR_OPT_TEST_FLOAT, + PN_TEST_ACTUATOR_OPT_TEST_STR, + PN_TEST_ACTUATOR_OPT_LAST +}; + +#define PN_TYPE_TEST_ACTUATOR (pn_test_actuator_get_type ()) +#define PN_TEST_ACTUATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_TEST_ACTUATOR, PnTestActuator)) +#define PN_TEST_ACTUATOR_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_TEST_ACTUATOR, PnTestActuatorClass)) +#define PN_IS_TEST_ACTUATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_TEST_ACTUATOR)) +#define PN_IS_TEST_ACTUATOR_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_TEST_ACTUATOR)) +#define PN_TEST_ACTUATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_TEST_ACTUATOR, PnTestActuatorClass)) + +typedef struct _PnTestActuator PnTestActuator; +typedef struct _PnTestActuatorClass PnTestActuatorClass; + +struct _PnTestActuator +{ + PnActuator parent; +}; + +struct _PnTestActuatorClass +{ + PnActuatorClass parent_class; +}; + +/* Creators */ +GType pn_test_actuator_get_type (void); +PnTestActuator *pn_test_actuator_new (void); + +#endif /* __PN_TEST_ACTUATOR_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnuserobject.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,178 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include "pnuserobject.h" + +/* Initialization */ +static void pn_user_object_class_init (PnUserObjectClass *class); + +/* PnUserObject methods */ +static void pn_user_object_real_save_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static GObjectClass *parent_class = NULL; + +GType +pn_user_object_get_type (void) +{ + static GType user_object_type = 0; + + if (! user_object_type) + { + static const GTypeInfo user_object_info = + { + sizeof (PnUserObjectClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_user_object_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnUserObject), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + + /* FIXME: should this be dynamic? */ + user_object_type = g_type_register_static (PN_TYPE_OBJECT, + "PnUserObject", + &user_object_info, + G_TYPE_FLAG_ABSTRACT); + } + return user_object_type; +} + +static void +pn_user_object_class_init (PnUserObjectClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + + /* PnUserObject methods */ + class->save_thyself = pn_user_object_real_save_thyself; + + parent_class = g_type_class_peek_parent (class); +} + +static void +pn_user_object_real_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_USER_OBJECT (user_object)); + g_return_if_fail (node != NULL); + + xmlNodeSetName (node, user_object->name); +} + +void +pn_user_object_set_name (PnUserObject *user_object, const gchar *name) +{ + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_USER_OBJECT (user_object)); + g_return_if_fail (name != NULL); + + if (user_object->name) + g_free (user_object->name); + + user_object->name = g_strdup (name); +} + +gchar* +pn_user_object_get_name (PnUserObject *user_object) +{ + g_return_val_if_fail (user_object != NULL, NULL); + g_return_val_if_fail (PN_IS_USER_OBJECT (user_object), NULL); + + return user_object->name; +} + +void +pn_user_object_set_description (PnUserObject *user_object, const gchar *desc) +{ + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_USER_OBJECT (user_object)); + g_return_if_fail (desc != NULL); + + if (user_object->desc) + g_free (user_object->desc); + + user_object->desc = g_strdup (desc); +} + +gchar* +pn_user_object_get_description (PnUserObject *user_object) +{ + g_return_val_if_fail (user_object != NULL, NULL); + g_return_val_if_fail (PN_IS_USER_OBJECT (user_object), NULL); + + return user_object->desc; +} + +void +pn_user_object_set_owner (PnUserObject *user_object, PnUserObject *owner) +{ + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_USER_OBJECT (user_object)); + g_return_if_fail (owner != NULL); + g_return_if_fail (PN_IS_USER_OBJECT (owner)); + + user_object->owner = owner; +} + +PnUserObject* +pn_user_object_get_owner (PnUserObject *user_object) +{ + g_return_val_if_fail (user_object != NULL, NULL); + g_return_val_if_fail (PN_IS_USER_OBJECT (user_object), NULL); + + return user_object->owner; +} + +void +pn_user_object_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnUserObjectClass *class; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_USER_OBJECT (user_object)); + g_return_if_fail (node != NULL); + + class = PN_USER_OBJECT_GET_CLASS (user_object); + + if (class->save_thyself) + class->save_thyself (user_object, node); +} + +void +pn_user_object_load_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnUserObjectClass *class; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_USER_OBJECT (user_object)); + g_return_if_fail (node != NULL); + + class = PN_USER_OBJECT_GET_CLASS (user_object); + + if (class->load_thyself) + class->load_thyself (user_object, node); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnuserobject.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,91 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_USER_OBJECT_H__ +#define __PN_USER_OBJECT_H__ + +#include "pnobject.h" +#include "pnxml.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_USER_OBJECT (pn_user_object_get_type ()) +#define PN_USER_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_USER_OBJECT, PnUserObject)) +#define PN_USER_OBJECT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_USER_OBJECT, PnUserObjectClass)) +#define PN_IS_USER_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_USER_OBJECT)) +#define PN_IS_USER_OBJECT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_USER_OBJECT)) +#define PN_USER_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_USER_OBJECT, PnUserObjectClass)) +#define PN_USER_OBJECT_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +#define PN_USER_OBJECT_CLASS_NAME(class) (g_type_name (PN_USER_OBJECT_CLASS_TYPE (class))) + +#define PN_USER_OBJECT_TYPE(obj) (G_TYPE_FROM_INSTANCE (obj)) +#define PN_USER_OBJECT_TYPE_NAME(obj) (g_type_name (PN_USER_OBJECT_TYPE (obj))) + +#define PN_USER_OBJECT_NAME(obj) (PN_USER_OBJECT (obj)->name) +#define PN_USER_OBJECT_DESC(obj) (PN_USER_OBJECT (obj)->desc) +#define PN_USER_OBJECT_OWNER(obj) (PN_USER_OBJECT (obj)->owner) + +typedef struct _PnUserObject PnUserObject; +typedef struct _PnUserObjectClass PnUserObjectClass; + +struct _PnUserObject +{ + PnObject parent; + + gchar *name; + gchar *desc; + PnUserObject *owner; +}; + +struct _PnUserObjectClass +{ + PnObjectClass parent_class; + + void (* save_thyself) (PnUserObject *user_object, + xmlNodePtr node); + void (* load_thyself) (PnUserObject *user_object, + xmlNodePtr node); +}; + +GType pn_user_object_get_type (void); +#define pn_user_object_destroy(object) pn_object_destroy (PN_OBJECT (object)) + +/* Accessors */ +void pn_user_object_set_name (PnUserObject *user_object, + const gchar *name); +gchar *pn_user_object_get_name (PnUserObject *user_object); +void pn_user_object_set_description (PnUserObject *user_object, + const gchar *desc); +gchar *pn_user_object_get_description (PnUserObject *user_object); +void pn_user_object_set_owner (PnUserObject *user_object, + PnUserObject *owner); +PnUserObject *pn_user_object_get_owner (PnUserObject *user_object); + +/* Actions */ +void pn_user_object_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +void pn_user_object_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + + + + + +#endif /* __PN_USER_OBJECT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnvis.c Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,323 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <glib.h> +#include "pnvis.h" +#include "pnactuatorfactory.h" +#include "pnerror.h" + +static void pn_vis_class_init (PnVisClass *class); +static void pn_vis_init (PnVis *vis, + PnVisClass *class); + +/* GObject signals */ +static void pn_vis_finalize (GObject *gobject); + +/* PnObject signals */ +static void pn_vis_destroy (PnObject *object); + +/* PnUserObject methods */ +static void pn_vis_save_thyself (PnUserObject *user_object, + xmlNodePtr node); +static void pn_vis_load_thyself (PnUserObject *user_object, + xmlNodePtr node); + +static PnUserObjectClass *parent_class = NULL; + +GType +pn_vis_get_type (void) +{ + static GType vis_type = 0; + + if (! vis_type) + { + static const GTypeInfo vis_info = + { + sizeof (PnVisClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) pn_vis_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PnVis), + 0, /* n_preallocs */ + (GInstanceInitFunc) pn_vis_init + }; + + /* FIXME: should this be dynamic? */ + vis_type = g_type_register_static (PN_TYPE_USER_OBJECT, + "PnVis", + &vis_info, + 0); + } + return vis_type; +} + +static void +pn_vis_class_init (PnVisClass *class) +{ + GObjectClass *gobject_class; + PnObjectClass *object_class; + PnUserObjectClass *user_object_class; + + parent_class = g_type_class_peek_parent (class); + + gobject_class = (GObjectClass *) class; + object_class = (PnObjectClass *) class; + user_object_class = (PnUserObjectClass *) class; + + /* GObject signals */ + gobject_class->finalize = pn_vis_finalize; + + /* PnObject signals */ + object_class->destroy = pn_vis_destroy; + + /* PnUserObject methods */ + user_object_class->save_thyself = pn_vis_save_thyself; + user_object_class->load_thyself = pn_vis_load_thyself; +} + +static void +pn_vis_init (PnVis *vis, PnVisClass *class) +{ + /* Set a name for xml stuffs */ + pn_user_object_set_name (PN_USER_OBJECT (vis), "Paranormal_Visualization"); + + /* Create a new image context */ + vis->root_image = pn_image_new (); + pn_object_ref (PN_OBJECT (vis->root_image)); + pn_object_sink (PN_OBJECT (vis->root_image)); +} + +static void +pn_vis_destroy (PnObject *object) +{ + PnVis *vis = (PnVis *) object; + + if (vis->root_actuator) + pn_object_unref (PN_OBJECT (vis->root_actuator)); + + if (vis->root_image) + pn_object_unref (PN_OBJECT (vis->root_image)); +} + +static void +pn_vis_finalize (GObject *gobject) +{ + PnVis *vis; + + vis = (PnVis *) gobject; +} + +static void +pn_vis_save_thyself (PnUserObject *user_object, xmlNodePtr node) +{ + PnVis *vis; + xmlNsPtr ns; + xmlNodePtr actuators_node, actuator_node; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_VIS (user_object)); + g_return_if_fail (node != NULL); + + vis = (PnVis *) user_object; + + ns = xmlNewNs (node, PN_XML_NS_HREF, "pn"); + xmlSetNs (node, ns); + + actuators_node = xmlNewChild (node, NULL, "Actuators", NULL); + actuator_node = xmlNewChild (actuators_node, NULL, "BUG", NULL); + if (vis->root_actuator) + pn_user_object_save_thyself (PN_USER_OBJECT (vis->root_actuator), actuator_node); + + if (parent_class->save_thyself) + parent_class->save_thyself (user_object, node); +} + +static void +pn_vis_load_thyself (PnUserObject *user_object, const xmlNodePtr node) +{ + PnVis *vis; + xmlNodePtr actuators_node, actuator_node; + PnActuator *root_actuator; + + g_return_if_fail (user_object != NULL); + g_return_if_fail (PN_IS_VIS (user_object)); + g_return_if_fail (node != NULL); + + vis = (PnVis *) user_object; + + /* find the 'Actuators' node */ + for (actuators_node = node->xmlChildrenNode; actuators_node; actuators_node = actuators_node->next) + if (g_strcasecmp (actuators_node->name, "Actuators") == 0) + break; + if (! actuators_node) + { + pn_error ("unable to load a PnVis from xml node \"%s\"", node->name); + return; + } + + /* get the root actuator's node */ + actuator_node = actuators_node->xmlChildrenNode; + if (! actuator_node) + goto done; + + /* Create a new actuator */ + root_actuator = pn_actuator_factory_new_actuator_from_xml (actuator_node); + if (! root_actuator) + pn_error ("Unknown actuator \"%s\"", actuator_node->name); + + pn_vis_set_root_actuator (vis, root_actuator); + + done: + if (parent_class->load_thyself) + parent_class->load_thyself (user_object, node); +} + +PnVis* +pn_vis_new (guint image_width, guint image_height) +{ + PnVis *vis; + + g_return_val_if_fail (image_width > 0, NULL); + g_return_val_if_fail (image_height > 0, NULL); + + vis = (PnVis *) g_object_new (PN_TYPE_VIS, NULL); + pn_vis_set_image_size (vis, image_width, image_height); + + return vis; +} + +void +pn_vis_set_root_actuator (PnVis *vis, PnActuator *actuator) +{ + g_return_if_fail (vis != NULL); + g_return_if_fail (PN_IS_VIS (vis)); + g_return_if_fail (actuator != NULL); + g_return_if_fail (PN_IS_ACTUATOR (actuator)); + + if (vis->root_actuator) + pn_object_unref (PN_OBJECT (vis->root_actuator)); + + vis->root_actuator = actuator; + + pn_object_ref (PN_OBJECT (actuator)); + pn_object_sink (PN_OBJECT (actuator)); + pn_user_object_set_owner (PN_USER_OBJECT (actuator), PN_USER_OBJECT (vis)); + + pn_actuator_prepare (actuator, vis->root_image); +} + +PnActuator* +pn_vis_get_root_actuator (PnVis *vis) +{ + g_return_val_if_fail (vis != NULL, NULL); + g_return_val_if_fail (PN_IS_VIS (vis), NULL); + + return vis->root_actuator; +} + +void +pn_vis_set_image_size (PnVis *vis, guint width, guint height) +{ + g_return_if_fail (vis != NULL); + g_return_if_fail (PN_IS_VIS (vis)); + + pn_image_set_size (vis->root_image, width, height); + + if (vis->root_actuator) + pn_actuator_prepare (vis->root_actuator, vis->root_image); +} + +gboolean +pn_vis_save_to_file (PnVis *vis, const gchar *fname) +{ + xmlDocPtr doc; + + doc = xmlNewDoc ("1.0"); + + doc->xmlRootNode = xmlNewDocNode (doc, NULL, "BUG", NULL); + + pn_user_object_save_thyself (PN_USER_OBJECT (vis), doc->xmlRootNode); + + if ( xmlSaveFile (fname, doc) == -1) + { + xmlFreeDoc (doc); + return FALSE; + } + + xmlFreeDoc (doc); + return TRUE; +} + +gboolean +pn_vis_load_from_file (PnVis *vis, const gchar *fname) +{ + xmlDocPtr doc; + xmlNodePtr root_node; + xmlNsPtr ns; + + doc = xmlParseFile (fname); + if (! doc) + { + pn_error ("unable to parse file \"%s\"", fname); + return FALSE; + } + + root_node = xmlDocGetRootElement (doc); + if (! root_node) + { + pn_error ("no root element for file \"%s\"", fname); + return FALSE; + } + + ns = xmlSearchNsByHref (doc, root_node, PN_XML_NS_HREF); + if (! ns) + { + pn_error ("invalid file format: paranormal namespace not found"); + return FALSE; + } + + if (g_strcasecmp (root_node->name, pn_user_object_get_name (PN_USER_OBJECT (vis)))) + { + pn_error ("invalid file format: this file does not contain a Paranormal visualization"); + return FALSE; + } + + pn_user_object_load_thyself (PN_USER_OBJECT (vis), root_node); + + return TRUE; +} + +PnImage* +pn_vis_render (PnVis *vis, PnAudioData *audio_data) +{ + g_return_val_if_fail (vis != NULL, NULL); + g_return_val_if_fail (PN_IS_VIS (vis), NULL); + g_return_val_if_fail (audio_data != NULL, NULL); +/* g_return_val_if_fail (PN_IS_AUDIO_DATA (audio_data), NULL); */ + + if (vis->root_actuator) + pn_actuator_execute (vis->root_actuator, + vis->root_image, + audio_data); + + return vis->root_image; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnvis.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,80 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_VIS_H__ +#define __PN_VIS_H__ + +#include <glib.h> +#include "pnuserobject.h" +#include "pnactuator.h" +#include "pnimage.h" +#include "pnaudiodata.h" + + +G_BEGIN_DECLS + + +#define PN_TYPE_VIS (pn_vis_get_type ()) +#define PN_VIS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PN_TYPE_VIS, PnVis)) +#define PN_VIS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), PN_TYPE_VIS, PnVisClass)) +#define PN_IS_VIS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PN_TYPE_VIS)) +#define PN_IS_VIS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), PN_TYPE_VIS)) +#define PN_VIS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PN_TYPE_VIS, PnVisClass)) + +typedef struct _PnVis PnVis; +typedef struct _PnVisClass PnVisClass; + +struct _PnVis +{ + PnUserObject parent; + + PnActuator *root_actuator; + PnImage *root_image; +}; + +struct _PnVisClass +{ + PnUserObjectClass parent_class; +}; + +/* Creators */ +GType pn_vis_get_type (void); +PnVis *pn_vis_new (guint image_width, + guint image_height); + +/* Accessors */ +void pn_vis_set_root_actuator (PnVis *vis, + PnActuator *actuator); +PnActuator *pn_vis_get_root_actuator (PnVis *vis); +void pn_vis_set_image_size (PnVis *vis, + guint width, + guint height); + +/* Actions */ +gboolean pn_vis_save_to_file (PnVis *vis, + const gchar *fname); +gboolean pn_vis_load_from_file (PnVis *vis, + const gchar *fname); +PnImage *pn_vis_render (PnVis *vis, + PnAudioData *audio_data); + + + + + +#endif /* __PN_VIS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Visualization/paranormal/pn/pnxml.h Sun Aug 06 01:53:29 2006 -0700 @@ -0,0 +1,33 @@ +/* Paranormal - A highly customizable audio visualization library + * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PN_XML_H__ +#define __PN_XML_H__ + +#include <libxml/parser.h> + +/* compatibility w/ libxml1 */ +#ifndef xmlChildrenNode +#define xmlChildrenNode childs +#define xmlRootNode root +#endif + +/* The namespace href */ +#define PN_XML_NS_HREF "http://paranormal.sf.net/pnvis/1.0/" + +#endif /* __PN_XML_H__ */