btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / kits / game / GameSoundDevice.cpp
blobedfdafc23bf3f45f9761f4c39d766658ebab825f
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2001-2002, OpenBeOS
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
22 // File Name: BGameSoundDevice.cpp
23 // Author: Christopher ML Zumwalt May (zummy@users.sf.net)
24 // Description: Manages the game producer. The class may change with out
25 // notice and was only inteneded for use by the GameKit at
26 // this time. Use at your own risk.
27 //------------------------------------------------------------------------------
30 #include "GameSoundDevice.h"
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
36 #include <Autolock.h>
37 #include <List.h>
38 #include <Locker.h>
39 #include <MediaAddOn.h>
40 #include <MediaRoster.h>
41 #include <MediaTheme.h>
42 #include <TimeSource.h>
44 #include "GameSoundBuffer.h"
45 #include "GameProducer.h"
46 #include "GSUtility.h"
49 // BGameSoundDevice definitions ------------------------------------
50 const int32 kInitSoundCount = 32;
51 const int32 kGrowth = 16;
53 static int32 sDeviceCount = 0;
54 static BGameSoundDevice* sDevice = NULL;
55 static BLocker sDeviceRefCountLock("GameSound device lock");
58 BGameSoundDevice*
59 GetDefaultDevice()
61 BAutolock _(sDeviceRefCountLock);
63 if (!sDevice)
64 sDevice = new BGameSoundDevice();
66 sDeviceCount++;
67 return sDevice;
71 void
72 ReleaseDevice()
74 BAutolock _(sDeviceRefCountLock);
76 sDeviceCount--;
78 if (sDeviceCount <= 0) {
79 delete sDevice;
80 sDevice = NULL;
85 // BGameSoundDevice -------------------------------------------------------
86 BGameSoundDevice::BGameSoundDevice()
88 fIsConnected(false),
89 fSoundCount(kInitSoundCount)
91 memset(&fFormat, 0, sizeof(gs_audio_format));
93 fInitError = B_OK;
95 fSounds = new GameSoundBuffer*[kInitSoundCount];
96 for (int32 i = 0; i < kInitSoundCount; i++)
97 fSounds[i] = NULL;
101 BGameSoundDevice::~BGameSoundDevice()
103 // We need to stop all the sounds before we stop the mixer
104 for (int32 i = 0; i < fSoundCount; i++) {
105 if (fSounds[i])
106 fSounds[i]->StopPlaying();
107 delete fSounds[i];
110 delete[] fSounds;
114 status_t
115 BGameSoundDevice::InitCheck() const
117 return fInitError;
121 const gs_audio_format&
122 BGameSoundDevice::Format() const
124 return fFormat;
128 const gs_audio_format&
129 BGameSoundDevice::Format(gs_id sound) const
131 return fSounds[sound - 1]->Format();
135 void
136 BGameSoundDevice::SetInitError(status_t error)
138 fInitError = error;
142 status_t
143 BGameSoundDevice::CreateBuffer(gs_id* sound, const gs_audio_format* format,
144 const void* data, int64 frames)
146 if (frames <= 0 || !sound)
147 return B_BAD_VALUE;
149 status_t err = B_MEDIA_TOO_MANY_BUFFERS;
150 int32 position = AllocateSound();
152 if (position >= 0) {
153 fSounds[position] = new SimpleSoundBuffer(format, data, frames);
155 media_node systemMixer;
156 BMediaRoster::Roster()->GetAudioMixer(&systemMixer);
157 err = fSounds[position]->Connect(&systemMixer);
160 if (err == B_OK)
161 *sound = gs_id(position + 1);
162 return err;
166 status_t
167 BGameSoundDevice::CreateBuffer(gs_id* sound, const void* object,
168 const gs_audio_format* format, size_t inBufferFrameCount,
169 size_t inBufferCount)
171 if (!object || !sound)
172 return B_BAD_VALUE;
174 status_t err = B_MEDIA_TOO_MANY_BUFFERS;
175 int32 position = AllocateSound();
177 if (position >= 0) {
178 fSounds[position] = new StreamingSoundBuffer(format, object,
179 inBufferFrameCount, inBufferCount);
181 media_node systemMixer;
182 BMediaRoster::Roster()->GetAudioMixer(&systemMixer);
183 err = fSounds[position]->Connect(&systemMixer);
186 if (err == B_OK)
187 *sound = gs_id(position + 1);
188 return err;
192 void
193 BGameSoundDevice::ReleaseBuffer(gs_id sound)
195 if (sound <= 0)
196 return;
198 if (fSounds[sound - 1]) {
199 // We must stop playback befor destroying the sound or else
200 // we may receive fatal errors.
201 fSounds[sound - 1]->StopPlaying();
203 delete fSounds[sound - 1];
204 fSounds[sound - 1] = NULL;
209 status_t
210 BGameSoundDevice::Buffer(gs_id sound, gs_audio_format* format, void*& data)
212 if (!format || sound <= 0)
213 return B_BAD_VALUE;
215 memcpy(format, &fSounds[sound - 1]->Format(), sizeof(gs_audio_format));
216 if (fSounds[sound - 1]->Data()) {
217 data = malloc(format->buffer_size);
218 memcpy(data, fSounds[sound - 1]->Data(), format->buffer_size);
219 } else
220 data = NULL;
222 return B_OK;
226 status_t
227 BGameSoundDevice::StartPlaying(gs_id sound)
229 if (sound <= 0)
230 return B_BAD_VALUE;
232 if (!fSounds[sound - 1]->IsPlaying()) {
233 // tell the producer to start playing the sound
234 return fSounds[sound - 1]->StartPlaying();
237 fSounds[sound - 1]->Reset();
238 return EALREADY;
242 status_t
243 BGameSoundDevice::StopPlaying(gs_id sound)
245 if (sound <= 0)
246 return B_BAD_VALUE;
248 if (fSounds[sound - 1]->IsPlaying()) {
249 // Tell the producer to stop play this sound
250 fSounds[sound - 1]->Reset();
251 return fSounds[sound - 1]->StopPlaying();
254 return EALREADY;
258 bool
259 BGameSoundDevice::IsPlaying(gs_id sound)
261 if (sound <= 0)
262 return false;
263 return fSounds[sound - 1]->IsPlaying();
267 status_t
268 BGameSoundDevice::GetAttributes(gs_id sound, gs_attribute* attributes,
269 size_t attributeCount)
271 if (!fSounds[sound - 1])
272 return B_ERROR;
274 return fSounds[sound - 1]->GetAttributes(attributes, attributeCount);
278 status_t
279 BGameSoundDevice::SetAttributes(gs_id sound, gs_attribute* attributes,
280 size_t attributeCount)
282 if (!fSounds[sound - 1])
283 return B_ERROR;
285 return fSounds[sound - 1]->SetAttributes(attributes, attributeCount);
289 int32
290 BGameSoundDevice::AllocateSound()
292 for (int32 i = 0; i < fSoundCount; i++)
293 if (!fSounds[i])
294 return i;
296 // we need to allocate new space for the sound
297 GameSoundBuffer ** sounds = new GameSoundBuffer*[fSoundCount + kGrowth];
298 for (int32 i = 0; i < fSoundCount; i++)
299 sounds[i] = fSounds[i];
301 for (int32 i = fSoundCount; i < fSoundCount + kGrowth; i++)
302 sounds[i] = NULL;
304 // replace the old list
305 delete [] fSounds;
306 fSounds = sounds;
307 fSoundCount += kGrowth;
309 return fSoundCount - kGrowth;