Wednesday, March 18, 2015

Feature Update - Audio

Since the beginning there have been a few major features to implement I've been a bit intimidated by. Recently map generation has been added which took a solid week to implement in my spare time and still requires more work (such as adding enemies, portals, and decorations). With that out of the way, two other features were left that I am completely unfamiliar with: audio and networking. Thankfully this past weekend it has been implemented. Creatures now make sounds as they attack, die, cast spells, run, etc, and music accompanies each level.  I'm not sure if I just got lucky, but the visual client is setup in a way that already detects transitions in unit actions (for the purpose of changing the animations) which also makes it very easy to associate sounds with. Before going into an explanation, check out the below video to see a demo of audio in the game.



SFML includes a great audio API that makes loading and playing sounds very easy. First, you load all the sounds you want into "sound buffers", which the game holds in a map, then a sound object is created and has a sound buffer assigned to it, allowing it to play that sound. The game limits sound objects to 256 simultaneous sounds that can play. To manage this, the game creates a vector of 256 sounds, and manages which sound objects are in use. When a sound object is no longer in use, it becomes available for the next audio to play (this includes changing which sound buffer is assigned to it).

A concurrent queue is used that holds all new actions occurring, and once per frame it polls through the queue and plays all sounds associated with the actions. This keeps the whole process thread safe, while allowing for concurrency in the parts of the program that concurrently execute multiple actions (otherwise you'd have multiple threads trying to play sounds at the same time in an unsafe manner).

The final piece of the puzzle for implementing sounds in the game is how to assign all these actions to specific sound files. A configuration file is used to assign all of this. Below is the current configuration file used. To note, a safeguard exists to make sure actions with no corresponding sound simply play nothing.

 # Player  
 Player_Run_Default_0=Player/Actions/running.ogg  
 Player_Swing_Sword=Player/Actions/sword_swing.ogg  
 Player_Hit_Sword=Player/Actions/sword_hit.ogg  
 # Skywatch  
 Skywatch_Die_Default=Creature/Actions/skywatch_death.ogg  
 Skywatch_Swing_Default=Creature/Actions/skywatch_swing.ogg  
 # Skeleton  
 skeleton_Die_Default=Creature/Actions/skeleton_death.ogg  
 skeleton_Swing_Default=Player/Actions/sword_swing.ogg  
 skeleton_Hit_Sword=Player/Actions/sword_hit.ogg  
 # Spells  
 fireball_Die_Default=Player/Spells/fireball_death.ogg  
 fireball_Cast_Default=Player/Spells/fireball_cast.ogg  
 teleport_Cast_Default=Player/Spells/teleport_cast.ogg  
 summon_Cast_Default=Player/Spells/summon_cast.ogg  
 # Miscellaneous  
 Default_Waypoint_Default=Player/Actions/waypoint.ogg  
 # Music  
 town=Music/OnlyIf-WhitePawn-5-Infinity.ogg  
 town2=Music/OnlyIf-WhitePawn-5-Infinity.ogg  
 test_map=Music/OnlyIf-Intro-2-MeetingVinny.ogg  

As of now, there a few things left to implement. First, the game will have no problem loading the same sound file twice for different actions instead of just re-using the same loaded file. This needs to be addressed. Secondly, all sounds are played at the same volume. SFML supports positional audio, and this will be added so that distant sounds are quieter and also their direction will be accounted for. Finally, while it's already programmed into the game to have both a master volume, and volume for music and other audio types, it needs to be added to the interface.

As a final note, most of the audio used is taken from free websites like http://www.freesfx.co.uk/ and modified using Audacity. I'll admit that I have next to no experience with audio, but my background in electrical engineering and my internship with Visteon in the audio department (working on electronics like amplifiers) does make things a lot easier. For example, the sound of the bird monsters attacking and dying in the video was originally from an elephant sound clip that was heavily processed.

No comments: