Add 2018/algmyr/try.sh + format/typo checks

The README.md file has been format/typo checked.

This entry was also expanded some in bugs.md.
This commit is contained in:
Cody Boone Ferguson committed 2023-12-14 10:08:03 -08:00
1 parent 7b7530e9f1
commit 0cbd1db764
4 files changed
+110 -35

No files matched your search

+31 -33
View File
@@ -4,6 +4,10 @@
make
```
To use this entry requires, in some invocations, a sound processing program.
This can be ALSA or SoX but we recommend the latter. See [FAQ 3.10 - How do I
compile and use an IOCCC winner that requires sound?](/faq.md#faq3_10).
### Bugs and (Mis)features:
@@ -19,31 +23,16 @@ For more detailed information see [2018 algmyr in bugs.md](/bugs.md#2018-algmyr)
## To use:
```sh
cat prog.c | ./prog # Printing garbage might break your font
cat prog.c | ./prog # Print garbage: might mess up your terminal
./prog <file1> <file2> > out.raw
./prog -d 2 0 out.raw # Decode the first (0th) channel out of two
```
NOTE: this entry will crash if a file specified cannot be opened.
### Try:
```sh
./prog -h | ./prog -d 1 0
# Who needs cat?
./prog prog.c | ./prog -d 1 0
# Assuming ALSA:
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
./prog | aplay -c1 -fFLOAT_LE -r44100
# Assuming sox:
echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog |\
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - -n spectrogram -d 10 -X 300
# now open spectrogram.png with a graphics viewer or editor
./try.sh
```
@@ -55,11 +44,13 @@ or at least a handy and well-tested volume knob.
Pixels are numbered, amplitudes are weighed, frequencies are divided,
and the message can be displayed in fiery letters, but don't be alarmed.
How does decoding of the waveform work? Can you encode an arbitrary text in a sound sample?
How does decoding of the waveform work? Can you encode an arbitrary text in a
sound sample?
## Author's remarks:
### What is this?
To put it brief, this entry is akin to a sound based cat. It takes characters as
@@ -67,18 +58,20 @@ input and outputs them into frequency space as audio. The entry also supports
decoding the produced waveforms using the `-d` flag. Usage instructions is
output if run with the `-h` flag, albeit not in an immediately legible format.
### Details
In normal operation, the entry reads characters from one or more sources. If the
`-h` flag is given, usage instructions is used as a source. Else if file paths
are present as arguments those will be used. Else stdin is used.
are present as arguments those will be used. Else `stdin` is used.
If a character is part of the supported subset of ASCII `{10, 32-126}` then that
character is output into frequency space of an audio signal (44.1 kHz single
precision float, endianness should depend on system endianness) through `stdout`.
Any other character will be interpreted and outputted as a space.
Characters are printed using a (slightly modified) pixel font based on [gohufont](https://github.com/hchargois/gohufont).
Characters are printed using a (slightly modified) pixel font based on
[gohufont](https://github.com/hchargois/gohufont).
Pixels are drawn using crosses in frequency space, achieved by simultaneous up
and down chirps.
@@ -93,12 +86,13 @@ characters.
See image [spoiler.png](spoilers.png) for an example spectrogram.
### Limitations
There is no error checking done when opening files, so expect segfaults if you
provide the wrong path to a file.
This program is bound to misbehave if int is less than 32 bits.
This program is bound to misbehave if `int` is less than 32 bits.
Flags will only be interpreted correctly if they are the first argument. Reading
a file named `-d` or `-h` is fully possible if it is not the first file
@@ -109,32 +103,32 @@ behavior. Some erroneous arguments cause segfaults (negative number of channels,
channel id outside valid range). One argument in particular causes an infinite
loop printing whitespace.
#### Techniques:
##### Obfuscation:
### Obfuscation:
A lot of the obfuscations done came naturally from trying to appease the size
tool. To name some:
* One character names
* Merging of related (and not so related) arithmetic operations
* Short circuiting for flow control to replace some `if`s
* Some `#defines`, sadly
* One character names.
* Merging of related (and not so related) arithmetic operations.
* Short circuiting for flow control to replace some `if`s.
* Some `#defines`, sadly.
On the intersection of size and obfuscation is the data encoding, which was
quite fun to design.
Some additional obfuscation was done to mathematical formulas. Somewhat known
expressions was transformed into equivalent but less recognizable counterparts.
expressions were transformed into equivalent but less recognizable counterparts.
I have tried to avoid intentional red herrings in the code, although fishy
statements are plentiful.
### Data encoding:
The large string in the beginning of the source file contains font data, encoded
in base64 using characters in the range `' '` to `'_'`. The space was chosen as
the zero because the data contains a lot of zeroes, and quite helpfully the size
zero because the data contains a lot of zeroes, and quite helpfully the size
tool ignores whitespace even in strings. Without this fact the program would
have been too large and the decoding feature would have had to go. Fortunately
this hole in the size spec was readily available. :)
@@ -142,9 +136,10 @@ this hole in the size spec was readily available. :)
Characters in the font (5x8 pixels, 40 bits) are packed into 7 base64 digits
(which was a pain to decode in minimal code).
### Math:
Note that even though floats are used for the waveforms, the standard math
Note that even though `float`s are used for the waveforms, the standard math
library is not used at all! Most arithmetic is done purely on integers. The only
major exception is generating a table of sine values which are interpolated to
give high resolution waveforms. Can you see when the generation is triggered,
@@ -157,13 +152,15 @@ function was used. Although the one used is quite well known, it is not in a
form that should be familiar to anyone. What looks like a polynomial and quacks
like a polynomial might not actually be a polynomial, at least not deep inside.
### Printing a string:
The program was written to deal exclusively with file descriptors, so how would
one go about printing a char array not from a file descriptor without adding
additional logic? Answer: `ungetc` into stdin, one char at a time (to be
one go about printing a `char` array not from a file descriptor without adding
additional logic? Answer: `ungetc(3)` into `stdin`, one `char` at a time (to be
standards compliant). This is used to print the usage instructions.
### Compilation warnings
Compiling using
@@ -179,7 +176,7 @@ clang -Wall -Wextra -pedantic
```
is a bit more pessimistic and gives `-Wempty-body` (I like loops without
bodies), `-Wstring-plus-int` (since apparently some people think string+int is a
bodies), `-Wstring-plus-int` (since apparently some people think string+`int` is a
concatenation) and one of the weirder warnings I have seen from me splitting a
negative constant with whitespace. Compiling using
@@ -190,6 +187,7 @@ clang -Wall -Wextra -pedantic -Weverything
produces a few page faults of warnings and makes me feel generally bad about
myself. :(
### Misc
The reported size of the source code using the size tool is very intentionally
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
#
# try.sh - demonstrate IOCCC winner 2018/algmyr
#
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
# this way allows us to have the user specify a different compiler in an easy
# way.
if [[ -z "$CC" ]]; then
CC="cc"
fi
make CC="$CC" all >/dev/null || exit 1
# clear screen after compilation so that only the entry is shown
clear
echo "$ ./prog -h | ./prog -d 1 0" 1>&2
./prog -h | ./prog -d 1 0
echo 1>&2
# Who needs cat? Answer: more people than you think.
read -r -n 1 -p "Press any key to run: ./prog prog.c | ./prog -d 1 0 (space = next page, q = quit): "
echo 1>&2
./prog prog.c | ./prog -d 1 0 | less -EXF
echo 1>&2
APLAY="$(type -P aplay)"
SOX="$(type -P sox)"
if [[ -z "$SOX" && -z "$APLAY" ]]; then
echo "Missing both sox and aplay, cannot do this step."
elif [[ -n "$SOX" ]]; then
echo "$ echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog | \
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 \
- -n spectrogram -d 10 -X 300" 1>&2
echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog |\
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - -n spectrogram -d 10 -X 300
echo "Now open spectrogram.png in an image viewer or editor." 1>&2
read -r -n 1 -p "Press any key to continue: "
echo 1>&2
echo "$ echo "IOCCC 2018" | ./prog | sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - ioccc.wav"
echo "IOCCC 2018" | ./prog | sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - ioccc.wav
echo "Now listen to ioccc.wav." 1>&2
else
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
./prog | aplay -c1 -fFLOAT_LE -r44100
echo '<<<<<< /\_/\_/\ _-_-_-_ !!!!! :.:.:.: >>>>>> ****** ~~~~~~~' |
./prog | aplay -c1 -fFLOAT_LE -r44100
echo "Now open spectrogram.png in an image viewer or editor." 1>&2
fi
echo 1>&2
echo "$ echo "IOCCC 2018!" | ./prog | ./prog -d 1 0" 1>&2
echo "IOCCC 2018!" | ./prog | ./prog -d 1 0
+13 -2
View File
@@ -3151,8 +3151,19 @@ There was no IOCCC in 2017.
### Source code: [2018/algmyr/algmyr.c](2018/algmyr/algmyr.c)
### Information: [2018/algmyr/README.md](2018/algmyr/README.md)
This entry is known to crash if a file cannot be opened. This is noted by the
author and is easy enough to fix but need not be.
The author wrote:
* There is no error checking done when opening files, so expect segfaults if you
provide the wrong path to a file.
* This program is bound to misbehave if `int` is less than 32 bits.
* Flags will only be interpreted correctly if they are the first argument. Reading
a file named `-d` or `-h` is fully possible if it is not the first file
provided, even though I am not sure why you would want to do that.
* Providing invalid/unexpected arguments to the decode flag will result in odd
behavior. Some erroneous arguments cause segfaults (negative number of channels,
channel id outside valid range). One argument in particular causes an infinite
loop printing whitespace.
## 2018 hou
+6
View File
@@ -3952,6 +3952,12 @@ He also added the [try.sh](/2015/yang/try.sh) script.
# <a name="2018"></a>2018
## <a name="2018_algmyr"></a>[2018/algmyr](/2018/algmyr/prog.c) ([README.md](/2018/algmyr/README.md))
[Cody](#cody) added the [try.sh](/2018/algmyr/try.sh) script.
## <a name="2018_bellard"></a>[2018/bellard](/2018/bellard/prog.c) ([README.md](/2018/bellard/README.md))
[Cody](#cody) added explicit linking of libm (`-lm`) for systems that do not do this