Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145165588
D35772.id108013.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D35772.id108013.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35772: beep(1): Add support for rendering text and numbers as audio.
Attached
Detach File
Event Timeline
Log In to Comment