├── .github └── workflows │ └── project.yml ├── .gitignore ├── LICENSE ├── README.md ├── export └── README.md ├── img ├── js-export-location.png ├── use-this-template-button.png └── warner.svg ├── index.html ├── js ├── app.js └── guardrails.js └── style └── style.css /.github/workflows/project.yml: -------------------------------------------------------------------------------- 1 | name: Add Issues and PRs to RNBO Project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | pull_request: 8 | types: 9 | - opened 10 | 11 | jobs: 12 | add-to-project: 13 | name: Add to RNBO Project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/add-to-project@v0.3.0 17 | with: 18 | project-url: https://github.com/orgs/Cycling74/projects/${{ secrets.RNBO_PROJECT_NUMBER }} 19 | github-token: ${{ secrets.RNBO_PROJECT_PAT }} 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | lerna-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # Bower dependency directory (https://bower.io/) 34 | bower_components 35 | 36 | # node-waf configuration 37 | .lock-wscript 38 | 39 | # Compiled binary addons (https://nodejs.org/api/addons.html) 40 | build/Release 41 | 42 | # Dependency directories 43 | node_modules/ 44 | jspm_packages/ 45 | 46 | # TypeScript v1 declaration files 47 | typings/ 48 | 49 | # TypeScript cache 50 | *.tsbuildinfo 51 | 52 | # Optional npm cache directory 53 | .npm 54 | 55 | # Optional eslint cache 56 | .eslintcache 57 | 58 | # Microbundle cache 59 | .rpt2_cache/ 60 | .rts2_cache_cjs/ 61 | .rts2_cache_es/ 62 | .rts2_cache_umd/ 63 | 64 | # Optional REPL history 65 | .node_repl_history 66 | 67 | # Output of 'npm pack' 68 | *.tgz 69 | 70 | # Yarn Integrity file 71 | .yarn-integrity 72 | 73 | # dotenv environment variables file 74 | .env 75 | .env.test 76 | 77 | # parcel-bundler cache (https://parceljs.org/) 78 | .cache 79 | 80 | # Next.js build output 81 | .next 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Ignore exported files 109 | export/*.json 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Cycling '74 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RNBO Webpage Example 2 | 3 | This example shows you how to add dynamic audio to a webpage, using the web export feature of RNBO, part of [Max 8](https://cycling74.com/products/max) made by [Cycling '74](https://cycling74.com). 4 | 5 | This repository uses [Node](https://nodejs.org/en/) to launch a simple web server to make your webpage available locally. For more on why this is necessary, see [Why a local server?](#why-a-local-server) 6 | 7 | ## Prerequisites 8 | 9 | In order to run this example, you'll need `node`, `npm`, and access to the command line. The `npx` binary ships with `node`, so just download and install that from the [Node.js downloads site](https://nodejs.org/en/download/). The recommended version is their latest `LTS`, which at the time of writing this document is version 16. 10 | 11 | If have heard about `node` and `npm` before but would like to know more about the included `npx` Package Runner please refer to the [Node.js Documentation](https://nodejs.dev/learn/the-npx-nodejs-package-runner). 12 | 13 | ## File structure 14 | 15 | The source code of the web application is in the `js/` directory. This directory contains the file `app.js`, which does all the work of loading and connecting your RNBO patch. There is also a file `guardrails.js`, which simply tries to provide some clear feedback if you're not running this example in the intended way. 16 | 17 | Some notable files/directories: 18 | 19 | | Location | Explanation | 20 | | --------------------------------- | ------------- | 21 | | export/ | The directory into which you should export your RNBO code | 22 | | js/ | Source for the project, edit it however you like | 23 | | index.html | The web page itself | 24 | 25 | ## Using this Template 26 | 27 | This Github repo is a template, which means you can use it to start your own git-based project using this repository as a starting point. The major difference between a template and a fork is that your new project won't include the commit history of this template--it will be an entirely new starting point. For more see [the official description](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template). 28 | 29 | ### Getting Started 30 | 31 | To get started, first create a new repository to hold your project using this repository as a template. If you're viewing this repo on Github, you should see a button at the top of the page that says `Use this template`. 32 | 33 | ![Use this template button](./img/use-this-template-button.png) 34 | 35 | You can also follow [the official steps](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) on Github for creating a new repository from a template. 36 | 37 | Now you need to copy this repository locally. Follow [the official steps](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) to clone your repository. 38 | 39 | ### Working with RNBO 40 | 41 | Next, open the RNBO patcher you'd like to work with, and navigate to the export sidebar. Find the "Web Export" target. 42 | 43 | ![Web export in the sidebar](./img/js-export-location.png) 44 | 45 | Export your project, making sure to export into the `export` folder in your repository directory. Your export directory should look something like this: 46 | 47 | ``` 48 | export/ 49 | ├─ patch.export.json 50 | ├─ README.md 51 | ``` 52 | 53 | Whenever you make a change to your RNBO patch, remember to export the source code again to update this file. Now that you've exported your RNBO code, we're ready to open the webpage. From the repository root, run the following command to start the local web server 54 | 55 | ```sh 56 | npx http-server 57 | ``` 58 | 59 | When asked to install the `http-server` in order to proceed simply agree by using `y`. You will only have to agree on that once. 60 | Once the server started up successfully you may see something like the following in the console: 61 | 62 | ```sh 63 | Available on: 64 | http://127.0.0.1:8080 65 | http://192.168.88.139:8080 66 | Hit CTRL-C to stop the server 67 | ``` 68 | Open the shown URL, fe. `http://127.0.0.1:8080` in your default browser, if everything went well, you should see and hear your RNBO patch. 69 | 70 | ### Exporting a new patch 71 | 72 | This example looks in the `export` directory for a patch named `patch.export.json`. If you change the name of your export to something other than `patch.export.json`, you'll need to change the JavaScript as well. In `js/app.js`, the line: 73 | 74 | ```js 75 | const patchExportURL = "export/patch.export.json"; 76 | ``` 77 | 78 | can be changed to reflect the name of your export. 79 | 80 | ## Troubleshooting 81 | 82 | ### Why don't I see anything? 83 | 84 | First, check your developer console. On MacOS, you can bring this up in most browsers by pressing Command-Option-I on a Mac. Firefox puts developer tools under Tools > Browser Tools > Web Developer Tools. Other browsers may put this feature somewhere else, so check the documentation for your browser of choice. The important thing to do here is to make sure you don't see any error. If you see something in red, read the message carefully. 85 | 86 | ### Something doesn't seem to be working right 87 | 88 | It might be that the version of RNBO that you used to export your patch doesn't match the version of the RNBO library that `index.html` is downloading. Look for a message in the developer console talking about mismatched versions. To fix this, either export a version of your patch using a more up-to-date version of RNBO, or else change the `script` tags in `index.html` to download a different version of the RNBO libraries. 89 | 90 | ### My samples aren't loading correctly 91 | 92 | Again check the developer console, this time looking for error messages about a failure to decode audio data. Some browsers, like Chrome for example, don't support decoding `.aif` files. So if you're using `anton.aif` as a sample dependency, you should export again using `anton.wav`. Or maybe find another sample to use. 93 | 94 | ### Why isn't my patch changing in the browser? 95 | 96 | If you changed your exported patch in the `export` folder but your patch isn't changing in the browser, you might need to hard refresh the page (cmd+shift+R). This clears the cache to account for any changes to the page being served. 97 | 98 | ## Why a local server? 99 | We're recreating on a very small scale what happens whenever you load a website on your computer. When you run `npx http-server`, a Node process starts. This process binds to a port on your machine, defaulting to port 8080. When your browser tries to access the website `http://localhost:8080`, it connects to the server and tries to get the content for the given path, which is `/`. Given this path, the server returns the contents of the file `index.html`, which is what you see when you load the page. 100 | 101 | As part of loading that page, your web browser also asks the server for the JavaScript file at `js/app.js`. When the browser executes this script, it makes yet another request to fetch the file at the path `export/patch.export.json`. Finally, the script can use this exported patch to create a RNBO JavaScript object and connect it to the audio graph in the current page. 102 | 103 | The important takeaway here is that this is the kind of interaction that your browser is expecting: making HTTP and HTTPS requests to fetch resources from a remote server. It's technically possible to simply double-click on the `index.html` file and to load the page using the `file:` protocol instead of `http:` or `https:`. However, for security reasons this will block access to `WebAssembly` or `AudioWorklets`, which will keep our exported RNBO patch from working the way we want. Running a local server lets the browser treat the webpage as if it were pulled from the internet like any other page. 104 | 105 | The other reason that we run a server this way is because this brings us much closer to putting our RNBO patch on the publically accessible internet. If you want to build a public website containing a RNBO patch, it's helpful to keep this simple example in mind when you think about what resources to put where. 106 | 107 | ## Customizing your web page 108 | 109 | From this point, the sky is the limit. You can do anything and everything to your web page, adding custom graphics and interaction in whatever way you like. A full discussion of web programming is beyond the scope of this README, but some useful reading material would include: 110 | 111 | - [ReactJS](https://reactjs.org/) 112 | - [p5JS](https://p5js.org/) 113 | - [Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial) 114 | - [Netlify](https://www.netlify.com/) 115 | -------------------------------------------------------------------------------- /export/README.md: -------------------------------------------------------------------------------- 1 | Export your RNBO code into this directory. -------------------------------------------------------------------------------- /img/js-export-location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cycling74/rnbo.example.webpage/40c8874c9304f672655a9324c838f907a881da5d/img/js-export-location.png -------------------------------------------------------------------------------- /img/use-this-template-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cycling74/rnbo.example.webpage/40c8874c9304f672655a9324c838f907a881da5d/img/use-this-template-button.png -------------------------------------------------------------------------------- /img/warner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | RNBO Web Export 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

Unnamed patcher

18 |
19 |
20 |

MIDI Keyboard

21 | No MIDI input 22 |
23 |
24 |

Inports

25 | No inports available 26 |
27 |
28 | 29 | 30 | 31 |
32 |
33 |
34 |
35 |

Outports

36 | No outports available 37 |
38 |

Waiting for messages...

39 | Check the developer console for more messages from the RNBO device 40 |
41 |
42 |
43 |

Presets

44 | No presets defined 45 | 46 |
47 |
48 |

Parameters

49 | No parameters 50 |
51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | async function setup() { 2 | const patchExportURL = "export/patch.export.json"; 3 | 4 | // Create AudioContext 5 | const WAContext = window.AudioContext || window.webkitAudioContext; 6 | const context = new WAContext(); 7 | 8 | // Create gain node and connect it to audio output 9 | const outputNode = context.createGain(); 10 | outputNode.connect(context.destination); 11 | 12 | // Fetch the exported patcher 13 | let response, patcher; 14 | try { 15 | response = await fetch(patchExportURL); 16 | patcher = await response.json(); 17 | 18 | if (!window.RNBO) { 19 | // Load RNBO script dynamically 20 | // Note that you can skip this by knowing the RNBO version of your patch 21 | // beforehand and just include it using a