static VALUE ffts_plan_initialize(VALUE self, VALUE rb_frames, VALUE rb_sign) { ffts_plan_t *plan; size_t n = RARRAY_LEN(rb_frames); if (!is_power_of_two(n)) { rb_raise(rb_eRuntimeError, "Frames must be a power of 2."); return Qnil; } int sign_v = NUM2INT(rb_sign); if (sign_v != -1 && sign_v != 1) { rb_raise(rb_eRuntimeError, "Sign must be 1 or -1."); return Qnil; } plan = ffts_init_1d(n, sign_v); VALUE rb_plan = Data_Wrap_Struct(cCPlan, NULL, ffts_free, plan); rb_funcall(self, rb_intern("n="), 1, INT2NUM(n)); rb_funcall(self, rb_intern("frames="), 1, rb_frames); rb_funcall(self, rb_intern("sign="), 1, rb_sign); rb_funcall(self, rb_intern("plan="), 1, rb_plan); return self; }
int test_transform(int n, int sign) { #ifdef HAVE_SSE float __attribute__ ((aligned(32))) *input = _mm_malloc(2 * n * sizeof(float), 32); float __attribute__ ((aligned(32))) *output = _mm_malloc(2 * n * sizeof(float), 32); #else float __attribute__ ((aligned(32))) *input = valloc(2 * n * sizeof(float)); float __attribute__ ((aligned(32))) *output = valloc(2 * n * sizeof(float)); #endif int i; for(i=0;i<n;i++) { input[2*i] = 0.0f; input[2*i+1] = 0.0f; } input[2] = 1.0f; ffts_plan_t *p = ffts_init_1d(i, sign); if(p) { ffts_execute(p, input, output); printf(" %3d | %9d | %10E\n", sign, n, impulse_error(n, sign, output)); ffts_free(p); }else{ printf("Plan unsupported\n"); return 0; } return 1; }
int main(int argc, char *argv[]) { if(argc == 3) { // test specific transform with test pattern and display output int n = atoi(argv[1]); int sign = atoi(argv[2]); #ifdef HAVE_SSE float __attribute__ ((aligned(32))) *input = _mm_malloc(2 * n * sizeof(float), 32); float __attribute__ ((aligned(32))) *output = _mm_malloc(2 * n * sizeof(float), 32); #else float __attribute__ ((aligned(32))) *input = valloc(2 * n * sizeof(float)); float __attribute__ ((aligned(32))) *output = valloc(2 * n * sizeof(float)); #endif int i; for(i=0;i<n;i++) { input[2*i] = i; input[2*i+1] = 0.0f; } // input[2] = 1.0f; ffts_plan_t *p = ffts_init_1d(i, sign); if(p) { ffts_execute(p, input, output); for(i=0;i<n;i++) printf("%d %d %f %f\n", i, sign, output[2*i], output[2*i+1]); ffts_free(p); }else{ printf("Plan unsupported\n"); return 0; } #ifdef HAVE_NEON _mm_free(input); _mm_free(output); #else free(input); free(output); #endif }else{
FFTSEngine::FFTSEngine() : m_currentplan(ffts_init_1d(1024, -1)) { allocate(8192); }
void FFTSEngine::configure(int n, bool inverse) { ffts_free(m_currentplan); m_currentplan = ffts_init_1d(n, inverse ? 1 : -1); }
ffts_plan_t *ffts_init_nd_real(int rank, size_t *Ns, int sign) { size_t vol = 1; size_t bufsize; ffts_plan_t *p = malloc(sizeof(ffts_plan_t)); if(sign < 0) p->transform = &ffts_execute_nd_real; else p->transform = &ffts_execute_nd_real_inv; p->destroy = &ffts_free_nd_real; p->rank = rank; p->Ns = malloc(sizeof(size_t) * rank); p->Ms = malloc(sizeof(size_t) * rank); p->plans = malloc(sizeof(ffts_plan_t **) * rank); int i; for(i=0;i<rank;i++) { p->Ns[i] = Ns[i]; vol *= Ns[i]; } //There is probably a prettier way of doing this, but it works.. if(sign < 0) { bufsize = 2 * vol; } else { bufsize = 2 * (Ns[0] * ((vol / Ns[0]) / 2 + 1) + vol); } p->buf = valloc(sizeof(float) * bufsize); for(i=0;i<rank;i++) { p->Ms[i] = vol / p->Ns[i]; p->plans[i] = NULL; int k; if(sign < 0) { for(k=1;k<i;k++) { if(p->Ms[k] == p->Ms[i]) p->plans[i] = p->plans[k]; } if(!i) p->plans[i] = ffts_init_1d_real(p->Ms[i], sign); else if(!p->plans[i]) p->plans[i] = ffts_init_1d(p->Ms[i], sign); }else{ for(k=0;k<i;k++) { if(p->Ns[k] == p->Ns[i]) p->plans[i] = p->plans[k]; } if(i==rank-1) p->plans[i] = ffts_init_1d_real(p->Ns[i], sign); else if(!p->plans[i]) p->plans[i] = ffts_init_1d(p->Ns[i], sign); } } if(sign < 0) { for(i=1;i<rank;i++) { p->Ns[i] = p->Ns[i] / 2 + 1; } }else{ for(i=0;i<rank-1;i++) { p->Ms[i] = p->Ms[i] / 2 + 1; } } p->transpose_buf = valloc(sizeof(float) * 2 * 8 * 8); return p; }