{"id":21570399,"url":"https://github.com/arirusso/patch","last_synced_at":"2025-04-10T14:12:50.799Z","repository":{"id":18033193,"uuid":"21072200","full_name":"arirusso/patch","owner":"arirusso","description":"Universal controller message hub","archived":false,"fork":false,"pushed_at":"2015-09-28T23:05:55.000Z","size":972,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T12:56:21.342Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"Ludeon/RimWorld-it","license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arirusso.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}},"created_at":"2014-06-21T15:50:53.000Z","updated_at":"2018-09-01T14:25:27.000Z","dependencies_parsed_at":"2022-08-21T00:50:43.494Z","dependency_job_id":null,"html_url":"https://github.com/arirusso/patch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arirusso%2Fpatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arirusso%2Fpatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arirusso%2Fpatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arirusso%2Fpatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arirusso","download_url":"https://codeload.github.com/arirusso/patch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248232743,"owners_count":21069489,"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":[],"created_at":"2024-11-24T11:12:31.922Z","updated_at":"2025-04-10T14:12:50.778Z","avatar_url":"https://github.com/arirusso.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Patch\n\nPatch is a universal hub for controller messages\n\nThese message protocols are currently supported\n\n* [MIDI](http://en.wikipedia.org/wiki/MIDI)\n* [OSC](http://en.wikipedia.org/wiki/Open_Sound_Control)\n* JSON over [Websocket](http://en.wikipedia.org/wiki/WebSocket)\n\nOther possibilities:\n\n* [HTML5 Server-Sent Events](http://www.w3schools.com/html/html5_serversentevents.asp)\n* HTTP\n* [JSON RPC 2.0](http://en.wikipedia.org/wiki/JSON-RPC)\n\nPatch receives messages in these formats and instantly translates and sends them to others\n\nFor example:\n\nPatch receive messages from an OSC controller, and relays them to a web API. The web API in turn responds with JSON that Patch relays to a MIDI synthesizer\n\nWhile this particular example can probably be accomplished using other specialized utilities or scripts, Patch makes it possible to receive, merge, split and send different types of messages like this in a general way, with much less configuration\n\n## Usage\n\n### Installation\n\nPatch is packaged as a Ruby gem.  \n\nIt can be installed by using `gem install patch` on the command line or by adding `gem \"patch\"` to a project's Gemfile.\n\n### Configuration\n\nConfiguring Patch can be done two ways:\n\n* [In Ruby code](#in-ruby)\n* [Using configuration files](#using-configuration-files)\n\n### In Ruby\n\n```ruby\nrequire \"patch\"\n```\n\nA *node* is a single source and/or destination of control messages. Here, we define three nodes:\n\n```ruby\nwebsocket = Patch::IO::Websocket::Node.new(1, \"localhost\", 9006)\n\nmidi = Patch::IO::MIDI::Input.new(2, \"Apple Inc. IAC Driver\")\n\nosc = Patch::IO::OSC::Server.new(3, 8000)\n```\n\nA *node map* defines where messages should flow to and from.  \n\nIn this example, when our MIDI and OSC nodes receive messages, those messages are then echoed to the Websocket node.\n\n```ruby\nmap = { [midi, osc] =\u003e websocket }\n```\n\nThe message protocols used by Patch have no implicit way to translate between each other.  Therefore *actions* are used to describe how to do that.\n\n```ruby\n\naction = {\n  :name =\u003e \"Zoom\",\n  :key =\u003e \"zoom\",\n  :default =\u003e {\n    :scale =\u003e 10..200.0\n  },\n  :midi =\u003e {\n    :channel =\u003e 0,\n    :index =\u003e 1\n  },\n  :osc =\u003e {\n    :address=\u003e\"/1/rotaryA\",\n    :scale =\u003e 0..1.0\n  }\n}\n```\n\nGiven these example actions,\n\n1. When a MIDI control change message is received on channel 0 with index 1, send a JSON over websocket message with the key `zoom`.  The value of the MIDI message should be scaled to a float between 10 and 200.\n\n2. When an OSC message is received for address `/1/rotaryA`, send a JSON over websocket message with the key `zoom`.  Scale the OSC value, which will be a float between 0 and 1 to a float between 10 and 200.\n\nNow start Patch listening for messages:\n\n```ruby\npatch = Patch::Patch.new(:simple, map, action)\n\nhub = Patch::Hub.new(:patch =\u003e patch)\nhub.listen\n```\n\nThe full example can be found [here](https://github.com/arirusso/patch/blob/master/examples/simple/simple.rb).\n\n### Using Configuration Files\n\nIt's also possible to configure Patch using configuration files.  To do that, two files are necessary:\n\n* [nodes.yml](#nodesyml)\n* [patches.yml](#patchesyml)\n\nThe configuration in these example files is similar to the one in Ruby above.\n\n##### nodes.yml\n\n`nodes.yml` describes what nodes to use and how to configure them.  \n\nIn addition, each node is given an ID number for reference later.\n\n```yaml\n:nodes:\n  - :id: 1\n    :type: websocket\n    :host: localhost\n    :port: 9006\n  - :id: 2\n    :type: midi\n    :direction: input\n    :name: Apple Inc. IAC Driver\n  - :id: 3\n    :type: osc\n    :server:\n      :port: 8000\n    :client:\n      :host: 192.168.1.136\n      :port: 9000\n```\n\n##### patches.yml\n\nNode maps and actions are specified in the second configuration file, `patches.yml`.\n\n```yaml\n:patches:\n  :simple:\n    :node_map:\n      [2, 3]: 1\n    :actions:\n    - :name: Zoom\n      :key: zoom\n      :default:\n        :scale: !ruby/range 10..200.0\n      :midi:\n        :channel: 0\n        :index: 1\n      :osc:\n        :address: /1/rotaryA\n        :scale: !ruby/range 0..1.0\n\n```\n\nThe `patches.yml` file can contain any number of patches, they will all be run concurrently.\n\n### Command Line\n\nYou can run Patch at the command line by executing `patchrb nodes.yml patches.yml`.\n\n## Author\n\n[Ari Russo](http://github.com/arirusso) \u003cari.russo at gmail.com\u003e\n\n## License\n\nApache 2.0, See the file LICENSE\n\nCopyright (c) 2014-2015 [Ari Russo](http://arirusso.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farirusso%2Fpatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farirusso%2Fpatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farirusso%2Fpatch/lists"}