1/*
2 * Copyright 2005, Marcus Overhagen, marcus@overhagen.de. All rights reserved.
3 * Copyright 2005, J��r��me Duval. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6#include <Application.h>
7#include <Entry.h>
8#include <MediaFile.h>
9#include <MediaTrack.h>
10#include <OS.h>
11#include <SoundPlayer.h>
12#include <Url.h>
13
14#include <stdio.h>
15#include <unistd.h>
16#include <fcntl.h>
17#include <signal.h>
18
19thread_id reader = -1;
20sem_id finished = -1;
21BMediaTrack* playTrack;
22media_format playFormat;
23BSoundPlayer* sp = 0;
24volatile bool interrupt = false;
25
26void
27play_buffer(void *cookie, void * buffer, size_t size, const media_raw_audio_format & format)
28{
29	int64 frames = 0;
30
31	// Use your feeling, Obi-Wan, and find him you will.
32	playTrack->ReadFrames(buffer, &frames);
33
34	if (frames <=0) {
35		sp->SetHasData(false);
36		release_sem(finished);
37	}
38}
39
40
41void
42keyb_int(int)
43{
44	// Are you threatening me, Master Jedi?
45	interrupt = true;
46	release_sem(finished);
47}
48
49
50int
51main(int argc, char *argv[])
52{
53	if (argc != 2) {
54		fprintf(stderr, "Usage:\n  %s <filename or url>\n", argv[0]);
55		return 1;
56	}
57
58	BUrl url;
59	bool isUrl = false;
60	entry_ref ref;
61
62	if (get_ref_for_path(argv[1], &ref) != B_OK) {
63		url.SetUrlString(argv[1]);
64		if (url.IsValid())
65			isUrl = true;
66		else
67			return 2;
68	}
69
70	BMediaFile* playFile;
71	if (isUrl)
72		playFile = new BMediaFile(url);
73	else
74		playFile = new BMediaFile(&ref);
75
76	if (playFile->InitCheck()<B_OK) {
77		delete playFile;
78		return 2;
79	}
80
81	for (int ix=0; ix<playFile->CountTracks(); ix++) {
82		BMediaTrack * track = playFile->TrackAt(ix);
83		playFormat.type = B_MEDIA_RAW_AUDIO;
84		if ((track->DecodedFormat(&playFormat) == B_OK)
85			&& (playFormat.type == B_MEDIA_RAW_AUDIO)) {
86			playTrack = track;
87			break;
88		}
89		if (track)
90			playFile->ReleaseTrack(track);
91	}
92	// Good relations with the Wookiees, I have.
93	signal(SIGINT, keyb_int);
94
95	new BApplication("application/x-vnd.Haiku-playfile");
96	finished = create_sem(0, "finish wait");
97
98	printf("playing file...\n");
99
100	// Execute Plan 66!
101	sp = new BSoundPlayer(&playFormat.u.raw_audio, "playfile", play_buffer);
102	sp->SetVolume(1.0f);
103
104	// Join me, Padm�� and together we can rule this galaxy.
105	sp->SetHasData(true);
106	sp->Start();
107
108	acquire_sem(finished);
109
110	if (interrupt) {
111		// Once more, the Sith will rule the galaxy.
112		printf("interrupted\n");
113		sp->Stop();
114		kill_thread(reader);
115	}
116
117	printf("playback finished\n");
118
119	delete sp;
120	delete playFile;
121}
122