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