Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rakannimer/react-orchestra
A declarative toolbox to build interactive musical instruments on web and mobile.
https://github.com/rakannimer/react-orchestra
instrument javascript music music-composition music-theory music-theory-apps orchestra react react-native
Last synced: 15 days ago
JSON representation
A declarative toolbox to build interactive musical instruments on web and mobile.
- Host: GitHub
- URL: https://github.com/rakannimer/react-orchestra
- Owner: rakannimer
- Created: 2016-12-20T05:37:49.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2022-10-06T00:57:11.000Z (about 2 years ago)
- Last Synced: 2024-08-29T18:36:11.163Z (3 months ago)
- Topics: instrument, javascript, music, music-composition, music-theory, music-theory-apps, orchestra, react, react-native
- Language: JavaScript
- Homepage: http://react-orchestra.surge.sh/
- Size: 15.7 MB
- Stars: 75
- Watchers: 7
- Forks: 20
- Open Issues: 71
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
Awesome Lists containing this project
README
# React Orchestra
[![CircleCI](https://circleci.com/gh/RakanNimer/react-orchestra.svg?style=shield&circle-token=6fe92a6008747c5902e40a5038690d7e0118865d)](https://circleci.com/gh/RakanNimer/react-orchestra)
A toolbox to build interactive and smart instruments on the web and mobile.
Web example can be seen [here](http://react-orchestra.surge.sh/)
### [Web example repo](https://github.com/RakanNimer/react-orchestra-web-demo)
### [Native example repo](https://github.com/RakanNimer/react-orchestra-native-demo)
## Getting Started
React Orchestra can be integrated easily into any project.
### Prerequisites
#### Native
##### Installing peer dependencies
Under the hood RO uses :[react-native-sound](https://github.com/zmxv/react-native-sound) to play mp3 sounds.
[react-native-fs](https://github.com/johanneslumpe/react-native-fs) to cache sounds in the filesystem.
[realm](https://github.com/realm/realm-js) 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](http://caniuse.com/#feat=audio-api).
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 :
```sh
git clone [email protected]:RakanNimer/react-orchestra.git
cd react-orchestra/web/
{yarn && yarn start} || {npm i && npm start}
```- Native example :
```sh
git clone [email protected]:RakanNimer/react-orchestra.git
cd react-orchestra/ReactOrchestraNativeDemo/
yarn || {npm i;}
npm run init-app
react-native run-ios # or run-android
```**1. A non-interactive instrument that can play notes and sync ui.**
```javascript
import React from 'react';
import { Instrument, Note } from 'react-orchestra/web';
// If you're using react-native then it's :
// import { Instrument, Note } from 'react-orchestra/native';const delay = ms => new Promise(resolve => setTimeout(ms, resolve));
class App extends Component {
constructor(props) {
super(props);
this.state = {
playA: false,
playC: false,
};
}
componentDidMount() {
this.playMelody();
}
async playMelody() {
await delay(1000);
this.setState({ playA: true });
await delay(1000);
this.setState({ playB: true, playA: false });
await delay(1000);
this.setState({ playB: false });
}
render() {
return (
{/*
You can put any react element here native or web.
*/}
This is what I want my note to look like ! I can put anything in here.
Another note
);
}
}
export default App;```
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.
```javascript
import React from 'react';
import { Instrument, Note } from 'react-orchestra/web';
// If you're using react-native then it's :
// import { Instrument, Note } from 'react-orchestra/native';class App extends React.Component {
constructor(props) {
super(props);
this.state = {
};
this.onStartPlaying.bind(this);
this.onStopPlaying.bind(this);
}
onStartPlaying(noteName) {
console.warn(`Note played ${noteName}. Use this function if you want to sync your state with the instrument, dispatch redux action or alter mobx observable or just setting state inside your component`);
}
onStopPlaying(noteName) {
console.warn(`Stopped playing ${noteName}. Use this function if you want to sync your state with the instrument, dispatch redux action or alter mobx observable or just setting state inside your component`);
}
render() {
return (
Click me to play A3
Click me to play C3
);
}
}
export default App;```
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.
```javascript
import React from 'react';
import { Orchestra } from 'react-orchestra/web';
// 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';
class App extends Component {
constructor(props) {
super(props);
this.state = {
playSong: false,
};
this.onMidiLoaded = this.onMidiLoaded.bind(this);
this.onInstrumentsReady = this.onInstrumentsReady.bind(this);
}
componentDidMount() {}
onMidiLoaded(parsedMidi) {
console.warn(`Midi loaded ${JSON.stringify(parsedMidi, 2, 2)}. Loading instruments now ...`);
return parsedMidi;
}
onInstrumentsReady(instruments) {
console.warn(`Instruments ${JSON.stringify(instruments, 2, 2)} are loaded into memory and ready !`);
this.setState({ play: true });
return instruments;
}
onNotePlayed(noteName) {
console.warn(`Note ${noteName} was played, optionally handle this event`);
}
render() {
return (
This is an orchestra it can play complex melodies !
);
}
}
export default App;
```**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
```javascript
import React from 'react';
import { NoteFactory } from 'react-orchestra/web';const renderNote = (instrumentName, noteName) =>
I am a note : {instrumentName} {noteName} You can click me !;class NoteFactoryExample extends React.Component {
render() {
return (
);
}
}
export default NoteFactoryExample;```
## Documentation- [API](docs/api.md#api)
- [``](docs/api.md#Note)
- [``](docs/api.md#Instrument)
- [``](docs/api.md#Orchestra)
- [``](docs/api.md#NoteFactory)
- [`` (*web only*)](docs/api.md#KeyBinding)## Showcase
Did you build something cool with this library ?
Show it off here by [submittiing a pull request](https://github.com/RakanNimer/react-orchestra/compare).
## 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
- [x] 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](LICENSE.md) file for details