aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-02-22 15:01:58 +0100
committerMattias Andrée <m@maandree.se>2026-02-22 15:01:58 +0100
commit19b6c708a001feeced04f5cf8431b4a4eff54b06 (patch)
tree12b7442891da498f1f28b94a5158cf2996116e14 /src
parentFix typos (diff)
downloadfodtmf-19b6c708a001feeced04f5cf8431b4a4eff54b06.tar.gz
fodtmf-19b6c708a001feeced04f5cf8431b4a4eff54b06.tar.bz2
fodtmf-19b6c708a001feeced04f5cf8431b4a4eff54b06.tar.xz
m fixesHEADmaster
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'src')
-rw-r--r--src/common.h1
-rw-r--r--src/fodtmf-send.c557
-rw-r--r--src/goertzel.c72
-rw-r--r--src/goertzel.h18
4 files changed, 320 insertions, 328 deletions
diff --git a/src/common.h b/src/common.h
index d2fdf1b..4097f20 100644
--- a/src/common.h
+++ b/src/common.h
@@ -36,4 +36,3 @@
* This is the 'End of transmission' character.
*/
#define CHAR_END 0x04
-
diff --git a/src/fodtmf-send.c b/src/fodtmf-send.c
index 0c3709e..2fbe70c 100644
--- a/src/fodtmf-send.c
+++ b/src/fodtmf-send.c
@@ -51,12 +51,12 @@
/**
* The process's name.
*/
-static const char* argv0;
+static const char *argv0;
/**
* Audio descriptor.
*/
-static snd_pcm_t* sound_handle = NULL;
+static snd_pcm_t *sound_handle = NULL;
/**
* Audio playback buffer for each nibble.
@@ -70,7 +70,7 @@ static int parity = 3;
/**
* Whether to add an additional parity tone (of all
- * data tones) in addition to those numerated by `parity`.
+ * data tones) in addition to those enumerated by `parity`.
*/
static int use_extra_parity = 0;
@@ -87,12 +87,12 @@ static double redundant_freq_mul = 0;
/**
* Data buffer used for error correcting code support.
*/
-static int* data;
+static int *data;
/**
* Code buffer used for error correcting code support.
*/
-static int* code;
+static int *code;
/**
* The number elements that can be stored in `data`.
@@ -109,7 +109,7 @@ static int code_n;
* rather than sending it to the audio subsystem.
*
* This is available for developers of the receiver.
- * It is not intend to be used for anything else.
+ * It is not intended to be used for anything else.
*/
static int output_fd = -1;
@@ -121,9 +121,10 @@ static int output_fd = -1;
*
* @param signo The received signal.
*/
-static void signoop(int signo)
+static void
+signoop(int signo)
{
- (void) signo;
+ (void) signo;
}
@@ -134,44 +135,48 @@ static void signoop(int signo)
* @param low Output parameter for the lower frequency.
* @param high Output parameter for the higher frequency.
*/
-static void get_freq(int nibble, int* low, int* high)
+static void
+get_freq(int nibble, int *low, int *high)
{
- static const int LOW[] = { 697, 770, 852, 941 };
- static const int HIGH[] = { 1209, 1336, 1477, 1663 };
-
- *low = LOW[(nibble >> 0) & 0x03];
- *high = HIGH[(nibble >> 2) & 0x03];
+ static const int LOW[] = { 697, 770, 852, 941 };
+ static const int HIGH[] = { 1209, 1336, 1477, 1663 };
+
+ *low = LOW[(nibble >> 0) & 0x03];
+ *high = HIGH[(nibble >> 2) & 0x03];
}
/**
* Initialise to before for each nibble.
*/
-static void init_buffers(void)
+static void
+init_buffers(void)
{
#define GENERATE_TONE(tone) sin(2 * M_PI * ((double)i / (SAMPLE_RATE / (tone))))
-
- size_t i;
- UTYPE* buffer;
- int j, low, high;
-
- for (j = 0; j < 16; j++)
- {
- buffer = buffers[j];
- get_freq(j, &low, &high);
-
- if (use_redundant_freq)
- for (i = 0; i < N; i++)
- buffer[i] = (GENERATE_TONE(low) +
- GENERATE_TONE(high) +
- GENERATE_TONE(low * redundant_freq_mul) +
- GENERATE_TONE(high * redundant_freq_mul)) *
- (SMAX / 4) - SMIN;
- else
- for (i = 0; i < N; i++)
- buffer[i] = (GENERATE_TONE(low) + GENERATE_TONE(high)) *
- (SMAX / 2) - SMIN;
- }
+
+ size_t i;
+ UTYPE *buffer;
+ int j, low, high;
+
+ for (j = 0; j < 16; j++) {
+ buffer = buffers[j];
+ get_freq(j, &low, &high);
+
+ if (use_redundant_freq) {
+ for (i = 0; i < N; i++) {
+ buffer[i] = (GENERATE_TONE(low) +
+ GENERATE_TONE(high) +
+ GENERATE_TONE(low * redundant_freq_mul) +
+ GENERATE_TONE(high * redundant_freq_mul)) *
+ (SMAX / 4) - SMIN;
+ }
+ } else {
+ for (i = 0; i < N; i++) {
+ buffer[i] = (GENERATE_TONE(low) + GENERATE_TONE(high)) *
+ (SMAX / 2) - SMIN;
+ }
+ }
+ }
}
@@ -181,40 +186,38 @@ static void init_buffers(void)
* @param n The nibble.
* @return 0 on success, -1 on error.
*/
-static int send_nibble(int n)
+static int
+send_nibble(int n)
{
- UTYPE* buffer = buffers[n];
- snd_pcm_sframes_t frames;
- int r;
-
- if (output_fd >= 0)
- {
- char* buf = (char*)buffer;
- size_t ptr = 0;
- ssize_t wrote;
- while (ptr < N)
- {
- wrote = write(output_fd, buf + ptr, N - ptr);
- if (wrote < 0)
- return -1;
- ptr += (size_t)write;
+ UTYPE *buffer = buffers[n];
+ snd_pcm_sframes_t frames;
+ int r;
+
+ if (output_fd >= 0) {
+ char *buf = (char *)buffer;
+ size_t ptr = 0;
+ ssize_t wrote;
+ while (ptr < N) {
+ wrote = write(output_fd, buf + ptr, N - ptr);
+ if (wrote < 0)
+ return -1;
+ ptr += (size_t)wrote;
+ }
+ return 0;
}
- return 0;
- }
-
- r = frames = snd_pcm_writei(sound_handle, buffer, N);
- if (frames < 0)
- r = frames = snd_pcm_recover(sound_handle, r, 0 /* do not print error reason? */);
- if (r < 0)
- {
- fprintf(stderr, "%s: snd_pcm_writei: %s\n", argv0, snd_strerror(r));
- errno = 0;
- return -1;
- }
- if ((r > 0) && ((size_t)r < N))
- printf("%s: short write: expected %zu, wrote %zu\n", argv0, N, (size_t)frames);
-
- return 0;
+
+ r = frames = snd_pcm_writei(sound_handle, buffer, N);
+ if (frames < 0)
+ r = frames = snd_pcm_recover(sound_handle, r, 0 /* do not print error reason? */);
+ if (r < 0) {
+ fprintf(stderr, "%s: snd_pcm_writei: %s\n", argv0, snd_strerror(r));
+ errno = 0;
+ return -1;
+ }
+ if (r > 0 && (size_t)r < N)
+ printf("%s: short write: expected %zu, wrote %zu\n", argv0, N, (size_t)frames);
+
+ return 0;
}
@@ -224,14 +227,15 @@ static int send_nibble(int n)
* @param c The byte.
* @return 0 on success, -1 on error.
*/
-static int send_byte(int c)
+static int
+send_byte(int c)
{
#ifdef DEBUG
- fprintf(stderr, "%s: sending byte: %i\n", argv0, c);
+ fprintf(stderr, "%s: sending byte: %i\n", argv0, c);
#endif
- if (send_nibble((c >> 0) & 0x0F)) return -1;
- if (send_nibble((c >> 4) & 0x0F)) return -1;
- return 0;
+ if (send_nibble((c >> 0) & 0x0F)) return -1;
+ if (send_nibble((c >> 4) & 0x0F)) return -1;
+ return 0;
}
@@ -245,68 +249,67 @@ static int send_byte(int c)
*
* @param c The byte, the negative of that byte (intended
* only for `CHAR_END` and `CHAR_CANCEL`) to fill
- * the remained of the buffer with the byte.
+ * the remainder of the buffer with the byte.
* Note that if a negative value is used, it is
- * no necessary that anything will happen.
+ * not necessary that anything will happen.
* @return 0 on success, -1 on error.
*/
-static int send_byte_with_ecc(int c)
+static int
+send_byte_with_ecc(int c)
{
- static int ptr = 0;
- int i, j, d, p;
-
- if (parity < 2)
- {
- if (c < 0)
+ static int ptr = 0;
+ int i, j, d, p;
+
+ if (parity < 2) {
+ if (c < 0)
+ return 0;
+ if (send_byte(c))
+ return -1;
+ if (parity)
+ if (send_byte(c))
+ return -1;
+ if (use_extra_parity)
+ if (send_byte(c))
+ return -1;
+ return 0;
+ }
+
+ /* Fill buffer. */
+ if (c < 0) {
+ if (ptr > 0)
+ while (ptr < data_n)
+ data[ptr++] = -c;
+ }
+ else {
+ data[ptr++] = c;
+ }
+
+ /* Is it full? */
+ if (ptr < data_n)
+ return 0;
+ ptr = 0;
+
+ /* Hamming code. */
+ memset(code, 0, code_n * sizeof(*code));
+ for (i = 1, j = 0; i <= (1 << parity) - 1; i++) {
+ if ((i & -i) == i)
+ continue;
+ for (d = i, p = 0; d; d >>= 1, p++)
+ if (d & 1)
+ code[(1 << p) - 1] ^= data[j];
+ code[i - 1] = data[j];
+ j++;
+ }
+ if (use_extra_parity)
+ for (i = 0; i < data_n; i++)
+ code[(1 << parity) - 1] ^= data[i];
+
+ /* Transmit. */
+ for (i = 0; i < code_n; i++)
+ if (send_byte(code[i]))
+ return -1;
+
return 0;
- if (send_byte(c))
- return -1;
- if (parity)
- if (send_byte(c))
- return -1;
- if (use_extra_parity)
- if (send_byte(c))
- return -1;
- return 0;
- }
-
- /* Fill buffer. */
- if (c < 0)
- {
- if (ptr > 0)
- while (ptr < data_n)
- data[ptr++] = -c;
- }
- else
- data[ptr++] = c;
-
- /* Is it full? */
- if (ptr < data_n)
- return 0;
- ptr = 0;
-
- /* Hamming code. */
- memset(code, 0, code_n * sizeof(*code));
- for (i = 1, j = 0; i <= (1 << parity) - 1; i++)
- {
- if ((i & -i) == i)
- continue;
- for (d = i, p = 0; d; d >>= 1, p++)
- if (d & 1)
- code[(1 << p) - 1] ^= data[j];
- code[i - 1] = data[j];
- j++;
- }
- if (use_extra_parity)
- for (i = 0; i < data_n; i++)
- code[(1 << parity) - 1] ^= data[i];
-
- /* Transmit. */
- for (i = 0; i < code_n; i++)
- if (send_byte(code[i]))
- return -1;
-
- return 0;
}
@@ -317,26 +320,26 @@ static int send_byte_with_ecc(int c)
* @param n The number of bytes in the chunk.
* @return 0 on success, -1 on failure.
*/
-static int send_chunk(char* buf, size_t n)
+static int
+send_chunk(char *buf, size_t n)
{
- size_t i;
- int c;
-
- for (i = 0; i < n; i++)
- {
- c = buf[i];
- if ((c == CHAR_ESCAPE) || (c == CHAR_CANCEL) || (c == CHAR_END))
- if (send_byte_with_ecc(CHAR_ESCAPE))
- goto qfile;
- if (send_byte_with_ecc(c))
- goto qfile;
- }
-
- return 0;
- qfile:
- errno = 0;
- fail:
- return -1;
+ size_t i;
+ int c;
+
+ for (i = 0; i < n; i++) {
+ c = buf[i];
+ if (c == CHAR_ESCAPE || c == CHAR_CANCEL || c == CHAR_END)
+ if (send_byte_with_ecc(CHAR_ESCAPE))
+ goto qfile;
+ if (send_byte_with_ecc(c))
+ goto qfile;
+ }
+
+ return 0;
+qfile:
+ errno = 0;
+fail:
+ return -1;
}
@@ -345,23 +348,23 @@ static int send_chunk(char* buf, size_t n)
*
* @return 0 on success, -1 on failure.
*/
-static int send_file(void)
+static int
+send_file(void)
{
- char buf[1024];
- ssize_t n;
-
- for (;;)
- {
- n = read(STDIN_FILENO, buf, sizeof(buf));
- if (n < 0) goto fail;
- if (n == 0) break;
- if (send_chunk(buf, (size_t)n))
- goto fail;
- }
-
- return 0;
- fail:
- return -1;
+ char buf[1024];
+ ssize_t n;
+
+ for (;;) {
+ n = read(STDIN_FILENO, buf, sizeof(buf));
+ if (n < 0) goto fail;
+ if (n == 0) break;
+ if (send_chunk(buf, (size_t)n))
+ goto fail;
+ }
+
+ return 0;
+fail:
+ return -1;
}
@@ -370,39 +373,39 @@ static int send_file(void)
*
* @return 0 on success, -1 on failure.
*/
-static int send_term(void)
+static int
+send_term(void)
{
- char* buf = NULL;
- size_t size = 0;
- size_t ptr = 0;
- ssize_t n;
- void* new;
- int saved_errno;
-
- for (;;)
- {
- if (ptr == size)
- {
- size = size ? (size << 1) : 128;
- new = realloc(buf, size);
- if (new == NULL)
- goto fail;
- buf = new;
+ char *buf = NULL;
+ size_t size = 0;
+ size_t ptr = 0;
+ ssize_t n;
+ void *new;
+ int saved_errno;
+
+ for (;;) {
+ if (ptr == size) {
+ size = size ? (size << 1) : 128;
+ new = realloc(buf, size);
+ if (!new)
+ goto fail;
+ buf = new;
+ }
+ n = read(STDIN_FILENO, buf + ptr, size - ptr);
+ if (n < 0) goto fail;
+ if (n == 0) break;
+ ptr += (size_t)n;
}
- n = read(STDIN_FILENO, buf + ptr, size - ptr);
- if (n < 0) goto fail;
- if (n == 0) break;
- ptr += (size_t)n;
- }
- if (send_chunk(buf, ptr))
- goto fail;
+ if (send_chunk(buf, ptr))
+ goto fail;
- return 0;
- fail:
- saved_errno = errno;
- free(buf);
- errno = saved_errno;
- return -1;
+ return 0;
+
+fail:
+ saved_errno = errno;
+ free(buf);
+ errno = saved_errno;
+ return -1;
}
@@ -413,91 +416,83 @@ static int send_term(void)
* @param argv Command line arguments.
* @return 0 on success, 1 on failure.
*/
-int main(int argc, char* argv[])
+int
+main(int argc, char *argv[])
{
- struct sigaction act;
- int r, rc = 1;
-
- /* Parse command line. */
- argv0 = argc ? argv[0] : "";
- for (;;)
- {
- r = getopt (argc, argv, "f:pr:o:");
- if (r == -1)
- break;
- else if (r == 'f') use_redundant_freq = 1, redundant_freq_mul = atof(optarg);
- else if (r == 'p') use_extra_parity = 1;
- else if (r == 'r') parity = atoi(optarg);
- else if (r == 'o') output_fd = atoi(optarg);
- else if (r != '?')
- abort();
- }
-
- /* Set up signal handling. */
- siginterrupt(SIGTERM, 1);
- siginterrupt(SIGQUIT, 1);
- siginterrupt(SIGINT, 1);
- siginterrupt(SIGHUP, 1);
- sigemptyset(&(act.sa_mask));
- act.sa_handler = signoop;
- act.sa_flags = 0;
- sigaction(SIGTERM, &act, NULL);
- sigaction(SIGQUIT, &act, NULL);
- sigaction(SIGHUP, &act, NULL);
- sigprocmask(SIG_SETMASK, &(act.sa_mask), NULL);
-
- /* Generate the tones to play. */
- init_buffers();
- /* Generate buffers for error correcting code. */
- data_n = (1 << parity) - parity - 1;
- code_n = (1 << parity) - 1 + use_extra_parity;
- data = alloca(data_n * sizeof(*data));
- code = alloca(code_n * sizeof(*code));
+ struct sigaction act;
+ int r, rc = 1;
- /* Set up audio. */
- if (output_fd >= 0)
- goto no_audio;
- r = snd_pcm_open(&sound_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
- if (r < 0)
- return fprintf(stderr, "%s: snd_pcm_open: %s\n", *argv, snd_strerror(r)), 1;
- if (sound_handle == NULL)
- perror("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)
- return fprintf(stderr, "%s: snd_pcm_set_params: %s\n", *argv, snd_strerror(r)), 1;
- no_audio:
-
- /* Send message. */
- if (isatty(STDIN_FILENO))
- {
- if (send_term())
- goto fail;
- }
- else
- if (send_file())
- goto fail;
-
- /* Mark end of transmission. */
- if (send_byte_with_ecc(CHAR_END)) goto cleanup;
- if (send_byte_with_ecc(-CHAR_END)) goto cleanup;
-
- /* Done! */
- rc = 0;
- goto cleanup;
- fail:
- if (errno)
- perror(argv0);
- cleanup:
- /* Mark aborted transmission. */
- if (rc)
- {
- send_byte_with_ecc(CHAR_CANCEL);
- send_byte_with_ecc(-CHAR_CANCEL);
- }
- if (output_fd >= 0)
- snd_pcm_close(sound_handle);
- return rc;
-}
+ /* Parse command line. */
+ argv0 = argc ? argv[0] : "";
+ for (;;) {
+ r = getopt (argc, argv, "f:pr:o:");
+ if (r == -1)
+ break;
+ else if (r == 'f') use_redundant_freq = 1, redundant_freq_mul = atof(optarg);
+ else if (r == 'p') use_extra_parity = 1;
+ else if (r == 'r') parity = atoi(optarg);
+ else if (r == 'o') output_fd = atoi(optarg);
+ else if (r != '?')
+ abort();
+ }
+
+ /* Set up signal handling. */
+ siginterrupt(SIGTERM, 1);
+ siginterrupt(SIGQUIT, 1);
+ siginterrupt(SIGINT, 1);
+ siginterrupt(SIGHUP, 1);
+ sigemptyset(&(act.sa_mask));
+ act.sa_handler = signoop;
+ act.sa_flags = 0;
+ sigaction(SIGTERM, &act, NULL);
+ sigaction(SIGQUIT, &act, NULL);
+ sigaction(SIGHUP, &act, NULL);
+ sigprocmask(SIG_SETMASK, &(act.sa_mask), NULL);
+
+ /* Generate the tones to play. */
+ init_buffers();
+ /* Generate buffers for error correcting code. */
+ data_n = (1 << parity) - parity - 1;
+ code_n = (1 << parity) - 1 + use_extra_parity;
+ data = alloca(data_n * sizeof(*data));
+ code = alloca(code_n * sizeof(*code));
+
+ /* Set up audio. */
+ if (output_fd >= 0)
+ goto no_audio;
+ r = snd_pcm_open(&sound_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
+ if (r < 0)
+ return fprintf(stderr, "%s: snd_pcm_open: %s\n", *argv, snd_strerror(r)), 1;
+ if (sound_handle == NULL)
+ perror("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)
+ return fprintf(stderr, "%s: snd_pcm_set_params: %s\n", *argv, snd_strerror(r)), 1;
+no_audio:
+ /* Send message. */
+ if (isatty(STDIN_FILENO) ? send_term() : send_file())
+ goto fail;
+
+ /* Mark end of transmission. */
+ if (send_byte_with_ecc(CHAR_END)) goto cleanup;
+ if (send_byte_with_ecc(-CHAR_END)) goto cleanup;
+
+ /* Done! */
+ rc = 0;
+ goto cleanup;
+fail:
+ if (errno)
+ perror(argv0);
+cleanup:
+ /* Mark aborted transmission. */
+ if (rc) {
+ send_byte_with_ecc(CHAR_CANCEL);
+ send_byte_with_ecc(-CHAR_CANCEL);
+ }
+ if (output_fd >= 0)
+ snd_pcm_close(sound_handle);
+ return rc;
+}
diff --git a/src/goertzel.c b/src/goertzel.c
index a4174be..21bdfbc 100644
--- a/src/goertzel.c
+++ b/src/goertzel.c
@@ -20,45 +20,45 @@
-void goertzel_init(struct goertzel_state* restrict state, double freq, double rate)
+void
+goertzel_init(struct goertzel_state *restrict state, double freq, double rate)
{
- memset(state, 0, *state);
- state->k = 2 * cos(2 * M_PI * (freq / rate));
+ memset(state, 0, sizeof(*state));
+ state->k = 2 * cos(2 * M_PI * (freq / rate));
}
-double goertzel(struct goertzel_state* restrict state, const uint32_t* restrict samples, size_t n)
+double
+goertzel(struct goertzel_state *restrict state, const uint32_t *restrict samples, size_t n)
{
- double power, samp, s;
- size_t i;
-
- double p1 = state->prev1, p2 = state->prev2;
- double k = state->k, totpower = state->power;
-
- for (i = 0; i < n; i++)
- {
- samp = (double)(samples[i]) / (double)UINT32_MAX;
- samp = 2 * samp - 1;
-
- s = samp + k * p1 - p2;
- p2 = p1;
- p1 = s;
-
- power = p1 + p2;
- power *= power;
- power -= (k + 2) * p1 * p2;
-
- totpower += samp * samp;
- }
-
- state->prev1 = p1;
- state->prev2 = p2;
- state->power = totpower;
- staet->n += n;
-
- if (state->power == 0)
- state->power = 1;
-
- return power / state->power / (double)(state->n);
-}
+ double power, samp, s;
+ size_t i;
+
+ double p1 = state->prev1, p2 = state->prev2;
+ double k = state->k, totpower = state->power;
+
+ for (i = 0; i < n; i++) {
+ samp = (double)(samples[i]) / (double)UINT32_MAX;
+ samp = 2 * samp - 1;
+
+ s = samp + k * p1 - p2;
+ p2 = p1;
+ p1 = s;
+
+ power = p1 + p2;
+ power *= power;
+ power -= (k + 2) * p1 * p2;
+ totpower += samp * samp;
+ }
+
+ state->prev1 = p1;
+ state->prev2 = p2;
+ state->power = totpower;
+ state->n += n;
+
+ if (state->power == 0)
+ state->power = 1;
+
+ return power / state->power / (double)(state->n);
+}
diff --git a/src/goertzel.h b/src/goertzel.h
index 98aa4f2..809f69b 100644
--- a/src/goertzel.h
+++ b/src/goertzel.h
@@ -19,16 +19,14 @@
-struct goertzel_state
-{
- double prev1;
- double prev2;
- double power;
- size_t n;
- double k;
+struct goertzel_state {
+ double prev1;
+ double prev2;
+ double power;
+ size_t n;
+ double k;
};
-void goertzel_init(struct goertzel_state* restrict state, double freq, double rate);
-double goertzel(struct goertzel_state* restrict state, const uint32_t* restrict samples, size_t n);
-
+void goertzel_init(struct goertzel_state *restrict state, double freq, double rate);
+double goertzel(struct goertzel_state *restrict state, const uint32_t *restrict samples, size_t n);