Working with Sound
From C4 Engine Wiki
The C4 Engine Sound Manager plays standard WAV files directly. The supported formats are 16-bit mono or stereo sounds having any sampling frequency. Each sound can either be loaded into memory all at once or streamed from the disk. If a sound is loaded into memory to be played, then it must be stored in uncompressed PCM format. If a sound is streamed from the disk, then it must be stored in compressed ADPCM 4:1 format.
The sound system is generally accessible at two separate levels. At the low level, sounds can be played using the Sound class. At the high level, sounds are played using the Source scene graph node.
Low-level Sound class example
An uncompressed WAV file can be played without any 3D spatialization very easily. The following code plays the sound whose file name is “Splat.wav”. This file can reside in any directory Data/*/, where * is any top-level subdirectory.
Sound *sound = new Sound; sound->Load("Splat"); sound->Play();
This method of playing sounds is fire-and-forget. Non-streaming sounds are initially non-persistent, meaning that once the sound finishes playing, it deletes itself. There's no need to worry about deleting the Sound object, and in fact, a non-persistent Sound object cannot be safely accessed once it has been played. The actual sound resource will be cached in memory after the sound plays so that there is no loading cost the next time it is played.
To play a streaming sound, such as music, the following code is typically used.
Sound *music = new Sound; WaveStreamer *streamer = new WaveStreamer; streamer->AddComponent("Music"); music->Stream(streamer); music->SetLoopCount(kSoundLoopInfinite); music->Play();
Streaming sounds are initially persistent, so they are still valid once they've finished playing. To stop and release the above Sound object, the following code can be used.
music->Stop(); music->Release();
Releasing a streaming sound will also release the streamer assigned to it, so the streamer object in the above example does not need to be explicitly deleted.
High-level Source node example
The above code does not apply any 3D sound spatialization (although it can be done with the low-level interface). A game typically needs to play sounds that emanate from a particular point in space. For example, if a grenade bounces on the floor, then the bouncing sound should be centered at the location where the grenade hit. The following code snippet creates an OmniSource scene graph node and adds it to the world. Source nodes represent sound sources in the world and automatically play from the right location within the sound data when the listener gets close enough to hear them.
void PlayBounceSound(World *world, const Point3D& position) { // Find the zone containing a particular point in world space Zone *zone = world->FindZone(position); // Create a sound source that plays "Bounce.wav" // and has a range of 50 meters OmniSource *source = new OmniSource("Bounce", 50.0F); // Set the local position of the sound source source->SetNodePosition(zone->GetInverseWorldTransform() * position); // Add the sound source to the zone zone->AddNewSubnode(source); }
Like the low-level Sound object, Source nodes are initially non-persistent, meaning that they have the fire-and-forget property. For one-shot sound effects, all you have to do is use the above code to place the sound in the world, and then you can safely forget about it.
Documentation Links
-
Soundclass -
WaveStreamerclass
