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 memset(&fPlayFormat, 0, sizeof(fPlayFormat)); 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->SetVolume(1.0f); 104 fSoundPlayer->SetHasData(true); 105 fSoundPlayer->Start(); 106 } 107 108 109 MediaFilePlayer::~MediaFilePlayer() 110 { 111 delete fSoundPlayer; 112 delete fPlayFile; 113 } 114 115 116 status_t 117 MediaFilePlayer::InitCheck() 118 { 119 return fInitCheck; 120 } 121 122 123 const char* 124 MediaFilePlayer::Name() 125 { 126 return fName; 127 } 128 129 130 const entry_ref* 131 MediaFilePlayer::Ref() 132 { 133 return &fRef; 134 } 135 136 137 bool 138 MediaFilePlayer::IsPlaying() 139 { 140 return (fSoundPlayer != NULL && fSoundPlayer->HasData()); 141 } 142 143 void 144 MediaFilePlayer::Restart() 145 { 146 fSoundPlayer->Stop(); 147 int64 frame = 0; 148 fPlayTrack->SeekToFrame(&frame); 149 fSoundPlayer->SetHasData(true); 150 fSoundPlayer->Start(); 151 } 152 153 154 void 155 MediaFilePlayer::Stop() 156 { 157 fSoundPlayer->Stop(); 158 } 159 160 161 void 162 MediaFilePlayer::PlayFunction(void* cookie, void* buffer, 163 size_t size, const media_raw_audio_format& format) 164 { 165 MediaFilePlayer* player = (MediaFilePlayer*)cookie; 166 int64 frames = 0; 167 player->fPlayTrack->ReadFrames(buffer, &frames); 168 169 if (frames <= 0) 170 player->fSoundPlayer->SetHasData(false); 171 } 172