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:
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src servers media_addon ;
|
|||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
UsePrivateHeaders media ;
|
UsePrivateHeaders media shared ;
|
||||||
|
|
||||||
AddResources media_addon_server : media_addon_server.rdef ;
|
AddResources media_addon_server : media_addon_server.rdef ;
|
||||||
|
|
||||||
|
|||||||
@@ -4,27 +4,147 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <FileGameSound.h>
|
|
||||||
#include <MediaFiles.h>
|
#include <MediaFiles.h>
|
||||||
#include "MediaFilePlayer.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)
|
PlayMediaFile(const char *media_type, const char *media_name)
|
||||||
{
|
{
|
||||||
TRACE("PlayMediaFile: type '%s', name '%s'\n", media_type, media_name);
|
|
||||||
|
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
if (BMediaFiles().GetRefFor(media_type, media_name, &ref)!=B_OK
|
if (BMediaFiles().GetRefFor(media_type, media_name, &ref)!=B_OK
|
||||||
|| !BEntry(&ref).Exists())
|
|| !BEntry(&ref).Exists())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BFileGameSound *sound = new BFileGameSound(&ref, false);
|
MediaFilePlayer *player = list.EachElement(FindMediaFilePlayer, (void *)media_name);
|
||||||
if (sound->InitCheck() == B_OK) {
|
if (player) {
|
||||||
sound->Preload();
|
if (*(player->Ref()) == ref) {
|
||||||
sound->StartPlaying();
|
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
|
#ifndef _MEDIA_FILE_PLAYER_H
|
||||||
#define _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);
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user