예제 #1
0
파일: DelayN.cpp 프로젝트: Angeldude/pd
void DelayN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out)
{
    t_sample *nin = *in;
    t_sample *nout = *out;

    float *dlybuf = m_dlybuf;
    long iwrphase = m_iwrphase;
    float dsamp = m_dsamp;
    long mask = m_mask;

    if (changed)
    {
	float next_dsamp = CalcDelay(m_delaytime);
	float dsamp_slope = CALCSLOPE(next_dsamp, dsamp);
		
	for (int i = 0; i!= n;++i)
	{
	    dlybuf[iwrphase & mask] = ZXP(nin);
	    dsamp += dsamp_slope;
	    ++iwrphase;
	    long irdphase = iwrphase - (long)dsamp;
	    ZXP(nout) = dlybuf[irdphase & mask];
	}
	m_dsamp = dsamp;
	changed = false;
    }
    else
    {
	long irdphase = iwrphase - (long)dsamp;
	float* dlybuf1 = dlybuf - ZOFF;
	float* dlyrd   = dlybuf1 + (irdphase & mask);
	float* dlywr   = dlybuf1 + (iwrphase & mask);
	float* dlyN    = dlybuf1 + m_idelaylen;
	long remain = n;
	while (remain) 
	{
	    long rdspace = dlyN - dlyrd;
	    long wrspace = dlyN - dlywr;
	    long nsmps = sc_min(rdspace, wrspace);
	    nsmps = sc_min(remain, nsmps);
	    remain -= nsmps;
	    for (int i = 0; i!= nsmps;++i)
	    {
		ZXP(dlywr) = ZXP(nin);
		ZXP(nout) = ZXP(dlyrd);
	    }
	    if (dlyrd == dlyN) dlyrd = dlybuf1;
	    if (dlywr == dlyN) dlywr = dlybuf1;
	}
	iwrphase += n;
    }
    m_iwrphase = iwrphase;
}
예제 #2
0
int sc_strtoi(const char *str, int n, int base)
{
	int z = 0;
	for (int i=0; i<n; ++i)
	{
		int c = *str++;
		if (!c) break;
		if (c >= '0' && c <= '0' + sc_min(10,base) - 1) z = z * base + c - '0';
		else if (c >= 'a' && c <= 'a' + sc_min(36,base) - 11) z = z * base + c - 'a' + 10;
		else if (c >= 'A' && c <= 'A' + sc_min(36,base) - 11) z = z * base + c - 'A' + 10;
	}
	return z;
}
예제 #3
0
파일: GC.cpp 프로젝트: scztt/sc-debug
PyrObject *PyrGC::NewFrame(size_t inNumBytes, long inFlags, long inFormat, bool inAccount)
{
	PyrObject *obj = NULL;

#if SANITYCHECK
	SanityCheck();
#endif

	// obtain size info

	int32 alignedSize = (inNumBytes + kAlignMask) & ~kAlignMask; // 16 byte align
	int32 numSlots = alignedSize / sizeof(PyrSlot);
	numSlots = numSlots < 1 ? 1 : numSlots;
	int32 sizeclass = LOG2CEIL(numSlots);
	sizeclass = sc_min(sizeclass, kNumGCSizeClasses-1);

	int32 credit = 1L << sizeclass;
	mAllocTotal += credit;
	mNumAllocs++;
	if (inAccount) {
		mNumToScan += credit;
		if (mNumToScan >= kScanThreshold) {
			Collect();
		}
	}

	GCSet *gcs = mSets + sizeclass;

	obj = (PyrObject*)gcs->mFree;
	if (!IsMarker(obj)) {
		// from free list
		gcs->mFree = obj->next;
	} else {
		if (sizeclass > kMaxPoolSet) {
			SweepBigObjects();
			int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass);
			obj = (PyrObject*)mPool->Alloc(allocSize);
		} else {
			int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass);
			obj = (PyrObject*)mNewPool.Alloc(allocSize);
		}
		if (!obj) {
			post("Frame alloc failed. size = %d\n", inNumBytes);
			MEMFAILED;
		}
		DLInsertAfter(&gcs->mWhite, obj);
	}

	obj->obj_sizeclass = sizeclass;
	obj->obj_format = inFormat;
	obj->obj_flags = inFlags;
	obj->size = 0;
	obj->classptr = class_frame;
	obj->gc_color = mWhiteColor;

#if SANITYCHECK
	SanityCheck();
#endif
	return obj;
}
예제 #4
0
파일: GC.cpp 프로젝트: ASauer/supercollider
HOT PyrObject *PyrGC::NewFrame(size_t inNumBytes, long inFlags, long inFormat, bool inAccount)
{
	PyrObject *obj = NULL;

#ifdef GC_SANITYCHECK
	SanityCheck();
#endif

	// obtain size info

	int32 alignedSize = (inNumBytes + kAlignMask) & ~kAlignMask; // 16 byte align
	int32 numSlots = alignedSize / sizeof(PyrSlot);
	numSlots = numSlots < 1 ? 1 : numSlots;
	int32 sizeclass = LOG2CEIL(numSlots);
	sizeclass = sc_min(sizeclass, kNumGCSizeClasses-1);

	int32 credit = 1L << sizeclass;
	mAllocTotal += credit;
	mNumAllocs++;
	mNumToScan += credit;

	obj = Allocate(inNumBytes, sizeclass, inAccount);

	obj->obj_format = inFormat;
	obj->obj_flags = inFlags;
	obj->size = 0;
	obj->classptr = class_frame;
	obj->gc_color = mWhiteColor;

#ifdef GC_SANITYCHECK
	SanityCheck();
#endif
	return obj;
}
예제 #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 MatchingP_Ctor(MatchingP* unit)
{
	SETCALC(MatchingP_next);

	//  [trigger, residual, activ0, activ1,...] = MatchingP.ar(dict, in, dictsize, ntofind, hop=1, method=0)

	CTOR_GET_BUF

	// initialize the unit generator state variables.
	unit->m_dictsize = IN0(2);
	if(unit->m_dictsize != buf->channels){
		printf("ERROR: (unit->m_dictsize != bufChannels)\n");
		SETCALC(ClearUnitOutputs);
		return;
	}
	unit->m_hopspls  = static_cast<int>(sc_max(0.f, sc_min(1.f, IN0(4))) * buf->frames);
	unit->m_shuntspls = buf->frames - unit->m_hopspls;
	const int ntofind = (const int)IN0(3);
	// UNUSED: unit->mMethod = IN0(5);

	unit->m_audiowritepos    = unit->m_hopspls;
	unit->m_audioplaybackpos = 0;
	// audiobuf size is bufFrames + hopspls -- playback happens in first bufFrames, input is written in last hopspls, analysis is in last bufFrames
	unit->m_audiobuf    = (float* )RTAlloc(unit->mWorld, sizeof(float)  * (buf->frames + unit->m_hopspls));
	Clear(buf->frames + unit->m_hopspls, unit->m_audiobuf);
	// "activations" will contain [index0, activ0, index1, activ1, ... ]
	unit->m_activations = (float* )RTAlloc(unit->mWorld, sizeof(float)  * 2 * ntofind);

	// calculate one sample of output.
	unit->m_fbufnum = -9.9e9; // set it to something that will force the buffer info to be updated when _next runs
	MatchingP_next(unit, 1);
}
예제 #7
0
파일: DWG.hpp 프로젝트: LFSaw/sc3-plugins
    void set_area(float a1,float lossF)
    {
        if(a1 < 1e-18)
            loss = 0.0;
        else
            loss = 1.0 - sc_min(lossF/sqrt(a1),1.0f);

    }
예제 #8
0
double sc_strtof(const char *str, int n, int base)
{
	double z = 0.;
	int decptpos = 0;
	for (int i=0; i<n; ++i)
	{
		int c = *str++;
		if (!c) break;
		if (c >= '0' && c <= '0' + sc_min(10,base) - 1) z = z * base + c - '0';
		else if (c >= 'a' && c <= 'a' + sc_min(36,base) - 11) z = z * base + c - 'a' + 10;
		else if (c >= 'A' && c <= 'A' + sc_min(36,base) - 11) z = z * base + c - 'A' + 10;
		else if (c == '.') decptpos = i;
	}
	//calculation previously included decimal point in count of columns (was n-decptpos); there are 1 less than n characters which are columns in the number contribution
	z = z / pow((double)base, n -1- decptpos);
	return z;
}
int vpost(const char *fmt, va_list ap)
{
	char buf[512];
	int n = vsnprintf(buf, sizeof(buf), fmt, ap);
	if (n > 0) {
		SC_LanguageClient::instance()->postText(buf, sc_min(n, sizeof(buf) - 1));
	}
	return 0;
}
예제 #10
0
void Squiz_next(Squiz *unit, int inNumSamples)
{
	float *in = ZIN(0);
	float *out = ZOUT(0);

	float *buf = unit->m_buf;
	int buflen = unit->m_buflen;

	float ratio = sc_min(sc_max(ZIN0(1), 1.0f), (float)buflen); // pitch ratio; also === the sample-by-sample readback increment
	int zcperchunk = (int)ZIN0(2);

	int writepos = unit->m_writepos;
	float prevval = unit->m_prevval; // Used for checking for positivegoing zero crossings
	float readpos = unit->m_readpos; // Where in the buffer we're reading back from. Float value for accuracy, cast to uninterpolated int position though.
	int zcsofar = unit->m_zcsofar;

	float curval, outval;
	int readposi;
	for (int i=0; i < inNumSamples; ++i)
	{
		// First we read from the buffer
		readposi = (int)readpos;
		if(readposi >= buflen){
			outval = 0.f;
		}else{
			outval = buf[readposi];
			// postincrement the play-head position
			readpos += ratio;
		}

		// Next we write to the buffer
		curval = ZXP(in);
		writepos++;

		// If positive-going zero-crossing (or if buffer full), this is a new segment.
		//Print("zcsofar: %i\n", zcsofar);
		if((writepos==buflen) || (prevval<0.f && curval>=0.f && (++zcsofar >= zcperchunk))){
			writepos = 0;
			readpos = 0.f;
			zcsofar = 0;
		}
		buf[writepos] = curval;

		//Print("prevval: %g, curval: %g, on: %i, drop: %i, outof: %i, mode: %i\n", prevval, curval, on, drop, outof, mode);

		// Now output the thing we read
		ZXP(out) = outval;
		prevval = curval;
	}

	// Store state
	unit->m_writepos = writepos;
	unit->m_readpos = readpos;
	unit->m_prevval = prevval;
	unit->m_zcsofar = zcsofar;
}
예제 #11
0
void error(const char *fmt, ...)
{
	char buf[512];
    va_list ap;
    va_start(ap, fmt);
	int n = vsnprintf(buf, sizeof(buf), fmt, ap);
	if (n > 0) {
		SC_LanguageClient::instance()->postError(buf, sc_min(n, sizeof(buf) - 1));
	}
}
예제 #12
0
int vpost(const char *fmt, va_list ap)
{
	char buf[512];
	int n = vsnprintf(buf, sizeof(buf), fmt, ap);
	if (n > 0) {
		SC_LanguageClient *client = SC_LanguageClient::lockedInstance();
		if (client) client->postText(buf, sc_min(n, sizeof(buf) - 1));
		SC_LanguageClient::unlockInstance();
	}
	return 0;
}
예제 #13
0
double hypotx(double x, double y)
{
	double minxy;

	x = fabs(x);
	y = fabs(y);

	minxy = sc_min(x,y);

	return x + y - SQRT2M1 * minxy;
}
void error(const char *fmt, ...)
{
	char buf[512];
	va_list ap;
	va_start(ap, fmt);
	int n = vsnprintf(buf, sizeof(buf), fmt, ap);
	if (n > 0) {
		SC_LanguageClient *client = SC_LanguageClient::lockedInstance();
		if (client) client->postError(buf, sc_min(n, sizeof(buf) - 1));
		SC_LanguageClient::unlockInstance();
	}
}
예제 #15
0
void
sc_filter_ansitropic(GLenum target)
{
    static float max = -1.0f;
    float level;
    if (!GLEE_EXT_texture_filter_anisotropic)
        return;
    if (max < 0)
        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max);
    level = sc_min((int)max, sc_config.ansitropic_filtering);
    if (level > 1)
        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, level);
}
예제 #16
0
t_int *lfnoise_perform(t_int *w){
    t_lfnoise       *x      = (t_lfnoise *) w[1];	
    t_float         *out    = (t_float *)       w[3];
	int             remain  = (int)  w[4];
    
    t_float         freq    = x->m_connected ? (*(t_float *)(w[2])) : x->m_freq;
    float           level   = x->m_level;
	float           slope   = x->m_slope;
    float           curve   = x->m_curve;
    int32            counter = x->m_counter;
    
    
    if (x->ob.z_disabled) return w + 5;
    
	
	RGET
    
	do {
		if (counter<=0) {
			float value = x->m_nextvalue;
			x->m_nextvalue = frand2(s1,s2,s3);
			level = x->m_nextmidpt;
			x->m_nextmidpt = (x->m_nextvalue + value) * 0.5;
            
			counter = (int32)(x->m_sr / sc_max(freq, 0.001f));
			counter = sc_max(2, counter);
			float fseglen = (float)counter;
			curve = 2.f * (x->m_nextmidpt - level - fseglen * slope) / (fseglen * fseglen + fseglen);
		}
        
		int nsmps = sc_min(remain, counter);
		remain -= nsmps;
		counter -= nsmps;
        
        while (nsmps--) {
            *out++ = level;
            slope += curve;
			level += slope;
        }

	} while (remain);

	x->m_level  = level;
	x->m_slope  = slope;
    x->m_curve  = curve;
	x->m_counter= counter;
	
    RPUT
    
	return w + 5;
}
예제 #17
0
int pstrcmp(unsigned char *s1, unsigned char *s2)
{
	int i, len1, len2, len;
	len1 = *s1++;
	len2 = *s2++;
	len = sc_min(len1, len2);
	for (i=0; i<len; ++i) {
		if (s1[i] < s2[i]) return -1;
		if (s1[i] > s2[i]) return 1;
	}
	if (len1 < len2) return -1;
	if (len1 > len2) return 1;
	return 0;
}
예제 #18
0
void FFT_Ctor(FFT *unit)
{
	int winType = sc_clip((int)ZIN0(3), -1, 1); // wintype may be used by the base ctor
	unit->m_wintype = winType;
	if(!FFTBase_Ctor(unit, 5)){
		SETCALC(FFT_ClearUnitOutputs);
		// These zeroes are to prevent the dtor freeing things that don't exist:
		unit->m_inbuf = 0;
		unit->m_scfft = 0;
		return;
	}
	int audiosize = unit->m_audiosize * sizeof(float);

	int hopsize = (int)(sc_max(sc_min(ZIN0(2), 1.f), 0.f) * unit->m_audiosize);
	if (hopsize < unit->mWorld->mFullRate.mBufLength) {
		Print("FFT_Ctor: hopsize smaller than SC's block size (%i) - automatically corrected.\n", hopsize, unit->mWorld->mFullRate.mBufLength);
		hopsize = unit->mWorld->mFullRate.mBufLength;
	} else if (((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength
				!= hopsize) {
		Print("FFT_Ctor: hopsize (%i) not an exact multiple of SC's block size (%i) - automatically corrected.\n", hopsize, unit->mWorld->mFullRate.mBufLength);
		hopsize = ((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength;
	}
	unit->m_hopsize = hopsize;
	unit->m_shuntsize = unit->m_audiosize - hopsize;

	unit->m_inbuf = (float*)RTAlloc(unit->mWorld, audiosize);

	SCWorld_Allocator alloc(ft, unit->mWorld);
	unit->m_scfft = scfft_create(unit->m_fullbufsize, unit->m_audiosize, (SCFFT_WindowFunction)unit->m_wintype, unit->m_inbuf,
								 unit->m_fftsndbuf->data, kForward, alloc);

	if (!unit->m_scfft) {
		SETCALC(*ClearUnitOutputs);
		return;
	}

	memset(unit->m_inbuf, 0, audiosize);

	//Print("FFT_Ctor: hopsize %i, shuntsize %i, bufsize %i, wintype %i, \n",
	//	unit->m_hopsize, unit->m_shuntsize, unit->m_bufsize, unit->m_wintype);

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

	SETCALC(FFT_next);
}
예제 #19
0
	void calcFilterCoefficients(const double newFreq, double & a, double & a2, double & a_inv,
								double & b, double & b2, double & c, double & g, double & g0)
	{
		double fc = sc_max(10, newFreq) * sampleDur();
		fc = sc_min(fc, 0.25);
		a = M_PI * fc; // PI is Nyquist frequency
//		a = 2 * tan(0.5*a); // dewarping, not required with 2x oversampling

		a_inv = 1/a;

		a2 = a*a;
		b = 2*a + 1;
		b2 = b*b;
		c = 1 / (2*a2*a2 - 4*a2*b2 + b2*b2);
		g0 = 2*a2*a2*c;
		g = g0 * bh;
	}
예제 #20
0
파일: Logistic.cpp 프로젝트: Angeldude/pd
void Logistic_ar::m_signal(int n, t_sample *const *in, 
			       t_sample *const *out)
{
    t_sample *nout = *out;

    if(m_sr == m_paramf)
    {
	/* it might be possible to implement this without the branch */

	double y1 = m_y1;
	double paramf = m_paramf;
	for (int i = 0; i!= n;++i)
	{
	    (*(nout)++)= y1 = paramf * y1 * (1.0 - y1);
	}
	m_y1 = y1;
    }
    else
    {
	double y1 = m_y1;
	double paramf = m_paramf;
	int counter = m_counter;
	int remain = n;
	do
	{
	    if (counter<=0) 
	    {
		counter = (int)(m_sr / sc_max(m_freq, .001f));
		counter = sc_max(1, counter);
		y1 = paramf * y1 * (1.0 - y1);
	    }
	    
	    int nsmps = sc_min(remain, counter);
	    remain -= nsmps;
	    counter -= nsmps;
	    
	    for (int i = 0; i!= nsmps;++i)
	    {
		(*(nout)++)=y1;
	    }
	}
	while(remain);
	m_y1 = y1;
	m_counter = counter;
    }
}
예제 #21
0
파일: DWG.hpp 프로젝트: LFSaw/sc3-plugins
	float Convol(T &buf)
	{
		int AlSize = buf.buffer_size;
		assertv(AlSize >= kernel_size);
		float sum=0.;

		//int pAl2 = (buf.pointer - kernel_size + 1);
		//pAl2 = pAl2%AlSize;
		//if( pAl2 < 0 ){ pAl2 += AlSize;}
		int pAl2 = buf.pointerInRange(buf.pointer + kernel_size - 1);
		int howmany = sc_min(AlSize - pAl2,kernel_size);
		for(int i=0; i < howmany; i++)
			sum += Kernel[i]*buf.Buffer[pAl2 + i];
		int howmany2 = kernel_size - howmany;
		for(int i=0; i < howmany2; i++)
			sum += Kernel[howmany + i]*buf.Buffer[i];
		return sum;
	}
예제 #22
0
int prSymbolIsPrefix(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b;
	int length;

	a = g->sp - 1;
	b = g->sp;
	if (!IsSym(a) || !IsSym(b)) return errWrongType;
	int32 alen = slotRawSymbol(a)->length;
	int32 blen = slotRawSymbol(b)->length;
	length = sc_min(alen, blen);
	if (memcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name, length) == 0) {
		SetTrue(a);
	} else {
		SetFalse(a);
	}
	return errNone;
}
예제 #23
0
void
sc_lv_base::assign_from_string( const std::string& s )
{
    // s must have been converted to bin
    int len = m_len;
    int s_len = s.length() - 1;
    int min_len = sc_min( len, s_len );
    int i = 0;
    for( ; i < min_len; ++ i ) {
	char c = s[s_len - i - 1];
	set_bit( i, sc_logic::char_to_logic[(int)c] );
    }
    // if formatted, fill the rest with sign(s), otherwise fill with zeros
    sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
		                             : sc_logic_value_t( 0 ));
    for( ; i < len; ++ i ) {
	set_bit( i, fill );
    }
}
예제 #24
0
void FFT_Ctor(FFT *unit)
{
	unit->m_wintype = (int)ZIN0(3); // wintype may be used by the base ctor
	if(!FFTBase_Ctor(unit, 5)){
		SETCALC(FFT_ClearUnitOutputs);
		// These zeroes are to prevent the dtor freeing things that don't exist:
		unit->m_inbuf = 0;
		unit->m_transformbuf = 0;
		unit->m_scfft = 0;
		return;
	}
	int fullbufsize = unit->m_fullbufsize * sizeof(float);
	int audiosize = unit->m_audiosize * sizeof(float);

	int hopsize = (int)(sc_max(sc_min(ZIN0(2), 1.f), 0.f) * unit->m_audiosize);
	if (((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength
				!= hopsize) {
		Print("FFT_Ctor: hopsize (%i) not an exact multiple of SC's block size (%i) - automatically corrected.\n", hopsize, unit->mWorld->mFullRate.mBufLength);
		hopsize = ((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength;
	}
	unit->m_hopsize = hopsize;
	unit->m_shuntsize = unit->m_audiosize - hopsize;

	unit->m_inbuf = (float*)RTAlloc(unit->mWorld, audiosize);

	unit->m_transformbuf = (float*)RTAlloc(unit->mWorld, scfft_trbufsize(unit->m_fullbufsize));
	unit->m_scfft        = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
	scfft_create(unit->m_scfft, unit->m_fullbufsize, unit->m_audiosize, unit->m_wintype, unit->m_inbuf, unit->m_fftsndbuf->data, unit->m_transformbuf, true);

	memset(unit->m_inbuf, 0, audiosize);

	//Print("FFT_Ctor: hopsize %i, shuntsize %i, bufsize %i, wintype %i, \n",
	//	unit->m_hopsize, unit->m_shuntsize, unit->m_bufsize, unit->m_wintype);

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

	SETCALC(FFT_next);
}
예제 #25
0
파일: LFNoise1.cpp 프로젝트: Angeldude/pd
void LFNoise1_ar::m_signal(int n, t_sample *const *in, 
			       t_sample *const *out)
{
    t_sample *nout = *out;

    float level = m_level;
    int32 counter = m_counter;
    float slope = m_slope;
    
    RGET;

    int remain = n;
    do
    {
	if (counter<=0) 
	{
	    counter = (int)(m_sr / sc_max(m_freq, .001f));
	    counter = sc_max(1, counter);
	    float nextlevel = frand2(s1,s2,s3);
	    slope = (nextlevel - level) / counter;
	}
	int nsmps = sc_min(remain, counter);
	remain -= nsmps;
	counter -= nsmps;
	
	for (int i = 0; i!= nsmps;++i)
	{
	    (*(nout)++)=level;
	    level+=slope;
	}
    }
    while(remain);

    m_level = level;
    m_counter = counter;
    m_slope = slope;
    
    RPUT;
}
예제 #26
0
파일: GC.cpp 프로젝트: ASauer/supercollider
PyrObject *PyrGC::NewPermanent(size_t inNumBytes, long inFlags, long inFormat)
{
	// obtain size info
	int32 alignedSize = (inNumBytes + kAlignMask) & ~kAlignMask; // 16 byte align
	int32 numSlots = alignedSize / sizeof(PyrSlot);
	numSlots = numSlots < 1 ? 1 : numSlots;
	int32 sizeclass = LOG2CEIL(numSlots);
	sizeclass = sc_min(sizeclass, kNumGCSizeClasses-1);

	int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass);

	// allocate permanent objects
	PyrObject* obj = (PyrObject*)pyr_pool_runtime->Alloc(allocSize);

	obj->gc_color = obj_permanent;
	obj->next = obj->prev = NULL;
	obj->obj_sizeclass = sizeclass;
	obj->obj_format = inFormat;
	obj->obj_flags = inFlags;
	obj->size = 0;
	obj->classptr = class_object;
	return obj;
}
예제 #27
0
파일: GC.cpp 프로젝트: ASauer/supercollider
HOT void PyrGC::DoPartialScan(int32 inObjSize)
{
	int32 remain = inObjSize - mPartialScanSlot;
	mNumPartialScans++;
	if (remain <= 0) {
		mPartialScanObj = NULL;
		mNumToScan -= 4;
		if (mNumToScan<0) mNumToScan = 0;
		return;
	}
	int32 numtoscan = sc_min(remain, mNumToScan);
	ScanSlots(mPartialScanObj->slots + mPartialScanSlot, numtoscan);

	if (numtoscan == remain) {
		mPartialScanObj = NULL;
		mNumToScan -= numtoscan + 4;
	} else {
		mPartialScanSlot += numtoscan;
		mNumToScan -= numtoscan;
	}
	if (mNumToScan < 0) mNumToScan = 0;
	//post("partial %5d xx %4d %2d %s\n", mScans, mNumToScan, mNumGrey);
	//post("partial %5d %2d %4d %2d %s\n", mScans, i, mNumToScan, mNumGrey, slotRawSymbol(&obj->classptr->name)->name);
}
예제 #28
0
int yylex()
{
	int r, c, c2, d;
	int radix;
    char extPath[MAXPATHLEN]; // for error reporting

	yylen = 0;
	// finite state machine to parse input stream into tokens

	if (lexCmdLine == 1) {
		lexCmdLine = 2;
		r = INTERPRET;
		goto leave;
	}
start:
	c = input();

	if (c == 0)   { r = 0; goto leave; }
	else if (c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f') {
		yylen = 0;
		goto start;
	}
	else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') goto ident;
	else if (c == '/') {
		c = input();
		if (c == '/') goto comment1;
		else if (c == '*') goto comment2;
		else { unput(c); goto binop; }
	}
	else if (c >= '0' && c <= '9') goto digits_1;
	else if (c == OPENPAREN || c == OPENSQUAR || c == OPENCURLY) {
		pushls(&brackets, (int)c);
		if (c == OPENCURLY) {
			pushls(&closedFuncCharNo, linestarts[lineno] + charno - 1);
		}
		r = c;
		goto leave;
	}
	else if (c == CLOSSQUAR) {
		if (!emptyls(&brackets)) {
			if ((d = popls(&brackets)) != OPENSQUAR) {
				fatal();
				post("opening bracket was a '%c', but found a '%c'\n",d,c);
				goto error2;
			}
		} else {
			fatal();
			post("unmatched '%c'\n",c);
			goto error2;
		}
		r = c;
		goto leave;
	}
	else if (c == CLOSPAREN) {
		if (!emptyls(&brackets)) {
			if ((d = popls(&brackets)) != OPENPAREN) {
				fatal();
				post("opening bracket was a '%c', but found a '%c'\n",d,c);
				goto error2;
			}
		} else {
			fatal();
			post("unmatched '%c'\n",c);
			goto error2;
		}
		r = c;
		goto leave;
	}
	else if (c == CLOSCURLY) {
		if (!emptyls(&brackets)) {
			if ((d = popls(&brackets)) != OPENCURLY) {
				fatal();
				post("opening bracket was a '%c', but found a '%c'\n",d,c);
				goto error2;
			}
			lastClosedFuncCharNo = popls(&closedFuncCharNo);
		} else {
			fatal();
			post("unmatched '%c'\n",c);
			goto error2;
		}
		r = c;
		goto leave;
	}
	else if (c == '^') { r = c; goto leave; }
	else if (c == '~') { r = c; goto leave; }
	else if (c == ';') { r = c; goto leave; }
	else if (c == ':') { r = c; goto leave; }
	else if (c == '`') { r = c; goto leave; }
	else if (c == '\\') goto symbol1;
	else if (c == '\'') goto symbol3;
	else if (c == '"') goto string1;
	else if (c == '.') {
		if ((c = input()) == '.') {
			if ((c = input()) == '.') {
				r = ELLIPSIS;
				goto leave;
			} else {
				r = DOTDOT;
				unput(c);
				goto leave;
			}
		} else {
			unput(c);
			r = '.';
			goto leave;
		}

	}
	else if (c == '#') {
		if ((c = input()) == OPENCURLY) {
			pushls(&brackets, OPENCURLY);
			pushls(&closedFuncCharNo, linestarts[lineno] + charno - 2);
			r = BEGINCLOSEDFUNC;
		} else {
			unput(c);
			r = '#';
		}
		goto leave;
	}
	else if (c == '$') {
		c = input();
		if (c == '\\') {
			c = input();
			switch (c) {
				case 'n' : c = '\n'; break;
				case 'r' : c = '\r'; break;
				case 't' : c = '\t'; break;
				case 'f' : c = '\f'; break;
				case 'v' : c = '\v'; break;
			}
		}
		r = processchar(c);
		goto leave;
	}
	else if (c == ',') { r = c; goto leave; }
	else if (c == '=') {
		c = input();
		if (strchr(binopchars, c)) goto binop;
		else {
			unput(c);
			r = '=';
			goto leave;
		}
	}
	else if (strchr(binopchars, c))  goto binop;
	else if(!(isprint(c) || isspace(c) || c == 0)) {
		yylen = 0;
		goto start;
	}
	else goto error1;

ident:
	c = input();

	if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
		|| c == '_' || (c >= '0' && c <= '9')) goto ident;
	else if (c == ':') {
		yytext[yylen] = 0;
		r = processkeywordbinop(yytext) ;
		goto leave;
	} else {
		unput(c);
		yytext[yylen] = 0;
		r = processident(yytext) ;
		goto leave;
	}

symbol1:
	c = input();

	if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') goto symbol2;
	else if (c >= '0' && c <= '9') goto symbol4;
	else {
		unput(c);
		yytext[yylen] = 0;
		r = processsymbol(yytext) ;
		goto leave;
	}

symbol2:
	c = input();

	if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
		|| c == '_' || (c >= '0' && c <= '9')) goto symbol2;
	else {
		unput(c);
		yytext[yylen] = 0;
		r = processsymbol(yytext) ;
		goto leave;
	}

symbol4:
	c = input();
	if (c >= '0' && c <= '9') goto symbol4;
	else {
		unput(c);
		yytext[yylen] = 0;
		r = processsymbol(yytext) ;
		goto leave;
	}



binop:

	c = input();

	if (c == 0) goto binop2;
	if (strchr(binopchars, c))  goto binop;
	else {
		binop2:
		unput(c);
		yytext[yylen] = 0;
		r = processbinop(yytext) ;
		goto leave;
	}

radix_digits_1:

	c = input();
	if (c >= '0' && c <= '0' + sc_min(10,radix) - 1) goto radix_digits_1;
	if (c >= 'a' && c <= 'a' + sc_min(36,radix) - 11) goto radix_digits_1;
	if (c >= 'A' && c <= 'A' + sc_min(36,radix) - 11) goto radix_digits_1;
	if (c == '.') {
		goto radix_digits_2;
	}
	unput(c);
	yytext[yylen] = 0;
	r = processintradix(yytext, yylen, radix);
	goto leave;

radix_digits_2:

	c = input();
	if (c >= '0' && c <= '0' + sc_min(10,radix) - 1)  goto radix_digits_2;
	if (c >= 'A' && c <= 'A' + sc_min(36,radix) - 11) goto radix_digits_2;
	// do not allow lower case after decimal point.
	unput(c);
	yytext[yylen] = 0;
	r = processfloatradix(yytext, yylen, radix);
	goto leave;

hexdigits:

	c = input();
	if (c >= '0' && c <= '9') goto hexdigits;
	if (c >= 'a' && c <= 'f') goto hexdigits;
	if (c >= 'A' && c <= 'F') goto hexdigits;
	unput(c);
	yytext[yylen] = 0;
	r = processhex(yytext);
	goto leave;

digits_1:	/* number started with digits */

	c = input();

	if (c >= '0' && c <= '9') goto digits_1;
	else if (c == 'r') {
		radix = sc_strtoi(yytext, yylen-1, 10);
		yylen = 0;
		goto radix_digits_1;
	}
	else if (c == 'e' || c == 'E') goto expon_1;
	else if (c == '.') {
		c2 = input();
		if (c2 >= '0' && c2 <= '9') goto digits_2;
		else {
			unput(c2);
			unput(c);
			yytext[yylen] = 0;
			r = processint(yytext);
			goto leave;
		}
	}
	else if (c == 'b' || c == 's') {
		d = input();
		if (d >= '0' && d <= '9') goto accidental1;
		if (d == c) goto accidental2;
		goto accidental3;
accidental1:
		d = input();
		if (d >= '0' && d <= '9') goto accidental1;
		unput(d);
		yytext[yylen] = 0;
		r = processaccidental1(yytext);
		goto leave;
accidental2:
		d = input();
		if (d == c) goto accidental2;
accidental3:
		unput(d);
		yytext[yylen] = 0;
		r = processaccidental2(yytext);
		goto leave;
	}
	else if (c == 'x') {
		yylen = 0;
		goto hexdigits;
	} else {
		unput(c);
		yytext[yylen] = 0;
		r = processint(yytext);
		goto leave;
	}

digits_2:

	c = input();

	if (c >= '0' && c <= '9') goto digits_2;
	else if (c == 'e' || c == 'E') goto expon_1;
//	else if (c == 'π' || c == '∏') {
//		--yylen;
//		yytext[yylen] = 0;
//		r = processfloat(yytext, 1);
//		goto leave;
//	}
	else {
		unput(c);
		yytext[yylen] = 0;
		r = processfloat(yytext, 0);
		goto leave;
	}

expon_1:	/* e has been seen, need digits */
	c = input();

	if (c >= '0' && c <= '9') goto expon_3;
	else if (c == '+' || c == '-') goto expon_2;
	else goto error1;

expon_2:	/* + or - seen but still need digits */
	c = input();

	if (c >= '0' && c <= '9') goto expon_3;
	else goto error1;

expon_3:
	c = input();

	if (c >= '0' && c <= '9') goto expon_3;
//	else if (c == 'π' || c == '∏') {
//		--yylen;
//		yytext[yylen] = 0;
//		r = processfloat(yytext, 1);
//		goto leave;
//	}
	else {
		unput(c);
		yytext[yylen] = 0;
		r = processfloat(yytext, 0);
		goto leave;
	}

symbol3 : {
		int startline, endchar;
		startline = lineno;
		endchar = '\'';

		/*do {
			c = input();
		} while (c != endchar && c != 0);*/
		for (;yylen<MAXYYLEN;) {
			c = input();
			if (c == '\n' || c == '\r') {
                asRelativePath(curfilename,extPath);
				post("Symbol open at end of line on line %d in file '%s'\n",
					startline+errLineOffset, extPath);
				yylen = 0;
				r = 0;
				goto leave;
			}
			if (c == '\\') {
				yylen--;
				c = input();
			} else if (c == endchar) break;
			if (c == 0) break;
		}
		if (c == 0) {
            asRelativePath(curfilename,extPath);
			post("Open ended symbol ... started on line %d in file '%s'\n",
				startline+errLineOffset, extPath);
			yylen = 0;
			r = 0;
			goto leave;
		}
		yytext[yylen] = 0;
		yytext[yylen-1] = 0;
		r = processsymbol(yytext);
		goto leave;
	}

string1 : {
		int startline, endchar;
		startline = lineno;
		endchar = '"';

		for (;yylen<MAXYYLEN;) {
			c = input();
			if (c == '\\') {
				yylen--;
				c = input();
				switch (c) {
					case 'n' : yytext[yylen-1] = '\n'; break;
					case 'r' : yytext[yylen-1] = '\r'; break;
					case 't' : yytext[yylen-1] = '\t'; break;
					case 'f' : yytext[yylen-1] = '\f'; break;
					case 'v' : yytext[yylen-1] = '\v'; break;
				}
			} else if (c == '\r') c = '\n';
			else if (c == endchar) break;
			if (c == 0) break;
		}
		if (c == 0) {
            asRelativePath(curfilename,extPath);
			post("Open ended string ... started on line %d in file '%s'\n",
				startline+errLineOffset, extPath);
			yylen = 0;
			r = 0;
			goto leave;
		}
		yylen--;

		do {
			c = input0();
		} while (c && isspace(c));

		if (c == '"') goto string1;
		else if (c) unput0(c);

		yytext[yylen] = 0;
		r = processstring(yytext);
		goto leave;
	}

comment1:	/* comment -- to end of line */
	do {
		c = input0();
	} while (c != '\n' && c != '\r' && c != 0);
	yylen = 0;
	if (c == 0) { r = 0; goto leave; }
	else goto start;

comment2 : {
		int startline, clevel, prevc;
		startline = lineno;
		prevc = 0;
		clevel = 1;
		do {
			c = input0();
			if (c == '/' && prevc == '*') {
				if (--clevel <= 0) break;
			} else if (c == '*' && prevc == '/') clevel++;
			prevc = c;
		} while (c != 0);
		yylen = 0;
		if (c == 0) {
            asRelativePath(curfilename,extPath);
			post("Open ended comment ... started on line %d in file '%s'\n",
				startline+errLineOffset, extPath);
			r = 0;
			goto leave;
		}
		goto start;
	}


error1:

	yytext[yylen] = 0;

    asRelativePath(curfilename, extPath);
	post("illegal input string '%s' \n   at '%s' line %d char %d\n",
		yytext, extPath, lineno+errLineOffset, charno);
	post("code %d\n", c);
	//postfl(" '%c' '%s'\n", c, binopchars);
	//postfl("%d\n", strchr(binopchars, c));

error2:
    asRelativePath(curfilename, extPath);
	post("  in file '%s' line %d char %d\n", extPath, lineno+errLineOffset, charno);
	r = BADTOKEN;
	goto leave;

leave:
	yytext[yylen] = 0;

#if DEBUGLEX
	if (gDebugLexer) postfl("yylex: %d  '%s'\n",r,yytext);
#endif
	//if (lexCmdLine>0) postfl("yylex: %d  '%s'\n",r,yytext);
	return r;
}
예제 #29
0
void SC_JackDriver::Run()
{
	jack_client_t* client = mClient;
	World* world = mWorld;

#ifdef SC_JACK_USE_DLL
	mDLL.Update(secondsSinceEpoch(getTime()));
#if SC_JACK_DEBUG_DLL
	static int tick = 0;
	if (++tick >= 10) {
		tick = 0;
		scprintf("DLL: t %.6f p %.9f sr %.6f e %.9f avg(e) %.9f inc %.9f\n",
				 mDLL.PeriodTime(), mDLL.Period(), mDLL.SampleRate(),
				 mDLL.Error(), mDLL.AvgError(), mOSCincrement * kOSCtoSecs);
	}
#endif
#else
	HostTime hostTime = getTime();

	double hostSecs = secondsSinceEpoch(hostTime);
	double sampleTime = (double)(jack_frame_time(client) + jack_frames_since_cycle_start(client));

	if (mStartHostSecs == 0) {
		mStartHostSecs = hostSecs;
		mStartSampleTime = sampleTime;
	} else {
		double instSampleRate = (sampleTime - mPrevSampleTime) / (hostSecs - mPrevHostSecs);
		double smoothSampleRate = mSmoothSampleRate;
		smoothSampleRate = smoothSampleRate + 0.002 * (instSampleRate - smoothSampleRate);
		if (fabs(smoothSampleRate - mSampleRate) > 10.) {
			smoothSampleRate = mSampleRate;
		}
		mOSCincrement = (int64)(mOSCincrementNumerator / smoothSampleRate);
		mSmoothSampleRate = smoothSampleRate;
#if 0
		double avgSampleRate = (sampleTime - mStartSampleTime)/(hostSecs - mStartHostSecs);
		double jitter = (smoothSampleRate * (hostSecs - mPrevHostSecs)) - (sampleTime - mPrevSampleTime);
		double drift = (smoothSampleRate - mSampleRate) * (hostSecs - mStartHostSecs);
#endif
	}

	mPrevHostSecs = hostSecs;
	mPrevSampleTime = sampleTime;
#endif

	try {
		mFromEngine.Free();
		mToEngine.Perform();
		mOscPacketsToEngine.Perform();

		int numInputs = mInputList->mSize;
		int numOutputs = mOutputList->mSize;
		jack_port_t **inPorts = mInputList->mPorts;
		jack_port_t **outPorts = mOutputList->mPorts;
		sc_jack_sample_t **inBuffers = mInputList->mBuffers;
		sc_jack_sample_t **outBuffers = mOutputList->mBuffers;

		int numSamples = NumSamplesPerCallback();
		int bufFrames = mWorld->mBufLength;
		int numBufs = numSamples / bufFrames;

		float *inBuses = mWorld->mAudioBus + mWorld->mNumOutputs * bufFrames;
		float *outBuses = mWorld->mAudioBus;
		int32 *inTouched = mWorld->mAudioBusTouched + mWorld->mNumOutputs;
		int32 *outTouched = mWorld->mAudioBusTouched;

		int minInputs = sc_min(numInputs, (int)mWorld->mNumInputs);
		int minOutputs = sc_min(numOutputs, (int)mWorld->mNumOutputs);

		int bufFramePos = 0;

		// cache I/O buffers
		for (int i = 0; i < minInputs; ++i) {
			inBuffers[i] = (sc_jack_sample_t*)jack_port_get_buffer(inPorts[i], numSamples);
		}

		for (int i = 0; i < minOutputs; ++i) {
			outBuffers[i] = (sc_jack_sample_t*)jack_port_get_buffer(outPorts[i], numSamples);
		}

		// main loop
#ifdef SC_JACK_USE_DLL
		int64 oscTime = mOSCbuftime = (int64)((mDLL.PeriodTime() - mMaxOutputLatency) * kSecondsToOSCunits + .5);
// 		int64 oscInc = mOSCincrement = (int64)(mOSCincrementNumerator / mDLL.SampleRate());
		int64 oscInc = mOSCincrement = (int64)((mDLL.Period() / numBufs) * kSecondsToOSCunits + .5);
		mSmoothSampleRate = mDLL.SampleRate();
		double oscToSamples = mOSCtoSamples = mSmoothSampleRate * kOSCtoSecs /* 1/pow(2,32) */;
#else
		int64 oscTime = mOSCbuftime = OSCTime(hostTime) - (int64)(mMaxOutputLatency * kSecondsToOSCunits + .5);
		int64 oscInc = mOSCincrement;
		double oscToSamples = mOSCtoSamples;
#endif

		for (int i = 0; i < numBufs; ++i, mWorld->mBufCounter++, bufFramePos += bufFrames) {
			int32 bufCounter = mWorld->mBufCounter;
			int32 *tch;

			// copy+touch inputs
			tch = inTouched;
			for (int k = 0; k < minInputs; ++k) {
				sc_jack_sample_t *src = inBuffers[k] + bufFramePos;
				float *dst = inBuses + k * bufFrames;
				for (int n = 0; n < bufFrames; ++n) {
					*dst++ = *src++;
				}
				*tch++ = bufCounter;
			}

			// run engine
			int64 schedTime;
			int64 nextTime = oscTime + oscInc;

			while ((schedTime = mScheduler.NextTime()) <= nextTime) {
				float diffTime = (float)(schedTime - oscTime) * oscToSamples + 0.5;
				float diffTimeFloor = floor(diffTime);
				world->mSampleOffset = (int)diffTimeFloor;
				world->mSubsampleOffset = diffTime - diffTimeFloor;

				if (world->mSampleOffset < 0) world->mSampleOffset = 0;
				else if (world->mSampleOffset >= world->mBufLength) world->mSampleOffset = world->mBufLength-1;

				SC_ScheduledEvent event = mScheduler.Remove();
				event.Perform();
			}

			world->mSampleOffset = 0;
			world->mSubsampleOffset = 0.f;
			World_Run(world);

			// copy touched outputs
			tch = outTouched;
			for (int k = 0; k < minOutputs; ++k) {
				sc_jack_sample_t *dst = outBuffers[k] + bufFramePos;
				if (*tch++ == bufCounter) {
					float *src = outBuses + k * bufFrames;
					for (int n = 0; n < bufFrames; ++n) {
						*dst++ = *src++;
					}
				} else {
					for (int n = 0; n < bufFrames; ++n) {
						*dst++ = 0.0f;
					}
				}
			}

			// advance OSC time
			mOSCbuftime = oscTime = nextTime;
		}
	} catch (std::exception& exc) {
		scprintf("%s: exception in real time: %s\n", kJackDriverIdent, exc.what());
	} catch (...) {
		scprintf("%s: unknown exception in real time\n", kJackDriverIdent);
	}

	double cpuUsage = (double)jack_cpu_load(mClient);
	mAvgCPU = mAvgCPU + 0.1 * (cpuUsage - mAvgCPU);
	if (cpuUsage > mPeakCPU || --mPeakCounter <= 0) {
		mPeakCPU = cpuUsage;
		mPeakCounter = mMaxPeakCounter;
	}

	mAudioSync.Signal();
}
예제 #30
0
void SVF_next(SVF *unit, int inNumSamples)
{
    float *out = OUT(0);
    float *in  = IN(0);
    float cutoff     = IN0(1);
    float resonance  = IN0(2);
    float lowlevel   = IN0(3);
    float bandlevel  = IN0(4);
    float highlevel  = IN0(5);
    float notchlevel = IN0(6);
    float peaklevel  = IN0(7);
//    float drive      = IN0(8);

    cutoff	= sc_clip(cutoff, 20.f, SAMPLERATE);
    resonance	= sc_clip(resonance, 0.f, 1.f);
    lowlevel	= sc_clip(lowlevel, 0.f, 1.f);
    bandlevel	= sc_clip(bandlevel, 0.f, 1.f);
    highlevel	= sc_clip(highlevel, 0.f, 1.f);
    notchlevel	= sc_clip(notchlevel, 0.f, 1.f);
    peaklevel 	= sc_clip(peaklevel, 0.f, 1.f);
//    drive	= sc_clip(drive, 0.f, 1.f) * 0.1;

    float m_freq, m_damp;

    if (cutoff != unit->m_cutoff || resonance != unit->m_resonance) {
	unit->m_cutoff = cutoff;
	unit->m_resonance = resonance;
	unit->m_freq = m_freq = (float)(2.f * sin(pi * sc_min(0.25, cutoff / (SAMPLERATE * 2.f))));
	unit->m_damp = m_damp = sc_min(2.0 * (1.0 - pow(resonance, 0.25f)), (double)sc_min(2.f, 2.f / m_freq - m_freq * 0.5f));
    } else {
	m_freq = unit->m_freq;
	m_damp = unit->m_damp;
    }

    float input;
    float low;
    float band;
    float high;
    float notch;

    float outPeak;

    float m_notch = unit->m_notch;
    float m_low   = unit->m_low;
    float m_high  = unit->m_high;
    float m_band  = unit->m_band;

    for (long i = 0; i < inNumSamples; ++i)
    {
	    input = in[i];

	    // First iteration
	    m_notch	= input - m_damp * m_band;
	    m_low	= m_low + m_freq * m_band;
	    m_high	= m_notch - m_low;
	    m_band	= m_freq * m_high + m_band;

	    low   = 0.5f * m_low;
	    band  = 0.5f * m_band;
	    high  = 0.5f * m_high;
	    notch = 0.5f * m_notch;
	    outPeak = 0.5f * (m_low - m_high);

	    // Double sampled...
	    m_notch 	= input - m_damp * m_band;
	    m_low 	= m_low + m_freq * m_band;
	    m_high 	= m_notch - m_low;
	    m_band 	= m_freq * m_high + m_band;

	    low   += 0.5f * m_low;
	    band  += 0.5f * m_band;
	    high  += 0.5f * m_high;
	    notch += 0.5f * m_notch;
	    outPeak += 0.5f * (m_low - m_high);

	    out[i] = (low * lowlevel) + (band * bandlevel) + (high * highlevel) + (notch * notchlevel) + (outPeak * peaklevel);
    }

    unit->m_notch = m_notch;
    unit->m_low   = m_low;
    unit->m_high  = m_high;
    unit->m_band  = m_band;
}