Exemple #1
0
// 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());
	}
}
Exemple #2
0
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());	
}
Exemple #3
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;
		}
	}
}
Exemple #4
0
// 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;
		}
	}
}
Exemple #5
0
// 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;
}