* Moved _SoundPlayNode into the BPrivate namespace and dismissed the '_' prefix.
* Further cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34482 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -16,7 +16,9 @@
|
|||||||
class BContinuousParameter;
|
class BContinuousParameter;
|
||||||
class BParameterWeb;
|
class BParameterWeb;
|
||||||
class BSound;
|
class BSound;
|
||||||
class _SoundPlayNode;
|
namespace BPrivate {
|
||||||
|
class SoundPlayNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class sound_error : public std::exception {
|
class sound_error : public std::exception {
|
||||||
@@ -155,10 +157,10 @@ private:
|
|||||||
const media_raw_audio_format& format);
|
const media_raw_audio_format& format);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class _SoundPlayNode;
|
friend class BPrivate::SoundPlayNode;
|
||||||
|
|
||||||
struct _playing_sound {
|
struct playing_sound {
|
||||||
_playing_sound* next;
|
playing_sound* next;
|
||||||
off_t current_offset;
|
off_t current_offset;
|
||||||
BSound* sound;
|
BSound* sound;
|
||||||
play_id id;
|
play_id id;
|
||||||
@@ -168,8 +170,8 @@ private:
|
|||||||
float volume;
|
float volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _waiting_sound {
|
struct waiting_sound {
|
||||||
_waiting_sound* next;
|
waiting_sound* next;
|
||||||
bigtime_t start_time;
|
bigtime_t start_time;
|
||||||
BSound* sound;
|
BSound* sound;
|
||||||
play_id id;
|
play_id id;
|
||||||
@@ -177,10 +179,10 @@ private:
|
|||||||
float volume;
|
float volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
_SoundPlayNode* fPlayerNode;
|
BPrivate::SoundPlayNode* fPlayerNode;
|
||||||
|
|
||||||
_playing_sound* fPlayingSounds;
|
playing_sound* fPlayingSounds;
|
||||||
_waiting_sound* fWaitingSounds;
|
waiting_sound* fWaitingSounds;
|
||||||
|
|
||||||
BufferPlayerFunc fPlayBufferFunc;
|
BufferPlayerFunc fPlayBufferFunc;
|
||||||
EventNotifierFunc fNotifierFunc;
|
EventNotifierFunc fNotifierFunc;
|
||||||
|
|||||||
+183
-179
@@ -8,9 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*! This is the BBufferProducer, used internally by BSoundPlayer
|
/*! This is the BBufferProducer used internally by BSoundPlayer.
|
||||||
This belongs into a private namespace, but isn't for
|
|
||||||
compatibility reasons.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -28,25 +26,28 @@
|
|||||||
#define SEND_NEW_BUFFER_EVENT (BTimedEventQueue::B_USER_EVENT + 1)
|
#define SEND_NEW_BUFFER_EVENT (BTimedEventQueue::B_USER_EVENT + 1)
|
||||||
|
|
||||||
|
|
||||||
_SoundPlayNode::_SoundPlayNode(const char* name, BSoundPlayer* player)
|
namespace BPrivate {
|
||||||
|
|
||||||
|
|
||||||
|
SoundPlayNode::SoundPlayNode(const char* name, BSoundPlayer* player)
|
||||||
:
|
:
|
||||||
BMediaNode(name),
|
BMediaNode(name),
|
||||||
BBufferProducer(B_MEDIA_RAW_AUDIO),
|
BBufferProducer(B_MEDIA_RAW_AUDIO),
|
||||||
BMediaEventLooper(),
|
BMediaEventLooper(),
|
||||||
mPlayer(player),
|
fPlayer(player),
|
||||||
mInitCheckStatus(B_OK),
|
fInitStatus(B_OK),
|
||||||
mOutputEnabled(true),
|
fOutputEnabled(true),
|
||||||
mBufferGroup(NULL),
|
fBufferGroup(NULL),
|
||||||
mFramesSent(0),
|
fFramesSent(0),
|
||||||
mTooEarlyCount(0)
|
fTooEarlyCount(0)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
mOutput.format.type = B_MEDIA_RAW_AUDIO;
|
fOutput.format.type = B_MEDIA_RAW_AUDIO;
|
||||||
mOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
fOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_SoundPlayNode::~_SoundPlayNode()
|
SoundPlayNode::~SoundPlayNode()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
Quit();
|
Quit();
|
||||||
@@ -54,25 +55,25 @@ _SoundPlayNode::~_SoundPlayNode()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
_SoundPlayNode::IsPlaying()
|
SoundPlayNode::IsPlaying()
|
||||||
{
|
{
|
||||||
return RunState() == B_STARTED;
|
return RunState() == B_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bigtime_t
|
bigtime_t
|
||||||
_SoundPlayNode::CurrentTime()
|
SoundPlayNode::CurrentTime()
|
||||||
{
|
{
|
||||||
int frameRate = (int)mOutput.format.u.raw_audio.frame_rate;
|
int frameRate = (int)fOutput.format.u.raw_audio.frame_rate;
|
||||||
return frameRate == 0 ? 0
|
return frameRate == 0 ? 0
|
||||||
: bigtime_t((1000000LL * mFramesSent) / frameRate);
|
: bigtime_t((1000000LL * fFramesSent) / frameRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
media_multi_audio_format
|
media_multi_audio_format
|
||||||
_SoundPlayNode::Format() const
|
SoundPlayNode::Format() const
|
||||||
{
|
{
|
||||||
return mOutput.format.u.raw_audio;
|
return fOutput.format.u.raw_audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ _SoundPlayNode::Format() const
|
|||||||
|
|
||||||
|
|
||||||
BMediaAddOn*
|
BMediaAddOn*
|
||||||
_SoundPlayNode::AddOn(int32* _internalID) const
|
SoundPlayNode::AddOn(int32* _internalID) const
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
// This only gets called if we are in an add-on.
|
// This only gets called if we are in an add-on.
|
||||||
@@ -89,7 +90,7 @@ _SoundPlayNode::AddOn(int32* _internalID) const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::Preroll()
|
SoundPlayNode::Preroll()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
// TODO: Performance opportunity
|
// TODO: Performance opportunity
|
||||||
@@ -98,7 +99,7 @@ _SoundPlayNode::Preroll()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::HandleMessage(int32 message, const void* data, size_t size)
|
SoundPlayNode::HandleMessage(int32 message, const void* data, size_t size)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -106,31 +107,31 @@ _SoundPlayNode::HandleMessage(int32 message, const void* data, size_t size)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::NodeRegistered()
|
SoundPlayNode::NodeRegistered()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (mInitCheckStatus != B_OK) {
|
if (fInitStatus != B_OK) {
|
||||||
ReportError(B_NODE_IN_DISTRESS);
|
ReportError(B_NODE_IN_DISTRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPriority(B_URGENT_PRIORITY);
|
SetPriority(B_URGENT_PRIORITY);
|
||||||
|
|
||||||
mOutput.format.type = B_MEDIA_RAW_AUDIO;
|
fOutput.format.type = B_MEDIA_RAW_AUDIO;
|
||||||
mOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
fOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
||||||
mOutput.destination = media_destination::null;
|
fOutput.destination = media_destination::null;
|
||||||
mOutput.source.port = ControlPort();
|
fOutput.source.port = ControlPort();
|
||||||
mOutput.source.id = 0;
|
fOutput.source.id = 0;
|
||||||
mOutput.node = Node();
|
fOutput.node = Node();
|
||||||
strcpy(mOutput.name, Name());
|
strcpy(fOutput.name, Name());
|
||||||
|
|
||||||
Run();
|
Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::RequestCompleted(const media_request_info& info)
|
SoundPlayNode::RequestCompleted(const media_request_info& info)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -138,7 +139,7 @@ _SoundPlayNode::RequestCompleted(const media_request_info& info)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::SetTimeSource(BTimeSource* timeSource)
|
SoundPlayNode::SetTimeSource(BTimeSource* timeSource)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
BMediaNode::SetTimeSource(timeSource);
|
BMediaNode::SetTimeSource(timeSource);
|
||||||
@@ -146,9 +147,9 @@ _SoundPlayNode::SetTimeSource(BTimeSource* timeSource)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::SetRunMode(run_mode mode)
|
SoundPlayNode::SetRunMode(run_mode mode)
|
||||||
{
|
{
|
||||||
TRACE("_SoundPlayNode::SetRunMode mode:%i\n", mode);
|
TRACE("SoundPlayNode::SetRunMode mode:%i\n", mode);
|
||||||
BMediaNode::SetRunMode(mode);
|
BMediaNode::SetRunMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +158,7 @@ _SoundPlayNode::SetRunMode(run_mode mode)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::FormatSuggestionRequested(media_type type, int32 /*quality*/,
|
SoundPlayNode::FormatSuggestionRequested(media_type type, int32 /*quality*/,
|
||||||
media_format* format)
|
media_format* format)
|
||||||
{
|
{
|
||||||
// FormatSuggestionRequested() is not necessarily part of the format
|
// FormatSuggestionRequested() is not necessarily part of the format
|
||||||
@@ -179,7 +180,7 @@ _SoundPlayNode::FormatSuggestionRequested(media_type type, int32 /*quality*/,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::FormatProposal(const media_source& output, media_format* format)
|
SoundPlayNode::FormatProposal(const media_source& output, media_format* format)
|
||||||
{
|
{
|
||||||
// FormatProposal() is the first stage in the BMediaRoster::Connect()
|
// FormatProposal() is the first stage in the BMediaRoster::Connect()
|
||||||
// process. We hand out a suggested format, with wildcards for any
|
// process. We hand out a suggested format, with wildcards for any
|
||||||
@@ -187,8 +188,8 @@ _SoundPlayNode::FormatProposal(const media_source& output, media_format* format)
|
|||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// is this a proposal for our one output?
|
// is this a proposal for our one output?
|
||||||
if (output != mOutput.source) {
|
if (output != fOutput.source) {
|
||||||
TRACE("_SoundPlayNode::FormatProposal returning B_MEDIA_BAD_SOURCE\n");
|
TRACE("SoundPlayNode::FormatProposal returning B_MEDIA_BAD_SOURCE\n");
|
||||||
return B_MEDIA_BAD_SOURCE;
|
return B_MEDIA_BAD_SOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,14 +199,14 @@ _SoundPlayNode::FormatProposal(const media_source& output, media_format* format)
|
|||||||
|
|
||||||
// if not raw audio, we can't support it
|
// if not raw audio, we can't support it
|
||||||
if (format->type != B_MEDIA_RAW_AUDIO) {
|
if (format->type != B_MEDIA_RAW_AUDIO) {
|
||||||
TRACE("_SoundPlayNode::FormatProposal returning B_MEDIA_BAD_FORMAT\n");
|
TRACE("SoundPlayNode::FormatProposal returning B_MEDIA_BAD_FORMAT\n");
|
||||||
return B_MEDIA_BAD_FORMAT;
|
return B_MEDIA_BAD_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG >0
|
#if DEBUG >0
|
||||||
char buf[100];
|
char buf[100];
|
||||||
string_for_format(*format, buf, sizeof(buf));
|
string_for_format(*format, buf, sizeof(buf));
|
||||||
TRACE("_SoundPlayNode::FormatProposal: format %s\n", buf);
|
TRACE("SoundPlayNode::FormatProposal: format %s\n", buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -213,7 +214,7 @@ _SoundPlayNode::FormatProposal(const media_source& output, media_format* format)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::FormatChangeRequested(const media_source& source,
|
SoundPlayNode::FormatChangeRequested(const media_source& source,
|
||||||
const media_destination& destination, media_format* _format,
|
const media_destination& destination, media_format* _format,
|
||||||
int32* /* deprecated */)
|
int32* /* deprecated */)
|
||||||
{
|
{
|
||||||
@@ -225,12 +226,12 @@ _SoundPlayNode::FormatChangeRequested(const media_source& source,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::GetNextOutput(int32* cookie, media_output* _output)
|
SoundPlayNode::GetNextOutput(int32* cookie, media_output* _output)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (*cookie == 0) {
|
if (*cookie == 0) {
|
||||||
*_output = mOutput;
|
*_output = fOutput;
|
||||||
*cookie += 1;
|
*cookie += 1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
} else {
|
} else {
|
||||||
@@ -240,7 +241,7 @@ _SoundPlayNode::GetNextOutput(int32* cookie, media_output* _output)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::DisposeOutputCookie(int32 cookie)
|
SoundPlayNode::DisposeOutputCookie(int32 cookie)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
// do nothing because we don't use the cookie for anything special
|
// do nothing because we don't use the cookie for anything special
|
||||||
@@ -249,19 +250,19 @@ _SoundPlayNode::DisposeOutputCookie(int32 cookie)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::SetBufferGroup(const media_source& forSource,
|
SoundPlayNode::SetBufferGroup(const media_source& forSource,
|
||||||
BBufferGroup* newGroup)
|
BBufferGroup* newGroup)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// is this our output?
|
// is this our output?
|
||||||
if (forSource != mOutput.source) {
|
if (forSource != fOutput.source) {
|
||||||
TRACE("_SoundPlayNode::SetBufferGroup returning B_MEDIA_BAD_SOURCE\n");
|
TRACE("SoundPlayNode::SetBufferGroup returning B_MEDIA_BAD_SOURCE\n");
|
||||||
return B_MEDIA_BAD_SOURCE;
|
return B_MEDIA_BAD_SOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we being passed the buffer group we're already using?
|
// Are we being passed the buffer group we're already using?
|
||||||
if (newGroup == mBufferGroup)
|
if (newGroup == fBufferGroup)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// Ahh, someone wants us to use a different buffer group. At this point we
|
// Ahh, someone wants us to use a different buffer group. At this point we
|
||||||
@@ -270,19 +271,19 @@ _SoundPlayNode::SetBufferGroup(const media_source& forSource,
|
|||||||
// use *that*. Note that if we're caching a BBuffer that we requested
|
// use *that*. Note that if we're caching a BBuffer that we requested
|
||||||
// earlier, we have to Recycle() that buffer *before* deleting the buffer
|
// earlier, we have to Recycle() that buffer *before* deleting the buffer
|
||||||
// group, otherwise we'll deadlock waiting for that buffer to be recycled!
|
// group, otherwise we'll deadlock waiting for that buffer to be recycled!
|
||||||
delete mBufferGroup;
|
delete fBufferGroup;
|
||||||
// waits for all buffers to recycle
|
// waits for all buffers to recycle
|
||||||
if (newGroup != NULL) {
|
if (newGroup != NULL) {
|
||||||
// we were given a valid group; just use that one from now on
|
// we were given a valid group; just use that one from now on
|
||||||
mBufferGroup = newGroup;
|
fBufferGroup = newGroup;
|
||||||
} else {
|
} else {
|
||||||
// we were passed a NULL group pointer; that means we construct
|
// we were passed a NULL group pointer; that means we construct
|
||||||
// our own buffer group to use from now on
|
// our own buffer group to use from now on
|
||||||
size_t size = mOutput.format.u.raw_audio.buffer_size;
|
size_t size = fOutput.format.u.raw_audio.buffer_size;
|
||||||
int32 count = int32(mLatency / BufferDuration() + 1 + 1);
|
int32 count = int32(fLatency / BufferDuration() + 1 + 1);
|
||||||
if (count < 3)
|
if (count < 3)
|
||||||
count = 3;
|
count = 3;
|
||||||
mBufferGroup = new BBufferGroup(size, count);
|
fBufferGroup = new BBufferGroup(size, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -290,7 +291,7 @@ _SoundPlayNode::SetBufferGroup(const media_source& forSource,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::GetLatency(bigtime_t* _latency)
|
SoundPlayNode::GetLatency(bigtime_t* _latency)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
@@ -301,7 +302,7 @@ _SoundPlayNode::GetLatency(bigtime_t* _latency)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::PrepareToConnect(const media_source& what,
|
SoundPlayNode::PrepareToConnect(const media_source& what,
|
||||||
const media_destination& where, media_format* format,
|
const media_destination& where, media_format* format,
|
||||||
media_source* _source, char* _name)
|
media_source* _source, char* _name)
|
||||||
{
|
{
|
||||||
@@ -314,14 +315,14 @@ _SoundPlayNode::PrepareToConnect(const media_source& what,
|
|||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// is this our output?
|
// is this our output?
|
||||||
if (what != mOutput.source) {
|
if (what != fOutput.source) {
|
||||||
TRACE("_SoundPlayNode::PrepareToConnect returning "
|
TRACE("SoundPlayNode::PrepareToConnect returning "
|
||||||
"B_MEDIA_BAD_SOURCE\n");
|
"B_MEDIA_BAD_SOURCE\n");
|
||||||
return B_MEDIA_BAD_SOURCE;
|
return B_MEDIA_BAD_SOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// are we already connected?
|
// are we already connected?
|
||||||
if (mOutput.destination != media_destination::null)
|
if (fOutput.destination != media_destination::null)
|
||||||
return B_MEDIA_ALREADY_CONNECTED;
|
return B_MEDIA_ALREADY_CONNECTED;
|
||||||
|
|
||||||
// the format may not yet be fully specialized (the consumer might have
|
// the format may not yet be fully specialized (the consumer might have
|
||||||
@@ -331,13 +332,13 @@ _SoundPlayNode::PrepareToConnect(const media_source& what,
|
|||||||
#if DEBUG > 0
|
#if DEBUG > 0
|
||||||
char buf[100];
|
char buf[100];
|
||||||
string_for_format(*format, buf, sizeof(buf));
|
string_for_format(*format, buf, sizeof(buf));
|
||||||
TRACE("_SoundPlayNode::PrepareToConnect: input format %s\n", buf);
|
TRACE("SoundPlayNode::PrepareToConnect: input format %s\n", buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// if not raw audio, we can't support it
|
// if not raw audio, we can't support it
|
||||||
if (format->type != B_MEDIA_UNKNOWN_TYPE
|
if (format->type != B_MEDIA_UNKNOWN_TYPE
|
||||||
&& format->type != B_MEDIA_RAW_AUDIO) {
|
&& format->type != B_MEDIA_RAW_AUDIO) {
|
||||||
TRACE("_SoundPlayNode::PrepareToConnect: non raw format, returning "
|
TRACE("SoundPlayNode::PrepareToConnect: non raw format, returning "
|
||||||
"B_MEDIA_BAD_FORMAT\n");
|
"B_MEDIA_BAD_FORMAT\n");
|
||||||
return B_MEDIA_BAD_FORMAT;
|
return B_MEDIA_BAD_FORMAT;
|
||||||
}
|
}
|
||||||
@@ -354,7 +355,7 @@ _SoundPlayNode::PrepareToConnect(const media_source& what,
|
|||||||
&& *(uint32 *)&format->user_data[44] == FORMAT_USER_DATA_MAGIC_2) {
|
&& *(uint32 *)&format->user_data[44] == FORMAT_USER_DATA_MAGIC_2) {
|
||||||
channel_count = *(uint32 *)&format->user_data[4];
|
channel_count = *(uint32 *)&format->user_data[4];
|
||||||
frame_rate = *(float *)&format->user_data[20];
|
frame_rate = *(float *)&format->user_data[20];
|
||||||
TRACE("_SoundPlayNode::PrepareToConnect: found mixer info: "
|
TRACE("SoundPlayNode::PrepareToConnect: found mixer info: "
|
||||||
"channel_count %ld, frame_rate %.1f\n", channel_count, frame_rate);
|
"channel_count %ld, frame_rate %.1f\n", channel_count, frame_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,28 +378,28 @@ _SoundPlayNode::PrepareToConnect(const media_source& what,
|
|||||||
|
|
||||||
#if DEBUG > 0
|
#if DEBUG > 0
|
||||||
string_for_format(*format, buf, sizeof(buf));
|
string_for_format(*format, buf, sizeof(buf));
|
||||||
TRACE("_SoundPlayNode::PrepareToConnect: output format %s\n", buf);
|
TRACE("SoundPlayNode::PrepareToConnect: output format %s\n", buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Now reserve the connection, and return information about it
|
// Now reserve the connection, and return information about it
|
||||||
mOutput.destination = where;
|
fOutput.destination = where;
|
||||||
mOutput.format = *format;
|
fOutput.format = *format;
|
||||||
*_source = mOutput.source;
|
*_source = fOutput.source;
|
||||||
strcpy(_name, Name());
|
strcpy(_name, Name());
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::Connect(status_t error, const media_source& source,
|
SoundPlayNode::Connect(status_t error, const media_source& source,
|
||||||
const media_destination& destination, const media_format& format,
|
const media_destination& destination, const media_format& format,
|
||||||
char* name)
|
char* name)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// is this our output?
|
// is this our output?
|
||||||
if (source != mOutput.source) {
|
if (source != fOutput.source) {
|
||||||
TRACE("_SoundPlayNode::Connect returning\n");
|
TRACE("SoundPlayNode::Connect returning\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,85 +407,85 @@ _SoundPlayNode::Connect(status_t error, const media_source& source,
|
|||||||
// a non-zero error code. When that happens we simply unreserve the
|
// a non-zero error code. When that happens we simply unreserve the
|
||||||
// connection and do nothing else.
|
// connection and do nothing else.
|
||||||
if (error) {
|
if (error) {
|
||||||
mOutput.destination = media_destination::null;
|
fOutput.destination = media_destination::null;
|
||||||
mOutput.format.type = B_MEDIA_RAW_AUDIO;
|
fOutput.format.type = B_MEDIA_RAW_AUDIO;
|
||||||
mOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
fOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Okay, the connection has been confirmed. Record the destination and
|
// Okay, the connection has been confirmed. Record the destination and
|
||||||
// format that we agreed on, and report our connection name again.
|
// format that we agreed on, and report our connection name again.
|
||||||
mOutput.destination = destination;
|
fOutput.destination = destination;
|
||||||
mOutput.format = format;
|
fOutput.format = format;
|
||||||
strcpy(name, Name());
|
strcpy(name, Name());
|
||||||
|
|
||||||
// Now that we're connected, we can determine our downstream latency.
|
// Now that we're connected, we can determine our downstream latency.
|
||||||
// Do so, then make sure we get our events early enough.
|
// Do so, then make sure we get our events early enough.
|
||||||
media_node_id id;
|
media_node_id id;
|
||||||
FindLatencyFor(mOutput.destination, &mLatency, &id);
|
FindLatencyFor(fOutput.destination, &fLatency, &id);
|
||||||
TRACE("_SoundPlayNode::Connect: downstream latency = %Ld\n", mLatency);
|
TRACE("SoundPlayNode::Connect: downstream latency = %Ld\n", fLatency);
|
||||||
|
|
||||||
// reset our buffer duration, etc. to avoid later calculations
|
// reset our buffer duration, etc. to avoid later calculations
|
||||||
bigtime_t duration = ((mOutput.format.u.raw_audio.buffer_size * 1000000LL)
|
bigtime_t duration = ((fOutput.format.u.raw_audio.buffer_size * 1000000LL)
|
||||||
/ ((mOutput.format.u.raw_audio.format
|
/ ((fOutput.format.u.raw_audio.format
|
||||||
& media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
& media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
||||||
* mOutput.format.u.raw_audio.channel_count))
|
* fOutput.format.u.raw_audio.channel_count))
|
||||||
/ (int32)mOutput.format.u.raw_audio.frame_rate;
|
/ (int32)fOutput.format.u.raw_audio.frame_rate;
|
||||||
SetBufferDuration(duration);
|
SetBufferDuration(duration);
|
||||||
TRACE("_SoundPlayNode::Connect: buffer duration is %Ld\n", duration);
|
TRACE("SoundPlayNode::Connect: buffer duration is %Ld\n", duration);
|
||||||
|
|
||||||
mInternalLatency = (3 * BufferDuration()) / 4;
|
fInternalLatency = (3 * BufferDuration()) / 4;
|
||||||
TRACE("_SoundPlayNode::Connect: using %Ld as internal latency\n",
|
TRACE("SoundPlayNode::Connect: using %Ld as internal latency\n",
|
||||||
mInternalLatency);
|
fInternalLatency);
|
||||||
SetEventLatency(mLatency + mInternalLatency);
|
SetEventLatency(fLatency + fInternalLatency);
|
||||||
|
|
||||||
// Set up the buffer group for our connection, as long as nobody handed us
|
// Set up the buffer group for our connection, as long as nobody handed us
|
||||||
// a buffer group (via SetBufferGroup()) prior to this.
|
// a buffer group (via SetBufferGroup()) prior to this.
|
||||||
// That can happen, for example, if the consumer calls SetOutputBuffersFor()
|
// That can happen, for example, if the consumer calls SetOutputBuffersFor()
|
||||||
// on us from within its Connected() method.
|
// on us from within its Connected() method.
|
||||||
if (!mBufferGroup)
|
if (!fBufferGroup)
|
||||||
AllocateBuffers();
|
AllocateBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::Disconnect(const media_source& what,
|
SoundPlayNode::Disconnect(const media_source& what,
|
||||||
const media_destination& where)
|
const media_destination& where)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// is this our output?
|
// is this our output?
|
||||||
if (what != mOutput.source) {
|
if (what != fOutput.source) {
|
||||||
TRACE("_SoundPlayNode::Disconnect returning\n");
|
TRACE("SoundPlayNode::Disconnect returning\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that our connection is the one being disconnected
|
// Make sure that our connection is the one being disconnected
|
||||||
if (where == mOutput.destination && what == mOutput.source) {
|
if (where == fOutput.destination && what == fOutput.source) {
|
||||||
mOutput.destination = media_destination::null;
|
fOutput.destination = media_destination::null;
|
||||||
mOutput.format.type = B_MEDIA_RAW_AUDIO;
|
fOutput.format.type = B_MEDIA_RAW_AUDIO;
|
||||||
mOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
fOutput.format.u.raw_audio = media_multi_audio_format::wildcard;
|
||||||
delete mBufferGroup;
|
delete fBufferGroup;
|
||||||
mBufferGroup = NULL;
|
fBufferGroup = NULL;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "\tDisconnect() called with wrong source/destination (%ld/%ld), ours is (%ld/%ld)\n",
|
fprintf(stderr, "\tDisconnect() called with wrong source/destination (%ld/%ld), ours is (%ld/%ld)\n",
|
||||||
what.id, where.id, mOutput.source.id, mOutput.destination.id);
|
what.id, where.id, fOutput.source.id, fOutput.destination.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::LateNoticeReceived(const media_source& what, bigtime_t howMuch,
|
SoundPlayNode::LateNoticeReceived(const media_source& what, bigtime_t howMuch,
|
||||||
bigtime_t performanceTime)
|
bigtime_t performanceTime)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
TRACE("_SoundPlayNode::LateNoticeReceived, %Ld too late at %Ld\n", howMuch,
|
TRACE("SoundPlayNode::LateNoticeReceived, %Ld too late at %Ld\n", howMuch,
|
||||||
performanceTime);
|
performanceTime);
|
||||||
|
|
||||||
// is this our output?
|
// is this our output?
|
||||||
if (what != mOutput.source) {
|
if (what != fOutput.source) {
|
||||||
TRACE("_SoundPlayNode::LateNoticeReceived returning\n");
|
TRACE("SoundPlayNode::LateNoticeReceived returning\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,31 +496,31 @@ _SoundPlayNode::LateNoticeReceived(const media_source& what, bigtime_t howMuch,
|
|||||||
// that at the moment, so we try to start producing buffers earlier to
|
// that at the moment, so we try to start producing buffers earlier to
|
||||||
// compensate.
|
// compensate.
|
||||||
|
|
||||||
mInternalLatency += howMuch;
|
fInternalLatency += howMuch;
|
||||||
|
|
||||||
if (mInternalLatency > 30000) // avoid getting a too high latency
|
if (fInternalLatency > 30000) // avoid getting a too high latency
|
||||||
mInternalLatency = 30000;
|
fInternalLatency = 30000;
|
||||||
|
|
||||||
SetEventLatency(mLatency + mInternalLatency);
|
SetEventLatency(fLatency + fInternalLatency);
|
||||||
TRACE("_SoundPlayNode::LateNoticeReceived: increasing latency to %Ld\n", mLatency + mInternalLatency);
|
TRACE("SoundPlayNode::LateNoticeReceived: increasing latency to %Ld\n", fLatency + fInternalLatency);
|
||||||
} else {
|
} else {
|
||||||
// The other run modes dictate various strategies for sacrificing data quality
|
// The other run modes dictate various strategies for sacrificing data quality
|
||||||
// in the interests of timely data delivery. The way *we* do this is to skip
|
// in the interests of timely data delivery. The way *we* do this is to skip
|
||||||
// a buffer, which catches us up in time by one buffer duration.
|
// a buffer, which catches us up in time by one buffer duration.
|
||||||
|
|
||||||
size_t nFrames = mOutput.format.u.raw_audio.buffer_size
|
size_t nFrames = fOutput.format.u.raw_audio.buffer_size
|
||||||
/ ((mOutput.format.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
/ ((fOutput.format.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
||||||
* mOutput.format.u.raw_audio.channel_count);
|
* fOutput.format.u.raw_audio.channel_count);
|
||||||
|
|
||||||
mFramesSent += nFrames;
|
fFramesSent += nFrames;
|
||||||
|
|
||||||
TRACE("_SoundPlayNode::LateNoticeReceived: skipping a buffer to try to catch up\n");
|
TRACE("SoundPlayNode::LateNoticeReceived: skipping a buffer to try to catch up\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::EnableOutput(const media_source& what, bool enabled,
|
SoundPlayNode::EnableOutput(const media_source& what, bool enabled,
|
||||||
int32* /* deprecated */)
|
int32* /* deprecated */)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -531,17 +532,17 @@ _SoundPlayNode::EnableOutput(const media_source& what, bool enabled,
|
|||||||
// matches, then set the enable state accordingly.
|
// matches, then set the enable state accordingly.
|
||||||
|
|
||||||
// is this our output?
|
// is this our output?
|
||||||
if (what != mOutput.source) {
|
if (what != fOutput.source) {
|
||||||
fprintf(stderr, "_SoundPlayNode::EnableOutput returning\n");
|
fprintf(stderr, "SoundPlayNode::EnableOutput returning\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutputEnabled = enabled;
|
fOutputEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::AdditionalBufferRequested(const media_source& source,
|
SoundPlayNode::AdditionalBufferRequested(const media_source& source,
|
||||||
media_buffer_id previousBuffer, bigtime_t previousTime,
|
media_buffer_id previousBuffer, bigtime_t previousTime,
|
||||||
const media_seek_tag* previousTag)
|
const media_seek_tag* previousTag)
|
||||||
{
|
{
|
||||||
@@ -552,22 +553,22 @@ _SoundPlayNode::AdditionalBufferRequested(const media_source& source,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::LatencyChanged(const media_source& source,
|
SoundPlayNode::LatencyChanged(const media_source& source,
|
||||||
const media_destination& destination, bigtime_t newLatency, uint32 flags)
|
const media_destination& destination, bigtime_t newLatency, uint32 flags)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
TRACE("_SoundPlayNode::LatencyChanged: new_latency %Ld\n", newLatency);
|
TRACE("SoundPlayNode::LatencyChanged: new_latency %Ld\n", newLatency);
|
||||||
|
|
||||||
// something downstream changed latency, so we need to start producing
|
// something downstream changed latency, so we need to start producing
|
||||||
// buffers earlier (or later) than we were previously. Make sure that the
|
// buffers earlier (or later) than we were previously. Make sure that the
|
||||||
// connection that changed is ours, and adjust to the new downstream
|
// connection that changed is ours, and adjust to the new downstream
|
||||||
// latency if so.
|
// latency if so.
|
||||||
if (source == mOutput.source && destination == mOutput.destination) {
|
if (source == fOutput.source && destination == fOutput.destination) {
|
||||||
mLatency = newLatency;
|
fLatency = newLatency;
|
||||||
SetEventLatency(mLatency + mInternalLatency);
|
SetEventLatency(fLatency + fInternalLatency);
|
||||||
} else {
|
} else {
|
||||||
TRACE("_SoundPlayNode::LatencyChanged: ignored\n");
|
TRACE("SoundPlayNode::LatencyChanged: ignored\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,7 +577,7 @@ _SoundPlayNode::LatencyChanged(const media_source& source,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::HandleEvent(const media_timed_event* event, bigtime_t lateness,
|
SoundPlayNode::HandleEvent(const media_timed_event* event, bigtime_t lateness,
|
||||||
bool realTimeEvent)
|
bool realTimeEvent)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -619,7 +620,7 @@ _SoundPlayNode::HandleEvent(const media_timed_event* event, bigtime_t lateness,
|
|||||||
// how should we handle late buffers? drop them?
|
// how should we handle late buffers? drop them?
|
||||||
// notify the producer?
|
// notify the producer?
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::SendNewBuffer(const media_timed_event* event,
|
SoundPlayNode::SendNewBuffer(const media_timed_event* event,
|
||||||
bigtime_t lateness, bool realTimeEvent)
|
bigtime_t lateness, bool realTimeEvent)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -627,7 +628,7 @@ _SoundPlayNode::SendNewBuffer(const media_timed_event* event,
|
|||||||
|
|
||||||
// make sure we're both started *and* connected before delivering a buffer
|
// make sure we're both started *and* connected before delivering a buffer
|
||||||
if (RunState() != BMediaEventLooper::B_STARTED
|
if (RunState() != BMediaEventLooper::B_STARTED
|
||||||
|| mOutput.destination == media_destination::null)
|
|| fOutput.destination == media_destination::null)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// The event->event_time is the time at which the buffer we are preparing
|
// The event->event_time is the time at which the buffer we are preparing
|
||||||
@@ -637,12 +638,12 @@ _SoundPlayNode::SendNewBuffer(const media_timed_event* event,
|
|||||||
// lateness is independent of EventLatency()!
|
// lateness is independent of EventLatency()!
|
||||||
|
|
||||||
if (lateness > (BufferDuration() / 3) ) {
|
if (lateness > (BufferDuration() / 3) ) {
|
||||||
printf("_SoundPlayNode::SendNewBuffer, event scheduled much too late, "
|
printf("SoundPlayNode::SendNewBuffer, event scheduled much too late, "
|
||||||
"lateness is %Ld\n", lateness);
|
"lateness is %Ld\n", lateness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip buffer creation if output not enabled
|
// skip buffer creation if output not enabled
|
||||||
if (mOutputEnabled) {
|
if (fOutputEnabled) {
|
||||||
|
|
||||||
// Get the next buffer of data
|
// Get the next buffer of data
|
||||||
BBuffer* buffer = FillNextBuffer(event->event_time);
|
BBuffer* buffer = FillNextBuffer(event->event_time);
|
||||||
@@ -651,26 +652,26 @@ _SoundPlayNode::SendNewBuffer(const media_timed_event* event,
|
|||||||
|
|
||||||
// If we are ready way too early, decrase internal latency
|
// If we are ready way too early, decrase internal latency
|
||||||
/*
|
/*
|
||||||
bigtime_t how_early = event->event_time - TimeSource()->Now() - mLatency - mInternalLatency;
|
bigtime_t how_early = event->event_time - TimeSource()->Now() - fLatency - fInternalLatency;
|
||||||
if (how_early > 5000) {
|
if (how_early > 5000) {
|
||||||
|
|
||||||
printf("_SoundPlayNode::SendNewBuffer, event scheduled too early, how_early is %Ld\n", how_early);
|
printf("SoundPlayNode::SendNewBuffer, event scheduled too early, how_early is %Ld\n", how_early);
|
||||||
|
|
||||||
if (mTooEarlyCount++ == 5) {
|
if (fTooEarlyCount++ == 5) {
|
||||||
mInternalLatency -= how_early;
|
fInternalLatency -= how_early;
|
||||||
if (mInternalLatency < 500)
|
if (fInternalLatency < 500)
|
||||||
mInternalLatency = 500;
|
fInternalLatency = 500;
|
||||||
printf("_SoundPlayNode::SendNewBuffer setting internal latency to %Ld\n", mInternalLatency);
|
printf("SoundPlayNode::SendNewBuffer setting internal latency to %Ld\n", fInternalLatency);
|
||||||
SetEventLatency(mLatency + mInternalLatency);
|
SetEventLatency(fLatency + fInternalLatency);
|
||||||
mTooEarlyCount = 0;
|
fTooEarlyCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// send the buffer downstream if and only if output is enabled
|
// send the buffer downstream if and only if output is enabled
|
||||||
if (B_OK != SendBuffer(buffer, mOutput.destination)) {
|
if (B_OK != SendBuffer(buffer, fOutput.destination)) {
|
||||||
// we need to recycle the buffer
|
// we need to recycle the buffer
|
||||||
// if the call to SendBuffer() fails
|
// if the call to SendBuffer() fails
|
||||||
printf("_SoundPlayNode::SendNewBuffer: Buffer sending "
|
printf("SoundPlayNode::SendNewBuffer: Buffer sending "
|
||||||
"failed\n");
|
"failed\n");
|
||||||
buffer->Recycle();
|
buffer->Recycle();
|
||||||
}
|
}
|
||||||
@@ -678,17 +679,17 @@ _SoundPlayNode::SendNewBuffer(const media_timed_event* event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// track how much media we've delivered so far
|
// track how much media we've delivered so far
|
||||||
size_t nFrames = mOutput.format.u.raw_audio.buffer_size
|
size_t nFrames = fOutput.format.u.raw_audio.buffer_size
|
||||||
/ ((mOutput.format.u.raw_audio.format
|
/ ((fOutput.format.u.raw_audio.format
|
||||||
& media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
& media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
||||||
* mOutput.format.u.raw_audio.channel_count);
|
* fOutput.format.u.raw_audio.channel_count);
|
||||||
mFramesSent += nFrames;
|
fFramesSent += nFrames;
|
||||||
|
|
||||||
// The buffer is on its way; now schedule the next one to go
|
// The buffer is on its way; now schedule the next one to go
|
||||||
// nextEvent is the time at which the buffer should arrive at it's
|
// nextEvent is the time at which the buffer should arrive at it's
|
||||||
// destination
|
// destination
|
||||||
bigtime_t nextEvent = mStartTime + bigtime_t((1000000LL * mFramesSent)
|
bigtime_t nextEvent = fStartTime + bigtime_t((1000000LL * fFramesSent)
|
||||||
/ (int32)mOutput.format.u.raw_audio.frame_rate);
|
/ (int32)fOutput.format.u.raw_audio.frame_rate);
|
||||||
media_timed_event nextBufferEvent(nextEvent, SEND_NEW_BUFFER_EVENT);
|
media_timed_event nextBufferEvent(nextEvent, SEND_NEW_BUFFER_EVENT);
|
||||||
EventQueue()->AddEvent(nextBufferEvent);
|
EventQueue()->AddEvent(nextBufferEvent);
|
||||||
|
|
||||||
@@ -697,10 +698,10 @@ _SoundPlayNode::SendNewBuffer(const media_timed_event* event,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::HandleDataStatus(const media_timed_event* event,
|
SoundPlayNode::HandleDataStatus(const media_timed_event* event,
|
||||||
bigtime_t lateness, bool realTimeEvent)
|
bigtime_t lateness, bool realTimeEvent)
|
||||||
{
|
{
|
||||||
TRACE("_SoundPlayNode::HandleDataStatus status: %li, lateness: %Li\n",
|
TRACE("SoundPlayNode::HandleDataStatus status: %li, lateness: %Li\n",
|
||||||
event->data, lateness);
|
event->data, lateness);
|
||||||
|
|
||||||
switch (event->data) {
|
switch (event->data) {
|
||||||
@@ -718,7 +719,7 @@ _SoundPlayNode::HandleDataStatus(const media_timed_event* event,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::HandleStart(const media_timed_event* event, bigtime_t lateness,
|
SoundPlayNode::HandleStart(const media_timed_event* event, bigtime_t lateness,
|
||||||
bool realTimeEvent)
|
bool realTimeEvent)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -727,8 +728,8 @@ _SoundPlayNode::HandleStart(const media_timed_event* event, bigtime_t lateness,
|
|||||||
// We want to start sending buffers now, so we set up the buffer-sending
|
// We want to start sending buffers now, so we set up the buffer-sending
|
||||||
// bookkeeping and fire off the first "produce a buffer" event.
|
// bookkeeping and fire off the first "produce a buffer" event.
|
||||||
|
|
||||||
mFramesSent = 0;
|
fFramesSent = 0;
|
||||||
mStartTime = event->event_time;
|
fStartTime = event->event_time;
|
||||||
media_timed_event firstBufferEvent(event->event_time,
|
media_timed_event firstBufferEvent(event->event_time,
|
||||||
SEND_NEW_BUFFER_EVENT);
|
SEND_NEW_BUFFER_EVENT);
|
||||||
|
|
||||||
@@ -744,18 +745,18 @@ _SoundPlayNode::HandleStart(const media_timed_event* event, bigtime_t lateness,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::HandleSeek(const media_timed_event* event, bigtime_t lateness,
|
SoundPlayNode::HandleSeek(const media_timed_event* event, bigtime_t lateness,
|
||||||
bool realTimeEvent)
|
bool realTimeEvent)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
TRACE("_SoundPlayNode::HandleSeek(t=%lld, d=%li, bd=%lld)\n",
|
TRACE("SoundPlayNode::HandleSeek(t=%lld, d=%li, bd=%lld)\n",
|
||||||
event->event_time, event->data, event->bigdata);
|
event->event_time, event->data, event->bigdata);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::HandleWarp(const media_timed_event* event, bigtime_t lateness,
|
SoundPlayNode::HandleWarp(const media_timed_event* event, bigtime_t lateness,
|
||||||
bool realTimeEvent)
|
bool realTimeEvent)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -764,7 +765,7 @@ _SoundPlayNode::HandleWarp(const media_timed_event* event, bigtime_t lateness,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::HandleStop(const media_timed_event* event, bigtime_t lateness,
|
SoundPlayNode::HandleStop(const media_timed_event* event, bigtime_t lateness,
|
||||||
bool realTimeEvent)
|
bool realTimeEvent)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -777,7 +778,7 @@ _SoundPlayNode::HandleStop(const media_timed_event* event, bigtime_t lateness,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_SoundPlayNode::HandleParameter(const media_timed_event* event,
|
SoundPlayNode::HandleParameter(const media_timed_event* event,
|
||||||
bigtime_t lateness, bool realTimeEvent)
|
bigtime_t lateness, bool realTimeEvent)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
@@ -786,60 +787,63 @@ _SoundPlayNode::HandleParameter(const media_timed_event* event,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_SoundPlayNode::AllocateBuffers()
|
SoundPlayNode::AllocateBuffers()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// allocate enough buffers to span our downstream latency, plus one
|
// allocate enough buffers to span our downstream latency, plus one
|
||||||
size_t size = mOutput.format.u.raw_audio.buffer_size;
|
size_t size = fOutput.format.u.raw_audio.buffer_size;
|
||||||
int32 count = int32(mLatency / BufferDuration() + 1 + 1);
|
int32 count = int32(fLatency / BufferDuration() + 1 + 1);
|
||||||
|
|
||||||
TRACE("_SoundPlayNode::AllocateBuffers: latency = %Ld, buffer duration "
|
TRACE("SoundPlayNode::AllocateBuffers: latency = %Ld, buffer duration "
|
||||||
"= %Ld, count %ld\n", mLatency, BufferDuration(), count);
|
"= %Ld, count %ld\n", fLatency, BufferDuration(), count);
|
||||||
|
|
||||||
if (count < 3)
|
if (count < 3)
|
||||||
count = 3;
|
count = 3;
|
||||||
|
|
||||||
TRACE("_SoundPlayNode::AllocateBuffers: creating group of %ld buffers, "
|
TRACE("SoundPlayNode::AllocateBuffers: creating group of %ld buffers, "
|
||||||
"size = %lu\n", count, size);
|
"size = %lu\n", count, size);
|
||||||
|
|
||||||
mBufferGroup = new BBufferGroup(size, count);
|
fBufferGroup = new BBufferGroup(size, count);
|
||||||
if (mBufferGroup->InitCheck() != B_OK) {
|
if (fBufferGroup->InitCheck() != B_OK) {
|
||||||
ERROR("_SoundPlayNode::AllocateBuffers: BufferGroup::InitCheck() "
|
ERROR("SoundPlayNode::AllocateBuffers: BufferGroup::InitCheck() "
|
||||||
"failed\n");
|
"failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBuffer*
|
BBuffer*
|
||||||
_SoundPlayNode::FillNextBuffer(bigtime_t event_time)
|
SoundPlayNode::FillNextBuffer(bigtime_t eventTime)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// get a buffer from our buffer group
|
// get a buffer from our buffer group
|
||||||
BBuffer* buf = mBufferGroup->RequestBuffer(
|
BBuffer* buffer = fBufferGroup->RequestBuffer(
|
||||||
mOutput.format.u.raw_audio.buffer_size, BufferDuration() / 2);
|
fOutput.format.u.raw_audio.buffer_size, BufferDuration() / 2);
|
||||||
|
|
||||||
// If we fail to get a buffer (for example, if the request times out), we
|
// If we fail to get a buffer (for example, if the request times out), we
|
||||||
// skip this buffer and go on to the next, to avoid locking up the control
|
// skip this buffer and go on to the next, to avoid locking up the control
|
||||||
// thread
|
// thread
|
||||||
if (!buf) {
|
if (buffer == NULL) {
|
||||||
ERROR("_SoundPlayNode::FillNextBuffer: RequestBuffer failed\n");
|
ERROR("SoundPlayNode::FillNextBuffer: RequestBuffer failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPlayer->HasData()) {
|
if (fPlayer->HasData()) {
|
||||||
mPlayer->_PlayBuffer(buf->Data(),
|
fPlayer->_PlayBuffer(buffer->Data(),
|
||||||
mOutput.format.u.raw_audio.buffer_size, mOutput.format.u.raw_audio);
|
fOutput.format.u.raw_audio.buffer_size, fOutput.format.u.raw_audio);
|
||||||
} else {
|
} else
|
||||||
memset(buf->Data(), 0, mOutput.format.u.raw_audio.buffer_size);
|
memset(buffer->Data(), 0, fOutput.format.u.raw_audio.buffer_size);
|
||||||
}
|
|
||||||
|
|
||||||
// fill in the buffer header
|
// fill in the buffer header
|
||||||
media_header* hdr = buf->Header();
|
media_header* header = buffer->Header();
|
||||||
hdr->type = B_MEDIA_RAW_AUDIO;
|
header->type = B_MEDIA_RAW_AUDIO;
|
||||||
hdr->size_used = mOutput.format.u.raw_audio.buffer_size;
|
header->size_used = fOutput.format.u.raw_audio.buffer_size;
|
||||||
hdr->time_source = TimeSource()->ID();
|
header->time_source = TimeSource()->ID();
|
||||||
hdr->start_time = event_time;
|
header->start_time = eventTime;
|
||||||
return buf;
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|||||||
+87
-112
@@ -1,177 +1,152 @@
|
|||||||
#ifndef _SOUND_PLAY_NODE_
|
/*
|
||||||
#define _SOUND_PLAY_NODE_
|
* Copyright 2002-2009, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Marcus Overhagen
|
||||||
|
* Jérôme Duval
|
||||||
|
*/
|
||||||
|
#ifndef _SOUND_PLAY_NODE_H
|
||||||
|
#define _SOUND_PLAY_NODE_H
|
||||||
|
|
||||||
|
|
||||||
#include <BufferProducer.h>
|
|
||||||
#include <MediaEventLooper.h>
|
|
||||||
#include <Buffer.h>
|
#include <Buffer.h>
|
||||||
#include <BufferGroup.h>
|
#include <BufferGroup.h>
|
||||||
#include "SoundPlayer.h"
|
#include <BufferProducer.h>
|
||||||
|
#include <MediaEventLooper.h>
|
||||||
|
#include <SoundPlayer.h>
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* AUTHOR: Marcus Overhagen, Jérôme Duval
|
|
||||||
* FILE: SoundPlayNode.h
|
|
||||||
* DESCR: This is the BBufferProducer, used internally by BSoundPlayer
|
|
||||||
* This belongs into a private namespace, but isn't for
|
|
||||||
* compatibility reasons.
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
class _SoundPlayNode
|
namespace BPrivate {
|
||||||
: public BBufferProducer, public BMediaEventLooper
|
|
||||||
{
|
|
||||||
|
class SoundPlayNode : public BBufferProducer, public BMediaEventLooper {
|
||||||
public:
|
public:
|
||||||
_SoundPlayNode(const char *name, BSoundPlayer *player);
|
SoundPlayNode(const char* name,
|
||||||
~_SoundPlayNode();
|
BSoundPlayer* player);
|
||||||
|
virtual ~SoundPlayNode();
|
||||||
|
|
||||||
bool IsPlaying();
|
bool IsPlaying();
|
||||||
bigtime_t CurrentTime();
|
bigtime_t CurrentTime();
|
||||||
|
|
||||||
/*************************/
|
// BMediaNode methods
|
||||||
/* begin from BMediaNode */
|
|
||||||
public:
|
virtual BMediaAddOn* AddOn(int32* _internalID) const;
|
||||||
virtual BMediaAddOn* AddOn(
|
|
||||||
int32 * internal_id) const; /* Who instantiated you -- or NULL for app class */
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* These don't return errors; instead, they use the global error condition reporter. */
|
virtual void Preroll();
|
||||||
/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
|
|
||||||
/* and is recommended to allow for at least one pending command of each type. */
|
|
||||||
/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
|
|
||||||
/* cannot depend on that happening. */
|
|
||||||
virtual void Preroll(void);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual status_t HandleMessage(
|
virtual status_t HandleMessage(int32 message, const void* data,
|
||||||
int32 message,
|
|
||||||
const void * data,
|
|
||||||
size_t size);
|
size_t size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void NodeRegistered(void); /* reserved 2 */
|
virtual void NodeRegistered();
|
||||||
virtual status_t RequestCompleted(const media_request_info &info);
|
virtual status_t RequestCompleted(
|
||||||
virtual void SetTimeSource(BTimeSource *timeSource);
|
const media_request_info& info);
|
||||||
virtual void SetRunMode(run_mode mode);
|
virtual void SetTimeSource(BTimeSource* timeSource);
|
||||||
|
virtual void SetRunMode(run_mode mode);
|
||||||
|
|
||||||
/* end from BMediaNode */
|
// BBufferProducer methods
|
||||||
/***********************/
|
|
||||||
|
|
||||||
/******************************/
|
virtual status_t FormatSuggestionRequested(media_type type,
|
||||||
/* begin from BBufferProducer */
|
int32 quality, media_format* format);
|
||||||
|
|
||||||
virtual status_t FormatSuggestionRequested( media_type type,
|
virtual status_t FormatProposal(const media_source& output,
|
||||||
int32 quality,
|
|
||||||
media_format* format);
|
media_format* format);
|
||||||
|
|
||||||
virtual status_t FormatProposal( const media_source& output,
|
virtual status_t FormatChangeRequested(
|
||||||
media_format* format);
|
const media_source& source,
|
||||||
|
|
||||||
virtual status_t FormatChangeRequested( const media_source& source,
|
|
||||||
const media_destination& destination,
|
const media_destination& destination,
|
||||||
media_format* io_format,
|
media_format* format, int32* _deprecated_);
|
||||||
int32* _deprecated_);
|
virtual status_t GetNextOutput(int32* cookie,
|
||||||
virtual status_t GetNextOutput( int32* cookie,
|
media_output* _output);
|
||||||
media_output* out_output);
|
virtual status_t DisposeOutputCookie(int32 cookie);
|
||||||
virtual status_t DisposeOutputCookie( int32 cookie);
|
|
||||||
|
|
||||||
virtual status_t SetBufferGroup( const media_source& for_source,
|
virtual status_t SetBufferGroup(const media_source& forSource,
|
||||||
BBufferGroup* group);
|
BBufferGroup* group);
|
||||||
virtual status_t GetLatency( bigtime_t * out_latency);
|
virtual status_t GetLatency(bigtime_t* _latency);
|
||||||
|
|
||||||
virtual status_t PrepareToConnect( const media_source& what,
|
virtual status_t PrepareToConnect(const media_source& what,
|
||||||
const media_destination& where,
|
const media_destination& where,
|
||||||
media_format* format,
|
media_format* format, media_source* _source,
|
||||||
media_source* out_source,
|
char* _name);
|
||||||
char* out_name);
|
|
||||||
|
|
||||||
virtual void Connect( status_t error,
|
virtual void Connect(status_t error,
|
||||||
const media_source& source,
|
const media_source& source,
|
||||||
const media_destination& destination,
|
const media_destination& destination,
|
||||||
const media_format& format,
|
const media_format& format,
|
||||||
char* io_name);
|
char* name);
|
||||||
|
|
||||||
virtual void Disconnect( const media_source& what,
|
virtual void Disconnect(const media_source& what,
|
||||||
const media_destination& where);
|
const media_destination& where);
|
||||||
|
|
||||||
virtual void LateNoticeReceived( const media_source& what,
|
virtual void LateNoticeReceived(const media_source& what,
|
||||||
bigtime_t how_much,
|
bigtime_t howMuch,
|
||||||
bigtime_t performance_time);
|
bigtime_t performanceTime);
|
||||||
|
|
||||||
virtual void EnableOutput( const media_source & what,
|
virtual void EnableOutput(const media_source& what,
|
||||||
bool enabled,
|
bool enabled, int32* _deprecated_);
|
||||||
int32* _deprecated_);
|
virtual void AdditionalBufferRequested(
|
||||||
virtual void AdditionalBufferRequested( const media_source& source,
|
const media_source& source,
|
||||||
media_buffer_id prev_buffer,
|
media_buffer_id previousBuffer,
|
||||||
bigtime_t prev_time,
|
bigtime_t previousTime,
|
||||||
const media_seek_tag* prev_tag);
|
const media_seek_tag* previousTag);
|
||||||
virtual void LatencyChanged( const media_source& source,
|
virtual void LatencyChanged(const media_source& source,
|
||||||
const media_destination& destination,
|
const media_destination& destination,
|
||||||
bigtime_t new_latency,
|
bigtime_t newLatency, uint32 flags);
|
||||||
uint32 flags);
|
|
||||||
/* end from BBufferProducer */
|
|
||||||
/****************************/
|
|
||||||
|
|
||||||
/********************************/
|
// BMediaEventLooper methods
|
||||||
/* start from BMediaEventLooper */
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* you must override to handle your events! */
|
virtual void HandleEvent(const media_timed_event* event,
|
||||||
/* you should not call HandleEvent directly */
|
|
||||||
virtual void HandleEvent( const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
|
|
||||||
/* end from BMediaEventLooper */
|
|
||||||
/******************************/
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
media_multi_audio_format Format() const;
|
media_multi_audio_format Format() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual status_t HandleStart(const media_timed_event* event,
|
||||||
virtual status_t HandleStart(
|
|
||||||
const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
virtual status_t HandleSeek(
|
virtual status_t HandleSeek(const media_timed_event* event,
|
||||||
const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
virtual status_t HandleWarp(
|
virtual status_t HandleWarp(const media_timed_event* event,
|
||||||
const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
virtual status_t HandleStop(
|
virtual status_t HandleStop(const media_timed_event* event,
|
||||||
const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
virtual status_t SendNewBuffer(
|
virtual status_t SendNewBuffer(const media_timed_event* event,
|
||||||
const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
virtual status_t HandleDataStatus(
|
virtual status_t HandleDataStatus(const media_timed_event* event,
|
||||||
const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
virtual status_t HandleParameter(
|
virtual status_t HandleParameter(const media_timed_event* event,
|
||||||
const media_timed_event *event,
|
|
||||||
bigtime_t lateness,
|
bigtime_t lateness,
|
||||||
bool realTimeEvent = false);
|
bool realTimeEvent = false);
|
||||||
|
|
||||||
void AllocateBuffers();
|
void AllocateBuffers();
|
||||||
BBuffer* FillNextBuffer(bigtime_t event_time);
|
BBuffer* FillNextBuffer(bigtime_t eventTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BSoundPlayer *mPlayer;
|
BSoundPlayer* fPlayer;
|
||||||
|
|
||||||
status_t mInitCheckStatus;
|
status_t fInitStatus;
|
||||||
bool mOutputEnabled;
|
bool fOutputEnabled;
|
||||||
media_output mOutput;
|
media_output fOutput;
|
||||||
BBufferGroup *mBufferGroup;
|
BBufferGroup* fBufferGroup;
|
||||||
media_format mFormat;
|
bigtime_t fLatency;
|
||||||
bigtime_t mLatency;
|
bigtime_t fInternalLatency;
|
||||||
bigtime_t mInternalLatency;
|
bigtime_t fStartTime;
|
||||||
bigtime_t mStartTime;
|
uint64 fFramesSent;
|
||||||
uint64 mFramesSent;
|
int32 fTooEarlyCount;
|
||||||
int32 mTooEarlyCount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _SOUND_PLAY_NODE_H
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define atomic_read(a) atomic_or(a, 0)
|
|
||||||
|
|
||||||
// Flags used internally in BSoundPlayer
|
// Flags used internally in BSoundPlayer
|
||||||
enum {
|
enum {
|
||||||
@@ -293,10 +292,10 @@ BSoundPlayer::Latency()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BSoundPlayer::SetHasData(bool has_data)
|
BSoundPlayer::SetHasData(bool hasData)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (has_data)
|
if (hasData)
|
||||||
atomic_or(&fFlags, F_HAS_DATA);
|
atomic_or(&fFlags, F_HAS_DATA);
|
||||||
else
|
else
|
||||||
atomic_and(&fFlags, ~F_HAS_DATA);
|
atomic_and(&fFlags, ~F_HAS_DATA);
|
||||||
@@ -307,7 +306,7 @@ bool
|
|||||||
BSoundPlayer::HasData()
|
BSoundPlayer::HasData()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
return (atomic_read(&fFlags) & F_HAS_DATA) != 0;
|
return (atomic_get(&fFlags) & F_HAS_DATA) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -445,7 +444,7 @@ BSoundPlayer::StartPlaying(BSound* sound, bigtime_t atTime, float withVolume)
|
|||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
// TODO: support the at_time and with_volume parameters
|
// TODO: support the at_time and with_volume parameters
|
||||||
_playing_sound *item = (_playing_sound *)malloc(sizeof(_playing_sound));
|
playing_sound* item = (playing_sound*)malloc(sizeof(playing_sound));
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -478,7 +477,7 @@ BSoundPlayer::SetSoundVolume(play_id id, float newVolume)
|
|||||||
if (!fLocker.Lock())
|
if (!fLocker.Lock())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
_playing_sound *item = fPlayingSounds;
|
playing_sound *item = fPlayingSounds;
|
||||||
while (item) {
|
while (item) {
|
||||||
if (item->id == id) {
|
if (item->id == id) {
|
||||||
item->volume = newVolume;
|
item->volume = newVolume;
|
||||||
@@ -501,7 +500,7 @@ BSoundPlayer::IsPlaying(play_id id)
|
|||||||
if (!fLocker.Lock())
|
if (!fLocker.Lock())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
_playing_sound *item = fPlayingSounds;
|
playing_sound *item = fPlayingSounds;
|
||||||
while (item) {
|
while (item) {
|
||||||
if (item->id == id) {
|
if (item->id == id) {
|
||||||
fLocker.Unlock();
|
fLocker.Unlock();
|
||||||
@@ -523,8 +522,8 @@ BSoundPlayer::StopPlaying(play_id id)
|
|||||||
if (!fLocker.Lock())
|
if (!fLocker.Lock())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
_playing_sound** link = &fPlayingSounds;
|
playing_sound** link = &fPlayingSounds;
|
||||||
_playing_sound* item = fPlayingSounds;
|
playing_sound* item = fPlayingSounds;
|
||||||
|
|
||||||
while (item != NULL) {
|
while (item != NULL) {
|
||||||
if (item->id == id) {
|
if (item->id == id) {
|
||||||
@@ -557,7 +556,7 @@ BSoundPlayer::WaitForSound(play_id id)
|
|||||||
if (!fLocker.Lock())
|
if (!fLocker.Lock())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
_playing_sound* item = fPlayingSounds;
|
playing_sound* item = fPlayingSounds;
|
||||||
while (item != NULL) {
|
while (item != NULL) {
|
||||||
if (item->id == id) {
|
if (item->id == id) {
|
||||||
sem_id waitSem = item->wait_sem;
|
sem_id waitSem = item->wait_sem;
|
||||||
@@ -684,7 +683,7 @@ BSoundPlayer::_SoundPlayBufferFunc(void *cookie, void *buffer, size_t size,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_playing_sound *sound = player->fPlayingSounds;
|
playing_sound *sound = player->fPlayingSounds;
|
||||||
if (sound == NULL) {
|
if (sound == NULL) {
|
||||||
player->SetHasData(false);
|
player->SetHasData(false);
|
||||||
player->fLocker.Unlock();
|
player->fLocker.Unlock();
|
||||||
@@ -774,7 +773,7 @@ BSoundPlayer::_Init(const media_node* node,
|
|||||||
media_format tryFormat;
|
media_format tryFormat;
|
||||||
|
|
||||||
// Create the player node and register it
|
// Create the player node and register it
|
||||||
fPlayerNode = new _SoundPlayNode(name, this);
|
fPlayerNode = new BPrivate::SoundPlayNode(name, this);
|
||||||
fInitStatus = roster->RegisterNode(fPlayerNode);
|
fInitStatus = roster->RegisterNode(fPlayerNode);
|
||||||
if (fInitStatus != B_OK) {
|
if (fInitStatus != B_OK) {
|
||||||
TRACE("BSoundPlayer::_Init: Couldn't RegisterNode: %s\n",
|
TRACE("BSoundPlayer::_Init: Couldn't RegisterNode: %s\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user