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 #include <MediaFiles.h> 8 #include "MediaFilePlayer.h" 9 #include "ObjectList.h" 10 11 #include <stdio.h> 12 13 BObjectList<MediaFilePlayer> list; 14 15 MediaFilePlayer * 16 FindMediaFilePlayer(MediaFilePlayer *player, void *media_name) 17 { 18 if (!strcmp(player->Name(), (const char *)media_name)) 19 return player; 20 return NULL; 21 } 22 23 24 void 25 PlayMediaFile(const char *media_type, const char *media_name) 26 { 27 entry_ref ref; 28 if (BMediaFiles().GetRefFor(media_type, media_name, &ref)!=B_OK 29 || !BEntry(&ref).Exists()) 30 return; 31 32 MediaFilePlayer *player = list.EachElement(FindMediaFilePlayer, (void *)media_name); 33 if (player) { 34 if (*(player->Ref()) == ref) { 35 player->Restart(); 36 return; 37 } 38 39 list.RemoveItem(player); 40 delete player; 41 player = NULL; 42 } 43 44 if (!player) { 45 player = new MediaFilePlayer(media_type, media_name, &ref); 46 if (player->InitCheck() == B_OK) 47 list.AddItem(player); 48 else 49 delete player; 50 } 51 } 52 53 54 55 MediaFilePlayer::MediaFilePlayer(const char *media_type, 56 const char *media_name, entry_ref *ref) : 57 fInitCheck(B_ERROR), 58 fRef(*ref), 59 fSoundPlayer(NULL), 60 fPlayTrack(NULL) 61 { 62 fName = strdup(media_name); 63 64 fPlayFile = new BMediaFile(&fRef); 65 if ((fInitCheck = fPlayFile->InitCheck()) <B_OK) { 66 return; 67 } 68 69 memset(&fPlayFormat, 0, sizeof(fPlayFormat)); 70 71 for (int i=0; i < fPlayFile->CountTracks(); i++) { 72 BMediaTrack *track = fPlayFile->TrackAt(i); 73 fPlayFormat.type = B_MEDIA_RAW_AUDIO; 74 fPlayFormat.u.raw_audio.buffer_size = 256; 75 if ((track->DecodedFormat(&fPlayFormat) == B_OK) 76 && (fPlayFormat.type == B_MEDIA_RAW_AUDIO)) { 77 fPlayTrack = track; 78 break; 79 } 80 if (track) 81 fPlayFile->ReleaseTrack(track); 82 } 83 84 if (fPlayTrack == NULL) { 85 fInitCheck = B_BAD_VALUE; 86 return; 87 } 88 89 fSoundPlayer = new BSoundPlayer(&fPlayFormat.u.raw_audio, media_name, PlayFunction, 90 NULL, this); 91 if ((fInitCheck = fSoundPlayer->InitCheck()) != B_OK) { 92 return; 93 } 94 95 fSoundPlayer->SetVolume(1.0f); 96 fSoundPlayer->SetHasData(true); 97 fSoundPlayer->Start(); 98 } 99 100 101 MediaFilePlayer::~MediaFilePlayer() 102 { 103 delete fSoundPlayer; 104 delete fPlayFile; 105 free(fName); 106 } 107 108 109 status_t 110 MediaFilePlayer::InitCheck() 111 { 112 return fInitCheck; 113 } 114 115 116 bool 117 MediaFilePlayer::IsPlaying() 118 { 119 return (fSoundPlayer && fSoundPlayer->HasData()); 120 } 121 122 void 123 MediaFilePlayer::Restart() 124 { 125 fSoundPlayer->Stop(); 126 int64 frame = 0; 127 fPlayTrack->SeekToFrame(&frame); 128 fSoundPlayer->SetHasData(true); 129 fSoundPlayer->Start(); 130 } 131 132 133 void 134 MediaFilePlayer::Stop() 135 { 136 fSoundPlayer->Stop(); 137 } 138 139 140 void 141 MediaFilePlayer::PlayFunction(void *cookie, void * buffer, size_t size, const media_raw_audio_format & format) 142 { 143 MediaFilePlayer *player = (MediaFilePlayer *)cookie; 144 int64 frames = 0; 145 player->fPlayTrack->ReadFrames(buffer, &frames); 146 147 if (frames <=0) { 148 player->fSoundPlayer->SetHasData(false); 149 } 150 } 151