aboutsummaryrefslogtreecommitdiff
path: root/src/symtodp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/symtodp.c')
-rwxr-xr-xsrc/symtodp.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/symtodp.c b/src/symtodp.c
new file mode 100755
index 0000000..9b889f7
--- /dev/null
+++ b/src/symtodp.c
@@ -0,0 +1,133 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2013 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* -------------------------- symtodp ------------------------------ */
+/* symbol double precision number to double float converter */
+
+/* double float is only internal used */
+/* to transfer this value, we divide this double value into use one float casted value */
+/* and into the difference to the accurate double value. */
+
+/* double float (sign_1 + exp_12 + mant_51) */
+
+static t_class *symtodp_class;
+
+typedef struct _symtodp
+{
+ t_object x_obj;
+ double x_inner_double_value;
+ t_outlet *x_out_floatcasted;
+ t_outlet *x_out_residual;
+} t_symtodp;
+
+static double symtodp_calc_list_sum(int ac, t_atom *av)
+{
+ int i;
+ char str[1000], buf[100], *dummy;
+
+ str[0] = 0;
+ for(i=0; i<ac; i++)
+ {
+ if(IS_A_FLOAT(av, i))
+ {
+ sprintf(buf, "%g", (float)atom_getfloatarg(i, ac, av));
+ strcat(str, buf);
+ }
+ }
+ // post("listtodp string: %s", str);
+
+ return(strtod(str, &dummy));
+}
+
+static void symtodp_bang(t_symtodp *x)
+{
+ t_float float_casted_value;
+
+ float_casted_value = iem_dp_cast_to_float(x->x_inner_double_value);
+ outlet_float(x->x_out_residual, iem_dp_calc_residual(x->x_inner_double_value, float_casted_value));
+ outlet_float(x->x_out_floatcasted, float_casted_value);
+}
+
+static void symtodp_float(t_symtodp *x, t_floatarg f)
+{
+ x->x_inner_double_value = (double)f;
+ symtodp_bang(x);
+}
+
+static void symtodp_symbol(t_symtodp *x, t_symbol *s)
+{
+ char *dummy;
+
+ if((s->s_name[0] == '"') && (s->s_name[1]))
+ {
+ if((s->s_name[1] == '.') || (s->s_name[1] == '+') || (s->s_name[1] == '-') || ((s->s_name[1] >= '0') && (s->s_name[1] <= '9')))
+ {
+ x->x_inner_double_value = strtod(s->s_name+1, &dummy);
+ symtodp_bang(x);
+ }
+ }
+ else if((s->s_name[0] == '.') || (s->s_name[0] == '+') || (s->s_name[0] == '-') || ((s->s_name[0] >= '0') && (s->s_name[0] <= '9')))
+ {
+ x->x_inner_double_value = strtod(s->s_name, &dummy);
+ symtodp_bang(x);
+ }
+}
+
+static void symtodp_list(t_symtodp *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(ac > 0)
+ {
+ x->x_inner_double_value = symtodp_calc_list_sum(ac, av);
+ // post("listtodp double: %.18g", x->x_inner_double_value);
+ symtodp_bang(x);
+ }
+}
+
+static void symtodp_anything(t_symtodp *x, t_symbol *s, int ac, t_atom *av)
+{
+ char *dummy;
+
+ if((s->s_name[0] == '"') && (s->s_name[1]))
+ {
+ if((s->s_name[1] == '.') || (s->s_name[1] == '+') || (s->s_name[1] == '-') || ((s->s_name[1] >= '0') && (s->s_name[1] <= '9')))
+ {
+ x->x_inner_double_value = strtod(s->s_name+1, &dummy);
+ symtodp_bang(x);
+ }
+ }
+}
+
+static void *symtodp_new(void)
+{
+ t_symtodp *x = (t_symtodp *)pd_new(symtodp_class);
+
+ x->x_inner_double_value = 0.0;
+ x->x_out_floatcasted = outlet_new(&x->x_obj, &s_float);
+ x->x_out_residual = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void symtodp_free(t_symtodp *x)
+{
+}
+
+void symtodp_setup(void)
+{
+ symtodp_class = class_new(gensym("symtodp"),
+ (t_newmethod)symtodp_new, (t_method)symtodp_free, sizeof(t_symtodp), 0, 0);
+ class_addbang(symtodp_class, symtodp_bang);
+ class_addfloat(symtodp_class, symtodp_float);
+ class_addsymbol(symtodp_class, symtodp_symbol);
+ class_addlist(symtodp_class, symtodp_list);
+ class_addanything(symtodp_class, symtodp_anything);
+}