// Insert a new vertex static void insert_vert(TriMesh *mesh, int scheme, int f, int e) { int v1 = mesh->faces[f][NEXT(e)], v2 = mesh->faces[f][PREV(e)]; if (scheme == SUBDIV_PLANAR) { point p = 0.5f * (mesh->vertices[v1] + mesh->vertices[v2]); mesh->vertices.push_back(p); return; } int ae = mesh->across_edge[f][e]; if (ae == -1) { // Boundary point p = 0.5f * (mesh->vertices[v1] + mesh->vertices[v2]); if (scheme == SUBDIV_BUTTERFLY || scheme == SUBDIV_BUTTERFLY_MODIFIED) { p *= 1.5f; p -= 0.25f * (avg_bdy(mesh, v1) + avg_bdy(mesh, v2)); } mesh->vertices.push_back(p); return; } int v0 = mesh->faces[f][e]; const TriMesh::Face &aef = mesh->faces[ae]; int v3 = aef[NEXT(aef.indexof(v1))]; point p; if (scheme == SUBDIV_LOOP || scheme == SUBDIV_LOOP_ORIG) { p = loop(mesh, f, ae, v0, v1, v2, v3); } else if (scheme == SUBDIV_LOOP_NEW) { bool e1 = (mesh->adjacentfaces[v1].size() != 6); bool e2 = (mesh->adjacentfaces[v2].size() != 6); if (e1 && e2) p = 0.5f * (new_loop_edge(mesh, f, ae, v0, v1, v2, v3) + new_loop_edge(mesh, ae, f, v3, v2, v1, v0)); else if (e1) p = new_loop_edge(mesh, f, ae, v0, v1, v2, v3); else if (e2) p = new_loop_edge(mesh, ae, f, v3, v2, v1, v0); else p = loop(mesh, f, ae, v0, v1, v2, v3); } else if (scheme == SUBDIV_BUTTERFLY) { p = butterfly(mesh, f, ae, v0, v1, v2, v3); } else if (scheme == SUBDIV_BUTTERFLY_MODIFIED) { bool e1 = (mesh->adjacentfaces[v1].size() != 6); bool e2 = (mesh->adjacentfaces[v2].size() != 6); if (e1 && e2) p = 0.5f * (zorin_edge(mesh, f, ae, v0, v1, v2, v3) + zorin_edge(mesh, ae, f, v3, v2, v1, v0)); else if (e1) p = zorin_edge(mesh, f, ae, v0, v1, v2, v3); else if (e2) p = zorin_edge(mesh, ae, f, v3, v2, v1, v0); else p = butterfly(mesh, f, ae, v0, v1, v2, v3); } mesh->vertices.push_back(p); }
void OsakanaFft(const OsakanaFftContext_t* ctx, osk_complex_t* x) { for (int i = 0; i < ctx->bitReverseIndexTableLen; i++) { const osk_bitreverse_idx_pair_t* pair = &ctx->bitReverseIndexTable[i]; complex_swap(&x[pair->first], &x[pair->second]); } int dj = 2; int bnum = 1; // number of butterfly in 2nd loop int tw_idx_shift = ctx->log2N - 1; for (int i = 0; i < ctx->log2N; i++) { // j = 0,2,4,6 // j = 0,4 // j = 0 for (int j = 0; j < ctx->N; j += dj) { int idx_a = j; int idx_b = j + bnum; for (int k = 0; k < bnum; k++) { //osk_complex_t tf = twiddle(k, dj); //butterfly(&f[0], &tf, idx_a++, idx_b++); int tw_idx = k << tw_idx_shift; osk_complex_t tf = ctx->twiddles[tw_idx]; butterfly(&x[0], &tf, idx_a++, idx_b++); } } dj = dj << 1; bnum = bnum << 1; tw_idx_shift--; } }
/* Do FFT for 4096 points of data. * * Return the frequency which has the max response. */ int fft_4096( int16_t *data ) { int i, maxIndex; float maxResponse = 0.0; fft_input_init( data ); bit_reversal(); butterfly(); // Magnitude of complex number for ( i = 0; i < DATA_LENGTH; ++i ) { arm_sqrt_f32( fft_input[i].real * fft_input[i].real + fft_input[i].imag * fft_input[i].imag, &fft_input[i].real ); fft_input[i].real /= ( i == 0 ? DATA_LENGTH : DATA_LENGTH / 2 ); } // Find the max response index // Only care about the first half of the fft output for ( i = 0; i < HALF_DATA_LENGTH; ++i ) { if ( fft_input[i].real > maxResponse ) { maxResponse = fft_input[i].real; maxIndex = i; } } return (int)(2000 / 2 / 4096 * maxIndex); } // end of fft_4096()
// Compute Zorin's edge mask for an extraordinary vertex for // SUBDIV_BUTTERFLY_MODIFIED static point zorin_edge(TriMesh *mesh, int f1, int f2, int v0, int v1, int v2, int v3) { static const float wts[6][5] = { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0.4166667f, -0.08333333f, -0.08333333f, 0, 0 }, { 0.375f, 0, -0.125f, 0, 0 }, { 0.35f, 0.0309017f, -0.0809017f, -0.0809017f, 0.0309017f }, }; int n = mesh->adjacentfaces[v1].size(); if (n < 3) return butterfly(mesh, f1, f2, v0, v1, v2, v3); point p; float sumwts = 0.0f; int f = f1; float s1 = 1.0f / n; float s2 = M_TWOPIf * s1; for (int i = 0; i < n; i++) { int ind = mesh->faces[f].indexof(v1); if (ind == -1) return butterfly(mesh, f1, f2, v0, v1, v2, v3); ind = NEXT(ind); int v = mesh->faces[f][ind]; float wt; if (n < 6) { wt = wts[n][i]; } else { float c = cos(s2 * i); wt = s1 * (c*c + c - 0.25f); } p += wt * mesh->vertices[v]; sumwts += wt; f = mesh->across_edge[f][ind]; if (f == -1) return butterfly(mesh, f1, f2, v0, v1, v2, v3); } if (f != f1) return butterfly(mesh, f1, f2, v0, v1, v2, v3); return p + (1.0f - sumwts) * mesh->vertices[v1]; }
void JSArrayBufferView::finishCreation(VM& vm) { Base::finishCreation(vm); switch (m_mode) { case FastTypedArray: return; case OversizeTypedArray: vm.heap.addFinalizer(this, finalize); return; case WastefulTypedArray: vm.heap.addReference(this, butterfly()->indexingHeader()->arrayBuffer()); return; case DataViewMode: ASSERT(!butterfly()); vm.heap.addReference(this, jsCast<JSDataView*>(this)->buffer()); return; } RELEASE_ASSERT_NOT_REACHED(); }
void perform (const Complex<float>* input, Complex<float>* output, int stride, int strideIn, const Factor* facs) const noexcept { auto factor = *facs++; auto* originalOutput = output; auto* outputEnd = output + factor.radix * factor.length; if (stride == 1 && factor.radix <= 5) { for (int i = 0; i < factor.radix; ++i) perform (input + stride * strideIn * i, output + i * factor.length, stride * factor.radix, strideIn, facs); butterfly (factor, output, stride); return; } if (factor.length == 1) { do { *output++ = *input; input += stride * strideIn; } while (output < outputEnd); } else { do { perform (input, output, stride * factor.radix, strideIn, facs); input += stride * strideIn; output += factor.length; } while (output < outputEnd); } butterfly (factor, originalOutput, stride); }
void OsakanaIfft(const OsakanaFftContext_t* ctx, osk_complex_t* x) { for (int i = 0; i < ctx->bitReverseIndexTableLen; i++) { const osk_bitreverse_idx_pair_t* pair = &ctx->bitReverseIndexTable[i]; complex_swap(&x[pair->first], &x[pair->second]); } int dj = 2; int bnum = 1; int tw_idx_shift = ctx->log2N - 1; for (int i = 0; i < ctx->log2N; i++) { for (int j = 0; j < ctx->N; j += dj) { int idx_a = j; int idx_b = j + bnum; for (int k = 0; k < bnum; k++) { /*osk_complex_t tf = twiddle(k, dj); tf.im = -tf.im; butterfly(&f[0], &tf, idx_a++, idx_b++);*/ int tw_idx = k << tw_idx_shift; osk_complex_t tf = ctx->twiddles[tw_idx]; tf.im = -tf.im; butterfly(&x[0], &tf, idx_a, idx_b); x[idx_a].re /= 2.0; x[idx_a].im /= 2.0; x[idx_b].re /= 2.0; x[idx_b].im /= 2.0; idx_a++; idx_b++; } } dj = dj << 1; bnum = bnum << 1; tw_idx_shift--; } }
void fft(double *rv, double *iv, int ln, // ln = log2 n double rw, double iw) { // (rw,iw) = nth root of unity int n = 1<<ln; double *rvn = rv+n; double *ivn = iv+n; int n2 = n>>1; int s, i, j; // First do the perfect shuffle reorder(rv, iv, n); // Then do all the butterfly operations for(s = 1; s<=ln; s++) { int m = 1<<s; int m2 = m>>1; double rwk=1; double iwk=0; double rwkfac=rw; double iwkfac=iw; for(i = s+1; i<=ln; i++) { rwkfac = rwkfac*rwkfac - iwkfac*iwkfac; iwkfac = rwkfac*iwkfac + iwkfac*rwkfac; } for(j = 0; j<m2; j++) { double *rp = rv+j; double *ip = iv+j; while(rp<rvn) { butterfly(rp, ip, rp+m2, ip+m2, rwk, iwk); rp += m; ip += m; } rwk = rwk*rwkfac - iwk*iwkfac; iwk = rwk*iwkfac + iwk*rwkfac; } } }