1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | /*
|
---|
10 | * Control interface to front ends.
|
---|
11 | * written/copyrights 1997 by Michael Hipp
|
---|
12 | */
|
---|
13 |
|
---|
14 | #include <stdio.h>
|
---|
15 |
|
---|
16 | #include <sys/time.h>
|
---|
17 | #include <sys/types.h>
|
---|
18 | #include <unistd.h>
|
---|
19 |
|
---|
20 | #include <linux/socket.h>
|
---|
21 | /* <sys/socket.h> */
|
---|
22 |
|
---|
23 | #include "jukebox/controldata.h"
|
---|
24 | #include "mpg123.h"
|
---|
25 |
|
---|
26 | #define MODE_STOPPED 0
|
---|
27 | #define MODE_PLAYING 1
|
---|
28 | #define MODE_PAUSED 2
|
---|
29 |
|
---|
30 | extern int tabsel_123[2][3][16];
|
---|
31 |
|
---|
32 | int sajber_sendmsg(int type,int data)
|
---|
33 | {
|
---|
34 | TControlMsg msg;
|
---|
35 | msg.type = type;
|
---|
36 | msg.data = data;
|
---|
37 | return write(1,&msg,sizeof(TControlMsg));
|
---|
38 | }
|
---|
39 |
|
---|
40 | void control_sajber(struct frame *fr)
|
---|
41 | {
|
---|
42 | struct timeval timeout;
|
---|
43 | fd_set readfds;
|
---|
44 | int n;
|
---|
45 | int mode = MODE_STOPPED;
|
---|
46 | TControlMsg smsg,rmsg;
|
---|
47 | struct msghdr msghdr;
|
---|
48 | struct m_cmsghdr cmsghdr;
|
---|
49 | struct iovec iovec[1];
|
---|
50 | char buf[2];
|
---|
51 | int init = 0;
|
---|
52 | int framecnt = 0;
|
---|
53 |
|
---|
54 | while(1) {
|
---|
55 | timeout.tv_sec = 0;
|
---|
56 | timeout.tv_usec = 0;
|
---|
57 | FD_ZERO(&readfds);
|
---|
58 | FD_SET(0,&readfds);
|
---|
59 |
|
---|
60 | if(mode == MODE_PLAYING) {
|
---|
61 | n = select(32,&readfds,NULL,NULL,&timeout);
|
---|
62 | if(n == 0) {
|
---|
63 | if(!read_frame(fr)) {
|
---|
64 | mode = MODE_STOPPED;
|
---|
65 | close_stream();
|
---|
66 | sajber_sendmsg(MSG_NEXT,0);
|
---|
67 | continue;
|
---|
68 | }
|
---|
69 | play_frame(init,fr);
|
---|
70 | if(init) {
|
---|
71 | AudioInfo sai;
|
---|
72 | sai.bitrate = tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index] * 1000;
|
---|
73 | sai.frequency = freqs[fr->sampling_frequency];
|
---|
74 | sai.stereo = fr->stereo;
|
---|
75 | sai.type = fr->lay;
|
---|
76 | sai.sample = 16;
|
---|
77 | sajber_sendmsg(MSG_INFO,TRUE);
|
---|
78 | write(1,&sai,sizeof(AudioInfo));
|
---|
79 | init = 0;
|
---|
80 |
|
---|
81 | }
|
---|
82 | framecnt++;
|
---|
83 | if(!(framecnt & 0xf)) {
|
---|
84 | sajber_sendmsg(MSG_FRAMES,framecnt);
|
---|
85 | sajber_sendmsg(MSG_POSITION,tell_stream());
|
---|
86 | }
|
---|
87 | }
|
---|
88 | }
|
---|
89 | else {
|
---|
90 | while(1) {
|
---|
91 | n = select(32,&readfds,NULL,NULL,NULL);
|
---|
92 | if(n > 0)
|
---|
93 | break;
|
---|
94 | }
|
---|
95 | }
|
---|
96 | if(n < 0) {
|
---|
97 | exit(1);
|
---|
98 | }
|
---|
99 | if(n > 0) {
|
---|
100 | int len;
|
---|
101 | len = read(0,&rmsg,sizeof(TControlMsg));
|
---|
102 | if(len != sizeof(TControlMsg)) {
|
---|
103 | fprintf(stderr,"Error reading control message!\n");
|
---|
104 | exit(1);
|
---|
105 | }
|
---|
106 | #if 0
|
---|
107 | fprintf(stderr,"%d.%d\n",rmsg.type,rmsg.data);
|
---|
108 | #endif
|
---|
109 | switch(rmsg.type) {
|
---|
110 | case MSG_CTRL:
|
---|
111 | switch(rmsg.data) {
|
---|
112 | case FORWARD_STEP:
|
---|
113 | if(mode != MODE_STOPPED) {
|
---|
114 | int i;
|
---|
115 | for(i=0;i<16;i++) {
|
---|
116 | read_frame(fr);
|
---|
117 | if(framecnt && fr->lay == 3)
|
---|
118 | set_pointer(512);
|
---|
119 | framecnt++;
|
---|
120 | }
|
---|
121 | }
|
---|
122 | sajber_sendmsg(MSG_RESPONSE,FORWARD_STEP);
|
---|
123 | break;
|
---|
124 | case FORWARD_BEGIN:
|
---|
125 | sajber_sendmsg(MSG_RESPONSE,FORWARD_BEGIN);
|
---|
126 | break;
|
---|
127 | case FORWARD_END:
|
---|
128 | sajber_sendmsg(MSG_RESPONSE,FORWARD_END);
|
---|
129 | break;
|
---|
130 | case REWIND_BEGIN:
|
---|
131 | sajber_sendmsg(MSG_RESPONSE,REWIND_BEGIN);
|
---|
132 | break;
|
---|
133 | case REWIND_STEP:
|
---|
134 | if(back_frame(fr,16) == 0)
|
---|
135 | framecnt -= 16;
|
---|
136 | else
|
---|
137 | framecnt = 0;
|
---|
138 | sajber_sendmsg(MSG_RESPONSE,REWIND_STEP);
|
---|
139 | break;
|
---|
140 | case REWIND_END:
|
---|
141 | sajber_sendmsg(MSG_RESPONSE,REWIND_END);
|
---|
142 | break;
|
---|
143 | case PLAY_STOP:
|
---|
144 | mode = MODE_STOPPED;
|
---|
145 | close_stream();
|
---|
146 | break;
|
---|
147 | case PLAY_PAUSE:
|
---|
148 | mode = MODE_PAUSED;
|
---|
149 | break;
|
---|
150 | }
|
---|
151 | break;
|
---|
152 | case MSG_BUFFER:
|
---|
153 | break;
|
---|
154 | case MSG_SONG:
|
---|
155 | if(mode == MODE_PLAYING) {
|
---|
156 | close_stream();
|
---|
157 | mode = MODE_STOPPED;
|
---|
158 | }
|
---|
159 |
|
---|
160 | iovec[0].iov_base = buf;
|
---|
161 | iovec[0].iov_len = 2;
|
---|
162 | /*
|
---|
163 | * this control message 'delivers' a given file
|
---|
164 | * descriptor to another process ..
|
---|
165 | * the sent descriptor can then be accesed by the
|
---|
166 | * child process.
|
---|
167 | */
|
---|
168 | cmsghdr.cmsg_len = sizeof(cmsghdr);
|
---|
169 | cmsghdr.cmsg_level = SOL_SOCKET;
|
---|
170 | cmsghdr.cmsg_type = SCM_RIGHTS;
|
---|
171 |
|
---|
172 | msghdr.msg_name = NULL;
|
---|
173 | msghdr.msg_namelen = 0;
|
---|
174 | msghdr.msg_iov = iovec;
|
---|
175 | msghdr.msg_iovlen = 1;
|
---|
176 | msghdr.msg_control = &cmsghdr;
|
---|
177 | msghdr.msg_controllen = sizeof(cmsghdr);
|
---|
178 |
|
---|
179 | if(recvmsg(0,&msghdr,0) < 0) {
|
---|
180 | perror("recvmsg");
|
---|
181 | exit(1);
|
---|
182 | }
|
---|
183 |
|
---|
184 | open_stream(NULL,cmsghdr.fd);
|
---|
185 | mode = MODE_PLAYING;
|
---|
186 | init = 1;
|
---|
187 | framecnt = 0;
|
---|
188 | read_frame_init();
|
---|
189 | break;
|
---|
190 | case MSG_QUIT:
|
---|
191 | exit(0);
|
---|
192 | break;
|
---|
193 | case MSG_QUERY:
|
---|
194 | smsg.type = MSG_RESPONSE;
|
---|
195 | smsg.data = FALSE;
|
---|
196 | switch(rmsg.data) {
|
---|
197 | case QUERY_PLAYING:
|
---|
198 | if(mode == MODE_PLAYING)
|
---|
199 | smsg.data = TRUE;
|
---|
200 | break;
|
---|
201 | case QUERY_PAUSED:
|
---|
202 | if(mode == MODE_PAUSED)
|
---|
203 | smsg.data = TRUE;
|
---|
204 | break;
|
---|
205 | }
|
---|
206 | write(1,&smsg,sizeof(TControlMsg));
|
---|
207 | break;
|
---|
208 | case MSG_BUFAHEAD:
|
---|
209 | break;
|
---|
210 | case MSG_SEEK:
|
---|
211 | break;
|
---|
212 | case MSG_PRIORITY:
|
---|
213 | break;
|
---|
214 | case MSG_RELEASE:
|
---|
215 | break;
|
---|
216 | }
|
---|
217 |
|
---|
218 | }
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | void control_tk3play(struct frame *fr)
|
---|
223 | {
|
---|
224 |
|
---|
225 | }
|
---|
226 |
|
---|
227 |
|
---|