Leviathan  0.8.0.0
Leviathan game engine
Leviathan::SoundDevice Class Reference

Manages loading the audio library and provides some helpers. More...

#include <SoundDevice.h>

Public Member Functions

DLLEXPORT SoundDevice ()
 
DLLEXPORT ~SoundDevice ()
 
DLLEXPORT bool Init (bool simulatesound=false, bool noconsolelog=false)
 
DLLEXPORT void Release ()
 
DLLEXPORT void Tick (int PassedMs)
 
DLLEXPORT void SetSoundListenerPosition (const Float3 &pos, const Float4 &orientation)
 Loads the file and plays the sound. More...
 
DLLEXPORT void SetGlobalVolume (float vol)
 
DLLEXPORT void Play2DSoundEffect (const std::string &filename)
 Plays a 2d sound without possibility of interrupting. More...
 
DLLEXPORT AudioSource::pointer Play2DSound (const std::string &filename, bool looping, bool startpaused)
 Plays a 2d sound with options. More...
 
DLLEXPORT AudioSource::pointer CreateProceduralSound (ProceduralSoundData::pointer data, const char *soundname)
 Opens an audio source from a procedural data stream. More...
 
DLLEXPORT void BabysitAudio (AudioSource::pointer audio)
 This class holds the audio source until it has finished playing and then releases the reference. More...
 
DLLEXPORT cAudio::IAudioManager * GetAudioManager ()
 

Static Public Member Functions

static DLLEXPORT std::vector< std::string > GetAudioDevices (size_t *indexofdefault=nullptr)
 Returns a list of audio playback devices. More...
 

Detailed Description

Manages loading the audio library and provides some helpers.

Definition at line 20 of file SoundDevice.h.

Constructor & Destructor Documentation

◆ SoundDevice()

SoundDevice::SoundDevice ( )

Definition at line 20 of file SoundDevice.cpp.

20 {}

◆ ~SoundDevice()

SoundDevice::~SoundDevice ( )

Definition at line 21 of file SoundDevice.cpp.

22 {
23  Release();
24 }
DLLEXPORT void Release()
Definition: SoundDevice.cpp:99

Member Function Documentation

◆ BabysitAudio()

DLLEXPORT void SoundDevice::BabysitAudio ( AudioSource::pointer  audio)

This class holds the audio source until it has finished playing and then releases the reference.

Definition at line 209 of file SoundDevice.cpp.

210 {
212 
213  HandledAudioSources.push_back(audio);
214 }
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84
DLLEXPORT void AssertIfNotMainThread() const
Asserts if not called on the main thread.
Definition: Engine.h:104

◆ CreateProceduralSound()

DLLEXPORT AudioSource::pointer SoundDevice::CreateProceduralSound ( ProceduralSoundData::pointer  data,
const char *  soundname 
)

Opens an audio source from a procedural data stream.

Parameters
soundnameName for this audio source. Should be at least somewhat unique

Definition at line 197 of file SoundDevice.cpp.

199 {
200  if(!AudioManager || !data)
201  return nullptr;
202 
203  return AudioSource::MakeShared<AudioSource>(
204  AudioManager->createFromAudioDecoder(soundname, data->Properties.SourceName.c_str(),
205  CAUDIO_NEW ProceduralSoundStream(data)),
206  this);
207 }
Used to feed data retrieved from a callback to cAudio::IAudioSource.

◆ GetAudioDevices()

DLLEXPORT std::vector< std::string > SoundDevice::GetAudioDevices ( size_t *  indexofdefault = nullptr)
static

Returns a list of audio playback devices.

Parameters
indexofdefaultReturns the index of the default device (if not null)

Definition at line 216 of file SoundDevice.cpp.

218 {
219  std::vector<std::string> result;
220 
221  cAudio::IAudioDeviceList* devices = cAudio::createAudioDeviceList();
222 
223  if(!devices) {
224  LOG_ERROR("SoundDevice: GetAudioDevices: failed to get audio device list");
225  return {};
226  }
227 
228  const auto deviceCount = devices->getDeviceCount();
229  result.reserve(deviceCount);
230 
231  const auto defaultDeviceName = devices->getDefaultDeviceName();
232 
233  for(unsigned int i = 0; i < deviceCount; ++i) {
234 
235  const auto deviceName = devices->getDeviceName(i);
236 
237  if(deviceName.compare(defaultDeviceName) == 0 && indexofdefault) {
238 
239  *indexofdefault = i;
240  }
241 
242  result.push_back(deviceName);
243  }
244 
245  CAUDIO_DELETE devices;
246 
247  return result;
248 }
#define LOG_ERROR(x)
Definition: Define.h:84

◆ GetAudioManager()

DLLEXPORT cAudio::IAudioManager* Leviathan::SoundDevice::GetAudioManager ( )
inline

Definition at line 73 of file SoundDevice.h.

74  {
75  return AudioManager;
76  }

◆ Init()

bool SoundDevice::Init ( bool  simulatesound = false,
bool  noconsolelog = false 
)
Parameters
simulatenosoundIf true the sound device isn't initialized to simulate not having a valid audio device (or if the user just doesn't want sound)

Definition at line 26 of file SoundDevice.cpp.

27 {
28  AudioLogPath = StringOperations::RemoveExtension(Logger::Get()->GetLogFile(), false) +
29  "cAudioLog.html";
30 
31  AudioManager = cAudio::createAudioManager(
32  // No default init, we want to select the device
33  false,
34  // And write to a program specific log file
35  AudioLogPath.c_str(), noconsolelog);
36 
37  LEVIATHAN_ASSERT(AudioManager, "Failed to create cAudio manager");
38 
39  size_t defaultDevice = 0;
40  const auto devices = GetAudioDevices(&defaultDevice);
41 
42  if(simulatesound == true) {
43 
44  LOG_WARNING("SoundDevice: simulating not having a playing device");
45  return true;
46  }
47 
48  if(devices.empty() || defaultDevice >= devices.size()) {
49 
50  LOG_ERROR("SoundDevice: no sound devices detected");
51  return false;
52  }
53 
54  if(std::find(devices.begin(), devices.end(), devices[defaultDevice]) == devices.end()) {
55  // I have no clue how it would ever get here, but you never know
56  LOG_ERROR("SoundDevice: Default device doesn't exist. The code should not have "
57  "been able to get here.");
58  }
59 
60  LOG_INFO("Detected audio devices: ");
61 
62  for(const auto& dev : devices)
63  LOG_INFO("> " + dev);
64 
65  LOG_INFO("End of devices");
66 
67  std::string selectedDevice;
68  // There's no print error here if missing to make tests run
69  ObjectFileProcessor::LoadValueFromNamedVars<std::string>(
70  Engine::Get()->GetDefinition()->GetValues(), "AudioDevice", selectedDevice, "default");
71 
72  if(selectedDevice == "default") {
73 
74  selectedDevice = devices[defaultDevice];
75 
76  } else if(std::find(devices.begin(), devices.end(), selectedDevice) == devices.end()) {
77  LOG_ERROR("SoundDevice: selected audio device \"" + selectedDevice +
78  "\" doesn't exists. Using default");
79  selectedDevice = devices[defaultDevice];
80  }
81 
82  LOG_INFO("SoundDevice: Initializing sound with device: " + selectedDevice);
83 
84  if(!AudioManager->initialize(selectedDevice.c_str())) {
85 
86  LOG_ERROR("SoundDevice: initializing failed");
87  return false;
88  }
89 
90  ListeningPosition = AudioManager->getListener();
91 
92  // setup global volume //
93  SetGlobalVolume(1.f);
94 
95  ListeningPosition->setUpVector(cAudio::cVector3(0, 1, 0));
96 
97  return true;
98 }
#define LOG_INFO(x)
Definition: Define.h:82
#define LOG_ERROR(x)
Definition: Define.h:84
DLLEXPORT void SetGlobalVolume(float vol)
static const StringTypeN RemoveExtension(const StringTypeN &filepath, bool delpath=true)
#define LOG_WARNING(x)
Definition: Define.h:83
DLLEXPORT NamedVars * GetValues()
Definition: AppDefine.cpp:40
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:92
static DLLEXPORT std::vector< std::string > GetAudioDevices(size_t *indexofdefault=nullptr)
Returns a list of audio playback devices.
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
AppDef * GetDefinition()
Definition: Engine.h:198
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84

◆ Play2DSound()

DLLEXPORT AudioSource::pointer SoundDevice::Play2DSound ( const std::string &  filename,
bool  looping,
bool  startpaused 
)

Plays a 2d sound with options.

Note
If both looping and startpaused are false then this is the same as Play2DSoundEffect and returns null
Returns
The audio source that is playing the sound (this must be held onto until it is done playing, can be passed to BabysitAudio if not manually wanted to be managed or use the SoundEffect variant of this method) is null if looping and startpaused are false

Definition at line 170 of file SoundDevice.cpp.

172 {
173  if(!AudioManager)
174  return nullptr;
175 
176  if(!looping && !startpaused)
177  LOG_WARNING("SoundDevice: Play2DSound: called with same settings that "
178  "Play2DSoundEffect uses. looping or startpaused must be true to return an "
179  "AudioSource.");
180 
181  cAudio::IAudioSource* source =
182  AudioManager->play2D(filename.c_str(), looping, startpaused);
183 
184  if(!source) {
185  LOG_ERROR(
186  "SoundDevice: Play2DSound: failed to create IAudioSource from file: " + filename);
187 
188  if(!boost::filesystem::is_regular(filename))
189  LOG_INFO("SoundDevice: file '" + filename + "' doesn't exist");
190 
191  return nullptr;
192  }
193 
194  return AudioSource::MakeShared<AudioSource>(source, this);
195 }
#define LOG_INFO(x)
Definition: Define.h:82
#define LOG_ERROR(x)
Definition: Define.h:84
#define LOG_WARNING(x)
Definition: Define.h:83

◆ Play2DSoundEffect()

DLLEXPORT void SoundDevice::Play2DSoundEffect ( const std::string &  filename)

Plays a 2d sound without possibility of interrupting.

Definition at line 153 of file SoundDevice.cpp.

154 {
155  if(!AudioManager)
156  return;
157 
158  cAudio::IAudioSource* source = AudioManager->play2D(filename.c_str(), false, false);
159 
160  if(source) {
161 
162  LOG_ERROR("SoundDevice: Play2DSoundEffect: shouldn't return a source but it did. "
163  "Babysitting it");
164 
166  [=]() { this->BabysitAudio(AudioSource::MakeShared<AudioSource>(source, this)); });
167  }
168 }
#define LOG_ERROR(x)
Definition: Define.h:84
DLLEXPORT void RunOnMainThread(const std::function< void()> &function)
Runs the function now if on the main thread otherwise calls Invoke.
Definition: Engine.cpp:1161
DLLEXPORT void BabysitAudio(AudioSource::pointer audio)
This class holds the audio source until it has finished playing and then releases the reference...
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84

◆ Release()

void SoundDevice::Release ( )

Definition at line 99 of file SoundDevice.cpp.

100 {
101  HandledAudioSources.clear();
102 
103  if(AudioManager) {
104 
105  cAudio::destroyAudioManager(AudioManager);
106  AudioManager = nullptr;
107  }
108 }

◆ SetGlobalVolume()

DLLEXPORT void SoundDevice::SetGlobalVolume ( float  vol)
Parameters
volThe volume [0.f, 1.f]

Definition at line 143 of file SoundDevice.cpp.

144 {
145  if(!AudioManager)
146  return;
147 
148  vol = std::clamp(vol, 0.f, 1.f);
149 
150  AudioManager->setMasterVolume(vol);
151 }

◆ SetSoundListenerPosition()

DLLEXPORT void SoundDevice::SetSoundListenerPosition ( const Float3 pos,
const Float4 orientation 
)

Loads the file and plays the sound.

This creates a temporary SoundEffect on a background thread that is loaded from the file and destroyed once it finishes

Returns
False if the file doesn't exist or the sound couldn't be played for some other reason

Definition at line 121 of file SoundDevice.cpp.

123 {
124  // we need to create a vector from the angles //
125  // Float3 vec = Float3(-sin(pitchyawroll.X*DEGREES_TO_RADIANS),
126  // sin(pitchyawroll.Y*DEGREES_TO_RADIANS), -cos(pitchyawroll.X*DEGREES_TO_RADIANS));
127 
128  if(!ListeningPosition)
129  return;
130 
131  ListeningPosition->move(cAudio::cVector3(pos.X, pos.Y, pos.Z));
132 
133  Ogre::Quaternion quaternion(orientation);
134 
135  Ogre::Radian angle;
136  Ogre::Vector3 direction;
137 
138  quaternion.ToAngleAxis(angle, direction);
139 
140  ListeningPosition->setDirection(cAudio::cVector3(direction.x, direction.y, direction.z));
141 }

◆ Tick()

void SoundDevice::Tick ( int  PassedMs)

Definition at line 110 of file SoundDevice.cpp.

111 {
112  for(auto iter = HandledAudioSources.begin(); iter != HandledAudioSources.end(); ++iter) {
113 
114  if(!(*iter)->Get()->isPlaying()) {
115 
116  iter = HandledAudioSources.erase(iter);
117  }
118  }
119 }

The documentation for this class was generated from the following files: