* 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:
parent
0b2267c921
commit
9b9aa75aac
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user