コード例 #1
0
ファイル: STEREO.cpp プロジェクト: RTcmix/RTcmix
int STEREO::init(double p[], int n_args)
{
	nargs = n_args;
	outslots = n_args - MATRIX_PFIELD_OFFSET;
	const float outskip = p[0];
	const float inskip = p[1];
	float dur = p[2];
	if (dur < 0.0)
		dur = -dur - inskip;

	if (n_args <= MATRIX_PFIELD_OFFSET)
		return die("STEREO", "You need at least one channel assignment.");

	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
	if (rtsetinput(inskip, this) == -1)
		return DONT_SCHEDULE;	// no input

	if (outputChannels() != 2)
		return die("STEREO", "Output must be stereo.");

	initamp(dur, p, 3, 1);
	if (fastUpdate)
		updatePans(p);

	return nSamps();
}
コード例 #2
0
ファイル: WAVETABLE.cpp プロジェクト: eriser/RTcmix-1
int WAVETABLE::run()
{
    const int nframes = framesToRun();
    for (int i = 0; i < nframes; i++) {
        if (--branch <= 0) {
            if (fastUpdate) {
                if (amptable)
                    amp = ampmult * tablei(currentFrame(), amptable, amptabs);
            }
            else
                doupdate();
            branch = getSkip();
        }

        float out[2];
        out[0] = osc->next() * amp;

        if (outputChannels() == 2) {
            out[1] = (1.0 - spread) * out[0];
            out[0] *= spread;
        }

        rtaddout(out);
        increment();
    }
    return framesToRun();
}
コード例 #3
0
ファイル: GRANSYNTH.cpp プロジェクト: eriser/rtcmix-android
int GRANSYNTH::run()
{
   const int frames = framesToRun();
   const int outchans = outputChannels();
   int i;
   for (i = 0; i < frames; i++) {
      if (--_branch <= 0) {
         doupdate();
         _branch = getSkip();
      }

      _stream->prepare();

      float out[outchans];
      if (outchans == 2) {
         out[0] = _stream->lastL() * _amp;
         out[1] = _stream->lastR() * _amp;
      }
      else
         out[0] = _stream->lastL() * _amp;

      rtaddout(out);
      increment();
   }

   return i;
}
コード例 #4
0
ファイル: WAVESHAPE.cpp プロジェクト: RTcmix/RTcmix
int WAVESHAPE::run()
{
	for (int i = 0; i < framesToRun(); i++) {
		if (--branch <= 0) {
			doupdate();
			branch = skip;
		}

		float sig = osc->next();
		float wsig = wshape(sig * index, xferfunc, lenxfer);

		// dc blocking filter
		float osig = a1 * z1;
		z1 = b1 * z1 + wsig;
		osig += a0 * z1;

		float out[2];
		out[0] = osig * amp;

		if (outputChannels() == 2) {
			out[1] = (1.0 - spread) * out[0];
			out[0] *= spread;
		}

		rtaddout(out);
		increment();
	}
	return framesToRun();
}
コード例 #5
0
ファイル: MMESH2D.cpp プロジェクト: CreativeInquiry/RTcmix
int MMESH2D :: run()
{
	int   i;
	float out[2];

	for (i = 0; i < framesToRun(); i++) {
		if (--branch <= 0) {
			double p[10];
			update (p, 10, kAmp | kPan);

			amp = p[2];
			if (amptable)
				amp *= theEnv->next(currentFrame());

			branch = getSkip();
		}

		out[0] = dcblocker->next(theMesh->tick()) * amp;

		if (outputChannels() == 2) {
			out[1] = out[0] * (1.0 - pctleft);
			out[0] *= pctleft;
		}

		rtaddout(out);
		increment();
	}

	return framesToRun();
}
コード例 #6
0
int MBOWED :: run()
{
    int   i;
    float out[2];

    for (i = 0; i < framesToRun(); i++) {
        if (--branch <= 0) {
            doupdate();
            branch = getSkip();
        }
        if (--vibupdate < 0) { // reset the vibrato freq after each cycle
            float vibfreq = theRand->range(viblo, vibhi);
            theVib->setfreq(vibfreq);
            vibupdate = (int)(SR/vibfreq);
        }

        out[0] = theBow->tick(bowvel) * amp;
        theBow->setFrequency(freqbase + (freqamp * ( (theVib->next()+2.0) * 0.5 )));

        if (outputChannels() == 2) {
            out[1] = out[0] * (1.0 - pctleft);
            out[0] *= pctleft;
        }

        rtaddout(out);
        increment();
    }

    return framesToRun();
}
コード例 #7
0
ファイル: FREEVERB.cpp プロジェクト: CreativeInquiry/RTcmix
int FREEVERB :: run()
{
   float *inL, *inR, *outL, *outR;

   inL = in;
   inR = inputChannels() > 1 ? in + 1 : in;
   outL = outbuf;
   outR = outputChannels() > 1 ? outbuf + 1 : outbuf;

   int samps = framesToRun() * inputChannels();

   if (currentFrame() < insamps)
      rtgetin(in, this, samps);

   // Scale input signal by amplitude multiplier and setline curve.
   for (int i = 0; i < samps; i += inputChannels()) {
      if (--branch <= 0) {
         double p[11];
         update(p, 11, kRoomSize | kPreDelay | kDamp | kDry | kWet | kWidth);
         if (currentFrame() < insamps) {  // amp is pre-effect
            amp = update(3, insamps);
            if (amparray)
               amp *= tablei(currentFrame(), amparray, amptabs);
         }
         updateRvb(p);
         branch = getSkip();
      }
      if (currentFrame() < insamps) {     // still taking input from file
         in[i] *= amp;
         if (inputChannels() == 2)
            in[i + 1] *= amp;
      }
      else {                              // in ringdown phase
         in[i] = 0.0;
         if (inputChannels() == 2)
            in[i + 1] = 0.0;
      }
      increment();
   }

   // Hand off to Freeverb to do the actual work.
   rvb->processreplace(inL, inR, outL, outR, framesToRun(), inputChannels(),
                                                         outputChannels());

   return framesToRun();
}
コード例 #8
0
ファイル: FMINST.cpp プロジェクト: RTcmix/RTcmix
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();
}
コード例 #9
0
ファイル: MYINST.cpp プロジェクト: CreativeInquiry/RTcmix
int MYINST::run()
{
	// framesToRun() gives the number of sample frames -- 1 sample for each
	// channel -- that we have to write during this scheduler time slice.

	const int samps = framesToRun() * inputChannels();

	// Read <samps> samples from the input file (or audio input device).

	rtgetin(_in, this, samps);

	// Each loop iteration processes 1 sample frame. */

	for (int i = 0; i < samps; i += inputChannels()) {

		// This block updates certain parameters at the control rate -- the
		// rate set by the user with the control_rate() or reset() script
		// functions.  The Instrument base class holds this value as a number
		// of sample frames to skip between updates.  Get this value using
		// getSkip() to reset the <_branch> counter.

		if (--_branch <= 0) {
			doupdate();
			_branch = getSkip();
		}

		// Grab the current input sample, scaled by the amplitude multiplier.

		float insig = _in[i + _inchan] * _amp;

		float out[2];		// Space for only 2 output chans!

		// Just copy it to the output array with no processing.

		out[0] = insig;

		// If we have stereo output, use the pan pfield.

		if (outputChannels() == 2) {
			out[1] = out[0] * (1.0f - _pan);
			out[0] *= _pan;
		}

		// Write this sample frame to the output buffer.

		rtaddout(out);

		// Increment the count of sample frames this instrument has written.

		increment();
	}

	// Return the number of frames we processed.

	return framesToRun();
}
コード例 #10
0
ファイル: MYINST.cpp プロジェクト: CreativeInquiry/RTcmix
int MYINST::init(double p[], int n_args)
{
	_nargs = n_args;		// store this for use in doupdate()

	// Store pfields in variables, to allow for easy pfield renumbering.
	// You should retain the RTcmix numbering convention for the first
	// 4 pfields: outskip, inskip, dur, amp; or, for instruments that 
	// take no input: outskip, dur, amp.

	const float outskip = p[0];
	const float inskip = p[1];
	const float dur = p[2];

	// Here's how to handle an optional pfield.

	_inchan = (n_args > 4) ? int(p[4]) : 0;			// default is chan 0

	// no need to retrieve amp or pan here, because these will be set 
	// before their first use inside of doupdate().

	// Tell scheduler when to start this inst.  If rtsetoutput returns -1 to
	// indicate an error, then return DONT_SCHEDULE.

	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;

	// Test whether the requested number of output channels is right for your
	// instrument.  The die function reports the error; the system decides
	// whether this should exit the program or keep going.

	if (outputChannels() > 2)
		return die("MYINST", "Use mono or stereo output only.");

	// Set file pointer on audio input.  If the input source is real-time or
	// an aux bus, then <inskip> must be zero.  The system will return an
	// an error in this case, which we must pass along.

	if (rtsetinput(inskip, this) == -1)
		return DONT_SCHEDULE;

	// Make sure requested input channel number is valid for this input source.
	// inputChannels() gives the total number of input channels, initialized
	// in rtsetinput.

	if (_inchan >= inputChannels())
		return die("MYINST", "You asked for channel %d of a %d-channel input.",
		                                             _inchan, inputChannels());

	// Return the number of sample frames that we'll write to output, which
	// the base class has already computed in response to our rtsetoutput call
	// above.  nSamps() equals the duration passed to rtsetoutput multiplied
	// by the sampling rate and then rounded to the nearest integer.

	return nSamps();
}
コード例 #11
0
ファイル: MULTEQ.cpp プロジェクト: eriser/rtcmix-android
int MULTEQ :: init(double p[], int n_args)
{
   nargs = n_args;
   const float ringdur = 0.1;
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR + 0.5);

   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;

   if (inputChannels() > MAXCHAN)
      return die("MULTEQ",
               "Input and output must have no more than %d channels.", MAXCHAN);
   if (outputChannels() != inputChannels())
      return die("MULTEQ", "Input and output must have same number of "
                           "channels, no more than %d.", MAXCHAN);

   if ((nargs - FIRST_BAND_PF) % BAND_PFS)
      return die("MULTEQ",
                 "For each band, need type, freq, Q, gain and bypass.");

   numbands = 0;
   int band = 0;
   for (int i = FIRST_BAND_PF; i < nargs; i += BAND_PFS, band += MAXCHAN) {
      if (numbands == MAXBAND) {
         warn("MULTEQ", "You can only have %d EQ bands.", MAXBAND);
         break;
      }

      OeqType type = getEQType(true, i);
      if (type == OeqInvalid)
         return die("MULTEQ", "Invalid EQ type string or code.");
      float freq = p[i + 1];
      float Q = p[i + 2];
      float gain = p[i + 3];
      bool bypass = (bool) p[i + 4];

      for (int c = 0; c < inputChannels(); c++) {
         eq[band + c] = new EQBand(SR, type, freq, Q, gain, bypass);
         if (eq[band + c] == NULL)
            return die("MULTEQ", "Can't allocate EQ band.");
      }

      numbands++;
   }

   skip = (int) (SR / (float) resetval);

   return nSamps();
}
コード例 #12
0
ファイル: BROWN.cpp プロジェクト: RTcmix/RTcmix
int BROWN::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("BROWN", "Use mono or stereo output only.");
	return nSamps();
}
コード例 #13
0
ファイル: PINK.cpp プロジェクト: RTcmix/RTcmix
int PINK::init(double p[], int n_args)
{
	_nargs = n_args;		// store this for use in doupdate()

	const float outskip = p[0];
	const float dur = p[1];
	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() > 2)
		return die("PINK", "Use mono or stereo output only.");

	return nSamps();
}
コード例 #14
0
ファイル: HOLO.cpp プロジェクト: eriser/RTcmix
int HOLO::init(double p[], int n_args)
{
    /* HOLO: stereo FIR filter to perform crosstalk cancellation
    *
    *  p0 = outsk
    *  p1 = insk
    *  p2 = dur
    *  p3 = amp
    *  p4 = xtalk amp mult
    *
    */

    int i, rvin;

    if (inputChannels() != 2) {
        return die("HOLO", "Input must be stereo.");
    }
    if (outputChannels() != 2) {
        return die("HOLO", "Output must be stereo.");
    }

    rvin = rtsetinput(p[1], this);
    if (rvin == -1) { // no input
        return(DONT_SCHEDULE);
    }
    rvin = rtsetoutput(p[0], p[2], this);
    if (rvin == -1) { // no output
        return(DONT_SCHEDULE);
    }

    ncoefs = nCoeffs;

    for (int n = 0; n < 2; n++) {
        pastsamps[n] = new float[ncoefs + 1];
        pastsamps2[n] = new float[ncoefs + 1];
        for (i = 0; i < ncoefs; i++) {
            pastsamps[n][i] = 0.0;
            pastsamps2[n][i] = 0.0;
        }
    }

    amp = p[3];

    xtalkAmp = (p[4] != 0.0) ? p[4] : 1.0;

    intap = 0;

    skip = (int)(SR / (float) resetval);

    return 0;
}
コード例 #15
0
ファイル: GRANSYNTH.cpp プロジェクト: RTcmix/RTcmix
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();
}
コード例 #16
0
ファイル: COMBIT.cpp プロジェクト: jwmatthys/RTcmix
int COMBIT::run()
{
	int samps = framesToRun() * inputChannels();

	if (currentFrame() < insamps)
		rtgetin(in, this, samps);

	for (int i = 0; i < samps; i += inputChannels())  {
		if (--branch <= 0) {
			double p[8];
			update(p, 8);
			amp = p[3];
			if (amptable) {
#ifdef EMBEDDED
				amp *= rtcmix_table(currentFrame(), amptable, tabs);
#else
				amp *= table(currentFrame(), amptable, tabs);
#endif
			}
			if (p[4] != frequency) {
				frequency = p[4];
				delsamps = (int) ((1.0 / frequency) * SR + 0.5);
			}
			if (p[5] != rvbtime) {
				rvbtime = p[5];
				comb->setReverbTime(rvbtime);
			}
			pctleft = p[7];
			branch = skip;
		}

		float insig, out[2];

		if (currentFrame() < insamps)
			insig = in[i + inchan];
		else
			insig = 0.0;
		out[0] = comb->next(insig, delsamps) * amp;
		if (outputChannels() == 2) {
			out[1] = out[0] * (1.0 - pctleft);
			out[0] *= pctleft;
		}

		rtaddout(out);
		increment();
	}

	return framesToRun();
}
コード例 #17
0
ファイル: WAVY.cpp プロジェクト: RTcmix/RTcmix
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();
}
コード例 #18
0
ファイル: WAVETABLE.cpp プロジェクト: eriser/RTcmix-1
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();
}
コード例 #19
0
ファイル: LSFLUTE.cpp プロジェクト: CreativeInquiry/RTcmix
int LSFLUTE::run()
{
	for (int i = 0; i < framesToRun(); i++) {
		if (olength1 < length1) olength1++;
		if (olength1 > length1) olength1--;
		if (olength2 < length2) olength2++;
		if (olength2 > length2) olength2--;
		if (--branch <= 0) {
			aamp = tablei(currentFrame(), amparr, amptabs);
			oamp = tablei(currentFrame(), oamparr, oamptabs);
			branch = skip;
		}

		float sig = (rrand() * namp * aamp) + aamp;
		float del1sig = mdelget(del1ptr,olength1,dl1ptr);
		sig = sig + (del1sig * -0.35);
#ifdef MAXMSP
		delput(sig,del2ptr,dl2ptr);
#else
		mdelput(sig,del2ptr,dl2ptr);
#endif

		sig = mdelget(del2ptr,olength2,dl2ptr);
		sig = (sig * sig * sig) - sig;
		sig = (0.4 * sig) + (0.9 * del1sig);

		float out[2];
		out[0] = sig * amp * oamp;
		sig = (dampcoef * sig) + ((1.0 - dampcoef) * oldsig);
		oldsig = sig;
#ifdef MAXMSP
		delput(sig,del1ptr,dl1ptr);
#else
		mdelput(sig,del1ptr,dl1ptr);
#endif

		if (outputChannels() == 2) {
			out[1] = (1.0 - spread) * out[0];
			out[0] *= spread;
		}

		rtaddout(out);
		increment();
	}
	return framesToRun();
}
コード例 #20
0
ファイル: WIGGLE.cpp プロジェクト: RTcmix/RTcmix
int WIGGLE::run()
{
   const int nframes = framesToRun();

   for (int i = 0; i < nframes; i++) {
      if (--branch <= 0) {
         doupdate();
         branch = getSkip();
      }

      float mod_sig = 0.0f;
      if (mod_depth != 0.0f) {
         if (depth_type == CarPercent)
            mod_sig = modulator->tick(mod_freq, mod_depth * car_freq);
         else {   // ModIndex
            float mdepth = mod_depth * mod_freq;  // convert mdepth to peak dev.
            mod_sig = modulator->tick(mod_freq, mdepth);
         }
      }
      float car_sig = carrier->tick(car_freq + mod_sig, amp);
#ifdef DEBUG2
      printf("carfreq=%f carsig=%f modsig=%f\n", car_freq, car_sig, mod_sig);
#endif

      float sig = car_sig;
      for (int j = 0; j < nfilts; j++)
         sig = filt[j]->tick(sig);

      if (do_balance)
         sig = balancer->tick(sig, car_sig);

      float out[2];
      if (outputChannels() == 2) {
         out[0] = sig * pan;
         out[1] = sig * (1.0f - pan);
      }
      else
         out[0] = sig;

      rtaddout(out);
      increment();
   }

   return nframes;
}
コード例 #21
0
ファイル: CONVOLVE1.cpp プロジェクト: CreativeInquiry/RTcmix
int CONVOLVE1::run()
{
	const int inchans = inputChannels();
	const int outchans = outputChannels();
	const int nframes = framesToRun();

	if (currentFrame() < _inframes) {
		const int insamps = nframes * inchans;
		rtgetin(_inbuf, this, insamps);
		for (int i = _inchan; i < insamps; i += inchans)
			_bucket->drop(_inbuf[i]);
	}
	else {
		for (int i = 0; i < nframes; i++)
			_bucket->drop(0.0f);
	}
	// If in last run invocation, make sure everything in bucket is processed.
	if (currentFrame() + nframes >= nSamps())
		_bucket->flush();

	float drypct = 1.0 - _wetpct;

	for (int i = 0; i < nframes; i++) {
		if (--_branch <= 0) {
			doupdate();
			drypct = 1.0 - _wetpct;
			_branch = getSkip();
		}

		float out[2];
		out[0] = (_wet[_outReadIndex] * _wetpct) + (_dry[_outReadIndex] * drypct);
		incrementOutReadIndex();
		out[0] *= _amp;

		if (outchans == 2) {
			out[1] = out[0] * (1.0 - _pan);
			out[0] *= _pan;
		}

		rtaddout(out);
		increment();
	}

	return framesToRun();
}
コード例 #22
0
// ---------------------------------------------------------------------- run --
int SPECTACLE2_BASE::run()
{
	const int nframes = framesToRun();
	const int inchans = inputChannels();
	const int outchans = outputChannels();

	// If still taking input, store framesToRun() frames into <_inbuf>.
	const bool input_avail = (currentFrame() < _input_frames);
	const int insamps = nframes * inchans;
	if (input_avail)
		rtgetin(_inbuf, this, insamps);

	for (int i = 0; i < nframes; i++) {
		if (--_branch <= 0) {
			doupdate();
			subupdate();
			_branch = getSkip();
		}

		float insig;
		if (input_avail)
			insig = _inbuf[(i * inchans) + _inchan] * _iamp;
		else
			insig = 0.0f;
		_bucket->drop(insig);	// may process <_decimation> input frames

		float outsig = _outbuf[_out_read_index] * _wet;
		increment_out_read_index();

		float drysig = _dry_delay->next(insig);
		outsig += drysig * _dry;

		float out[outchans];
		out[0] = outsig * _oamp;
		if (outchans == 2) {
			out[1] = out[0] * (1.0f - _pan);
			out[0] *= _pan;
		}

		rtaddout(out);
		increment();
	}

	return nframes;
}
コード例 #23
0
int CLAR::run()
{
	for (int i = 0; i < framesToRun(); i++) {
		if (--branch <= 0) {
			if (amparr) {
#ifdef MAXMSP
				aamp = rtcmix_table(currentFrame(), amparr, amptabs);
#else
				aamp = table(currentFrame(), amparr, amptabs);
#endif
			}
			if (oamparr)
				oamp = tablei(currentFrame(), oamparr, oamptabs);
			branch = skip;
		}

		float sig = (rrand() * namp * aamp) + aamp;
		float del1sig = mdelget(del1,length1,dl1);
		float del2sig = mdelget(del2,length2,dl2);
		if (del1sig > 1.0) del1sig = 1.0;
		if (del1sig < -1.0) del1sig = -1.0;
		if (del2sig > 1.0) del2sig = 1.0;
		if (del2sig < -1.0) del2sig = -1.0;
		sig = sig + 0.9 * ((d2gain * del2sig) + ((0.9-d2gain) * del1sig));
		float csig = -0.5 * sig + aamp;
		float ssig = sig * sig;
		sig = (0.3 * ssig) + (-0.8 * (sig * ssig));
		sig = sig + csig;
		sig = (0.7 * sig) + (0.3 * oldsig);
		oldsig = sig;
		delput(sig,del2,dl2);
		delput(sig,del1,dl1);

		float out[2];
		out[0] = sig * amp * oamp;
		if (outputChannels() == 2) {
			out[1] = (1.0 - spread) * out[0];
			out[0] *= spread;
		}

		rtaddout(out);
		increment();
	}
	return framesToRun();
}
コード例 #24
0
ファイル: ffi_rtinstrument.cpp プロジェクト: joambi/silencio
  /**
   * Allocates input and output buffers just before run() is called.
   */
  virtual int configure()
  {
    if (state.input) 
      {
	delete [] state.input;
	state.input = 0;
      }
    state.inputSampleCount = RTBUFSAMPS * inputChannels();
    state.input = new float[state.inputSampleCount];
    if (state.output) 
      {
	delete [] state.output;
	state.output = 0;
      }
    state.outputSampleCount = RTBUFSAMPS * outputChannels();
    state.output = new float[state.outputSampleCount];
    return 0;
  }
コード例 #25
0
ファイル: CHAIN.cpp プロジェクト: eriser/RTcmix-1
int CHAIN::run()
{
	for (std::vector<Instrument *>::iterator it = mInstVector.begin(); it != mInstVector.end(); ++it) {
		Instrument *inst = *it;
		if (!inst->isDone()) {
			inst->setchunk(framesToRun());	// For outer instrument, this is done in inTraverse()
			inst->run(true);
		}
		else {
			inst->clearOutput(framesToRun());			// This should be optimized to happen only once
		}
		inst->addout(BUS_NONE_OUT, 0);		// Special bus type makes this a no-op
	}
	// Copy from inputChainedBuf, which points to the outbuf of the last instrument in the chain.
	unsigned copySize = framesToRun() * outputChannels() * sizeof(BUFTYPE);
	memcpy(outbuf, inputChainBuf, copySize);
	return framesToRun();
}
コード例 #26
0
ファイル: PANECHO.cpp プロジェクト: RTcmix/RTcmix
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();
}
コード例 #27
0
ファイル: RVB.cpp プロジェクト: eriser/rtcmix-android
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() != 2)
		return die(name(), "Input must be stereo.");

	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);

	_skip = (int) (SR / (float) resetval);
	
	if (rtsetoutput(outskip, m_dur + rvb_time, this) == -1)
		return DONT_SCHEDULE;
	DBG1(printf("nsamps = %d\n", nSamps()));
	return nSamps();
}
コード例 #28
0
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();
}
コード例 #29
0
ファイル: MSITAR.cpp プロジェクト: eriser/rtcmix-android
int MSITAR :: run()
{
	int   i;
	float out[2];

	for (i = 0; i < framesToRun(); i++) {
		if (--branch <= 0) {
			double p[7];
			update(p, 7, kAmp | kFreq | kPan | kStramp);

			// "amp" is now separate from the internal string amp
			// string amp is controlled by makegen 1, or a table, or it is 1.0
			amp = p[2];
			if (amptable)
				stramp = theEnv->next(currentFrame());
			else if (nargs > 6)
				stramp = p[6];
			else 
				stramp = 1.0;

			if (freq != p[3]) {
				theSitar->setFrequency(p[3]);
				freq = p[3];
			}

			if (nargs > 5) pctleft = p[5];

			branch = getSkip();
		}

		out[0] = theSitar->tick(stramp) * amp;

		if (outputChannels() == 2) {
			out[1] = out[0] * (1.0 - pctleft);
			out[0] *= pctleft;
		}

		rtaddout(out);
		increment();
	}

	return framesToRun();
}
コード例 #30
0
ファイル: CRACKLE.cpp プロジェクト: jwmatthys/RTcmix
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();
}