int SPECTEQ2::subinit(double p[], int n_args) { int eqtablen; _eqtable = (double *) getPFieldTable(8, &eqtablen); if (!_eqtable) _eqconst = p[8]; else _control_table_size = eqtablen; int len; double *binmaptable = (double *) getPFieldTable(11, &len); if (binmaptable) { if (len != eqtablen) die(instname(), "The bin-mapping table (p11) must be the same size as " "the EQ table (p8)."); set_binmap_table(binmaptable); if (p[9] != 0.0 || (p[10] != 0.0 || p[10] != _nyquist)) warn(instname(), "Use of the bin-mapping table ignores the freq. " "range set in p9-10."); } set_ringdur(0.0f); return 0; }
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 MULTIWAVE::init(double p[], int n_args) { if (n_args < 8) return usage(); float outskip = p[0]; float dur = p[1]; nargs = n_args; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() < 1 || outputChannels() > 2) return die("MULTIWAVE", "Must have mono or stereo output only."); int wavelen; double *wavet = (double *) getPFieldTable(3, &wavelen); if (wavet == NULL) return die("MULTIWAVE", "p3 must be wavetable (use maketable)"); numpartials = (nargs - FIRST_FREQ_ARG) / 4; oscil = new Ooscili * [numpartials]; amp = new double [numpartials]; pan = new double [numpartials]; for (int i = 0; i < numpartials; i++) { oscil[i] = new Ooscili(SR, 440.0, wavet, wavelen); const int index = FIRST_FREQ_ARG + (4 * i); oscil[i]->setphase(p[index + 2] / 360.0); amp[i] = 0.0; pan[i] = 0.0; } return nSamps(); }
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 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 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 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 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(); }
// ---------------------------------------------------------------- configure -- int SPECTACLE2_BASE::configure() { _inbuf = new float [RTBUFSAMPS * inputChannels()]; _input = new float [_window_len]; // interior input buffer _output = new float [_window_len]; // interior output buffer _anal_bins = new float [_fftlen + 2]; // analysis bins if (_inbuf == NULL || _input == NULL || _output == NULL || _anal_bins == NULL) return -1; for (int i = 0; i < _window_len; i++) _input[i] = _output[i] = 0.0f; // Delay dry output by latency to sync with wet sig. _dry_delay = new Odelay(_window_len); _dry_delay->setdelay(_latency); // Read index chases write index by _decimation; add 2 extra locations to // keep read point from stepping on write point. Verify with asserts in // increment_out_*_index(). _outframes = _decimation + 2; _out_read_index = _outframes - _decimation; _out_write_index = 0; _outbuf = new float [_outframes]; if (_outbuf == NULL) return -1; for (int i = 0; i < _outframes; i++) _outbuf[i] = 0.0f; DPRINT1("_outframes: %d\n", _outframes); _bucket = new Obucket(_decimation, process_wrapper, (void *) this); _fft = new Offt(_fftlen); _fft_buf = _fft->getbuf(); _anal_window = new float [_window_len]; _synth_window = new float [_window_len]; if (_anal_window == NULL || _synth_window == NULL) return -1; int len; double *window = (double *) getPFieldTable(_window_pfield_index, &len); if (make_windows(window, len) != 0) return DONT_SCHEDULE; if (subconfigure() != 0) return -1; return 0; }
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 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 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 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 JGRAN :: init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float dur = p[1]; int seed = (int) p[3]; osctype = (p[4] == 0.0) ? AS : FM; randomize_phase = n_args > 5 ? (bool) p[5] : true; // default: yes if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("JGRAN", "Output must be mono or stereo."); amp_table = make_table(1, dur, SR); // get grain envelope table double *function = NULL; int tablelen = 0; if (n_args > 6) { // handle table coming in as optional p6 TablePField function = (double *) getPFieldTable(6, &tablelen); } if (function == NULL) { function = floc(2); if (function == NULL) return die("JGRAN", "Either use the grain envelope pfield (p6) " "or make an old-style gen function in slot 2."); tablelen = fsize(2); } grainenv_oscil = new OscilL(SR, 0.0, function, tablelen); // get grain waveform table and create oscillator(s) function = NULL; tablelen = 0; if (n_args > 7) { // handle table coming in as optional p7 TablePField function = (double *) getPFieldTable(7, &tablelen); } if (function == NULL) { function = floc(3); if (function == NULL) { tablelen = DEFAULT_WAVETABLE_SIZE; rtcmix_advise("JGRAN", "Using sine for grain waveform (no table 3)."); } else tablelen = fsize(3); } car_oscil = new OscilL(SR, 0.0, function, tablelen); if (osctype == FM) mod_oscil = new OscilL(SR, 0.0, function, tablelen); // create additional tables, if corresponding pfield is missing if (osctype == FM) { if (n_args <= 8) { modmult_table = make_table(4, dur, SR); if (modmult_table == NULL) return die("JGRAN", "Either use the modulation frequency " "multiplier pfield (p8) or make an old-style " "gen function in slot 4."); } if (n_args <= 9) { modindex_table = make_table(5, dur, SR); if (modindex_table == NULL) return die("JGRAN", "Either use the index envelope pfield (p9) " "or make an old-style gen function in slot 5."); } } if (n_args <= 10) { minfreq_table = make_table(6, dur, SR); if (minfreq_table == NULL) return die("JGRAN", "Either use the min. grain frequency pfield (p10) " "or make an old-style gen function in slot 6."); } if (n_args <= 11) { maxfreq_table = make_table(7, dur, SR); if (maxfreq_table == NULL) return die("JGRAN", "Either use the max. grain frequency pfield (p11) " "or make an old-style gen function in slot 7."); } if (n_args <= 12) { minspeed_table = make_table(8, dur, SR); if (minspeed_table == NULL) return die("JGRAN", "Either use the min. grain speed pfield (p12) " "or make an old-style gen function in slot 8."); } if (n_args <= 13) { maxspeed_table = make_table(9, dur, SR); if (maxspeed_table == NULL) return die("JGRAN", "Either use the max. grain speed pfield (p13) " "or make an old-style gen function in slot 9."); } if (n_args <= 14) { minintens_table = make_table(10, dur, SR); if (minintens_table == NULL) return die("JGRAN", "Either use the min. grain intensity pfield (p14) " "or make an old-style gen function in slot 10."); } if (n_args <= 15) { maxintens_table = make_table(11, dur, SR); if (maxintens_table == NULL) return die("JGRAN", "Either use the max. grain intensity pfield (p15) " "or make an old-style gen function in slot 11."); } if (n_args <= 16) { density_table = make_table(12, dur, SR); if (density_table == NULL) return die("JGRAN", "Either use the grain density pfield (p16) " "or make an old-style gen function in slot 12."); } if (outputChannels() == 2) { if (n_args <= 17) { pan_table = make_table(13, dur, SR); if (pan_table == NULL) return die("JGRAN", "Either use the pan pfield (p17) or make an " "old-style gen function in slot 13."); } if (n_args <= 18) { panvar_table = make_table(14, dur, SR); if (panvar_table == NULL) return die("JGRAN", "Either use the pan randomization pfield (p18) " "or make an old-style gen function in slot 14."); } } // seed multipliers straight from Piche/Bezkorowajny source durnoi = new JGNoise((unsigned int) seed * 243); freqnoi = new JGNoise((unsigned int) seed * 734); pannoi = new JGNoise((unsigned int) seed * 634); ampnoi = new JGNoise((unsigned int) seed * 824); if (randomize_phase) phasenoi = new JGNoise((unsigned int) seed * 951); krate = resetval; skip = (int) (SR / (float) krate); return nSamps(); }
int WAVESHAPE::init(double p[], int n_args) { nargs = n_args; float outskip = p[0]; float dur = p[1]; rawfreq = p[2]; doampnorm = n_args > 10 ? (bool) p[10] : true; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("WAVESHAPE", "Can't handle more than 2 output channels."); waveform = NULL; int tablelen = 0; if (n_args > 7) { // handle table coming in as optional p7 TablePField waveform = (double *) getPFieldTable(7, &tablelen); } if (waveform == NULL) { waveform = floc(WAVE_GEN_SLOT); if (waveform == NULL) return die("WAVESHAPE", "Either use the wavetable pfield (p7) or make " "an old-style gen function in slot %d.", WAVE_GEN_SLOT); tablelen = fsize(WAVE_GEN_SLOT); } float freq = rawfreq; if (rawfreq < 15.0) freq = cpspch(rawfreq); osc = new Ooscili(SR, freq, waveform, tablelen); xferfunc = NULL; lenxfer = 0; if (n_args > 8) { // handle table coming in as optional p8 TablePField xferfunc = (double *) getPFieldTable(8, &lenxfer); } if (xferfunc == NULL) { xferfunc = floc(XFER_GEN_SLOT); if (xferfunc == NULL) return die("WAVESHAPE", "Either use the transfer function pfield " "(p8) or make an old-style gen function in slot %d.", XFER_GEN_SLOT); lenxfer = fsize(XFER_GEN_SLOT); } indenv = NULL; if (n_args < 10) { // no p9 guide PField, so must use gen table indenv = floc(INDEX_GEN_SLOT); if (indenv == NULL) return die("WAVESHAPE", "Either use the index pfield (p9) or make " "an old-style gen function in slot %d.", INDEX_GEN_SLOT); lenind = fsize(INDEX_GEN_SLOT); tableset(SR, dur, lenind, indtabs); } ampenv = floc(AMP_GEN_SLOT); if (ampenv) { int lenamp = fsize(AMP_GEN_SLOT); tableset(SR, dur, lenamp, amptabs); } setDCBlocker(freq, true); // initialize dc blocking filter skip = (int) (SR / (float) resetval); return nSamps(); }
int SPECTACLE2::subinit(double p[], int n_args) { _eqtable = (double *) getPFieldTable(10, &_eqtablen); if (!_eqtable) _eqconst = p[10]; int deltimetablen; _deltimetable = (double *) getPFieldTable(11, &deltimetablen); if (!_deltimetable) _deltimeconst = p[11]; // read later in this function int feedbacktablen; _feedbacktable = (double *) getPFieldTable(12, &feedbacktablen); if (!_feedbacktable) _feedbackconst = p[12]; // Delay and feedback tables, if they exist, must be the same size. int cntltablen = 0; if (_deltimetable) cntltablen = deltimetablen; if (_feedbacktable) { cntltablen = feedbacktablen; if (_deltimetable && (feedbacktablen != deltimetablen)) return die(instname(), "Delay time and feedback tables must be the " "same size."); } _control_table_size = cntltablen; int binmaptablen; double *binmaptable = (double *) getPFieldTable(17, &binmaptablen); if (binmaptable) { if (binmaptablen != _eqtablen || binmaptablen != _control_table_size) die(instname(), "The bin-mapping table (p17) must be the same size as " "the EQ and delay tables (p10-12)."); set_binmap_table(binmaptable); if (p[13] != 0.0 || (p[14] != 0.0 || p[14] != _nyquist) || p[15] != 0.0 || (p[16] != 0.0 || p[16] != _nyquist)) rtcmix_warn(instname(), "Use of the bin-mapping table ignores the freq. " "ranges set in p13-16."); } // Init delay minfreq and maxfreq, so that bin groups will be ready for use // below. This calls update_bin_groups, which reads _control_table_size. set_freqrange(p[15], p[16]); // Compute maximum delay lag and create delay lines for FFT magnitude // and phase values. Make ringdur at least as long as the longest // delay time. Remember that these delays function at the decimation // rate, not at the audio rate, so the memory footprint is not as large // as you would expect -- about 44100 samples per second at fftlen=1024, // overlap=2 and SR=44100. // Set max delay time and bounds-check initial state of delay time array. // Also increase ringdur to accommodate longest delay time, if necessary. // Note that if user updates delay time table while running, values are // pinned to max delay time without notification. _maxdelsamps = long(kMaxDelayTime * SR / float(_decimation) + 0.5); float maxtime = 0.0f; float deltime = _deltimeconst; for (int i = 0; i <= _half_fftlen; i++) { if (_deltimetable) deltime = _deltimetable[_bin_groups[i]]; if (deltime < 0.0f || deltime > kMaxDelayTime) return die(instname(), "Delay times must be between 0 and %g seconds.", kMaxDelayTime); if (deltime > maxtime) maxtime = deltime; } float ringdur = p[5]; if (ringdur < maxtime) ringdur = maxtime; // but will still cut off any trailing feedback set_ringdur(ringdur); DPRINT3("decimation=%d, _maxdelsamps=%ld, ringdur=%g\n", _decimation, _maxdelsamps, ringdur); return 0; }
int VOCODE3::init(double p[], int n_args) { _nargs = n_args; if (_nargs < 11) return usage(); 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() > 2) return die("VOCODE3", "Output must be either mono or stereo."); if (inputChannels() != 2) return die("VOCODE3", "Must use 2 input channels: 'left' for carrier; 'right' for modulator."); _modtable_src = (double *) getPFieldTable(4, &_numfilts); if (_modtable_src == NULL) return die("VOCODE3", "p4 must have the modulator center freq. table."); int len; _cartable_src = (double *) getPFieldTable(5, &len); if (_cartable_src == NULL) return die("VOCODE3", "p5 must have the carrier center freq. table."); if (len != _numfilts) return die("VOCODE3", "Modulator and carrier center freq. tables must " "be the same size."); _modtable_prev = new double [_numfilts]; // these two arrays inited below _cartable_prev = new double [_numfilts]; _maptable_src = (double *) getPFieldTable(6, &len); if (_maptable_src && (len != _numfilts)) return die("VOCODE3", "Center freq. mapping table (p6) must be the same " "size as the modulator and carrier tables."); _maptable = new int [_numfilts]; if (_maptable_src) { for (int i = 0; i < _numfilts; i++) _maptable[i] = int(_maptable_src[i]); } else { // no user mapping table; make linear mapping for (int i = 0; i < _numfilts; i++) _maptable[i] = i; } _scaletable = (double *) getPFieldTable(7, &len); if (_scaletable && (len != _numfilts)) return die("VOCODE3", "The carrier scaling table must be the same size " "(%d elements) as the carrier frequency table.", _numfilts); _modtransp = p[8]; _cartransp = p[9]; _modq = p[10]; _carq = p[11]; _lastmod = new float [_numfilts]; _modulator_filt = new Oequalizer * [_numfilts]; _carrier_filt = new Oequalizer * [_numfilts]; _balancer = new Obalance * [_numfilts]; #ifdef NOTYET const bool print_stats = Option::printStats(); #else const bool print_stats = true; #endif if (print_stats) { rtcmix_advise(NULL, "VOCODE3: mod. CF\tcar. CF [Hz, after transp]"); rtcmix_advise(NULL, " (Q=%2.1f)\t(Q=%2.1f)", _modq, _carq); rtcmix_advise(NULL, " -----------------------------------------"); } for (int i = 0; i < _numfilts; i++) { _modulator_filt[i] = new Oequalizer(SR, kBandPassType); _modtable_prev[i] = _modtable_src[i]; float mfreq = updateFreq(_modtable_src[i], _modtransp); _modulator_filt[i]->setparams(mfreq, _modq); _carrier_filt[i] = new Oequalizer(SR, kBandPassType); _cartable_prev[i] = _cartable_src[i]; float cfreq = updateFreq(_cartable_src[i], _cartransp); _carrier_filt[i]->setparams(cfreq, _carq); _balancer[i] = new Obalance(SR); _lastmod[i] = 0.0f; // not necessary if (print_stats) rtcmix_advise(NULL, " %7.1f\t%7.1f", mfreq, cfreq); } 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 CONVOLVE1::init(double p[], int n_args) { const float outskip = p[0]; const float inskip = p[1]; const float indur = p[2]; const float impskip = p[5]; const float impdur = p[6]; if (impdur <= 0.0) return die("CONVOLVE1", "Impulse duration must be greater than zero."); _impgain = p[7]; _wetpct = p[9]; // NB: used before first call to doupdate if (_wetpct < 0.0 || _wetpct > 1.0) return die("CONVOLVE1", "Wet percent must be between 0 and 1."); _inchan = int(p[10]); // Read impulse response table, and set FFT size based on this. _imptab = (double *) getPFieldTable(4, &_imptablen); if (_imptab == NULL) return die("CONVOLVE1", "Must store impulse response in a table."); _impStartIndex = int(impskip * SR + 0.5); if (_impStartIndex >= _imptablen) return die("CONVOLVE1", "Impulse start time exceeds impulse duration."); int impend = _impStartIndex + int(impdur * SR + 0.5); // NOTE: <impend> may be past end of table; we handle that in prepareImpulse. DPRINT2("impend=%d, _imptablen=%d\n", impend, _imptablen); _impframes = impend - _impStartIndex; _halfFFTlen = kMinFFTsize / 2; for ( ; _halfFFTlen < kMaxImpulseFrames; _halfFFTlen *= 2) if (_halfFFTlen >= _impframes) break; _fftlen = 2 * _halfFFTlen; DPRINT2("_impframes=%d, _halfFFTlen=%d\n", _impframes, _halfFFTlen); rtcmix_advise("CONVOLVE1", "Using %d impulse response frames. FFT length is %d.", _impframes, _fftlen); if (rtsetinput(inskip, this) == -1) return DONT_SCHEDULE; // no input if (_inchan >= inputChannels()) return die("CONVOLVE1", "You asked for channel %d of a %d-channel input.", _inchan, inputChannels()); // Latency is the delay before the FFT looks at actual input rather than // zero-padding. Need to let inst run long enough to compensate for this. const float latency = float(_impframes) / SR; const float ringdur = latency; if (rtsetoutput(outskip, latency + indur + ringdur, this) == -1) return DONT_SCHEDULE; if (outputChannels() > 2) return die("CONVOLVE1", "Must have mono or stereo output."); _inframes = int(indur * SR + 0.5); // not including latency int winlen; double *wintab = (double *) getPFieldTable(8, &winlen); if (wintab) { if (winlen > 32767) // limit for new fixed-point Ooscili return die("CONVOLVE1", "Window table size must be less than 32768."); const float freq = 1.0 / ((float) _impframes / SR); _winosc = new Ooscili(SR, freq, wintab, winlen); } return nSamps(); }