Пример #1
0
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();
}
Пример #3
0
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();
}
Пример #4
0
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();
}
Пример #5
0
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();
}
Пример #6
0
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();
}
Пример #7
0
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();
}
Пример #8
0
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();
}
Пример #9
0
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();
}
Пример #10
0
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();
}
Пример #11
0
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();
}
Пример #12
0
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();
}
Пример #14
0
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();
}
Пример #15
0
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();
}
Пример #16
0
  /**
   * 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();
}
Пример #18
0
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();
}
Пример #19
0
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();
}
Пример #21
0
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();
}
Пример #24
0
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();
}
Пример #25
0
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();
}
Пример #26
0
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();
}
Пример #27
0
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();
}
Пример #28
0
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();
}
Пример #29
0
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();
}
Пример #30
0
/* ----------------------------------------------------------------- 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();
}