* Implement basic support for the BSound parts of BSoundPlayer. Only one sound

at a time is supported and volume as well as start time are not taken into
  account. For reasons I don't feel like investigating right now all the
  BMediaTrack calls in the BTrackReader end up as pure virtual function calls
  though, so it's unusable for now.
* Fix leaking the temporary buffer in BSound.
* Whitespace cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29374 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2009-03-01 23:22:30 +00:00
parent 0b2267c921
commit 9b9aa75aac
3 changed files with 211 additions and 74 deletions

View File

@ -123,6 +123,8 @@ protected:
status_t in_error);
private:
static void _SoundPlayBufferFunc(void *cookie, void *buffer, size_t size,
const media_raw_audio_format &format);
virtual status_t _Reserved_SoundPlayer_0(void *, ...);
virtual status_t _Reserved_SoundPlayer_1(void *, ...);
@ -134,16 +136,19 @@ virtual status_t _Reserved_SoundPlayer_6(void *, ...);
virtual status_t _Reserved_SoundPlayer_7(void *, ...);
_SoundPlayNode * fPlayerNode;
struct _playing_sound {
_playing_sound * next;
off_t cur_offset;
BSound * sound;
_playing_sound *next;
off_t current_offset;
BSound *sound;
play_id id;
int32 delta;
int32 rate;
sem_id wait_sem;
float volume;
};
_playing_sound * _m_sounds;
_playing_sound *fPlayingSounds;
struct _waiting_sound {
_waiting_sound * next;
bigtime_t start_time;
@ -152,7 +157,8 @@ virtual status_t _Reserved_SoundPlayer_7(void *, ...);
int32 rate;
float volume;
};
_waiting_sound * _m_waiting;
_waiting_sound *fWaitingSounds;
void (*fPlayBufferFunc)(void * cookie, void * buffer, size_t size, const media_raw_audio_format & format);
void (*fNotifierFunc)(void * cookie, sound_player_notification what, ...);
BLocker fLocker;

View File

@ -207,6 +207,8 @@ BSound::GetDataAt(off_t offset, void *intoBuffer, size_t bufferSize,
indirectSize - bufferOffset);
if (outUsed != NULL)
*outUsed = indirectSize - bufferOffset;
free(buffer);
} else if (outUsed != NULL)
*outUsed = 0;

View File

@ -6,6 +6,7 @@
#include <TimeSource.h>
#include <MediaRoster.h>
#include <ParameterWeb.h>
#include <Sound.h>
#include <math.h>
#include <string.h>
@ -24,6 +25,9 @@ enum {
};
static BSoundPlayer::play_id sCurrentPlayID = 1;
/*************************************************************
* public BSoundPlayer
*************************************************************/
@ -109,14 +113,19 @@ BSoundPlayer::Init( const media_node * node,
void * cookie)
{
CALLED();
_m_sounds = NULL; // unused
_m_waiting = NULL; // unused
fPlayingSounds = NULL;
fWaitingSounds = NULL;
fPlayerNode = NULL;
fPlayBufferFunc = PlayBuffer;
if (fPlayBufferFunc == NULL) {
fPlayBufferFunc = _SoundPlayBufferFunc;
fCookie = this;
} else
fCookie = cookie;
fNotifierFunc = Notifier;
fVolumeDB = 0.0f;
fCookie = cookie;
fFlags = 0;
fInitStatus = B_ERROR;
fParameterWeb = NULL;
@ -572,58 +581,143 @@ BSoundPlayer::Preroll()
BSoundPlayer::play_id
BSoundPlayer::StartPlaying(BSound *sound,
bigtime_t at_time)
BSoundPlayer::StartPlaying(BSound *sound, bigtime_t atTime)
{
UNIMPLEMENTED();
return 1;
return StartPlaying(sound, atTime, 1.0);
}
BSoundPlayer::play_id
BSoundPlayer::StartPlaying(BSound *sound,
bigtime_t at_time,
float with_volume)
BSoundPlayer::StartPlaying(BSound *sound, bigtime_t atTime, float withVolume)
{
UNIMPLEMENTED();
return 1;
CALLED();
// TODO: support the at_time and with_volume parameters
_playing_sound *item = (_playing_sound *)malloc(sizeof(_playing_sound));
if (item == NULL)
return B_NO_MEMORY;
item->current_offset = 0;
item->sound = sound;
item->id = atomic_add(&sCurrentPlayID, 1);
item->delta = 0;
item->rate = 0;
item->volume = withVolume;
if (!fLocker.Lock()) {
free(item);
return B_ERROR;
}
item->next = fPlayingSounds;
fPlayingSounds = item;
fLocker.Unlock();
SetHasData(true);
return item->id;
}
status_t
BSoundPlayer::SetSoundVolume(play_id sound,
float new_volume)
BSoundPlayer::SetSoundVolume(play_id id, float newVolume)
{
UNIMPLEMENTED();
CALLED();
if (!fLocker.Lock())
return B_ERROR;
return B_OK;
_playing_sound *item = fPlayingSounds;
while (item) {
if (item->id == id) {
item->volume = newVolume;
fLocker.Unlock();
return B_OK;
}
item = item->next;
}
fLocker.Unlock();
return B_ENTRY_NOT_FOUND;
}
bool
BSoundPlayer::IsPlaying(play_id id)
{
UNIMPLEMENTED();
CALLED();
if (!fLocker.Lock())
return B_ERROR;
return true;
_playing_sound *item = fPlayingSounds;
while (item) {
if (item->id == id) {
fLocker.Unlock();
return true;
}
item = item->next;
}
fLocker.Unlock();
return false;
}
status_t
BSoundPlayer::StopPlaying(play_id id)
{
UNIMPLEMENTED();
CALLED();
if (!fLocker.Lock())
return B_ERROR;
return B_OK;
_playing_sound **link = &fPlayingSounds;
_playing_sound *item = fPlayingSounds;
while (item) {
if (item->id == id) {
*link = item->next;
sem_id waitSem = item->wait_sem;
free(item);
fLocker.Unlock();
NotifySoundDone(id, true);
if (waitSem >= 0)
release_sem(waitSem);
return B_OK;
}
link = &item->next;
item = item->next;
}
fLocker.Unlock();
return B_ENTRY_NOT_FOUND;
}
status_t
BSoundPlayer::WaitForSound(play_id id)
{
UNIMPLEMENTED();
CALLED();
if (!fLocker.Lock())
return B_ERROR;
return B_OK;
_playing_sound *item = fPlayingSounds;
while (item) {
if (item->id == id) {
sem_id waitSem = item->wait_sem;
if (waitSem < 0)
waitSem = item->wait_sem = create_sem(0, "wait for sound");
fLocker.Unlock();
return acquire_sem(waitSem);
}
item = item->next;
}
fLocker.Unlock();
return B_ENTRY_NOT_FOUND;
}
@ -631,7 +725,6 @@ float
BSoundPlayer::Volume()
{
CALLED();
return pow(10.0, VolumeDB(true) / 20.0);
}
@ -730,6 +823,42 @@ BSoundPlayer::SetInitError(status_t in_error)
* private BSoundPlayer
*************************************************************/
void
BSoundPlayer::_SoundPlayBufferFunc(void *cookie, void *buffer, size_t size,
const media_raw_audio_format &format)
{
// TODO: support more than one sound and make use of the format parameter
BSoundPlayer *player = (BSoundPlayer *)cookie;
if (!player->fLocker.Lock()) {
memset(buffer, 0, size);
return;
}
_playing_sound *sound = player->fPlayingSounds;
if (sound == NULL) {
player->SetHasData(false);
player->fLocker.Unlock();
memset(buffer, 0, size);
return;
}
size_t used = 0;
if (!sound->sound->GetDataAt(sound->current_offset, buffer, size, &used)) {
// will take care of removing the item and notifying others
player->StopPlaying(sound->id);
player->fLocker.Unlock();
memset(buffer, 0, size);
return;
}
sound->current_offset += used;
player->fLocker.Unlock();
if (used < size)
memset((uint8 *)buffer + used, 0, size - used);
}
status_t BSoundPlayer::_Reserved_SoundPlayer_0(void *, ...) { return B_ERROR; }
status_t BSoundPlayer::_Reserved_SoundPlayer_1(void *, ...) { return B_ERROR; }
status_t BSoundPlayer::_Reserved_SoundPlayer_2(void *, ...) { return B_ERROR; }
@ -741,10 +870,10 @@ status_t BSoundPlayer::_Reserved_SoundPlayer_7(void *, ...) { return B_ERROR; }
void
BSoundPlayer::NotifySoundDone(play_id sound,
bool got_to_play)
BSoundPlayer::NotifySoundDone(play_id id, bool gotToPlay)
{
UNIMPLEMENTED();
CALLED();
Notify(B_SOUND_DONE, id, gotToPlay);
}