Skip to content

Repository files navigation

FloatNote 🎙️

Real-time meeting intelligence — transcription, speaker diarization, screen reading, AI summaries, and a chatbot that knows your meeting.

FloatNote is a desktop-first meeting assistant that quietly runs in the background while you work. It captures your microphone and your system audio (remote participants), tells speakers apart in real time, reads your screen during presentations, and turns everything into searchable, queryable meeting memory — powered by local Whisper transcription and HuggingFace LLMs.


✨ Features

FeatureDescription
🎤 Live TranscriptionStreams mic audio through OpenAI Whisper (base model) in real time, gated by Silero VAD so only real speech is transcribed
🔊 System Audio CaptureCaptures remote participants via WASAPI loopback (soundcard) — hear both sides of the meeting, with per-meeting consent
🗣️ Speaker DiarizationStreaming, fully-offline speaker identification (Resemblyzer d-vectors) — consistent SPEAKER_00 / SPEAKER_01 labels across a live meeting
✏️ Speaker Aliases & TitlesRename speakers to real names and edit the meeting title mid-recording, live-synced to all connected clients
⏯️ Meeting ControlsStart, pause, resume, stop, and mute (mic/speaker independently) from the dashboard
🖥️ Screen OCRCaptures slide content as it changes, extracting text and keywords automatically (opt-in)
🧠 AI SummarizationGenerates meeting summaries via the project's single LLM (Qwen2.5-7B), with a local fallback
💬 Meeting ChatbotAsk questions about any past meeting — answers grounded in a FAISS vector store via RAG
🗃️ Persistent StorageAll transcripts, speaker labels, OCR captures, and action items saved to SQLite via async SQLAlchemy
Action Item ExtractionNLP pipeline (spaCy) detects tasks and assignees from spoken text
🖥️ Electron Desktop AppOptional Electron wrapper for a native windowed experience

🏗️ Architecture

FloatNote/
├── run.ps1 # Dev runner: launches backend + React + Electron
├── backend/
│ ├── main.py # Entry point (starts the server below)
│ ├── requirements.txt
│ ├── ai_modules/
│ │ ├── stt/
│ │ │ └── whisper_engine.py # FastAPI app + WebSocket server, mic & loopback
│ │ │ # capture, Silero VAD, Whisper transcription
│ │ ├── diarization/
│ │ │ └── diarizer.py # Streaming speaker diarization (Resemblyzer)
│ │ ├── ocr/
│ │ │ ├── ocr_processor.py # Screen capture + Tesseract OCR
│ │ │ └── keyword_filter.py # LLM keyword filtering (local fallback)
│ │ ├── summarizer/
│ │ │ └── summarizer.py # LLM meeting summaries (local fallback)
│ │ ├── chatbot/
│ │ │ └── chatbot.py # RAG chatbot (FAISS retrieval + LLM)
│ │ └── utils/
│ │ ├── llm_client.py # THE single LLM client (Qwen2.5-7B via HF)
│ │ └── nlp_processor.py # spaCy NLP pipeline
│ └── database/
│ ├── models.py # SQLAlchemy models (Meeting, Transcript, ActionItem)
│ ├── crud.py # Async database operations
│ └── view_db.py # Database viewer utility
├── frontend/
│ ├── react-app/ # Vite + React 19 + Tailwind CSS UI
│ │ └── src/App.jsx # Dashboard: live transcript, speaker labels,
│ │ # meeting controls, summaries, chat
│ └── electron/
│ └── main.js # Electron wrapper (loads localhost:5173)
└── website/
└── index.html # Landing page

🚀 Setup & Installation

Prerequisites

  • Python 3.10+
  • Node.js 18+
  • Windows (for system-audio loopback capture; mic-only works elsewhere)
  • Tesseract OCR (only if you enable screen reading)

1. Clone the repo

git clone https://github.com/Parth-Gupta-github/FloatNote.git
cd FloatNote

2. Install Python dependencies

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r backend/requirements.txt

⚠️ First run downloads the Whisper base model (~150MB), the Silero VAD model, the Resemblyzer voice encoder, and the spaCy en_core_web_sm model automatically.

3. (Optional) Install Tesseract OCR

Only needed if you set ENABLE_OCR=true. On Windows:

winget install UB-Mannheim.TesseractOCR

Then verify the path in backend/ai_modules/ocr/ocr_processor.py:

pytesseract.pytesseract.tesseract_cmd=r"C:\Program Files\Tesseract-OCR\tesseract.exe"

4. Configure environment variables

Create a .env file inside backend/:

# Required — powers the chatbot, summaries, and keyword filtering (one model for everything)HUGGINGFACEHUB_API_TOKEN=hf_...HUGGINGFACE_PROVIDER=auto

💡 All LLM features run on a single model (Qwen/Qwen2.5-7B-Instruct) through the HuggingFace router. Create a token with the "Make calls to Inference Providers" permission at huggingface.co/settings/tokens. Without a token, summaries, chat, and keyword filtering degrade to local fallbacks.

5. Run everything (recommended)

.\run.ps1 # backend + React + Electron, each in its own window
.\run.ps1 -NoElectron # backend + React only (open http://localhost:5173)

Or start each part manually

# Backend — http://localhost:8000
.\.venv\Scripts\Activate.ps1
cd backend
python main.py
# Frontend — http://localhost:5173cd frontend/react-app
npm install
npm run dev
# (Optional) Electron desktop appcd frontend/electron
npm install
npm start

📡 API Reference

MethodEndpointDescription
WS/wsReal-time transcript / status / OCR stream
POST/meetings/startStart a new meeting (recording begins)
POST/meetings/pausePause recording
POST/meetings/resumeResume recording
POST/meetings/stopStop and finalize the meeting
POST/meetings/muteMute/unmute mic and/or system audio
POST/meetings/titleSet or edit the active meeting's title
GET/meetings/{id}/speakersList speaker aliases for a meeting
POST/meetings/{id}/speakersRename a speaker (speaker_keydisplay_name)
GET/meetings/latest/summarySummarize the most recent meeting
GET/meetings/{id}/summarySummarize a specific meeting by ID
POST/meetings/latest/chatAsk a question about the latest meeting
POST/meetings/{id}/chatAsk a question about a specific meeting
GET/meetings/{id}/debug/exportExport raw meeting data for debugging

Chat request body

{
"question": "What action items were assigned to me?"
}

WebSocket status message

{
"type": "status",
"recording": true,
"paused": false,
"meeting_id": 42,
"title": "Q3 Roadmap Sync",
"mic_muted": false,
"speaker_muted": false,
"speaker_enabled": true
}

WebSocket transcript message

{
"text": "Let's align on the Q3 roadmap.",
"keywords": ["roadmap", "Q3"],
"actions": [{ "task": "Share roadmap draft", "assignee": "SPEAKER_00" }],
"meeting_id": 42
}

🤖 AI Models

FloatNote uses exactly one LLM for every language task — chatbot answers, meeting summaries, and keyword filtering all go through ai_modules/utils/llm_client.py. The remaining models are small local pipeline models (audio/NLP), not LLM providers.

ComponentDefault ModelConfigurable
The LLM (chat + summaries + keywords)Qwen/Qwen2.5-7B-Instruct (HuggingFace router)HUGGINGFACE_CHAT_MODEL env var
Transcriptionopenai/whisper-base (local)Change model size in whisper_engine.py
Voice Activity DetectionSilero VAD (local)VAD_THRESHOLD env var
Speaker DiarizationResemblyzer d-vector encoder (local)DIARIZATION_SIMILARITY env var
Embeddingssentence-transformers/all-MiniLM-L6-v2 (local)Hardcoded in chatbot.py
NLP / Action Itemsen_core_web_sm (spaCy, local)

🗄️ Database Schema

FloatNote uses SQLite (backend/database/meeting_assistant.db) with async SQLAlchemy.

meetings
id, title, start_time, summary
transcripts
id, meeting_id → meetings.id, timestamp, text, keywords,
source (MIC / SPEAKER_xx / OCR)
action_items
id, meeting_id → meetings.id, description, assignee, status

Speaker aliases (SPEAKER_00 → "Priya") are stored per meeting and applied live across the dashboard.

To inspect the database directly:

python backend/database/view_db.py

⚙️ Configuration Reference

VariableDefaultDescription
HUGGINGFACEHUB_API_TOKENRequired. HF token for the single LLM (chat + summaries + keywords)
HUGGINGFACE_CHAT_MODELQwen/Qwen2.5-7B-InstructThe one LLM used everywhere
HUGGINGFACE_PROVIDERautoInference provider routing (auto recommended)
ENABLE_SPEAKERtrueCapture system (loopback) audio
ENABLE_DIARIZATIONtrueLabel speakers on the system-audio stream
DIARIZATION_SIMILARITY0.70Cosine similarity to match an existing speaker
DIARIZATION_MIN_SAMPLES16000Min samples (~1s) needed to embed an utterance
VAD_THRESHOLD0.5Silero VAD speech-probability threshold
RMS_GATE0.002Energy pre-gate; skips dead-silent chunks before VAD
CHUNK_SECONDS5Audio chunk length fed to Whisper
AUDIO_BUFFER_SECONDS30Rolling capture buffer size
ENABLE_OCRfalseEnable screen capture + OCR
OCR_INTERVAL_SECONDS1.0How often to poll for screen changes
OCR_CHANGE_THRESHOLD0.02Minimum pixel-change ratio to trigger OCR
HOST0.0.0.0Backend bind host
PORT8000Backend bind port

🛠️ Tech Stack

Backend

Frontend


🐛 Known Issues & Limitations

  • System-audio capture is Windows-only — loopback recording uses WASAPI via soundcard. On other platforms FloatNote runs mic-only.
  • Windows-only OCR path — the Tesseract path in ocr_processor.py defaults to a Windows path. Linux/macOS users must update it or ensure tesseract is on PATH.
  • Single monitor — OCR captures monitor index 1 by default. Adjust monitor_index in OCRProcessor for multi-monitor setups.
  • Diarization needs ~1s of speech — very short utterances keep the previous speaker's label (sticky fallback) rather than guessing.
  • HF API latency — summarization and chat responses depend on HuggingFace Inference API availability and may be slow on free tier.

👥 Team

Built as a group project by:

  • Parth Gupta
  • Parv Tiwari
  • Vansh Agrawal
  • Tashvi Gangrade
  • Shaurya

About

Real-time meeting intelligence — transcription, screen reading, AI summaries, and a chatbot that knows your meeting.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages