xref: /haiku/src/servers/media_addon/MediaFilePlayer.cpp (revision 5d898e77d26e1d5b2dc3c68a64dbf977a519cbf5)
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