]> mj.ucw.cz Git - misc.git/blob - jukebox.c
Merge branch 'master' of git+ssh://git.ucw.cz/home/mj/GIT/misc
[misc.git] / jukebox.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <ctype.h>
5 #include <glib.h>
6 #include <xmms/xmmsctrl.h>
7
8 #define session 0
9
10 struct pl {
11         struct pl *next;
12         int id;
13         char *name;
14         int tstart, tstop, fstart, fstop;
15 };
16
17 static struct pl *
18 load_pl(char *name)
19 {
20         struct pl *pl = NULL, *p, **l = &pl;
21         int cnt = 0;
22         char buf[1024], b2[1024];
23         FILE *f = fopen(name, "r");
24         if (!f) {
25                 fprintf(stderr, "Unable to open %s: %m\n", name);
26                 exit(1);
27         }
28         while (fgets(buf, sizeof(buf), f)) {
29                 p = malloc(sizeof(struct pl));
30                 p->id = cnt++;
31                 if (sscanf(buf, "%d%d %[^\n]", &p->tstart, &p->tstop, b2) != 3) {
32                         fprintf(stderr, "Syntax error in %s, line %d\n", name, cnt);
33                         exit(1);
34                 }
35                 p->name = g_strdup(b2);
36                 p->fstart = p->tstart + 1000;
37                 p->fstop = p->tstop - 1000;
38                 printf("%02d: <%s> %d %d %d %d\n", p->id, p->name, p->tstart, p->fstart, p->fstop, p->tstop);
39                 *l = p;
40                 l = &p->next;
41         }
42         *l = NULL;
43         fclose(f);
44         if (!pl) {
45                 fprintf(stderr, "The track list is empty!\n");
46                 exit(1);
47         }
48         return pl;
49 }
50
51 static void
52 feed_pl(struct pl *pl)
53 {
54         GList *l;
55         xmms_remote_stop(session);
56         xmms_remote_set_main_volume(session, 0);
57         xmms_remote_playlist_clear(session);
58         l = NULL;
59         while (pl) {
60                 l = g_list_append(l, pl->name);
61                 pl = pl->next;
62         }
63         xmms_remote_playlist_add(session, l);
64         g_list_free(l);
65 }
66
67 void fade_in(int l)
68 {
69         int t0 = xmms_remote_get_output_time(session);
70         for(;;) {
71                 int t = xmms_remote_get_output_time(session) - t0;
72                 printf("%d %d\n",t,t0 );
73                 if (t >= l || t < 0) {
74                         xmms_remote_set_main_volume(session, 100);
75                         return;
76                 }
77                 xmms_remote_set_main_volume(session, t*100/l);
78 //              usleep(10000);
79         }
80 }
81
82 static void
83 vol(int n)
84 {
85         static int lv = -1;
86         if (lv != n) {
87                 lv = n;
88                 xmms_remote_set_main_volume(session, n);
89         }
90 }
91
92 int main(int argc, char **argv)
93 {
94         struct pl *pl, *this = NULL;
95         int state = -1, st, t;
96
97         if (argc != 2) {
98                 fprintf(stderr, "Usage: jukebox <file-with-track-list>\n");
99                 return 1;
100         }
101         pl = load_pl(argv[1]);
102
103         if (!xmms_remote_is_running(session)) {
104                 fprintf(stderr, "No XMMS session found.\n");
105                 return 1;
106         }
107         feed_pl(pl);
108         for(;;) {
109                 if (!xmms_remote_is_running(session)) {
110                         fprintf(stderr, "XMMS exited.\n");
111                         return 0;
112                 }
113                 if (!xmms_remote_is_playing(session)) {
114                         if (state >= 0) {
115                                 state = -1;
116                                 puts("### Stop");
117                                 vol(0);
118                         }
119                 } else {
120                         st = xmms_remote_get_playlist_pos(session);
121                         if (state != st) {
122                                 state = st;
123                                 printf("### Start %d\n", state);
124                                 for (this=pl; this && this->id != state; this = this->next)
125                                         ;
126                                 if (!this) {
127                                         fprintf(stderr, "Internal error: unknown song ID\n");
128                                         return 1;
129                                 }
130                                 vol(0);
131                                 xmms_remote_jump_to_time(session, this->tstart);
132                         }
133                         t = xmms_remote_get_output_time(session);
134                         //printf(" %d %d\n", st, t);
135                         if (t < this->tstart)
136                                 ;
137                         else if (t < this->fstart)
138                                 vol(100 * ((t - this->tstart) / (float)(this->fstart - this->tstart)));
139                         else if (t < this->fstop)
140                                 vol(100);
141                         else if (t < this->tstop)
142                                 vol(100 * (1-((t - this->fstop) / (float)(this->tstop - this->fstop))));
143                         else {
144                                 vol(0);
145                                 if (this->next)
146                                         xmms_remote_playlist_next(session);
147                                 else
148                                         xmms_remote_stop(session);
149                         }
150                 }
151                 usleep(10);
152         }
153         return 0;
154 }