~ubuntu-branches/ubuntu/saucy/pd-smlib/saucy

« back to all changes in this revision

Viewing changes to vvconv.c

  • Committer: Bazaar Package Importer
  • Author(s): Hans-Christoph Steiner
  • Date: 2010-11-10 15:17:58 UTC
  • Revision ID: james.westby@ubuntu.com-20101110151758-3acjf69kiudo3gh4
Tags: upstream-0.12.1
ImportĀ upstreamĀ versionĀ 0.12.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "defines.h"
 
2
 
 
3
/*--------------- vvconv ---------------*/
 
4
/* vector convolution
 
5
*/
 
6
 
 
7
static t_class *vvconv_class;
 
8
static t_class *vvconv_scal_class;
 
9
 
 
10
typedef struct _vvconv
 
11
{
 
12
  t_object x_obj;
 
13
 
 
14
  t_int n1, n2;
 
15
 
 
16
  t_float *buf1, *buf2;
 
17
 
 
18
  t_float f;
 
19
} t_vvconv;
 
20
 
 
21
 
 
22
static void vvconv_lst2(t_vvconv *x, t_symbol *s, int argc, t_atom *argv)
 
23
{
 
24
  t_float *fp;
 
25
  if (x->n2 != argc) {
 
26
    freebytes(x->buf2, x->n2 * sizeof(t_float));
 
27
    x->n2 = argc;
 
28
    x->buf2=(t_float *)getbytes(sizeof(t_float)*x->n2);
 
29
  };
 
30
  fp = x->buf2;
 
31
  while(argc--)*fp++=atom_getfloat(argv++);
 
32
}
 
33
 
 
34
static void vvconv_lst(t_vvconv *x, t_symbol *s, int argc, t_atom *argv)
 
35
{
 
36
  t_float *fp;
 
37
  t_atom  *ap;
 
38
  int n;
 
39
 
 
40
  if (argc){
 
41
    if (x->n1 != argc) {
 
42
      freebytes(x->buf1, x->n1 * sizeof(t_float));
 
43
      x->n1 = argc;
 
44
      x->buf1=(t_float *)getbytes(sizeof(t_float)*x->n1);
 
45
    };
 
46
    fp = x->buf1;
 
47
    while(argc--)*fp++=atom_getfloat(argv++);
 
48
  }
 
49
 
 
50
  if (x->n1*x->n2==1){
 
51
    outlet_float(x->x_obj.ob_outlet, *x->buf1**x->buf2);
 
52
    return;
 
53
  }
 
54
  if (x->n1==1){
 
55
    t_atom *a;
 
56
    int i = x->n2;
 
57
    t_float f = *x->buf1;
 
58
    fp = x->buf2;
 
59
    n = x->n2;
 
60
    ap = (t_atom *)getbytes(sizeof(t_atom)*n);
 
61
    a = ap;
 
62
    while(i--){
 
63
      SETFLOAT(a, *fp++*f);
 
64
      a++;
 
65
    }
 
66
  } else if (x->n2==1){
 
67
    t_float f = *x->buf2;
 
68
    t_atom *a;
 
69
    int i = x->n1;
 
70
    n = x->n1;
 
71
    ap = (t_atom *)getbytes(sizeof(t_atom)*n);
 
72
    a = ap;
 
73
    fp = x->buf1;
 
74
    while(i--){
 
75
      SETFLOAT(a, *fp++*f);
 
76
      a++;
 
77
    }
 
78
  } else {
 
79
    t_atom *a;
 
80
    int i,j,n1,n2;
 
81
        t_float *f;
 
82
        t_float *g;
 
83
    t_float *fp2=x->buf2;
 
84
    fp = x->buf1;
 
85
        n1=x->n1;
 
86
        n2=x->n2;
 
87
    n = n1 + n2 - 1;
 
88
    f = (t_float *)getbytes(sizeof(t_float)*n);
 
89
        g=f;
 
90
        for(i=0;i<n;i++)
 
91
                *g++=0.0f;
 
92
        for(i=0;i<n1;i++)
 
93
                for(j=0;j<n2;j++)
 
94
                        f[i+j]+=fp[i]*fp2[j];
 
95
 
 
96
        g=f;
 
97
    ap = (t_atom *)getbytes(sizeof(t_atom)*n);
 
98
    a = ap;
 
99
    i=n;
 
100
    while(i--){
 
101
      SETFLOAT(a, *g++);
 
102
      a++;
 
103
    }
 
104
    freebytes(f,sizeof(float)*n);
 
105
  }
 
106
  outlet_list(x->x_obj.ob_outlet, gensym("list"), n, ap);
 
107
  freebytes(ap, sizeof(t_atom)*n);
 
108
}
 
109
static void vvconv_free(t_vvconv *x)
 
110
{
 
111
  freebytes(x->buf1, sizeof(t_float)*x->n1);
 
112
  freebytes(x->buf2, sizeof(t_float)*x->n2);
 
113
}
 
114
 
 
115
static void *vvconv_new(t_symbol *s, int argc, t_atom *argv)
 
116
{
 
117
  t_vvconv *x;
 
118
 
 
119
  if (argc-1){
 
120
    x = (t_vvconv *)pd_new(vvconv_class);
 
121
    inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("list"), gensym(""));
 
122
  } else x = (t_vvconv *)pd_new(vvconv_scal_class);
 
123
 
 
124
  outlet_new(&x->x_obj, 0);
 
125
 
 
126
  x->n1   =1;
 
127
  x->buf1 =(t_float*)getbytes(sizeof(t_float));
 
128
  *x->buf1=0;
 
129
 
 
130
  if (argc)vvconv_lst2(x, gensym("list"), argc, argv);
 
131
  else {
 
132
    x->n2   =1;
 
133
    x->buf2 =(t_float*)getbytes(sizeof(t_float));
 
134
    *x->buf2=0;
 
135
  }
 
136
 
 
137
  if (argc==1)floatinlet_new(&x->x_obj, x->buf2);
 
138
 
 
139
  return (x);
 
140
}
 
141
 
 
142
void vvconv_setup(void)
 
143
{
 
144
  vvconv_class = class_new(gensym("vvconv"), (t_newmethod)vvconv_new, 
 
145
                            (t_method)vvconv_free, sizeof(t_vvconv), 0, A_GIMME, 0);
 
146
  class_addlist(vvconv_class, vvconv_lst);
 
147
  class_addmethod  (vvconv_class, (t_method)vvconv_lst2, gensym(""), A_GIMME, 0);
 
148
  vvconv_scal_class = class_new(gensym("vv+"), 0, (t_method)vvconv_free, 
 
149
                                 sizeof(t_vvconv), 0, 0);
 
150
  class_addlist(vvconv_scal_class, vvconv_lst);
 
151
}