split or combine decoder buffers to match mixer buffer size.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28414 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ struct _gs_media_tracker
|
|||||||
size_t position;
|
size_t position;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Locale utility functions -----------------------------------------------
|
// Local utility functions -----------------------------------------------
|
||||||
bool FillBuffer(_gs_ramp * ramp, uint8 * data, uint8 * buffer, size_t * bytes)
|
bool FillBuffer(_gs_ramp * ramp, uint8 * data, uint8 * buffer, size_t * bytes)
|
||||||
{
|
{
|
||||||
int32 samples = *bytes / sizeof(uint8);
|
int32 samples = *bytes / sizeof(uint8);
|
||||||
@@ -218,77 +219,79 @@ void
|
|||||||
BFileGameSound::FillBuffer(void *inBuffer,
|
BFileGameSound::FillBuffer(void *inBuffer,
|
||||||
size_t inByteCount)
|
size_t inByteCount)
|
||||||
{
|
{
|
||||||
size_t bytes = inByteCount;
|
// Split or combine decoder buffers into mixer buffers
|
||||||
|
// fPlayPosition is where we got up to in the input buffer after last call
|
||||||
|
|
||||||
if (!fPaused || fPausing) {
|
size_t out_offset = 0;
|
||||||
if (fPlayPosition == 0 || fPlayPosition + inByteCount >= fBufferSize) {
|
|
||||||
Load();
|
while (inByteCount > 0 && !fPaused) {
|
||||||
}
|
if (!fPaused || fPausing) {
|
||||||
|
printf("mixout %ld, inByteCount %ld, decin %ld, BufferSize %ld\n",out_offset, inByteCount, fPlayPosition, fBufferSize);
|
||||||
if (fPlayPosition + bytes > fBufferSize)
|
if (fPlayPosition == 0 || fPlayPosition >= fBufferSize) {
|
||||||
bytes = fBufferSize - fPlayPosition;
|
Load();
|
||||||
|
|
||||||
if (bytes == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fPausing) {
|
|
||||||
Lock();
|
|
||||||
|
|
||||||
bool rampDone = false;
|
|
||||||
|
|
||||||
// Fill the requested buffer, stopping if the paused flag is set
|
|
||||||
switch(Format().format) {
|
|
||||||
case gs_audio_format::B_GS_U8:
|
|
||||||
rampDone = ::FillBuffer(fPausing, (uint8*)inBuffer,
|
|
||||||
(uint8*)&fBuffer[fPlayPosition], &bytes);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case gs_audio_format::B_GS_S16:
|
|
||||||
rampDone = ::FillBuffer(fPausing, (int16*)inBuffer,
|
|
||||||
(int16*)&fBuffer[fPlayPosition], &bytes);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case gs_audio_format::B_GS_S32:
|
|
||||||
rampDone = ::FillBuffer(fPausing, (int32*)inBuffer,
|
|
||||||
(int32*)&fBuffer[fPlayPosition], &bytes);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case gs_audio_format::B_GS_F:
|
|
||||||
rampDone = ::FillBuffer(fPausing, (float*)inBuffer,
|
|
||||||
(float*)&fBuffer[fPlayPosition], &bytes);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We finished ramping
|
if (fPausing) {
|
||||||
if (rampDone) {
|
Lock();
|
||||||
if (bytes < inByteCount && !fPausing) {
|
|
||||||
// Since we are resuming play back,
|
bool rampDone = false;
|
||||||
// we need to copy any remaining samples
|
size_t bytes = fBufferSize - fPlayPosition;
|
||||||
char * buffer = (char*)inBuffer;
|
|
||||||
memcpy(&buffer[bytes], &fBuffer[fPlayPosition + bytes],
|
if (bytes > inByteCount) {
|
||||||
inByteCount - bytes);
|
bytes = inByteCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill the requested buffer, stopping if the paused flag is set
|
||||||
|
char * buffer = (char*)inBuffer;
|
||||||
|
|
||||||
delete fPausing;
|
switch(Format().format) {
|
||||||
fPausing = NULL;
|
case gs_audio_format::B_GS_U8:
|
||||||
|
rampDone = ::FillBuffer(fPausing, (uint8*)&buffer[out_offset], (uint8*)&fBuffer[fPlayPosition], &bytes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case gs_audio_format::B_GS_S16:
|
||||||
|
rampDone = ::FillBuffer(fPausing, (int16*)&buffer[out_offset], (int16*)&fBuffer[fPlayPosition], &bytes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case gs_audio_format::B_GS_S32:
|
||||||
|
rampDone = ::FillBuffer(fPausing, (int32*)&buffer[out_offset], (int32*)&fBuffer[fPlayPosition], &bytes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case gs_audio_format::B_GS_F:
|
||||||
|
rampDone = ::FillBuffer(fPausing, (float*)&buffer[out_offset], (float*)&fBuffer[fPlayPosition], &bytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
inByteCount -= bytes;
|
||||||
|
out_offset += bytes;
|
||||||
|
fPlayPosition += bytes;
|
||||||
|
|
||||||
|
// We finished ramping
|
||||||
|
if (rampDone) {
|
||||||
|
|
||||||
|
// We need to be able to stop asap when the pause flag is flipped.
|
||||||
|
while(fPlayPosition < fBufferSize && (inByteCount > 0)) {
|
||||||
|
buffer[out_offset++] = fBuffer[fPlayPosition++];
|
||||||
|
inByteCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fPausing;
|
||||||
|
fPausing = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unlock();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
char * buffer = (char*)inBuffer;
|
||||||
|
|
||||||
|
// We need to be able to stop asap when the pause flag is flipped.
|
||||||
|
while(fPlayPosition < fBufferSize && (!fPaused || fPausing) && (inByteCount > 0)) {
|
||||||
|
buffer[out_offset++] = fBuffer[fPlayPosition++];
|
||||||
|
inByteCount--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unlock();
|
|
||||||
} else {
|
|
||||||
size_t byte = 0;
|
|
||||||
char * buffer = (char*)inBuffer;
|
|
||||||
|
|
||||||
// We need to be able to stop asap when the pause flag is flipped.
|
|
||||||
while(byte < bytes && (!fPaused || fPausing)) {
|
|
||||||
buffer[byte] = fBuffer[fPlayPosition + byte];
|
|
||||||
byte++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = byte;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fPlayPosition += bytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -402,19 +405,14 @@ BFileGameSound::Init(const entry_ref* file)
|
|||||||
bool
|
bool
|
||||||
BFileGameSound::Load()
|
BFileGameSound::Load()
|
||||||
{
|
{
|
||||||
if (fPlayPosition != 0) {
|
// read a new buffer
|
||||||
if (fBufferSize > fPlayPosition)
|
|
||||||
memcpy(fBuffer, fBuffer + fPlayPosition, fBufferSize - fPlayPosition);
|
|
||||||
fPlayPosition = fBufferSize - fPlayPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// time to read a new buffer
|
|
||||||
int64 frames = 0;
|
int64 frames = 0;
|
||||||
fAudioStream->stream->ReadFrames(fBuffer + fPlayPosition, &frames);
|
fAudioStream->stream->ReadFrames(fBuffer, &frames);
|
||||||
fBufferSize = fPlayPosition + frames * fFrameSize;
|
fBufferSize = frames * fFrameSize;
|
||||||
fPlayPosition = 0;
|
fPlayPosition = 0;
|
||||||
|
|
||||||
if (fBufferSize == 0) {
|
if (fBufferSize <= 0) {
|
||||||
|
// EOF
|
||||||
if (fLooping) {
|
if (fLooping) {
|
||||||
// start reading next time from the start of the file
|
// start reading next time from the start of the file
|
||||||
int64 frame = 0;
|
int64 frame = 0;
|
||||||
@@ -423,7 +421,7 @@ BFileGameSound::Load()
|
|||||||
StopPlaying();
|
StopPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user