Example #1
0
void AmbientSounds::Update()
{
	float v_env = (Pi::worldView->GetActiveCamera()->IsExternal() ? 1.0f : 0.5f) * Sound::GetSfxVolume();

	if (Pi::player->GetFlightState() == Ship::DOCKED) {
		if (starNoise.IsPlaying()) {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			starNoise.VolumeAnimate(target, dv_dt);
			starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}
		if (atmosphereNoise.IsPlaying()) {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			atmosphereNoise.VolumeAnimate(target, dv_dt);
			atmosphereNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}
		if (planetSurfaceNoise.IsPlaying()) {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			planetSurfaceNoise.VolumeAnimate(target, dv_dt);
			planetSurfaceNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}

		if (!stationNoise.IsPlaying()) {
			const char *sounds[] = {
				"Large_Station_ambient",
				"Medium_Station_ambient",
				"Small_Station_ambient"
			};
			// just use a random station noise until we have a
			// concept of 'station size'
			stationNoise.Play(sounds[Pi::player->GetDockedWith()->GetSystemBody()->seed % 3],
					0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT);
		}
	} else if (Pi::player->GetFlightState() == Ship::LANDED) {
		/* Planet surface noise on rough-landing */
		if (starNoise.IsPlaying()) {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			starNoise.VolumeAnimate(target, dv_dt);
			starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}
		if (atmosphereNoise.IsPlaying()) {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			atmosphereNoise.VolumeAnimate(target, dv_dt);
			atmosphereNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}
		if (stationNoise.IsPlaying()) {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			stationNoise.VolumeAnimate(target, dv_dt);
			stationNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}

		// lets try something random for the time being
		if (!planetSurfaceNoise.IsPlaying()) {
			SystemBody *sbody = Pi::player->GetFrame()->GetSystemBodyFor();
			assert(sbody);
			const char *sample = NULL;

			if (sbody->m_life > fixed(1,5)) {
				const char *s[] = {
					"Wind", "Thunder_1", "Thunder_2", "Thunder_3",
					"Thunder_4", "Storm", "Rain_Light", "River",
					"RainForestIntroducedNight", "RainForestIntroduced",
					"NormalForestIntroduced"
				};
				sample = s[sbody->seed % 11];
			}
			else if (sbody->m_volatileGas > fixed(1,2)) {
				const char *s[] = {
					"Wind", "Thunder_1", "Thunder_2", "Thunder_3",
					"Thunder_4", "Storm"
				};
				sample = s[sbody->seed % 6];
			}
			else if (sbody->m_volatileGas > fixed(1,10)) {
				sample = "Wind";
			}

			if (sample) {
				planetSurfaceNoise.Play(sample, 0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT);
			}
		}
    } else if (planetSurfaceNoise.IsPlaying()) {
        // planetSurfaceNoise.IsPlaying() - if we are out of the atmosphere then stop playing
        if (Pi::player->GetFrame()->m_astroBody) {
            Body *astro = Pi::player->GetFrame()->m_astroBody;
            if (astro->IsType(Object::PLANET)) {
                double dist = Pi::player->GetPosition().Length();
                double pressure, density;
                static_cast<Planet*>(astro)->GetAtmosphericState(dist, &pressure, &density);
                if (pressure < 0.001) {
                    // Stop playing surface noise once out of the atmosphere
                    planetSurfaceNoise.Stop();
                }
            }
        }
    } else {
		if (stationNoise.IsPlaying()) {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			stationNoise.VolumeAnimate(target, dv_dt);
			stationNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}
		{
			if (Pi::game->IsNormalSpace()) {
				StarSystem *s = Pi::game->GetSpace()->GetStarSystem().Get();
				if (astroNoiseSeed != s->GetSeed()) {
					// change sound!
					astroNoiseSeed = s->GetSeed();
					float target[2] = {0.0f,0.0f};
					float dv_dt[2] = {0.1f,0.1f};
					starNoise.VolumeAnimate(target, dv_dt);
					starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
					// XXX the way Sound::Event works isn't totally obvious.
					// to destroy the object doesn't stop the sound. it is
					// really just a sound event reference
					starNoise = Sound::Event();
				}
			}
		}
		// when all the sounds are in we can use the body we are in frame of reference to
		if (!starNoise.IsPlaying()) {
			Frame *f = Pi::player->GetFrame();
			if (!f) return; // When player has no frame (game abort) then get outta here!!
			const SystemBody *sbody = f->GetSystemBodyFor();
			const char *sample = 0;
			for (; sbody && !sample; sbody = f->GetSystemBodyFor()) {
				switch (sbody->type) {
					case SystemBody::TYPE_BROWN_DWARF: sample = "Brown_Dwarf_Substellar_Object"; break;
					case SystemBody::TYPE_STAR_M: sample = "M_Red_Star"; break;
					case SystemBody::TYPE_STAR_K: sample = "K_Star"; break;
					case SystemBody::TYPE_WHITE_DWARF: sample = "White_Dwarf_Star"; break;
					case SystemBody::TYPE_STAR_G: sample = "G_Star"; break;
					case SystemBody::TYPE_STAR_F: sample = "F_Star"; break;
					case SystemBody::TYPE_STAR_A: sample = "A_Star"; break;
					case SystemBody::TYPE_STAR_B: sample = "B_Hot_Blue_STAR"; break;
					case SystemBody::TYPE_STAR_O: sample = "Blue_Super_Giant"; break;
					case SystemBody::TYPE_PLANET_GAS_GIANT: {
							if (sbody->mass > fixed(400,1)) {
								sample = "Very_Large_Gas_Giant";
							} else if (sbody->mass > fixed(80,1)) {
								sample = "Large_Gas_Giant";
							} else if (sbody->mass > fixed(20,1)) {
								sample = "Medium_Gas_Giant";
							} else {
								sample = "Small_Gas_Giant";
							}
						}
						break;
					default: sample = 0; break;
				}
				if (sample) {
					starNoise.Play(sample, 0.0f, 0.0f, Sound::OP_REPEAT);
					starNoise.VolumeAnimate(.3f*v_env, .3f*v_env, .05f, .05f);
				} else {
					// go up orbital hierarchy tree to see if we can find a sound
					f = f->m_parent;
					if (f == 0) break;
				}
			}
		}

		Body *astro;
		if ((astro = Pi::player->GetFrame()->m_astroBody) && (astro->IsType(Object::PLANET))) {
			double dist = Pi::player->GetPosition().Length();
			double pressure, density;
			static_cast<Planet*>(astro)->GetAtmosphericState(dist, &pressure, &density);
			// maximum volume at around 2km/sec at earth density, pressure
			float volume = float(density * Pi::player->GetVelocity().Length() * 0.0005);
			volume = Clamp(volume, 0.0f, 1.0f) * v_env;
			if (atmosphereNoise.IsPlaying()) {
				float target[2] = {volume, volume};
				float dv_dt[2] = {1.0f,1.0f};
				atmosphereNoise.VolumeAnimate(target, dv_dt);
			} else {
				atmosphereNoise.Play("Atmosphere_Flying", volume, volume, Sound::OP_REPEAT);
			}
		} else {
			float target[2] = {0.0f,0.0f};
			float dv_dt[2] = {1.0f,1.0f};
			atmosphereNoise.VolumeAnimate(target, dv_dt);
			atmosphereNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME);
		}
	}
}