1/* 2 * Copyright (c) 2004, Marcus Overhagen <marcus@overhagen.de>. All rights reserved. 3 * Copyright (c) 2007, J��r��me Duval. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8#include "MediaFilePlayer.h" 9 10#include <MediaFiles.h> 11#include <ObjectList.h> 12 13#include <stdlib.h> 14 15 16BObjectList<MediaFilePlayer> list; 17 18 19MediaFilePlayer* 20FindMediaFilePlayer(MediaFilePlayer* player, void* media_name) 21{ 22 if (strcmp(player->Name(), (const char*)media_name) == 0) 23 return player; 24 return NULL; 25} 26 27 28void 29PlayMediaFile(const char* media_type, const char* media_name) 30{ 31 entry_ref ref; 32 if (BMediaFiles().GetRefFor(media_type, media_name, &ref) != B_OK 33 || !BEntry(&ref).Exists()) 34 return; 35 36 MediaFilePlayer* player = list.EachElement(FindMediaFilePlayer, 37 (void*)media_name); 38 39 if (player != NULL) { 40 if (*(player->Ref()) == ref) { 41 player->Restart(); 42 return; 43 } 44 45 list.RemoveItem(player); 46 delete player; 47 player = NULL; 48 } 49 50 if (player == NULL) { 51 player = new MediaFilePlayer(media_type, media_name, &ref); 52 if (player->InitCheck() == B_OK) 53 list.AddItem(player); 54 else 55 delete player; 56 } 57} 58 59 60 61MediaFilePlayer::MediaFilePlayer(const char* media_type, 62 const char* media_name, entry_ref* ref) 63 : 64 fName(media_name), 65 fInitCheck(B_ERROR), 66 fRef(*ref), 67 fSoundPlayer(NULL), 68 fPlayTrack(NULL) 69{ 70 fPlayFile = new BMediaFile(&fRef); 71 fInitCheck = fPlayFile->InitCheck(); 72 if (fInitCheck != B_OK) 73 return; 74 75 fPlayFormat.Clear(); 76 77 for (int i=0; i < fPlayFile->CountTracks(); i++) { 78 BMediaTrack* track = fPlayFile->TrackAt(i); 79 if (track == NULL) 80 continue; 81 fPlayFormat.type = B_MEDIA_RAW_AUDIO; 82 fPlayFormat.u.raw_audio.buffer_size = 256; 83 if ((track->DecodedFormat(&fPlayFormat) == B_OK) 84 && (fPlayFormat.type == B_MEDIA_RAW_AUDIO)) { 85 fPlayTrack = track; 86 break; 87 } 88 fPlayFile->ReleaseTrack(track); 89 } 90 91 if (fPlayTrack == NULL) { 92 fInitCheck = B_BAD_VALUE; 93 return; 94 } 95 96 fSoundPlayer = new BSoundPlayer(&fPlayFormat.u.raw_audio, 97 media_name, PlayFunction, NULL, this); 98 99 fInitCheck = fSoundPlayer->InitCheck(); 100 if (fInitCheck != B_OK) 101 return; 102 103 fSoundPlayer->SetHasData(true); 104 fSoundPlayer->Start(); 105} 106 107 108MediaFilePlayer::~MediaFilePlayer() 109{ 110 delete fSoundPlayer; 111 delete fPlayFile; 112} 113 114 115status_t 116MediaFilePlayer::InitCheck() 117{ 118 return fInitCheck; 119} 120 121 122const char* 123MediaFilePlayer::Name() 124{ 125 return fName; 126} 127 128 129const entry_ref* 130MediaFilePlayer::Ref() 131{ 132 return &fRef; 133} 134 135 136bool 137MediaFilePlayer::IsPlaying() 138{ 139 return (fSoundPlayer != NULL && fSoundPlayer->HasData()); 140} 141 142void 143MediaFilePlayer::Restart() 144{ 145 fSoundPlayer->Stop(); 146 int64 frame = 0; 147 fPlayTrack->SeekToFrame(&frame); 148 fSoundPlayer->SetHasData(true); 149 fSoundPlayer->Start(); 150} 151 152 153void 154MediaFilePlayer::Stop() 155{ 156 fSoundPlayer->Stop(); 157} 158 159 160void 161MediaFilePlayer::PlayFunction(void* cookie, void* buffer, 162 size_t size, const media_raw_audio_format& format) 163{ 164 MediaFilePlayer* player = (MediaFilePlayer*)cookie; 165 int64 frames = 0; 166 player->fPlayTrack->ReadFrames(buffer, &frames); 167 168 if (frames <= 0) 169 player->fSoundPlayer->SetHasData(false); 170} 171