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 WAVESHAPE::run() { for (int i = 0; i < framesToRun(); i++) { if (--branch <= 0) { doupdate(); branch = skip; } float sig = osc->next(); float wsig = wshape(sig * index, xferfunc, lenxfer); // dc blocking filter float osig = a1 * z1; z1 = b1 * z1 + wsig; osig += a0 * z1; float out[2]; out[0] = osig * amp; if (outputChannels() == 2) { out[1] = (1.0 - spread) * out[0]; out[0] *= spread; } rtaddout(out); increment(); } return framesToRun(); }
int MMESH2D :: run() { int i; float out[2]; for (i = 0; i < framesToRun(); i++) { if (--branch <= 0) { double p[10]; update (p, 10, kAmp | kPan); amp = p[2]; if (amptable) amp *= theEnv->next(currentFrame()); branch = getSkip(); } out[0] = dcblocker->next(theMesh->tick()) * amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - pctleft); out[0] *= pctleft; } rtaddout(out); increment(); } return framesToRun(); }
int WAVETABLE::run() { const int nframes = framesToRun(); for (int i = 0; i < nframes; i++) { if (--branch <= 0) { if (fastUpdate) { if (amptable) amp = ampmult * tablei(currentFrame(), amptable, amptabs); } else doupdate(); branch = getSkip(); } float out[2]; out[0] = osc->next() * amp; if (outputChannels() == 2) { out[1] = (1.0 - spread) * out[0]; out[0] *= spread; } rtaddout(out); increment(); } return framesToRun(); }
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 MULTIWAVE::run() { const int samps = framesToRun(); const int chans = outputChannels(); float out[chans]; for (int i = 0; i < samps; i++) { if (--branch <= 0) { doupdate(); branch = getSkip(); } for (int j = 0; j < chans; j++) out[j] = 0.0f; for (int j = 0; j < numpartials; j++) { float sig = oscil[j]->next() * amp[j]; if (chans == 1) out[0] += sig; else { out[0] += sig * pan[j]; out[1] += sig * (1.0 - pan[j]); } } float scale = (1.0 / float(numpartials)) * (overall_amp * chans); for (int j = 0; j < chans; j++) out[j] *= scale; rtaddout(out); increment(); } return framesToRun(); }
int BEND1::run() { for (int i = 0; i < framesToRun(); i++) { if (--branch <= 0) { if (amptable) aamp = tablei(currentFrame(), amptable, amptabs) * amp; float freq = diff * tablei(currentFrame(), glissf, tags) + freq0; sset(SR, freq, tf0, tfN, strumq1); branch = reset; } float a = strum(d, strumq1); float b = dist(dgain*a); d = fbgain*delay(b, dq); float out[2]; out[0] = (cleanlevel*a + distlevel*b) * aamp; if (outputChannels() == 2) { /* split stereo files between the channels */ out[1] = (1.0 - spread) * out[0]; out[0] *= spread; } rtaddout(out); increment(); } return framesToRun(); }
int MBOWED :: run() { int i; float out[2]; for (i = 0; i < framesToRun(); i++) { if (--branch <= 0) { doupdate(); branch = getSkip(); } if (--vibupdate < 0) { // reset the vibrato freq after each cycle float vibfreq = theRand->range(viblo, vibhi); theVib->setfreq(vibfreq); vibupdate = (int)(SR/vibfreq); } out[0] = theBow->tick(bowvel) * amp; theBow->setFrequency(freqbase + (freqamp * ( (theVib->next()+2.0) * 0.5 ))); if (outputChannels() == 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 IINOISE::run() { for (int i = 0; i < framesToRun(); i++) { if (--branch <= 0) { if (fastUpdate) { if (amptable) amp = ampmult * tablei(currentFrame(), amptable, amptabs); } else doupdate(); branch = getSkip(); } float sig = rrand(); float out[2]; out[0] = 0.0f; for (int j = 0; j < nresons; j++) out[0] += resons[j]->next(sig) * resonamp[j]; out[0] *= amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0f - pan); out[0] *= pan; } rtaddout(out); increment(); } return framesToRun(); }
int FMINST::run() { const int nframes = framesToRun(); for (int i = 0; i < nframes; i++) { if (--branch <= 0) { if (fastUpdate) { if (amptable) amp = ampmult * tablei(currentFrame(), amptable, amptabs); float guide = tablei(currentFrame(), indexenv, indtabs); peakdev = modfreq * (minindex + (indexdiff * guide)); } else doupdate(); branch = getSkip(); } float out[2]; float modsig = modosc->next() * peakdev; carosc->setfreq(carfreq + modsig); out[0] = carosc->next() * amp; if (outputChannels() == 2) { out[1] = (1.0 - pan) * out[0]; out[0] *= pan; } rtaddout(out); increment(); } return framesToRun(); }
int WAVY::run() { const int frames = framesToRun(); const int chans = outputChannels(); for (int i = 0; i < frames; i++) { if (--_branch <= 0) { doupdate(); _branch = getSkip(); } float sig1 = _oscilA->nexti(); float sig2 = _oscilB->nexti(); float out[chans]; if (_fp) out[0] = eval(sig1, sig2) * _amp; else out[0] = (*_combiner)(sig1, sig2) * _amp; if (chans == 2) { out[1] = out[0] * (1.0f - _pan); out[0] *= _pan; } 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 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 CRACKLE::run() { for (int i = 0; i < framesToRun(); i++) { if (--branch <= 0) { doupdate(); branch = getSkip(); } x3 = x2; x2 = x1; x1 = x0; x0 = std::abs(0.03 - x2 + x3 - param * x1); float out[2]; out[0] = x0 * amp * 5; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - pan); out[0] *= pan; } rtaddout(out); increment(); } return framesToRun(); }
int BROWN::run() { for (int i = 0; i < framesToRun(); i++) { if (--_branch <= 0) { doupdate(); _branch = getSkip(); } float out[2]; while (true) { float r = rrand(); _brown += r; if (_brown <- 8.0 || _brown > 8.0) _brown -= r; else break; } out[0] = _brown * 0.125 * _amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - _pan); out[0] *= _pan; } rtaddout(out); increment(); } return framesToRun(); }
int MMODALBAR :: run() { int i; float out[2]; for (i = 0; i < framesToRun(); i++) { if (--branch <=0) { doupdate(); branch = getSkip(); } if (currentFrame() < 256) // feed in excitation out[0] = theBar->tick(exciteamp, excite[currentFrame()]) * amp; else out[0] = theBar->tick(exciteamp, 0.0) * amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - pctleft); out[0] *= pctleft; } rtaddout(out); increment(); } return framesToRun(); }
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 NOISE :: run() { for (int i = 0; i < framesToRun(); i++) { if (--branch <= 0) { double p[nargs]; update(p, nargs); amp = p[2]; if (amparray) amp *= tablei(currentFrame(), amparray, amptabs); pctleft = nargs > 3 ? p[3] : 0.5; // default is .5 branch = skip; } float out[2]; out[0] = rrand() * amp; if (outputChannels() == 2) { out[1] = out[0] * (1.0 - pctleft); out[0] *= pctleft; } rtaddout(out); increment(); } return framesToRun(); }
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 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 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 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 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 DUMP::run() { float out[2] = {0.0, 0.0}; for (int i = 0; i < framesToRun(); i++) { if (--branch <= 0) { doupdate(); branch = skip; } rtaddout(out); increment(); } return framesToRun(); }
int GRANSYNTH::run() { // NOTE: Without a lot more code, we can't guarantee that doupdate will // be called exactly every getSkip() samples, the way we can when not doing // block I/O. But this seems worth sacrificing for the clear performance // improvement that block I/O offers. const int frames = framesToRun(); int blockframes = min(frames, getSkip()); int framesdone = 0; while (1) { if (_branch <= 0) { doupdate(); _branch = getSkip(); } _branch -= blockframes; _stream->processBlock(_block, blockframes, _amp); rtbaddout(_block, blockframes); increment(blockframes); framesdone += blockframes; if (framesdone == frames) break; assert(framesdone < frames); const int remaining = frames - framesdone; if (remaining < blockframes) blockframes = remaining; } return frames; }
int GRANSYNTH::run() { const int frames = framesToRun(); const int outchans = outputChannels(); int i; for (i = 0; i < frames; i++) { if (--_branch <= 0) { doupdate(); _branch = getSkip(); } _stream->prepare(); float out[outchans]; if (outchans == 2) { out[0] = _stream->lastL() * _amp; out[1] = _stream->lastR() * _amp; } else out[0] = _stream->lastL() * _amp; rtaddout(out); increment(); } return i; }
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 LSFLUTE::run() { for (int i = 0; i < framesToRun(); i++) { if (olength1 < length1) olength1++; if (olength1 > length1) olength1--; if (olength2 < length2) olength2++; if (olength2 > length2) olength2--; if (--branch <= 0) { aamp = tablei(currentFrame(), amparr, amptabs); oamp = tablei(currentFrame(), oamparr, oamptabs); branch = skip; } float sig = (rrand() * namp * aamp) + aamp; float del1sig = mdelget(del1ptr,olength1,dl1ptr); sig = sig + (del1sig * -0.35); #ifdef MAXMSP delput(sig,del2ptr,dl2ptr); #else mdelput(sig,del2ptr,dl2ptr); #endif sig = mdelget(del2ptr,olength2,dl2ptr); sig = (sig * sig * sig) - sig; sig = (0.4 * sig) + (0.9 * del1sig); float out[2]; out[0] = sig * amp * oamp; sig = (dampcoef * sig) + ((1.0 - dampcoef) * oldsig); oldsig = sig; #ifdef MAXMSP delput(sig,del1ptr,dl1ptr); #else mdelput(sig,del1ptr,dl1ptr); #endif if (outputChannels() == 2) { out[1] = (1.0 - spread) * out[0]; out[0] *= spread; } rtaddout(out); increment(); } return framesToRun(); }
int FREEVERB :: run() { float *inL, *inR, *outL, *outR; inL = in; inR = inputChannels() > 1 ? in + 1 : in; outL = outbuf; outR = outputChannels() > 1 ? outbuf + 1 : outbuf; int samps = framesToRun() * inputChannels(); if (currentFrame() < insamps) rtgetin(in, this, samps); // Scale input signal by amplitude multiplier and setline curve. for (int i = 0; i < samps; i += inputChannels()) { if (--branch <= 0) { double p[11]; update(p, 11, kRoomSize | kPreDelay | kDamp | kDry | kWet | kWidth); if (currentFrame() < insamps) { // amp is pre-effect amp = update(3, insamps); if (amparray) amp *= tablei(currentFrame(), amparray, amptabs); } updateRvb(p); branch = getSkip(); } if (currentFrame() < insamps) { // still taking input from file in[i] *= amp; if (inputChannels() == 2) in[i + 1] *= amp; } else { // in ringdown phase in[i] = 0.0; if (inputChannels() == 2) in[i + 1] = 0.0; } increment(); } // Hand off to Freeverb to do the actual work. rvb->processreplace(inL, inR, outL, outR, framesToRun(), inputChannels(), outputChannels()); return framesToRun(); }