/* GraphView::LoadImage(Image img) * This fuction copies data from an Image into a QImage that is displayed in the * widget. */ void GraphView::loadImage(Image img){ im = img; image = QImage(width(),height(),32); if(im){ float min = IE(im,0,0,0); float max = IE(im,0,0,0); for(int x = 0; x < im->width; x++){ for(int y = 0; y < im->height; y++){ for(int c = 0; c < im->channels; c++){ if(min > IE(im,x,y,c)) min = IE(im,x,y,c); if(max < IE(im,x,y,c)) max = IE(im,x,y,c); } } } double iScale = im->width/(double)image.width(); double jScale = im->height/(double)image.height(); for(int i = 0; i < image.width(); i++){ for(int j = 0; j < image.height(); j++){ int level = ROUND(255.0 * (interpLinear(im,i*iScale,j*jScale,0) - min )/(max-min)); image.setPixel(i,j,(uint)qRgb(level,level,level)); } } } repaint(TRUE); }
void DelayNode::process( Buffer *buffer ) { const float sampleRate = mSampleRate; const size_t numFrames = buffer->getNumFrames(); const size_t delayBufferFrames = mDelayBuffer.getNumFrames(); float *inChannel = buffer->getData(); float *delayChannel = mDelayBuffer.getData(); // currently doesn't support delay buffer size smaller than one processing block. // TODO: with more work this can support smaller delay sizes (and more effects). if( delayBufferFrames < numFrames ) return; size_t writeIndex = mWriteIndex; if( mParamDelaySeconds.eval() ) { const float *delaySecondsArray = mParamDelaySeconds.getValueArray(); for( size_t i = 0; i < numFrames; i++ ) { const float delayFrames = delaySecondsArray[i] * sampleRate; float readPos = float( writeIndex + delayBufferFrames ) - delayFrames; if( readPos >= delayBufferFrames ) readPos -= delayBufferFrames; else if( readPos < 0 ) readPos = float( delayBufferFrames - 1 ); // value was over delayBufferFrames, set to last available frame (will cause distortion) float sample = *inChannel; *inChannel++ = interpLinear( delayChannel, delayBufferFrames, readPos ); delayChannel[writeIndex] = sample; writeIndex = ( writeIndex + 1 ) % delayBufferFrames; } } else { const size_t delayFrames = size_t( mParamDelaySeconds.getValue() * sampleRate ); size_t readIndex = writeIndex + delayBufferFrames - delayFrames; for( size_t i = 0; i < numFrames; i++ ) { float sample = *inChannel; *inChannel++ = delayChannel[readIndex]; delayChannel[writeIndex] = sample; writeIndex = ( writeIndex + 1 ) % delayBufferFrames; readIndex = ( readIndex + 1 ) % delayBufferFrames; } } mWriteIndex = writeIndex; }
/* This function performs a 3X3 two dimentional perspective transform to an image This is used to perform geomentric normalization */ Image transformImage(Image source, int newWidth, int newHeight, const Matrix m){ Image dest = makeImage(newWidth, newHeight, source->channels); Matrix point = makeMatrix(3,1); Matrix inv; Matrix pt; int x, y, c; assert(m->row_dim == 3); assert(m->col_dim == 3); /* initialize homogenius point */ ME(point,2,0) = 1; /* find the inverse transformation to convert from dest to source */ inv = invertRREF(m); for(x = 0; x < dest->width; x++){ for(y = 0; y < dest->height; y++){ /* calculate source point */ ME(point,0,0) = x; ME(point,1,0) = y; ME(point,2,0) = 1.0; pt = multiplyMatrix(inv, point); ME(pt,0,0) = ME(pt,0,0) / ME(pt,2,0); ME(pt,1,0) = ME(pt,1,0) / ME(pt,2,0); for(c = 0; c < dest->channels; c++){ /* interpolate value */ IE(dest,x,y,c) = interpLinear(source, ME(pt,0,0),ME(pt,1,0),c); } /* clean up */ freeMatrix(pt); } } freeMatrix(point); freeMatrix(inv); return dest; }