אנחנו משפרים את התמיכה ב-Web Audio API ב-Chrome באופן שוטף ובשקט. ב-Chrome 49 (גרסת בטא נכון לפברואר 2016, גרסת יציבה צפויה לצאת במרץ 2016) עדכנו כמה תכונות כדי לעקוב אחרי המפרט, והוספנו גם צומת חדש אחד.
הפונקציה decodeAudioData() מחזירה עכשיו promise
השיטה decodeAudioData() ב-AudioContext
מחזירה עכשיו Promise
, ומאפשרת טיפול בסטרימינג אסינכרוני מבוסס-Promise. ה-method decodeAudioData()
תמיד קיבל פונקציות קריאה חוזרת (callbacks) של הצלחה ושגיאה כפרמטרים:
context.decodeAudioData( arraybufferData, onSuccess, onError);
אבל עכשיו אפשר להשתמש במקום זאת בשיטת Promise רגילה כדי לטפל בטבע האסינכרוני של פענוח נתוני האודיו:
context.decodeAudioData( arraybufferData ).then(
(buffer) => { /* store the buffer */ },
(reason) => { console.log("decode failed! " + reason) });
בדוגמה אחת זה נראה מפורט יותר, אבל ה-Promises מאפשרים לבצע תכנות אסינכרוני בקלות ובאופן עקבי יותר. מטעמי תאימות, עדיין יש תמיכה בפונקציות הקריאה החוזרת (callbacks) של הצלחה ושל שגיאה, בהתאם למפרט.
OfflineAudioContext תומך עכשיו ב-suspend() וב-resume()
במבט ראשון, יכול להיות שייראה מוזר להשתמש ב-suspend() ב-OfflineAudioContext.
אחרי הכל, suspend()
נוסף ל-AudioContext
כדי לאפשר להעביר את חומרת האודיו למצב המתנה, וזה נראה חסר טעם בתרחישים שבהם מבצעים עיבוד (לזה מיועד OfflineAudioContext
, כמובן).
עם זאת, המטרה של התכונה הזו היא לאפשר ליצור רק חלק מ'הניקוד' בכל פעם, כדי למזער את השימוש בזיכרון. אפשר ליצור צמתים נוספים בזמן ההשהיה באמצע הרינדור.
לדוגמה, סונטת הירח של בטהובן מכילה כ-6,500 תווים.
סביר להניח שכל 'הערה' מפורקת לפחות לשני צמתים בתרשים האודיו (למשל, צומת AudioBuffer וצומת Gain). אם רוצים ליצור עיבוד של כל שבע וחצי הדקות במאגר באמצעות OfflineAudioContext
, סביר להניח שלא רוצים ליצור את כל הצמתים האלה בבת אחת. במקום זאת, אפשר ליצור אותם בקטעים של זמן:
var context = new OfflineAudioContext(2, length, sampleRate);
scheduleNextBlock();
context.startRendering().then( (buffer) => { /* store the buffer */ } );
function scheduleNextBlock() {
// create any notes for the next blockSize number of seconds here
// ...
// make sure to tell the context to suspend again after this block;
context.suspend(context.currentTime + blockSize).then( scheduleNextBlock );
context.resume();
}
כך תוכלו לצמצם את מספר הצמתים שצריך ליצור מראש בתחילת העיבוד, ולצמצם את דרישות הזיכרון.
IIRFilterNode
למפרט נוספ צולב לאוהבי אודיו שרוצים ליצור תגובה מיידית אינסופית משלהם שמוגדרת במדויק: IIRFilterNode.
המסנן הזה משלים את BiquadFilterNode, אבל מאפשר לציין באופן מלא את הפרמטרים של תגובת המסנן (במקום AudioParams
של BiquadFilterNode
, שקל להשתמש בו כדי לציין את הסוג, התדר, הערך Q וכו'). ה-IIRFilterNode
מאפשר לציין מסננים בצורה מדויקת שלא ניתן היה ליצור בעבר, כמו מסננים מסדר יחיד. עם זאת, כדי להשתמש ב-IIRFilterNode צריך ידע מעמיק לגבי אופן הפעולה של מסנני IIR, וגם אי אפשר לתזמן אותם כמו BiquadFilterNodes.
שינויים קודמים
רציתי גם לציין כמה שיפורים שנוספו בעבר: ב-Chrome 48, האוטומציה של צמתים מסוג BiquadFilter
התחילה לפעול בקצב אודיו. ממשק ה-API לא השתנה כלל כדי לעשות זאת, אבל זה אומר שהסינון של הצלילים יהיה חלק יותר. בנוסף, ב-Chrome 48 הוספנו שרשרת לשיטה AudioNode.connect()
על ידי החזרת הצומת שאליו אנחנו מתחברים. כך קל יותר ליצור רשתות של צמתים, כמו בדוגמה הזו:
sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);
זה הכול בינתיים, ושיהיה לך המשך יום מצוין!