]> camargo.eng.br - camargo/neiasound.git/blob - src/nSoundSystem.cpp
Initial commit
[camargo/neiasound.git] / src / nSoundSystem.cpp
1 #include "nSoundSystem.h"
2 #include "nSoundSource.h"
3 #include "nSoundBuffer.h"
4 #include "nSoundListener.h"
5 #include "nSoundStreamer.h"
6 #include "nSoundStreamerPlaylist.h"
7
8 #include <AL/al.h>
9 #include <AL/alc.h>
10 #include <AL/alext.h>
11
12 #include "util/nEfxHelper.h"
13 #include <QSettings>
14 #include <QUuid>
15
16 nSoundSystem::nSoundSystem(QObject *parent) :
17     QObject(parent), m_success(false)
18 {
19     qDebug("nSoundSystem initializing.");
20
21     m_context = 0;
22     m_device = 0;
23
24     m_device = alcOpenDevice(0); //default device
25     if(!m_device)
26         throw QString("Error creating OpenAL device.");
27
28     int attributes[] = {ALC_FREQUENCY, 44100, 0};
29     m_context = alcCreateContext(m_device, attributes);
30     if(!m_context)
31         throw QString("Error creating OpenAL context.");
32
33     alcMakeContextCurrent(m_context);
34     if( alGetError()!=AL_NO_ERROR)
35         qWarning("nSoundSystem::nSoundSystem(): Failed to set context as current.");
36
37     if(!nEfxHelper::initialize(m_device))
38         qWarning("nSoundSystem::nSoundSystem(): nEfxHelper initialization failed.");
39
40     m_listener = new nSoundListener(this);
41     m_success = true;
42
43 #ifdef ANDROID
44 #ifdef MOB
45     alcDeviceEnableHrtfMOB( m_device, false );
46 #endif
47 #endif
48
49     qDebug("nSoundSystem initialized successfully.");
50
51     alcGetIntegerv(m_device, ALC_MAX_AUXILIARY_SENDS, 1, &m_numSends);
52     qDebug(QString("OpenAL device supports %1 auxiliary sends per source.").arg(m_numSends).toLocal8Bit());
53
54     nSoundSource::_resetRoleGains();
55     QSettings settings;
56     settings.beginGroup("Audio");
57     setMasterGain(settings.value("MasterGain", 100).toFloat()/100.0f);
58     settings.endGroup();
59
60 }
61
62 nSoundSystem::~nSoundSystem()
63 {
64     // ensure deletion of resources in right order
65     QHash<QString, nSoundSource*> sources = m_sources;
66     QHash<QString, nSoundBuffer*> buffers = m_buffers;
67     QHash<QString, nSoundStreamer*> streamers = m_streamers;
68
69     foreach(nSoundStreamer * streamer, streamers)
70     {
71         destroyStreamer(streamer);
72     }
73
74     foreach(nSoundSource * source, sources)
75     {
76         destroySource(source);
77     }
78
79     foreach(nSoundBuffer * buffer, buffers)
80     {
81         destroyBuffer(buffer);
82     }
83
84
85     alcMakeContextCurrent(0);
86     alcDestroyContext(m_context);
87     alcCloseDevice(m_device);
88 }
89
90 void nSoundSystem::update(qreal frameTime)
91 {
92
93     m_listener->update(frameTime);
94
95 //    Not necessary anymore, streamers update themselves in owned threads.
96
97 //    foreach(nSoundStreamer * streamer, m_streamers)
98 //    {
99 //        streamer->update(frameTime);
100 //    }
101
102     QList<nSoundSource*> toDestroy;
103     foreach(nSoundSource * source, m_sources)
104     {
105         if(!source->update(frameTime))
106             toDestroy.append(source);
107     }
108
109     foreach (nSoundSource * source, toDestroy) {
110         destroySource(source);
111     }
112 }
113
114 // SOUND STUFF METHODS
115
116 qreal nSoundSystem::masterGain()
117 {
118     float ret;
119     alGetListenerf(AL_GAIN, &ret);
120     return ret;
121 }
122
123 void nSoundSystem::setMasterGain(qreal gain)
124 {
125     alListenerf(AL_GAIN, gain);
126
127     emit masterGainChanged(gain);
128 }
129
130 // SOURCE METHODS
131
132 nSoundSource * nSoundSystem::createSource(QString name, nSoundSourceRole role)
133 {
134     if(name.isEmpty())
135     {
136         name = QString("nSoundSource_%1").arg(QUuid::createUuid().toString());
137     }
138
139     nSoundSource * src;
140     try{
141         src = new nSoundSource(name, role, this);
142         m_sources.insert(name, src);
143         return src;
144     }catch(...)
145     {
146         return 0;
147     }
148 }
149
150 nSoundSource * nSoundSystem::source(QString name)
151 {
152     return m_sources.value(name, 0);
153 }
154
155 bool nSoundSystem::destroySource(QString name)
156 {
157     nSoundSource * src = m_sources.value(name, 0);
158     if(!src) return false;
159     m_sources.remove(name);
160     delete src;
161     return true;
162 }
163
164 bool nSoundSystem::destroySource(nSoundSource * source)
165 {
166     nSoundSource * src = m_sources.value(source->objectName(), 0);
167     if(!src) return false;
168     m_sources.remove(source->objectName());
169     delete src;
170     return true;
171 }
172
173
174 // BUFFER METHODS
175
176 nSoundBuffer * nSoundSystem::createBuffer(QString name)
177 {
178     if(name.isEmpty()) qWarning("Creating nSoundBuffer with empty name.");
179
180     nSoundBuffer * buf = new nSoundBuffer(name, this);
181     m_buffers.insert(name, buf);
182     return buf;
183 }
184
185 nSoundBuffer * nSoundSystem::buffer(QString name)
186 {
187     return m_buffers.value(name, 0);
188 }
189
190 bool nSoundSystem::destroyBuffer(QString name)
191 {
192     nSoundBuffer * buf = m_buffers.value(name, 0);
193     if(!buf) return false;
194     m_buffers.remove(name);
195     delete buf;
196     return true;
197 }
198
199 bool nSoundSystem::destroyBuffer(nSoundBuffer * buffer)
200 {
201     nSoundBuffer * buf = m_buffers.value(buffer->objectName(), 0);
202     if(!buf) return false;
203     m_buffers.remove(buffer->objectName());
204     delete buf;
205     return true;
206 }
207
208
209 // STREAMER METHODS
210
211 nSoundStreamer * nSoundSystem::createStreamer(QString name, nSoundSource * source, nSoundStreamerPlaylist * playlist)
212 {
213     if(name.isEmpty()) qWarning("Creating nSoundStreamer with an empty name.");
214
215     nSoundStreamer * streamer = new nSoundStreamer(name, source, playlist, this);
216     playlist->setParent(streamer);
217     m_streamers.insert(name, streamer);
218     return streamer;
219 }
220
221 nSoundStreamerPlaylist *nSoundSystem::createStreamerPlaylist(QObject *parent)
222 {
223     return new nSoundStreamerPlaylist(parent);
224 }
225
226 nSoundStreamer * nSoundSystem::streamer(QString name)
227 {
228     return m_streamers.value(name, 0);
229 }
230
231 bool nSoundSystem::destroyStreamer(QString name)
232 {
233     nSoundStreamer * streamer = m_streamers.value(name, 0);
234     if(!streamer) return false;
235     m_streamers.remove(name);
236     delete streamer;
237     return true;
238 }
239
240 bool nSoundSystem::destroyStreamer(nSoundStreamer * streamer)
241 {
242     nSoundStreamer * strm = m_streamers.value(streamer->objectName(), 0);
243     if(!strm) return false;
244     m_streamers.remove(strm->objectName());
245     delete strm;
246     return true;
247 }