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 16 BObjectList<MediaFilePlayer> list; 17 18 19 MediaFilePlayer* 20 FindMediaFilePlayer(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 28 void 29 PlayMediaFile(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 61 MediaFilePlayer::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 108 MediaFilePlayer::~MediaFilePlayer() 109 { 110 delete fSoundPlayer; 111 delete fPlayFile; 112 } 113 114 115 status_t 116 MediaFilePlayer::InitCheck() 117 { 118 return fInitCheck; 119 } 120 121 122 const char* 123 MediaFilePlayer::Name() 124 { 125 return fName; 126 } 127 128 129 const entry_ref* 130 MediaFilePlayer::Ref() 131 { 132 return &fRef; 133 } 134 135 136 bool 137 MediaFilePlayer::IsPlaying() 138 { 139 return (fSoundPlayer != NULL && fSoundPlayer->HasData()); 140 } 141 142 void 143 MediaFilePlayer::Restart() 144 { 145 fSoundPlayer->Stop(); 146 int64 frame = 0; 147 fPlayTrack->SeekToFrame(&frame); 148 fSoundPlayer->SetHasData(true); 149 fSoundPlayer->Start(); 150 } 151 152 153 void 154 MediaFilePlayer::Stop() 155 { 156 fSoundPlayer->Stop(); 157 } 158 159 160 void 161 MediaFilePlayer::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