8 #include <glm/gtc/type_ptr.hpp>
9 #include <glm/gtx/io.hpp>
14 const char *al_error_string(ALenum num) {
19 return "invalid name";
21 return "invalid enum";
22 case AL_INVALID_VALUE:
23 return "invalid value";
24 case AL_INVALID_OPERATION:
25 return "invalid operation";
26 case AL_OUT_OF_MEMORY:
27 return "out of memory";
29 return "unknown AL error";
32 std::string al_error_append(ALenum num, std::string msg) {
33 return msg + ": " + al_error_string(num);
40 ALError::ALError(ALenum num)
41 : std::runtime_error(al_error_string(num)) {
45 ALError::ALError(ALenum num, const std::string &msg)
46 : std::runtime_error(al_error_append(num, msg)) {
52 alGenSources(NUM_SRC, source);
53 ALenum err = alGetError();
54 if (err != AL_NO_ERROR) {
55 throw ALError(err, "alGenSources");
57 for (std::size_t i = 0; i < NUM_SRC; ++i) {
58 alSourcef(source[i], AL_REFERENCE_DISTANCE, 2.0f);
59 alSourcef(source[i], AL_ROLLOFF_FACTOR, 1.0f);
64 alDeleteSources(NUM_SRC, source);
65 ALenum err = alGetError();
66 if (err != AL_NO_ERROR) {
67 std::cerr << "warning: alDeleteSources failed with " << al_error_string(err) << std::endl;
68 //throw ALError(err, "alDeleteSources");
72 void Audio::Position(const glm::vec3 &pos) noexcept {
73 alListenerfv(AL_POSITION, glm::value_ptr(pos));
74 //std::cout << "listener at " << pos << std::endl;
77 void Audio::Velocity(const glm::vec3 &vel) noexcept {
78 alListenerfv(AL_VELOCITY, glm::value_ptr(vel));
81 void Audio::Orientation(const glm::vec3 &dir, const glm::vec3 &up) noexcept {
86 alListenerfv(AL_ORIENTATION, orient);
95 // TODO: find next free source
96 ALuint src = source[0];
99 alSourcefv(src, AL_POSITION, glm::value_ptr(pos));
100 alSourcefv(src, AL_VELOCITY, glm::value_ptr(vel));
101 alSourcefv(src, AL_DIRECTION, glm::value_ptr(dir));
105 void Audio::StopAll() noexcept {
106 alSourceStopv(NUM_SRC, source);
107 for (std::size_t i = 0; i < NUM_SRC; ++i) {
108 alSourcei(source[i], AL_BUFFER, AL_NONE);
115 alGenBuffers(1, &handle);
116 ALenum err = alGetError();
117 if (err != AL_NO_ERROR) {
118 throw ALError(err, "alGenBuffers");
122 Sound::Sound(const char *file)
123 : handle(alutCreateBufferFromFile(file)) {
124 if (handle == AL_NONE) {
125 throw ALError(alGetError(), "alutCreateBufferFromFile");
130 if (handle != AL_NONE) {
131 alDeleteBuffers(1, &handle);
132 ALenum err = alGetError();
133 if (err != AL_NO_ERROR) {
134 std::cerr << "warning: alDeleteBuffers failed with " << al_error_string(err) << std::endl;
135 //throw ALError(err, "alDeleteBuffers");
140 Sound::Sound(Sound &&other)
141 : handle(other.handle) {
142 other.handle = AL_NONE;
145 Sound &Sound::operator =(Sound &&other) {
146 std::swap(handle, other.handle);
150 void Sound::Bind(ALuint src) const {
151 alSourcei(src, AL_BUFFER, handle);