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*
FindMediaFilePlayer(MediaFilePlayer * player,void * media_name)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
PlayMediaFile(const char * media_type,const char * media_name)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
MediaFilePlayer(const char * media_type,const char * media_name,entry_ref * ref)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
~MediaFilePlayer()108 MediaFilePlayer::~MediaFilePlayer()
109 {
110 delete fSoundPlayer;
111 delete fPlayFile;
112 }
113
114
115 status_t
InitCheck()116 MediaFilePlayer::InitCheck()
117 {
118 return fInitCheck;
119 }
120
121
122 const char*
Name()123 MediaFilePlayer::Name()
124 {
125 return fName;
126 }
127
128
129 const entry_ref*
Ref()130 MediaFilePlayer::Ref()
131 {
132 return &fRef;
133 }
134
135
136 bool
IsPlaying()137 MediaFilePlayer::IsPlaying()
138 {
139 return (fSoundPlayer != NULL && fSoundPlayer->HasData());
140 }
141
142 void
Restart()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
Stop()154 MediaFilePlayer::Stop()
155 {
156 fSoundPlayer->Stop();
157 }
158
159
160 void
PlayFunction(void * cookie,void * buffer,size_t size,const media_raw_audio_format & format)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