summaryrefslogtreecommitdiffstats
path: root/dogwhistle.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-06-09 16:35:13 +0200
committerMattias Andrée <maandree@kth.se>2021-06-09 16:35:13 +0200
commitf98ef76a45198a58467a68d110dab4b6013e14de (patch)
tree65488dc857a53bd9c20f4a3d94e69d49ee4a0a17 /dogwhistle.c
parentSilence warnings (diff)
downloadpdatools-f98ef76a45198a58467a68d110dab4b6013e14de.tar.gz
pdatools-f98ef76a45198a58467a68d110dab4b6013e14de.tar.bz2
pdatools-f98ef76a45198a58467a68d110dab4b6013e14de.tar.xz
Add dogwhistle
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--dogwhistle.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/dogwhistle.c b/dogwhistle.c
new file mode 100644
index 0000000..2d48b82
--- /dev/null
+++ b/dogwhistle.c
@@ -0,0 +1,76 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#include <alsa/asoundlib.h>
+#include <math.h>
+
+/* TODO add support for 12, 14, 18 and 20, 22 kHz in addition to 16 kHz as well as custom frequencies */
+/* TODO add support for selecting output device and backend */
+/* TODO add support for selecting volume */
+/* TODO add support for pausing and exiting */
+
+#define UTYPE uint32_t
+#define SMIN INT32_MIN
+#define SMAX INT32_MAX
+#define FORMAT SND_PCM_FORMAT_U32
+
+#define SAMPLE_RATE 52000 /* Hz */
+#define LATENCY 100000 /* µs */
+
+USAGE("");
+
+
+int
+main(int argc, char *argv[])
+{
+ UTYPE *buffer;
+ snd_pcm_uframes_t i, buflen = SAMPLE_RATE;
+ snd_pcm_sframes_t n;
+ snd_pcm_t *sound_handle = NULL;
+ unsigned long int freq = 16000;
+ double volume = (double)0.1f, imul, omul;
+ int r;
+
+ NOFLAGS(argc);
+
+ /* Set up audio */
+ r = snd_pcm_open(&sound_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
+ if (r < 0)
+ eprintf("snd_pcm_open: %s\n", snd_strerror(r));
+ if (!sound_handle)
+ eprintf("snd_pcm_open:");
+
+ /* Configure audio */
+ r = snd_pcm_set_params(sound_handle, FORMAT, SND_PCM_ACCESS_RW_INTERLEAVED, 1 /* channels */,
+ SAMPLE_RATE, 1 /* allow resampling? */, LATENCY);
+ if (r < 0)
+ eprintf("snd_pcm_set_params: %s\n", snd_strerror(r));
+
+ /* Generate tone */
+ buffer = emallocn((size_t)buflen, sizeof(*buffer), 0);
+ omul = volume * SMAX * 2;
+ imul = 2 * (double)freq / (double)SAMPLE_RATE;
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants"
+#endif
+ imul *= M_PI;
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+ for (i = 0; i < buflen; i++)
+ buffer[i] = (UTYPE)(sin(imul * (double)i) * omul - SMIN);
+
+ /* Play tone */
+ for (;;) {
+ n = snd_pcm_writei(sound_handle, buffer, buflen);
+ if (n < 0)
+ n = snd_pcm_recover(sound_handle, (int)n, 0 /* do not print error reason? */);
+ if (n < 0)
+ eprintf("snd_pcm_writei: %s\n", snd_strerror((int)n));
+ if (n > 0 && (snd_pcm_uframes_t)n < buflen)
+ eprintf("short write from snd_pcm_writei\n");
+ }
+
+ snd_pcm_close(sound_handle);
+ return 0;
+}