From 22b3307b23ccd849c3409ef973b4e0f9c460cd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 19 Apr 2007 21:59:55 +0000 Subject: [PATCH] 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 --- src/servers/media_addon/Jamfile | 2 +- src/servers/media_addon/MediaFilePlayer.cpp | 142 ++++++++++++++++++-- src/servers/media_addon/MediaFilePlayer.h | 37 ++++- 3 files changed, 168 insertions(+), 13 deletions(-) diff --git a/src/servers/media_addon/Jamfile b/src/servers/media_addon/Jamfile index 75e5c9f1aa..b5e62aae5b 100644 --- a/src/servers/media_addon/Jamfile +++ b/src/servers/media_addon/Jamfile @@ -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 ; diff --git a/src/servers/media_addon/MediaFilePlayer.cpp b/src/servers/media_addon/MediaFilePlayer.cpp index b48b6a683c..a9ab0cc8ce 100644 --- a/src/servers/media_addon/MediaFilePlayer.cpp +++ b/src/servers/media_addon/MediaFilePlayer.cpp @@ -4,27 +4,147 @@ * Distributed under the terms of the MIT License. */ -#include -#include #include #include "MediaFilePlayer.h" -#include "debug.h" +#include "ObjectList.h" -void +#include + +BObjectList 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()) 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); + } +} diff --git a/src/servers/media_addon/MediaFilePlayer.h b/src/servers/media_addon/MediaFilePlayer.h index 6044e4b8f3..4c85458a15 100644 --- a/src/servers/media_addon/MediaFilePlayer.h +++ b/src/servers/media_addon/MediaFilePlayer.h @@ -5,6 +5,41 @@ #ifndef _MEDIA_FILE_PLAYER_H #define _MEDIA_FILE_PLAYER_H +#include +#include +#include +#include +#include + + 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