Setting Sound Files



Sound File Basics

Sound File Format

Key Open Rails Trigger Events for Sounds

Example Sound Configurations

Working with WAV Files

Troubleshooting and Debugging

Useful Links


SMS (Sound Management System) files are used in OR to add sounds to the experience of operating trains, and this page describes how to set up sound files for Open Rails, and is based upon contributions by Roger van Duijnhoven

If you wish to provide any feedback on this page, please use the contact page. It would be great to have some feedback, as this helps to ensure the accuracy of the information.


Sound File Basics

Files Required

To set up a train with functional sounds the following files will be required:

Locomotives - there are two sound files that are used for the configuration of sounds for a locomotive, xxxxxCAB.SMS and xxxxxENG.SMS. Where 'xxxxx' is a name of the model. The file xxxxCAB.SMS is used for the inside, so the cabin sounds. The file xxxxENG.SMS is used for the outside. This name must be specified exactly in the "wagon of engine" section in the corresponding ENG file.

Tenders and Wagon - Wagons (freight wagons, passenger coaches or tenders) also have their own xxxxx.SMS file, which lists the external sounds. This name must be specified exactly in the corresponding WAG file. If a passenger view has been made, it can also have its own SMS file.

Sound file location

Typically each piece of rolling stock (locomotive or wagon, etc.) has its own folder in the \TRAINSET folder, and this folder contains all ENG and WAG files required to define the train. An additional folder called \SOUND is usually included to hold all the relevant sound information, such as the SMS and WAV. The WAV file is a sound recording that is usually in a particular format, and is "called" by the SMS file to provide the relevant sound effect. Where the sounds are likely to be used by many different items of rolling stock, it is often prefferable to create a common folder to hold the sounds. This prevents the need to duplicate the sound files in multiple locations on the HDD.

Naming Conventions

Where the SMS and WAV files are located in the same folder structure as the rolling stock, then when referenced in the ENG or WAG, just the name of the sound file is required as OR will automatically search for the sound files in the \SOUND folder.

Where a common sound folder structure is used (for example, "common_sounds"), it will be necessary to provide a path that OR can follow to find the files, such as ../../common_sounds/xxxx.sms. Where the appropriate reference to the common directory represents the WAV file in the sound file.


Sound File Format

Below is a description how the SMS files are built and how to 'read' them.

Overall SMS Format

Typically the overall format of the SMS files might look something like the following:


Tr_SMS (

     ScalabiltyGroup( 5
         Activation ( CabCam () Distance (100) )
         Deactivation ( ExternalCam () PassengerCam () Distance (100) )
         Stereo ()

            Streams ( 2
                Stream (

                    Skip ( **** Air Horn **** )
                    Priority ( 6 )
                    Triggers ( 2
                         Discrete_Trigger ( 8 StartLoopRelease ( 1 File ( "2tonsAirhorn.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )
                         Discrete_Trigger ( 9 ReleaseLoopRelease () )

                Stream (

                     Skip ( **** bell **** )
                     Priority ( 6 )
                     Volume ( 0.9 )
                     Triggers ( 2
                         Discrete_Trigger ( 10 StartLoopRelease ( 1 File ( "bell1.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )
                         Discrete_Trigger ( 11 ReleaseLoopRelease () )

                             CurvePoints ( 7 etc. etc.



The following points should be noted about the above format:

1. The SMS file container ( "head and tail part ).
2. Every sound or 'sound function' is included within an appropriate Stream.
3. Every Stream has his triggers (lines).
4. Optional frequency or volume curve settings.
5. It is important to ensure that all the "brackets" are matched, otherwise incorrect operation may occur.

The components of the above SMS file are now described below in more detail.

SMS File "Header" and "Tail" Structure

The SMS file has a "header" structure, and a "tail" section which contains all the relevant sound commands. The header structure looks like this:

The "tail" structure is enclosed within the Tr_SMS ( ) statement. Typically the "tail" is structured with a number of subsections, and is contained within the Tr_SMS statement, as follows:

Tr_SMS (

   ( The contents of the ScalibilityGroups are described hereafter )


The key sub-sections of the above overall file structure are described in more detail in the following sections.


Comments can be added to the SMS using one of the following syntaxes:
Skip ( text )
Comment ( text )
_( text )

It is strongly recommended that lots of comments are used in the SMS file, as these will help the creator to remeber the logic that they have used, and also make the file easier to read by others.


The SMS files can consist of multiple groups ScalabiltyGroup. The different groups are used in MSTS to make a difference as "Player locomotive", "AI locomotive", etc. and to define their own sounds. However OR only uses one group, so for "OR only use" you can remove the other parts. (you can also leave it, as OR "won't care").

The ScalabiltyGroup section takes the following form:

     ScalabiltyGroup( x
         Activation ( y )
         Deactivation ( y )
         Stereo ()

            ( The contents of the Streams are described hereafter )

Where x = the number of the scalability group, commonly "5" is used in OR.

The lines Activation ( y ) and Deactivation ( y ) indicate within which view the sounds in this file are audible and at what maximum distance. The y value will be an appropriate combination of one or more of the following parameters.

Valid parameters are:
ExternalCam () - External Camera View (Keypress 2 3 4);
CabCam () - Camera within the cab (Keypress 1);
PassengerCam () - camera within the passenger view (Keypress 5);
Distance ( z ) - distance z (in metres) from the sound source that a sound can still be heard.

This is also when a SMS file is "active". In OR you can check this via the sound Debug tool. See below for more detail.

The difference between CAB.SMS and ENG.SMS is also that the ExternalCam and CabCam have been swapped.

Stereo ( ) - is not used in OR. However if in one Stream stereo .wav sound is used, never use mono .wav sounds in the same Stream.


Every sound or 'sound function' is included within an appropriate Stream command, which in turn are enclosed within the Streams command. A Stream also has 'a head and a tail', with various triggers that control the sound.

The "head and tail part" of a Stream consists of:

     Streams ( 2
            Stream (

                Priority ( x )
                Volume ( y )

                   ( The contents of the Triggers are described hereafter )

The value Streams ( x is very important, as x indicates the number of Stream statements included. The function is simple, it indicates how many Stream ( are used in the respective file. [Remember the 's' !! Streams ( or Stream ( ]

Priority ( x ) - The "Priority" is necessary in a stream, but has no meaning in OR.

Volume ( y ) - The 'stream volume' can be adjusted by changing the y value. Valid values are between (0.0) = 0% to (1.0) = 100%. Although the advice is to leave everything at 100%, and give the correct volume of the WAV file via a sound editor.

A Stream may have additional settings, such as the frequency or volume being changed depending on the speed or power. Practically this may be necessary for sounds like traction motors, turbo, diesel engine, etc. This is done by using the FrequencyCurve or VolumeCurve. (See examples in locomotive SMS files).


The triggers section has the following format:

Triggers ( x
        ( Each of the different Trigger statements has a slightly different format as described below )

where x = number of triggers to follow (This value must also be given exactly, because other errors occur and sounds do not function properly).

Each trigger line starts with "the type of trigger" as "if trigger is activated, do next". Think of a trigger as a one-time action or passing point! (never an "on / off function").

The following types of triggers are available to use:

Discrete_Trigger - this is a one-off trigger, and takes the form Discrete_Trigger ( x y ), where x = Trigger event, and y = Play Command. For example, if you press the Space bar to activate the "Horn" function, the discrete_trigger will only allow a one-off playing of the sound, even if you keep the Space bar is held pressed. (See the
Table of Key Open Rails Trigger Events for Sounds for all discrete_triggers events).

Initial_Trigger - Actually "start with ...." and immediately start the relevant sound file. An Initial_Trigger is also often used to set other triggers "activated or deactivated" as a starting point. It takes the form of Initial_Trigger ( x ) where x = play command as described below.

Random_Trigger - This trigger is occasionally used to play a number of sounds, with intermediate pauses. It has its own structure. It takes the form of Random_Trigger ( x y ) where x = Delay_Min_Max ( a b ) Volume_Min_Max ( c d ), and y = play command as described below.

Dist_Travelled_Trigger - This trigger is rarely used, however it can be used to play a number of sounds per intermediate distance traveled. It has its own structure. It takes the form of Dist_Travelled_Trigger ( x y ) where x = Dist_Min_Max ( a b ) Volume_Min_Max ( c d ), and y = play command as described below.

Variable_Trigger - This trigger start when a certain 'variable value' is reached. It takes the form of Variable_Trigger ( x y ) where x = one of the variables described below, and y = play command as described below.

These variables include the following:
Speed_Inc_Past, Speed_Dec_Past, CurveForce_Inc_Past, CurveForce_Dec_Past, BrakeCyl_Inc_Past, BrakeCyl_Dec_Past, Distance_Inc_Past, Distance_Dec_Past, Variable1_Inc_Past, Variable1_Dec_Past, Variable2_Inc_Past, Variable2_Dec_Past, Variable3_Inc_Past, Variable3_Dec_Past.

Each of these parameters is typically written as Speed_Inc_Past ( x ) where x = a kind of % 'variable value', not a parameter such as km/h, Miles, etc. The 'variable value' can be tested and read during various circumstances via Sound Debug monitor in OR. It is suggested that a "simple route" with no objects, etc. is used for testing, such as the Coals to Newcastle test route. This is because the sound debug monitor requires a lot of performance.

The following sound triggers have also been defined for Duplex and Booster steam engines.
Variable1_2_Inc_Past, Variable1_3_Inc_Past, Variable1_4_Inc_Past, Variable1_2_Dec_Past, Variable1_3_Dec_Past, Variable1_4_Dec_Past, Variable2BoosterControlled.
where, Variable1_x (where x = engine number)

Play Commands

Play commands have the following format:

PlayCommand ( x y z )
where x= number of sound files, y = sound file name, and z = Selection Method.

The following types of play commands are available to use:

PlayOneShot - sound is played once.

StartLoopRelease - sound starts and played in a continuous loop from the first cue point to the last cue point.

ReleaseLoopReleaseWithJump - sound loop is stopped, typically grouped with the above play command. Only applies if the WAV file has cue points!

StartLoop - sound starts and played in a continuous loop. As standard with WAV files without cue points.

ReleaseLoopRelease - sound loop is stopped, typically grouped with the above play command.

SetStreamVolume - adjusts the Stream volume. Practically, you often use these as "on" and "off", so the value (1.0) = 100% and (0.0) = 0% respectively. This can be used if the trigger + sound is still playing in the background, but you want to mute the sound beforehand. Regarding volume of the sound in question, always try to make sure that the source WAV file has the correct volume or adjust this via an audio editor. (increase or decrease a few dB).

EnableTrigger - activates certain triggers (rules) within this stream. This means that a certain trigger (rule) may or may not work during certain moments in the simulator. It is also often used to define dependencies, so chooses like if "trigger-1 is allowed to work when trigger 3 is activated". IOW, a kind of temporary "on / off buttons", depending on what activity you are doing during the simulator. Again, the count is very important that it is filled in exactly. Also the 'reading order' from top to bottom, as the steam is executed in the simulator. So with adjustments always "10x check. For example, EnableTrigger ( x ) x = the trigger line number within the current groups of Triggers.

DisableTrigger - deactivates a certain trigger (line), as described with EnableTrigger.

Selection Method

The Selection Method command has the following format:
SelectionMethod ( x )
where x= file play method.

The following types of selection method commands are available to use:

SequentialSelection -each sound file is played "alternately" with each activation of the trigger. Naturally if there is only one file, then this will be the only filed played.

RandomSelection - each sound file is played "randomly" with each activation of the trigger.

General Comments

Some general remarks:


Key Open Rails Trigger Events for Sounds

The key trigger events in Open Rails that can have a sound attached to them are described in the following table.

Sound Events (updated Jul 2021)


Example Sound Configurations

In this section some simple sample sound configurations will be provided to help see how it all "comes together".

Each "sound function" (Horn, Bell, Doors open/close, Brakes, etc.) are configured separately in a "Stream". In this way, the sounds can also be used "independently of each other". The composition of the triggers (in a Stream) mainly depends on the function and the available sounds.

Example 1 -

For example when the driver in the cab operates the brakes the following configuration will play a WAV file that makes a sound like the brakes being released or applied.

Stream (
Skip ( **** AirTrainBrake**** )
Priority ( 6 )
Triggers ( 2
Discrete_Trigger ( 14 PlayOneShot ( 1 File ( "TrainBrake1.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )
Discrete_Trigger ( 54 PlayOneShot ( 1 File ( "TrainBrake2.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )


In this example: Two Triggers are configured which operate as follows, when Trigger event #14 (Train Brake Pressure Increase) is triggered, the WAV file TrainBrake1 will be played once. Similarly when Trigger event #54 (Train Brake Pressure Decrease) is triggered, the WAV file TrainBrake2 will be played once.

Example 2 -

Stream (
Skip ( **** Stoker sounds. ****)
Priority ( 5 )
Triggers ( 2
Variable_Trigger ( Variable3_Inc_Past 1 StartLoopRelease ( 1 File ( "fuel_coal.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )
Variable_Trigger ( Variable3_Dec_Past 1 ReleaseLoopRelease () )

In this example: Two Triggers are configured to provide sounds for the fuel stoker. The first trigger is activated once Variable3 increases beyond a value of 1. The WAV file is then played continuously until the second trigger is activated once Variable3 decreases below a value of 1, and hence stops playing the WAV.

Example 3 -

Stream (
Priority ( 6 )
Volume ( 0.5 )
Triggers ( 3
Initial_Trigger ( StartLoop ( 1 File ( "fs_power_cruise0.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )

Variable_Trigger ( Speed_Inc_Past 0.1 ReleaseLoopRelease () )
Variable_Trigger ( Speed_Dec_Past 0.1 StartLoop ( 1 File ( "fs_power_cruise0.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )

In this example: The Initial_Trigger is used to play the WAV file fs_power_cruise0.wav initially when first starting OR, and whilst the locomotive is stationary. The other two triggers are to turn this sound off if the spped of the locomotive is above 0.1m/s, ie the locomotive starts to move. Conversely if the locomotive speed drops below 0.1m/s (ie it is stationary) then the sound will be played again.

Look here for Advanced Sound Examples. Alternatively, a working example can be found by trying the locomotives which have been set up, and studying their respective sound files. For example, look at the H6a locomotive.


Working with WAV Files

The SMS files contain all the instructions about how and when to play sounds in Open Rails, whilst the WAV files contain the actual sounds, and they can be played on the PC, or edited it with an audio editor.

WAV files can be editted to ensure optimal performance in Open Rails, typically they should be sampled at a rate of 11025hz, and saved as 16 bit stereo signed for the cab (inside) sound and 16 bit mono signed for the external sounds.

Cue points

Cue points (or marker points) can be embedded into a WAV file to provide a series of "control" points in the file, which can be used for controlling were the sound starts and finishes. For example, with the whaistle, once the user presses the whistle control the full whistle sound would need to be played once the user stops pressing the whistle control, if there are no cue points in the WAV file. Whereas if there are cue points in the WAV file then the file can stop at the next cue point, rather then playing the full file.

WAV File Playing Examples

Below are some examples of how WAV files can be played in Open Rails.


Example: PlayOneShot

The simplest example, a sound xxxxx.WAV is played once from start to end.

Discrete_Trigger ( 6 PlayOneShot ( 1 File ( "Ding_Dong.wav" -1 ) SelectionMethod ( SequentialSelection ) ) )

Playone shot
Example: StartLoopRelease (with "start-loop-stop" from 3 xxxxx.wav files)

This method is often used. A sound source can be "cut" in a "Start, loop and Stop" section. When "cutting" in the audio editor, make a good note of the duration (cut point time), so that the files 'connect' well with each other. If a Stream is made from different sound sources, please note that the xxxxx.WAV properties are 100% equal. (xx bit / Mono or Stereo / xxxxx Hz) In case of differences, first adjust this in the audio editor. Differences create frequency (speed of sound) differences, so that the Stream is played "distorted"! This also applies if a "silence" xxxxx.WAV (Mute) is applied.

Discrete_Trigger ( 6 PlayOneShot ( 1 File ( "Ventil_1.wav" -1 ) SelectionMethod ( SequentialSelection ) ) ) Start sound in Figure A
Discrete_Trigger ( 6 StartLoopRelease ( 1 File ( "Ventil_2.wav" -1 ) SelectionMethod ( SequentialSelection ) ) ) Start sound in Figure B (When A has ended)
Discrete_Trigger ( 7 ReleaseLoopRelease () ) Stop B (until the end)
Discrete_Trigger ( 7 PlayOneShot ( 1 File ( "Ventil_3.wav" -1 ) SelectionMethod ( SequentialSelection ) ) ) Start sound in Figure C (When B has ended)

Figure A:


Figure B:


Figure C:

Example: StartLoopRelease (with "start-loop-stop" as marker points within the xxxxx.wav files)

This method can only be applied if the xxxxx.WAV has Marker points (Cue points). Note that this is not (immediately) visible in all audio editors! (a freely available and simple audio editor like Wavosaur works well with this). An additional point of attention is that: Only xxxxx.WAV files with marker points (Cue points) apply the ReleaseLoopReleaseWithJump, otherwise always ReleaseLoopRelease !!!

Discrete_Trigger ( 6 StartLoopRelease ( 1 File ( "repos-motrice.wav" -1 ) SelectionMethod ( SequentialSelection ) ) ) Start from the beginning to "M0", then proceed as Loop between "M0 and M1"
Discrete_Trigger ( 7 ReleaseLoopReleaseWithJump () ) Stops Loop "M0 - M1" and stops to the end

Example: Loop xxxxx.WAV

If you make a "loop xxxxx.WAV", you do this in an audio editor by marking a part of the sound and playing it simultaneously as a "loop function". By shifting the starting point and end point, you try to get the best result. Record the start and end times (usually needed as the start and end points of the "start and stop" sounds). It is often possible that "the loop sound" in itself sounds good, but an annoying "click" is heard. Try to remove it, it can be very annoying in the simulator!

The "click" is because the end does not correspond 100% to the starting point. You can fix this by increasing the sound file and going to the start and end point. Try to cut the sound "to the zero line" and make sure the sound goes "in the same direction". (so end point flows through to start point). This removes "clicking" and gives you a good Loop sound.

If the above fails, you can also try using the "Fade-in" and "Fade-out" on the first / last sound points. (not too big part, otherwise this is audible as a "dip" ....)

Similarly, you can also edit the "linked sounds" (such as Start and Stop sounds), if it appears in the simulator that they also "click" when playing.

Example: "Clipping" sound

If you want to increase the volume of a sound, make sure you don't do this "too much". It depends a bit on the type of sound, but when "the top level become flat" a "tinny, cracking" sound is created. Do the volume increase in small steps of + 3dB or better smaller values. (And test each sound again or it is not 'deformed').

Usually this is only audible what is 'right or wrong', but the above also makes it partly visible.



Troubleshooting and Debugging


The "Sound Debug tool" is a nice tool when working with sound files. The Sound Debug tool is standard in OR. If you start Openrails (ORTS) with "Play" with your locomotive (consist), you will enter the simulator. As 'normal' you can then run the train, etc.

It is highly recommended to use a "empty" route without too much object, such as the Coals to Newcastle test route. This is because the sound debug monitor requires a lot of performance capability.

During the simulation in OR you start the Sound Debug tool by using the key combination Alt-S. A pop-up window, as shown below, appears on the screen. If you want to see both images (OR and Sound Debug) simultaneously, you can move Sound Debug to another monitor (if any), or make OR "small" using Alt-Enter, otherwise, always switch between windows using Alt-Tab.

Sound Debug Tool

As can be seen in the above screenshot information is displayed in four areas on the Sound Debug tool. Each of these areas will be described in more detail below.

Active / Inactive Windows

In the large field you see all the "active" SMS files that are currently available, which means that the sounds mentioned in this SMS should be audible.

In the small field at the bottom right you see the "inactive" SMS files. Inactive means that the sound files mentioned here (WAV) will not be played, but the SMS itself is 'active'!

An example of how the information could be displayed in the active/inactive windows is described as follows.

A locomotive has a xxxxxCAB.SMS and a xxxxxENG.SMS. When you are in the cabin, after pressing the 1 key, you will see the xxxxxCAB.SMS in the field 'active sounds' and the xxxxxENG.SMS in the field 'inactive sounds'. You can "open" the SMS with the correct name by clicking the + key. At that point you will see the number of Streams that are available, and which sounds are 'playing'.

If you open the xxxxxENG.SMS in the same way, you will also see that this SMS file is active. (try with the "air horn" function or something), but you will not hear the sound (.WAV file) because this SMS file is inactive when you are in the cabin.

For example, if you switch from cabview to external 2, you will also see both SMS files switch from active to inactive, and vice versa.

Make sure you open the correct SMS file. First check in the ENG file or WAG file which SMS file is used [e.g. Sound (xxxx.SMS)]. With a consistency of several similar locomotives or wagons, there are of course several identical names! (So test with a simple consist, possibly one locomotive and one wagon, etc.)

If an SMS file is open, you can see in a Stream line which sound WAV file is used, and the (last) status.

The WAV sound is as the SMS file knows it. This does not mean 100% that the sound is audible !!, as one of the following may have occurred:

Using 'the status' you can also see how a Stream in the SMS works. You can check if a Stream functions correctly in certain circumstances:

You will also see the "other SMS" activities, such as background (game) sounds, track sounds, etc.

Variable Data Window

Another help in Sound Debug, for both checking and setting in Streams, is the variable data on the left. These data are the values used for the "Variable_trigger" in a Stream, with the increase and decrease variables of:

Because it is often not 100% known which "unit" is needed, or the calculated value, or the difference in which situation (steam, diesel, electric), the simplest way is: Make various test drives in various conditions, and check the values you see in the Sound Debug tool. This allows you to tune the Stream (and thus the sounds).

(- Volume is the SMS volume, but the real volume which is audible also depends on the Stream volume and the WAV file)

Sound Cache Window

WAV Cache: Every sound that is played is stored (for a certain time) in Cache. Cache ensures that sounds can be started "with less delay". This is only an information field that shows how many (played) files are 'stored in Cache'. (possibly an item for research into performance problems).

AL Sources: This is only an information field that shows the current number of sources (actually directory sources) where the .WAV sounds come from. (possibly an item for research into performance problems).

Problem Solving

With the Sound Debug as a tool you can already check most errors with sounds (SMS, Streams, WAV). Always try "what is theoretically conceived, is visible in the active SMS". If you try out all sounds in OR after some 'test drives', after closing OR look in the "Openrails.log". Errors such as "incorrect numbers of Streams", "missing sounds WAV file" or other errors such as "xxx.SMS, line yyy error" can help to find the cause. Errors in the WAV file itself (cue, distorted sound, cliping sound, etc.) can only be resolved via an audio editor. (the simulator cannot improve this ...)


Useful Links