change the way FileGameSound works : avoid using a port

code style, some clean up


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20603 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2007-04-06 22:40:23 +00:00
parent afed18de79
commit 0c93c0a807
9 changed files with 68 additions and 137 deletions
-2
View File
@@ -95,8 +95,6 @@ private:
status_t Init(const entry_ref* file); status_t Init(const entry_ref* file);
static int32 ReadThread(void* arg);
bool Load(); bool Load();
bool Read(void * buffer, size_t bytes); bool Read(void * buffer, size_t bytes);
+49 -109
View File
@@ -24,24 +24,18 @@
// Description: BFileGameSound is a class that streams data out of a file. // Description: BFileGameSound is a class that streams data out of a file.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
// System Includes -------------------------------------------------------------
#include <Entry.h> #include <Entry.h>
#include <FileGameSound.h>
#include <MediaFile.h> #include <MediaFile.h>
#include <MediaTrack.h> #include <MediaTrack.h>
#include <scheduler.h> #include <scheduler.h>
// Project Includes ------------------------------------------------------------ #include "GameSoundDevice.h"
#include <GameSoundDevice.h> #include "GSUtility.h"
#include <GSUtility.h>
// Local Includes --------------------------------------------------------------
#include <FileGameSound.h>
// Local Defines ---------------------------------------------------------------
const int32 kPages = 20; const int32 kPages = 20;
struct _gs_media_tracker struct _gs_media_tracker
{ {
@@ -150,7 +144,8 @@ BFileGameSound::BFileGameSound(const entry_ref *file,
fPaused(false), fPaused(false),
fPauseGain(1.0) fPauseGain(1.0)
{ {
if (InitCheck() == B_OK) SetInitError(Init(file)); if (InitCheck() == B_OK)
SetInitError(Init(file));
} }
@@ -185,11 +180,9 @@ BFileGameSound::~BFileGameSound()
if (fAudioStream) if (fAudioStream)
{ {
if (fAudioStream->stream) fAudioStream->file->ReleaseTrack(fAudioStream->stream); if (fAudioStream->stream)
fAudioStream->file->ReleaseTrack(fAudioStream->stream);
fAudioStream->file->CloseFile();
//delete fAudioStream->stream;
delete fAudioStream->file; delete fAudioStream->file;
} }
@@ -209,16 +202,8 @@ status_t
BFileGameSound::StartPlaying() BFileGameSound::StartPlaying()
{ {
// restart playback if needed // restart playback if needed
if (IsPlaying()) StopPlaying(); if (IsPlaying())
StopPlaying();
fPort = create_port(kPages, "audioque");
// create the thread that will read the file
fReadThread = spawn_thread(ReadThread, "audiostream", B_NORMAL_PRIORITY, this);
if (fReadThread < B_OK) return B_NO_MORE_THREADS;
status_t error = resume_thread(fReadThread);
if (error != B_OK) return error;
// start playing the file // start playing the file
return BStreamingGameSound::StartPlaying(); return BStreamingGameSound::StartPlaying();
@@ -237,10 +222,6 @@ BFileGameSound::StopPlaying()
fStopping = false; fStopping = false;
fAudioStream->position = 0; fAudioStream->position = 0;
fPlayPosition = 0; fPlayPosition = 0;
// we don't need to read any more
kill_thread(fReadThread);
delete_port(fPort);
return error; return error;
} }
@@ -250,9 +231,7 @@ status_t
BFileGameSound::Preload() BFileGameSound::Preload()
{ {
if (!IsPlaying()) if (!IsPlaying())
{ Load();
for(int32 i = 0; i < kPages / 2; i++) Load();
}
return B_OK; return B_OK;
} }
@@ -262,23 +241,20 @@ void
BFileGameSound::FillBuffer(void *inBuffer, BFileGameSound::FillBuffer(void *inBuffer,
size_t inByteCount) size_t inByteCount)
{ {
int32 cookie;
size_t bytes = inByteCount; size_t bytes = inByteCount;
if (!fPaused || fPausing) if (!fPaused || fPausing) {
{ if (fPlayPosition == 0 || fPlayPosition + inByteCount >= fBufferSize) {
// time to read a new buffer Load();
if (fPlayPosition == 0) read_port_etc(fPort, &cookie, fBuffer, fBufferSize, B_TIMEOUT, 0); }
if (fPausing) if (fPausing) {
{
Lock(); Lock();
bool rampDone = false; bool rampDone = false;
// Fill the requsted buffer, stopping if the paused flag is set // Fill the requested buffer, stopping if the paused flag is set
switch(Format().format) switch(Format().format) {
{
case gs_audio_format::B_GS_U8: case gs_audio_format::B_GS_U8:
rampDone = ::FillBuffer(fPausing, (uint8*)inBuffer, (uint8*)&fBuffer[fPlayPosition], &bytes); rampDone = ::FillBuffer(fPausing, (uint8*)inBuffer, (uint8*)&fBuffer[fPlayPosition], &bytes);
break; break;
@@ -297,11 +273,9 @@ BFileGameSound::FillBuffer(void *inBuffer,
} }
// We finished ramping // We finished ramping
if (rampDone) if (rampDone) {
{ if (bytes < inByteCount && !fPausing) {
if (bytes < inByteCount && !fPausing) // Since we are resuming play back, we need to copy any remaining samples
{
// Since are resumming play back, we need to copy any remaining samples
char * buffer = (char*)inBuffer; char * buffer = (char*)inBuffer;
memcpy(&buffer[bytes], &fBuffer[fPlayPosition + bytes], inByteCount - bytes); memcpy(&buffer[bytes], &fBuffer[fPlayPosition + bytes], inByteCount - bytes);
} }
@@ -311,15 +285,12 @@ BFileGameSound::FillBuffer(void *inBuffer,
} }
Unlock(); Unlock();
} } else {
else
{
size_t byte = 0; size_t byte = 0;
char * buffer = (char*)inBuffer; char * buffer = (char*)inBuffer;
// We need to be able to stop asap when the pause flag is flipped. // We need to be able to stop asap when the pause flag is flipped.
while(byte < bytes && (!fPaused || fPausing)) while(byte < bytes && (!fPaused || fPausing)) {
{
buffer[byte] = fBuffer[fPlayPosition + byte]; buffer[byte] = fBuffer[fPlayPosition + byte];
byte++; byte++;
} }
@@ -328,13 +299,7 @@ BFileGameSound::FillBuffer(void *inBuffer,
} }
} }
fPlayPosition += bytes; fPlayPosition += bytes;
if (fPlayPosition >= fBufferSize)
{
// We have finished reading the buffer. Setup for the next buffer.
fPlayPosition = 0;
memset(fBuffer, 0, fBufferSize);
}
} }
@@ -394,31 +359,35 @@ BFileGameSound::Init(const entry_ref* file)
fAudioStream->file = new BMediaFile(file); fAudioStream->file = new BMediaFile(file);
status_t error = fAudioStream->file->InitCheck(); status_t error = fAudioStream->file->InitCheck();
if (error != B_OK) return error; if (error != B_OK)
return error;
fAudioStream->stream = fAudioStream->file->TrackAt(0); fAudioStream->stream = fAudioStream->file->TrackAt(0);
// is this is an audio file? // is this is an audio file?
media_format mformat; media_format playFormat;
fAudioStream->stream->EncodedFormat(&mformat); fAudioStream->stream->EncodedFormat(&playFormat);
if (!mformat.IsAudio()) return B_MEDIA_BAD_FORMAT; if (!playFormat.IsAudio())
return B_MEDIA_BAD_FORMAT;
gs_audio_format dformat = Device()->Format(); gs_audio_format dformat = Device()->Format();
// request the format we want the sound // request the format we want the sound
memset(&mformat, 0, sizeof(media_format)); memset(&playFormat, 0, sizeof(media_format));
mformat.type = B_MEDIA_RAW_AUDIO; playFormat.type = B_MEDIA_RAW_AUDIO;
fAudioStream->stream->DecodedFormat(&mformat); if (fAudioStream->stream->DecodedFormat(&playFormat) != B_OK)
return B_MEDIA_BAD_FORMAT;
// translate the format into a "GameKit" friendly one // translate the format into a "GameKit" friendly one
gs_audio_format gsformat; gs_audio_format gsformat;
media_to_gs_format(&gsformat, &mformat.u.raw_audio); media_to_gs_format(&gsformat, &playFormat.u.raw_audio);
// Since the buffer sized read from the file is most likely differnt // Since the buffer sized read from the file is most likely differnt
// then the buffer used by the audio mixer, we must allocate a buffer // then the buffer used by the audio mixer, we must allocate a buffer
// large enough to hold the largest request. // large enough to hold the largest request.
fBufferSize = gsformat.buffer_size; fBufferSize = gsformat.buffer_size;
if (fBufferSize < dformat.buffer_size) fBufferSize = dformat.buffer_size; if (fBufferSize < dformat.buffer_size)
fBufferSize = dformat.buffer_size;
// create the buffer // create the buffer
fBuffer = new char[fBufferSize * 2]; fBuffer = new char[fBufferSize * 2];
@@ -430,57 +399,28 @@ BFileGameSound::Init(const entry_ref* file)
// Ask the device to attach our sound to it // Ask the device to attach our sound to it
gs_id sound; gs_id sound;
error = Device()->CreateBuffer(&sound, this, &gsformat); error = Device()->CreateBuffer(&sound, this, &gsformat);
if (error != B_OK) return error; if (error != B_OK)
return error;
return BGameSound::Init(sound); return BGameSound::Init(sound);
} }
int32
BFileGameSound::ReadThread(void* arg)
{
BFileGameSound* obj = (BFileGameSound*)arg;
while(true) obj->Load();
return 0;
}
bool bool
BFileGameSound::Load() BFileGameSound::Load()
{ {
int64 frames;
char * buffer = &fBuffer[fBufferSize + fAudioStream->position]; if (fPlayPosition != 0) {
status_t err = fAudioStream->stream->ReadFrames(buffer, &frames); memcpy(fBuffer, fBuffer + fPlayPosition, fBufferSize - fPlayPosition);
if (err < B_OK) { fPlayPosition = fBufferSize - fPlayPosition;
StopPlaying(); // XXX this is a hack, the whole class design is broken
}
int32 frame = fAudioStream->stream->CurrentFrame();
fAudioStream->position += fFrameSize * frames;
if (fAudioStream->position >= fBufferSize)
{
// we have filled the enter buffer, time to send
write_port(fPort, fBufferSize, &fBuffer[fBufferSize], fBufferSize);
fAudioStream->position = 0;
}
if (frame >= fAudioStream->frames)
{
if (fLooping)
{
// since we are looping, we need to start reading from
// the begining of the file again.
int64 firstFrame = 0;
fAudioStream->stream->SeekToFrame(&firstFrame);
fStopping = true;
}
else fStopping = true;
} }
// time to read a new buffer
int64 frames = 0;
fAudioStream->stream->ReadFrames(fBuffer + fPlayPosition, &frames);
fBufferSize = fPlayPosition + frames * fFrameSize;
fPlayPosition = 0;
return true; return true;
} }
+1 -1
View File
@@ -33,7 +33,7 @@
#include <GameSoundDefs.h> #include <GameSoundDefs.h>
// Local Includes -------------------------------------------------------------- // Local Includes --------------------------------------------------------------
#include <GSUtility.h> #include "GSUtility.h"
// Local Defines --------------------------------------------------------------- // Local Defines ---------------------------------------------------------------
+4 -4
View File
@@ -42,12 +42,12 @@
#include <MediaDefs.h> #include <MediaDefs.h>
// Project Includes ------------------------------------------------------------ // Project Includes ------------------------------------------------------------
#include <GameSoundBuffer.h> #include "GameSoundBuffer.h"
#include <GameSoundDevice.h> #include "GameSoundDevice.h"
#include <GSUtility.h> #include "GSUtility.h"
// Local Includes -------------------------------------------------------------- // Local Includes --------------------------------------------------------------
#include <GameProducer.h> #include "GameProducer.h"
// Local Defines --------------------------------------------------------------- // Local Defines ---------------------------------------------------------------
struct _gs_play struct _gs_play
+4 -8
View File
@@ -25,19 +25,15 @@
// of the rest of it's childern. // of the rest of it's childern.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
// System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------
#include <GameSoundBuffer.h>
#include <GameSoundDevice.h>
// Local Includes --------------------------------------------------------------
#include <GameSound.h> #include <GameSound.h>
#include "GameSoundBuffer.h"
#include "GameSoundDevice.h"
using std::nothrow; using std::nothrow;
// Local Defines --------------------------------------------------------------- // Local Defines ---------------------------------------------------------------
+2
View File
@@ -1,5 +1,7 @@
SubDir HAIKU_TOP src kits game ; SubDir HAIKU_TOP src kits game ;
SetSubDirSupportedPlatformsBeOSCompatible ;
AddSubDirSupportedPlatforms libbe_test ; AddSubDirSupportedPlatforms libbe_test ;
UsePrivateHeaders app ; UsePrivateHeaders app ;
+2 -9
View File
@@ -24,21 +24,14 @@
// Description: BPushGameSound class // Description: BPushGameSound class
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
#include <string.h> #include <string.h>
// System Includes -------------------------------------------------------------
#include <List.h> #include <List.h>
// Project Includes ------------------------------------------------------------
#include <GSUtility.h>
// Local Includes --------------------------------------------------------------
#include <PushGameSound.h> #include <PushGameSound.h>
// Local Defines --------------------------------------------------------------- #include "GSUtility.h"
// BPushGameSound --------------------------------------------------------------
BPushGameSound::BPushGameSound(size_t inBufferFrameCount, BPushGameSound::BPushGameSound(size_t inBufferFrameCount,
const gs_audio_format *format, const gs_audio_format *format,
size_t inBufferCount, size_t inBufferCount,
+4 -2
View File
@@ -43,7 +43,8 @@ BSimpleGameSound::BSimpleGameSound(const entry_ref *inFile,
BGameSoundDevice *device) BGameSoundDevice *device)
: BGameSound(device) : BGameSound(device)
{ {
if (InitCheck() == B_OK) SetInitError(Init(inFile)); if (InitCheck() == B_OK)
SetInitError(Init(inFile));
} }
@@ -69,7 +70,8 @@ BSimpleGameSound::BSimpleGameSound(const void *inData,
BGameSoundDevice *device) BGameSoundDevice *device)
: BGameSound(device) : BGameSound(device)
{ {
if (InitCheck() == B_OK) SetInitError(Init(inData, inFrameCount, format)); if (InitCheck() == B_OK)
SetInitError(Init(inData, inFrameCount, format));
} }
+2 -2
View File
@@ -30,10 +30,10 @@
// System Includes ------------------------------------------------------------- // System Includes -------------------------------------------------------------
// Project Includes ------------------------------------------------------------ // Project Includes ------------------------------------------------------------
#include <GameSoundDevice.h> #include "GameSoundDevice.h"
// Local Includes -------------------------------------------------------------- // Local Includes --------------------------------------------------------------
#include <StreamingGameSound.h> #include "StreamingGameSound.h"
// Local Defines --------------------------------------------------------------- // Local Defines ---------------------------------------------------------------
BStreamingGameSound::BStreamingGameSound(size_t inBufferFrameCount, BStreamingGameSound::BStreamingGameSound(size_t inBufferFrameCount,