דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
מתמחים טופ
כ

כבוד הרב

@כבוד הרב
אודות
פוסטים
310
נושאים
47
שיתופים
0
קבוצות
0
עוקבים
6
עוקב אחרי
0

פוסטים

פוסטים אחרונים הגבוה ביותר שנוי במחלוקת

  • בירור | תמלול הקלטות לעברית - בדיוק מלא
    כ כבוד הרב

    @אסטרונאוט אני לא חושב שיש שם משהו מסובך.
    אולי הממשק לא כ"כ נוח אבל די פשוט.
    אתה נכנס לקישור שהבאתי ויש לך למטה מקום לכתוב הנחיה ולעלות קבצים מהמחשב ואז יש לך לשלוח את זה ולקבל את התוצאה.

    עזרה הדדית - בינה מלאכותית

  • בירור | תמלול הקלטות לעברית - בדיוק מלא
    כ כבוד הרב

    @אסטרונאוט יותר מג'מני סטודיו?

    עזרה הדדית - בינה מלאכותית

  • בירור | בינה מלאכותית שאפשר לאמן/להכניס טקסט ויש לה API
    כ כבוד הרב

    @עידו300

    האם יש בינה מלאכותית שאפשר לאמן או להכניס לה טקסט (ותהיה צמודה אליו, ורק אליו, בלי >סטיות כלל) ויש לה API שנותן לשלוח בקשות ולקבל תשובות?

    לצורך יצירת בוט טלפוני עסקי.

    לכן חשוב שהוא ישתמש אך ורק בחומר שנתנו לו ולא יבלבלו אותו או ינצלו אותו לדברים אחרים.

    יש לי קצת ניסיון בתחום.
    לדעתי אם יש לך עד 150 טקסטים קבועים פשוט תיצור 150 שלוחות שכל אחת משמיע טקסט אחר ואז אתה כותב לג'מני אינדקס של תמצית של כל שלוחה ומה מספר השלוחה ומבקש ממנו להחזיר את מספר השלוחה התואם בלבד ואז כמובן עם זה אתה מפנה את הלקוח לשלוחה הרצויה.
    אם מדובר על הרבה יותר מזה אז אני גם ניסיתי עם גמני 3 פלש עם הטמעה והוא עובד כמעט ב-100% בציטוט מדוייק אתה יכול לנסות למצא את הטקסט שאליו הוא התכוון עם חיפוש מקורב.
    אני הגעתי איתו מתוך מאגרים ענקיים לתוצאות מושלמות.

    עזרה הדדית - בינה מלאכותית

  • בירור | מה זה הקלוד קוד שנכנס לחיינו ביום בהיר
    כ כבוד הרב

    @למה-באתי כן צריך מנוי פרו ב-20$ לחודש.
    או שאתה רוצה ב-API לשלם לפי שימוש.
    כפי שאתה רואה.

    כללי - עזרה הדדית

  • בירור | תמלול הקלטות לעברית - בדיוק מלא
    כ כבוד הרב

    @לעזור-לכולם לדעתי הכי מדויק זה ג'מני 3 פרו יש לך אותו כאן בחינם לבדיקות.
    אתה יכול להגיד לו בדיוק איך אתה רוצה את הנתונים וכו' וכמובן יש לו גם API תיעוד כאן.

    עזרה הדדית - בינה מלאכותית

  • המלצה | ממשק פניות למוקדי תמיכה שמסתנכרן עם ג'מייל.
    כ כבוד הרב

    @דוד-ארן אני לא מצאתי משהו יותר טוב במחיר כזה.
    אם מצאת אדרבה תמליץ לי אם כי לא חסר לי שם כלום ואני יכול לעשות שם הכל.
    שים לב שזה יותר ניהול מערכת פניות אין שם ניהול מכירות וכד'

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | ממשק פניות למוקדי תמיכה שמסתנכרן עם ג'מייל.
    כ כבוד הרב

    @דוד-ארן זה ממשק במקום ג'מייל הוא מושך משם את המיילים.
    זה בעברית מלאה תורגם על ידי והוכנס רשמית לספריה

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | ממשק פניות למוקדי תמיכה שמסתנכרן עם ג'מייל.
    כ כבוד הרב

    שלום וברכה.
    חיפשתי המון זמן איך אפשר בקלות להפוך חשבון ג'מייל רגיל לממשק לניהול פניות (CRM).
    לפני כמה חודשים מצאתי את מבוקשי freescout.net זה ממשק שמתחבר גם לג'מייל ודרכו אפשר לנהל נציגים לראות מה כל אחד ענה ולהקצות משימות לנציגים ולדעתי בעצם כמעט כל מה שצריך כדי להקים מערך פניות מקצועי כלל גישה ב-API התמשקות עם ווצאפ' ועוד המון פונקציות.
    הספריה עצמה היא בחינם אם כי התוספים שלה הרשמים עולים כסף (אני שילמתי פחות מ-1,000 ש"ח חד פעמי לכל התוספים שהייתי צריך ולא מאמין שמישהו צריך יותר מזה) כמובן שצריך שרת בשביל זה (אם אתם רוצים שרת במיוחד בשביל זה יש כאן זולים).
    אני אישית משתמש עם זה כבר כמה חודשים טובים למאות פניות ביום ואני מאוד מרוצה מזה.
    הם גם מפתחים את זה כל הזמן בלי הפסקה וכל מה שביקשתי מהם הם הוסיפו תוך זמן קצר מאוד!
    ממליץ בחום לכל מי שיש לו ארגון קצת גדול וכל המייל שלו נהיה בלאגן אחד גדול.

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @מתכנת-חובב
    לגבי המרת Base64 מול בינארי:
    אתה צודק ש-Base64 מוסיף תקורה של כ-33% וזה לא יעיל.
    פשוט מסיבה פרקטית שאיך שאני משתמש עכשי בתוכנה זה עובד רק עם הדבקה של טקסט ורק ככה אפשר לשלוח קובץ בימארי בטקסט.
    לגבי WEFAX:
    נכון, זה פרוטוקול עתיק ואיטי. היתרון היחיד שלו הוא שהוא ויזואלי וסלחן לשגיאות. אם יש קטיעה בשידור, אתה מקבל פס שחור קטן בתמונה אבל שאר התמונה ממשיכה להגיע. בהעברת קובץ ZIP, ביט אחד שגוי והקובץ מושחת. למשתמש הפשוט שרוצה להעביר מסמך קריא, לפעמים הויזואליות עדיפה על היעילות.

    בכל אופן הגישה שלי היא למצא משהו בנוי שכבר תואם לדרישות שלי ואחרי שאני ימצא את הכלי המדויק אולי ננסה לחכות אותו, ואני משער שזה אפשרי לשנות את הפרויקט כאן ולהתאים אותו לצרכים המלאים.
    או שאולי פשוט לעשות לו ממשק דרך הדפדפן (בדקתי וזה עובד).

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @מתכנת-חובב ממה שאני בדקתי וניסיתי המודל המהיר ביותר שתפס טוב זה היה BPSK-250 שהוא ממש מהיר משמעותית מכל מה שבדקתי עד עכשיו והוא עבד מעולה כמעט ללא שגיאות, לדעתי זה פשוט צלילים שפחות מסוננים בחברות תקשורת.
    יש לציין שעדיין לא הצלחתי לחבר את הטלפון עם כבל אוקס למחשב ושהמחשב יקלוט אותו אני משער שאם הייתי מצליח הייתי יכול אפילו להשתמש ביותר מהירים.
    כמו כן יש לציין שזה עבד לי רק כשהיה לי דור 4 ברמה יציבה בדור שלוש זה פשוט לא עבד.
    יצרתי גם סקריפט להמרת קובץ לפורמט טוב לתוכנה:
    Drag_To_Encode.bat
    גוררים על זה קובץ והוא מעתיק אוטמטית את הטקסט להדבקה בתוכנה.
    וסקריפט להמרה בחזרה מהתוכנה:
    Paste_To_File.bat
    פותחים את הסקריפט לוחצים על כל מקש במקלדת ואז נפתח חלון של פנקס רשימות מדביקים בו את התוצאה של ההמרה של הצליל מהתוכנה ואז שומרים וסוגרים את החלון של פנקס רשימות ואז צריך להקליד שם לשמירה (כולל סיומת) והקובץ נשמר.
    כמו כן יש פרוטוקול מיוחד לתמונות שהוא עובר שורה שורה ומדפיס אותה וגם אם התפשל שורה אחת השורה הבאה יכולה לצאת טובה קוראים לו WEFAX-IOS288 (כמדומני ש-WEFAX-IOS576 לא עבד טוב עם ימות המשיח) מגעים לממשק של שליחת תמונה ככה: View > Weather Fax Image TX.

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    מי שרוצה לראות תוצאות ומהירות בשטח.
    יש לבחור בפרוטוקול MFSK32 (בהודעה הקודמת כתוב איך לעשות את זה לגבי MT63-2000L).
    להתקשר לקו שמספרו: 0794946346 להפעיל על רמקול לא מדאי חזק אבל שיהיה קרוב למיקרופון ותראו את התוצאות בחלון הצהוב של התוכנה הנ"ל.

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    טוב מצאתי לזה תוכנה שיש שם את האופציה הזו מובנית שפחות או יותר לזה היא נוצרה (בשביל אנשים שמנותקים מהעולם).
    לפרטים נוספים על התוכנה עיין כאן.
    בכל אופן לא היה לי זמן וראש לכתוב לזה מדריך אז כתבתי לג'מיני שיכתוב לי לזה מדריך, זה לא יצא משהו אבל סביר, צריך עוד הרבה חוש תכני כדי להבין מה צריך לעשות ואיך.
    בכל אופן צריך לשבת על זה ולבדוק מה באמת הפרוטוקול הטוב ביותר שלא מדאי רגיש וקולט כל נשימה ולא מדי גס שלא קולט הכל.
    אשמח אם מישהו יוכל לעשות את זה לטובת הכלל כי נראה לי שדרך זה הגענו ליעד!

    @מתכנת-חובב לדעתי תהנה מהתוכנה הזו.

    מדריך מלא: העברת קבצים למחשב מנותק (Offline) דרך קו טלפון

    באמצעות מערכת "ימות המשיח" ותוכנת Fldigi

    מדריך זה מסביר כיצד להעביר קבצים (EXE, PDF, תמונות, סקריפטים) למחשב מנותק מרשת, על ידי המרת הקובץ לצלילים העמידים בפני הפרעות קו טלפון.

    רשימת ציוד נדרש

    1. מחשב שולח (מחובר): להכנת הקובץ.
    2. מחשב מקבל (מנותק): אליו נעביר את המידע.
    3. תוכנת Fldigi: להורדה מכאן (SourceForge).
    4. מיקרופון: מחובר למחשב המנותק (או כבל AUX).

    שלב א': התקנה והגדרות ראשוניות (חובה בשני המחשבים)

    לאחר התקנת התוכנה והפעלתה בפעם הראשונה, יפתח "אשף ההגדרות". יש לפעול בדיוק לפי השלבים הבאים:

    1. מסך 1 (Welcome): לחץ Next.
    2. מסך 2 (Operator Info):
      • מלא פרטים פיקטיביים (למשל: TEST ב-Callsign, ו-USER ב-Name).
      • זה לא משנה לשימוש שלנו. לחץ Next.
    3. מסך 3 (Audio Devices) - המסך הכי חשוב!
      • סמן את האפשרות PortAudio.
      • Capture: בחר את המיקרופון שדרכו תקלוט את הצלילים.
      • Playback: בחר את הרמקולים של המחשב.
      • חשוב מאוד: וודא שהתיבה "File I/O only" אינה מסומנת (ריקה). אם היא מסומנת, לא תוכל לייצר קבצי שמע.
      • לחץ Next.
    4. מסכים 4, 5, 6 (Rig Control - Flrig/RigCAT/Hamlib):
      • אל תיגע בכלום. מסכים אלו מיועדים למכשירי קשר פיזיים.
      • פשוט לחץ Next שוב ושוב עד שתעבור אותם.
    5. מסכים 7, 8 (Updates/Web):
      • לחץ Finish.

    שלב ב': הכנת הקובץ לשידור (במחשב השולח)

    מכיוון שהמודם משדר טקסט, עלינו להמיר את הקובץ הבינארי לטקסט.

    1. המרת הקובץ לטקסט:

      • פתח שורת פקודה (CMD) בתיקייה שבה נמצא הקובץ.
      • הקלד: certutil -encode file.pdf data.txt (החלף את file.pdf בשם הקובץ שלך).
      • פתח את data.txt והעתק את כל תוכנו (כולל השורות BEGIN CERTIFICATE).
    2. המרת הטקסט לקובץ שמע (WAV) ב-Fldigi:

      • פתח את Fldigi.
      • בחר פרוטוקול עמיד לרעשים: Op Mode > MT63 > MT63-2000L.
      • הדבק את הטקסט שהעתקת בחלון התכלת (התחתון).
      • בתפריט: File > Audio > TX Generate.
      • שמור את הקובץ בשם 000.wav.
      • אינדיקציה: הטקסט בחלון התכלת ישנה צבע במהירות – סימן שהקובץ נוצר.

    שלב ג': העלאה למערכת "ימות המשיח"

    1. כנס לממשק הניהול -> שלוחה ריקה.
    2. הגדרות מתקדמות: הגדר type=playfile.
    3. קבצים: העלה את הקובץ 000.wav שיצרת בשלב הקודם.

    שלב ד': ביצוע ההעברה למחשב המנותק

    1. פתח את Fldigi במחשב המנותק.
    2. הגדרות קליטה:
      • וודא שהפרוטוקול הוא: MT63-2000L.
      • ביטול סינון רעשים (SQL): בפינה הימנית התחתונה, וודא שכפתור SQL כבוי (לא ירוק) והמחוון שלידו למטה לגמרי. המחשב צריך "לשמוע הכל".
      • ווליום: בהגדרות ווינדוס, וודא שהמיקרופון על 100%.
    3. לחץ קליק ימני על החלון הלבן (העליון) -> Clear.
    4. השידור:
      • חייג בטלפון למערכת ימות המשיח.
      • הצמד את הטלפון למיקרופון (או חבר כבל). שמור על שקט בחדר.
    5. בזמן השיחה:
      • תראה פסים צהובים יורדים ב"מפל" השחור למטה.
      • בחלון הלבן יופיע ג'יבריש, ואז הטקסט הנקי: -----BEGIN CERTIFICATE-----.

    שלב ה': שחזור הקובץ (במחשב המנותק)

    1. כשהשידור מסתיים, סמן ב-Fldigi את הטקסט רק מהשורה -----BEGIN CERTIFICATE----- ועד -----END CERTIFICATE----- (כולל).
    2. העתק את הטקסט (Ctrl+C).
    3. פתח "פנקס רשימות" (Notepad), הדבק ושמור בשם received.txt.
    4. פתח שורת פקודה (CMD) באותה תיקייה והרץ:
      certutil -decode received.txt final_file.pdf
      
      (שנה את הסיומת pdf לסיומת המקורית של הקובץ).

    פתרון תקלות

    • הטקסט יוצא "זבל" (ג'יבריש) ללא הפסקה: האות חלש מדי. הגבר את הווליום בטלפון לאזור 80%-90% וודא שמיקרופון המחשב על 100%.
    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @חנוך-הכהן
    כן, טכנית זה נכון, אבל האתגר הוא לא "לעשות ביפ", האתגר הוא לגרום לביפ הזה לשרוד.
    זה כמו להגיד על Wi-Fi: "אז זה בסך הכל רדיו שעושה גלים באוויר במקום מוזיקה?
    או על סיבים אופטיים: "אז זה בסך הכל פנס שמהבהב ממש מהר בקצה של צינור?

    תכלס התוצאה חמודה גם אם לא כל כך שימושית.
    אבל אני תולה תקוות שאיך שהוא מישהו ימצא תדרך להוציא מזה משהו.

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @דוד-יצחק נכון!
    כי לא נראה לי שיש סיכוי להעביר קבצים בזה כרגע.
    זה גרסה רק כדי להראות את היכולות של זה.

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @מתכנת-חובב עכשיו שזה לטקסט זה המיר לי 2,697 תווים ל-7:10 דקות!

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @smct מוזר תנסה שוב
    או שאולי המחשב שלך איטי מדאי

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @דוד-יצחק תפתח ותראה זה שונה לגמרי וכל הלוגיקה שונתה והיא תואמת בעיקר לטקסט.

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    מי שרוצה דוגמה חייה לאחת הגרסאות המתקדמות שלי זה הקישור:

    https://drive.google.com/file/d/1WtkPXOtK0Dm0_yI*****Csmf7FbsBG8NLrkAb/view?usp=sharing
    

    להוריד כוכביות ולא לפרסם ללא הכוכביות.
    יש הקלטה מוכנה להשמעה בקו שמספרו: 0794946346.
    יש להיכנס לתוכנה ללחוץ על "התחל האזנה" ואז לחייג לקו ולהיכנס לשלוחה 1 לעשות על רמקול לסתום אוזנים ואז תתחילו לראות את הטקסט שג'ימני יצר שהוא מסביר על התוכנה.
    שימו לב שבקוד הזה הטקסט חולק למקטעים ולכן גם אם יתפספס קטע אחד אתם תראו את הקטע הבא אחרי כמה שניות.

    הקוד בספוילר:

    import sys
    import os
    import struct
    import threading
    import zlib
    import base64
    import time
    import queue
    import datetime
    import numpy as np
    import sounddevice as sd
    import soundfile as sf
    from scipy.io import wavfile
    from scipy import signal as sig
    from reedsolo import RSCodec, ReedSolomonError
    import tkinter as tk
    from tkinter import filedialog, messagebox, ttk, scrolledtext
    
    # === הגדרות ליבה: STREAMER V3 ===
    SAMPLE_RATE = 8000
    BAUD_RATE = 50        
    RS_ECC_SYMBOLS = 20   
    INTERLEAVE_STEP = 10  
    FREQS = [1000, 1400, 1800, 2200] # 4-FSK
    
    # סנכרון
    SYNC_DURATION = 0.4
    t_sync = np.arange(int(SAMPLE_RATE * SYNC_DURATION)) / SAMPLE_RATE
    SYNC_SIGNAL = sig.chirp(t_sync, f0=1000, f1=2200, t1=SYNC_DURATION, method='linear')
    
    # גודל מנה (תווים)
    CHUNK_SIZE = 120 
    
    TEXT_EXTENSIONS = ['.txt', '.csv', '.json', '.xml', '.html', '.php', '.py', '.js', '.ini', '.log']
    
    # === לוגיקה מתמטית (Modem Engine) ===
    def interleave(bits):
        n = len(bits)
        pad = (INTERLEAVE_STEP - (n % INTERLEAVE_STEP)) % INTERLEAVE_STEP
        src = bits + [0]*pad
        dst = [0]*len(src)
        rows = len(src)//INTERLEAVE_STEP
        for i in range(len(src)):
            dst[(i%INTERLEAVE_STEP)*rows + (i//INTERLEAVE_STEP)] = src[i]
        return dst, pad
    
    def deinterleave(bits, pad):
        n = len(bits)
        rows = n//INTERLEAVE_STEP
        dst = [0]*n
        for i in range(n):
            col = i // rows
            row = i % rows
            dst[row*INTERLEAVE_STEP + col] = bits[i]
        return dst[:-pad] if pad else dst
    
    def text2bits(b):
        res = []
        for x in b:
            for i in range(7,-1,-1): res.append((x>>i)&1)
        return res
    
    def bits2bytes(b):
        res = bytearray()
        for i in range(0, len(b), 8):
            byte = b[i:i+8]
            if len(byte)<8: break
            v = 0
            for bit in byte: v = (v<<1)|bit
            res.append(v)
        return bytes(res)
    
    # === Encoder ===
    def encode_packet(data_bytes, packet_id, total_packets):
        try:
            compressed = zlib.compress(data_bytes, level=9)
            header = struct.pack('>HHH', packet_id, total_packets, len(compressed))
            payload = header + compressed
            
            rsc = RSCodec(RS_ECC_SYMBOLS)
            encoded = rsc.encode(payload)
            
            bits = text2bits(encoded)
            shuffled, pad = interleave(bits)
            
            meta_header = struct.pack('>BH', pad, len(shuffled))
            meta_bits = text2bits(meta_header)
            
            final_bits = meta_bits + shuffled
            if len(final_bits) % 2 != 0: final_bits.append(0)
            
            sps = int(SAMPLE_RATE / BAUD_RATE)
            t_sym = np.arange(sps) / SAMPLE_RATE
            phase = 0
            waves = []
            
            for i in range(0, len(final_bits), 2):
                val = (final_bits[i] << 1) | final_bits[i+1]
                freq = FREQS[val]
                w = np.sin(2 * np.pi * freq * t_sym + phase)
                waves.append(w)
                phase += 2 * np.pi * freq * (sps / SAMPLE_RATE)
                phase %= 2 * np.pi
                
            silence = np.zeros(int(SAMPLE_RATE * 0.25)) 
            return np.concatenate([SYNC_SIGNAL, np.concatenate(waves), silence])
        except: return None
    
    def generate_stream_file(filename, file_content, output_wav):
        try:
            ext = os.path.splitext(filename)[1].lower()
            is_text = ext in TEXT_EXTENSIONS
            chunks = []
            
            if is_text:
                try:
                    text_str = file_content.decode('utf-8', errors='ignore')
                    curr = ""
                    words = text_str.replace('\n', ' \n ').split(' ') 
                    for word in words:
                        if len(word.encode('utf-8')) > CHUNK_SIZE:
                            if curr: chunks.append(curr.encode('utf-8')); curr = ""
                            chunks.append(word.encode('utf-8')); continue
                        if len(curr.encode('utf-8')) + len(word.encode('utf-8')) < CHUNK_SIZE:
                            curr += word + " "
                        else:
                            chunks.append(curr.encode('utf-8')); curr = word + " "
                    if curr: chunks.append(curr.encode('utf-8'))
                except:
                    chunks = [file_content[i:i+CHUNK_SIZE] for i in range(0, len(file_content), CHUNK_SIZE)]
            else:
                chunks = [file_content[i:i+CHUNK_SIZE] for i in range(0, len(file_content), CHUNK_SIZE)]
                
            total = len(chunks)
            audio_parts = []
            t_wake = np.arange(int(SAMPLE_RATE * 2.0)) / SAMPLE_RATE
            wake = np.sin(2 * np.pi * 2200 * t_wake)
            audio_parts.append(wake)
            
            for i, chunk in enumerate(chunks):
                pkt = encode_packet(chunk, i+1, total)
                if pkt is not None: audio_parts.append(pkt)
                    
            final_float = np.concatenate(audio_parts)
            mx = np.max(np.abs(final_float))
            final_int16 = (final_float / mx * 32767).astype(np.int16) if mx > 0 else final_float.astype(np.int16)
                
            wavfile.write(output_wav, SAMPLE_RATE, final_int16)
            return True, f"{total}"
        except Exception as e: return False, str(e)
    
    # === Decoder ===
    def decode_packet_from_stream(clean_audio):
        try:
            sps = int(SAMPLE_RATE / BAUD_RATE)
            num_syms = len(clean_audio) // sps
            if num_syms < 50: return None, 0
            
            t = np.arange(sps) / SAMPLE_RATE
            refs = [np.exp(-2j * np.pi * f * t) for f in FREQS]
            
            bits_str = ""
            for i in range(num_syms):
                chunk = clean_audio[i*sps : (i+1)*sps]
                energies = [np.abs(np.dot(chunk, r))**2 for r in refs]
                bits_str += str((np.argmax(energies)>>1)&1) + str(np.argmax(energies)&1)
                
            if len(bits_str) < 24: return None, 0
            meta_bits = [int(b) for b in bits_str[:24]]
            pad, bit_len = struct.unpack('>BH', bits2bytes(meta_bits))
            
            if bit_len > 10000 or bit_len == 0: return None, 0
            if len(bits_str) < 24 + bit_len: return None, 0 
            
            payload_bits = [int(b) for b in bits_str[24 : 24+bit_len]]
            raw_bits = deinterleave(payload_bits, pad)
            packet_bytes = bits2bytes(raw_bits)
            
            decoded = RSCodec(RS_ECC_SYMBOLS).decode(packet_bytes)[0]
            
            pkt_id, pkt_total, content_len = struct.unpack('>HHH', decoded[:6])
            content = zlib.decompress(decoded[6 : 6+content_len])
            samples_consumed = ((24 + bit_len) // 2) * sps
            
            return (pkt_id, pkt_total, content), samples_consumed
        except: return None, 0
    
    # === GUI Professional ===
    class AcousticReader:
        def __init__(self, root):
            self.root = root
            self.root.title("Acoustic Reader Pro")
            self.root.geometry("600x700")
            self.root.configure(bg="#2C3E50")
            
            self.audio_buffer = np.array([], dtype=float)
            self.is_rec = False
            self.q = queue.Queue()
            self.received_packets = {} 
            
            # Styles
            style = ttk.Style()
            style.theme_use('clam')
            style.configure("TNotebook", background="#2C3E50", borderwidth=0)
            style.configure("TNotebook.Tab", background="#34495E", foreground="white", padding=[20, 10], font=("Segoe UI", 11))
            style.map("TNotebook.Tab", background=[("selected", "#3498DB")])
            style.configure("TFrame", background="#ECF0F1")
            
            tabs = ttk.Notebook(root)
            t_decode = ttk.Frame(tabs) # קבלה ראשון
            t_encode = ttk.Frame(tabs) # יצירה שני
            
            tabs.add(t_decode, text=" 📥 קליטת נתונים (חיבור AUX) ")
            tabs.add(t_encode, text=" 📤 יצירת קובץ (למנהל) ")
            tabs.pack(fill="both", expand=True, padx=10, pady=10)
            
            self.setup_decoder(t_decode)
            self.setup_encoder(t_encode)
            
            self.root.after(100, self.process_queue)
    
        def setup_decoder(self, parent):
            frame = tk.Frame(parent, bg="#ECF0F1")
            frame.pack(fill="both", expand=True, padx=20, pady=20)
            
            # Header
            tk.Label(frame, text="מערכת לקליטת עלונים וקבצים", font=("Segoe UI", 18, "bold"), bg="#ECF0F1", fg="#2C3E50").pack(pady=10)
            
            # Status & Vol
            status_frame = tk.Frame(frame, bg="#BDC3C7", bd=1, relief="sunken")
            status_frame.pack(fill="x", pady=10)
            
            self.canvas_vol = tk.Canvas(status_frame, width=300, height=15, bg="#95a5a6", highlightthickness=0)
            self.canvas_vol.pack(side="left", padx=10, pady=5)
            self.vol_bar = self.canvas_vol.create_rectangle(0,0,0,15, fill="#2ECC71")
            
            self.lbl_status = tk.Label(status_frame, text="ממתין להפעלה...", font=("Segoe UI", 10), bg="#BDC3C7")
            self.lbl_status.pack(side="right", padx=10)
    
            # Main Button
            self.btn_rec = tk.Button(frame, text="התחל האזנה", command=self.toggle_rec, 
                                     font=("Segoe UI", 16, "bold"), bg="#27AE60", fg="white", 
                                     activebackground="#2ECC71", activeforeground="white", bd=0, padx=20, pady=10)
            self.btn_rec.pack(pady=10)
            
            # Text Area
            tk.Label(frame, text="תוכן הקובץ המתקבל:", font=("Segoe UI", 11), bg="#ECF0F1", anchor="w").pack(fill="x")
            self.txt_display = scrolledtext.ScrolledText(frame, height=15, font=("Segoe UI", 12), bd=2, relief="flat")
            self.txt_display.pack(fill="both", expand=True, pady=5)
            self.txt_display.tag_config("info", foreground="#E67E22", font=("Segoe UI", 10, "bold"))
            self.txt_display.tag_config("content", foreground="#2C3E50")
            
            # Footer buttons
            btn_frame = tk.Frame(frame, bg="#ECF0F1")
            btn_frame.pack(pady=5)
            tk.Button(btn_frame, text="נקה מסך", command=self.clear_screen, bg="#95a5a6", fg="white", bd=0, padx=10).pack(side="left", padx=5)
            tk.Button(btn_frame, text="העתק טקסט", command=self.copy_text, bg="#3498DB", fg="white", bd=0, padx=10).pack(side="left", padx=5)
    
        def setup_encoder(self, parent):
            frame = tk.Frame(parent, bg="#ECF0F1")
            frame.pack(fill="both", expand=True, padx=20, pady=20)
            
            tk.Label(frame, text="יצירת קובץ שמע למערכת הטלפונית", font=("Segoe UI", 16, "bold"), bg="#ECF0F1", fg="#2C3E50").pack(pady=20)
            tk.Label(frame, text="בחר קובץ טקסט/מסמך להמרה.\nהמערכת תיצור קובץ WAV מותאם לשידור.", font=("Segoe UI", 11), bg="#ECF0F1", fg="#7F8C8D").pack(pady=10)
            
            tk.Button(frame, text="בחר קובץ והמר", command=self.do_enc, 
                      font=("Segoe UI", 14), bg="#2980B9", fg="white", 
                      activebackground="#3498DB", activeforeground="white", bd=0, padx=20, pady=15).pack(pady=40)
            
            self.lbl_enc = tk.Label(frame, text="", font=("Segoe UI", 11, "bold"), bg="#ECF0F1", fg="#27AE60")
            self.lbl_enc.pack()
    
        def clear_screen(self):
            self.txt_display.delete('1.0', tk.END)
            self.received_packets = {}
    
        def copy_text(self):
            self.root.clipboard_clear()
            self.root.clipboard_append(self.txt_display.get("1.0", tk.END))
            messagebox.showinfo("הועתק", "התוכן הועתק ללוח")
    
        def do_enc(self):
            fn = filedialog.askopenfilename()
            if not fn: return
            sn = filedialog.asksaveasfilename(defaultextension=".wav", filetypes=[("WAV","*.wav")])
            if not sn: return
            
            self.lbl_enc.config(text="מעבד... אנא המתן", fg="blue")
            self.root.update()
            try:
                with open(fn,'rb') as f: c=f.read()
                ok, msg = generate_stream_file(fn, c, sn)
                if ok: self.lbl_enc.config(text=f"הצלחה! נוצר קובץ עם {msg} מנות.", fg="#27AE60")
                else: self.lbl_enc.config(text=f"שגיאה: {msg}", fg="#C0392B")
            except Exception as e: self.lbl_enc.config(text=f"שגיאה: {e}", fg="#C0392B")
    
        def toggle_rec(self):
            if not self.is_rec:
                self.is_rec = True
                self.btn_rec.config(text="⏹️ עצור הקשבה", bg="#C0392B", activebackground="#E74C3C")
                self.audio_buffer = np.array([], dtype=float)
                self.lbl_status.config(text="מקשיב לקו... (נא להשמיע)", fg="#2980B9")
                self.clear_screen()
                threading.Thread(target=self.rec_thread).start()
            else:
                self.is_rec = False
                self.btn_rec.config(text="התחל האזנה", bg="#27AE60", activebackground="#2ECC71")
                self.lbl_status.config(text="מוכן")
    
        def update_vol(self, indata):
            peak = np.max(np.abs(indata)) / 32768.0
            w = min(300, int(peak * 300))
            c = "#2ECC71" if w < 200 else "#E74C3C"
            self.canvas_vol.coords(self.vol_bar, 0, 0, w, 15)
            self.canvas_vol.itemconfig(self.vol_bar, fill=c)
    
        def rec_thread(self):
            def cb(i, f, t, s): self.q.put(i.copy())
            # שימוש בברירת מחדל של המערכת (ללא device index)
            try:
                with sd.InputStream(samplerate=SAMPLE_RATE, channels=1, callback=cb):
                    while self.is_rec: sd.sleep(100)
            except Exception as e:
                self.is_rec = False
                messagebox.showerror("Error", f"שגיאת מיקרופון: {e}")
    
        def process_queue(self):
            try:
                while not self.q.empty():
                    chunk = self.q.get_nowait().flatten()
                    self.update_vol(chunk * 32767)
                    self.audio_buffer = np.concatenate((self.audio_buffer, chunk))
                
                if len(self.audio_buffer) > SAMPLE_RATE * 15:
                    self.audio_buffer = self.audio_buffer[-SAMPLE_RATE*15:]
                self.try_decode()
            except: pass
            self.root.after(50, self.process_queue)
    
        def try_decode(self):
            if len(self.audio_buffer) < 4000: return
            buff = self.audio_buffer.copy()
            
            sos = sig.butter(4, [800, 2400], btype='bandpass', fs=SAMPLE_RATE, output='sos')
            clean = sig.sosfilt(sos, buff)
            mx = np.max(np.abs(clean))
            if mx > 0.01: clean /= mx
            
            corr = sig.correlate(clean, SYNC_SIGNAL, mode='valid')
            peaks, _ = sig.find_peaks(np.abs(corr), height=5, distance=SAMPLE_RATE)
            
            for peak_idx in peaks:
                start_data = peak_idx + len(SYNC_SIGNAL)
                if len(clean) > start_data + 500:
                    audio_chunk = clean[start_data:]
                    result, consumed = decode_packet_from_stream(audio_chunk)
                    if result:
                        pkt_id, total, content = result
                        if pkt_id not in self.received_packets:
                            self.received_packets[pkt_id] = True
                            try:
                                text = content.decode('utf-8')
                                self.append_text(f"--- חלק {pkt_id} מתוך {total} ---\n", "info")
                                self.append_text(text + "\n", "content")
                            except:
                                self.append_text(f"--- חלק {pkt_id}/{total} (קובץ בינארי) ---\n", "info")
                        
                        cut_pos = start_data + consumed + 100
                        if cut_pos < len(self.audio_buffer): self.audio_buffer = self.audio_buffer[cut_pos:]
                        else: self.audio_buffer = np.array([], dtype=float)
                        break 
    
        def append_text(self, text, tag):
            self.txt_display.insert(tk.END, text, tag)
            self.txt_display.see(tk.END)
    
    if __name__ == "__main__":
        root = tk.Tk()
        app = AcousticReader(root)
        root.mainloop()
    

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @דוד-יצחק אחד הדברים שאפשר לעשות כדי לדחוס מעבר לדחיסה רגילה זה להוריד את השימוש ב-UTF-8 כי זה מכפיל כל ביט.
    השאלה היא אם אפשר לשלוח מהתוכנה DTMF לימות המשיח שימשיך להקלטה הבאה אם זה עבר טוב או שישמיע שוב אם זה לא עבר טוב.
    את התפריט לאחר כל קובץ אפשר להגדיר עם ההקדרה הבאה במודול השמעת קבצים כמו שמופיע כאן:

    ניתן להגדיר תפריט לאחר כל השמעה

    after_play_tfr=tfr_more_options
    

    ברירת מחדל של התפריט M1459 לשמיעה חוזרת הקישו 0 למעבר להשמעה הבאה הקישו 1
    ניתן להגדיר את התפריט מחדש ראה כאן

    י

    עזרה הדדית - מחשבים וטכנולוגיה

  • המלצה | 🚀 [פרויקט מהפכני] העברת קבצים למחשב ללא אינטרנט דרך שיחה קולית (טלפון כשר!) - הקוד המלא
    כ כבוד הרב

    @מתכנת-חובב אגב חשבתי על ראיון שיהיה שמיש לטקסט שאפשר לחתוך למקטעים וכל פעם שהוא שומע מקטע הוא מציג אותו למשתמש.
    ניסיתי וזה עובד.
    זה כבר אולי יותר הגיוני כך שאם לדוגמה אתה שולח לו טקסט ארוך אחרי דקה יש לו מה לקרא כבר.
    אבל תכלס באמת זה לא נראה מדי מתקדם ובפרט שאין לנו אפשרות לשלוט על מה שימות המשיח מורידים מהאיכות ועל מה שהחברות תקשורת מורידים מהאיכות כך שלא נשאר הרבה אופציות איך לדחוס את זה הרבה יותר מזה ושזה יקלוט הכל
    אבל האמת היא שאין לי כבל אוקס ואני מנסה את זה דרך הרמקול שזה מוריד את הרמה דרסטית אולי אני יקנה בהמשך ונראה מה הרמה ההכי דחוסה שאפשר לשלוח את זה.

    עזרה הדדית - מחשבים וטכנולוגיה
  • התחברות

  • אין לך חשבון עדיין? הרשמה

  • התחברו או הירשמו כדי לחפש.
  • פוסט ראשון
    פוסט אחרון
0
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר