Giter Site home page Giter Site logo

unkleho / reactronica Goto Github PK

View Code? Open in Web Editor NEW
456.0 456.0 33.0 14.88 MB

React audio components for making music in the browser

Home Page: https://reactronica.com

License: MIT License

JavaScript 10.76% CSS 2.71% TypeScript 83.55% HTML 2.98%
react tonejs

reactronica's People

Contributors

dependabot[bot] 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

reactronica's Issues

Buffer / loading sample files

Even after using onload Buffer as well as the tone.js buffer component, the console still loads buffer is either not set or not loaded. I've checked the network location and it does show that the .wav files have loaded, so is there something we should include in between?

<Song isPlaying={isPlaying} bpm={60}>
    <Track steps={[(props.note)]}>
      {/* <Instrument type="monoSynth" notes={['C3']} envelope={{attack: 0.2,release: 0.5,}} /> */}
      <Instrument
        type="sampler"
        notes={notes}
        samples={{
          A0: "/public/piano/A0vH.wav",
          B0: "/public/piano/B0vH.wav",,
        }}

        onLoad={(buffers) => {
         // runs when all samples are loaded
        }}
      />
    </Track>
</Song>

Thank you!

No Sound on Safari for iOS

When attempting to play sounds on Safari iOS from this app, no sounds can be heard. Opening the same website in Chrome for desktop plays the sounds correctly, but there are some errors in the console related to AudioContext:
AudioContext

There's a Tone.js issue open and appears to affect safari and some other browsers.

Edit: Testing the piano roll example from the documentation page also results in silence when using safari iOS (but works great on Chrome desktop). I haven't been able to test from Android yet.

(question/help wanted) Converting ToneJS-style Loop to Reactronica composition

Hi there,

Hoping to have some extra direction here. I programmed a simple drum beat in plain ToneJS using the Loop API, and I'm having some trouble converting the pattern over to a composition of Reactronica components. Here's a live site with what the loop sounds like: https://tonejs-pattern--beets.netlify.app/

The code for this in ToneJS looks like this:

import { Loop } from "tone";
import * as Tone from "tone";

Tone.Transport.bpm.value = CoreUtils.randomInt(75, 85);
Tone.Transport.swing = CoreUtils.randomFloat(0.25, 0.3);

new Loop((time) => closedHiHat.start(time), "8n").start();
new Loop((time) => openHiHat.start(time), "1m").start("0:7");
new Loop((time) => kick.start(time), "1m").start();
new Loop((time) => kick.start(time), "1m").start("0:5");
new Loop((time) => snare.start(time), "2n").start("4n");

For samples that I want to play on as different note lengths (1/8 note, 1/2 note), do I need to render a new <Track /> with the subdivision prop?

Here's what I currently have, but it sounds a little bit off, and I think I might be missing something. You can test how it sounds here: https://reactronica-experiment--beets.netlify.app/ and the code that's currently powering this is here: https://github.com/brandongregoryscott/beets/blob/reactronica-experiment/src/app.tsx#L6:L112

Any help is much appreciated ๐Ÿ˜…

Roadmap for v1.0

Great project! Would like to know what the plan for v1.0

What features or stability structure are you looking to add. I am asking because I plan to use it part of a project but I wouldn't want the APIs to drastically change by the time v1.0 rolls out.

๐Ÿค”

Track steps are not properly removed/disposed when they change

It looks like the <Track /> component is not properly removing or disposing of steps when props change. I ran into this on my own project using reactronica, but I've reproduced the issue in a smaller sandbox environment: https://codesandbox.io/s/reactronica-42-step-duplication-bug-qnd8h?file=/src/App.tsx

To reproduce in the sandbox:

  1. Wait for the samples to load (Play button will be disabled until onLoad runs)
  2. Play the initial state of the Track which includes 4 hi-hat notes and a kick on the first step.
  3. Pause the track.
  4. Toggle the steps to be the hi-hat only set.
  5. Play the track again. (You should hear hi-hats only)
  6. Pause the track, and toggle the steps.
  7. Play the track - on this time around, you'll notice the kick and hi-hats sound louder. (as if they are layered on top of the original array of steps)
  8. Pause the track, then toggle the steps back to the hi-hat only set.
  9. Play the track - you will hear both the kick and hi-hats, and they sound even louder.

I've patched the issue in a branch of my fork (85405d7) which I've tested against my project using reactronica, but not this sandbox example. I imagine it will resolve it, too, but I'm not 100% sure.

Tone.Part instead of Tone.Sequencer

With my brief understanding of Tone.js, it would seem that Tone.Part would allow users to play MidiNotes that have a time property as opposed to having everything be sequenced to a fixed tempo/time as provided by `Tone.Sequence.

Am I right in understanding that this is a current limitation of reactronica? Or am I not understanding Tone enough?

Document/require 'onLoad' prop for sampler type Instrument

First off, I wanted to say thank you for building out this awesome library! I stumbled upon ToneJS first and figured I was going to have to build out similar abstractions for interacting with that API in React, so I'm thankful that most of the heavy lifting has been done here already.

One issue that I just spent a lot of time trying to debug was why a song with a track and sampler instrument would throw errors as soon as it attempted to play a note. I had sent through a samples prop with notes and file URLs in the structure shown in the docs...

<Instrument 
    samples={{
        "C-2": "...",
        "C#-2": "...",
    }}
    type="sampler" />

Any time I change isPlaying to true for the <Song />, it would throw this error:

Uncaught Error: No available buffers for note: -12
    at s.default.Sampler._findClosest (Tone.js:7)
    at s.default.Sampler.triggerAttack (Tone.js:7)
    at s.default.Sampler.triggerAttackRelease (Tone.js:7)
    at Track.tsx:95
    at Array.map (<anonymous>)
    at Track.tsx:94
    at Array.forEach (<anonymous>)
    at s.default.Sequence.callback (Track.tsx:93)
    at s.default.Sequence.s.default.Part._tick (Tone.js:7)
    at s.default.Event._tick (Tone.js:7)
    at s.default.TransportRepeatEvent.s.default.TransportEvent.invoke (Tone.js:7)
    at s.default.TransportRepeatEvent.invoke (Tone.js:7)
    at s.default.TransportEvent.invoke (Tone.js:7)
    at s.default.Timeline.<anonymous> (Tone.js:7)
    at s.default.Timeline.<anonymous> (Tone.js:7)
    at s.default.Timeline.<anonymous> (Tone.js:7)
    at Array.forEach (<anonymous>)
    at s.default.Timeline._iterate (Tone.js:7)
    at s.default.Timeline.forEachAtTime (Tone.js:7)
    at s.default.Transport._processTick (Tone.js:7)
    at s.default.Clock.<anonymous> (Tone.js:7)
    at s.default.TickSource.forEachTickBetween (Tone.js:7)
    at s.default.Clock._loop (Tone.js:7)
    at s.default.Context.s.default.Emitter.emit (Tone.js:7)

After some more trial and error, I realized from the network tab in dev tools that samples weren't actually being loaded. Once the onLoad function was provided, network requests were firing off to load the resources and then it would play as expected.

At the very least, there should be a JSDoc comment that notes this function is required when providing type="sampler". It would be even better if we could use conditional types to require this property when type is passed through as "sampler".

DAW Code Example

Hello, thank you for creating this library I've been wrestling with using MIDI in the browser with Tonejs for months and I've been much more productive since adding this library. I was wondering is the DAW Example on the website open source as well? I'm trying to build out a MIDI player that's slightly more complicated than the examples and having a reference would be very helpful.

Bug Report: Residual notes in Track component of step sequencer

Description:
When using the Track component to build a step sequencer, I've noticed that after adding and deleting multiple notes on a step, some notes persist indefinitely. These residual notes continue playing even if they are no longer present in the steps prop array.

Steps to Reproduce:
Build a step sequencer using the Track component, and pass an array of notes into the steps prop.
Add and delete multiple notes on a particular step multiple times via an onClick function that adds and removes notes from the array that's passed into the Track components steps prop.
Observe that after a few iterations, some notes continue to play indefinitely.

Observations:
Notes will infinitely sustain if there are no successive notes present.
Sustaining notes can be interrupted if other notes on a successive step are present.
Logging out the array on each step reveals, that even if the steps prop array is empty, playback and infinite note sustain still occur.
This behaviour was also observed in the piano roll step sequencer example from the documentation.

Suspected Cause:
It seems that the Track component might be caching some notes and not updating them correctly after they are deleted multiple times. This is based on the observation that even with an empty steps prop array, playback and infinite note sustain still happens.

Additional Information:
I've built a sequencer setup that's functionally very similar to the one in the documentation, and this issue was consistent in both my own version and the example in the docs.

How to save a song to a file?

I saw this project demoed at nextjs conf and it looks awesome, can't wait to try it out.

I was curious if there is a way to export a given Song component (and all of its children) to a sound file (i.e. .mp3). If not officially supported, do you have any suggestions for how to go from react components to file export?

Sequencer/Track: sample trigger timing

First of all, very nice project. so intuitive! great!

I have built a drum sequencer.
unfortunately, the timing here is not quite correct. the rhythm sounds a little out of sync, as if the note is not played exactly on the beat. actually, tonejs should trigger the sample exactly, but unfortunately it does not sound quite like that in your implementation. have you ever had problems with this?

export const App = () => {
  const [playing, setPlaying] = useState(false);
  const [isLoaded, setLoaded] = useState(false);
  
  return (
    <div>
      <button disabled={!isLoaded} onClick={() => setPlaying(!playing)}>
        play/pause
      </button>
      <Song isPlaying={playing}>
        <Track
          subdivision="8n"
          steps={[
            ["C3", { name: "E3", velocity: 0.2 }],
            [{ name: "E3", velocity: 0.05 }],
            [{ name: "E3", velocity: 0.4 }],
            [{ name: "E3", velocity: 0.05 }],
            ["D3", { name: "E3", velocity: 0.4 }],
            [{ name: "E3", velocity: 0.1 }],
            [{ name: "E3", velocity: 0.2 }],
            [{ name: "E3", velocity: 0.05 }],
            [{ name: "E3", velocity: 0.4 }],
            [{ name: "E3", velocity: 0.1 }],
            ["C3", { name: "E3", velocity: 0.4 }],
            [{ name: "E3", velocity: 0.05 }],
            ["D3", { name: "E3", velocity: 0.4 }],
            [{ name: "E3", velocity: 0.05 }],
            [{ name: "E3", velocity: 0.4 }],
            [{ name: "E3", velocity: 0.05 }],
          ]}
        >
          <Instrument
            type="sampler"
            onLoad={() => setLoaded(true)}
            samples={{
              C3: "samples/drums/1/kick.wav",
              D3: "samples/drums/1/snare.wav",
              E3: "samples/drums/1/hat2.wav",
            }}
          />
        </Track>
      </Song>
    </div>
  );
};

greetings, Jonathan :)

Here the samples:
samples.zip

PianoRoll Component Missing

I'm trying to follow this example to use the PianoRoll, but I'm getting the following error:

Compiled with problems:
ERROR

src\SynthEngine.js
  Line 25:10:  'PianoRoll' is not defined  react/jsx-no-undef

Looking inside the Reactronica source I don't see a PianoRoll in the components.

Feature request: Recorder component

Hey there, not sure if this is on your roadmap or not, but I will have a use case for a wrapper around the Recorder from ToneJS to export an audio file of the current song arrangement.

I'm not exactly sure what the API should look like just yet, but I figured I would document an issue and start discussion. I'm also happy to try to hack on something if no one else gets to it, either ๐Ÿ˜„

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.