~ubuntu-branches/ubuntu/lucid/squeak-vm/lucid

« back to all changes in this revision

Viewing changes to platforms/unix/src/vm/intplugins/FFTPlugin/FFTPlugin.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2005-07-15 11:44:08 UTC
  • Revision ID: james.westby@ubuntu.com-20050715114408-lgcvpntigab09l00
Tags: upstream-3.7.7
ImportĀ upstreamĀ versionĀ 3.7.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Automatically generated from Squeak on #(19 March 2005 10:08:54 am) */
 
2
 
 
3
#include <math.h>
 
4
#include <stdio.h>
 
5
#include <stdlib.h>
 
6
#include <string.h>
 
7
#include <time.h>
 
8
 
 
9
/* Default EXPORT macro that does nothing (see comment in sq.h): */
 
10
#define EXPORT(returnType) returnType
 
11
 
 
12
/* Do not include the entire sq.h file but just those parts needed. */
 
13
/*  The virtual machine proxy definition */
 
14
#include "sqVirtualMachine.h"
 
15
/* Configuration options */
 
16
#include "sqConfig.h"
 
17
/* Platform specific definitions */
 
18
#include "sqPlatformSpecific.h"
 
19
 
 
20
#define true 1
 
21
#define false 0
 
22
#define null 0  /* using 'null' because nil is predefined in Think C */
 
23
#ifdef SQUEAK_BUILTIN_PLUGIN
 
24
#undef EXPORT
 
25
// was #undef EXPORT(returnType) but screws NorCroft cc
 
26
#define EXPORT(returnType) static returnType
 
27
#endif
 
28
 
 
29
/* memory access macros */
 
30
#define byteAt(i) (*((unsigned char *) (i)))
 
31
#define byteAtput(i, val) (*((unsigned char *) (i)) = val)
 
32
#define longAt(i) (*((int *) (i)))
 
33
#define longAtput(i, val) (*((int *) (i)) = val)
 
34
 
 
35
 
 
36
/*** Constants ***/
 
37
 
 
38
/*** Function Prototypes ***/
 
39
static float * checkedFloatPtrOf(int oop);
 
40
static unsigned int * checkedWordPtrOf(int oop);
 
41
#pragma export on
 
42
EXPORT(const char*) getModuleName(void);
 
43
#pragma export off
 
44
static int halt(void);
 
45
static int loadFFTFrom(int fftOop);
 
46
static int msg(char *s);
 
47
static int permuteData(void);
 
48
#pragma export on
 
49
EXPORT(int) primitiveFFTPermuteData(void);
 
50
EXPORT(int) primitiveFFTScaleData(void);
 
51
EXPORT(int) primitiveFFTTransformData(void);
 
52
#pragma export off
 
53
static int scaleData(void);
 
54
#pragma export on
 
55
EXPORT(int) setInterpreter(struct VirtualMachine* anInterpreter);
 
56
#pragma export off
 
57
static int transformData(int forward);
 
58
static int transformForward(int forward);
 
59
/*** Variables ***/
 
60
static int fftSize;
 
61
static float* imagData;
 
62
static int imagDataSize;
 
63
 
 
64
#ifdef SQUEAK_BUILTIN_PLUGIN
 
65
extern
 
66
#endif
 
67
struct VirtualMachine* interpreterProxy;
 
68
static const char *moduleName =
 
69
#ifdef SQUEAK_BUILTIN_PLUGIN
 
70
        "FFTPlugin 19 March 2005 (i)"
 
71
#else
 
72
        "FFTPlugin 19 March 2005 (e)"
 
73
#endif
 
74
;
 
75
static int nu;
 
76
static unsigned int* permTable;
 
77
static int permTableSize;
 
78
static float* realData;
 
79
static int realDataSize;
 
80
static float* sinTable;
 
81
static int sinTableSize;
 
82
 
 
83
 
 
84
 
 
85
/*      Return the first indexable word of oop which is assumed to be variableWordSubclass */
 
86
 
 
87
static float * checkedFloatPtrOf(int oop) {
 
88
        interpreterProxy->success(interpreterProxy->isWords(oop));
 
89
        if (interpreterProxy->failed()) {
 
90
                return 0;
 
91
        }
 
92
        return ((float *) (interpreterProxy->firstIndexableField(oop)));
 
93
}
 
94
 
 
95
 
 
96
/*      Return the first indexable word of oop which is assumed to be variableWordSubclass */
 
97
 
 
98
static unsigned int * checkedWordPtrOf(int oop) {
 
99
        interpreterProxy->success(interpreterProxy->isWords(oop));
 
100
        return ((unsigned int *) (interpreterProxy->firstIndexableField(oop)));
 
101
}
 
102
 
 
103
 
 
104
/*      Note: This is hardcoded so it can be run from Squeak.
 
105
        The module name is used for validating a module *after*
 
106
        it is loaded to check if it does really contain the module
 
107
        we're thinking it contains. This is important! */
 
108
 
 
109
EXPORT(const char*) getModuleName(void) {
 
110
        return moduleName;
 
111
}
 
112
 
 
113
static int halt(void) {
 
114
        ;
 
115
}
 
116
 
 
117
static int loadFFTFrom(int fftOop) {
 
118
    int oop;
 
119
 
 
120
        interpreterProxy->success((interpreterProxy->slotSizeOf(fftOop)) >= 6);
 
121
        if (interpreterProxy->failed()) {
 
122
                return 0;
 
123
        }
 
124
        nu = interpreterProxy->fetchIntegerofObject(0, fftOop);
 
125
        fftSize = interpreterProxy->fetchIntegerofObject(1, fftOop);
 
126
        oop = interpreterProxy->fetchPointerofObject(2, fftOop);
 
127
        sinTableSize = interpreterProxy->stSizeOf(oop);
 
128
        /* begin checkedFloatPtrOf: */
 
129
        interpreterProxy->success(interpreterProxy->isWords(oop));
 
130
        if (interpreterProxy->failed()) {
 
131
                sinTable = 0;
 
132
                goto l1;
 
133
        }
 
134
        sinTable = ((float *) (interpreterProxy->firstIndexableField(oop)));
 
135
l1:     /* end checkedFloatPtrOf: */;
 
136
        oop = interpreterProxy->fetchPointerofObject(3, fftOop);
 
137
        permTableSize = interpreterProxy->stSizeOf(oop);
 
138
        /* begin checkedWordPtrOf: */
 
139
        interpreterProxy->success(interpreterProxy->isWords(oop));
 
140
        permTable = ((unsigned int *) (interpreterProxy->firstIndexableField(oop)));
 
141
        oop = interpreterProxy->fetchPointerofObject(4, fftOop);
 
142
        realDataSize = interpreterProxy->stSizeOf(oop);
 
143
        /* begin checkedFloatPtrOf: */
 
144
        interpreterProxy->success(interpreterProxy->isWords(oop));
 
145
        if (interpreterProxy->failed()) {
 
146
                realData = 0;
 
147
                goto l2;
 
148
        }
 
149
        realData = ((float *) (interpreterProxy->firstIndexableField(oop)));
 
150
l2:     /* end checkedFloatPtrOf: */;
 
151
        oop = interpreterProxy->fetchPointerofObject(5, fftOop);
 
152
        imagDataSize = interpreterProxy->stSizeOf(oop);
 
153
        /* begin checkedFloatPtrOf: */
 
154
        interpreterProxy->success(interpreterProxy->isWords(oop));
 
155
        if (interpreterProxy->failed()) {
 
156
                imagData = 0;
 
157
                goto l3;
 
158
        }
 
159
        imagData = ((float *) (interpreterProxy->firstIndexableField(oop)));
 
160
l3:     /* end checkedFloatPtrOf: */;
 
161
        interpreterProxy->success((((((1 << nu) == fftSize) && (((((int) fftSize >> 2)) + 1) == sinTableSize)) && (fftSize == realDataSize)) && (fftSize == imagDataSize)) && (realDataSize == imagDataSize));
 
162
        return (interpreterProxy->failed()) == 0;
 
163
}
 
164
 
 
165
static int msg(char *s) {
 
166
        fprintf(stderr, "\n%s: %s", moduleName, s);
 
167
}
 
168
 
 
169
static int permuteData(void) {
 
170
    int a;
 
171
    int end;
 
172
    int i;
 
173
    float tmp;
 
174
    int b;
 
175
 
 
176
        i = 0;
 
177
        end = permTableSize;
 
178
        while (i < end) {
 
179
                a = (permTable[i]) - 1;
 
180
                b = (permTable[i + 1]) - 1;
 
181
                if (!((a < realDataSize) && (b < realDataSize))) {
 
182
                        return interpreterProxy->success(0);
 
183
                }
 
184
                tmp = realData[a];
 
185
                realData[a] = (realData[b]);
 
186
                realData[b] = tmp;
 
187
                tmp = imagData[a];
 
188
                imagData[a] = (imagData[b]);
 
189
                imagData[b] = tmp;
 
190
                i += 2;
 
191
        }
 
192
}
 
193
 
 
194
EXPORT(int) primitiveFFTPermuteData(void) {
 
195
    int rcvr;
 
196
 
 
197
        rcvr = interpreterProxy->stackObjectValue(0);
 
198
        if (!(loadFFTFrom(rcvr))) {
 
199
                return null;
 
200
        }
 
201
        permuteData();
 
202
        if (interpreterProxy->failed()) {
 
203
                permuteData();
 
204
        }
 
205
}
 
206
 
 
207
EXPORT(int) primitiveFFTScaleData(void) {
 
208
    int rcvr;
 
209
 
 
210
        rcvr = interpreterProxy->stackObjectValue(0);
 
211
        if (!(loadFFTFrom(rcvr))) {
 
212
                return null;
 
213
        }
 
214
        scaleData();
 
215
}
 
216
 
 
217
EXPORT(int) primitiveFFTTransformData(void) {
 
218
    int forward;
 
219
    int rcvr;
 
220
 
 
221
        forward = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(0));
 
222
        rcvr = interpreterProxy->stackObjectValue(1);
 
223
        if (!(loadFFTFrom(rcvr))) {
 
224
                return null;
 
225
        }
 
226
        /* begin transformData: */
 
227
        permuteData();
 
228
        if (interpreterProxy->failed()) {
 
229
                permuteData();
 
230
                goto l1;
 
231
        }
 
232
        transformForward(forward);
 
233
        if (!(forward)) {
 
234
                scaleData();
 
235
        }
 
236
l1:     /* end transformData: */;
 
237
        if (!(interpreterProxy->failed())) {
 
238
                interpreterProxy->pop(1);
 
239
        }
 
240
}
 
241
 
 
242
 
 
243
/*      Scale all elements by 1/n when doing inverse */
 
244
 
 
245
static int scaleData(void) {
 
246
    float realN;
 
247
    int i;
 
248
 
 
249
        if (fftSize <= 1) {
 
250
                return null;
 
251
        }
 
252
        realN = ((float) (1.0 / (((double) fftSize))));
 
253
        for (i = 0; i <= (fftSize - 1); i += 1) {
 
254
                realData[i] = ((realData[i]) * realN);
 
255
                imagData[i] = ((imagData[i]) * realN);
 
256
        }
 
257
}
 
258
 
 
259
 
 
260
/*      Note: This is coded so that is can be run from Squeak. */
 
261
 
 
262
EXPORT(int) setInterpreter(struct VirtualMachine* anInterpreter) {
 
263
    int ok;
 
264
 
 
265
        interpreterProxy = anInterpreter;
 
266
        ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR;
 
267
        if (ok == 0) {
 
268
                return 0;
 
269
        }
 
270
        ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR;
 
271
        return ok;
 
272
}
 
273
 
 
274
static int transformData(int forward) {
 
275
        permuteData();
 
276
        if (interpreterProxy->failed()) {
 
277
                permuteData();
 
278
                return null;
 
279
        }
 
280
        transformForward(forward);
 
281
        if (!(forward)) {
 
282
                scaleData();
 
283
        }
 
284
}
 
285
 
 
286
static int transformForward(int forward) {
 
287
    int lev1;
 
288
    int theta;
 
289
    int fftSize4;
 
290
    int fftScale;
 
291
    int i;
 
292
    int ip;
 
293
    int lev;
 
294
    int fftSize2;
 
295
    float imagU;
 
296
    int level;
 
297
    int ii;
 
298
    float realT;
 
299
    int j;
 
300
    float realU;
 
301
    float imagT;
 
302
 
 
303
        fftSize2 = ((int) fftSize >> 1);
 
304
        fftSize4 = ((int) fftSize >> 2);
 
305
        for (level = 1; level <= nu; level += 1) {
 
306
                lev = ((level < 0) ? ((unsigned) 1 >> -level) : ((unsigned) 1 << level));
 
307
                lev1 = ((int) lev >> 1);
 
308
                fftScale = fftSize / lev;
 
309
                for (j = 1; j <= lev1; j += 1) {
 
310
 
 
311
                        /* pi * (j-1) / lev1 mapped onto 0..n/2 */
 
312
 
 
313
                        theta = (j - 1) * fftScale;
 
314
                        if (theta < fftSize4) {
 
315
                                realU = sinTable[(sinTableSize - theta) - 1];
 
316
                                imagU = sinTable[theta];
 
317
                        } else {
 
318
                                realU = 0.0 - (sinTable[theta - fftSize4]);
 
319
                                imagU = sinTable[fftSize2 - theta];
 
320
                        }
 
321
                        if (!(forward)) {
 
322
                                imagU = 0.0 - imagU;
 
323
                        }
 
324
                        i = j;
 
325
                        while (i <= fftSize) {
 
326
                                ip = (i + lev1) - 1;
 
327
                                ii = i - 1;
 
328
                                realT = ((realData[ip]) * realU) - ((imagData[ip]) * imagU);
 
329
                                imagT = ((realData[ip]) * imagU) + ((imagData[ip]) * realU);
 
330
                                realData[ip] = ((realData[ii]) - realT);
 
331
                                imagData[ip] = ((imagData[ii]) - imagT);
 
332
                                realData[ii] = ((realData[ii]) + realT);
 
333
                                imagData[ii] = ((imagData[ii]) + imagT);
 
334
                                i += lev;
 
335
                        }
 
336
                }
 
337
        }
 
338
}
 
339
 
 
340
 
 
341
#ifdef SQUEAK_BUILTIN_PLUGIN
 
342
 
 
343
 
 
344
void* FFTPlugin_exports[][3] = {
 
345
        {"FFTPlugin", "primitiveFFTScaleData", (void*)primitiveFFTScaleData},
 
346
        {"FFTPlugin", "primitiveFFTTransformData", (void*)primitiveFFTTransformData},
 
347
        {"FFTPlugin", "primitiveFFTPermuteData", (void*)primitiveFFTPermuteData},
 
348
        {"FFTPlugin", "getModuleName", (void*)getModuleName},
 
349
        {"FFTPlugin", "setInterpreter", (void*)setInterpreter},
 
350
        {NULL, NULL, NULL}
 
351
};
 
352
 
 
353
 
 
354
#endif /* ifdef SQ_BUILTIN_PLUGIN */
 
355