From 6eaf18596da6b2fc964d5bf2b818ce599f9b06aa Mon Sep 17 00:00:00 2001 From: beveloper Date: Mon, 21 Oct 2002 16:53:45 +0000 Subject: [PATCH] updated by Christopher ML Zumwalt May git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1585 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/game/GameSoundBuffer.cpp | 52 ++++++++++------- src/kits/game/GameSoundDevice.cpp | 32 ++++++----- src/kits/game/SimpleGameSound.cpp | 93 +++++++++---------------------- 3 files changed, 74 insertions(+), 103 deletions(-) diff --git a/src/kits/game/GameSoundBuffer.cpp b/src/kits/game/GameSoundBuffer.cpp index 721bd4fa1c..f94a9e8019 100644 --- a/src/kits/game/GameSoundBuffer.cpp +++ b/src/kits/game/GameSoundBuffer.cpp @@ -24,27 +24,20 @@ // Description: Interface to a single sound, managed by the GameSoundDevice. //------------------------------------------------------------------------------ -// Standard Includes ----------------------------------------------------------- #include #include #include -// System Includes ------------------------------------------------------------- -#include #include +#include #include #include -// Project Includes ------------------------------------------------------------ -#include -#include -#include - -// Local Includes -------------------------------------------------------------- -#include -#include - -// Local Defines --------------------------------------------------------------- +#include "GameProducer.h" +#include "GameSoundBuffer.h" +#include "GameSoundDevice.h" +#include "StreamingGameSound.h" +#include "GSUtility.h" // Sound Buffer Utility functions ---------------------------------------- inline void ApplyMod(uint8 * data, uint8 * buffer, int64 index, float gain, float * pan) @@ -94,13 +87,12 @@ GameSoundBuffer::GameSoundBuffer(const gs_audio_format * format) memcpy(&fFormat, format, sizeof(gs_audio_format)); } - +// Play must stop before the distructor is called; otherwise, a fatel +// error occures if the playback is in a subclass. GameSoundBuffer::~GameSoundBuffer() { BMediaRoster* r = BMediaRoster::Roster(); - if (fIsPlaying) r->StopNode(fConnection->producer, 0, true); - if (fIsConnected) { // Ordinarily we'd stop *all* of the nodes in the chain at this point. However, @@ -481,7 +473,9 @@ SimpleSoundBuffer::SimpleSoundBuffer(const gs_audio_format * format, { fBuffer = new char[frames * fFrameSize]; - fBufferSize = frames * fFrameSize; + fBufferSize = frames * fFrameSize; + + memcpy(fBuffer, data, fBufferSize); } @@ -507,12 +501,28 @@ SimpleSoundBuffer::FillBuffer(void * data, int64 frames) if (fPosition + bytes >= fBufferSize) { - size_t remainder = fBufferSize - fPosition; - memcpy(buffer, &fBuffer[fPosition], remainder); + if (fPosition < fBufferSize) + { + // copy the remaining frames + size_t remainder = fBufferSize - fPosition; + memcpy(buffer, &fBuffer[fPosition], remainder); - if (fLooping) memcpy(&buffer[remainder], fBuffer, bytes - remainder); + if (fLooping) + { + // restart the sound from the begging + memcpy(&buffer[remainder], fBuffer, bytes - remainder); + fPosition = bytes - remainder; + } + else fPosition = fBufferSize; + } + else memset(data, 0, bytes); + // there is nothing left to play + } + else + { + memcpy(buffer, &fBuffer[fPosition], bytes); + fPosition += bytes; } - else memcpy(buffer, &fBuffer[fPosition], bytes); } diff --git a/src/kits/game/GameSoundDevice.cpp b/src/kits/game/GameSoundDevice.cpp index 6bc10dbda6..6eab3723d8 100644 --- a/src/kits/game/GameSoundDevice.cpp +++ b/src/kits/game/GameSoundDevice.cpp @@ -26,26 +26,18 @@ // this time. Use at your own risk. //------------------------------------------------------------------------------ -// Standard Includes ----------------------------------------------------------- #include #include -// System Includes ------------------------------------------------------------- #include -#include #include -#include +#include #include +#include -// Project Includes ------------------------------------------------------------ -#include -#include -#include - -// Local Includes -------------------------------------------------------------- -#include - -// Local Defines --------------------------------------------------------------- +#include "GameSoundDevice.h" +#include "GameSoundBuffer.h" +#include "GameProducer.h" // BGameSoundDevice definitions ------------------------------------ const int32 kInitSoundCount = 32; @@ -96,7 +88,10 @@ BGameSoundDevice::~BGameSoundDevice() // We need to stop all the sounds before we stop the mixer for(int32 i = 0; i < fSoundCount; i++) + { + if (fSounds[i]) fSounds[i]->StopPlaying(); delete fSounds[i]; + } if (fIsConnected) { @@ -193,8 +188,15 @@ BGameSoundDevice::CreateBuffer(gs_id * sound, void BGameSoundDevice::ReleaseBuffer(gs_id sound) { - delete fSounds[sound-1]; - fSounds[sound-1] = NULL; + if (fSounds[sound-1]) + { + // We must stop playback befor destroying the sound or else + // we may recieve fatel errors. + fSounds[sound-1]->StopPlaying(); + + delete fSounds[sound-1]; + fSounds[sound-1] = NULL; + } } diff --git a/src/kits/game/SimpleGameSound.cpp b/src/kits/game/SimpleGameSound.cpp index cf3e0c942b..18f8521ed1 100644 --- a/src/kits/game/SimpleGameSound.cpp +++ b/src/kits/game/SimpleGameSound.cpp @@ -25,25 +25,20 @@ // short, and consists of non-changing samples in memory. //------------------------------------------------------------------------------ -// Standard Includes ----------------------------------------------------------- #include #include -// System Includes ------------------------------------------------------------- #include #include #include -// Project Includes ------------------------------------------------------------ -#include -#include +#include "GameSoundDefs.h" +#include "GameSoundBuffer.h" +#include "GameSoundDevice.h" +#include "GSUtility.h" -// Local Includes -------------------------------------------------------------- #include -// Local Defines --------------------------------------------------------------- - -// BSimpleGameSound ------------------------------------------------------------ BSimpleGameSound::BSimpleGameSound(const entry_ref *inFile, BGameSoundDevice *device) : BGameSound(device) @@ -140,13 +135,6 @@ BSimpleGameSound::IsLooping() const return bool(attribute.value); } -status_t -BSimpleGameSound::Perform(int32 selector, - void *data) -{ - return B_ERROR; -} - status_t BSimpleGameSound::Init(const entry_ref* inFile) { @@ -165,14 +153,12 @@ BSimpleGameSound::Init(const entry_ref* inFile) memset(&mformat, 0, sizeof(media_format)); mformat.type = B_MEDIA_RAW_AUDIO; - mformat.u.raw_audio.byte_order = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; - audioStream->DecodedFormat(&mformat); +// mformat.u.raw_audio.byte_order = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; + status_t error = audioStream->DecodedFormat(&mformat); + if (error != B_OK) return error; memset(&gsformat, 0, sizeof(gs_audio_format)); - gsformat.frame_rate = mformat.u.raw_audio.frame_rate; - gsformat.channel_count = mformat.u.raw_audio.channel_count; - gsformat.byte_order = mformat.u.raw_audio.byte_order; - gsformat.buffer_size = mformat.u.raw_audio.buffer_size; + media_to_gs_format(&gsformat, &mformat.u.raw_audio); if (mformat.u.raw_audio.format == media_raw_audio_format::B_AUDIO_CHAR) { @@ -197,62 +183,35 @@ BSimpleGameSound::Init(const entry_ref* inFile) gsformat.format = gs_audio_format::B_GS_U8; - status_t error = Init(data, frames, &gsformat); + error = Init(data, frames, &gsformat); // free the buffers we no longer need delete [] buffer; delete [] data; - - file.ReleaseTrack(audioStream); - return error; } - - // We need to detriman the size, in bytes, of a single sample. - // At the same time, we will store the format of the audio buffer - size_t sampleSize; - switch(mformat.u.raw_audio.format) + else { - case media_raw_audio_format::B_AUDIO_UCHAR: - sampleSize = sizeof(uchar); - gsformat.format = gs_audio_format::B_GS_U8; - break; - - case media_raw_audio_format::B_AUDIO_SHORT: - sampleSize = sizeof(int16); - gsformat.format = gs_audio_format::B_GS_S16; - break; - - case media_raw_audio_format::B_AUDIO_INT: - sampleSize = sizeof(int32); - gsformat.format = gs_audio_format::B_GS_S32; - break; - - case media_raw_audio_format::B_AUDIO_FLOAT: - sampleSize = sizeof(float); - gsformat.format = gs_audio_format::B_GS_F; - break; - - default: return B_ERROR; - } + // We need to detriman the size, in bytes, of a single sample. + // At the same time, we will store the format of the audio buffer + size_t frameSize = get_sample_size(gsformat.format) * gsformat.channel_count; + char * data = new char[frames * frameSize]; + gsformat.buffer_size = frames * frameSize; - - char * data = (char*)malloc(frames * gsformat.channel_count * sampleSize); - gsformat.buffer_size = frames * gsformat.channel_count * sampleSize; - - while(framesTotal < frames) - { - int64 position = framesTotal * gsformat.channel_count * sampleSize; - audioStream->ReadFrames(&data[position], &framesRead); + while(framesTotal < frames) + { + char * position = &data[framesTotal * frameSize]; + audioStream->ReadFrames(position, &framesRead); - framesTotal += framesRead; - } + framesTotal += framesRead; + } - status_t error = Init(data, frames, &gsformat); - - free(data); + error = Init(data, frames, &gsformat); + delete [] data; + } + file.ReleaseTrack(audioStream); - return error; + return error; }