1 // This file is part of Dust Racing 2D.
2 // Copyright (C) 2013 Jussi Lind <jussi.lind@iki.fi>
3 //
4 // Dust Racing 2D is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 // Dust Racing 2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
15
16 #include "openalsource.hpp"
17 #include "openaldata.hpp"
18
19 #include <AL/alc.h>
20
21 #include <memory>
22 #include <stdexcept>
23
checkError()24 static bool checkError()
25 {
26 ALCenum error = alGetError();
27 return error == AL_NO_ERROR;
28 }
29
OpenALSource(STFH::DataPtr data)30 OpenALSource::OpenALSource(STFH::DataPtr data)
31 : m_handle(0)
32 {
33 alGenSources((ALuint)1, &m_handle);
34
35 alSourcef(m_handle, AL_PITCH, pitch());
36 alSourcef(m_handle, AL_GAIN, volume());
37 alSource3f(m_handle, AL_POSITION, 0, 0, 0);
38 alSource3f(m_handle, AL_VELOCITY, 0, 0, 0);
39 alSourcei(m_handle, AL_LOOPING, AL_FALSE);
40
41 setData(data);
42 }
43
setData(STFH::DataPtr data)44 void OpenALSource::setData(STFH::DataPtr data)
45 {
46 alGetError();
47
48 if (auto soundData = std::dynamic_pointer_cast<OpenALData>(data))
49 {
50 Source::setData(data);
51 alSourcei(m_handle, AL_BUFFER, soundData->buffer());
52
53 if (!checkError())
54 {
55 throw std::runtime_error("Failed to bind '" + data->path() + "'");
56 }
57 }
58 else
59 {
60 throw std::runtime_error("Incompatible sound data container for '" + data->path() + "'");
61 }
62 }
63
play(bool loop)64 void OpenALSource::play(bool loop)
65 {
66 alSourcei(m_handle, AL_LOOPING, loop);
67 alSourcePlay(m_handle);
68 }
69
stop()70 void OpenALSource::stop()
71 {
72 alSourceStop(m_handle);
73 }
74
setVolume(float volume)75 void OpenALSource::setVolume(float volume)
76 {
77 STFH::Source::setVolume(volume);
78 alSourcef(m_handle, AL_GAIN, volume);
79 }
80
setPitch(float pitch)81 void OpenALSource::setPitch(float pitch)
82 {
83 STFH::Source::setPitch(pitch);
84 alSourcef(m_handle, AL_PITCH, STFH::Source::pitch());
85 }
86
setLocation(const STFH::Location & location)87 void OpenALSource::setLocation(const STFH::Location & location)
88 {
89 STFH::Source::setLocation(location);
90 alSource3f(m_handle, AL_POSITION, location.x(), location.y(), 0);
91 }
92
setMaxDist(float maxDist)93 void OpenALSource::setMaxDist(float maxDist)
94 {
95 Source::setMaxDist(maxDist);
96 alSourcef(m_handle, AL_MAX_DISTANCE, maxDist);
97 }
98
setReferenceDist(float refDist)99 void OpenALSource::setReferenceDist(float refDist)
100 {
101 Source::setReferenceDist(refDist);
102 alSourcef(m_handle, AL_REFERENCE_DISTANCE, refDist);
103 }
104
~OpenALSource()105 OpenALSource::~OpenALSource()
106 {
107 alDeleteSources(1, &m_handle);
108 }
109