void DFT::resize(uint32_t newWindowSize, uint32_t newPadSize){ //printf("DFT::resize()\n"); if(0 == newWindowSize && 0 == newPadSize) return; uint32_t oldDFTSize = sizeDFT(); uint32_t newDFTSize = newWindowSize + newPadSize; uint32_t oldFrqSize = oldDFTSize+2; // 2 extra for DC/Nyquist imaginary uint32_t newFrqSize = newDFTSize+2; // " if(mem::resize(mBuf, oldFrqSize, newFrqSize)){ mBufInv = mBuf; if(mAux) mem::resize(mAux, oldFrqSize, newFrqSize); mFFT.resize(newDFTSize); mem::deepZero(mBuf, newFrqSize); } mem::resize(mPadOA, sizePad(), newPadSize); mem::deepZero(mPadOA, newPadSize); mSizeDFT = newDFTSize; mSizeWin = newWindowSize; mSizeHop = mSizeWin; onResync(1); }
void DFT::forward(const float * src){ //printf("DFT::forward(const float *)\n"); if(src != bufPos()) mem::deepCopy(bufPos(), src, sizeWin()); mem::deepZero(bufPos() + sizeWin(), sizePad()); // zero pad mFFT.forward(mBuf, true, true); // complex buffer and normalize // // do a mem move rather than offsetting input buffer pointer... // if(src != mBuf) mem::deepCopy(mBuf, src, sizeWin()); // mem::deepZero(mBuf + sizeWin(), sizePad()); // zero pad // //... do zero-phase window (rotate buffer 180) // // mFFT.forward(mBuf); // // // re-arrange DC and Nyquist bins // mem::deepMove(mBuf+2, mBuf+1, sizeDFT()-1); // mBuf[1] = 0.f; // mBuf[numBins()*2-1] = 0.f; switch(mSpctFormat){ case COMPLEX: break; case MAG_PHASE: case MAG_FREQ: CART_TO_POL break; default:; } }
void DFT::inverse(float * dst){ //printf("DFT::inverse(float *)\n"); switch(mSpctFormat){ case COMPLEX: break; case MAG_PHASE: case MAG_FREQ: POL_TO_CART break; } mFFT.inverse(mBuf, true); // overlap-add inverse window with prev spill if(sizePad() > 0){ arr::add(bufPos(), mPadOA, scl::min(sizePad(), sizeWin())); // add prev spill if(sizePad() <= sizeWin()){ // no spill overlap mem::deepCopy(mPadOA, bufPos() + sizeWin(), sizePad()); // save current spill } else{ // spill overlaps // add and save current spill to previous arr::add(mPadOA, bufPos() + sizeWin(), mPadOA + sizeWin(), sizePad() - sizeWin()); mem::deepCopy(mPadOA + sizePad() - sizeWin(), bufPos() + sizePad(), sizeWin()); } } if(dst) mem::deepCopy(dst, bufPos(), sizeWin()); // // arrange/scale bins for inverse xfm // // TODO: can we avoid this move by pointer offsetting? // mem::deepMove(mBuf+1, mBuf+2, sizeDFT()-1); // //slice(mBuf+1, sizeDFT()-2) *= 0.5f; // // mFFT.inverse(mBuf); // // // o.a. inverse window with prev spill // if(sizePad() > 0){ // arr::add(mBuf, mPadOA, scl::min(sizePad(), sizeWin())); // add prev spill // // if(sizePad() <= sizeWin()){ // no spill overlap // mem::deepCopy(mPadOA, mBuf + sizeWin(), sizePad()); // save current spill // } // else{ // spill overlaps // // add and save current spill to previous // arr::add(mPadOA, mBuf + sizeWin(), mPadOA + sizeWin(), sizePad() - sizeWin()); // mem::deepCopy(mPadOA + sizePad() - sizeWin(), mBuf + sizePad(), sizeWin()); // } // } // // if(dst) mem::deepCopy(dst, mBuf, sizeWin()); }
void DFT::forward(const float * src){ //printf("DFT::forward(const float *)\n"); if(src) mem::deepCopy(bufFwdPos(), src, sizeWin()); mem::deepZero(bufFwdPos() + sizeWin(), sizePad()); // zero pad mFFT.forward(bufFwdFrq(), true, true); // complex buffer and normalize switch(mSpctFormat){ case COMPLEX: break; case MAG_PHASE: case MAG_FREQ: CART_TO_POL(mBins) break; default:; } }
void DFT::inverse(float * dst){ //printf("DFT::inverse(float *)\n"); // operate on copy of bins if(MAG_FREQ != mSpctFormat){ mem::deepCopy(bufInvFrq(), bufFwdFrq(), sizeDFT()+2); } switch(mSpctFormat){ case COMPLEX: break; case MAG_PHASE: case MAG_FREQ: { Complex<float> * bins = mBins+numBins(); POL_TO_CART(bins) } break; } mFFT.inverse(bufInvFrq(), true); // overlap-add inverse window with prev spill if(sizePad() > 0){ // add spill from previous transform arr::add(bufInvPos(), mPadOA, scl::min(sizePad(), sizeWin())); // no spill overlap if(sizePad() <= sizeWin()){ // copy current spill into overlap-add buffer mem::deepCopy(mPadOA, bufInvPos() + sizeWin(), sizePad()); } // spill overlaps else{ // add and save current spill to previous arr::add(mPadOA, bufInvPos() + sizeWin(), mPadOA + sizeWin(), sizePad() - sizeWin()); mem::deepCopy(mPadOA + sizePad() - sizeWin(), bufInvPos() + sizePad(), sizeWin()); } } if(dst) mem::deepCopy(dst, bufInvPos(), sizeWin()); }
void DFT::forward(const float * window){ //printf("DFT::forward(const float *)\n"); // this attempts to avoid a memory move, but doesn't work when window == mBuf // if(window != mBuf) mem::deepCopy(mBuf+1, window, sizeWin()); // mem::deepZero(mBuf+1 + sizeWin(), sizePad()); // zero pad // // TODO: zero-phase window (rotate buffer 180) // // mFFT.forward(mBuf+1, true); // // // re-arrange DC and Nyquist bins // mBuf[0] = mBuf[1]; // mBuf[1] = 0.f; // mBuf[numBins()*2-1] = 0.f; // old code which did a mem move, rather offsetting input buffer pointer... if(window != mBuf) mem::deepCopy(mBuf, window, sizeWin()); mem::deepZero(mBuf + sizeWin(), sizePad()); // zero pad //... do zero-phase window (rotate buffer 180) mFFT.forward(mBuf, true); // re-arrange DC and Nyquist bins mem::deepMove(mBuf+2, mBuf+1, sizeDFT()-1); mBuf[1] = 0.f; mBuf[numBins()*2-1] = 0.f; switch(mSpctFormat){ case Bin::Polar: case Bin::MagFreq: RECT_POLAR //arr::mul(bins0(), gen::val(normForward()), nbins); break; default:; // rectangular //arr::mul(bins0(), gen::val(normForward()), nbins<<1); } }
void DFT::inverse(float * output){ //printf("DFT::inverse(float *)\n"); switch(mSpctFormat){ case Bin::Polar: case Bin::MagFreq: //arr::mul(bins0(), gen::val(normInverse()), nbins); POLAR_RECT break; default:; //arr::mul(bins0(), gen::val(normInverse()), nbins<<1); } // arrange/scale bins for inverse xfm // TODO: can we avoid this move by pointer offsetting? mem::deepMove(mBuf+1, mBuf+2, sizeDFT()-1); slice(mBuf+1, sizeDFT()-2) *= 0.5f; mFFT.inverse(mBuf); // o.a. inverse window with prev spill if(sizePad() > 0){ arr::add(mBuf, mPadOA, scl::min(sizePad(), sizeWin())); // add prev spill if(sizePad() <= sizeWin()){ // no spill overlap mem::deepCopy(mPadOA, mBuf + sizeWin(), sizePad()); // save current spill } else{ // spill overlaps // add and save current spill to previous arr::add(mPadOA, mBuf + sizeWin(), mPadOA + sizeWin(), sizePad() - sizeWin()); mem::deepCopy(mPadOA + sizePad() - sizeWin(), mBuf + sizePad(), sizeWin()); } } if(output) mem::deepCopy(output, mBuf, sizeWin()); }