We have a new shiny API to play sounds in Castle Game Engine!
I think it’s a major improvement over the previous API (that revolved around
TSound classes). The new API is easier to use:
- It hides some internal constraints (a limited internal number of sounds that can be mixed simultaneously, or impossibility to change internal buffer contents/streaming after loading). You don’t need to care about that anymore.
The lifetime of instances is easier to grasp. You control the lifetime of everything, and there’s no need to deal with
The new classes, that you should use now for all sound loading and playing, are:
TCastleSound: The most important class, you should use this always when you want to play any sound.
This is a new non-visual component that represents a sound file with some playback parameters. The most important properties are:
URL — undoubtedly the most important property, set this to actually load the sound file.
Stream — optionally use “streaming”, which is an alternative loading method best suited for longer playing sounds (like music tracks).
Volume — how loud the sound is. This is multiplied by volume at
TCastleSoundSource.Volumeand by spatial calculations.
Pitch — sound playing speed. As with volume, the volume of
TCastleSound.Pitchis multiplied by similar parameters controlled at
TCastleSoundby itself doesn’t manage playing the sound. You have to use SoundEngine.Play to play the sound (the simplest way to play, for non-spatial sounds) or TCastleSoundSource (for sounds that can be spatial; assign to TCastleSoundSource.Sound for looping, use TCastleSoundSource.Play for non-looping).
TCastleSoundalso replaces previous
TSoundTypeis now an alias of
TCastleSound). So reading sounds from
sounds.xmlfile and using SoundEngine.SoundFromName just gives you ready
TCastleSoundinstance. This XML file now becomes a new way to define “a list of TCastleSound instances”. Though you can also now ditch the manually-crafted XML files, and use a new approach we mention below — design a non-visual collection of components like
TCastleSoundSource: A way to play spatial (3D) sounds.
TCastlePlayingSound: Optional, use if you need more control before and during the sound playback.
TCastleSound can be created, configured and linked in the CGE editor, e.g. when designing your state. You can hear the 3D sounds in the editor. You can also create and control them from code, as all CGE components.
All CGE examples have been upgraded to use the new approach for sounds.
- See all the examples in examples/audio subdirectory.
In particular I recommend opening the examples/audio/game_3d_sound demo. Aside from using new sound API, it has also been recently upgraded to use CGE editor and glTF intensively.
See also examples/fixed_camera_game for a new approach to design a collection of sounds (a new, better approach than manually crafting XML files). In particular:
examples/fixed_camera_game/data/sounds/all_sounds.castle-componentdescribes all sounds
Editor sound features:
- Sound volume, and “auto-mute on play” are now available in the editor settings.
Drag-and-drop sound files on the viewport to automatically create a spatial sound:
You can manage a collection of sounds independent of state/UI by simply using
TCastleComponentas a design root and adding
TCastleSoundchildren. Save the resulting design to a file like
all_sounds.castle-component. This is a great alternative to previous XML files to describe sounds which will soon be deprecated most likely.
You can see an example of using the new approach in examples/fixed_camera_game mentioned above.
Distance model changes:
Our previous default SoundEngine.DistanceModel was poor (linear, which is not realistic).
Now it is dmInverse, and corresponds to FMOD default and OpenAL default. It’s the most natural model to play 3D spatial sounds.
Our default MaxDistance was poor (1, equal
ReferenceDistance, which means that there’s no attenuation with linear model at all).
Our possible TSoundDistanceModel were not portable (they reflected OpenAL models closely, and did not reflect FMOD models).
We limit ourselves now to actually useful models, supported by various sound backends (OpenAL and FMOD) now:
The sound API upgrade described here is almost completely backward-compatible. Old classes still work, just make a warning about deprecation at compilation. The breaking changes are:
By default we use
dmInversemodel now, as it is much more natural for 3D sounds (and it is default in both OpenAL and FMOD too, for the same reason). If you want the same approach as in previous engine version, set
SoundEngine.DistanceModel := dmLinear. Remember to adjust the
TCastleSound.MaxDistanceto sound good.
Our sounds XML file no longer supports “random aliases”. See the bottom of upgrading wiki page for explanation. I suppose it was quite obscure feature, not used by many, and maintaining it is just too much cost in new API. If you miss this feature, I released a small unit that allows you to bring it back into your game: use and adjust this in your projects.
We also made a fix for sounds defined in X3D files: 3D sounds defined using X3D nodes are now correctly played in world coordinates, i.e. loading an X3D scene with sounds inside
TCastleScene, and then transforming this
TCastleScene makes a proper sound effect.
Our manual chapter about sound has also been updated to reflect the information above. It’s admittedly very brief now, quite similar to this news post, but I hope to extend it into more tutorial-like description soon.