示例#1
0
文件: DFT.cpp 项目: LuaAV/LuaAV
// input is sizeWin
void STFT::forward(float * input){ //printf("STFT::forward(float *)\n");

	arr::mul(input, mFwdWin, sizeWin());	// apply forward window
	if(mRotateForward) mem::rotateHalf(input, sizeWin()); // do zero-phase windowing rotation?
	DFT::forward(input);					// do forward transform
	
	// compute frequency estimates?
	if(Bin::MagFreq == mSpctFormat){
		
		// This will effectively subtract the expected phase difference from the computed.
		// This extra step seems to give more precise frequency estimates.
		slice(mPhases, numBins()) += float(M_2PI * sizeHop()) / sizeDFT();
		
		// compute relative frequencies
		//arr::phaseToFreq(phs, mPhases, numBins(), unitsHop());
		float factor = 1.f / (M_2PI * unitsHop());
		for(uint32_t i=1; i<numBins()-1; ++i){
			float dp = scl::wrapPhase(bins()[i][1] - mPhases[i]);	// wrap phase into [-pi, pi)
			mPhases[i] = bins()[i][1];							// prev phase = curr phase
			bins()[i][1] = dp*factor;
		}
		
		// compute absolute frequencies by adding respective bin center frequency
		slice(mBuf, numBins(), 2) += gen::RAdd<float>(binFreq());
	}
}
示例#2
0
文件: DFT.cpp 项目: PeterZhouSZ/Gamma
void STFT::inverse(float * dst){
	//printf("STFT::inverse(float *)\n");
	if(MAG_FREQ == mSpctFormat){
		// 2pi / hopRate: converts Hz to phase diff in radians
		double factor = M_2PI * unitsHop();

		// 2pi / overlap: expected phase diff of fundamental due to overlap
		double expdp1 = double(sizeHop())/sizeWin() * M_2PI;
		double fund = binFreq();

		for(unsigned k=1; k<numBins()-1; ++k){
			double t = bin(k)[1];		// freq
			t -= k*fund;				// freq to freq deviation
			t *= factor;				// freq deviation to phase diff
			t += k*expdp1;				// add expected phase diff due to overlap
			mAccums[k] += t;			// accumulate phase diff
			//bin(k)[1] = mAccums[k];		// copy accum phase for inverse xfm
			bufInvFrq()[2*k] = bin(k)[0];
			bufInvFrq()[2*k+1] = mAccums[k];
		}

		bufInvFrq()[0] = bin(0)[0];
		bufInvFrq()[2*(numBins()-1)] = bin(numBins()-1)[0];
	}

	DFT::inverse();	// result goes into bufInvPos()

	// undo zero-phase windowing rotation?
	if(mRotateForward) mem::rotateRight(sizeWin()/2, bufInvPos(), sizeDFT());

	// apply secondary window to smooth ends?
	if(mWindowInverse){
		arr::mulBartlett(bufInvPos(), sizeWin());
	}

	if(overlapping()){	//inverse windows overlap?

		// scale inverse so overlap-add is normalized
		for(unsigned i=0; i<sizeWin(); ++i){
			bufInvPos()[i] *= mInvWinMul;
		}

		// shift old output left while adding new output
		arr::add(mBufInv, bufInvPos(), mBufInv + sizeHop(), sizeWin() - sizeHop());
	}

	// copy remaining non-overlapped portion of new output
	unsigned sizeOverlap = sizeWin() - sizeHop();
	mem::deepCopy(mBufInv + sizeOverlap, bufInvPos() + sizeOverlap, sizeHop());

	// copy output if external buffer provided
	if(dst) mem::deepCopy(dst, mBufInv, sizeWin());	
}
示例#3
0
文件: DFT.cpp 项目: LuaAV/LuaAV
void STFT::inverse(float * dst){
	//printf("STFT::inverse(float *)\n");
	if(Bin::MagFreq == mSpctFormat){
		//mem::copy(bins1(), mPhases, numBins()); // not correct, need to unwrap frequencies
		for(uint32_t i=1; i<numBins()-1; ++i) bins()[i] = mPhases[i];
	}	
	
	DFT::inverse(0);	// result goes into mBuf
	
	// undo zero-phase windowing rotation?
	if(mRotateForward) mem::rotateHalf(mBuf, sizeWin());
	
	// apply secondary window to smooth ends?
	if(mWindowInverse){
		arr::mulBartlett(mBuf, sizeWin());
	}

	if(overlapping()){	//inverse windows overlap?
	
		// scale inverse so overlap-add is normalized
		//arr::mul(mBuf, gen::val(mInvWinMul), sizeWin());
		slice(mBuf, sizeWin()) *= mInvWinMul;
	
		// shift old output left while adding new output
		arr::add(mBufInv, mBuf, mBufInv + sizeHop(), sizeWin() - sizeHop());
	}

	// copy remaining non-overlapped portion of new output
	uint32_t sizeOverlap = sizeWin() - sizeHop();
	mem::deepCopy(mBufInv + sizeOverlap, mBuf + sizeOverlap, sizeHop());

	// copy output if external buffer provided
	if(dst) mem::deepCopy(dst, mBufInv, sizeWin());	
}
示例#4
0
// input is sizeWin
void STFT::forward(const float * src){ //printf("STFT::forward(float *)\n");

	if(src != bufPos()) mem::deepCopy(bufPos(), src, sizeWin());

	// apply forward window
	arr::mul(bufPos(), mFwdWin, sizeWin());
	
	// do zero-phase windowing rotation?
	if(mRotateForward) mem::rotateHalf(bufPos(), sizeWin());

	DFT::forward(bufPos());
	
	// compute frequency estimates?
	if(MAG_FREQ == mSpctFormat){
		
//		// This will effectively subtract the expected phase difference from the computed.
//		// This extra step seems to give more precise frequency estimates.
//		{
//			float expdp = float(M_2PI * sizeHop()) / sizeDFT();
//			for(uint32_t i=0; i<numBins(); ++i){
//				mPhases[i] += expdp;
//			}
//		}
		
		// compute frequency estimates
		float factor = 1.f / (M_2PI * unitsHop()); // converts phase difference from radians to Hz
		
		// expected phase difference of fundamental
		float expdp1 = float(sizeHop())/sizeWin() * M_2PI;

		for(uint32_t i=1; i<numBins()-1; ++i){
			float ph = bin(i)[1];						// current phase
			float dp = ph - mPhases[i] - i*expdp1;		// compute phase difference
			dp = scl::wrapPhase(dp);					// wrap back into [-pi, pi)
			mPhases[i] = ph;							// save current phase
			bin(i)[1] = dp*factor;						// convert phase diff to freq
		}
		
		// compute absolute frequencies by adding respective bin center frequency
		for(uint32_t i=0; i<numBins(); ++i){
			bins()[i][1] += binFreq()*i;
		}
	}
}
示例#5
0
文件: DFT.cpp 项目: PeterZhouSZ/Gamma
void DFT::print(FILE * f, const char * a){
	fprintf(f, "DFT, Win, Hop: %d, %d, %d samples\n", (int)sizeDFT(), (int)sizeWin(), (int)sizeHop());
	fprintf(f, "# bins:        %d\n", (int)numBins());
	fprintf(f, "Freq res:      %f units/sample\n", freqRes());
	fprintf(f, "Bin freq:      %f units\n", binFreq());
	fprintf(f, "Data format:   %s\n", toString(mSpctFormat));
	fprintf(f, "Precise:       %s\n", mPrecise ? "true" : "false");	
	fprintf(f, "Aux buffers:   %d\n", (int)mNumAux);
	//printf("buf, pad, inv, aux: %p %p %p %p", mBuf, mPadOA, mBufInv, mAux);
	fprintf(f, "%s", a);
}
示例#6
0
文件: DFT.cpp 项目: LuaAV/LuaAV
void STFT::resize(uint32_t winSize, uint32_t padSize){
	float * tmp = mBufInv;
	uint32_t oldWinSize = sizeWin();
	uint32_t oldNumBins = numBins();
	
	// resize DFT buffers
	DFT::resize(winSize, padSize);
	
	mBufInv = tmp;	// DFT::resize changes this, so change it back
	
	// resize STFT-specific buffers
	mSlide.sizeWin(winSize);
	mem::resize(mFwdWin, oldWinSize, winSize);
	mem::resize(mBufInv, oldWinSize, winSize);
	mem::resize(mPhases, oldNumBins, numBins());
	
	mem::deepZero(mPhases, numBins());
	mem::deepZero(mBufInv, winSize);
	
	// re-compute fwd window
	winType(mWinType);
}
示例#7
0
文件: DFT.cpp 项目: PeterZhouSZ/Gamma
// input is sizeWin
void STFT::forward(const float * src){ //printf("STFT::forward(float *)\n");

	if(src) mem::deepCopy(bufFwdPos(), src, sizeWin());

	// apply forward window
	arr::mul(bufFwdPos(), mFwdWin, sizeWin());
	
	// do zero-phase windowing rotation?
	if(mRotateForward) mem::rotateLeft(sizeWin()/2, bufFwdPos(), sizeDFT());

	DFT::forward();
	
	// compute frequency estimates?
	if(MAG_FREQ == mSpctFormat){

		// hopRate / 2pi: converts phase diff from radians to Hz
		double factor = 1. / (M_2PI * unitsHop());
		
		// 2pi / overlap: expected phase diff of fundamental due to overlap
		double expdp1 = double(sizeHop())/sizeWin() * M_2PI;
		double fund = binFreq();

		bin(0)[1] = 0.;
		bin(numBins()-1)[1] = spu() * 0.5;

		for(unsigned k=1; k<numBins()-1; ++k){
			float ph = bin(k)[1];		// current phase
			double t = ph - mPhases[k];	// compute phase diff
			mPhases[k] = ph;			// save current phase
			t -= k*expdp1;				// subtract expected phase diff due to overlap
			t = scl::wrapPhase(t);		// wrap back into [-pi, pi)
			t *= factor;				// convert phase diff to freq deviation
			t += k*fund;				// freq deviation to freq
			bin(k)[1] = t;
		}
	}
}
示例#8
0
文件: DFT.cpp 项目: PeterZhouSZ/Gamma
// The principle here is to configure things so that after the phase
// accumulation step, the synthesis bin phases equal the analysis bin phases.
// To do this, we first zero the phase accumulators and then compute new
// instantaneous frequencies which after conversion yield a phase increment
// equal to the analysis bin phase.
STFT& STFT::resetPhases(){
	mem::deepZero(mAccums, numBins());

	// hopRate / 2pi: converts phase diff from radians to Hz
	double factor = 1. / (M_2PI * unitsHop());

	// 2pi / overlap: expected phase diff of fundamental due to overlap
	double expdp1 = double(sizeHop())/sizeWin() * M_2PI;
	double fund = binFreq();

	bin(0)[1] = 0.;
	bin(numBins()-1)[1] = spu() * 0.5;

	for(unsigned k=1; k<numBins()-1; ++k){
		double t = mPhases[k];		// the phase diff is simply the analysis phase
		t -= k*expdp1;				// subtract expected phase diff due to overlap
		t = scl::wrapPhase(t);		// wrap back into [-pi, pi)
		t *= factor;				// convert phase diff to freq deviation
		t += k*fund;				// freq deviation to freq
		bin(k)[1] = t;
	}

	return *this;
}
示例#9
0
文件: DFT.cpp 项目: PeterZhouSZ/Gamma
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());
}
示例#10
0
文件: DFT.cpp 项目: LuaAV/LuaAV
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);
	}
}
示例#11
0
void STFT::inverse(float * dst){
	//printf("STFT::inverse(float *)\n");
	if(MAG_FREQ == mSpctFormat){
		// TODO:
		for(uint32_t i=1; i<numBins()-1; ++i) bin(i)[1] = mPhases[i];
	}	
	
	DFT::inverse(0);	// result goes into bufPos()
	
	// undo zero-phase windowing rotation?
	if(mRotateForward) mem::rotateHalf(bufPos(), sizeWin());

	// apply secondary window to smooth ends?
	if(mWindowInverse){
		arr::mulBartlett(bufPos(), sizeWin());
	}

	if(overlapping()){	//inverse windows overlap?
	
		// scale inverse so overlap-add is normalized
		//slice(mBuf, sizeWin()) *= mInvWinMul;
		for(unsigned i=0; i<sizeWin(); ++i){
			bufPos()[i] *= mInvWinMul;
		}
	
		// shift old output left while adding new output
		arr::add(mBufInv, bufPos(), mBufInv + sizeHop(), sizeWin() - sizeHop());
	}

	// copy remaining non-overlapped portion of new output
	uint32_t sizeOverlap = sizeWin() - sizeHop();
	mem::deepCopy(mBufInv + sizeOverlap, bufPos() + sizeOverlap, sizeHop());

	// copy output if external buffer provided
	if(dst) mem::deepCopy(dst, mBufInv, sizeWin());	
}