Пример #1
0
void lb302Synth::processNote( NotePlayHandle * _n )
{
		/// Start a new note.
		if( _n->m_pluginData != this ) 
		{
			m_playingNote = _n;
			new_freq = true;
			_n->m_pluginData = this;
		}
		
		if( ! m_playingNote && ! _n->isReleased() && release_frame > 0 )
		{
			m_playingNote = _n;
			if ( slideToggle.value() ) 
			{
				vco_slideinc = GET_INC( _n->frequency() );
			}
		}

		// Check for slide
		if( m_playingNote == _n ) 
		{
			true_freq = _n->frequency();

			if( slideToggle.value() ) {
				vco_slidebase = GET_INC( true_freq );			// The REAL frequency
			}
			else {
				vco_inc = GET_INC( true_freq );
			}
		}
}
Пример #2
0
void lb302Synth::playNote( notePlayHandle * _n, sampleFrame * _working_buffer )
{
	//fpp_t framesPerPeriod = engine::getMixer()->framesPerPeriod();

	if( _n->isArpeggioBaseNote() )
	{
		return;
	}

	// Currently have release/decay disabled
	// Start the release decay if this is the first release period.
	//if (_n->released() && catch_decay == 0)
	//        catch_decay = 1;

	bool decay_note = false;

	release_frame = _n->framesLeft() - desiredReleaseFrames();


	//LB303 if ( _n->totalFramesPlayed() <= 0 ) {
		// This code is obsolete, hence the "if false"

		// Existing note. Allow it to decay. 
		if(deadToggle.value() == 0 && decay_note) {

	/*		lb302Note note;
			note.vco_inc = _n->frequency()*vco_detune/engine::getMixer()->processingSampleRate();  // TODO: Use actual sampling rate.
			note.dead = deadToggle.value();
			initNote(&note);
			vca_mode=0;
	*/

		}
		/// Start a new note.
		else if( _n->totalFramesPlayed() == 0 ) {
			new_freq = _n->unpitchedFrequency();
			true_freq = _n->frequency();
			_n->m_pluginData = this;
		}

		// Check for slide
		if( _n->unpitchedFrequency() == current_freq ) {
			true_freq = _n->frequency();

			if( slideToggle.value() ) {
				vco_slidebase = GET_INC( true_freq );			// The REAL frequency
			}
			else {
				vco_inc = GET_INC( true_freq );
			}
		}

	//LB303 }


}
Пример #3
0
void lb303Synth::playNote( NotePlayHandle * _n,
						sampleFrame * _working_buffer )
{
	if( _n->arpBaseNote() )
	{
		//return;
	}

	// Currently have release/decay disabled
	// Start the release decay if this is the first release period.
	//if (_n->released() && catch_decay == 0)
	//        catch_decay = 1;

	bool decay_note = false;

	release_frame = _n->framesLeft() - desiredReleaseFrames();


	if(deadToggle.value() == 0 && decay_note) {
	}
	/// Start a new note.
	else if( _n->totalFramesPlayed() == 0 ) {
		new_freq = _n->unpitchedFrequency();
		true_freq = _n->frequency();
		_n->m_pluginData = this;
	}

	// Check for slide
	if( _n->unpitchedFrequency() == current_freq ) {
		true_freq = _n->frequency();

		if( slideToggle.value() ) {
			vco_slidebase = GET_INC( true_freq );			// The REAL frequency
		}
		else {
			vco_inc = GET_INC( true_freq );
		}
	}
}
Пример #4
0
int lb302Synth::process(sampleFrame *outbuf, const int size)
{
	const float sampleRatio = 44100.f / engine::mixer()->processingSampleRate();
	float w;
	float samp;

	// Hold on to the current VCF, and use it throughout this period
	lb302Filter *filter = vcf;

	if( release_frame == 0 || ! m_playingNote ) 
	{
		vca_mode = 1;
	}

	if( new_freq ) 
	{
		//printf("  playing new note..\n");
		lb302Note note;
		note.vco_inc = GET_INC( true_freq );
		note.dead = deadToggle.value();
		initNote(&note);

		new_freq = false;
	}



	// TODO: NORMAL RELEASE
	// vca_mode = 1;

	for( int i=0; i<size; i++ ) 
	{
		// start decay if we're past release
		if( i >= release_frame )
		{
			vca_mode = 1;
		}

		// update vcf
		if(vcf_envpos >= ENVINC) {
			filter->envRecalc();

			vcf_envpos = 0;

			if (vco_slide) {
					vco_inc = vco_slidebase - vco_slide;
					// Calculate coeff from dec_knob on knob change.
					vco_slide -= vco_slide * ( 0.1f - slide_dec_knob.value() * 0.0999f ) * sampleRatio; // TODO: Adjust for ENVINC

			}
		}


		sample_cnt++;
		vcf_envpos++;

		//int  decay_frames = 128;

		// update vco
		vco_c += vco_inc;
		
		if(vco_c > 0.5)
			vco_c -= 1.0;

		switch(int(rint(wave_shape.value()))) {
			case 0: vco_shape = SAWTOOTH; break;
			case 1: vco_shape = TRIANGLE; break;
			case 2: vco_shape = SQUARE; break;
			case 3: vco_shape = ROUND_SQUARE; break;
			case 4: vco_shape = MOOG; break;
			case 5: vco_shape = SINE; break;
			case 6: vco_shape = EXPONENTIAL; break;
			case 7: vco_shape = WHITE_NOISE; break;
			case 8: vco_shape = BL_SAWTOOTH; break;
			case 9: vco_shape = BL_SQUARE; break;
			case 10: vco_shape = BL_TRIANGLE; break;
			case 11: vco_shape = BL_MOOG; break;
			default:  vco_shape = SAWTOOTH; break;
		}

		// add vco_shape_param the changes the shape of each curve.
		// merge sawtooths with triangle and square with round square?
		switch (vco_shape) {
			case SAWTOOTH: // p0: curviness of line
				vco_k = vco_c;  // Is this sawtooth backwards?
				break;

			case TRIANGLE:  // p0: duty rev.saw<->triangle<->saw p1: curviness
				vco_k = (vco_c*2.0)+0.5;
				if (vco_k>0.5)
					vco_k = 1.0- vco_k;
				break;

			case SQUARE: // p0: slope of top
				vco_k = (vco_c<0)?0.5:-0.5;
				break;

			case ROUND_SQUARE: // p0: width of round
				vco_k = (vco_c<0)?(sqrtf(1-(vco_c*vco_c*4))-0.5):-0.5;
				break;

			case MOOG: // Maybe the fall should be exponential/sinsoidal instead of quadric.
				// [-0.5, 0]: Rise, [0,0.25]: Slope down, [0.25,0.5]: Low
				vco_k = (vco_c*2.0)+0.5;
				if (vco_k>1.0) {
					vco_k = -0.5 ;
				}
				else if (vco_k>0.5) {
					w = 2.0*(vco_k-0.5)-1.0;
					vco_k = 0.5 - sqrtf(1.0-(w*w));
				}
				vco_k *= 2.0;  // MOOG wave gets filtered away
				break;

			case SINE:
				// [-0.5, 0.5]  : [-pi, pi]
				vco_k = 0.5f * Oscillator::sinSample( vco_c );
				break;

			case EXPONENTIAL:
				vco_k = 0.5 * Oscillator::expSample( vco_c );
				break;

			case WHITE_NOISE:
				vco_k = 0.5 * Oscillator::noiseSample( vco_c );
				break;

			case BL_SAWTOOTH:
				vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLSaw ) * 0.5f;
				break;

			case BL_SQUARE:
				vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLSquare ) * 0.5f;
				break;

			case BL_TRIANGLE:
				vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLTriangle ) * 0.5f;
				break;

			case BL_MOOG:
				vco_k = BandLimitedWave::oscillate( vco_c + 0.5f, BandLimitedWave::pdToLen( vco_inc ), BandLimitedWave::BLMoog );
				break;
		}

		//vca_a = 0.5;
		// Write out samples.
#ifdef LB_FILTERED
		//samp = vcf->process(vco_k)*2.0*vca_a;
		//samp = vcf->process(vco_k)*2.0;
		samp = filter->process(vco_k) * vca_a;
		//printf("%f %d\n", vco_c, sample_cnt);


		//samp = vco_k * vca_a;

		if( sample_cnt <= 4 )
		{
	//			vca_a = 0;
		}

#else
		//samp = vco_k*vca_a;
#endif
		/*
		float releaseFrames = desiredReleaseFrames();
		samp *= (releaseFrames - catch_decay)/releaseFrames;
		*/
		//LB302 samp *= (float)(decay_frames - catch_decay)/(float)decay_frames;

		for( int c = 0; c < DEFAULT_CHANNELS; c++ ) 
		{
			outbuf[i][c] = samp;
		}

		// Handle Envelope
		if(vca_mode==0) {
			vca_a+=(vca_a0-vca_a)*vca_attack;
			if(sample_cnt>=0.5*engine::mixer()->processingSampleRate())
				vca_mode = 2;
		}
		else if(vca_mode == 1) {
			vca_a *= vca_decay;

			// the following line actually speeds up processing
			if(vca_a < (1/65536.0)) {
				vca_a = 0;
				vca_mode = 3;
			}
		}

	}
	return 1;
}
Пример #5
0
int lb302Synth::process(sampleFrame *outbuf, const Uint32 size)
{
	unsigned int i;
	float w;
	float samp;

	if( delete_freq == current_freq ) {
		// Normal release
		delete_freq = -1;
		vca_mode = 1;
	}

	if( new_freq > 0.0f ) {
		//printf("  playing new note..\n");
		lb302Note note;
		note.vco_inc = GET_INC( true_freq );
		//printf("GET_INC %f %f %d\n", note.vco_inc, new_freq, vca_mode );
		///**vco_detune*//engine::getMixer()->processingSampleRate();  // TODO: Use actual sampling rate.
		//printf("VCO_INC = %f\n", note.vco_inc);
		note.dead = deadToggle.value();
		initNote(&note);
		//printf("%f %f,  ", vco_inc, vco_c);
		
		current_freq = new_freq; 

		new_freq = -1.0f;
		//printf("GOT_INC %f %f %d\n\n", note.vco_inc, new_freq, vca_mode );
	} 

	

	// TODO: NORMAL RELEASE
	// vca_mode = 1;

	for(i=0;i<size;i++) {

		// update vcf
		if(vcf_envpos >= ENVINC) {
			vcf->envRecalc();

			vcf_envpos = 0;

			if (vco_slide) {
					vco_inc=vco_slidebase-vco_slide;
					// Calculate coeff from dec_knob on knob change.
					vco_slide*= 0.9+(slide_dec_knob.value()*0.0999); // TODO: Adjust for Hz and ENVINC

			}
		}


		sample_cnt++;
		vcf_envpos++;

		//int  decay_frames = 128;

		// update vco
		vco_c += vco_inc;

		if(vco_c > 0.5)
			vco_c -= 1.0;

		/*LB303
		if (catch_decay > 0) {
			if (catch_decay < decay_frames) {
				catch_decay++;
			}
		}*/

		switch(int(rint(wave_shape.value()))) {
			case 0: vco_shape = SAWTOOTH; break;
			case 1: vco_shape = TRIANGLE; break;
			case 2: vco_shape = SQUARE; break;
			case 3: vco_shape = ROUND_SQUARE; break;
			case 4: vco_shape = MOOG; break;
			case 5: vco_shape = SINE; break;
			case 6: vco_shape = EXPONENTIAL; break;
			case 7: vco_shape = WHITE_NOISE; break;
			default:  vco_shape = SAWTOOTH; break;
		}

		// add vco_shape_param the changes the shape of each curve.
		// merge sawtooths with triangle and square with round square?
		switch (vco_shape) {
			case SAWTOOTH: // p0: curviness of line
				vco_k = vco_c;  // Is this sawtooth backwards?
				break;

			case TRIANGLE:  // p0: duty rev.saw<->triangle<->saw p1: curviness
				vco_k = (vco_c*2.0)+0.5;
				if (vco_k>0.5)
					vco_k = 1.0- vco_k;
				break;

			case SQUARE: // p0: slope of top
				vco_k = (vco_c<0)?0.5:-0.5;
				break;

			case ROUND_SQUARE: // p0: width of round
				vco_k = (vco_c<0)?(sqrtf(1-(vco_c*vco_c*4))-0.5):-0.5;
				break;

			case MOOG: // Maybe the fall should be exponential/sinsoidal instead of quadric.
				// [-0.5, 0]: Rise, [0,0.25]: Slope down, [0.25,0.5]: Low 
				vco_k = (vco_c*2.0)+0.5;
				if (vco_k>1.0) {
					vco_k = -0.5 ;
				}
				else if (vco_k>0.5) {
					w = 2.0*(vco_k-0.5)-1.0;
					vco_k = 0.5 - sqrtf(1.0-(w*w));
				}
				vco_k *= 2.0;  // MOOG wave gets filtered away 
				break;

			case SINE:
				// [-0.5, 0.5]  : [-pi, pi]
				vco_k = 0.5f * Oscillator::sinSample( vco_c );
				break;

			case EXPONENTIAL:
				vco_k = 0.5 * Oscillator::expSample( vco_c );
				break;

			case WHITE_NOISE:
				vco_k = 0.5 * Oscillator::noiseSample( vco_c );
				break;
		}

		//vca_a = 0.5;
		// Write out samples.
#ifdef LB_FILTERED
		//samp = vcf->process(vco_k)*2.0*vca_a;
		//samp = vcf->process(vco_k)*2.0;
		samp = vcf->process(vco_k) * vca_a;
		//printf("%f %d\n", vco_c, sample_cnt);	
		

		//samp = vco_k * vca_a;

		if( sample_cnt <= 4 )
		{
	//			vca_a = 0;
		}
		
#else
		//samp = vco_k*vca_a;
#endif
		/*
		float releaseFrames = desiredReleaseFrames();
		samp *= (releaseFrames - catch_decay)/releaseFrames;
		*/
		//LB302 samp *= (float)(decay_frames - catch_decay)/(float)decay_frames;

		for(int c=0; c<DEFAULT_CHANNELS; c++) {
			outbuf[i][c]=samp;
		}


		/*LB303
		if((int)i>=release_frame) {
			vca_mode=1;
		}
		*/

		// Handle Envelope
		if(vca_mode==0) {
			vca_a+=(vca_a0-vca_a)*vca_attack;
			if(sample_cnt>=0.5*engine::getMixer()->processingSampleRate()) 
				vca_mode = 2;
		}
		else if(vca_mode == 1) {
			vca_a *= vca_decay;

			// the following line actually speeds up processing
			if(vca_a < (1/65536.0)) {
				vca_a = 0;
				vca_mode = 3;
			}
		}

	}
	return 1;
}