forked from markmcconnell/mai
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mai.c
100 lines (78 loc) · 2.63 KB
/
mai.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "mai.h"
/* ######################################################################## */
struct mai_func {
int (*func)(void);
int mode;
};
static struct mai_func mai_init[] = {
{ mai_ptp_init, '*' },
{ mai_rtp_init, '*' },
{ mai_sap_init, 's' },
{ mai_jack_init, '*' },
{ mai_ptp_start, '*' },
{ mai_rtp_start, '*' },
{ mai_sap_start, 's' },
{ NULL, 0 }
};
static struct mai_func mai_fini[] = {
{ mai_rtp_stop, '*' },
{ mai_ptp_stop, '*' },
{ mai_sap_stop, 's' },
{ NULL, 0 }
};
static void run(const struct mai_func *ptr) {
for (; ptr && ptr->func; ptr++) {
if (((ptr->mode == mai.args.mode) || (ptr->mode == '*')) && (ptr->func)())
exit(-1);
}
}
/* ######################################################################## */
static void stats(void) {
fprintf(stderr, "\n\n----- Statistics -----\n\n");
fprintf(stderr, "Audio Clock Drift: %zd\n", MAI_STAT_GET(audio.drift));
fprintf(stderr, "Audio Buffer Underrun: %zu\n", MAI_STAT_GET(audio.underrun));
fprintf(stderr, "Audio Buffer Overrun: %zu\n\n", MAI_STAT_GET(audio.overrun));
fprintf(stderr, "RTP Clock Resynced: %zu\n", MAI_STAT_GET(rtp.resynced));
fprintf(stderr, "RTP Total Packets: %zu\n", MAI_STAT_GET(rtp.packets));
fprintf(stderr, "RTP Reordered Packets: %zu\n", MAI_STAT_GET(rtp.reordered));
fprintf(stderr, "RTP Dropped Packets: %zu\n\n", MAI_STAT_GET(rtp.skipped));
fprintf(stderr, "PTP Master Changes: %zu\n", MAI_STAT_GET(ptp.masters));
fprintf(stderr, "PTP Delay Updates: %zu\n", MAI_STAT_GET(ptp.requests));
fprintf(stderr, "PTP General Messages: %zu\n", MAI_STAT_GET(ptp.general));
fprintf(stderr, "PTP Event Messages: %zu\n\n", MAI_STAT_GET(ptp.event));
}
/* ######################################################################## */
int main(int argc, char *argv[]) {
// intialize drng
srand48(time(NULL) * getpid());
// parse command line options
mai_args_init(argc, argv);
// block signals for all threads
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigaddset(&sigset, SIGTERM);
sigaddset(&sigset, SIGUSR1);
sigaddset(&sigset, SIGUSR2);
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
return(mai_error("could not mask signals: %m\n"));
// initialize modules
run(mai_init);
// wait for signal
int signum = 0;
while (1) {
sigwait(&sigset, &signum);
if (signum == SIGUSR1)
stats();
else
break;
}
mai_info("Signal %d. Exiting.\n", signum);
// stop modules
run(mai_fini);
// print final statistics
if (mai.args.verbose)
stats();
return(0);
}
/* ######################################################################## */