sound works

sound works 2

sound works 3

sound works

sound works

sound works

sound works

sound works

sound fixes

fix
This commit is contained in:
milek7
2017-08-05 22:18:59 +02:00
parent 06f00ebdeb
commit 08acc60a8b
28 changed files with 1468 additions and 1499 deletions

View File

@@ -1,181 +0,0 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "AdvSound.h"
#include "Timer.h"
//---------------------------------------------------------------------------
TAdvancedSound::~TAdvancedSound()
{ // Ra: stopowanie się sypie
// SoundStart.Stop();
// SoundCommencing.Stop();
// SoundShut.Stop();
}
void TAdvancedSound::Free()
{
}
void TAdvancedSound::Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation,
vector3 const &pPosition)
{
SoundStart.Init(NameOn, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
SoundCommencing.Init(Name, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
SoundShut.Init(NameOff, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
fStartLength = SoundStart.GetWaveTime();
fShutLength = SoundShut.GetWaveTime();
SoundStart.AM = 1.0;
SoundStart.AA = 0.0;
SoundStart.FM = 1.0;
SoundStart.FA = 0.0;
SoundCommencing.AM = 1.0;
SoundCommencing.AA = 0.0;
SoundCommencing.FM = 1.0;
SoundCommencing.FA = 0.0;
defAM = 1.0;
defFM = 1.0;
SoundShut.AM = 1.0;
SoundShut.AA = 0.0;
SoundShut.FM = 1.0;
SoundShut.FA = 0.0;
}
void TAdvancedSound::Load(cParser &Parser, vector3 const &pPosition)
{
std::string nameon, name, nameoff;
double attenuation;
Parser.getTokens( 3, true, "\n\t ;," ); // samples separated with commas
Parser
>> nameon
>> name
>> nameoff;
Parser.getTokens( 1, false );
Parser
>> attenuation;
Init( nameon, name, nameoff, attenuation, pPosition );
}
void TAdvancedSound::TurnOn(bool ListenerInside, vector3 NewPosition)
{
// hunter-311211: nie trzeba czekac na ponowne odtworzenie dzwieku, az sie wylaczy
if ((State == ss_Off || State == ss_ShuttingDown) && (SoundStart.AM > 0))
{
SoundStart.ResetPosition();
SoundCommencing.ResetPosition();
SoundStart.Play(1, 0, ListenerInside, NewPosition);
// SoundStart->SetVolume(-10000);
State = ss_Starting;
fTime = 0;
}
}
void TAdvancedSound::TurnOff(bool ListenerInside, vector3 NewPosition)
{
if ((State == ss_Commencing || State == ss_Starting) && (SoundShut.AM > 0))
{
SoundStart.Stop();
SoundCommencing.Stop();
SoundShut.ResetPosition();
SoundShut.Play(1, 0, ListenerInside, NewPosition);
State = ss_ShuttingDown;
fTime = fShutLength;
// SoundShut->SetVolume(0);
}
}
void TAdvancedSound::Update(bool ListenerInside, vector3 NewPosition)
{
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
{
// SoundCommencing->SetFrequency();
SoundShut.Stop(); // hunter-311211
SoundCommencing.Play(1, DSBPLAY_LOOPING, ListenerInside, NewPosition);
}
else if (State == ss_Starting)
{
fTime += Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime >= fStartLength)
{
State = ss_Commencing;
SoundCommencing.ResetPosition();
SoundCommencing.Play(1, DSBPLAY_LOOPING, ListenerInside, NewPosition);
SoundStart.Stop();
}
else
SoundStart.Play(1, 0, ListenerInside, NewPosition);
}
else if (State == ss_ShuttingDown)
{
fTime -= Timer::GetDeltaTime();
// SoundShut->SetVolume(-1000*(4-fTime)/4);
if (fTime <= 0)
{
State = ss_Off;
SoundShut.Stop();
}
else
SoundShut.Play(1, 0, ListenerInside, NewPosition);
}
}
void TAdvancedSound::UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition)
{ // update, ale z amplituda i czestotliwoscia
if( State == ss_Off ) {
return;
}
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
{
SoundShut.Stop(); // hunter-311211
SoundCommencing.Play(A, DSBPLAY_LOOPING, ListenerInside, NewPosition);
}
else if (State == ss_Starting)
{
fTime += Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime >= fStartLength)
{
State = ss_Commencing;
SoundCommencing.ResetPosition();
SoundCommencing.Play(A, DSBPLAY_LOOPING, ListenerInside, NewPosition);
SoundStart.Stop();
}
else
SoundStart.Play(A, 0, ListenerInside, NewPosition);
}
else if (State == ss_ShuttingDown)
{
fTime -= Timer::GetDeltaTime();
// SoundShut->SetVolume(-1000*(4-fTime)/4);
if (fTime <= 0)
{
State = ss_Off;
SoundShut.Stop();
}
else
SoundShut.Play(A, 0, ListenerInside, NewPosition);
}
SoundCommencing.AdjFreq(F, Timer::GetDeltaTime());
}
void TAdvancedSound::CopyIfEmpty(TAdvancedSound &s)
{ // skopiowanie, gdyby był potrzebny, a nie został wczytany
if ((fStartLength > 0.0) || (fShutLength > 0.0))
return; // coś jest
SoundStart = s.SoundStart;
SoundCommencing = s.SoundCommencing;
SoundShut = s.SoundShut;
State = s.State;
fStartLength = s.fStartLength;
fShutLength = s.fShutLength;
defAM = s.defAM;
defFM = s.defFM;
};

View File

@@ -1,50 +0,0 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#ifndef AdvSoundH
#define AdvSoundH
#include "RealSound.h"
#include "parser.h"
typedef enum
{
ss_Off,
ss_Starting,
ss_Commencing,
ss_ShuttingDown
} TSoundState;
class TAdvancedSound
{ // klasa dźwięków mających początek, dowolnie długi środek oraz zakończenie (np. Rp1)
TRealSound SoundStart;
TRealSound SoundCommencing;
TRealSound SoundShut;
TSoundState State = ss_Off;
double fTime = 0.0;
double fStartLength = 0.0;
double fShutLength = 0.0;
double defAM = 0.0;
double defFM = 0.0;
public:
TAdvancedSound() = default;
~TAdvancedSound();
void Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation, vector3 const &pPosition);
void Load(cParser &Parser, vector3 const &pPosition);
void TurnOn(bool ListenerInside, vector3 NewPosition);
void TurnOff(bool ListenerInside, vector3 NewPosition);
void Free();
void Update(bool ListenerInside, vector3 NewPosition);
void UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition);
void CopyIfEmpty(TAdvancedSound &s);
};
//---------------------------------------------------------------------------
#endif

View File

@@ -16,7 +16,6 @@ set(SOURCES
"TrkFoll.cpp" "TrkFoll.cpp"
"VBO.cpp" "VBO.cpp"
"World.cpp" "World.cpp"
"AdvSound.cpp"
"AirCoupler.cpp" "AirCoupler.cpp"
"AnimModel.cpp" "AnimModel.cpp"
"Button.cpp" "Button.cpp"
@@ -27,7 +26,6 @@ set(SOURCES
"EU07.cpp" "EU07.cpp"
"Event.cpp" "Event.cpp"
"EvLaunch.cpp" "EvLaunch.cpp"
"FadeSound.cpp"
"Float3d.cpp" "Float3d.cpp"
"Gauge.cpp" "Gauge.cpp"
"Globals.cpp" "Globals.cpp"
@@ -45,7 +43,6 @@ set(SOURCES
"parser.cpp" "parser.cpp"
"renderer.cpp" "renderer.cpp"
"PyInt.cpp" "PyInt.cpp"
"RealSound.cpp"
"ResourceManager.cpp" "ResourceManager.cpp"
"sn_utils.cpp" "sn_utils.cpp"
"Segment.cpp" "Segment.cpp"
@@ -54,7 +51,7 @@ set(SOURCES
"stars.cpp" "stars.cpp"
"lightarray.cpp" "lightarray.cpp"
"skydome.cpp" "skydome.cpp"
"Sound.cpp" "sound.cpp"
"Spring.cpp" "Spring.cpp"
"shader.cpp" "shader.cpp"
"frustum.cpp" "frustum.cpp"
@@ -116,4 +113,13 @@ target_link_libraries(${PROJECT_NAME} Threads::Threads)
find_package(GLM REQUIRED) find_package(GLM REQUIRED)
include_directories(${GLM_INCLUDE_DIRS}) include_directories(${GLM_INCLUDE_DIRS})
#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize=undefined -g") find_package(OpenAL REQUIRED)
include_directories(${OPENAL_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${OPENAL_LIBRARY})
find_package(libsndfile REQUIRED)
include_directories(${LIBSNDFILE_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${LIBSNDFILE_LIBRARY})
#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g")

View File

@@ -0,0 +1,34 @@
# - Try to find libsndfile
# Once done, this will define
#
# LIBSNDFILE_FOUND - system has libsndfile
# LIBSNDFILE_INCLUDE_DIRS - the libsndfile include directories
# LIBSNDFILE_LIBRARIES - link these to use libsndfile
# Use pkg-config to get hints about paths
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(LIBSNDFILE_PKGCONF sndfile)
endif(PKG_CONFIG_FOUND)
# Include dir
find_path(LIBSNDFILE_INCLUDE_DIR
NAMES sndfile.h
PATHS ${LIBSNDFILE_PKGCONF_INCLUDE_DIRS}
)
# Library
find_library(LIBSNDFILE_LIBRARY
NAMES sndfile libsndfile-1
PATHS ${LIBSNDFILE_PKGCONF_LIBRARY_DIRS}
)
find_package(PackageHandleStandardArgs)
find_package_handle_standard_args(LibSndFile DEFAULT_MSG LIBSNDFILE_LIBRARY LIBSNDFILE_INCLUDE_DIR)
if(LIBSNDFILE_FOUND)
set(LIBSNDFILE_LIBRARIES ${LIBSNDFILE_LIBRARY})
set(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE_INCLUDE_DIR})
endif(LIBSNDFILE_FOUND)
mark_as_advanced(LIBSNDFILE_LIBRARY LIBSNDFILE_LIBRARIES LIBSNDFILE_INCLUDE_DIR LIBSNDFILE_INCLUDE_DIRS)

View File

@@ -23,8 +23,8 @@ class TModel3d; //siatka modelu wspólna dla egzemplarzy
class TSubModel; // fragment modelu (tu do wyświetlania terenu) class TSubModel; // fragment modelu (tu do wyświetlania terenu)
class TMemCell; // komórka pamięci class TMemCell; // komórka pamięci
class cParser; class cParser;
class TRealSound; // dźwięk ze współrzędnymi XYZ class sound;
class TTextSound; // dźwięk ze stenogramem class text_sound;
class TEventLauncher; class TEventLauncher;
class TTraction; // drut class TTraction; // drut
class TTractionPowerSource; // zasilanie drutów class TTractionPowerSource; // zasilanie drutów

View File

@@ -25,6 +25,7 @@ http://mozilla.org/MPL/2.0/.
#include "World.h" #include "World.h"
#include "McZapkie/mctools.h" #include "McZapkie/mctools.h"
#include "McZapkie/MOVER.h" #include "McZapkie/MOVER.h"
#include "sound.h"
#define LOGVELOCITY 0 #define LOGVELOCITY 0
#define LOGORDERS 1 #define LOGORDERS 1
@@ -1467,7 +1468,7 @@ void TController::CloseLog()
TController::~TController() TController::~TController()
{ // wykopanie mechanika z roboty { // wykopanie mechanika z roboty
delete tsGuardSignal; sound_man->destroy_sound(&tsGuardSignal);
delete TrainParams; delete TrainParams;
CloseLog(); CloseLog();
}; };
@@ -2380,7 +2381,7 @@ bool TController::DecBrake()
bool TController::IncSpeed() bool TController::IncSpeed()
{ // zwiększenie prędkości; zwraca false, jeśli dalej się nie da zwiększać { // zwiększenie prędkości; zwraca false, jeśli dalej się nie da zwiększać
if (tsGuardSignal) // jeśli jest dźwięk kierownika if (tsGuardSignal) // jeśli jest dźwięk kierownika
if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // jeśli gada, to nie jedziemy if (tsGuardSignal->is_playing()) // jeśli gada, to nie jedziemy
return false; return false;
bool OK = true; bool OK = true;
if( ( iDrivigFlags & moveDoorOpened ) if( ( iDrivigFlags & moveDoorOpened )
@@ -2864,9 +2865,8 @@ bool TController::PutCommand(std::string NewCommand, double NewValue1, double Ne
NewCommand = Global::asCurrentSceneryPath + NewCommand + ".wav"; // na razie jeden NewCommand = Global::asCurrentSceneryPath + NewCommand + ".wav"; // na razie jeden
if (FileExists(NewCommand)) if (FileExists(NewCommand))
{ // wczytanie dźwięku odjazdu podawanego bezpośrenido { // wczytanie dźwięku odjazdu podawanego bezpośrenido
tsGuardSignal = new TTextSound(NewCommand, 30, pVehicle->GetPosition().x, tsGuardSignal = sound_man->create_text_sound(NewCommand);
pVehicle->GetPosition().y, pVehicle->GetPosition().z, tsGuardSignal->position(pVehicle->GetPosition());
false);
// rsGuardSignal->Stop(); // rsGuardSignal->Stop();
iGuardRadio = 0; // nie przez radio iGuardRadio = 0; // nie przez radio
} }
@@ -2875,9 +2875,8 @@ bool TController::PutCommand(std::string NewCommand, double NewValue1, double Ne
NewCommand = NewCommand.insert(NewCommand.find_last_of("."),"radio"); // wstawienie przed kropkč NewCommand = NewCommand.insert(NewCommand.find_last_of("."),"radio"); // wstawienie przed kropkč
if (FileExists(NewCommand)) if (FileExists(NewCommand))
{ // wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie) { // wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
tsGuardSignal = new TTextSound(NewCommand, -1, pVehicle->GetPosition().x, tsGuardSignal = sound_man->create_text_sound(NewCommand);
pVehicle->GetPosition().y, pVehicle->GetPosition().z, tsGuardSignal->position(pVehicle->GetPosition());
false);
iGuardRadio = iRadioChannel; iGuardRadio = iRadioChannel;
} }
} }
@@ -4202,7 +4201,7 @@ bool TController::UpdateSituation(double dt)
->DoorOpenCtrl ) // jeśli drzwi niesterowane przez maszynistę ->DoorOpenCtrl ) // jeśli drzwi niesterowane przez maszynistę
Doors( false ); // a EZT zamknie dopiero po odegraniu komunikatu kierownika Doors( false ); // a EZT zamknie dopiero po odegraniu komunikatu kierownika
tsGuardSignal->Stop(); tsGuardSignal->stop();
// w zasadzie to powinien mieć flagę, czy jest dźwiękiem radiowym, czy // w zasadzie to powinien mieć flagę, czy jest dźwiękiem radiowym, czy
// bezpośrednim // bezpośrednim
// albo trzeba zrobić dwa dźwięki, jeden bezpośredni, słyszalny w // albo trzeba zrobić dwa dźwięki, jeden bezpośredni, słyszalny w
@@ -4210,9 +4209,7 @@ bool TController::UpdateSituation(double dt)
// na razie zakładam, że to nie jest dźwięk radiowy, bo trzeba by zrobić // na razie zakładam, że to nie jest dźwięk radiowy, bo trzeba by zrobić
// obsługę kanałów radiowych itd. // obsługę kanałów radiowych itd.
if (!iGuardRadio) // jeśli nie przez radio if (!iGuardRadio) // jeśli nie przez radio
tsGuardSignal->Play( tsGuardSignal->position(pVehicle->GetPosition()).play();
1.0, 0, !FreeFlyModeFlag,
pVehicle->GetPosition()); // dla true jest głośniej
else else
// if (iGuardRadio==iRadioChannel) //zgodność kanału // if (iGuardRadio==iRadioChannel) //zgodność kanału
// if (!FreeFlyModeFlag) //obserwator musi być w środku pojazdu // if (!FreeFlyModeFlag) //obserwator musi być w środku pojazdu
@@ -4221,9 +4218,7 @@ bool TController::UpdateSituation(double dt)
if (SquareMagnitude(pVehicle->GetPosition() - if (SquareMagnitude(pVehicle->GetPosition() -
Global::pCameraPosition) < Global::pCameraPosition) <
2000 * 2000) // w odległości mniejszej niż 2km 2000 * 2000) // w odległości mniejszej niż 2km
tsGuardSignal->Play( tsGuardSignal->position(pVehicle->GetPosition()).play();
1.0, 0, true,
pVehicle->GetPosition()); // dźwięk niby przez radio
} }
} }
if (mvOccupied->V == 0.0) if (mvOccupied->V == 0.0)

View File

@@ -232,7 +232,7 @@ class TController
// AnsiString OrderCommand; //komenda pobierana z pojazdu // AnsiString OrderCommand; //komenda pobierana z pojazdu
// double OrderValue; //argument komendy // double OrderValue; //argument komendy
int iRadioChannel = 1; // numer aktualnego kanału radiowego int iRadioChannel = 1; // numer aktualnego kanału radiowego
TTextSound *tsGuardSignal = nullptr; // komunikat od kierownika sound *tsGuardSignal = nullptr; // komunikat od kierownika
int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia)
public: public:
double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji) double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji)

View File

@@ -31,6 +31,7 @@ http://mozilla.org/MPL/2.0/.
#include "Camera.h" //bo likwidujemy trzęsienie #include "Camera.h" //bo likwidujemy trzęsienie
#include "Console.h" #include "Console.h"
#include "Traction.h" #include "Traction.h"
#include "sound.h"
// Ra: taki zapis funkcjonuje lepiej, ale może nie jest optymalny // Ra: taki zapis funkcjonuje lepiej, ale może nie jest optymalny
#define vWorldFront Math3D::vector3(0, 0, 1) #define vWorldFront Math3D::vector3(0, 0, 1)
@@ -1631,21 +1632,32 @@ TDynamicObject::~TDynamicObject()
// parametrow fizycznych // parametrow fizycznych
SafeDelete(Mechanik); SafeDelete(Mechanik);
SafeDelete(MoverParameters); SafeDelete(MoverParameters);
// Ra: wyłączanie dźwięków powinno być dodane w ich destruktorach, ale się
// sypie for (size_t i = 0; i < MaxAxles; i++)
/* to też się sypie sound_man->destroy_sound(&rsStukot[i]);
for (int i=0;i<MaxAxles;++i) sound_man->destroy_sound(&rsSilnik);
rsStukot[i].Stop(); //dzwieki poszczegolnych osi sound_man->destroy_sound(&rsWentylator);
rsSilnik.Stop(); sound_man->destroy_sound(&rsPisk);
rsWentylator.Stop(); sound_man->destroy_sound(&rsDerailment);
rsPisk.Stop(); sound_man->destroy_sound(&rsPrzekladnia);
rsDerailment.Stop(); sound_man->destroy_sound(&sHorn1);
sPantUp.Stop(); sound_man->destroy_sound(&sHorn2);
sPantDown.Stop(); sound_man->destroy_sound(&sCompressor);
sBrakeAcc.Stop(); //dzwiek przyspieszacza sound_man->destroy_sound(&sConverter);
rsDiesielInc.Stop(); sound_man->destroy_sound(&sSmallCompressor);
rscurve.Stop(); sound_man->destroy_sound(&sDepartureSignal);
*/ sound_man->destroy_sound(&sTurbo);
sound_man->destroy_sound(&sSand);
sound_man->destroy_sound(&sReleaser);
sound_man->destroy_sound(&sPantUp);
sound_man->destroy_sound(&sPantDown);
sound_man->destroy_sound(&rsDoorOpen);
sound_man->destroy_sound(&rsDoorClose);
sound_man->destroy_sound(&sBrakeAcc);
sound_man->destroy_sound(&rsUnbrake);
sound_man->destroy_sound(&rsDiesielInc);
sound_man->destroy_sound(&rscurve);
/* /*
delete[] pAnimations; // obiekty obsługujące animację delete[] pAnimations; // obiekty obsługujące animację
*/ */
@@ -3044,7 +3056,8 @@ bool TDynamicObject::Update(double dt, double dt1)
// McZapkie-270202 // McZapkie-270202
if (MyTrack->fSoundDistance != -1) if (MyTrack->fSoundDistance != -1)
{ {
if (ObjectDist < rsStukot[0].dSoundAtt * rsStukot[0].dSoundAtt * 15.0) //m7todo: restore
//if (ObjectDist < rsStukot[0].dSoundAtt * rsStukot[0].dSoundAtt * 15.0)
{ {
vol = (20.0 + MyTrack->iDamageFlag) / 21; vol = (20.0 + MyTrack->iDamageFlag) / 21;
if (MyTrack->eEnvironment == e_tunnel) if (MyTrack->eEnvironment == e_tunnel)
@@ -3079,16 +3092,15 @@ bool TDynamicObject::Update(double dt, double dt1)
// McZapkie-040302 // McZapkie-040302
if (i == iAxles - 1) if (i == iAxles - 1)
{ {
rsStukot[0].Stop(); if (rsStukot[0]) rsStukot[0]->stop();
MoverParameters->AccV += MoverParameters->AccV +=
0.5 * GetVelocity() / (1 + MoverParameters->Vmax); 0.5 * GetVelocity() / (1 + MoverParameters->Vmax);
} }
else else
{ {
rsStukot[i + 1].Stop(); if (rsStukot[i + 1]) rsStukot[i + 1]->stop();
} }
rsStukot[i].Play(vol, 0, MechInside, if (rsStukot[i]) rsStukot[i]->gain(vol).position(vPosition).play(); // poprawic pozycje o uklad osi
vPosition); // poprawic pozycje o uklad osi
if (i == 1) if (i == 1)
MoverParameters->AccV -= MoverParameters->AccV -=
0.5 * GetVelocity() / (1 + MoverParameters->Vmax); 0.5 * GetVelocity() / (1 + MoverParameters->Vmax);
@@ -3105,11 +3117,10 @@ bool TDynamicObject::Update(double dt, double dt1)
int flag = MoverParameters->Hamulec->GetSoundFlag(); int flag = MoverParameters->Hamulec->GetSoundFlag();
if ((bBrakeAcc) && (TestFlag(flag, sf_Acc)) && (ObjectDist < 2500)) if ((bBrakeAcc) && (TestFlag(flag, sf_Acc)) && (ObjectDist < 2500))
{ {
sBrakeAcc->SetVolume(-ObjectDist * 3 - (FreeFlyModeFlag ? 0 : 2000)); sBrakeAcc->gain(-ObjectDist * 3 - (FreeFlyModeFlag ? 0 : 2000));
sBrakeAcc->Play(0, 0, 0); sBrakeAcc->play();
sBrakeAcc->SetPan(10000 * sin(ModCamRot));
} }
if ((rsUnbrake.AM != 0) && (ObjectDist < 5000)) if ((rsUnbrake) && (ObjectDist < 5000))
{ {
if ((TestFlag(flag, sf_CylU)) && if ((TestFlag(flag, sf_CylU)) &&
((MoverParameters->BrakePress * MoverParameters->MaxBrakePress[3]) > 0.05)) ((MoverParameters->BrakePress * MoverParameters->MaxBrakePress[3]) > 0.05))
@@ -3120,11 +3131,10 @@ bool TDynamicObject::Update(double dt, double dt1)
MoverParameters->MaxBrakePress[3]), MoverParameters->MaxBrakePress[3]),
1); 1);
vol = vol + (FreeFlyModeFlag ? 0 : -0.5) - ObjectDist / 5000; vol = vol + (FreeFlyModeFlag ? 0 : -0.5) - ObjectDist / 5000;
rsUnbrake.SetPan(10000 * sin(ModCamRot)); rsUnbrake->loop().gain(vol).position(GetPosition()).play();
rsUnbrake.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition());
} }
else else
rsUnbrake.Stop(); rsUnbrake->stop();
} }
// fragment z EXE Kursa // fragment z EXE Kursa
@@ -3237,8 +3247,8 @@ bool TDynamicObject::Update(double dt, double dt1)
&& ( PantDiff < 0.01 ) ) // tolerancja niedolegania && ( PantDiff < 0.01 ) ) // tolerancja niedolegania
{ {
if ((MoverParameters->PantFrontVolt == 0.0) && if ((MoverParameters->PantFrontVolt == 0.0) &&
(MoverParameters->PantRearVolt == 0.0)) (MoverParameters->PantRearVolt == 0.0) && sPantUp)
sPantUp.Play(vol, 0, MechInside, vPosition); sPantUp->gain(vol).position(vPosition).play();
if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na
// pantograf i // pantograf i
// wstawić do GetVoltage() // wstawić do GetVoltage()
@@ -3266,8 +3276,8 @@ bool TDynamicObject::Update(double dt, double dt1)
&& ( PantDiff < 0.01 ) ) && ( PantDiff < 0.01 ) )
{ {
if ((MoverParameters->PantRearVolt == 0.0) && if ((MoverParameters->PantRearVolt == 0.0) &&
(MoverParameters->PantFrontVolt == 0.0)) (MoverParameters->PantFrontVolt == 0.0) && sPantUp)
sPantUp.Play(vol, 0, MechInside, vPosition); sPantUp->gain(vol).position(vPosition).play();
if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na
// pantograf i // pantograf i
// wstawić do GetVoltage() // wstawić do GetVoltage()
@@ -3354,12 +3364,12 @@ bool TDynamicObject::Update(double dt, double dt1)
} // koniec pętli po pantografach } // koniec pętli po pantografach
if ((MoverParameters->PantFrontSP == false) && (MoverParameters->PantFrontUp == false)) if ((MoverParameters->PantFrontSP == false) && (MoverParameters->PantFrontUp == false))
{ {
sPantDown.Play(vol, 0, MechInside, vPosition); sPantDown->gain(vol).position(vPosition).play();
MoverParameters->PantFrontSP = true; MoverParameters->PantFrontSP = true;
} }
if ((MoverParameters->PantRearSP == false) && (MoverParameters->PantRearUp == false)) if ((MoverParameters->PantRearSP == false) && (MoverParameters->PantRearUp == false))
{ {
sPantDown.Play(vol, 0, MechInside, vPosition); sPantDown->gain(vol).position(vPosition).play();
MoverParameters->PantRearSP = true; MoverParameters->PantRearSP = true;
} }
/* /*
@@ -3462,24 +3472,24 @@ bool TDynamicObject::Update(double dt, double dt1)
// NBMX Obsluga drzwi, MC: zuniwersalnione // NBMX Obsluga drzwi, MC: zuniwersalnione
if ((dDoorMoveL < MoverParameters->DoorMaxShiftL) && (MoverParameters->DoorLeftOpened)) if ((dDoorMoveL < MoverParameters->DoorMaxShiftL) && (MoverParameters->DoorLeftOpened))
{ {
rsDoorOpen.Play(1, 0, MechInside, vPosition); rsDoorOpen->position(vPosition).play();
dDoorMoveL += dt1 * 0.5 * MoverParameters->DoorOpenSpeed; dDoorMoveL += dt1 * 0.5 * MoverParameters->DoorOpenSpeed;
} }
if ((dDoorMoveL > 0) && (!MoverParameters->DoorLeftOpened)) if ((dDoorMoveL > 0) && (!MoverParameters->DoorLeftOpened))
{ {
rsDoorClose.Play(1, 0, MechInside, vPosition); rsDoorClose->position(vPosition).play();
dDoorMoveL -= dt1 * MoverParameters->DoorCloseSpeed; dDoorMoveL -= dt1 * MoverParameters->DoorCloseSpeed;
if (dDoorMoveL < 0) if (dDoorMoveL < 0)
dDoorMoveL = 0; dDoorMoveL = 0;
} }
if ((dDoorMoveR < MoverParameters->DoorMaxShiftR) && (MoverParameters->DoorRightOpened)) if ((dDoorMoveR < MoverParameters->DoorMaxShiftR) && (MoverParameters->DoorRightOpened))
{ {
rsDoorOpen.Play(1, 0, MechInside, vPosition); rsDoorOpen->position(vPosition).play();
dDoorMoveR += dt1 * 0.5 * MoverParameters->DoorOpenSpeed; dDoorMoveR += dt1 * 0.5 * MoverParameters->DoorOpenSpeed;
} }
if ((dDoorMoveR > 0) && (!MoverParameters->DoorRightOpened)) if ((dDoorMoveR > 0) && (!MoverParameters->DoorRightOpened))
{ {
rsDoorClose.Play(1, 0, MechInside, vPosition); rsDoorClose->position(vPosition).play();
dDoorMoveR -= dt1 * MoverParameters->DoorCloseSpeed; dDoorMoveR -= dt1 * MoverParameters->DoorCloseSpeed;
if (dDoorMoveR < 0) if (dDoorMoveR < 0)
dDoorMoveR = 0; dDoorMoveR = 0;
@@ -3658,7 +3668,7 @@ void TDynamicObject::RenderSounds()
if (MoverParameters->Power > 0) if (MoverParameters->Power > 0)
{ {
if ((rsSilnik.AM != 0) if ((rsSilnik)
&& ((MoverParameters->Mains) && ((MoverParameters->Mains)
// McZapkie-280503: zeby dla dumb dzialal silnik na jalowych obrotach // McZapkie-280503: zeby dla dumb dzialal silnik na jalowych obrotach
|| (MoverParameters->EngineType == DieselEngine))) || (MoverParameters->EngineType == DieselEngine)))
@@ -3666,39 +3676,33 @@ void TDynamicObject::RenderSounds()
if ((fabs(MoverParameters->enrot) > 0.01) || if ((fabs(MoverParameters->enrot) > 0.01) ||
(MoverParameters->EngineType == Dumb)) //&& (MoverParameters->EnginePower>0.1)) (MoverParameters->EngineType == Dumb)) //&& (MoverParameters->EnginePower>0.1))
{ {
freq = rsSilnik.FM * fabs(MoverParameters->enrot) + rsSilnik.FA; freq = fabs(MoverParameters->enrot);
if (MoverParameters->EngineType == Dumb) if (MoverParameters->EngineType == Dumb)
freq = freq - freq = freq -
0.2 * MoverParameters->EnginePower / (1 + MoverParameters->Power * 1000); 0.2 * MoverParameters->EnginePower / (1 + MoverParameters->Power * 1000);
rsSilnik.AdjFreq(freq, dt); rsSilnik->pitch(freq);
if (MoverParameters->EngineType == DieselEngine) if (MoverParameters->EngineType == DieselEngine)
{ {
if (MoverParameters->enrot > 0) if (MoverParameters->enrot > 0)
{ {
if (MoverParameters->EnginePower > 0) if (MoverParameters->EnginePower > 0)
vol = rsSilnik.AM * MoverParameters->dizel_fill + rsSilnik.AA; vol = MoverParameters->dizel_fill;
else else
vol = vol =
rsSilnik.AM * fabs(MoverParameters->enrot / MoverParameters->dizel_nmax) + fabs(MoverParameters->enrot / MoverParameters->dizel_nmax);
rsSilnik.AA * 0.9;
} }
else else
vol = 0; vol = 0;
} }
else if (MoverParameters->EngineType == DieselElectric) else if (MoverParameters->EngineType == DieselElectric)
vol = rsSilnik.AM * vol = (MoverParameters->EnginePower / 1000 / MoverParameters->Power) +
(MoverParameters->EnginePower / 1000 / MoverParameters->Power) +
0.2 * (MoverParameters->enrot * 60) / 0.2 * (MoverParameters->enrot * 60) /
(MoverParameters->DElist[MoverParameters->MainCtrlPosNo].RPM) + (MoverParameters->DElist[MoverParameters->MainCtrlPosNo].RPM);
rsSilnik.AA;
else if (MoverParameters->EngineType == ElectricInductionMotor) else if (MoverParameters->EngineType == ElectricInductionMotor)
vol = rsSilnik.AM * vol = (MoverParameters->EnginePower + fabs(MoverParameters->enrot * 2));
(MoverParameters->EnginePower + fabs(MoverParameters->enrot * 2)) +
rsSilnik.AA;
else else
vol = rsSilnik.AM * (MoverParameters->EnginePower / 1000 + vol = (MoverParameters->EnginePower / 1000 +
fabs(MoverParameters->enrot) * 60.0) + fabs(MoverParameters->enrot) * 60.0);
rsSilnik.AA;
// McZapkie-250302 - natezenie zalezne od obrotow i mocy // McZapkie-250302 - natezenie zalezne od obrotow i mocy
if ((vol < 1) && (MoverParameters->EngineType == ElectricSeriesMotor) && if ((vol < 1) && (MoverParameters->EngineType == ElectricSeriesMotor) &&
(MoverParameters->EnginePower < 100)) (MoverParameters->EnginePower < 100))
@@ -3731,11 +3735,11 @@ void TDynamicObject::RenderSounds()
if (enginevolume > 0.0001) if (enginevolume > 0.0001)
if (MoverParameters->EngineType != DieselElectric) if (MoverParameters->EngineType != DieselElectric)
{ {
rsSilnik.Play(enginevolume, DSBPLAY_LOOPING, MechInside, GetPosition()); rsSilnik->loop().gain(enginevolume).position(GetPosition()).play();
} }
else else
{ {
sConverter.UpdateAF(vol, freq, MechInside, GetPosition()); sConverter->gain(vol).pitch(freq).position(GetPosition());
float fincvol; float fincvol;
fincvol = 0; fincvol = 0;
@@ -3746,100 +3750,114 @@ void TDynamicObject::RenderSounds()
(MoverParameters->enrot * 60)); (MoverParameters->enrot * 60));
fincvol /= (0.05 * MoverParameters->DElist[0].RPM); fincvol /= (0.05 * MoverParameters->DElist[0].RPM);
}; };
if (fincvol > 0.02) if (rsDiesielInc)
rsDiesielInc.Play(fincvol, DSBPLAY_LOOPING, MechInside, GetPosition()); {
else if (fincvol > 0.02)
rsDiesielInc.Stop(); rsDiesielInc->loop().position(GetPosition()).gain(fincvol).play();
else
rsDiesielInc->stop();
}
} }
} }
else else
rsSilnik.Stop(); rsSilnik->stop();
} }
enginevolume = (enginevolume + vol) * 0.5; enginevolume = (enginevolume + vol) * 0.5;
if( enginevolume < 0.01 ) { if( enginevolume < 0.01 ) {
rsSilnik.Stop(); rsSilnik->stop();
} }
if ( ( MoverParameters->EngineType == ElectricSeriesMotor ) if ( (( MoverParameters->EngineType == ElectricSeriesMotor )
|| ( MoverParameters->EngineType == ElectricInductionMotor ) || ( MoverParameters->EngineType == ElectricInductionMotor ))
&& ( rsWentylator.AM != 0 ) ) && ( rsWentylator ) )
{ {
if (MoverParameters->RventRot > 0.1) { if (MoverParameters->RventRot > 0.1) {
// play ventilator sound if the ventilators are rotating fast enough... // play ventilator sound if the ventilators are rotating fast enough...
freq = rsWentylator.FM * MoverParameters->RventRot + rsWentylator.FA; freq = MoverParameters->RventRot;
rsWentylator.AdjFreq(freq, dt); rsWentylator->pitch(freq);
if( MoverParameters->EngineType == ElectricInductionMotor ) { if( MoverParameters->EngineType == ElectricInductionMotor ) {
vol = rsWentylator.AM * std::sqrt( std::fabs( MoverParameters->dizel_fill ) ) + rsWentylator.AA; vol = std::sqrt( std::fabs( MoverParameters->dizel_fill ) );
} }
else { else {
vol = rsWentylator.AM * MoverParameters->RventRot + rsWentylator.AA; vol = MoverParameters->RventRot;
} }
rsWentylator.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition()); rsWentylator->gain(vol).loop().position(GetPosition()).play();
} }
else { else {
// ...otherwise shut down the sound // ...otherwise shut down the sound
rsWentylator.Stop(); rsWentylator->stop();
} }
} }
if (MoverParameters->TrainType == dt_ET40) if (MoverParameters->TrainType == dt_ET40 && rsPrzekladnia)
{ {
if (MoverParameters->Vel > 0.1) if (MoverParameters->Vel > 0.1)
{ {
freq = rsPrzekladnia.FM * (MoverParameters->Vel) + rsPrzekladnia.FA; freq = MoverParameters->Vel;
rsPrzekladnia.AdjFreq(freq, dt); rsPrzekladnia->pitch(freq);
vol = rsPrzekladnia.AM * (MoverParameters->Vel) + rsPrzekladnia.AA; vol = MoverParameters->Vel;
rsPrzekladnia.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition()); rsPrzekladnia->loop().position(GetPosition()).gain(vol).play();
} }
else else
rsPrzekladnia.Stop(); rsPrzekladnia->stop();
} }
} }
// youBy: dzwiek ostrych lukow i ciasnych zwrotek // youBy: dzwiek ostrych lukow i ciasnych zwrotek
if ((ts.R * ts.R > 1) && (MoverParameters->Vel > 0)) if (rscurve)
vol = MoverParameters->AccN * MoverParameters->AccN;
else
vol = 0;
// vol+=(50000/ts.R*ts.R);
if (vol > 0.001)
{ {
rscurve.Play(2 * vol, DSBPLAY_LOOPING, MechInside, GetPosition()); if ((ts.R * ts.R > 1) && (MoverParameters->Vel > 0))
vol = MoverParameters->AccN * MoverParameters->AccN;
else
vol = 0;
// vol+=(50000/ts.R*ts.R);
if (vol > 0.001)
{
rscurve->gain(2 * vol).loop().position(GetPosition()).play();
}
else
rscurve->stop();
} }
else
rscurve.Stop();
// McZapkie-280302 - pisk mocno zacisnietych hamulcow - trzeba jeszcze // McZapkie-280302 - pisk mocno zacisnietych hamulcow - trzeba jeszcze
// zabezpieczyc przed // zabezpieczyc przed
// brakiem deklaracji w mmedia.dta // brakiem deklaracji w mmedia.dta
if (rsPisk.AM != 0)
if (rsPisk)
{ {
if ((MoverParameters->Vel > (rsPisk.GetStatus() != 0 ? 0.01 : 0.5)) && if ((MoverParameters->Vel > (rsPisk->is_playing() != 0 ? 0.01 : 0.5)) &&
(!MoverParameters->SlippingWheels) && (MoverParameters->UnitBrakeForce > rsPisk.AM)) (!MoverParameters->SlippingWheels) && (MoverParameters->UnitBrakeForce > rsPisk->gain_mul))
{ {
vol = MoverParameters->UnitBrakeForce / (rsPisk.AM + 1) + rsPisk.AA; vol = (MoverParameters->UnitBrakeForce / (rsPisk->gain_mul + 1)) / rsPisk->gain_mul;
rsPisk.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition()); rsPisk->gain(vol).loop().position(GetPosition()).play();
} }
else else
rsPisk.Stop(); rsPisk->stop();
} }
if (MoverParameters->SandDose) // Dzwiek piasecznicy if (sSand)
sSand.TurnOn(MechInside, GetPosition()); {
else if (MoverParameters->SandDose) // Dzwiek piasecznicy
sSand.TurnOff(MechInside, GetPosition()); sSand->position(GetPosition()).play();
sSand.Update(MechInside, GetPosition()); else
if (MoverParameters->Hamulec->GetStatus() & b_rls) // Dzwiek odluzniacza sSand->stop();
sReleaser.TurnOn(MechInside, GetPosition()); }
else
sReleaser.TurnOff(MechInside, GetPosition()); if (sReleaser)
//sReleaser.Update(MechInside, GetPosition()); {
double releaser_vol = 1; if (MoverParameters->Hamulec->GetStatus() & b_rls) // Dzwiek odluzniacza
if (MoverParameters->BrakePress < 0.1) sReleaser->position(GetPosition()).play();
releaser_vol = MoverParameters->BrakePress * 10; else
sReleaser.UpdateAF(releaser_vol, 1, MechInside, GetPosition()); sReleaser->stop();
//sReleaser.Update(MechInside, GetPosition());
double releaser_vol = 1;
if (MoverParameters->BrakePress < 0.1)
releaser_vol = MoverParameters->BrakePress * 10;
sReleaser->gain(releaser_vol);
}
// if ((MoverParameters->ConverterFlag==false) && // if ((MoverParameters->ConverterFlag==false) &&
// (MoverParameters->TrainType!=dt_ET22)) // (MoverParameters->TrainType!=dt_ET22))
// if // if
@@ -3851,51 +3869,59 @@ void TDynamicObject::RenderSounds()
// MoverParameters->CompressorAllow=MoverParameters->ConverterFlag; // MoverParameters->CompressorAllow=MoverParameters->ConverterFlag;
// McZapkie! - dzwiek compressor.wav tylko gdy dziala sprezarka // McZapkie! - dzwiek compressor.wav tylko gdy dziala sprezarka
if (MoverParameters->VeselVolume != 0)
{
if (MoverParameters->CompressorFlag)
sCompressor.TurnOn(MechInside, GetPosition());
else
sCompressor.TurnOff(MechInside, GetPosition());
sCompressor.Update(MechInside, GetPosition());
}
if (MoverParameters->PantCompFlag) // Winger 160404 - dzwiek malej sprezarki
sSmallCompressor.TurnOn(MechInside, GetPosition());
else
sSmallCompressor.TurnOff(MechInside, GetPosition());
sSmallCompressor.Update(MechInside, GetPosition());
// youBy - przenioslem, bo diesel tez moze miec turbo if (sCompressor)
if( (MoverParameters->TurboTest > 0)
&& (MoverParameters->MainCtrlPos >= MoverParameters->TurboTest))
{ {
// udawanie turbo: (6.66*(eng_vol-0.85)) if (MoverParameters->VeselVolume != 0)
if (eng_turbo > 6.66 * (enginevolume - 0.8) + 0.2 * dt) {
eng_turbo = eng_turbo - 0.2 * dt; // 0.125 if (MoverParameters->CompressorFlag)
else if (eng_turbo < 6.66 * (enginevolume - 0.8) - 0.4 * dt) sCompressor->position(GetPosition()).play();
eng_turbo = eng_turbo + 0.4 * dt; // 0.333 else
else sCompressor->stop();
eng_turbo = 6.66 * (enginevolume - 0.8); }
}
sTurbo.TurnOn(MechInside, GetPosition());
// sTurbo.UpdateAF(eng_turbo,0.7+(eng_turbo*0.6),MechInside,GetPosition()); if (sSmallCompressor)
sTurbo.UpdateAF(3 * eng_turbo - 1, 0.4 + eng_turbo * 0.4, MechInside, GetPosition()); {
// eng_vol_act=enginevolume; if (MoverParameters->PantCompFlag) // Winger 160404 - dzwiek malej sprezarki
// eng_frq_act=eng_frq; sSmallCompressor->position(GetPosition()).play();
else
sSmallCompressor->stop();
}
if (sTurbo)
{
// youBy - przenioslem, bo diesel tez moze miec turbo
if( (MoverParameters->TurboTest > 0)
&& (MoverParameters->MainCtrlPos >= MoverParameters->TurboTest))
{
// udawanie turbo: (6.66*(eng_vol-0.85))
if (eng_turbo > 6.66 * (enginevolume - 0.8) + 0.2 * dt)
eng_turbo = eng_turbo - 0.2 * dt; // 0.125
else if (eng_turbo < 6.66 * (enginevolume - 0.8) - 0.4 * dt)
eng_turbo = eng_turbo + 0.4 * dt; // 0.333
else
eng_turbo = 6.66 * (enginevolume - 0.8);
sTurbo->gain(3 * eng_turbo - 1).pitch(0.4 + eng_turbo * 0.4).position(GetPosition()).play();
}
else
sTurbo->stop();
} }
else
sTurbo.TurnOff(MechInside, GetPosition());
if (MoverParameters->TrainType == dt_PseudoDiesel) if (MoverParameters->TrainType == dt_PseudoDiesel)
{ {
// ABu: udawanie woodwarda dla lok. spalinowych // ABu: udawanie woodwarda dla lok. spalinowych
// jesli silnik jest podpiety pod dzwiek przetwornicy // jesli silnik jest podpiety pod dzwiek przetwornicy
if (MoverParameters->ConverterFlag) // NBMX dzwiek przetwornicy if (sConverter)
{ {
sConverter.TurnOn(MechInside, GetPosition()); if (MoverParameters->ConverterFlag) // NBMX dzwiek przetwornicy
{
sConverter->position(GetPosition()).play();
}
else
sConverter->stop();
} }
else
sConverter.TurnOff(MechInside, GetPosition());
// glosnosc zalezy od stosunku mocy silnika el. do mocy max // glosnosc zalezy od stosunku mocy silnika el. do mocy max
double eng_vol; double eng_vol;
@@ -3942,7 +3968,7 @@ void TDynamicObject::RenderSounds()
if (eng_frq_act < defrot + 0.1 * dt) if (eng_frq_act < defrot + 0.1 * dt)
eng_frq_act = defrot; eng_frq_act = defrot;
} }
sConverter.UpdateAF(eng_vol_act, eng_frq_act + eng_dfrq, MechInside, GetPosition()); sConverter->gain(eng_vol_act).pitch(eng_frq_act + eng_dfrq).position(GetPosition());
// udawanie turbo: (6.66*(eng_vol-0.85)) // udawanie turbo: (6.66*(eng_vol-0.85))
if (eng_turbo > 6.66 * (eng_vol - 0.8) + 0.2 * dt) if (eng_turbo > 6.66 * (eng_vol - 0.8) + 0.2 * dt)
eng_turbo = eng_turbo - 0.2 * dt; // 0.125 eng_turbo = eng_turbo - 0.2 * dt; // 0.125
@@ -3951,62 +3977,67 @@ void TDynamicObject::RenderSounds()
else else
eng_turbo = 6.66 * (eng_vol - 0.8); eng_turbo = 6.66 * (eng_vol - 0.8);
sTurbo.TurnOn(MechInside, GetPosition()); if (sTurbo) sTurbo->gain(3 * eng_turbo - 1).pitch(0.4 + eng_turbo * 0.4).position(GetPosition()).play();
// sTurbo.UpdateAF(eng_turbo,0.7+(eng_turbo*0.6),MechInside,GetPosition()); // sTurbo.UpdateAF(eng_turbo,0.7+(eng_turbo*0.6),MechInside,GetPosition());
sTurbo.UpdateAF(3 * eng_turbo - 1, 0.4 + eng_turbo * 0.4, MechInside, GetPosition());
eng_vol_act = eng_vol; eng_vol_act = eng_vol;
// eng_frq_act=eng_frq; // eng_frq_act=eng_frq;
} }
else else
{ {
if (MoverParameters->ConverterFlag) // NBMX dzwiek przetwornicy if (sConverter)
sConverter.TurnOn(MechInside, GetPosition()); {
else if (MoverParameters->ConverterFlag) // NBMX dzwiek przetwornicy
sConverter.TurnOff(MechInside, GetPosition()); {
sConverter.Update(MechInside, GetPosition()); sConverter->position(GetPosition()).play();
}
else
sConverter->stop();
}
} }
if( TestFlag( MoverParameters->WarningSignal, 1 ) ) { if (sHorn1)
sHorn1.TurnOn( MechInside, GetPosition() ); {
} if( TestFlag( MoverParameters->WarningSignal, 1 ) ) {
else { sHorn1->position(GetPosition()).play();
sHorn1.TurnOff( MechInside, GetPosition() ); }
} else {
if( TestFlag( MoverParameters->WarningSignal, 2 ) ) { sHorn1->stop();
sHorn2.TurnOn( MechInside, GetPosition() ); }
}
else {
sHorn2.TurnOff( MechInside, GetPosition() );
} }
if (MoverParameters->DoorClosureWarning) if (sHorn2)
{ {
if (MoverParameters->DepartureSignal) // NBMX sygnal odjazdu, MC: pod warunkiem ze jest if( TestFlag( MoverParameters->WarningSignal, 2 ) ) {
// zdefiniowane w chk sHorn2->position(GetPosition()).play();
sDepartureSignal.TurnOn(MechInside, GetPosition()); }
else else {
sDepartureSignal.TurnOff(MechInside, GetPosition()); sHorn2->stop();
sDepartureSignal.Update(MechInside, GetPosition()); }
} }
sHorn1.Update(MechInside, GetPosition());
sHorn2.Update(MechInside, GetPosition()); if (sDepartureSignal)
// McZapkie: w razie wykolejenia
if (MoverParameters->EventFlag)
{ {
if (TestFlag(MoverParameters->DamageFlag, dtrain_out) && GetVelocity() > 0) if (MoverParameters->DoorClosureWarning)
rsDerailment.Play(1, 0, true, GetPosition()); {
if (GetVelocity() == 0) if (MoverParameters->DepartureSignal) // NBMX sygnal odjazdu, MC: pod warunkiem ze jest
rsDerailment.Stop(); // zdefiniowane w chk
sDepartureSignal->position(GetPosition()).play();
else
sDepartureSignal->stop();
}
}
if (rsDerailment)
{
// McZapkie: w razie wykolejenia
if (MoverParameters->EventFlag)
{
if (TestFlag(MoverParameters->DamageFlag, dtrain_out) && GetVelocity() > 0)
rsDerailment->position(GetPosition()).play();
if (GetVelocity() == 0)
rsDerailment->stop();
}
} }
/* //Ra: dwa razy?
if (MoverParameters->EventFlag)
{
if (TestFlag(MoverParameters->DamageFlag,dtrain_out) && GetVelocity()>0)
rsDerailment.Play(1,0,true,GetPosition());
if (GetVelocity()==0)
rsDerailment.Stop();
}
*/
}; };
// McZapkie-250202 // McZapkie-250202
@@ -4711,9 +4742,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser.getTokens(); parser.getTokens();
parser >> token; parser >> token;
if( token != "end" ) { if( token != "end" ) {
rsStukot[ i ].Init( token, dSDist, GetPosition().x, rsStukot[i] = sound_man->create_sound(token);
GetPosition().y + dWheelsPosition[ i ], GetPosition().z, if (rsStukot[i]) rsStukot[i]->position(glm::vec3(GetPosition().x,
true ); GetPosition().y + dWheelsPosition[ i ], GetPosition().z)).dist(dSDist);
} }
} }
if( token != "end" ) { if( token != "end" ) {
@@ -4730,32 +4761,31 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rsSilnik.Init( rsSilnik = sound_man->create_sound(token);
token, attenuation, if (rsSilnik)
GetPosition().x, GetPosition().y, GetPosition().z, {
true, true ); rsSilnik->dist(attenuation);
if( rsSilnik.GetWaveTime() == 0 ) { parser.getTokens( 4, false );
ErrorLog( "Missed sound: \"" + token + "\" for " + asFileName );
}
parser.getTokens( 1, false );
parser >> rsSilnik.AM;
if( MoverParameters->EngineType == DieselEngine ) {
rsSilnik.AM /= ( MoverParameters->Power + MoverParameters->nmax * 60 ); parser >> rsSilnik->gain_mul;
} if( MoverParameters->EngineType == DieselEngine ) {
else if( MoverParameters->EngineType == DieselElectric ) {
rsSilnik.AM /= ( MoverParameters->Power * 3 ); rsSilnik->gain_mul /= ( MoverParameters->Power + MoverParameters->nmax * 60 );
} }
else { else if( MoverParameters->EngineType == DieselElectric ) {
rsSilnik.AM /= ( MoverParameters->Power + MoverParameters->nmax * 60 + MoverParameters->Power + MoverParameters->Power ); rsSilnik->gain_mul /= ( MoverParameters->Power * 3 );
} }
parser.getTokens( 3, false ); else {
parser
>> rsSilnik.AA rsSilnik->gain_mul /= ( MoverParameters->Power + MoverParameters->nmax * 60 + MoverParameters->Power + MoverParameters->Power );
>> rsSilnik.FM // MoverParameters->nmax; }
>> rsSilnik.FA;
parser
>> rsSilnik->gain_off
>> rsSilnik->pitch_mul // MoverParameters->nmax;
>> rsSilnik->pitch_off;
}
} }
else if( ( token == "ventilator:" ) else if( ( token == "ventilator:" )
@@ -4767,18 +4797,19 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rsWentylator.Init( rsWentylator = sound_man->create_sound(token);
token, attenuation, if (rsWentylator)
GetPosition().x, GetPosition().y, GetPosition().z, {
true, true ); rsWentylator->dist(attenuation);
parser.getTokens( 4, false ); parser.getTokens( 4, false );
parser parser
>> rsWentylator.AM >> rsWentylator->gain_mul
>> rsWentylator.AA >> rsWentylator->gain_off
>> rsWentylator.FM >> rsWentylator->pitch_mul
>> rsWentylator.FA; >> rsWentylator->pitch_off;
rsWentylator.AM /= MoverParameters->RVentnmax; rsWentylator->gain_mul /= MoverParameters->RVentnmax;
rsWentylator.FM /= MoverParameters->RVentnmax; rsWentylator->pitch_mul /= MoverParameters->RVentnmax;
}
} }
else if( ( token == "transmission:" ) else if( ( token == "transmission:" )
@@ -4789,14 +4820,15 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rsPrzekladnia.Init( rsPrzekladnia = sound_man->create_sound(token);
token, attenuation, if (rsPrzekladnia)
GetPosition().x, GetPosition().y, GetPosition().z, {
true ); rsPrzekladnia->dist(attenuation);
rsPrzekladnia.AM = 0.029; rsPrzekladnia->gain_mul = 0.029;
rsPrzekladnia.AA = 0.1; rsPrzekladnia->gain_off = 0.1;
rsPrzekladnia.FM = 0.005; rsPrzekladnia->pitch_mul = 0.005;
rsPrzekladnia.FA = 1.0; rsPrzekladnia->pitch_off = 1.0;
}
} }
else if( token == "brake:" ){ else if( token == "brake:" ){
@@ -4806,26 +4838,27 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rsPisk.Init( rsPisk = sound_man->create_sound(token);
token, attenuation, if (rsPisk)
GetPosition().x, GetPosition().y, GetPosition().z, {
true ); rsPisk->dist(attenuation);
rsPisk.AM = parser.getToken<double>(); rsPisk->gain_mul = parser.getToken<double>();
rsPisk.AA = parser.getToken<double>() * ( 105 - Random( 10 ) ) / 100; rsPisk->gain_off = parser.getToken<double>() * ( 105 - Random( 10 ) ) / 100;
rsPisk.FM = 1.0; rsPisk->pitch_mul = 1.0;
rsPisk.FA = 0.0; rsPisk->pitch_off = 0.0;
}
} }
else if( token == "brakeacc:" ) { else if( token == "brakeacc:" ) {
// plik z przyspieszaczem (upust po zlapaniu hamowania) // plik z przyspieszaczem (upust po zlapaniu hamowania)
// sBrakeAcc.Init(str.c_str(),Parser->GetNextSymbol().ToDouble(),GetPosition().x,GetPosition().y,GetPosition().z,true); // sBrakeAcc.Init(str.c_str(),Parser->GetNextSymbol().ToDouble(),GetPosition().x,GetPosition().y,GetPosition().z,true);
parser.getTokens( 1, false ); parser >> token; parser.getTokens( 1, false ); parser >> token;
sBrakeAcc = TSoundsManager::GetFromName( token, true ); sBrakeAcc = sound_man->create_sound(token);
bBrakeAcc = true; bBrakeAcc = true;
// sBrakeAcc.AM=1.0; // sBrakeAcc->gain_mul=1.0;
// sBrakeAcc.AA=0.0; // sBrakeAcc->gain_off=0.0;
// sBrakeAcc.FM=1.0; // sBrakeAcc->pitch_mul=1.0;
// sBrakeAcc.FA=0.0; // sBrakeAcc->pitch_off=0.0;
} }
else if( token == "unbrake:" ) { else if( token == "unbrake:" ) {
@@ -4835,14 +4868,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rsUnbrake.Init( rsUnbrake = sound_man->create_sound(token);
token, attenuation, if (rsUnbrake)
GetPosition().x, GetPosition().y, GetPosition().z, rsUnbrake->dist(attenuation);
true );
rsUnbrake.AM = 1.0;
rsUnbrake.AA = 0.0;
rsUnbrake.FM = 1.0;
rsUnbrake.FA = 0.0;
} }
else if( token == "derail:" ) { else if( token == "derail:" ) {
@@ -4852,14 +4880,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rsDerailment.Init( rsDerailment = sound_man->create_sound(token);
token, attenuation, if (rsDerailment)
GetPosition().x, GetPosition().y, GetPosition().z, rsDerailment->dist(attenuation);
true );
rsDerailment.AM = 1.0;
rsDerailment.AA = 0.0;
rsDerailment.FM = 1.0;
rsDerailment.FA = 0.0;
} }
else if( token == "dieselinc:" ) { else if( token == "dieselinc:" ) {
@@ -4869,14 +4892,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rsDiesielInc.Init( rsDiesielInc = sound_man->create_sound(token);
token, attenuation, if (rsDiesielInc)
GetPosition().x, GetPosition().y, GetPosition().z, rsDiesielInc->dist(attenuation);
true );
rsDiesielInc.AM = 1.0;
rsDiesielInc.AA = 0.0;
rsDiesielInc.FM = 1.0;
rsDiesielInc.FA = 0.0;
} }
else if( token == "curve:" ) { else if( token == "curve:" ) {
@@ -4886,24 +4904,19 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
parser parser
>> token >> token
>> attenuation; >> attenuation;
rscurve.Init( rscurve = sound_man->create_sound(token);
token, attenuation, if (rscurve)
GetPosition().x, GetPosition().y, GetPosition().z, rscurve->dist(attenuation);
true );
rscurve.AM = 1.0;
rscurve.AA = 0.0;
rscurve.FM = 1.0;
rscurve.FA = 0.0;
} }
else if( token == "horn1:" ) { else if( token == "horn1:" ) {
// pliki z trabieniem // pliki z trabieniem
sHorn1.Load( parser, GetPosition() ); sHorn1 = sound_man->create_complex_sound(parser);
} }
else if( token == "horn2:" ) { else if( token == "horn2:" ) {
// pliki z trabieniem wysokoton. // pliki z trabieniem wysokoton.
sHorn2.Load( parser, GetPosition() ); sHorn2 = sound_man->create_complex_sound(parser);
if( iHornWarning ) { if( iHornWarning ) {
iHornWarning = 2; // numer syreny do użycia po otrzymaniu sygnału do jazdy iHornWarning = 2; // numer syreny do użycia po otrzymaniu sygnału do jazdy
} }
@@ -4911,74 +4924,62 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
else if( token == "departuresignal:" ) { else if( token == "departuresignal:" ) {
// pliki z sygnalem odjazdu // pliki z sygnalem odjazdu
sDepartureSignal.Load( parser, GetPosition() ); sDepartureSignal = sound_man->create_complex_sound(parser);
} }
else if( token == "pantographup:" ) { else if( token == "pantographup:" ) {
// pliki dzwiekow pantografow // pliki dzwiekow pantografow
parser.getTokens( 1, false ); parser >> token; parser.getTokens( 1, false ); parser >> token;
sPantUp.Init( sPantUp = sound_man->create_sound(token);
token, 50,
GetPosition().x, GetPosition().y, GetPosition().z,
true );
} }
else if( token == "pantographdown:" ) { else if( token == "pantographdown:" ) {
// pliki dzwiekow pantografow // pliki dzwiekow pantografow
parser.getTokens( 1, false ); parser >> token; parser.getTokens( 1, false ); parser >> token;
sPantDown.Init( sPantDown = sound_man->create_sound(token);
token, 50,
GetPosition().x, GetPosition().y, GetPosition().z,
true );
} }
else if( token == "compressor:" ) { else if( token == "compressor:" ) {
// pliki ze sprezarka // pliki ze sprezarka
sCompressor.Load( parser, GetPosition() ); sCompressor = sound_man->create_complex_sound(parser);
} }
else if( token == "converter:" ) { else if( token == "converter:" ) {
// pliki z przetwornica // pliki z przetwornica
// if (MoverParameters->EngineType==DieselElectric) //będzie modulowany? // if (MoverParameters->EngineType==DieselElectric) //będzie modulowany?
sConverter.Load( parser, GetPosition() ); sConverter = sound_man->create_complex_sound(parser);
} }
else if( token == "turbo:" ) { else if( token == "turbo:" ) {
// pliki z turbogeneratorem // pliki z turbogeneratorem
sTurbo.Load( parser, GetPosition() ); sTurbo = sound_man->create_complex_sound(parser);
} }
else if( token == "small-compressor:" ) { else if( token == "small-compressor:" ) {
// pliki z przetwornica // pliki z przetwornica
sSmallCompressor.Load( parser, GetPosition() ); sSmallCompressor = sound_man->create_complex_sound(parser);
} }
else if( token == "dooropen:" ) { else if( token == "dooropen:" ) {
parser.getTokens( 1, false ); parser >> token; parser.getTokens( 1, false ); parser >> token;
rsDoorOpen.Init( rsDoorOpen = sound_man->create_sound(token);
token, 50,
GetPosition().x, GetPosition().y, GetPosition().z,
true );
} }
else if( token == "doorclose:" ) { else if( token == "doorclose:" ) {
parser.getTokens( 1, false ); parser >> token; parser.getTokens( 1, false ); parser >> token;
rsDoorClose.Init( rsDoorClose = sound_man->create_sound(token);
token, 50,
GetPosition().x, GetPosition().y, GetPosition().z,
true );
} }
else if( token == "sand:" ) { else if( token == "sand:" ) {
// pliki z piasecznica // pliki z piasecznica
sSand.Load( parser, GetPosition() ); sSand = sound_man->create_complex_sound(parser);
} }
else if( token == "releaser:" ) { else if( token == "releaser:" ) {
// pliki z odluzniaczem // pliki z odluzniaczem
sReleaser.Load( parser, GetPosition() ); sReleaser = sound_man->create_complex_sound(parser);
} }
} while( ( token != "" ) } while( ( token != "" )

View File

@@ -14,8 +14,6 @@ http://mozilla.org/MPL/2.0/.
#include "TrkFoll.h" #include "TrkFoll.h"
// McZapkie: // McZapkie:
#include "RealSound.h"
#include "AdvSound.h"
#include "Button.h" #include "Button.h"
#include "AirCoupler.h" #include "AirCoupler.h"
#include "Texture.h" #include "Texture.h"
@@ -307,28 +305,28 @@ public: // modele składowe pojazdu
double dRailLength; double dRailLength;
double dRailPosition[MaxAxles]; // licznik pozycji osi w/m szyny double dRailPosition[MaxAxles]; // licznik pozycji osi w/m szyny
double dWheelsPosition[MaxAxles]; // pozycja osi w/m srodka pojazdu double dWheelsPosition[MaxAxles]; // pozycja osi w/m srodka pojazdu
TRealSound rsStukot[MaxAxles]; // dzwieki poszczegolnych osi //McZapkie-270202 sound* rsStukot[MaxAxles] = { nullptr }; // dzwieki poszczegolnych osi //McZapkie-270202
TRealSound rsSilnik; // McZapkie-010302 - silnik sound* rsSilnik = nullptr; // McZapkie-010302 - silnik
TRealSound rsWentylator; // McZapkie-030302 sound* rsWentylator = nullptr; // McZapkie-030302
TRealSound rsPisk; // McZapkie-260302 sound* rsPisk = nullptr; // McZapkie-260302
TRealSound rsDerailment; // McZapkie-051202 sound* rsDerailment = nullptr; // McZapkie-051202
TRealSound rsPrzekladnia; sound* rsPrzekladnia = nullptr;
TAdvancedSound sHorn1; sound* sHorn1 = nullptr;
TAdvancedSound sHorn2; sound* sHorn2 = nullptr;
TAdvancedSound sCompressor; // NBMX wrzesien 2003 sound* sCompressor = nullptr; // NBMX wrzesien 2003
TAdvancedSound sConverter; sound* sConverter = nullptr;
TAdvancedSound sSmallCompressor; sound* sSmallCompressor = nullptr;
TAdvancedSound sDepartureSignal; sound* sDepartureSignal = nullptr;
TAdvancedSound sTurbo; sound* sTurbo = nullptr;
TAdvancedSound sSand; sound* sSand = nullptr;
TAdvancedSound sReleaser; sound* sReleaser = nullptr;
// Winger 010304 // Winger 010304
// TRealSound rsPanTup; //PSound sPantUp; // sound* rsPanTup; //PSound sPantUp;
TRealSound sPantUp; sound* sPantUp = nullptr;
TRealSound sPantDown; sound* sPantDown = nullptr;
TRealSound rsDoorOpen; // Ra: przeniesione z kabiny sound* rsDoorOpen = nullptr; // Ra: przeniesione z kabiny
TRealSound rsDoorClose; sound* rsDoorClose = nullptr;
double eng_vol_act; double eng_vol_act;
double eng_frq_act; double eng_frq_act;
@@ -339,10 +337,10 @@ public: // modele składowe pojazdu
vector3 modelShake; vector3 modelShake;
bool renderme; // yB - czy renderowac bool renderme; // yB - czy renderowac
// TRealSound sBrakeAcc; //dźwięk przyspieszacza // sound* sBrakeAcc; //dźwięk przyspieszacza
PSound sBrakeAcc; sound* sBrakeAcc = nullptr;
bool bBrakeAcc; bool bBrakeAcc;
TRealSound rsUnbrake; // yB - odglos luzowania sound* rsUnbrake = nullptr; // yB - odglos luzowania
float ModCamRot; float ModCamRot;
int iInventory; // flagi bitowe posiadanych submodeli (np. świateł) int iInventory; // flagi bitowe posiadanych submodeli (np. świateł)
void TurnOff(); void TurnOff();
@@ -397,8 +395,8 @@ public: // modele składowe pojazdu
return this ? asName : std::string(""); return this ? asName : std::string("");
}; };
TRealSound rsDiesielInc; // youBy sound* rsDiesielInc = nullptr; // youBy
TRealSound rscurve; // youBy sound* rscurve = nullptr; // youBy
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych // std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
// youBy - dym // youBy - dym
// TSmoke Smog; // TSmoke Smog;

View File

@@ -73,7 +73,7 @@ union TParam
bool asBool; bool asBool;
double asdouble; double asdouble;
int asInt; int asInt;
TTextSound *tsTextSound; sound *tsTextSound;
char *asText; char *asText;
TCommandType asCommand; TCommandType asCommand;
TTractionPowerSource *psPower; TTractionPowerSource *psPower;

View File

@@ -1,92 +0,0 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
/*
MaSzyna EU07 locomotive simulator
Copyright (C) 2001-2004 Marcin Wozniak and others
*/
#include "stdafx.h"
#include "FadeSound.h"
#include "Timer.h"
TFadeSound::~TFadeSound()
{
Free();
}
void TFadeSound::Free()
{
}
void TFadeSound::Init(std::string const &Name, float fNewFade)
{
Sound = TSoundsManager::GetFromName(Name, false);
if (Sound)
Sound->SetVolume(0);
fFade = fNewFade;
fTime = 0;
}
void TFadeSound::TurnOn()
{
State = ss_Starting;
Sound->Play(0, 0, DSBPLAY_LOOPING);
fTime = fFade;
}
void TFadeSound::TurnOff()
{
State = ss_ShuttingDown;
}
void TFadeSound::Update()
{
if (State == ss_Starting)
{
fTime += Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime >= fFade)
{
fTime = fFade;
State = ss_Commencing;
Sound->SetVolume(-2000 * (fFade - fTime) / fFade);
Sound->SetFrequency(44100 - 500 + 500 * (fTime) / fFade);
}
else if (Timer::GetSoundTimer())
{
Sound->SetVolume(-2000 * (fFade - fTime) / fFade);
Sound->SetFrequency(44100 - 500 + 500 * (fTime) / fFade);
}
}
else if (State == ss_ShuttingDown)
{
fTime -= Timer::GetDeltaTime();
if (fTime <= 0)
{
State = ss_Off;
fTime = 0;
Sound->Stop();
}
if (Timer::GetSoundTimer())
{ // DSBVOLUME_MIN
Sound->SetVolume(-2000 * (fFade - fTime) / fFade);
Sound->SetFrequency(44100 - 500 + 500 * fTime / fFade);
}
}
}
void TFadeSound::Volume(long vol)
{
float glos = 1;
Sound->SetVolume(vol * glos);
}
//---------------------------------------------------------------------------

View File

@@ -1,40 +0,0 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#ifndef FadeSoundH
#define FadeSoundH
#include "Sound.h"
#include "AdvSound.h"
class TFadeSound
{
PSound Sound = nullptr;
float fFade = 0.0f;
float dt = 0.0f,
fTime = 0.0f;
TSoundState State = ss_Off;
public:
TFadeSound();
~TFadeSound();
void Init(std::string const &Name, float fNewFade);
void TurnOn();
void TurnOff();
bool Playing()
{
return (State == ss_Commencing || State == ss_Starting);
};
void Free();
void Update();
void Volume(long vol);
};
//---------------------------------------------------------------------------
#endif

View File

@@ -121,7 +121,7 @@ class TDynamicObject;
class TAnimModel; // obiekt terenu class TAnimModel; // obiekt terenu
class cParser; // nowy (powolny!) parser class cParser; // nowy (powolny!) parser
class TEvent; class TEvent;
class TTextSound; class sound;
class TTranscript class TTranscript
{ // klasa obsługująca linijkę napisu do dźwięku { // klasa obsługująca linijkę napisu do dźwięku
@@ -320,7 +320,7 @@ class Global
static float4 UITextColor; // base color of UI text static float4 UITextColor; // base color of UI text
static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47 static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47
static int iHiddenEvents; // czy łączyć eventy z torami poprzez nazwę toru static int iHiddenEvents; // czy łączyć eventy z torami poprzez nazwę toru
static TTextSound *tsRadioBusy[10]; // zajętość kanałów radiowych (wskaźnik na odgrywany dźwięk) static sound *tsRadioBusy[10]; // zajętość kanałów radiowych (wskaźnik na odgrywany dźwięk)
static int iPoKeysPWM[7]; // numery wejść dla PWM static int iPoKeysPWM[7]; // numery wejść dla PWM
//randomizacja //randomizacja

View File

@@ -26,7 +26,6 @@ http://mozilla.org/MPL/2.0/.
#include "TractionPower.h" #include "TractionPower.h"
#include "Traction.h" #include "Traction.h"
#include "Track.h" #include "Track.h"
#include "RealSound.h"
#include "AnimModel.h" #include "AnimModel.h"
#include "MemCell.h" #include "MemCell.h"
#include "mtable.h" #include "mtable.h"
@@ -38,13 +37,16 @@ http://mozilla.org/MPL/2.0/.
#include "Names.h" #include "Names.h"
#include "World.h" #include "World.h"
#include "uilayer.h" #include "uilayer.h"
#include "sound.h"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#ifdef _WIN32
extern "C" extern "C"
{ {
GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window ); //m7todo: potrzebne do directsound GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window );
} }
#endif
bool bCondition; // McZapkie: do testowania warunku na event multiple bool bCondition; // McZapkie: do testowania warunku na event multiple
std::string LogComment; std::string LogComment;
@@ -231,13 +233,6 @@ void TGroundNode::RenderHidden()
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition); double mgn = SquareMagnitude(pCenter - Global::pCameraPosition);
switch (iType) switch (iType)
{ {
case TP_SOUND: // McZapkie - dzwiek zapetlony w zaleznosci od odleglosci
if ((tsStaticSound->GetStatus() & DSBSTATUS_PLAYING) == DSBPLAY_LOOPING)
{
tsStaticSound->Play(1, DSBPLAY_LOOPING, true, tsStaticSound->vSoundPosition);
tsStaticSound->AdjFreq(1.0, Timer::GetDeltaTime());
}
return;
case TP_EVLAUNCH: case TP_EVLAUNCH:
if (EvLaunch->Render()) if (EvLaunch->Render())
if ((EvLaunch->dRadius < 0) || (mgn < EvLaunch->dRadius)) if ((EvLaunch->dRadius < 0) || (mgn < EvLaunch->dRadius))
@@ -1060,8 +1055,11 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
str = token; str = token;
//str = AnsiString(token.c_str());
tmp->tsStaticSound = new TTextSound(str, sqrt(tmp->fSquareRadius), tmp->pCenter.x, tmp->pCenter.y, tmp->pCenter.z, false, false, rmin); tmp->tsStaticSound = sound_man->create_text_sound(str);
if (tmp->tsStaticSound)
tmp->tsStaticSound->position(tmp->pCenter).dist(sqrt(tmp->fSquareRadius));
if (rmin < 0.0) if (rmin < 0.0)
rmin = 0.0; // przywrócenie poprawnej wartości, jeśli służyła do wyłączenia efektu Dopplera rmin = 0.0; // przywrócenie poprawnej wartości, jeśli służyła do wyłączenia efektu Dopplera
parser->getTokens(); parser->getTokens();
@@ -3183,15 +3181,13 @@ bool TGround::CheckQuery()
switch (tmpEvent->Params[0].asInt) switch (tmpEvent->Params[0].asInt)
{ // trzy możliwe przypadki: { // trzy możliwe przypadki:
case 0: case 0:
tmpEvent->Params[9].tsTextSound->Stop(); tmpEvent->Params[9].tsTextSound->stop();
break; break;
case 1: case 1:
tmpEvent->Params[9].tsTextSound->Play( tmpEvent->Params[9].tsTextSound->play();
1, 0, true, tmpEvent->Params[9].tsTextSound->vSoundPosition);
break; break;
case -1: case -1:
tmpEvent->Params[9].tsTextSound->Play( tmpEvent->Params[9].tsTextSound->play();
1, DSBPLAY_LOOPING, true, tmpEvent->Params[9].tsTextSound->vSoundPosition);
break; break;
} }
break; break;

View File

@@ -123,7 +123,7 @@ public:
TEventLauncher *EvLaunch; // wyzwalacz zdarzeń TEventLauncher *EvLaunch; // wyzwalacz zdarzeń
TTraction *hvTraction; // drut zasilający TTraction *hvTraction; // drut zasilający
TTractionPowerSource *psTractionPowerSource; // zasilanie drutu (zaniedbane w sceneriach) TTractionPowerSource *psTractionPowerSource; // zasilanie drutu (zaniedbane w sceneriach)
TTextSound *tsStaticSound; // dźwięk przestrzenny sound *tsStaticSound; // dźwięk przestrzenny
TGroundNode *nNode; // obiekt renderujący grupowo ma tu wskaźnik na listę obiektów TGroundNode *nNode; // obiekt renderujący grupowo ma tu wskaźnik na listę obiektów
}; };
Math3D::vector3 pCenter; // współrzędne środka do przydzielenia sektora Math3D::vector3 pCenter; // współrzędne środka do przydzielenia sektora

View File

@@ -1,278 +0,0 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
/*
MaSzyna EU07 locomotive simulator
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
*/
#include "stdafx.h"
#include "RealSound.h"
#include "Globals.h"
#include "Logs.h"
//#include "math.h"
#include "Timer.h"
#include "McZapkie/mctools.h"
#include "usefull.h"
TRealSound::TRealSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic,
bool freqmod, double rmin)
{
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
}
TRealSound::~TRealSound()
{
// if (this) if (pSound) pSound->Stop();
}
void TRealSound::Free()
{
}
void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation, double X, double Y, double Z,
bool Dynamic, bool freqmod, double rmin)
{
// Nazwa=SoundName; //to tak raczej nie zadziała, (SoundName) jest tymczasowe
pSound = TSoundsManager::GetFromName(SoundName, Dynamic, &fFrequency);
if (pSound)
{
if (freqmod)
if (fFrequency != 22050.0)
{ // dla modulowanych nie może być zmiany mnożnika, bo częstotliwość w nagłówku byłą
// ignorowana, a mogła być inna niż 22050
fFrequency = 22050.0;
ErrorLog("Bad sound: " + SoundName + ", as modulated, should have 22.05kHz in header");
}
AM = 1.0;
pSound->SetVolume(DSBVOLUME_MIN);
}
else
{ // nie ma dźwięku, to jest wysyp
AM = 0;
ErrorLog("Missed sound: " + SoundName);
}
if (DistanceAttenuation > 0.0)
{
dSoundAtt = DistanceAttenuation * DistanceAttenuation;
vSoundPosition.x = X;
vSoundPosition.y = Y;
vSoundPosition.z = Z;
if (rmin < 0)
iDoppler = 1; // wyłączenie efektu Dopplera, np. dla dźwięku ptaków
}
else
dSoundAtt = -1;
};
double TRealSound::ListenerDistance(vector3 ListenerPosition)
{
if (dSoundAtt == -1)
{
return 0.0;
}
else
{
return SquareMagnitude(ListenerPosition - vSoundPosition);
}
}
void TRealSound::Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition)
{
if (!pSound)
return;
long int vol;
double dS = 0.0;
// double Distance;
DWORD stat;
if ((Global::bSoundEnabled) && (AM != 0))
{
if (Volume > 1.0)
Volume = 1.0;
fPreviousDistance = fDistance;
fDistance = 0.0; //??
if (dSoundAtt > 0.0)
{
vSoundPosition = NewPosition;
dS = dSoundAtt; //*dSoundAtt; //bo odleglosc podawana w kwadracie
fDistance = ListenerDistance(Global::pCameraPosition);
if (ListenerInside) // osłabianie dźwięków z odległością
Volume = Volume * dS / (dS + fDistance);
else
Volume = Volume * dS / (dS + 2 * fDistance); // podwójne dla ListenerInside=false
}
if (iDoppler) //
{ // Ra 2014-07: efekt Dopplera nie zawsze jest wskazany
// if (FreeFlyModeFlag) //gdy swobodne latanie - nie sprawdza się to
fPreviousDistance = fDistance; // to efektu Dopplera nie będzie
}
if (Looping) // dźwięk zapętlony można wyłączyć i zostanie włączony w miarę potrzeby
bLoopPlay = true; // dźwięk wyłączony
// McZapkie-010302 - babranie tylko z niezbyt odleglymi dźwiękami
if ((dSoundAtt == -1) || (fDistance < 20.0 * dS))
{
// vol=2*Volume+1;
// if (vol<1) vol=1;
// vol=10000*(log(vol)-1);
// vol=10000*(vol-1);
// int glos=1;
// Volume=Volume*glos; //Ra: whatta hella is this
if (Volume < 0.0)
Volume = 0.0;
vol = -5000.0 + 5000.0 * Volume;
if (vol >= 0)
vol = -1;
if (Timer::GetSoundTimer() || !Looping) // Ra: po co to jest?
pSound->SetVolume(vol); // Attenuation, in hundredths of a decibel (dB).
pSound->GetStatus(&stat);
if (!(stat & DSBSTATUS_PLAYING))
pSound->Play(0, 0, Looping);
}
else // wylacz dzwiek bo daleko
{ // Ra 2014-09: oddalanie się nie może być powodem do wyłączenie dźwięku
/*
// Ra: stara wersja, ale podobno lepsza
pSound->GetStatus(&stat);
if (bLoopPlay) //jeśli zapętlony, to zostanie ponownie włączony, o ile znajdzie się
bliżej
if (stat&DSBSTATUS_PLAYING)
pSound->Stop();
// Ra: wyłączyłem, bo podobno jest gorzej niż wcześniej
//ZiomalCl: dźwięk po wyłączeniu sam się nie włączy, gdy wrócimy w rejon odtwarzania
pSound->SetVolume(DSBVOLUME_MIN); //dlatego lepiej go wyciszyć na czas oddalenia się
pSound->GetStatus(&stat);
if (!(stat&DSBSTATUS_PLAYING))
pSound->Play(0,0,Looping); //ZiomalCl: włączenie odtwarzania rownież i tu, gdyż
jesli uruchamiamy dźwięk poza promieniem, nie uruchomi się on w ogóle
*/
}
}
};
void TRealSound::Start(){
// włączenie dźwięku
};
void TRealSound::Stop()
{
DWORD stat;
if (pSound)
if ((Global::bSoundEnabled) && (AM != 0))
{
bLoopPlay = false; // dźwięk wyłączony
pSound->GetStatus(&stat);
if (stat & DSBSTATUS_PLAYING)
pSound->Stop();
}
};
void TRealSound::AdjFreq(double Freq, double dt) // McZapkie TODO: dorobic tu efekt Dopplera
// Freq moze byc liczba dodatnia mniejsza od 1 lub wieksza od 1
{
float df, Vlist;
if ((Global::bSoundEnabled) && (AM != 0) && (pSound != nullptr))
{
if (dt > 0)
// efekt Dopplera
{
Vlist = (sqrt(fPreviousDistance) - sqrt(fDistance)) / dt;
df = Freq * (1 + Vlist / 299.8);
}
else
df = Freq;
if (Timer::GetSoundTimer())
{
df = fFrequency * df; // TODO - brac czestotliwosc probkowania z wav
pSound->SetFrequency( clamp( df, static_cast<float>(DSBFREQUENCY_MIN), static_cast<float>(DSBFREQUENCY_MAX) ) );
}
}
}
double TRealSound::GetWaveTime() // McZapkie: na razie tylko dla 22KHz/8bps
{ // używana do pomiaru czasu dla dźwięków z początkiem i końcem
if (!pSound)
return 0.0;
double WaveTime;
DSBCAPS caps;
caps.dwSize = sizeof(caps);
pSound->GetCaps(&caps);
WaveTime = caps.dwBufferBytes;
return WaveTime /
fFrequency; //(pSound->); // wielkosc w bajtach przez czestotliwosc probkowania
}
void TRealSound::SetPan(int Pan)
{
pSound->SetPan(Pan);
}
int TRealSound::GetStatus()
{
DWORD stat;
if ((Global::bSoundEnabled) && (AM != 0))
{
pSound->GetStatus(&stat);
return stat;
}
else
return 0;
}
void TRealSound::ResetPosition()
{
if (pSound) // Ra: znowu jakiś badziew!
pSound->SetCurrentPosition(0);
}
TTextSound::TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
bool Dynamic, bool freqmod, double rmin)
: TRealSound(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin)
{
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
}
void TTextSound::Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
bool Dynamic, bool freqmod, double rmin)
{ // dodatkowo doczytuje plik tekstowy
//TRealSound::Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
fTime = GetWaveTime();
std::string txt(SoundName);
txt.erase( txt.rfind( '.' ) ); // obcięcie rozszerzenia
for (size_t i = txt.length(); i > 0; --i)
if (txt[i] == '/')
txt[i] = '\\'; // bo nie rozumi
txt += "-" + Global::asLang + ".txt"; // już może być w różnych językach
if (!FileExists(txt))
txt = "sounds\\" + txt; //ścieżka może nie być podana
if (FileExists(txt))
{ // wczytanie
/* TFileStream *ts = new TFileStream(txt, fmOpenRead);
asText = AnsiString::StringOfChar(' ', ts->Size);
ts->Read(asText.c_str(), ts->Size);
delete ts;
*/ std::ifstream inputfile( txt );
asText.assign( std::istreambuf_iterator<char>( inputfile ), std::istreambuf_iterator<char>() );
}
};
void TTextSound::Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition)
{
if (false == asText.empty())
{ // jeśli ma powiązany tekst
DWORD stat;
pSound->GetStatus(&stat);
if (!(stat & DSBSTATUS_PLAYING)) {
// jeśli nie jest aktualnie odgrywany
Global::tranTexts.Add( asText, fTime, true );
}
}
TRealSound::Play(Volume, Looping, ListenerInside, NewPosition);
};
//---------------------------------------------------------------------------

View File

@@ -1,83 +0,0 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#ifndef RealSoundH
#define RealSoundH
#include <string>
#include "Sound.h"
#include "geometry.h"
class TRealSound
{
protected:
PSound pSound = nullptr;
// char *Nazwa; // dla celow odwszawiania NOTE: currently not used anywhere
double fDistance = 0.0,
fPreviousDistance = 0.0; // dla liczenia Dopplera
float fFrequency = 22050.0; // częstotliwość samplowania pliku
int iDoppler = 0; // Ra 2014-07: możliwość wyłączenia efektu Dopplera np. dla śpiewu ptaków
public:
vector3 vSoundPosition; // polozenie zrodla dzwieku
double dSoundAtt = -1.0; // odleglosc polowicznego zaniku dzwieku
double AM = 0.0; // mnoznik amplitudy
double AA = 0.0; // offset amplitudy
double FM = 0.0; // mnoznik czestotliwosci
double FA = 0.0; // offset czestotliwosci
bool bLoopPlay = false; // czy zapętlony dźwięk jest odtwarzany
TRealSound() = default;
TRealSound( std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic,
bool freqmod = false, double rmin = 0.0);
~TRealSound();
void Free();
void Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic,
bool freqmod = false, double rmin = 0.0);
double ListenerDistance(vector3 ListenerPosition);
void Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition);
void Start();
void Stop();
void AdjFreq(double Freq, double dt);
void SetPan(int Pan);
double GetWaveTime(); // McZapkie TODO: dorobic dla roznych bps
int GetStatus();
void ResetPosition();
// void FreqReset(float f=22050.0) {fFrequency=f;};
bool Empty() { return ( pSound == nullptr ); }
};
class TTextSound : public TRealSound
{ // dźwięk ze stenogramem
std::string asText;
float fTime; // czas trwania
public:
TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
bool Dynamic, bool freqmod = false, double rmin = 0.0);
void Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
bool Dynamic, bool freqmod = false, double rmin = 0.0);
void Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition);
};
class TSynthSound
{ // klasa generująca sygnał odjazdu (Rp12, Rp13), potem rozbudować o pracę manewrowego...
int iIndex[44]; // indeksy początkowe, gdy mamy kilka wariantów dźwięków składowych
// 0..9 - cyfry 0..9
// 10..19 - liczby 10..19
// 21..29 - dziesiątki (*21==*10?)
// 31..39 - setki 100,200,...,800,900
// 40 - "tysiąc"
// 41 - "tysiące"
// 42 - indeksy początkowe dla "odjazd"
// 43 - indeksy początkowe dla "gotów"
PSound *sSound; // posortowana tablica dźwięków, rozmiar zależny od liczby znalezionych plików
// a może zamiast wielu plików/dźwięków zrobić jeden połączony plik i posługiwać się czasem
// od..do?
};
//---------------------------------------------------------------------------
#endif

View File

@@ -1,5 +0,0 @@
#ifdef _WIN32
#include "WinSound.cpp"
#else
#include "DummySound.cpp"
#endif

81
Sound.h
View File

@@ -1,81 +0,0 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <stack>
#include <cinttypes>
#ifdef _WIN32
#include <dsound.h>
#else
#define DSBFREQUENCY_MIN 0
#define DSBFREQUENCY_MAX 0
#define DSBSTATUS_PLAYING 0
#define DSBPLAY_LOOPING 0
#define DSBVOLUME_MIN 0
#define DSBVOLUME_MAX 0
struct DSBCAPS
{
uint16_t dwBufferBytes;
uint16_t dwSize;
};
struct dummysb
{
void Stop() {}
void SetCurrentPosition(int) {}
void SetVolume(int) {}
void Play(int, int, int) {}
void GetStatus(unsigned int *stat) { *stat = 0; }
void SetPan(int) {}
void SetFrequency(int) {}
void GetCaps(DSBCAPS *caps) { caps->dwBufferBytes = 0; }
};
typedef dummysb* LPDIRECTSOUNDBUFFER;
typedef int LPDIRECTSOUNDNOTIFY;
typedef int LPDIRECTSOUND;
typedef int HWND;
#endif
typedef LPDIRECTSOUNDBUFFER PSound;
class TSoundContainer
{
public:
int Concurrent;
int Oldest;
std::string m_name;
LPDIRECTSOUNDBUFFER DSBuffer;
float fSamplingRate; // częstotliwość odczytana z pliku
int iBitsPerSample; // ile bitów na próbkę
TSoundContainer *Next;
std::stack<LPDIRECTSOUNDBUFFER> DSBuffers;
TSoundContainer(LPDIRECTSOUND pDS, std::string const &Directory, std::string const &Filename, int NConcurrent);
~TSoundContainer();
LPDIRECTSOUNDBUFFER GetUnique( LPDIRECTSOUND pDS );
};
class TSoundsManager
{
private:
static LPDIRECTSOUND pDS;
static LPDIRECTSOUNDNOTIFY pDSNotify;
static TSoundContainer *First;
static int Count;
static TSoundContainer * LoadFromFile( std::string const &Directory, std::string const &FileName, int Concurrent);
public:
~TSoundsManager();
static void Init( HWND hWnd );
static void Free();
static LPDIRECTSOUNDBUFFER GetFromName( std::string const &Name, bool Dynamic, float *fSamplingRate = NULL );
static void RestoreAll();
};

544
Train.cpp

File diff suppressed because it is too large Load Diff

78
Train.h
View File

@@ -14,8 +14,6 @@ http://mozilla.org/MPL/2.0/.
#include "Button.h" #include "Button.h"
#include "Gauge.h" #include "Gauge.h"
#include "Spring.h" #include "Spring.h"
#include "AdvSound.h"
#include "FadeSound.h"
#include "PyInt.h" #include "PyInt.h"
#include "command.h" #include "command.h"
@@ -99,8 +97,8 @@ class TTrain
bool initialize_button(cParser &Parser, std::string const &Label, int const Cabindex); bool initialize_button(cParser &Parser, std::string const &Label, int const Cabindex);
// plays specified sound, or fallback sound if the primary sound isn't presend // plays specified sound, or fallback sound if the primary sound isn't presend
// NOTE: temporary routine until sound system is sorted out and paired with switches // NOTE: temporary routine until sound system is sorted out and paired with switches
void play_sound( PSound Sound, int const Volume = DSBVOLUME_MAX, DWORD const Flags = 0 ); void play_sound( sound* Sound, float gain = 1.0f);
void play_sound( PSound Sound, PSound Fallbacksound, int const Volume, DWORD const Flags ); void play_sound( sound* Sound, sound* Fallbacksound, float gain = 1.0f );
// helper, returns true for EMU with oerlikon brake // helper, returns true for EMU with oerlikon brake
bool is_eztoer() const; bool is_eztoer() const;
// command handlers // command handlers
@@ -379,48 +377,48 @@ public: // reszta może by?publiczna
double fMechRoll; double fMechRoll;
double fMechPitch; double fMechPitch;
PSound dsbNastawnikJazdy; sound* dsbNastawnikJazdy = nullptr;
PSound dsbNastawnikBocz; // hunter-081211 sound* dsbNastawnikBocz = nullptr; // hunter-081211
PSound dsbRelay; sound* dsbRelay = nullptr;
PSound dsbPneumaticRelay; sound* dsbPneumaticRelay = nullptr;
PSound dsbSwitch; sound* dsbSwitch = nullptr;
PSound dsbPneumaticSwitch; sound* dsbPneumaticSwitch = nullptr;
PSound dsbReverserKey; // hunter-121211 sound* dsbReverserKey = nullptr; // hunter-121211
PSound dsbCouplerAttach; // Ra: w kabinie???? sound* dsbCouplerAttach = nullptr; // Ra: w kabinie????
PSound dsbCouplerDetach; // Ra: w kabinie??? sound* dsbCouplerDetach = nullptr; // Ra: w kabinie???
PSound dsbDieselIgnition; // Ra: w kabinie??? sound* dsbDieselIgnition = nullptr; // Ra: w kabinie???
PSound dsbDoorClose; // Ra: w kabinie??? sound* dsbDoorClose = nullptr; // Ra: w kabinie???
PSound dsbDoorOpen; // Ra: w kabinie??? sound* dsbDoorOpen = nullptr; // Ra: w kabinie???
// Winger 010304 // Winger 010304
PSound dsbPantUp; sound* dsbPantUp = nullptr;
PSound dsbPantDown; sound* dsbPantDown = nullptr;
PSound dsbWejscie_na_bezoporow; sound* dsbWejscie_na_bezoporow = nullptr;
PSound dsbWejscie_na_drugi_uklad; // hunter-081211: poprawka literowki sound* dsbWejscie_na_drugi_uklad = nullptr; // hunter-081211: poprawka literowki
// PSound dsbHiss1; // sound* dsbHiss1;
// PSound dsbHiss2; // sound* dsbHiss2;
// McZapkie-280302 // McZapkie-280302
TRealSound rsBrake; sound* rsBrake = nullptr;
TRealSound rsSlippery; sound* rsSlippery = nullptr;
TRealSound rsHiss; // upuszczanie sound* rsHiss = nullptr; // upuszczanie
TRealSound rsHissU; // napelnianie sound* rsHissU = nullptr; // napelnianie
TRealSound rsHissE; // nagle sound* rsHissE = nullptr; // nagle
TRealSound rsHissX; // fala sound* rsHissX = nullptr; // fala
TRealSound rsHissT; // czasowy sound* rsHissT = nullptr; // czasowy
TRealSound rsSBHiss; sound* rsSBHiss = nullptr;
TRealSound rsRunningNoise; sound* rsRunningNoise = nullptr;
TRealSound rsEngageSlippery; sound* rsEngageSlippery = nullptr;
TRealSound rsFadeSound; sound* rsFadeSound = nullptr;
PSound dsbHasler; sound* dsbHasler = nullptr;
PSound dsbBuzzer; sound* dsbBuzzer = nullptr;
PSound dsbSlipAlarm; // Bombardier 011010: alarm przy poslizgu dla 181/182 sound* dsbSlipAlarm = nullptr; // Bombardier 011010: alarm przy poslizgu dla 181/182
// TFadeSound sConverter; //przetwornica // TFadeSound sConverter; //przetwornica
// TFadeSound sSmallCompressor; //przetwornica // TFadeSound sSmallCompressor; //przetwornica
@@ -432,10 +430,10 @@ public: // reszta może by?publiczna
vector3 MirrorPosition(bool lewe); vector3 MirrorPosition(bool lewe);
private: private:
// PSound dsbBuzzer; // sound* dsbBuzzer;
PSound dsbCouplerStretch; sound* dsbCouplerStretch = nullptr;
PSound dsbEN57_CouplerStretch; sound* dsbEN57_CouplerStretch = nullptr;
PSound dsbBufferClamp; sound* dsbBufferClamp = nullptr;
// TSubModel *smCzuwakShpOn; // TSubModel *smCzuwakShpOn;
// TSubModel *smCzuwakOn; // TSubModel *smCzuwakOn;
// TSubModel *smShpOn; // TSubModel *smShpOn;

View File

@@ -21,7 +21,7 @@ http://mozilla.org/MPL/2.0/.
#include "renderer.h" #include "renderer.h"
#include "Timer.h" #include "Timer.h"
#include "mtable.h" #include "mtable.h"
#include "Sound.h" #include "sound.h"
#include "Camera.h" #include "Camera.h"
#include "ResourceManager.h" #include "ResourceManager.h"
#include "Event.h" #include "Event.h"
@@ -217,7 +217,7 @@ TWorld::~TWorld()
Global::bManageNodes = false; // Ra: wyłączenie wyrejestrowania, bo się sypie Global::bManageNodes = false; // Ra: wyłączenie wyrejestrowania, bo się sypie
TrainDelete(); TrainDelete();
// Ground.Free(); //Ra: usunięcie obiektów przed usunięciem dźwięków - sypie się // Ground.Free(); //Ra: usunięcie obiektów przed usunięciem dźwięków - sypie się
TSoundsManager::Free(); delete sound_man;
TModelsManager::Free(); TModelsManager::Free();
} }
@@ -304,12 +304,9 @@ bool TWorld::Init( GLFWwindow *Window ) {
std::shared_ptr<ui_panel> initpanel = std::make_shared<ui_panel>(85, 600); std::shared_ptr<ui_panel> initpanel = std::make_shared<ui_panel>(85, 600);
#ifdef _WIN32 sound_man = new sound_manager();
TSoundsManager::Init( glfwGetWin32Window( window ) );
#else
TSoundsManager::Init( 0 );
#endif
WriteLog("Sound Init OK"); WriteLog("Sound Init OK");
TModelsManager::Init(); TModelsManager::Init();
WriteLog("Models init OK"); WriteLog("Models init OK");
@@ -760,8 +757,7 @@ void TWorld::OnKeyDown(int cKey)
temp->MoverParameters->DecBrakeMult()) temp->MoverParameters->DecBrakeMult())
if (Train) if (Train)
{ // dźwięk oczywiście jest w kabinie { // dźwięk oczywiście jest w kabinie
Train->dsbSwitch->SetVolume(DSBVOLUME_MAX); Train->dsbSwitch->gain(1.0f).play();
Train->dsbSwitch->Play(0, 0, 0);
} }
} }
} }
@@ -790,8 +786,7 @@ void TWorld::OnKeyDown(int cKey)
tmp->iLights[CouplNr] = (tmp->iLights[CouplNr] & ~mask) | set; tmp->iLights[CouplNr] = (tmp->iLights[CouplNr] & ~mask) | set;
if (Train) if (Train)
{ // Ra: ten dźwięk z kabiny to przegięcie, ale na razie zostawiam { // Ra: ten dźwięk z kabiny to przegięcie, ale na razie zostawiam
Train->dsbSwitch->SetVolume(DSBVOLUME_MAX); Train->dsbSwitch->gain(1.0f).play();
Train->dsbSwitch->Play(0, 0, 0);
} }
} }
} }
@@ -811,8 +806,7 @@ void TWorld::OnKeyDown(int cKey)
if (temp->MoverParameters->IncLocalBrakeLevelFAST()) if (temp->MoverParameters->IncLocalBrakeLevelFAST())
if (Train) if (Train)
{ // dźwięk oczywiście jest w kabinie { // dźwięk oczywiście jest w kabinie
Train->dsbPneumaticRelay->SetVolume(-80); Train->dsbPneumaticRelay->gain(0.5f).play();
Train->dsbPneumaticRelay->Play(0, 0, 0);
} }
} }
} }
@@ -831,8 +825,7 @@ void TWorld::OnKeyDown(int cKey)
if (temp->MoverParameters->DecLocalBrakeLevelFAST()) if (temp->MoverParameters->DecLocalBrakeLevelFAST())
if (Train) if (Train)
{ // dźwięk oczywiście jest w kabinie { // dźwięk oczywiście jest w kabinie
Train->dsbPneumaticRelay->SetVolume(-80); Train->dsbPneumaticRelay->gain(0.5f).play();
Train->dsbPneumaticRelay->Play(0, 0, 0);
} }
} }
} }
@@ -1125,6 +1118,9 @@ bool TWorld::Update()
dt = Timer::GetDeltaRenderTime(); // nie uwzględnia pauzowania ani mnożenia czasu dt = Timer::GetDeltaRenderTime(); // nie uwzględnia pauzowania ani mnożenia czasu
sound_man->set_listener(Camera.Pos, Camera.LookAt, Camera.vUp);
sound_man->update(dt);
// fixed step render time routines // fixed step render time routines
fTime50Hz += dt; // w pauzie też trzeba zliczać czas, bo przy dużym FPS będzie problem z odczytem ramek fTime50Hz += dt; // w pauzie też trzeba zliczać czas, bo przy dużym FPS będzie problem z odczytem ramek

View File

@@ -11,5 +11,9 @@ cmake ../.. -T v140_xp ^
-DPNG_PNG_INCLUDE_DIR=%DEPS_DIR%/libpng/include ^ -DPNG_PNG_INCLUDE_DIR=%DEPS_DIR%/libpng/include ^
-DPNG_LIBRARY=%DEPS_DIR%/libpng/lib/win32/libpng16.lib ^ -DPNG_LIBRARY=%DEPS_DIR%/libpng/lib/win32/libpng16.lib ^
-DZLIB_INCLUDE_DIR=%DEPS_DIR%/zlib-1.2.11 ^ -DZLIB_INCLUDE_DIR=%DEPS_DIR%/zlib-1.2.11 ^
-DGLM_ROOT_DIR=%DEPS_DIR%/glm-0.9.8.4 -DGLM_ROOT_DIR=%DEPS_DIR%/glm-0.9.8.4 ^
-DOPENAL_INCLUDE_DIR=%DEPS_DIR%/openal/include ^
-DOPENAL_LIBRARY=%DEPS_DIR%/openal/lib/win32/OpenAL32.lib ^
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win32/libsndfile-1.lib
popd popd

View File

@@ -11,5 +11,9 @@ cmake ../.. -A x64 ^
-DPNG_PNG_INCLUDE_DIR=%DEPS_DIR%/libpng/include ^ -DPNG_PNG_INCLUDE_DIR=%DEPS_DIR%/libpng/include ^
-DPNG_LIBRARY=%DEPS_DIR%/libpng/lib/win64/libpng16.lib ^ -DPNG_LIBRARY=%DEPS_DIR%/libpng/lib/win64/libpng16.lib ^
-DZLIB_INCLUDE_DIR=%DEPS_DIR%/zlib-1.2.11 ^ -DZLIB_INCLUDE_DIR=%DEPS_DIR%/zlib-1.2.11 ^
-DGLM_ROOT_DIR=%DEPS_DIR%/glm-0.9.8.4 -DGLM_ROOT_DIR=%DEPS_DIR%/glm-0.9.8.4 ^
-DOPENAL_INCLUDE_DIR=%DEPS_DIR%/openal/include ^
-DOPENAL_LIBRARY=%DEPS_DIR%/openal/lib/win64/OpenAL32.lib ^
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win64/libsndfile-1.lib
popd popd

View File

@@ -1,2 +1,2 @@
powershell "$wc = New-Object System.Net.WebClient; $wc.DownloadFile(\"https://milek7.pl/.stuff/eu07exe/builddep1.zip\", \"%cd%\deps_win.zip\")" powershell "$wc = New-Object System.Net.WebClient; $wc.DownloadFile(\"https://milek7.pl/.stuff/eu07exe/builddep2.zip\", \"%cd%\deps_win.zip\")"
powershell "$s = New-Object -ComObject shell.application; $z = $s.Namespace(\"%cd%\deps_win.zip\"); foreach ($i in $z.items()) { $s.Namespace(\"%cd%\").CopyHere($i) }" powershell "$s = New-Object -ComObject shell.application; $z = $s.Namespace(\"%cd%\deps_win.zip\"); foreach ($i in $z.items()) { $s.Namespace(\"%cd%\").CopyHere($i) }"

561
sound.cpp Normal file
View File

@@ -0,0 +1,561 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "stdafx.h"
#include "McZapkie/mctools.h"
#include "Globals.h"
#include "sound.h"
#include "Logs.h"
#include <sndfile.h>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/string_cast.hpp>
load_error::load_error(std::string const &f) : std::runtime_error("sound: cannot find " + f)
{
}
sound_manager::sound_manager()
{
dev = alcOpenDevice(0);
if (!dev)
throw std::runtime_error("sound: cannot open device");
ALCint attr[3] = { ALC_MONO_SOURCES, 20000, 0 };
// we're requesting horrible max amount of sources here
// because we create AL source object for each sound object,
// even if not active currently. considier creating AL source
// object only when source is played and destroying it afterwards
ctx = alcCreateContext(dev, attr);
if (!ctx)
throw std::runtime_error("sound: cannot create context");
if (!alcMakeContextCurrent(ctx))
throw std::runtime_error("sound: cannot select context");
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
alGetError();
}
sound_manager::~sound_manager()
{
alcMakeContextCurrent(0);
alcDestroyContext(ctx);
alcCloseDevice(dev);
}
sound_buffer* sound_manager::find_buffer(std::string name)
{
name.erase(name.rfind('.'));
std::replace(name.begin(), name.end(), '\\', '/');
auto search = buffers.find(name);
if (search != buffers.end())
return search->second;
else
return nullptr;
}
std::string sound_manager::find_file(std::string name)
{
if (FileExists(name))
return name;
name.erase(name.rfind('.'));
std::vector<std::string> exts { ".wav", ".flac", ".ogg" };
for (auto const &ext : exts)
if (FileExists(name + ext))
return name + ext;
return "";
}
sound_buffer* sound_manager::get_buffer(std::string const &name)
{
sound_buffer* buf = find_buffer(Global::asCurrentDynamicPath + name);
if (buf)
return buf;
buf = find_buffer("sounds/" + name);
if (buf)
return buf;
std::string file = find_file(Global::asCurrentDynamicPath + name);
if (!file.size())
file = find_file("sounds/" + name);
if (!file.size())
throw load_error(name);
std::replace(file.begin(), file.end(), '\\', '/');
buf = new sound_buffer(file);
file.erase(file.rfind('.'));
buffers.emplace(file, buf);
return buf;
}
simple_sound* sound_manager::create_sound(std::string const &file)
{
try
{
WriteLog("creating source with " + file);
simple_sound *s = new simple_sound(get_buffer(file));
sounds.emplace(s);
return s;
}
catch (load_error& e)
{
WriteLog(e.what());
}
return nullptr;
}
text_sound* sound_manager::create_text_sound(std::string const &file)
{
try
{
WriteLog("creating source with " + file);
text_sound *s = new text_sound(get_buffer(file));
sounds.emplace(s);
return s;
}
catch (load_error& e)
{
WriteLog(e.what());
}
return nullptr;
}
complex_sound* sound_manager::create_complex_sound(std::string const &pre, std::string const &main, std::string const &post)
{
try
{
WriteLog("creating source with " + pre + ", " + main + ", " + post);
complex_sound *s = new complex_sound(get_buffer(pre), get_buffer(main), get_buffer(post));
sounds.emplace(s);
return s;
}
catch (load_error& e)
{
WriteLog(e.what());
}
return nullptr;
}
complex_sound* sound_manager::create_complex_sound(cParser &parser)
{
std::string pre, main, post;
double attenuation;
parser.getTokens(3, true, "\n\t ;,"); // samples separated with commas
parser >> pre >> main >> post;
parser.getTokens(1, false);
parser >> attenuation;
complex_sound* s = create_complex_sound(pre, main, post);
if (s)
s->dist(attenuation);
return s;
}
void sound_manager::destroy_sound(sound **s)
{
if (*s != nullptr)
{
sounds.erase(*s);
delete *s;
*s = nullptr;
}
}
void sound_manager::update(float dt)
{
ALenum err = alGetError();
if (err != AL_NO_ERROR)
{
std::string errname;
if (err == AL_INVALID_NAME)
errname = "AL_INVALID_NAME";
else if (err == AL_INVALID_ENUM)
errname = "AL_INVALID_ENUM";
else if (err == AL_INVALID_VALUE)
errname = "AL_INVALID_VALUE";
else if (err == AL_INVALID_OPERATION)
errname = "AL_INVALID_OPERATION";
else if (err == AL_OUT_OF_MEMORY)
errname = "AL_OUT_OF_MEMORY";
else
errname = "?";
throw std::runtime_error("sound: al error: " + errname);
}
auto now = std::chrono::steady_clock::now();
auto it = buffers.begin();
while (it != buffers.end())
{
if (now - it->second->unused_since() > gc_time)
{
delete it->second;
it = buffers.erase(it);
}
else
it++;
}
glm::vec3 velocity = (pos - last_pos) / dt;
alListenerfv(AL_VELOCITY, glm::value_ptr(velocity));
last_pos = pos;
for (auto &s : sounds)
s->update(dt);
}
void sound_manager::set_listener(glm::vec3 const &p, glm::vec3 const &at, glm::vec3 const &up)
{
pos = p;
alListenerfv(AL_POSITION, glm::value_ptr(p));
glm::vec3 ori[] = { at, up };
alListenerfv(AL_ORIENTATION, (ALfloat*)ori);
}
void sound_manager::set_listener(Math3D::vector3 const &p, Math3D::vector3 const &at, Math3D::vector3 const &up)
{
set_listener((glm::vec3)glm::make_vec3(&p.x), (glm::vec3)glm::make_vec3(&at.x), (glm::vec3)glm::make_vec3(&up.x));
}
sound::sound()
{
id = 0;
alGenSources(1, &id);
if (!id)
throw std::runtime_error("sound: cannot generate source");
alSourcei(id, AL_SOURCE_RELATIVE, AL_TRUE);
dist(5.0f * 3.82f);
spatial = false;
gain_off = 0.0f;
gain_mul = 1.0f;
pitch_off = 0.0f;
pitch_mul = 1.0f;
}
simple_sound::simple_sound(sound_buffer *buf) : sound::sound()
{
looping = false;
playing = false;
buffer = buf;
alSourcei(id, AL_BUFFER, buffer->get_id());
buffer->ref();
}
sound::~sound()
{
alDeleteSources(1, &id);
}
simple_sound::~simple_sound()
{
buffer->unref();
}
sound& sound::position(glm::vec3 const &p)
{
if (!spatial)
{
alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE);
spatial = true;
last_pos = p;
}
if (p != pos)
{
pos = p;
pos_dirty = true;
alSourcefv(id, AL_POSITION, glm::value_ptr(p));
}
return *this;
}
sound& sound::position(Math3D::vector3 const &pos)
{
position((glm::vec3)glm::make_vec3(&pos.x));
return *this;
}
sound& sound::dist(float dist)
{
max_dist = dist;
alSourcef(id, AL_MAX_DISTANCE, dist);
alSourcef(id, AL_REFERENCE_DISTANCE, dist / 3.82f);
return *this;
}
void simple_sound::play()
{
if (playing || (spatial && glm::distance(pos, sound_man->pos) > max_dist))
return;
alSourcePlay(id);
playing = true;
}
void simple_sound::stop()
{
if (!playing)
return;
alSourceStop(id);
playing = false;
}
void sound::update(float dt)
{
if (spatial && pos_dirty)
{
glm::vec3 velocity = (pos - last_pos) / dt; // m/s
alSourcefv(id, AL_VELOCITY, glm::value_ptr(velocity));
last_pos = pos;
pos_dirty = false;
}
}
void simple_sound::update(float dt)
{
sound::update(dt);
if (playing)
{
ALint v;
alGetSourcei(id, AL_SOURCE_STATE, &v);
if (v != AL_PLAYING)
playing = false;
else if (spatial && glm::distance(pos, sound_man->pos) > max_dist)
stop();
}
}
sound& sound::gain(float gain)
{
gain = std::min(std::max(0.0f, gain * gain_mul + gain_off), 1.0f);
alSourcef(id, AL_GAIN, gain);
return *this;
}
sound& sound::pitch(float pitch)
{
pitch = std::min(std::max(0.05f, pitch * pitch_mul + pitch_off), 20.0f);
alSourcef(id, AL_PITCH, pitch);
return *this;
}
sound& simple_sound::loop(bool loop)
{
if (loop != looping)
{
alSourcei(id, AL_LOOPING, (ALint)loop);
looping = loop;
}
return *this;
}
bool simple_sound::is_playing()
{
return playing;
}
//m7todo: implement text_sound
text_sound::text_sound(sound_buffer *buf) : simple_sound::simple_sound(buf)
{
}
void text_sound::play()
{
simple_sound::play();
}
complex_sound::complex_sound(sound_buffer* pre, sound_buffer* main, sound_buffer* post) : sound::sound()
{
this->pre = pre;
this->buffer = main;
this->post = post;
pre->ref();
buffer->ref();
post->ref();
cs = state::post;
}
complex_sound::~complex_sound()
{
pre->unref();
buffer->unref();
post->unref();
}
void complex_sound::play()
{
if (cs != state::post)
return;
if (spatial && glm::distance(pos, sound_man->pos) > max_dist)
return;
alSourceRewind(id);
alSourcei(id, AL_LOOPING, AL_FALSE);
alSourcei(id, AL_BUFFER, 0);
ALuint buffers[] = { pre->get_id(), buffer->get_id() };
alSourceQueueBuffers(id, 2, buffers);
alSourcePlay(id);
cs = state::premain;
}
void complex_sound::stop()
{
if (cs == state::main)
{
alSourceRewind(id);
alSourcei(id, AL_LOOPING, AL_FALSE);
alSourcei(id, AL_BUFFER, 0);
alSourcei(id, AL_BUFFER, post->get_id());
alSourcePlay(id);
cs = state::post;
}
else if (cs == state::premain)
cs = state::prepost;
}
void complex_sound::update(float dt)
{
sound::update(dt);
if (cs == state::premain || cs == state::prepost)
{
ALint processed;
alGetSourcei(id, AL_BUFFERS_PROCESSED, &processed);
if (processed > 0) // already processed pre
{
if (cs == state::premain)
{
cs = state::main;
ALuint pre_id = pre->get_id();
alSourceUnqueueBuffers(id, 1, &pre_id);
alSourcei(id, AL_LOOPING, AL_TRUE);
if (processed > 1) // underrun occured
alSourcePlay(id);
}
else if (cs == state::prepost)
{
cs = state::main;
stop();
}
}
}
if (cs == state::main)
if (spatial && glm::distance(pos, sound_man->pos) > max_dist)
stop();
}
sound& complex_sound::loop(bool loop)
{
throw std::runtime_error("cannot loop complex_sound");
return *this;
}
bool complex_sound::is_playing()
{
return cs != state::post; // almost accurate
}
sound_buffer::sound_buffer(std::string &file)
{
WriteLog("creating sound buffer from " + file);
SF_INFO si;
si.format = 0;
SNDFILE *sf = sf_open(file.c_str(), SFM_READ, &si);
if (sf == nullptr)
throw std::runtime_error("sound: sf_open failed");
int16_t *fbuf = new int16_t[si.frames * si.channels];
if (sf_readf_short(sf, fbuf, si.frames) != si.frames)
throw std::runtime_error("sound: incomplete file");
sf_close(sf);
int16_t *buf = nullptr;
if (si.channels == 1)
buf = fbuf;
else
{
WriteLog("sound: warning: mixing multichannel file to mono");
buf = new int16_t[si.frames];
for (size_t i = 0; i < si.frames; i++)
{
int32_t accum = 0;
for (size_t j = 0; j < si.channels; j++)
accum += fbuf[i * si.channels + j];
buf[i] = accum / si.channels;
}
}
id = 0;
alGenBuffers(1, &id);
if (!id)
throw std::runtime_error("sound: cannot generate buffer");
alBufferData(id, AL_FORMAT_MONO16, buf, si.frames * 2, si.samplerate);
if (si.channels != 1)
delete[] buf;
delete[] fbuf;
}
sound_buffer::~sound_buffer()
{
alDeleteBuffers(1, &id);
}
void sound_buffer::ref()
{
refcount++;
}
void sound_buffer::unref()
{
refcount--;
last_unref = std::chrono::steady_clock::now();
}
ALuint sound_buffer::get_id()
{
return id;
}
std::chrono::time_point<std::chrono::steady_clock> sound_buffer::unused_since()
{
if (refcount > 0)
return std::chrono::time_point<std::chrono::steady_clock>::max();
return last_unref;
}
sound_manager* sound_man;

160
sound.h Normal file
View File

@@ -0,0 +1,160 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#pragma once
#include <AL/al.h>
#include <AL/alc.h>
#include <cinttypes>
#include <chrono>
#include <unordered_map>
#include <unordered_set>
#include <glm/glm.hpp>
#include "dumb3d.h"
#include "parser.h"
class load_error : public std::runtime_error
{
public:
load_error(std::string const &f);
};
class sound_buffer
{
ALuint id;
uint32_t refcount;
std::chrono::time_point<std::chrono::steady_clock> last_unref;
public:
sound_buffer(std::string &file);
~sound_buffer();
ALuint get_id();
void ref();
void unref();
std::chrono::time_point<std::chrono::steady_clock> unused_since();
};
//m7todo: make constructor/destructor private friend to sound_manager
class sound
{
bool pos_dirty;
glm::vec3 last_pos;
protected:
float max_dist;
bool spatial;
glm::vec3 pos;
ALuint id;
sound();
public:
float gain_off;
float gain_mul;
float pitch_off;
float pitch_mul;
virtual ~sound();
virtual bool is_playing() = 0;
virtual void play() = 0;
virtual void stop() = 0;
virtual void update(float dt);
sound& dist(float);
sound& gain(float);
sound& pitch(float);
virtual sound& loop(bool loop = true) = 0;
sound& position(glm::vec3 const &);
sound& position(Math3D::vector3 const &);
};
class simple_sound : public sound
{
sound_buffer *buffer;
bool looping;
bool playing;
public:
simple_sound(sound_buffer *buf);
~simple_sound();
void play();
void stop();
void update(float dt);
sound& loop(bool loop = true);
bool is_playing();
};
class complex_sound : public sound
{
sound_buffer *pre, *buffer, *post;
enum class state
{
premain, // playing pre and continue to main
prepost, // playing pre and jump to post
main, //playing main
post // playing post or idling
} cs;
public:
complex_sound(sound_buffer* pre, sound_buffer* main, sound_buffer* post);
~complex_sound();
bool is_playing();
void play();
void stop();
void update(float dt);
sound& loop(bool loop = true);
};
class text_sound : public simple_sound
{
public:
text_sound(sound_buffer *buf);
void play();
};
class sound_manager
{
ALCdevice *dev;
ALCcontext *ctx;
const std::chrono::duration<float> gc_time = std::chrono::duration<float>(60.0f);
std::unordered_map<std::string, sound_buffer*> buffers;
std::unordered_set<sound*> sounds;
std::string find_file(std::string);
sound_buffer* find_buffer(std::string);
sound_buffer* get_buffer(std::string const &);
public:
glm::vec3 pos, last_pos;
sound_manager();
~sound_manager();
simple_sound* create_sound(std::string const &file);
text_sound* create_text_sound(std::string const &file);
complex_sound* create_complex_sound(std::string const &pre, std::string const &main, std::string const &post);
complex_sound* create_complex_sound(cParser &);
void destroy_sound(sound**);
void update(float dt);
void set_listener(glm::vec3 const &pos, glm::vec3 const &at, glm::vec3 const &up);
void set_listener(Math3D::vector3 const &pos, Math3D::vector3 const &at, Math3D::vector3 const &up);
};
extern sound_manager* sound_man;

View File

@@ -9,10 +9,12 @@
ui_layer UILayer; ui_layer UILayer;
#ifdef _WIN32
extern "C" extern "C"
{ {
GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window ); //m7todo: potrzebne do directsound GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window );
} }
#endif
ui_layer::~ui_layer() { ui_layer::~ui_layer() {
/* /*