# Guitar Tuner Library A configurable client-side JavaScript library for guitar tuning with real-time pitch detection. Supports standard and alternate tunings for guitar, bass, ukulele, banjo, and custom instruments. **This library powers [tuningfork.co](https://tuningfork.co) - a free online instrument tuner.** ## Features - **Real-time pitch detection** using autocorrelation algorithm - **Multiple instruments**: Guitar, Bass, Ukulele, Banjo - **20+ preset tunings** including Standard, Drop D, Open G, DADGAD, and more - **Custom tunings** support via frequency arrays - **Browser-compatible**: Works in Chrome, Firefox, Safari, and Edge - **TypeScript support** with full type definitions - **Zero runtime dependencies** - **Small bundle size**: ~4KB gzipped (ESM) ## Installation ```bash npm install guitar-tuner ``` ## Quick Start ```javascript import { GuitarTuner } from 'guitar-tuner'; // Create a tuner instance const tuner = new GuitarTuner(); // Initialize with configuration await tuner.init({ instrument: 'guitar', tuning: 'standard', referenceFrequency: 440, tolerance: 5 }); // Listen for pitch detection events tuner.on('pitchDetected', (pitchInfo) => { console.log(`Frequency: ${pitchInfo.frequency.toFixed(2)} Hz`); console.log(`Note: ${pitchInfo.note}`); console.log(`Cents: ${pitchInfo.cents.toFixed(1)}`); console.log(`In tune: ${pitchInfo.inTune}`); }); // Start the tuner (requests microphone access) await tuner.start(); // Stop when done tuner.stop(); ``` ## Supported Instruments & Tunings ### Guitar (6-string) - Standard (E A D G B E) - Drop D - Open G - DADGAD - Half Step Down - Full Step Down - Drop C - Open D, Open E, Open A ### Bass - Standard 4-string (E A D G) - Standard 5-string (B E A D G) - Drop D (4-string) - Half Step Down (4-string) ### Ukulele - Standard C (G C E A) - Standard C with Low G - Baritone (D G B E) - D Tuning ### Banjo (5-string) - Open G (Standard) - Double C - Open D ## API Reference ### Constructor ```javascript const tuner = new GuitarTuner(); ``` ### Methods #### `init(config?: TunerConfig): Promise` Initialize the tuner with configuration options. ```javascript await tuner.init({ instrument: 'guitar', // Instrument type tuning: 'standard', // Tuning preset or custom array referenceFrequency: 440, // Reference frequency for A4 (Hz) tolerance: 5, // Tolerance in cents for "in tune" bufferSize: 4096, // Audio buffer size minCorrelation: 0.9 // Minimum correlation threshold }); ``` #### `start(): Promise` Start the tuner and request microphone access. ```javascript await tuner.start(); ``` #### `stop(): void` Stop the tuner and release resources. ```javascript tuner.stop(); ``` #### `setInstrument(instrument: string): void` Change the instrument. ```javascript tuner.setInstrument('bass4'); ``` #### `setTuning(tuning: string | number[]): void` Change the tuning (preset name or custom frequencies). ```javascript // Use preset tuner.setTuning('dropD'); // Use custom frequencies (Hz) tuner.setTuning([82.41, 110, 146.83, 196, 246.94, 329.63]); ``` #### `setReferenceFrequency(frequency: number): void` Set the reference frequency for A4. ```javascript tuner.setReferenceFrequency(432); // A4 = 432 Hz ``` #### `setTolerance(cents: number): void` Set the tolerance in cents for "in tune" detection. ```javascript tuner.setTolerance(10); // Within 10 cents = in tune ``` #### `on(event: TunerEventType, handler: Function): void` Register an event handler. ```javascript tuner.on('pitchDetected', (pitchInfo) => { // Handle pitch detection }); ``` #### `off(event: TunerEventType, handler: Function): void` Unregister an event handler. ```javascript tuner.off('pitchDetected', handler); ``` #### `destroy(): void` Clean up all resources and event handlers. ```javascript tuner.destroy(); ``` ### Static Methods #### `GuitarTuner.getInstruments(): string[]` Get list of available instruments. ```javascript const instruments = GuitarTuner.getInstruments(); // ['guitar', 'bass4', 'bass5', 'ukulele', 'banjo', ...] ``` #### `GuitarTuner.getTunings(instrument: string): string[]` Get list of available tunings for an instrument. ```javascript const tunings = GuitarTuner.getTunings('guitar'); // ['standard', 'dropD', 'openG', 'dadgad', ...] ``` ## Events ### `pitchDetected` Fired continuously while a pitch is detected. ```javascript tuner.on('pitchDetected', (pitchInfo) => { pitchInfo.frequency // Detected frequency in Hz pitchInfo.note // Nearest note name (e.g., 'E2', 'A4') pitchInfo.cents // Deviation in cents (-50 to +50) pitchInfo.correlation // Correlation value (0-1) pitchInfo.stringNumber // Matched string number (1-based) pitchInfo.targetFrequency // Target frequency for matched string pitchInfo.inTune // Whether pitch is within tolerance }); ``` ### `noteMatched` Fired when the detected pitch is close to a target note (within 50 cents). ```javascript tuner.on('noteMatched', (pitchInfo) => { // Same as pitchDetected }); ``` ### `inTune` Fired when the detected pitch is within the configured tolerance. ```javascript tuner.on('inTune', (pitchInfo) => { console.log('String is in tune!'); }); ``` ### `error` Fired when an error occurs. ```javascript tuner.on('error', (errorEvent) => { console.error(errorEvent.message); }); ``` ## Browser Compatibility The library works in all modern browsers that support: - Web Audio API - getUserMedia API - ES2020 features Tested on: - Chrome 90+ - Firefox 88+ - Safari 14+ (including iOS Safari) - Edge 90+ ### Safari Compatibility The library includes Safari-specific fixes: - WebKit prefix support for older Safari versions - Explicit AudioContext resume (required by Safari) - Proper microphone permission handling ## Advanced Usage ### Custom Tunings Create custom tunings by providing an array of frequencies: ```javascript tuner.setTuning([ 73.42, // D2 98.00, // G2 146.83, // D3 196.00, // G3 246.94, // B3 293.66 // D4 ]); ``` ### Using Utility Functions The library exports utility functions for frequency/note calculations: ```javascript import { frequencyToNoteName, calculateCents, midiToFrequency } from 'guitar-tuner'; const note = frequencyToNoteName(440); // 'A4' const cents = calculateCents(445, 440); // ~19.6 cents const freq = midiToFrequency(69); // 440 Hz ``` ### Accessing Tuning Presets ```javascript import { GUITAR_TUNINGS, BASS_TUNINGS } from 'guitar-tuner'; console.log(GUITAR_TUNINGS.standard); // { // name: 'Standard', // frequencies: [82.41, 110, 146.83, 196, 246.94, 329.63], // notes: ['E2', 'A2', 'D3', 'G3', 'B3', 'E4'] // } ``` ## Examples Check the `examples/` directory for a complete working demo with UI. To run the example: ```bash npm run dev ``` Then open http://localhost:5173/examples/ in your browser. ## Development ```bash # Install dependencies npm install # Run tests npm test # Type checking npm run typecheck # Build library npm run build # Run dev server for examples npm run dev ``` ## License MIT