示例#1
0
bool CarSound::Load(
	const std::string & carpath,
	const std::string & carname,
	Sound & sound,
	ContentManager & content,
	std::ostream & error_output)
{
	assert(!psound);

	// check for sound specification file
	std::string path_aud = carpath + "/" + carname + ".aud";
	std::ifstream file_aud(path_aud.c_str());
	if (file_aud.good())
	{
		PTree aud;
		read_ini(file_aud, aud);
		enginesounds.reserve(aud.size());
		for (const auto & i : aud)
		{
			const PTree & audi = i.second;

			std::string filename;
			std::shared_ptr<SoundBuffer> soundptr;
			if (!audi.get("filename", filename, error_output)) return false;

			enginesounds.push_back(EngineSoundInfo());
			EngineSoundInfo & info = enginesounds.back();

			if (!audi.get("MinimumRPM", info.minrpm, error_output)) return false;
			if (!audi.get("MaximumRPM", info.maxrpm, error_output)) return false;
			if (!audi.get("NaturalRPM", info.naturalrpm, error_output)) return false;

			bool powersetting;
			if (!audi.get("power", powersetting, error_output)) return false;
			if (powersetting)
				info.power = EngineSoundInfo::POWERON;
			else if (!powersetting)
				info.power = EngineSoundInfo::POWEROFF;
			else
				info.power = EngineSoundInfo::BOTH;

			info.sound_source = sound.AddSource(soundptr, 0, true, true);
			sound.SetSourceGain(info.sound_source, 0);
		}

		// set blend start and end locations -- requires multiple passes
		std::map <EngineSoundInfo *, EngineSoundInfo *> temporary_to_actual_map;
		std::list <EngineSoundInfo> poweron_sounds, poweroff_sounds;
		for (auto & info : enginesounds)
		{
			if (info.power == EngineSoundInfo::POWERON)
			{
				poweron_sounds.push_back(info);
				temporary_to_actual_map[&poweron_sounds.back()] = &info;
			}
			else if (info.power == EngineSoundInfo::POWEROFF)
			{
				poweroff_sounds.push_back(info);
				temporary_to_actual_map[&poweroff_sounds.back()] = &info;
			}
		}

		poweron_sounds.sort();
		poweroff_sounds.sort();

		// we only support 2 overlapping sounds at once each for poweron and poweroff; this
		// algorithm fails for other cases (undefined behavior)
		std::list <EngineSoundInfo> * cursounds = &poweron_sounds;
		for (int n = 0; n < 2; n++)
		{
			if (n == 1)
				cursounds = &poweroff_sounds;

			for (auto i = (*cursounds).begin(); i != (*cursounds).end(); ++i)
			{
				// set start blend
				if (i == (*cursounds).begin())
					i->fullgainrpmstart = i->minrpm;

				// set end blend
				auto inext = i;
				inext++;
				if (inext == (*cursounds).end())
					i->fullgainrpmend = i->maxrpm;
				else
				{
					i->fullgainrpmend = inext->minrpm;
					inext->fullgainrpmstart = i->maxrpm;
				}
			}

			// now assign back to the actual infos
			for (auto & info : *cursounds)
			{
				assert(temporary_to_actual_map.find(&info) != temporary_to_actual_map.end());
				*temporary_to_actual_map[&info] = info;
			}
		}
	}
	else
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "engine");
		enginesounds.push_back(EngineSoundInfo());
		enginesounds.back().sound_source = sound.AddSource(soundptr, 0, true, true);
	}

	//set up tire squeal sounds
	for (int i = 0; i < 4; ++i)
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "tire_squeal");
		tiresqueal[i] = sound.AddSource(soundptr, i * 0.25, true, true);
	}

	//set up tire gravel sounds
	for (int i = 0; i < 4; ++i)
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "gravel");
		gravelsound[i] = sound.AddSource(soundptr, i * 0.25, true, true);
	}

	//set up tire grass sounds
	for (int i = 0; i < 4; ++i)
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "grass");
		grasssound[i] = sound.AddSource(soundptr, i * 0.25, true, true);
	}

	//set up bump sounds
	for (int i = 0; i < 4; ++i)
	{
		std::shared_ptr<SoundBuffer> soundptr;
		if (i >= 2)
		{
			content.load(soundptr, carpath, "bump_rear");
		}
		else
		{
			content.load(soundptr, carpath, "bump_front");
		}
		tirebump[i] = sound.AddSource(soundptr, 0, true, false);
	}

	//set up crash sound
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "crash");
		crashsound = sound.AddSource(soundptr, 0, true, false);
	}

	//set up gear sound
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "gear");
		gearsound = sound.AddSource(soundptr, 0, true, false);
	}

	//set up brake sound
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "brake");
		brakesound = sound.AddSource(soundptr, 0, true, false);
	}

	//set up handbrake sound
	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "handbrake");
		handbrakesound = sound.AddSource(soundptr, 0, true, false);
	}

	{
		std::shared_ptr<SoundBuffer> soundptr;
		content.load(soundptr, carpath, "wind");
		roadnoise = sound.AddSource(soundptr, 0, true, true);
	}

	psound = &sound;

	return true;
}