Commit Diff


commit - 1b77ad485132dd80c7671fc8119cc0c6dc00d6e1
commit + ff06024f86fb68ea11b030f669b162794eb5bc19
blob - 62e1d02ba3a388d9eb1249ec41f666d8270c6466
blob + 010475656324920fc1b72c00b83ce54e1fa499e6
--- amused.c
+++ amused.c
@@ -131,6 +131,24 @@ main_dispatch_player(int sig, short event, void *d)
 
 		datalen = IMSG_DATA_SIZE(imsg);
 		switch (imsg.hdr.type) {
+		case IMSG_POS:
+			if (datalen != sizeof(current_position))
+				fatalx("IMSG_POS: got wrong size (%zu vs %zu)",
+				    datalen, sizeof(current_position));
+			memcpy(&current_position, imsg.data,
+			    sizeof(current_position));
+			if (current_position < 0)
+				current_position = -1;
+			break;
+		case IMSG_LEN:
+			if (datalen != sizeof(current_duration))
+				fatalx("IMSG_LEN: got wrong size (%zu vs %zu)",
+				    datalen, sizeof(current_duration));
+			memcpy(&current_duration, imsg.data,
+			    sizeof(current_duration));
+			if (current_duration < 0)
+				current_duration = -1;
+			break;
 		case IMSG_ERR:
 			if (datalen == 0)
 				errstr = "unknown error";
@@ -558,6 +576,8 @@ main_send_status(struct imsgev *iev)
 	if (current_song != NULL)
 		strlcpy(s.path, current_song, sizeof(s.path));
 	s.status = play_state;
+	s.position = current_position;
+	s.duration = current_duration;
 	s.rp.repeat_all = repeat_all;
 	s.rp.repeat_one = repeat_one;
 
blob - a367a2191db86563bc283b6308007026c0c1b6c6
blob + f6bc33c15b87d092b1e6e218184abe3dc651c267
--- amused.h
+++ amused.h
@@ -30,6 +30,8 @@ enum imsg_type {
 	IMSG_RESUME,
 	IMSG_PAUSE,
 	IMSG_STOP,
+	IMSG_POS,
+	IMSG_LEN,
 	IMSG_EOF,
 	IMSG_ERR,		/* error string */
 
@@ -92,6 +94,8 @@ struct player_repeat {
 struct player_status {
 	char			path[PATH_MAX];
 	int			status;
+	int64_t			position;
+	int64_t			duration;
 	struct player_repeat	rp;
 };
 
@@ -138,6 +142,7 @@ __dead void	ctl(int, char **);
 
 /* player.c */
 int	player_setup(int, int, int);
+void	player_setduration(int64_t);
 int	play(const void *, size_t);
 int	player(int, int);
 
blob - defeffcce38cf120112997bc240612b02ed0f6b0
blob + 848f14a3c782c9627ef53a7817254da3b3cfaf9f
--- player.c
+++ player.c
@@ -39,11 +39,13 @@
 #include "xmalloc.h"
 
 struct sio_hdl		*hdl;
+struct sio_par		 par;
 struct pollfd		*player_pfds;
 static struct imsgbuf	*ibuf;
 
 static int stopped = 1;
 static int nextfd = -1;
+static int64_t samples;
 
 volatile sig_atomic_t halted;
 
@@ -56,7 +58,6 @@ player_signal_handler(int signo)
 int
 player_setup(int bits, int rate, int channels)
 {
-	static struct sio_par par;
 	int nfds, fpct;
 
 	log_debug("%s: bits=%d, rate=%d, channels=%d", __func__,
@@ -112,6 +113,32 @@ start:
 	}
 	stopped = 0;
 	return 0;
+}
+
+void
+player_setduration(int64_t duration)
+{
+	int64_t seconds;
+
+	seconds = duration / par.rate;
+	imsg_compose(ibuf, IMSG_LEN, 0, 0, -1, &seconds, sizeof(seconds));
+	imsg_flush(ibuf);
+}
+
+void
+player_onmove(void *arg, int delta)
+{
+	static int64_t reported;
+	int64_t sec;
+
+	samples += delta;
+	if (llabs(samples - reported) >= par.rate) {
+		reported = samples;
+		sec = samples / par.rate;
+
+		imsg_compose(ibuf, IMSG_POS, 0, 0, -1, &sec, sizeof(sec));
+		imsg_flush(ibuf);
+	}
 }
 
 /* process only one message */
@@ -192,6 +219,11 @@ player_playnext(const char **errstr)
 	assert(nextfd != -1);
 	nextfd = -1;
 
+	/* reset samples and set position to zero */
+	samples = 0;
+	imsg_compose(ibuf, IMSG_POS, 0, 0, -1, &samples, sizeof(samples));
+	imsg_flush(ibuf);
+
 	r = read(fd, buf, sizeof(buf));
 
 	/* 8 byte is the larger magic number */
@@ -301,6 +333,8 @@ player(int debug, int verbose)
 	if ((hdl = sio_open(SIO_DEVANY, SIO_PLAY, 1)) == NULL)
 		fatal("sio_open");
 
+	sio_onmove(hdl, player_onmove, NULL);
+
 	/* allocate one extra for imsg */
 	player_pfds = calloc(sio_nfds(hdl) + 1, sizeof(*player_pfds));
 	if (player_pfds == NULL)
blob - 472bbfe1eb473d4adaaaf1db2e12e9055f47ceed
blob + 64e5452d7f2e271272ce6f375187a95109068027
--- player_123.c
+++ player_123.c
@@ -68,6 +68,8 @@ play_mp3(int fd, const char **errstr)
 	if (!setup(mh))
 		goto done;
 
+	player_setduration(mpg123_length(mh));
+
 	for (;;) {
 		err = mpg123_read(mh, buf, sizeof(buf), &len);
 		switch (err) {
blob - 88846e8f416041db4d6c326b5a2e7ef14ffd2e91
blob + 58fc73e10d2b517e8e87573da6fcf6e743f3b86e
--- player_flac.c
+++ player_flac.c
@@ -95,6 +95,8 @@ metacb(const FLAC__StreamDecoder *decoder, const FLAC_
 
 		if (player_setup(bits, sample_rate, channels) == -1)
 			err(1, "player_setup");
+
+		player_setduration(meta->data.stream_info.total_samples);
 	}
 }
 
blob - 1c9ebd7895c4eb54f0153630e9d31880ec5d49b8
blob + 218771d35ea22a6ad324b2cc6aadfe4d4d72cd9d
--- player_oggvorbis.c
+++ player_oggvorbis.c
@@ -66,6 +66,8 @@ play_oggvorbis(int fd, const char **errstr)
 	if (player_setup(16, vi->rate, vi->channels) == -1)
 		err(1, "player_setup");
 
+	player_setduration(ov_time_total(&vf, -1) * vi->rate);
+
 	while (!eof) {
 		long r;
 
blob - 168cde58de46948e84dfc38bec48333ad817214e
blob + 2df2f10b98c6f44843387b38112266d3bbe9d1e5
--- player_opus.c
+++ player_opus.c
@@ -47,7 +47,7 @@ play_opus(int fd, const char **errstr)
 	void *f;
 	int r, ret = 0;
 	OpusFileCallbacks cb = {NULL, NULL, NULL, NULL};
-	int i, li, prev_li = -1;
+	int i, li, prev_li = -1, duration_set = 0;
 
 	if ((f = op_fdopen(&cb, fd, "r")) == NULL)
 		err(1, "fdopen");
@@ -80,6 +80,11 @@ play_opus(int fd, const char **errstr)
 			if (head->input_sample_rate &&
 			    player_setup(16, head->input_sample_rate, 2) == -1)
 				err(1, "player_setup");
+
+			if (!duration_set) {
+				duration_set = 1;
+				player_setduration(op_pcm_total(of, -1));
+			}
 		}
 
 		for (i = 0; i < 2*r; ++i) {
blob - 3db2815c6b8aeb82a2d7d9efc18ba3b6de7e037a
blob + f2821ef2c9500cc78ba6202d4a4a171047d46fd4
--- playlist.c
+++ playlist.c
@@ -33,6 +33,8 @@ int		 repeat_one;
 int		 repeat_all = 1;
 ssize_t		 play_off = -1;
 const char	*current_song;
+int64_t		 current_position;
+int64_t		 current_duration;
 
 static void
 setsong(ssize_t i)
blob - 63b7b13c147f39aef28532cf6b5851e6ff795ce1
blob + 661528a56a0c09521566e5336720e9e905af4240
--- playlist.h
+++ playlist.h
@@ -36,6 +36,8 @@ extern int		 repeat_one;
 extern int		 repeat_all;
 extern ssize_t		 play_off;
 extern const char	*current_song;
+extern int64_t		 current_position;
+extern int64_t		 current_duration;
 
 void			 playlist_swap(struct playlist *, ssize_t);
 void			 playlist_push(struct playlist *, const char *);