React Orchestra
A toolbox to build interactive and smart instruments on the web and mobile.
Web example can be seen here
Web example repo
Native example repo
Getting Started
React Orchestra can be integrated easily into any project.
Prerequisites
Native
Installing peer dependencies
Under the hood RO uses :
react-native-sound to play mp3 sounds.
react-native-fs to cache sounds in the filesystem.
realm as an offline store for caching and state storage ( might remove this in future versions unless I or someone builds up on realm features to improve react-orchestra functionality )
In your project root :
Install it :
With npm
npm install --save react-native-sound react-native-fs realm
With yarn
yarn add react-native-sound react-native-fs realm
Then link it :
react-native link
Web
IMPORTANT READ THIS:
The sound generation and playback for the web orchestra depends on the WebAudio API. Check support for your platform target here. If your targeted platform is supported you can go ahead and install it.
Install react-orchestra
With npm
npm install --save react-orchestra
With yarn
yarn add react-orchestra
No need to link it ! It's plain JS.
And you're good to go 💃.
Let's start writing some instruments.
TLDR; I just want to copy paste stuff !
There you go :
Web
yarn add react-orchestra || { npm i -S react-orchestra; }
Native
yarn add react-native-sound react-native-fs realm || { npm i -S react-native-sound react-native-fs realm; }
react-native link react-native-sound react-native-fs realm
yarn add react-orchestra || { npm i -S react-orchestra; }
API + Examples
Let's build a couple of use-cases to get familiar with the API. Or you can directly check out and run the examples :
- Web example :
git clone git@github.com:RakanNimer/react-orchestra.gitcd react-orchestra/web/{yarn && yarn start} || {npm i && npm start}
- Native example :
git clone git@github.com:RakanNimer/react-orchestra.gitcd react-orchestra/ReactOrchestraNativeDemo/yarn || {npm i;}npm run init-appreact-native run-ios # or run-android
1. A non-interactive instrument that can play notes and sync ui.
;;// If you're using react-native then it's :// import { Instrument, Note } from 'react-orchestra/native'; const delay = ; { superprops; thisstate = playA: false playC: false ; } { this; } async { await ; this; await ; this; await ; this; } { return <Instrument name='acoustic_grand_piano' interactive=false> <Note name='A3' play=thisstateplayA> /* You can put any react element here native or web. */ <div> This is what I want my note to look like ! I can put anything in here <img alt="Some pic" src="https://s-media-cache-ak0.pinimg.com/originals/36/43/e7/3643e7e8dab9b88b3972ee1c9f909dea.jpg" /> </div> </Note> <Note name='C3' play=thisstateplayC><div>Another note</div></Note> </Instrument> ; };
The API aims to be self-explanatory, for example, in the code above we're creating two controlled note components, that we can play and stop using the play prop.
When the component mounts, we start playing a simple melody.
2. An interactive instrument that the end-user controls.
Let's build an instrument that the user can play by clicking or tapping on notes.
;;// If you're using react-native then it's :// import { Instrument, Note } from 'react-orchestra/native'; Component { superprops; thisstate = ; thisonStartPlaying; thisonStopPlaying; } { console; } { console; } { return <Instrument name='acoustic_grand_piano' onStartPlaying=thisonStartPlaying onStopPlaying=thisonStopPlaying interactive> <Note name='A3'> <div> <div>Click me to play A3</div> </div> </Note> <Note name='C3'><div>Click me to play C3</div></Note> </Instrument> ; };
You don't need to listen to clicks or taps setting the interactive
prop to true will attach the right events and clean them up for you !
The onPlay handler can be used to manage your state.
3. Playing midi and displaying playback.
As any orchestra, react-orchestra can learn and play music tracks ! For now, it understands MIDI out of the box, more input sources are in the roadmap.
Let's play Beethoven Moonlight's sonata.
;;// If you're using react-native then it's :// import { Orchestra } from 'react-orchestra/native';const midiURL = 'https://s3-eu-west-1.amazonaws.com/ut-music-player/assets/midis/beet1track-medium-fast.mid'; { superprops; thisstate = playSong: false ; thisonMidiLoaded = thisonMidiLoaded; thisonInstrumentsReady = thisonInstrumentsReady; } { } { console; return parsedMidi; } { console; this; return instruments; } { console; } { return <Orchestra midiURL=midiURL onMidiLoaded=thisonMidiLoaded onInstrumentsReady=thisonInstrumentsReady play=thisstateplaySong selectedTracks=0 1 onNotePlayed=thisonNotePlayed > <div> This is an orchestra it can play complex melodies ! </div> </Orchestra> ; };
**4. Creating a note factory **
This is useful when you want to generate notes that follow a given rule
Example : Render the C Major scale starting at the third octave over 2 octaves
;; const renderNote = <div style= cursor: 'pointer' > I am a note : instrumentName noteName You can click me ! </div>; Component { return <NoteFactory type="scale" scaleName="ionian" noteName="C" instrumentName="acoustic_grand_piano" startOctave="3" octaveCount="1" renderNote=renderNote /> ; };
Documentation
Showcase
Did you build something cool with this library ?
Show it off here by submittiing a pull request.
Running the tests
npm test
Tests lint all js files using the js airbnb coding style and runs the jest tests in __tests__ directory.
Contributing
You can contribute by submitting, and responding to issues. If you'd like to add a new feature PRs are very welcome, but please open an issue beforehand so we can discuss the optimal way to go when adding the feature !
Roadmap
- Create NoteFactory component that takes in a scale name or chord name or Midi URL and creates user-rendered Notes.
- Add tests that run on browser
- Add react-orchestra/native jest tests
- Add more web jest tests
License
This project is licensed under the MIT License - see the LICENSE.md file for details