Beispiel #1
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;
}
Beispiel #2
0
void Onsets_next(Onsets *unit, int inNumSamples)
{
	Onsets_GET_BUF

	// In practice, making the polar conversion here in SC is more efficient because SC provides a lookup table method.
	SCPolarBuf *p = ToPolarApx(buf);

	OnsetsDS *ods = unit->m_ods;

	int   odftype  = (int)ZIN0(2);
	float relaxtime     = ZIN0(3);
	int   medspan  = (int)ZIN0(6);

	if(unit->m_needsinit){
		// Init happens here because we need to be sure about FFT size.
		unit->m_odsdata = (float*) RTAlloc(unit->mWorld, onsetsds_memneeded(odftype, buf->samples, medspan) );

		onsetsds_init(ods, unit->m_odsdata, ODS_FFT_SC3_POLAR, odftype, buf->samples, medspan, FULLRATE);
		onsetsds_setrelax(ods, relaxtime, buf->samples>>1);

		unit->m_needsinit = false;
	}
void PV_DecorTransExtract_next(PV_DecorTransExtract *unit, int inNumSamples)
{
	unsigned int numTransBins = 0;
	unsigned int diffBins = 0;
	float kVal = 0.0;
	float outputVal = 0.0;
	float gain = 1.0;

	// this macro gets an FFT chain if it has "fired"
	// otherwise, returns -1 and we go on our way...
	PV_GET_BUF

	// primes the ugen upon first calculation
	if (unit->initFirstCalc)
	{
		unit->numFreqBins = numbins;
		firstCalc(unit);
		unit->initFirstCalc = false;
	}
	
	// check that number of bins is static! this can't change!
	if (unit->numFreqBins != numbins)
	{
		printf("PV_DecorTransExtract: num bins mismatch!\n");
		printf(" - fft chain must be of constant size with PV_DecoreTransExtract()\n");
		printf(" - userbins = %d, numbins = %d\n", unit->numFreqBins, numbins);
		return;
	}
	else if (unit->lowFreqCutVal > unit->numFreqBins)
	{
		printf("PV_DecorTransExtract: low cut bin > number of bins\n");
		printf("setting low cut to 0\n");
		unit->lowFreqCutVal = 0;
		return;
	}

	SCPolarBuf *p = ToPolarApx(buf);

	// store bin values
	for (int i = unit->lowFreqCutVal; i < numbins; ++i)
		unit->prevBins[unit->prevBinsIdx][i] = p->bin[i].mag;

	// calculate average freq history for each bin
	for (int j = unit->lowFreqCutVal; j < numbins; ++j)
		unit->littleOmegaBins[unit->littleOmegaIdx][j] = calcAverageBins(unit, j);

	// reset transient flag
	memset(unit->transFlagBins, 0, unit->numFreqBins * sizeof(bool));

	// printf("mark transients. little omega index = %d\n", unit->littleOmegaIdx);

	for (int i = unit->lowFreqCutVal; i < numbins; ++i)
	{
		unit->bigOmegaBins[i] = calcMinBin(unit, i);

		if (p->bin[i].mag > unit->alphaVal * unit->bigOmegaBins[i])
			numTransBins++;
		else 
		{
			if (numTransBins >= unit->dVal) 
			{
				diffBins = (i - 1) - numTransBins;
				for (int j = (i - 1); j >= diffBins; --j)
					unit->transFlagBins[j] = true;	
			}
			numTransBins = 0;
		}
	}

	// printf("release stage. little omega index = %d\n", unit->littleOmegaIdx);

	// this is where the lower freq bins are cut out
	if (unit->retTrans)
		for (int i = 0; i < unit->lowFreqCutVal; ++i)
		 	p->bin[i].mag = 0.0;

	for (int i = unit->lowFreqCutVal; i < numbins; ++i)
	{
		unit->releaseBins[i] = calcReleaseBin(unit, i);

		kVal = min(unit->releaseBins[i], p->bin[i].mag);
		outputVal = kVal / p->bin[i].mag;

		if (unit->retTrans)
			gain = 1.0 - outputVal;
		else gain = outputVal;

		// apply gain to output
		p->bin[i].mag = gain * p->bin[i].mag;
	}

	// increment circular queue of bins
	if (unit->prevBinsIdx < unit->iVal - 1)
		unit->prevBinsIdx++;
	else unit->prevBinsIdx = 0;

	if (unit->littleOmegaIdx < unit->jVal - 1)
		unit->littleOmegaIdx++;
	else unit->littleOmegaIdx = 0;
}
void MedianSeparation_next( MedianSeparation *unit, int inNumSamples ) {
	
	int i,j;
    
    //calculate medians around pos-midpoint
    int medsize = unit->mediansize_; 
    int mid = unit->midpoint_; 
    
    float * mags = unit->magnitudes_; 
    float * phases = unit->phases_;
    
    float * array = unit->collection_; 
    
    int numbands = unit->fftbins_; 
    int top = numbands-1; 
    
    int pos = unit->magnitudeposition_; 
    
    int midindex = (pos+medsize-mid)%medsize; 
    
    
    float * vertical = unit->verticalmedians_; 
    
    float * horizontal = unit->horizontalmedians_; 
    
    float * magsnow = mags + (midindex*numbands);
    
    
    //cover outputs before early return in macro
    OUT0(0) = -1.f;
    OUT0(1) = -1.f;
    
    
    //0 normal, 
    //1 vertical sort
    //2 horizontal sort
    //3 final output
    
    switch (unit->amortisationstep_) {
        case 0:
        {
            
            //printf("case 0 %f \n",ZIN0(0));
            
            PV_GET_BUF
            
            //avoid output being overwritten by macro to pass input FFT buffer
            OUT0(0) = -1.f;
            OUT0(1) = -1.f;
            
            SCPolarBuf *polar = ToPolarApx(buf);
            
            //update data stored
            
            SCPolar * data = polar->bin; 
            
            int base = unit->magnitudeposition_ * numbands; 
            
            mags[base] = polar->dc; 
            mags[base+numbands-1] = polar->nyq; 
            //no need to set phases for these indices, since will always be 0.0 and initialised in constructor
            
            for (i=0; i<numbands-2; ++i)
                mags[base+i+1] = data[i].mag; 
            
            base = unit->phaseposition_ * numbands;
            
            for (i=0; i<numbands-2; ++i)
                phases[base+i+1] = data[i].phase; 
            
            uint32 bufnum1 = (uint32) IN0(1); //ZIN0(1);
            uint32 bufnum2 = (uint32) IN0(2); //ZIN0(2);
            
            //store for recall in step 3
            
            unit->bufnum1_ = bufnum1;
            unit->bufnum2_ = bufnum2;
            
            //printf("store for recall %d %d what? %d uh? %d %f %f \n",bufnum1,bufnum2,(uint32) IN0(3), (uint32) ZIN0(3), IN0(1),IN0(2));
            
            
            //will have returned early otherwise
            unit->amortisationstep_ =1; 
            break;
            
        }
        case 1:
        {   
            
            //printf("case 1\n");
            
            float medianormean = ZIN0(7); 
            
            //to avoid if inside loop, code copied twice with difference at point of array calculation (median or mean)
            if(medianormean<0.5f) {
                
                //printf("median calc vertical\n");     
                
                //vertical; easier to do in indexing 
                
                for (i=0; i<numbands; ++i) {
                    
                    int lower = i-mid; 
                    if(lower<0) lower =0; 
                    int higher = i+mid; 
                    if(higher>top) higher = top; 
                    int number = higher-lower+1; 
                    
                    float * pnow = magsnow + lower; 
                    
                    //collect into array
                    for (j=0; j<number; ++j)
                        array[j] = pnow[j]; 
                    
                    qsort(array,number,sizeof(float),cmp);
                    //result is midpoint of magnitudes
                    
                    vertical[i] = array[number/2];
                    
                }
                
            } else {
                
                float sum; 
                
                for (i=0; i<numbands; ++i) {
                    
                    int lower = i-mid; 
                    if(lower<0) lower =0; 
                    int higher = i+mid; 
                    if(higher>top) higher = top; 
                    int number = higher-lower+1; 
                    
                    float * pnow = magsnow + lower; 
                    //                    
                    //                    //collect into array
                    //                    for (j=0; j<number; ++j)
                    //                        array[j] = pnow[j]; 
                    //                    
                    sum = 0.0f; 
                    
                    //no need for intermediate array 
                    for (j=0; j<number; ++j)
                        sum += pnow[j]; 
                    
                    vertical[i] = sum/number;
                    
                }
                
                
                
            }
            
            
            unit->amortisationstep_ = 2; 
            break;
        }    
        case 2:
        {   
            
            //printf("case 2\n");
            //horizontal, requires cross steps within 2D array
            
            float medianormean = ZIN0(7); 
            
            if(medianormean<0.5f) {
                
                
                //printf("median calc horizontal\n");   
                
                for (i=0; i<numbands; ++i) {
                    
                    //no checks required for the medsize, but have to get correct indices
                    
                    //collect into array
                    for (j=0; j<medsize; ++j)
                        array[j] = mags[(j*numbands) + i]; 
                    
                    qsort(array,medsize,sizeof(float),cmp);
                    //result is midpoint of magnitudes
                    
                    horizontal[i] = array[mid];
                    
                }
                
            } else {
                
                //mean
                
                float sum; 
                float recip = 1.0f/medsize; 
                
                for (i=0; i<numbands; ++i) {
                    
                    //no checks required for the medsize, but have to get correct indices
                    
                    sum = 0.0f; 
                    //sum up directly, no need for array 
                    for (j=0; j<medsize; ++j)
                        sum+= mags[(j*numbands) + i]; 
                    
                    horizontal[i] = sum*recip;
                    
                }                
                
            }
            
            unit->amortisationstep_ = 3; 
            break;
            
        }     
        case 3:
        {
            
            //printf("case 3\n");
            uint32 bufnum1 = unit->bufnum1_; //(uint32) ZIN0(1);
            uint32 bufnum2 = unit->bufnum2_; //(uint32) ZIN0(2);
            
            //printf("now recall %d %d \n",bufnum1,bufnum2);
            
            World *world = unit->mWorld;

            SndBuf *buf1, *buf2;

            if (bufnum1 >= world->mNumSndBufs) {
                int localBufNum = bufnum1 - world->mNumSndBufs;
                Graph *parent = unit->mParent;
                if(localBufNum <= parent->localBufNum) {
                    buf1 = parent->mLocalSndBufs + localBufNum;
                } else {
                    buf1 = world->mSndBufs;
                }
            } else {
                buf1 = world->mSndBufs + bufnum1;
            }

            LOCK_SNDBUF(buf1);

            if (bufnum2 >= world->mNumSndBufs) {
                int localBufNum = bufnum2 - world->mNumSndBufs;
                Graph *parent = unit->mParent;
                if(localBufNum <= parent->localBufNum) {
                    buf2 = parent->mLocalSndBufs + localBufNum;
                } else {
                    buf2 = world->mSndBufs;
                }
            } else {
                buf2 = world->mSndBufs + bufnum2;
            }

            LOCK_SNDBUF(buf2);

            int numbins1 = (buf1->samples >> 1)  + 1;
            int numbins2 = (buf2->samples >> 1)  + 1;

            //printf("check %d %d numbands %d further check %d %d \n",numbins1,numbins2,numbands,buf1->samples,buf2->samples);


            if((numbins1 == numbands) && (numbins2 ==numbands)) {

                int hardorsoft = ZIN0(5);

                //unit->hardorsoft_ = ZIN0(5);
                //unit->p_ = ZIN0(6);

                //to magnitude and phase representation
                SCPolarBuf *polar1 = ToPolarApx(buf1);
                SCPolarBuf *polar2 = ToPolarApx(buf2);

                SCPolar * data1 = polar1->bin;
                SCPolar * data2 = polar2->bin;

                //writing into the two output arrays of the buffers


                //magsnow already pointing to write place in magnitudes
                //magsnow = mags + (midindex*numbands);

                //+mid+2, adding so no danger, just add 1
                int phaseindex = (unit->phaseposition_+1)%(mid+1); //midpoint is next one (about to be overwritten after increment below)

                float * phasesnow = phases + (phaseindex*numbands);

                //dc, nyquist, phase to zero

                //buf1,polar 1 is harmonic, 2 is percussive

                //0 larger of horizontal and vertical is winner, or 1 more subtle blend
                if(hardorsoft==0) {
                    //hard

                    //printf("hard calc \n");

                    if(horizontal[0]>vertical[0]) {

                        polar1->dc = magsnow[0];
                        polar2->dc = 0.f;

                    } else {

                        polar2->dc = magsnow[0];
                        polar1->dc = 0.f;
                    }


                    if(horizontal[top]>vertical[top]) {

                        polar1->nyq = magsnow[top];
                        polar2->nyq = 0.f;

                    } else {

                        polar2->nyq = magsnow[top];
                        polar1->nyq = 0.f;
                    }

                    int count = 0;

                    //setting
                    for (i=0; i<numbands-2; ++i) {

                        int indexnow = i+1;

                        //if(i==20) {data1[i].mag=1024; data2[i].mag=1024;}

                        //else {data1[i].mag = 0.0f; data2[i].mag = 0.f;}


                        if(horizontal[indexnow]>vertical[indexnow]) {

                            ++count;

                            data1[i].mag = magsnow[indexnow];
                            data1[i].phase = phasesnow[indexnow];
                            data2[i].mag = 0.0f;
                            data2[i].phase = 0.0f; //phasesnow[i+1];

                        } else {

                            data2[i].mag = magsnow[indexnow];
                            data2[i].phase = phasesnow[indexnow];
                            data1[i].mag = 0.0f;
                            data1[i].phase = 0.0f; //phasesnow[i+1];

                        }

                        //                        if(i<10) {
                        //
                        //                            printf("mag %d %f %f horiz %f vert %f further %f %f \n ",i, data1[i].mag,data2[i].mag,horizontal[indexnow],vertical[indexnow],polar1->bin[i].mag,polar2->bin[i].mag);
                        //
                        //                        }
                        //
                    }


                    //printf("count %d \n",count);


                } else {


                    //printf("I hope not!\n");

                    //soft, Wiener filtering
                    float pfactor = ZIN0(6);

                    float maskp, maskh, hp, pp, combine;

                    //dc
                    hp = powf(horizontal[0],pfactor);
                    pp = powf(vertical[0],pfactor);

                    combine = hp+pp;

                    maskh = 0.f;
                    maskp = 0.f;

                    //watch for zeroes
                    if(combine>0.00000000001f) {
                        maskh = hp/combine;
                        maskp = pp/combine;
                    }

                    polar1->dc = magsnow[0] * maskh;
                    polar2->dc = magsnow[0] * maskp;

                    //nyquist
                    hp = powf(horizontal[top],pfactor);
                    pp = powf(vertical[top],pfactor);

                    combine = hp+pp;

                    maskh = 0.f;
                    maskp = 0.f;

                    //watch for zeroes
                    if(combine>0.00000000001f) {
                        maskh = hp/combine;
                        maskp = pp/combine;
                    }

                    polar1->nyq = magsnow[top] * maskh;
                    polar2->nyq = magsnow[top] * maskp;

                    //setting
                    for (i=0; i<numbands-2; ++i) {

                        int indexnow = i+1;

                        hp = powf(horizontal[indexnow],pfactor);
                        pp = powf(vertical[indexnow],pfactor);

                        combine = hp+pp;

                        //if(i<5) {
                        //     printf("mag %d %f %f %f %f %f \n",i ,horizontal[indexnow],vertical[indexnow],hp,pp,combine);
                        //}

                        maskh = 0.f;
                        maskp = 0.f;

                        //watch for zeroes
                        if(combine>0.00000000001f) {
                            maskh = hp/combine;
                            maskp = pp/combine;
                        }

                        data1[i].mag = magsnow[indexnow] * maskh;
                        data1[i].phase = phasesnow[indexnow];
                        data2[i].mag = magsnow[indexnow] * maskp;
                        data2[i].phase = phasesnow[indexnow];

                    }


                }


                //printf("now output %d %d \n",bufnum1,bufnum2);

                //update output

                OUT0(0) = bufnum1; //2.f; //-1.f; //bufnum1; //-1;
                OUT0(1) = bufnum2; //-1;

            }

            unit->magnitudeposition_ = (unit->magnitudeposition_+1)%medsize; 
            unit->phaseposition_ = (unit->phaseposition_+1)%(mid+1); 
            
            unit->amortisationstep_ = 0; 
            break;
        }   
        default:
            //printf("default\n");
            break;
    }
    
    //printf("actual output %f %f \n",OUT0(0),OUT0(1));
    
 
 
    
    //    for(j=0; j<inNumSamples; ++j) {
    //		
    //		output[j]= input[j]*0.1; //((float)j/inNumSamples); 
    //	}
}