// NB! The 'input' arg points to an array which WILL BE MODIFIED: on return, it will contain the residual.
// "activations" will contain [index0, activ0, index1, activ1, ... ]
static void doMatchingPursuit(float* input, float* activations, const float* dict, const int natoms, const int nsamples, const int niters)
{
	Clear(niters * 2, activations); // initialise activations (correlations) to zero
	for(int whichiter=0; whichiter<niters; ++whichiter){
		int chosenatom=-1;
		double chosencorr=0.f, chosenabscorr=0.f;
		for(int whichatom=0; whichatom<natoms; ++whichatom){
			float corr = innerproductWithDictAtom(input, dict, whichatom, natoms, nsamples);
			float abscorr = sc_abs(corr);
			if(abscorr>chosenabscorr){
				chosencorr = corr;
				chosenabscorr = abscorr;
				chosenatom = whichatom;
			}
		}
		if(chosenatom == -1){
			//printf("MP (iter %i): no atoms selected, finished early.\n", whichiter);
		}else{
			//printf("MP (iter %i): selected atom %i (corr %g)\n", whichiter, chosenatom, chosencorr);
			// Now we have our winner for this iter, time to update: subtract the projection from the residual, and add chosencorr to the resultsarray
			//float projectionfac = -1.f / chosencorr;
			float projectionfac = -chosencorr;
			//printf("projectionfac %g\n", projectionfac);
			const float* readpos = dict + chosenatom;
			for(int i=0; i<nsamples; ++i){
				input[i] += projectionfac * (*readpos);
				readpos += natoms;
			}
			activations[whichiter * 2    ] = chosenatom;
			activations[whichiter * 2 + 1] = chosencorr;
		}
	}
}
예제 #2
0
void RedLbyl_next_a(RedLbyl *unit, int inNumSamples) {
	float *out= ZOUT(0);
	float *in= ZIN(0);
	float thresh= ZIN0(1);
	float samples= ZIN0(2);
	float prevout= unit->m_prevout;
	unsigned long counter= unit->m_counter;
	
	LOOP(inNumSamples,
		 float zout= ZXP(in);
		 if(sc_abs(zout-prevout)>thresh) {
			counter++;
			if(counter<samples) {
				zout= prevout;
			} else {
				counter= 0;
			}
		 } else {
			counter= 0;
		 }
		 prevout= zout;
		 ZXP(out)= zout;
	);
예제 #3
0
void FFTPower_next(FFTPower *unit, int inNumSamples)
{
	FFTAnalyser_GET_BUF

	float normfactor = unit->m_normfactor;
	bool square = unit->m_square;
	if(normfactor == 0.f){
		if(square)
			unit->m_normfactor = normfactor = 1.f / powf(numbins + 2.f, 1.5f);
		else
			unit->m_normfactor = normfactor = 1.f / (numbins + 2.f);
	}


	SCComplexBuf *p = ToComplexApx(buf);
//	SCPolarBuf *p = ToPolarApx(buf);

	float total;
	if(square){
		total = sc_abs(p->dc) * sc_abs(p->dc) + sc_abs(p->nyq) *  sc_abs(p->nyq);

		for (int i=0; i<numbins; ++i) {
			float rabs = (p->bin[i].real);
			float iabs = (p->bin[i].imag);
			total += (rabs*rabs) + (iabs*iabs);
		}
	}else{
		total = sc_abs(p->dc) + sc_abs(p->nyq);

		for (int i=0; i<numbins; ++i) {
			float rabs = (p->bin[i].real);
			float iabs = (p->bin[i].imag);
			total += sqrt((rabs*rabs) + (iabs*iabs));
		}
	//	for (int i=0; i<numbins; ++i) {
	//		total += sc_abs(p->bin[i].mag);
	//	}
	}

	// Store the val for output in future calls
	unit->outval = total * normfactor;

	ZOUT0(0) = unit->outval;
}
예제 #4
0
void FFTSubbandPower_next(FFTSubbandPower *unit, int inNumSamples)
{
	int numbands = unit->m_numbands;
	int numcutoffs = numbands - 1;

	// Multi-output equiv of FFTAnalyser_GET_BUF
	float fbufnum = ZIN0(0);
	if (fbufnum < 0.f) {
		for(int i=0; i<numbands; i++){
			ZOUT0(i) = unit->m_outvals[i];
		}
		return;
	}
	uint32 ibufnum = (uint32)fbufnum;
	World *world = unit->mWorld;
	SndBuf *buf;
	if (ibufnum >= world->mNumSndBufs) {
		int localBufNum = ibufnum - world->mNumSndBufs;
		Graph *parent = unit->mParent;
		if(localBufNum <= parent->localBufNum) {
			buf = parent->mLocalSndBufs + localBufNum;
		} else {
			buf = world->mSndBufs;
		}
	} else {
		buf = world->mSndBufs + ibufnum;
	}
	int numbins = (buf->samples - 2) >> 1;
	// End: Multi-output equiv of FFTAnalyser_GET_BUF

	int scalemode = unit->m_scalemode;

	float normfactor = unit->m_normfactor;
	bool square = unit->m_square;
	if(normfactor == 0.f){
		if(square)
			unit->m_normfactor = normfactor = 1.f / powf(numbins + 2.f, 1.5f);
		else
			unit->m_normfactor = normfactor = 1.f / (numbins + 2.f);
	}

	// Now we create the integer lookup list, if it doesn't already exist
	int * cutoffs = unit->m_cutoffs;
	if(!unit->m_cutoff_inited){

		float srate = world->mFullRate.mSampleRate;
		for(int i=0; i < numcutoffs; ++i) {
			cutoffs[i] = (int)(buf->samples * ZIN0(4 + i) / srate);
			//Print("Allocated bin cutoff #%d, at bin %d\n", i, cutoffs[i]);
		}

		unit->m_cutoff_inited = true;
	}

	SCComplexBuf *p = ToComplexApx(buf);

	// Now we can actually calculate the bandwise subtotals
	float total = sc_abs(p->dc);
	if(square){
		total *= total; // square the DC val
	}
	int binaddcount = 1; // Counts how many bins contributed to the current band (1 because of the DC value)
	int curband = 0;
	float * outvals = unit->m_outvals;
	float magsq;
	for (int i=0; i<numbins; ++i) {
		if((curband != numbands) && (i >= cutoffs[curband])){
			if(scalemode==1){
				outvals[curband] = total * normfactor;
			}else{
				if(square)
					outvals[curband] = total / powf((float)binaddcount, 1.5f);
				else
					outvals[curband] = total / binaddcount;
			}
			//Print("Finished off band %i while in bin %i\n", curband, i);
			++curband;
			total = 0.f;
			binaddcount = 0;
		}

		float rabs = (p->bin[i].real);
		float iabs = (p->bin[i].imag);
		magsq = ((rabs*rabs) + (iabs*iabs));
		if(square)
			total += magsq;
		else
			total += std::sqrt(magsq);
		++binaddcount;
	}
	// Remember to output the very last (highest) band
	if(square)
		total += p->nyq * p->nyq;
	else
		total += sc_abs(p->nyq);
	// Pop the last one onto the end of the lovely list
	if(scalemode==1){
		outvals[curband] = total * normfactor;
	}else{
		if(square)
			outvals[curband] = total / powf((float)binaddcount + 1.f, 1.5f); // Plus one because of the nyq value
		else
			outvals[curband] = total / (binaddcount + 1); // Plus one because of the nyq value
	}

	// Now we can output the vals
	for(int i=0; i<numbands; i++) {
		ZOUT0(i) = outvals[i];
	}
}
예제 #5
0
	unit->m_oneovern = 0.;
}

void SpecFlatness_next(SpecFlatness *unit, int inNumSamples)
{
	FFTAnalyser_GET_BUF
	if(unit->m_oneovern == 0.)
		unit->m_oneovern = 1./(numbins + 2);

	SCComplexBuf *p = ToComplexApx(buf);

	// Spectral Flatness Measure is geometric mean divided by arithmetic mean.
	//
	// In order to calculate geom mean without hitting the precision limit,
	//  we use the trick of converting to log, taking the average, then converting back from log.
	double geommean = std::log(sc_abs(p->dc)) + std::log(sc_abs(p->nyq));
	double mean     = sc_abs(p->dc)      + sc_abs(p->nyq);

	for (int i=0; i<numbins; ++i) {
		float rabs = (p->bin[i].real);
		float iabs = (p->bin[i].imag);
		float amp = std::sqrt((rabs*rabs) + (iabs*iabs));
		if(amp != 0.f) { // zeroes lead to NaNs
			geommean += std::log(amp);
			mean += amp;
		}
	}

	double oneovern = unit->m_oneovern;
	geommean = exp(geommean * oneovern); // Average and then convert back to linear
	mean *= oneovern;
예제 #6
0
void Friction_next(Friction *unit, int inNumSamples)
{
    float *out = OUT(0);

    float *in = IN(0);

    // Control-rate parameters
    float friction	= ZIN0(1);
    float spring	= ZIN0(2);
    float damp		= ZIN0(3);
    float mass		= ZIN0(4);
    float beltmass	= ZIN0(5);

    // Retrive state
    float beltpos = unit->m_beltpos;
    float V = unit->m_V;
    float x = unit->m_x;
    float dx = unit->m_dx;

    // vars used in the loop
    float F_N, relspeed, F_f, drivingforce, F_s, F, ddx, oldbeltpos, oldV, beltaccn;
    bool sticking;

    // The normal force is just due to the weight of the object
    F_N = mass * 9.81f;
    float frictimesF_N = (friction * F_N);

    for (int i=0; i < inNumSamples; ++i)
    {
        oldbeltpos = beltpos;
        oldV = V;

        beltpos = in[i];
        V = beltpos - oldbeltpos;
        beltaccn = V - oldV;

        // Calc the kinetic friction force
        relspeed = dx - V;
        if(relspeed==0.f) {
            F_f = 0.f; // No kinetic friction when no relative motion
        } else if (relspeed > 0.f) {
            F_f = frictimesF_N;
        } else {
            F_f = 0.f - frictimesF_N;
        }

        drivingforce = beltaccn * beltmass;

        // Calc the nonfriction force that would occur if moving along with the belt
        F_s = drivingforce - (damp * V) - (spring * x);


        // Decide if we're sticking or not
        sticking = sc_abs(F_s) < frictimesF_N;

        // NOW TO UPDATE THE MASS'S POSITION.
        // If sticking it's easy. Mass speed == belt speed
        if(sticking) {
            dx = V;
        } else {
            // Based on eq (5)
            F = F_s - F_f;
            ddx = F / mass;
            dx += ddx;
        }

        x += dx;

        // write the output
        out[i] = x;
    }

    // Store state
    unit->m_beltpos = beltpos;
    unit->m_V  = V;
    unit->m_x  = x;
    unit->m_dx  = dx;
}
예제 #7
0
void FincoSprottS_next(FincoSprottS *unit, int inNumSamples)
{
	float *xout = ZOUT(0);
	float *yout = ZOUT(1);
	float *zout = ZOUT(2);
	float freq = ZIN0(0);
	double a = ZIN0(1);
	double b = ZIN0(2);
	double h = ZIN0(3);
	double x0 = ZIN0(4);
	double y0 = ZIN0(5);
	double z0 = ZIN0(6);

	double xn = unit->xn;
	double yn = unit->yn;
	double zn = unit->zn;
	float counter = unit->counter;
	double xnm1 = unit->xnm1;
	double ynm1 = unit->ynm1;
	double znm1 = unit->znm1;
	double frac = unit->frac;

	float samplesPerCycle;
	double slope;
	if(freq < unit->mRate->mSampleRate){
		samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f);
		slope = 1.f / samplesPerCycle;
	}
	else {
		samplesPerCycle = 1.f;
		slope = 1.f;
	}

	if((unit->x0 != x0) || (unit->y0 != y0) || (unit->z0 != z0)){
		xnm1 = xn;
		ynm1 = yn;
		znm1 = zn;
		unit->x0 = xn = x0;
		unit->y0 = yn = y0;
		unit->z0 = zn = z0;
	}

	double dx = xn - xnm1;
	double dy = yn - ynm1;
	double dz = zn - znm1;

	for (int i=0; i<inNumSamples; ++i) {
		if(counter >= samplesPerCycle){
			counter -= samplesPerCycle;
			frac = 0.f;

			xnm1 = xn;
			ynm1 = yn;
			znm1 = zn;

			double k1x, k2x, k3x, k4x,
				k1y, k2y, k3y, k4y,
				k1z, k2z, k3z, k4z,
				kxHalf, kyHalf, kzHalf;

			// 4th order Runge-Kutta approximate solution for differential equations

			k1x = h * (0.0 - (xnm1 + a * ynm1));
			k1y = h * (xnm1 + b * sc_abs(znm1));
			k1z = h * (xnm1 + 1.0);
			kxHalf = k1x * 0.5;
			kyHalf = k1y * 0.5;
			kzHalf = k1z * 0.5;

			k2x = h * (0.0 - (xnm1 + kxHalf + a * (ynm1 + kyHalf)));
			k2y = h * (xnm1 + kxHalf + b * sc_abs(znm1 + kzHalf));
			k2z = h * (xnm1 + kxHalf + 1.0);
			kxHalf = k2x * 0.5;
			kyHalf = k2y * 0.5;
			kzHalf = k2z * 0.5;

			k3x = h * (0.0 - (xnm1 + kxHalf + a * (ynm1 + kyHalf)));
			k3y = h * (xnm1 + kxHalf + b * sc_abs(znm1 + kzHalf));
			k3z = h * (xnm1 + kxHalf + 1.0);

			k4x = h * (0.0 - (xnm1 + k3x + a * (ynm1 + k3y)));
			k4y = h * (xnm1 + k3x + b * sc_abs(znm1 + k3z));
			k4z = h * (xnm1 + k3x + 1.0);

			xn = xn + (k1x + 2.0*(k2x + k3x) + k4x) * ONESIXTH;
			yn = yn + (k1y + 2.0*(k2y + k3y) + k4y) * ONESIXTH;
			zn = zn + (k1z + 2.0*(k2z + k3z) + k4z) * ONESIXTH;

			dx = xn - xnm1;
			dy = yn - ynm1;
			dz = zn - znm1;
		}
		counter++;
		ZXP(xout) = (xnm1 + dx * frac) * 0.5f;
		ZXP(yout) = (ynm1 + dy * frac) * 0.5f;
		ZXP(zout) = (znm1 + dz * frac) * 1.0f;
		frac += slope;
	}

	unit->xn = xn;
	unit->yn = yn;
	unit->zn = zn;
	unit->counter = counter;
	unit->xnm1 = xnm1;
	unit->ynm1 = ynm1;
	unit->znm1 = znm1;
	unit->frac = frac;
}