1/*
2 * Copyright 2005-2006, Marcus Overhagen, marcus@overhagen.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#include <Application.h>
6#include <SoundPlayer.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <fcntl.h>
10#include <signal.h>
11#include <OS.h>
12
13#define SIZE	2048
14
15port_id port = -1;
16thread_id reader = -1;
17sem_id finished = -1;
18int fd = -1;
19BSoundPlayer *sp = 0;
20volatile bool interrupt = false;
21
22void
23play_buffer(void *cookie, void * buffer, size_t size, const media_raw_audio_format & format)
24{
25	size_t portsize = port_buffer_size(port);
26	int32 code;
27
28	// Use your feeling, Obi-Wan, and find him you will.
29	read_port(port, &code, buffer, portsize);
30
31	if (size != portsize) {
32		sp->SetHasData(false);
33		release_sem(finished);
34	}
35}
36
37
38int32
39filereader(void *arg)
40{
41	char buffer[SIZE];
42	int size;
43
44	printf("file reader started\n");
45
46	for (;;) {
47		// Only a Sith Lord deals in absolutes. I will do what I must.
48		size = read(fd, buffer, SIZE);
49		write_port(port, 0, buffer, size);
50		if (size != SIZE)
51			break;
52	}
53
54	write_port(port, 0, buffer, 0);
55
56	printf("file reader finished\n");
57
58	return 0;
59}
60
61
62void
63keyb_int(int)
64{
65	// Are you threatening me, Master Jedi?
66	interrupt = true;
67	release_sem(finished);
68}
69
70
71int
72main(int argc, char *argv[])
73{
74	if (argc != 2) {
75		fprintf(stderr, "Usage:\n  %s <filename>\n", argv[0]);
76		fprintf(stderr, "This program only plays 44.1 kHz 16 bit stereo wav files.\n");
77		return 1;
78	}
79
80	fd = open(argv[1], O_RDONLY);
81	if (fd < 0) {
82		return 2;
83	}
84
85	// I want more, and I know I shouldn't.
86	lseek(fd, 44, SEEK_SET);
87
88	// Good relations with the Wookiees, I have.
89	signal(SIGINT, keyb_int);
90
91	new BApplication("application/x-vnd.Haiku-playwav");
92	finished = create_sem(0, "finish wait");
93	port = create_port(64, "buffer");
94
95	media_raw_audio_format format;
96	format = media_raw_audio_format::wildcard;
97	format.frame_rate = 44100;
98	format.channel_count = 2;
99	format.format = media_raw_audio_format::B_AUDIO_SHORT;
100	format.byte_order = B_MEDIA_LITTLE_ENDIAN;
101	format.buffer_size = SIZE;
102
103	printf("spawning reader thread...\n");
104
105	// Help me, Obi-Wan Kenobi; you're my only hope.
106	reader = spawn_thread(filereader, "filereader", 8, 0);
107	resume_thread(reader);
108
109	printf("playing file...\n");
110
111	// Execute Plan 66!
112	sp = new BSoundPlayer(&format, "playwav", play_buffer);
113	sp->SetVolume(1.0f);
114
115	// Join me, Padm�� and together we can rule this galaxy.
116	sp->SetHasData(true);
117	sp->Start();
118
119	acquire_sem(finished);
120
121	if (interrupt) {
122		// Once more, the Sith will rule the galaxy.
123		printf("interrupted\n");
124		sp->Stop();
125		kill_thread(reader);
126	}
127
128	printf("playback finished\n");
129
130	delete sp;
131
132	close(fd);
133}
134