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

« back to all changes in this revision

Viewing changes to deltas.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
/*--------------- deltas ---------------*/
 
4
 
 
5
static t_class *deltas_class;
 
6
 
 
7
typedef struct _deltas
 
8
{
 
9
    t_object x_obj;
 
10
        float m_lo;
 
11
        float m_hi;
 
12
        int m_buffer_size;
 
13
        int m_buffer_index;
 
14
        float *m_buffer;  // circular buffer
 
15
} t_deltas;
 
16
 
 
17
 
 
18
static void deltas_perform_float(t_deltas *x, t_float f)
 
19
{
 
20
        int index;
 
21
        index=x->m_buffer_index+1;
 
22
        index=(index==x->m_buffer_size)?0:index;
 
23
        x->m_buffer_index=index;
 
24
        x->m_buffer[index]=f;
 
25
}
 
26
 
 
27
static void deltas_bang(t_deltas *x)
 
28
{
 
29
        int lo,hi,n,index,size;
 
30
        t_atom *ap,*app;
 
31
        float last;
 
32
        float *buffer, *bp;
 
33
 
 
34
        lo=(int)x->m_lo;
 
35
        hi=(int)x->m_hi;
 
36
 
 
37
        n=hi-lo;
 
38
        size=x->m_buffer_size;
 
39
        index=x->m_buffer_index;
 
40
    ap = (t_atom *)getbytes(sizeof(t_atom)*n);
 
41
        app=ap;
 
42
        buffer=x->m_buffer;
 
43
        last=buffer[index];
 
44
        bp=buffer+index-lo;
 
45
        bp=(bp>=buffer)?bp:bp+size; // wrap
 
46
        
 
47
        if (bp-buffer>=n)
 
48
        { // no wrap-around needed
 
49
                index=n;
 
50
                while(index--){
 
51
                  SETFLOAT(app, last-*bp--);
 
52
                  app++;
 
53
                }
 
54
//              post("not wrapped, app-ap=%i",app-ap);
 
55
        }
 
56
        else // need to wrap
 
57
        {
 
58
                int ps, nn;
 
59
                ps = bp-buffer;
 
60
                nn=n;
 
61
//              post("        nn=%i",nn);
 
62
                for(;ps>=0;ps--)  // don't we miss one sample in signal??? 
 
63
                {
 
64
//                      post("ps=%i",ps);
 
65
                        SETFLOAT(app, last-buffer[ps]);
 
66
                        app++;
 
67
                        nn--;
 
68
                }
 
69
                ps=size-1;
 
70
//              post("       nn=%i",nn);
 
71
                for(;nn>0;nn--)
 
72
                {
 
73
//                      post("ps=%i",ps);
 
74
                        SETFLOAT(app, last-buffer[ps--]);
 
75
                        app++;
 
76
                }
 
77
 
 
78
/*
 
79
                int i2;
 
80
                index=bp-buffer;
 
81
                i2=index;
 
82
                post("first part %i",index);
 
83
                while(index--){
 
84
                  SETFLOAT(app, last-*bp--);
 
85
                  app++;
 
86
                }
 
87
                index=n-i2;
 
88
                post("2nd part %i",index);
 
89
                bp=buffer+size-1;
 
90
                while(index--){
 
91
                  SETFLOAT(app, last-*bp--);
 
92
                  app++;
 
93
                }
 
94
*/
 
95
//              post("wrapped, app-ap=%i",app-ap);
 
96
        }
 
97
 
 
98
        outlet_list(x->x_obj.ob_outlet,gensym("list"),n,ap);
 
99
        freebytes(ap, sizeof(t_atom)*n);
 
100
}
 
101
 
 
102
static void deltas_clear(t_deltas *x)
 
103
{
 
104
        int i,s;
 
105
        float *f;
 
106
        f=x->m_buffer;
 
107
        s=x->m_buffer_size;
 
108
        for (i=0;i<s;i++)
 
109
                *f++=0.0f;
 
110
}
 
111
 
 
112
static void deltas_set(t_deltas *x, t_float lo, t_float hi, t_float size)
 
113
{
 
114
        if (size<1)
 
115
        {
 
116
                size=1;
 
117
                post("deltas: size is minimum 1...");
 
118
        }
 
119
        if (hi>size)
 
120
        {
 
121
                post("deltas: higher bound cannot be higher than the buffer size...");  
 
122
                hi=size;
 
123
        }
 
124
        if (lo<0)
 
125
        {
 
126
                post("deltas: lower bound cannot be negative...");      
 
127
                lo=0;
 
128
        }
 
129
        if (hi<1)
 
130
        {
 
131
                post("deltas: higher bound cannot be smaller than one...");     
 
132
                hi=1;
 
133
        }
 
134
        if (hi<=lo)
 
135
        {
 
136
                post("deltas: higher bound must be higher than lower bound...");        
 
137
                lo=hi-1.0f;
 
138
        }
 
139
 
 
140
        freebytes(x->m_buffer, x->m_buffer_size);
 
141
 
 
142
        x->m_hi=(float)((int)hi);
 
143
        x->m_lo=(float)((int)lo);
 
144
        x->m_buffer_size=(int)size;
 
145
    x->m_buffer = (float*)getbytes(sizeof(float)*x->m_buffer_size);
 
146
        deltas_clear(x);
 
147
        x->m_buffer_index=0;
 
148
}
 
149
 
 
150
static void *deltas_new(t_float lo, t_float hi, t_float size)
 
151
{
 
152
        t_deltas *x=(t_deltas *)pd_new(deltas_class);
 
153
        outlet_new(&x->x_obj, gensym("list"));
 
154
        x->m_buffer_size=0;
 
155
        x->m_buffer=0;
 
156
        deltas_set(x, lo, hi, size);
 
157
 
 
158
    floatinlet_new(&x->x_obj, &x->m_lo);
 
159
    floatinlet_new(&x->x_obj, &x->m_hi);
 
160
 
 
161
        return (void *)x;
 
162
}
 
163
 
 
164
static void deltas_free(t_deltas *x)
 
165
{
 
166
        freebytes(x->m_buffer, x->m_buffer_size);
 
167
}
 
168
 
 
169
void deltas_setup(void)
 
170
{
 
171
    deltas_class = class_new(gensym("deltas"),
 
172
        (t_newmethod)deltas_new, (t_method)deltas_free,
 
173
                sizeof(t_deltas), 
 
174
                CLASS_DEFAULT,
 
175
            A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT,0);
 
176
 
 
177
        class_addmethod(deltas_class, (t_method)deltas_clear, gensym("clear"),0);
 
178
    class_addfloat(deltas_class, (t_method)deltas_perform_float);
 
179
    class_addbang(deltas_class, (t_method)deltas_bang);
 
180
}
 
181