2002-10-06 15:31:21 +04:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Copyright (c) 2001-2002, OpenBeOS
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
//
|
|
|
|
// File Name: GameSound.cpp
|
|
|
|
// Author: Christopher ML Zumwalt May (zummy@users.sf.net)
|
|
|
|
// Description: BPushGameSound class
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Standard Includes -----------------------------------------------------------
|
2005-11-13 02:27:14 +03:00
|
|
|
#include <string.h>
|
2002-10-06 15:31:21 +04:00
|
|
|
|
|
|
|
// System Includes -------------------------------------------------------------
|
|
|
|
#include <List.h>
|
|
|
|
|
|
|
|
// Project Includes ------------------------------------------------------------
|
|
|
|
#include <GSUtility.h>
|
2002-08-11 04:34:01 +04:00
|
|
|
|
2002-10-06 15:31:21 +04:00
|
|
|
// Local Includes --------------------------------------------------------------
|
2002-08-11 04:34:01 +04:00
|
|
|
#include <PushGameSound.h>
|
|
|
|
|
2002-10-06 15:31:21 +04:00
|
|
|
// Local Defines ---------------------------------------------------------------
|
2002-08-11 04:34:01 +04:00
|
|
|
|
2002-10-06 15:31:21 +04:00
|
|
|
// BPushGameSound --------------------------------------------------------------
|
2002-08-11 04:34:01 +04:00
|
|
|
BPushGameSound::BPushGameSound(size_t inBufferFrameCount,
|
|
|
|
const gs_audio_format *format,
|
|
|
|
size_t inBufferCount,
|
|
|
|
BGameSoundDevice *device)
|
2002-10-06 15:31:21 +04:00
|
|
|
: BStreamingGameSound(inBufferFrameCount, format, inBufferCount, device)
|
2002-08-11 04:34:01 +04:00
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
if (InitCheck() == B_OK)
|
|
|
|
{
|
|
|
|
status_t error = SetParameters(inBufferFrameCount, format, inBufferCount);
|
|
|
|
if (error != B_OK)
|
|
|
|
fPageLocked = new BList;
|
|
|
|
else
|
|
|
|
SetInitError(error);
|
|
|
|
}
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-06 15:31:21 +04:00
|
|
|
BPushGameSound::BPushGameSound(BGameSoundDevice * device)
|
|
|
|
: BStreamingGameSound(device),
|
|
|
|
fLockPos(0),
|
|
|
|
fPlayPos(0),
|
|
|
|
fBuffer(NULL),
|
|
|
|
fPageSize(0),
|
|
|
|
fPageCount(0),
|
|
|
|
fBufferSize(0)
|
|
|
|
{
|
|
|
|
fPageLocked = new BList;
|
|
|
|
}
|
|
|
|
|
2002-08-11 04:34:01 +04:00
|
|
|
BPushGameSound::~BPushGameSound()
|
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
delete [] fBuffer;
|
|
|
|
delete fPageLocked;
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BPushGameSound::lock_status
|
|
|
|
BPushGameSound::LockNextPage(void **out_pagePtr,
|
|
|
|
size_t *out_pageSize)
|
2002-10-06 15:31:21 +04:00
|
|
|
{
|
|
|
|
// the user can not lock every page
|
|
|
|
if (fPageLocked->CountItems() > fPageCount - 3) return lock_failed;
|
|
|
|
|
|
|
|
// the user cann't lock a page being played
|
|
|
|
if (fLockPos < fPlayPos && fLockPos + fPageSize > fPlayPos) return lock_failed;
|
|
|
|
|
|
|
|
// lock the page
|
|
|
|
char * lockPage = &fBuffer[fLockPos];
|
|
|
|
fPageLocked->AddItem(lockPage);
|
|
|
|
|
|
|
|
// move the locker to the next page
|
|
|
|
fLockPos += fPageSize;
|
|
|
|
if (fLockPos > fBufferSize) fLockPos = 0;
|
|
|
|
|
|
|
|
*out_pagePtr = lockPage;
|
|
|
|
*out_pageSize = fPageSize;
|
|
|
|
|
|
|
|
return lock_ok;
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::UnlockPage(void *in_pagePtr)
|
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
return (fPageLocked->RemoveItem(in_pagePtr)) ? B_OK : B_ERROR;
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BPushGameSound::lock_status
|
|
|
|
BPushGameSound::LockForCyclic(void **out_basePtr,
|
|
|
|
size_t *out_size)
|
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
*out_basePtr = fBuffer;
|
|
|
|
*out_size = fBufferSize;
|
|
|
|
return lock_ok;
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::UnlockCyclic()
|
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
return B_OK;
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t
|
|
|
|
BPushGameSound::CurrentPosition()
|
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
return fPlayPos;
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BGameSound *
|
|
|
|
BPushGameSound::Clone() const
|
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
gs_audio_format format = Format();
|
|
|
|
size_t frameSize = get_sample_size(format.format) * format.channel_count;
|
|
|
|
size_t bufferFrameCount = fPageSize / frameSize;
|
|
|
|
|
|
|
|
return new BPushGameSound(bufferFrameCount, &format, fPageCount, Device());
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::Perform(int32 selector,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::SetParameters(size_t inBufferFrameCount,
|
|
|
|
const gs_audio_format *format,
|
|
|
|
size_t inBufferCount)
|
|
|
|
{
|
2002-10-06 15:31:21 +04:00
|
|
|
status_t error = BStreamingGameSound::SetParameters(inBufferFrameCount, format, inBufferCount);
|
|
|
|
if (error != B_OK) return error;
|
|
|
|
|
|
|
|
size_t frameSize = get_sample_size(format->format) * format->channel_count;
|
|
|
|
|
|
|
|
fPageCount = inBufferCount;
|
|
|
|
fPageSize = frameSize * inBufferFrameCount;
|
|
|
|
fBufferSize = fPageSize * fPageCount;
|
|
|
|
|
|
|
|
fBuffer = new char[fBufferSize];
|
|
|
|
|
|
|
|
return B_OK;
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::SetStreamHook(void (*hook)(void * inCookie, void * inBuffer, size_t inByteCount, BStreamingGameSound * me),
|
|
|
|
void * cookie)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
BPushGameSound::FillBuffer(void *inBuffer,
|
|
|
|
size_t inByteCount)
|
2002-10-06 15:31:21 +04:00
|
|
|
{
|
|
|
|
size_t bytes = inByteCount;
|
|
|
|
|
|
|
|
if (BytesReady(&bytes))
|
|
|
|
{
|
|
|
|
if (fPlayPos + bytes > fBufferSize)
|
|
|
|
{
|
|
|
|
size_t remainder = fPlayPos + bytes - fBufferSize;
|
|
|
|
char * buffer = (char*)inBuffer;
|
|
|
|
|
|
|
|
// fill the buffer with the samples left at the end of our buffer
|
|
|
|
memcpy(buffer, &fBuffer[fPlayPos], remainder);
|
|
|
|
fPlayPos = 0;
|
|
|
|
|
|
|
|
// fill the remainder of the buffer by looping to the start
|
|
|
|
// of the buffer if it isn't locked
|
|
|
|
bytes -= remainder;
|
|
|
|
if (BytesReady(&bytes))
|
|
|
|
{
|
|
|
|
memcpy(&buffer[remainder], fBuffer, bytes);
|
|
|
|
fPlayPos += bytes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(inBuffer, &fBuffer[fPlayPos], bytes);
|
|
|
|
fPlayPos += bytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
BStreamingGameSound::FillBuffer(inBuffer, inByteCount);
|
|
|
|
}
|
2002-08-11 04:34:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-06 15:31:21 +04:00
|
|
|
bool
|
|
|
|
BPushGameSound::BytesReady(size_t * bytes)
|
|
|
|
{
|
|
|
|
if (fPageLocked->CountItems() > 0)
|
|
|
|
{
|
|
|
|
size_t start = fPlayPos;
|
|
|
|
size_t ready = fPlayPos;
|
|
|
|
int32 page = int32(start / fPageSize);
|
|
|
|
|
|
|
|
// return if there is nothing to do
|
|
|
|
if (fPageLocked->HasItem(&fBuffer[page * fPageSize])) return false;
|
|
|
|
|
|
|
|
while (ready < *bytes)
|
|
|
|
{
|
|
|
|
ready += fPageSize;
|
|
|
|
page = int32(ready / fPageSize);
|
|
|
|
|
|
|
|
if (fPageLocked->HasItem(&fBuffer[page * fPageSize]))
|
|
|
|
{
|
|
|
|
// we have found a locked page
|
|
|
|
*bytes = ready - start - (ready - page * fPageSize);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// all of the bytes are ready
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-08-11 04:34:01 +04:00
|
|
|
/* unimplemented for protection of the user:
|
|
|
|
*
|
|
|
|
* BPushGameSound::BPushGameSound()
|
|
|
|
* BPushGameSound::BPushGameSound(const BPushGameSound &)
|
|
|
|
* BPushGameSound &BPushGameSound::operator=(const BPushGameSound &)
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_0(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_1(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_2(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_3(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_4(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_5(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_6(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_7(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_8(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_9(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_10(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_11(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_12(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_13(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_14(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_15(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_16(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_17(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_18(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_19(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_20(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_21(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_22(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
BPushGameSound::_Reserved_BPushGameSound_23(int32 arg, ...)
|
|
|
|
{
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|