Elvas Tower: Bug in volume calculation in volume curves? - Elvas Tower

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Bug in volume calculation in volume curves? Rate Topic: -----

#1 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 7,010
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 10 September 2013 - 12:31 PM

I made a fast check on the computation of the volume level for external sounds, as it seems to me that such sounds are too low in volume level (e.g. for external track sound), and this level has diminished starting with some ORTS version. I found something strange in function SetFreqAndVolume ( ) within file sound.cs. There is this code block:

            if (MSTSStream.VolumeCurves.Count > 0)
                for (int i = 0; i < MSTSStream.VolumeCurves.Count; i++)
                {
                    float x;
                    if (SoundSource.Car != null)
                        x = ReadValue(MSTSStream.VolumeCurves[i].Control, SoundSource.Car);
                    else if (SoundSource.Viewer.Camera.AttachedCar != null)
                        x = ReadValue(MSTSStream.VolumeCurves[i].Control, (MSTSWagon)SoundSource.Viewer.Camera.AttachedCar);
                    else
                        x = SoundSource.DistanceSquared;

                    volume *= Interpolate(x, MSTSStream.VolumeCurves[i]);
                }

            if (SoundSource.IsntThisCabView)
                volume *= 0.75f;

            if (SoundSource.IsExternal && SoundSource.Viewer.Camera.Style != Camera.Styles.External)
                volume *= 0.5f;



There is a line
x = SoundSource.DistanceSquared;
why? There aren't only DistanceControlled volume curves, there are also SpeedControlled ones and so on. So computing in general x from DistanceSquared is not understandable to me, and in fact in older versions of the file there wasn't this line.
I would also like to understand the conditions that lead to volume reduction to 75% and to 50%. Why two different values? And independently from the condition leading to it, reducing to 50% seems to me a big reduction.
My insufficient SW knowledge does not allow me to state if this/these is/are real bug/bugs.

#2 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 10 September 2013 - 01:17 PM

View PostCsantucci, on 10 September 2013 - 12:31 PM, said:

And independently from the condition leading to it, reducing to 50% seems to me a big reduction.
My insufficient SW knowledge does not allow me to state if this/these is/are real bug/bugs.

Carlo, it was your suggestion to set it to 0.5, at May 15. "I suggest to raise the attenuation factor for external sounds heard internally from 0.3 to 0.5. I tested it." - you wrote. ;)

If you look at the code, you will see that the line x = SoundSource.DistanceSquared; is embedded into an if() statement. So that is only executed in case the sound is not attached to a car, and also the camera is not attached to any car. In this case SpeedControlled volume curve cannot be used, since there is no car to get the speed from. So that line is fine as is.

#3 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 7,010
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 11 September 2013 - 07:32 AM

Ooops! Now I've started debugging how the various types of sounds are affected by the volume reductions and the checks about the conditions to be met to play them. I will then report here.

#4 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 7,010
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 11 September 2013 - 11:30 AM

View PostCsantucci, on 11 September 2013 - 07:32 AM, said:

Ooops! Now I've started debugging how the various types of sounds are affected by the volume reductions and the checks about the conditions to be met to play them. I will then report here.

I have found a first issue. In my opinion the clause
                if (SoundSource.IsntThisCabView)
                    volume *= 0.75f;

as it is inserted now is not correct. I have verified that, when being in cabview, sounds related to AI trains and to crossings (and I suppose also sound sources, I could not check) are subjected both to the clause multiplying volume by 0.75 and to the clause multiplying volume by 0.50. So the volume is reduced twice. In my opinion the clause multiplying volume by .50 is enough. I tested by modifying 0.75 to 1.0 and things worked more satisfactorily. So I would suggest to remove such clause. If instead it has to remain to take into consideration a specific condition (which I am not able to identify), the two clauses should be mutually exclusive, with the second prevailing.
So my proposals to replace this code

               if (SoundSource.IsntThisCabView)
                    volume *= 0.75f;

                if (SoundSource.IsExternal && SoundSource.Viewer.Camera.Style != Camera.Styles.External)
                    volume *= 0.5f;

are either simply
               if (SoundSource.IsExternal && SoundSource.Viewer.Camera.Style != Camera.Styles.External)
                    volume *= 0.5f;


or
                if (SoundSource.IsExternal && SoundSource.Viewer.Camera.Style != Camera.Styles.External)
                    volume *= 0.5f;
                else if (SoundSource.IsntThisCabView)
                    volume *= 0.75f;

Moreover I am uncertain about raising 0.5 to 0.6.

#5 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 11 September 2013 - 12:07 PM

Hmmm, it makes sense. It's a good catch, I cannot explain now, even for myself, why I left that 0.75 multiplier there. I think that indeed can be removed.

#6 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 7,010
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 11 September 2013 - 08:51 PM

Thanks Peter, I would be happy if you could commit a patch for this (leaving for the moment 0.5 as it is). Now I will make some test on the second volume issue, that is general volume level in external views being quite lower than that of MSTS compared to volume level of internal views.

P.S.: found a second issue: the volume level is computed by multiplying TWICE the volume with the general scalabilty Group volume, if the stream volume is not defined. So in such case the volume level is lower than correct value, except in the case that the general scalabilty Group volume is equal to 1. This is due to the combined effect of such block in the SMSFile.cs
 Volume = VolumeOfScGroup;
            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("priority", ()=>{ Priority = stf.ReadIntBlock(null); }),
                new STFReader.TokenProcessor("triggers", ()=>{ Triggers = new Triggers(stf); }),
                new STFReader.TokenProcessor("volumecurve", ()=>{ VolumeCurves.Add(new VolumeCurve(stf)); }),
                new STFReader.TokenProcessor("frequencycurve", ()=>{ FrequencyCurve = new FrequencyCurve(stf); }),
                new STFReader.TokenProcessor("volume", ()=>{ Volume = stf.ReadFloatBlock(STFReader.UNITS.None, Volume); }),

and of following line of sound.cs (few lines above the multiplications by 0.5 and 0.75):
            float volume = SoundSource.Volume * Volume;

where Volume is the general volume of the sound stream.
The error is in the SMSFile.cs file. It sets the volume of the stream to the volume of the scalabilty Group if the stream volume is not defined; practically it overrides the volume of the scalabilty group; instead, if the volume of the stream is not explicitly defined, it should be set to 1, that is line

            Volume = VolumeOfScGroup;

must be replaced by

            Volume = 1.0f;

because it is sound.cs that provides the final computation of the volume level with the above shown line.

#7 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 11 September 2013 - 11:21 PM

Carlo, it was your suggestion again. See your post at May 7 below:

Csantucci said:

Referring to the volume I found out some time ago annoying differences between MSTS and ORTS. In MSTS the effective sound volume is computed as Vsl*Vs*Vvc, where Vsl is the volume of the whole scalabilitylevel (1 if the related line is not there), Vs is the volume of the stream (1 if the related line is not there), and Vvc is the volume computed by the volume curve (1 if the curve is not there). Moreover (in MSTS) Vs may be overridden by SetStreamVolume () or Volume_Min_Max () commands present within the stream trigger lines ( e.g. Initial_Trigger ( SetStreamVolume ( 0.5 )) or Random_Trigger ( Delay_Min_Max ( 2.0 2.0 ) Volume_Min_Max ( 0.5 1.0 ) DisableTrigger ( 9 ))).
Accordingly to my tests ORTS instead uses Vs as an override value of Vsl. So, even if Vsl e.g. is set to 0 and Vs is present, the sound gets the volume of Vs.

Always in ORTS, SetStreamVolume () values are multiplied by Vs, that is they do not override Vs as in MSTS (about Volume_Min_Max I don't know).

It would be advisable that ORTS uses the same rules as MSTS.


#8 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 7,010
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 12 September 2013 - 02:08 AM

Peter, sorry but what has been implemented does not correspond, on a specific but frequent case, to the formula I have suggested, that is volume=Vsl*Vs*Vvc.
What is implemented now works as follows:
- if Vs is explicitly defined in the header of the stream the formula volume=Vsl*Vs*Vvc works (SMSfile.cs operates well)
- if Vs is not explicitily defined the formula Vsl*Vsl*Vvc is implemented (because SMSfile takes Vsl (instead of 1.0) as Vs if Vs is not explicitly defined).
To make the formula Vsl*Vs*Vvc always working, the correction in SMSfile.cs as I suggested has to be done.

I hope I was able to clarify the point.

By the way, I would also suggest to delete following lines of code

                    if (y > 16000)
                    {
                        Console.Write("");
                    }

that unnecessarily eat a bit of CPU time.

#9 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 12 September 2013 - 03:04 AM

I'm at work now, so I can check the program files only by Notepad++, not with VS, so searching for variable references is a bit hard this way, but for the first check you seems to be right. I can see the volume of scalability group is stored in SoundSource.Volume, which is considered as a multiplication factor in SetFreqAndVolume() function, so there is no need to construct a SoundStream using its volume as a default value.

So indeed the line Volume = VolumeOfScGroup; should no be modified, rather it should be deleted completely, and also the parameter list of SMSStream() and SMSStreams() constructors can be modified not to contain VolumeOfScGroup. A good catch again! :)

#10 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 7,010
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 13 September 2013 - 08:44 AM

Peter,
thanks for having committed the patches! :)

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users