knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%", eval = FALSE )
{noon} allows to watch for incoming MIDI events from R.
Because why not.
You'll need a running installation of NodeJS, that you can get from nodejs.org.
Then, the package can be installed with:
remotes::install_github("ColinFay/noon")
After install, you'll need to run one time noon_npm_install() to set up all the Node dependencies.
This will ask you if you're OK with doing that installation.
library(noon) noon_npm_install()
midi_list()List all the available midi interfaces:
midi_list()
midi_all()midi_all() will launch a process that checks every n seconds (default 0.5) if a new midi event has been received on all the midi interface.
It takes a function defining what to do with the message (note it's received in JSON).
By default, R will cat() the output.
midi_all()
This function takes the following arguments:
The message is received with the following format:
{"input":"microKONTROL PORT A","event":"cc","msg":{"channel":4,"controller":13,"value":127,"_type":"cc"}}
midi_close_all()Don't forget to midi_close_all(), if you don't want to watch on MIDI inputs anymore.
midi_close_all()
midi_one_event()This function will listen to one event type only (all interfaces)
midi_one_event(event = "cc")
This function takes the following arguments:
midi_one_interface()This function will listen to one interface type only (all events)
midi_one_interface(interface = "microKONTROL PORT A")
This function takes the following arguments:
midi_list().midi_one_event_one_interface()This function will listen to one event on one interface
midi_one_event_one_interface(event = "cc", interface = "microKONTROL PORT A")
midi_list().callback argumentEach function takes a callback parameter, which define the logic to handle the message (received as a JSON string) under the following format:
{"input":"microKONTROL PORT A","event":"cc","msg":{"channel":4,"controller":13,"value":127,"_type":"cc"}}
Important note: given that the functions checks the for MIDI midi on a recursive basis (i.e every
nseconds), it's possible that at some point R receives more than one JSON strings in a row, for example if you 'noteon' and 'noteoff' very quickly. Thecallbackwill then belapply-ed on all the inputs.
handle <- function(x){ print(jsonlite::fromJSON(x)) } midi_all(callback = handle)
Note that it can also be written as a formula, following {rlang} syntax.
midi_all(callback = ~ print(jsonlite::fromJSON(.x)))
callback exampleload_all() on a button pressload_all <- function(x){ x <- jsonlite::fromJSON(x) # listen on event 16 and only on press (value 127) if (x$msg$controller == 16 && x$msg$value == 127){ cli::cat_line("Reloading the package") pkgload::load_all() } } midi_all(callback = load_all)
ggplot() on a button presslibrary(ggplot2) ggplotit <- function(x){ x <- jsonlite::fromJSON(x) if (x$msg$controller == 15 && x$msg$value == 127){ gg <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) + geom_point() print(gg) } } midi_all(callback = ggplotit)
handle <- function(x){ x <- jsonlite::fromJSON(x) if (x$msg$controller == 11 && x$msg$value == 127){ cli::cat_line("Opening README") rstudioapi::navigateToFile("README.Rmd") } if (x$msg$controller == 12 && x$msg$value == 127){ cli::cat_line("Opening DESCRIPTION") rstudioapi::navigateToFile("DESCRIPTION") } if (x$msg$controller == 13 && x$msg$value == 127){ cli::cat_line("Testing") devtools::test() } if (x$msg$controller == 14 && x$msg$value == 127){ cli::cat_line("Checking") devtools::check() } if (x$msg$controller == 15 && x$msg$value == 127){ cli::cat_line("Document") devtools::document() } if (x$msg$controller == 16 && x$msg$value == 127){ cli::cat_line("Reloading the package") pkgload::load_all() } } midi_all(callback = handle)
{beepr}library(beepr) handle <- function(x){ x <- jsonlite::fromJSON(x) cli::cat_rule(x$msg$note) note <- switch( as.character(x$msg$note), "60" = 1, "61" = 2, "62" = 3, "63" = 4, "64" = 5, "65" = 6, "66" = 7, "67" = 8, "68" = 9, "69" = 10, "70" = 11 ) beep(note) } midi_one_event(event = "noteon", callback = handle, n = 0)
library(audio) handle <- function(x){ x <- jsonlite::fromJSON(x) cli::cat_rule(x$msg$note) note <- switch( as.character(x$msg$note), "60" = system.file("samples/C5.wav", package = "noon"), "61" = system.file("samples/C#5.wav", package = "noon"), "62" = system.file("samples/D5.wav", package = "noon"), "63" = system.file("samples/D#5.wav", package = "noon"), "64" = system.file("samples/E5.wav", package = "noon"), "65" = system.file("samples/F5.wav", package = "noon"), "66" = system.file("samples/F#5.wav", package = "noon"), "67" = system.file("samples/G5.wav", package = "noon"), "68" = system.file("samples/G#5.wav", package = "noon"), "69" = system.file("samples/A5.wav", package = "noon"), "70" = system.file("samples/A#5.wav", package = "noon"), "71" = system.file("samples/B5.wav", package = "noon") ) if (file.exists(note)){ withr::with_environment( .GlobalEnv, { x <- load.wave(note) play(x, rate = 44100 / 2) } ) } } midi_one_event(event = "noteon", callback = handle, n = 0)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.