Example #1
0
	void	rgba::set_lerp(const rgba& a, const rgba& b, float f)
	{
		m_r = (Uint8) frnd(flerp(a.m_r, b.m_r, f));
		m_g = (Uint8) frnd(flerp(a.m_g, b.m_g, f));
		m_b = (Uint8) frnd(flerp(a.m_b, b.m_b, f));
		m_a = (Uint8) frnd(flerp(a.m_a, b.m_a, f));
	}
Example #2
0
void sfxrInstrumentView::genPowerup()
{
    sfxrInstrument * s = castModel<sfxrInstrument>();
    s->resetModels();

    if(rnd(1))
        s->m_waveFormModel.setValue( 1 );
    else
        s->m_sqrDutyModel.setValue( frnd(0.6f) );
    if(rnd(1))
    {
        s->m_startFreqModel.setValue( 0.2f+frnd(0.3f) );
        s->m_slideModel.setValue( 0.1f+frnd(0.4f) );
        s->m_repeatSpeedModel.setValue( 0.4f+frnd(0.4f) );
    }
    else
    {
        s->m_startFreqModel.setValue( 0.2f+frnd(0.3f) );
        s->m_slideModel.setValue( 0.05f+frnd(0.2f) );
        if(rnd(1))
        {
            s->m_vibDepthModel.setValue( frnd(0.7f) );
            s->m_vibSpeedModel.setValue( frnd(0.6f) );
        }
    }

    s->m_attModel.setValue( 0.0f );
    s->m_holdModel.setValue( frnd(0.4f) );
    s->m_decModel.setValue( 0.1f+frnd(0.4f) );
}
Example #3
0
void sfxr::PowerupButtonPressed()
{
    ResetParams();
    if(rnd(1))
        wave_type=1;
    else
        p_duty=frnd(0.6f);
    if(rnd(1))
    {
        p_base_freq=0.2f+frnd(0.3f);
        p_freq_ramp=0.1f+frnd(0.4f);
        p_repeat_speed=0.4f+frnd(0.4f);
    }
    else
    {
        p_base_freq=0.2f+frnd(0.3f);
        p_freq_ramp=0.05f+frnd(0.2f);
        if(rnd(1))
        {
            p_vib_strength=frnd(0.7f);
            p_vib_speed=frnd(0.6f);
        }
    }
    p_env_attack=0.0f;
    p_env_sustain=frnd(0.4f);
    p_env_decay=0.1f+frnd(0.4f);
    PlaySample();
}
Example #4
0
void generator::GenerateBasicPowerUp(void)
{
	ResetParams();
	if(rnd(1)) {
		wave_type=1;
	} else {
		p_duty=frnd(0.6f);
	}
	if(rnd(1)) {
		p_base_freq=0.2f+frnd(0.3f);
		p_freq_ramp=0.1f+frnd(0.4f);
		p_repeat_speed=0.4f+frnd(0.4f);
	} else {
		p_base_freq=0.2f+frnd(0.3f);
		p_freq_ramp=0.05f+frnd(0.2f);
		if(rnd(1)) {
			p_vib_strength=frnd(0.7f);
			p_vib_speed=frnd(0.6f);
		}
	}
	p_env_attack=0.0f;
	p_env_sustain=frnd(0.4f);
	p_env_decay=0.1f+frnd(0.4f);
	PlaySample();
}
Example #5
0
void sfxr::BlitSelectButtonPressed()
{
    ResetParams();
    wave_type=rnd(1);
    if(wave_type==0)
        p_duty=frnd(0.6f);
    p_base_freq=0.2f+frnd(0.4f);
    p_env_attack=0.0f;
    p_env_sustain=0.1f+frnd(0.1f);
    p_env_decay=frnd(0.2f);
    p_hpf_freq=0.1f;
    PlaySample();
}
Example #6
0
void generator::GenerateBasicBlipSelect(void)
{
	ResetParams();
	wave_type=rnd(1);
	if(wave_type==0) {
		p_duty=frnd(0.6f);
	}
	p_base_freq=0.2f+frnd(0.4f);
	p_env_attack=0.0f;
	p_env_sustain=0.1f+frnd(0.1f);
	p_env_decay=frnd(0.2f);
	p_hpf_freq=0.1f;
	PlaySample();
}
Example #7
0
void sfxrInstrumentView::genJump()
{
    sfxrInstrument * s = castModel<sfxrInstrument>();
    s->resetModels();

    s->m_waveFormModel.setValue( 0 );
    s->m_sqrDutyModel.setValue( frnd(0.6f) );

    s->m_startFreqModel.setValue( 0.3f+frnd(0.3f) );
    s->m_slideModel.setValue( 0.1f+frnd(0.2f) );

    s->m_attModel.setValue( 0.0f );
    s->m_holdModel.setValue( 0.1f+frnd(0.3f) );
    s->m_decModel.setValue( 0.1f+frnd(0.2f) );

    if(rnd(1))
    {
        s->m_hpFilCutModel.setValue( frnd(0.3f) );
    }
    if(rnd(1))
    {

        s->m_lpFilCutModel.setValue( 1.0f-frnd(0.6f) );
    }

}
Example #8
0
void sfxrInstrumentView::genBlip()
{
    sfxrInstrument * s = castModel<sfxrInstrument>();
    s->resetModels();

    s->m_waveFormModel.setValue( rnd(1) );
    if( s->m_waveFormModel.value()==0 )
    {
        s->m_sqrDutyModel.setValue( frnd(0.6f) );
    }

    s->m_startFreqModel.setValue( 0.2f+frnd(0.4f) );

    s->m_attModel.setValue( 0.0f );
    s->m_holdModel.setValue( 0.1f+frnd(0.1f) );
    s->m_decModel.setValue( frnd(0.2f) );
    s->m_hpFilCutModel.setValue( 0.1f );
}
Example #9
0
	void	resample(SDL_Surface* dest, int out_x0, int out_y0, int out_x1, int out_y1,
			 SDL_Surface* src, float in_x0, float in_y0, float in_x1, float in_y1)
	// Resample the specified rectangle of the src surface into the
	// specified rectangle of the destination surface.  Output coords
	// are inclusive.
	{
		// Make sure output is within bounds.
		assert(out_x0 >= 0 && out_x0 < dest->w);
		assert(out_x1 > out_x0 && out_x1 < dest->w);
		assert(out_y0 >= 0 && out_y0 < dest->h);
		assert(out_y1 > out_y0 && out_y1 < dest->h);

		int	dxo = (out_x1 - out_x0);
		int	dyo = (out_y1 - out_y0);

		// @@ check input...

		float	dxi = in_x1 - in_x0;
		float	dyi = in_y1 - in_y0;
		assert(dxi > 0.001f);
		assert(dyi > 0.001f);

		float	x_factor = dxi / dxo;
		float	y_factor = dyi / dyo;

		// @@ not optimized.

		for (int j = 0; j <= dyo; j++) {
			for (int i = 0; i <= dxo; i++) {
				// @@ simple nearest-neighbor point-sample.
				float	x = i * x_factor + in_x0;
				float	y = j * y_factor + in_y0;
				x = fclamp(x, 0.f, float(src->w - 1));
				y = fclamp(y, 0.f, float(src->h - 1));

				Uint8*	p = scanline(src, frnd(y)) + 3 * frnd(x);
				Uint8*	q = scanline(dest, out_y0 + j) + 3 * (out_x0 + i);

				*q++ = *p++;	// red
				*q++ = *p++;	// green
				*q++ = *p++;	// blue
			}
		}
	}
Example #10
0
bool PathFinder::lookFor(NodeId from, const Vec3f & pos, float radius, Result & rlist,
                         bool stealth) const {
	
	if(radius <= MIN_RADIUS) {
		rlist.push_back(from);
		return true;
	}
	
	size_t s = rlist.size();
	
	NodeId to = getNearestNode(pos);
	
	NodeId last = from;
	
	unsigned long step_c = Random::get() % 5 + 5;
	for(unsigned long i = 0; i < step_c; i++) {
		
		Vec3f pos;
		pos.x = map_d[to].pos.x + radius * frnd();
		pos.y = map_d[to].pos.y + radius * frnd();
		pos.z = map_d[to].pos.z + radius * frnd();
		
		NodeId next = getNearestNode(pos);
		
		if(!move(last, next, rlist, stealth)) {
			// TODO can cause infinite loop?
			i--;
			last = next;
			continue;
		}
		
		last = next;
	}
	
	if(rlist.size() == s) {
		return false;
	}
	
	return true;
}
Example #11
0
void
GradientFill::setLerp(const GradientFill& a, const GradientFill& b,
        double ratio)
{
    assert(type() == a.type());
    assert(_gradients.size() == a.recordCount());
    assert(_gradients.size() == b.recordCount());

    for (size_t i = 0, e = _gradients.size(); i < e; ++i) {
        const GradientRecord& ra = a.record(i);
        const GradientRecord& rb = b.record(i);
        _gradients[i].ratio = frnd(lerp<float>(ra.ratio, rb.ratio, ratio));
        _gradients[i].color.set_lerp(ra.color, rb.color, ratio);
    }
    _matrix.set_lerp(a.matrix(), b.matrix(), ratio);
}
Example #12
0
void sfxr::JumpButtonPressed()
{
    ResetParams();
    wave_type=0;
    p_duty=frnd(0.6f);
    p_base_freq=0.3f+frnd(0.3f);
    p_freq_ramp=0.1f+frnd(0.2f);
    p_env_attack=0.0f;
    p_env_sustain=0.1f+frnd(0.3f);
    p_env_decay=0.1f+frnd(0.2f);
    if(rnd(1))
        p_hpf_freq=frnd(0.3f);
    if(rnd(1))
        p_lpf_freq=1.0f-frnd(0.6f);
    PlaySample();
}
Example #13
0
// pickup/coin
void generator::GenerateBasicPickUpCoin(void)
{
	ResetParams();
	p_base_freq=0.4f+frnd(0.5f);
	p_env_attack=0.0f;
	p_env_sustain=frnd(0.1f);
	p_env_decay=0.1f+frnd(0.4f);
	p_env_punch=0.3f+frnd(0.3f);
	if(rnd(1)) {
		p_arp_speed=0.5f+frnd(0.2f);
		p_arp_mod=0.2f+frnd(0.4f);
	}
	PlaySample();
}
Example #14
0
void generator::GenerateBasicJump(void)
{
	ResetParams();
	wave_type=0;
	p_duty=frnd(0.6f);
	p_base_freq=0.3f+frnd(0.3f);
	p_freq_ramp=0.1f+frnd(0.2f);
	p_env_attack=0.0f;
	p_env_sustain=0.1f+frnd(0.3f);
	p_env_decay=0.1f+frnd(0.2f);
	if(rnd(1)) {
		p_hpf_freq=frnd(0.3f);
	}
	if(rnd(1)) {
		p_lpf_freq=1.0f-frnd(0.6f);
	}
	PlaySample();
}
Example #15
0
static void
bloops_start_voice(bloopsavoice *A) {
  int i = 0;
  A->phase = 0;
  A->filter[0] = 0.0f;
  A->filter[1] = 0.0f;
  A->filter[2] = pow(A->params.lpf, 3.0f) * 0.1f;
  A->filter[3] = 1.0f + A->params.lsweep * 0.0001f;
  A->filter[4] = 5.0f / (1.0f + pow(A->params.resonance, 2.0f) * 20.0f) * (0.01f + A->filter[2]);
  if (A->filter[4] > 0.8f) A->filter[4] = 0.8f;
  A->filter[5] = 0.0f;
  A->filter[6] = pow(A->params.hpf, 2.0f) * 0.1f;
  A->filter[7] = 1.0 + A->params.hsweep * 0.0003f;

  A->vibe = 0.0f;
  A->vspeed = pow(A->params.vspeed, 2.0f) * 0.01f;
  A->vdelay = A->params.vibe * 0.5f;

  A->volume = 0.0f;
  A->stage = 0;
  A->time = 0;
  A->length[0] = (int)(A->params.attack * A->params.attack * 100000.0f);
  A->length[1] = (int)(A->params.sustain * A->params.sustain * 100000.0f);
  A->length[2] = (int)(A->params.decay * A->params.decay * 100000.0f);

  A->fphase = pow(A->params.phase, 2.0f) * 1020.0f;
  if (A->params.phase < 0.0f) A->fphase = -A->fphase;
  A->dphase = pow(A->params.psweep, 2.0f) * 1.0f;
  if (A->params.psweep < 0.0f) A->dphase = -A->dphase;
  A->iphase = abs((int)A->fphase);
  A->phasex = 0;

  memset(A->phaser, 0, 1024 * sizeof(float));
  for (i = 0; i < 32; i++)
    A->noise[i] = frnd(2.0f) - 1.0f;

  A->repeat = 0;
  A->limit = (int)(pow(1.0f - A->params.repeat, 2.0f) * 20000 + 32);
  if (A->params.repeat == 0.0f)
    A->limit = 0;
  A->state = BLOOPS_PLAY;
}
Example #16
0
void sfxr::PickupCoinButtonPressed()
{
    ResetParams();
    p_base_freq=0.4f+frnd(0.5f);
    p_env_attack=0.0f;
    p_env_sustain=frnd(0.1f);
    p_env_decay=0.1f+frnd(0.4f);
    p_env_punch=0.3f+frnd(0.3f);
    if(rnd(1))
    {
        p_arp_speed=0.5f+frnd(0.2f);
        p_arp_mod=0.2f+frnd(0.4f);
    }
    PlaySample();
}
Example #17
0
void sfxrInstrumentView::genPickup()
{
    sfxrInstrument * s = castModel<sfxrInstrument>();
    s->resetModels();
    s->m_startFreqModel.setValue( 0.4f+frnd(0.5f) );
    s->m_attModel.setValue( 0.0f );
    s->m_holdModel.setValue( frnd(0.1f) );
    s->m_decModel.setValue( 0.1f+frnd(0.4f) );
    s->m_susModel.setValue( 0.3f+frnd(0.3f) );

    if(rnd(1))
    {
        s->m_changeSpeedModel.setValue( 0.5f+frnd(0.2f) );
        s->m_changeAmtModel.setValue( 0.2f+frnd(0.4f) );
    }
}
Example #18
0
void sfxr::HitHurtButtonPressed()
{
    ResetParams();
    wave_type=rnd(2);
    if(wave_type==2)
        wave_type=3;
    if(wave_type==0)
        p_duty=frnd(0.6f);
    p_base_freq=0.2f+frnd(0.6f);
    p_freq_ramp=-0.3f-frnd(0.4f);
    p_env_attack=0.0f;
    p_env_sustain=frnd(0.1f);
    p_env_decay=0.1f+frnd(0.2f);
    if(rnd(1))
        p_hpf_freq=frnd(0.3f);
    PlaySample();
}
Example #19
0
void generator::GenerateBasicHitHurt(void)
{
	ResetParams();
	wave_type=rnd(2);
	if(wave_type==2) {
		wave_type=3;
	}
	if(wave_type==0) {
		p_duty=frnd(0.6f);
	}
	p_base_freq=0.2f+frnd(0.6f);
	p_freq_ramp=-0.3f-frnd(0.4f);
	p_env_attack=0.0f;
	p_env_sustain=frnd(0.1f);
	p_env_decay=0.1f+frnd(0.2f);
	if(rnd(1)) {
		p_hpf_freq=frnd(0.3f);
	}
	PlaySample();
}
Example #20
0
File: main.cpp Project: nyov/sfxr
void DrawScreen()
{
	bool redraw=true;
	if(!firstframe && mouse_x-mouse_px==0 && mouse_y-mouse_py==0 && !mouse_left && !mouse_right)
		redraw=false;
	if(!mouse_left)
	{
		if(vselected!=NULL || vcurbutton>-1)
		{
			redraw=true;
			refresh_counter=2;
		}
		vselected=NULL;
	}
	if(refresh_counter>0)
	{
		refresh_counter--;
		redraw=true;
	}

	if(playing_sample)
		redraw=true;

	if(drawcount++>20)
	{
		redraw=true;
		drawcount=0;
	}

	if(!redraw)
		return;

	firstframe=false;

	ddkLock();

	ClearScreen(0xC0B090);

	DrawText(10, 10, 0x504030, "GENERATOR");
	for(int i=0;i<7;i++)
	{
		if(Button(5, 35+i*30, false, categories[i].name, 300+i))
		{
			switch(i)
			{
			case 0: // pickup/coin
				ResetParams();
				p_base_freq=0.4f+frnd(0.5f);
				p_env_attack=0.0f;
				p_env_sustain=frnd(0.1f);
				p_env_decay=0.1f+frnd(0.4f);
				p_env_punch=0.3f+frnd(0.3f);
				if(rnd(1))
				{
					p_arp_speed=0.5f+frnd(0.2f);
					p_arp_mod=0.2f+frnd(0.4f);
				}
				break;
			case 1: // laser/shoot
				ResetParams();
				wave_type=rnd(2);
				if(wave_type==2 && rnd(1))
					wave_type=rnd(1);
				p_base_freq=0.5f+frnd(0.5f);
				p_freq_limit=p_base_freq-0.2f-frnd(0.6f);
				if(p_freq_limit<0.2f) p_freq_limit=0.2f;
				p_freq_ramp=-0.15f-frnd(0.2f);
				if(rnd(2)==0)
				{
					p_base_freq=0.3f+frnd(0.6f);
					p_freq_limit=frnd(0.1f);
					p_freq_ramp=-0.35f-frnd(0.3f);
				}
				if(rnd(1))
				{
					p_duty=frnd(0.5f);
					p_duty_ramp=frnd(0.2f);
				}
				else
				{
					p_duty=0.4f+frnd(0.5f);
					p_duty_ramp=-frnd(0.7f);
				}
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.2f);
				p_env_decay=frnd(0.4f);
				if(rnd(1))
					p_env_punch=frnd(0.3f);
				if(rnd(2)==0)
				{
					p_pha_offset=frnd(0.2f);
					p_pha_ramp=-frnd(0.2f);
				}
				if(rnd(1))
					p_hpf_freq=frnd(0.3f);
				break;
			case 2: // explosion
				ResetParams();
				wave_type=3;
				if(rnd(1))
				{
					p_base_freq=0.1f+frnd(0.4f);
					p_freq_ramp=-0.1f+frnd(0.4f);
				}
				else
				{
					p_base_freq=0.2f+frnd(0.7f);
					p_freq_ramp=-0.2f-frnd(0.2f);
				}
				p_base_freq*=p_base_freq;
				if(rnd(4)==0)
					p_freq_ramp=0.0f;
				if(rnd(2)==0)
					p_repeat_speed=0.3f+frnd(0.5f);
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.3f);
				p_env_decay=frnd(0.5f);
				if(rnd(1)==0)
				{
					p_pha_offset=-0.3f+frnd(0.9f);
					p_pha_ramp=-frnd(0.3f);
				}
				p_env_punch=0.2f+frnd(0.6f);
				if(rnd(1))
				{
					p_vib_strength=frnd(0.7f);
					p_vib_speed=frnd(0.6f);
				}
				if(rnd(2)==0)
				{
					p_arp_speed=0.6f+frnd(0.3f);
					p_arp_mod=0.8f-frnd(1.6f);
				}
				break;
			case 3: // powerup
				ResetParams();
				if(rnd(1))
					wave_type=1;
				else
					p_duty=frnd(0.6f);
				if(rnd(1))
				{
					p_base_freq=0.2f+frnd(0.3f);
					p_freq_ramp=0.1f+frnd(0.4f);
					p_repeat_speed=0.4f+frnd(0.4f);
				}
				else
				{
					p_base_freq=0.2f+frnd(0.3f);
					p_freq_ramp=0.05f+frnd(0.2f);
					if(rnd(1))
					{
						p_vib_strength=frnd(0.7f);
						p_vib_speed=frnd(0.6f);
					}
				}
				p_env_attack=0.0f;
				p_env_sustain=frnd(0.4f);
				p_env_decay=0.1f+frnd(0.4f);
				break;
			case 4: // hit/hurt
				ResetParams();
				wave_type=rnd(2);
				if(wave_type==2)
					wave_type=3;
				if(wave_type==0)
					p_duty=frnd(0.6f);
				p_base_freq=0.2f+frnd(0.6f);
				p_freq_ramp=-0.3f-frnd(0.4f);
				p_env_attack=0.0f;
				p_env_sustain=frnd(0.1f);
				p_env_decay=0.1f+frnd(0.2f);
				if(rnd(1))
					p_hpf_freq=frnd(0.3f);
				break;
			case 5: // jump
				ResetParams();
				wave_type=0;
				p_duty=frnd(0.6f);
				p_base_freq=0.3f+frnd(0.3f);
				p_freq_ramp=0.1f+frnd(0.2f);
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.3f);
				p_env_decay=0.1f+frnd(0.2f);
				if(rnd(1))
					p_hpf_freq=frnd(0.3f);
				if(rnd(1))
					p_lpf_freq=1.0f-frnd(0.6f);
				break;
			case 6: // blip/select
				ResetParams();
				wave_type=rnd(1);
				if(wave_type==0)
					p_duty=frnd(0.6f);
				p_base_freq=0.2f+frnd(0.4f);
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.1f);
				p_env_decay=frnd(0.2f);
				p_hpf_freq=0.1f;
				break;
			default:
				break;
			}

			PlaySample();
		}
	}
	DrawBar(110, 0, 2, 480, 0x000000);
	DrawText(120, 10, 0x504030, "MANUAL SETTINGS");
	DrawSprite(ld48, 8, 440, 0, 0xB0A080);

	if(Button(130, 30, wave_type==0, "SQUAREWAVE", 10))
		wave_type=0;
	if(Button(250, 30, wave_type==1, "SAWTOOTH", 11))
		wave_type=1;
	if(Button(370, 30, wave_type==2, "SINEWAVE", 12))
		wave_type=2;
	if(Button(490, 30, wave_type==3, "NOISE", 13))
		wave_type=3;

	bool do_play=false;

	DrawBar(5-1-1, 412-1-1, 102+2, 19+2, 0x000000);
	if(Button(5, 412, false, "RANDOMIZE", 40))
	{
		p_base_freq=pow(frnd(2.0f)-1.0f, 2.0f);
		if(rnd(1))
			p_base_freq=pow(frnd(2.0f)-1.0f, 3.0f)+0.5f;
		p_freq_limit=0.0f;
		p_freq_ramp=pow(frnd(2.0f)-1.0f, 5.0f);
		if(p_base_freq>0.7f && p_freq_ramp>0.2f)
			p_freq_ramp=-p_freq_ramp;
		if(p_base_freq<0.2f && p_freq_ramp<-0.05f)
			p_freq_ramp=-p_freq_ramp;
		p_freq_dramp=pow(frnd(2.0f)-1.0f, 3.0f);
		p_duty=frnd(2.0f)-1.0f;
		p_duty_ramp=pow(frnd(2.0f)-1.0f, 3.0f);
		p_vib_strength=pow(frnd(2.0f)-1.0f, 3.0f);
		p_vib_speed=frnd(2.0f)-1.0f;
		p_vib_delay=frnd(2.0f)-1.0f;
		p_env_attack=pow(frnd(2.0f)-1.0f, 3.0f);
		p_env_sustain=pow(frnd(2.0f)-1.0f, 2.0f);
		p_env_decay=frnd(2.0f)-1.0f;
		p_env_punch=pow(frnd(0.8f), 2.0f);
		if(p_env_attack+p_env_sustain+p_env_decay<0.2f)
		{
			p_env_sustain+=0.2f+frnd(0.3f);
			p_env_decay+=0.2f+frnd(0.3f);
		}
		p_lpf_resonance=frnd(2.0f)-1.0f;
		p_lpf_freq=1.0f-pow(frnd(1.0f), 3.0f);
		p_lpf_ramp=pow(frnd(2.0f)-1.0f, 3.0f);
		if(p_lpf_freq<0.1f && p_lpf_ramp<-0.05f)
			p_lpf_ramp=-p_lpf_ramp;
		p_hpf_freq=pow(frnd(1.0f), 5.0f);
		p_hpf_ramp=pow(frnd(2.0f)-1.0f, 5.0f);
		p_pha_offset=pow(frnd(2.0f)-1.0f, 3.0f);
		p_pha_ramp=pow(frnd(2.0f)-1.0f, 3.0f);
		p_repeat_speed=frnd(2.0f)-1.0f;
		p_arp_speed=frnd(2.0f)-1.0f;
		p_arp_mod=frnd(2.0f)-1.0f;
		do_play=true;
	}

	if(Button(5, 382, false, "MUTATE", 30))
	{
		if(rnd(1)) p_base_freq+=frnd(0.1f)-0.05f;
//		if(rnd(1)) p_freq_limit+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_freq_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_freq_dramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_duty+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_duty_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_vib_strength+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_vib_speed+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_vib_delay+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_attack+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_sustain+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_decay+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_punch+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_lpf_resonance+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_lpf_freq+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_lpf_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_hpf_freq+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_hpf_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_pha_offset+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_pha_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_repeat_speed+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_arp_speed+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_arp_mod+=frnd(0.1f)-0.05f;
		do_play=true;
	}

	DrawText(515, 170, 0x000000, "VOLUME");
	DrawBar(490-1-1+60, 180-1+5, 70, 2, 0x000000);
	DrawBar(490-1-1+60+68, 180-1+5, 2, 205, 0x000000);
	DrawBar(490-1-1+60, 180-1, 42+2, 10+2, 0xFF0000);
	Slider(490, 180, sound_vol, false, " ");
	if(Button(490, 200, false, "PLAY SOUND", 20))
		PlaySample();

	if(Button(490, 290, false, "LOAD SOUND", 14))
	{
		char filename[256];
		if(FileSelectorLoad(hWndMain, filename, 1)) // WIN32
		{
			ResetParams();
			LoadSettings(filename);
			PlaySample();
		}
	}
	if(Button(490, 320, false, "SAVE SOUND", 15))
	{
		char filename[256];
		if(FileSelectorSave(hWndMain, filename, 1)) // WIN32
			SaveSettings(filename);
	}

	DrawBar(490-1-1+60, 380-1+9, 70, 2, 0x000000);
	DrawBar(490-1-2, 380-1-2, 102+4, 19+4, 0x000000);
	if(Button(490, 380, false, "EXPORT .WAV", 16))
	{
		char filename[256];
		if(FileSelectorSave(hWndMain, filename, 0)) // WIN32
			ExportWAV(filename);
	}
	char str[10];
	sprintf(str, "%i HZ", wav_freq);
	if(Button(490, 410, false, str, 18))
	{
		if(wav_freq==44100)
			wav_freq=22050;
		else
			wav_freq=44100;
	}
	sprintf(str, "%i-BIT", wav_bits);
	if(Button(490, 440, false, str, 19))
	{
		if(wav_bits==16)
			wav_bits=8;
		else
			wav_bits=16;
	}

	int ypos=4;

	int xpos=350;

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_env_attack, false, "ATTACK TIME");
	Slider(xpos, (ypos++)*18, p_env_sustain, false, "SUSTAIN TIME");
	Slider(xpos, (ypos++)*18, p_env_punch, false, "SUSTAIN PUNCH");
	Slider(xpos, (ypos++)*18, p_env_decay, false, "DECAY TIME");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_base_freq, false, "START FREQUENCY");
	Slider(xpos, (ypos++)*18, p_freq_limit, false, "MIN FREQUENCY");
	Slider(xpos, (ypos++)*18, p_freq_ramp, true, "SLIDE");
	Slider(xpos, (ypos++)*18, p_freq_dramp, true, "DELTA SLIDE");

	Slider(xpos, (ypos++)*18, p_vib_strength, false, "VIBRATO DEPTH");
	Slider(xpos, (ypos++)*18, p_vib_speed, false, "VIBRATO SPEED");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_arp_mod, true, "CHANGE AMOUNT");
	Slider(xpos, (ypos++)*18, p_arp_speed, false, "CHANGE SPEED");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_duty, false, "SQUARE DUTY");
	Slider(xpos, (ypos++)*18, p_duty_ramp, true, "DUTY SWEEP");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_repeat_speed, false, "REPEAT SPEED");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_pha_offset, true, "PHASER OFFSET");
	Slider(xpos, (ypos++)*18, p_pha_ramp, true, "PHASER SWEEP");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_lpf_freq, false, "LP FILTER CUTOFF");
	Slider(xpos, (ypos++)*18, p_lpf_ramp, true, "LP FILTER CUTOFF SWEEP");
	Slider(xpos, (ypos++)*18, p_lpf_resonance, false, "LP FILTER RESONANCE");
	Slider(xpos, (ypos++)*18, p_hpf_freq, false, "HP FILTER CUTOFF");
	Slider(xpos, (ypos++)*18, p_hpf_ramp, true, "HP FILTER CUTOFF SWEEP");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	DrawBar(xpos-190, 4*18-5, 1, (ypos-4)*18, 0x0000000);
	DrawBar(xpos-190+299, 4*18-5, 1, (ypos-4)*18, 0x0000000);

	if(do_play)
		PlaySample();

	ddkUnlock();

	if(!mouse_left)
		vcurbutton=-1;
}
Example #21
0
File: main.cpp Project: nyov/sfxr
void SynthSample(int length, float* buffer, FILE* file)
{
	for(int i=0;i<length;i++)
	{
		if(!playing_sample)
			break;

		rep_time++;
		if(rep_limit!=0 && rep_time>=rep_limit)
		{
			rep_time=0;
			ResetSample(true);
		}

		// frequency envelopes/arpeggios
		arp_time++;
		if(arp_limit!=0 && arp_time>=arp_limit)
		{
			arp_limit=0;
			fperiod*=arp_mod;
		}
		fslide+=fdslide;
		fperiod*=fslide;
		if(fperiod>fmaxperiod)
		{
			fperiod=fmaxperiod;
			if(p_freq_limit>0.0f)
				playing_sample=false;
		}
		float rfperiod=fperiod;
		if(vib_amp>0.0f)
		{
			vib_phase+=vib_speed;
			rfperiod=fperiod*(1.0+sin(vib_phase)*vib_amp);
		}
		period=(int)rfperiod;
		if(period<8) period=8;
		square_duty+=square_slide;
		if(square_duty<0.0f) square_duty=0.0f;
		if(square_duty>0.5f) square_duty=0.5f;
		// volume envelope
		env_time++;
		if(env_time>env_length[env_stage])
		{
			env_time=0;
			env_stage++;
			if(env_stage==3)
				playing_sample=false;
		}
		if(env_stage==0)
			env_vol=(float)env_time/env_length[0];
		if(env_stage==1)
			env_vol=1.0f+pow(1.0f-(float)env_time/env_length[1], 1.0f)*2.0f*p_env_punch;
		if(env_stage==2)
			env_vol=1.0f-(float)env_time/env_length[2];

		// phaser step
		fphase+=fdphase;
		iphase=abs((int)fphase);
		if(iphase>1023) iphase=1023;

		if(flthp_d!=0.0f)
		{
			flthp*=flthp_d;
			if(flthp<0.00001f) flthp=0.00001f;
			if(flthp>0.1f) flthp=0.1f;
		}

		float ssample=0.0f;
		for(int si=0;si<8;si++) // 8x supersampling
		{
			float sample=0.0f;
			phase++;
			if(phase>=period)
			{
//				phase=0;
				phase%=period;
				if(wave_type==3)
					for(int i=0;i<32;i++)
						noise_buffer[i]=frnd(2.0f)-1.0f;
			}
			// base waveform
			float fp=(float)phase/period;
			switch(wave_type)
			{
			case 0: // square
				if(fp<square_duty)
					sample=0.5f;
				else
					sample=-0.5f;
				break;
			case 1: // sawtooth
				sample=1.0f-fp*2;
				break;
			case 2: // sine
				sample=(float)sin(fp*2*PI);
				break;
			case 3: // noise
				sample=noise_buffer[phase*32/period];
				break;
			}
			// lp filter
			float pp=fltp;
			fltw*=fltw_d;
			if(fltw<0.0f) fltw=0.0f;
			if(fltw>0.1f) fltw=0.1f;
			if(p_lpf_freq!=1.0f)
			{
				fltdp+=(sample-fltp)*fltw;
				fltdp-=fltdp*fltdmp;
			}
			else
			{
				fltp=sample;
				fltdp=0.0f;
			}
			fltp+=fltdp;
			// hp filter
			fltphp+=fltp-pp;
			fltphp-=fltphp*flthp;
			sample=fltphp;
			// phaser
			phaser_buffer[ipp&1023]=sample;
			sample+=phaser_buffer[(ipp-iphase+1024)&1023];
			ipp=(ipp+1)&1023;
			// final accumulation and envelope application
			ssample+=sample*env_vol;
		}
		ssample=ssample/8*master_vol;

		ssample*=2.0f*sound_vol;

		if(buffer!=NULL)
		{
			if(ssample>1.0f) ssample=1.0f;
			if(ssample<-1.0f) ssample=-1.0f;
			*buffer++=ssample;
		}
		if(file!=NULL)
		{
			// quantize depending on format
			// accumulate/count to accomodate variable sample rate?
			ssample*=4.0f; // arbitrary gain to get reasonable output volume...
			if(ssample>1.0f) ssample=1.0f;
			if(ssample<-1.0f) ssample=-1.0f;
			filesample+=ssample;
			fileacc++;
			if(wav_freq==44100 || fileacc==2)
			{
				filesample/=fileacc;
				fileacc=0;
				if(wav_bits==16)
				{
					short isample=(short)(filesample*32000);
					fwrite(&isample, 1, 2, file);
				}
				else
				{
					unsigned char isample=(unsigned char)(filesample*127+128);
					fwrite(&isample, 1, 1, file);
				}
				filesample=0.0f;
			}
			file_sampleswritten++;
		}
	}
}
Example #22
0
File: main.cpp Project: nyov/sfxr
void ResetSample(bool restart)
{
	if(!restart)
		phase=0;
	fperiod=100.0/(p_base_freq*p_base_freq+0.001);
	period=(int)fperiod;
	fmaxperiod=100.0/(p_freq_limit*p_freq_limit+0.001);
	fslide=1.0-pow((double)p_freq_ramp, 3.0)*0.01;
	fdslide=-pow((double)p_freq_dramp, 3.0)*0.000001;
	square_duty=0.5f-p_duty*0.5f;
	square_slide=-p_duty_ramp*0.00005f;
	if(p_arp_mod>=0.0f)
		arp_mod=1.0-pow((double)p_arp_mod, 2.0)*0.9;
	else
		arp_mod=1.0+pow((double)p_arp_mod, 2.0)*10.0;
	arp_time=0;
	arp_limit=(int)(pow(1.0f-p_arp_speed, 2.0f)*20000+32);
	if(p_arp_speed==1.0f)
		arp_limit=0;
	if(!restart)
	{
		// reset filter
		fltp=0.0f;
		fltdp=0.0f;
		fltw=pow(p_lpf_freq, 3.0f)*0.1f;
		fltw_d=1.0f+p_lpf_ramp*0.0001f;
		fltdmp=5.0f/(1.0f+pow(p_lpf_resonance, 2.0f)*20.0f)*(0.01f+fltw);
		if(fltdmp>0.8f) fltdmp=0.8f;
		fltphp=0.0f;
		flthp=pow(p_hpf_freq, 2.0f)*0.1f;
		flthp_d=1.0+p_hpf_ramp*0.0003f;
		// reset vibrato
		vib_phase=0.0f;
		vib_speed=pow(p_vib_speed, 2.0f)*0.01f;
		vib_amp=p_vib_strength*0.5f;
		// reset envelope
		env_vol=0.0f;
		env_stage=0;
		env_time=0;
		env_length[0]=(int)(p_env_attack*p_env_attack*100000.0f);
		env_length[1]=(int)(p_env_sustain*p_env_sustain*100000.0f);
		env_length[2]=(int)(p_env_decay*p_env_decay*100000.0f);

		fphase=pow(p_pha_offset, 2.0f)*1020.0f;
		if(p_pha_offset<0.0f) fphase=-fphase;
		fdphase=pow(p_pha_ramp, 2.0f)*1.0f;
		if(p_pha_ramp<0.0f) fdphase=-fdphase;
		iphase=abs((int)fphase);
		ipp=0;
		for(int i=0;i<1024;i++)
			phaser_buffer[i]=0.0f;

		for(int i=0;i<32;i++)
			noise_buffer[i]=frnd(2.0f)-1.0f;

		rep_time=0;
		rep_limit=(int)(pow(1.0f-p_repeat_speed, 2.0f)*20000+32);
		if(p_repeat_speed==0.0f)
			rep_limit=0;
	}
}
Example #23
0
	void SfxrInstance::getAudio(float *aBuffer, unsigned int aSamples)
	{
		float *buffer = aBuffer;
		unsigned int i;
		for(i = 0; i < aSamples; i++)
		{
			if(!playing_sample)
			{
				*aBuffer = 0;
				aBuffer++;
				continue;
			}

			rep_time++;
			if(rep_limit!=0 && rep_time>=rep_limit)
			{
				rep_time=0;
				resetSample(true);
			}

			// frequency envelopes/arpeggios
			arp_time++;
			if(arp_limit!=0 && arp_time>=arp_limit)
			{
				arp_limit=0;
				fperiod*=arp_mod;
			}
			fslide+=fdslide;
			fperiod*=fslide;
			if(fperiod>fmaxperiod)
			{
				fperiod=fmaxperiod;
				if(mParams.p_freq_limit>0.0f)
				{
					if (mFlags & LOOPING)
					{
						resetSample(false);
					}
					else
					{
						playing_sample=false;
					}
				}
			}
			float rfperiod=(float)fperiod;
			if(vib_amp>0.0f)
			{
				vib_phase+=vib_speed;
				rfperiod=(float)(fperiod*(1.0+sin(vib_phase)*vib_amp));
			}
			period=(int)rfperiod;
			if(period<8) period=8;
			square_duty+=square_slide;
			if(square_duty<0.0f) square_duty=0.0f;
			if(square_duty>0.5f) square_duty=0.5f;		
			// volume envelope
			env_time++;
			if(env_time>env_length[env_stage])
			{
				env_time=0;
				env_stage++;
				if(env_stage==3)
				{
					if (mFlags & LOOPING)
					{
						resetSample(false);
					}
					else
					{
						playing_sample=false;
					}
				}
			}
			if (env_stage == 0)
			{
				if (env_length[0])
					env_vol = (float)env_time / env_length[0];
				else
					env_vol = 0;
			}
			if (env_stage == 1)
			{
				if (env_length[1])
					env_vol = 1.0f + (float)pow(1.0f - (float)env_time / env_length[1], 1.0f)*2.0f*mParams.p_env_punch;
				else
					env_vol = 0;
			}
			if (env_stage == 2)
			{
				if (env_length[2])
					env_vol = 1.0f - (float)env_time / env_length[2];
				else
					env_vol = 0;
			}

			// phaser step
			fphase+=fdphase;
			iphase=abs((int)fphase);
			if(iphase>1023) iphase=1023;

			if(flthp_d!=0.0f)
			{
				flthp*=flthp_d;
				if(flthp<0.00001f) flthp=0.00001f;
				if(flthp>0.1f) flthp=0.1f;
			}

			float ssample=0.0f;
			for(int si=0;si<8;si++) // 8x supersampling
			{
				float sample=0.0f;
				phase++;
				if(phase>=period)
				{
					//				phase=0;
					phase%=period;
					if(mParams.wave_type==3)
						for(int i=0;i<32;i++)
							noise_buffer[i]=frnd(2.0f)-1.0f;
				}
				// base waveform
				float fp=(float)phase/period;
				switch(mParams.wave_type)
				{
				case 0: // square
					if(fp<square_duty)
						sample=0.5f;
					else
						sample=-0.5f;
					break;
				case 1: // sawtooth
					sample=1.0f-fp*2;
					break;
				case 2: // sine
					sample=(float)sin(fp*2*M_PI);
					break;
				case 3: // noise
					sample=noise_buffer[phase*32/period];
					break;
				}
				// lp filter
				float pp=fltp;
				fltw*=fltw_d;
				if(fltw<0.0f) fltw=0.0f;
				if(fltw>0.1f) fltw=0.1f;
				if(mParams.p_lpf_freq!=1.0f)
				{
					fltdp+=(sample-fltp)*fltw;
					fltdp-=fltdp*fltdmp;
				}
				else
				{
					fltp=sample;
					fltdp=0.0f;
				}
				fltp+=fltdp;
				// hp filter
				fltphp+=fltp-pp;
				fltphp-=fltphp*flthp;
				sample=fltphp;
				// phaser
				phaser_buffer[ipp&1023]=sample;
				sample+=phaser_buffer[(ipp-iphase+1024)&1023];
				ipp=(ipp+1)&1023;
				// final accumulation and envelope application
				ssample+=sample*env_vol;
			}
			ssample=ssample/8*mParams.master_vol;

			ssample*=2.0f*mParams.sound_vol;

			if(buffer!=NULL)
			{
				if(ssample>1.0f) ssample=1.0f;
				if(ssample<-1.0f) ssample=-1.0f;
				*buffer++=ssample;
			}
		}

	}
Example #24
0
	result Sfxr::loadPreset(int aPresetNo, int aRandSeed)
	{
		if (aPresetNo < 0 || aPresetNo > 6)
			return INVALID_PARAMETER;

		resetParams();
		mRand.srand(aRandSeed);
		switch(aPresetNo)
		{
		case 0: // pickup/coin
			mParams.p_base_freq=0.4f+frnd(0.5f);
			mParams.p_env_attack=0.0f;
			mParams.p_env_sustain=frnd(0.1f);
			mParams.p_env_decay=0.1f+frnd(0.4f);
			mParams.p_env_punch=0.3f+frnd(0.3f);
			if(rnd(1))
			{
				mParams.p_arp_speed=0.5f+frnd(0.2f);
				mParams.p_arp_mod=0.2f+frnd(0.4f);
			}
			break;
		case 1: // laser/shoot
			mParams.wave_type=rnd(2);
			if(mParams.wave_type==2 && rnd(1))
				mParams.wave_type=rnd(1);
			mParams.p_base_freq=0.5f+frnd(0.5f);
			mParams.p_freq_limit=mParams.p_base_freq-0.2f-frnd(0.6f);
			if(mParams.p_freq_limit<0.2f) mParams.p_freq_limit=0.2f;
			mParams.p_freq_ramp=-0.15f-frnd(0.2f);
			if(rnd(2)==0)
			{
				mParams.p_base_freq=0.3f+frnd(0.6f);
				mParams.p_freq_limit=frnd(0.1f);
				mParams.p_freq_ramp=-0.35f-frnd(0.3f);
			}
			if(rnd(1))
			{
				mParams.p_duty=frnd(0.5f);
				mParams.p_duty_ramp=frnd(0.2f);
			}
			else
			{
				mParams.p_duty=0.4f+frnd(0.5f);
				mParams.p_duty_ramp=-frnd(0.7f);
			}
			mParams.p_env_attack=0.0f;
			mParams.p_env_sustain=0.1f+frnd(0.2f);
			mParams.p_env_decay=frnd(0.4f);
			if(rnd(1))
				mParams.p_env_punch=frnd(0.3f);
			if(rnd(2)==0)
			{
				mParams.p_pha_offset=frnd(0.2f);
				mParams.p_pha_ramp=-frnd(0.2f);
			}
			if(rnd(1))
				mParams.p_hpf_freq=frnd(0.3f);
			break;
		case 2: // explosion
			mParams.wave_type=3;
			if(rnd(1))
			{
				mParams.p_base_freq=0.1f+frnd(0.4f);
				mParams.p_freq_ramp=-0.1f+frnd(0.4f);
			}
			else
			{
				mParams.p_base_freq=0.2f+frnd(0.7f);
				mParams.p_freq_ramp=-0.2f-frnd(0.2f);
			}
			mParams.p_base_freq*=mParams.p_base_freq;
			if(rnd(4)==0)
				mParams.p_freq_ramp=0.0f;
			if(rnd(2)==0)
				mParams.p_repeat_speed=0.3f+frnd(0.5f);
			mParams.p_env_attack=0.0f;
			mParams.p_env_sustain=0.1f+frnd(0.3f);
			mParams.p_env_decay=frnd(0.5f);
			if(rnd(1)==0)
			{
				mParams.p_pha_offset=-0.3f+frnd(0.9f);
				mParams.p_pha_ramp=-frnd(0.3f);
			}
			mParams.p_env_punch=0.2f+frnd(0.6f);
			if(rnd(1))
			{
				mParams.p_vib_strength=frnd(0.7f);
				mParams.p_vib_speed=frnd(0.6f);
			}
			if(rnd(2)==0)
			{
				mParams.p_arp_speed=0.6f+frnd(0.3f);
				mParams.p_arp_mod=0.8f-frnd(1.6f);
			}
			break;
		case 3: // powerup
			if(rnd(1))
				mParams.wave_type=1;
			else
				mParams.p_duty=frnd(0.6f);
			if(rnd(1))
			{
				mParams.p_base_freq=0.2f+frnd(0.3f);
				mParams.p_freq_ramp=0.1f+frnd(0.4f);
				mParams.p_repeat_speed=0.4f+frnd(0.4f);
			}
			else
			{
				mParams.p_base_freq=0.2f+frnd(0.3f);
				mParams.p_freq_ramp=0.05f+frnd(0.2f);
				if(rnd(1))
				{
					mParams.p_vib_strength=frnd(0.7f);
					mParams.p_vib_speed=frnd(0.6f);
				}
			}
			mParams.p_env_attack=0.0f;
			mParams.p_env_sustain=frnd(0.4f);
			mParams.p_env_decay=0.1f+frnd(0.4f);
			break;
		case 4: // hit/hurt
			mParams.wave_type=rnd(2);
			if(mParams.wave_type==2)
				mParams.wave_type=3;
			if(mParams.wave_type==0)
				mParams.p_duty=frnd(0.6f);
			mParams.p_base_freq=0.2f+frnd(0.6f);
			mParams.p_freq_ramp=-0.3f-frnd(0.4f);
			mParams.p_env_attack=0.0f;
			mParams.p_env_sustain=frnd(0.1f);
			mParams.p_env_decay=0.1f+frnd(0.2f);
			if(rnd(1))
				mParams.p_hpf_freq=frnd(0.3f);
			break;
		case 5: // jump
			mParams.wave_type=0;
			mParams.p_duty=frnd(0.6f);
			mParams.p_base_freq=0.3f+frnd(0.3f);
			mParams.p_freq_ramp=0.1f+frnd(0.2f);
			mParams.p_env_attack=0.0f;
			mParams.p_env_sustain=0.1f+frnd(0.3f);
			mParams.p_env_decay=0.1f+frnd(0.2f);
			if(rnd(1))
				mParams.p_hpf_freq=frnd(0.3f);
			if(rnd(1))
				mParams.p_lpf_freq=1.0f-frnd(0.6f);
			break;
		case 6: // blip/select
			mParams.wave_type=rnd(1);
			if(mParams.wave_type==0)
				mParams.p_duty=frnd(0.6f);
			mParams.p_base_freq=0.2f+frnd(0.4f);
			mParams.p_env_attack=0.0f;
			mParams.p_env_sustain=0.1f+frnd(0.1f);
			mParams.p_env_decay=frnd(0.2f);
			mParams.p_hpf_freq=0.1f;
			break;
		}
		return 0;
	}
Example #25
0
UBool PathFinder::LookFor(const ULong & flags, const ULong & f, const EERIE_3D & pos, const Float & radius, SLong * rstep, UWord ** rlist)
{
    Void * ptr;
    ULong step_c, to, last, next;
    SLong temp_c(0), path_c(0);
    UWord * temp_d = NULL, *path_d = NULL;

    Clean();
    //Check if params are valid
    if (!rlist || !rstep)
    {
        Clean();
        *rstep = 0;
        return UFALSE;
    }

    if (radius <= MIN_RADIUS)
    {
        *rlist = (UWord *)malloc(sizeof(UWord));
        ** rlist = (UWord)f;
        *rstep = 1;
        Clean();
        return UTRUE;
    }

    to = GetNearestNode(pos);

    last = f;

    step_c = Random() % 5 + 5;

    for (ULong i(0); i < step_c; i++)
    {
        EERIE_3D pos;

        pos.x = map_d[to].pos.x + radius * frnd();
        pos.y = map_d[to].pos.y + radius * frnd();
        pos.z = map_d[to].pos.z + radius * frnd();
        next = GetNearestNode(pos);

        if (Move(flags, last, next, &temp_c, &temp_d) && temp_c)
        {
            if ((path_c + temp_c - 1) <= 0)
            {
                if (temp_d)
                {
                    free(temp_d);
                    temp_d = NULL;
                }

                if (path_d)
                {
                    free(path_d);
                    path_d = NULL;
                }

                Clean();
                *rstep = 0;
                return UFALSE;
            }

            if (!(ptr = realloc(path_d, sizeof(UWord) * (path_c + temp_c - 1))))
            {
                if (temp_d)
                {
                    free(temp_d);
                    temp_d = NULL;
                }

                Clean();
                *rstep = 0;
                return UFALSE;
            }

            //Add temp path to wander around path
            path_d = (UWord *)ptr;
            memcpy(&path_d[path_c], temp_d, sizeof(UWord) *(temp_c - 1));
            path_c += temp_c - 1;

            //Free temp path
            free(temp_d), temp_d = NULL, temp_c = 0;
        }
        else i--;

        last = next;
    }

    //Close wander around path (return to start position)
    if (!path_c)
    {
        Clean(); // Cyril
        *rstep = 0;
        return UFALSE;
    }

    *rlist = path_d;
    *rstep = path_c;
    Clean(); // Cyril
    return UTRUE;
}
Example #26
0
static void
bloops_synth(int length, float* buffer)
{
  int bi, t, i, si;

  while (length--)
  {
    int samplecount = 0;
    float allsample = 0.0f;

    for (bi = 0; bi < BLOOPS_MAX_CHANNELS; bi++)
    {
      int moreframes = 0;
      bloops *B = MIXER->B[bi];
      if (B == NULL)
        continue;
      for (t = 0; t < BLOOPS_MAX_TRACKS; t++)
      {
        bloopsavoice *A = &B->voices[t];
        bloopsatrack *track = A->track;
        if (track == NULL)
          continue;

        if (track->notes)
        {
          if (A->frames == A->nextnote[0])
          {
            if (A->nextnote[1] < track->nlen)
            {
              bloopsanote *note = &track->notes[A->nextnote[1]];
              float freq = A->params.freq;
              if (note->tone != 'n')
                freq = bloops_note_freq(note->tone, (int)note->octave);
              if (freq == 0.0f) {
                A->period = 0.0f;
                A->state = BLOOPS_STOP;
              } else {
                bloopsanote *note = &track->notes[A->nextnote[1]];
                bloopsafx *fx = note->FX;
                while (fx) {
                  switch (fx->cmd) {
                    case BLOOPS_FX_VOLUME:    FX(fx, A->params.volume);     break;
                    case BLOOPS_FX_PUNCH:     FX(fx, A->params.punch);      break;
                    case BLOOPS_FX_ATTACK:    FX(fx, A->params.attack);     break;
                    case BLOOPS_FX_SUSTAIN:   FX(fx, A->params.sustain);    break;
                    case BLOOPS_FX_DECAY:     FX(fx, A->params.decay);      break;
                    case BLOOPS_FX_SQUARE:    FX(fx, A->params.square);     break;
                    case BLOOPS_FX_SWEEP:     FX(fx, A->params.sweep);      break;
                    case BLOOPS_FX_VIBE:      FX(fx, A->params.vibe);       break;
                    case BLOOPS_FX_VSPEED:    FX(fx, A->params.vspeed);     break;
                    case BLOOPS_FX_VDELAY:    FX(fx, A->params.vdelay);     break;
                    case BLOOPS_FX_LPF:       FX(fx, A->params.lpf);        break;
                    case BLOOPS_FX_LSWEEP:    FX(fx, A->params.lsweep);     break;
                    case BLOOPS_FX_RESONANCE: FX(fx, A->params.resonance);  break;
                    case BLOOPS_FX_HPF:       FX(fx, A->params.hpf);        break;
                    case BLOOPS_FX_HSWEEP:    FX(fx, A->params.hsweep);     break;
                    case BLOOPS_FX_ARP:       FX(fx, A->params.arp);        break;
                    case BLOOPS_FX_ASPEED:    FX(fx, A->params.aspeed);     break;
                    case BLOOPS_FX_PHASE:     FX(fx, A->params.phase);      break;
                    case BLOOPS_FX_PSWEEP:    FX(fx, A->params.psweep);     break;
                    case BLOOPS_FX_REPEAT:    FX(fx, A->params.repeat);     break;
                  }
                  fx = fx->next;
                }

                bloops_reset_voice(A);
                bloops_start_voice(A);
                A->period = 100.0 / (freq * freq + 0.001);
              }

              float length = 4.0f / note->duration;
              A->nextnote[0] += (int)(tempo2frames(B->tempo) * (length + length * (1 - 1.0f / (1 << note->dotted))));
            }
            A->nextnote[1]++;
          }

          if (A->nextnote[1] <= track->nlen)
            moreframes++;
        }
        else
        {
          moreframes++;
        }

        A->frames++;

        if (A->state == BLOOPS_STOP)
          continue;

        samplecount++;
        A->repeat++;
        if (A->limit != 0 && A->repeat >= A->limit)
        {
          A->repeat = 0;
          bloops_reset_voice(A);
        }

        A->atime++;
        if (A->alimit != 0 && A->atime >= A->alimit)
        {
          A->alimit = 0;
          A->period *= A->arp;
        }

        A->slide += A->dslide;
        A->period *= A->slide;
        if (A->period > A->maxperiod)
        {
          A->period = A->maxperiod;
          if (A->params.limit > 0.0f)
            A->state = BLOOPS_STOP;
        }

        float rfperiod = A->period;
        if (A->vdelay > 0.0f)
        {
          A->vibe += A->vspeed;
          rfperiod = A->period * (1.0 + sin(A->vibe) * A->vdelay);
        }

        int period = (int)rfperiod;
        if (period < 8) period = 8;
        A->square += A->sweep;
        if(A->square < 0.0f) A->square = 0.0f;
        if(A->square > 0.5f) A->square = 0.5f;    

        A->time++;
        while (A->time >= A->length[A->stage])
        {
          A->time = 0;
          A->stage++;
          if (A->stage == 3)
            A->state = BLOOPS_STOP;
        }

        switch (A->stage) {
          case 0:
            A->volume = (float)A->time / A->length[0];
          break;
          case 1:
            A->volume = 1.0f + (1.0f - (float)A->time / A->length[1]) * 2.0f * A->params.punch;
          break;
          case 2:
            A->volume = 1.0f - (float)A->time / A->length[2];
          break;
        }

        A->fphase += A->dphase;
        A->iphase = abs((int)A->fphase);
        if (A->iphase > 1023) A->iphase = 1023;

        if (A->filter[7] != 0.0f)
        {
          A->filter[6] *= A->filter[7];
          if (A->filter[6] < 0.00001f) A->filter[6] = 0.00001f;
          if (A->filter[6] > 0.1f)     A->filter[6] = 0.1f;
        }

        float ssample = 0.0f;
        for (si = 0; si < 8; si++)
        {
          float sample = 0.0f;
          A->phase++;
          if (A->phase >= period)
          {
            A->phase %= period;
            if (A->params.type == BLOOPS_NOISE)
              for (i = 0; i < 32; i++)
                A->noise[i] = frnd(2.0f) - 1.0f;
          }

          float fp = (float)A->phase / period;
          switch (A->params.type)
          {
            case BLOOPS_SQUARE:
              if (fp < A->square)
                sample = 0.5f;
              else
                sample = -0.5f;
            break;
            case BLOOPS_SAWTOOTH:
              sample = 1.0f - fp * 2;
            break;
            case BLOOPS_SINE:
              sample = (float)sin(fp * 2 * PI);
            break;
            case BLOOPS_NOISE:
              sample = A->noise[A->phase * 32 / period];
            break;
          }

          float pp = A->filter[0];
          A->filter[2] *= A->filter[3];
          if (A->filter[2] < 0.0f) A->filter[2] = 0.0f;
          if (A->filter[2] > 0.1f) A->filter[2] = 0.1f;
          if (A->params.lpf != 1.0f)
          {
            A->filter[1] += (sample - A->filter[0]) * A->filter[2];
            A->filter[1] -= A->filter[1] * A->filter[4];
          }
          else
          {
            A->filter[0] = sample;
            A->filter[1] = 0.0f;
          }
          A->filter[0] += A->filter[1];

          A->filter[5] += A->filter[0] - pp;
          A->filter[5] -= A->filter[5] * A->filter[6];
          sample = A->filter[5];

          A->phaser[A->phasex & 1023] = sample;
          sample += A->phaser[(A->phasex - A->iphase + 1024) & 1023];
          A->phasex = (A->phasex + 1) & 1023;

          ssample += sample * A->volume;
        }
        ssample = ssample / 8 * B->volume;
        ssample *= 2.0f * A->params.volume;

        if (ssample > 1.0f)  ssample = 1.0f;
        if (ssample < -1.0f) ssample = -1.0f;
        allsample += ssample;
      }
      if (moreframes == 0)
        B->state = BLOOPS_STOP;
    }

    *buffer++ = allsample;
  }
}
Example #27
0
// check attack task for Group
void AIAttack_CheckTask(string sGroupID)
{
	ref rG1 = Group_GetGroupByID(sGroupID);
	ref rG2 = Group_GetGroupByID(rG1.Task.Target);

	string sGroupType1 = Group_GetTypeR(rG1);

	ref rCharacter1 = Group_GetGroupCommanderR(rG1);

	// skip if group is player group
	if (sGroupID == PLAYER_GROUP) { return; }
	
	// if group task is lock, check for task complete, if not - continue task
	float fAng = frnd() * PIm2;
	if (Group_isDeadR(rG2))
	{
		switch (sGroupType1)
		{
			case "trade":
				Group_SetTaskMove(sGroupID, stf(rG1.Task.Target.Pos.x), stf(rG1.Task.Target.Pos.z));
			break;
			case "war":
				Group_SetTaskMove(sGroupID, 10000.0 * sin(fAng) , 10000.0 * cos(fAng));
			break;
			case "pirate":
				Group_SetTaskMove(sGroupID, 10000.0 * sin(fAng) , 10000.0 * cos(fAng));
			break;
		}
		// find new task
		return;
	}

	if (!Group_isTaskLockR(rG1))
	{
		float fHP1 = Group_GetPowerHP_R(rG1);
		float fHP2 = Group_GetPowerHP_R(rG2);
		float fAHP1 = Group_GetAttackHPDistance_R(rG1, 300.0);

		float fAHPRatio1 = fHP1 / (fAHP1 + 0.0001);
		float fHPRatio1 = fHP1 / (fHP2 + 0.0001);

		float fLeadership = MakeFloat(GetSummonSkillFromName(rCharacter1, SKILL_LEADERSHIP)) / SKILL_MAX;

		float fTmp = fAHPRatio1;// * Clampf(fLeadership + 0.01);

		switch (AIAttack_SelectTask(sGroupType1, fTmp))
		{
			case AITASK_RUNAWAY:
				Group_SetTaskRunaway(sGroupID);
				return;
			break;
		}
	}

	// check attack task for dead targets
	int iIndex = 0;

	int iCharactersNum2 = Group_GetCharactersNumR(rG2);
	
	// find targets for rG1
	int i = 0;
	while (true)
	{
		int iCharacterIndex = Group_GetCharacterIndexR(rG1, i); i++;
		if (iCharacterIndex < 0) { break; }
		ref rCharacter = GetCharacter(iCharacterIndex);
		if (LAi_IsDead(rCharacter)) { continue; }
		if (CheckAttribute(rCharacter, "SeaAI.Task"))
		{
			if (sti(rCharacter.SeaAI.Task) != AITASK_ATTACK) { continue; }
			if (!LAi_IsDead(&Characters[sti(rCharacter.SeaAI.Task.Target)])) { continue; }
		}

		int iCharacterVictim = -1;
		while (iCharacterVictim < 0)
		{
			iCharacterVictim = Group_GetCharacterIndexR(rG2, iIndex); 
			if (iCharacterVictim < 0) { iIndex = 0; continue; }
			if (LAi_IsDead(&Characters[iCharacterVictim])) { iCharacterVictim = -1; }
			iIndex++;
		}
    
		Ship_SetTaskAttack(SECONDARY_TASK, iCharacterIndex, iCharacterVictim);
	}		
}      	
Example #28
0
int	main(int argc, char* argv[])
{
	char*	infile = NULL;
	char*	outfile = NULL;
	int	tree_depth = 6;
	int	tile_size = 256;

	for ( int arg = 1; arg < argc; arg++ ) {
		if ( argv[arg][0] == '-' ) {
			// command-line switch.
			
			switch ( argv[arg][1] ) {
			case 'h':
			case '?':
				print_usage();
				exit( 1 );
				break;

			case 't':
				// Set the tilesize.
				if (arg + 1 >= argc) {
					printf("error: -t option requires an integer for tile_size\n");
					print_usage();
					exit(1);
				}
				arg++;
				tile_size = atoi(argv[arg]);
				break;
			case 'd':
				// Tree depth.
				if (arg + 1 >= argc) {
					printf("error: -d option requires an integer for tree_depth\n");
					print_usage();
					exit(1);
				}
				arg++;
				tree_depth = atoi(argv[arg]);
				break;

			default:
				printf("error: unknown command-line switch -%c\n", argv[arg][1]);
				exit(1);
				break;
			}

		} else {
			// File argument.
			if ( infile == NULL ) {
				infile = argv[arg];
			} else if ( outfile == NULL ) {
				outfile = argv[arg];
			} else {
				// This looks like extra noise on the command line; complain and exit.
				printf( "argument '%s' looks like extra noise; exiting.\n", argv[arg]);
				print_usage();
				exit( 1 );
			}
		}
	}

	// Must specify input filename.
	if (infile == NULL) {
		printf("error: you must supply an input filename which points to a .jpg image\n");
		print_usage();
		exit(1);
	}

	// Must specify an output filename.
	if (outfile == NULL) {
		printf("error: you must specify an output filename, for the texture quadtree output\n");
		print_usage();
		exit(1);
	}

	// Validate the tile_size.  Must be a power of two.
	int	logged_tile_size = 1 << frnd(log2((float) tile_size));
	if (tile_size <= 0 || logged_tile_size != tile_size) {
		printf("error: tile_size must be a power of two.\n");
		print_usage();
		exit(1);
	}

	// Validate tree depth.  Keep it within reason.
	if (tree_depth <= 0 || tree_depth > 12)
	{
		printf("error: tree_depth out of range.  Keep it between 1 and 12.\n");
		print_usage();
		exit(1);
	}
	
	// Open input file.
	tu_file*	in = new tu_file(infile, "rb");
	if (in->get_error())
	{
		printf("Can't open input file '%s'!\n", infile);
		delete in;
		exit(1);
	}

	// Open output file.
	tu_file*	out = new tu_file(outfile, "w+b");
	if (out->get_error())
	{
		printf("Can't open output file '%s'!\n", outfile);
		delete in;
		delete out;
		exit(1);
	}

	// Start reading the input.
	jpeg::input*	j_in = jpeg::input::create(in);
	if (j_in == NULL) {
		printf("Failure reading JPEG header of input file '%s'!\n", infile);
		delete in;
		delete out;
		exit(1);
	}

	// Size the tiles.
	int	tile_dim = 1 << (tree_depth - 1);

	// Write .tqt header.
	out->write_bytes("tqt\0", 4);	// filetype tag
	out->write_le32(1);			// version number.
	out->write_le32(tree_depth);
	out->write_le32(tile_size);

	// Make a null table of contents, and write it to the file.
	array<Uint32>	toc;
	toc.resize(tqt::node_count(tree_depth));

	int	toc_start = out->get_position();
	for (int i = 0; i < toc.size(); i++) {
		toc[i] = 0;
		out->write_le32(toc[i]);
	}

	int	tile_max_source_height = int(j_in->get_height() / float(tile_dim) + 1);

	// Create a horizontal strip, as wide as the image, and tall
	// enough to cover a whole tile.
	image::rgb*	strip = image::create_rgb(j_in->get_width(), tile_max_source_height);

	// Initialize the strip by reading the first set of scanlines.
	int	next_scanline = 0;
	int	strip_top = 0;
	while (next_scanline < tile_max_source_height) {
		j_in->read_scanline(image::scanline(strip, next_scanline));
		next_scanline++;
	}

	image::rgb*	tile = image::create_rgb(tile_size, tile_size);

	printf("making leaf tiles....     ");

	// generate base level tiles.
	for (int row = 0; row < tile_dim; row++) {
		float	y0 = float(row) / tile_dim * j_in->get_height();
		float	y1 = float(row + 1) / tile_dim * j_in->get_height();

		int	lines_to_read = imin(int(y1), j_in->get_height()) - (strip_top + strip->m_height);
		if (lines_to_read > 0)
		{
			// Copy existing lines up...
			int	lines_to_keep = strip->m_height - lines_to_read;
			{for (int i = 0; i < lines_to_keep; i++) {
				memcpy(image::scanline(strip, i), image::scanline(strip, i + lines_to_read /*keep*/), strip->m_width * 3);
			}}

			// Read new lines
			{for (int i = lines_to_keep; i < strip->m_height; i++) {
				j_in->read_scanline(image::scanline(strip, i));
			}}

			strip_top += lines_to_read;
		}

		for (int col = 0; col < tile_dim; col++) {
			float	x0 = float(col) / tile_dim * j_in->get_width();
			float	x1 = float(col + 1) / tile_dim * j_in->get_width();

			// Resample from the input strip to the output tile.
			image::resample(tile, 0, 0, tile_size - 1, tile_size - 1,
					strip, x0, y0 - strip_top, x1, y1 - strip_top);

			// Update the table of contents with an offset
			// to the data we're about to write.
			int	offset = out->get_position();
			int	quadtree_index = tqt::node_index(tree_depth - 1, col, row);
			toc[quadtree_index] = offset;

			// Write the jpeg data.
			image::write_jpeg(out, tile, 90);

			int	percent_done = int(100.f * float(col + row * tile_dim) / (tile_dim * tile_dim));
			printf("\b\b\b\b\b\b%3d%% %c", percent_done, spinner[(spin_count++)&3]);
		}
	}


	// Done reading the input file.
	delete j_in;
	delete in;

	delete strip;
	delete tile;	// done with the working tile surface.

	printf("\n");

	printf("making interior tiles....");

	// Now generate the upper levels of the tree by resampling the
	// lower levels.
	// 
	// The output file is both input and output at this point.
	tqt_info	inf(out, &toc, tree_depth, tile_size);
	image::rgb*	root_tile = generate_tiles(&inf, 0, 0, 0);

	delete root_tile;	// dispose of root tile.

	// Write the TOC back into the head of the file.
	out->set_position(toc_start);
	{for (int i = 0; i < toc.size(); i++) {
		out->write_le32(toc[i]);
	}}

	delete out;

	return 0;
}
Example #29
0
	void	root::set_background_alpha(float alpha)
	{
		m_background_color.m_a = iclamp(frnd(alpha * 255.0f), 0, 255);
	}
Example #30
0
void SynthSample(int length, float* buffer, FILE* file)
{
	for(int i=0;i<length;i++)
	{
		if(!havePlayingSample())
			break;

		float ssample=0.0f;
		for(int j=0;j<CHANNEL_N;j++)
		{
			if(!channels[j].playing_sample)
				continue;

			// volume envelope
			channels[j].env_time++;
			if(channels[j].env_time>channels[j].env_length[channels[j].env_stage])
			{
				channels[j].env_time=0;
				channels[j].env_stage++;
				if(channels[j].env_stage==4)
					channels[j].playing_sample=false;
			}
			if(channels[j].env_stage==0) continue;

			switch(channels[j].env_stage)
			{
				case 1: channels[j].env_vol=(float)channels[j].env_time/channels[j].env_length[1]; break;
				case 2: channels[j].env_vol=1.0f+pow(1.0f-(float)channels[j].env_time/channels[j].env_length[2], 1.0f)*2.0f*channels[j].p_env_punch; break;
				case 3: channels[j].env_vol=1.0f-(float)channels[j].env_time/channels[j].env_length[3]; break;
			}

			channels[j].rep_time++;
			if(channels[j].rep_limit!=0 && channels[j].rep_time>=channels[j].rep_limit)
			{
				channels[j].rep_time=0;
				ResetSample(true, j);
			}

			// frequency envelopes/arpeggios
			channels[j].arp_time++;
			if(channels[j].arp_limit!=0 && channels[j].arp_time>=channels[j].arp_limit)
			{
				channels[j].arp_limit=0;
				channels[j].fperiod*=channels[j].arp_mod;
			}
			channels[j].fslide+=channels[j].fdslide;
			channels[j].fperiod*=channels[j].fslide;
			if(channels[j].fperiod>channels[j].fmaxperiod)
			{
				channels[j].fperiod=channels[j].fmaxperiod;
				if(channels[j].p_freq_limit>0.0f)
					channels[j].playing_sample=false;
			}
			float rfperiod=channels[j].fperiod;
			if(channels[j].vib_amp>0.0f)
			{
				channels[j].vib_phase+=channels[j].vib_speed;
				rfperiod=channels[j].fperiod*(1.0+sin(channels[j].vib_phase)*channels[j].vib_amp);
			}
			channels[j].period=(int)rfperiod;
			if(channels[j].period<8) channels[j].period=8;
			channels[j].square_duty+=channels[j].square_slide;
			if(channels[j].square_duty<0.0f) channels[j].square_duty=0.0f;
			if(channels[j].square_duty>0.5f) channels[j].square_duty=0.5f;

			// phaser step
			channels[j].fphase+=channels[j].fdphase;
			channels[j].iphase=abs((int)channels[j].fphase);
			if(channels[j].iphase>=PHASER_BUFFER_SIZE) channels[j].iphase=PHASER_BUFFER_SIZE;

			if(channels[j].flthp_d!=0.0f)
			{
				channels[j].flthp*=channels[j].flthp_d;
				if(channels[j].flthp<0.00001f) channels[j].flthp=0.00001f;
				if(channels[j].flthp>0.1f) channels[j].flthp=0.1f;
			}
			float sub_ssample = 0.0f;
			for(int si=0;si<8;si++) // 8x supersampling
			{
				float sample=0.0f;
				channels[j].phase++;
				if(channels[j].phase>=channels[j].period)
				{
	//				phase=0;
					channels[j].phase%=channels[j].period;
					if(channels[j].wave_type==3)
						for(int i=0;i<32;i++)
							channels[j].noise_buffer[i]=frnd(2.0f)-1.0f;
				}
				// base waveform
				float fp=(float)channels[j].phase/channels[j].period;
				switch(channels[j].wave_type)
				{
				case 0: // square
					if(fp<channels[j].square_duty)
						sample=0.5f;
					else
						sample=-0.5f;
					break;
				case 1: // sawtooth
					sample=1.0f-fp*2;
					break;
				case 2: // sine
					sample=(float)sin(fp*2*PI);
					break;
				case 3: // noise
					sample=channels[j].noise_buffer[channels[j].phase*32/channels[j].period];
					break;
				}
				// lp filter
				float pp=channels[j].fltp;
				channels[j].fltw*=channels[j].fltw_d;
				if(channels[j].fltw<0.0f) channels[j].fltw=0.0f;
				if(channels[j].fltw>0.1f) channels[j].fltw=0.1f;
				if(channels[j].p_lpf_freq!=1.0f)
				{
					channels[j].fltdp+=(sample-channels[j].fltp)*channels[j].fltw;
					channels[j].fltdp-=channels[j].fltdp*channels[j].fltdmp;
				}
				else
				{
					channels[j].fltp=sample;
					channels[j].fltdp=0.0f;
				}


				channels[j].fltp+=channels[j].fltdp;
				// hp filter
				channels[j].fltphp+=channels[j].fltp-pp;
				channels[j].fltphp-=channels[j].fltphp*channels[j].flthp;
				sample=channels[j].fltphp;
				// phaser
				channels[j].phaser_buffer[channels[j].ipp&PHASER_BUFFER_MASK]=sample;
				sample+=channels[j].phaser_buffer[(channels[j].ipp-channels[j].iphase+PHASER_BUFFER_SIZE)&PHASER_BUFFER_MASK];
				channels[j].ipp=(channels[j].ipp+1)&PHASER_BUFFER_MASK;
				// final accumulation and envelope application
				sub_ssample+=sample*channels[j].env_vol;
			}
			ssample+=(sub_ssample/8*master_vol*master_vol_multiplier)*(2.0f*channels[j].sound_vol);
		}
		if(buffer!=NULL)
		{
			if(ssample>1.0f) ssample=1.0f;
			if(ssample<-1.0f) ssample=-1.0f;
			*buffer++=ssample;
		}
		if(file!=NULL)
		{
			// quantize depending on format
			// accumulate/count to accomodate variable sample rate?
			ssample*=4.0f; // arbitrary gain to get reasonable output volume...
			if(ssample>1.0f) ssample=1.0f;
			if(ssample<-1.0f) ssample=-1.0f;
			filesample+=ssample;
			fileacc++;
			if(wav_freq==44100 || fileacc==2)
			{
				filesample/=fileacc;
				fileacc=0;
				if(wav_bits==16)
				{
					short isample=(short)(filesample*32000);
					fwrite(&isample, 1, 2, file);
				}
				else
				{
					unsigned char isample=(unsigned char)(filesample*127+128);
					fwrite(&isample, 1, 1, file);
				}
				filesample=0.0f;
			}
			file_sampleswritten++;
		}
	}
}