Sound events are now played with a BSoundPlayer, because it's more easy to handle restart and have a correct name displayed in the mixer. Sound players are reused when possible

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20760 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2007-04-19 21:59:55 +00:00
parent 9504919814
commit 22b3307b23
3 changed files with 168 additions and 13 deletions

View File

@ -2,7 +2,7 @@ SubDir HAIKU_TOP src servers media_addon ;
SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders media ;
UsePrivateHeaders media shared ;
AddResources media_addon_server : media_addon_server.rdef ;

View File

@ -4,27 +4,147 @@
* Distributed under the terms of the MIT License.
*/
#include <Entry.h>
#include <FileGameSound.h>
#include <MediaFiles.h>
#include "MediaFilePlayer.h"
#include "debug.h"
#include "ObjectList.h"
void
#include <stdio.h>
BObjectList<MediaFilePlayer> list;
MediaFilePlayer *
FindMediaFilePlayer(MediaFilePlayer *player, void *media_name)
{
if (!strcmp(player->Name(), (const char *)media_name))
return player;
return NULL;
}
void
PlayMediaFile(const char *media_type, const char *media_name)
{
TRACE("PlayMediaFile: type '%s', name '%s'\n", media_type, media_name);
entry_ref ref;
if (BMediaFiles().GetRefFor(media_type, media_name, &ref)!=B_OK
|| !BEntry(&ref).Exists())
return;
BFileGameSound *sound = new BFileGameSound(&ref, false);
if (sound->InitCheck() == B_OK) {
sound->Preload();
sound->StartPlaying();
MediaFilePlayer *player = list.EachElement(FindMediaFilePlayer, (void *)media_name);
if (player) {
if (*(player->Ref()) == ref) {
player->Restart();
return;
}
list.RemoveItem(player);
delete player;
player = NULL;
}
if (!player) {
player = new MediaFilePlayer(media_type, media_name, &ref);
if (player->InitCheck() == B_OK)
list.AddItem(player);
else
delete player;
}
// TODO reclaim sound
}
MediaFilePlayer::MediaFilePlayer(const char *media_type,
const char *media_name, entry_ref *ref) :
fInitCheck(B_ERROR),
fRef(*ref),
fSoundPlayer(NULL),
fPlayTrack(NULL)
{
fName = strdup(media_name);
fPlayFile = new BMediaFile(&fRef);
if ((fInitCheck = fPlayFile->InitCheck()) <B_OK) {
return;
}
memset(&fPlayFormat, 0, sizeof(fPlayFormat));
for (int i=0; i < fPlayFile->CountTracks(); i++) {
BMediaTrack *track = fPlayFile->TrackAt(i);
fPlayFormat.type = B_MEDIA_RAW_AUDIO;
fPlayFormat.u.raw_audio.buffer_size = 256;
if ((track->DecodedFormat(&fPlayFormat) == B_OK)
&& (fPlayFormat.type == B_MEDIA_RAW_AUDIO)) {
fPlayTrack = track;
break;
}
if (track)
fPlayFile->ReleaseTrack(track);
}
if (fPlayTrack == NULL) {
fInitCheck = B_BAD_VALUE;
return;
}
fSoundPlayer = new BSoundPlayer(&fPlayFormat.u.raw_audio, media_name, PlayFunction,
NULL, this);
if ((fInitCheck = fSoundPlayer->InitCheck()) != B_OK) {
return;
}
fSoundPlayer->SetVolume(1.0f);
fSoundPlayer->SetHasData(true);
fSoundPlayer->Start();
}
MediaFilePlayer::~MediaFilePlayer()
{
delete fSoundPlayer;
delete fPlayFile;
free(fName);
}
status_t
MediaFilePlayer::InitCheck()
{
return fInitCheck;
}
bool
MediaFilePlayer::IsPlaying()
{
return (fSoundPlayer && fSoundPlayer->HasData());
}
void
MediaFilePlayer::Restart()
{
fSoundPlayer->Stop();
int64 frame = 0;
fPlayTrack->SeekToFrame(&frame);
fSoundPlayer->SetHasData(true);
fSoundPlayer->Start();
}
void
MediaFilePlayer::Stop()
{
fSoundPlayer->Stop();
}
void
MediaFilePlayer::PlayFunction(void *cookie, void * buffer, size_t size, const media_raw_audio_format & format)
{
MediaFilePlayer *player = (MediaFilePlayer *)cookie;
int64 frames = 0;
player->fPlayTrack->ReadFrames(buffer, &frames);
if (frames <=0) {
player->fSoundPlayer->SetHasData(false);
}
}

View File

@ -5,6 +5,41 @@
#ifndef _MEDIA_FILE_PLAYER_H
#define _MEDIA_FILE_PLAYER_H
#include <Entry.h>
#include <SoundPlayer.h>
#include <MediaFile.h>
#include <MediaTrack.h>
#include <MediaDefs.h>
void PlayMediaFile(const char *media_type, const char *media_name);
#endif
class MediaFilePlayer
{
public:
MediaFilePlayer(const char *media_type, const char *media_name,
entry_ref *ref);
~MediaFilePlayer();
bool IsPlaying();
void Restart();
void Stop();
status_t InitCheck();
const char *Name() { return fName; };
const entry_ref *Ref() { return &fRef; };
static void PlayFunction(void *cookie, void * buffer,
size_t size, const media_raw_audio_format & format);
private:
char *fName;
status_t fInitCheck;
entry_ref fRef;
BSoundPlayer *fSoundPlayer;
BMediaFile *fPlayFile;
BMediaTrack *fPlayTrack;
media_format fPlayFormat;
};
#endif // _MEDIA_FILE_PLAYER_H