예제 #1
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;
}
예제 #2
0
scfft * scfft_create(size_t fullsize, size_t winsize, SCFFT_WindowFunction wintype,
					 float *indata, float *outdata, SCFFT_Direction forward, SCFFT_Allocator & alloc)
{
	char * chunk = (char*) alloc.alloc(sizeof(scfft) + scfft_trbufsize(fullsize));
	if (!chunk)
		return NULL;

	scfft * f = (scfft*)chunk;
	float *trbuf = (float*)(chunk + sizeof(scfft));

	f->nfull = fullsize;
	f->nwin  =  winsize;
	f->log2nfull = LOG2CEIL(fullsize);
	f->log2nwin  = LOG2CEIL( winsize);
	f->wintype = wintype;
	f->indata  = indata;
	f->outdata = outdata;
	f->trbuf   = trbuf;

	// Buffer is larger than the range of sizes we provide for at startup; we can get ready just-in-time though
	if (fullsize > SC_FFT_MAXSIZE)
		scfft_ensurewindow(f->log2nfull, f->log2nwin, wintype);

#if SC_FFT_FFTW
	if(forward)
		f->plan = fftwf_plan_dft_r2c_1d(fullsize, trbuf, (fftwf_complex*) trbuf, FFTW_ESTIMATE);
	else
		f->plan = fftwf_plan_dft_c2r_1d(fullsize, (fftwf_complex*) trbuf, outdata, FFTW_ESTIMATE);
#endif

	// The scale factors rescale the data to unity gain. The old Green lib did this itself, meaning scalefacs would here be 1...
	if(forward){
#if SC_FFT_VDSP
		f->scalefac = 0.5f;
#else // forward FFTW and Green factor
		f->scalefac = 1.f;
#endif
	} else { // backward FFTW and VDSP factor
#if SC_FFT_GREEN
		f->scalefac = 1.f;
#else  // fftw, vdsp
		f->scalefac = 1.f / fullsize;
#endif
	}

	memset(trbuf, 0, scfft_trbufsize(fullsize));

	return f;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
0
int scfft_create(scfft *f, unsigned int fullsize, unsigned int winsize, short wintype, float *indata, float *outdata, float *trbuf, bool forward){
	f->nfull = fullsize;
	f->nwin  =  winsize;
	f->log2nfull = LOG2CEIL(fullsize);
	f->log2nwin  = LOG2CEIL( winsize);
	f->wintype = wintype;
	f->indata  = indata;
	f->outdata = outdata;
	f->trbuf   = trbuf;

	// Buffer is larger than the range of sizes we provide for at startup; we can get ready just-in-time though
	if (fullsize > SC_FFT_MAXSIZE){
		scfft_ensurewindow(f->log2nfull, f->log2nwin, wintype);
	}

	#if SC_FFT_FFTW
		if(forward)
			f->plan = fftwf_plan_dft_r2c_1d(fullsize, trbuf, (fftwf_complex*) trbuf, FFTW_ESTIMATE);
		else
			f->plan = fftwf_plan_dft_c2r_1d(fullsize, (fftwf_complex*) trbuf, outdata, FFTW_ESTIMATE);
	#endif

	// The scale factors rescale the data to unity gain. The old Green lib did this itself, meaning scalefacs would here be 1...
	if(forward){
		#if SC_FFT_VDSP
			f->scalefac = 0.5f;
		#else // forward FFTW factor
			f->scalefac = 1.f;
		#endif
	}else{ // backward FFTW and VDSP factor
		f->scalefac = 1.f / fullsize;
	}

	memset(trbuf, 0, scfft_trbufsize(fullsize));

	return 0;
}
예제 #6
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;
}