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.

21 {}

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 197 of file SoundDevice.cpp.

198 {
200 
201  HandledAudioSources.push_back(audio);
202 }
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:82
DLLEXPORT void AssertIfNotMainThread() const
Asserts if not called on the main thread.
Definition: Engine.h:93

◆ 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 185 of file SoundDevice.cpp.

187 {
188  if(!AudioManager || !data)
189  return nullptr;
190 
191  return AudioSource::MakeShared<AudioSource>(
192  AudioManager->createFromAudioDecoder(soundname, data->Properties.SourceName.c_str(),
193  CAUDIO_NEW ProceduralSoundStream(data)),
194  this);
195 }
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 204 of file SoundDevice.cpp.

206 {
207  std::vector<std::string> result;
208 
209  cAudio::IAudioDeviceList* devices = cAudio::createAudioDeviceList();
210 
211  if(!devices) {
212  LOG_ERROR("SoundDevice: GetAudioDevices: failed to get audio device list");
213  return {};
214  }
215 
216  const auto deviceCount = devices->getDeviceCount();
217  result.reserve(deviceCount);
218 
219  const auto defaultDeviceName = devices->getDefaultDeviceName();
220 
221  for(unsigned int i = 0; i < deviceCount; ++i) {
222 
223  const auto deviceName = devices->getDeviceName(i);
224 
225  if(deviceName.compare(defaultDeviceName) == 0 && indexofdefault) {
226 
227  *indexofdefault = i;
228  }
229 
230  result.push_back(deviceName);
231  }
232 
233  CAUDIO_DELETE devices;
234 
235  return result;
236 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ 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 23 of file SoundDevice.cpp.

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

◆ 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 158 of file SoundDevice.cpp.

160 {
161  if(!AudioManager)
162  return nullptr;
163 
164  if(!looping && !startpaused)
165  LOG_WARNING("SoundDevice: Play2DSound: called with same settings that "
166  "Play2DSoundEffect uses. looping or startpaused must be true to return an "
167  "AudioSource.");
168 
169  cAudio::IAudioSource* source =
170  AudioManager->play2D(filename.c_str(), looping, startpaused);
171 
172  if(!source) {
173  LOG_ERROR(
174  "SoundDevice: Play2DSound: failed to create IAudioSource from file: " + filename);
175 
176  if(!boost::filesystem::is_regular(filename))
177  LOG_INFO("SoundDevice: file '" + filename + "' doesn't exist");
178 
179  return nullptr;
180  }
181 
182  return AudioSource::MakeShared<AudioSource>(source, this);
183 }
#define LOG_INFO(x)
Definition: Define.h:81
#define LOG_ERROR(x)
Definition: Define.h:83
#define LOG_WARNING(x)
Definition: Define.h:82

◆ Play2DSoundEffect()

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

Plays a 2d sound without possibility of interrupting.

Definition at line 141 of file SoundDevice.cpp.

142 {
143  if(!AudioManager)
144  return;
145 
146  cAudio::IAudioSource* source = AudioManager->play2D(filename.c_str(), false, false);
147 
148  if(source) {
149 
150  LOG_ERROR("SoundDevice: Play2DSoundEffect: shouldn't return a source but it did. "
151  "Babysitting it");
152 
154  [=]() { this->BabysitAudio(AudioSource::MakeShared<AudioSource>(source, this)); });
155  }
156 }
#define LOG_ERROR(x)
Definition: Define.h:83
DLLEXPORT void RunOnMainThread(const std::function< void()> &function)
Runs the function now if on the main thread otherwise calls Invoke.
Definition: Engine.cpp:1135
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:82

◆ Release()

void SoundDevice::Release ( )

Definition at line 87 of file SoundDevice.cpp.

88 {
89  HandledAudioSources.clear();
90 
91  if(AudioManager) {
92 
93  cAudio::destroyAudioManager(AudioManager);
94  AudioManager = nullptr;
95  }
96 }

◆ SetGlobalVolume()

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

Definition at line 131 of file SoundDevice.cpp.

132 {
133  if(!AudioManager)
134  return;
135 
136  vol = std::clamp(vol, 0.f, 1.f);
137 
138  AudioManager->setMasterVolume(vol);
139 }

◆ 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 109 of file SoundDevice.cpp.

111 {
112  // we need to create a vector from the angles //
113  // Float3 vec = Float3(-sin(pitchyawroll.X*DEGREES_TO_RADIANS),
114  // sin(pitchyawroll.Y*DEGREES_TO_RADIANS), -cos(pitchyawroll.X*DEGREES_TO_RADIANS));
115 
116  if(!ListeningPosition)
117  return;
118 
119  ListeningPosition->move(cAudio::cVector3(pos.X, pos.Y, pos.Z));
120 
121  Ogre::Quaternion quaternion(orientation);
122 
123  Ogre::Radian angle;
124  Ogre::Vector3 direction;
125 
126  quaternion.ToAngleAxis(angle, direction);
127 
128  ListeningPosition->setDirection(cAudio::cVector3(direction.x, direction.y, direction.z));
129 }

◆ Tick()

void SoundDevice::Tick ( int  PassedMs)

Definition at line 98 of file SoundDevice.cpp.

99 {
100  for(auto iter = HandledAudioSources.begin(); iter != HandledAudioSources.end(); ++iter) {
101 
102  if(!(*iter)->Get()->isPlaying()) {
103 
104  iter = HandledAudioSources.erase(iter);
105  }
106  }
107 }

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