QVector2D WarpGrid::getWarpPointPos(int x, int y, float u, float v) const { switch (interpolation_) { default: // perform linear interpolation case Interpolation::LINEAR: { auto _p00 = getWarpPointPos(x + 0, y + 0); auto _p10 = getWarpPointPos(x + 1, y + 0); auto _p01 = getWarpPointPos(x + 0, y + 1); auto _p11 = getWarpPointPos(x + 1, y + 1); QVector2D p1((1.0f - u) * _p00 + u * _p10); QVector2D p2((1.0f - u) * _p01 + u * _p11); return QVector2D((1.0f - v) * p1 + v * p2); } // perform bicubic interpolation case Interpolation::BICUBIC: { array4_type _rows, _cols; for (int i = -1; i < 3; ++i) { for (int j = -1; j < 3; ++j) { _cols[j + 1] = getWarpPointPos(x + i, y + j); } _rows[i + 1] = cubicInterpolate(_cols, v); } return cubicInterpolate(_rows, u); } } return QVector2D(0.0, 0.0); }
Color bicubicInterpolate (Color p[4][4], double x, double y) { Color arr[4]; arr[0] = cubicInterpolate(p[0], y); arr[1] = cubicInterpolate(p[1], y); arr[2] = cubicInterpolate(p[2], y); arr[3] = cubicInterpolate(p[3], y); return cubicInterpolate(arr, x); }
// p is a 16-point 4x4 array of the 2 rows & columns left/right/above/below float bicubicInterpolate(float p[], float x, float y) { float arr[4] = {0,0,0,0}; arr[0] = cubicInterpolate(p+0, x); arr[1] = cubicInterpolate(p+4, x); arr[2] = cubicInterpolate(p+8, x); arr[3] = cubicInterpolate(p+12, x); return cubicInterpolate(arr, y); }
double bicubicInterpolate (double p[4][4], double x, double y) { double arr[4]; arr[0] = cubicInterpolate(p[0], y); arr[1] = cubicInterpolate(p[1], y); arr[2] = cubicInterpolate(p[2], y); arr[3] = cubicInterpolate(p[3], y); return cubicInterpolate(arr, x); }
float bicubicInterpolate (float p[4][4], float x, float y) { float arr[4]; arr[0] = cubicInterpolate(p[0], y); arr[1] = cubicInterpolate(p[1], y); arr[2] = cubicInterpolate(p[2], y); arr[3] = cubicInterpolate(p[3], y); return cubicInterpolate(arr, x); }
double bicubicInterpolate(double p[4][4], double x, double y) { double yy[4]; yy[0] = cubicInterpolate(p[0], y); yy[1] = cubicInterpolate(p[1], y); yy[2] = cubicInterpolate(p[2], y); yy[3] = cubicInterpolate(p[3], y); return cubicInterpolate(yy, x); }
Type bicubicInterpolate(__global const Type* sourcePtr, const Type xSource, const Type ySource, const int widthSource, const int heightSource, const int widthSourcePtr) { int xIntArray[4]; int yIntArray[4]; Type dx; Type dy; cubicSequentialData(xIntArray, yIntArray, &dx, &dy, xSource, ySource, widthSource, heightSource); Type temp[4]; for (unsigned char i = 0; i < 4; i++) { const int offset = yIntArray[i]*widthSourcePtr; temp[i] = cubicInterpolate(sourcePtr[offset + xIntArray[0]], sourcePtr[offset + xIntArray[1]], sourcePtr[offset + xIntArray[2]], sourcePtr[offset + xIntArray[3]], dx); } return cubicInterpolate(temp[0], temp[1], temp[2], temp[3], dy); }
void vibratingString::resample( float *_src, f_cnt_t _src_frames, f_cnt_t _dst_frames ) { for( f_cnt_t frame = 0; frame < _dst_frames; ++frame ) { const float src_frame_float = frame * (float) _src_frames / _dst_frames; const float frac_pos = src_frame_float - static_cast<f_cnt_t>( src_frame_float ); const f_cnt_t src_frame = tLimit<f_cnt_t>( static_cast<f_cnt_t>( src_frame_float ), 1, _src_frames - 3 ); m_impulse[frame] = cubicInterpolate( _src[src_frame - 1], _src[src_frame + 0], _src[src_frame + 1], _src[src_frame + 2], frac_pos ); } }
/* Expand a spline segment into a buffer */ static int expandSpline(AS3_Val *modPoint, float *buffer, int frames) { double y0Arg, y1Arg, y2Arg, y3Arg; float y0, y1, y2, y3; float p, incr; int count; AS3_ObjectValue(*modPoint, "y0:DoubleType, y1:DoubleType, y2:DoubleType, y3:DoubleType", &y0Arg, &y1Arg, &y2Arg, &y3Arg); y0 = (float) y0Arg; y1 = (float) y1Arg; y2 = (float) y2Arg; y3 = (float) y3Arg; incr = 1 / (float) frames; count = frames; p = 0; // Optimize continuous, linear, and cubic modes if (y0 == 0 && y1 == 0 && y2 == 0 && y3 == 0 ) { // All values are zero memset(buffer, 0, frames * 4); } else if (y0 == y1 && y1 == y2 && y2 == y3) { // All values are the same while (count--) { *buffer++ = y1; } } else if (y0 == y1 && y2 == y3) { // Linear interpolation while (count--) { *buffer++ = interpolate(y1, y2, p); p += incr; } } else { // This is a full spline segment // Loop over the whole segment and calc instantaneous spline values with cubic interpolation while (count--) { *buffer++ = cubicInterpolate(y0, y1, y2, y3, p); p += incr; } } return 0; }
Quaternion Quaternion::endCubicInterpolate(const Quaternion& a, const Quaternion& b, const Quaternion& c, float alpha) { return cubicInterpolate(a, b, c, c, alpha); }
void polywave_perform64(t_polywave *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam) { int i; t_double *out = outs[0]; t_double *in1 = ins[0]; t_double *in2 = ins[1]; int n = sampleframes; if(x->numbufs == 0 || !x->w_connected[0]) { while (n--) *out++ = 0.; return; } int idx_connected = x->w_connected[1]; long numbufs = x->numbufs; long frames[numbufs], nchans[numbufs]; t_buffer_obj *buffer[numbufs]; t_float *tab[numbufs]; int valid[numbufs], modified[numbufs]; for (i=0; i<numbufs; i++) { buffer[i] = buffer_ref_getobject(x->buf_proxy[i]->ref); if(!buffer[i]) valid[i] = 0; else { tab[i] = buffer_locksamples(buffer[i]); if(!tab[i]) valid[i] = 0; else { modified[i] = x->buf_proxy[i]->buffer_modified; if(modified[i]) { frames[i] = buffer_getframecount(buffer[i]); nchans[i] = buffer_getchannelcount(buffer[i]); x->buf_proxy[i]->nframes = frames[i]; x->buf_proxy[i]->nchans = nchans[i]; x->buf_proxy[i]->buffer_modified = false; } else { frames[i] = x->buf_proxy[i]->nframes; nchans[i] = x->buf_proxy[i]->nchans; } valid[i] = (nchans[i] > 0 && frames[i] > 0); } } } t_polywave_interp interp = x->interp_type; double p, pSamp, upperVal, lowerSamp, upperSamp, frac, a, b, c, d; long bindx = 0; switch (interp) { case CUBIC: while(n--) { p = *in1++; p = CLAMP(p, 0, 1); if(idx_connected) { bindx = (long)*in2++; bindx = CLAMP(bindx, 0, numbufs-1); } if(valid[bindx]) { pSamp = frames[bindx] * p; lowerSamp = floor(pSamp); frac = pSamp - lowerSamp; a = (long)lowerSamp - 1 < 0 ? 0 : tab[bindx][ nchans[bindx] * ((long)lowerSamp - 1)]; b = tab[bindx][ nchans[bindx] * (long)lowerSamp]; c = (long)lowerSamp + 1 > frames[bindx] ? 0 : tab[bindx][ nchans[bindx] * ((long)lowerSamp + 1)]; d = (long)lowerSamp + 2 > frames[bindx] ? 0 : tab[bindx][ nchans[bindx] * ((long)lowerSamp + 2)]; *out++ = cubicInterpolate(a,b,c,d,frac); } else *out++ = 0.0; } break; case LINEAR: while(n--) { p = *in1++; p = CLAMP(p, 0, 1); if(idx_connected) { bindx = (long)*in2++; bindx = CLAMP(bindx, 0, numbufs-1); } if(valid[bindx]) { pSamp = frames[bindx] * p; lowerSamp = floor(pSamp); upperSamp = ceil(pSamp); upperVal = (upperSamp < frames[bindx]) ? tab[bindx][ nchans[bindx] * (long)upperSamp ] : 0.0; *out++ = linear_interp(tab[bindx][ nchans[bindx] * (long)lowerSamp ], upperVal, pSamp - lowerSamp); } else *out++ = 0.0; } break; default: case NONE: while(n--) { p = *in1++; p = CLAMP(p, 0, 1); if(idx_connected) { bindx = (long)*in2++; bindx = CLAMP(bindx, 0, numbufs-1); } if(valid[bindx]) { *out++ = tab[bindx][nchans[bindx] * (long)(frames[bindx] * p)]; } else *out++ = 0.0; } break; } for(i=0; i<numbufs; i++) { if(valid[i]) buffer_unlocksamples(buffer[i]); } return; }
void polywave_perform64_two(t_polywave *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam) { int i; t_double *out = outs[0]; t_double *x1_in = ins[0]; t_double *x2_in = ins[1]; t_double *interp_in = ins[2]; t_double *idx1_in = ins[3]; t_double *idx2_in = ins[4]; int n = sampleframes; if(x->numbufs == 0 || !x->w_connected[0]) { while (n--) *out++ = 0.; return; } int *connected = x->w_connected; long numbufs = x->numbufs; long frames[numbufs], nchans[numbufs]; t_buffer_obj *buffer[numbufs]; t_float *tab[numbufs]; int valid[numbufs], modified[numbufs]; t_polywave_interp interp_t = x->interp_type; // post("%d %d", x->interp_type, x->backup); for (i=0; i<numbufs; i++) { buffer[i] = buffer_ref_getobject(x->buf_proxy[i]->ref); if(!buffer[i]) valid[i] = 0; else { tab[i] = buffer_locksamples(buffer[i]); if(!tab[i]) valid[i] = 0; else { modified[i] = x->buf_proxy[i]->buffer_modified; if(modified[i]) { frames[i] = buffer_getframecount(buffer[i]); nchans[i] = buffer_getchannelcount(buffer[i]); x->buf_proxy[i]->nframes = frames[i]; x->buf_proxy[i]->nchans = nchans[i]; x->buf_proxy[i]->buffer_modified = false; } else { frames[i] = x->buf_proxy[i]->nframes; nchans[i] = x->buf_proxy[i]->nchans; } valid[i] = (nchans[i] > 0 && frames[i] > 0); } } } double x1_p, x2_p, interp_p = 0, pSamp1, pSamp2, upperVal, lowerSamp, upperSamp, frac, a1, a2, b, c, d; long idx1 = 0, idx2 = 0; switch (interp_t) { case CUBIC: while(n--) { x1_p = *x1_in++; x1_p = CLAMP(x1_p, 0, 1); if(connected[1]) { x2_p = *x2_in++; x2_p = CLAMP(x2_p, 0, 1); } else { x2_p = x1_p; } if (connected[2]) { interp_p = *interp_in++; interp_p = CLAMP(interp_p, 0, 1); } if(connected[3]) { idx1 = (long)*idx1_in++; idx1 = CLAMP(idx1, 0, numbufs-1); } if(connected[4]) { idx2 = (long)*idx2_in++; idx2 = CLAMP(idx2, 0, numbufs-1); } if(valid[idx1] && valid[idx2]) { pSamp1 = frames[idx1] * x1_p; lowerSamp = floor(pSamp1); frac = pSamp1 - lowerSamp; a1 = (long)lowerSamp - 1 < 0 ? 0 : tab[idx1][ nchans[idx1] * ((long)lowerSamp - 1)]; b = tab[idx1][ nchans[idx1] * (long)lowerSamp]; c = (long)lowerSamp + 1 > frames[idx1] ? 0 : tab[idx1][ nchans[idx1] * ((long)lowerSamp + 1)]; d = (long)lowerSamp + 2 > frames[idx1] ? 0 : tab[idx1][ nchans[idx1] * ((long)lowerSamp + 2)]; pSamp1 = cubicInterpolate(a1,b,c,d,frac); pSamp2 = frames[idx2] * x2_p; lowerSamp = floor(pSamp2); frac = pSamp2 - lowerSamp; a2 = (long)lowerSamp - 1 < 0 ? 0 : tab[idx2][ nchans[idx2] * ((long)lowerSamp - 1)]; b = tab[idx2][ nchans[idx2] * (long)lowerSamp]; c = (long)lowerSamp + 1 > frames[idx2] ? 0 : tab[idx2][ nchans[idx2] * ((long)lowerSamp + 1)]; d = (long)lowerSamp + 2 > frames[idx2] ? 0 : tab[idx2][ nchans[idx2] * ((long)lowerSamp + 2)]; pSamp2 = cubicInterpolate(a2,b,c,d,frac); *out++ = cubicInterpolate(a1,pSamp1,pSamp2,d,interp_p); } else *out++ = 0.0; } break; case LINEAR: while(n--) { x1_p = *x1_in++; x1_p = CLAMP(x1_p, 0, 1); if(connected[1]) { x2_p = *x2_in++; x2_p = CLAMP(x2_p, 0, 1); } else { x2_p = x1_p; } if (connected[2]) { interp_p = *interp_in++; interp_p = CLAMP(interp_p, 0, 1); } if(connected[3]) { idx1 = (long)*idx1_in++; idx1 = CLAMP(idx1, 0, numbufs-1); } if(connected[4]) { idx2 = (long)*idx2_in++; idx2 = CLAMP(idx2, 0, numbufs-1); } if(valid[idx1] && valid[idx2]) { pSamp1 = frames[idx1] * x1_p; lowerSamp = floor(pSamp1); upperSamp = ceil(pSamp1); upperVal = (upperSamp < frames[idx1]) ? tab[idx1][ nchans[idx1] * (long)upperSamp ] : 0.0; pSamp1 = linear_interp(tab[idx1][ nchans[idx1] * (long)lowerSamp ], upperVal, pSamp1 - lowerSamp); pSamp2 = frames[idx2] * x2_p; lowerSamp = floor(pSamp2); upperSamp = ceil(pSamp2); upperVal = (upperSamp < frames[idx2]) ? tab[idx2][ nchans[idx2] * (long)upperSamp ] : 0.0; pSamp2 = linear_interp(tab[idx2][ nchans[idx2] * (long)lowerSamp ], upperVal, pSamp2 - lowerSamp); *out++ = linear_interp(pSamp1, pSamp2, interp_p); } else *out++ = 0.0; } break; default: case NONE: while(n--) { x1_p = *x1_in++; x1_p = CLAMP(x1_p, 0, 1); if(connected[2]) { idx1 = (long)*idx1_in++; idx1 = CLAMP(idx1, 0, numbufs-1); } if(valid[idx1]) { *out++ = tab[idx1][nchans[idx1] * (long)(frames[idx1] * x1_p)]; } else *out++ = 0.0; } break; } for(i=0; i<numbufs; i++) { if(valid[i]) buffer_unlocksamples(buffer[i]); } return; }
/** * Converts a Sample at a lower rate (22050 Hz) or lower number of channels (mono) * to the standard Flash sound format (44.1k stereo interleaved). * The descriptor in this case represents the sourceBuffer, not the targetBuffer, which is stereo/44.1 */ static AS3_Val standardize(void *self, AS3_Val args) { int bufferPosition; int rate; int channels; int frames; float *buffer; int sourceBufferPosition; float *sourceBuffer; int count; AS3_ArrayValue(args, "IntType, IntType, IntType, IntType, IntType", &bufferPosition, &sourceBufferPosition, &channels, &frames, &rate); buffer = (float *) bufferPosition; sourceBuffer = (float *) sourceBufferPosition; if (rate == 44100 && channels == 2) { // We're already standardized. Just copy the memory memcpy(buffer, sourceBuffer, frames * channels * sizeof(float)); } else if (rate == 22050 && channels == 1) { // Upsample and stereoize with cubic interpolation // First set hold first sample *buffer++ = *sourceBuffer; *buffer++ = *sourceBuffer; *buffer++ = cubicInterpolate(*(sourceBuffer), *(sourceBuffer), *(sourceBuffer+1), *(sourceBuffer+2), 0.5); *buffer = *(buffer-1); buffer++; sourceBuffer++; // Loop count = (frames/2) - 2; while (--count) { *buffer++ = *sourceBuffer; *buffer++ = *sourceBuffer; *buffer++ = cubicInterpolate(*(sourceBuffer-1), *sourceBuffer, *(sourceBuffer+1), *(sourceBuffer+2), 0.5); *buffer = *(buffer-1); buffer++; sourceBuffer++; } // Last set hold 2 samples *buffer++ = *sourceBuffer; *buffer++ = *sourceBuffer; *buffer++ = cubicInterpolate(*(sourceBuffer-1), *sourceBuffer, *(sourceBuffer+1), *(sourceBuffer+1), 0.5); *buffer = *(buffer-1); buffer++; sourceBuffer++; *buffer++ = *sourceBuffer; *buffer++ = *sourceBuffer; *buffer++ = cubicInterpolate(*(sourceBuffer-1), *sourceBuffer, *sourceBuffer, *sourceBuffer, 0.5); *buffer = *(buffer-1); // Done } else if (rate == 22050 && channels == 2) { // Upsample with cubic interpolation // First set hold sample *buffer++ = *sourceBuffer; *buffer++ = *(sourceBuffer+1); *buffer++ = cubicInterpolate(*sourceBuffer, *sourceBuffer, *(sourceBuffer+2), *(sourceBuffer+4), 0.5); *buffer = cubicInterpolate(*(sourceBuffer+1), *(sourceBuffer+1), *(sourceBuffer+3), *(sourceBuffer+5), 0.5); buffer++; sourceBuffer += 2; count = frames/2 - 2; while (--count) { *buffer++ = *sourceBuffer; // left *buffer++ = *(sourceBuffer+1); // right *buffer++ = cubicInterpolate(*(sourceBuffer-2), *sourceBuffer, *(sourceBuffer+2), *(sourceBuffer+4), 0.5); *buffer++ = cubicInterpolate(*(sourceBuffer-1), *(sourceBuffer+1), *(sourceBuffer+3), *(sourceBuffer+5), 0.5); sourceBuffer += 2; } // second to last set *buffer++ = *sourceBuffer; // left *buffer++ = *(sourceBuffer+1); // right *buffer++ = cubicInterpolate(*(sourceBuffer-2), *sourceBuffer, *(sourceBuffer+2), *(sourceBuffer+2), 0.5); *buffer++ = cubicInterpolate(*(sourceBuffer-1), *(sourceBuffer+1), *(sourceBuffer+3), *(sourceBuffer+3), 0.5); sourceBuffer += 2; // last set *buffer++ = *sourceBuffer; // left *buffer++ = *(sourceBuffer+1); // right *buffer++ = cubicInterpolate(*(sourceBuffer-2), *sourceBuffer, *sourceBuffer, *sourceBuffer, 0.5); *buffer= cubicInterpolate(*(sourceBuffer-1), *(sourceBuffer+1), *(sourceBuffer+1), *(sourceBuffer+1), 0.5); // Done } else if (rate == 44100 && channels == 1) { // Stereoize count = frames; while (--count) { *buffer++ = *sourceBuffer; *buffer++ = *sourceBuffer++; } } return 0; }