-
Notifications
You must be signed in to change notification settings - Fork 0
audio pronunciation
للتفصيلِ الكاملِ عن Piper (الإعدادُ من الصفر · خصائصُ كلِّ لغة · إصلاحُ النطق · التوليدُ التفاضليُّ · الحدود):
piper-tts-guide.md.
مرجعٌ شاملٌ لطبقات الصوت في «مِشكاة»، مع وصفةِ علاجِ مشكلات النطق (ترتيب التشكيل، لفظ الجلالة، حدود المحرّكات). كلُّ النطق محلّيٌّ 100%: مقاطع MP3 ثابتةٌ تُولَّد وقتَ التطوير، وتُشغَّل دون إنترنت أو ذكاءٍ وقتَ التشغيل.
| الطبقة | الملفّ | الدور |
|---|---|---|
| التفضيلات | src/sound-prefs.js |
isTonesOn/isVoiceOn + اختيارُ مجموعة الصوت لكلِّ نوع (letter/word/sentence/story) |
| التوجيه | src/tts-clips.js |
classify(text) ثمّ srcFor يختار المصدر بحسب المجموعة المحدّدة، ويرتدُّ لـespeak إن غاب المقطع |
| النطق | src/speak.js |
يجرّب المقطعَ المضمون أولاً ثمّ Web Speech للنصوص الطويلة؛ مهلةُ أمانٍ تُطلق onend إن لم تَجهز أصواتُ المتصفّح |
| التهجئة | src/spell.js |
segment(text) يحلّل الكلمةَ لمقاطع، playSpelled يشغّلها بالتتابع ثمّ الكلمة كاملة |
| التسجيل البشريّ (مشترَك) |
src/voices.js + voices-bundled.json
|
نموذجُ الصوت الذي يبنيه الأهل في record.html (IndexedDB tilmithi_voices، عامٌّ للجميع) |
| تسجيل التمرّن (لكلِّ حساب) |
src/practice.js + src/reader-recorder.js
|
الطفل يسجّل قراءتَه ويستمع، محفوظٌ في حسابه وحده |
-
espeak‑ng (آليّ):
npm run gen:audio→tools/gen-audio.mjs→public/tts/*.mp3+src/tts-manifest.json(نصّ → ملفّ). -
Piper العصبيّ (عربيّ
ar_JO-kareem):npm run gen:piper→ كلمات/جمل/قصص → مجموعةtts-kareemفيvoices-bundled.json. -
Piper اللغات الأجنبيّة (
en_GB-alba/fr_FR-tom):node tools/gen-piper-lang.mjs en|fr. - المصدرُ الموحَّد للنصوص:
src/vocab.js(يقرؤه الاستوديو والمولّدات معاً، فإضافةُ المحتوى تتزامن تلقائيّاً).
محرّكا النطق (espeak والعصبيُّ Piper الذي يعتمد espeak في التفنيم) يتوقّعان ترتيب «حرف + شدّة + حركة». لكنّ كثيراً من النصوص (وما يُنتجه تطبيعُ Unicode NFC) يأتي بترتيب «حرف + حركة + شدّة»، فتضيع الشدّة وتُسمَع كالسكون:
| الكلمة | ترتيب «حركة+شدّة» (خطأ) | ترتيب «شدّة+حركة» (صحيح) |
|---|---|---|
| أوّل |
ʔˈauːl (أَوْل) |
ʔˈauːˌal (أوّل) |
| محرّم | mˈuħarrm |
mˈuħarram |
| عدّ | ʕˈadː |
ʕˈadːa |
| جنّة | dʒˈannt |
dʒˈannat |
وكذلك لفظُ الجلالة المشكَّل يُشوَّه: اللَّهِ → ʔˈalllhi (تُسمَع «lhi»)، لأنّ قاعدةَ espeak الخاصّةَ لا تعملُ إلّا للكلمة المجرّدة وحدها دون حركةِ إعراب.
دالّتان في src/arabic-normalize.js (نقيّةٌ بلا DOM، تُقرأ في Node والمتصفّح):
-
reorderMarks(text)—NFCثمّ تبديلُ كلِّ تتابع «حركة/تنوين + شدّة» إلى «شدّة + حركة/تنوين». (NFC يضع الحركةَ قبل الشدّة دائماً بسبب الـccc، فالتبديلُ بعده يُنتج الترتيبَ الصحيحَ مهما كان الإدخال.) -
jalalahBare(text)— يعالج كلَّ كلمةٍ على حدة: إن طابق هيكلُها المجرّد لفظَ الجلالة (الله/لله/بالله/تالله/والله/كالله/اللهمّ) تُستبدَل بإملاءٍ صوتيٍّ بمدٍّ صريح مع الحفاظ على حركة الإعراب الأخيرة:
| المُدخَل | يُركَّب صوتيّاً | النطق |
|---|---|---|
| اللهِ / اللهُ / اللهَ | اَلّاهِ / اَلّاهُ / اَلّاهَ | ʔallaːhi/u/a |
| لله (الحمد لله) | لِلّاه + الحركة | lillaːhi |
| بالله | بِلّاه + الحركة | billaːhi |
| اللهمّ | اَلّاهُمّ | ʔallaːhumm |
forSynthesis(text) = jalalahBare(reorderMarks(text)).
يُطبَّق على نصّ التركيب الصوتيّ فقط، بينما مفتاحُ البحث يبقى النصَّ الأصليَّ — فلا يتغيّر اللوكب وقتَ التشغيل، ويتحسّن الصوتُ المُولَّد فقط:
-
tools/gen-audio.mjs→ داخلspokenFor(المفتاح = الأصل، المنطوق =forSynthesis). -
tools/gen-piper.mjs→text: forSynthesis(t)مع بقاءkey/outعلى الأصل. -
src/spell.js segment()→ يطبّقreorderMarksعلى كلِّ مقطع ليطابقَ مفاتيحَ المقاطع المُسجَّلة/المُولَّدة (التي تستعمل ترتيبَsyl.js: «شدّة+حركة»).
npm run gen:audio # espeak (يتطلّب espeak-ng + lame)
npm run gen:piper # العصبيّ kareem (يتطلّب .piper-venv + النموذج)
npm run buildالتحقّق التجريبيّ (بلا تشغيلٍ صوتيّ) عبر فونيمات espeak:
espeak-ng -v ar -q --ipa -- "$(node -e 'import("./src/arabic-normalize.js").then(m=>process.stdout.write(m.forSynthesis("اللَّهِ")))')"
# المتوقَّع: ʔˈallaːhˌi-
مطابقةُ المقاطع حرفيّة:
playClip(text)والتسجيلاتُ تطابق النصَّ تماماً. أيُّ اختلافٍ (تشكيلٌ، ترتيبٌ، مسافة) ⇒ ارتدادٌ لـWeb Speech أو صمت. النصوصُ المركّبةُ وقتَ التشغيل لا تجد مقطعاً. -
أصواتٌ ضعيفةٌ في espeak: الحلق/اللهاة (العين، الغين) تُطال فونيميّاً في
gen-audio (weakFix)؛ السكونُ على ب/ج/د/ض والهمزة أْ = صمتٌ تقريبيّ؛ نِ تلتبس بـذِ؛ الشدّةُ تقريبيّة. الحلُّ الجذريُّ: تسجيلٌ بشريّ (الاستوديو/public/tts/custom/). -
النماذجُ العصبيّةُ للحروف المفردة: Piper ضعيفٌ للحرف المنفرد (طبيعتُه للجُمل)؛ لذا الحروفُ مستثناةٌ من المجموعات العصبيّة (
types) وافتراضُها espeak. في اللغات الأجنبيّة يُنطَق اسمُ الحرف ككلمة (حقلname: H→aitch) لا الحرفُ المجرّد. - مزلقُ ترتيب التشكيل: انظر القسم ٢ أعلاه — أهمُّ سببٍ لتشويه النطق المُولَّد.
-
أمانُ Node: ما يستورده المولّدون (
vocab.js/syl.js/robo-phrases.js/islamic.js/arabic-normalize.js) يجب أن يخلوَ منwindow/DOM.
playUrlAsync (في tts-clips) ينتظر جهوزيّةَ المقطع (canplay) قبل التشغيل فلا يفشلُ أوّلُ تشغيلٍ لمقطعٍ لم يُحمَّل (كان يرتدُّ خطأً للنطق الآليّ). ويحترمُ النموذجَ المختار (عصبيّ/بشريّ/آليّ) دون استبداله بسبب توقيت التحميل. قارئُ القصص (story-reader.js) يُهيّئ المجموعةَ (primeVoices) قبل أوّل تشغيلٍ تفادياً للارتداد.
انظر أيضاً: pitfalls-and-solutions.md · architecture.md · ../CLAUDE.md.
📖 هذا الويكي مرآةٌ مولَّدةٌ من GT-MK/docs/ في المستودع — حرّرِ الملفَّ هناك ثمّ شغّلْ bash tools/publish-wiki.sh.
رخصةُ المشروعِ والوثائق: GPL-3.0.
البداية
المرجعُ التقنيّ
الخبرةُ المتراكمة