Exemple #1
0
void SOMTrain_Ctor(SOMTrain* unit)
{
	// set the calculation function. do this before the base ctor because it may want to change it!
	SETCALC(SOMTrain_next);

	SOM_Ctor_base(unit, 7); // 7 is the offset before we get input data

	int traindur = (int)ZIN0(3);
	int traincountdown = traindur; // Decrement by one on each occasion

	double nhood = ZIN0(4) * (unit->m_netsize) * 0.5; // Neighbourhood size (fraction of total, here converted to span of nodes) to be included in a training update. Will decrement slowly.
	// The reason we halve it is for convenience: we look nhood/2 in positive direction, nhood/2 in negative direction.
	double nhooddelta = nhood / traindur; // This is how much it decrements by, each occasion.

	float weightfactor = ZIN0(6); // Scaling factor for how much the node "bends" towards the datum
	float mfactor = traindur * 0.25f; // Empirical scaling - weight falls to half of its value after 0.25 of the training

	// initialize the unit generator state variables.
	unit->m_traindur   = traindur;
	unit->m_traincountdown = traincountdown;
	unit->m_traincountup   = 0;
	unit->m_nhood      = nhood;
	unit->m_nhooddelta = nhooddelta;
	unit->m_weightfactor   = weightfactor;
	unit->m_mfactor   = mfactor;
	unit->m_writeloc  = 0.f;

	// calculate one sample of output.
	ZOUT0(0) = 0.f;
	ZOUT0(1) = 0.f;
}
Exemple #2
0
void FFT_next(FFT *unit, int wrongNumSamples)
{
	float *in = IN(1);
	float *out = unit->m_inbuf + unit->m_pos + unit->m_shuntsize;

	int numSamples = unit->m_numSamples;

	// copy input
	memcpy(out, in, numSamples * sizeof(float));

	unit->m_pos += numSamples;

	bool gate = ZIN0(4) > 0.f; // Buffer shunting continues, but no FFTing

	if (unit->m_pos != unit->m_hopsize || !unit->m_fftsndbuf->data || unit->m_fftsndbuf->samples != unit->m_fullbufsize) {
		if(unit->m_pos == unit->m_hopsize)
			unit->m_pos = 0;
		ZOUT0(0) = -1.f;
	} else {

		unit->m_pos = 0;
		if(gate){
			scfft_dofft(unit->m_scfft);
			unit->m_fftsndbuf->coord = coord_Complex;
			ZOUT0(0) = unit->m_fftbufnum;
		} else {
			ZOUT0(0) = -1;
		}
		// Shunt input buf down
		memmove(unit->m_inbuf, unit->m_inbuf + unit->m_hopsize, unit->m_shuntsize * sizeof(float));
	}
}
Exemple #3
0
void FFTTrigger_next(FFTTrigger *unit, int inNumSamples)
{
	if (unit->m_periodsRemain > 0) {
		ZOUT0(0) = -1.f;
		unit->m_periodsRemain--;
	} else {
		ZOUT0(0) = unit->m_fftbufnum;
		unit->m_pos = 0;
		unit->m_periodsRemain = unit->m_numPeriods;
	}

}
void PV_DecorTransExtract_Ctor(PV_DecorTransExtract *unit)
{
	// get input variables
	unit->retTrans = IN0(1);
	unit->iVal = IN0(2);
	unit->jVal = IN0(3);
	unit->alphaVal = IN0(4);
	unit->betaVal = IN0(5);
	unit->dVal = IN0(6);
	unit->lowFreqCutVal = IN0(7);

	// set other variables
	unit->numFreqBins = 0;
	unit->prevBinsIdx = 0;
	unit->littleOmegaIdx = 0;
	unit->bigOmegaIdx = 0;
	unit->initDebugFlag = true;
	unit->initFirstCalc = true;

	// set output
	ZOUT0(0) = ZIN0(0);

	// set calculation function (next)
	SETCALC(PV_DecorTransExtract_next);
}
Exemple #5
0
int FFTBase_Ctor(FFTBase *unit, int frmsizinput)
{
	World *world = unit->mWorld;

	uint32 bufnum = (uint32)ZIN0(0);
	SndBuf *buf;
	if (bufnum >= world->mNumSndBufs) {
			int localBufNum = bufnum - world->mNumSndBufs;
			Graph *parent = unit->mParent;
			if(localBufNum <= parent->localMaxBufNum) {
				buf = parent->mLocalSndBufs + localBufNum;
			} else {
				if(unit->mWorld->mVerbosity > -1){ Print("FFTBase_Ctor error: invalid buffer number: %i.\n", bufnum); }
				return 0;
			}
	} else {
			buf = world->mSndBufs + bufnum;
	}


	if (!buf->data) {
		if(unit->mWorld->mVerbosity > -1){ Print("FFTBase_Ctor error: Buffer %i not initialised.\n", bufnum); }
		return 0;
	}

	unit->m_fftsndbuf = buf;
	unit->m_fftbufnum = bufnum;
	unit->m_fullbufsize = buf->samples;
	int framesize = (int)ZIN0(frmsizinput);
	if(framesize < 1)
		unit->m_audiosize = buf->samples;
	else
		unit->m_audiosize = sc_min(buf->samples, framesize);

	unit->m_log2n_full  = LOG2CEIL(unit->m_fullbufsize);
	unit->m_log2n_audio = LOG2CEIL(unit->m_audiosize);


	// Although FFTW allows non-power-of-two buffers (vDSP doesn't), this would complicate the windowing, so we don't allow it.
	if (!ISPOWEROFTWO(unit->m_fullbufsize)) {
		Print("FFTBase_Ctor error: buffer size (%i) not a power of two.\n", unit->m_fullbufsize);
		return 0;
	}
	else if (!ISPOWEROFTWO(unit->m_audiosize)) {
		Print("FFTBase_Ctor error: audio frame size (%i) not a power of two.\n", unit->m_audiosize);
		return 0;
	}
	else if (unit->m_audiosize < SC_FFT_MINSIZE ||
			(((int)(unit->m_audiosize / unit->mWorld->mFullRate.mBufLength))
					* unit->mWorld->mFullRate.mBufLength != unit->m_audiosize)) {
		Print("FFTBase_Ctor error: audio frame size (%i) not a multiple of the block size (%i).\n", unit->m_audiosize, unit->mWorld->mFullRate.mBufLength);
		return 0;
	}

	unit->m_pos = 0;

	ZOUT0(0) = ZIN0(0);

	return 1;
}
void KeyState_next(KeyState *unit, int inNumSamples)
{
    // minval, maxval, warp, lag
    uint8 *keys = (uint8*)unit->gstate->keys;
    int keynum = (int)ZIN0(0);
#ifdef __APPLE__
    int byte = (keynum >> 3) & 15;
#else
    int byte = (keynum >> 3) & 31;
#endif
    int bit = keynum & 7;
    int val = keys[byte] & (1 << bit);

    float minval = ZIN0(1);
    float maxval = ZIN0(2);
    float lag = ZIN0(3);

    float y1 = unit->m_y1;
    float b1 = unit->m_b1;

    if (lag != unit->m_lag) {
        unit->m_b1 = lag == 0.f ? 0.f : exp(log001 / (lag * unit->mRate->mSampleRate));
        unit->m_lag = lag;
    }
    float y0 = val ? maxval : minval;
    ZOUT0(0) = y1 = y0 + b1 * (y1 - y0);
    unit->m_y1 = zapgremlins(y1);
}
Exemple #7
0
void FFTSubbandPower_Ctor(FFTSubbandPower *unit)
{
	SETCALC(FFTSubbandPower_next);
	ZOUT0(0) = unit->outval = 0.;

	unit->m_square = ZIN0(2) > 0.f;
	unit->m_normfactor = 0.f;

	// ZIN0(1) tells us how many cutoffs we're looking for
	int numcutoffs = (int)ZIN0(1);
	int numbands = numcutoffs+1;

	unit->m_scalemode = (int)ZIN0(3);

	float * outvals = (float*)RTAlloc(unit->mWorld, numbands * sizeof(float));
	for(int i=0; i<numbands; i++) {
		outvals[i] = 0.f;
	}
	unit->m_outvals = outvals;

	unit->m_cutoffs = (int*)RTAlloc(unit->mWorld, numcutoffs * sizeof(int));
	unit->m_cutoff_inited = false;

	unit->m_numbands = numbands;
}
Exemple #8
0
void MouseY_next(MouseInputUGen *unit, int inNumSamples)
{
	// minval, maxval, warp, lag

	float minval = ZIN0(0);
	float maxval = ZIN0(1);
	float warp = ZIN0(2);
	float lag = ZIN0(3);

	float y1 = unit->m_y1;
	float b1 = unit->m_b1;

	if (lag != unit->m_lag) {
		unit->m_b1 = lag == 0.f ? 0.f : (float)exp(log001 / (lag * unit->mRate->mSampleRate));
		unit->m_lag = lag;
	}
	float y0 = gMouseUGenGlobals.mouseY;
	if (warp == 0.0) {
		y0 = (maxval - minval) * y0 + minval;
	} else {
		y0 = pow(maxval/minval, y0) * minval;
	}
	ZOUT0(0) = y1 = y0 + b1 * (y1 - y0);
	unit->m_y1 = zapgremlins(y1);
}
Exemple #9
0
void FrameCompare_Ctor(FrameCompare* unit)
{

	SETCALC(FrameCompare_next);
	unit->magSum = 0.f, unit->numFrames = 0;
	ZOUT0(0) = unit->outVal = ZIN0(0);
}
Exemple #10
0
void MIDIUIUgen_next(MIDIUIUgen *unit, int inNumSamples)
{
	uint8 device = ZIN0(0);
	uint8 type = ZIN0(1);
	uint8 channel = ZIN0(2);
    float minval = ZIN0(3);
	float maxval = ZIN0(4);
	float warp = ZIN0(5);
	float lag = ZIN0(6);

	float y1 = unit->m_y1;
	float b1 = unit->m_b1;

	if (lag != unit->m_lag) {
		unit->m_b1 = lag == 0.f ? 0.f : (float)exp(log001 / (lag * unit->mRate->mSampleRate));
		unit->m_lag = lag;
	}
	float value = (float)(gMIDIUIUgenGlobals[device][type][channel]).value/(float)127;
	if (warp == 0.0) {
		value = (maxval - minval) * value + minval;
	} else {
		value = pow(maxval/minval, value) * minval;
	}
	ZOUT0(0) = y1 = value + b1 * (y1 - value);
	unit->m_y1 = zapgremlins(y1);
	
}
Exemple #11
0
void FFTPower_Ctor(FFTPower *unit)
{
	SETCALC(FFTPower_next);
	ZOUT0(0) = unit->outval = 0.;

	unit->m_square = ZIN0(1) > 0.f;
	unit->m_normfactor = 0.f;
}
Exemple #12
0
void Onsets_Ctor(Onsets *unit)
{
	if(ZIN0(8)>0)
		SETCALC(Onsets_next_rawodf);
	else
		SETCALC(Onsets_next);

	unit->m_needsinit = true;
	unit->m_ods = (OnsetsDS*) RTAlloc(unit->mWorld, sizeof(OnsetsDS) );

	ZOUT0(0) = unit->outval = 0.f;
}
void AmplitudeMod_Ctor(AmplitudeMod* unit)
{
	//printf("AmplitudeMod_Reset\n");
	SETCALC(AmplitudeMod_next);

	float clamp = ZIN0(1);
	unit->m_clampcoef  = clamp == 0.0 ? 0.0 : exp(log1/(clamp * SAMPLERATE));

	float relax = ZIN0(2);
	unit->m_relaxcoef = relax == 0.0 ? 0.0 : exp(log1/(relax * SAMPLERATE));

	ZOUT0(0) = unit->m_previn = ZIN0(0);
}
Exemple #14
0
void FFTFlux_Ctor(FFTFlux_Unit *unit)
{
	SETCALC(FFTFlux_next);

	unit->m_tempbuf = 0;

	unit->m_yesternorm = 1.0f;
	unit->m_yesterdc = 0.0f;
	unit->m_yesternyq = 0.0f;

	unit->m_normalise = ZIN0(1) > 0.f; // Whether we want to normalise or not

	unit->outval = 0.f;
	ZOUT0(0) = 0.f;
}
Exemple #15
0
void GlitchRHPF_Ctor(GlitchRHPF* unit)
{
	//printf("GlitchRHPF_Reset\n");
	if (unit->mBufLength == 1) {
		SETCALC(GlitchRHPF_next_1);
	} else {
		SETCALC(GlitchRHPF_next);
	};
	unit->m_a0 = 0.f;
	unit->m_b1 = 0.f;
	unit->m_b2 = 0.f;
	unit->m_y1 = 0.f;
	unit->m_y2 = 0.f;
	unit->m_freq = 0.f;
	unit->m_reson = 0.f;
	ZOUT0(0) = 0.f;
}
Exemple #16
0
void Loudness_next(Loudness *unit, int wrongNumSamples)
{
	float fbufnum = ZIN0(0);

	//next FFT bufffer ready, update
	//assuming at this point that buffer precalculated for any resampling
	if (fbufnum > -0.01f)
		Loudness_dofft(unit, (uint32)fbufnum);

	//always output sones
	//float outval= unit->m_sones;

	//printf("sones %f phontotal %f \n",outval, unit->m_phontotal);

	//control rate output
	ZOUT0(0)=unit->m_sones;
}
Exemple #17
0
void RedPhasor_Ctor(RedPhasor *unit) {
	if(unit->mCalcRate==calc_FullRate) {
		if(INRATE(0)==calc_FullRate) {
			if(INRATE(1)==calc_FullRate) {
				SETCALC(RedPhasor_next_aa);
			} else {
				SETCALC(RedPhasor_next_ak);
			}
		} else {
			SETCALC(RedPhasor_next_kk);
		}
	} else {
		SETCALC(RedPhasor_next_ak);
	}
	unit->m_previn= ZIN0(0);
	unit->ppdir= 1;
	ZOUT0(0)= unit->mLevel= ZIN0(2);
}
Exemple #18
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;
}
Exemple #19
0
void MouseButton_next(MouseInputUGen *unit, int inNumSamples)
{
	// minval, maxval, warp, lag

	float minval = ZIN0(0);
	float maxval = ZIN0(1);
	float lag = ZIN0(2);

	float y1 = unit->m_y1;
	float b1 = unit->m_b1;

	if (lag != unit->m_lag) {
		unit->m_b1 = lag == 0.f ? 0.f : (float)exp(log001 / (lag * unit->mRate->mSampleRate));
		unit->m_lag = lag;
	}
	float y0 = gMouseUGenGlobals.mouseButton ? maxval : minval;
	ZOUT0(0) = y1 = y0 + b1 * (y1 - y0);
	unit->m_y1 = zapgremlins(y1);
}
Exemple #20
0
void Graph_CalcTrace(Graph *inGraph)
{
	uint32 numCalcUnits = inGraph->mNumCalcUnits;
	Unit **calcUnits = inGraph->mCalcUnits;
	scprintf("\nTRACE %d  %s    #units: %d\n", inGraph->mNode.mID, inGraph->mNode.mDef->mName, numCalcUnits);
	for (uint32 i=0; i<numCalcUnits; ++i) {
		Unit *unit = calcUnits[i];
		scprintf("  unit %d %s\n    in ", i, (char*)unit->mUnitDef->mUnitDefName);
		for (uint32 j=0; j<unit->mNumInputs; ++j) {
			scprintf(" %g", ZIN0(j));
		}
		scprintf("\n");
		(unit->mCalcFunc)(unit, unit->mBufLength);
		scprintf("    out");
		for (uint32 j=0; j<unit->mNumOutputs; ++j) {
			scprintf(" %g", ZOUT0(j));
		}
		scprintf("\n");
	}
	inGraph->mNode.mCalcFunc = (NodeCalcFunc)&Graph_Calc;
}
Exemple #21
0
void KeyTrack_next(KeyTrack *unit, int wrongNumSamples)
{
	//int numSamples = unit->mWorld->mFullRate.mBufLength;

	//float *output = ZOUT(0);

	float fbufnum = ZIN0(0)+0.001;

	//next FFT bufffer ready, update
	//assuming at this point that buffer precalculated for any resampling
	if (fbufnum > -0.01f) {  // && ( ZIN0(3)<0.5)

		//unit->m_frame= unit->m_frame+1;
		KeyTrack_calculatekey(unit, (uint32)fbufnum);
	}

	//always output current best key
	float outval= unit->m_currentKey;

	//control rate output
	ZOUT0(0)=outval;
}
void Crest_Ctor(Crest* unit)
{
    SETCALC(Crest_next);

    unsigned int length = (unsigned int)ZIN0(1); // Fixed number of items to store in the ring buffer
    if(length==0)
        length=1; // ...because things would get painful in the stupid scenario of length 0

    unit->m_circbuf = (float*)RTAlloc(unit->mWorld, length * sizeof(float));
    unit->m_circbuf[0] = ZIN0(0); // Load first sample in...
    unit->m_circbufpos = 0U;
    unit->m_length = length;
    unit->m_notfullyet = true; // Only after first filled do we scan the whole buffer. Otherwise we scan up to and including the current position.

    if (INRATE(0) == calc_FullRate) {
        unit->m_realNumSamples = unit->mWorld->mFullRate.mBufLength;
    } else {
        unit->m_realNumSamples = 1;
    }

    ZOUT0(0) = unit->m_result = 1.f; // Necessarily 1 at first since only 1 sample received. No need to run calc func
}
Exemple #23
0
void FrameCompare_next(FrameCompare *unit, int inNumSamples)
{
	PV_GET_BUF2_FCOMPARE

	float minTargetMag = 900000.f, maxTargetMag = 0.f;
	float magdiff, magweight, lmtemp, minmaxtemp, p1mag, p2mag, scaleFactor;
	float wOffset = ZIN0(2);

	SCPolarBuf *p1 = ToPolarApx(buf1); //rendered
	SCPolarBuf *p2 = ToPolarApx(buf2); //target

	scaleFactor =  (numbins + 1) * 0.5; //hanning window only
	//Print("%f\n", p2->bin[100].mag / scaleFactor);

	for(int i = 0; i < numbins; ++i)
	{
		p2mag = p2->bin[i].mag / scaleFactor;

		minmaxtemp = (p2mag < 2e-42) ? log(2e-42) : log(fabs(p2mag));

		minTargetMag = (minmaxtemp <= minTargetMag) ? minmaxtemp : minTargetMag;
		maxTargetMag = (minmaxtemp >= maxTargetMag) ? minmaxtemp : maxTargetMag;
	}

	for(int i = 0; i < numbins; ++i)
	{
		p1mag = p1->bin[i].mag / scaleFactor;
		p2mag = p2->bin[i].mag / scaleFactor;

		magdiff = fabs(p1mag) - fabs(p2mag);
		lmtemp = p2mag < 2e-42 ? log(2e-42) : log(fabs(p2mag));
		magweight = (1 - wOffset) + (wOffset * ((lmtemp - minTargetMag) / fabs(minTargetMag - maxTargetMag)));
		unit->magSum = unit->magSum + (magdiff * magdiff * magweight);
	}

	unit->numFrames = unit->numFrames + 1;
	ZOUT0(0) = unit->outVal = unit->magSum/unit->numFrames;
}
// calculation function for a control rate threshold argument
void PhaseInIrm_next_k(PhaseInIrm *unit, int inNumSamples)
{
    int lastState =  unit->curstate;

    float meanRand;

    // get the pointer to the output buffer

    float threshBool = IN0(_threshBool);
    float callPeriod = IN0(_callPeriod);
    float restPeriod = IN0(_restPeriod);
    float inhibitMax = IN0(_inhibitMax);
    float inhibitDist = IN0(_inhibitDist);
    float playProb = IN0(_playProb);
    float restMode = IN0(_restMode);

    RGen& rgen = *unit->mParent->mRGen;


    //check for any inputs that have been changed
    if (unit->lastRestPeriod != restPeriod) {
        unit->restTime = restPeriod; //reset rest period
    };
    unit->lastRestPeriod = restPeriod;


    //	float sr = unit->mRate->mSampleRate;

    unit->callPeriod = callPeriod; //store vars for other functions

    switch (unit->curstate) {
    case listen1:
        //ENTRY
        if (unit->changeState) {
            updateScore(unit, false);
        };

        //DURING

        //EXIT
        if(threshBool > 0) {
            //update score
            unit->curstate = call; //exit
            break; //environment is clear - we're ready to go
        } else {
            unit->curstate = inhibit1; //exit
        }

        break;

    case inhibit1:

        //ENTRY
        if (unit->changeState) {
            //get random value for thisTimeInhibited
            unit->timeInhibited = 0;
            unit->thisInhibit = randWithScaleAndDist(unit, inhibitMax, inhibitDist);
        };

        //update time inhibited
        unit->timeInhibited = unit->timeInhibited + SAMPLEDUR;



        if (unit->timeInhibited >= unit->thisInhibit) {
            unit->timeInhibitedBeforeCall = unit->timeInhibitedBeforeCall + unit->thisInhibit;

            //update score
            updateScore(unit, false);

            unit->curstate = listen1; //exit
        };

        break;

    case call:

        //entry into the state
        if (unit->changeState) {
            updateScore(unit, true);
            unit->timeInhibitedBeforeCall = 0;

            //update call timer
            unit->timeCallRest = 0;
            unit->callTrig = 1; //trig outputs during call period
        };

        //during
        unit->timeCallRest = unit->timeCallRest + SAMPLEDUR; //increment time in current state


        if (unit->timeCallRest >= callPeriod) {
            unit->curstate = listen2;
            unit->callTrig = 0; //trig outputs during call period
            break;
        };
        break;

    case listen2:
        if (threshBool > 0) {
            unit->curstate = rest; //not inhibited - exit
        } else {
            unit->curstate = inhibit2; //inhibited - go to inhibit 2
        }
        break;

    case inhibit2:
        if (unit->changeState) {
            //positive or negative
            unit->addToRest = randWithScaleAndDist(unit, inhibitMax, inhibitDist);
            unit->addToRest = unit->addToRest * rgen.fcoin();

            unit->timeInhibitedBeforeCall = unit->timeInhibitedBeforeCall + unit->addToRest;
        };

        //EXIT
        unit->curstate = rest;


        break;

    case rest:
        if (unit->changeState) {
            //add accumulated rest time to rest
            if (restMode == 0) { //fixed restTime
                unit->restTime = restPeriod + unit->addToRest;
            } else if (restMode == 1) { //flexible restTime
                unit->restTime = unit->restTime + unit->addToRest;
            }
            //clear rest counter
            unit->timeCallRest = 0;

        };

        //increment rest counter
        unit->timeCallRest = unit->timeCallRest + SAMPLEDUR;

        if (unit->timeCallRest >= unit->restTime) {
            unit->curstate = listen1; //EXIT
        };

        break;
    default: //catches outliers
        //should throw an error here?
        break;
    };


    //see if we've changed state

    if (unit->curstate != lastState) {
        unit->changeState = true;

    } else {
        unit->changeState = false;
    };



    ZOUT0(0) = unit->callTrig;
    ZOUT0(1) = unit->score;
    ZOUT0(2) = unit->curstate;
}
Exemple #25
0
// Ordinary ClearUnitOutputs outputs zero, potentially telling the IFFT (+ PV UGens) to act on buffer zero, so let's skip that:
void FFT_ClearUnitOutputs(FFT *unit, int wrongNumSamples)
{
	ZOUT0(0) = -1;
}
void BeatTrack2_Ctor(BeatTrack2* unit)
{
    //unit->m_srate = unit->mWorld->mFullRate.mSampleRate;
    float kblocklength=  unit->mWorld->mFullRate.mBufDuration; //seconds per control block
    unit->m_krlength= kblocklength;
    //N features per block over numphases*2 variants for one of 120 tempi, so need at least 120 blocks to complete

    unit->m_phaseaccuracy = ZIN0(3); //0.02; //20 msec resolution; could be argument of UGen

    unit->m_numphases = (int*)RTAlloc(unit->mWorld, g_numtempi * sizeof(int));
    //unit->m_phases = (float**)RTAlloc(unit->mWorld, g_numtempi * sizeof(float*));

    for (int j=0; j<g_numtempi; ++j) {

        float period= g_periods[j];

        int num= (int)(period/unit->m_phaseaccuracy); //maximum will be 1.0/0.02 = 50

        unit->m_numphases[j]=num;

        //
        //	unit->m_phases[j]= (float*)RTAlloc(unit->mWorld, unit->m_numphases[j] * sizeof(float));
        //
        //	float phase=0.0;
        //
        //	for (i=0; i<num; ++i) {
        //	unit->m_phases[j][i] = phase;
        //	phase += unit->m_phaseaccuracy;
        //	}

    }

    unit->m_numfeatures = (int)(ZIN0(1)+0.001);



    //for efficiency
    unit->m_scores= (float*)RTAlloc(unit->mWorld, (2*unit->m_numfeatures) * sizeof(float));

    unit->m_temporalwindowsize= ZIN0(2); //typically small, 2 seconds for fast reactions compared to 6 secs for BeatTrack

    unit->m_fullwindowsize = unit->m_temporalwindowsize + 1.0 + 0.1; //plus one to cover all phases of the 60bpm based period, and a further 0.1 for indexing safety; ie looking at areas around the point you're interested in

    unit->m_buffersize = (int)(unit->m_fullwindowsize/unit->m_krlength); //in control blocks


    //printf("loading test blocklength %f numfeatures %d temporal %f full %f blocks %d \n",unit->m_krlength, unit->m_numfeatures, unit->m_temporalwindowsize, unit->m_fullwindowsize, unit->m_buffersize);



    //float ** m_pastfeatures;  //for each feature, a trail of last m_workingmemorysize values
    unit->m_pastfeatures = (float**)RTAlloc(unit->mWorld, unit->m_numfeatures * sizeof(float*));

    for (int j=0; j<unit->m_numfeatures; ++j) {

        unit->m_pastfeatures[j]= (float*)RTAlloc(unit->mWorld, unit->m_buffersize * sizeof(float));

        Clear(unit->m_buffersize, unit->m_pastfeatures[j]); //set all to zero at first

        //for (i=0; i<unit->m_buffersize; ++i) {
        //	unit->m_pastfeatures[j][i] = 0.0;
        //	}
        //
    }

    //main counter
    unit->m_counter= 0;

    //could avoid allocation by having a hard limit on
    unit->bestscore= (float*)RTAlloc(unit->mWorld, 4 * unit->m_numfeatures * sizeof(float));
    unit->bestphase= (int*)RTAlloc(unit->mWorld, 4 * unit->m_numfeatures * sizeof(int));
    unit->besttempo= (int*)RTAlloc(unit->mWorld, 4 * unit->m_numfeatures * sizeof(int));
    unit->bestgroove= (int*)RTAlloc(unit->mWorld, 4 * unit->m_numfeatures * sizeof(int));

    for (int i=0; i<4; ++i) {

        int basepos= i*unit->m_numfeatures;

        for (int j=0; j<unit->m_numfeatures; ++j) {
            unit->bestscore[basepos+j]= -9999.0;
            unit->bestphase[basepos+j]= 0;
            unit->besttempo[basepos+j]= 60;
            unit->bestgroove[basepos+j]= 0;
        }
    }

    unit->m_phase= 0.0;
    unit->m_period= 0.5;
    unit->m_groove= 0;
    unit->m_currtempo=2;
    unit->m_phaseperblock= unit->m_krlength/unit->m_period;

    unit->m_predictphase= 0.4f;
    unit->m_predictperiod = 0.3f;


    unit->m_outputphase= unit->m_phase;
    unit->m_outputtempo= unit->m_currtempo;
    unit->m_outputgroove= unit->m_groove;
    unit->m_outputphaseperblock= unit->m_phaseperblock;



    unit->m_calculationperiod= 0.5; //every half second; could also be additional argument to UGen
    unit->m_calculationschedule= 0.0;

    //printf("srate %f conversion factor %f frame period %f \n", unit->m_srate, unit->m_srateconversion, unit->m_frameperiod);


    int bufnum = (int)(ZIN0(5)+0.001f);
    if (bufnum >= unit->mWorld->mNumSndBufs)
        bufnum = 0;

    if (bufnum<0)
        unit->m_weightingscheme = bufnum<2 ? 0 : 1;
    else {
        SndBuf *buf = unit->mWorld->mSndBufs + bufnum;
        unit->m_tempoweights= buf;
        unit->m_weightingscheme=2;
    }

    //printf("bufnum %d weightingscheme %d check %f %f\n", bufnum, unit->m_weightingscheme, unit->m_tempoweights[0], unit->m_tempoweights[119]);


    unit->halftrig=0;
    unit->q1trig=0;
    unit->q2trig=0;


    unit->mCalcFunc = (UnitCalcFunc)&BeatTrack2_next;

    // initialize outputs
    ZOUT0(0) = 0.0;
    ZOUT0(1) = 0.0;
    ZOUT0(2) = 0.0;
    ZOUT0(3) = unit->m_outputtempo;
    ZOUT0(4) = unit->m_outputphase;
    ZOUT0(5) = unit->m_outputgroove;
}
void BeatTrack2_next(BeatTrack2 *unit, int wrongNumSamples)
{
    //keep updating feature memories
    unit->m_counter= (unit->m_counter+1)%(unit->m_buffersize);

    int busnum = (int)(ZIN0(0)+0.001f);

    //unit->m_features = unit->mWorld->mControlBus + busnum;

    float * features= unit->mWorld->mControlBus + busnum;

    //hmm, is this pointer guaranteed to stay the same? may have to update each time...
    for (int j=0; j<unit->m_numfeatures; ++j) {
        unit->m_pastfeatures[j][unit->m_counter]= features[j]; //unit->m_features[j];
    }

    unit->m_calculationschedule += unit->m_krlength;

    //check for new calculation round
    if(unit->m_calculationschedule> unit->m_calculationperiod) {

        unit->m_calculationschedule -= unit->m_calculationperiod;

        //reset best scores and move old to previous slots
        for (int i=0; i<2; ++i) {

            int pos1= (2+i)*unit->m_numfeatures;
            int pos2= i*unit->m_numfeatures;

            for (int j=0; j<unit->m_numfeatures; ++j) {
                unit->bestscore[pos1+j]= unit->bestscore[pos2+j];
                unit->bestscore[pos2+j]= -9999.0;
                unit->bestphase[pos1+j]= unit->bestphase[pos2+j];
                unit->bestphase[pos2+j]= 0;
                unit->besttempo[pos1+j]= unit->besttempo[pos2+j];
                unit->besttempo[pos2+j]= 60;
            }

        }

        //state 0 is do nothing
        unit->m_amortisationstate=1;
        unit->m_amortcount=0;
        unit->m_amortlength=g_numtempi*2; //
        //unit->m_amortisationsteps=0;

        //store essential data
        unit->m_startcounter = unit->m_counter;

        unit->m_currphase=unit->m_phase;
    }


    //keeps incrementing but will be reset with each calculation run
    //unit->m_amortisationsteps=unit->m_amortisationsteps+1;

    //if state nonzero do something
    switch(unit->m_amortisationstate) {
    case 0:
        break; //do nothing case
    case 1: //calculate acf
        calculatetemplate(unit,unit->m_amortcount >> 1, unit->m_amortcount %2);

        unit->m_amortcount=unit->m_amortcount+1;

        if(unit->m_amortcount==unit->m_amortlength) {
            unit->m_amortisationstate=2;
            //unit->m_amortlength=1;
            //unit->m_amortcount=0;
        }
        break;
    case 2: //done calculating template matches, now decide whether to follow through
        finaldecision(unit);
        unit->m_amortisationstate=0;
        break;

    default:
        break;
    }




    //test if impulse to output
    unit->m_phase+=unit->m_phaseperblock;

    //if(unit->m_counter%400==0) printf("phase %f period %f\n", unit->m_phase, unit->m_period);

    //if not locked, update output phase from model phase, else keep a separate output phase

    float lock= ZIN0(4);
    //printf("lock %f \n",lock);

    if(lock<0.5f) {

        unit->m_outputphase= unit->m_phase;
        unit->m_outputtempo= unit->m_currtempo;
        unit->m_outputgroove= unit->m_groove;
        unit->m_outputphaseperblock= unit->m_phaseperblock;
    } else {

        unit->m_outputphase+=unit->m_outputphaseperblock;

    }

    if (unit->m_phase >= 1.f) {
        unit->m_phase-= 1.f;
    }

    //0 is beat, 1 is quaver, 2 is semiquaver, 3 is actual current tempo in bps
    //so no audio accuracy with beats, just asap, may as well be control rate
    ZOUT0(0)=0.0;
    ZOUT0(1)=0.0;
    ZOUT0(2)=0.0;
    ZOUT0(3)=unit->m_outputtempo; //*0.016666667;
    ZOUT0(4)=unit->m_outputphase;
    ZOUT0(5)=unit->m_outputgroove;

    //output beat
    if (unit->m_outputphase >= 1.f) {

        //printf("beat \n");

        unit->m_outputphase -= 1.f;
        ZOUT0(0)=1.0;
        ZOUT0(1)=1.0;
        ZOUT0(2)=1.0;
        unit->halftrig=0;
        unit->q1trig=0;
        unit->q2trig=0;
    }

    if (unit->m_outputphase>=0.5 && unit->halftrig==0) {
        ZOUT0(1)=1.0;
        ZOUT0(2)=1.0;
        unit->halftrig=1;
    }

    float groove= unit->m_outputgroove *0.07;

    if (unit->m_outputphase>=(0.25+groove) && unit->q1trig==0) {
        ZOUT0(2)=1.0;
        unit->q1trig=1;
    }

    if (unit->m_outputphase>=(0.75+groove) && unit->q2trig==0) {
        ZOUT0(2)=1.0;
        unit->q2trig=1;
    }

}
Exemple #28
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];
	}
}
void SpecFlatness_Ctor(SpecFlatness *unit)
{
	SETCALC(SpecFlatness_next);
	ZOUT0(0) = unit->outval = 0.;
	unit->m_oneovern = 0.;
}