Create String Sounds with Tone.PluckSynth in Tone.js

This article guides you through implementing realistic physical modeling string sounds using Tone.PluckSynth in Tone.js. You will learn the core concepts behind the Karplus-Strong algorithm used by this synthesizer, how to configure its parameters to customize the acoustic qualities of the virtual string, and how to trigger string plucks in your web audio projects with clean, practical JavaScript code.

Understanding Tone.PluckSynth

Tone.PluckSynth uses the Karplus-Strong algorithm to simulate the sound of a plucked string. Instead of using traditional oscillators, it generates a short burst of noise (the “pluck”) and feeds it through a filtered delay line. The feedback loop causes the noise to decay into a pitched, harmonic waveform, mimicking the physical behavior of an acoustic string instrument like a guitar or harp.

Basic Implementation

To create a basic pluck sound, you need to import Tone.js, instantiate the Tone.PluckSynth class, connect it to the master output (toDestination()), and trigger a note using a user interaction (as browsers block autoplay audio).

Here is the minimal code required to get started:

import * as Tone from "tone";

// 1. Create and connect the PluckSynth
const pluck = new Tone.PluckSynth().toDestination();

// 2. Function to play a note
async function playString() {
  // Ensure the audio context is started
  await Tone.start();
  
  // Trigger the note "C4" immediately
  pluck.triggerAttack("C4");
}

// Example: Trigger the sound on a button click
document.getElementById("pluck-button").addEventListener("click", playString);

Unlike other synths in Tone.js, Tone.PluckSynth only utilizes triggerAttack to play a note. It does not require a triggerRelease because the physical model naturally decays based on its internal parameters.

Customizing the String Sound

You can alter the physical characteristics of the string by passing configuration options when instantiating the synth, or by modifying its properties dynamically. The three primary parameters are:

Advanced Configuration Example

Here is how to configure a damp, acoustic-sounding nylon guitar string:

const guitarString = new Tone.PluckSynth({
  attackNoise: 1.2,
  dampening: 4000, // Hertz
  resonance: 0.98   // Decays slowly
}).toDestination();

// Play a low E string note
guitarString.triggerAttack("E2");

Playing a Sequence

Because Tone.PluckSynth is highly responsive and polyphonically lightweight, it is ideal for rapid arpeggios and sequences. Below is an example of playing a rapid string pattern using Tone.Sequence:

const harp = new Tone.PluckSynth({
  attackNoise: 0.8,
  dampening: 5000,
  resonance: 0.95
}).toDestination();

const notes = ["C4", "E4", "G4", "B4", "C5"];

const sequence = new Tone.Sequence((time, note) => {
  harp.triggerAttack(note, time);
}, notes, "8n");

// Start the sequence and transport
Tone.getTransport().start();
sequence.start(0);