diff --git a/src/kits/game/GameProducer.cpp b/src/kits/game/GameProducer.cpp index f65fabcca5..0fd42520b1 100644 --- a/src/kits/game/GameProducer.cpp +++ b/src/kits/game/GameProducer.cpp @@ -214,11 +214,15 @@ GameProducer::Connect(status_t error, const media_source& source, const media_de media_node_id id; FindLatencyFor(fOutput.destination, &fLatency, &id); + if (!fBufferGroup) + fBufferSize = fOutput.format.u.raw_audio.buffer_size; + // Have to set it before latency calculating + // Use a dry run to see how long it takes me to fill a buffer of data // The first step to setup the buffer bigtime_t start, produceLatency; - int32 frames = int32(fOutput.format.u.raw_audio.buffer_size / fFrameSize); + int32 frames = int32(fBufferSize / fFrameSize); float* data = new float[frames * 2]; // Second, fill the buffer @@ -243,9 +247,8 @@ GameProducer::Connect(status_t error, const media_source& source, const media_de // Set up the buffer group for our connection, as long as nobody handed us a // buffer group (via SetBufferGroup()) prior to this. if (!fBufferGroup) { - size_t size = fOutput.format.u.raw_audio.buffer_size; int32 count = int32(fLatency / BufferDuration() + 2); - fBufferGroup = new BBufferGroup(size, count); + fBufferGroup = new BBufferGroup(fBufferSize, count); } } @@ -292,12 +295,18 @@ GameProducer::SetBufferGroup(const media_source& for_source, BBufferGroup* newGr if (newGroup != NULL) { // we were given a valid group; just use that one from now on fBufferGroup = newGroup; + + // get buffer length from the first buffer + BBuffer *buffers[1]; + if (newGroup->GetBufferList(1, buffers) != B_OK) + return B_BAD_VALUE; + fBufferSize = buffers[0]->SizeAvailable(); } else { // we were passed a NULL group pointer; that means we construct // our own buffer group to use from now on - size_t size = fOutput.format.u.raw_audio.buffer_size; + fBufferSize = fOutput.format.u.raw_audio.buffer_size; int32 count = int32(fLatency / BufferDuration() + 2); - fBufferGroup = new BBufferGroup(size, count); + fBufferGroup = new BBufferGroup(fBufferSize, count); } return B_OK; @@ -336,7 +345,7 @@ GameProducer::LateNoticeReceived(const media_source& what, bigtime_t how_much, b // The other run modes dictate various strategies for sacrificing data quality // in the interests of timely data delivery. The way *we* do this is to skip // a buffer, which catches us up in time by one buffer duration. - size_t nSamples = fOutput.format.u.raw_audio.buffer_size / fFrameSize; + size_t nSamples = fBufferSize / fFrameSize; fFramesSent += nSamples; } } @@ -460,7 +469,7 @@ GameProducer::HandleEvent(const media_timed_event* event, bigtime_t lateness, bo } // track how much media we've delivered so far - size_t nFrames = fOutput.format.u.raw_audio.buffer_size / fFrameSize; + size_t nFrames = fBufferSize / fFrameSize; fFramesSent += nFrames; // The buffer is on its way; now schedule the next one to go @@ -479,9 +488,9 @@ GameProducer::HandleEvent(const media_timed_event* event, bigtime_t lateness, bo BBuffer* GameProducer::FillNextBuffer(bigtime_t event_time) -{ +{ // get a buffer from our buffer group - BBuffer* buf = fBufferGroup->RequestBuffer(fOutput.format.u.raw_audio.buffer_size, BufferDuration()); + BBuffer* buf = fBufferGroup->RequestBuffer(fBufferSize, BufferDuration()); // if we fail to get a buffer (for example, if the request times out), we skip this // buffer and go on to the next, to avoid locking up the control thread @@ -489,8 +498,8 @@ GameProducer::FillNextBuffer(bigtime_t event_time) return NULL; // we need to discribe the buffer - int64 frames = int64(fOutput.format.u.raw_audio.buffer_size / fFrameSize); - memset(buf->Data(), 0, fOutput.format.u.raw_audio.buffer_size); + int64 frames = int64(fBufferSize / fFrameSize); + memset(buf->Data(), 0, fBufferSize); // now fill the buffer with data, continuing where the last buffer left off fObject->Play(buf->Data(), frames); @@ -498,7 +507,7 @@ GameProducer::FillNextBuffer(bigtime_t event_time) // fill in the buffer header media_header* hdr = buf->Header(); hdr->type = B_MEDIA_RAW_AUDIO; - hdr->size_used = fOutput.format.u.raw_audio.buffer_size; + hdr->size_used = fBufferSize; hdr->time_source = TimeSource()->ID(); bigtime_t stamp; diff --git a/src/kits/game/GameProducer.h b/src/kits/game/GameProducer.h index fd88d962cb..0be7aae083 100644 --- a/src/kits/game/GameProducer.h +++ b/src/kits/game/GameProducer.h @@ -146,6 +146,7 @@ private: size_t fFrameSize; int64 fFramesSent; GameSoundBuffer * fObject; + size_t fBufferSize; }; #endif diff --git a/src/kits/game/GameSoundBuffer.cpp b/src/kits/game/GameSoundBuffer.cpp index ae016d720d..9dcfa94006 100644 --- a/src/kits/game/GameSoundBuffer.cpp +++ b/src/kits/game/GameSoundBuffer.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "GameProducer.h" #include "GameSoundBuffer.h" @@ -271,7 +272,7 @@ GameSoundBuffer::Play(void * data, int64 frames) pan[1] = fPanLeft; char * buffer = new char[fFrameSize * frames]; - + FillBuffer(buffer, frames); switch (fFormat.format) { @@ -533,11 +534,17 @@ SimpleSoundBuffer::FillBuffer(void * data, int64 frames) // StreamingSoundBuffer ------------------------------------------------------ StreamingSoundBuffer::StreamingSoundBuffer(const gs_audio_format * format, - const void * streamHook) + const void * streamHook, size_t inBufferFrameCount, + size_t inBufferCount) : GameSoundBuffer(format), fStreamHook(const_cast(streamHook)) { + if (inBufferFrameCount != 0 && inBufferCount != 0) { + BBufferGroup *bufferGroup = new BBufferGroup(inBufferFrameCount + * fFrameSize, inBufferCount); + fNode->SetBufferGroup(fConnection->source, bufferGroup); + } } @@ -554,4 +561,3 @@ StreamingSoundBuffer::FillBuffer(void * buffer, int64 frames) size_t bytes = fFrameSize * frames; object->FillBuffer(buffer, bytes); } - diff --git a/src/kits/game/GameSoundBuffer.h b/src/kits/game/GameSoundBuffer.h index 3790c0b9a6..3c5d17688f 100644 --- a/src/kits/game/GameSoundBuffer.h +++ b/src/kits/game/GameSoundBuffer.h @@ -65,10 +65,11 @@ protected: size_t fFrameSize; -private: - Connection * fConnection; GameProducer * fNode; + +private: + bool fIsConnected; bool fIsPlaying; @@ -103,7 +104,9 @@ private: class StreamingSoundBuffer : public GameSoundBuffer { public: StreamingSoundBuffer(const gs_audio_format * format, - const void * streamHook); + const void * streamHook, + size_t inBufferFrameCount, + size_t inBufferCount); virtual ~StreamingSoundBuffer(); protected: diff --git a/src/kits/game/GameSoundDevice.cpp b/src/kits/game/GameSoundDevice.cpp index 5431a50415..2a4eed1014 100644 --- a/src/kits/game/GameSoundDevice.cpp +++ b/src/kits/game/GameSoundDevice.cpp @@ -161,7 +161,8 @@ BGameSoundDevice::CreateBuffer(gs_id* sound, const gs_audio_format* format, status_t BGameSoundDevice::CreateBuffer(gs_id* sound, const void* object, - const gs_audio_format* format) + const gs_audio_format* format, size_t inBufferFrameCount, + size_t inBufferCount) { if (!object || !sound) return B_BAD_VALUE; @@ -172,7 +173,8 @@ BGameSoundDevice::CreateBuffer(gs_id* sound, const void* object, if (position >= 0) { media_node systemMixer; BMediaRoster::Roster()->GetAudioMixer(&systemMixer); - fSounds[position] = new StreamingSoundBuffer(format, object); + fSounds[position] = new StreamingSoundBuffer(format, object, + inBufferFrameCount, inBufferCount); err = fSounds[position]->Connect(&systemMixer); } diff --git a/src/kits/game/GameSoundDevice.h b/src/kits/game/GameSoundDevice.h index d388e1c2eb..12323fa369 100644 --- a/src/kits/game/GameSoundDevice.h +++ b/src/kits/game/GameSoundDevice.h @@ -51,7 +51,9 @@ public: int64 frames); virtual status_t CreateBuffer(gs_id * sound, const void * object, - const gs_audio_format * format); + const gs_audio_format * format, + size_t inBufferFrameCount = 0, + size_t inBufferCount = 0); virtual void ReleaseBuffer(gs_id sound); virtual status_t Buffer(gs_id sound, @@ -73,6 +75,7 @@ protected: void SetInitError(status_t error); gs_audio_format fFormat; + private: int32 AllocateSound(); diff --git a/src/kits/game/StreamingGameSound.cpp b/src/kits/game/StreamingGameSound.cpp index bdf7743486..61913aebc2 100644 --- a/src/kits/game/StreamingGameSound.cpp +++ b/src/kits/game/StreamingGameSound.cpp @@ -106,7 +106,8 @@ BStreamingGameSound::SetParameters(size_t inBufferFrameCount, size_t inBufferCount) { gs_id sound; - status_t error = Device()->CreateBuffer(&sound, this, format); + status_t error = Device()->CreateBuffer(&sound, this, format, + inBufferFrameCount, inBufferCount); if (error != B_OK) return error; return BGameSound::Init(sound);