Annwan
5 months ago
27 changed files with 518 additions and 0 deletions
-
31.gitignore
-
3.gitmodules
-
1README.md
-
239grammar/main.tex
-
1grammar/nguhslides
-
BINtools/0.wav
-
BINtools/1.wav
-
BINtools/2.wav
-
BINtools/3.wav
-
BINtools/4.wav
-
BINtools/5.wav
-
BINtools/6.wav
-
BINtools/7.wav
-
BINtools/8.wav
-
BINtools/9.wav
-
BINtools/A.wav
-
BINtools/B.wav
-
BINtools/C.wav
-
BINtools/D.wav
-
BINtools/Octothorpe.wav
-
BINtools/Star.wav
-
5tools/ppn2seq/CHANGELOG.md
-
20tools/ppn2seq/LICENSE
-
27tools/ppn2seq/ppn2seq.cabal
-
136tools/ppn2seq/src/Ppn2Seq.hs
-
55tools/seqtoaudio
-
BINtools/skip.wav
@ -0,0 +1,31 @@ |
|||
# seq2audio output |
|||
tools/*.wav |
|||
tools/*.filelist |
|||
|
|||
# except the input files |
|||
!tools/1.wav |
|||
!tools/2.wav |
|||
!tools/3.wav |
|||
!tools/4.wav |
|||
!tools/5.wav |
|||
!tools/6.wav |
|||
!tools/7.wav |
|||
!tools/8.wav |
|||
!tools/9.wav |
|||
!tools/0.wav |
|||
!tools/Star.wav |
|||
!tools/Octothorpe.wav |
|||
!tools/skip.wav |
|||
|
|||
# TeX output |
|||
*.aux |
|||
*.fdb_latexmk |
|||
*.fls |
|||
*.log |
|||
*.toc |
|||
*.xdv |
|||
*.pdf |
|||
*.synctex.gz |
|||
|
|||
# Haskell outputs |
|||
dist-newstyle |
@ -0,0 +1,3 @@ |
|||
[submodule "grammar/nguhslides"] |
|||
path = grammar/nguhslides |
|||
url = git@github.com:Agma-Schwa/nguhslides.git |
@ -0,0 +1 @@ |
|||
Submission for the 3rd annual Cursed Conlang Circus |
@ -0,0 +1,239 @@ |
|||
%! TeX Root: main.tex |
|||
% vim: set et tw=80 ts=4 sw=4: |
|||
\documentclass{article} |
|||
\usepackage{fontspec} |
|||
\setmainfont{Andika}[StylisticSet=13] |
|||
\setsansfont{Minion 3}[Scale=MatchUppercase] |
|||
\setmonofont{Iosevka}[ |
|||
Scale=MatchUppercase, |
|||
CharacterVariant={99:8} |
|||
] |
|||
\usepackage[margin=25mm]{geometry} |
|||
\usepackage{nguhgloss} |
|||
\let\nf\normalfont |
|||
\def\z#1{\texttt{#1}} |
|||
\def\Clong{\z{811\#0*034C534*4\#C004-*\#3*75} } |
|||
\title{\Clong\\{\large A CCC3 Submission}} |
|||
\author{Annwan} |
|||
\date{2024} |
|||
|
|||
\setlength\parskip{1ex} |
|||
\setlength\parindent{0ex} |
|||
|
|||
\begin{document} |
|||
\maketitle |
|||
% \tableofcontents |
|||
\section{Presentation} |
|||
|
|||
\Clong is the language of telephone exchanges |
|||
|
|||
\section{Phone-ology} |
|||
|
|||
Telephone exchanges cannot speak like humans do. Instead, \Clong uses DTMF |
|||
Keypad Tones to convey information. |
|||
|
|||
Here is a table of DTMF tones for reference. |
|||
|
|||
\begin{center} |
|||
\begin{tabular}{c|cccc} |
|||
& \bf 1209 Hz & \bf 1336 Hz & \bf 1477 Hz & \bf 1633 Hz \\\hline |
|||
\bf 697 Hz & \z 1 & \z 2 & \z 3 & \z A \\ |
|||
\bf 770 Hz & \z 4 & \z 5 & \z 6 & \z B \\ |
|||
\bf 852 Hz & \z 7 & \z 8 & \z 9 & \z C \\ |
|||
\bf 941 Hz & \z * & \z 0 & \z \# & \z D |
|||
\end{tabular} |
|||
\end{center} |
|||
|
|||
|
|||
|
|||
\section{Units of meaning -- Packets} |
|||
|
|||
Semantic information is encoded into packets. A packet can be of 5 types: {\bf |
|||
Semantic}, {\bf Proper Noun}, {\bf Syntactic}, {\bf Continuation} and {\bf |
|||
Variable}. A packet is a sequences of coniguous tones surrounded by blanks. |
|||
additionally individual packets have a maximal length of 20 tones. If a |
|||
packet's information would exceed that length limit, the extra data shall be |
|||
included in one or more continuation packets. |
|||
|
|||
\subsection{Semantic Packet} |
|||
|
|||
A semantic packet is a packet encoding a concept. It uses the Universal Decimal |
|||
Clasification to encode the topics. Numeric values are encoded with their |
|||
appropriate digit, dots are encoded with \z*, slashes are encoded with \z A. |
|||
dashes are encoded with \z{BA}, equals with \z{BB}, column with \z C and quotes |
|||
with \z D and parens with \z\#. This has the side effect that semantic packets |
|||
cannot start with \z*. |
|||
|
|||
A reference to a variable (see \ref{variables}) starts with \z{B*} and ends with |
|||
\z{B\#}. The variable prefix is omitted in that use. |
|||
|
|||
\newpage |
|||
\subsection{Proper Nouns} |
|||
|
|||
A proper noun packet is encoded as follows: |
|||
\begin{enumerate} |
|||
\item Two Stars (\z{**}) |
|||
\item The length of the encoding of the proper noun in tones, expressed as an |
|||
hexadecimal digit where \z* stands for 14, \z\# stands for 15 and \z0 |
|||
stands for 16. |
|||
\item the proper noun encoded according to EBCDIC page 00803 in hexadecimal |
|||
where \z* stands for 0xE and \z\# stands for 0xF. |
|||
\end{enumerate} |
|||
If the noun exceeds 16 tones (8 bytes) when encoded, one shall use continuation |
|||
packets. |
|||
|
|||
If the noun cannot be fully encoded into EBCDIC 00803 it shall be expressed |
|||
as a sequences of hexadecimal unicode codepoints of the form U+xxxxxxxx in |
|||
normalised decomposed form then subsequently encoded to EBCDIC page 00803 |
|||
|
|||
A proper noun must be followed by a semantic packet qualifying the nature of |
|||
the entity described by the proper noun. |
|||
|
|||
\subsection{Syntactic Packet} |
|||
|
|||
Syntactic Packets start with a \z* followed by one or more digit or letters. If |
|||
they take parameters those are expressed after the Syntactic packet in the order |
|||
specified. They are of two kinds: |
|||
|
|||
\subsubsection {Morphological packets} There exists 5 such packets. They encode |
|||
the gramatical role of parameters in the sentence. |
|||
|
|||
\begin{description} |
|||
\item[Assertive \z{*1}] takes one argument and produces the clause that |
|||
asserts that the postulate is true, or that the object exists |
|||
\item[Intransitive \z{*2A}] takes two arguments and produces the clause with |
|||
the first argument as Agent and the second argument as Verb |
|||
\item[Intransitive Passive \z{*2B}] takes two arguments and produces the |
|||
clause with the first argument as Patient and the second argument as Verb |
|||
\item[Transitive \z{*3}] takes three arguments and produces the clause with the |
|||
first argument as Subject, the sencond argument as Object, and the third |
|||
argument as Verb. For an equivalent of a passive construction, simply reverse |
|||
the arguments |
|||
\item[Ditransitive \z{*4}] takes four arguments and produces the clause with |
|||
the first argument as Subject, the second as Object, the third as Beneficiary |
|||
and the fourth as Verb. |
|||
\item[Collectionaliser \z{*C}] takes two constructs and forms the collection of |
|||
those constructs. For larger collections, one instance of the |
|||
collectionaliser is required per element. While the order is not |
|||
gramatically mandated, it is common to emit all the collectionalisers of a |
|||
group at the start, then list the elements. |
|||
\end{description} |
|||
|
|||
\subsubsection{Referential Packets} |
|||
\begin{description} |
|||
\item[Proper Noun Qualifier \z{*D}] Proper nouns cannot be used on their |
|||
own, instead they must be qualified by:LL: the type of {\it thing} refered |
|||
to by the proper noun. For that one uses this qualifer. Takes a proper |
|||
noun and a common noun and produces the a reference to the {\it thing} |
|||
described by the common noun refered to by the proper noun. |
|||
\item[Variable Definition Packet \z{*0}] takes a variable name and a |
|||
syntactic construct and assigns the syntactic construct as value of the |
|||
variable. the Variable may, after this point be used in stead of the |
|||
construct, this is effectively a pronoun, but not limited to just nouns |
|||
and noun phrases. |
|||
\item[Participant Reference \z{*A1} and \z{*A2}] refer to the |
|||
participants of the conversation. The respectly refer to the speaker, |
|||
the listner and both the speaker and the listner |
|||
\item |
|||
\end{description} |
|||
|
|||
|
|||
|
|||
\subsection{Continuation Packet} |
|||
|
|||
A continuation packet is used whenever a packet goes over it's maximum size |
|||
(3+16 tones for proper noun packets, 20 tones for semantic packets) to contain |
|||
the rest of the information to be contained. |
|||
|
|||
A continuation packet is formed as follws |
|||
\begin{itemize} |
|||
\item A Star and an Octothorpe (\z{*\#}) |
|||
\item The number of tones in the body of the semantic packet as a single |
|||
hexadecimal digit with \z* standing for 14, \z\# standing for 15 and \z0 |
|||
standing for 16. |
|||
\item The tones of the body |
|||
\end{itemize} |
|||
|
|||
If the entire contents cannot be fit in the body of the packey, more |
|||
continuation packets shall be used. |
|||
|
|||
\subsection{Variable packet}\label{variables} |
|||
|
|||
A variable packet represents a variable to be refered too as later, they act a |
|||
bit like pronouns but can refer to any construct of the language. They are |
|||
formed by two Octothorpes followed by the identifier of the variables composed |
|||
of up to 18 digits. |
|||
|
|||
\section{Actually communicating -- Flow control and error correction} |
|||
|
|||
The packets previously documented are only the encapsulated semantic meaning of |
|||
language. An actual conversation would use the following flow control language: |
|||
|
|||
A discussion is initiated by a |
|||
|
|||
\section{Sample Texts} |
|||
|
|||
These text samples do not contain the control flow communications. The |
|||
corresponding audio samples are as if said by a speaker at adress 42069 |
|||
(decimal) broadcasting to the network. |
|||
|
|||
\begin{quote} |
|||
Hark! It was ruled by Agamashuya and His son Gu Sabah: Tian practices against |
|||
the lesser side of the invisible origin of light, beset by cosmetic prohibitions |
|||
of silence and restraint; for Ngu, a slave to creativity, shall make inspection |
|||
and certification prior to confirmation of Najva Guns’ official status. Deny |
|||
thine humanity: There are no politics in real life. |
|||
\end{quote} |
|||
\ExplSyntaxOn |
|||
\cs_set:Npn \__nguh_multigloss_word:nn #1#2 { |
|||
\allowbreak |
|||
|
|||
\hbox { |
|||
\begin{tabular}{@{}l} |
|||
\ttfamily \__nguh_gloss_rescan:n {\ignorespaces#1} \\ |
|||
\noalign{\vskip-6pt} |
|||
\scshape \__nguh_gloss_rescan:n {\ignorespaces#2} \\ |
|||
\end{tabular} |
|||
} |
|||
|
|||
\space |
|||
} |
|||
\ExplSyntaxOff |
|||
{ |
|||
\catcode`#=12 |
|||
\multigloss { |
|||
*B | *B | *B |
|||
cnew | cnew | cnew |
|||
|
|||
*1 | *A1 | *0 | ##0 | *D | **0*44*#0#0#0#0#0#0 |
|||
assert | 1sg | let | var[0] | ppn | ``Agamashuya'' |
|||
|
|||
*#0#4#1*44*#0#0#0#0 | *#0#0#0#6#7*44*#0#0 | *#0#0#0#0#0#6#1*44* |
|||
cont | cont | cont |
|||
|
|||
*#0#0#0#0#0#0#0#6C4 | *#0*44*#0#0#0#0#0#0 | *#0#6#1*44*#0#0#0#0 |
|||
cont | cont | cont |
|||
|
|||
*#0#0#0#7#3*44*#0#0 | *#0#0#0#0#0#6#8*44* | *#0#0#0#0#0#0#0#7#5 |
|||
cont | cont | cont |
|||
|
|||
*#0*44*#0#0#0#0#0#0 | *#0#7#9*44*#0#0#0#0 | *#8#0#0#6#1 | BA05 | *3 | *C |
|||
cont | cont | cont | person | trans | col |
|||
|
|||
##0 | *D | **0*44*#0#0#0#0#0#0 |
|||
var[0] | ppn | ``Gu Sabah'' |
|||
|
|||
*#0#4#7*44*#0#0#0#0 | *#0#0#0#7#5*44*#0#0 | *#0#0#0#0#0#2#0*44* |
|||
cont | cont | cont |
|||
|
|||
*#0#0#0#0#0#0#0#5#3 | *#0*44*#0#0#0#0#0#0 | *#0#6#1*44*#0#0#0#0 |
|||
cont | cont | cont |
|||
|
|||
*#0#0#0#6#2*44*#0#0 | *#0#0#0#0#0#6#1*44* | *#0#0#0#0#0#0#0#6#8 |
|||
cont | cont | cont |
|||
|
|||
BA055*1B0BA055*6CB*0 | *#4B#B1 | * | 328 |
|||
{\nf male child of} var[0] | cont | gnr | govern |
|||
} |
|||
} |
|||
\end{document} |
@ -0,0 +1,5 @@ |
|||
# Revision history for ppn2seq |
|||
|
|||
## 0.1.0.0 -- YYYY-mm-dd |
|||
|
|||
* First version. Released on an unsuspecting world. |
@ -0,0 +1,20 @@ |
|||
Copyright (c) 2024 Annwan |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining |
|||
a copy of this software and associated documentation files (the |
|||
"Software"), to deal in the Software without restriction, including |
|||
without limitation the rights to use, copy, modify, merge, publish, |
|||
distribute, sublicense, and/or sell copies of the Software, and to |
|||
permit persons to whom the Software is furnished to do so, subject to |
|||
the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included |
|||
in all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,27 @@ |
|||
cabal-version: 3.0 |
|||
name: ppn2seq |
|||
version: 0.1.0.0 |
|||
-- synopsis: |
|||
-- description: |
|||
license: MIT |
|||
license-file: LICENSE |
|||
author: Annwan |
|||
maintainer: annwan@annwan.me |
|||
-- copyright: |
|||
build-type: Simple |
|||
extra-doc-files: CHANGELOG.md |
|||
-- extra-source-files: |
|||
|
|||
common warnings |
|||
ghc-options: -Wall |
|||
|
|||
executable ppn2seq |
|||
import: warnings |
|||
main-is: Ppn2Seq.hs |
|||
-- other-modules: |
|||
-- other-extensions: |
|||
build-depends: base ^>=4.18.0.0 |
|||
, text |
|||
, unicode-transforms |
|||
hs-source-dirs: src |
|||
default-language: GHC2021 |
@ -0,0 +1,136 @@ |
|||
module Main where |
|||
|
|||
import Text.Printf |
|||
import Data.Text.Normalize |
|||
import qualified Data.Text as T |
|||
|
|||
chunksof :: Int -> [a] -> [[a]] |
|||
chunksof n s = case drop n s of |
|||
[] -> [s] |
|||
rest -> (take n s) : chunksof n rest |
|||
|
|||
phoneify :: [String] -> String |
|||
phoneify [] = "" |
|||
phoneify (x:xs) = "**" ++ length_fmt x ++ x ++ phoneify_rest xs |
|||
where |
|||
length_fmt :: String -> String |
|||
length_fmt s = case length s of |
|||
{ 1 -> "1" ; 2 -> "2" ; 3 -> "3"; 4 -> "4" |
|||
; 5 -> "5" ; 6 -> "6" ; 7 -> "7"; 8 -> "8" |
|||
; 9 -> "9" ; 10 -> "A" ; 11 -> "B" ; 12 -> "C" |
|||
; 13 -> "D"; 14 -> "*" ; 15 -> "#" ; 16 -> "0" |
|||
; _ -> "!" |
|||
} |
|||
phoneify_rest [] = "" |
|||
phoneify_rest (y:ys) = "-*#" ++ length_fmt y ++ y ++ phoneify_rest ys |
|||
|
|||
toEbcdic :: String -> String |
|||
toEbcdic = concatMap $ \x -> case x of |
|||
' ' -> "40" |
|||
'$' -> "4A" |
|||
'.' -> "4B" |
|||
'<' -> "4C" |
|||
'(' -> "4D" |
|||
'+' -> "4*" |
|||
'|' -> "4#" |
|||
'א' -> "50" |
|||
'!' -> "5A" |
|||
'*' -> "5C" |
|||
')' -> "5D" |
|||
';' -> "5*" |
|||
'¬' -> "5#" |
|||
'-' -> "60" |
|||
'/' -> "61" |
|||
',' -> "6B" |
|||
'%' -> "6C" |
|||
'_' -> "6D" |
|||
'>' -> "6*" |
|||
'?' -> "6#" |
|||
':' -> "7A" |
|||
'#' -> "7B" |
|||
'@' -> "7C" |
|||
'\'' -> "7D" |
|||
'=' -> "7*" |
|||
'"' -> "7#" |
|||
'ב' -> "81" |
|||
'ג' -> "82" |
|||
'ד' -> "83" |
|||
'ה' -> "84" |
|||
'ו' -> "85" |
|||
'ז' -> "86" |
|||
'ח' -> "84" |
|||
'ט' -> "88" |
|||
'י' -> "89" |
|||
'ך' -> "91" |
|||
'כ' -> "92" |
|||
'ל' -> "93" |
|||
'ם' -> "94" |
|||
'מ' -> "95" |
|||
'ן' -> "96" |
|||
'נ' -> "97" |
|||
'ס' -> "98" |
|||
'ע' -> "99" |
|||
'€' -> "9C" |
|||
'₪' -> "9E" |
|||
-- 'ע' -> "A2" -- FOR SOME UN-FUCKING-GODLY REASON IBM DECIDED TO ENCODE THIS TWICE, ENCODED AS 99 |
|||
'ף' -> "A3" |
|||
'פ' -> "A4" |
|||
'ץ' -> "A5" |
|||
'צ' -> "A6" |
|||
'ק' -> "A7" |
|||
'ר' -> "A8" |
|||
'ש' -> "A9" |
|||
'ת' -> "AA" |
|||
'A' -> "C1" |
|||
'B' -> "C2" |
|||
'C' -> "C3" |
|||
'D' -> "C4" |
|||
'E' -> "C5" |
|||
'F' -> "C6" |
|||
'G' -> "C7" |
|||
'H' -> "C8" |
|||
'I' -> "C9" |
|||
'J' -> "D1" |
|||
'K' -> "D2" |
|||
'L' -> "D3" |
|||
'M' -> "D4" |
|||
'N' -> "D5" |
|||
'O' -> "D6" |
|||
'P' -> "D7" |
|||
'Q' -> "D8" |
|||
'R' -> "D9" |
|||
'S' -> "*2" |
|||
'T' -> "*3" |
|||
'U' -> "*4" |
|||
'V' -> "*5" |
|||
'W' -> "*6" |
|||
'X' -> "*7" |
|||
'Y' -> "*8" |
|||
'Z' -> "*9" |
|||
'0' -> "#0" |
|||
'1' -> "#1" |
|||
'2' -> "#2" |
|||
'3' -> "#3" |
|||
'4' -> "#4" |
|||
'5' -> "#5" |
|||
'6' -> "#6" |
|||
'7' -> "#7" |
|||
'8' -> "#8" |
|||
'9' -> "#9" |
|||
_ -> "!" |
|||
|
|||
|
|||
toUnicodeC :: Char -> String |
|||
toUnicodeC = printf "U+%08X" |
|||
|
|||
toUnicode :: String -> String |
|||
toUnicode = concatMap toUnicodeC |
|||
|
|||
convert :: String -> String |
|||
convert s = |
|||
if '!' `elem` toEbcdic s |
|||
then toEbcdic $ toUnicode s |
|||
else toEbcdic s |
|||
|
|||
main :: IO () |
|||
main = interact $ unlines . map (phoneify . chunksof 16 . convert . T.unpack . normalize NFD . T.pack) . lines |
@ -0,0 +1,55 @@ |
|||
#!/usr/bin/env lua |
|||
|
|||
--- Transforms a code into a list of file to stitch |
|||
---@param code string the code to parse |
|||
---@return table |
|||
local function parse(code) |
|||
if type(code) ~= "string" then error("parse expects a string") end |
|||
local filemap = { |
|||
["1"] = "1.wav", |
|||
["2"] = "2.wav", |
|||
["3"] = "3.wav", |
|||
["4"] = "4.wav", |
|||
["5"] = "5.wav", |
|||
["6"] = "6.wav", |
|||
["7"] = "7.wav", |
|||
["8"] = "8.wav", |
|||
["9"] = "9.wav", |
|||
["0"] = "0.wav", |
|||
["*"] = "Star.wav", |
|||
["#"] = "Octothorpe.wav", |
|||
["A"] = "A.wav", |
|||
["B"] = "B.wav", |
|||
["C"] = "C.wav", |
|||
["D"] = "D.wav", |
|||
["-"] = "skip.wav", |
|||
} |
|||
local seq = {} |
|||
for i = 1, #code do |
|||
table.insert(seq, filemap[code:sub(i, i)] or filemap["-"]) |
|||
end |
|||
return seq |
|||
end |
|||
|
|||
|
|||
|
|||
local args = {...} |
|||
|
|||
local i = 1 |
|||
while i <= #args do |
|||
local code = args[i] |
|||
local out = args[i+1] or "out.wav" |
|||
local sequence = parse(code) |
|||
local list = io.open(out .. ".filelist", "w") |
|||
if not list then |
|||
io.stderr:write("Cannot open `" .. out .. ".filelist\n") |
|||
io.stderr:write("Abborting\n") |
|||
os.exit(1) |
|||
end |
|||
for _, v in ipairs(sequence) do |
|||
list:write("file '" .. v .. "'\n") |
|||
end |
|||
list:close() |
|||
os.execute("ffmpeg -f concat -safe 0 -i " .. out .. ".filelist -c copy " .. out) |
|||
i = i + 2 |
|||
end |
Write
Preview
Loading…
Cancel
Save
Reference in new issue