stringpitcher 0.1.3

Ultra low-latency pitch detection library for guitar and bass instruments
docs.rs failed to build stringpitcher-0.1.3
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

StringPitcher

Ultra low-latency pitch detection library for guitar and bass instruments. Built in Rust with bindings for multiple platforms.

Crates.io npm License: MIT

Features

  • Ultra Low Latency: < 20ms pitch detection using McLeod Pitch Method (MPM)
  • Multi-Instrument Support: 6-string guitar, 4-string bass, 5-string bass
  • 12 Built-in Tunings: Standard, Drop D, Drop C, Open G, DADGAD, and more
  • Chromatic Mode: Detect any note, not just string frequencies
  • Configurable Reference Pitch: A4 = 432-448 Hz
  • Cross-Platform: iOS, Android, Web (WASM), Node.js, and native Rust

Installation

Platform Install Command
Rust cargo add stringpitcher
npm npm install stringpitcher
iOS (SPM) Add https://github.com/pablocalofatti/stringpitcher
Android implementation 'com.github.pablocalofatti:stringpitcher:0.1.0'

Platform Documentation

Quick Start

Rust

use stringpitcher::{TunerInstance, InstrumentType};

let mut tuner = TunerInstance::default();

tuner.set_callback(|result| {
    println!("{}{}: {:.1} cents",
        result.note_name(), result.octave, result.cent_deviation);
});

// In your audio callback:
tuner.process_audio(&audio_samples);

JavaScript / TypeScript

import { StringPitcher, Instrument, TuningPreset } from 'stringpitcher';

const tuner = new StringPitcher(48000);
tuner.setInstrument(Instrument.Guitar6String);

const result = tuner.processAudio(audioSamples);
if (result?.confidence > 0.5) {
    console.log(`${result.noteName}${result.octave}: ${result.centDeviation} cents`);
}

Swift (iOS)

import StringPitcherLib

let tuner = StringPitcher(sampleRate: 48000)
tuner.onPitchDetected = { result in
    print("\(result.noteName)\(result.octave): \(result.centDeviation) cents")
}
tuner.processAudio(samples: audioBuffer)

Kotlin (Android)

val tuner = StringPitcher(sampleRate = 48000)

lifecycleScope.launch {
    tuner.pitchResults.collect { result ->
        Log.d("Tuner", "${result.noteName}${result.octave}: ${result.centDeviation}")
    }
}

tuner.processAudio(samples, sampleCount)

API Reference

PitchResult

Property Type Description
frequency Float Detected frequency in Hz
confidence Float Detection confidence (0.0 - 1.0)
noteName String Note name (C, C#, D, etc.)
octave Int Octave number (0-8)
centDeviation Float Cents off from target (-50 to +50)
isInTune Bool True if within tuning threshold
tuningDirection Int -1: flat, 0: in tune, 1: sharp
matchedString Int Matched string index (0-5) or -1
signalLevel Float Input signal level (0.0 - 1.0)

Tuning Presets

ID Tuning Notes
0 Standard E A D G B E
1 Half Step Down Eb Ab Db Gb Bb Eb
5 Drop D D A D G B E
6 Drop C C G C F A D
9 Open G D G D G B D
11 DADGAD D A D G A D

Architecture

┌─────────────────────────────────────────┐
│          Rust Core Library              │
│    McLeod Pitch Detection + Tuning      │
└─────────────────────────────────────────┘
                    │
    ┌───────────────┼───────────────┐
    ▼               ▼               ▼
┌───────┐      ┌───────┐       ┌───────┐
│  FFI  │      │ WASM  │       │  JNI  │
│(Swift)│      │ (JS)  │       │(Kotlin)│
└───────┘      └───────┘       └───────┘
    │               │               │
    ▼               ▼               ▼
  iOS           Browser         Android
               Node.js

Performance

Metric Value
Latency < 20ms
Frequency Range 20Hz - 5kHz
Accuracy ±1 cent
WASM Size ~300KB

License

MIT License