3 #include "SoundBank.hpp"
5 #include "../app/AssetLoader.hpp"
6 #include "../app/error.hpp"
7 #include "../app/ResourceIndex.hpp"
12 #include <glm/gtc/type_ptr.hpp>
13 #include <glm/gtx/io.hpp>
21 alGenSources(NUM_SRC, source);
22 ALenum err = alGetError();
23 if (err != AL_NO_ERROR) {
24 throw app::ALError(err, "alGenSources");
26 for (std::size_t i = 0; i < NUM_SRC; ++i) {
27 alSourcef(source[i], AL_REFERENCE_DISTANCE, 2.0f);
28 alSourcef(source[i], AL_ROLLOFF_FACTOR, 1.0f);
33 alDeleteSources(NUM_SRC, source);
34 ALenum err = alGetError();
35 if (err != AL_NO_ERROR) {
36 app::ALError error(err, "alDeleteSources");
37 std::cerr << "warning: " << error.what() << std::endl;
42 void Audio::Position(const glm::vec3 &pos) noexcept {
43 alListenerfv(AL_POSITION, glm::value_ptr(pos));
44 //std::cout << "listener at " << pos << std::endl;
47 void Audio::Velocity(const glm::vec3 &vel) noexcept {
48 alListenerfv(AL_VELOCITY, glm::value_ptr(vel));
51 void Audio::Orientation(const glm::vec3 &dir, const glm::vec3 &up) noexcept {
56 alListenerfv(AL_ORIENTATION, orient);
67 std::cerr << "unable to find free audio source" << std::endl;
71 ALuint src = source[i];
72 app::CoarseTimer &t = timer[i];
75 alSourcefv(src, AL_POSITION, glm::value_ptr(pos));
76 alSourcefv(src, AL_VELOCITY, glm::value_ptr(vel));
77 alSourcefv(src, AL_DIRECTION, glm::value_ptr(dir));
80 t = app::CoarseTimer(sound.Duration());
84 void Audio::StopAll() noexcept {
85 alSourceStopv(NUM_SRC, source);
86 for (std::size_t i = 0; i < NUM_SRC; ++i) {
87 alSourcei(source[i], AL_BUFFER, AL_NONE);
91 void Audio::Update(int dt) noexcept {
92 for (std::size_t i = 0; i < NUM_SRC; ++i) {
94 if (timer[i].HitOnce()) {
96 alSourceStop(source[i]);
97 alSourcei(source[i], AL_BUFFER, AL_NONE);
103 int Audio::NextFree() noexcept {
104 if (!timer[last_free].Running()) {
107 for (int i = (last_free + 1) % NUM_SRC; i != last_free; i = (i + 1) % NUM_SRC) {
108 if (!timer[i].Running()) {
123 Sound::Sound(const char *file)
124 : handle(alutCreateBufferFromFile(file)) {
125 if (handle == AL_NONE) {
126 throw app::ALError(alGetError(), "alutCreateBufferFromFile");
129 ALint size, channels, bits, freq;
130 alGetBufferi(handle, AL_SIZE, &size);
131 alGetBufferi(handle, AL_CHANNELS, &channels);
132 alGetBufferi(handle, AL_BITS, &bits);
133 alGetBufferi(handle, AL_FREQUENCY, &freq);
135 duration = size * 8 * 1000 / (channels * bits * freq);
139 if (handle != AL_NONE) {
140 alDeleteBuffers(1, &handle);
141 ALenum err = alGetError();
142 if (err != AL_NO_ERROR) {
143 app::ALError error(err, "alDeleteBuffers");
144 std::cerr << "warning: " << error.what() << std::endl;
150 Sound::Sound(Sound &&other)
151 : handle(other.handle)
152 , duration(other.duration) {
153 other.handle = AL_NONE;
156 Sound &Sound::operator =(Sound &&other) {
157 std::swap(handle, other.handle);
158 std::swap(duration, other.duration);
162 void Sound::Bind(ALuint src) const {
163 alSourcei(src, AL_BUFFER, handle);
167 SoundBank::SoundBank()
172 void SoundBank::Load(const app::AssetLoader &loader, const app::ResourceIndex &index) {
174 sounds.resize(index.Size());
175 for (const auto &entry : index.Entries()) {
176 sounds[entry.second] = loader.LoadSound(entry.first);