summaryrefslogtreecommitdiff
path: root/sys/src/games/music/playlistfs/playlist.h
blob: ba9259767e4e3773e2f9d307096b3bcaf645a8fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
typedef struct Worker Worker;
typedef struct Req Req;
typedef struct Fid Fid;
typedef struct File File;
typedef struct Playlist Playlist;
typedef struct Wmsg Wmsg;
typedef union Pmsg Pmsg;
typedef struct Pacbuf Pacbuf;

enum {
	Qdir,
	Qplayctl,
	Qplaylist,
	Qplayvol,
	Qplaystat,
	Nqid,
};

enum {
	DbgPcm		= 0x01000,
	DbgPac		= 0x02000,
	DbgFs		= 0x10000,
	DbgWorker	= 0x20000,
	DbgPlayer	= 0x40000,
	DbgError	= 0x80000,
};

enum {
	Messagesize = 8*1024+IOHDRSZ,
	Undef = 0x80000000,
	/* 256 buffers of 4096 bytes represents 5.9 seconds
	 * of playout at 44100 Hz (2*16bit samples)
	 */
	NPacbuf = 256,
	Pacbufsize = 4096,
	NSparebuf = 16,	/* For in-line commands (Pause, Resume, Error) */
};

enum {
	/* Named commands (see fs.c): */
	Nostate,	// can't use zero for state
	Error,
	Stop,
	Pause,
	Play,
	Resume,
	Skip,
	/* Unnamed commands */
	Work,
	Check,
	Flush,
	Prep,
	Preq,
};

union Pmsg {
	ulong m;
	struct{
		ushort cmd;
		ushort off;
	};
};

struct Wmsg {
	Pmsg;
	void	*arg;	/* if(cmd != Work) mallocated by sender, freed by receiver */
};

struct Playlist {
	/* The play list consists of a sequence of {objectref, filename}
	 * entries.  Object ref and file name are separated by a tab.
	 * An object ref may not contain a tab.  Entries are seperated
	 * by newline characters.  Neither file names, nor object refs
	 * may contain newlines.
	 */
	ulong	*lines;
	ulong	nlines;
	char	*data;
	ulong	ndata;
};

struct File {
	Dir	dir;
	Channel	*workers;
};

struct Worker
{
	Req	*r;
	Channel	*eventc;
};

struct Fid
{
	int	fid;
	File	*file;
	ushort	flags;
	short	readers;
	ulong	vers;	/* set to file's version when completely read */
	Fid	*next;
};

struct Req
{
	uchar	indata[Messagesize];
	uchar	outdata[Messagesize];
	Fcall	ifcall;
	Fcall	ofcall;
	Fid*	fid;
};

struct Pacbuf {
	Pmsg;
	int len;
	char data[Pacbufsize];
};

void	allocwork(Req*);
Wmsg	waitmsg(Worker*, Channel*);
int	sendmsg(Channel*, Wmsg*);
void	bcastmsg(Channel*, Wmsg*);
void	reqfree(Req*);
Req	*reqalloc(void);
void	readbuf(Req*, void*, long);
void	readstr(Req*, char*);
void	volumeset(int *v);
void	playupdate(Pmsg, char*);
void	playinit(void);
void	volumeproc(void*);
void	srv(void *);
long	robustread(int, void*, long);
void	volumeupdate(int*);
char	*getplaylist(int);
char	*getplaystat(char*, char*);

extern int		debug, aflag;
extern char	*user;
extern Channel	*playc;
extern char	*statetxt[];
extern int		volume[8];
extern Playlist	playlist;
extern Channel	*workers;
extern Channel	*volumechan;
extern Channel	*playchan;
extern Channel	*playlistreq;
extern File	files[];
extern int		srvfd[];