9cb2202425c23b9456c68fb76d955c68f169afe4
[blender.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 = false;
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         }
108         else
109         {
110                 // find the first id object which doesn't have a high priority soundobject
111                 bool ThisSoundMustStay = false;
112                 bool OutOfIds = false;
113
114                 do
115                 {
116                         // if no soundobject present, it's seat may be taken
117                         if (pIdObject->GetSoundObject())
118                         {
119                                 // and also if it ain't highprio
120                                 if (pIdObject->GetSoundObject()->IsHighPriority())
121                                 {
122                                         ThisSoundMustStay = true;
123                                         pIdObject = (SND_IdObject*)pIdObject->getNext();
124                                         
125                                         // if the last one is a priority sound too, then there are no id's left
126                                         // and we won't add any new sounds
127                                         if (pIdObject->isTail())
128                                                 OutOfIds = true;
129                                 }
130                                 else
131                                 {
132                                         ThisSoundMustStay = false;
133                                 }
134                         }
135                         else
136                         {
137                                 ThisSoundMustStay = false;
138                         }
139
140                 } while (ThisSoundMustStay && !OutOfIds);
141
142                 if (!OutOfIds)
143                 {
144                         SND_SoundObject* oldobject = oldobject = pIdObject->GetSoundObject();
145                         
146                         // revoke the old object if present
147                         if (oldobject)
148                         {
149 #ifdef ONTKEVER
150                                 printf("oldobject: %x\n", oldobject);
151 #endif
152                                 RevokeSoundObject(oldobject);
153                         }
154                         
155                         // set the new soundobject into the idobject
156                         pIdObject->SetSoundObject(pObject);
157                         
158                         // set the id into the soundobject
159                         int id = pIdObject->GetId();
160                         pObject->SetId(id);
161                         
162                         // connect the new id to the buffer the sample is stored in
163                         SetObjectBuffer(id, pObject->GetBuffer());
164                         
165                         // remove the idobject from the list and add it in the back again
166                         pIdObject->remove();
167                         m_idObjectList.addTail(pIdObject);
168                         
169                         result = true;
170                 }
171         }
172
173         return result;
174 }
175
176
177
178 void SND_AudioDevice::ClearId(SND_SoundObject* pObject)
179 {
180 #ifdef ONTKEVER
181         printf("SND_AudioDevice::ClearId\n");
182 #endif
183
184         if (pObject)
185         {
186                 int id = pObject->GetId();
187                 
188                 if (id != -1)
189                 {
190                         // lets get the idobject belonging to the soundobject
191                         SND_IdObject* pIdObject = m_idObjectArray[id];
192                         SND_SoundObject* oldobject = pIdObject->GetSoundObject();
193                         
194                         if (oldobject)
195                         {
196                                 RevokeSoundObject(oldobject);
197
198                                 // clear the idobject from the soundobject
199                                 pIdObject->SetSoundObject(NULL);
200                         }
201
202                         // remove the idobject and place it in front
203                         pIdObject->remove();
204                         m_idObjectList.addHead(pIdObject);
205                 }
206         }
207 }
208
209
210
211 void SND_AudioDevice::RevokeSoundObject(SND_SoundObject* pObject)
212 {
213 #ifdef ONTKEVER
214         printf("SND_AudioDevice::RevokeSoundObject\n");
215 #endif
216
217         // stop the soundobject
218         int id = pObject->GetId();
219
220         if (id >= 0 && id < NUM_SOURCES)
221         {
222                 StopObject(id);
223
224                 // remove the object from the 'activelist'
225                 pObject->SetActive(false);
226
227 #ifdef ONTKEVER
228                 printf("pObject->remove();\n");
229 #endif
230         }
231
232         // make sure its id is invalid
233         pObject->SetId(-1);
234 }
235
236 /*
237 void SND_AudioDevice::RemoveSample(const char* filename)
238 {
239         if (m_wavecache)
240                 m_wavecache->RemoveSample(filename);
241 }
242 */
243
244 void SND_AudioDevice::RemoveAllSamples()
245 {
246         if (m_wavecache)
247                 m_wavecache->RemoveAllSamples();
248 }
249