1ea4f253fSJérôme Duval /*
22066acfbSAlexander von Gluck IV * Copyright 2001-2012 Haiku, Inc. All Rights Reserved.
32066acfbSAlexander von Gluck IV * Distributed under the terms of the MIT License.
42066acfbSAlexander von Gluck IV *
5ea4f253fSJérôme Duval * Authors:
6ea4f253fSJérôme Duval * Christopher ML Zumwalt May (zummy@users.sf.net)
7ea4f253fSJérôme Duval * Jérôme Duval
8ea4f253fSJérôme Duval */
90b4a36abSbeveloper
102066acfbSAlexander von Gluck IV
112066acfbSAlexander von Gluck IV #include <PushGameSound.h>
124703fb5dSbeveloper
134703fb5dSbeveloper #include <List.h>
142066acfbSAlexander von Gluck IV #include <string.h>
150b4a36abSbeveloper
160c93c0a8SJérôme Duval #include "GSUtility.h"
170b4a36abSbeveloper
180c93c0a8SJérôme Duval
BPushGameSound(size_t inBufferFrameCount,const gs_audio_format * format,size_t inBufferCount,BGameSoundDevice * device)190044a8c3SAdrien Destugues BPushGameSound::BPushGameSound(size_t inBufferFrameCount,
200044a8c3SAdrien Destugues const gs_audio_format *format, size_t inBufferCount,
210044a8c3SAdrien Destugues BGameSoundDevice *device)
220044a8c3SAdrien Destugues :
230044a8c3SAdrien Destugues BStreamingGameSound(inBufferFrameCount, format, inBufferCount, device),
240044a8c3SAdrien Destugues fLockPos(0),
250044a8c3SAdrien Destugues fPlayPos(0)
260b4a36abSbeveloper {
274703fb5dSbeveloper fPageLocked = new BList;
28ea4f253fSJérôme Duval
29ea4f253fSJérôme Duval size_t frameSize = get_sample_size(format->format) * format->channel_count;
30ea4f253fSJérôme Duval
31ea4f253fSJérôme Duval fPageCount = inBufferCount;
32ea4f253fSJérôme Duval fPageSize = frameSize * inBufferFrameCount;
33ea4f253fSJérôme Duval fBufferSize = fPageSize * fPageCount;
34ea4f253fSJérôme Duval
35ea4f253fSJérôme Duval fBuffer = new char[fBufferSize];
364703fb5dSbeveloper }
370b4a36abSbeveloper
380b4a36abSbeveloper
BPushGameSound(BGameSoundDevice * device)394703fb5dSbeveloper BPushGameSound::BPushGameSound(BGameSoundDevice * device)
404703fb5dSbeveloper : BStreamingGameSound(device),
414703fb5dSbeveloper fLockPos(0),
424703fb5dSbeveloper fPlayPos(0),
434703fb5dSbeveloper fBuffer(NULL),
444703fb5dSbeveloper fPageSize(0),
454703fb5dSbeveloper fPageCount(0),
464703fb5dSbeveloper fBufferSize(0)
474703fb5dSbeveloper {
484703fb5dSbeveloper fPageLocked = new BList;
494703fb5dSbeveloper }
504703fb5dSbeveloper
51ea4f253fSJérôme Duval
~BPushGameSound()520b4a36abSbeveloper BPushGameSound::~BPushGameSound()
530b4a36abSbeveloper {
544703fb5dSbeveloper delete [] fBuffer;
554703fb5dSbeveloper delete fPageLocked;
560b4a36abSbeveloper }
570b4a36abSbeveloper
580b4a36abSbeveloper
590b4a36abSbeveloper BPushGameSound::lock_status
LockNextPage(void ** out_pagePtr,size_t * out_pageSize)60c7509fceSJérôme Duval BPushGameSound::LockNextPage(void **out_pagePtr, size_t *out_pageSize)
610b4a36abSbeveloper {
624703fb5dSbeveloper // the user can not lock every page
63*93e30a47SAdrien Destugues - PulkoMandy if (fPageLocked->CountItems() > fPageCount - 1)
64c7509fceSJérôme Duval return lock_failed;
654703fb5dSbeveloper
66*93e30a47SAdrien Destugues - PulkoMandy // the user can't lock a page being played
67c7509fceSJérôme Duval if (fLockPos < fPlayPos
68c7509fceSJérôme Duval && fLockPos + fPageSize > fPlayPos)
69c7509fceSJérôme Duval return lock_failed;
704703fb5dSbeveloper
714703fb5dSbeveloper // lock the page
724703fb5dSbeveloper char * lockPage = &fBuffer[fLockPos];
734703fb5dSbeveloper fPageLocked->AddItem(lockPage);
744703fb5dSbeveloper
754703fb5dSbeveloper // move the locker to the next page
764703fb5dSbeveloper fLockPos += fPageSize;
77*93e30a47SAdrien Destugues - PulkoMandy if (fLockPos >= fBufferSize)
78c7509fceSJérôme Duval fLockPos = 0;
794703fb5dSbeveloper
804703fb5dSbeveloper *out_pagePtr = lockPage;
814703fb5dSbeveloper *out_pageSize = fPageSize;
824703fb5dSbeveloper
834703fb5dSbeveloper return lock_ok;
840b4a36abSbeveloper }
850b4a36abSbeveloper
860b4a36abSbeveloper
870b4a36abSbeveloper status_t
UnlockPage(void * in_pagePtr)880b4a36abSbeveloper BPushGameSound::UnlockPage(void *in_pagePtr)
890b4a36abSbeveloper {
904703fb5dSbeveloper return (fPageLocked->RemoveItem(in_pagePtr)) ? B_OK : B_ERROR;
910b4a36abSbeveloper }
920b4a36abSbeveloper
930b4a36abSbeveloper
940b4a36abSbeveloper BPushGameSound::lock_status
LockForCyclic(void ** out_basePtr,size_t * out_size)95c7509fceSJérôme Duval BPushGameSound::LockForCyclic(void **out_basePtr, size_t *out_size)
960b4a36abSbeveloper {
974703fb5dSbeveloper *out_basePtr = fBuffer;
984703fb5dSbeveloper *out_size = fBufferSize;
994703fb5dSbeveloper return lock_ok;
1000b4a36abSbeveloper }
1010b4a36abSbeveloper
1020b4a36abSbeveloper
1030b4a36abSbeveloper status_t
UnlockCyclic()1040b4a36abSbeveloper BPushGameSound::UnlockCyclic()
1050b4a36abSbeveloper {
1064703fb5dSbeveloper return B_OK;
1070b4a36abSbeveloper }
1080b4a36abSbeveloper
1090b4a36abSbeveloper
1100b4a36abSbeveloper size_t
CurrentPosition()1110b4a36abSbeveloper BPushGameSound::CurrentPosition()
1120b4a36abSbeveloper {
1134703fb5dSbeveloper return fPlayPos;
1140b4a36abSbeveloper }
1150b4a36abSbeveloper
1160b4a36abSbeveloper
1170b4a36abSbeveloper BGameSound *
Clone() const1180b4a36abSbeveloper BPushGameSound::Clone() const
1190b4a36abSbeveloper {
1204703fb5dSbeveloper gs_audio_format format = Format();
1214703fb5dSbeveloper size_t frameSize = get_sample_size(format.format) * format.channel_count;
1224703fb5dSbeveloper size_t bufferFrameCount = fPageSize / frameSize;
1234703fb5dSbeveloper
1244703fb5dSbeveloper return new BPushGameSound(bufferFrameCount, &format, fPageCount, Device());
1250b4a36abSbeveloper }
1260b4a36abSbeveloper
1270b4a36abSbeveloper
1280b4a36abSbeveloper status_t
Perform(int32 selector,void * data)129c7509fceSJérôme Duval BPushGameSound::Perform(int32 selector, void *data)
1300b4a36abSbeveloper {
131ea4f253fSJérôme Duval return BStreamingGameSound::Perform(selector, data);
1320b4a36abSbeveloper }
1330b4a36abSbeveloper
1340b4a36abSbeveloper
1350b4a36abSbeveloper status_t
SetParameters(size_t inBufferFrameCount,const gs_audio_format * format,size_t inBufferCount)1360b4a36abSbeveloper BPushGameSound::SetParameters(size_t inBufferFrameCount,
1372066acfbSAlexander von Gluck IV const gs_audio_format *format, size_t inBufferCount)
1380b4a36abSbeveloper {
139ea4f253fSJérôme Duval return B_UNSUPPORTED;
1400b4a36abSbeveloper }
1410b4a36abSbeveloper
1420b4a36abSbeveloper
1430b4a36abSbeveloper status_t
SetStreamHook(void (* hook)(void * inCookie,void * inBuffer,size_t inByteCount,BStreamingGameSound * me),void * cookie)1440044a8c3SAdrien Destugues BPushGameSound::SetStreamHook(void (*hook)(void * inCookie, void * inBuffer,
1450044a8c3SAdrien Destugues size_t inByteCount, BStreamingGameSound * me), void * cookie)
1460b4a36abSbeveloper {
147ea4f253fSJérôme Duval return B_UNSUPPORTED;
1480b4a36abSbeveloper }
1490b4a36abSbeveloper
1500b4a36abSbeveloper
1510b4a36abSbeveloper void
FillBuffer(void * inBuffer,size_t inByteCount)152c7509fceSJérôme Duval BPushGameSound::FillBuffer(void *inBuffer, size_t inByteCount)
1530b4a36abSbeveloper {
1544703fb5dSbeveloper size_t bytes = inByteCount;
1554703fb5dSbeveloper
156c7509fceSJérôme Duval if (!BytesReady(&bytes))
157c7509fceSJérôme Duval return;
158c7509fceSJérôme Duval
159c7509fceSJérôme Duval if (fPlayPos + bytes > fBufferSize) {
1600044a8c3SAdrien Destugues size_t remainder = fBufferSize - fPlayPos;
1610044a8c3SAdrien Destugues // Space left in buffer
1624703fb5dSbeveloper char * buffer = (char*)inBuffer;
1634703fb5dSbeveloper
1644703fb5dSbeveloper // fill the buffer with the samples left at the end of our buffer
1654703fb5dSbeveloper memcpy(buffer, &fBuffer[fPlayPos], remainder);
1664703fb5dSbeveloper fPlayPos = 0;
1674703fb5dSbeveloper
1684703fb5dSbeveloper // fill the remainder of the buffer by looping to the start
1694703fb5dSbeveloper // of the buffer if it isn't locked
1704703fb5dSbeveloper bytes -= remainder;
171c7509fceSJérôme Duval if (BytesReady(&bytes)) {
1724703fb5dSbeveloper memcpy(&buffer[remainder], fBuffer, bytes);
1734703fb5dSbeveloper fPlayPos += bytes;
1744703fb5dSbeveloper }
175c7509fceSJérôme Duval } else {
1764703fb5dSbeveloper memcpy(inBuffer, &fBuffer[fPlayPos], bytes);
1774703fb5dSbeveloper fPlayPos += bytes;
1780b4a36abSbeveloper }
1790b4a36abSbeveloper
1804703fb5dSbeveloper BStreamingGameSound::FillBuffer(inBuffer, inByteCount);
1814703fb5dSbeveloper }
1824703fb5dSbeveloper
1834703fb5dSbeveloper
1844703fb5dSbeveloper bool
BytesReady(size_t * bytes)1854703fb5dSbeveloper BPushGameSound::BytesReady(size_t * bytes)
1864703fb5dSbeveloper {
187c7509fceSJérôme Duval if (fPageLocked->CountItems() <= 0)
188c7509fceSJérôme Duval return true;
189c7509fceSJérôme Duval
1904703fb5dSbeveloper size_t start = fPlayPos;
1914703fb5dSbeveloper size_t ready = fPlayPos;
1924703fb5dSbeveloper int32 page = int32(start / fPageSize);
1934703fb5dSbeveloper
1944703fb5dSbeveloper // return if there is nothing to do
195c7509fceSJérôme Duval if (fPageLocked->HasItem(&fBuffer[page * fPageSize]))
196c7509fceSJérôme Duval return false;
1974703fb5dSbeveloper
198c7509fceSJérôme Duval while (ready < *bytes) {
1994703fb5dSbeveloper ready += fPageSize;
2004703fb5dSbeveloper page = int32(ready / fPageSize);
2014703fb5dSbeveloper
202c7509fceSJérôme Duval if (fPageLocked->HasItem(&fBuffer[page * fPageSize])) {
2034703fb5dSbeveloper // we have found a locked page
2044703fb5dSbeveloper *bytes = ready - start - (ready - page * fPageSize);
2054703fb5dSbeveloper return true;
2064703fb5dSbeveloper }
2074703fb5dSbeveloper }
2084703fb5dSbeveloper
2094703fb5dSbeveloper // all of the bytes are ready
2104703fb5dSbeveloper return true;
2114703fb5dSbeveloper }
2120b4a36abSbeveloper
2132066acfbSAlexander von Gluck IV
2140b4a36abSbeveloper /* unimplemented for protection of the user:
2150b4a36abSbeveloper *
2160b4a36abSbeveloper * BPushGameSound::BPushGameSound()
2170b4a36abSbeveloper * BPushGameSound::BPushGameSound(const BPushGameSound &)
2180b4a36abSbeveloper * BPushGameSound &BPushGameSound::operator=(const BPushGameSound &)
2190b4a36abSbeveloper */
2200b4a36abSbeveloper
2210b4a36abSbeveloper
2220b4a36abSbeveloper status_t
_Reserved_BPushGameSound_0(int32 arg,...)2230b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_0(int32 arg, ...)
2240b4a36abSbeveloper {
2250b4a36abSbeveloper return B_ERROR;
2260b4a36abSbeveloper }
2270b4a36abSbeveloper
2280b4a36abSbeveloper
2290b4a36abSbeveloper status_t
_Reserved_BPushGameSound_1(int32 arg,...)2300b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_1(int32 arg, ...)
2310b4a36abSbeveloper {
2320b4a36abSbeveloper return B_ERROR;
2330b4a36abSbeveloper }
2340b4a36abSbeveloper
2350b4a36abSbeveloper
2360b4a36abSbeveloper status_t
_Reserved_BPushGameSound_2(int32 arg,...)2370b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_2(int32 arg, ...)
2380b4a36abSbeveloper {
2390b4a36abSbeveloper return B_ERROR;
2400b4a36abSbeveloper }
2410b4a36abSbeveloper
2420b4a36abSbeveloper
2430b4a36abSbeveloper status_t
_Reserved_BPushGameSound_3(int32 arg,...)2440b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_3(int32 arg, ...)
2450b4a36abSbeveloper {
2460b4a36abSbeveloper return B_ERROR;
2470b4a36abSbeveloper }
2480b4a36abSbeveloper
2490b4a36abSbeveloper
2500b4a36abSbeveloper status_t
_Reserved_BPushGameSound_4(int32 arg,...)2510b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_4(int32 arg, ...)
2520b4a36abSbeveloper {
2530b4a36abSbeveloper return B_ERROR;
2540b4a36abSbeveloper }
2550b4a36abSbeveloper
2560b4a36abSbeveloper
2570b4a36abSbeveloper status_t
_Reserved_BPushGameSound_5(int32 arg,...)2580b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_5(int32 arg, ...)
2590b4a36abSbeveloper {
2600b4a36abSbeveloper return B_ERROR;
2610b4a36abSbeveloper }
2620b4a36abSbeveloper
2630b4a36abSbeveloper
2640b4a36abSbeveloper status_t
_Reserved_BPushGameSound_6(int32 arg,...)2650b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_6(int32 arg, ...)
2660b4a36abSbeveloper {
2670b4a36abSbeveloper return B_ERROR;
2680b4a36abSbeveloper }
2690b4a36abSbeveloper
2700b4a36abSbeveloper
2710b4a36abSbeveloper status_t
_Reserved_BPushGameSound_7(int32 arg,...)2720b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_7(int32 arg, ...)
2730b4a36abSbeveloper {
2740b4a36abSbeveloper return B_ERROR;
2750b4a36abSbeveloper }
2760b4a36abSbeveloper
2770b4a36abSbeveloper
2780b4a36abSbeveloper status_t
_Reserved_BPushGameSound_8(int32 arg,...)2790b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_8(int32 arg, ...)
2800b4a36abSbeveloper {
2810b4a36abSbeveloper return B_ERROR;
2820b4a36abSbeveloper }
2830b4a36abSbeveloper
2840b4a36abSbeveloper
2850b4a36abSbeveloper status_t
_Reserved_BPushGameSound_9(int32 arg,...)2860b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_9(int32 arg, ...)
2870b4a36abSbeveloper {
2880b4a36abSbeveloper return B_ERROR;
2890b4a36abSbeveloper }
2900b4a36abSbeveloper
2910b4a36abSbeveloper
2920b4a36abSbeveloper status_t
_Reserved_BPushGameSound_10(int32 arg,...)2930b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_10(int32 arg, ...)
2940b4a36abSbeveloper {
2950b4a36abSbeveloper return B_ERROR;
2960b4a36abSbeveloper }
2970b4a36abSbeveloper
2980b4a36abSbeveloper
2990b4a36abSbeveloper status_t
_Reserved_BPushGameSound_11(int32 arg,...)3000b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_11(int32 arg, ...)
3010b4a36abSbeveloper {
3020b4a36abSbeveloper return B_ERROR;
3030b4a36abSbeveloper }
3040b4a36abSbeveloper
3050b4a36abSbeveloper
3060b4a36abSbeveloper status_t
_Reserved_BPushGameSound_12(int32 arg,...)3070b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_12(int32 arg, ...)
3080b4a36abSbeveloper {
3090b4a36abSbeveloper return B_ERROR;
3100b4a36abSbeveloper }
3110b4a36abSbeveloper
3120b4a36abSbeveloper
3130b4a36abSbeveloper status_t
_Reserved_BPushGameSound_13(int32 arg,...)3140b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_13(int32 arg, ...)
3150b4a36abSbeveloper {
3160b4a36abSbeveloper return B_ERROR;
3170b4a36abSbeveloper }
3180b4a36abSbeveloper
3190b4a36abSbeveloper
3200b4a36abSbeveloper status_t
_Reserved_BPushGameSound_14(int32 arg,...)3210b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_14(int32 arg, ...)
3220b4a36abSbeveloper {
3230b4a36abSbeveloper return B_ERROR;
3240b4a36abSbeveloper }
3250b4a36abSbeveloper
3260b4a36abSbeveloper
3270b4a36abSbeveloper status_t
_Reserved_BPushGameSound_15(int32 arg,...)3280b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_15(int32 arg, ...)
3290b4a36abSbeveloper {
3300b4a36abSbeveloper return B_ERROR;
3310b4a36abSbeveloper }
3320b4a36abSbeveloper
3330b4a36abSbeveloper
3340b4a36abSbeveloper status_t
_Reserved_BPushGameSound_16(int32 arg,...)3350b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_16(int32 arg, ...)
3360b4a36abSbeveloper {
3370b4a36abSbeveloper return B_ERROR;
3380b4a36abSbeveloper }
3390b4a36abSbeveloper
3400b4a36abSbeveloper
3410b4a36abSbeveloper status_t
_Reserved_BPushGameSound_17(int32 arg,...)3420b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_17(int32 arg, ...)
3430b4a36abSbeveloper {
3440b4a36abSbeveloper return B_ERROR;
3450b4a36abSbeveloper }
3460b4a36abSbeveloper
3470b4a36abSbeveloper
3480b4a36abSbeveloper status_t
_Reserved_BPushGameSound_18(int32 arg,...)3490b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_18(int32 arg, ...)
3500b4a36abSbeveloper {
3510b4a36abSbeveloper return B_ERROR;
3520b4a36abSbeveloper }
3530b4a36abSbeveloper
3540b4a36abSbeveloper
3550b4a36abSbeveloper status_t
_Reserved_BPushGameSound_19(int32 arg,...)3560b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_19(int32 arg, ...)
3570b4a36abSbeveloper {
3580b4a36abSbeveloper return B_ERROR;
3590b4a36abSbeveloper }
3600b4a36abSbeveloper
3610b4a36abSbeveloper
3620b4a36abSbeveloper status_t
_Reserved_BPushGameSound_20(int32 arg,...)3630b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_20(int32 arg, ...)
3640b4a36abSbeveloper {
3650b4a36abSbeveloper return B_ERROR;
3660b4a36abSbeveloper }
3670b4a36abSbeveloper
3680b4a36abSbeveloper
3690b4a36abSbeveloper status_t
_Reserved_BPushGameSound_21(int32 arg,...)3700b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_21(int32 arg, ...)
3710b4a36abSbeveloper {
3720b4a36abSbeveloper return B_ERROR;
3730b4a36abSbeveloper }
3740b4a36abSbeveloper
3750b4a36abSbeveloper
3760b4a36abSbeveloper status_t
_Reserved_BPushGameSound_22(int32 arg,...)3770b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_22(int32 arg, ...)
3780b4a36abSbeveloper {
3790b4a36abSbeveloper return B_ERROR;
3800b4a36abSbeveloper }
3810b4a36abSbeveloper
3820b4a36abSbeveloper
3830b4a36abSbeveloper status_t
_Reserved_BPushGameSound_23(int32 arg,...)3840b4a36abSbeveloper BPushGameSound::_Reserved_BPushGameSound_23(int32 arg, ...)
3850b4a36abSbeveloper {
3860b4a36abSbeveloper return B_ERROR;
3870b4a36abSbeveloper }
388