تحديثات صوتية على الويب في Chrome 49

كريس ويلسون
"كريس ويلسون"

يعمل Chrome باستمرار وبشكل هادئ على تحسين دعمه لواجهة برمجة تطبيقات Web Audio. في الإصدار Chrome 49 (الإصدار التجريبي اعتبارًا من شباط (فبراير) 2016، ومن المتوقّع أن يصبح ثابتًا في آذار (مارس) 2016)، حدّثنا العديد من الميزات لتتبع المواصفات، كما أضفنا عقدة جديدة واحدة.

تقوم فك ترميز AudioData() الآن بإرجاع وعد

تعرض الآن طريقة decodeAudioData() في AudioContext عرض Promise، ما يؤدي إلى تفعيل المعالجة غير المتزامنة للأنماط المستندة إلى Promise. تعتبر الطريقة decodeAudioData() دائمًا دوال استدعاء النجاح والخطأ كمعلمات:

context.decodeAudioData( arraybufferData, onSuccess, onError);

أما الآن، فيمكنك استخدام طريقة Promise العادية للتعامل مع الطبيعة غير المتزامنة لفك ترميز البيانات الصوتية بدلاً من ذلك:

context.decodeAudioData( arraybufferData ).then(
        (buffer) => { /* store the buffer */ },
        (reason) => { console.log("decode failed! " + reason) });

على الرغم من أن هذا الإجراء يبدو مطولاً في مثال واحد، فإن الوعود تجعل البرمجة غير المتزامنة أسهل وأكثر اتساقًا. من أجل التوافق، لا تزال دالتي النجاح وخطأ معاودة الاتصال مدعومة، وفقًا للمواصفات.

يدعم وضع عدم اتصال AudioContext الآن comment() و resume()

للوهلة الأولى، قد يبدو الأمر غريبًا أن يكون لديك comment() على OfflineAudioContext. بعد كل شيء، تمت إضافة suspend() إلى AudioContext لتفعيل وضع جهاز الصوت في وضع الاستعداد، وهو ما يبدو بلا جدوى في حالات العرض على مخزن مؤقّت (وهذا هو الغرض من استخدام OfflineAudioContext بالطبع). غير أن الهدف من هذه الميزة هو أن تكون قادرًا على إنشاء جزء فقط من "درجة" في كل مرة، لتقليل استخدام الذاكرة. يمكنك إنشاء المزيد من العُقد أثناء تعليقها في منتصف العرض.

على سبيل المثال، تحتوي لوحة Moonlight Sonata من تأليف "بيتهوفن" على 6,500 ملاحظة تقريبًا. من المحتمل أن تُفكك كل "ملاحظة" عُقدتين على الأقل من عُقد الرسم البياني الصوتي (مثل مخزن بيانات الصوت المؤقت وعقدة الكسب). إذا كنت تريد تحويل السبع دقائق ونصف بالكامل إلى مخزن مؤقت باستخدام 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

أضاف المواصفات عقدة لعشاق الصوت الذين يريدون إنشاء infinite-im إطلاق-Response وتحديد الاستجابة الخاصة بهم بدقة: IIRFilterNode. يُكمّل هذا الفلتر BiquadFilterNode، ولكنّه يسمح بمواصفات كاملة لمَعلمات استجابة الفلاتر (بدلاً من مَعلمة AudioParams سهلة الاستخدام في BiquadFilterNode لنوع البيانات وترددها وQ وما شابه). تسمح IIRFilterNode بالمواصفات الدقيقة للفلاتر التي تعذّر إنشاؤها من قبل، مثل الفلاتر ذات الترتيب الفردي، ومع ذلك، يتطلّب استخدام IIRFilterNode معرفة عميقة بكيفية عمل فلاتر IIR، كما أنّه لا يمكن جدولتها، مثل BiquadFilterNodes.

التغييرات السابقة

أود أيضًا أن أذكر اثنين من التحسينات التي تم إدخالها سابقًا: في Chrome 48، بدأ تشغيل التشغيل الآلي للعقدة BiquadFilter بمعدل الصوت. لم تتغير واجهة برمجة التطبيقات على الإطلاق للقيام بذلك، ولكن هذا يعني أن عمليات مسح عوامل التصفية الخاصة بك ستبدو أكثر سلاسة. في Chrome 48 أيضًا، أضفنا التسلسل إلى الطريقة AudioNode.connect() عن طريق عرض العقدة التي نتصل بها. يسهّل ذلك إنشاء سلاسل من العُقد، كما في هذا المثال:

sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);

هذا كل ما لدينا الآن ومواصلة الاستماع إلى الموسيقى.