הרשמה לניוזלטר

הרשמה לניוזלטר

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

Ⓒ כל הזכויות שמורות ל- Fed Cast – קהילת מפתחי הפרונט בישראל

ניהול, עריכה ויצירת צלילם

ניהול, עריכה ויצירת צלילים – Web Audio API

עולם הווב עשיר מאוד ביכולות כמו ניהול זמן, וזיהוי מיקום. אחת היכולות אולי הכי פחות מדוברות היא ניהול, עריכה ויצירת צלילים.

אנחנו מקבלים בהכנעה את העובדה שאתרים ויישומים רבים הם אילמים. כאשר לא מדובר על אתרים המכוונים ישירות לאודיו/וידאו אנחנו פחות מצפים לשמוע קולות וצלילים. אך למעשה קולות יכולים להעשיר את חוויית המשתמש, יעיד על כך כל מי שזוכר אתרי ״פלאש״.

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

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

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

התשמע קולי?

יש כמה עקרונות ומושגים בסיסיים מאד שכדאי להכיר בממשק של web audio:

  • Node – יש שלוש תחנות עיקריות עבור הצלילים, כל אחת מהן נקראת node. והן:
    • input – מקור הצליל (מיקרופון, קובץ וכו׳).
    • modification – עיבוד על גבי הצליל (אפקטים, פילטרים וכו׳).
    • output – ממשק היציאה של הצליל. באופן טבעי זה יהיה הרמקול.
  • audio context – הערוץ דרכו הצליל עובר. כל תהליך קולי חייב לשבת על גבי קונטקסט.
  • oscillator – צלילים מסונתזים נוצרים כתוצאה מגל. האופי של הגל הזה יכתיב את אופי הצליל. האוסילטור הוא צורת הגל.
  • צליל יכול לנבוע אך ורק מאינטראקציה. נגמרו הימים שבהם אתר וואלה היה מקפיץ אתכם באמצע הליילה עם פרסומת קולית שהתחילה אוטומטית. כיום חייבים לבצע פעולה יזומה בשביל להפעיל צליל.

בשלב הראשון נייצר צלילים מסונתזים ולכן בגדול סדר הפעולות הוא כזה:

  1. מייצרים קונטקסט אודיו חדש.
  2. מתייחס לסטטוס של הקונטקסט במידת הצורך.
  3. מייצרים אוסילטור ומצמידים לקונטקסט.
  4. מאפיינים את הגל של האוסילטור:
    • סוג: sine, square, sawtooth, triangle, custom.
    • קובעים את התדר שלו, כלומר גובה הצליל.
    • קובעים את המאפיינים שלו, כגון איך העוצמה שלו תתנהג, או האם יתחיל בתדר אחר ויגיע לתדר הרצוי אחרי זמן מה (צליל עולה או יורד).
  5. מפעילים את האוסילטור.
  6. קוראים (מיד) להפסקת האוסילטור עם פרק זמן מוגדר עד לעצירה. החלק הזה מתנהג כמו טיימר פנימי והקריאה אליו היא סינכרונית.

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

צליל מכוון

ניכנס ישירות לעניינים. קודם כל ניצור קונטקסט.

const ctx = new AudioContext()

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

const btn1 = document.querySelector('#btn1')
btn1.addEventListener('click', () => {
  play()
})

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

function play(freq) {
  if (ctx.state === 'suspended') {
    ctx.resume()
  }
  
  const osc = ctx.createOscillator()

נשדך את האוסילטור לקונטקסט ע״י חיבור ליעדו.

  osc.connect(ctx.destination)

נקבע את סוג הצליל.

  osc.type = 'sine'

נקבע את גובה הצליל.

  osc.frequency.value = 300

נתחיל את האוסילטור.

  osc.start()

נקרא לעצירה מתוזמנת.

  osc.stop(ctx.currentTime + 0.5)
}

נטפח לעצמנו על השכם על הכישרון המוסיקלי והתכנותי שלנו.

קרדיט: GIPHY

יונתן לא קטן – הוא צעיר

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

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

function play(freq) {
  if (ctx.state === 'suspended') {
    ctx.resume()
  }
  
  const osc = ctx.createOscillator()
  osc.connect(ctx.destination)
  
  osc.type = 'sine'
  osc.frequency.value = freq
  // osc.frequency.exponentialRampToValueAtTime(freq + 100, ctx.currentTime + 1)
  osc.start()
  osc.stop(ctx.currentTime + 0.5)
}

נוסיף את השורה שמאתחלת את הקונטקסט ואת האירועים שקוראים לפונקציית הנגינה שלנו. רגע אחד… אבל מה גובה הצליל? איך מגדירים דו רה מי? אל דאגה, לא סתם למדתי נגינה בפסנתר בגיל 6. כל המספרים אצלי. או לייתר דיוק, הלכתי לגוגל וגיליתי ש:

do = 261.63

re = 293.66

mi = 329.63

fa = 349.23

sol = 392.00

בשלב הבא נוסיף האזנה ללחיצה על מקשים, כאשר המקלדת הוירטואלית שלנו תעבוד על המקשים a-g.

const ctx = new AudioContext()

document.addEventListener('keydown', (event)  => {
  const keys = {
    a: 261.63,
    s: 293.66,
    d: 329.63,
    f: 349.23,
    g: 392
  }
  
  play(keys[event.key])
})

עכשיו הבמה כולה שלכם!

קרדיט: GIPHY

איפה זה נתמך?

מקורות נוספים

שלום לך 👋 נעים להכיר.

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

אנחנו לא שולחים ספאם!

רוצים לקבל מאיתנו עדכונים?

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

הרשמה לניוזלטר

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