Mercurial > audlegacy
annotate Plugins/Visualization/paranormal/pn/pnvis.c @ 1594:44f67f556b60 trunk
[svn] - precision in title format is regarded as character count, not byte count.
author | yaz |
---|---|
date | Thu, 24 Aug 2006 23:08:22 -0700 |
parents | 752949e9aec4 |
children |
rev | line source |
---|---|
1507 | 1 /* Paranormal - A highly customizable audio visualization library |
2 * Copyright (C) 2001 Jamie Gennis <jgennis@mindspring.com> | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public | |
15 * License along with this library; if not, write to the Free | |
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
17 */ | |
18 | |
19 #include <config.h> | |
20 | |
21 #include <glib.h> | |
22 #include "pnvis.h" | |
23 #include "pnactuatorfactory.h" | |
24 #include "pnerror.h" | |
25 | |
26 static void pn_vis_class_init (PnVisClass *class); | |
27 static void pn_vis_init (PnVis *vis, | |
28 PnVisClass *class); | |
29 | |
30 /* GObject signals */ | |
31 static void pn_vis_finalize (GObject *gobject); | |
32 | |
33 /* PnObject signals */ | |
34 static void pn_vis_destroy (PnObject *object); | |
35 | |
36 /* PnUserObject methods */ | |
37 static void pn_vis_save_thyself (PnUserObject *user_object, | |
38 xmlNodePtr node); | |
39 static void pn_vis_load_thyself (PnUserObject *user_object, | |
40 xmlNodePtr node); | |
41 | |
42 static PnUserObjectClass *parent_class = NULL; | |
43 | |
44 GType | |
45 pn_vis_get_type (void) | |
46 { | |
47 static GType vis_type = 0; | |
48 | |
49 if (! vis_type) | |
50 { | |
51 static const GTypeInfo vis_info = | |
52 { | |
53 sizeof (PnVisClass), | |
54 NULL, /* base_init */ | |
55 NULL, /* base_finalize */ | |
56 (GClassInitFunc) pn_vis_class_init, | |
57 NULL, /* class_finalize */ | |
58 NULL, /* class_data */ | |
59 sizeof (PnVis), | |
60 0, /* n_preallocs */ | |
61 (GInstanceInitFunc) pn_vis_init | |
62 }; | |
63 | |
64 /* FIXME: should this be dynamic? */ | |
65 vis_type = g_type_register_static (PN_TYPE_USER_OBJECT, | |
66 "PnVis", | |
67 &vis_info, | |
68 0); | |
69 } | |
70 return vis_type; | |
71 } | |
72 | |
73 static void | |
74 pn_vis_class_init (PnVisClass *class) | |
75 { | |
76 GObjectClass *gobject_class; | |
77 PnObjectClass *object_class; | |
78 PnUserObjectClass *user_object_class; | |
79 | |
80 parent_class = g_type_class_peek_parent (class); | |
81 | |
82 gobject_class = (GObjectClass *) class; | |
83 object_class = (PnObjectClass *) class; | |
84 user_object_class = (PnUserObjectClass *) class; | |
85 | |
86 /* GObject signals */ | |
87 gobject_class->finalize = pn_vis_finalize; | |
88 | |
89 /* PnObject signals */ | |
90 object_class->destroy = pn_vis_destroy; | |
91 | |
92 /* PnUserObject methods */ | |
93 user_object_class->save_thyself = pn_vis_save_thyself; | |
94 user_object_class->load_thyself = pn_vis_load_thyself; | |
95 } | |
96 | |
97 static void | |
98 pn_vis_init (PnVis *vis, PnVisClass *class) | |
99 { | |
100 /* Set a name for xml stuffs */ | |
101 pn_user_object_set_name (PN_USER_OBJECT (vis), "Paranormal_Visualization"); | |
102 | |
103 /* Create a new image context */ | |
104 vis->root_image = pn_image_new (); | |
105 pn_object_ref (PN_OBJECT (vis->root_image)); | |
106 pn_object_sink (PN_OBJECT (vis->root_image)); | |
107 } | |
108 | |
109 static void | |
110 pn_vis_destroy (PnObject *object) | |
111 { | |
112 PnVis *vis = (PnVis *) object; | |
113 | |
114 if (vis->root_actuator) | |
115 pn_object_unref (PN_OBJECT (vis->root_actuator)); | |
116 | |
117 if (vis->root_image) | |
118 pn_object_unref (PN_OBJECT (vis->root_image)); | |
119 } | |
120 | |
121 static void | |
122 pn_vis_finalize (GObject *gobject) | |
123 { | |
124 PnVis *vis; | |
125 | |
126 vis = (PnVis *) gobject; | |
127 } | |
128 | |
129 static void | |
130 pn_vis_save_thyself (PnUserObject *user_object, xmlNodePtr node) | |
131 { | |
132 PnVis *vis; | |
133 xmlNsPtr ns; | |
134 xmlNodePtr actuators_node, actuator_node; | |
135 | |
136 g_return_if_fail (user_object != NULL); | |
137 g_return_if_fail (PN_IS_VIS (user_object)); | |
138 g_return_if_fail (node != NULL); | |
139 | |
140 vis = (PnVis *) user_object; | |
141 | |
1591
02841f72b897
[svn] Cast variable to proper type before passing it into libxml2. Include necessary header to make this possible. Resolves 35 pointer signedness warnings on PPC.
chainsaw
parents:
1531
diff
changeset
|
142 ns = xmlNewNs (node, PN_XML_NS_HREF, (xmlChar *) "pn"); |
1507 | 143 xmlSetNs (node, ns); |
144 | |
1591
02841f72b897
[svn] Cast variable to proper type before passing it into libxml2. Include necessary header to make this possible. Resolves 35 pointer signedness warnings on PPC.
chainsaw
parents:
1531
diff
changeset
|
145 actuators_node = xmlNewChild (node, NULL, (xmlChar *) "Actuators", NULL); |
02841f72b897
[svn] Cast variable to proper type before passing it into libxml2. Include necessary header to make this possible. Resolves 35 pointer signedness warnings on PPC.
chainsaw
parents:
1531
diff
changeset
|
146 actuator_node = xmlNewChild (actuators_node, NULL, (xmlChar *) user_object->name, NULL); |
1507 | 147 if (vis->root_actuator) |
148 pn_user_object_save_thyself (PN_USER_OBJECT (vis->root_actuator), actuator_node); | |
149 | |
150 if (parent_class->save_thyself) | |
151 parent_class->save_thyself (user_object, node); | |
152 } | |
153 | |
154 static void | |
155 pn_vis_load_thyself (PnUserObject *user_object, const xmlNodePtr node) | |
156 { | |
157 PnVis *vis; | |
1592
752949e9aec4
[svn] Actually cast variables to glib types before feeding them into glib compare functions. Resolves another 16 signedness warnings on PPC.
chainsaw
parents:
1591
diff
changeset
|
158 xmlNodePtr actuators_node, actuator_node; |
752949e9aec4
[svn] Actually cast variables to glib types before feeding them into glib compare functions. Resolves another 16 signedness warnings on PPC.
chainsaw
parents:
1591
diff
changeset
|
159 #if 0 |
752949e9aec4
[svn] Actually cast variables to glib types before feeding them into glib compare functions. Resolves another 16 signedness warnings on PPC.
chainsaw
parents:
1591
diff
changeset
|
160 , tptr; |
752949e9aec4
[svn] Actually cast variables to glib types before feeding them into glib compare functions. Resolves another 16 signedness warnings on PPC.
chainsaw
parents:
1591
diff
changeset
|
161 #endif |
1527 | 162 PnActuator *root_actuator = NULL; |
1507 | 163 |
164 g_return_if_fail (user_object != NULL); | |
165 g_return_if_fail (PN_IS_VIS (user_object)); | |
166 g_return_if_fail (node != NULL); | |
167 | |
168 vis = (PnVis *) user_object; | |
169 | |
170 /* find the 'Actuators' node */ | |
171 for (actuators_node = node->xmlChildrenNode; actuators_node; actuators_node = actuators_node->next) | |
1592
752949e9aec4
[svn] Actually cast variables to glib types before feeding them into glib compare functions. Resolves another 16 signedness warnings on PPC.
chainsaw
parents:
1591
diff
changeset
|
172 if (g_strcasecmp ((gchar *) actuators_node->name, "Actuators") == 0) |
1507 | 173 break; |
174 if (! actuators_node) | |
175 { | |
176 pn_error ("unable to load a PnVis from xml node \"%s\"", node->name); | |
177 return; | |
178 } | |
179 | |
180 /* get the root actuator's node */ | |
1592
752949e9aec4
[svn] Actually cast variables to glib types before feeding them into glib compare functions. Resolves another 16 signedness warnings on PPC.
chainsaw
parents:
1591
diff
changeset
|
181 for (actuator_node = actuators_node->xmlChildrenNode; actuator_node != NULL && !g_strcasecmp((gchar *) actuator_node->name, "text"); |
1531
4319ae8c8f69
[svn] - ok, with this commit, loading now works =)
nenolod
parents:
1527
diff
changeset
|
182 actuator_node = actuator_node->next); |
1507 | 183 if (! actuator_node) |
184 goto done; | |
185 | |
1527 | 186 /* Create a new actuator (reworked by nenolod) */ |
1531
4319ae8c8f69
[svn] - ok, with this commit, loading now works =)
nenolod
parents:
1527
diff
changeset
|
187 #if 0 |
1527 | 188 for (tptr = actuator_node; tptr != NULL && root_actuator == NULL; tptr = tptr->next) |
189 { | |
190 xmlNodePtr ttptr; | |
191 | |
192 for (ttptr = tptr; ttptr != NULL; ttptr = ttptr->xmlChildrenNode) | |
193 } | |
1531
4319ae8c8f69
[svn] - ok, with this commit, loading now works =)
nenolod
parents:
1527
diff
changeset
|
194 #endif |
1527 | 195 |
1531
4319ae8c8f69
[svn] - ok, with this commit, loading now works =)
nenolod
parents:
1527
diff
changeset
|
196 root_actuator = pn_actuator_factory_new_actuator_from_xml (actuator_node); |
1527 | 197 if (!root_actuator) |
1531
4319ae8c8f69
[svn] - ok, with this commit, loading now works =)
nenolod
parents:
1527
diff
changeset
|
198 pn_error ("Unknown actuator \"%s\" -> '%s'", actuator_node->name, actuator_node->content); |
1507 | 199 |
200 pn_vis_set_root_actuator (vis, root_actuator); | |
201 | |
202 done: | |
203 if (parent_class->load_thyself) | |
204 parent_class->load_thyself (user_object, node); | |
205 } | |
206 | |
207 PnVis* | |
208 pn_vis_new (guint image_width, guint image_height) | |
209 { | |
210 PnVis *vis; | |
211 | |
212 g_return_val_if_fail (image_width > 0, NULL); | |
213 g_return_val_if_fail (image_height > 0, NULL); | |
214 | |
215 vis = (PnVis *) g_object_new (PN_TYPE_VIS, NULL); | |
216 pn_vis_set_image_size (vis, image_width, image_height); | |
217 | |
218 return vis; | |
219 } | |
220 | |
221 void | |
222 pn_vis_set_root_actuator (PnVis *vis, PnActuator *actuator) | |
223 { | |
224 g_return_if_fail (vis != NULL); | |
225 g_return_if_fail (PN_IS_VIS (vis)); | |
226 g_return_if_fail (actuator != NULL); | |
227 g_return_if_fail (PN_IS_ACTUATOR (actuator)); | |
228 | |
229 if (vis->root_actuator) | |
230 pn_object_unref (PN_OBJECT (vis->root_actuator)); | |
231 | |
232 vis->root_actuator = actuator; | |
233 | |
234 pn_object_ref (PN_OBJECT (actuator)); | |
235 pn_object_sink (PN_OBJECT (actuator)); | |
236 pn_user_object_set_owner (PN_USER_OBJECT (actuator), PN_USER_OBJECT (vis)); | |
237 | |
238 pn_actuator_prepare (actuator, vis->root_image); | |
239 } | |
240 | |
241 PnActuator* | |
242 pn_vis_get_root_actuator (PnVis *vis) | |
243 { | |
244 g_return_val_if_fail (vis != NULL, NULL); | |
245 g_return_val_if_fail (PN_IS_VIS (vis), NULL); | |
246 | |
247 return vis->root_actuator; | |
248 } | |
249 | |
250 void | |
251 pn_vis_set_image_size (PnVis *vis, guint width, guint height) | |
252 { | |
253 g_return_if_fail (vis != NULL); | |
254 g_return_if_fail (PN_IS_VIS (vis)); | |
255 | |
256 pn_image_set_size (vis->root_image, width, height); | |
257 | |
258 if (vis->root_actuator) | |
259 pn_actuator_prepare (vis->root_actuator, vis->root_image); | |
260 } | |
261 | |
262 gboolean | |
263 pn_vis_save_to_file (PnVis *vis, const gchar *fname) | |
264 { | |
265 xmlDocPtr doc; | |
266 | |
1591
02841f72b897
[svn] Cast variable to proper type before passing it into libxml2. Include necessary header to make this possible. Resolves 35 pointer signedness warnings on PPC.
chainsaw
parents:
1531
diff
changeset
|
267 doc = xmlNewDoc ((xmlChar *) "1.0"); |
1507 | 268 |
1591
02841f72b897
[svn] Cast variable to proper type before passing it into libxml2. Include necessary header to make this possible. Resolves 35 pointer signedness warnings on PPC.
chainsaw
parents:
1531
diff
changeset
|
269 doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *) "BUG", NULL); |
1507 | 270 |
271 pn_user_object_save_thyself (PN_USER_OBJECT (vis), doc->xmlRootNode); | |
272 | |
273 if ( xmlSaveFile (fname, doc) == -1) | |
274 { | |
275 xmlFreeDoc (doc); | |
276 return FALSE; | |
277 } | |
278 | |
279 xmlFreeDoc (doc); | |
280 return TRUE; | |
281 } | |
282 | |
283 gboolean | |
284 pn_vis_load_from_file (PnVis *vis, const gchar *fname) | |
285 { | |
286 xmlDocPtr doc; | |
287 xmlNodePtr root_node; | |
288 xmlNsPtr ns; | |
289 | |
290 doc = xmlParseFile (fname); | |
291 if (! doc) | |
292 { | |
293 pn_error ("unable to parse file \"%s\"", fname); | |
294 return FALSE; | |
295 } | |
296 | |
297 root_node = xmlDocGetRootElement (doc); | |
298 if (! root_node) | |
299 { | |
300 pn_error ("no root element for file \"%s\"", fname); | |
301 return FALSE; | |
302 } | |
303 | |
304 ns = xmlSearchNsByHref (doc, root_node, PN_XML_NS_HREF); | |
305 if (! ns) | |
306 { | |
307 pn_error ("invalid file format: paranormal namespace not found"); | |
308 return FALSE; | |
309 } | |
310 | |
1592
752949e9aec4
[svn] Actually cast variables to glib types before feeding them into glib compare functions. Resolves another 16 signedness warnings on PPC.
chainsaw
parents:
1591
diff
changeset
|
311 if (g_strcasecmp ((gchar *) root_node->name, pn_user_object_get_name (PN_USER_OBJECT (vis)))) |
1507 | 312 { |
313 pn_error ("invalid file format: this file does not contain a Paranormal visualization"); | |
314 return FALSE; | |
315 } | |
316 | |
317 pn_user_object_load_thyself (PN_USER_OBJECT (vis), root_node); | |
318 | |
319 return TRUE; | |
320 } | |
321 | |
322 PnImage* | |
323 pn_vis_render (PnVis *vis, PnAudioData *audio_data) | |
324 { | |
325 g_return_val_if_fail (vis != NULL, NULL); | |
326 g_return_val_if_fail (PN_IS_VIS (vis), NULL); | |
327 g_return_val_if_fail (audio_data != NULL, NULL); | |
328 /* g_return_val_if_fail (PN_IS_AUDIO_DATA (audio_data), NULL); */ | |
329 | |
330 if (vis->root_actuator) | |
331 pn_actuator_execute (vis->root_actuator, | |
332 vis->root_image, | |
333 audio_data); | |
334 | |
335 return vis->root_image; | |
336 } |