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:
1 parent
7b7530e9f1
commit
0cbd1db764
4 files changed
+110
-35
No files matched your search
+31
-33
@@ -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
|
||||
|
||||
Executable
+60
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user