make header_len an integer
[paraslash.git] / afs.c
1 /*
2 * Copyright (C) 1997-2006 Andre Noll <maan@systemlinux.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
17 */
18
19 /** \file afs.c audio file sending functions
20 *
21 * This contains the audio sending part of para_server which is independent
22 * of the current audio format, database tool and of the activated senders.
23 */
24
25 #include <sys/time.h> /* gettimeofday */
26 #include "server.cmdline.h"
27 #include "db.h"
28 #include "server.h"
29 #include "afs.h"
30 #include "send.h"
31 #include "error.h"
32 #include "string.h"
33
34 extern const char *status_item_list[];
35
36 static struct timeval announce_tv;
37 static struct timeval data_send_barrier;
38 static struct timeval eof_barrier;
39
40 extern struct misc_meta_data *mmd;
41 extern struct dbtool dblist[];
42 extern struct sender senders[];
43 extern struct gengetopt_args_info conf;
44
45 static FILE *audio_file = NULL;
46
47 #if 1
48 void mp3_init(void *);
49 #endif
50
51 #ifdef HAVE_OGGVORBIS
52 void ogg_init(void *);
53 #endif
54
55 /**
56 * the list of supported audio formats
57 */
58 struct audio_format afl[] = {
59 #if 1
60 {
61 .name = "mp3",
62 .init = mp3_init,
63 },
64 #endif
65 #ifdef HAVE_OGGVORBIS
66 {
67 .name = "ogg",
68 .init = ogg_init,
69 },
70 #endif
71 {
72 .name = NULL,
73 }
74 };
75
76
77 /**
78 * check if audio file sender is playing
79 *
80 * \return greater than zero if playing, zero otherwise.
81 *
82 */
83 unsigned int afs_playing(void)
84 {
85 return mmd->new_afs_status_flags & AFS_PLAYING;
86 }
87
88 /**
89 * check if 'next' flag is set afs_status_flags
90 *
91 * \return greater than zero if set, zero if not.
92 *
93 */
94 unsigned int afs_next(void)
95 {
96 return mmd->new_afs_status_flags & AFS_NEXT;
97 }
98
99 /**
100 * check if a reposition request is pending
101 *
102 * \return greater than zero if true, zero otherwise.
103 *
104 */
105 unsigned int afs_repos(void)
106 {
107 return mmd->new_afs_status_flags & AFS_REPOS;
108 }
109
110 /**
111 * check if audio file sender is paused
112 *
113 * \return greater than zero if paused, zero otherwise.
114 *
115 */
116 unsigned int afs_paused(void)
117 {
118 return !(mmd->new_afs_status_flags & AFS_NEXT)
119 && !(mmd->new_afs_status_flags & AFS_PLAYING);
120 }
121
122 /**
123 * get the name of the given audio format
124 * \param i the audio format number
125 *
126 * This returns a pointer to statically allocated memory so it
127 * must not be freed by the caller.
128 */
129 const char *audio_format_name(int i)
130 {
131 return i >= 0? afl[i].name : "(none)";
132 }
133
134 /**
135 * initialize the audio file sender
136 *
137 * Call the init functions of all supported audio format handlers and
138 * initialize all supported senders.
139 */
140 void afs_init(void)
141 {
142 int i;
143 char *hn = para_hostname(), *home = para_homedir();
144
145 PARA_DEBUG_LOG("supported audio formats: %s\n",
146 SUPPORTED_AUDIO_FORMATS);
147 for (i = 0; afl[i].name; i++) {
148 PARA_NOTICE_LOG("initializing %s handler\n",
149 afl[i].name);
150 afl[i].init(&afl[i]);
151 }
152 ms2tv(conf.announce_time_arg, &announce_tv);
153 PARA_INFO_LOG("announce timeval: %lu:%lu\n", announce_tv.tv_sec, announce_tv.tv_usec);
154 for (i = 0; senders[i].name; i++) {
155 PARA_NOTICE_LOG("initializing %s sender\n", senders[i].name);
156 senders[i].init(&senders[i]);
157 }
158 free(hn);
159 free(home);
160 }
161
162 static int get_file_info(int i)
163 {
164 return afl[i].get_file_info(audio_file, mmd->audio_file_info,
165 &mmd->chunks_total, &mmd->seconds_total);
166 }
167
168 /*
169 * guess the audio format judging from filename
170 * \param name the filename
171 *
172 * \return This function returns -1 if it has no idea what kind of audio
173 * file this might be. Otherwise the (non-negative) number of the audio format
174 * is returned.
175 */
176 static int guess_audio_format(const char *name)
177 {
178
179 int i, len1 = strlen(name), len2;
180
181 for (i = 0; afl[i].name; i++) {
182 len2 = strlen(afl[i].name);
183 if (len1 < len2)
184 continue;
185 if (!strncasecmp(name + (len1 - len2), afl[i].name, len2)) {
186 PARA_DEBUG_LOG("might be %s\n", afl[i].name);
187 return i;
188 }
189 }
190 return -1;
191 }
192
193 static int get_audio_format(int omit)
194 {
195 int i;
196
197 for (i = 0; afl[i].name; i++) {
198 if (i == omit || !afl[i].get_file_info)
199 continue;
200 rewind(audio_file);
201 if (get_file_info(i) > 0)
202 return i;
203 rewind(audio_file);
204 }
205 return -E_AUDIO_FORMAT;
206 }
207
208 /*
209 * upddate shared mem
210 */
211 static int update_mmd(void)
212 {
213 int i;
214 struct stat file_status;
215
216 i = guess_audio_format(mmd->filename);
217 if (i < 0 || get_file_info(i) < 0)
218 i = get_audio_format(i);
219 if (i < 0)
220 return i;
221 mmd->audio_format = i;
222 mmd->chunks_sent = 0;
223 mmd->current_chunk = 0;
224 mmd->offset = 0;
225 if (fstat(fileno(audio_file), &file_status) == -1)
226 return -E_FSTAT;
227 mmd->size = file_status.st_size;
228 mmd->mtime = file_status.st_mtime;
229 mmd->events++;
230 PARA_NOTICE_LOG("next audio file: %s\n", mmd->filename);
231 return 1;
232 }
233
234 static void get_song(void)
235 {
236 char **sl = dblist[mmd->dbt_num].get_audio_file_list(10);
237 int i;
238
239 if (!sl)
240 goto err_out;
241 for (i = 0; sl[i]; i++) {
242 struct timeval now;
243 PARA_INFO_LOG("trying %s\n", sl[i]);
244 if (strlen(sl[i]) >= _POSIX_PATH_MAX)
245 continue;
246 audio_file = fopen(sl[i], "r");
247 if (!audio_file)
248 continue;
249 strcpy(mmd->filename, sl[i]);
250 if (update_mmd() < 0) {
251 fclose(audio_file);
252 audio_file = NULL;
253 continue;
254 }
255 mmd->num_played++;
256 if (dblist[mmd->dbt_num].update_audio_file)
257 dblist[mmd->dbt_num].update_audio_file(sl[i]);
258 PARA_DEBUG_LOG("%s", "success\n");
259 mmd->new_afs_status_flags &= (~AFS_NEXT);
260 gettimeofday(&now, NULL);
261 tv_add(&now, &announce_tv, &data_send_barrier);
262
263 goto free;
264 }
265 PARA_ERROR_LOG("%s", "no valid files found\n");
266 err_out:
267 mmd->new_afs_status_flags = AFS_NEXT;
268 free:
269 if (sl) {
270 for (i = 0; sl[i]; i++)
271 free(sl[i]);
272 free(sl);
273 }
274 }
275
276 static int chk_barrier(const char *bname, const struct timeval *now,
277 const struct timeval *barrier, struct timeval *diff, int log)
278 {
279 long ms;
280
281 if (tv_diff(now, barrier, diff) > 0)
282 return 1;
283 ms = tv2ms(diff);
284 if (log && ms)
285 PARA_DEBUG_LOG("%s barrier: %lims left\n", bname, ms);
286 return -1;
287 }
288
289 static void afs_next_chunk_time(struct timeval *due)
290 {
291 struct timeval tmp;
292
293 tv_scale(mmd->chunks_sent, &afl[mmd->audio_format].chunk_tv, &tmp);
294 tv_add(&tmp, &mmd->stream_start, due);
295 }
296
297 /*
298 * != NULL: timeout for next chunk
299 * NULL: nothing to do
300 */
301 static struct timeval *afs_compute_timeout(void)
302 {
303 static struct timeval the_timeout;
304 struct timeval now, next_chunk;
305
306 if (afs_next() && mmd->audio_format >= 0) {
307 /* only sleep a bit, nec*/
308 the_timeout.tv_sec = 0;
309 the_timeout.tv_usec = 100;
310 return &the_timeout;
311 }
312 gettimeofday(&now, NULL);
313 if (chk_barrier("eof", &now, &eof_barrier, &the_timeout, 1) < 0)
314 return &the_timeout;
315 if (chk_barrier("data send", &now, &data_send_barrier,
316 &the_timeout, 1) < 0)
317 return &the_timeout;
318 if (mmd->audio_format < 0 || !afs_playing() || !audio_file)
319 return NULL;
320 afs_next_chunk_time(&next_chunk);
321 if (chk_barrier(afl[mmd->audio_format].name, &now, &next_chunk,
322 &the_timeout, 0) < 0)
323 return &the_timeout;
324 /* chunk is due or bof */
325 the_timeout.tv_sec = 0;
326 the_timeout.tv_usec = 0;
327 return &the_timeout;
328 }
329
330 static void afs_eof(struct audio_format *af)
331 {
332 struct timeval now;
333 int i;
334 char *tmp;
335
336 if (!af || !audio_file) {
337 for (i = 0; senders[i].name; i++)
338 senders[i].shutdown_clients();
339 return;
340 }
341 gettimeofday(&now, NULL);
342 tv_add(&af->eof_tv, &now, &eof_barrier);
343 af->close_audio_file();
344 audio_file = NULL;
345 mmd->audio_format = -1;
346 af = NULL;
347 mmd->chunks_sent = 0;
348 mmd->offset = 0;
349 mmd->seconds_total = 0;
350 tmp = make_message("%s:\n%s:\n%s:\n", status_item_list[SI_AUDIO_INFO1],
351 status_item_list[SI_AUDIO_INFO2], status_item_list[SI_AUDIO_INFO3]);
352 strcpy(mmd->audio_file_info, tmp);
353 free(tmp);
354 tmp = make_message("%s:\n%s:\n%s:\n", status_item_list[SI_DBINFO1],
355 status_item_list[SI_DBINFO2], status_item_list[SI_DBINFO3]);
356 strcpy(mmd->dbinfo, tmp);
357 free(tmp);
358 mmd->filename[0] = '\0';
359 mmd->size = 0;
360 mmd->events++;
361 }
362
363 /**
364 * compute the timeout for para_server's main select-loop
365 *
366 * This function gets called from para_server to determine the timeout value
367 * for its main select loop.
368 *
369 * Before the timeout is computed, the current afs status flags are evaluated
370 * and acted upon by calling appropriate functions from the lower layers.
371 * Possible actions include
372 *
373 * - request a new file list from the current dabase tool (audio file change)
374 * - shutdown of all senders (stop/pause command)
375 * - repositioning of the stream (ff/jmp command)
376 *
377 * \return A pointer to a struct timeval containing the timeout for the next
378 * chunk of data to be sent, or NULL if we're not sending right now.
379 */
380 struct timeval *afs_preselect(void)
381 {
382 struct audio_format *af = NULL;
383 int i, format;
384 struct timeval *ret;
385 again:
386 format = mmd->audio_format;
387 if (format >= 0)
388 af = afl + format;
389 else
390 for (i = 0; senders[i].name; i++)
391 senders[i].shutdown_clients();
392 if (afs_next() && af) {
393 afs_eof(af);
394 return afs_compute_timeout();
395 }
396 if (afs_paused() || afs_repos()) {
397 for (i = 0; senders[i].name; i++)
398 senders[i].shutdown_clients();
399 if (af) {
400 struct timeval now;
401 if (!afs_paused() || mmd->chunks_sent) {
402 gettimeofday(&now, NULL);
403 tv_add(&af->eof_tv, &now, &eof_barrier);
404 }
405 if (afs_repos())
406 tv_add(&now, &announce_tv, &data_send_barrier);
407 if (mmd->new_afs_status_flags & AFS_NOMORE)
408 mmd->new_afs_status_flags = AFS_NEXT;
409 }
410 mmd->chunks_sent = 0;
411 }
412 if (af && afs_repos() && mmd->current_chunk != mmd->repos_request)
413 af->reposition_stream(mmd->repos_request);
414 if (afs_repos()) {
415 mmd->new_afs_status_flags &= ~(AFS_REPOS);
416 mmd->current_chunk = mmd->repos_request;
417 }
418 ret = afs_compute_timeout();
419 if (!ret && !audio_file && afs_playing() &&
420 !(mmd->new_afs_status_flags & AFS_NOMORE)) {
421 PARA_DEBUG_LOG("%s", "ready and playing, but no audio file\n");
422 get_song();
423 goto again;
424 }
425 return ret;
426 }
427
428 /**
429 * afs_send_chunk - paraslash's main sending function
430 *
431 * This function gets called from para_server as soon as the next chunk of
432 * data should be pushed out. It first calls the read_chunk() function of
433 * the current audio format handler to obtain a pointer to the data to be
434 * sent out as well as its length. This information is then passed to each
435 * supported sender's send() function which does the actual sending.
436 *
437 * Return value: Positive return value on success, zero on eof and negative
438 * on errors.
439 */
440
441 void afs_send_chunk(void)
442 {
443 int i;
444 struct audio_format *af;
445 char *buf;
446 ssize_t ret;
447 struct timeval now, due;
448
449 if (mmd->audio_format < 0 || !audio_file || !afs_playing())
450 return;
451 af = &afl[mmd->audio_format];
452 gettimeofday(&now, NULL);
453 afs_next_chunk_time(&due);
454 if (tv_diff(&due, &now, NULL) > 0)
455 return;
456 buf = af->read_chunk(mmd->current_chunk, &ret);
457 mmd->new_afs_status_flags &= ~(AFS_NEXT | AFS_REPOS);
458 if (!buf) {
459 if (ret < 0)
460 mmd->new_afs_status_flags = AFS_NEXT;
461 else
462 mmd->new_afs_status_flags |= AFS_NEXT;
463 afs_eof(af);
464 return;
465 }
466 if (!mmd->chunks_sent) {
467 struct timeval tmp;
468 gettimeofday(&mmd->stream_start, NULL);
469 tv_scale(mmd->current_chunk, &af->chunk_tv, &tmp);
470 mmd->offset = tv2ms(&tmp);
471 mmd->events++;
472 }
473 for (i = 0; senders[i].name; i++)
474 senders[i].send(af, mmd->current_chunk,
475 mmd->chunks_sent, buf, ret);
476 mmd->new_afs_status_flags |= AFS_PLAYING;
477 mmd->chunks_sent++;
478 mmd->current_chunk++;
479 }