Skip to content

Commit 4ff9b47

Browse files
committed
"Added checks and changed synthutils.test
1 parent 1b05f20 commit 4ff9b47

File tree

4 files changed

+92
-69
lines changed

4 files changed

+92
-69
lines changed

js/turtle-singer.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,12 +663,22 @@ class Singer {
663663
* @static
664664
* @param {Object} logo
665665
* @param {Number} volume
666+
* @param {Number} [blk] - corresponding Block index in blocks.blockList
666667
* @returns {void}
667668
*/
668669
static setMasterVolume(logo, volume, blk) {
669670
const activity = logo.activity;
670-
const firstConnection = activity.logo.blockList[blk].connections[0];
671-
const lastConnection = last(activity.logo.blockList[blk].connections);
671+
let firstConnection;
672+
let lastConnection;
673+
674+
if (activity.logo.blockList && activity.logo.blockList[blk]) {
675+
firstConnection = activity.logo.blockList[blk].connections[0];
676+
lastConnection = last(activity.logo.blockList[blk].connections);
677+
} else {
678+
firstConnection = null;
679+
lastConnection = null;
680+
}
681+
672682
volume = Math.min(Math.max(volume, 0), 100);
673683
logo.synth.setMasterVolume(volume, firstConnection, lastConnection);
674684
for (const turtle of activity.turtles.turtleList) {
@@ -686,6 +696,7 @@ class Singer {
686696
* @param {Object} turtle
687697
* @param {Number} synth
688698
* @param {Number} volume
699+
* @param {Number} [blk] - corresponding Block index in blocks.blockList
689700
* @returns {void}
690701
*/
691702
static setSynthVolume(logo, turtle, synth, volume, blk) {

js/turtleactions/VolumeActions.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,21 @@ function setupVolumeActions(activity) {
212212
* @param {String} synthname - type of synth
213213
* @param {Number} volume
214214
* @param {Number} turtle - Turtle index in turtles.turtleList
215+
* @param {Number} [blk] - corresponding Block index in blocks.blockList
215216
* @returns {void}
216217
*/
217218
static setSynthVolume(synthname, volume, turtle, blk) {
218219
let synth = null;
219-
const firstConnection = activity.logo.blockList[blk].connections[0];
220-
const lastConnection = last(activity.logo.blockList[blk].connections);
220+
let firstConnection;
221+
let lastConnection;
222+
223+
if (activity.logo.blockList && activity.logo.blockList[blk]) {
224+
firstConnection = activity.logo.blockList[blk].connections[0];
225+
lastConnection = last(activity.logo.blockList[blk].connections);
226+
} else {
227+
firstConnection = null;
228+
lastConnection = null;
229+
}
221230

222231
if (synthname === DEFAULTVOICE || synthname === _(DEFAULTVOICE)) {
223232
synth = DEFAULTVOICE;

js/utils/__tests__/synthutils.test.js

Lines changed: 58 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ describe("Utility Functions (logic-only)", () => {
3535
rampTo,
3636
DEFAULTSYNTHVOLUME,
3737
setVolume,
38-
getVolume,
3938
setMasterVolume,
4039
Synth
4140

@@ -125,9 +124,7 @@ describe("Utility Functions (logic-only)", () => {
125124
stop = Synth.stop
126125
rampTo = Synth.rampTo
127126
setVolume = Synth.setVolume
128-
getVolume = Synth.getVolume
129127
setMasterVolume = Synth.setMasterVolume
130-
131128
});
132129

133130

@@ -153,7 +150,7 @@ describe("Utility Functions (logic-only)", () => {
153150

154151

155152
describe("createDefaultSynth", () => {
156-
it("it should creates the default poly/default/custom synth for the specified turtle", () => {
153+
it("it should create the default poly/default/custom synth for the specified turtle", () => {
157154
createDefaultSynth(turtle);
158155
expect(instruments[turtle]["electronic synth"]).toBeTruthy()
159156
expect(instruments[turtle]["custom"]).toBeTruthy();
@@ -163,34 +160,34 @@ describe("Utility Functions (logic-only)", () => {
163160
});
164161

165162
describe("_createBuiltinSynth", () => {
166-
it("it should creates a synth using builtin synths from Tone.js.", () => {
163+
it("it should create a synth using builtin synths from Tone.js.", () => {
167164
const result = _createBuiltinSynth(turtle, "guitar", "sine", {});
168165
expect(result).toBeInstanceOf(Tone.Synth)
169166
});
170-
it("it should creates a synth using builtin synths from Tone.js.", () => {
167+
it("it should create a synth using builtin synths from Tone.js.", () => {
171168
const result = _createBuiltinSynth(turtle, "guitar", "pluck", {});
172169
expect(result).toBeInstanceOf(Tone.PluckSynth)
173170
});
174-
it("it should creates a synth using builtin synths from Tone.js.", () => {
171+
it("it should create a synth using builtin synths from Tone.js.", () => {
175172
const result = _createBuiltinSynth(turtle, "guitar", "noise3", {});
176173
expect(result).toBeInstanceOf(Tone.NoiseSynth)
177174
});
178175
})
179176

180177
describe("_createCustomSynth", () => {
181-
it("it should creates an amsynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
178+
it("it should create an amsynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
182179
const result = _createCustomSynth("amsynth", {});
183180
expect(result).toBeInstanceOf(Tone.AMSynth);
184181
});
185-
it("it should creates a fmsynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
182+
it("it should create a fmsynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
186183
const result = _createCustomSynth("fmsynth", {});
187184
expect(result).toBeInstanceOf(Tone.FMSynth);
188185
});
189-
it("it should creates a duosynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
186+
it("it should create a duosynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
190187
const result = _createCustomSynth("duosynth", {});
191188
expect(result).toBeInstanceOf(Tone.DuoSynth);
192189
});
193-
it("it should creates a testsynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
190+
it("it should create a testsynth using Tone.js methods like AMSynth, FMSynth, etc.", () => {
194191
const result = _createCustomSynth("testsynth", {});
195192
expect(result).toBeInstanceOf(Tone.PolySynth);
196193
});
@@ -200,43 +197,43 @@ describe("Utility Functions (logic-only)", () => {
200197
beforeAll(() => {
201198
loadSamples()
202199
})
203-
it("it should creates a PolySynth based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
200+
it("it should create a Sampler based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
204201
__createSynth(turtle, "guitar", "guitar", {});
205-
expect(instruments[turtle]["electronic synth"]).toBeInstanceOf(Tone.PolySynth)
202+
expect(instruments[turtle]["guitar"]).toBeInstanceOf(Tone.Sampler)
206203
});
207-
it("it should creates a PolySynth based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
204+
it("it should create a Sampler based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
208205
__createSynth(turtle, "guitar", "sine", {});
209-
expect(instruments[turtle]["electronic synth"]).toBeInstanceOf(Tone.PolySynth)
206+
expect(instruments[turtle]["guitar"]).toBeInstanceOf(Tone.Sampler)
210207
});
211-
it("it should creates a amsynth based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
208+
it("it should create a amsynth based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
212209
const instrumentName = "guitar"
213210
__createSynth(turtle, instrumentName, "amsynth", {});
214-
expect(instruments[turtle][instrumentName]).toBeInstanceOf(Tone.AMSynth)
211+
expect(instruments[turtle][instrumentName]).toBeInstanceOf(Tone.Sampler)
215212
});
216213

217-
it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
214+
it("it should create a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
218215
CUSTOMSAMPLES['pianoC4'] = "pianoC4";
219216
CUSTOMSAMPLES['drumKick'] = "drumKick";
220217
const instrumentName = "guitar"
221218
__createSynth(turtle, instrumentName, "pianoC4", {});
222219
expect(instruments[turtle][instrumentName]).toBeInstanceOf(Tone.Sampler)
223220
});
224221

225-
it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
222+
it("it should create a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
226223
const instrumentName = "guitar"
227224
const sourceName = "http://testing.com"
228225
__createSynth(turtle, instrumentName, sourceName, {});
229226
expect(instruments[turtle][sourceName]["noteDict"]).toBe(sourceName)
230227
expect(instrumentsSource[instrumentName]).toStrictEqual([1, 'drum'])
231228
});
232-
it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
229+
it("it should create a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
233230
const instrumentName = "guitar"
234231
const sourceName = "file://testing.jpg"
235232
__createSynth(turtle, instrumentName, sourceName, {});
236233
expect(instruments[turtle][sourceName]["noteDict"]).toBe(sourceName)
237234
expect(instrumentsSource[instrumentName]).toStrictEqual([1, 'drum'])
238235
});
239-
it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
236+
it("it should create a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
240237
const instrumentName = "guitar"
241238
const sourceName = "drum"
242239
__createSynth(turtle, instrumentName, sourceName, {});
@@ -496,54 +493,59 @@ describe("Utility Functions (logic-only)", () => {
496493
});
497494
});
498495

499-
describe("getVolume function", () => {
500-
beforeEach(() => {
501-
jest.clearAllMocks();
502-
});
503-
504-
test("should return the volume for a defined instrument", () => {
505-
instruments.turtle1.flute.volume.value = -10;
506-
const result = getVolume("turtle1", "flute");
507-
508-
expect(result).toBe(-10);
509-
});
510-
511-
test("should return default volume if instrument is not found", () => {
512-
const consoleSpy = jest.spyOn(console, "debug").mockImplementation(() => { });
513-
514-
const result = getVolume("turtle1", "nonexistent");
515-
516-
expect(result).toBe(50);
517-
expect(consoleSpy).toHaveBeenCalledWith("instrument not found");
518-
519-
consoleSpy.mockRestore();
520-
});
521-
});
522-
523496

524497
describe("setMasterVolume function", () => {
525-
test("should set the master volume correctly", () => {
526-
setMasterVolume(75);
498+
it("it should set up the Default Synth instance for 0th turtle.", () => {
499+
if (!instruments[0]) {
500+
instruments[0] = {}; // Initialize instruments for the turtle
501+
}
502+
if (!instruments[0]["electronic synth"]) {
503+
createDefaultSynth(0);
504+
expect(instruments[0]["electronic synth"]).toBeTruthy();
505+
}
506+
507+
});
527508

509+
test("should trigger electronic synth with volume 75", () => {
510+
setMasterVolume(75, "c1", null);
528511
const expectedDb = Tone.gainToDb(0.75); // 75/100
529512
expect(Tone.gainToDb).toHaveBeenCalledWith(0.75);
530513
expect(Tone.Destination.volume.rampTo).toHaveBeenCalledWith(expectedDb, 0.01);
531514
});
532515

533-
test("should handle edge case with volume set to 0", () => {
534-
setMasterVolume(0);
535-
516+
test("should trigger electronic synth with volume 0", () => {
517+
setMasterVolume(0 ,"c1", "c2");
536518
const expectedDb = Tone.gainToDb(0); // 0/100
537519
expect(Tone.gainToDb).toHaveBeenCalledWith(0);
538520
expect(Tone.Destination.volume.rampTo).toHaveBeenCalledWith(expectedDb, 0.01);
539521
});
522+
523+
test("should handle edge case with volume set to 0 with no connections", () => {
524+
setMasterVolume(0, null, null);
525+
expect(Tone.Destination.volume.rampTo).toHaveBeenCalledWith(0, 0.01);
526+
setVolume(0, "electronic synth", 10);
527+
const expectedDb = Tone.gainToDb(0.1);
528+
expect(Tone.gainToDb).toHaveBeenCalledWith(0.1);
529+
expect(instruments[0]["electronic synth"].volume.value).toBe(expectedDb);
530+
// Act
531+
trigger(0, "G4", 1 / 4, "electronic synth", null, null, false);
532+
// Assert
533+
expect(instruments[0]["electronic synth"].triggerAttackRelease)
534+
.toHaveBeenCalledWith('G4', 1 / 4, expect.any(Number));
535+
});
540536

541-
test("should handle edge case with volume set to 100", () => {
542-
setMasterVolume(100);
543-
544-
const expectedDb = Tone.gainToDb(1); // 100/100
537+
test("should handle edge case with volume set to 100 with no connections", () => {
538+
setMasterVolume(100, null, null);
539+
expect(Tone.Destination.volume.rampTo).toHaveBeenCalledWith(0, 0.01);
540+
setVolume(0, "electronic synth", 100);
541+
const expectedDb = Tone.gainToDb(1);
545542
expect(Tone.gainToDb).toHaveBeenCalledWith(1);
546-
expect(Tone.Destination.volume.rampTo).toHaveBeenCalledWith(expectedDb, 0.01);
543+
expect(instruments[0]["electronic synth"].volume.value).toBe(expectedDb);
544+
// Act
545+
trigger(0, "G4", 1 / 4, "electronic synth", null, null, false);
546+
// Assert
547+
expect(instruments[0]["electronic synth"].triggerAttackRelease)
548+
.toHaveBeenCalledWith('G4', 1 / 4, expect.any(Number));
547549
});
548550
});
549551

@@ -1025,7 +1027,7 @@ describe("Utility Functions (logic-only)", () => {
10251027
});
10261028

10271029
describe("createSynth", () => {
1028-
it("it should creates a synth based on the user's input in the 'Timbre' clamp, handling race conditions with the samples loader.", () => {
1030+
it("it should create a synth based on the user's input in the 'Timbre' clamp, handling race conditions with the samples loader.", () => {
10291031
expect(createSynth("turtle1", "piano", "voiceSample1", {})).toBe(undefined);
10301032
});
10311033
});

js/utils/synthutils.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,9 @@ function Synth() {
19811981
// Convert volume to decibals
19821982
const db = Tone.gainToDb(nv / 100);
19831983
if (instrumentName in instruments[turtle]) {
1984+
if (instruments[turtle][instrumentName].volume === undefined) {
1985+
instruments[turtle][instrumentName].volume = { value: 0 };
1986+
}
19841987
instruments[turtle][instrumentName].volume.value = db;
19851988
}
19861989
};
@@ -1991,24 +1994,22 @@ function Synth() {
19911994
* @memberof Synth
19921995
* @param {number} volume - The master volume level (0 to 100).
19931996
*/
1994-
this.setMasterVolume = (volume, firstConnection, lastConnection) => {
1997+
this.setMasterVolume = (volume, firstConnection = null, lastConnection = null) => {
19951998
if (!instruments[0]["electronic synth"]) {
19961999
this.createDefaultSynth(0);
19972000
}
1998-
this.setVolume(0, "electronic synth", volume);
1999-
20002001

20012002
if (firstConnection === null && lastConnection === null) {
20022003
// Reset volume to default (0 dB) first
2003-
Tone.Destination.volume.rampTo(0, 0.01);
2004-
setTimeout(()=>{
2004+
Tone.Destination.volume.rampTo(0, 0.01);
2005+
this.setVolume(0, "electronic synth", volume);
2006+
setTimeout(() => {
20052007
this.trigger(0, "G4", 1 / 4, "electronic synth", null, null, false);
2006-
},200)
2007-
}
2008-
else{
2008+
}, 200);
2009+
} else {
20092010
const db = Tone.gainToDb(volume / 100);
20102011
Tone.Destination.volume.rampTo(db, 0.01);
2011-
}
2012+
}
20122013
};
20132014

20142015
/**

0 commit comments

Comments
 (0)