changeset 14:f96153d15889

sipout-test-voice: implement play from file
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 May 2024 22:10:38 -0800
parents 059b79c9f0c3
children 71f01a834820
files test-voice/rtp_tx.c test-voice/user_cmd.c
diffstat 2 files changed, 107 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/test-voice/rtp_tx.c	Sun Apr 07 17:09:32 2024 -0800
+++ b/test-voice/rtp_tx.c	Sat May 11 22:10:38 2024 -0800
@@ -3,6 +3,8 @@
  */
 
 #include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <netinet/in.h>
@@ -32,6 +34,10 @@
 static uint8_t pcm_fill_octet;
 static int dmw_active;
 
+static uint8_t *play_buffer;
+static unsigned play_buf_nframes, play_buf_ptr;
+static int play_loop;
+
 static uint16_t tfo_fill_buf[9], tfo_req_buf[7];
 static uint16_t *is_out_ptr;
 static unsigned is_out_count;
@@ -100,6 +106,22 @@
 	}
 }
 
+static void
+fill_with_play(outbuf)
+	uint8_t *outbuf;
+{
+	memcpy(outbuf, play_buffer + play_buf_ptr * 160, 160);
+	play_buf_ptr++;
+	if (play_buf_ptr < play_buf_nframes)
+		return;
+	if (play_loop)
+		play_buf_ptr = 0;
+	else {
+		free(play_buffer);
+		play_buffer = 0;
+	}
+}
+
 void
 generate_rtp_packet()
 {
@@ -112,7 +134,9 @@
 	pkt.tstamp = htonl(rtp_out_ts);
 	rtp_out_ts += 160;
 	pkt.ssrc = rtp_ssrc;
-	if (dmw_active)
+	if (play_buffer)
+		fill_with_play(pkt.payload);
+	else if (dmw_active)
 		fill_with_dmw(pkt.payload);
 	else
 		memset(pkt.payload, pcm_fill_octet, RTP_MAX_PAYLOAD);
@@ -168,3 +192,54 @@
 {
 	dmw_active = 0;
 }
+
+void
+play_file_cmdop(filename, loop)
+	char *filename;
+{
+	int fd;
+	struct stat st;
+
+	if (play_buffer) {
+		fprintf(stderr, "error: file play already in progress\n");
+		return;
+	}
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		perror(filename);
+		return;
+	}
+	fstat(fd, &st);
+	if (!S_ISREG(st.st_mode)) {
+		close(fd);
+		fprintf(stderr, "error: %s is not a regular file\n", filename);
+		return;
+	}
+	if (st.st_size % 160) {
+		close(fd);
+		fprintf(stderr,
+			"error: size of %s is not a multiple of 160 bytes\n",
+			filename);
+		return;
+	}
+	play_buffer = malloc(st.st_size);
+	if (!play_buffer) {
+		close(fd);
+		fprintf(stderr, "unable to malloc buffer for %s\n", filename);
+		return;
+	}
+	read(fd, play_buffer, st.st_size);
+	close(fd);
+	play_buf_nframes = st.st_size / 160;
+	play_buf_ptr = 0;
+	play_loop = loop;
+}
+
+void
+play_file_stop()
+{
+	if (!play_buffer)
+		return;
+	free(play_buffer);
+	play_buffer = 0;
+}
--- a/test-voice/user_cmd.c	Sun Apr 07 17:09:32 2024 -0800
+++ b/test-voice/user_cmd.c	Sat May 11 22:10:38 2024 -0800
@@ -34,6 +34,33 @@
 }
 
 static void
+play_file_cmd(args)
+	char *args;
+{
+	char *cp, *filename;
+	int loop;
+
+	for (cp = args; isspace(*cp); cp++)
+		;
+	if (!*cp) {
+inv_syntax:	fprintf(stderr, "error: play-file command invalid syntax\n");
+		return;
+	}
+	for (filename = cp; *cp && !isspace(*cp); cp++)
+		;
+	if (*cp) {
+		*cp++ = '\0';
+		while (isspace(*cp))
+			cp++;
+		if (strcmp(cp, "loop"))
+			goto inv_syntax;
+		loop = 1;
+	} else
+		loop = 0;
+	play_file_cmdop(filename, loop);
+}
+
+static void
 tfo_req_cmd(args)
 	char *args;
 {
@@ -97,6 +124,10 @@
 		cmd_dmw_on();
 	else if (!strcmp(cp, "dmw-off"))
 		cmd_dmw_off();
+	else if (!strncmp(cp, "play-file", 9) && isspace(cp[9]))
+		play_file_cmd(cp + 10);
+	else if (!strcmp(cp, "play-stop"))
+		play_file_stop();
 	else if (!strncmp(cp, "tfo-req", 7) && isspace(cp[7]))
 		tfo_req_cmd(cp + 8);
 	else if (!strcmp(cp, "tfo-stop"))