3fd8334d506124981b4cdddb1524e9366633f4df
[blender-staging.git] / intern / SoundSystem / intern / SND_AudioDevice.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 #include "SND_AudioDevice.h"
33 #include "SND_SoundObject.h"
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #ifdef WIN32
40 // This warning tells us about truncation of __long__ stl-generated names.
41 // It can occasionally cause DevStudio to have internal compiler warnings.
42 #pragma warning( disable : 4786 )     
43 #endif
44
45
46 SND_AudioDevice::SND_AudioDevice()
47 {
48         m_wavecache = NULL;
49         m_audio = false;
50
51         for (int i = 0; i < NUM_SOURCES; i++)
52         {
53                 m_idObjectArray[i] = new SND_IdObject();
54                 m_idObjectArray[i]->SetId(i);
55                 m_idObjectArray[i]->SetSoundObject(NULL);
56                 m_idObjectList.addTail(m_idObjectArray[i]);
57         }
58 }
59
60
61
62 SND_AudioDevice::~SND_AudioDevice()
63 {
64         for (int i = 0; i < NUM_SOURCES; i++)
65         {
66                 delete m_idObjectArray[i];
67                 m_idObjectArray[i] = NULL;
68         }
69
70         if (m_wavecache)
71         {
72                 delete m_wavecache;
73                 m_wavecache = NULL;
74         }
75 }
76
77
78
79 bool SND_AudioDevice::IsInitialized()
80 {
81         return m_audio;
82 }
83
84
85
86 SND_WaveCache* SND_AudioDevice::GetWaveCache() const
87 {
88         return m_wavecache;
89 }
90
91
92
93 /* seeks an unused id and returns it */
94 bool SND_AudioDevice::GetNewId(SND_SoundObject* pObject)
95 {
96 #ifdef ONTKEVER
97         printf("SND_AudioDevice::GetNewId\n");
98 #endif
99
100         bool result;
101
102         // first, get the oldest (the first) idobject
103         SND_IdObject* pIdObject = (SND_IdObject*)m_idObjectList.getHead();
104
105         if (pIdObject->isTail())
106         {
107                 result = false;
108         }
109         else
110         {
111                 // find the first id object which doesn't have a high priority soundobject
112                 bool ThisSoundMustStay = false;
113                 bool OutOfIds = false;
114
115                 do
116                 {
117                         // if no soundobject present, it's seat may be taken
118                         if (pIdObject->GetSoundObject())
119                         {
120                                 // and also if it ain't highprio
121                                 if (pIdObject->GetSoundObject()->IsHighPriority())
122                                 {
123                                         ThisSoundMustStay = true;
124                                         pIdObject = (SND_IdObject*)pIdObject->getNext();
125                                         
126                                         // if the last one is a priority sound too, then there are no id's left
127                                         // and we won't add any new sounds
128                                         if (pIdObject->isTail())
129                                                 OutOfIds = true;
130                                 }
131                                 else
132                                 {
133                                         ThisSoundMustStay = false;
134                                 }
135                         }
136                         else
137                         {
138                                 ThisSoundMustStay = false;
139                         }
140
141                 } while (ThisSoundMustStay && !OutOfIds);
142
143                 if (!OutOfIds)
144                 {
145                         SND_SoundObject* oldobject = oldobject = pIdObject->GetSoundObject();
146                         
147                         // revoke the old object if present
148                         if (oldobject)
149                         {
150 #ifdef ONTKEVER
151                                 printf("oldobject: %x\n", oldobject);
152 #endif
153                                 RevokeSoundObject(oldobject);
154                         }
155                         
156                         // set the new soundobject into the idobject
157                         pIdObject->SetSoundObject(pObject);
158                         
159                         // set the id into the soundobject
160                         int id = pIdObject->GetId();
161                         pObject->SetId(id);
162                         
163                         // connect the new id to the buffer the sample is stored in
164                         SetObjectBuffer(id, pObject->GetBuffer());
165                         
166                         // remove the idobject from the list and add it in the back again
167                         pIdObject->remove();
168                         m_idObjectList.addTail(pIdObject);
169                         
170                         result = true;
171                 }
172         }
173
174         return result;
175 }
176
177
178
179 void SND_AudioDevice::ClearId(SND_SoundObject* pObject)
180 {
181 #ifdef ONTKEVER
182         printf("SND_AudioDevice::ClearId\n");
183 #endif
184
185         if (pObject)
186         {
187                 int id = pObject->GetId();
188                 
189                 if (id != -1)
190                 {
191                         // lets get the idobject belonging to the soundobject
192                         SND_IdObject* pIdObject = m_idObjectArray[id];
193                         SND_SoundObject* oldobject = pIdObject->GetSoundObject();
194                         
195                         if (oldobject)
196                         {
197                                 RevokeSoundObject(oldobject);
198
199                                 // clear the idobject from the soundobject
200                                 pIdObject->SetSoundObject(NULL);
201                         }
202
203                         // remove the idobject and place it in front
204                         pIdObject->remove();
205                         m_idObjectList.addHead(pIdObject);
206                 }
207         }
208 }
209
210
211
212 void SND_AudioDevice::RevokeSoundObject(SND_SoundObject* pObject)
213 {
214 #ifdef ONTKEVER
215         printf("SND_AudioDevice::RevokeSoundObject\n");
216 #endif
217
218         // stop the soundobject
219         int id = pObject->GetId();
220
221         if (id >= 0 && id < NUM_SOURCES)
222         {
223                 StopObject(id);
224
225                 // remove the object from the 'activelist'
226                 pObject->SetActive(false);
227
228 #ifdef ONTKEVER
229                 printf("pObject->remove();\n");
230 #endif
231         }
232
233         // make sure its id is invalid
234         pObject->SetId(-1);
235 }
236
237 /*
238 void SND_AudioDevice::RemoveSample(const char* filename)
239 {
240         if (m_wavecache)
241                 m_wavecache->RemoveSample(filename);
242 }
243 */
244
245 void SND_AudioDevice::RemoveAllSamples()
246 {
247         if (m_wavecache)
248                 m_wavecache->RemoveAllSamples();
249 }
250