6 newPowerSpectrum(int size, SPECTRUMTYPE type) {
7 PWS p = (PWS) safealloc(1, sizeof(powerspectrum), "New Power Spectrum");
9 p->buf.win = newRLB(size, NULL, "Power Spectrum Window Buffer");
10 p->buf.res = newRLB(32768, NULL, "Save buffer");
11 p->buf.wdat = newCXB(size, NULL, "Power Spectrum Windowed Signal buffer");
12 p->buf.zdat = newCXB(size, NULL, "Power Spectrum FFT Results Buffer");
16 makewindow(BLACKMANHARRIS_WINDOW, size, RLBbase(p->buf.win));
20 REAL *tmp = (REAL *) alloca(size * sizeof(REAL));
21 int n = size / 2, nb = n * sizeof(REAL);
22 memcpy(&tmp[n], RLBbase(p->buf.win), nb);
23 memcpy(tmp, &RLBdata(p->buf.win, n), nb);
27 p->fft.plan = fftw_create_plan(size, FFTW_FORWARD, uni.wisdom.bits);
33 delPowerSpectrum(PWS pws) {
34 delCXB(pws->buf.wdat);
35 delCXB(pws->buf.zdat);
37 delRLB(pws->buf.win2);
38 fftw_destroy_plan(pws->fft.plan);
39 safefree((char *) pws);
43 process_spectrum(float *results) {
44 int i, j, n = CXBsize(uni.powsp.buf);
46 if (getChan_nowait(uni.powsp.chan.c,
47 (char *) CXBbase(uni.powsp.buf),
48 uni.powsp.fft.size * sizeof(COMPLEX))
51 // Window the data to minimize "splatter" in the powerspectrum
52 for (i = 0; i < uni.powsp.fft.size; i++)
53 CXBdata(uni.powsp.gen->buf.wdat, i) = Cscl(CXBdata(uni.powsp.buf, i),
54 RLBdata(uni.powsp.gen->buf.win, i));
57 fftw_one(uni.powsp.gen->fft.plan,
58 (fftw_complex *) CXBbase(uni.powsp.gen->buf.wdat),
59 (fftw_complex *) CXBbase(uni.powsp.gen->buf.zdat));
60 for (i = 0; i < n / 2; i++) {
61 RLBdata(uni.powsp.gen->buf.res, 8 * i) =
65 Csqrmag(CXBdata(uni.powsp.gen->buf.zdat,
67 RLBdata(uni.powsp.gen->buf.res, 8 * (i + uni.buflen)) =
68 results[8 * (i + uni.buflen)] =
71 Csqrmag(CXBdata(uni.powsp.gen->buf.zdat, i))));
74 // Interpolate for display on high resolution monitors
76 for (i = 0; i < 32768; i += 8)
77 for (j = 1; j < 8; j++)
78 RLBdata(uni.powsp.gen->buf.res, i + j) =
79 results[i + j] = (float) 0.125 * (results[i] * (float) (8 - j)
80 + results[i + 8] * (float) j);
83 for (i = 0; i < 32768; i++)
84 results[i] = (float) RLBdata(uni.powsp.gen->buf.res, i);
90 process_phase(float *results, int numpoints) {
92 if (getChan_nowait(uni.powsp.chan.c,
93 (char *) CXBbase(uni.powsp.buf),
94 uni.powsp.fft.size * sizeof(COMPLEX))
96 for (i = 0, j = 0; i < numpoints; i++, j += 2) {
97 RLBdata(uni.powsp.gen->buf.res, j) =
98 results[j] = (float) CXBreal(uni.powsp.buf, i);
99 RLBdata(uni.powsp.gen->buf.res, j + 1) =
100 results[j + 1] = (float) CXBimag(uni.powsp.buf, i);
103 for (i = 0; i < 2 * numpoints; i++)
104 results[i] = (float) RLBdata(uni.powsp.gen->buf.res, i);
109 // Send out Real Signal, reals only
112 process_scope(float *results) {
114 if (getChan_nowait(uni.powsp.chan.c,
115 (char *) CXBbase(uni.powsp.buf),
116 uni.powsp.fft.size * sizeof(COMPLEX))
118 for (i = 0; i < uni.powsp.fft.size; i++) {
119 results[i] = (float) CXBreal(uni.powsp.buf, i);
122 for (i = 0; i < uni.powsp.fft.size; i++)
123 results[i] = (float) CXBreal(uni.powsp.buf, i);