Giter Club home page Giter Club logo

react-music's Introduction

Maintenance Status

react-music

Make music with React!


http://i.imgur.com/2t1NPJy.png

Contents

Install

npm install react-music

Get Started

The easiest way to get started is to clone this repo and run npm start. The demo song will be running at http://localhost:3000. You can open up the /demo/index.js file and edit your song there, using the API below as reference.

That said, you can import the primitives yourself and run your own build setup if you want.

Basic Concepts

Song

The first thing you want to do is create a Song component. This is the controller for your entire beat. It takes a tempo prop where you specify a BPM, and an playing prop that configures whether the song should play right away, or wait to press the play button. Set up it like so:

<Song tempo={90}>

</Song>

Sequencer

Your Sequencer's are what you use to define a looping section. They take two props. The first resolution is the resolution of steps in your sequence array. This defaults to 16, which is a sixteenth note. The second is bars which is how many bars the sequencer sequences before it loops. You can have multiple sequencers in your song, and the main Song loop is based upon the sequencer with the largest number of bars. Here is an example:

<Song tempo={90}>
  <Sequencer resolution={16} bars={1}>

  </Sequencer>
</Song>

Once you have a Song and a Sequencer component, you can add instruments to your Sequencer. Lets take a look at how these work:

Instruments

Sampler

The sampler component is used to play audio samples. To use it, you must at very least provide two props, sample and steps.sample is a path to an audio file, and steps is an array of indexes that map to the steps available based upon the resolution and bars props of your sequencer. So if you wanted a 4/4 kick line, you would do this:

<Song tempo={90}>
  <Sequencer resolution={16} bars={1}>
    <Sampler
	  sample="/samples/kick.wav"
	  steps={[0, 4, 8, 12]}
    />
  </Sequencer>
</Song>

You can also provide an array for a step, where the second value is a tuning, from -12 to 12.

Synth

The Synth component is used to create an oscillator and play it on steps, just like the Sampler does. To use it, you must provide two props, type and steps. Valid types are sine, square, triangle and sawtooth. The Synth component also takes an envelope prop, where you can specify your ASDR settings. The shape of the step prop is a bit different for the Synth component, as you must specify an array in the format of [ step, duration, note || [notes] ]. The duration portion specifies duration in steps. The note portion is a string of a musical note and octave like "a4" or "c#1", and for chords, can be an array of the same notes. This would look like:

<Song tempo={90}>
  <Sequencer resolution={16} bars={1}>
    <Synth
      type="square"
	  steps={[
	    [0, 2, "c3"],
	    [8, 2, ["c3", "d#3", "f4"]]
	  ]}
    />
  </Sequencer>
</Song>

Monosynth

The Monosynth component is a Synth component, but it only plays one note at a time. It also has a glide prop that specifies portamento length. So if two notes overlap, the monosynth glides up to the next value on that duration. Check out how:

<Song tempo={90}>
  <Sequencer resolution={16} bars={1}>
    <Monosynth
      glide={0.5}
      type="square"
      steps={[
        [0, 5, "c3"],
        [4, 4, "c4"],
      ]}
    />
  </Sequencer>
</Song>

Effects

There are a ton of new effects added in 1.0.0. You can compose effect chains by wrapping effects around your instruments. Here is an example of how you would do that:

<Song tempo={90}>
  <Sequencer resolution={16} bars={1}>
    <Reverb>
      <Delay>
        <Monosynth
          steps={[
            [0, 4, "c3"],
            [4, 4, "c4"],
          ]}
        />
      </Delay>
    </Reverb>
  </Sequencer>
</Song>

Effect Busses

If you want to define an effects bus, which is a set of effects that multiple instruments can send their output to, this is achieved with the Bus component.

First you want to create a Bus component, and give it an identifier:

<Song tempo={90}>
  <Bus id="myBus"/>
</Song>

Next, wrap your bus with the effect chain you want to make available, similarly to the way you would wrap effects around an instrument. You generally want to do this with effects that have wet/dry control, and set the dryLevel to 0:

<Song tempo={90}>
  <Delay dryLevel={0}>
    <Bus id="myBus"/>
  </Delay>
</Song>

Finally, to hook an instrument up to your bus, or several busses, add their id's to the busses prop on an instrument:

<Song tempo={90}>
  <Delay dryLevel={0}>
    <Bus id="myBus"/>
  </Delay>
  <Sampler
  	busses={['myBus']}
  	sample='/samples/kick.wav'
  	steps={[1,4,8,12]}
  />
</Song>

LFO

You know whats bananas? LFO. Thats what. You can use an oscillator to modify properties of your instruments and effects. This is done with the LFO component. Any node that you want to apply LFO to just needs it added as a child. Then you define a connect prop that returns a function that lets you select a parent AudioNode property to oscillate. See the following example.

<Song tempo={90}>
  <Synth
    type="square"
    steps={[
      [0, 2, "c3"],
      [8, 2, ["c3", "d#3", "f4"]]
    ]}
  >
    <LFO
      type="sine"
      frequency={0.05}
      connect={(c) => c.gain}
    />
  </Synth>
</Song>

API

Top Level


<Song />

playing (boolean) : Whether the song should start playing automatically

tempo (number) : Your song tempo

--

<Sequencer />

bars (number) : Number of bars in your sequence

resolution (number) : Step resolution for your sequence

Instruments


<Monosynth />

busses (array) : An array of Bus id strings to send output to

envelope (object) : An object specifying envelope settings

envelope={{
  attack: 0.1,
  sustain: 0.3,
  decay: 20,
  release: 0.5
}}

gain (number) : A number specifying instrument gain

glide (number) : Portamento length for overlapping notes

steps (array) : Array of step arrays for the notes to be played at

steps={[
  [0, 2, "a2"]
]}

transpose (number) : Positive or negative number for transposition of notes

type (string) : Oscillator type. Accepts square, triangle, sawtooth & sine

--

<Sampler />

busses (array) : An array of Bus id strings to send output to

detune (number) : A number (in cents) specifying instrument detune

gain (number) : A number specifying instrument gain

sample (string) : Path to an audio file

steps (array) : Array of step indexes for the sample to be played at. Accepts arrays for steps in order to provide a second argument for index based detune (in between -12 & 12).

--

<Synth />

busses (array) : An array of Bus id strings to send output to

envelope (object) : An object specifying envelope settings

envelope={{
  attack: 0.1,
  sustain: 0.3,
  decay: 20,
  release: 0.5
}}

gain (number) : A number specifying instrument gain

steps (array) : Array of step arrays for the notes to be played at. Accepts in array in the [ step, duration, note || [notes] ] format.

// single note
steps={[
  [0, 2, "a2"]
]}

// chord
steps={[
  [0, 2, ["c2", "e2", "g2"]]
]}

transpose (number) : Positive or negative number for transposition of notes

type (string) : Oscillator type. Accepts square, triangle, sawtooth & sine

Effects


<Bitcrusher />

bits (number)

bufferSize (number)

normfreq (number)

--

<Chorus />

bypass (number)

delay (number)

feedback (number)

rate (number)

--

<Compressor />

attack (number)

knee (number)

ratio (number)

release (number)

threshold (number)

--

<Delay />

bypass (number)

cutoff (number)

delayTime (number)

dryLevel (number)

feedback (number)

wetLevel (number)

--

<Filter />

Q (number)

frequency (number)

gain (number)

type (string)

--

<Gain />

amount (number)

--

<MoogFilter />

bufferSize (number)

cutoff (number)

resonance (number)

--

<Overdrive />

algorithmIndex (number)

bypass (number)

curveAmount (number)

drive (number)

outputGain (number)

--

<PingPong />

delayTimeLeft (number)

delayTimeRight (number)

feedback (number)

wetLevel (number)

--

<Reverb />

bypass (number)

dryLevel (number)

highCut (number)

impulse (string)

level (number)

lowCut (number)

wetLevel (number)

Special


<Analyser />

fftSize (number) : FFT Size value

onAudioProcess (function) : Callback function with audio processing data

smoothingTimeConstant (number) : Smoothing time constant

--

<Bus />

gain (number) : A number specifying Bus gain

id (string) : Bus ID

--

<LFO />

connect (function) : LFO property selection function

frequency (number) : LFO frequency

gain (number) : A number specifying LFO gain

type (string) : Oscillator type. Accepts square, triangle, sawtooth & sine

Known Issues & Roadmap

  • Currently only the 4/4 time signature is supported
  • Synth presets need to be added
  • Record/Ouput audio file
  • Optional working mixing board alongside viz
  • Sampler sample maps

License

MIT License

Maintenance Status

Archived: This project is no longer maintained by Formidable. We are no longer responding to issues or pull requests unless they relate to security concerns. We encourage interested developers to fork this project and make it their own!

react-music's People

Contributors

alavkx avatar alvaromb avatar areiterer avatar aunyks avatar boygirl avatar chentsulin avatar davidnaas avatar ebrillhart avatar fson avatar gaearon avatar haroenv avatar kale-stew avatar kenwheeler avatar ryan-roemer avatar samageloff avatar simonswiss avatar ultimapanzer avatar unkleho 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  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  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  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

react-music's Issues

Unable to run on LinuxMint

Hi
Thanks for this program. Using this for a while on Windows and this works great.
However running npm start gives the following unhelpful error message on Linux mint:

~/Desktop/Music/react-music-master $ npm start

> [email protected] start /home/gublu/Desktop/Music/react-music-master
> webpack-dev-server --hot --inline --port 3000 --config webpack.config.dev.js --content-base public/

module.js:471
    throw err;
    ^

Error: Cannot find module 'core-util-is'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/home/gublu/Desktop/Music/react-music-master/node_modules/readable-stream/lib/_stream_readable.js:37:12)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)

npm ERR! Linux 4.4.0-53-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
npm ERR! node v6.10.3
npm ERR! npm  v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `webpack-dev-server --hot --inline --port 3000 --config webpack.config.dev.js --content-base public/`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script 'webpack-dev-server --hot --inline --port 3000 --config webpack.config.dev.js --content-base public/'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the react-music package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     webpack-dev-server --hot --inline --port 3000 --config webpack.config.dev.js --content-base public/

I have already tried reinstalling nodejs and npm and my versions are latest.
node v6.10.3
npm v3.10.10

But this does not seem to work.

Refactor Internals

While this gets the job done initially, and you can definitely make beats, the internals need to be refactored. Right now, the render treats the tree like a data structure. The refactor should instead have a registry of node relationships so that deep updates can propagate and patch the adjacent audio API, rather than reconstructing it. This would make this like this possible:

<Reverb>
  <Filter type="lowpass">
    <Synth/>
  </Filter>
</Reverb>

The meat and potatoes would be:

Would love some input on approaches.

Only few notes get played when other tab is focused

Hello, I'm not sure if this is a bug or an intended behavior or not, but I couldn't find it in README so I'm reporting it.

I cloned the repo and ran demo, it worked just fine. But as I leave it playing and moved into other tab (in Chrome), only few notes of the song - every three unit beat (I don't know the terminology in English but it goes like sound, mute, mute, sound, mute, mute, ...) get played.

I'm using Chrome Version 52.0.2743.116 (64-bit) on OS X 10.11.6.

Wrong notation for some notes

Using a sawtooth synth for example, I need to use a2 in order to get an a3.

You can reproduce by setting up the bass line to Muse's Plug in Baby like I did:

<Synth
    type="sawtooth"
    steps={[
        [0, 2, "f#2"],
        [4, 2, "f#3"],
        [7, 1, "f#3"],
        [8, 2, "f#2"],
        [10, 2, "f#2"],
        [12, 2, "c#3"],
        [14, 2, "f#3"],

        [16, 2, "f#2"],
        [20, 2, "f#3"],
        [23, 1, "f#3"],
        [24, 2, "f#2"],
        [26, 2, "f#2"],
        [28, 2, "c#3"],
        [30, 2, "f#3"],

        [32, 2, "g2"],
        [36, 2, "g3"],
        [39, 1, "g3"],
        [40, 2, "g2"],
        [42, 2, "g2"],
        [44, 2, "d3"],
        [46, 2, "g3"],

        [48, 2, "g2"],
        [52, 2, "g3"],
        [55, 1, "g3"],
        [56, 2, "g2"],
        [58, 2, "g2"],
        [60, 2, "d3"],
        [62, 2, "g3"],

        [64, 2, "d2"],
        [68, 2, "d3"],
        [71, 1, "d3"],
        [72, 2, "d2"],
        [74, 2, "d2"],
        [76, 2, "a2"], // should be a3
        [78, 2, "d3"],

        [80, 2, "d2"],
        [84, 2, "d3"],
        [87, 1, "d3"],
        [88, 2, "d2"],
        [90, 2, "d2"],
        [92, 2, "a2"], // same here
        [94, 2, "d3"]
    ]}
/>

Tunajs bypass property propType assigned as number

Hello!
Thanks for this amazing project 🎼 I have noted that in the effects file, the tunaJS bypass propTypes are set as propTypes.number. Shouldn't it be propTypes.bool?
Test file of the tunaJS library where the bypass properties are assigned as booleans

Should we change the proptypes of the bypass property to be boolean, from number? Also, It would be nice to implement the Phaser effect (I used it a lot). I can make a pull request adding the phaser effect and correcting the propTypes today, WDYT?

React 16 support

Expected Behavior: When creating a test project to try out react-music and running it, I should be able to hear sound playing.
Current Behavior: When installing/running the project, it fails and gives these errors.
This in terminal when attempting to npm install react-music

WARN [email protected] requires a peer of react-dom@^15.2.1 but none is installed. You must install peer dependencies yourself.

And this in browser when attempting to npm start

TypeError: Cannot read property 'propTypes' of undefined

Possible Solution: I read here that changes made to PropTypes have changed:

React.createClass is now available as create-react-class, React.PropTypes as prop-types, ...

It's likely that the changes in the switch from 15.x.x to 16.x.x are causing the error to occur and can possibly be fixed by having react-music package install proptypes to be compatible with the newest version of react.
Steps to Reproduce: Initiate a project using create-react-app <project-name> if the create-react-app module is installed. npm install react-music in the project, create a test to ensure react-music package is working and npm start
Context: In trying to create this project, I ran into the PropTypes error many times and could not find an answer that wasn't too specific or even touched on the differences between react 15.x.x and 16.x.x. After talking with an instructor, we looked at differences in the package.json of the react project from the demo to a test project and saw that the demo was using react 15.2.1 and the create-react-app command installs the newest version of react on the test project. After uninstalling react from the test project and npm install [email protected], the test project started working.
Your Environment: Ubuntu 16.04, Chrome 60+, React 16/React 15.2.1

You'll find in my project using react-music a commit showing the differences, and that the subsequent commits indicate a success in making it work.

Standard library

Just throwing an idea out there.
I could really use functions like transpose and maybe some more.
What do you think?

Mobile support?

Expected Behavior: Sound should play when a tile is selected
Current Behavior: The tile animates, indicating it has been selected/is active, but no sound plays.
Steps to Reproduce: http://synchrono-app.firebaseapp.com
Context: Hi there! I'm trying to make a mobile friendly web app that allows the user to use a 'launchpad'. It currently works on my laptop/Google Chrome but it does not work on mobile. Any ideas on how to fix/what's going on?
Your Environment: iPhone 7 running iOS 10.3.3 on Safari

edit: the demo doesn't work on mobile either :(

Contributing

Very cool project, I was thinking of working on a 3 band EQ, but it may be a bit over my head as I'm rather new to javascript. I'd still love to contribute, is there anything a little simpler you have for me that could get me started? Docs, tests, whatever.
Thanks

Changing sampler settings on the fly

I noticed that when I change sampler settings with props, the changes get applied only after it finishes the current run. I wonder if it’s possible to make it change right away, removing the scheduled beats and scheduling new (remaining) beats according to the new props.

So if I replace 0, 2, 10 with 0, 2, 12 while I’m on 8, I expect 10 to not be played, and 12 to be played.

note-parser not working when using as a library in another project

Hi!

Synthesizers work great for me in the demo project. However, when I add react-music as a dependency to another project, I'm unable to use Synth or Monosynth, seemingly because of an error using note-parser:

Uncaught TypeError: Cannot read property 'freq' of undefined
    at Monosynth.createOscillator (monosynth.js:147)
    at Monosynth.playStep (monosynth.js:163)
    at Scheduler.process (scheduler.js:119)
    at loop (scheduler.js:34)

The Sampler instrument works fine.

Demo song not working

Either the demo song is not working, or it has intentionally been removed from the repo, in which case you may want to consider updating the Readme.

Improve error messages

Currently when developing and something is wrong in a component i get the following error:

bundle.js:8859 Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `AppContainer`.

bundle.js:8400 Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `AppContainer`.

It's incredibly hard to find the actual error which usually is something simple. It would speed up development a lot if it was possible to make the error messages more explicit.

this.context.close is not a function

I am trying to create a UI for React-Music.
Sometimes (I can't understand not always) my component is unable to unmount because in the willUnmount event this.context.close is not a function.
Which could be the fix for this?

screen shot 2016-09-10 at 17 50 57

Uncaught (in promise) DOMException: Unable to decode audio data

this is my code :
constructor(props) { super(props); this.state = { playing: false }; } handleClick(){ this.setState({ playing: !this.state.playing, }); } return( <Song playing={this.state.playing} tempo={90} > <Sequencer resolution={16} bars={1} > <Sampler sample="./Snare.wav" steps={[0, 2, 8, 10]} /> </Sequencer> </Song>)
but this error occured

play midi files?

We could make it play midi files from online sources. There are midi archives online so that you could play from online midi files...

Song does not play when disabling autoplay

Chromium x64 version 62.0.3202.89 on Arch Linux 4.13.11

Chromium has a great hidden feature in chrome://flags that allows to disable autoplay, when setting the Autoplay policy flag to Document user activation is required and restarting. But the music on this app does not start playing, and the following warning is shown in the developer tools :

An AudioContext in a cross origin iframe must be created or resumed from a user gesture to enable audio output. (Song @ bundle.js:14055)

If possible, there should be a way to start it manually, or at least to detect that autoplay is disabled and ask the user to enable it.

Doesn't work in Chrome 71+

If you open the page in Chrome 71 or newer, it displays a blank rectangle with a Stop/Start button. Clicking the button, even multiple times, doesn't do anything.

The DevTools console displays a warning:

The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu

The URL linked at the end of the message explains the issue. tl;dr is included in one box:

Key Point: If an AudioContext is created prior to the document receiving a user gesture, it will be created in the "suspended" state, and you will need to call resume() after a user gesture is received.

This is a measure preventing websites from playing potentially unwanted audio, as I understand.

Tested on macOS 10.13.6 (17G4015) but the issue should be present on all operating systems.

Alternate time signatures & time signature/tempo changes?

Just curious if anyone has any ideas yet about how to support alternate time signatures & changing time signatures (and tempo?) at specific points in a song.

This is usually done with time grids & markers describing the time/tempo change set on the grid in DAWs & midi notation apps like Guitar Pro, TuxGuitar, TabIt, etc.

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.