chiark / gitweb /
correct disorder-normalize
[disorder] / server / play.c
1 /*
2  * This file is part of DisOrder.
3  * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  */
20
21 #include <config.h>
22 #include "types.h"
23
24 #include <sys/types.h>
25 #include <sys/time.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <fnmatch.h>
29 #include <time.h>
30 #include <signal.h>
31 #include <stdlib.h>
32 #include <assert.h>
33 #include <sys/socket.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <pcre.h>
37 #include <ao/ao.h>
38 #include <sys/wait.h>
39
40 #include "event.h"
41 #include "log.h"
42 #include "mem.h"
43 #include "configuration.h"
44 #include "queue.h"
45 #include "trackdb.h"
46 #include "play.h"
47 #include "plugin.h"
48 #include "wstat.h"
49 #include "eventlog.h"
50 #include "logfd.h"
51 #include "syscalls.h"
52 #include "speaker-protocol.h"
53 #include "disorder.h"
54 #include "signame.h"
55 #include "hash.h"
56
57 #define SPEAKER "disorder-speaker"
58
59 struct queue_entry *playing;
60 int paused;
61
62 static void finished(ev_source *ev);
63
64 static int speaker_fd = -1;
65 static hash *player_pids;
66 static int shutting_down;
67
68 static void store_player_pid(const char *id, pid_t pid) {
69   if(!player_pids) player_pids = hash_new(sizeof (pid_t));
70   hash_add(player_pids, id, &pid, HASH_INSERT_OR_REPLACE);
71 }
72
73 static pid_t find_player_pid(const char *id) {
74   pid_t *pidp;
75
76   if(player_pids && (pidp = hash_find(player_pids, id))) return *pidp;
77   return -1;
78 }
79
80 static void forget_player_pid(const char *id) {
81   if(player_pids) hash_remove(player_pids, id);
82 }
83
84 /* called when speaker process terminates */
85 static int speaker_terminated(ev_source attribute((unused)) *ev,
86                               pid_t attribute((unused)) pid,
87                               int attribute((unused)) status,
88                               const struct rusage attribute((unused)) *rusage,
89                               void attribute((unused)) *u) {
90   if(status)
91     error(0, "speaker subprocess terminated with status %s",
92           wstat(status));
93   return 0;
94 }
95
96 /* called when speaker process has something to say */
97 static int speaker_readable(ev_source *ev, int fd,
98                             void attribute((unused)) *u) {
99   struct speaker_message sm;
100   int ret = speaker_recv(fd, &sm, 0);
101   
102   if(ret < 0) return 0;                 /* EAGAIN */
103   if(!ret) {                            /* EOF */
104     ev_fd_cancel(ev, ev_read, fd);
105     return 0;
106   }
107   switch(sm.type) {
108   case SM_PAUSED:
109     /* track ID is paused, DATA seconds played */
110     D(("SM_PAUSED %s %ld", sm.id, sm.data));
111     playing->sofar = sm.data;
112     break;
113   case SM_FINISHED:
114     /* the playing track finished */
115     D(("SM_FINISHED %s", sm.id));
116     finished(ev);
117     break;
118   case SM_PLAYING:
119     /* track ID is playing, DATA seconds played */
120     D(("SM_PLAYING %s %ld", sm.id, sm.data));
121     playing->sofar = sm.data;
122     break;
123   default:
124     error(0, "unknown message type %d", sm.type);
125   }
126   return 0;
127 }
128
129 void speaker_setup(ev_source *ev) {
130   int sp[2], lfd;
131   pid_t pid;
132
133   if(socketpair(PF_UNIX, SOCK_DGRAM, 0, sp) < 0)
134     fatal(errno, "error calling socketpair");
135   if(!isatty(2))
136     lfd = logfd(ev, SPEAKER);
137   else
138     lfd = -1;
139   if(!(pid = xfork())) {
140     exitfn = _exit;
141     ev_signal_atfork(ev);
142     xdup2(sp[0], 0);
143     xdup2(sp[0], 1);
144     xclose(sp[0]);
145     xclose(sp[1]);
146     if(lfd != -1) {
147       xdup2(lfd, 2);
148       xclose(lfd);
149     }
150     signal(SIGPIPE, SIG_DFL);
151 #if 0
152     execlp("valgrind", "valgrind", SPEAKER, "--config", configfile,
153            debugging ? "--debug" : "--no-debug", (char *)0);
154 #else
155     execlp(SPEAKER, SPEAKER, "--config", configfile,
156            debugging ? "--debug" : "--no-debug", (char *)0);
157 #endif
158     fatal(errno, "error invoking %s", SPEAKER);
159   }
160   ev_child(ev, pid, 0, speaker_terminated, 0);
161   speaker_fd = sp[1];
162   xclose(sp[0]);
163   cloexec(speaker_fd);
164   /* Don't need to make speaker_fd nonblocking because speaker_recv() uses
165    * MSG_DONTWAIT. */
166   ev_fd(ev, ev_read, speaker_fd, speaker_readable, 0);
167 }
168
169 void speaker_reload(void) {
170   struct speaker_message sm;
171
172   memset(&sm, 0, sizeof sm);
173   sm.type = SM_RELOAD;
174   speaker_send(speaker_fd, &sm, -1);
175 }
176
177 /* timeout for play retry */
178 static int play_again(ev_source *ev,
179                       const struct timeval attribute((unused)) *now,
180                       void attribute((unused)) *u) {
181   D(("play_again"));
182   play(ev);
183   return 0;
184 }
185
186 /* try calling play() again after @offset@ seconds */
187 static void retry_play(ev_source *ev, int offset) {
188   struct timeval w;
189
190   D(("retry_play(%d)", offset));
191   gettimeofday(&w, 0);
192   w.tv_sec += offset;
193   ev_timeout(ev, 0, &w, play_again, 0);
194 }
195
196 /* Called when the currently playing track finishes playing.  This
197  * might be because the player finished or because the speaker process
198  * told us so. */
199 static void finished(ev_source *ev) {
200   D(("finished playing=%p", (void *)playing));
201   if(!playing)
202     return;
203   if(playing->state != playing_scratched)
204     notify_not_scratched(playing->track, playing->submitter);
205   switch(playing->state) {
206   case playing_ok:
207     eventlog("completed", playing->track, (char *)0);
208     break;
209   case playing_scratched:
210     eventlog("scratched", playing->track, playing->scratched, (char *)0);
211     break;
212   case playing_failed:
213     eventlog("failed", playing->track, wstat(playing->wstat), (char *)0);
214     break;
215   default:
216     break;
217   }
218   queue_played(playing);
219   recent_write();
220   forget_player_pid(playing->id);
221   playing = 0;
222   if(ev) retry_play(ev, config->gap);
223 }
224
225 /* Called when a player terminates. */
226 static int player_finished(ev_source *ev,
227                            pid_t pid,
228                            int status,
229                            const struct rusage attribute((unused)) *rusage,
230                            void *u) {
231   struct queue_entry *q = u;
232
233   D(("player_finished pid=%lu status=%#x",
234      (unsigned long)pid, (unsigned)status));
235   /* Record that this PID is dead.  If we killed the track we might know this
236    * already, but also it might have exited or crashed.  Either way we don't
237    * want to end up signalling it. */
238   if(pid == find_player_pid(q->id))
239     forget_player_pid(q->id);
240   switch(q->state) {
241   case playing_unplayed:
242   case playing_random:
243     /* If this was an SM_PREPARE track then either it failed or we deliberately
244      * stopped it because it was removed from the queue or moved down it.  So
245      * leave it state alone for future use. */
246     break;
247   default:
248     /* We actually started playing this track. */
249     if(status) {
250       if(q->state != playing_scratched)
251         q->state = playing_failed;
252     } else 
253       q->state = playing_ok;
254     break;
255   }
256   /* Regardless we always report and record the status and do cleanup for
257    * prefork calls. */
258   if(status)
259     error(0, "player for %s %s", q->track, wstat(status));
260   if(q->type & DISORDER_PLAYER_PREFORK)
261     play_cleanup(q->pl, q->data);
262   q->wstat = status;
263   /* If this actually was the current track, and does not use the speaker
264    * process, then it must have finished.  For raw-output players we will get a
265    * separate notification from the speaker process. */
266   if(q == playing
267      && (q->type & DISORDER_PLAYER_TYPEMASK) != DISORDER_PLAYER_RAW)
268     finished(ev);
269   return 0;
270 }
271
272 /* Find the player for Q */
273 static int find_player(const struct queue_entry *q) {
274   int n;
275   
276   for(n = 0; n < config->player.n; ++n)
277     if(fnmatch(config->player.s[n].s[0], q->track, 0) == 0)
278       break;
279   if(n >= config->player.n)
280     return -1;
281   else
282     return n;
283 }
284
285 /* Return values from start() */
286 #define START_OK 0                      /* Succeeded. */
287 #define START_HARDFAIL 1                /* Track is broken. */
288 #define START_SOFTFAIL 2           /* Track OK, system (temporarily?) broken */
289
290 /* Play or prepare Q */
291 static int start(ev_source *ev,
292                  struct queue_entry *q,
293                  int smop) {
294   int n, lfd;
295   const char *p;
296   int np[2], sp[2];
297   struct speaker_message sm;
298   char buffer[64];
299   int optc;
300   ao_sample_format format;
301   ao_device *device;
302   int retries;
303   struct timespec ts;
304   const char *waitdevice = 0;
305   const char *const *optv;
306   pid_t pid, npid;
307
308   memset(&sm, 0, sizeof sm);
309   if(find_player_pid(q->id) > 0) {
310     if(smop == SM_PREPARE) return START_OK;
311     /* We have already sent an SM_PREPARE for this track so we just need to
312      * tell the speaker process to start actually playing the queued up audio
313      * data */
314     strcpy(sm.id, q->id);
315     sm.type = SM_PLAY;
316     speaker_send(speaker_fd, &sm, -1);
317     return START_OK;
318   }
319   /* Find the player plugin. */
320   if((n = find_player(q)) < 0) return START_HARDFAIL;
321   if(!(q->pl = open_plugin(config->player.s[n].s[1], 0)))
322     return START_HARDFAIL;
323   q->type = play_get_type(q->pl);
324   /* Can't prepare non-raw tracks. */
325   if(smop == SM_PREPARE
326      && (q->type & DISORDER_PLAYER_TYPEMASK) != DISORDER_PLAYER_RAW)
327     return START_OK;
328   /* Call the prefork function. */
329   p = trackdb_rawpath(q->track);
330   if(q->type & DISORDER_PLAYER_PREFORK)
331     if(!(q->data = play_prefork(q->pl, p))) {
332       error(0, "prefork function for %s failed", q->track);
333       return START_HARDFAIL;
334     }
335   /* Use the second arg as the tag if available (it's probably a command name),
336    * otherwise the module name. */
337   lfd = logfd(ev, (config->player.s[n].s[2]
338                    ? config->player.s[n].s[2] : config->player.s[n].s[1]));
339   optc = config->player.s[n].n - 2;
340   optv = (void *)&config->player.s[n].s[2];
341   while(optc > 0 && optv[0][0] == '-') {
342     if(!strcmp(optv[0], "--")) {
343       ++optv;
344       --optc;
345       break;
346     }
347     if(!strcmp(optv[0], "--wait-for-device")
348        || !strncmp(optv[0], "--wait-for-device=", 18)) {
349       if((waitdevice = strchr(optv[0], '='))) {
350         ++waitdevice;
351       } else
352         waitdevice = "";                /* use default */
353       ++optv;
354       --optc;
355     } else {
356       error(0, "unknown option %s", optv[0]);
357       return START_HARDFAIL;
358     }
359   }
360   switch(pid = fork()) {
361   case 0:                       /* child */
362     exitfn = _exit;
363     ev_signal_atfork(ev);
364     signal(SIGPIPE, SIG_DFL);
365     xdup2(lfd, 1);
366     xdup2(lfd, 2);
367     xclose(lfd);                        /* tidy up */
368     setpgid(0, 0);
369     if((q->type & DISORDER_PLAYER_TYPEMASK) == DISORDER_PLAYER_RAW) {
370       /* "Raw" format players need special treatment:
371        * 1) their output needs to go via the disorder-normalize process
372        * 2) the output of that needs to be passed to the disorder-speaker
373        *    process.
374        */
375       /* np will be the pipe to disorder-normalize */
376       if(socketpair(PF_UNIX, SOCK_STREAM, 0, np) < 0)
377         fatal(errno, "error calling socketpair");
378       xshutdown(np[0], SHUT_WR);        /* normalize reads from np[0] */
379       xshutdown(np[1], SHUT_RD);        /* decoder writes to np[1] */
380       /* sp will be the pipe to disorder-speaker */
381       sm.type = smop;
382       if(socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0)
383         fatal(errno, "error calling socketpair");
384       xshutdown(sp[0], SHUT_WR);        /* speaker reads from sp[0] */
385       xshutdown(sp[1], SHUT_RD);        /* normalize writes to sp[1] */
386       /* Start disorder-normalize */
387       if(!(npid = xfork())) {
388         if(!xfork()) {
389           xdup2(np[0], 0);
390           xdup2(sp[1], 1);
391           xclose(np[0]);
392           xclose(np[1]);
393           xclose(sp[0]);
394           xclose(sp[1]);
395           execlp("disorder-normalize", "disorder-normalize", (char *)0);
396           fatal(errno, "executing disorder-normalize");
397         }
398         _exit(0);
399       } else {
400         int w;
401
402         while(waitpid(npid, &w, 0) < 0 && errno == EINTR)
403           ;
404       }
405       /* Send the speaker process the file descriptor to read from */
406       strcpy(sm.id, q->id);
407       speaker_send(speaker_fd, &sm, sp[0]);
408       /* Pass the file descriptor to the driver in an environment
409        * variable. */
410       snprintf(buffer, sizeof buffer, "DISORDER_RAW_FD=%d", np[1]);
411       if(putenv(buffer) < 0)
412         fatal(errno, "error calling putenv");
413       /* Close all the FDs we don't need */
414       xclose(sp[0]);
415       xclose(sp[1]);
416       xclose(np[0]);
417     }
418     if(waitdevice) {
419       ao_initialize();
420       if(*waitdevice) {
421         n = ao_driver_id(waitdevice);
422         if(n == -1)
423           fatal(0, "invalid libao driver: %s", optv[0]);
424         } else
425           n = ao_default_driver_id();
426       /* Make up a format. */
427       memset(&format, 0, sizeof format);
428       format.bits = 8;
429       format.rate = 44100;
430       format.channels = 1;
431       format.byte_format = AO_FMT_NATIVE;
432       retries = 20;
433       ts.tv_sec = 0;
434       ts.tv_nsec = 100000000;   /* 0.1s */
435       while((device = ao_open_live(n, &format, 0)) == 0 && retries-- > 0)
436           nanosleep(&ts, 0);
437       if(device)
438         ao_close(device);
439     }
440     play_track(q->pl,
441                optv, optc,
442                p,
443                q->track);
444     _exit(0);
445   case -1:                      /* error */
446     error(errno, "error calling fork");
447     if(q->type & DISORDER_PLAYER_PREFORK)
448       play_cleanup(q->pl, q->data);     /* else would leak */
449     xclose(lfd);
450     return START_SOFTFAIL;
451   }
452   store_player_pid(q->id, pid);
453   xclose(lfd);
454   setpgid(pid, pid);
455   ev_child(ev, pid, 0, player_finished, q);
456   D(("player subprocess ID %lu", (unsigned long)pid));
457   return START_OK;
458 }
459
460 int prepare(ev_source *ev,
461             struct queue_entry *q) {
462   int n;
463
464   /* Find the player plugin */
465   if(find_player_pid(q->id) > 0) return 0; /* Already going. */
466   if((n = find_player(q)) < 0) return -1; /* No player */
467   q->pl = open_plugin(config->player.s[n].s[1], 0); /* No player */
468   q->type = play_get_type(q->pl);
469   if((q->type & DISORDER_PLAYER_TYPEMASK) != DISORDER_PLAYER_RAW)
470     return 0;                           /* Not a raw player */
471   return start(ev, q, SM_PREPARE);      /* Prepare it */
472 }
473
474 void abandon(ev_source attribute((unused)) *ev,
475              struct queue_entry *q) {
476   struct speaker_message sm;
477   pid_t pid = find_player_pid(q->id);
478
479   if(pid < 0) return;                   /* Not prepared. */
480   if((q->type & DISORDER_PLAYER_TYPEMASK) != DISORDER_PLAYER_RAW)
481     return;                             /* Not a raw player. */
482   /* Terminate the player. */
483   kill(-pid, config->signal);
484   forget_player_pid(q->id);
485   /* Cancel the track. */
486   memset(&sm, 0, sizeof sm);
487   sm.type = SM_CANCEL;
488   strcpy(sm.id, q->id);
489   speaker_send(speaker_fd, &sm, -1);
490 }
491
492 int add_random_track(void) {
493   struct queue_entry *q;
494   const char *p;
495   long qlen = 0;
496   int rc = 0;
497
498   /* If random play is not enabled then do nothing. */
499   if(shutting_down || !random_is_enabled())
500     return 0;
501   /* Count how big the queue is */
502   for(q = qhead.next; q != &qhead; q = q->next)
503     ++qlen;
504   /* Add random tracks until the queue is at the right size */
505   while(qlen < config->queue_pad) {
506     /* Try to pick a random track */
507     if(!(p = trackdb_random(16))) {
508       rc = -1;
509       break;
510     }
511     /* Add it to the end of the queue. */
512     q = queue_add(p, 0, WHERE_END);
513     q->state = playing_random;
514     D(("picked %p (%s) at random", (void *)q, q->track));
515     ++qlen;
516   }
517   /* Commit the queue */
518   queue_write();
519   return rc;
520 }
521
522 /* try to play a track */
523 void play(ev_source *ev) {
524   struct queue_entry *q;
525   int random_enabled = random_is_enabled();
526
527   D(("play playing=%p", (void *)playing));
528   if(shutting_down || playing || !playing_is_enabled()) return;
529   /* If the queue is empty then add a random track. */
530   if(qhead.next == &qhead) {
531     if(!random_enabled)
532       return;
533     if(add_random_track()) {
534       /* On error, try again in 10s. */
535       retry_play(ev, 10);
536       return;
537     }
538     /* Now there must be at least one track in the queue. */
539   }
540   q = qhead.next;
541   /* If random play is disabled but the track is a random one then don't play
542    * it.  play() will be called again when random play is re-enabled. */
543   if(!random_enabled && q->state == playing_random)
544     return;
545   D(("taken %p (%s) from queue", (void *)q, q->track));
546   /* Try to start playing. */
547   switch(start(ev, q, SM_PLAY)) {
548   case START_HARDFAIL:
549     if(q == qhead.next) {
550       queue_remove(q, 0);               /* Abandon this track. */
551       queue_played(q);
552       recent_write();
553     }
554     if(qhead.next == &qhead)
555       /* Queue is empty, wait a bit before trying something else (so we don't
556        * sit there looping madly in the presence of persistent problem).  Note
557        * that we might not reliably get a random track lookahead in this case,
558        * but if we get here then really there are bigger problems. */
559       retry_play(ev, 1);
560     else
561       /* More in queue, try again now. */
562       play(ev);
563     break;
564   case START_SOFTFAIL:
565     /* Try same track again in a bit. */
566     retry_play(ev, 10);
567     break;
568   case START_OK:
569     if(q == qhead.next) {
570       queue_remove(q, 0);
571       queue_write();
572     }
573     playing = q;
574     time(&playing->played);
575     playing->state = playing_started;
576     notify_play(playing->track, playing->submitter);
577     eventlog("playing", playing->track,
578              playing->submitter ? playing->submitter : (const char *)0,
579              (const char *)0);
580     /* Maybe add a random track. */
581     add_random_track();
582     /* If there is another track in the queue prepare it now.  This could
583      * potentially be a just-added random track. */
584     if(qhead.next != &qhead)
585       prepare(ev, qhead.next);
586     break;
587   }
588 }
589
590 int playing_is_enabled(void) {
591   const char *s = trackdb_get_global("playing");
592
593   return !s || !strcmp(s, "yes");
594 }
595
596 void enable_playing(const char *who, ev_source *ev) {
597   trackdb_set_global("playing", "yes", who);
598   /* Add a random track if necessary. */
599   add_random_track();
600   play(ev);
601 }
602
603 void disable_playing(const char *who) {
604   trackdb_set_global("playing", "no", who);
605 }
606
607 int random_is_enabled(void) {
608   const char *s = trackdb_get_global("random-play");
609
610   return !s || !strcmp(s, "yes");
611 }
612
613 void enable_random(const char *who, ev_source *ev) {
614   trackdb_set_global("random-play", "yes", who);
615   add_random_track();
616   play(ev);
617 }
618
619 void disable_random(const char *who) {
620   trackdb_set_global("random-play", "no", who);
621 }
622
623 void scratch(const char *who, const char *id) {
624   struct queue_entry *q;
625   struct speaker_message sm;
626   pid_t pid;
627
628   D(("scratch playing=%p state=%d id=%s playing->id=%s",
629      (void *)playing,
630      playing ? playing->state : 0,
631      id ? id : "(none)",
632      playing ? playing->id : "(none)"));
633   if(playing
634      && (playing->state == playing_started
635          || playing->state == playing_paused)
636      && (!id
637          || !strcmp(id, playing->id))) {
638     playing->state = playing_scratched;
639     playing->scratched = who ? xstrdup(who) : 0;
640     if((pid = find_player_pid(playing->id)) > 0) {
641       D(("kill -%d %lu", config->signal, (unsigned long)pid));
642       kill(-pid, config->signal);
643       forget_player_pid(playing->id);
644     } else
645       error(0, "could not find PID for %s", playing->id);
646     if((playing->type & DISORDER_PLAYER_TYPEMASK) == DISORDER_PLAYER_RAW) {
647       memset(&sm, 0, sizeof sm);
648       sm.type = SM_CANCEL;
649       strcpy(sm.id, playing->id);
650       speaker_send(speaker_fd, &sm, -1);
651       D(("sending SM_CANCEL for %s", playing->id));
652     }
653     /* put a scratch track onto the front of the queue (but don't
654      * bother if playing is disabled) */
655     if(playing_is_enabled() && config->scratch.n) {
656       int r = rand() * (double)config->scratch.n / (RAND_MAX + 1.0);
657       q = queue_add(config->scratch.s[r], who, WHERE_START);
658       q->state = playing_isscratch;
659     }
660     notify_scratch(playing->track, playing->submitter, who,
661                    time(0) - playing->played);
662   }
663 }
664
665 void quitting(ev_source *ev) {
666   struct queue_entry *q;
667   pid_t pid;
668
669   /* Don't start anything new */
670   shutting_down = 1;
671   /* Shut down the current player */
672   if(playing) {
673     if((pid = find_player_pid(playing->id)) > 0) {
674       kill(-pid, config->signal);
675       forget_player_pid(playing->id);
676     } else
677       error(0, "could not find PID for %s", playing->id);
678     playing->state = playing_quitting;
679     finished(0);
680   }
681   /* Zap any other players */
682   for(q = qhead.next; q != &qhead; q = q->next)
683     if((pid = find_player_pid(q->id)) > 0) {
684       D(("kill -%d %lu", config->signal, (unsigned long)pid));
685       kill(-pid, config->signal);
686       forget_player_pid(q->id);
687     } else
688       error(0, "could not find PID for %s", q->id);
689   /* Don't need the speaker any more */
690   ev_fd_cancel(ev, ev_read, speaker_fd);
691   xclose(speaker_fd);
692 }
693
694 int pause_playing(const char *who) {
695   struct speaker_message sm;
696   long played;
697   
698   /* Can't pause if already paused or if nothing playing. */
699   if(!playing || paused) return 0;
700   switch(playing->type & DISORDER_PLAYER_TYPEMASK) {
701   case DISORDER_PLAYER_STANDALONE:
702     if(!(playing->type & DISORDER_PLAYER_PAUSES)) {
703     default:
704       error(0,  "cannot pause because player is not powerful enough");
705       return -1;
706     }
707     if(play_pause(playing->pl, &played, playing->data)) {
708       error(0, "player indicates it cannot pause");
709       return -1;
710     }
711     time(&playing->lastpaused);
712     playing->uptopause = played;
713     playing->lastresumed = 0;
714     break;
715   case DISORDER_PLAYER_RAW:
716     memset(&sm, 0, sizeof sm);
717     sm.type = SM_PAUSE;
718     speaker_send(speaker_fd, &sm, -1);
719     break;
720   }
721   if(who) info("paused by %s", who);
722   notify_pause(playing->track, who);
723   paused = 1;
724   if(playing->state == playing_started)
725     playing->state = playing_paused;
726   eventlog("state", "pause", (char *)0);
727   return 0;
728 }
729
730 void resume_playing(const char *who) {
731   struct speaker_message sm;
732
733   if(!paused) return;
734   paused = 0;
735   if(!playing) return;
736   switch(playing->type & DISORDER_PLAYER_TYPEMASK) {
737   case DISORDER_PLAYER_STANDALONE:
738     if(!playing->type & DISORDER_PLAYER_PAUSES) {
739     default:
740       /* Shouldn't happen */
741       return;
742     }
743     play_resume(playing->pl, playing->data);
744     time(&playing->lastresumed);
745     break;
746   case DISORDER_PLAYER_RAW:
747     memset(&sm, 0, sizeof sm);
748     sm.type = SM_RESUME;
749     speaker_send(speaker_fd, &sm, -1);
750     break;
751   }
752   if(who) info("resumed by %s", who);
753   notify_resume(playing->track, who);
754   if(playing->state == playing_paused)
755     playing->state = playing_started;
756   eventlog("state", "resume", (char *)0);
757 }
758
759 /*
760 Local Variables:
761 c-basic-offset:2
762 comment-column:40
763 fill-column:79
764 End:
765 */