void DspLine::processDspWithIndex(int fromIndex, int toIndex) { if (numSamplesToTarget <= 0.0f) { // if we have already reached the target if (ArrayArithmetic::hasAccelerate) { #if __APPLE__ vDSP_vfill(&target, dspBufferAtOutlet0+fromIndex, 1, toIndex-fromIndex); #endif } else { memset_pattern4(dspBufferAtOutlet0+fromIndex, &target, (toIndex-fromIndex)*sizeof(float)); } lastOutputSample = target; } else { // the number of samples to be processed this iteration float processLength = toIndex - fromIndex; if (processLength > 0.0f) { // if there is anything to process at all (several messages may be received at once) if (numSamplesToTarget < processLength) { int targetIndexInt = fromIndex + numSamplesToTarget; if (ArrayArithmetic::hasAccelerate) { #if __APPLE__ vDSP_vramp(&lastOutputSample, &slope, dspBufferAtOutlet0+fromIndex, 1, targetIndexInt-fromIndex); vDSP_vfill(&target, dspBufferAtOutlet0+targetIndexInt, 1, toIndex-targetIndexInt); #endif } else { // if we will process more samples than we have remaining to the target // i.e., if we will arrive at the target while processing dspBufferAtOutlet0[fromIndex] = lastOutputSample + slope; for (int i = fromIndex+1; i < targetIndexInt; i++) { dspBufferAtOutlet0[i] = dspBufferAtOutlet0[i-1] + slope; } for (int i = targetIndexInt; i < toIndex; i++) { dspBufferAtOutlet0[i] = target; } } lastOutputSample = target; numSamplesToTarget = 0; } else { // if the target is far off if (ArrayArithmetic::hasAccelerate) { #if __APPLE__ vDSP_vramp(&lastOutputSample, &slope, dspBufferAtOutlet0+fromIndex, 1, toIndex-fromIndex); #endif } else { dspBufferAtOutlet0[fromIndex] = lastOutputSample + slope; for (int i = fromIndex+1; i < toIndex; i++) { dspBufferAtOutlet0[i] = dspBufferAtOutlet0[i-1] + slope; } } lastOutputSample = dspBufferAtOutlet0[toIndex-1]; numSamplesToTarget -= processLength; } } } }
void DspLine::processDspWithIndex(int fromIndex, int toIndex) { if (numSamplesToTarget <= 0.0f) { // if we have already reached the target int n = toIndex - fromIndex; if (n > 0) { // n may be zero ArrayArithmetic::fill(dspBufferAtOutlet[0], target, fromIndex, toIndex); lastOutputSample = target; } } else { // the number of samples to be processed this iteration int n = toIndex - fromIndex; if (n > 0) { // n may be zero // if there is anything to process at all (several messages may be received at once) if (numSamplesToTarget < n) { int targetIndexInt = fromIndex + numSamplesToTarget; #if __APPLE__ vDSP_vramp(&lastOutputSample, &slope, dspBufferAtOutlet[0]+fromIndex, 1, targetIndexInt-fromIndex); vDSP_vfill(&target, dspBufferAtOutlet[0]+targetIndexInt, 1, toIndex-targetIndexInt); #else // if we will process more samples than we have remaining to the target // i.e., if we will arrive at the target while processing dspBufferAtOutlet[0][fromIndex] = lastOutputSample; for (int i = fromIndex+1; i < targetIndexInt; i++) { dspBufferAtOutlet[0][i] = dspBufferAtOutlet[0][i-1] + slope; } for (int i = targetIndexInt; i < toIndex; i++) { dspBufferAtOutlet[0][i] = target; } #endif lastOutputSample = target; numSamplesToTarget = 0; } else { // if the target is far off #if __APPLE__ vDSP_vramp(&lastOutputSample, &slope, dspBufferAtOutlet[0]+fromIndex, 1, n); #else dspBufferAtOutlet[0][fromIndex] = lastOutputSample; for (int i = fromIndex+1; i < toIndex; i++) { dspBufferAtOutlet[0][i] = dspBufferAtOutlet[0][i-1] + slope; } #endif lastOutputSample = dspBufferAtOutlet[0][toIndex-1] + slope; numSamplesToTarget -= n; } } } }
// NOTE(mhroth): this code could be improved to be sub-sample accurate with regards to calculating last sample output void DspVariableLine::processSignal(DspObject *dspObject, int fromIndex, int toIndex) { DspVariableLine *d = reinterpret_cast<DspVariableLine *>(dspObject); if (d->numSamplesToTarget <= 0.0f) { ArrayArithmetic::fill(d->dspBufferAtOutlet[0], d->lastOutputSample, fromIndex, toIndex); } else { // there are pending messages int n = toIndex - fromIndex; if (n < (int) d->numSamplesToTarget) { // can update entire buffer #if __APPLE__ vDSP_vramp(&(d->lastOutputSample), &(d->slope), d->dspBufferAtOutlet[0]+fromIndex, 1, n); #else #endif d->lastOutputSample = d->dspBufferAtOutlet[0][toIndex-1] + d->slope; d->numSamplesToTarget -= n; } else { // must update slope in this buffer #if __APPLE__ vDSP_vramp(&(d->lastOutputSample), &(d->slope), d->dspBufferAtOutlet[0]+fromIndex, 1, (int) d->numSamplesToTarget); #else #endif // update the path d->slope = 0.0f; d->lastOutputSample = d->target; fromIndex += (int) ceilf(d->numSamplesToTarget); d->numSamplesToTarget = 0.0f; // process the remainder of the buffer ArrayArithmetic::fill(d->dspBufferAtOutlet[0], d->lastOutputSample, fromIndex, toIndex); } } }
/* TB: vectorized version */ static t_int *line_tilde_perf8(t_int *w) { t_line *x = (t_line *)(w[1]); t_sample *out = (t_sample *)(w[2]); int n = (int)(w[3]); t_sample f = x->x_value; if (PD_BIGORSMALL(f)) x->x_value = f = 0; if (x->x_retarget) { int nticks = x->x_inletwas * x->x_dspticktomsec; if (!nticks) nticks = 1; x->x_ticksleft = nticks; x->x_biginc = (x->x_target - x->x_value)/(t_sample)nticks; x->x_inc = x->x_1overn * x->x_biginc; x->x_retarget = 0; } if (x->x_ticksleft) { t_sample f = x->x_value; #if USE_ACCEL_OPTIM vDSP_vramp(&f, &x->x_inc, out, 1, n); #else while (n--) *out++ = f, f += x->x_inc; #endif x->x_value += x->x_biginc; x->x_ticksleft--; } else { t_sample f = x->x_value = x->x_target; #if USE_ACCEL_OPTIM vDSP_vfill(&f, out, 1, n); #else for (; n; n -= 8, out += 8) { out[0] = f; out[1] = f; out[2] = f; out[3] = f; out[4] = f; out[5] = f; out[6] = f; out[7] = f; } #endif } return (w+4); }
inline void maxiCollider::createGabor(flArr &atom, const float freq, const float sampleRate, const uint length, float startPhase, const float kurtotis, const float amp) { atom.resize(length); flArr sine; sine.resize(length); // float gausDivisor = (-2.0 * kurtotis * kurtotis); // float phase =-1.0; double *env = maxiCollider::envCache.getWindow(length); #ifdef __APPLE_CC__ vDSP_vdpsp(env, 1, &atom[0], 1, length); #else for(uint i=0; i < length; i++) { atom[i] = env[i]; } #endif //#ifdef __APPLE_CC__ // vDSP_vramp(&phase, &inc, &atom[0], 1, length); // vDSP_vsq(&atom[0], 1, &atom[0], 1, length); // vDSP_vsdiv(&atom[0], 1, &gausDivisor, &atom[0], 1, length); // for(uint i=0; i < length; i++) atom[i] = exp(atom[i]); //#else // for(uint i=0; i < length; i++) { // //gaussian envelope // atom[i] = exp((phase* phase) / gausDivisor); // phase += inc; // } //#endif float cycleLen = sampleRate / freq; float maxPhase = length / cycleLen; float inc = 1.0 / length; #ifdef __APPLE_CC__ flArr interpConstants; interpConstants.resize(length); float phase = 0.0; vDSP_vramp(&phase, &inc, &interpConstants[0], 1, length); vDSP_vsmsa(&interpConstants[0], 1, &maxPhase, &startPhase, &interpConstants[0], 1, length); float waveTableLength = 512; vDSP_vsmul(&interpConstants[0], 1, &waveTableLength, &interpConstants[0], 1, length); for(uint i=0; i < length; i++) { interpConstants[i] = fmod(interpConstants[i], 512.0f); } vDSP_vlint(sineBuffer2, &interpConstants[0], 1, &sine[0], 1, length, 514); vDSP_vmul(&atom[0], 1, &sine[0], 1, &atom[0], 1, length); vDSP_vsmul(&atom[0], 1, &, &atom[0], 1, length); #else maxPhase *= TWOPI; for(uint i=0; i < length; i++) { //multiply by sinewave float x = inc * i; sine[i] = sin((x * maxPhase) + startPhase); } for(uint i=0; i < length; i++) { atom[i] *= sine[i]; atom[i] *= amp; } #endif }