]> camargo.eng.br - camargo/neiasound.git/blob - src/nSoundSource.cpp
Initial commit
[camargo/neiasound.git] / src / nSoundSource.cpp
1 #include "nSoundSource.h"
2 #include "nSoundSystem.h"
3 #include "nSoundBuffer.h"
4
5 #include "AL/al.h"
6
7
8 nSoundSource::nSoundSource(QString name, nSoundSourceRole role, nSoundSystem * parent) :
9     QObject(parent)
10 {
11     setObjectName(name);
12     m_role = role;
13     m_gainMirror = _roleGainVolume(role);
14     m_fading = false;
15     m_fadeTarget = 0.0f;
16     m_fadeDeltaPerSecond = 0.0f;
17     m_destroyAfterStopped = false;
18
19     alGetError(); //reset error state
20
21     unsigned int hnd;
22     alGenSources(1, &hnd);
23     m_handle = hnd;
24
25     ALenum error = alGetError();
26     if(error!=AL_NO_ERROR)
27     {
28         throw QString("nSoundSource: alGenSources() failed.");
29     }
30
31     alSourcef(m_handle, AL_GAIN, m_gainMirror);
32     alSource3f(m_handle, AL_POSITION, 0.0f ,0.0f ,0.0f);
33     alSource3f(m_handle, AL_VELOCITY, 0.0f ,0.0f ,0.0f);
34     alSource3f(m_handle, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
35     if(error!=AL_NO_ERROR)
36         throw QString("nSoundSource: Setting of source properties failed.");
37
38 }
39
40 nSoundSource::~nSoundSource()
41 {
42     alDeleteSources(1, &m_handle);
43 }
44
45 // PROPERTIES
46
47 nSoundSource::nSoundSourceState nSoundSource::state()
48 {
49     alGetError();
50
51     int state;
52     alGetSourcei(m_handle, AL_SOURCE_STATE, &state);
53
54     switch (state)
55     {
56     case AL_INITIAL:
57         return SSS_INITIAL;
58
59     case AL_PLAYING:
60         return SSS_PLAYING;
61
62     case AL_PAUSED:
63         return SSS_PAUSED;
64
65     case AL_STOPPED:
66         return SSS_STOPPED;
67     }
68
69     return SSS_UNKNOWN;
70
71 }
72
73 qreal nSoundSource::gain()
74 {
75     return m_gainMirror;
76 }
77
78 void nSoundSource::setGain(qreal f)
79 {
80     if(f<0.0f)
81         f=0.0f;
82     alSourcef(m_handle, AL_GAIN, f);    
83     m_gainMirror = f;
84 }
85
86
87 qreal nSoundSource::pitch()
88 {
89     ALfloat pitch;
90     alGetSourcef(m_handle, AL_PITCH, &pitch);
91     return pitch;
92 }
93
94 void nSoundSource::setPitch(qreal f)
95 {
96     if(f<0.0f)
97         f=0.0f;
98     alSourcef(m_handle, AL_PITCH, f);
99 }
100
101
102 qreal nSoundSource::rolloffFactor()
103 {
104     ALfloat rolloff;
105     alGetSourcef(m_handle, AL_ROLLOFF_FACTOR, &rolloff);
106     return rolloff;
107 }
108
109 void nSoundSource::setRolloffFactor(qreal f)
110 {
111     if(f<0.0f)
112         f=0.0f;
113     alSourcef(m_handle, AL_ROLLOFF_FACTOR, f);
114 }
115
116
117 bool nSoundSource::loop()
118 {
119     ALint loop;
120     alGetSourcei(m_handle, AL_LOOPING, &loop);
121     return (loop?true:false);
122 }
123
124 void nSoundSource::setLoop(bool b)
125 {
126     alSourcei(m_handle, AL_LOOPING, (b?AL_TRUE:AL_FALSE));
127 }
128
129 QVector3D nSoundSource::position()
130 {
131     ALfloat x,y,z;
132     alGetSource3f(m_handle, AL_POSITION, &x, &y, &z);
133     return QVector3D(x,y,z);
134 }
135
136 void nSoundSource::setPosition(QVector3D pos)
137 {
138     alSource3f(m_handle, AL_POSITION, pos.x(), pos.y(), pos.z() );
139 }
140
141
142 // METHODS
143
144 bool nSoundSource::update(qreal frameTime)
145 {
146     if(m_fading)
147     {
148         qreal newGain = m_gainMirror + frameTime*m_fadeDeltaPerSecond;
149         if( ((m_fadeDeltaPerSecond < 0.0f)&&(newGain<m_fadeTarget)) ||
150             ((m_fadeDeltaPerSecond > 0.0f)&&(newGain>m_fadeTarget)) )
151         {
152             newGain = m_fadeTarget;
153             m_fading = false;
154         }
155         setGain(newGain);
156     }if(destroyAfterStopped() && state() == SSS_STOPPED)
157     {
158         return false;
159     }
160
161     return true;
162 }
163
164 void nSoundSource::fade(qreal to, qreal duration, qreal from)
165 {
166     if(to==from)
167     {
168         setGain(to);
169         m_fading = false;
170         return;
171     }
172
173     qreal newGain;
174     if(from >= 0.0f)
175     {
176         setGain(from);
177         newGain = from;
178     }else newGain = gain();
179
180     m_fadeTarget = to;
181     m_fadeDeltaPerSecond = (to - newGain)/duration;
182     m_fading = true;
183
184 }
185
186 void nSoundSource::attachBuffer(nSoundBuffer * buffer)
187 {
188     if(!buffer) return;
189     alGetError();
190
191     ALint sourceType;
192     alGetSourcei(m_handle, AL_SOURCE_TYPE, &sourceType);
193     if(sourceType == AL_STREAMING)
194         throw QString("nSoundSource: Tried to play a single buffer on a streaming source.");
195
196     alSourcei(m_handle, AL_BUFFER, buffer->openalHandle());
197
198     ALenum err = alGetError();
199     if(err!=AL_NO_ERROR)
200         throw QString("nSoundSource: failed to bind buffer \"")+buffer->objectName()+
201                 QString("\" to source \"")+objectName()+QString("\".");
202 }
203
204 void nSoundSource::play()
205 {
206     alGetError();
207     alSourcePlay(m_handle);
208     if(alGetError()!=AL_NO_ERROR)
209         throw QString("nSoundSource: Failed to play source.");
210 }
211
212 void nSoundSource::pause()
213 {
214     alGetError();
215     alSourcePause(m_handle);
216     if(alGetError()!=AL_NO_ERROR)
217         throw QString("nSoundSource: Failed to pause source.");
218 }
219
220 void nSoundSource::stop()
221 {
222     alGetError();
223     alSourceStop(m_handle);
224     if(alGetError()!=AL_NO_ERROR)
225         throw QString("nSoundSource: Failed to stop source.");
226 }
227
228 void nSoundSource::rewind()
229 {
230     alGetError();
231     alSourceRewind(m_handle);
232     if(alGetError()!=AL_NO_ERROR)
233         throw QString("nSoundSource: Failed to rewind source.");
234 }
235
236 // GAIN CFG SUPPORT
237
238 bool nSoundSource::_m_gainsInitialized = false;
239 qreal nSoundSource::_m_musicGain = 0.0f;
240 qreal nSoundSource::_m_sfxGain = 0.0f;
241 qreal nSoundSource::_m_voiceGain = 0.0f;
242 qreal nSoundSource::_m_ambienceGain = 0.0f;
243
244 #include <QSettings>
245
246 void nSoundSource::_resetRoleGains()
247 {
248     QSettings settings;
249     settings.beginGroup("Audio");
250     _m_musicGain = settings.value("MusicGain", 60).toFloat()/100.0f;
251     _m_sfxGain = settings.value("SfxGain", 90).toFloat()/100.0f;
252     _m_voiceGain = settings.value("VoiceGain", 70).toFloat()/100.0f;
253     _m_ambienceGain = settings.value("AmbienceGain", 60).toFloat()/100.0f;
254     _m_gainsInitialized = true;
255     settings.endGroup();
256
257     _m_gainsInitialized = true;
258 }
259
260 qreal nSoundSource::_roleGainVolume(nSoundSourceRole role)
261 {
262     if(!_m_gainsInitialized)
263         nSoundSource::_resetRoleGains();
264
265     switch(role)
266     {
267     case SSR_MUSIC:
268         return _m_musicGain;
269     case SSR_SFX:
270         return _m_sfxGain;
271     case SSR_AMBIENCE:
272         return _m_ambienceGain;
273     case SSR_VOICE:
274         return _m_voiceGain;
275     default:
276         return 1.0f;
277     }
278
279 }
280