Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update audio engine #366

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
aea0e26
Update audio engine
frabert Sep 12, 2018
f773798
Fix disabling OpenAL audio system if needed
frabert Sep 13, 2018
f2d84e4
Fix no-sound command line flag having wrong short form
frabert Sep 13, 2018
5979f79
Address various issues in the code
frabert Sep 14, 2018
4306e72
Move AudioWorld from World to BaseEngine
frabert Sep 14, 2018
cd5e440
Play music during game start and loading screens
frabert Sep 14, 2018
7ed92f6
Cleanup usage of `std::transform` instead of `Utils::uppered/lowered`
frabert Sep 14, 2018
c3e0385
Make `m_AudioEngine` a `unique_ptr`
frabert Sep 14, 2018
1ab3fbe
Add some comments
frabert Sep 14, 2018
ce3042c
Put static members directly inside function definition
frabert Sep 14, 2018
d3a0348
Simplify constructors
frabert Sep 14, 2018
dac612d
Use `emplace_back` instead of `push_back`
frabert Sep 14, 2018
e10c5aa
Fix sounds being played even when out of range
frabert Sep 15, 2018
6651301
Use default initializers where possible
frabert Sep 15, 2018
69574b0
Revert default initializer for `m_stop`
frabert Sep 15, 2018
e820843
Fix that intersecting music zones could cause issues
frabert Sep 16, 2018
54c13a3
Use player's position instead of camera's to detect music zones
frabert Sep 18, 2018
3cbb8d9
Increase MusicController's draw distance factor to disable pruning of…
frabert Sep 18, 2018
c671961
Remove superfluous whitespace
frabert Sep 19, 2018
c4b4588
Clarify audio buffering loop
frabert Sep 19, 2018
e0f423a
_Actually_ remove items from container
frabert Sep 19, 2018
f0691c0
Rewrite music zone system
frabert Sep 20, 2018
d5f9367
Fix random typo
frabert Sep 20, 2018
2220b89
Add virtual destructor for Sound
frabert Sep 20, 2018
0285540
Play loading music also on savegame load
frabert Sep 21, 2018
84b22ce
Move MusicZoneManager, enable (de)serialization for savegames
frabert Sep 22, 2018
e5e1124
Update CMake version
frabert Sep 22, 2018
7ec8c7d
Update Gradle plugin
frabert Sep 22, 2018
f93d45c
Change apk path
frabert Sep 22, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 0 additions & 71 deletions src/audio/AudioEngine.cpp

This file was deleted.

213 changes: 161 additions & 52 deletions src/audio/AudioEngine.h
Original file line number Diff line number Diff line change
@@ -1,66 +1,175 @@
#pragma once

#include <string>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <vector>

#include <glm/glm.hpp>

typedef struct ALCdevice_struct ALCdevice;
#include <math/mathlib.h>

namespace Audio
{
class AudioWorld;
enum class State {
Stopped,
Paused,
Playing
};

/** The AudioEngine represents the target OS sound system.
*
* The engine class matches the OpenAL device level.
enum class Format {
Mono,
Stereo
};

/**
* @brief Sounds represent audio sources.
*
* All of the information about a sound should be re-set before it is played
* after it had been stopped.
*
*/
class Sound {
public:
frabert marked this conversation as resolved.
Show resolved Hide resolved
/**
* @brief Set sound pitch, must be positive
*
* 1 means original pitch, values < 1 mean lower, > 1 mean higher.
*
* @return float
*/
virtual void pitch(float) = 0;

/**
* @brief Set sound gain
*
* 1 means original volume, <1 means lower gain, >1 means higher.
*
* @return float
*/
virtual void gain(float) = 0;

/**
* @brief Set the maximum distance from which this sound can be heard.
* Must be positive.
*
*/
virtual void maxDistance(float) = 0;

/**
* @brief Set the coordinates of the sound's position.
*
*/
virtual void position(const Math::float3&) = 0;

/**
* @brief Set the components of the sound's velocity.
*
*/
virtual void velocity(const Math::float3&) = 0;

/**
* @brief Set the componenets of the sound's direction.
*
*/
virtual void direction(const Math::float3&) = 0;

/**
* @brief Set whether the sound's position is relative to the listener.
*
*/
virtual void relative(bool) = 0;

/**
* @brief Set wheter the sound should loop back to the beginning once it
* finishes playing.
*
* This is ignored in the case of streming sounds
*/
virtual void looping(bool) = 0;

/**
* @brief Get the playback state of this sound.
*
* @return State
*/
virtual State state() = 0;

/**
* @brief Starts sound playback.
*
* This method is idempotent: if the sound was already playing,
* nothing happens.
*/
virtual void play() = 0;
/**
* @brief Pauses sound playback.
*
* This method is idempotent: if the sound was already paused,
* nothing happens.
*/
virtual void pause() = 0;
/**
* @brief Stops sound playback.
*
* Playback will resume from the beginning.
* This method is idempotent: if the sound was already stopped,
* nothing happens.
*/
virtual void stop() = 0;
};

using SoundPtr = std::shared_ptr<Sound>;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it should be doable with unique_ptr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to do it with a unique_ptr because OpenGLAudioEngine keeps reference of the sounds that have been created

Copy link
Contributor

@mdrost mdrost Oct 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the destruction order of Sound and OpenGLAudioEngine unspecified?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering that OpenGLAudioEngine is basically guaranteed to never be destroyed (it should be destroyed when the application closes), Sounds are always going to die before the engine. The issue is that the Engine gives out Sounds to its users, and these objects must stay alive even if they go out of scope, otherwise the sounds would stop playing. So the Engine keeps reference of all created sounds and destroys them when they are not tracked anymore by anyone else and they are not playing

using SoundStream = std::function<int(std::int16_t* buf, std::size_t size)>;

struct Orientation {
Math::float3 at;
Math::float3 up;
};

/** An AudioEngine is the interface to the system's audio driver
*
*/
class AudioEngine final
class AudioEngine
{
public:
/** Initializes the AudioEngine.
*
* The @p device param specifies the device to use and can be determined
* using enumerateDevices().
*
* @param device_name The name of the device to use.
*
* @see AudioEngine::enumerateDevices()
*
*/
AudioEngine(const std::string& device_name = std::string());

/** Deinitializes the AudioEngine.
*/
~AudioEngine();

/** Returns the OpenAL device used by this engine.
*
* @return The OpenAL device or nullptr when initialization has failed.
*/
ALCdevice* getDevice() const { return m_Device; }
/** Enumerates the audio devices available on the current machine.
*
* Note that not all OpenAL implementations support enumeration. In this case you'll
* retrieve a single element list with an empty device name, indicating that it is
* the default device.
*
* @param[out] devices A list of available devices.
*
*/
static void enumerateDevices(std::vector<std::string>& devices);

/** Returns a text representation of an error code.
*
* @param The error code returned by alGetError() or alcGetError().
*
* @return The error text.
*
*/
static const char* getErrorString(size_t errorCode);

private:
ALCdevice* m_Device = nullptr;
/**
* @brief Set master listener gain, must be positive
*
* 1 means original volume, <1 means lower gain, >1 means higher.
*
*/
virtual void gain(float) = 0;

/**
* @brief Set coordinates of listener's position
*
*/
virtual void position(const Math::float3&) = 0;

/**
* @brief Set components of listener's velocity
*
*/
virtual void velocity(const Math::float3&) = 0;

/**
* @brief Set listener's orientation
*
*/
virtual void orientation(const Orientation&) = 0;

/**
* @brief Creates a sound object from an audio buffer
*
* @return SoundPtr
*/
virtual SoundPtr createSound(const std::int16_t* buf, std::size_t len, Format, std::size_t samplingFreq) = 0;

/**
* @brief Creates a sound object from an audio stream
*
* @return SoundPtr
*/
virtual SoundPtr createSound(SoundStream, Format, std::size_t samplingFreq) = 0;
};
}
Loading