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:
parent
9504919814
commit
22b3307b23
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue