xipd

programming language for audio processing that compiles to PureData
git clone https://git.ce9e.org/xipd.git

commit
a48e0e3be30723d86374323543d298a5c33b6da4
parent
a0335318475750af60e9fe7e6cbaca19e25fb8dc
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2022-08-26 21:26
add README.md

Diffstat

A README.md 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A screenshots/example.png 0
A screenshots/simple.png 0

3 files changed, 136 insertions, 0 deletions


diff --git a/README.md b/README.md

@@ -0,0 +1,136 @@
   -1     1 xipd is a programming language for audio processing that compiles to
   -1     2 [PureData](http://msp.ucsd.edu/Pd_documentation/index.htm).
   -1     3 
   -1     4 ## Example
   -1     5 
   -1     6 ```
   -1     7 include "std.xipd"
   -1     8 
   -1     9 osc(freq) {
   -1    10     osc = `osc~`
   -1    11     freq -> osc
   -1    12     return osc
   -1    13 }
   -1    14 
   -1    15 osc1 = osc(1)
   -1    16 osc2 = osc(osc1 *~ 20 +~ 440)
   -1    17 osc2 -> `dac~`
   -1    18 ```
   -1    19 
   -1    20 ## PureData Primer
   -1    21 
   -1    22 PureData is a graphical programming environment for real-time audio processing.
   -1    23 It consists of *nodes* and *connections*. For example, there could be one
   -1    24 oscillator node, one node for audio output, and a connection between them.
   -1    25 
   -1    26 ![](screenshots/simple.png)
   -1    27 
   -1    28 There are two kinds of connections: *control* connections for sporadic messages
   -1    29 and *signal* connections for continuous streams. Nodes that expect signal
   -1    30 connections are usually suffixed with "~". For example, the `+` node can be
   -1    31 used to add two numbers, but if you want to mix audio streams you have to use
   -1    32 `+~` instead.
   -1    33 
   -1    34 Nodes can have multiple *inlets* and *outlets*. For example, the `+` node has
   -1    35 two inlets. The value of a node is only updated when it receives a message to
   -1    36 its first inlet. The first inlet is therefore referred to as *hot* while the
   -1    37 others are called *cold*.
   -1    38 
   -1    39 PureData comes with a large set of built-in nodes for low-level audio
   -1    40 processing. There is also a large community that shares more high-level
   -1    41 structures.
   -1    42 
   -1    43 ## Goals
   -1    44 
   -1    45 I personally had some issues with PureData, so I tried to wrap it in something
   -1    46 that feels more familiar to me. The result of that attempt is xipd. The goals
   -1    47 are:
   -1    48 
   -1    49 -   **Text-based instead of visual programming language**: This is crucial so
   -1    50     authors can use common tools like vim or git. PureData does have a [text
   -1    51     representation](http://puredata.info/docs/developer/PdFileFormat), but it is
   -1    52     not really meant for humans.
   -1    53 -   **Variables**: In its text representation, PureData references nodes by
   -1    54     index. I want to use human-readable names instead.
   -1    55 -   **Includes**: In order to structure code, I want to be able to split it into
   -1    56     several files.
   -1    57 -   **Functions**: With PureData it is common to copy large sets of nodes.
   -1    58     Instead I want to have functions so that code can be reused in a structured
   -1    59     way.
   -1    60 -   **Inlets are hot by default**: While I understand that cold inlets are a
   -1    61     powerful tool for control flow, I found it to be very unintuitive.
   -1    62 -   **Small language, extensive standard library**: The language itself should be
   -1    63     simple and stable. Over time, a standard library of functions should emerge
   -1    64     that provides useful abstractions.
   -1    65 -   **Intuitive standard library**: I had a hard time adjusting to the built-in
   -1    66     nodes. I still don't really understand some of them, while some features that
   -1    67     I would have expected are missing. I hope that a standard library of
   -1    68     functions can provide a more intuitive set of primitives by wrapping those
   -1    69     builtins.
   -1    70 -   **No loss of features**: xipd should be able to express everything that
   -1    71     PureData can express.
   -1    72 
   -1    73 ## Features
   -1    74 
   -1    75 ### Names
   -1    76 
   -1    77 Names for functions and variables must consist of upper and lower letters,
   -1    78 digits, and underscores. The first character must not be a digit.
   -1    79 
   -1    80 ### Expressions
   -1    81 
   -1    82 An expression always represents a node combined with a default inlet/outlet. If
   -1    83 no inlet/outlet is provided it always defaults to 0. There are many
   -1    84 different types of expressions:
   -1    85 
   -1    86 -   **String**: (e.g. `"foo"`)
   -1    87 -   **Integer**: (e.g. `1`)
   -1    88 -   **Float**: (e.g. `1.0`)
   -1    89 -   **Raw**: a raw PureData object node (e.g. `` `osc~ 440` ``)
   -1    90 -   **Reference**: A variable with an optional explicit inlet/outlet that
   -1    91     overwrites the default one (e.g. `foo:1`)
   -1    92 -   **Function call**: The arguments can be arbitrary expressions (e.g.
   -1    93     ``foo(`osc~`, 15)``)
   -1    94 -   **Operator**: (e.g. `foo:1 * 2 + 15`)
   -1    95 
   -1    96 ### Statements
   -1    97 
   -1    98 Each file is parsed line by line. Empty lines and lines starting with `#` are
   -1    99 ignored, as is leading and trailing whitespace. All other lines must match one
   -1   100 of the following patterns:
   -1   101 
   -1   102 -   **Assignment**: Assign an expression to a name (e.g. `foo = 1`)
   -1   103 -   **Connection**: Create a connection between two nodes. (e.g. ``foo:1 ->
   -1   104     `dac~` ``)
   -1   105 -   **Include**: Include code from another file (e.g. `include "../foo.xirb"`)
   -1   106 -   **Start a function**: (e.g. `foo(a, b) {`)
   -1   107 -   **End a function**: Each function must end with `}`
   -1   108 -   **Return**: Each function must return an expression. This should be the
   -1   109     last statement of the function because no further statements are executed.
   -1   110     (e.g. `return foo:1`)
   -1   111 
   -1   112 ## Low-level language
   -1   113 
   -1   114 By not using functions and operators you can have a low-level language that is
   -1   115 quite close to the PureData text representation:
   -1   116 
   -1   117 ```
   -1   118 X1 = 1
   -1   119 X2 = `osc~`
   -1   120 X3 = 20
   -1   121 X4 = `*~`
   -1   122 X5 = 440
   -1   123 X6 = `+~`
   -1   124 X7 = `osc~`
   -1   125 X8 = `dac~`
   -1   126 X1:0 -> X2:0
   -1   127 X2:0 -> X4:0
   -1   128 X3:0 -> X4:1
   -1   129 X4:0 -> X6:0
   -1   130 X5:0 -> X6:1
   -1   131 X6:0 -> X7:0
   -1   132 X7:0 -> X8:0
   -1   133 ```
   -1   134 
   -1   135 ![](screenshots/example.png)
   -1   136 

diff --git a/screenshots/example.png b/screenshots/example.png

Binary files differ.

diff --git a/screenshots/simple.png b/screenshots/simple.png

Binary files differ.