Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
{
"name": "notio",
"version": "0.1.0",
"license": "UNLICENSED",
"private": true,
"dependencies": {
"@react-firebase/database": "^0.3.11",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"@tonejs/piano": "^0.2.1",
"check-peer-dependencies": "^4.2.0",
"color": "^4.2.3",
"firebase": "^9.9.4",
"react": "^18.2.0",
Expand All @@ -20,6 +18,7 @@
"react-scripts": "5.0.1",
"react-tooltip": "^4.2.21",
"sass": "^1.54.9",
"soundfont-player": "^0.12.0",
"tone": "^14.7.77",
"vexflow": "^4.0.3",
"web-vitals": "^2.1.0",
Expand Down Expand Up @@ -54,18 +53,14 @@
]
},
"devDependencies": {
"@babel/core": "^7.8.0",
"@babel/plugin-syntax-flow": "^7.14.5",
"@babel/plugin-transform-react-jsx": "^7.14.9",
"@babel/preset-env": "^7.19.0",
"@babel/preset-react": "^7.18.6",
"@testing-library/jest-dom": "^5.16.5",
"babel-jest": "^29.0.3",
"jest": "29.0.3",
"jest": "^29.0.3",
"jest-html-reporter": "^3.7.0",
"mutation-observer": "^1.0.3",
"react-test-renderer": "^18.2.0",
"typescript": "^4.3.x"
"react-test-renderer": "^18.2.0"
},
"jest": {
"coverageReporters": [
Expand Down
94 changes: 94 additions & 0 deletions src/Model/Adapters/Adapter_SoundFont_to_SoundMaker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import SoundFontLibraryNames from "data/SoundFontLibraryNames";
import Soundfont from "soundfont-player";
import Adapter_X_to_SoundMaker from "./Adapter_X_to_SoundMaker";

//TODO: make some adaptor pattern to implement different sound libraries: Sounds, Choose instrument, StartSound, StopSound
//TODO: Note that you must change the the list of availlable sounds in wholeApp when changing lib
class Adapter_SoundFont_to_SoundMaker extends Adapter_X_to_SoundMaker {
/*
Module handling all making of sounds.
Made as a Component so it updates when a new instrument is made, but never renders.
So far only handles the Piano module from tonejs.
*/
// constructor(props) {
// super(props);
// // this.instrumentSound = props.instrumentSound;
// // this.velocities = props.velocities;
// // this.synth = this.chooseInstrument();
// }
constructor(props) {
super(props);
this.soundfont = Soundfont;
this.instrumentSound = props.instrumentSound;
this.velocities = props.velocities;
this.ac = new AudioContext();
this.synth = this.chooseInstrument();
this.playingNotes = {};
// this.releaseNotes = [];
}
Instruments = SoundFontLibraryNames;

chooseInstrument() {
if (this.Instruments.some((inst) => inst.name === this.instrumentSound)) {
if (this.synth) {
this.synth.then((instrument) => {
Object.keys(this.playingNotes).forEach((tone) => {
this.playingNotes[tone].stop(this.ac.currentTime);
});
});
}
return Soundfont.instrument(this.ac, this.instrumentSound, {
// soundfont: "FluidR3_GM",
soundfont: "MusyngKite",
gain: 2.0,
adsr: [0, 0.3, 0.2, 1],
// loop: false,
loop: !(
this.instrumentSound.includes("piano") ||
this.instrumentSound.includes("guitar") ||
this.instrumentSound.includes("bass") ||
this.instrumentSound.includes("clavinet")
),
});
} else {
return Soundfont.instrument(this.ac, "acoustic_grand_piano", {
soundfont: "FluidR3_GM",
gain: 2.0,
});
}
}
initInstrument() {
// this.synth;
}

getState(note) {
return this.ac.state;
}

resumeSound(tone) {}

startSound(note) {
if (this.playingNotes.hasOwnProperty(note)) {
return;
}
this.synth.then((instrument) => {
this.playingNotes[note] = instrument.play(note);
});
}

stopSound(note) {
if (this.playingNotes.hasOwnProperty(note)) {
// this.playingNotes.delete(note)
this.synth.then((instrument) => {
this.playingNotes[note].stop(this.ac.currentTime);
delete this.playingNotes[note];
});
}
}

render() {
return null;
}
}

export default Adapter_SoundFont_to_SoundMaker;
81 changes: 81 additions & 0 deletions src/Model/Adapters/Adapter_Tonejs_to_SoundMaker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// import SoundFontLibraryNames from "data/SoundFontLibraryNames";
import { Component } from "react";
import { Piano } from "@tonejs/piano";
import * as Tone from "tone";
import TonejsSoundsNames from "data/TonejsSoundNames";
//TODO: make some adaptor pattern to implement different sound libraries: Sounds, Choose instrument, StartSound, StopSound
class Adapter_Tonejs_to_SoundMaker extends Component {
/*
Module handling all making of sounds.
Made as a Component so it updates when a new instrument is made, but never renders.
So far only handles the Piano module from tonejs.
*/
constructor(props) {
super(props);
this.sound = Tone;
this.instrumentSound = props.instrumentSound;
this.velocities = props.velocities;
//this.volume = options.volume;
this.synth = this.chooseInstrument();
// this.initInstrument();
}

// startSound =(note) =>{};
// stopSound = (note) =>{};
Instruments = TonejsSoundsNames;
chooseInstrument() {
let tempSynth = {};
switch (this.instrumentSound) {
//TODO: Uncomm and implement some piano sound
case "piano":
tempSynth = new Piano({
velocities: this.velocities,
}).toDestination();

tempSynth.load();
break;

default:
tempSynth = new Tone.PolySynth(Tone.AMSynth).toDestination();
break;
}

return tempSynth;
}

initInstrument() {
this.synth.load();
}

getState(tone) {
return this.sound.context.state;
}

resumeSound(tone) {
this.sound.context.resume();
}

startSound(note) {
if (this.instrumentSound === "piano") {
this.synth.keyDown({ note: note });
} else {
const now = Tone.now();
this.synth.triggerAttack(note, now);
}
}

stopSound(note) {
if (this.instrumentSound === "piano") {
this.synth.keyUp({ note: note });
} else {
const now = Tone.now();
this.synth.triggerRelease([note], now);
}
}

render() {
return null;
}
}

export default Adapter_Tonejs_to_SoundMaker;
45 changes: 45 additions & 0 deletions src/Model/Adapters/Adapter_X_to_SoundMaker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Component } from "react";
//TODO: make some adaptor pattern to implement different sound libraries: Sounds, Choose instrument, StartSound, StopSound
class Adapter_X_to_SoundMaker extends Component {
/*
Module handling all making of sounds.
Made as a Component so it updates when a new instrument is made, but never renders.
So far only handles the Piano module from tonejs.
*/
// constructor(props) {
// super(props);
// // this.instrumentSound = props.instrumentSound;
// // this.velocities = props.velocities;
// // this.synth = this.chooseInstrument();
// }
Instruments = [{ name: "Not Implemented" }];

chooseInstrument() {
throw new Error("Not implemented");
}
initInstrument() {
throw new Error("Not implemented");
}

getState(note) {
throw new Error("Not implemented");
}

resumeSound(tone) {
throw new Error("Not implemented");
}

startSound(note) {
throw new Error("Not implemented");
}

stopSound(note) {
throw new Error("Not implemented");
}

render() {
return null;
}
}

export default Adapter_X_to_SoundMaker;
82 changes: 30 additions & 52 deletions src/Model/SoundMaker.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,56 @@
// import SoundFontLibraryNames from "data/SoundFontLibraryNames";
import { Component } from "react";
import { Piano } from "@tonejs/piano";
import * as Tone from "tone";

import sf_Adapter_to_SoundMaker from "./Adapters/Adapter_SoundFont_to_SoundMaker";
import ts_Adapter_to_SoundMaker from "./Adapters/Adapter_Tonejs_to_SoundMaker";
//TODO: make some adaptor pattern to implement different sound libraries: Sounds, Choose instrument, StartSound, StopSound
class SoundMaker extends Component {
/*
Module handling all making of sounds.
Made as a Component so it updates when a new instrument is made, but never renders.
So far only handles the Piano module from tonejs.
*/
/*
Module handling all making of sounds.
Made as a Component so it updates when a new instrument is made, but never renders.
So far only handles the Piano module from tonejs.
*/
constructor(props) {
super(props);
this.sound = Tone;
this.instrumentSound = props.instrumentSound;
this.velocities = props.velocities;
//this.volume = options.volume;
this.synth = this.chooseInstrument();
// this.initInstrument();
// this.instrumentSound = props.instrumentSound;
// this.velocities = props.velocities;
// this.synth = this.chooseInstrument();
// this.soundMakerAdapter = new Adapter_to_SoundMaker(props);
this.selectedAdaptor = "soundfont-player";
this.soundMakerAdapters = {
"soundfont-player": new sf_Adapter_to_SoundMaker(props),
"tonejs-player": new ts_Adapter_to_SoundMaker(props),
};
this.soundMakerAdapter = this.soundMakerAdapters[this.selectedAdaptor];
}

// startSound =(note) =>{};
// stopSound = (note) =>{};
// Instruments = () => SoundFontLibraryNames; //this.soundMakerAdapter.Instruments;
Instruments = () => this.soundMakerAdapter.Instruments;

chooseInstrument() {
var tempSynth = {};
switch (this.instrumentSound) {
//TODO: Uncomm and implement some piano sound
case "piano":
tempSynth = new Piano({
velocities: this.velocities,
}).toDestination();

tempSynth.load();
break;

default:
tempSynth = new Tone.PolySynth(Tone.AMSynth).toDestination();
break;
}

return tempSynth;
this.soundMakerAdapter.chooseInstrument();
}

initInstrument() {
this.synth.load();
this.soundMakerAdapter.initInstrument();
}

getState() {
return this.sound.context.state;
getState(note) {
return this.soundMakerAdapter.getState();
}

resumeSound() {
this.sound.context.resume();
resumeSound(note) {
this.soundMakerAdapter.resumeSound(note);
}

startSound(note) {
if (this.instrumentSound === "piano") {
this.synth.keyDown({ note: note });
} else {
const now = Tone.now();
this.synth.triggerAttack(note, now);
}
this.soundMakerAdapter.startSound(note);
}

stopSound(note) {
if (this.instrumentSound === "piano") {
this.synth.keyUp({ note: note });
} else {
const now = Tone.now();
this.synth.triggerRelease([note], now);
}
this.soundMakerAdapter.stopSound(note);
}

render() {
return null;
return this.soundMakerAdapter.render();
}
}

Expand Down
Loading