All Projects → rakannimer → react-orchestra

rakannimer / react-orchestra

Licence: other
A declarative toolbox to build interactive musical instruments on web and mobile.

Programming Languages

javascript
184084 projects - #8 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to react-orchestra

ziffers
Numbered musical notation for composing algorithmic and generative melodies
Stars: ✭ 53 (-26.39%)
Mutual labels:  music-composition, music-theory
NegativeHarmonizer
A python tool to invert the tonality (a.k.a negative harmony) of midi notation
Stars: ✭ 23 (-68.06%)
Mutual labels:  music-composition, music-theory
musyn
Write music together, in real time.
Stars: ✭ 20 (-72.22%)
Mutual labels:  music-composition, music-theory
Webaudiofont
Use full GM set of musical instruments to play MIDI and single sounds or effects. Support for reverberation and equaliser. No plugins, no Flash. Pure HTML5 implementation compatible with desktop and mobile browser. See live examples.
Stars: ✭ 600 (+733.33%)
Mutual labels:  music-composition, instrument
fretboarder
🎸 A web app to visualize scales, chords and arpeggios on all kinds of fretboards.
Stars: ✭ 34 (-52.78%)
Mutual labels:  music-theory, music-theory-apps
chords
Text-based chord progression editor
Stars: ✭ 25 (-65.28%)
Mutual labels:  music-composition, music-theory
Dyci2Lib
"Dicy2 for Max" is a Max package implementing interactive agents using machine-learning to generate musical sequences that can be integrated into musical situations ranging from the production of structured material within a compositional process to the design of autonomous agents for improvised interaction. Check also our plugin for Ableton live !
Stars: ✭ 35 (-51.39%)
Mutual labels:  music-composition
csound-extended
Extensions for Csound including algorithmic composition, Android app, and WebAssembly.
Stars: ✭ 38 (-47.22%)
Mutual labels:  music-composition
bnote
BNote - Open Source Ensemble Management
Stars: ✭ 20 (-72.22%)
Mutual labels:  orchestra
balldrop
An experimental musical instrument, made with Godot 3.1.
Stars: ✭ 29 (-59.72%)
Mutual labels:  instrument
octave-compass
A tool for exploring musical scales and chords
Stars: ✭ 21 (-70.83%)
Mutual labels:  music-theory
scamp
a Suite in Python for Computer-Assisted Music [MIRROR of https://git.sr.ht/~marcevanstein/scamp]
Stars: ✭ 55 (-23.61%)
Mutual labels:  music-composition
sunrise
NumPy, SciPy, MRI and Music | Presented at ISMRM 2021 Sunrise Educational Session
Stars: ✭ 20 (-72.22%)
Mutual labels:  music-composition
django-music-publisher
Software for managing music metadata, registration/licencing of musical works and royalty processing.
Stars: ✭ 46 (-36.11%)
Mutual labels:  music-composition
Modulo7
A semantic and technical analysis of musical scores based on Information Retrieval Principles
Stars: ✭ 15 (-79.17%)
Mutual labels:  music-theory
AndroidFuzz
JavaFuzz 4 Android
Stars: ✭ 27 (-62.5%)
Mutual labels:  instrument
r e c u r
an open diy py/pi based video sampler
Stars: ✭ 220 (+205.56%)
Mutual labels:  instrument
alda-clj
A Clojure library for live-coding music with Alda
Stars: ✭ 54 (-25%)
Mutual labels:  music-composition
hexpress
Modern mobile music instrument
Stars: ✭ 51 (-29.17%)
Mutual labels:  instrument
chords
A Kotlin multi-platform view library for displaying stringed instrument chord diagrams
Stars: ✭ 25 (-65.28%)
Mutual labels:  music-composition

React Orchestra

CircleCI

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 [email protected]:RakanNimer/react-orchestra.git
cd  react-orchestra/web/
{yarn && yarn start} || {npm i && npm start}
  • Native example :
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.

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 (
      <Instrument name={'acoustic_grand_piano'} interactive={false}>
        <Note name={'A3'} play={this.state.playA}>
          {/*
            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={this.state.playC}><div>Another note</div></Note>
      </Instrument>
    );
  }
}
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.

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 (
      <Instrument name={'acoustic_grand_piano'} onStartPlaying={this.onStartPlaying} onStopPlaying={this.onStopPlaying} 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>
    );
  }
}
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.

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 (
      <Orchestra
        midiURL={midiURL}
        onMidiLoaded={this.onMidiLoaded}
        onInstrumentsReady={this.onInstrumentsReady}
        play={this.state.playSong}
        selectedTracks={[0, 1]}
        onNotePlayed={this.onNotePlayed}
      >
        <div> This is an orchestra it can play complex melodies ! </div>
      </Orchestra>
    );
  }
}
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

import React from 'react';
import { NoteFactory } from 'react-orchestra/web';

const renderNote = (instrumentName, noteName) => <div style={{ cursor: 'pointer' }}> I am a note : {instrumentName} {noteName} You can click me ! </div>;

class NoteFactoryExample extends React.Component {
  render() {
    return (
      <NoteFactory
        type="scale"
        scaleName="ionian"
        noteName="C"
        instrumentName="acoustic_grand_piano"
        startOctave="3"
        octaveCount="1"
        renderNote={renderNote}
      />
    );
  }
}
export default NoteFactoryExample;

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].