// Sounds.cc - sound management // // Vamos Automotive Simulator // Copyright (C) 2003--2004 Sam Varner // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Sounds.h" #include "../geometry/Numeric.h" #include #include #include using Vamos_Media::Sample; using namespace Vamos_Geometry; Vamos_World:: Sounds::Sounds () : mp_engine_sound (0), mp_tire_squeal_sound (0), mp_grass_sound (0), mp_gravel_sound (0), mp_scrape_sound (0), mp_wind_sound (0), mp_soft_crash_sound (0), mp_hard_crash_sound (0) { alutInit (0, 0); } Vamos_World:: Sounds::~Sounds () { delete mp_soft_crash_sound; delete mp_hard_crash_sound; delete mp_wind_sound; delete mp_scrape_sound; delete mp_gravel_sound; delete mp_grass_sound; delete mp_tire_squeal_sound; } void Vamos_World:: Sounds::add_sample (std::string file, Sound_Type type, double volume, double pitch) { Sample* sample = 0; file = m_data_dir + file; switch (type) { case TIRE_SQUEAL: sample = mp_tire_squeal_sound = new Sample (file, volume, pitch, true); break; case GRASS: sample = mp_grass_sound = new Sample (file, volume, pitch, true); break; case GRAVEL: sample = mp_gravel_sound = new Sample (file, volume, pitch, true); break; case SCRAPE: sample = mp_scrape_sound = new Sample (file, volume, pitch, true); break; case WIND: sample = mp_wind_sound = new Sample (file, volume, pitch, true); break; case SOFT_CRASH: sample = mp_soft_crash_sound = new Sample (file, volume, pitch, false); break; case HARD_CRASH: sample = mp_hard_crash_sound = new Sample (file, volume, pitch, false); break; default: assert (false); } } void Vamos_World:: Sounds::read (std::string data_dir, std::string sounds_file) { delete mp_soft_crash_sound; delete mp_hard_crash_sound; delete mp_wind_sound; delete mp_scrape_sound; delete mp_gravel_sound; delete mp_grass_sound; delete mp_tire_squeal_sound; mp_soft_crash_sound = 0; mp_hard_crash_sound = 0; mp_wind_sound = 0; mp_scrape_sound = 0; mp_gravel_sound = 0; mp_grass_sound = 0; mp_tire_squeal_sound = 0; if (data_dir != "") m_data_dir = data_dir; if (sounds_file != "") m_sounds_file = sounds_file; Sounds_Reader reader (m_data_dir + m_sounds_file, this); } void Vamos_World:: Sounds::set_engine_sound (Sample* sound) { mp_engine_sound = sound; } void Vamos_World:: Sounds::play_engine_sound (const double pitch, double volume, const Three_Vector& position, const Three_Vector& velocity) { if (mp_engine_sound != 0) { if ((volume > 0.0) && (pitch > 0.0)) { mp_engine_sound->pitch (pitch); mp_engine_sound->volume (volume); mp_engine_sound->position (position); mp_engine_sound->velocity (velocity); mp_engine_sound->play (); } else { mp_engine_sound->pause (); } } } void Vamos_World:: Sounds::play_tire_squeal_sound (double slide, const Three_Vector& position) { double volume = slide - 0.4; if (volume > 0.0) { mp_tire_squeal_sound->pitch (std::max (1.5 - slide, 1.0)); mp_tire_squeal_sound->volume (volume); mp_tire_squeal_sound->position (position); mp_grass_sound->pause (); mp_gravel_sound->pause (); mp_scrape_sound->pause (); mp_tire_squeal_sound->play (); } else { mp_tire_squeal_sound->pause (); } } void Vamos_World:: Sounds::play_grass_sound (double speed, const Three_Vector& position) { double volume = clip (0.05 * speed, 0.0, 1.0); if (speed > 0.0) { mp_grass_sound->volume (volume); mp_tire_squeal_sound->position (position); mp_gravel_sound->pause (); mp_grass_sound->play (); } else { mp_grass_sound->pause (); } } void Vamos_World:: Sounds::play_gravel_sound (double speed, const Three_Vector& position) { double volume = clip (0.08 * speed, 0.0, 1.0); if (speed > 0.0) { mp_gravel_sound->volume (volume); mp_gravel_sound->position (position); mp_grass_sound->pause (); mp_gravel_sound->play (); } else { mp_gravel_sound->pause (); } } void Vamos_World:: Sounds::play_scrape_sound (double speed, const Three_Vector& position) { double volume = clip (0.1 * speed, 0.0, 1.0); if (speed > 0.0) { mp_scrape_sound->volume (volume); mp_scrape_sound->position (position); mp_tire_squeal_sound->pause (); mp_grass_sound->pause (); mp_gravel_sound->pause (); mp_scrape_sound->play (); } else { mp_scrape_sound->pause(); } } void Vamos_World:: Sounds::play_wind_sound (double speed, const Three_Vector& position) { double volume = clip (0.005 * speed, 0.0, 1.0); if (volume > 0.0) { mp_wind_sound->volume (volume); mp_wind_sound->position (position); mp_wind_sound->play (); } else { mp_wind_sound->pause (); } } void Vamos_World:: Sounds::play_hard_crash_sound (double speed, const Three_Vector& position) { double volume = clip (0.1 * (speed - 1.0), 0.0, 1.0); if (volume > 0.0) { mp_hard_crash_sound->volume (volume); mp_hard_crash_sound->position (position); mp_hard_crash_sound->play (); } } void Vamos_World:: Sounds::play_soft_crash_sound (double speed, const Three_Vector& position) { double volume = clip (0.1 * (speed - 1.0), 0.0, 1.0); if (volume > 0.0) { mp_soft_crash_sound->volume (volume); mp_soft_crash_sound->position (position); mp_soft_crash_sound->play (); } } // Pause all sounds. void Vamos_World:: Sounds::pause () { //! Might be good to have a registration system to make it easier //! to do something to all sounds. mp_engine_sound->pause (); mp_tire_squeal_sound->pause (); mp_grass_sound->pause (); mp_gravel_sound->pause (); mp_scrape_sound->pause (); mp_wind_sound->pause (); mp_soft_crash_sound->pause (); mp_hard_crash_sound->pause (); } //* Class Sounds_Reader //** Constructor Vamos_World:: Sounds_Reader::Sounds_Reader (std::string file_name, Sounds* sounds) : mp_sounds (sounds), m_rate (8000), // The default sample rate is 8 kHz. m_buffer_duration (0.2) { read (file_name); } void Vamos_World:: Sounds_Reader::on_start_tag (const XML_Tag& tag) { } void Vamos_World:: Sounds_Reader::on_end_tag (const XML_Tag& tag) { Sounds::Sound_Type type = Sounds::NONE; if (label () == "tire-squeal") { type = Sounds::TIRE_SQUEAL; } else if (label () == "grass-sound") { type = Sounds::GRASS; } else if (label () == "gravel-sound") { type = Sounds::GRAVEL; } else if (label () == "scrape-sound") { type = Sounds::SCRAPE; } else if (label () == "wind-sound") { type = Sounds::WIND; } else if (label () == "soft-crash-sound") { type = Sounds::SOFT_CRASH; } else if (label () == "hard-crash-sound") { type = Sounds::HARD_CRASH; } if (type != Sounds::NONE) { mp_sounds->add_sample (m_file, type, m_volume, m_pitch); } } void Vamos_World:: Sounds_Reader::on_data (std::string data) { if (data.size () == 0) { return; } std::istringstream is (data.c_str ()); if (label () == "file") { m_file = data; } else if (label () == "pitch") { is >> m_pitch; } else if (label () == "volume") { is >> m_volume; } else if (label () == "sample-rate") { is >> m_rate; } else if (label () == "buffer-duration") { is >> m_buffer_duration; } }