File size: 4,933 Bytes
9d29c62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import os
import re
import time
import torch
import torchaudio
import warnings
from pydub import AudioSegment

warnings.filterwarnings("ignore")

# =========================================================================
# פתרון חסין לטעינה על CPU
# =========================================================================
original_load = torch.load

def safe_load(*args, **kwargs):
    if 'map_location' not in kwargs:
        kwargs['map_location'] = 'cpu'
    if 'weights_only' in kwargs:
        kwargs['weights_only'] = False
    return original_load(*args, **kwargs)

torch.load = safe_load
# =========================================================================

try:
    from chatterbox.mtl_tts import ChatterboxMultilingualTTS
    from phonikud_onnx import Phonikud
    from phonikud import lexicon
except ImportError:
    print("❌ שגיאה: חסרות ספריות. וודא שאתה ב-venv_fix והרצת pip install.")
    exit()

class TTSManager:
    def __init__(self, reference_audio_path="new_teacher_reference.wav"):
        print("⚙️  טוען מנוע 'המורה למתמטיקה' (ZipVoice Mode)...")
        self.device = "cpu"
        self.ref_audio_path = reference_audio_path
        self.phonikud_model = Phonikud("phonikud-1.0.int8.onnx")
        self.tts_model = ChatterboxMultilingualTTS.from_pretrained(device=self.device)
        print("✅ המנוע מוכן.")

    def _split_to_sentences(self, text):
        return [s.strip() for s in re.split(r'(?<=[.!?]) +', text) if s.strip()]

    def generate_audio(self, text, output_filename="welcome_speech_v2.wav"):
        sentences = self._split_to_sentences(text)
        print(f"📝 מעבד {len(sentences)} משפטים קצרים (למניעת 'נשימות')...")
        
        combined = AudioSegment.empty()
        silence = AudioSegment.silent(duration=250) 

        for i, sentence in enumerate(sentences):
            temp_file = f"temp_part_{i}.wav"
            print(f"🎙️  משפט {i+1}/{len(sentences)}: {sentence[:30]}...")
            
            # שלב 1: ניקוד אוטומטי
            voweled = self.phonikud_model.add_diacritics(sentence)
            voweled = re.sub(fr"[{lexicon.NON_STANDARD_DIAC}]", "", voweled)
            
            # שלב 2: תיקון כפוי לנקבה! מחליף "מורֶה" ב-"מורָה"
            voweled = voweled.replace("מוֹרֶה", "מוֹרָה").replace("מּוֹרֶה", "מּוֹרָה")
            
            # ייצור הקול
            wav = self.tts_model.generate(
                voweled, 
                language_id="he", 
                audio_prompt_path=self.ref_audio_path,
                cfg_weight=0.90 
            )
            torchaudio.save(temp_file, wav, self.tts_model.sr)
            combined += AudioSegment.from_wav(temp_file) + silence
            os.remove(temp_file)

        combined.export(output_filename, format="wav")
        print(f"✨ הושלם! הקובץ מחכה ב: {output_filename}")

if __name__ == "__main__":
    REFERENCE_FILE = "new_teacher_reference.wav"
    
    if not os.path.exists(REFERENCE_FILE):
        print(f"❌ שגיאה: קובץ דגימה '{REFERENCE_FILE}' לא נמצא.")
    else:
        tts = TTSManager(reference_audio_path=REFERENCE_FILE)
        
        # הטקסט פוצל למשפטים קצרים עם נקודות למניעת רעשי נשימה ועומס על המודל
        script = (
            "היי! ברוכים הבאים למורה למתמטיקה. איזה כיף שהצטרפתם אליי! "
            "אני כאן כדי להפוך את המתמטיקה לחוויה ברורה וחזותית. "
            "במסך כאן תמצאו שני כפתורים עיקריים. "
            "לחצו על הכפתור הירוק פתרי לי תרגיל, אם אתם צריכים פתרון מלא ומודרך מאפס. "
            "או על הכפתור הוורוד בדקי לי תשובה, כדי שאעבור על הדרך שאתם עשיתם ואגיד לכם אם צדקתם. "
            "חשוב שתדעו, אני תמיד כאן בשבילכם. "
            "אם סיימתי לפתור ועדיין משהו לא מובן, פשוט תלחצו על הכפתור שאל את המורה. "
            "אני אשמח להסביר הכל שוב עד שהכל יהיה ברור ומסודר בראש. "
            "ועוד טיפ קטן ממני. "
            "אם אתם יושבים ללמוד למבחן, הכי כדאי לעבוד עם מחשב ולא עם הטלפון, כי שם הכל הרבה יותר ברור. "
            "כדי להתחבר, פשוט נכנסים לאתר מהמחשב ומאשרים את הכניסה דרך הטלפון שלכם. "
            "שיהיה המון בהצלחה!"
        )
        
        tts.generate_audio(script, "welcome_speech_v2.wav")