1 //------------------------------------------------------------------------------
2 // Copyright (c) 2001-2002, OpenBeOS
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"
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
= BLocker("GameSound device lock");
61 BAutolock
_(sDeviceRefCountLock
);
64 sDevice
= new BGameSoundDevice();
74 BAutolock
_(sDeviceRefCountLock
);
78 if (sDeviceCount
<= 0) {
85 // BGameSoundDevice -------------------------------------------------------
86 BGameSoundDevice::BGameSoundDevice()
89 fSoundCount(kInitSoundCount
)
91 memset(&fFormat
, 0, sizeof(gs_audio_format
));
95 fSounds
= new GameSoundBuffer
*[kInitSoundCount
];
96 for (int32 i
= 0; i
< kInitSoundCount
; i
++)
101 BGameSoundDevice::~BGameSoundDevice()
103 // We need to stop all the sounds before we stop the mixer
104 for (int32 i
= 0; i
< fSoundCount
; i
++) {
106 fSounds
[i
]->StopPlaying();
115 BGameSoundDevice::InitCheck() const
121 const gs_audio_format
&
122 BGameSoundDevice::Format() const
128 const gs_audio_format
&
129 BGameSoundDevice::Format(gs_id sound
) const
131 return fSounds
[sound
- 1]->Format();
136 BGameSoundDevice::SetInitError(status_t error
)
143 BGameSoundDevice::CreateBuffer(gs_id
* sound
, const gs_audio_format
* format
,
144 const void* data
, int64 frames
)
146 if (frames
<= 0 || !sound
)
149 status_t err
= B_MEDIA_TOO_MANY_BUFFERS
;
150 int32 position
= AllocateSound();
153 fSounds
[position
] = new SimpleSoundBuffer(format
, data
, frames
);
155 media_node systemMixer
;
156 BMediaRoster::Roster()->GetAudioMixer(&systemMixer
);
157 err
= fSounds
[position
]->Connect(&systemMixer
);
161 *sound
= gs_id(position
+ 1);
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
)
174 status_t err
= B_MEDIA_TOO_MANY_BUFFERS
;
175 int32 position
= AllocateSound();
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
);
187 *sound
= gs_id(position
+ 1);
193 BGameSoundDevice::ReleaseBuffer(gs_id sound
)
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
;
210 BGameSoundDevice::Buffer(gs_id sound
, gs_audio_format
* format
, void*& data
)
212 if (!format
|| sound
<= 0)
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
);
227 BGameSoundDevice::StartPlaying(gs_id sound
)
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();
243 BGameSoundDevice::StopPlaying(gs_id sound
)
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();
259 BGameSoundDevice::IsPlaying(gs_id sound
)
263 return fSounds
[sound
- 1]->IsPlaying();
268 BGameSoundDevice::GetAttributes(gs_id sound
, gs_attribute
* attributes
,
269 size_t attributeCount
)
271 if (!fSounds
[sound
- 1])
274 return fSounds
[sound
- 1]->GetAttributes(attributes
, attributeCount
);
279 BGameSoundDevice::SetAttributes(gs_id sound
, gs_attribute
* attributes
,
280 size_t attributeCount
)
282 if (!fSounds
[sound
- 1])
285 return fSounds
[sound
- 1]->SetAttributes(attributes
, attributeCount
);
290 BGameSoundDevice::AllocateSound()
292 for (int32 i
= 0; i
< fSoundCount
; 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
++)
304 // replace the old list
307 fSoundCount
+= kGrowth
;
309 return fSoundCount
- kGrowth
;