int AM::run() { const int samps = framesToRun() * inputChannels(); rtgetin(in, this, samps); for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { double p[7]; update(p, 7, kAmp | kFreq | kPan); amp = p[3]; if (amptable) amp *= tablei(currentFrame(), amptable, amptabs); if (freqtable) modfreq = tablei(currentFrame(), freqtable, freqtabs); else modfreq = p[4]; modosc->setfreq(modfreq); spread = p[6]; branch = skip; } float out[2]; out[0] = in[i + inchan] * modosc->next() * amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - spread); out[0] *= spread; } rtaddout(out); increment(); } return framesToRun(); }
int REVMIX::run() { int samps = framesToRun() * inputChannels(); rtinrepos(this, -framesToRun(), SEEK_CUR); rtgetin(in, this, samps); for (int i = samps - inputChannels(); i >= 0; i -= inputChannels()) { if (--branch <= 0) { double p[nargs]; update(p, nargs); amp = p[3]; if (amparray) amp *= tablei(currentFrame(), amparray, amptabs); pctleft = nargs > 5 ? p[5] : 0.5; // default is .5 branch = skip; } float out[2]; out[0] = in[i + inchan] * amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - pctleft); out[0] *= pctleft; } rtaddout(out); increment(); } rtinrepos(this, -framesToRun(), SEEK_CUR); return framesToRun(); }
int AM::init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; inchan = (int) p[5]; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; // no input if (inchan >= inputChannels()) return die("AM", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("AM", "Can't handle more than 2 output channels."); amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } int tablelen = 0; if (n_args > 7) { // handle table coming in as optional p7 TablePField wavetable = (double *) getPFieldTable(7, &tablelen); } if (wavetable == NULL) { // use old gen slot wavetable = floc(2); if (wavetable) tablelen = fsize(2); else { // use default sine wave rtcmix_advise("AM", "No modulator wavetable specified, so using sine wave."); tablelen = 1024; wavetable = new double [tablelen]; ownWavetable = true; const double twopi = M_PI * 2.0; for (int i = 0; i < tablelen; i++) wavetable[i] = sin(twopi * ((double) i / tablelen)); } } modfreq = p[4]; modosc = new Ooscili(SR, modfreq, wavetable, tablelen); if (modfreq == 0.0) { freqtable = floc(3); if (freqtable) { int len = fsize(3); tableset(SR, dur, len, freqtabs); } else return die("AM", "If p4 is zero, old-style gen table 3 must " "contain modulator frequency curve."); } skip = (int) (SR / (float) resetval); return nSamps(); }
int JFIR :: run() { const int samps = framesToRun() * inputChannels(); rtgetin(in, this, samps); for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { doupdate(); branch = getSkip(); } float insig; if (currentFrame() < insamps) // still taking input insig = in[i + inchan] * amp; else // in ring-down phase insig = 0.0; float out[2]; if (bypass) out[0] = insig; else out[0] = filt->tick(insig); if (outputchans == 2) { out[1] = out[0] * (1.0 - pctleft); out[0] *= pctleft; } rtaddout(out); increment(); } return framesToRun(); }
int DISTORT::run() { const int insamps = framesToRun() * inputChannels(); rtgetin(in, this, insamps); for (int i = 0; i < insamps; i += inputChannels()) { if (--branch <= 0) { doupdate(); branch = getSkip(); } float sig = in[i + inchan]; if (!bypass) { sig *= (gain / 32768.0f); // apply gain, convert range sig = distort->next(sig, param); sig *= 32768.0f; if (usefilt) sig = filt->tick(sig); } sig *= amp; float out[2]; if (outputChannels() == 2) { out[0] = sig * pctleft; out[1] = sig * (1.0f - pctleft); } else out[0] = sig; rtaddout(out); increment(); } return framesToRun(); }
int FILTSWEEP :: init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float inskip = p[1]; float dur = p[2]; float ringdur = p[4]; nfilts = n_args > 5 ? (int) p[5] : 1; do_balance = n_args > 6 ? (bool) p[6] : true; inchan = n_args > 7 ? (int) p[7] : 0; // default is chan 0 if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) return die("FILTSWEEP", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR + 0.5); if (nfilts < 1 || nfilts > MAXFILTS) return die("FILTSWEEP", "Steepness (p5) must be an integer between 1 and %d.", MAXFILTS); for (int i = 0; i < nfilts; i++) filt[i] = new JGBiQuad(SR); if (do_balance) { balancer = new Balance(SR); balancer->setWindowSize(BALANCE_WINDOW_SIZE); scale = 1.0; } else scale = 1.0 / pow((double) nfilts, 1.8); // just a guess; needs work amparray = floc(1); if (amparray) { int lenamp = fsize(1); tableset(SR, dur, lenamp, amptabs); } if (n_args < 11) { // no p10 center freq PField, must use gen table cfarray = floc(2); if (cfarray == NULL) return die("FILTSWEEP", "Either use the center frequency pfield (p10) " "or make an old-style gen function in slot 2."); int len = fsize(2); tableset(SR, dur, len, cftabs); } if (n_args < 12) { // no p11 bandwidth PField, must use gen table bwarray = floc(3); if (bwarray == NULL) return die("FILTSWEEP", "Either use the bandwidth pfield (p11) " "or make an old-style gen function in slot 3."); int len = fsize(3); tableset(SR, dur, len, bwtabs); } return nSamps(); }
int SHAPE :: run() { const int samps = framesToRun() * inputChannels(); rtgetin(in, this, samps); for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { doupdate(); branch = skip; } // NB: WavShape deals with samples in range [-1, 1]. float insig = in[i + inchan] * (1.0 / 32768.0); float outsig = shaper->tick(insig * index); if (outsig) { if (ampnorm) outsig = dcblocker->tick(outsig) * ampnorm->tick(norm_index); else outsig = dcblocker->tick(outsig); } float out[2]; out[0] = outsig * amp * 32768.0; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - pctleft); out[0] *= pctleft; } rtaddout(out); increment(); } return framesToRun(); }
int GVERB::run() { const int samps = framesToRun() * inputChannels(); int i; float out[2]; rtgetin(in, this, samps); for (i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { doupdate(); branch = getSkip(); } if (currentFrame() > inputframes) in[i+inputchan] = 0.0; gverb_do(p, in[i+inputchan], out, out+1); out[0] = (out[0] * amp) + (in[i+inputchan] * p->drylevel); out[1] = (out[1] * amp) + (in[i+inputchan] * p->drylevel); rtaddout(out); increment(); } return i; }
int MYINST::run() { // framesToRun() gives the number of sample frames -- 1 sample for each // channel -- that we have to write during this scheduler time slice. const int samps = framesToRun() * inputChannels(); // Read <samps> samples from the input file (or audio input device). rtgetin(_in, this, samps); // Each loop iteration processes 1 sample frame. */ for (int i = 0; i < samps; i += inputChannels()) { // This block updates certain parameters at the control rate -- the // rate set by the user with the control_rate() or reset() script // functions. The Instrument base class holds this value as a number // of sample frames to skip between updates. Get this value using // getSkip() to reset the <_branch> counter. if (--_branch <= 0) { doupdate(); _branch = getSkip(); } // Grab the current input sample, scaled by the amplitude multiplier. float insig = _in[i + _inchan] * _amp; float out[2]; // Space for only 2 output chans! // Just copy it to the output array with no processing. out[0] = insig; // If we have stereo output, use the pan pfield. if (outputChannels() == 2) { out[1] = out[0] * (1.0f - _pan); out[0] *= _pan; } // Write this sample frame to the output buffer. rtaddout(out); // Increment the count of sample frames this instrument has written. increment(); } // Return the number of frames we processed. return framesToRun(); }
int MULTEQ :: init(double p[], int n_args) { nargs = n_args; const float ringdur = 0.1; float outskip = p[0]; float inskip = p[1]; float dur = p[2]; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR + 0.5); if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; if (inputChannels() > MAXCHAN) return die("MULTEQ", "Input and output must have no more than %d channels.", MAXCHAN); if (outputChannels() != inputChannels()) return die("MULTEQ", "Input and output must have same number of " "channels, no more than %d.", MAXCHAN); if ((nargs - FIRST_BAND_PF) % BAND_PFS) return die("MULTEQ", "For each band, need type, freq, Q, gain and bypass."); numbands = 0; int band = 0; for (int i = FIRST_BAND_PF; i < nargs; i += BAND_PFS, band += MAXCHAN) { if (numbands == MAXBAND) { warn("MULTEQ", "You can only have %d EQ bands.", MAXBAND); break; } OeqType type = getEQType(true, i); if (type == OeqInvalid) return die("MULTEQ", "Invalid EQ type string or code."); float freq = p[i + 1]; float Q = p[i + 2]; float gain = p[i + 3]; bool bypass = (bool) p[i + 4]; for (int c = 0; c < inputChannels(); c++) { eq[band + c] = new EQBand(SR, type, freq, Q, gain, bypass); if (eq[band + c] == NULL) return die("MULTEQ", "Can't allocate EQ band."); } numbands++; } skip = (int) (SR / (float) resetval); return nSamps(); }
int MYINST::init(double p[], int n_args) { _nargs = n_args; // store this for use in doupdate() // Store pfields in variables, to allow for easy pfield renumbering. // You should retain the RTcmix numbering convention for the first // 4 pfields: outskip, inskip, dur, amp; or, for instruments that // take no input: outskip, dur, amp. const float outskip = p[0]; const float inskip = p[1]; const float dur = p[2]; // Here's how to handle an optional pfield. _inchan = (n_args > 4) ? int(p[4]) : 0; // default is chan 0 // no need to retrieve amp or pan here, because these will be set // before their first use inside of doupdate(). // Tell scheduler when to start this inst. If rtsetoutput returns -1 to // indicate an error, then return DONT_SCHEDULE. if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; // Test whether the requested number of output channels is right for your // instrument. The die function reports the error; the system decides // whether this should exit the program or keep going. if (outputChannels() > 2) return die("MYINST", "Use mono or stereo output only."); // Set file pointer on audio input. If the input source is real-time or // an aux bus, then <inskip> must be zero. The system will return an // an error in this case, which we must pass along. if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; // Make sure requested input channel number is valid for this input source. // inputChannels() gives the total number of input channels, initialized // in rtsetinput. if (_inchan >= inputChannels()) return die("MYINST", "You asked for channel %d of a %d-channel input.", _inchan, inputChannels()); // Return the number of sample frames that we'll write to output, which // the base class has already computed in response to our rtsetoutput call // above. nSamps() equals the duration passed to rtsetoutput multiplied // by the sampling rate and then rounded to the nearest integer. return nSamps(); }
int REVERBIT::run() { int samps = framesToRun() * inputChannels(); if (currentFrame() < insamps) rtgetin(in, this, samps); for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { doupdate(); branch = getSkip(); } float insig[2], out[2]; if (currentFrame() < insamps) { // still taking input from file insig[0] = in[i] * amp; insig[1] = (inputChannels() == 2) ? in[i + 1] * amp : insig[0]; } else // in ring-down phase insig[0] = insig[1] = 0.0; float rvbsig = -reverbpct * reverb(insig[0] + insig[1], rvbarray); if (usefilt) rvbsig = tone(rvbsig, tonedata); delput(rvbsig, delarray, deltabs); float delsig = delget(delarray, rtchan_delaytime, deltabs); out[0] = insig[0] + rvbsig; out[1] = insig[1] + delsig; if (dcblock) { float tmp_in[2]; tmp_in[0] = out[0]; tmp_in[1] = out[1]; out[0] = tmp_in[0] - prev_in[0] + (0.99 * prev_out[0]); prev_in[0] = tmp_in[0]; prev_out[0] = out[0]; out[1] = tmp_in[1] - prev_in[1] + (0.99 * prev_out[1]); prev_in[1] = tmp_in[1]; prev_out[1] = out[1]; } rtaddout(out); increment(); } return framesToRun(); }
int COMBFILT::init(double p[], int n_args) { // p0 = outsk; p1 = insk; p2 = input dur; p3 = amp mult // p4 = pitch; p5 = a (input mult); p6 = b (delay mult); // p7 = filter type (FIR/IIR) // p8 = wetdry; p9 = inchan [optional]; p10 = spread [optional] // p11 = rise // p12 = sustain // p13 = decay // assumes function table 1 is the amplitude envelope if (rtsetinput(p[1], this) != 0) return DONT_SCHEDULE; if (rtsetoutput(p[0], p[2], this) != 0) return DONT_SCHEDULE; insamps = (int)(p[2] * SR); if (p[4] < 15.0) combfreq = cpspch(p[4]); else combfreq = p[4]; // FIXME: need check here: combfreq < SR/2 delay = (int)rint(SR/combfreq); amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, p[2], amplen, tabs); } else rtcmix_advise("COMBFILT", "Setting phrase curve to all 1's."); amp = p[3]; a = p[5]; b = p[6]; // FIXME: need check here: type < 2 type = (int)p[7]; skip = (int)(SR/(float)resetval); // how often to update amp curve inchan = (int)p[9]; if ((inchan+1) > inputChannels()) return die("COMBFILT", "You asked for channel %d of a %d-channel file.", inchan,inputChannels()); wetdry = p[8]; spread = p[10]; maxdelay = (int)rint(SR); runsamp = 0; return(this->mytag); }
int ROOM::run() { const int samps = framesToRun() * inputChannels(); rtgetin(in, this, samps); for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { if (amparray) aamp = tablei(currentFrame(), amparray, amptabs) * amp; branch = skip; } float insig; if (currentFrame() < insamps) { /* still taking input */ if (inchan == AVERAGE_CHANS) { insig = 0.0; for (int n = 0; n < inputChannels(); n++) insig += in[i + n]; insig /= (float) inputChannels(); } else insig = in[i + inchan]; } else /* in ring-down phase */ insig = 0.0; echo[jpoint++] = insig; if (jpoint >= nmax) jpoint -= nmax; float out[2]; out[0] = out[1] = 0.0; for (int j = 0; j < NTAPS; j++) { float e = echo[ipoint[j]]; out[0] += e * lamp[j]; out[1] += e * ramp[j]; ipoint[j]++; if (ipoint[j] >= nmax) ipoint[j] -= nmax; } if (aamp != 1.0) { out[0] *= aamp; out[1] *= aamp; } rtaddout(out); increment(); } return framesToRun(); }
int ROOM::init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; amp = p[3]; inchan = n_args > 4 ? (int)p[4] : AVERAGE_CHANS; if (outputchans != 2) return die("ROOM", "Output must be stereo."); if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR + 0.5); if (inchan >= inputChannels()) return die("ROOM", "You asked for channel %d of a %d-channel input file.", inchan, inputChannels()); if (inputChannels() == 1) inchan = 0; nmax = get_room(ipoint, lamp, ramp, SR); if (nmax == 0) return die("ROOM", "You need to call roomset before ROOM."); echo = new float[nmax]; for (int i = 0; i < nmax; i++) echo[i] = 0.0; jpoint = 0; #ifdef DEBUG printf("maximum delay = %d samples.\n", nmax); #endif float ringdur = (float) nmax / SR; if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; amparray = floc(1); if (amparray) { int amplen = fsize(1); tableset(SR, dur + ringdur, amplen, amptabs); } else rtcmix_advise("ROOM", "Setting phrase curve to all 1's."); aamp = amp; /* in case amparray == NULL */ skip = (int)(SR / (float)resetval); return nSamps(); }
int COMBIT::run() { int samps = framesToRun() * inputChannels(); if (currentFrame() < insamps) rtgetin(in, this, samps); for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { double p[8]; update(p, 8); amp = p[3]; if (amptable) { #ifdef EMBEDDED amp *= rtcmix_table(currentFrame(), amptable, tabs); #else amp *= table(currentFrame(), amptable, tabs); #endif } if (p[4] != frequency) { frequency = p[4]; delsamps = (int) ((1.0 / frequency) * SR + 0.5); } if (p[5] != rvbtime) { rvbtime = p[5]; comb->setReverbTime(rvbtime); } pctleft = p[7]; branch = skip; } float insig, out[2]; if (currentFrame() < insamps) insig = in[i + inchan]; else insig = 0.0; out[0] = comb->next(insig, delsamps) * amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - pctleft); out[0] *= pctleft; } rtaddout(out); increment(); } return framesToRun(); }
int JFIR :: init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float inskip = p[1]; float dur = p[2]; int order = (int) p[4]; inchan = (int) p[5]; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR + 0.5); if (inchan >= inputChannels()) return die("JFIR", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); float ringdur = (float) order / SR; if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; double *response_table = NULL; int tablelen = 0; if (n_args > 8) { // handle table coming in as optional p8 TablePField response_table = (double *) getPFieldTable(8, &tablelen); } if (response_table == NULL) { response_table = floc(2); if (response_table == NULL) return die("JFIR", "Either use the frequency response pfield (p8) " "or make an old-style gen function in slot 2."); tablelen = fsize(2); } if (order < 1) return die("JFIR", "Order must be greater than 0."); filt = new NZero(SR, order); filt->designFromFunctionTable(response_table, tablelen, 0, 0); #ifdef PRINT_RESPONSE print_freq_response(); #endif amparray = floc(1); if (amparray) { int lenamp = fsize(1); tableset(SR, dur, lenamp, amptabs); } return nSamps(); }
int STEREO::run() { const int inchans = inputChannels(); const int samps = framesToRun() * inchans; rtgetin(in, this, samps); for (int i = 0; i < samps; i += inchans) { if (--branch <= 0) { if (fastUpdate) { if (amptable) amp = ampmult * tablei(currentFrame(), amptable, amptabs); } else doupdate(); branch = getSkip(); } float out[2]; out[0] = out[1] = 0.0; for (int j = 0; j < inchans; j++) { if (outPan[j] >= 0.0) { out[0] += in[i+j] * outPan[j] * amp; out[1] += in[i+j] * (1.0 - outPan[j]) * amp; } } rtaddout(out); increment(); } return framesToRun(); }
int MIX::init(double p[], int n_args) { const float outskip = p[0]; const float inskip = p[1]; float dur = p[2]; if (dur < 0.0) dur = -dur - inskip; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; // no input for (int i = 0; i < inputChannels(); i++) { outchan[i] = (int) p[i + 4]; if (outchan[i] + 1 > outputChannels()) return die("MIX", "You wanted output channel %d, but have only specified " "%d output channels", outchan[i], outputChannels()); } initamp(dur, p, 3, 1); return nSamps(); }
void MULTEQ :: doupdate() { double p[nargs]; update(p, nargs); amp = p[3]; bypass = (bool) p[4]; int band = 0; for (int i = FIRST_BAND_PF; i < nargs; i += BAND_PFS, band += MAXCHAN) { OeqType type = getEQType(false, i); float freq = p[i + 1]; if (freq < 0.0) freq = 0.0; else if (freq > SR * 0.5) freq = SR * 0.5; float Q = p[i + 2]; if (Q <= 0.0) Q = FLT_MIN; float gain = p[i + 3]; bool bypass = (bool) p[i + 4]; for (int c = 0; c < inputChannels(); c++) eq[band + c]->setparams(type, freq, Q, gain, bypass); } }
void LPCIN::SetupArrays(int) { _inbuf = new BUFTYPE[inputChannels() * RTBUFSAMPS]; _alpvals = new float[MAXVALS]; _buzvals = new float[MAXVALS]; }
int PVOC::configure() { /* * allocate memory */ Wanal = ::NewArray(Nw); /* analysis window */ Wsyn = ::NewArray(Nw); /* synthesis window */ _pvInput = ::NewArray(Nw); /* input buffer */ Hwin = ::NewArray(Nw); /* plain Hamming window */ winput = ::NewArray(Nw); /* windowed input buffer */ lpcoef = ::NewArray(Np+1); /* lp coefficients */ _fftBuf = ::NewArray(N); /* FFT buffer */ channel = ::NewArray(N+2); /* analysis channels */ _pvOutput = ::NewArray(Nw); /* output buffer */ /* * create windows */ makewindows( Hwin, Wanal, Wsyn, Nw, N, I, obank ); // The input buffer is larger than BUFSAMPS so it can be filled with // enough samples (via multiple calls to rtgetin()) to satisfy the input. _inbuf = new BUFTYPE[inputChannels() * Nw]; // The output buffer is also larger in order to allow at least a full // window of synthesized output to be stored. _outbuf = new BUFTYPE[Nw]; // XXX CHECK THIS SIZE return 0; }
int CONVOLVE1::configure() { _inbuf = new float [RTBUFSAMPS * inputChannels()]; _ovadd = new float [_impframes]; if (_inbuf == NULL || _ovadd == NULL) return -1; for (int i = 0; i < _impframes; i++) _ovadd[i] = 0.0f; // read index chases write index by _impframes _outframes = imax(_halfFFTlen, RTBUFSAMPS) * 2; _outReadIndex = _outframes - _impframes; _outWriteIndex = 0; _dry = new float [_outframes]; _wet = new float [_outframes]; if (_dry == NULL || _wet == NULL) return -1; for (int i = 0; i < _outframes; i++) _dry[i] = _wet[i] = 0.0f; DPRINT1("_outframes: %d\n", _outframes); _bucket = new Obucket(_impframes, processWrapper, (void *) this); if (_bucket == NULL) return -1; _fft = new Offt(_fftlen); if (_fft == NULL) return -1; _fftbuf = _fft->getbuf(); if (prepareImpulse() != 0) return -1; return 0; }
int TRANS3::run() { const int outframes = framesToRun(); const int inchans = inputChannels(); float *outp = outbuf; // point to inst private out buffer double frac; for (int i = 0; i < outframes; i++) { if (--branch <= 0) { doupdate(); branch = getSkip(); } while (getframe) { if (inframe >= RTBUFSAMPS) { rtgetin(in, this, RTBUFSAMPS * inchans); inframe = 0; } oldersig = oldsig; oldsig = newsig; newsig = newestsig; newestsig = in[(inframe * inchans) + inchan]; inframe++; incount++; if (counter - (double) incount < 0.0) getframe = false; } // const double frac = (counter - (double) incount) + 2.0; const double frac = (counter - (double) incount) + 1.0; outp[0] = interp3rdOrder(oldersig, oldsig, newsig, newestsig, frac) * amp; #ifdef DEBUG_FULL printf("i: %d counter: %g incount: %d frac: %g inframe: %d cursamp: %d\n", i, counter, incount, frac, inframe, currentFrame()); printf("interping %g, %g, %g, %g => %g\n", oldersig, oldsig, newsig, newestsig, outp[0]); #endif if (outputChannels() == 2) { outp[1] = outp[0] * (1.0 - pctleft); outp[0] *= pctleft; } outp += outputChannels(); increment(); counter += _increment; // keeps track of interp pointer if (counter - (double) incount >= 0.0) getframe = true; } #ifdef DEBUG printf("OUT %d frames\n\n", i); #endif return framesToRun(); }
int PANECHO::run() { int samps = framesToRun() * inputChannels(); if (currentFrame() < insamps) rtgetin(in, this, samps); for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { double p[7]; update(p, 7, kDelTime0 | kDelTime1 | kDelRegen); amp = update(3, insamps); if (amptable) amp *= tablei(currentFrame(), amptable, amptabs); float thisdeltime = p[4]; if (thisdeltime != prevdeltime0) { delsamps0 = getdelsamps(thisdeltime); prevdeltime0 = thisdeltime; } thisdeltime = p[5]; if (thisdeltime != prevdeltime1) { delsamps1 = getdelsamps(thisdeltime); prevdeltime1 = thisdeltime; } regen = p[6]; branch = getSkip(); } float sig, out[2]; if (currentFrame() < insamps) sig = in[i + inchan] * amp; else sig = 0.0; out[0] = sig + (delay1->getsamp(delsamps1) * regen); out[1] = delay0->getsamp(delsamps0); delay0->putsamp(out[0]); delay1->putsamp(out[1]); rtaddout(out); increment(); } return framesToRun(); }
int RVB::configure() { in = new float [RTBUFSAMPS * inputChannels()]; alloc_delays(); /* allocates memory for delays */ rvb_reset(); return 0; }
int DISTORT::init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float inskip = p[1]; float dur = p[2]; type = p[4]; cutoff = n_args > 6 ? p[6] : 0.0; // filter disabled inchan = n_args > 7 ? (int) p[7] : 0; // default is chan 0 if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) return die("DISTORT", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); if (type == 1) distort = new Odistort(Odistort::SoftClip); else if (type == 2) distort = new Odistort(Odistort::SimpleTube); else if (type == 3) distort = new Odistort(Odistort::VariableClip); else if (type == 4) distort = new Odistort(Odistort::WaveShape); else return die("DISTORT", "Distortion type must be 1-4."); usefilt = (cutoff > 0.0); if (usefilt) { filt = new Butter(SR); filt->setLowPass(cutoff); } // legacy support for makegen amp double *function = floc(1); if (function) { int len = fsize(1); amptable = new TableL(SR, dur, function, len); } return nSamps(); }
int MYINST::configure() { // RTBUFSAMPS is the maximum number of sample frames processed for each // call to run() below. _in = new float [RTBUFSAMPS * inputChannels()]; return _in ? 0 : -1; // IMPORTANT: Return 0 on success, and -1 on failure. }
int PANECHO::init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; float deltime0 = p[4]; float deltime1 = p[5]; float ringdur = p[7]; inchan = n_args > 8 ? (int) p[8] : 0; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) return die("PANECHO", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR + 0.5); if (outputChannels() != 2) return die("PANECHO", "Output must be stereo."); if (deltime0 <= 0.0 || deltime1 <= 0.0) return die("PANECHO", "Illegal delay times"); long delsamps = (long) (deltime0 * SR + 0.5); delay0 = new Odelayi(delsamps); delsamps = (long) (deltime1 * SR + 0.5); delay1 = new Odelayi(delsamps); if (delay0->length() == 0 || delay1->length() == 0) return die("PANECHO", "Can't allocate delay line memory."); prevdeltime0 = prevdeltime1 = -999999999.9; // force first update amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } return nSamps(); }
int COMBFILT::configure() { in = new float [RTBUFSAMPS * inputChannels()]; x = new float[maxdelay]; y = new float[maxdelay]; for (int i=0;i<maxdelay;i++) { x[i] = y[i] = 0.0; } return 0; }