style changes. Also added a TODO taken from a comment in bug #575
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27705 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -45,28 +45,33 @@
|
|||||||
const int32 kInitSoundCount = 32;
|
const int32 kInitSoundCount = 32;
|
||||||
const int32 kGrowth = 16;
|
const int32 kGrowth = 16;
|
||||||
|
|
||||||
static int32 deviceCount = 0;
|
static int32 sDeviceCount = 0;
|
||||||
static BGameSoundDevice* theDevice = NULL;
|
static BGameSoundDevice* sDevice = NULL;
|
||||||
|
|
||||||
BGameSoundDevice * GetDefaultDevice()
|
|
||||||
|
BGameSoundDevice *
|
||||||
|
GetDefaultDevice()
|
||||||
{
|
{
|
||||||
if (!theDevice)
|
if (!sDevice)
|
||||||
theDevice = new BGameSoundDevice();
|
sDevice = new BGameSoundDevice();
|
||||||
|
|
||||||
deviceCount++;
|
sDeviceCount++;
|
||||||
return theDevice;
|
return sDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReleaseDevice()
|
|
||||||
|
void
|
||||||
|
ReleaseDevice()
|
||||||
{
|
{
|
||||||
deviceCount--;
|
sDeviceCount--;
|
||||||
|
|
||||||
if (deviceCount <= 0) {
|
if (sDeviceCount <= 0) {
|
||||||
delete theDevice;
|
delete sDevice;
|
||||||
theDevice = NULL;
|
sDevice = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// BGameSoundDevice -------------------------------------------------------
|
// BGameSoundDevice -------------------------------------------------------
|
||||||
BGameSoundDevice::BGameSoundDevice()
|
BGameSoundDevice::BGameSoundDevice()
|
||||||
: fIsConnected(false),
|
: fIsConnected(false),
|
||||||
@@ -85,7 +90,7 @@ BGameSoundDevice::BGameSoundDevice()
|
|||||||
|
|
||||||
BGameSoundDevice::~BGameSoundDevice()
|
BGameSoundDevice::~BGameSoundDevice()
|
||||||
{
|
{
|
||||||
BMediaRoster* r = BMediaRoster::Roster();
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
|
||||||
// We need to stop all the sounds before we stop the mixer
|
// We need to stop all the sounds before we stop the mixer
|
||||||
for (int32 i = 0; i < fSoundCount; i++) {
|
for (int32 i = 0; i < fSoundCount; i++) {
|
||||||
@@ -96,20 +101,21 @@ BGameSoundDevice::~BGameSoundDevice()
|
|||||||
|
|
||||||
if (fIsConnected) {
|
if (fIsConnected) {
|
||||||
// stop the nodes if they are running
|
// stop the nodes if they are running
|
||||||
r->StopNode(fConnection->producer, 0, true); // synchronous stop
|
roster->StopNode(fConnection->producer, 0, true);
|
||||||
|
// synchronous stop
|
||||||
|
|
||||||
// Ordinarily we'd stop *all* of the nodes in the chain at this point. However,
|
// Ordinarily we'd stop *all* of the nodes in the chain at this point. However,
|
||||||
// one of the nodes is the System Mixer, and stopping the Mixer is a Bad Idea (tm).
|
// one of the nodes is the System Mixer, and stopping the Mixer is a Bad Idea (tm).
|
||||||
// So, we just disconnect from it, and release our references to the nodes that
|
// So, we just disconnect from it, and release our references to the nodes that
|
||||||
// we're using. We *are* supposed to do that even for global nodes like the Mixer.
|
// we're using. We *are* supposed to do that even for global nodes like the Mixer.
|
||||||
r->Disconnect(fConnection->producer.node, fConnection->source,
|
roster->Disconnect(fConnection->producer.node, fConnection->source,
|
||||||
fConnection->consumer.node, fConnection->destination);
|
fConnection->consumer.node, fConnection->destination);
|
||||||
|
|
||||||
r->ReleaseNode(fConnection->producer);
|
roster->ReleaseNode(fConnection->producer);
|
||||||
r->ReleaseNode(fConnection->consumer);
|
roster->ReleaseNode(fConnection->consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] fSounds;
|
delete[] fSounds;
|
||||||
delete fConnection;
|
delete fConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +137,7 @@ BGameSoundDevice::Format() const
|
|||||||
const gs_audio_format &
|
const gs_audio_format &
|
||||||
BGameSoundDevice::Format(gs_id sound) const
|
BGameSoundDevice::Format(gs_id sound) const
|
||||||
{
|
{
|
||||||
return fSounds[sound-1]->Format();
|
return fSounds[sound - 1]->Format();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -158,8 +164,9 @@ BGameSoundDevice::CreateBuffer(gs_id * sound,
|
|||||||
fSounds[position] = new SimpleSoundBuffer(format, data, frames);
|
fSounds[position] = new SimpleSoundBuffer(format, data, frames);
|
||||||
err = fSounds[position]->Connect(&fConnection->producer);
|
err = fSounds[position]->Connect(&fConnection->producer);
|
||||||
}
|
}
|
||||||
|
|
||||||
*sound = gs_id(position+1);
|
if (err == B_OK)
|
||||||
|
*sound = gs_id(position + 1);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,8 +186,9 @@ BGameSoundDevice::CreateBuffer(gs_id * sound,
|
|||||||
fSounds[position] = new StreamingSoundBuffer(format, object);
|
fSounds[position] = new StreamingSoundBuffer(format, object);
|
||||||
err = fSounds[position]->Connect(&fConnection->producer);
|
err = fSounds[position]->Connect(&fConnection->producer);
|
||||||
}
|
}
|
||||||
|
|
||||||
*sound = gs_id(position+1);
|
if (err == B_OK)
|
||||||
|
*sound = gs_id(position+1);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,13 +199,13 @@ BGameSoundDevice::ReleaseBuffer(gs_id sound)
|
|||||||
if (sound <= 0)
|
if (sound <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fSounds[sound-1]) {
|
if (fSounds[sound - 1]) {
|
||||||
// We must stop playback befor destroying the sound or else
|
// We must stop playback befor destroying the sound or else
|
||||||
// we may recieve fatel errors.
|
// we may recieve fatel errors.
|
||||||
fSounds[sound-1]->StopPlaying();
|
fSounds[sound - 1]->StopPlaying();
|
||||||
|
|
||||||
delete fSounds[sound-1];
|
delete fSounds[sound - 1];
|
||||||
fSounds[sound-1] = NULL;
|
fSounds[sound - 1] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,18 +229,19 @@ BGameSoundDevice::Buffer(gs_id sound,
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BGameSoundDevice::StartPlaying(gs_id sound)
|
BGameSoundDevice::StartPlaying(gs_id sound)
|
||||||
{
|
{
|
||||||
if (sound <= 0)
|
if (sound <= 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (!fSounds[sound-1]->IsPlaying()) {
|
if (!fSounds[sound - 1]->IsPlaying()) {
|
||||||
// tell the producer to start playing the sound
|
// tell the producer to start playing the sound
|
||||||
return fSounds[sound-1]->StartPlaying();
|
return fSounds[sound - 1]->StartPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
fSounds[sound-1]->Reset();
|
fSounds[sound - 1]->Reset();
|
||||||
return EALREADY;
|
return EALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,10 +252,10 @@ BGameSoundDevice::StopPlaying(gs_id sound)
|
|||||||
if (sound <= 0)
|
if (sound <= 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (fSounds[sound-1]->IsPlaying()) {
|
if (fSounds[sound - 1]->IsPlaying()) {
|
||||||
// Tell the producer to stop play this sound
|
// Tell the producer to stop play this sound
|
||||||
fSounds[sound-1]->Reset();
|
fSounds[sound - 1]->Reset();
|
||||||
return fSounds[sound-1]->StopPlaying();
|
return fSounds[sound - 1]->StopPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
return EALREADY;
|
return EALREADY;
|
||||||
@@ -258,7 +267,7 @@ BGameSoundDevice::IsPlaying(gs_id sound)
|
|||||||
{
|
{
|
||||||
if (sound <= 0)
|
if (sound <= 0)
|
||||||
return false;
|
return false;
|
||||||
return fSounds[sound-1]->IsPlaying();
|
return fSounds[sound - 1]->IsPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -267,10 +276,10 @@ BGameSoundDevice::GetAttributes(gs_id sound,
|
|||||||
gs_attribute * attributes,
|
gs_attribute * attributes,
|
||||||
size_t attributeCount)
|
size_t attributeCount)
|
||||||
{
|
{
|
||||||
if (!fSounds[sound-1])
|
if (!fSounds[sound - 1])
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
return fSounds[sound-1]->GetAttributes(attributes, attributeCount);
|
return fSounds[sound - 1]->GetAttributes(attributes, attributeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -279,66 +288,68 @@ BGameSoundDevice::SetAttributes(gs_id sound,
|
|||||||
gs_attribute * attributes,
|
gs_attribute * attributes,
|
||||||
size_t attributeCount)
|
size_t attributeCount)
|
||||||
{
|
{
|
||||||
if (!fSounds[sound-1])
|
if (!fSounds[sound - 1])
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
return fSounds[sound-1]->SetAttributes(attributes, attributeCount);
|
return fSounds[sound - 1]->SetAttributes(attributes, attributeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BGameSoundDevice::Connect()
|
BGameSoundDevice::Connect()
|
||||||
{
|
{
|
||||||
BMediaRoster* r = BMediaRoster::Roster();
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
status_t err;
|
|
||||||
|
|
||||||
// create your own audio mixer
|
// create your own audio mixer
|
||||||
|
// TODO: Don't do this!!! See bug #575
|
||||||
dormant_node_info mixer_dormant_info;
|
dormant_node_info mixer_dormant_info;
|
||||||
int32 mixer_count = 1; // for now, we only care about the first we find.
|
int32 mixer_count = 1; // for now, we only care about the first we find.
|
||||||
err = r->GetDormantNodes(&mixer_dormant_info, &mixer_count, 0, 0, 0, B_SYSTEM_MIXER, 0);
|
status_t err = roster->GetDormantNodes(&mixer_dormant_info,
|
||||||
|
&mixer_count, 0, 0, 0, B_SYSTEM_MIXER, 0);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
//fMixer = new media_node;
|
//fMixer = new media_node;
|
||||||
err = r->InstantiateDormantNode(mixer_dormant_info, &fConnection->producer);
|
err = roster->InstantiateDormantNode(mixer_dormant_info, &fConnection->producer);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
// retieve the system's audio mixer
|
// retieve the system's audio mixer
|
||||||
err = r->GetAudioMixer(&fConnection->consumer);
|
err = roster->GetAudioMixer(&fConnection->consumer);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
int32 count = 1;
|
int32 count = 1;
|
||||||
media_input mixerInput;
|
media_input mixerInput;
|
||||||
err = r->GetFreeInputsFor(fConnection->consumer, &mixerInput, 1, &count);
|
err = roster->GetFreeInputsFor(fConnection->consumer, &mixerInput, 1, &count);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
count = 1;
|
count = 1;
|
||||||
media_output mixerOutput;
|
media_output mixerOutput;
|
||||||
err = r->GetFreeOutputsFor(fConnection->producer, &mixerOutput, 1, &count);
|
err = roster->GetFreeOutputsFor(fConnection->producer, &mixerOutput, 1, &count);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
media_format format(mixerOutput.format);
|
media_format format(mixerOutput.format);
|
||||||
err = r->Connect(mixerOutput.source, mixerInput.destination, &format, &mixerOutput, &mixerInput);
|
err = roster->Connect(mixerOutput.source, mixerInput.destination,
|
||||||
|
&format, &mixerOutput, &mixerInput);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
// set the producer's time source to be the "default" time source, which
|
// set the producer's time source to be the "default" time source, which
|
||||||
// the Mixer uses too.
|
// the Mixer uses too.
|
||||||
r->GetTimeSource(&fConnection->timeSource);
|
roster->GetTimeSource(&fConnection->timeSource);
|
||||||
r->SetTimeSourceFor(fConnection->producer.node, fConnection->timeSource.node);
|
roster->SetTimeSourceFor(fConnection->producer.node, fConnection->timeSource.node);
|
||||||
|
|
||||||
// Start our mixer's time source if need be. Chances are, it won't need to be,
|
// Start our mixer's time source if need be. Chances are, it won't need to be,
|
||||||
// but if we forget to do this, our mixer might not do anything at all.
|
// but if we forget to do this, our mixer might not do anything at all.
|
||||||
BTimeSource* mixerTimeSource = r->MakeTimeSourceFor(fConnection->producer);
|
BTimeSource* mixerTimeSource = roster->MakeTimeSourceFor(fConnection->producer);
|
||||||
if (!mixerTimeSource)
|
if (!mixerTimeSource)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if (!mixerTimeSource->IsRunning()) {
|
if (!mixerTimeSource->IsRunning()) {
|
||||||
status_t err = r->StartNode(mixerTimeSource->Node(), BTimeSource::RealTime());
|
status_t err = roster->StartNode(mixerTimeSource->Node(), BTimeSource::RealTime());
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
mixerTimeSource->Release();
|
mixerTimeSource->Release();
|
||||||
return err;
|
return err;
|
||||||
@@ -347,7 +358,7 @@ BGameSoundDevice::Connect()
|
|||||||
|
|
||||||
// Start up our mixer
|
// Start up our mixer
|
||||||
bigtime_t tpNow = mixerTimeSource->Now();
|
bigtime_t tpNow = mixerTimeSource->Now();
|
||||||
err = r->StartNode(fConnection->producer, tpNow + 10000);
|
err = roster->StartNode(fConnection->producer, tpNow + 10000);
|
||||||
mixerTimeSource->Release();
|
mixerTimeSource->Release();
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
@@ -360,7 +371,7 @@ BGameSoundDevice::Connect()
|
|||||||
fConnection->destination = mixerInput.destination;
|
fConnection->destination = mixerInput.destination;
|
||||||
|
|
||||||
// Set an appropriate run mode for the producer
|
// Set an appropriate run mode for the producer
|
||||||
r->SetRunModeNode(fConnection->producer, BMediaNode::B_INCREASE_LATENCY);
|
roster->SetRunModeNode(fConnection->producer, BMediaNode::B_INCREASE_LATENCY);
|
||||||
|
|
||||||
media_to_gs_format(&fFormat, &format.u.raw_audio);
|
media_to_gs_format(&fFormat, &format.u.raw_audio);
|
||||||
fIsConnected = true;
|
fIsConnected = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user