{"id":22293570,"url":"https://github.com/xi/xipd","last_synced_at":"2026-07-04T22:31:37.201Z","repository":{"id":150048496,"uuid":"529409723","full_name":"xi/xipd","owner":"xi","description":"programming language for audio processing that compiles to PureData","archived":false,"fork":false,"pushed_at":"2024-08-09T14:08:27.000Z","size":30,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-27T01:27:29.808Z","etag":null,"topics":["audio-processing","puredata"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-26T21:29:14.000Z","updated_at":"2024-08-09T14:08:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"f4daa1e7-019a-4f84-b308-02ff794bfade","html_url":"https://github.com/xi/xipd","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/xi/xipd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xi%2Fxipd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xi%2Fxipd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xi%2Fxipd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xi%2Fxipd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xi","download_url":"https://codeload.github.com/xi/xipd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xi%2Fxipd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35138074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-processing","puredata"],"created_at":"2024-12-03T17:29:41.882Z","updated_at":"2026-07-04T22:31:37.159Z","avatar_url":"https://github.com/xi.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"xipd is a programming language for audio processing that compiles to\n[PureData](http://msp.ucsd.edu/Pd_documentation/index.htm).\n\n## Example\n\n```\ninclude \"std.xipd\"\n\nosc(freq) {\n    osc = `osc~`\n    freq -\u003e osc\n    return osc\n}\n\nosc1 = osc(1)\nosc2 = osc(osc1 *~ 20 +~ 440)\nosc2 -\u003e `dac~`\n```\n\n## PureData Primer\n\nPureData is a graphical programming environment for real-time audio processing.\nIt consists of *nodes* and *connections*. For example, there could be one\noscillator node, one node for audio output, and a connection between them.\n\n![](screenshots/simple.png)\n\nThere are two kinds of connections: *control* connections for sporadic messages\nand *signal* connections for continuous streams. Nodes that expect signal\nconnections are usually suffixed with \"~\". For example, the `+` node can be\nused to add two numbers, but if you want to mix audio streams you have to use\n`+~` instead.\n\nNodes can have multiple *inlets* and *outlets*. For example, the `+` node has\ntwo inlets. The value of a node is only updated when it receives a message to\nits first inlet. The first inlet is therefore referred to as *hot* while the\nothers are called *cold*.\n\nPureData comes with a large set of built-in nodes for low-level audio\nprocessing. There is also a large community that shares more high-level\nstructures.\n\n## Goals\n\nI personally had some issues with PureData, so I tried to wrap it in something\nthat feels more familiar to me. The result of that attempt is xipd. The goals\nare:\n\n-   **Text-based instead of visual programming language**: This is crucial so\n    authors can use common tools like vim or git. PureData does have a [text\n    representation](http://puredata.info/docs/developer/PdFileFormat), but it is\n    not really meant for humans.\n-   **Variables**: In its text representation, PureData references nodes by\n    index. I want to use human-readable names instead.\n-   **Includes**: In order to structure code, I want to be able to split it into\n    several files.\n-   **Functions**: With PureData it is common to copy large sets of nodes.\n    Instead I want to have functions so that code can be reused in a structured\n    way.\n-   **Inlets are hot by default**: While I understand that cold inlets are a\n    powerful tool for control flow, I found it to be very unintuitive.\n-   **Small language, extensive standard library**: The language itself should be\n    simple and stable. Over time, a standard library of functions should emerge\n    that provides useful abstractions.\n-   **Intuitive standard library**: I had a hard time adjusting to the built-in\n    nodes. I still don't really understand some of them, while some features that\n    I would have expected are missing. I hope that a standard library of\n    functions can provide a more intuitive set of primitives by wrapping those\n    builtins.\n-   **No loss of features**: xipd should be able to express everything that\n    PureData can express.\n\n## Features\n\n### Names\n\nNames for functions and variables must consist of upper and lower letters,\ndigits, and underscores. The first character must not be a digit.\n\n### Expressions\n\nAn expression always represents a node combined with a default inlet/outlet. If\nno inlet/outlet is provided it always defaults to 0. There are many\ndifferent types of expressions:\n\n-   **String**: (e.g. `\"foo\"`)\n-   **Integer**: (e.g. `1`)\n-   **Float**: (e.g. `1.0`)\n-   **Raw**: a raw PureData object node (e.g. `` `osc~ 440` ``)\n-   **Reference**: A variable with an optional explicit inlet/outlet that\n    overwrites the default one (e.g. `foo:1`)\n-   **Function call**: The arguments can be arbitrary expressions (e.g.\n    ``foo(`osc~`, 15)``)\n-   **Operator**: (e.g. `foo:1 * 2 + 15`)\n\n### Statements\n\nEach file is parsed line by line. Empty lines and lines starting with `#` are\nignored, as is leading and trailing whitespace. All other lines must match one\nof the following patterns:\n\n-   **Assignment**: Assign an expression to a name (e.g. `foo = 1`)\n-   **Connection**: Create a connection between two nodes. (e.g. ``foo:1 -\u003e\n    `dac~` ``)\n-   **Include**: Include code from another file (e.g. `include \"../foo.xipd\"`)\n-   **Array**: Create a named array that can store data, e.g. samples (e.g.\n    `array \"mysample\"`)\n-   **Start a function**: (e.g. `foo(a, b) {`)\n-   **End a function**: Each function must end with `}`\n-   **Return**: Each function must return an expression. This should be the\n    last statement of the function because no further statements are executed.\n    (e.g. `return foo:1`)\n-   **Expression**: Sometimes it is useful to have expressions (especially\n    function calls) without assigning them to a name, just for their side\n    effects.\n\n## Low-level language\n\nBy not using functions and operators you can have a low-level language that is\nquite close to the PureData text representation:\n\n```\nX1 = 1\nX2 = `osc~`\nX3 = 20\nX4 = `*~`\nX5 = 440\nX6 = `+~`\nX7 = `osc~`\nX8 = `dac~`\nX1:0 -\u003e X2:0\nX2:0 -\u003e X4:0\nX3:0 -\u003e X4:1\nX4:0 -\u003e X6:0\nX5:0 -\u003e X6:1\nX6:0 -\u003e X7:0\nX7:0 -\u003e X8:0\n```\n\n![](screenshots/example.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxi%2Fxipd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxi%2Fxipd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxi%2Fxipd/lists"}