Coding a Lunar Lander from the ground up: OrbiterSound Support


Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Dec 27, 2010
Reaction score
San Diego
This will be quick and simple, I just want to get it out of the way.

PART 11: OrbiterSound Support

Step 1 is obviously to install Dan Steph's OrbiterSound.

NOTE: my code uses v 4.0

Dan already included an excellent tutorial in his own documentation so I will only touch upon the basics. Once Orbitersound has been installed go to the sound/OrbiterSound_SDK folder in your Orbiter root directory and find the following files "OrbiterSoundSDK40.h" and "OrbiterSoundSDK40.lib". Copy and paste these files to your "OrbiterSDK/Include" and "Lib" folders respectivly so that Visual Studio will be able to see them.

Alternately you can go into your project properties and add the sound/OrbiterSound_SDK directory to your include directories.

Once youve done this you will be able to call OrbiterSound's Functions (load and play sound effects/music) from within your own code. So let's get to coding.

Open your vessels header file and add the following line to your class interface.

	void	clbkPostStep (double simt, double simdt, double mjd);					// Post-Step processes

[COLOR="red"]	// ID number for OrbiterSound
	int		OrbiterSoundID;[/COLOR]

	// Thruster and Propellant handles
	PROPELLANT_HANDLE	ph_rcsA, ph_rcsB, ph_ascentFuel, ph_descentFuel;			// Functional Propellant tanks
Orbiter sound assigns a unique ID number to every vessel in the scenario. This number is used by Orbiter Sound to keep track of which sounds belong to which vessel.

Now it's time to start adding sounds. By default orbitersound simply assigns a number to each sound in turn as it is loaded but this can become complex and hard to read. As such I will be assigning my own values using the #define macro. #define associates an identifier with a token string or variable so that rather than trying to remeber that our "Hatch opening" sound is sond effect # 1161 we can simply call it "Hatch_open" and the compiler will fill in the appropriate value for us.

To avoid conflicts from overlapping definitions #defines should be kept in thier own header files. As such lets create a new header file. I called mine "LM_Sounds.h"

here are it's contents...
// ==============================================================
//			A custom Vessel For Orbiter 2010/2011
// LM_Sounds.h
// Definitions for OrbiterSound 4.0
// ==============================================================

#pragma once

#define SILENCE				00 // "silence.wav" The sound of...

#define SOUND_BTN			01 // Button press "button.wav"
#define SOUND_ROTARY		02 // Dial click "rotary.wav"
#define SOUND_SWITCH		03 // Switch sound "switch_throw.wav"
#define SOUND_SWITCHGUARD	04 // Alternate Switch sound "switch_guard.wav"

#define SOUND_HATCHOPEN		05 // EVA Hatch opening "hatch_open.wav"
#define SOUND_HATCHCLOSE	06 // EVA Hatch closing "hatch_close.wav"
#define SOUND_STAGESEP		07 // Stage Seperation "stage_sep.wav"
#define SOUND_EXPLSVDEVICE	10 // Explsoive device firing "cad.wav"

#define SOUND_CAUTION		11 // Basic alert tone "alarm_caution.wav"
#define SOUND_WARNING		12 // OH :censored:! alarm tone "alarm_warning.wav"
Yes it is a direct copy/pase from my [ame=""]Spider Lunar Lander *Beta v2.3*[/ame] addon's code. don't worry about it.

What we've done is assign each name "SOUND_HATCHOPEN" to a number "05" and vice versa. I know it doesn't seem like much now but doing this will make things monumentally easier down the line. Especially as we get

into more complex operations involving sub-classes and the like.

Now that we've got our definitions set lets put them to work.

Go back to our original (from here on refered to as "our vessel's") header file and include "OrbiterSoundSDK40.h". Also include our new Sound header file.

// Orbiter SDK files
#include "orbitersdk.h"
[COLOR="red"]#include "OrbiterSoundSDK40.h"[/COLOR]

// Mesh resource files
#include "_ascentmesh.h"
#include "_cockpitmesh.h"
#include "_descentmesh.h"

[COLOR="red"]// Other resource files and sub-classes
#include "LM_Sounds.h"[/COLOR]
Now we're ready to start coding in earnest.

If you recall, back in Part 8 I added an empty function source code called called "DefineSounds", lets fill it.

// --------------------------------------------------------------
// Define sound effects
// --------------------------------------------------------------
void LM::DefineSounds (void)
	[COLOR="red"]// OrbiterSound 4.0
	OrbiterSoundID = ConnectToOrbiterSoundDLL (GetHandle());			// Init sound[/COLOR]
The first step is to get our vessel's ID number from orbitersound. We need this ID to modify our own vessel's sounds without effecting any other vessels in the simulation.

The next step is to take all those names/numbers that we declared in our LM_sounds header file and tie them to actual audio files.

// --------------------------------------------------------------
// Define sound effects
// --------------------------------------------------------------
void LM::DefineSounds (void)
	// OrbiterSound 4.0
	OrbiterSoundID = ConnectToOrbiterSoundDLL (GetHandle());			// Init sound
[COLOR="red"]	SoundOptionOnOff (OrbiterSoundID, PLAYCOUNTDOWNWHENTAKEOFF, FALSE);	// Disable the stock countdown... it's annoying :)

	RequestLoadVesselWave (OrbiterSoundID, SILENCE, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\silence.wav", DEFAULT);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_BTN, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\switch_button.wav", INTERNAL_ONLY);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_ROTARY, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\switch_rotary.wav", INTERNAL_ONLY);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_SWITCH, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\switch_click.wav", INTERNAL_ONLY);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_SWITCHGUARD, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\switch_guard.wav", INTERNAL_ONLY);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_HATCHOPEN, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\hatch_open.wav", BOTHVIEW_FADED_MEDIUM);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_HATCHCLOSE, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\hatch_close.wav", BOTHVIEW_FADED_MEDIUM);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_STAGESEP, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\stage_sep.wav", BOTHVIEW_FADED_MEDIUM);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_EXPLSVDEVICE, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\cad.wav", BOTHVIEW_FADED_MEDIUM);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_CAUTION, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\alarm_caution.wav", RADIO_SOUND);
	RequestLoadVesselWave (OrbiterSoundID, SOUND_WARNING, "Sound\\_CustomVesselsSounds\\UMMU_Apollo\\alarm_warning.wav", RADIO_SOUND);[/COLOR]
} // End "LM::DefineSounds"
NOTE: Exact syntax and use of these functions is explained in the OrbiterSound 4.0 documentation. Your file paths may vary. Make sure you enter the correct file path/name FOR YOU rather than just copy/pasting. Any crashes/errors that result are your problem. :compbash2:

Ok now that we have our sound files loaded and we've given them names it's time to actually play one.

Lets go back to our old friend the Hatch...

void LM::clbkPostStep (double simt, double simdt, double mjd)
	// EVA hatch control logic
	if (hatch_proc < 0)			// If process value is less than 0...
		HatchStatus = CLOSED;	// ...set status to "CLOSED"
		hatch_proc = 0;			// and process value to 0

	else if (hatch_proc > 1)	// If process value is greater than 1...
		HatchStatus = OPEN;		// ...set status to "OPEN"
		hatch_proc = 1;			// and process value to 1

	if (HatchStatus > CLOSED)	
		double	delta = simdt / 3;	

		if (HatchStatus == OPENING)				// if Status equals "OPENING"...
			hatch_proc += delta;				// ...add delta to process value
			[COLOR="red"]if (hatch_proc < 0.2) PlayVesselWave (OrbiterSoundID, SOUND_HATCHOPEN); // Play opening sound effect[/COLOR]
		if (HatchStatus == CLOSING)				// if Status equals "CLOSING"...
			hatch_proc -= delta;				// ...subtract it.
			[COLOR="red"]if (hatch_proc < 0.3) PlayVesselWave (OrbiterSoundID, SOUND_HATCHCLOSE); // Play closing/locking sound effect[/COLOR]

		SetAnimation (anim_Hatch, hatch_proc);	// Apply process value to animation.
	} // End "if (HatchStatus > CLOSED)"
As you may recall from back in Part 7, 0.2 and 0.3 are the points in the open/closing animations where the hatch handle begins to turn as such this is the moment that I want my sound of the hatch latching and unlatching sound to play.

As such I set up a pair of simple "if" statements. while the hatch is closing if (hatch_proc < 0.2) Play sound effect, then likewise for opening.

Compile and test...

there's nothing to take a screenshot shot of but you should now hear the hatch open and close when you press the k key.

This concludes PART 11.

Further information/tutorials on using the various features of OrbiterSound can be found in the OrbiterSound documentation and SDK samples.

In PART 12 I will start to discuss virtual cockpits, Followed by sub-system modelling. (making all those switches and buttons do something)

For those that requested thrust vectoring. It is on the to-do list but I see no point in coding an advanced thruster management system if there is no way to control that system.