Audio in ChilliSource uses Cricket Audio, a fantastic lightweight audio library, which Cricket Technology has kindly allowed us to include as part of the engine.
Cricket Audio can be used in a ChilliSource application for free, however there are a couple of conditions that need to be met to adhere to the Cricket free license. More information can be found on the Cricket Audio website.
Setup
Typically Cricket Audio should be used via the wrapper provided with ChilliSource as this deals with setup on different platforms and makes use of various engine concepts such as Resources and Storage Locations. Alternately Cricket can also be used directly. For more information on this, see the .
The CricketAudioSystem is not available by default so if you want to use it you will have to add it during the Application::CreateSystems() lifecycle event. If you intend to make use of audio banks you will also need to add the CkBankProvider.
void MyApp::CreateSystems()
{
CreateSystem();
CreateSystem();
}
Audio Banks
An audio bank is a resource comprised of a series of sounds, which are batched and loaded into memory together. To create an audio bank you will need a simple xml bank description file (.ckbx) which describes each piece of audio the bank will contain:
The bank file (.ckb) is then built using CkTool.jar, a simple java wrapper around the cktool binaries provided with Cricket Audio.
java -jar ChilliSource/Tools/CkTool.jar --action buildbank --input "BankDesc.ckbx" --output "Bank.ckb"
To load the audio bank the Resource Pool is used:
auto resourcePool = CSCore::Application::Get()->GetResourcePool();
CSAudio::CkBankCSPtr audioBank = resourcePool->LoadResource(CSCore::StorageLocation::k_package, "Bank.ckb");
Playback of audio inside an audio bank is handled via a CkSound. A CkSound is simply a single instance of a piece of audio and can be created using a bank and the name of the piece of audio within the bank. Playing the sound is simply a case of calling Play().
auto sound = CSAudio::CkSound::CreateFromBank(audioBank, "Effect01");
sound->Play();
A CkSound will automatically stop when it goes out of scope, so make sure to retain a reference to it!
CkSound also provides a number of ways to manipulate how the audio is played back. First of all, audio can be looped by specifying the looping playback mode as an optional parameter to play.
sound->Play(CSAudio::CkSound::PlaybackMode::k_loop);
The volume, pitch and the current playback position of the audio can all also be set:
sound->SetVolume(0.8f);
sound->SetPitchShift(2.0f);
sound->SetPlaybackPosition(4.0f);
Streams
CkSound can also be used to playback audio streams. As a stream does not load and retain any data in memory, there is no Resource associated with it. Instead a CkSound is created directly with a reference to the streamable file.
auto stream = CSAudio::CkSound::CreateFromStream(CSCore::StorageLocation::k_package, "Music.ogg");
stream->Play();
A stream required a small amount of buffer time so, if play is called immediately after creation, there will be a slight delay before the audio actually starts.
Events
Sometimes you need to know when a piece of audio has finished playing. This is exposed via a completion delegate, which is passed to the Play method.
sound->Play(CSAudio::CkSound::PlaybackMode::k_once, [=](const CSAudio::CkSound* in_ckAudio)
{
CS_LOG_VERBOSE("Audio Finished!");
});
Alternately, the current state of a piece of audio can be queried.
if (sound->GetPlaybackState() == CSAudio::CkSound::PlaybackState::k_stopped)
{
CS_LOG_VERBOSE("Audio Stopped!");
}
Audio Player
Often you just want to play audio and forget about it. It can be cumbersome to have to hold on to the CkSound until it has finished playing. To alleviate this, the CkAudioPlayer can be used. This provides an interface for playing “throw-away” sound effects and a single looping music track. This also ensures the audio adheres to the state lifecycle, in other words music and effects pause when the state is no longer top of the state stack.
As with the other Cricket Audio systems, the CkAudioPlayer is not a default system and must be added during the State::CreateSystems() lifecycle event.
void MyState::CreateSystems()
{
CreateSystem();
}
Playback of music and effects is simply a case of calling PlayEffect() and PlayMusic().
audioPlayer->PlayMusic(CSCore::StorageLocation::k_package, "Music.ogg");
audioPlayer->PlayEffect(audioBank, "Effect01");