surikov/midi-sounds-react

Issue while playing using playChordAt function

kedsnaik opened this issue · 6 comments

Hello Sir,
I have built a music website using your midi sounds package and this mail is with respect to an issue that I am facing. I am using the below method to play the music :
this.midiSounds.playChordAt(playAt, instrument, [value],delay);
The problem caused is that when I click the play button second time, all the values are being played in a second and its causing a large noise. Could you please help me solve this? It's been a while since I am trying to debug this issue.
I have pasted a portion of code below.

import React, { Component } from 'react';
import './ButtonCard.css';
import MIDISounds from 'midi-sounds-react';
import './CloudsBackground.jpg';
import { Varase } from './Varase';
// import './Modal.js'

class ButtonCard extends Component {
constructor(props){
super(props);
this.state = {
instrument : 771,
speedDivisor : 1
}
}
start(event){
console.log(this.props);
console.log(Varase);
var id1 = this.props.btnNum;
this.midiSounds.stopPlayLoop();
// var a = document.getElementById(id1).value;
//console.log(event.target.id);
Varase.map((val,i) =>{
if ((val.id) == id1){
var instrument = this.state.instrument;
var v = val.value;
for (var j = 0; j<v.length;j++){
var value = val.value[j];
var delay = val.delay[j]/this.state.speedDivisor;
var playAt = val.playAt[j]/this.state.speedDivisor;
console.log("playAt :"+playAt+" instrument: "+instrument+" value :" + value + "delay: "+delay);
this.midiSounds.playChordAt(playAt, instrument, [value],delay);
}
}
})
// console.log(a);
// Varase.map((val,i) =>{
// console.log(Varase[i].value);
// });
}
stop(){
this.midiSounds.stopPlayLoop();
}

f1 = (event) => {
    var instrument1 = event.target.value;
    this.setState({instrument : instrument1});
    this.midiSounds.stopPlayLoop();
}
f2 = (event) => {
    this.setState({speedDivisor : event.target.value});
    this.midiSounds.stopPlayLoop();
}
replay(){
    this.stop();
    this.start();
}

render(){
return (


Instrument : Flute Voilin Sitar
Speed : 1 2 3 4

Play


Stop


Replay

<MIDISounds ref={(ref) => (this.midiSounds = ref)} appElementName="root"/>

)
}
}

export default ButtonCard;

Use JSBin or any other service to create code that reproduces problem
Paste link to this code here

I tried to reproduce the same scenario using tools like JSBin and JSFiddle, but could not find a way to import the library. Can we have an alternate method for this ? Or maybe I can share a simple project with you to illustrate the issue.. Please let me know if it works for you.

Thank you.

Create a files to run and reproduce problem. Zip them and paste here with instruction to execute.

I have attached the demo.zip file down below. You just need cd into the folder, install the node modules folder (npm install), midi-sounds-react package and run npm start.
There is a Play button in the UI which plays using playChordAt function. The values are hardcoded in the function. My issues are as stated below :

  1. When you click the play button, the values are played accordingly and it is all fine. But, the issue arises when you click the button for the second time, all the values are being played at one shot and there is a large noise for the hardcoded duration (third parameter in the function playChordAt).

  2. When the button play is clicked while the first one is playing, there is noise again for a second and the old one continues.

  3. Is there a way I can remove the midiSounds icon from the UI ? If yes, how can I do that ?

Zip file : demo.zip

Thank you,
Kedar Naik

Fixed code for App.js

import React, { Component } from 'react';
import './App.scss';
import MIDISounds from 'midi-sounds-react';

class App extends Component {
  temp(){
	  console.log('cancel all sounds');
	  this.midiSounds.cancelQueue();
	  console.log('start sounds from',this.midiSounds.audioContext.currentTime);
	  var startTime=this.midiSounds.audioContext.currentTime;
    this.midiSounds.playChordAt(startTime+0, 771, [48], 1);
    this.midiSounds.playChordAt(startTime+1, 771, [49], 1);
    this.midiSounds.playChordAt(startTime+2, 771, [52], 1);
    this.midiSounds.playChordAt(startTime+3, 771, [53], 1);
    this.midiSounds.playChordAt(startTime+4, 771, [55], 1);
    this.midiSounds.playChordAt(startTime+5, 771, [56], 1);
    this.midiSounds.playChordAt(startTime+6, 771, [59], 1);
    this.midiSounds.playChordAt(startTime+7, 771, [60], 1);
    this.midiSounds.playChordAt(startTime+8, 771, [60], 1);
    this.midiSounds.playChordAt(startTime+9, 771, [59], 1);
    this.midiSounds.playChordAt(startTime+10, 771, [56], 1);
    this.midiSounds.playChordAt(startTime+11, 771, [55], 1);
    this.midiSounds.playChordAt(startTime+12, 771, [53], 1);
    this.midiSounds.playChordAt(startTime+13, 771, [52], 1);
    this.midiSounds.playChordAt(startTime+14, 771, [49], 1);
    this.midiSounds.playChordAt(startTime+15, 771, [48], 1);
  }

  render() {
    return(
      <div className="App">
        <header className="App-header">
          <p><button  className="btn draw-border" onClick={this.temp.bind(this)}>Play</button></p>
          <MIDISounds ref={(ref) => (this.midiSounds = ref)} appElementName="root" instruments={[771]} />	
        </header>
      </div>
    );
  }
}export default App;

You can't remove MIDISounds button. You can hide it in CSS.

Thank you very much sir. This works perfectly.