Giter VIP home page Giter VIP logo

node-keyboard's Introduction

node-keyboard

Greenkeeper badge

npm version

A REPL where music is simply streams of input in node. Uses the awesome soundfonts of midi-js-soundfonts. Supports optional MIDI input.

Install via

npm install -g node-keyboard

Note: Installing node-keyboard will clone a soundfont library during install, resulting in an 800MB download.

Run via

node-keyboard

Examples

Inside the REPL, the examples in the example folder are loaded as getters with the prefix example_. E.g. example_01_scales.chromatic({ key: 'b', ms: 100 })

Streaming Functionality tl;dr

MIDI In

Pipe the midiIn stream to a number of writable outputs. (To function, your MIDI device must be on when node starts.)

toAudio will play the notes

midiIn.pipe(toAudio)

toRepl will output the notes in the REPL

midiIn.pipe(toRepl)

toPiano will draw the piano for each note played

midiIn.pipe(toPiano)

toLogger will console log the note (pipe after toAudio to see more information about the played note)

midiIn.pipe(toLogger)

Or pipe them through each other midiIn.pipe(toPiano).pipe(toAudio)

And remove from MIDI input via midiIn.unpipe() (or CTRL+C)

node-keyboard

Create a Stream

Create an [infinite] stream of notes from an array using from (supports notes as variables).

from(c, e, g).pipe(toAudio) // Hit CTRL+C (SIGINT) to unpipe immediately

Note: supports all notes A0 to Cs8/Db8 (Cs8 is the syntax-friendly version of 'C#8')

Delay

Use delay(...args) to return a transform stream that will emit after the given delays (where the delays are cycled)

from(c1, g1, c2, g2, c3, g3).pipe(delay(250, 250, 500)).pipe(toAudio)

With Instrument

Use on(instrument) to return a transform stream that will ensure the given instrument is used.

from(c,e,g).pipe(on('guitar')).pipe(delay(200)).pipe(toAudio)

Note: Breaking via CTRL+C will stop the stream by unpiping everything

Functionality (sans streams)

Functionality, without the streams.

Properties

  • instruments list all instruments available
  • scales list all scales supported

###Side effects

  • play(note) plays a note. Eg.
[c,e,g].forEach(play)
  • piano(note) draws the piano playing that note Eg.
[c,e,g].forEach((note, i) => setTimeout(() => piano(note), 400 * i))
  • log(note) logs the note to stdout. (Includes the instrument if chained after play) Eg.
[f,a,c].map(play).forEach(log)

Projections

  • chord(name) projects a chord name out to an array of notes. Eg.
chord('cm9')
// [ 'c4', 'eb4', 'g4', 'bb4', 'd5' ]
  • scale(note, name) projects a note through the named scale Eg.
scale('a', 'flamenco')
// [ 'a5', 'bb5', 'c#6', 'd6', 'e6', 'f6', 'g#6' ]
  • sequence(note, ...semitones) projects a note through the given semitone sequence Eg.
sequence(c, 2, 1, 2, 2, 1, 2, 2) // c minor scale
// [ 'c3', 'd3', 'eb3', 'f3', 'g3', 'g#3', 'a#3', 'c4' ]

Functors

  • instrument([name]]) returns mapping function to play on instrument. If no parameter provided it chooses a random instrument. Eg.:
[c,e,g].map(instrument('guitar')).forEach(play)
  • interval(...intervals) returns mapping function to project intervals. Eg.
[c,e,g].map(interval('P1','P5')).reduce((acc, cur) => acc.concat(cur), [])
// [ 'c3', 'g3', 'e3', 'b3', 'g3', 'd4' ]
  • only(...numbers) returns filter predicate to filter out to required interval positions. Eg.
scale(c, 'major').filter(only(1,3,5,7)).map(play) // Cmaj7

Plugins

Known Issues

  • Reusing a stream and repiping it through transformers E.g.
let guitar = from(c,e,g).pipe(on('guitar')).pipe(delay(200))
guitar.pipe(toAudio)
// CTRL+C
guitar.pipe(toAudio) // works
// CTRL+C
guitar.pipe(on()).pipe(toAudio) // works first time only
// CTRL+C
guitar.pipe(on()).pipe(toAudio) // won't play the guitar stream's final on() is still piped to the previous on()

More info

I spoke on node-keyboard at EmpireNode in November 2016 image

Changelog

  • (see commit log for earlier releases)
  • 2.5.0 Support for switching instruments
  • 2.5.5 Adding every
  • 2.6.0 Persistent history for the REPL
    • 2.6.1 Adding eslint and ensuring play returns input
  • 2.7.0 Support for MIDI input
  • 2.8.0 Support for notes as first-class objects (Symbol-like)
  • 2.9.0 Support for midi streams: midiIn, toRepl, toAudio and toPiano
  • 3.0.0 Upgraded to stream-first, all stream variables are now factory functions (to reuse). Support for fromArray. Deprecated older array functionality.
  • 3.1.0 Renamed fromArray to from, allow from to continue forever, limited withDelay to have a highWaterMark of 1 and play first immediately, brought in SIGINT support to unpipe streams when CTRL+C pressed
  • 3.2.0 Renamed withDelay to delay. Added toLogger. Added on to play instruments.
  • 3.3.0 Added base functions chord(), scale, functors instrument() anf interval(), and properties instruments and scales. Many bug fixes.
  • 3.4.0 Migrated to using getters for writable streams for brevity
  • 3.5.0 Support for only()
  • 3.6.0 Subscription removal on SIGINT for Rx, support for piano function, support for runInThisContext, and stream getter bugfix
  • 3.7.0 Support for log function, removal of runInThisContext (not necessary)
  • 3.8.0 Errors no longer thrown, just shown. Support for examples
  • 3.9.0 Removed Rx support and turned it into a plugin

FAQ

  1. When no octave is provided (e.g. play(a)) then 3rd octave (a3 220Hz) (starting at c3 on an 8-octave piano) is the default.

  2. a0, bb0 (a#0) and b0 are the only notes below c1

  3. Sharp can be denoated by s when not surrounding note by strings (i.e. as4 ==== 'a#4'). Double-sharp is denoted with x as in ax3 (enharmonically b3). Double-flat is denoted with bb as in bbb3 (enharmonically a3)

Acknowledgements

node-keyboard's People

Contributors

greenkeeper[bot] avatar jjgonecrypto avatar winniehell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

node-keyboard's Issues

Soundfonts doesn't install

As such, the software cannot start. Error message:

PS C:\Users\Admin> node-keyboard
fs.js:870
  return binding.readdir(pathModule._makeLong(path), options.encoding);
                 ^

Error: ENOENT: no such file or directory, scandir 'C:\Users\Admin\AppData\Roaming\npm\node_modules\node-keyboard\midi-js
-soundfonts\FluidR3_GM'
    at Object.fs.readdirSync (fs.js:870:18)
    at Object.get all (C:\Users\Admin\AppData\Roaming\npm\node_modules\node-keyboard\lib\instruments.js:14:26)
    at Object.<anonymous> (C:\Users\Admin\AppData\Roaming\npm\node_modules\node-keyboard\lib\mappers.js:48:34)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
PS C:\Users\Admin>

Cannot install on ubuntu 16.04

Seems to not compile the native addon properly.

$ npm install -g node-keyboard
/home/aaron/.npm-global/bin/node-keyboard -> /home/aaron/.npm-global/lib/node_modules/node-keyboard/bin/cli.js

> [email protected] install /home/aaron/.npm-global/lib/node_modules/node-keyboard/node_modules/midi
> node-gyp rebuild

make: Entering directory '/home/aaron/.npm-global/lib/node_modules/node-keyboard/node_modules/midi/build'
  CXX(target) Release/obj.target/midi/src/node-midi.o
In file included from ../src/node-midi.cpp:6:0:
../src/lib/RtMidi/RtMidi.cpp:1095:28: fatal error: alsa/asoundlib.h: No such file or directory
compilation terminated.
midi.target.mk:97: recipe for target 'Release/obj.target/midi/src/node-midi.o' failed
make: *** [Release/obj.target/midi/src/node-midi.o] Error 1
make: Leaving directory '/home/aaron/.npm-global/lib/node_modules/node-keyboard/node_modules/midi/build'
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:258:23)
gyp ERR! stack     at emitTwo (events.js:126:13)
gyp ERR! stack     at ChildProcess.emit (events.js:214:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
gyp ERR! System Linux 4.13.0-41-generic
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/aaron/.npm-global/lib/node_modules/node-keyboard/node_modules/midi
gyp ERR! node -v v8.11.2
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok 
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

I think it has to do with some aspect of alsa not being available:

In file included from ../src/node-midi.cpp:6:0:
../src/lib/RtMidi/RtMidi.cpp:1095:28: fatal error: alsa/asoundlib.h: No such file or directory
compilation terminated.

Cannot parse note "eb3"

@justinjmoses What am I doing wrong here?

node-keyboard>sequence(c, 2, 1, 2, 2, 1, 2, 2)
[ 'c3', 'd3', 'eb3', 'f3', 'g3', 'g#3', 'a#3', 'c4' ]
node-keyboard>sequence(c, 2, 1, 2, 2, 1, 2, 2).map(play)

node_modules/node-keyboard/lib/mappers.js:14
        throw new Error(`Cannot parse note "${chunk.input}"\n`)
        ^
Error: Cannot parse note "eb3"

    at exports.play.e (node_modules/node-keyboard/lib/mappers.js:14:15)
    at Array.map (native)
    at evalmachine.<anonymous>:1:34
    at Object.exports.runInContext (vm.js:44:17)
    at REPLServer.module.exports (node_modules/node-keyboard/lib/evaluator.js:28:23)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:441:10)
    at emitOne (events.js:96:13)
    at REPLServer.emit (events.js:188:7)
node-keyboard>play('eb3');
play('eb3');
Error: Cannot parse note "eb3"

    at exports.play.e (node_modules/node-keyboard/lib/mappers.js:14:15)
    at evalmachine.<anonymous>:1:1
    at Object.exports.runInContext (vm.js:44:17)
    at REPLServer.module.exports (node_modules/node-keyboard/lib/evaluator.js:28:23)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:441:10)
    at emitOne (events.js:96:13)
    at REPLServer.emit (events.js:188:7)
    at REPLServer.Interface._onLine (readline.js:224:10)

node-keyboard doesn't work on Mac OS 10.13.3

I installed node-keyboard on Mac OS 10.13.3 but get below errors when typing anything on the terminal. I am using node v8.9.1, npm 5.5.1

node-keyboard>MIDI not detected. Disabling support.
fs.js:75
    throw new TypeError('"options" must be a string or an object, got ' +
    ^

TypeError: "options" must be a string or an object, got number instead.
    at getOptions (fs.js:75:11)
    at Object.fs.writeFile (fs.js:1261:13)
    at ReadFileContext.fs.readFile [as callback] (/Users/joey/.nvm/versions/node/v8.9.1/lib/node_modules/node-keyboard/lib/index.js:42:23)
    at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:420:13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.