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(); }
double param (float p[], int n_args) /* parametric setup for polar coordinates */ { int i; double *fun1, *fun2; if (n_args != 2) die("param", "Incorrect number of args. Should have 2."); fun1 = floc((int) p[0]); if (fun1 == NULL) die("param", "You haven't made function table %d.", (int) p[0]); fun2 = floc((int) p[1]); if (fun2 == NULL) die("param", "You haven't made function table %d.", (int) p[1]); for (i = 0; i < ARRAYSIZE; i++) { rholoc[i] = *fun1++; thetaloc[i] = *fun2++; } rtcmix_advise("param", "Functions loaded."); cartflag = 0; return 0.0; }
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 MBANDEDWG :: init(double p[], int n_args) { nargs = n_args; Stk::setSampleRate(SR); if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; amptable = floc(1); if (amptable) // the amp array has been created using makegen theEnv = new Ooscili(SR, 1.0/p[1], 1); veltable = floc(2); if (veltable) { // the velocity array has been created in the score theVeloc = new Ooscili(SR, 1.0/p[1], 2); } else { if (n_args < 13) { velarray[0] = velarray[1] = 1.0; rtcmix_advise("MBANDEDWG", "Setting velocity curve to all 1's."); theVeloc = new Ooscili(SR, 1.0/p[1], velarray, 2); } } freq = p[3]; strikepos = p[4]; pluck = p[5]; maxvelocity = p[6]; preset = int(p[7]); bowpress = p[8]; modereson = p[9]; integrate = p[10]; pctleft = n_args > 11 ? p[11] : 0.5; /* default is .5 */ return nSamps(); }
void IINOISE::initamp(float dur, double p[], int ampindex, int ampgenslot) { fastUpdate = Option::fastUpdate(); if (fastUpdate) { // Prefer PField table, otherwise makegen int tablen = 0; amptable = (double *) getPFieldTable(ampindex, &tablen); if (amptable) ampmult = 1.0f; else { ampmult = p[ampindex]; amptable = floc(ampgenslot); if (amptable) tablen = fsize(ampgenslot); } if (amptable) tableset(SR, dur, tablen, amptabs); else amp = ampmult; } else { // NB: ampmult never used, first amp set in doupdate amptable = floc(ampgenslot); if (amptable) { int tablen = fsize(ampgenslot); tableset(SR, dur, tablen, amptabs); } } }
int FMINST::init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float dur = p[1]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("FMINST", "Can't handle more than 2 output channels."); carfreqraw = p[3]; if (carfreqraw < 15.0) carfreq = cpspch(carfreqraw); else carfreq = carfreqraw; modfreqraw = p[4]; if (modfreqraw < 15.0) modfreq = cpspch(modfreqraw); else modfreq = modfreqraw; double *wavetable = NULL; int tablelen = 0; if (n_args > 8) { // handle table coming in as optional p8 TablePField wavetable = (double *) getPFieldTable(8, &tablelen); } if (wavetable == NULL) { wavetable = floc(WAVET_GEN_SLOT); if (wavetable == NULL) return die("FMINST", "Either use the wavetable pfield (p8) or make " "an old-style gen function in slot %d.", WAVET_GEN_SLOT); tablelen = fsize(WAVET_GEN_SLOT); } carosc = new Ooscili(SR, carfreq, wavetable, tablelen); modosc = new Ooscili(SR, modfreq, wavetable, tablelen); if (n_args < 10) { // no p9 guide PField, must use gen table indexenv = floc(INDEX_GEN_SLOT); if (indexenv == NULL) return die("FMINST", "Either use the index guide pfield (p9) or make " "an old-style gen function in slot %d.", INDEX_GEN_SLOT); int len = fsize(INDEX_GEN_SLOT); tableset(SR, dur, len, indtabs); } initamp(dur, p, 2, 1); if (fastUpdate) { minindex = p[5]; indexdiff = p[6] - minindex; pan = p[7]; } return nSamps(); }
int BEND1::init(double p[], int n_args) { // p0 = start; p1 = dur; p2 = pitch0 (oct.pc); p3 = pitch1 (oct.pc) // p4 = gliss function #; p5 = fundamental decay time // p6 = nyquist decay time; p7 = distortion gain; p8 = feedback gain // p9 = feedback pitch (oct.pc); p10 = clean signal level // p11 = distortion signal level; p12 = amp; p13 = update gliss nsamples // p14 = stereo spread [optional] float dur = p[1]; if (rtsetoutput(p[0], dur, this) == -1) return DONT_SCHEDULE; strumq1 = curstrumq[0]; freq0 = cpspch(p[2]); diff = cpspch(p[3]) - freq0; tf0 = p[5]; tfN = p[6]; sset(SR, freq0, tf0, tfN, strumq1); dq = curdelayq; delayset(SR, cpspch(p[9]), dq); amp = p[12]; amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } else { rtcmix_advise("BEND1", "Setting phrase curve to all 1's."); aamp = amp; } glissf = floc((int)p[4]); if (glissf) { int leng = fsize((int)p[4]); tableset(SR, p[1],leng,tags); } else return die("BEND1", "You haven't made the glissando function (table %d).", (int)p[4]); dgain = p[7]; fbgain = p[8]/dgain; cleanlevel = p[10]; distlevel = p[11]; reset = (int)p[13]; if (reset == 0) reset = 100; spread = p[14]; d = 0.0; return nSamps(); }
int SFLUTE::init(double p[], int n_args) { // p0 = start; p1 = dur; p2 = noise amp; p3 = length1; p4 = length2 // p5 = amp multiplier; p6 = stereo spread (0-1) <optional> // function slot 1 is the noise amp envelope // function slot 2 is the out amp envelope if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; dampcoef = .7; amparr = floc(1); if (amparr) { int len = fsize(1); tableset(SR, p[1], len, amptabs); } else return die("SFLUTE", "You haven't made the noise amp envelope (table 1)."); oamparr = floc(2); if (oamparr) { int len = fsize(2); tableset(SR, p[1], len, oamptabs); } else return die("SFLUTE", "You haven't made the output amp envelope (table 2)."); int imax = DELSIZE; mdelset(SR, del1,dl1,imax); mdelset(SR, del2,dl2,imax); dl1ptr = dl1; dl2ptr = dl2; del1ptr = del1; del2ptr = del2; // srrand(0.1); length1 = (int)p[3]; length2 = (int)p[4]; olength1 = length1; olength2 = length2; oldsig = 0; /* for the filter */ amp = p[5]; namp = p[2]; spread = p[6]; skip = (int)(SR/(float)resetval); aamp = oamp = 0.0; return nSamps(); }
int CLAR::init(double p[], int n_args) { // p0 = start; p1 = dur; p2 = noise amp; p3 = length1; p4 = length2 // p5 = output amp; p6 = d2 gain; p7 = stereo spread (0-1) <optional> // function slot 1 is the noise amp envelope // function slot 2 is the output amp envelope int imax; if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; dampcoef = .7; amparr = floc(1); if (amparr) { int lenamp = fsize(1); tableset(SR, p[1], lenamp, amptabs); } else rtcmix_advise("CLAR", "Setting noise amp curve to all 1's."); oamparr = floc(2); if (oamparr) { int olenamp = fsize(2); tableset(SR, p[1], olenamp, oamptabs); } else rtcmix_advise("CLAR", "Setting output amp curve to all 1's."); imax = DELSIZE; mdelset(SR, del1,dl1,imax); mdelset(SR, del2,dl2,imax); // srrand(0.1); length1 = (int)p[3]; length2 = (int)p[4]; oldsig = 0; /* for the filter */ amp = p[5]; namp = p[2]; d2gain = p[6]; spread = p[7]; skip = (int)(SR/(float)resetval); aamp = oamp = 1.0; /* in case amparr or oamparr are NULL */ return nSamps(); }
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(); }
/* Make a copy of the gen whose table number is given in p1. Assign the copy the table number given in p0. The copied table will have the size given in p2. p3 is a number specifying the type of interpolation to use when resampling the source table to fit the new number of locations. Return the size of the new table. p0 table number of new table p1 table number of original table p2 size of new table [optional, default is size of original] p3 interpolation type (0: no interpolation, 1: linear interpolation) [optional, default is 1] */ double m_copygen(float p[], int n_args, double pp[]) { int srcslot, destslot, srcsize, destsize; double *srctable, *desttable; InterpolationType interp; destslot = (int) p[0]; srcslot = (int) p[1]; srctable = floc(srcslot); if (srctable == NULL) return die("copygen", "No function table defined for slot %d.", srcslot); srcsize = fsize(srcslot); destsize = (n_args > 2) ? (int) p[2] : srcsize; interp = (n_args > 3) ? (InterpolationType) p[3] : LINEAR_INTERP; desttable = resample_gen(srctable, srcsize, destsize, interp); if (desttable == NULL) return die("copygen", "No memory to copy the gen in slot %d.", srcslot); if (!install_gen(destslot, destsize, desttable)) return die("copygen", "No more function tables available."); return (double) destsize; }
/* Send the contents of a makegen array to standard out or to an ASCII file. fdump(gennum [, "filename"]) JGG, 2/13/02 */ double fdump(float p[], short n_args, double pp[]) { int genslot; double *array; FILE *f = NULL; genslot = p[0]; if (n_args > 1) { char *fname = DOUBLE_TO_STRING(pp[1]); f = fopen(fname, "w+"); if (f == NULL) { perror("fdump"); return -1.0; } } else f = stdout; array = floc(genslot); if (array) { int i, len = fsize(genslot); printf("Dumping function table %d...\n", genslot); for (i = 0; i < len; i++) fprintf(f, "%d %.6f\n", i, array[i]); } else die(NULL, "You must make a gen before dumping it!"); if (f != stdout) fclose(f); return 0.0; }
int MBRASS :: init(double p[], int n_args) { nargs = n_args; Stk::setSampleRate(SR); if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; amptable = floc(1); if (amptable) // the amp array has been created using makegen theEnv = new Ooscili(SR, 1.0/p[1], 1); theHorn = new Brass(50.0); // 50 Hz is default lowest frequency freq = p[3]; theHorn->setFrequency(p[3]); theHorn->startBlowing(p[6], 0.0); slength = p[4]; theHorn->setSlide((int)p[4]); lipfilt = p[5]; theHorn->setLip(p[5]); pctleft = n_args > 7 ? p[7] : 0.5; /* default is .5 */ return nSamps(); }
int MBLOWHOLE :: init(double p[], int n_args) { nargs = n_args; Stk::setSampleRate(SR); if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; amptable = floc(1); if (amptable) // the amp array has been created using makegen theEnv = new Ooscili(SR, 1.0/p[1], 1); theClar = new BlowHole(50.0); // 50 Hz is lowest freq for now noiseamp = p[4]; theClar->setNoise(p[4]); stiff = p[6]; theClar->setReedStiffness(p[6]); tone = p[7]; theClar->setTonehole(p[7]); vent = p[8]; theClar->setVent(p[8]); freq = p[3]; theClar->noteOn(p[3], p[5]); pctleft = n_args > 9 ? p[9] : 0.5; /* default is .5 */ return nSamps(); }
int START::init(double p[], int n_args) { float outskip = p[0]; float dur = p[1]; float pitch = p[2]; float fdecay = p[3]; float nydecay = p[4]; float amp = p[5]; int squish = (int)p[6]; spread = p[7]; deleteflag = (int)p[8]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; strumq1 = new strumq; curstrumq[0] = strumq1; float freq = cpspch(pitch); sset(SR, freq, fdecay, nydecay, strumq1); randfill(amp, squish, strumq1); amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } else { rtcmix_advise("START", "Setting phrase curve to all 1's."); aamp = 1.0; } skip = (int)(SR / (float)resetval); return nSamps(); }
int MBOWED :: init(double p[], int n_args) { nargs = n_args; Stk::setSampleRate(SR); if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; amptable = floc(1); if (amptable) // the amp array has been created using makegen theEnv = new Ooscili(SR, 1.0/p[1], 1); theRand = new Orand(); if (n_args < 10) thePressure = new Ooscili(SR, 1.0/p[1], 2); if (n_args < 11) thePosition = new Ooscili(SR, 1.0/p[1], 3); viblo = p[4]; vibhi = p[5]; int vtablelen = 0; if (n_args > 11) // if vibrato waveform is p11 table-handle vibtable = (double *) getPFieldTable(11, &vtablelen); if (vibtable == NULL) { vibtable = floc(4); if (vibtable == NULL) return die("MBOWED", "no vibrato waveform in function slot 4 or p11"); vtablelen = fsize(4); } theVib = new Ooscili(SR, theRand->range(viblo, vibhi), vibtable, vtablelen); vibupdate = 0; freqbase = p[3] - (p[6] * p[3]); freqamp = 2.0 * (p[6] * p[3]); theBow = new Bowed(50.0); // 50 Hz is lowest freq for now theBow->noteOn(p[3], p[5]); pctleft = n_args > 7 ? p[7] : 0.5; /* default is .5 */ return nSamps(); }
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 PAN :: init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float inskip = p[1]; float dur = p[2]; inchan = n_args > 4 ? (int) p[4] : 0; // default is chan 0 if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (outputChannels() != 2) return die("PAN", "Output must be stereo."); if (inchan >= inputChannels()) return die("PAN", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); amparray = floc(1); if (amparray) { int lenamp = fsize(1); tableset(SR, dur, lenamp, amptabs); } if (n_args < 7) { // no p6 pan PField, must use gen table panarray = floc(2); if (panarray == NULL) return die("PAN", "Either use the pan pfield (p6) " "or make an old-style gen function in slot 2."); int len = fsize(2); tableset(SR, dur, len, pantabs); } skip = (int) (SR / (float) resetval); return nSamps(); }
inline TableL * make_table(int function_num, float dur, double SR) { TableL *table = NULL; double *tab = floc(function_num); if (tab) { int len = fsize(function_num); table = new TableL(SR, dur, tab, len); } return table; }
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 WAVETABLE::init(double p[], int n_args) { float outskip = p[0]; float dur = p[1]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("WAVETABLE", "Can't handle more than 2 output channels."); initamp(dur, p, 2, AMP_GEN_SLOT); freqraw = p[3]; float freq; if (freqraw < 15.0) freq = cpspch(freqraw); else freq = freqraw; spread = p[4]; wavetable = NULL; int tablelen = 0; if (n_args > 5) // handle table coming in as optional p5 TablePField wavetable = (double *) getPFieldTable(5, &tablelen); if (wavetable == NULL) { wavetable = floc(WAVET_GEN_SLOT); if (wavetable) tablelen = fsize(WAVET_GEN_SLOT); else { rtcmix_advise("WAVETABLE", "No 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)); } } if (tablelen > 32767) return die("WAVETABLE", "wavetable must have fewer than 32768 samples."); osc = new Ooscili(SR, freq, wavetable, tablelen); return nSamps(); }
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 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 MSITAR :: init(double p[], int n_args) { nargs = n_args; Stk::setSampleRate(SR); if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; amptable = floc(1); if (amptable) // the amp array has been created using makegen theEnv = new Ooscili(SR, 1.0/p[1], 1); theSitar = new Sitar(50.0); // 50 Hz is lowest freq for now freq = p[3]; theSitar->noteOn(p[3], p[4]); pctleft = n_args > 5 ? p[5] : 0.5; /* default is .5 */ return nSamps(); }
int NOISE :: init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float dur = p[1]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; amparray = floc(1); if (amparray) { int lenamp = fsize(1); tableset(SR, dur, lenamp, amptabs); } skip = (int) (SR / (float) resetval); return nSamps(); }
int REV :: init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; amp = p[3]; int rvbtype = (int) p[4]; float rvbtime = p[5]; inchan = (int) p[7]; if (rtsetoutput(outskip, dur + rvbtime, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR + 0.5); if (inchan >= inputChannels()) return die("REV", "You asked for channel %d of a %d-channel file", inchan, inputChannels()); switch (rvbtype) { case 1: reverb = new PRCRev(SR, rvbtime); break; case 2: reverb = new JCRev(SR, rvbtime); break; case 3: reverb = new NRev(SR, rvbtime); break; default: return die("REV", "Unknown reverb type %d.", rvbtype); } amparray = floc(1); if (amparray) { int lenamp = fsize(1); tableset(SR, dur, lenamp, amptabs); } return nSamps(); }
int MMODALBAR :: init(double p[], int n_args) { int i; nargs = n_args; Stk::setSampleRate(SR); if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; amptable = floc(1); if (amptable) // the amp array has been created using makegen theEnv = new Ooscili(SR, 1.0/p[1], 1); theBar = new ModalBar(); // create the excitation function -- I'm using the "marmstk1.raw" // file in perry/gary's stk as a very rough guide for this theRand = new Orand(); for (i = 0; i < 25; i++) excite[i] = theRand->rand() * (float)i/25.0; for (i = 25; i < 256; i++) excite[i] = theRand->rand() * ( (231.0 - (float)(i-25))/231.0 ); theFilt = new BiQuad(); theFilt->setResonance(p[4]*100.0, 1.0-p[4], true); for (i = 0; i < 256; i++) excite[i] = theFilt->tick(excite[i]); theBar->setPreset((int)p[6]); theBar->setStickHardness(p[4]); theBar->setStrikePosition(p[5]); freq = p[3]; // not sure if this normalizes the amplitude enough to compensate // for the filtering. oh well. theBar->noteOn(p[3], p[4]); // amplitude handled by p[2] in this one pctleft = n_args > 7 ? p[7] : 0.5; /* default is .5 */ return nSamps(); }
int COMBIT::init(double p[], int n_args) { float start = p[0]; float inskip = p[1]; float dur = p[2]; frequency = p[4]; rvbtime = p[5]; inchan = n_args > 6 ? (int) p[6] : 0; pctleft = n_args > 7 ? p[7] : 0.0; float ringdur = n_args > 8 ? p[8] : rvbtime; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; // no input if (inchan >= inputChannels()) return die("COMBIT", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); if (rtsetoutput(start, dur + ringdur, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR + 0.5); if (frequency <= 0.0) return die("COMBIT", "Invalid frequency value!"); float loopt = 1.0 / frequency; comb = new Ocombi(SR, loopt, loopt, rvbtime); if (comb->frequency() == 0.0) return die("COMBIT", "Failed to allocate comb memory!"); frequency = -1.0; // force update in run() amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur + rvbtime, amplen, tabs); } skip = (int) (SR / (float) resetval); return nSamps(); }
/* Shift the values of the gen whose table number is given in p0 by the number of array locations given in p1. Positive values shift to the right; negative values to the left. If a value is shifted off the end of the array in either direction, it reenters the other end of the array. Two examples: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] source table, size = 10 [7, 8, 9, 0, 1, 2, 3, 4, 5, 6] shift = 3 [3, 4, 5, 6, 7, 8, 9, 0, 1, 2] shift = -3 */ double m_shiftgen(float p[], int n_args, double pp[]) { int slot, size, shift, abs_shift; size_t movesize; double *srctable, *desttable; slot = (int) p[0]; srctable = floc(slot); if (srctable == NULL) return die("shiftgen", "No function table defined for slot %d.", slot); size = fsize(slot); shift = (int) p[1]; abs_shift = abs(shift); if (abs_shift == 0 || abs_shift == size) { advise("shiftgen", "Your shift of %d has no effect on the table!", shift); return (double) size; } if (abs_shift > size) return die("shiftgen", "You can't shift by more than the table size."); desttable = new_table(size); if (desttable == NULL) return die("shiftgen", "No memory for new function table."); if (!install_gen(slot, size, desttable)) return die("shiftgen", "No more function tables available."); movesize = (size_t) (size - abs_shift); /* doubles to shift */ if (shift > 0) { memcpy(desttable, srctable + movesize, (size_t) abs_shift * sizeof(double)); memcpy(desttable + abs_shift, srctable, movesize * sizeof(double)); } else { memcpy(desttable, srctable + abs_shift, movesize * sizeof(double)); memcpy(desttable + movesize, srctable, (size_t) abs_shift * sizeof(double)); } return (double) size; }
int DEL1::init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; float deltime = p[4]; inchan = n_args > 6 ? (int) p[6] : 0; float ringdur = n_args > 7 ? p[7] : deltime; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) return die("DEL1", "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("DEL1", "Output must be stereo."); if (deltime <= 0.0) return die("DEL1", "Illegal delay time (%g).", deltime); long delsamps = (long) (deltime * SR + 0.5); delay = new Odelayi(delsamps); if (delay->length() == 0) return die("DEL1", "Can't allocate delay line memory."); amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } skip = (int) (SR / (float) resetval); return nSamps(); }