Chrome 49 में वेब ऑडियो अपडेट

क्रिस विल्सन
क्रिस विल्सन

Chrome, Web Audio API के लिए अपनी सहायता को लगातार और धीरे-धीरे बेहतर बना रहा है. हमने Chrome 49 (फ़रवरी 2016 तक का बीटा वर्शन और मार्च 2016 में स्थिर रहने की उम्मीद है) में, हमने विशेषताओं को ट्रैक करने के लिए कई सुविधाएं अपडेट की हैं. साथ ही, एक नया नोड भी जोड़ा है.

decodeAudioData() अब एक प्रॉमिस देता है

AudioContext पर decodeAudioData() तरीका, अब Promise रिटर्न करता है. इससे, प्रॉमिस पर आधारित एसिंक्रोनस पैटर्न को हैंडल करने में मदद मिलती है. decodeAudioData() तरीके ने हमेशा सफलता और गड़बड़ी वाले कॉलबैक फ़ंक्शन को पैरामीटर के तौर पर लिया है:

context.decodeAudioData( arraybufferData, onSuccess, onError);

हालांकि, अब इसे डिकोड करने के ऑडियो डेटा के एसिंक्रोनस टाइप को हैंडल करने के लिए, स्टैंडर्ड Promise तरीका अपनाया जा सकता है:

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

हालांकि, एक उदाहरण में यह ज़्यादा शब्दों में दिखता है, लेकिन प्रॉमिस एसिंक्रोनस प्रोग्रामिंग को आसान और एक जैसा बना देता है. साथ ही, निर्देशों के मुताबिक 'सफलता' और 'गड़बड़ी' कॉलबैक फ़ंक्शन अब भी काम करते हैं.

ऑफ़लाइन ऑडियो कॉन्टेक्स्ट अब निलंबित() और फिर से शुरू करें() के साथ काम करता है

पहली नज़र में, किसी OfflineAudioContext में निलंबन() का होना अजीब लग सकता है. आखिरकार, ऑडियो हार्डवेयर को स्टैंडबाय मोड में रखने के लिए, suspend() को AudioContext में जोड़ा गया. बफ़र (यानी OfflineAudioContext की वजह से ही) को बफ़र में रेंडर करना ज़रूरी नहीं है. हालांकि, इस सुविधा का मकसद एक बार में "स्कोर" का सिर्फ़ एक हिस्सा बनाना है, ताकि मेमोरी का इस्तेमाल कम किया जा सके. अगर इमेज को रेंडर करते समय बीच में उसे निलंबित कर दिया जाता है, तो और नोड बनाए जा सकते हैं.

जैसे, बीथोवन के मूनलाइट सोनाटा में करीब 6,500 नोट शामिल हैं. हर "नोट" को शायद कम से कम कुछ ऑडियो ग्राफ़ नोड (उदाहरण के लिए, AudioBuffer और गेन नोड) के हिसाब से बनाया जाता है. अगर आपको 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-impulse-response बनाना चाहते हैं: IIRFilterNode. यह फ़िल्टर, BiquadFilterNode के साथ काम करता है. हालांकि, यह फ़िल्टर रिस्पॉन्स पैरामीटर की पूरी जानकारी देता है (टाइप, फ़्रीक्वेंसी, Q वगैरह के लिए BiquadFilterNode के इस्तेमाल में आसान AudioParams के बजाय). IIRFilterNode, ऐसे फ़िल्टर की सटीक जानकारी देता है जिन्हें पहले नहीं बनाया जा सकता था, जैसे कि सिंगल-ऑर्डर फ़िल्टर. हालांकि, IIRFilterNode को इस्तेमाल करने के बारे में थोड़ी जानकारी होना ज़रूरी है. साथ ही, इन्हें समय-समय पर शेड्यूल भी नहीं किया जा सकता, जैसे कि BiquadFilterNodes.

पिछले बदलाव

मैं कुछ सुधारों की जानकारी देना चाहता हूं जो पहले लागू हो चुके हैं: Chrome 48 में, BiquadFilter नोड ऑटोमेशन में ऑडियो रेट से चलने लगा. एपीआई ऐसा करने के लिए बिलकुल नहीं बदला, लेकिन इसका मतलब है कि आपका फ़िल्टर स्वीप और भी आसान होगा. साथ ही, Chrome 48 में, हमने उस नोड को लौटाकर AudioNode.connect() तरीके में चेन जोड़ा है जिससे हम कनेक्ट कर रहे हैं. इससे नोड की चेन बनाना आसान हो जाता है, जैसा कि इस उदाहरण में बताया गया है:

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

अभी के लिए बस इतना ही और धूम मचाते रहें!