القراءة بصوت عالٍ
حدّد كلمة أو فقرة بالفرنسية أو اليابانية أو العربية أو الإنجليزية واسمعها، بأصوات تعمل على معالج جهازك نفسه — بلا سحابة، وبلا بطاقة رسوميات.
حدّد بعض الكلمات واختر اقرأ بصوت عالٍ. تُنطق الكلمة الواحدة في الحال، وتُقرأ الفقرة جملةً جملة، وتُضاء في الصفحة الجملة التي تُقرأ، ويظهر أسفل النافذة مشغّل صغير للإيقاف المؤقت والبدء من جديد وتغيير السرعة والإيقاف. الأصوات مثبّتة على الجهاز الذي يشغّل أسطرلاب — حاسوبك المحمول، أو خادمك المنزلي، أو تطبيق سطح المكتب — وتعمل على معالجه، عمدًا: لا يُرسَل شيء إلى أي مكان، ولا حاجة إلى بطاقة رسوميات ولا يُستعمل شيء منها.
أين تجدها
| أين | كيف |
|---|---|
| المحرر | حدّد، ثم انقر بالزر الأيمن (أو Shift F10)، اقرأ بصوت عالٍ — آخر صف في قائمة التحديد |
| في أي مكان | حدّد، ثم Ctrl/Cmd Shift . — في المحرر، وعرض القراءة، والكتاب، وعنصر الخلاصة (اختصارات لوحة المفاتيح) |
| عرض القراءة، والكتاب، وملف EPUB | حدّد، واضغط زر اقرأ بصوت عالٍ الذي يظهر تحت التحديد |
| الملاحظة كلها | صف لوحة الأوامر اقرأ هذه الملاحظة بصوت عالٍ (Ctrl/Cmd P): من موضع المؤشر في المحرر، ومن أولها في عرض القراءة |
| الهاتف | حدّد، واضغط الزر — في عرض القراءة وفي المحرر، إذ لا قائمة نقر أيمن على الهاتف؛ أو ورقة ⋯ الخاصة بالملاحظة ← إجراءات ← اقرأ هذه الملاحظة بصوت عالٍ |
| المدونة العامة | لا يظهر الزر للزوار إلا إذا فعّلت يستطيع القرّاء الاستماع (أدناه) |
يبقى المشغّل أسفل النافذة وأنت تمرّر الصفحة. أزراره: إيقاف مؤقت / تشغيل، ومن البداية (مجانًا في المرة الثانية: كل ما نُطق محفوظ)، والسرعة (من 0.75× إلى 1.5×، تُطبَّق في الحال دون إعادة توليد)، وإيقاف.
بأي لغة
يُنطق التحديد باللغة التي كُتب بها، ويُقرَّر ذلك كما يقرّره بقية التطبيق:
- الخط أولًا. الحروف العربية عربية؛ والكانا والكانجي يابانية — بالعدد، فجملة إنجليزية تقتبس كانجي واحدًا تبقى إنجليزية.
- الفرنسية حين تكون الكلمات فرنسية — بالاختبار نفسه الذي يستعمله التصحيح الفرنسي أثناء الكتابة: كلمتان وظيفيتان فرنسيتان. فالاقتباس الفرنسي في ملاحظة إنجليزية يُقرأ بالفرنسية.
- حقل
lang:في الملاحظة نفسها (lang: fr،lang: es)، للنص اللاتيني الذي لا يحسمه الاختبار. - الجملة المحيطة بالكلمة المفردة. الكلمة المحدّدة وحدها لا شيء فيها يُعدّ؛ أما الفقرة التي حُدّدت منها ففيها، فكلمة grenouille المحدّدة في فقرة فرنسية فرنسية.
- المقطع كله. الفقرة أو الملاحظة الكاملة تُقرأ جملةً جملة، والجملة القصيرة — عنوان مثل Décrire son quotidien أو Le matin — لا كلمة فرنسية فيها تُعدّ. فكل جملة تحمل معها المقطع الذي هي منه: إذا كان نصف أسطر المقطع على الأقل فرنسيًّا، فأسطره القصيرة فرنسية كذلك. والعدّ بالأسطر، فالملاحظة الإنجليزية التي تقتبس سطرًا فرنسيًّا واحدًا تبقى إنجليزية.
- لغة الموقع، ثم الإنجليزية.
وصفّ الملاحظات الصوتية: لغة التفريغ المجاور للقراءة بصوت عالٍ ليس جزءًا من هذا: هو اللغة التي تُفرَّغ بها الملاحظات الصوتية، ولا يغيّر أبدًا اللغة التي يُقرأ بها النص.
الفوريغانا تُقرأ مرة واحدة، على أنها الكلمة: {図書館|としょかん} تُنطق 図書館، لا الكلمة ثم قراءتها (اليابانية والفوريغانا).
المحرّكان
كلاهما برنامج حرّ، وكلاهما يعمل على المعالج، وكلاهما يعمل داخل بيئة Python واحدة يصنعها التطبيق لك.
| خفيف (الافتراضي) | طبيعي | |
|---|---|---|
| المحرّك | Piper (MIT) | Kokoro-82M (Apache-2.0) عبر kokoro-onnx |
| اللغات | الإنجليزية، والفرنسية، والعربية | الإنجليزية، والفرنسية، واليابانية، والإسبانية، والإيطالية، والبرتغالية |
| الأصوات | Lessac (امرأة) · للفرنسية: Siwis (امرأة) وPierre (رجل) وJessica (امرأة) · Kareem (رجل) | خمسة للإنجليزية، وأربعة لليابانية، واثنان لكلٍّ من الإسبانية والإيطالية والبرتغالية — رجالًا ونساءً — وصوت فرنسي واحد، Siwis (امرأة) |
| التنزيل | 190 م.ب عند التثبيت (صوت لكل لغة)؛ وPierre وJessica، 77 م.ب معًا، حين يُختاران أول مرة | 354 م.ب مرة واحدة، لكل اللغات والأصوات |
| كلمة، مقيسة (8 / 2 / 1 أنوية) | 60 / 60 / 90 ملّي ثانية | 270 / 460 / 700 ملّي ثانية |
| جملة مدتها 4 ثوانٍ | 0.3 ثانية — أسرع من الكلام بنحو 15 مرة | 0.9 ثانية على 8 أنوية، و2.3 على نواة واحدة — أسرع من الكلام حتى حينئذ |
| الصوت | واضح، مسطّح قليلًا | أقرب إلى صوت إنسان، ولا سيما الإنجليزية واليابانية |
العربية يقرؤها دائمًا صوت «خفيف»، واليابانية يقرؤها دائمًا صوت «طبيعي»، أيًّا كان اختيارك؛ والاختيار يحسم الإنجليزية والفرنسية. الأرقام من معالج AMD Ryzen 7 7800X3D؛ وعمودا «نواتان» و«نواة واحدة» قيسا والمحرّك مقيّد بذلك العدد من الأنوية، ليقوما مقام حاسوب محمول عادي أو خادم منزلي صغير. على معالج أقدم أو قليل الاستهلاك قد يقترب «طبيعي» من الزمن الحقيقي في الجمل الطويلة، ولهذا «خفيف» هو الافتراضي، و«طبيعي» اختيار الجهاز الذي يقدر عليه.
والجهاز الذي لا بطاقة رسوميات فيه يحصل على هذا بالضبط. لا شيء هنا يستعمل واحدة، على أي جهاز.
أيّ محرّك يقرأ أيّ لغة، على هذا الجهاز
الجدول يقول ما يستطيع كل محرّك أن يقرأه. أما ما يقرؤه فعلًا على جهازك فيُفحص: بعد التثبيت — ومرة واحدة، من تلقاء نفسه، لمحرّك ثُبّت قبل أن يوجد هذا الفحص — ينطق كل محرّك كلمة واحدة لكل لغة (quotidien، mañana، giorno، coração، 図書館، morning، مكتبة) في عملية مستقلة قصيرة العمر، ويقارن التطبيق الأصوات التي أخرجها بالأصوات التي تُخرجها قواعد الإنجليزية من الكلمة نفسها. ثم يقول الصف ذلك صراحة: «طبيعي» يقرأ هنا: اليابانية والإنجليزية والفرنسية والإسبانية والإيطالية والبرتغالية.
واللغة التي تُخفق — أصوات إنجليزية لكلمة فرنسية، أو لا صوت، أو فحص توقّف في منتصفه — لا تُقرأ أبدًا بقواعد الإنجليزية: تذهب إلى المحرّك الآخر إن كان مثبّتًا ونجح (تعذّر على «طبيعي» أن يقرأ الفرنسية على هذا الجهاز، فيتولّاها «خفيف»)، وإلا قال الصف أيّ محرّك تثبّت. وافحص مرة أخرى يعيد الفحص.
لماذا وُجد هذا: «طبيعي» يقرأ كل لغة غير اليابانية عبر espeak-ng، ونسخة espeak-ng التي تأتي معه كانت تستسلم — وتُسقط القارئ كله معها — حين يكون المجلّد الذي ثُبّت فيه ذا مسار طويل (160 حرفًا أو أكثر، وهذا سهل تحت مجلّد بيانات يحمل اسم خزانة طويلًا)، أو في ويندوز حين يكون في المسار حروف خارج ASCII البسيطة (مستخدم أو خزانة باسم عربي). واليابانية، التي لا تمرّ بـespeak، ظلّت تُقرأ. والتطبيق الآن يعطي espeak-ng في هذه الحال نسخة قصيرة المسار من بياناته (في مجلّد الملفات المؤقتة، أو في ProgramData على ويندوز، 18 م.ب)، والفحص هو ما يثبت أن ذلك نجح.
صوت رجل، صوت امرأة
كل صوت من أصوات التطبيق يظهر في المنتقيات وبجانب اسمه (رجل) أو (امرأة). لـ«طبيعي» (Kokoro) صوت فرنسي واحد، صوت امرأة؛ ولـ«خفيف» Pierre (رجل) وJessica (امرأة) إلى جانب Siwis — وهما المتحدّثان في صوت fr_FR-upmc-medium. ومنتقي الفرنسية يسرد المحرّكين حين يكونان مثبّتين — طبيعي: Siwis (امرأة) · خفيف: Siwis (امرأة)، Pierre (رجل)، Jessica (امرأة) — والصوت الذي تختاره يقرؤه محرّكه هو: اختر Pierre و«طبيعي» محدّد، فتُقرأ الفرنسية بصوت Pierre من «خفيف»، وتبقى اليابانية والإنجليزية لـ«طبيعي».
وPierre وJessica ليسا جزءًا من التثبيت: اختيار أحدهما ينزّله (77 م.ب)، بسطر التقدّم نفسه الذي يكتبه التثبيت — يُنزَّل Pierre (رجل) — 40٪ — وإلى أن يصل يقرأ الصوت الأول للغة.
كيف اختير المحرّكان
بالاستماع، لا بالقراءة. نطق كلٌّ من Kokoro وPiper وMeloTTS الأسطر العشرة نفسها — كلمة فرنسية، وجملة فرنسية فيها وصل (liaison)، وكلمة يابانية وجملة يابانية، وكلمة عربية مشكولة وغير مشكولة، وجملة إنجليزية، وسطرًا يخلط الإنجليزية بالفرنسية، ورقمًا، واسم علم — على المعالج، وحُفظت العيّنات ليسمعها المالك. ووقف حَكَمان إلى جانب الأذن: فُرّغت كل عيّنة كتابةً بـwhisper (فالصوت الذي لا يفهمه لا يفهمه المتعلّم أيضًا)، وقُيّمت بـUTMOS، وهو نموذج دُرّب على توقّع مدى طبيعية الصوت عند المستمعين.
- اليابانية ← Kokoro. صوت MeloTTS قريب منه، لكنه يحتاج نحو 2 غ.ب من الاعتماديات للغة واحدة؛ وPiper لا يابانية فيه. أخطأ Kokoro في ثلاث كلمات كانجي قصيرة من عشر حين أُرسلت وحدها، ولم يخطئ في أي منها حين خُتمت كلٌّ منها بـ「。」، فصار التطبيق يختم الكلمة المفردة بنقطة لغتها قبل أن تصل إلى المحرّك.
- الإنجليزية ← Kokoro حين يُختار «طبيعي»: أعلى سطر تقييمًا في التجربة كلها.
- الفرنسية ← أيّهما. صوت Kokoro الفرنسي الوحيد وصوت Piper دُرّبا على التسجيلات نفسها، وتقارب تقييمهما إلى حدود العُشر؛ وكلاهما يأخذ الوصل من صوتيّات espeak-ng. وPiper أسرع بخمس مرات.
- العربية ← صوت Piper الأردني (ar_JO-kareem)، الصوت العربي الوحيد دون اتصال بين الثلاثة. بصراحة: مفهوم تمامًا (كتب whisper السطرين كما هما) لكنه اصطناعي مسموع، وأكثر تسطّحًا من صوت ترجمة Google. والنص غير المشكول لا يُترك للتخمين: في Piper مُشكِّل صغير (libtashkeel) يشكّل النص أولًا، ويُبقي أي حركات كتبتها بنفسك.
- نموذج Kokoro الأصغر (int8) كان أبطأ على المعالج بأربع إلى ست مرات لا أسرع، فالنموذج كامل الدقة هو الذي يُثبَّت.
مقارنةً بترجمة Google: الإنجليزية واليابانية في «طبيعي» من الطبقة نفسها؛ والفرنسية جيدة؛ والعربية متأخرة. وكل ذلك دون اتصال، على جهازك أنت.
التثبيت
الإعدادات ← القراءة بصوت عالٍ والملاحظات الصوتية ← القراءة بصوت عالٍ يعرض ما هو مثبّت وزر ثبّت. اختر «خفيف» أو «طبيعي» واضغطه؛ ويقول الصف ما يفعله — يهيّئ بيئة Python، ويثبّت المحرّك، وينزّل الأصوات مع نسبة مئوية، ثم يُفحص أيّ اللغات يقرأ (أعلاه) — والأصوات جاهزة حين يقول ذلك. ثبّت المحرّك الآخر بالطريقة نفسها متى شئت؛ فاليابانية تحتاج «طبيعي»، والصف يقول ذلك.
لا يحتاج الجهاز إلى تثبيت شيء قبل ذلك. يستعمل زر التثبيت، بهذا الترتيب:
- uv في
PATHإن وُجد (وهو يجلب Python 3.12 بنفسه)؛ - Python من 3.10 إلى 3.13 موجودًا على الجهاز (
python3؛ وpythonأوpyعلى ويندوز)؛ - وإلا جلب Python بنفسه: نسخة CPython 3.12 مستقلة من python-build-standalone لنظامك ومعالجك (لينكس أو ويندوز أو ماك؛ من 21 إلى 34 م.ب)، يُتحقَّق من حجمها ومن بصمتها بالضبط قبل استعمالها، إلى مجلد البيانات. ويقول الصف يُجلب Python لهذا الجهاز مع نسبة مئوية وهو يصل.
والأخير هو ما يجعل تطبيق سطح المكتب يقرأ على جهاز لم يعرف Python قط — وهو الحاسوب المعتاد بويندوز أو لينكس. ولا شيء يحتاج إلى مترجم: الحزم المترجمة تصل عجلاتٍ جاهزة (نسخة المعالج من onnxruntime؛ بلا torch، وبلا CUDA). ولا يقول الصف إن Python غير متاح إلا حين يتعذّر إيجاده وجلبه معًا (دون اتصال، أو على نظام لا نسخة مستقلة له مثل Alpine Linux)، وتقرأ أصوات الجهاز نفسه في الأثناء.
وفي الصف نفسه سرعة (أبطأ، عادية، أسرع) ومنتقي صوت لكل لغة فيها اختيار: الفرنسية (ثلاثة أصوات لـ«خفيف»، وصوت «طبيعي» حين يُثبَّت)، والإنجليزية واليابانية حين يُثبَّت «طبيعي» (خمسة أصوات وأربعة)، وكل لغة عندك لها أصواتك الخاصة. يسرد كل منتقٍ مجموعة لكل محرّك مثبّت — الذي يقرأ اللغة أولًا — ثم أصواتك؛ والصوت الذي لم يُنزَّل بعد يقول يُنزَّل عند اختياره. والاختيار هو صوت تلك اللغة في كل مكان، ويغلب اختيار المحرّك لتلك اللغة، والسهم ▾ في المشغّل يغيّر الإعداد نفسه.
أين يعيش
كل شيء في مجلد البيانات (ASTROLABE_DATA)، لا في الخزانة أبدًا:
tts/venv/ | بيئة Python |
tts/python/ | Python المجلوب، على جهاز لم يكن فيه Python فقط |
models/tts/piper/، models/tts/kokoro/ | الأصوات |
tts/cache/ | كل ما نُطق، محفوظًا بحسب ما قيل (النص، واللغة، والصوت، والسرعة)؛ 500 م.ب على الأكثر، ويذهب أولًا ما طال عهده بالسماع |
وتطبيق سطح المكتب يثبّت في مجلد بياناته هو بالطريقة نفسها، وزر التثبيت يعمل فيه كما هو: الخادم المضمَّن يصنع البيئة ويشغّل المحرّك عمليةً فرعية، كما يفعل مع مُفرِّغ الملاحظات الصوتية. وإزالة الأصوات هي حذف تلك المجلدات.
يبدأ المحرّك مع أول طلب، ويبقى قائمًا ما دمت تستمع، ويتوقف بعد عشر دقائق خاملة ليعيد ذاكرته (نحو 600 م.ب والمحرّكان محمّلان).
أصوات هذا الجهاز
إن لم تكن أصوات التطبيق نفسه مثبّتة للغة — لا شيء مثبّت أصلًا، أو اليابانية قبل تثبيت «طبيعي» — قرأ المشغّل بأصوات هذا الجهاز (أصوات نظام التشغيل، عبر المتصفّح)، ويقول المشغّل دائمًا أيّ الأحوال الثلاثة هو الواقع:
| ما يقوله المشغّل | |
|---|---|
| أصوات التطبيق تنطق | لا شيء — هذه هي الحال المعتادة |
| هي غير مثبّتة، وصوت على الجهاز يتكلم اللغة | أصوات التطبيق نفسه للغة الفرنسية غير مثبّتة — والقراءة الآن بصوت هذا الجهاز: Microsoft Paul ▾، وزرّ ثبّت أصوات التطبيق يفتح الصف أعلاه |
| لا صوت على هذا الجهاز يتكلم اللغة | لا يوجد على هذا الجهاز صوت يتكلم اليابانية. ثبّت أصوات التطبيق (الإعدادات ← القراءة بصوت عالٍ والملاحظات الصوتية ← القراءة بصوت عالٍ)، أو أضف صوتًا إلى النظام. |
أيّ صوت من أصوات الجهاز. الذي اخترته لتلك اللغة، على هذا الجهاز: فالسهم ▾ بجانب اسم الصوت في المشغّل يسرد كل صوت على الجهاز لتلك اللغة، باسمه ولهجته، ويُحفظ اختيارك (في هذا المتصفّح، لهذا الجهاز — وللحاسوب الآخر اختياره). والاختيار نفسه في الإعدادات ← القراءة بصوت عالٍ والملاحظات الصوتية ← القراءة بصوت عالٍ، تحت أصوات هذا الجهاز: منتقٍ لكل لغة يتكلمها الجهاز، وسطر يسمّي اللغات التي لا صوت لها عليه. وإلى أن تختار:
- في تطبيق سطح المكتب على ويندوز: الصوت الذي اخترته في إعدادات ويندوز ← الوقت واللغة ← الكلام — يقرؤه التطبيق من ويندوز. أما صفحة الويب فلا تستطيع: يَسِم Chromium أول صوت في القائمة بأنه «الافتراضي» أيًّا كان ما يقوله ويندوز، ولذلك قد يقرأ متصفّح على ويندوز بصوت آخر إلى أن تختار صوتك بـ▾؛
- على ماك وأندرويد: صوت النظام الافتراضي لتلك اللغة؛
- وإلا فصوت بلهجتك أنت (فرنسية فرنسا قبل فرنسية كندا)، وصوت على الجهاز قبل صوت يرسل الكلمات إلى خدمة على الشبكة.
وجودة الصوت تتوقف على الجهاز: أصوات Microsoft في ويندوز وأصوات Google في أندرويد جيدة. وتطبيق سطح المكتب على لينكس لا أصوات جهاز له أصلًا (فليس لـElectron محرّك نطق هناك)، فهو يقرأ بعد تثبيت أصوات التطبيق — وزر التثبيت يعمل هناك دون أي شيء آخر على الجهاز — ويقول لا يوجد على هذا الجهاز صوت يتكلم … إلى ذلك الحين بدل أن يصمت. والخزانة في الجيب على الهاتف لا خادم لها، فأصواتها دائمًا أصوات الهاتف، وصفّ القراءة بصوت عالٍ فيها هو أصوات الهاتف وحدها.
أصواتك الخاصة
إن كانت على حاسوبك أصوات Piper أصلًا — لأن امتداد Read Text في ليبر أوفيس ثبّتها، أو لأنك نزّلتها بنفسك — فأسطرلاب يستطيع استعمالها. الإعدادات ← القراءة بصوت عالٍ والملاحظات الصوتية ← أصواتك الخاصة تأخذ مجلّدًا؛ فيبحث الخادم فيه وفي كل مجلّد داخله، وكل صوت يجده ينضمّ إلى المنتقيات تحت أصواتك، لكل لغة، ويُختار تمامًا كما يُختار صوت من أصوات التطبيق. لا يُنسخ شيء ولا يُنزَّل: الصوت يُقرأ من مكانه.
توجيهه إلى المجلّد. اكتب المسار الكامل للمجلّد (وفي تطبيق سطح المكتب يفتح استعرض… منتقي المجلّدات في النظام) واحفظ. يقول الصف بعدها ما وجده — الفرنسية: ٣ أصوات · العربية: صوت واحد · تُرك ملفان: لا ملفّ .json بجانب النموذج — ويسرد أيّ الملفات، ولماذا ما لم يستطع استعماله. وأعد الفحص يقرأ المجلّد من جديد بعد أن تضيف صوتًا؛ ويُقرأ أيضًا حين يبدأ الخادم. يجب أن يكون المجلّد مسارًا كاملًا على الحاسوب الذي يعمل عليه الخادم، وخارج الخزانة (فالخزانة تُزامَن وتُنشر، وصوت بحجم 60 م.ب يخصّ هذا الحاسوب). ويُحفظ على هذا الحاسوب وحده، في مجلّد البيانات — فلا ينتقل مع الخزانة إلى أجهزتك الأخرى.
أين تكون أصوات Piper عادةً. صوت Piper دائمًا ملفّان متجاوران: name.onnx (الصوت، من 20 إلى 120 م.ب) وname.onnx.json (إعداداته، بضعة كيلوبايتات). أماكن شائعة:
~/.local/share/piper-voices/ | حيث تحفظ أدوات Piper كثيرة، وسكربتات مثل سكربت Read Text، الأصوات المنزّلة على لينكس |
~/piper/ أو ~/piper-voices/ | تثبيت يدوي |
…/piper-voices/fr/fr_FR/upmc/medium/fr_FR-upmc-medium.onnx | ترتيب فهرس piper-voices نفسه — اللغة/اللهجة/الاسم/الجودة/ — يُقرأ كما هو؛ وجّه إلى المجلّد الأعلى |
لست متأكدًا أين أصواتك؟ نافذة Read Text تعرض الأمر الذي تشغّله، ومسار ملفّ .onnx فيه أو في السكربت الذي يسمّيه؛ أو ابحث في مجلّد المنزل عن *.onnx.json.
صوت الرجل وصوت المرأة ملفّا صوت مختلفان. ليس في Piper مفتاح «ذكر/أنثى»: كل صوت شخص واحد، واختيار صوت آخر هو اختيار ملفّ آخر. وبعض الملفات فيها أكثر من شخص — fr_FR-upmc-medium فيه متحدّثان، jessica وpierre — فيظهران صوتين: Upmc · Jessica وUpmc · Pierre. (وهذا الصوت مدمج أيضًا: Pierre وJessica في «خفيف»، أعلاه.) وتُقرأ حزم Kokoro أيضًا (voices-*.bin بجانب kokoro-*.onnx)، صوتًا لكل مدخل في الحزمة.
ما تحتاجه. أصوات Piper التي عندك تعمل بمحرّك خفيف (بيئته: onnxruntime وpiper)، وحزمة Kokoro بمحرّك طبيعي. وإلى أن يُثبَّت ذلك المحرّك يقول الصف ذلك، مع زرّ التثبيت: تثبيت «خفيف» ينزّل أصوات «خفيف» المدمجة مرّة واحدة (نحو 190 م.ب) — ولا تُنزَّل ملفات أصواتك من جديد. والصوت بلغة لا تكتشفها القراءة بصوت عالٍ بعد (الألمانية مثلًا) يُسرد بين المتروك، مع لغته.
لمزيد من الأصوات: فهرس أصوات Piper (واستمع أولًا في صفحة العيّنات): نزّل ملفَّي .onnx و.onnx.json لصوت إلى مجلّدك واضغط أعد الفحص.
متحدّث خارجي
ولكل ما سوى ذلك، في أصواتك الخاصة جزء مطويّ اسمه متحدّث خارجي (متقدّم): أمر يشغّله الخادم مرّة لكل جملة، للّغات التي تختارها. تصل الجملة إلى المدخل القياسي للبرنامج؛ ويصير {lang} اللغة (fr) و{out} ملفًّا على البرنامج أن يكتب فيه WAV أو Ogg، خلال 20 ثانية. مثالان:
piper --model /home/you/voices/fr_FR-upmc-medium.onnx --speaker 1 --output_file {out}
python3 /home/you/my_speaker.py --language {lang} --out {out}
يُقسَّم الأمر كما يُقسَّم سطر في الصدفة (وعلامات الاقتباس تعمل) لكنه لا يُشغَّل عبر صدفة: فلا أنابيب ولا $VARIABLES، ولا تكون الجملة جزءًا من سطر الأمر أبدًا. وإن خرج البرنامج بخطأ، أو تجاوز 20 ثانية، أو لم يكتب ملفًّا، فالجملة لا تُقرأ بصوت آخر: يقول المشغّل أخفق متحدّثك الخارجي، ورسالة البرنامج نفسه في سجلّ الخادم. ولا يعمل للزوّار أبدًا — فـ«يستطيع القرّاء الاستماع» يستعمل أصوات التطبيق دائمًا.
يعمل بصفة الخادم، فالقرار لمشغّل الجهاز. يعمل البرنامج بمستخدم خادم أسطرلاب نفسه وصلاحياته: كل ما يقدر عليه ذلك المستخدم يقدر عليه الأمر. وهذا أكثر مما ينبغي أن تمنحه كلمة مرور المدير، فالحارس هو ملف .env للخادم نفسه:
SPEAK_EXTERNAL=on(الإعداد). وإلى أن يضبطه مشغّل الجهاز يقول الجزء لم يسمح مشغّل هذا الخادم بمتحدّث خارجي بدل أن يعرض الحقول، ولا يُحفظ أمر، ولا يُشغَّل أمر حُفظ من قبل. وتطبيق سطح المكتب مشغّلُ نفسه فيفعّله. فلا تسمِّ إلا برنامجًا تثق به. ومثل المجلّد، يُحفظ الأمر على هذا الحاسوب وحده ولا ينتقل مع الخزانة أبدًا — فأمرٌ يصل بالمزامنة ثم يُشغَّل يصير أمرَ أيّ أحد.
وليس في الخزانة في الجيب على الهاتف أيّ منهما: فلا خادم لها يفحص مجلّدًا أو يشغّل برنامجًا، وهي تقول ذلك.
يستطيع القرّاء الاستماع
الإعدادات ← القراءة بصوت عالٍ والملاحظات الصوتية ← يستطيع القرّاء الاستماع يعطي زوّار مدونتك الزرّ نفسه فوق تحديدهم. هو معطّل ما لم تفعّله، لأن كل جملة جديدة يطلبها زائر هي من معالج جهازك. ولا ينطق الخادم حينئذ إلا كلمات موجودة في صفحة منشورة (فلا يستطيع الزائر أن يرسل إليه شيئًا آخر ليقرأه)، وستين جملة جديدة على الأكثر لكل عنوان كل عشر دقائق؛ والجملة التي سمعها أحد من قبل تُقدَّم من المخزن المؤقت ولا تكلّف شيئًا.
للمطوّرين
POST /api/speak{ text, lang?, path?, context?, passage?, format? }← جملة واحدة بصيغة Ogg Opus (أو WAV)، معX-Speak-LangوX-Speak-Engine. وcontextفقرة الجملة، وpassageلغة المقطع كله (passageSpeechLangفيshared/speech.ts). و409 speakNotInstalledيسمّي المحرّك الذيneedsتحتاجه اللغة. الطلب الواحد ينطق 1000 حرف على الأكثر؛ والعميل يرسل جملة في كل مرة، ويجلب التالية وهذه تُنطق.GET /api/speak/status— ما هو مثبّت، وتقدّم التثبيت (fetch-pythonمع نسبةprogress، ثمpythonوpackagesوmodelsوcheck)، وفحص كل محرّك (engines.<engine>.check.langs.<lang>←okوphonemesوwhyحين يُخفق:englishأوsilentأوstoppedأوerror)، والأصوات التي تُنزَّل عند اختيارها (voices، بالمعرّف:readyوdownloadedوbytes) والتي تُنزَّل الآن (fetch)، والإعدادات النافذة، وown: مجلّد الأصوات، وما وجده آخر فحص (voices، بحسب اللغة) وما تركه (skipped، معreason). وPOST /api/speak/install{ engine }يبدأ تثبيتًا (وفحصه)؛ وPOST /api/speak/check{ engine }يعيد الفحص؛ وPOST /api/speak/voice{ voice }ينزّل صوتًا يُنزَّل عند اختياره؛ وPOST /api/speak/voices/rescanيقرأ المجلّد من جديد.الفحص هو
server/speakWorker.py --selftest، ويحكم عليهserver/speakSelfTest.ts، ويُحفظ فيASTROLABE_DATA/tts/selftest.json؛ ويُعاد حين يُعاد تثبيت المحرّك أو يتغيّر الفحص نفسه.PATCH /api/settings{ speak: { voicesDir, external: { command, langs } } }— وexternalحيثSPEAK_EXTERNAL=onوحده (وإلا400 speakExternalOff؛ ويقولGET /api/speak/statusذلك فيexternalAllowed)؛ ويُتحقَّق من الاثنين (مسار مطلق خارج الخزانة يستطيع الخادم قراءته؛ وأمر يسمّي{out}) ويُكتبان فيASTROLABE_DATA/speak-local.json، لا فيsettings.jsonالذي تنقله مرآة الإعدادات إلى الخزانة. والصوت الموجود يُحفظ فيspeak.voicesبصيغةown:<المسار داخل المجلّد>(و#speakerلمتحدّث واحد من نموذج)؛ ويحمّله العامل بمساره المطلق ويبقيه محمّلًا بحسب المسار ووقت التعديل، فالملفّ المستبدَل يُحمَّل من جديد. وX-Speak-Voiceيسمّي الصوت الذي نطق.Python المجلوب مثبّت على إصدار واحد من python-build-standalone بحجمه وبصمة SHA-256 (
server/standalonePython.ts)؛ والبرامج يُبحث عنها فيPATHداخل العملية، لا عبرwhichأوwhereأبدًا.ASTROLABE_TTS_THREADSيثبّت عدد خيوط المحرّك (الافتراضي: نصف الأنوية، ثمانية على الأكثر).ASTROLABE_SPEAK_FAKE=1يجعل خادمًا تجريبيًا يجيب بنغمة، لبوابات المتصفّح؛ ويقول الصف محرّك اختبار ما دام مفعّلًا.