A modern web-based sample generator built with Tone.js and TypeScript. This project features the CrystalHarp synthesizer and provides real-time parameter control with offline audio rendering capabilities.
- 🎹 CrystalHarp Synthesizer: Beautiful pluck synthesizer with configurable parameters
- 🔧 Real-time Parameter Control: Interactive sliders for tweaking sound parameters
- 🎚️ Effect Processing: Built-in delay effect with feedback control
- 🎼 Offline Sample Generation: Generate perfect quality samples using Tone.js offline rendering
- 💾 Sample Export: Download samples as WAV files for use in music production
- 🎨 Modern UI: Beautiful, responsive interface with dark theme
- 🚀 Fast Development: Built with Vite for lightning-fast hot reload
- Tone.js - Web Audio API synthesis library
- TypeScript - Type-safe JavaScript development
- Vite - Fast build tool and development server
- CSS Custom Properties - Modern styling with CSS variables
- Web Audio API - Native browser audio processing
- Node.js (v18 or higher)
- npm or yarn
-
Clone the repository:
git clone <repository-url> cd CrystalHarp-Sampler
-
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Open your browser and navigate to
http://localhost:5173
Try the live application on GitHub Pages!
This project is configured for easy deployment to GitHub Pages:
- Fork or clone this repository
- Update URLs in
package.json
with your GitHub username - Push to GitHub and enable GitHub Pages in repository settings
- Automatic deployment via GitHub Actions
For detailed deployment instructions, see DEPLOYMENT.md.
# Manual deployment (after setup)
npm run deploy
# Or push to main branch for automatic deployment
git push origin main
-
Start Audio Context: Click the "Start Audio Context" button to initialize the audio system
-
Adjust Parameters: Use the sliders to modify the CrystalHarp synthesizer parameters:
- Attack Noise: Controls the initial pluck noise burst (0.01-1) - PluckSynth mode only
- Dampening: Controls string dampening frequency (1000-10000 Hz) - PluckSynth mode only
- Resonance: Controls string resonance (0-0.99) - PluckSynth mode only
- Release: Controls note release time (0.1-5 seconds) - Available in both modes
- Delay Time: Controls delay effect timing (0-1 seconds) - Available in both modes
- Delay Feedback: Controls delay feedback amount (0-0.9) - Available in both modes
- Output Volume: Controls final output level (0-2x gain) - Available in both modes
Note: Parameters are automatically shown/hidden based on the current synth mode for clarity.
-
Play Notes: Select a note and click "Play Note" to hear the current sound
-
Continuous Play: Use "Continuous Play" for hands-free parameter tweaking (plays every 3 seconds)
-
Consistent Mode:
- Enabled (default): Uses DeterministicPluckSynth - identical PluckSynth-like sounds every time
- Disabled: Uses PluckSynth with natural Karplus-Strong variation for organic sound
-
Generate Samples: Set sample length and click "Generate & Download Sample" to create and download audio files
Technical Note: PluckSynth uses the Karplus-Strong algorithm which includes inherent randomness in the noise source for natural pluck variation. The "Consistent Mode" (default) uses a custom DeterministicPluckSynth that replicates the Karplus-Strong algorithm but with a deterministic noise source, ensuring identical sounds on every trigger while maintaining the characteristic pluck timbre. All sound parameters are available in both modes.
The CrystalHarp is based on Tone.js's PluckSynth with carefully tuned parameters:
const crystalHarp = new Tone.PluckSynth({
attackNoise: 0.1,
dampening: 6000,
resonance: 0.9,
release: 2,
}).connect(delay);
This creates a beautiful, crystalline harp-like sound perfect for ambient music, sound design, and musical production.
All synthesizer parameters work in both standard and consistent modes:
-
Attack Noise: Controls the duration of the initial noise burst. Higher values create a longer "pluck" sound at the beginning.
-
Dampening: Controls the brightness of the sound by adjusting the lowpass filter cutoff frequency. Lower values create darker, more muffled tones while higher values create brighter sounds.
-
Resonance: Controls how much energy is preserved in the feedback loop. Higher values create longer sustain and more pronounced harmonic content.
-
Release: Controls how quickly the sound decays after the initial attack. Lower values create short, percussive sounds while higher values create longer sustained notes.
The "Consistent Mode" implements a custom DeterministicPluckSynth
class that solves the inherent randomness in Tone.js's PluckSynth. Here's how:
The Problem: Tone.js PluckSynth uses the Karplus-Strong algorithm, which includes random noise to simulate natural string variations. The randomness comes from Math.random()
calls in the noise source that pick different starting positions in the noise buffer on each trigger.
The Solution: Our DeterministicPluckSynth
:
- Replicates the exact Karplus-Strong chain: Noise → LowpassCombFilter → Output
- Uses the same pink noise and comb filter as the original PluckSynth
- Eliminates randomness by ensuring the noise source always starts from the same state
- Maintains all the characteristic PluckSynth parameters and behavior
Result: Identical pluck sounds on every trigger while preserving the unique Karplus-Strong timbre that makes PluckSynth special.
// Custom implementation that maintains PluckSynth's exact signal chain
class DeterministicPluckSynth {
private _noise: Tone.Noise; // Pink noise source
private _lfcf: Tone.LowpassCombFilter; // Karplus-Strong filter
// ... identical parameter control to PluckSynth
}
src/
├── audio/
│ ├── SampleGenerator.ts # Main CrystalHarp synthesizer with DeterministicPluckSynth
│ └── SampleRenderer.ts # Offline audio rendering for sample generation
├── ui/
│ └── UIController.ts # UI interaction handling (legacy)
├── main.ts # Application entry point and UI logic
├── style.css # Modern UI styles with CSS variables
└── vite-env.d.ts # TypeScript environment definitions
public/
├── .nojekyll # Prevents GitHub Pages Jekyll processing
└── vite.svg # Application icon
.github/
└── workflows/
└── deploy.yml # GitHub Actions deployment workflow
- Chrome/Chromium (recommended)
- Firefox
- Safari (partial - some recording features may be limited)
- Edge
Note: Audio recording requires modern browser support for MediaRecorder API and getUserMedia/getDisplayMedia.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Benj (SoundCloud) for the original idea and inspiration
- Tone.js team for the amazing Web Audio library
- The web audio community for pushing the boundaries of browser-based audio
- Audio recording may require user permission for microphone access
- Some browsers may not support all audio recording features
- Sample quality depends on browser's audio processing capabilities
For questions, suggestions, or collaboration opportunities, please open an issue on GitHub.
Built with ❤️ for music producers and sound designers