* Added a couple TODOs after reading a bit in the source.

* Introduced a lock in GetDefaultDevice() and ReleaseDevice() as a quick
  solution to the race condition in those functions. It could also use
  proper atomic ref counting. Untested.
* Automatic white space cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31060 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-06-15 15:15:32 +00:00
parent fa00207c50
commit 914fb50397
3 changed files with 122 additions and 101 deletions
+20 -15
View File
@@ -151,8 +151,13 @@ BFileGameSound::BFileGameSound(const char *file,
BFileGameSound::~BFileGameSound() BFileGameSound::~BFileGameSound()
{ {
if (fReadThread >= 0) if (fReadThread >= 0) {
// TODO: kill_thread() is very bad, since it will leak any resources
// that the thread had allocated. It will also keep locks locked that
// the thread holds! Set a flag to make the thread quit and use
// wait_for_thread() here!
kill_thread(fReadThread); kill_thread(fReadThread);
}
if (fAudioStream) { if (fAudioStream) {
if (fAudioStream->stream) if (fAudioStream->stream)
@@ -223,7 +228,7 @@ BFileGameSound::FillBuffer(void *inBuffer,
// fPlayPosition is where we got up to in the input buffer after last call // fPlayPosition is where we got up to in the input buffer after last call
size_t out_offset = 0; size_t out_offset = 0;
while (inByteCount > 0 && !fPaused) { while (inByteCount > 0 && !fPaused) {
if (!fPaused || fPausing) { if (!fPaused || fPausing) {
printf("mixout %ld, inByteCount %ld, decin %ld, BufferSize %ld\n",out_offset, inByteCount, fPlayPosition, fBufferSize); printf("mixout %ld, inByteCount %ld, decin %ld, BufferSize %ld\n",out_offset, inByteCount, fPlayPosition, fBufferSize);
@@ -233,14 +238,14 @@ BFileGameSound::FillBuffer(void *inBuffer,
if (fPausing) { if (fPausing) {
Lock(); Lock();
bool rampDone = false; bool rampDone = false;
size_t bytes = fBufferSize - fPlayPosition; size_t bytes = fBufferSize - fPlayPosition;
if (bytes > inByteCount) { if (bytes > inByteCount) {
bytes = inByteCount; bytes = inByteCount;
} }
// Fill the requested buffer, stopping if the paused flag is set // Fill the requested buffer, stopping if the paused flag is set
char * buffer = (char*)inBuffer; char * buffer = (char*)inBuffer;
@@ -248,24 +253,24 @@ BFileGameSound::FillBuffer(void *inBuffer,
case gs_audio_format::B_GS_U8: case gs_audio_format::B_GS_U8:
rampDone = ::FillBuffer(fPausing, (uint8*)&buffer[out_offset], (uint8*)&fBuffer[fPlayPosition], &bytes); rampDone = ::FillBuffer(fPausing, (uint8*)&buffer[out_offset], (uint8*)&fBuffer[fPlayPosition], &bytes);
break; break;
case gs_audio_format::B_GS_S16: case gs_audio_format::B_GS_S16:
rampDone = ::FillBuffer(fPausing, (int16*)&buffer[out_offset], (int16*)&fBuffer[fPlayPosition], &bytes); rampDone = ::FillBuffer(fPausing, (int16*)&buffer[out_offset], (int16*)&fBuffer[fPlayPosition], &bytes);
break; break;
case gs_audio_format::B_GS_S32: case gs_audio_format::B_GS_S32:
rampDone = ::FillBuffer(fPausing, (int32*)&buffer[out_offset], (int32*)&fBuffer[fPlayPosition], &bytes); rampDone = ::FillBuffer(fPausing, (int32*)&buffer[out_offset], (int32*)&fBuffer[fPlayPosition], &bytes);
break; break;
case gs_audio_format::B_GS_F: case gs_audio_format::B_GS_F:
rampDone = ::FillBuffer(fPausing, (float*)&buffer[out_offset], (float*)&fBuffer[fPlayPosition], &bytes); rampDone = ::FillBuffer(fPausing, (float*)&buffer[out_offset], (float*)&fBuffer[fPlayPosition], &bytes);
break; break;
} }
inByteCount -= bytes; inByteCount -= bytes;
out_offset += bytes; out_offset += bytes;
fPlayPosition += bytes; fPlayPosition += bytes;
// We finished ramping // We finished ramping
if (rampDone) { if (rampDone) {
@@ -274,14 +279,14 @@ BFileGameSound::FillBuffer(void *inBuffer,
buffer[out_offset++] = fBuffer[fPlayPosition++]; buffer[out_offset++] = fBuffer[fPlayPosition++];
inByteCount--; inByteCount--;
} }
delete fPausing; delete fPausing;
fPausing = NULL; fPausing = NULL;
} }
Unlock(); Unlock();
} else { } else {
char * buffer = (char*)inBuffer; char * buffer = (char*)inBuffer;
// We need to be able to stop asap when the pause flag is flipped. // We need to be able to stop asap when the pause flag is flipped.
@@ -410,7 +415,7 @@ BFileGameSound::Load()
fAudioStream->stream->ReadFrames(fBuffer, &frames); fAudioStream->stream->ReadFrames(fBuffer, &frames);
fBufferSize = frames * fFrameSize; fBufferSize = frames * fFrameSize;
fPlayPosition = 0; fPlayPosition = 0;
if (fBufferSize <= 0) { if (fBufferSize <= 0) {
// EOF // EOF
if (fLooping) { if (fLooping) {
@@ -421,7 +426,7 @@ BFileGameSound::Load()
StopPlaying(); StopPlaying();
} }
} }
return true; return true;
} }
+29 -20
View File
@@ -1,8 +1,8 @@
/* /*
* Copyright 2001-2002, Haiku Inc. * Copyright 2001-2002, Haiku Inc.
* Authors: * Authors:
* Christopher ML Zumwalt May ([email protected]) * Christopher ML Zumwalt May ([email protected])
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -23,6 +23,9 @@ using std::nothrow;
BGameSound::BGameSound(BGameSoundDevice *device) BGameSound::BGameSound(BGameSoundDevice *device)
: fSound(-1) : fSound(-1)
{ {
// TODO: device is ignored!
// NOTE: BeBook documents that BGameSoundDevice must currently always
// be NULL...
fDevice = GetDefaultDevice(); fDevice = GetDefaultDevice();
fInitError = fDevice->InitCheck(); fInitError = fDevice->InitCheck();
} }
@@ -32,9 +35,10 @@ BGameSound::BGameSound(const BGameSound &other)
: fSound(-1) : fSound(-1)
{ {
memcpy(&fFormat, &other.fFormat, sizeof(gs_audio_format)); memcpy(&fFormat, &other.fFormat, sizeof(gs_audio_format));
// TODO: device from other is ignored!
fDevice = GetDefaultDevice(); fDevice = GetDefaultDevice();
fInitError = fDevice->InitCheck(); fInitError = fDevice->InitCheck();
} }
@@ -42,7 +46,7 @@ BGameSound::~BGameSound()
{ {
if (fSound >= 0) if (fSound >= 0)
fDevice->ReleaseBuffer(fSound); fDevice->ReleaseBuffer(fSound);
ReleaseDevice(); ReleaseDevice();
} }
@@ -57,6 +61,7 @@ BGameSound::InitCheck() const
BGameSoundDevice * BGameSoundDevice *
BGameSound::Device() const BGameSound::Device() const
{ {
// TODO: Must return NULL if default device is being used!
return fDevice; return fDevice;
} }
@@ -64,6 +69,8 @@ BGameSound::Device() const
gs_id gs_id
BGameSound::ID() const BGameSound::ID() const
{ {
// TODO: Should be 0 if no sound has been selected! But fSound
// is initialized with -1 in the constructors.
return fSound; return fSound;
} }
@@ -103,13 +110,13 @@ BGameSound::SetGain(float gain,
bigtime_t duration) bigtime_t duration)
{ {
gs_attribute attribute; gs_attribute attribute;
attribute.attribute = B_GS_GAIN; attribute.attribute = B_GS_GAIN;
attribute.value = gain; attribute.value = gain;
attribute.duration = duration; attribute.duration = duration;
attribute.flags = 0; attribute.flags = 0;
return fDevice->SetAttributes(fSound, &attribute, 1); return fDevice->SetAttributes(fSound, &attribute, 1);
} }
@@ -118,12 +125,12 @@ BGameSound::SetPan(float pan,
bigtime_t duration) bigtime_t duration)
{ {
gs_attribute attribute; gs_attribute attribute;
attribute.attribute = B_GS_PAN; attribute.attribute = B_GS_PAN;
attribute.value = pan; attribute.value = pan;
attribute.duration = duration; attribute.duration = duration;
attribute.flags = 0; attribute.flags = 0;
return fDevice->SetAttributes(fSound, &attribute, 1); return fDevice->SetAttributes(fSound, &attribute, 1);
} }
@@ -132,13 +139,13 @@ float
BGameSound::Gain() BGameSound::Gain()
{ {
gs_attribute attribute; gs_attribute attribute;
attribute.attribute = B_GS_GAIN; attribute.attribute = B_GS_GAIN;
attribute.flags = 0; attribute.flags = 0;
if (fDevice->GetAttributes(fSound, &attribute, 1) != B_OK) if (fDevice->GetAttributes(fSound, &attribute, 1) != B_OK)
return 0.0; return 0.0;
return attribute.value; return attribute.value;
} }
@@ -147,13 +154,13 @@ float
BGameSound::Pan() BGameSound::Pan()
{ {
gs_attribute attribute; gs_attribute attribute;
attribute.attribute = B_GS_PAN; attribute.attribute = B_GS_PAN;
attribute.flags = 0; attribute.flags = 0;
if (fDevice->GetAttributes(fSound, &attribute, 1) != B_OK) if (fDevice->GetAttributes(fSound, &attribute, 1) != B_OK)
return 0.0; return 0.0;
return attribute.value; return attribute.value;
} }
@@ -247,7 +254,7 @@ BGameSound::Init(gs_id handle)
{ {
if (fSound < 0) if (fSound < 0)
fSound = handle; fSound = handle;
return B_OK; return B_OK;
} }
@@ -257,10 +264,12 @@ BGameSound::operator=(const BGameSound &other)
{ {
if (fSound) if (fSound)
fDevice->ReleaseBuffer(fSound); fDevice->ReleaseBuffer(fSound);
fSound = other.fSound; fSound = other.fSound;
fInitError = other.fInitError; fInitError = other.fInitError;
// TODO: This would need to acquire the sound another time!
return this; return this;
} }
*/ */
@@ -269,7 +278,7 @@ BGameSound::operator=(const BGameSound &other)
* *
* BGameSound::BGameSound() * BGameSound::BGameSound()
*/ */
status_t status_t
BGameSound::_Reserved_BGameSound_0(int32 arg, ...) BGameSound::_Reserved_BGameSound_0(int32 arg, ...)
+73 -66
View File
@@ -22,7 +22,7 @@
// File Name: BGameSoundDevice.cpp // File Name: BGameSoundDevice.cpp
// Author: Christopher ML Zumwalt May ([email protected]) // Author: Christopher ML Zumwalt May ([email protected])
// Description: Manages the game producer. The class may change with out // Description: Manages the game producer. The class may change with out
// notice and was only inteneded for use by the GameKit at // notice and was only inteneded for use by the GameKit at
// this time. Use at your own risk. // this time. Use at your own risk.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -30,7 +30,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <Autolock.h>
#include <List.h> #include <List.h>
#include <Locker.h>
#include <MediaRoster.h> #include <MediaRoster.h>
#include <MediaAddOn.h> #include <MediaAddOn.h>
#include <TimeSource.h> #include <TimeSource.h>
@@ -47,14 +49,17 @@ const int32 kGrowth = 16;
static int32 sDeviceCount = 0; static int32 sDeviceCount = 0;
static BGameSoundDevice* sDevice = NULL; static BGameSoundDevice* sDevice = NULL;
static BLocker sDeviceRefCountLock = BLocker("GameSound device lock");
BGameSoundDevice * BGameSoundDevice *
GetDefaultDevice() GetDefaultDevice()
{ {
BAutolock _(sDeviceRefCountLock);
if (!sDevice) if (!sDevice)
sDevice = new BGameSoundDevice(); sDevice = new BGameSoundDevice();
sDeviceCount++; sDeviceCount++;
return sDevice; return sDevice;
} }
@@ -63,8 +68,10 @@ GetDefaultDevice()
void void
ReleaseDevice() ReleaseDevice()
{ {
BAutolock _(sDeviceRefCountLock);
sDeviceCount--; sDeviceCount--;
if (sDeviceCount <= 0) { if (sDeviceCount <= 0) {
delete sDevice; delete sDevice;
sDevice = NULL; sDevice = NULL;
@@ -79,12 +86,12 @@ BGameSoundDevice::BGameSoundDevice()
{ {
fConnection = new Connection; fConnection = new Connection;
memset(&fFormat, 0, sizeof(gs_audio_format)); memset(&fFormat, 0, sizeof(gs_audio_format));
fInitError = Connect(); fInitError = Connect();
fSounds = new GameSoundBuffer*[kInitSoundCount]; fSounds = new GameSoundBuffer*[kInitSoundCount];
for (int32 i = 0; i < kInitSoundCount; i++) for (int32 i = 0; i < kInitSoundCount; i++)
fSounds[i] = NULL; fSounds[i] = NULL;
} }
@@ -98,23 +105,23 @@ BGameSoundDevice::~BGameSoundDevice()
fSounds[i]->StopPlaying(); fSounds[i]->StopPlaying();
delete fSounds[i]; delete fSounds[i];
} }
if (fIsConnected) { if (fIsConnected) {
// stop the nodes if they are running // stop the nodes if they are running
roster->StopNode(fConnection->producer, 0, true); roster->StopNode(fConnection->producer, 0, true);
// synchronous stop // synchronous stop
// Ordinarily we'd stop *all* of the nodes in the chain at this point. However, // Ordinarily we'd stop *all* of the nodes in the chain at this point. However,
// one of the nodes is the System Mixer, and stopping the Mixer is a Bad Idea (tm). // one of the nodes is the System Mixer, and stopping the Mixer is a Bad Idea (tm).
// So, we just disconnect from it, and release our references to the nodes that // So, we just disconnect from it, and release our references to the nodes that
// we're using. We *are* supposed to do that even for global nodes like the Mixer. // we're using. We *are* supposed to do that even for global nodes like the Mixer.
roster->Disconnect(fConnection->producer.node, fConnection->source, roster->Disconnect(fConnection->producer.node, fConnection->source,
fConnection->consumer.node, fConnection->destination); fConnection->consumer.node, fConnection->destination);
roster->ReleaseNode(fConnection->producer); roster->ReleaseNode(fConnection->producer);
roster->ReleaseNode(fConnection->consumer); roster->ReleaseNode(fConnection->consumer);
} }
delete[] fSounds; delete[] fSounds;
delete fConnection; delete fConnection;
} }
@@ -154,20 +161,20 @@ BGameSoundDevice::CreateBuffer(gs_id * sound,
const void * data, const void * data,
int64 frames) int64 frames)
{ {
if (frames <= 0 || !sound) if (frames <= 0 || !sound)
return B_BAD_VALUE; return B_BAD_VALUE;
status_t err = B_MEDIA_TOO_MANY_BUFFERS; status_t err = B_MEDIA_TOO_MANY_BUFFERS;
int32 position = AllocateSound(); int32 position = AllocateSound();
if (position >= 0) { if (position >= 0) {
fSounds[position] = new SimpleSoundBuffer(format, data, frames); fSounds[position] = new SimpleSoundBuffer(format, data, frames);
err = fSounds[position]->Connect(&fConnection->producer); err = fSounds[position]->Connect(&fConnection->producer);
} }
if (err == B_OK) if (err == B_OK)
*sound = gs_id(position + 1); *sound = gs_id(position + 1);
return err; return err;
} }
@@ -176,20 +183,20 @@ BGameSoundDevice::CreateBuffer(gs_id * sound,
const void * object, const void * object,
const gs_audio_format * format) const gs_audio_format * format)
{ {
if (!object || !sound) if (!object || !sound)
return B_BAD_VALUE; return B_BAD_VALUE;
status_t err = B_MEDIA_TOO_MANY_BUFFERS; status_t err = B_MEDIA_TOO_MANY_BUFFERS;
int32 position = AllocateSound(); int32 position = AllocateSound();
if (position >= 0) { if (position >= 0) {
fSounds[position] = new StreamingSoundBuffer(format, object); fSounds[position] = new StreamingSoundBuffer(format, object);
err = fSounds[position]->Connect(&fConnection->producer); err = fSounds[position]->Connect(&fConnection->producer);
} }
if (err == B_OK) if (err == B_OK)
*sound = gs_id(position+1); *sound = gs_id(position+1);
return err; return err;
} }
@@ -203,12 +210,12 @@ BGameSoundDevice::ReleaseBuffer(gs_id sound)
// We must stop playback befor destroying the sound or else // We must stop playback befor destroying the sound or else
// we may recieve fatel errors. // we may recieve fatel errors.
fSounds[sound - 1]->StopPlaying(); fSounds[sound - 1]->StopPlaying();
delete fSounds[sound - 1]; delete fSounds[sound - 1];
fSounds[sound - 1] = NULL; fSounds[sound - 1] = NULL;
} }
} }
status_t status_t
BGameSoundDevice::Buffer(gs_id sound, gs_audio_format* format, void *& data) BGameSoundDevice::Buffer(gs_id sound, gs_audio_format* format, void *& data)
@@ -222,8 +229,8 @@ BGameSoundDevice::Buffer(gs_id sound, gs_audio_format* format, void *& data)
memcpy(data, fSounds[sound-1]->Data(), format->buffer_size); memcpy(data, fSounds[sound-1]->Data(), format->buffer_size);
} else } else
data = NULL; data = NULL;
return B_OK; return B_OK;
} }
@@ -232,12 +239,12 @@ BGameSoundDevice::StartPlaying(gs_id sound)
{ {
if (sound <= 0) if (sound <= 0)
return B_BAD_VALUE; return B_BAD_VALUE;
if (!fSounds[sound - 1]->IsPlaying()) { if (!fSounds[sound - 1]->IsPlaying()) {
// tell the producer to start playing the sound // tell the producer to start playing the sound
return fSounds[sound - 1]->StartPlaying(); return fSounds[sound - 1]->StartPlaying();
} }
fSounds[sound - 1]->Reset(); fSounds[sound - 1]->Reset();
return EALREADY; return EALREADY;
} }
@@ -248,13 +255,13 @@ BGameSoundDevice::StopPlaying(gs_id sound)
{ {
if (sound <= 0) if (sound <= 0)
return B_BAD_VALUE; return B_BAD_VALUE;
if (fSounds[sound - 1]->IsPlaying()) { if (fSounds[sound - 1]->IsPlaying()) {
// Tell the producer to stop play this sound // Tell the producer to stop play this sound
fSounds[sound - 1]->Reset(); fSounds[sound - 1]->Reset();
return fSounds[sound - 1]->StopPlaying(); return fSounds[sound - 1]->StopPlaying();
} }
return EALREADY; return EALREADY;
} }
@@ -265,7 +272,7 @@ BGameSoundDevice::IsPlaying(gs_id sound)
if (sound <= 0) if (sound <= 0)
return false; return false;
return fSounds[sound - 1]->IsPlaying(); return fSounds[sound - 1]->IsPlaying();
} }
status_t status_t
@@ -273,76 +280,76 @@ BGameSoundDevice::GetAttributes(gs_id sound,
gs_attribute * attributes, gs_attribute * attributes,
size_t attributeCount) size_t attributeCount)
{ {
if (!fSounds[sound - 1]) if (!fSounds[sound - 1])
return B_ERROR; return B_ERROR;
return fSounds[sound - 1]->GetAttributes(attributes, attributeCount); return fSounds[sound - 1]->GetAttributes(attributes, attributeCount);
} }
status_t status_t
BGameSoundDevice::SetAttributes(gs_id sound, BGameSoundDevice::SetAttributes(gs_id sound,
gs_attribute * attributes, gs_attribute * attributes,
size_t attributeCount) size_t attributeCount)
{ {
if (!fSounds[sound - 1]) if (!fSounds[sound - 1])
return B_ERROR; return B_ERROR;
return fSounds[sound - 1]->SetAttributes(attributes, attributeCount); return fSounds[sound - 1]->SetAttributes(attributes, attributeCount);
} }
status_t status_t
BGameSoundDevice::Connect() BGameSoundDevice::Connect()
{ {
BMediaRoster* roster = BMediaRoster::Roster(); BMediaRoster* roster = BMediaRoster::Roster();
// create your own audio mixer // create your own audio mixer
// TODO: Don't do this!!! See bug #575 // TODO: Don't do this!!! See bug #575
dormant_node_info mixer_dormant_info; dormant_node_info mixer_dormant_info;
int32 mixer_count = 1; // for now, we only care about the first we find. int32 mixer_count = 1; // for now, we only care about the first we find.
status_t err = roster->GetDormantNodes(&mixer_dormant_info, status_t err = roster->GetDormantNodes(&mixer_dormant_info,
&mixer_count, 0, 0, 0, B_SYSTEM_MIXER, 0); &mixer_count, 0, 0, 0, B_SYSTEM_MIXER, 0);
if (err != B_OK) if (err != B_OK)
return err; return err;
//fMixer = new media_node; //fMixer = new media_node;
err = roster->InstantiateDormantNode(mixer_dormant_info, &fConnection->producer); err = roster->InstantiateDormantNode(mixer_dormant_info, &fConnection->producer);
if (err != B_OK) if (err != B_OK)
return err; return err;
// retieve the system's audio mixer // retieve the system's audio mixer
err = roster->GetAudioMixer(&fConnection->consumer); err = roster->GetAudioMixer(&fConnection->consumer);
if (err != B_OK) if (err != B_OK)
return err; return err;
int32 count = 1; int32 count = 1;
media_input mixerInput; media_input mixerInput;
err = roster->GetFreeInputsFor(fConnection->consumer, &mixerInput, 1, &count); err = roster->GetFreeInputsFor(fConnection->consumer, &mixerInput, 1, &count);
if (err != B_OK) if (err != B_OK)
return err; return err;
count = 1; count = 1;
media_output mixerOutput; media_output mixerOutput;
err = roster->GetFreeOutputsFor(fConnection->producer, &mixerOutput, 1, &count); err = roster->GetFreeOutputsFor(fConnection->producer, &mixerOutput, 1, &count);
if (err != B_OK) if (err != B_OK)
return err; return err;
media_format format(mixerOutput.format); media_format format(mixerOutput.format);
err = roster->Connect(mixerOutput.source, mixerInput.destination, err = roster->Connect(mixerOutput.source, mixerInput.destination,
&format, &mixerOutput, &mixerInput); &format, &mixerOutput, &mixerInput);
if (err != B_OK) if (err != B_OK)
return err; return err;
// set the producer's time source to be the "default" time source, which // set the producer's time source to be the "default" time source, which
// the Mixer uses too. // the Mixer uses too.
roster->GetTimeSource(&fConnection->timeSource); roster->GetTimeSource(&fConnection->timeSource);
roster->SetTimeSourceFor(fConnection->producer.node, fConnection->timeSource.node); roster->SetTimeSourceFor(fConnection->producer.node, fConnection->timeSource.node);
// Start our mixer's time source if need be. Chances are, it won't need to be, // Start our mixer's time source if need be. Chances are, it won't need to be,
// but if we forget to do this, our mixer might not do anything at all. // but if we forget to do this, our mixer might not do anything at all.
BTimeSource* mixerTimeSource = roster->MakeTimeSourceFor(fConnection->producer); BTimeSource* mixerTimeSource = roster->MakeTimeSourceFor(fConnection->producer);
if (!mixerTimeSource) if (!mixerTimeSource)
return B_ERROR; return B_ERROR;
if (!mixerTimeSource->IsRunning()) { if (!mixerTimeSource->IsRunning()) {
@@ -357,9 +364,9 @@ BGameSoundDevice::Connect()
bigtime_t tpNow = mixerTimeSource->Now(); bigtime_t tpNow = mixerTimeSource->Now();
err = roster->StartNode(fConnection->producer, tpNow + 10000); err = roster->StartNode(fConnection->producer, tpNow + 10000);
mixerTimeSource->Release(); mixerTimeSource->Release();
if (err != B_OK) if (err != B_OK)
return err; return err;
// the inputs and outputs might have been reassigned during the // the inputs and outputs might have been reassigned during the
// nodes' negotiation of the Connect(). That's why we wait until // nodes' negotiation of the Connect(). That's why we wait until
// after Connect() finishes to save their contents. // after Connect() finishes to save their contents.
@@ -382,20 +389,20 @@ BGameSoundDevice::AllocateSound()
for (int32 i = 0; i < fSoundCount; i++) for (int32 i = 0; i < fSoundCount; i++)
if (!fSounds[i]) if (!fSounds[i])
return i; return i;
// we need to allocate new space for the sound // we need to allocate new space for the sound
GameSoundBuffer ** sounds = new GameSoundBuffer*[fSoundCount + kGrowth]; GameSoundBuffer ** sounds = new GameSoundBuffer*[fSoundCount + kGrowth];
for (int32 i = 0; i < fSoundCount; i++) for (int32 i = 0; i < fSoundCount; i++)
sounds[i] = fSounds[i]; sounds[i] = fSounds[i];
for (int32 i = fSoundCount; i < fSoundCount + kGrowth; i++) for (int32 i = fSoundCount; i < fSoundCount + kGrowth; i++)
sounds[i] = NULL; sounds[i] = NULL;
// replace the old list // replace the old list
delete [] fSounds; delete [] fSounds;
fSounds = sounds; fSounds = sounds;
fSoundCount += kGrowth; fSoundCount += kGrowth;
return fSoundCount - kGrowth; return fSoundCount - kGrowth;
} }