Page MenuHomeFreeBSD

D35772.id108013.diff
No OneTemporary

D35772.id108013.diff

diff --git a/usr.bin/beep/beep.1 b/usr.bin/beep/beep.1
--- a/usr.bin/beep/beep.1
+++ b/usr.bin/beep/beep.1
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 4, 2021
+.Dd July 11, 2022
.Dt beep 1
.Os
.Sh NAME
@@ -36,6 +36,7 @@
.Op Fl r Ar sample_rate_hz
.Op Fl d Ar oss_device
.Op Fl g Ar gain
+.Op Fl t Ar text
.Op Fl B
.Op Fl h
.Sh DESCRIPTION
@@ -60,6 +61,9 @@
.It Fl g
Sets the waveform gain, between 0 and 100 inclusively.
The default is 75.
+.It Fl t
+Render the given text as 8-bit audio codes starting at the least significant bit, similarly to Braille.
+This option can also be combined with the duration option to either speed up or slow down the audio.
.It Fl B
Runs the
.Nm
diff --git a/usr.bin/beep/beep.c b/usr.bin/beep/beep.c
--- a/usr.bin/beep/beep.c
+++ b/usr.bin/beep/beep.c
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <assert.h>
#define SAMPLE_RATE_DEF 48000 /* hz */
#define SAMPLE_RATE_MAX 48000 /* hz */
@@ -61,6 +62,7 @@
static int gain = GAIN_DEF;
static const char *oss_dev = DEFAULT_DEVICE;
static bool background;
+static const uint8_t *text;
/*
* wave_function_16
@@ -129,6 +131,65 @@
return (retval);
}
+static void
+render_beep(int32_t *buffer, size_t size, float amp)
+{
+ size_t slope;
+ size_t off; /* buffer offset */
+ float p; /* phase */
+ float d; /* delta phase */
+
+ /* compute slope duration in samples */
+ slope = (DURATION_MIN * sample_rate) / 2000;
+
+ /* set initial phase and delta */
+ p = 0;
+ d = (float)frequency / (float)sample_rate;
+
+ /* compute wave */
+ for (p = off = 0; off != size; off++, p += d) {
+ float sample;
+
+ p = p - floorf(p);
+ sample = amp * wave_function_16(p, WAVE_POWER);
+
+ if (off < slope)
+ sample = sample * off / (float)slope;
+ else if (off > (size - slope))
+ sample = sample * (size - off - 1) / (float)slope;
+
+ buffer[off] = sample * 0x7fffff00;
+ }
+}
+
+static void
+render_silence(int32_t *buffer, size_t size)
+{
+ for (size_t x = 0; x != size; x++)
+ buffer[x] = 0;
+}
+
+static size_t
+text_length_in_units(const uint8_t *ptr)
+{
+ size_t units = 0;
+
+ while (*ptr) {
+ uint8_t ch = *ptr;
+
+ for (uint8_t x = 0; x != 8; x++) {
+ if ((ch >> x) & 1)
+ units += 2;
+ else
+ units += 4;
+ }
+
+ units += 4;
+ ptr ++;
+ }
+ return (units);
+}
+
static void
usage(void)
{
@@ -138,6 +199,7 @@
"\t" "-r <sample rate in HZ, from %d Hz to %d Hz, default %d Hz>\n"
"\t" "-d <OSS device (default %s)>\n"
"\t" "-g <gain from %d to %d, default %d>\n"
+ "\t" "-t <render given text>\n"
"\t" "-B Run in background\n"
"\t" "-h Show usage\n",
getprogname(),
@@ -153,16 +215,14 @@
main(int argc, char **argv)
{
int32_t *buffer;
- size_t slope;
size_t size;
+ size_t units;
size_t off;
float a;
- float d;
- float p;
int c;
int f;
- while ((c = getopt(argc, argv, "BF:D:r:g:d:h")) != -1) {
+ while ((c = getopt(argc, argv, "BF:D:r:t:g:d:h")) != -1) {
switch (c) {
case 'F':
frequency = strtol(optarg, NULL, 10);
@@ -191,6 +251,9 @@
case 'B':
background = true;
break;
+ case 't':
+ text = optarg;
+ break;
default:
usage();
break;
@@ -224,38 +287,48 @@
if (ioctl(f, SNDCTL_DSP_GETODELAY, &c) != 0)
errx(1, "ioctl SNDCTL_DSP_GETODELAY failed");
+ if (text != NULL)
+ units = text_length_in_units(text);
+ else
+ units = 1;
+
size = ((sample_rate * duration_ms) + 999) / 1000;
- buffer = malloc(sizeof(buffer[0]) * size);
+ buffer = malloc(sizeof(buffer[0]) * size * units);
if (buffer == NULL)
errx(1, "out of memory");
- /* compute slope duration in samples */
- slope = (DURATION_MIN * sample_rate) / 2000;
-
/* compute base gain */
a = powf(65536.0f, (float)gain / (float)GAIN_MAX) / 65536.0f;
- /* set initial phase and delta */
- p = 0;
- d = (float)frequency / (float)sample_rate;
-
- /* compute wave */
- for (p = off = 0; off != size; off++, p += d) {
- float sample;
-
- p = p - floorf(p);
- sample = a * wave_function_16(p, WAVE_POWER);
-
- if (off < slope)
- sample = sample * off / (float)slope;
- else if (off > (size - slope))
- sample = sample * (size - off - 1) / (float)slope;
+ if (text != NULL) {
+ for (off = 0; *text != 0; text++) {
+ uint8_t ch = *text;
+
+ for (uint8_t x = 0; x != 8; x++) {
+ if ((ch >> x) & 1) {
+ render_beep(buffer + off, size, a);
+ off += size;
+ render_silence(buffer + off, size);
+ off += size;
+ } else {
+ render_beep(buffer + off, 3 * size, a);
+ off += 3 * size;
+ render_silence(buffer + off, size);
+ off += size;
+ }
+ }
+
+ render_silence(buffer + off, 4 * size);
+ off += 4 * size;
+ }
- buffer[off] = sample * 0x7fffff00;
+ assert(off == (size * units));
+ } else {
+ render_beep(buffer, size, a);
}
-
- if (write(f, buffer, size * sizeof(buffer[0])) !=
- (ssize_t)(size * sizeof(buffer[0])))
+
+ if (write(f, buffer, size * units * sizeof(buffer[0])) !=
+ (ssize_t)(size * units * sizeof(buffer[0])))
errx(1, "failed writing to DSP device(%s)", oss_dev);
free(buffer);

File Metadata

Mime Type
text/plain
Expires
Tue, Feb 17, 3:57 PM (6 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28818641
Default Alt Text
D35772.id108013.diff (5 KB)

Event Timeline