Skip to content
Merged
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
19 changes: 14 additions & 5 deletions js/__tests__/turtle-singer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ global.isCustomTemperament = mockGlobals.isCustomTemperament;
global.getStepSizeUp = mockGlobals.getStepSizeUp;
global.numberToPitch = mockGlobals.numberToPitch;
global.pitchToNumber = mockGlobals.pitchToNumber;
global.last = jest.fn((array) => array[array.length - 1]);


describe('Singer Class', () => {
let turtleMock;
Expand Down Expand Up @@ -54,6 +56,12 @@ describe('Singer Class', () => {
inPitchDrumMatrix: false,
inMatrix: false,
clearNoteParams: jest.fn(),
// Add blockList here
blockList: {
mockBlk: {
connections: [0, 0]
}
}
},
};

Expand Down Expand Up @@ -99,12 +107,13 @@ describe('Singer Class', () => {
});

test('should set master volume correctly', () => {
Singer.setMasterVolume(logoMock, 50);
expect(logoMock.synth.setMasterVolume).toHaveBeenCalledWith(50);
Singer.setMasterVolume(logoMock, 50, 'mockBlk');
expect(logoMock.synth.setMasterVolume).toHaveBeenCalledWith(50, 0, 0);
});

test('should set synth volume correctly', () => {
Singer.setSynthVolume(logoMock, turtleMock, 'noise1', 80);
expect(logoMock.synth.setVolume).toHaveBeenCalledWith(turtleMock, 'noise1', 80 / 25);
});
Singer.setSynthVolume(logoMock, turtleMock, 'noise1', 80, 'mockBlk');
expect(logoMock.synth.setVolume).toHaveBeenCalledWith(turtleMock, 'noise1', 80 / 25, 'mockBlk');
});

});
28 changes: 17 additions & 11 deletions js/utils/__tests__/synthutils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,36 +209,36 @@ describe("Utility Functions (logic-only)", () => {
expect(instruments[turtle]["electronic synth"]).toBeInstanceOf(Tone.PolySynth)
});
it("it should creates a amsynth based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
const instrumentName = "guitar"
let instrumentName = "poly"
__createSynth(turtle, instrumentName, "amsynth", {});
expect(instruments[turtle][instrumentName]).toBeInstanceOf(Tone.AMSynth)
});

it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
CUSTOMSAMPLES['pianoC4'] = "pianoC4";
CUSTOMSAMPLES['drumKick'] = "drumKick";
const instrumentName = "guitar"
let instrumentName = "piano"
__createSynth(turtle, instrumentName, "pianoC4", {});
expect(instruments[turtle][instrumentName]).toBeInstanceOf(Tone.Sampler)
});

it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
const instrumentName = "guitar"
const sourceName = "http://testing.com"
let instrumentName = "drumKick"
let sourceName = "http://example.com/drumKick.wav"
__createSynth(turtle, instrumentName, sourceName, {});
expect(instruments[turtle][sourceName]["noteDict"]).toBe(sourceName)
expect(instrumentsSource[instrumentName]).toStrictEqual([1, 'drum'])
});
it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
const instrumentName = "guitar"
const sourceName = "file://testing.jpg"
let instrumentName = "guitar"
let sourceName = "file://testing.wav"
__createSynth(turtle, instrumentName, sourceName, {});
expect(instruments[turtle][sourceName]["noteDict"]).toBe(sourceName)
expect(instrumentsSource[instrumentName]).toStrictEqual([1, 'drum'])
});
it("it should creates a CUSTOMSAMPLES based on the specified parameters, either using samples, built-in synths, or custom synths", () => {
const instrumentName = "guitar"
const sourceName = "drum"
let instrumentName = "snare drum"
let sourceName = "drum"
__createSynth(turtle, instrumentName, sourceName, {});
expect(instrumentsSource[instrumentName]).toStrictEqual([1, 'drum'])
});
Expand Down Expand Up @@ -553,9 +553,9 @@ describe("Utility Functions (logic-only)", () => {

test('should call start() for drum instruments', () => {
// Arrange
const instrumentName = 'guitar';
const instrumentName = 'guitar'; // Assuming 'snare' is a drum
const note = 'C4';

// Act
startSound(turtle, instrumentName, note);

Expand All @@ -564,6 +564,7 @@ describe("Utility Functions (logic-only)", () => {
expect(instruments[turtle][instrumentName].triggerAttack).not.toHaveBeenCalled();
});


test('should call triggerAttack() for non-drum instruments', () => {
// Arrange
const instrumentName = 'flute';
Expand Down Expand Up @@ -1024,9 +1025,14 @@ describe("Utility Functions (logic-only)", () => {
});
});


describe("createSynth", () => {
it("it should creates a synth based on the user's input in the 'Timbre' clamp, handling race conditions with the samples loader.", () => {
expect(createSynth("turtle1", "piano", "voiceSample1", {})).toBe(undefined);
const turtle = "turtle1"; // Use const or let
const instrumentName = "piano"; // Localize declaration
const sourceName = "voice recording"; // Localize declaration
expect(createSynth(turtle, instrumentName, sourceName, {})).toBe(undefined);
});
});

});
13 changes: 13 additions & 0 deletions js/utils/__tests__/tonemock.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Sampler {
this.stop = jest.fn().mockReturnThis();
this.triggerAttack = jest.fn().mockReturnThis();
this.volume = {
value: 0,
linearRampToValueAtTime: jest.fn().mockImplementation()
}
this.triggerRelease = jest.fn().mockReturnThis();
Expand Down Expand Up @@ -55,7 +56,15 @@ class Synth {
constructor(synthOptions) {
this.synthOptions = synthOptions
this.triggerAttackRelease = jest.fn().mockReturnThis();
this.stop = jest.fn().mockReturnThis();
this.triggerAttack = jest.fn().mockReturnThis();
this.triggerRelease = jest.fn().mockReturnThis();
this.start = jest.fn().mockReturnThis();
this.chain = jest.fn().mockReturnThis();
this.volume = {
value: 0,
linearRampToValueAtTime: jest.fn().mockImplementation()
};
}
toDestination() {
return this;
Expand All @@ -77,6 +86,10 @@ class PolySynth {
this.triggerAttack = jest.fn().mockReturnThis();
this.start = jest.fn().mockReturnThis();
this.triggerAttackRelease = jest.fn().mockReturnThis();
this.volume = {
value: 0,
linearRampToValueAtTime: jest.fn().mockImplementation()
};
}

toDestination() {
Expand Down
29 changes: 29 additions & 0 deletions js/utils/synthutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,7 @@ function Synth() {
* @param {Object} params - Additional parameters for synth configuration.
*/
this.__createSynth = (turtle, instrumentName, sourceName, params) => {
// Ensure the structure is initialized

this._loadSample(sourceName);
if (sourceName in this.samples.voice || sourceName in this.samples.drum) {
Expand All @@ -1384,6 +1385,10 @@ function Synth() {
)
}
} else if (sourceName in BUILTIN_SYNTHS) {
if (instruments[turtle] && instruments[turtle][instrumentName]) {
delete instruments[turtle][instrumentName];
}

if (!instruments[turtle][instrumentName]) {
instruments[turtle][instrumentName] = this._createBuiltinSynth(
turtle,
Expand All @@ -1393,7 +1398,12 @@ function Synth() {
);
}
} else if (sourceName in CUSTOM_SYNTHS) {
if (instruments[turtle] && instruments[turtle][instrumentName]) {
delete instruments[turtle][instrumentName];
}

if (!instruments[turtle][instrumentName]) {

instruments[turtle][instrumentName] = this._createCustomSynth(
sourceName,
params
Expand All @@ -1402,6 +1412,10 @@ function Synth() {

instrumentsSource[instrumentName] = [0, "poly"];
} else if (sourceName in CUSTOMSAMPLES) {
if (instruments[turtle] && instruments[turtle][instrumentName]) {
delete instruments[turtle][instrumentName];
}

if (!instruments[turtle][instrumentName]) {
instruments[turtle][instrumentName] = this._createSampleSynth(
turtle,
Expand Down Expand Up @@ -1953,6 +1967,21 @@ function Synth() {

synth.volume.linearRampToValueAtTime(db, Tone.now() + rampTime);
};

/**
* new Addtion
* Gets the volume for a specific instrument.
* @param {string} turtle - The name of the turtle (e.g., "turtle1").
* @param {string} instrumentName - The name of the instrument (e.g., "flute").
* @returns {number} The volume level in decibels or 50 if not found.
*/
this.getVolume = (turtle, instrumentName) => {
if (instruments[turtle] && instruments[turtle][instrumentName]) {
return instruments[turtle][instrumentName].volume.value;
}
console.debug("instrument not found");
return 50; // Default volume
}

/**
* Sets the volume of a specific instrument for a given turtle.
Expand Down
Loading