annotate pcm/pcm_tx.c @ 10:5cf7818a7d08

pcm: implement play command
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 23 Jun 2024 19:45:52 +0000
parents e3d16d490ce2
children e149ca1dd14f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * In this module we implement PCM Tx toward the TRAU.
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 */
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4
10
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
5 #include <sys/types.h>
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
6 #include <sys/file.h>
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
7 #include <sys/stat.h>
8
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
8 #include <ctype.h>
7
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdint.h>
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdbool.h>
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdio.h>
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <stdlib.h>
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <string.h>
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include <unistd.h>
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include <osmocom/core/select.h>
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 #include "globals.h"
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 static const uint8_t dmw_alaw[8] =
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 {0x34, 0x21, 0x21, 0x34, 0xB4, 0xA1, 0xA1, 0xB4};
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 static uint8_t pcm_fill_octet = 0x54;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 static bool dmw_active;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 static uint8_t *play_buffer;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 static unsigned play_buf_nframes, play_buf_ptr;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 static void fill_with_dmw(uint8_t *buf)
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 {
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 unsigned n;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 for (n = 0; n < 20; n++) {
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 memcpy(buf, dmw_alaw, 8);
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 buf += 8;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 }
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 }
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 static void fill_with_play(uint8_t *outbuf)
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 {
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 memcpy(outbuf, play_buffer + play_buf_ptr * 160, 160);
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 play_buf_ptr++;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 if (play_buf_ptr < play_buf_nframes)
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 return;
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 free(play_buffer);
10
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
45 play_buffer = NULL;
7
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 printf("file play finished\n");
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 }
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 void transmit_pcm_20ms(void)
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 {
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 uint8_t buf[160];
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 if (play_buffer)
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 fill_with_play(buf);
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 else if (dmw_active)
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 fill_with_dmw(buf);
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 else
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 memset(buf, pcm_fill_octet, 160);
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 write(ts_fd, buf, 160);
ca351324187a pcm: implement Tx on the E1 timeslot
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 }
8
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
61
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
62 void cmd_pcm_fill(int argc, char **argv)
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
63 {
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
64 u_long val;
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
65 char *cp;
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
66
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
67 if (argc != 2) {
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
68 printf("error: pcm-fill command needs 1 argument\n");
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
69 return;
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
70 }
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
71 if (!isxdigit(argv[1][0])) {
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
72 inv_arg: printf("error: argument is not a valid hex octet\n");
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
73 return;
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
74 }
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
75 val = strtoul(argv[1], &cp, 16);
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
76 if (*cp)
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
77 goto inv_arg;
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
78 if (val > 0xFF)
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
79 goto inv_arg;
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
80 pcm_fill_octet = val;
70aa8cbdbde9 pcm: implement pcm-fill command
Mychaela Falconia <falcon@freecalypso.org>
parents: 7
diff changeset
81 }
9
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
82
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
83 void cmd_dmw_on(int argc, char **argv)
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
84 {
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
85 dmw_active = true;
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
86 }
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
87
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
88 void cmd_dmw_off(int argc, char **argv)
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
89 {
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
90 dmw_active = false;
e3d16d490ce2 pcm: implement dmw-on and dmw-off commands
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
91 }
10
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
92
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
93 void cmd_play_file(int argc, char **argv)
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
94 {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
95 int fd;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
96 struct stat st;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
97
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
98 if (argc != 2) {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
99 printf("error: play command needs 1 argument\n");
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
100 return;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
101 }
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
102 if (play_buffer) {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
103 printf("error: file play already in progress\n");
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
104 return;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
105 }
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
106 fd = open(argv[1], O_RDONLY);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
107 if (fd < 0) {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
108 perror(argv[1]);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
109 return;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
110 }
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
111 fstat(fd, &st);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
112 if (!S_ISREG(st.st_mode)) {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
113 close(fd);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
114 fprintf(stderr, "error: %s is not a regular file\n", argv[1]);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
115 return;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
116 }
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
117 if (!st.st_size) {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
118 close(fd);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
119 fprintf(stderr, "error: %s is an empty file\n", argv[1]);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
120 return;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
121 }
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
122 if (st.st_size % 160) {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
123 close(fd);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
124 fprintf(stderr,
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
125 "error: size of %s is not a multiple of 160 bytes\n",
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
126 argv[1]);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
127 return;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
128 }
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
129 play_buffer = malloc(st.st_size);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
130 if (!play_buffer) {
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
131 close(fd);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
132 fprintf(stderr, "unable to malloc buffer for %s\n", argv[1]);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
133 return;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
134 }
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
135 read(fd, play_buffer, st.st_size);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
136 close(fd);
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
137 play_buf_nframes = st.st_size / 160;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
138 play_buf_ptr = 0;
5cf7818a7d08 pcm: implement play command
Mychaela Falconia <falcon@freecalypso.org>
parents: 9
diff changeset
139 }