ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证oriyomi is a full-stack web app that turns PDFs, DOCX files, Markdown, text files, or pasted text into a synchronized listen-and-read experience. It detects document sections, generates neural speech, highlights the sentence currently being spoken.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
ori—to fold, yomi—to read. Sentence-sync read-along that folds a document into speech.
oriyomi turns dense study material into something you can actually get through. Upload a textbook chapter, notes, or a PDF, and it becomes a listen-along experience: natural neural speech plays while the exact sentence being spoken is highlighted on screen. Optional comprehension quizzes close the loop — because hearing a chapter and understanding it are not the same thing.查看完整 README ↗ori—to fold, yomi—to read. Sentence-sync read-along that folds a document into speech.
oriyomi turns dense study material into something you can actually get through. Upload a textbook chapter, notes, or a PDF, and it becomes a listen-along experience: natural neural speech plays while the exact sentence being spoken is highlighted on screen. Optional comprehension quizzes close the loop — because hearing a chapter and understanding it are not the same thing.
Dense textbooks are overwhelming. A wall of text is hard to start, hard to stay oriented inside, and easy to abandon halfway through a chapter. Existing read-aloud tools either don't lock eyes and ears on the same sentence, or hide good neural voices behind API keys and paid usage.
oriyomi was built from that frustration. The name blends two Japanese words — ori (折り, to fold) and yomi (読み, to read). Like origami, you start with a flat, overwhelming sheet of paper. The parser creases it into logical sections; each section folds into clean speech you can follow along with. You aren't just hearing a textbook — you're reshaping it into something structured and digestible, one fold at a time.
.txt, .md, .pdf, or .docx, or paste text directly.No accounts. No subscriptions. No paid speech APIs. Free Microsoft Edge neural voices power the whole reading experience.
cp .env.example .env # optional: add GEMINI_API_KEY for the quiz
docker compose up --build
The Next.js app proxies /api/* to the backend, so the browser never needs to know where the API lives.
Backend:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python main.py
Frontend:
cd frontend
npm install
npm run dev
Open http://localhost:3000. Point the frontend at the API with API_PROXY_URL=http://localhost:8000 (or NEXT_PUBLIC_API_URL if you prefer a direct browser call).
| Variable | Service | Required | Purpose |
|---|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | frontend | Yes (deployed) | Supabase project URL. Inlined at build time from frontend/.env.local locally. |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | frontend | Yes (deployed) | Supabase publishable (anon) key. Same inlining rules. |
GEMINI_API_KEY | app | No | Enables the comprehension quiz. Without it, the reader still works; the quiz degrades gracefully. |
SUPABASE_URL | app | Yes (deployed) | FastAPI: persistent words-folded counter. Without it the counter is in-memory and resets on every serverless cold start — stats freeze near 0. |
SUPABASE_SERVICE_ROLE_KEY | app | Yes (deployed) | FastAPI: service-role key backing the counter RPC. |
FFMPEG_PATH | app | No | Explicit ffmpeg binary for MP3 chunk merging. Defaults to the static binary bundled via imageio-ffmpeg, then PATH. |
ALLOWED_ORIGINS | app | No | CORS origins for direct browser → API calls. Defaults to http://localhost:3000,http://127.0.0.1:3000. Unused when the Next.js proxy is in play. |
API_PROXY_URL | frontend (Docker) | No | Where the Next dev/proxy forwards /api/*. Defaults to http://localhost:8000. |
The two NEXT_PUBLIC_SUPABASE_* vars must be set in the Vercel project
(Settings → Environment Variables, scoped to the frontend service) before
the first deploy. They are inlined into the client bundle at build time — a
deployment without them builds cleanly but every page returns
500 Internal Server Error (the auth middleware has no project to talk to).
After adding or changing them, redeploy so the bundle is rebuilt.
The app (FastAPI) service also needs SUPABASE_URL and
SUPABASE_SERVICE_ROLE_KEY (same values, scoped to the app service) or
the words-folded counter resets on every serverless cold start and the stat
stays frozen near 0 on all devices. The reader and TTS work either way; only
the counter and quiz degrade. After setting them, check the app service logs
for Words-folded counter: Supabase-backed to confirm.
Run the supabase/migrations/ SQL against your project (0001 → 0005 in
order). 0005 is required in production: this project loads pg-safeupdate,
which rejects the original increment_words_folded body's WHERE-less
UPDATE, so every increment failed silently.
Local setup: copy the values from your Supabase project into
frontend/.env.local (see frontend/.env.example).
The FastAPI backend is also usable on its own — free text-to-speech with sentence-level timestamps, no API key.
GET /api/voicesReturns the 9 highest-quality US English voices, ordered best first.
Response:
[
{
"id": "en-US-AvaMultilingualNeural",
"name": "Microsoft AvaMultilingual Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-EmmaMultilingualNeural",
"name": "Microsoft EmmaMultilingual Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-AndrewMultilingualNeural",
"name": "Microsoft AndrewMultilingual Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-BrianMultilingualNeural",
"name": "Microsoft BrianMultilingual Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-AriaNeural",
"name": "Microsoft Aria Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-JennyNeural",
"name": "Microsoft Jenny Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-GuyNeural",
"name": "Microsoft Guy Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-ChristopherNeural",
"name": "Microsoft Christopher Online (Natural) - English (United States)",
"locale": "en-US"
},
{
"id": "en-US-MichelleNeural",
"name": "Microsoft Michelle Online (Natural) - English (United States)",
"locale": "en-US"
}
]
POST /api/ttsGenerate speech audio from text.
Always synchronous: long texts split at sentence boundaries and every chunk generates concurrently inside the request, then merges with ffmpeg — no task queue, no polling.
Request body:
{
"text": "Hello world. This is a test.",
"voice": "en-US-EmmaMultilingualNeural",
"speed": 1.0
}
| Field | Type | Default | Description |
|---|---|---|---|
text | string | (required) | Text to synthesize (1–50000 chars) |
voice | string | en-US-EmmaMultilingualNeural | Voice short name |
speed | float | 1.0 | Speech rate (0.5 = half, 2.0 = double) |
Response:
{
"audio_base64": "SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4...",
"sentences": [
{
"text": "Hello world.",
"start_ms": 0,
"end_ms": 820
},
{
"text": "This is a test.",
"start_ms": 820,
"end_ms": 1640
}
],
"voice": "en-US-EmmaMultilingualNeural",
"speed": 1.0
}
POST /api/tts/foldGenerate one fold (section) of a document. The reader client fires these in parallel — one request per fold — so folds generate concurrently and the first completed fold plays while the rest are still running.
Request body:
{
"text": "Glycolysis is the first step in cellular respiration...",
"voice": "en-US-EmmaMultilingualNeural",
"speed": 1.0,
"fold_index": 0,
"title": "Glycolysis"
}
| Field | Type | Default | Description |
|---|---|---|---|
text | string | (required) | This fold's text (1–50000 chars) |
voice | string | en-US-EmmaMultilingualNeural | Voice short name |
speed | float | 1.0 | Speech rate |
fold_index | int | 0 | Position of the fold in the document |
title | string | "" | Section title (defaults to Fold NN) |
Response: same shape as /api/tts plus fold_index, title, and duration_ms.
GET /api/healthHealth check. Returns {"status": "ok"}.
const res = await fetch('http://localhost:8000/api/tts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: 'Hello world. This is a test.',
voice: 'en-US-EmmaMultilingualNeural',
speed: 1.0,
}),
});
const { audio_base64, sentences } = await res.json();
// Play audio
const audio = new Audio(`data:audio/mpeg;base64,${audio_base64}`);
audio.play();
// Use sentences for text highlighting
// sentences[i].start_ms / end_ms tell you when each sentence plays
The /api/voices endpoint returns 9 curated high-quality US English voices, ordered best first:
| Voice ID | Type | Gender |
|---|---|---|
en-US-AvaMultilingualNeural | HD (newest) | Female |
en-US-EmmaMultilingualNeural | HD (newest) | Female |
en-US-AndrewMultilingualNeural | HD (newest) | Male |
en-US-BrianMultilingualNeural | HD (newest) | Male |
en-US-AriaNeural | Neural | Female |
en-US-JennyNeural | Neural | Female |
en-US-GuyNeural | Neural | Male |
en-US-ChristopherNeural | Neural | Male |
en-US-MichelleNeural | Neural | Female |
The four Multilingual voices are Microsoft's newest HD generation. The rest are the strongest of the classic neural voices. Lower-quality voices (child, telephony, and superseded duplicates) have been excluded.
├── main.py # FastAPI app — /api/voices, /api/tts, /api/tts/fold, /api/health
├── tts.py # TTS engine (edge-tts, sentence splitting, timestamp mapping)
├── text_structure.py # Chapter/section detection for fold generation
├── summaries.py # Optional per-fold summaries
├── requirements.txt # Python dependencies
├── Dockerfile # Backend container image
├── docker-compose.yml # Frontend + backend
├── vercel.json # Vercel deploy: Next.js frontend + FastAPI backend
├── frontend/ # Next.js / React / Tailwind reader UI
└── README.md
MIT