A lightweight, local, and text-independent speaker identification engine.
voice-recognition is a fast and efficient speaker identification project that extracts voice embeddings from audio clips, stores enrolled speakers locally, and identifies the closest match for any query clip.
Whether you're building a biometric login, a smart home assistant, or just experimenting with audio machine learning, this system provides a robust starting point without relying on cloud APIs.
- 🗣️ Text-Independent: The spoken words don't need to match between enrollment and inference.
- ⚡ Fast & Efficient: Uses
FAISSfor lightning-fast cosine-similarity search over normalized embeddings. - 🧠 State-of-the-Art ML: Powered by
SpeechBrainECAPA-TDNN speaker embeddings. - 🎛️ Energy-based VAD: Built-in Voice Activity Detection to filter out silence.
- 🖥️ Desktop UI: Includes a local Tkinter-based desktop app for easy recording and management.
- 🔒 Privacy First: Everything runs locally. No voice data is sent to the cloud.
The pipeline is streamlined for accuracy and speed:
- Audio Ingestion: Load audio from disk (supports
.wav,.flac,.mp3,.ogg,.m4a). - Preprocessing: Convert to mono and resample to
16 kHz. - VAD (Voice Activity Detection): Apply lightweight energy-based detection to isolate speech.
- Feature Extraction: Generate a
192-dimensional speaker embedding. - Matching: L2-normalize embeddings and compare with enrolled speakers using FAISS.
- Python
3.9+ - A compatible
torchandtorchaudioinstallation. (PyTorch Install Guide)
Clone the repository and install the dependencies:
git clone https://github.com/iamEtornam/voice-recognition.git
cd voice-recognition
pip install -r requirements.txt(Optional) Create a .env file for authenticated Hugging Face downloads:
HF_TOKEN=your_hugging_face_tokenPlace several clips for one person in a folder, then run the enrollment CLI:
python enroll.py --name alice --dir ./samples/alice/Note: If you enroll the same --name again, the existing entry is replaced with a new centroid computed from the supplied directory.
Run the identification CLI against a query audio file:
python main.py --audio ./samples/query.wav --threshold 0.45Example Output:
Identified: alice
Similarity: 0.8123 (threshold=0.45)
Prefer a graphical interface? Launch the built-in desktop recorder and manager:
python app.pyThe desktop UI includes four tabs:
- 🔴 Record: Capture and save a WAV file locally.
- 📝 Enroll: Record multiple clips, then enroll or replace a speaker profile.
- 🔎 Identify: Record one clip and compare it against the speaker database.
- 🗃️ Speakers: Inspect and delete enrolled speaker profiles.
(Note: MacOS users benefit from an automatic KMP_DUPLICATE_LIB_OK=TRUE workaround to prevent libomp crashes).
voice-recognition/
├── app.py # Desktop recording UI
├── database.py # Local embedding storage via FAISS
├── embedding.py # Embedding extraction helpers
├── enroll.py # Speaker enrollment CLI
├── env_utils.py # Local `.env` loading helpers
├── identify.py # FAISS similarity search
├── main.py # Speaker identification CLI
├── models.py # SpeechBrain ECAPA model loader
├── vad.py # Audio preprocessing and VAD
└── tests/ # Comprehensive regression & unit test suite
- Clean Audio: Use clean recordings with minimal background noise.
- Multiple Samples: Provide several enrollment clips per speaker (preferably 3-5 seconds of speech each).
- Consistency: Keep microphone and room conditions as consistent as possible between enrollment and query.
- Tuning: The default threshold is
0.25. For stricter matching, try values around0.45and evaluate against your own validation data.
Run the test suite to ensure everything is working correctly on your machine:
python -m unittest discover -s tests -v- Not for Anti-Spoofing: This system does not include liveness detection. It can be fooled by high-quality recordings.
- Biometric Data: Treat stored embeddings as biometric data. Protect your local
speaker_db/directory and ensure compliance with applicable data privacy laws. - Scalability: Uses
IndexFlatIPwhich is exact but tailored for modest gallery sizes. For huge datasets, consider swapping toIndexIVFFlat.
We love contributions! Whether it's a bug fix, a new feature, or documentation improvements, your help is welcome.
Please check out our Contributing Guide and Code of Conduct to get started.
This project is licensed under the MIT License - see the LICENSE file for details.