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
19 thread_id reader = -1;
20 sem_id finished = -1;
21 BMediaTrack* playTrack;
22 media_format playFormat;
23 BSoundPlayer* sp = 0;
24 volatile bool interrupt = false;
25
26 void
play_buffer(void * cookie,void * buffer,size_t size,const media_raw_audio_format & format)27 play_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
41 void
keyb_int(int)42 keyb_int(int)
43 {
44 // Are you threatening me, Master Jedi?
45 interrupt = true;
46 release_sem(finished);
47 }
48
49
50 int
main(int argc,char * argv[])51 main(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