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 DUMP::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("DUMP", "Output must be mono or stereo."); if (nargs > 3) table = (double *) getPFieldTable(3, &tablelen); skip = (int) (SR / (float) resetval); return nSamps(); }
int RVB::init(double p[], int n_args) { float outskip, inskip, rvb_time; outskip = p[0]; inskip = p[1]; m_dur = p[2]; if (m_dur < 0) /* "dur" represents timend */ m_dur = -m_dur - inskip; if (rtsetinput(inskip, this) == -1) { // no input return(DONT_SCHEDULE); } insamps = (int)(m_dur * SR); m_amp = p[3]; if (inputChannels() != 4) return die(name(), "Input must be 4-channel (2 sig+early refl, 2 reverb input)."); if (outputChannels() != 2) return die(name(), "Output must be stereo."); double Matrix[12][12]; /* Get results of Minc setup calls (space, mikes_on, mikes_off, matrix) */ if (get_rvb_setup_params(Dimensions, Matrix, &rvb_time) == -1) return die(name(), "You must call setup routine `space' first."); /* (perform some initialization that used to be in space.c) */ int meanLength = MFP_samps(SR, Dimensions); // mean delay length for reverb get_lengths(meanLength); /* sets up delay lengths */ set_gains(rvb_time); /* sets gains for filters */ set_random(); /* sets up random variation of delays */ set_allpass(); wire_matrix(Matrix); if (rtsetoutput(outskip, m_dur + rvb_time, this) == -1) return DONT_SCHEDULE; DBG1(printf("nsamps = %d\n", nSamps())); return nSamps(); }
int CRACKLE::init(double p[], int n_args) { nargs = n_args; const float outskip = p[0]; const float dur = p[1]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("CRACKLE", "Use mono or stereo output only."); x0 = rrand() * 0.1; x1 = 0; x2 = 0; x3 = 0; 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 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 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 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(); }
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(); }
int PFSCHED::init(double p[], int n_args) { // about ths RTBUFSAMPS+1 nonsense: // when a PFSCHED note finishes, it de-allocates the PFields associated // with it. This is generally not a problem (because the 'connected' // instrument/note drawing from the PField only needs the PField for // the duration specified in the PFSCHED note), but if the duration is // less than one RTBUFSAMP then the PFSCHED note will finish and deallocate // *before* the other instrument gets a chance to read through the // 'connected' PField. Instead of rewriting a huge amount of the PField // code to handle the ref counters, etc. I just make sure that the // PFSCHED note will last at least one buffer longer than the time // computed for the PField to be read. Almost no additional load // on the CPU, see the run() method below. if (rtsetoutput(p[0], p[1]+((double)(RTBUFSAMPS+1)/SR), this) == -1) return DONT_SCHEDULE; // if set_dq_flag is 1, then the dqflag of pfbusses[] will be set to // signal de-queuing at end of this duration/envelope if (n_args > 4) set_dq_flag = 1; else set_dq_flag = 0; pfbus = p[2]; if (pfbus_is_connected[pfbus] != 1) { rterror("PFSCHED", "pfbus %d not connected", pfbus); return DONT_SCHEDULE; } pfbusses[pfbus].drawflag = 0; // the 'connected' note will read when == 1 // pfbusses[pfbus].thepfield = &((*_pfields)[3]); // pfbusses[pfbus].thepfield = &(getPField(3)); // this is the PField to read PFSCHEDpfield = &(getPField(3)); // this is the PField to read // set the other fields in ::run in case multiple PFSCHEDs on one pfbus firsttime = 1; 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 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(); }
int DCBLOCK::init(double p[], int n_args) { const float outskip = p[0]; const float inskip = p[1]; const float dur = p[2]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (outputChannels() != inputChannels()) return die("DCBLOCK", "The number of input channels must be the same " "as the number of output channels."); _chans = inputChannels(); _blocker = new Odcblock * [_chans]; for (int i = 0; i < _chans; i++) _blocker[i] = new Odcblock(); return nSamps(); }
int LOOP::init(double p[], int n_args) { if (n_args < 7) return die("LOOP", "Usage: LOOP(start, inskip, dur, amp, trans, loopstart, looplen[, inchan, pan])"); const float outskip = p[0]; const float inskip = p[1]; float dur = p[2]; if (dur < 0.0) dur = -dur - inskip; _incr = getIncrement(p[4]); _inchan = (n_args > 7) ? (int) p[7] : 0; _usesPan = (n_args > 8); _pan = _usesPan ? p[8] : 0.5; if (calculateLoop(p) == -1) return DONT_SCHEDULE; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("LOOP", "Use mono or stereo output only."); if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (_inchan >= inputChannels()) return die("LOOP", "You asked for channel %d of a %d-channel input.", _inchan, inputChannels()); _position = inskip * SR; // Actual starting position in the input file _inOffset = 0; // Offset of first sample in _in array compared to _position. return nSamps(); }
int MMESH2D :: 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); theMesh = new Mesh2D((short)p[3], (short)p[4]); theMesh->setInputPosition(p[5], p[6]); theMesh->setDecay( 0.9 + (p[7]*0.1)); // from the Mesh2D code theMesh->noteOn(0.0, p[8]); dcblocker = new Odcblock(); pctleft = n_args > 9 ? p[9] : 0.5; /* default is .5 */ return nSamps(); }
/** * These pfields are standard for LUAINST instruments: * p0 = Lua instrument name (string, all others are doubles). * p1 = Output start time (outskip). * p2 = Input start time (inskip, must be zero if there is no input). * p3 = Duration. * p4 = Amplitude. * pN = User-defined optional parameters. */ virtual int init(double *parameters, int parameterCount) { state.name = strdup(DOUBLE_TO_STRING(parameters[0])); state.parameters = new double[parameterCount]; state.parameterCount = parameterCount; for (int parameterI = 0; parameterI < parameterCount; ++parameterI) { state.parameters[parameterI] = parameters[parameterI]; } if (rtsetoutput((float) parameters[1], (float) parameters[3], this) == -1) { return DONT_SCHEDULE; } if (parameters[2] != 0.0) { if (rtsetinput(parameters[1], this) == -1) { return DONT_SCHEDULE; } state.inputChannelCount = inputChannels(); } state.outputChannelCount = outputChannels(); return nSamps(); }
int REVMIX::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 (inskip == 0) return die("REVMIX", "Input start time must be greater than zero."); if (dur > inskip) { rtcmix_warn("REVMIX", "Duration must be greater than input start time. " "Adjusting..."); dur = inskip; } if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; // no input if (inchan >= inputChannels()) return die("REVMIX", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); amparray = floc(1); if (amparray) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } skip = (int) (SR / (float) resetval); return nSamps(); }
int DELAY::init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; float deltime = p[4]; float ringdur = p[6]; inchan = n_args > 7 ? (int) p[7] : 0; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; // no input if (inchan >= inputChannels()) return die("DELAY", "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 (deltime <= 0.0) return die("DELAY", "Invalid delay time (%g)", deltime); long defaultDelay = MAX(100L, long(deltime * SR + 0.5)); delay = new Odelayi(defaultDelay); // This is how we check for memory failure. if (delay->length() == 0) return die("DELAY", "Can't allocate delay line memory."); amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } return nSamps(); }
int GRANSYNTH::init(double p[], int n_args) { _nargs = n_args; if (_nargs < 11 || _nargs > 17) return die("GRANSYNTH", USAGE_MESSAGE); const double outskip = p[0]; const double dur = p[1]; const int seed = _nargs > 14 ? int(p[14]) : 0; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("GRANSYNTH", "You can have only mono or stereo output."); _stereoOut = (outputChannels() == 2); int length; double *table = (double *) getPFieldTable(3, &length); if (table == NULL) return die("GRANSYNTH", "You must create a table containing the " "oscillator waveform."); _stream = new SynthGrainStream(SR, table, length, outputChannels(), seed); table = (double *) getPFieldTable(4, &length); if (table == NULL) return die("GRANSYNTH", "You must create a table containing the grain " "envelope."); _stream->setGrainEnvelopeTable(table, length); if (_nargs > 12) { table = (double *) getPFieldTable(12, &length); if (table != NULL) _stream->setGrainTranspositionCollection(table, length); } return nSamps(); }
int TRANS3 :: init(double p[], int n_args) { nargs = n_args; if (nargs < 5) return die("TRANS3", "Usage: TRANS3(start, inskip, dur, amp, trans[, inchan, pan])"); const float outskip = p[0]; const float inskip = p[1]; float dur = p[2]; if (dur < 0.0) dur = -dur - inskip; inchan = (nargs > 5) ? (int) p[5] : 0; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) { return die("TRANS3", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); } // to trigger first read in run() inframe = RTBUFSAMPS; oneover_cpsoct10 = 1.0 / cpsoct(10.0); amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } return nSamps(); }
int WAVY::init(double p[], int n_args) { if (n_args < 9) return usage(); _nargs = n_args; const float outskip = p[0]; const float dur = p[1]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() < 1 || outputChannels() > 2) return die("WAVY", "Must have mono or stereo output only."); int wavelenA; double *wavetabA = (double *) getPFieldTable(6, &wavelenA); if (wavetabA == NULL) return die("WAVY", "p6 must be wavetable (use maketable)"); int wavelenB; double *wavetabB = (double *) getPFieldTable(7, &wavelenB); if (wavetabB == NULL) { wavetabB = wavetabA; wavelenB = wavelenA; } _oscilA = new Ooscil(SR, 440.0, wavetabA, wavelenA); _oscilB = new Ooscil(SR, 440.0, wavetabB, wavelenB); if (setExpression() != 0) return DONT_SCHEDULE; assert(_fp != NULL || _combiner != NULL); 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 StrumQueue; strumq1->ref(); 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 IINOISE::init(double p[], int n_args) { float outskip = p[0]; float dur = p[1]; pan = p[3]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; initamp(dur, p, 2, 1); float cf[MAXFILTER], bw[MAXFILTER], gain[MAXFILTER]; nresons = get_iir_filter_specs(cf, bw, gain); if (nresons == 0) die("IINOISE", "You must call setup() first to describe filters."); for (int i = 0; i < nresons; i++) { // NB: All the IIR insts used the RMS scale factor. resons[i] = new Oreson(SR, cf[i], bw[i], Oreson::kRMSResponse); resonamp[i] = gain[i]; } return nSamps(); }
int TRANS::init(double p[], int n_args) { nargs = n_args; if (nargs < 5) return die("TRANS", "Usage: TRANS(start, inskip, dur, amp, trans[, inchan, pan])"); const float outskip = p[0]; const float inskip = p[1]; float dur = p[2]; if (dur < 0.0) dur = -dur - inskip; inchan = (nargs > 5) ? (int) p[5] : 0; pctleft = (nargs > 6) ? p[6] : 0.5; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) { return die("TRANS", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); } // to trigger first read in run() inframe = RTBUFSAMPS; initamp(dur, p, 3, 1); oneover_cpsoct10 = 1.0 / cpsoct(10.0); if (fastUpdate) // no transp updates _increment = cpsoct(10.0 + octpch(p[4])) * oneover_cpsoct10; return nSamps(); }
int MCLAR :: 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 Clarinet(50.0); // 50 Hz is lowest freq for now noiseamp = p[4]; theClar->setNoise(p[4]); stiff = p[6]; theClar->setReedStiffness(p[6]); freq = p[3]; theClar->noteOn(p[3], p[5]); pctleft = n_args > 7 ? p[7] : 0.5; /* default is .5 */ return nSamps(); }
int WIGGLE::init(double p[], int n_args) { const float outskip = p[0]; const float dur = p[1]; depth_type = (n_args > 4) ? getDepthType(p[4]) : NoModOsc; filter_type = (n_args > 5) ? getFiltType(p[5]) : NoFilter; float ringdur; if (filter_type == NoFilter) { nfilts = 0; ringdur = 0.0f; } else { if (filter_type != LowPass && filter_type != HighPass) return die("WIGGLE", "Filter type (p5) must be 0, 1, or 2."); nfilts = (n_args > 6) ? int(p[6]) : 1; if (nfilts < 1 || nfilts > MAXFILTS) return die("WIGGLE", "Steepness (p6) must be an integer between 1 and %d.", MAXFILTS); if (n_args > 7) do_balance = bool(p[7]); if (do_balance) { balancer = new Balance(SR); balancer->setWindowSize(BALANCE_WINDOW_SIZE); } ringdur = 0.1f; } if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; if (outputChannels() < 1 || outputChannels() > 2) return die("WIGGLE", "Output must be mono or stereo."); for (int i = 0; i < nfilts; i++) filt[i] = new Butter(SR); double *array = floc(AMP_FUNC); if (array) { int len = fsize(AMP_FUNC); amp_table = new TableL(SR, dur, array, len); } int len; if (n_args > 8) carwave_array = (double *) getPFieldTable(8, &len); if (carwave_array == NULL) { carwave_array = floc(CAR_WAVE_FUNC); if (carwave_array == NULL) return die("WIGGLE", "Either use the carrier wavetable pfield (p8), " "or make an old-style gen function in slot %d.", CAR_WAVE_FUNC); len = fsize(CAR_WAVE_FUNC); } carrier = new OscilL(SR, 0.0, carwave_array, len); array = floc(CAR_GLISS_FUNC); if (array) { len = fsize(CAR_GLISS_FUNC); cargliss_table = new TableN(SR, dur, array, len); } if (depth_type != NoModOsc) { if (n_args > 9) modwave_array = (double *) getPFieldTable(9, &len); if (modwave_array == NULL) { modwave_array = floc(MOD_WAVE_FUNC); if (modwave_array == NULL) return die("WIGGLE", "Either use the modulator wavetable pfield " "(p9), or make an old-style gen function " "in slot %d.", MOD_WAVE_FUNC); len = fsize(MOD_WAVE_FUNC); } modulator = new OscilL(SR, 0.0, modwave_array, len); array = floc(MOD_FREQ_FUNC); if (array) { len = fsize(MOD_FREQ_FUNC); modfreq_table = new TableL(SR, dur, array, len); } else if (n_args < 11) // no p10 mod freq return die("WIGGLE", "Either use the modulator frequency pfield " "(p10), or make an old-style gen function in " "slot %d.", MOD_FREQ_FUNC); array = floc(MOD_DEPTH_FUNC); if (array) { len = fsize(MOD_DEPTH_FUNC); moddepth_table = new TableL(SR, dur, array, len); } else if (n_args < 12) // no p11 mod depth return die("WIGGLE", "Either use the modulator depth pfield " "(p11), or make an old-style gen function in " "slot %d.", MOD_DEPTH_FUNC); } if (filter_type != NoFilter) { array = floc(FILTER_CF_FUNC); if (array) { len = fsize(FILTER_CF_FUNC); filtcf_table = new TableL(SR, dur, array, len); } else if (n_args < 13) // no p12 filter cf return die("WIGGLE", "Either use the filter cutoff frequency pfield " "(p12), or make an old-style gen function in " "slot %d.", FILTER_CF_FUNC); } if (outputChannels() == 2) { array = floc(PAN_FUNC); if (array) { len = fsize(PAN_FUNC); pan_table = new TableL(SR, dur, array, len); } else if (n_args < 14) // no p13 pan return die("WIGGLE", "Either use the pan pfield (p13), or make an " "old-style gen function in slot %d.", PAN_FUNC); } cpsoct10 = cpsoct(10.0); return nSamps(); }
int SHAPE :: init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float inskip = p[1]; float dur = p[2]; amp = p[3]; min_index = p[4]; max_index = p[5]; int ampnorm_genno = (int) p[6]; inchan = n_args > 7 ? (int) p[7] : 0; /* default is chan 0 */ if (n_args < 7) return die("SHAPE", "Needs at least 7 arguments."); if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) return die("SHAPE", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); if (max_index < min_index) return die("SHAPE", "Max. distortion index must not be less than min. index."); double *function = floc(1); if (function) { int len = fsize(1); amp_table = new TableL(SR, dur, function, len); } function = NULL; int tablelen = 0; if (n_args > 9) { // handle table coming in as optional p9 TablePField function = (double *) getPFieldTable(9, &tablelen); } if (function == NULL) { function = floc(2); if (function == NULL) return die("SHAPE", "Either use the transfer function pfield (p9) " "or make an old-style gen function in slot 2."); tablelen = fsize(2); } shaper = new WavShape(); shaper->setTransferFunc(function, tablelen); function = NULL; if (n_args < 11) { // no p10 guide PField, must use gen table function = floc(3); if (function) { int len = fsize(3); index_table = new TableL(SR, dur, function, len); } else rtcmix_advise("SHAPE", "Setting distortion index curve to all 1's."); } /* Construct the <ampnorm> WavShape object if (1) p6 is a TablePField, or (2) if p6 is non-zero, in which case use p6 as the gen slot for the amp norm function. If p6 is zero, then don't construct <ampnorm>. */ function = NULL; const PField &field = getPField(6); tablelen = field.values(); function = (double *) field; if (function == NULL) { // no table pfield if (ampnorm_genno > 0) { function = floc(ampnorm_genno); if (function == NULL) return die("SHAPE", "You specified table %d as the amplitude " "normalization function, but you didn't create the table.", ampnorm_genno); tablelen = fsize(ampnorm_genno); } } if (function) { ampnorm = new WavShape(); ampnorm->setTransferFunc(function, tablelen); } dcblocker = new DCBlock(); skip = (int) (SR / (float) resetval); return nSamps(); }
int TRANSBEND :: init(double p[], int n_args) { float outskip, inskip, dur, transp, interval = 0, total_indur, dur_to_read; float averageInc; int pgen; if (n_args < 5) { die("TRANSBEND", "Wrong number of args."); return(DONT_SCHEDULE); } outskip = p[0]; inskip = p[1]; dur = p[2]; amp = p[3]; pgen = (int) p[4]; inchan = (n_args > 5) ? (int) p[5] : 0; pctleft = (n_args > 6) ? p[6] : 0.5; if (dur < 0.0) dur = -dur - inskip; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (inchan >= inputChannels()) { return die("TRANSBEND", "You asked for channel %d of a %d-channel file.", inchan, inputChannels()); } pitchtable = floc(pgen); if (pitchtable) { int plen = fsize(pgen); float isum = 0; for (int loc = 0; loc < plen; loc++) { float pch = pitchtable[loc]; isum += octpch(pch); } interval = isum / plen; #ifdef DEBUG printf("average interval: %g\n", interval); #endif tableset(SR, dur, plen, ptabs); } else { die("TRANSBEND", "Unable to load pitch curve (table %d)!", pgen); return(DONT_SCHEDULE); } averageInc = (double) cpsoct(10.0 + interval) / cpsoct(10.0); #ifdef NOTYET total_indur = (float) m_DUR(NULL, 0); dur_to_read = dur * averageInc; if (inskip + dur_to_read > total_indur) { warn("TRANSBEND", "This note will read off the end of the input file.\n" "You might not get the envelope decay you " "expect from setline.\nReduce output duration."); /* no exit() */ } #endif /* total number of frames to read during life of inst */ in_frames_left = (int) (nSamps() * averageInc + 0.5); /* to trigger first read in run() */ inframe = RTBUFSAMPS; amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, tabs); } else rtcmix_advise("TRANSBEND", "Setting phrase curve to all 1's."); skip = (int) (SR / (float) resetval); return nSamps(); }
int FREEVERB :: init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; roomsize = p[4]; predelay_time = p[5]; ringdur = p[6]; damp = p[7]; dry = p[8]; wet = p[9]; width = p[10]; // Keep reverb comb feedback <= 1.0 max_roomsize = (1.0 - offsetroom) / scaleroom; if (roomsize < 0.0) return die("FREEVERB", "Room size must be between 0 and %g.", max_roomsize); if (roomsize > max_roomsize) { roomsize = max_roomsize; rtcmix_advise("FREEVERB", "Room size cannot be greater than %g. Adjusting...", max_roomsize); } int predelay_samps = (int) ((predelay_time * SR) + 0.5); if (predelay_samps > max_predelay_samps) return die("FREEVERB", "Pre-delay must be between 0 and %g seconds.", (float) max_predelay_samps / SR); if (damp < 0.0 || damp > 100.0) return die("FREEVERB", "Damp must be between 0 and 100%%."); if (dry < 0.0 || dry > 100.0) return die("FREEVERB", "Dry signal level must be between 0 and 100%%."); if (wet < 0.0 || wet > 100.0) return die("FREEVERB", "Wet signal level must be between 0 and 100%%."); if (width < 0.0 || width > 100.0) return die("FREEVERB", "Width must be between 0 and 100%%."); if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; insamps = (int) (dur * SR); if (inputChannels() > 2) return die("FREEVERB", "Can't have more than 2 input channels."); if (outputChannels() > 2) return die("FREEVERB", "Can't have more than 2 output channels."); rvb = new revmodel(); rvb->setroomsize(roomsize); rvb->setpredelay(predelay_samps); rvb->setdamp(damp * 0.01); rvb->setdry(dry * 0.01); rvb->setwet(wet * 0.01); rvb->setwidth(width * 0.01); amparray = floc(1); if (amparray) { int lenamp = fsize(1); tableset(SR, dur, lenamp, amptabs); } return nSamps(); }
/* ----------------------------------------------------------------- init --- */ int MROOM::init(double p[], int n_args) { float outskip = p[0]; float inskip = p[1]; float dur = p[2]; ovamp = p[3]; xdim = p[4]; ydim = p[5]; float rvbtime = p[6]; reflect = p[7]; innerwidth = p[8]; inchan = n_args > 9 ? (int)p[9] : AVERAGE_CHANS; int quant = n_args > 10 ? (int)p[10] : DEFAULT_QUANTIZATION; if (outputchans != 2) return die("MROOM", "Requires stereo output."); float ringdur = (rvbtime > MAX_DELAY) ? rvbtime : MAX_DELAY; if (rtsetoutput(outskip, dur + ringdur, this) == -1) return DONT_SCHEDULE; if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; insamps = (int)(dur * SR + 0.5); if (inchan >= inputChannels()) return die("MROOM", "You asked for channel %d of a %d-channel input file.", inchan, inputChannels()); if (inputChannels() == 1) inchan = 0; // ***FIXME: input validation for trajectory points? int ntimes = get_timeset(timepts, xvals, yvals); if (ntimes == 0) return die("MROOM", "Must have at least two timeset calls before MROOM."); traject(ntimes); tableset(SR, dur, POS_ARRAY_SIZE, xpostabs); tableset(SR, dur, POS_ARRAY_SIZE, ypostabs); int delsamps = (int)(MAX_DELAY * SR + 0.5); delayline = new float[delsamps]; delset(SR, delayline, deltabs, MAX_DELAY); /* Array dimensions taken from lib/rvbset.c (+ 2 extra for caution). */ int rvbsamps = (int)((0.1583 * SR) + 18 + 2); rvbarrayl = new float[rvbsamps]; rvbarrayr = new float[rvbsamps]; rvbset(SR, rvbtime, 0, rvbarrayl); rvbset(SR, rvbtime, 0, rvbarrayr); amparray = floc(1); if (amparray) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } else rtcmix_advise("MROOM", "Setting phrase curve to all 1's."); aamp = ovamp; /* in case amparray == NULL */ skip = (int)(SR / (float)resetval); quantskip = (int)(SR / (float)quant); return nSamps(); }