From 89aa56f25116fc642928f352c14fe2d485532749 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 26 Feb 2019 13:21:29 +0000 Subject: working sync and audio --- .gitignore | 9 +++++++++ Makefile | 13 ++++++++++--- audio.c | 33 +++++++++++++++++++++++++++++++++ main.c | 34 +++++++++++++++++++--------------- msf.c | 17 +++++++++++------ project.h | 5 +++++ prototypes.h | 13 +++++++++++-- signal.c | 34 ++++++++++++++++++++++++++++++++++ sync.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 186 insertions(+), 26 deletions(-) create mode 100644 .gitignore create mode 100644 audio.c create mode 100644 signal.c create mode 100644 sync.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c47c50 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.o +*.d +core +*.orig +*.swp +*.swo +*% +*~ +msf diff --git a/Makefile b/Makefile index 01a4471..edd9837 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,18 @@ -CSRCS=time_fn.c msf.c util.c main.c +CSRCS=time_fn.c msf.c util.c main.c signal.c sync.c audio.c HSRCS=time_fn.h project.h +PROG=msf +AO_CFLAGS=$(shell pkg-config --cflags ao) +AO_LIBS=$(shell pkg-config --libs ao) +LIBS=-lm $(AO_LIBS) +CPPFLAGS=$(AO_CFLAGS) + + + +##################### OBJS=${CSRCS:%.c=%.o} -PROG=msf -CPPFLAGS= CFLAGS=-Wall ${CPPFLAGS} CPROTO=cproto diff --git a/audio.c b/audio.c new file mode 100644 index 0000000..83e6de9 --- /dev/null +++ b/audio.c @@ -0,0 +1,33 @@ +#include "project.h" +#include + +static ao_device *device; +static int d_num; + +void audio_init (void) +{ + + ao_initialize(); + + d_num = ao_default_driver_id(); +} + +void audio_start (void) +{ + ao_sample_format fmt = {0}; + + + fmt.bits = 16; + fmt.rate = SAMPLE_RATE; + fmt.channels = 1; + fmt.byte_format = AO_FMT_NATIVE; + fmt.matrix = 0; + + device = ao_open_live (d_num, &fmt, NULL); +} + + +void audio_play (void *data, size_t len) +{ + ao_play (device, data, len); +} diff --git a/main.c b/main.c index 5eae5ea..5b18a72 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ + int main (int argc, char *argv[]) { EPOCH e; @@ -11,35 +12,38 @@ int main (int argc, char *argv[]) unsigned i; + signal_init(); + + audio_init(); - gettimeofday (&tv, NULL); + audio_start(); + sync_to_minute (&tv); e.s = tv.tv_sec; e.ns = tv.tv_usec * 1000; - u = time_epoch_to_utc (e); + for (;;) { + e.s += 60; + u = time_epoch_to_utc (e); + time_print_utc ("Next:\n", u); + msf_make_stream (s, u); - time_print_utc ("Now:\n", u); - { - uint8_t a[60], b[60]; - msf_make_bits (u, a, b); + for (i = 0; i < 600; ++i) { + signal_send_bp (s[i]); - msf_make_stream (s, a, b); - } + putchar ('0' + s[i]); + fflush (stdout); + if ((i % 10) == 9) putchar (' '); - for (i = 0; i < 600; ++i) { - putchar ('0' + s[i]); + if ((i % 50) == 49) putchar ('\n'); + } - if ((i % 10) == 9) putchar (' '); + printf ("\n"); } - printf ("\n"); - - - return 0; } diff --git a/msf.c b/msf.c index 47e5188..411b601 100644 --- a/msf.c +++ b/msf.c @@ -19,7 +19,7 @@ static void msf_set_ident (uint8_t *i) -void msf_make_bits (UTC u, uint8_t *a, uint8_t *b) +static void msf_make_bits (UTC u, uint8_t *a, uint8_t *b) { bzero (a, 60); @@ -53,20 +53,25 @@ void msf_make_bits (UTC u, uint8_t *a, uint8_t *b) -void msf_make_stream (uint8_t *v, uint8_t *a, uint8_t *b) +void msf_make_stream (uint8_t *v, UTC u) { unsigned s; + uint8_t a[60], b[60]; + uint8_t *pa, *pb; + + msf_make_bits (u, a, b); + bzero (v, 600); - for (s = 0; s < 60; ++s, v += 10, ++a, ++b) { + for (s = 0, pa = a, pb = b; s < 60; ++s, v += 10, ++pa, ++pb) { if (!s) memset (v, 1, 5); - v[0] = 1; - v[1] = *a; - v[2] = *b; + v[1] = *pa; + v[2] = *pb; } } + diff --git a/project.h b/project.h index 9492bac..f6ad552 100644 --- a/project.h +++ b/project.h @@ -6,7 +6,12 @@ #include #include #include +#include +#include +#define KHZ(a) ((a)*1000) +#define SAMPLE_RATE KHZ(48) +#define CARRIER KHZ(20) #include "time_fn.h" diff --git a/prototypes.h b/prototypes.h index fc09337..e6c95a4 100644 --- a/prototypes.h +++ b/prototypes.h @@ -5,10 +5,19 @@ extern void utc_to_str(char *dst, UTC u); extern void time_print_utc(const char *p, UTC u); extern void time_print_epoch(const char *p, EPOCH e); /* msf.c */ -extern void msf_make_bits(UTC u, uint8_t *a, uint8_t *b); -extern void msf_make_stream(uint8_t *v, uint8_t *a, uint8_t *b); +extern void msf_make_stream(uint8_t *v, UTC u); /* util.c */ extern int set_parity(uint8_t *d, unsigned s, unsigned e); extern void bcd_set(uint8_t *d, unsigned s, unsigned e, unsigned v); /* main.c */ extern int main(int argc, char *argv[]); +/* signal.c */ +extern void signal_init(void); +extern void signal_send_bp(int b); +/* sync.c */ +extern void sync_to_second(struct timeval *ret); +extern void sync_to_minute(struct timeval *ret); +/* audio.c */ +extern void audio_init(void); +extern void audio_start(void); +extern void audio_play(void *data, size_t len); diff --git a/signal.c b/signal.c new file mode 100644 index 0000000..3e7319d --- /dev/null +++ b/signal.c @@ -0,0 +1,34 @@ +#include "project.h" + + +#define SPP (SAMPLE_RATE/10) + +static int16_t zero[SPP]; +static int16_t one[SPP]; + + +void signal_init (void) +{ + unsigned i; + double t; + + bzero (one, sizeof (one)); + + for (i = 0; i < SPP; ++i) { + + t = (1.0 / (double) SAMPLE_RATE) * (double) i; + t *= CARRIER * 2.0 * M_PI; + + zero[i] = 32000 * sin (t); + } + +} + +void signal_send_bp (int b) +{ + if (b) + audio_play (one, sizeof (one)); + else + audio_play (zero, sizeof (zero)); +} + diff --git a/sync.c b/sync.c new file mode 100644 index 0000000..1b6b6bc --- /dev/null +++ b/sync.c @@ -0,0 +1,54 @@ +#include "project.h" + +#define SLEEP_MIN 100000 +#define THRESH 1000 + +void sync_to_second (struct timeval *ret) +{ + struct timeval tv1, tv2; + ret->tv_usec = 0; + + for (;;) { + tv2.tv_sec = 0; + gettimeofday (&tv1, NULL); + tv2.tv_usec = 1000000 - tv1.tv_usec; + + if (tv1.tv_usec < THRESH) { + ret->tv_sec = tv1.tv_sec; + return; + } else if (tv2.tv_usec < THRESH) { + ret->tv_sec = tv1.tv_sec + 1; + return; + } + + if (tv2.tv_usec > SLEEP_MIN) + select (0, NULL, NULL, NULL, &tv2); + else + usleep (tv2.tv_usec / 2); + } +} + + + +void sync_to_minute (struct timeval *ret) +{ + struct timeval tv1, tv2; + ret->tv_usec = 0; + + for (;;) { + tv2.tv_sec = 0; + gettimeofday (&tv1, NULL); + tv2.tv_sec = 60 - (tv1.tv_sec % 60); + tv2.tv_usec = 1000; + + printf ("%d seconds left in min\n", (int) tv2.tv_sec); + + if (tv2.tv_sec > 1) { + tv2.tv_sec /= 2; + select (0, NULL, NULL, NULL, &tv2); + } else { + sync_to_second (ret); + return; + } + } +} -- cgit v1.2.3