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; }
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; }
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; }
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; }
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; }
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; }