diff pcm/pcm_tx.c @ 11:e149ca1dd14f

pcm: implement play-offset command
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 23 Jun 2024 19:59:17 +0000
parents 5cf7818a7d08
children 27ca01bb5b11
line wrap: on
line diff
--- a/pcm/pcm_tx.c	Sun Jun 23 19:45:52 2024 +0000
+++ b/pcm/pcm_tx.c	Sun Jun 23 19:59:17 2024 +0000
@@ -137,3 +137,60 @@
 	play_buf_nframes = st.st_size / 160;
 	play_buf_ptr = 0;
 }
+
+void cmd_play_offset(int argc, char **argv)
+{
+	int fd;
+	struct stat st;
+	unsigned offset, pre_offset;
+
+	if (argc != 3) {
+		printf("error: play-offset command needs 2 arguments\n");
+		return;
+	}
+	if (play_buffer) {
+		printf("error: file play already in progress\n");
+		return;
+	}
+	offset = strtoul(argv[2], NULL, 0);
+	if (offset < 1 || offset > 159) {
+		printf("error: offset argument out of range\n");
+		return;
+	}
+	fd = open(argv[1], O_RDONLY);
+	if (fd < 0) {
+		perror(argv[1]);
+		return;
+	}
+	fstat(fd, &st);
+	if (!S_ISREG(st.st_mode)) {
+		close(fd);
+		fprintf(stderr, "error: %s is not a regular file\n", argv[1]);
+		return;
+	}
+	if (!st.st_size) {
+		close(fd);
+		fprintf(stderr, "error: %s is an empty file\n", argv[1]);
+		return;
+	}
+	if (st.st_size % 160) {
+		close(fd);
+		fprintf(stderr,
+			"error: size of %s is not a multiple of 160 bytes\n",
+			argv[1]);
+		return;
+	}
+	play_buffer = malloc(st.st_size + 160);
+	if (!play_buffer) {
+		close(fd);
+		fprintf(stderr, "unable to malloc buffer for %s\n", argv[1]);
+		return;
+	}
+	pre_offset = 160 - offset;
+	memset(play_buffer, pcm_fill_octet, pre_offset);
+	read(fd, play_buffer + pre_offset, st.st_size);
+	close(fd);
+	memset(play_buffer + pre_offset + st.st_size, pcm_fill_octet, offset);
+	play_buf_nframes = st.st_size / 160 + 1;
+	play_buf_ptr = 0;
+}