{"id":20020507,"url":"https://github.com/shakfu/chuck-max","last_synced_at":"2025-05-05T01:30:45.569Z","repository":{"id":169485424,"uuid":"644239393","full_name":"shakfu/chuck-max","owner":"shakfu","description":"Embedding ChucK in a Max/MSP external.","archived":false,"fork":false,"pushed_at":"2025-04-11T12:35:09.000Z","size":33341,"stargazers_count":18,"open_issues_count":3,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-11T14:13:04.763Z","etag":null,"topics":["audio","chuck","dsp","faust","maxmsp"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shakfu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2023-05-23T05:41:39.000Z","updated_at":"2025-04-11T12:35:13.000Z","dependencies_parsed_at":"2024-04-16T07:36:26.712Z","dependency_job_id":null,"html_url":"https://github.com/shakfu/chuck-max","commit_stats":null,"previous_names":["shakfu/chuck-max"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fchuck-max","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fchuck-max/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fchuck-max/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shakfu%2Fchuck-max/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shakfu","download_url":"https://codeload.github.com/shakfu/chuck-max/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252422921,"owners_count":21745515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","chuck","dsp","faust","maxmsp"],"created_at":"2024-11-13T08:32:39.393Z","updated_at":"2025-05-05T01:30:40.533Z","avatar_url":"https://github.com/shakfu.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chuck-max\n\n![chuck~ help](https://github.com/shakfu/chuck-max/blob/main/media/screenshot-min.png)\n\nA project which embeds the [ChucK](https://chuck.stanford.edu) 1.5.4.2-dev (chai) engine in a Max/MSP external.\n\nThis repository is itself a Max package which includes one external (`chuck~`) with the following features and limitations:\n\n- Generate and process audio by running chuck files and evaluating chuck code with `global` parameters controlled and adjusted in realtime by Max messages.\n\n- Layer sounds from a single instance by running multiple chuck files concurrently.\n\n- Add, remove, replace audio and audio processes on the fly using chuck messages via Max messages.\n\n- Interact with Max via MIDI and OSC protocols.\n\nThe package also includes the following:\n\n- The complete set of current chuck examples\n\n- Most of the [base CCRMA chugins](https://github.com/ccrma/chugins) including `WarpBuf` and `Fauck` or `Faust` except for `Fluidsynth` and `Ladspa`.\n\n- Many Max patchers to test and demonstrate usage.\n\n- Contributed patchers and code examples.\n\n*For the impatient*: download the `chuck-max` package with pre-compiled externals and chugins from the the project's [Releases](https://github.com/shakfu/chuck-max/releases) section and check out the [cheatsheat](https://github.com/shakfu/chuck-max/blob/main/media/chuck-max-cheatsheat.pdf).\n\nNote that `chuck-max` has a sibling in the [pd-chuck](https://github.com/shakfu/pd-chuck) project.\n\n## Overview\n\n- The `chuck~` object can take the following arguments:\n\n  - `[chuck~]` : single channel in/out, no default chuck file\n  - `[chuck~ \u003cN\u003e]` : N channel in/out, no default chuck file\n  - `[chuck~ \u003cfilename\u003e]` : single channel in/out with default chuck file\n  - `[chuck~ \u003cN\u003e \u003cfilename\u003e]` : N channels with default chuck file\n\nIt's recommended to choose 2 channels for stereo audio. \n\nIf a `\u003cfilename\u003e` argument is given it will be searched for according to the following rules:\n\n1. Assume it's an absolute path, use it if it exists.\n\n2. Assume that it's a partial path with the package's `examples` folder as a prefix. So if `stk/flute.ck` is given as `\u003cfilename\u003e`, the absolute path of the package `examples` folder is prepended to it and if the resulting path exists, it is used.\n\n3. Assume `\u003cfilename\u003e` exists in the parent patcher's directory. Test that this is the case and if it is, use it. This is useful if you want to package patchers and chuck files together.\n\n4. Use Max's `locatefile_extended` search function to search for the `\u003cfilename\u003e` in the Max search path. The first successul result will be used.\n\n### Core Messages\n\nAs of the current version, `chuck~` implements the core Chuck vm messages as Max messages:\n\n| Action                            | Max msg                      | Max msg (alias)              |\n| :-------------------------------- | :--------------------------- | :--------------------------  |\n| Add shred from file               | `add \u003cfile\u003e [arg1 arg2 .. ]` | `+ \u003cfilepath\u003e [args]`        |\n| Run chuck file (save last used)   | `run \u003cfile\u003e`                 |                              |\n| Eval code as shred                | `eval \u003ccode\u003e`                |                              |\n| Remove shred                      | `remove \u003cshredID\u003e`           | `- \u003cshredID\u003e`                |\n| Remove last shred                 | `remove last`                |                              |\n| Remove all shreds                 | `remove all`                 |                              |\n| Replace shred                     | `replace \u003cshredID\u003e \u003cfile\u003e`   | `= \u003cshredID\u003e \u003cfile\u003e`         |\n| List running shreds               | `status`                     |                              |\n| Clear vm                          | `clear vm`                   | `reset`                      |\n| Clear globals                     | `clear globals`              |                              |\n| Reset id                          | `reset id`                   |                              |\n| Time                              | `time`                       |                              |\n\nIt's worth reading the [ChucK Language Specification's section on Concurrency and Shreds](https://chuck.cs.princeton.edu/doc/language/spork.html) to get a sense of what the above means. The first paragraph will be quoted here since it's quite informative:\n\n\u003e ChucK is able to run many processes concurrently (the process behave as if they are running in parallel). A ChucKian process is called a shred. To spork a shred means creating and adding a new process to the virtual machine. Shreds may be sporked from a variety of places, and may themselves spork new shreds.\n\n### Utility Messages\n\nThe core set of chuck vm messesages is also extended in `chuck-max` with the following utility messages:\n\n| Action                                  | Max msg                      |\n| :-------------------------------------- | :--------------------------- |\n| Set file attribute (does not run)       | `file \u003cpath\u003e`                |\n| Set full path to editor attribute       | `editor \u003cpath\u003e`              |\n| Prevent running shreds when dsp is off  | `run_needs_audio`            |\n| Open file in external editor            | `edit \u003cpath\u003e`                |\n| Probe chugins                           | `chugins`                    |\n| Get/set loglevel (0-10)                 | `loglevel` \u0026 `loglevel \u003cn\u003e`  |\n| Get state of chuck vm                   | `vm`                         |\n| Launch chuck docs in a browser          | `docs`                       |\n| Clear Max console                       | `clear console`              |\n\n### Parameter Messages\n\nOnce a shred is running you can change its parameters by sending values from Max to the `chuck~` object. To this end, ChucK makes available three mechanisms: global variables, global events, and callbacks which are triggered by events. `chuck~` maps these chuck language elements to corresponding Max/MSP constructs as per the following table:\n\n| Action                            | ChucK              | Max msg                      |\n| :-------------------------------- | :----------------  | :--------------------------  |\n| Change param value (untyped)      | global variable    | `\u003cname\u003e` `\u003cvalue\u003e`           |\n| Dump global variables to console  | global variable    | `globals`                    |\n| Trigger named event               | global event       | `sig \u003cname\u003e`                 |\n| Trigger named event all shreds    | global event       | `broadcast \u003cname\u003e`           |\n\nYou change a global variable by sending a `\u003cvariable-name\u003e \u003cvalue\u003e` message to a `chuck~` instance where the `value` can be an `int`, `float`, `string`, `array of ints` or `floats`, etc. You can also trigger events by sending `sig` or signal messages, `broadcast` messages as per the above table.\n\n*Note*: You can't use the ChucK types of `dur` or `time` in Max. Also, while in the above case, the Max msg seems untyped, it must match the type of the chuck global variable. So if you connect a Max number or flownum object to a message box, it needs to match the type of the global variable (int/float).\n\nSee `help/chuck~.maxhelp` and patchers in the `patchers/tests` directory for a demonstration of current features.\n\n### Parameter Messages using Callbacks (Advanced Usage)\n\nIn addition to the typical way of changing parameters there is also an extensive callback system which includes listening / stop-listening for events associated with callbacks, triggering them via `sig` and `broadcast` messages and also setting typed global variables via messages and symmetrically getting their values via typed callbacks:\n\n| Action                            | ChucK              | Max msg                              |\n| :-------------------------------- | :----------------  | :----------------------------------- |\n| Listen to event (one shot)        | global event       | `listen \u003cname\u003e` or `listen \u003cname\u003e 0` |\n| Listen to event (forever)         | global event       | `listen \u003cname\u003e 1`                    |\n| Stop listening to event           | global event       | `unlisten \u003cname\u003e`                    |\n| Trigger named callback            | global event       | `sig \u003cname\u003e`                         |\n| Trigger named callback all shreds | global event       | `broadcast \u003cname\u003e`                   |\n| Get int variable                  | global variable    | `get int \u003cname\u003e`                     |\n| Get float variable                | global variable    | `get float \u003cname\u003e`                   |\n| Get string variable               | global variable    | `get string \u003cname\u003e`                  |\n| Get int array                     | global variable    | `get int[] \u003cname\u003e`                   |\n| Get float array                   | global variable    | `get float[] \u003cname\u003e`                 |\n| Get int array indexed value       | global variable    | `get int[i] \u003cname\u003e \u003cindex\u003e`          |\n| Get float array indexed value     | global variable    | `get float[i] \u003cname\u003e \u003cindex\u003e`        |\n| Get int associative array value   | global variable    | `get int[k] \u003cname\u003e \u003ckey\u003e`            |\n| Get float associative array value | global variable    | `get float[k] \u003cname\u003e \u003ckey\u003e`          |\n| Set int variable                  | global variable    | `set int \u003cname\u003e \u003cvalue\u003e`             |\n| Set float variable                | global variable    | `set float \u003cname\u003e \u003cvalue\u003e`           |\n| Set string variable               | global variable    | `set string \u003cname\u003e \u003cvalue\u003e`          |\n| Set int array                     | global variable    | `set int[] \u003cname\u003e v1, v2, ..`        |\n| Set float array                   | global variable    | `set float[] \u003cname\u003e v1, v2, ..`      |\n| Set int array indexed value       | global variable    | `set int[i] \u003cname\u003e \u003cindex\u003e \u003cvalue\u003e`  |\n| Set float array indexed value     | global variable    | `set float[i] \u003cname\u003e \u003cindex\u003e \u003cvalue\u003e`|\n| Set int associative array value   | global variable    | `set int[k] \u003cname\u003e \u003ckey\u003e \u003cvalue\u003e`    |\n| Set float associative array value | global variable    | `set float[k] \u003cname\u003e \u003ckey\u003e \u003cvalue\u003e`  |\n\n## Build Requirements and Options\n\nPlease note that this external is currently only developed and tested on macOS, although a Windows version is on the TODO list (any help on this front would be much appreciated).\n\nA number of build variants have been made available to address platform-specific changes and library compatibility issues and also to provide for different levels of usage.\n\nThe following matrix shows feature coverage and also differences in compatibility among the different macOS versions:\n\n| feature/variant     | native | universal | brew | full | nomp3 | light |\n| :--------------     | :----: | :-------: | :--: | :--: | :---: | :---: |\n| External            | x      | x         | x    | x    | x     | x     |\n| Base chugins        | x      | x         | x    | x    | x     | x     |\n| Faust.chug          |        |           | x    | x    | x     | x     |\n| WarpBuf.chug        |        |           | x    | x    | x     | x     |\n| FluidSynth.chug     |        |           | x    |      |       |       |\n| .wav                | x      | x         | x    | x    | x     | x     |\n| .mp3                |        |           | x    | x    |       |       |\n| .flac               |        |           | x    | x    | x     |       |\n| .ogg                |        |           | x    | x    | x     |       |\n| .opus               |        |           | x    | x    | x     |       |\n| .vorbis             |        |           | x    | x    | x     |       |\n| macOS 15 (Sequoia)  | x      | x         | x    | x    | x     | x     |\n| macOS 14 (Sonoma)   | x      | x         | x    | x    | x     | x     |\n| macOS 13 (Ventura)  | x      | x         | x    | x    | x     | x     |\n| macOS 12 (Monterey) | x      | x         | x    | x    | x     | x     |\n| macOS 11 (Big Sur)  | x      | x         |      | x    | x     | x     |\n\n### A. The Base System\n\nThe base `chuck-max` system consists of a Max package with the `chuck~` external, the base [CCRMA chugins](https://github.com/ccrma/chugins) and extensive examples, tests and Max patchers.\n\nBuilding it requires the following to be available on your machine:\n\n1. Xcode from the App store or Xcode Command Line Tools via `xcode-select –install`\n\n2. cmake\n\n3. bison\n\n4. flex\n\nThe last three can be installed using [Homebrew](https://brew.sh) as follows:\n\n```bash\nbrew install cmake bison flex\n```\n\nThe buildsystem consists of a minimal Makefile frontend with CMake driving the build on the backend.\n\nTo get up and running:\n\n```bash\ngit clone https://github.com/shakfu/chuck-max.git\ncd chuck-max\nmake setup\n```\n\nNote that `make setup` does two things: (1) retrieves `max-sdk-base` as a git submodule and makes the package and its contents available to be used by Max by creating a symlink of the `chuck-max` folder in `$HOME/Documents/Max 8/Packages`.\n\nNow it should be possible to build the base system with either of the following two options:\n\n- `make` or `make native`: builds the external using your machine's native architecture which is `arm64` for Apple Silicon Macs and `x86_64` for Intel Macs. This is the default build option.\n\n- `make universal`: build the external as a `universal` binary making it compatible with both Mac architectural variants. This is useful if you want share the external with others in a custom Max package or standalone.\n\n### B. The Advanced System\n\nThe advanced system consists of the base system + two advanced chugins, `Faust.chug` and `WarpBuf.chug`:\n\n1. The [Fauck](https://github.com/ccrma/fauck) chugin contains the full llvm-based [faust](https://faust.grame.fr) engine and dsp platform which makes it quite powerful and also quite large compared to other chugins (at around 45 MB stripped down). It requires at least 2 output channels to work properly. It also uses the [libsndfile](https://github.com/libsndfile/libsndfile) library.\n\n2. The [WarpBuf](https://github.com/ccrma/chugins/tree/main/WarpBuf) chugin makes it possible to time-stretch and independently transpose the pitch of an audio file. It uses the [rubberband](https://github.com/breakfastquay/rubberband), [libsndfile](https://github.com/libsndfile/libsndfile), and [libsamplerate](https://github.com/libsndfile/libsamplerate) libraries.\n\nTo build these two chugins, you will need some additional dependencies which can also be installed via `Homebrew` as follows:\n\n```bash\nbrew install autoconf autogen automake flac libogg libtool libvorbis opus mpg123 lame rubberband libsamplerate\n```\n\nAfter these are installed, it should be possible, subject to the compatibility matrix above, to build the advanced system with one of the following options:\n\n- `make brew`: build the external using the previously installed homebrew dependencies, as well as downloaded `faust` headers and a downloaded pre-compiled `libfaust` (`libfaustwithllvm`) library. This is the newer, faster, recommended way of getting a full chuck-max system up and running.\n\n- `make brew2`: preliminary experimental support (currently not working) for building `FluidSynth.chug` is provided with this make target but this requires additional dependencies to be installed via `brew install glib portaudio gettext fluid-synth`\n\n- `make full`: build the external by manually building all of the dependencies except for `libfaust` from source. This is the previous way of building an advanced system. It is currently only for advanced developers who want maximum flexibility in their builds.\n\n- `make nomp3`: same as `make full` except without support for the .mp3 format. Try this variant if you are unable to build using `make full` on Intel Macs or on older macOS versions.\n\n- `make light`: Same as `make full` except for withouth `libsndfile` multi-file format support. This means that (.mp3, flac, vorbis, opus, ogg) formats are not supported in this build. Only `.wav` files can be used.\n\n## Usage\n\nThe `chuck-max` package consists of the following folders:\n\n```text\nchuck-max\n├── examples\n│    ├── ai\n│    ├── analysis\n│    ├── ...\n│    ├── **chugins**\n│    ├── ...\n│    ├── **fauck**\n│    ├── **faust**\n│    ├── ...\n│    ├── **max**\n│    ├── ...\n│    ├── **test**\n│    ├── ...\n│    └── warpbuf\n├── externals\n│    └── chuck~.mxo\n├── help\n├── media\n└── patchers\n    ├── abstractions\n    ├── contrib\n    └── tests\n```\n\nStart with the `chuck~.maxhelp` file in the `help` folder for an overview of the external's features. The `media` folder also has a [pdf cheatsheet](https://github.com/shakfu/chuck-max/blob/main/media/chuck-max-cheatsheat.pdf) of available `chuck~` methods.\n\nThe `examples` directory contains all chuck examples from the chuck repo, and some additional folders: `chugins` containing chugin binaries, `fauck`, containing `faust.chug` examples, `faust`, containing the faust stdlib, `max` chuck files which are used by the max patchers, and `test`, chuck files used by max patcher test files.\n\nIn the `patchers` section, there are quite a few patchers demonstrating one feature or other in the `tests` folder, and the `contrib` folder contains excellents advanced examples of uses by `chuck-max` contributors.\n\n## Known Unresolved Bugs\n\n- If a chuck file contains a custom event and the Max patch sends a `clear vm` or `reset` before running the chuck file while Max audio is turned off, it may cause Max to crash. The case is demonstrated in the `patchers/tests/crash` section. See [github issue #11](https://github.com/shakfu/chuck-max/issues/11) for updates on this. The interim solution is to only run chuck files with Max audio on, and there's an attribute `run_needs_audio` to force this and prevent the crash. Thanks to @HighHarmonics2 for discovering this one.\n\n## Credits\n\nThis project thanks the following:\n\n- Professors GE Wang and Perry Cook and all chuck and chuggin contributors for creating the amazing ChucK language and chuggin ecosystem!\n\n- Professor Perry Cook for co-authoring Chuck and creating the [Synthesis Toolkit](https://github.com/thestk/stk) which is integrated with chuck.\n\n- Professor [Brad Garton](http://sites.music.columbia.edu/brad) for creating the original [chuck~](http://sites.music.columbia.edu/brad/chuck~) external for Max 5. My failure to build it and run it on Max 8 motivated me to start this project.\n\n- David Braun, the author of the very cool and excellent [DawDreamer](https://github.com/DBraun/DawDreamer) project, for creating the excellent [ChucKDesigner](https://github.com/DBraun/ChucKDesigner) project which embeds chuck in a Touch Designer plugin. His project provided a super-clear blueprint on how to embed `libchuck` in another host or plugin system and was essential to this project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshakfu%2Fchuck-max","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshakfu%2Fchuck-max","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshakfu%2Fchuck-max/lists"}