Web Audio API के साथ गेम ऑडियो डेवलप करना

शुरुआती जानकारी

ऑडियो एक अहम हिस्सा है, जो मल्टीमीडिया सुविधाओं को दिलचस्प बनाता है. अगर आपने कभी बिना आवाज़ के कोई फ़िल्म देखने की कोशिश की है, तो शायद आपने ध्यान दिया होगा.

गेम भी अछूते नहीं हैं! वीडियो गेम की मेरी सबसे प्यारी यादें, संगीत और साउंड इफ़ेक्ट हैं. कई मामलों में, पसंदीदा गाने बजाने के करीब दो दशक बाद भी, मुझे कोजी कोंडो की ज़ेल्डा कंपोज़िशन और मैट यूलमेन का डायब्लो साउंडट्रैक पसंद नहीं आ रहा. साउंड इफ़ेक्ट पर भी यही चीज़ लागू होती है. जैसे, Warcraft के तुरंत पहचानने लायक यूनिट क्लिक रिस्पॉन्स और Nintendo के क्लासिक वर्शन के सैंपल.

गेम ऑडियो कुछ दिलचस्प चुनौतियां पेश करता है. गेम के बारे में दिलचस्प बातें जानने के लिए डिज़ाइनर को गेम की ऐसी स्थिति के हिसाब से खुद में बदलाव करना होगा जिसके बारे में अनुमान न लगाया जा सकता हो. असल में, गेम के कुछ हिस्से बिना जानकारी वाली अवधि तक चल सकते हैं, आवाज़ें पर्यावरण के साथ इंटरैक्ट कर सकती हैं और जटिल तरीकों से मिल सकती हैं, जैसे कि कमरों के असर और आस-पास की आवाज़ की स्थिति. आखिर में, एक बार में कई आवाज़ें बज सकती हैं. ये सभी आवाज़ें एक साथ अच्छी तरह सुननी चाहिए और परफ़ॉर्मेंस पेनल्टी की जानकारी दिए बिना रेंडर होनी चाहिए.

वेब पर गेम ऑडियो

सामान्य गेम के लिए, <audio> टैग का इस्तेमाल करना काफ़ी हो सकता है. हालांकि, कई ब्राउज़र इसे ठीक से लागू नहीं करते हैं. इसकी वजह से ऑडियो में समस्याएं होती हैं और इंतज़ार का समय ज़्यादा होता है. उम्मीद है कि यह अस्थायी समस्या है, क्योंकि वेंडर अपने लागू करने से जुड़े तरीकों को बेहतर बनाने के लिए कड़ी मेहनत कर रहे हैं. <audio> टैग की स्थिति के बारे में जानने के लिए, areweplayingyet.org पर एक अच्छा टेस्ट सुइट मौजूद है.

हालांकि, <audio> टैग की खास बातों पर ध्यान देने पर, यह साफ़ तौर पर पता चलता है कि इसमें ऐसी कई चीज़ें हैं जो इस तरह से नहीं की जा सकतीं. इसमें कोई हैरानी की बात नहीं है, क्योंकि इसे मीडिया चलाने के लिए डिज़ाइन किया गया था. कुछ सीमाओं में ये शामिल हैं:

  • साउंड सिग्नल पर फ़िल्टर लागू करने की सुविधा नहीं है
  • PCM के रॉ डेटा को ऐक्सेस करने का कोई तरीका नहीं है
  • सोर्स और लिसनर की पोज़िशन और डायरेक्शन का कोई कॉन्सेप्ट नहीं है
  • सटीक समय नहीं.

लेख के बाकी हिस्से में, हम Web Audio API की मदद से लिखे गए गेम ऑडियो के बारे में, इनमें से कुछ विषयों के बारे में जानेंगे. इस एपीआई के बारे में कम शब्दों में जानकारी पाने के लिए, शुरू करने का ट्यूटोरियल देखें.

बैकग्राउंड संगीत

गेम में अक्सर लूप में बैकग्राउंड संगीत चलता है.

अगर आपका लूप छोटा और अनुमान लगाने लायक है, तो हो सकता है कि आपको काफ़ी परेशानी हो. अगर कोई खिलाड़ी किसी इलाके या लेवल पर अटक जाता है और बैकग्राउंड में एक ही सैंपल लगातार चलता रहता है, तो उस ट्रैक को धीरे-धीरे फ़ेड आउट करना फ़ायदेमंद हो सकता है, ताकि आगे से निराशा न हो. दूसरी रणनीति है, गेम के संदर्भ के हिसाब से अलग-अलग तरह की तीव्रता के मिक्स जो धीरे-धीरे एक-दूसरे में बदल जाते हैं.

उदाहरण के लिए, अगर आपका खिलाड़ी किसी रोमांचक बॉस बैटल वाले ज़ोन में है, तो आपके पास माहौल के हिसाब से लेकर पहले से शेड्यूल किए गए और तेज़ रफ़्तार वाले माहौल के हिसाब से अलग-अलग मिक्स हो सकते हैं. म्यूज़िक सिंथेसिस सॉफ़्टवेयर से अक्सर, एक ही अवधि के कई मिक्स एक्सपोर्ट किए जा सकते हैं. एक ही अवधि के लिए, एक्सपोर्ट में इस्तेमाल करने के लिए ट्रैक का सेट चुना जा सकता है. इससे, आपके पास अंदरूनी कॉन्फ़िगरेशन बना रहता है. साथ ही, एक ट्रैक से दूसरे ट्रैक पर क्रॉस-फ़ेड होने पर, ट्रांज़िशन की झंझट से बचा जाता है.

गैरेजबैंड

इसके बाद, Web Audio API का इस्तेमाल करके, इन सभी सैंपल को XHR के ज़रिए BufferLoader क्लास का इस्तेमाल करके इंपोर्ट किया जा सकता है. इसके बारे में वेब ऑडियो एपीआई के शुरुआती लेख में बताया गया है. साउंड लोड होने में समय लगता है. इसलिए, गेम में इस्तेमाल की जाने वाली एसेट, पेज लोड होने के दौरान, लेवल की शुरुआत में या प्लेयर के खेलने के दौरान धीरे-धीरे लोड होनी चाहिए.

इसके बाद, हर नोड के लिए एक सोर्स और हर सोर्स के लिए एक गेन नोड बनाना होगा और ग्राफ़ को कनेक्ट करना होगा.

ऐसा करने के बाद, लूप में इन सभी सोर्स को एक साथ चलाया जा सकता है. ये सारे सोर्स एक जैसे हैं. इसलिए, Web Audio API इस बात की गारंटी देगा कि वे अलाइन रहेंगे. जैसे-जैसे कैरेक्टर, फ़ाइनल बॉस बैटल से करीब या आगे बढ़ता है, वैसे-वैसे गेम में हर नोड से जुड़े मुनाफ़े की वैल्यू अलग-अलग होती है. इसके लिए, गेन रकम एल्गोरिदम का इस्तेमाल किया जाता है, जैसे कि:

// Assume gains is an array of AudioGainNode, normVal is the intensity
// between 0 and 1.
var value = normVal - (gains.length - 1);
// First reset gains on all nodes.
for (var i = 0; i < gains.length; i++) {
    gains[i].gain.value = 0;
}
// Decide which two nodes we are currently between, and do an equal
// power crossfade between them.
var leftNode = Math.floor(value);
// Normalize the value between 0 and 1.
var x = value - leftNode;
var gain1 = Math.cos(x - 0.5*Math.PI);
var gain2 = Math.cos((1.0 - x) - 0.5*Math.PI);
// Set the two gains accordingly.
gains[leftNode].gain.value = gain1;
// Check to make sure that there's a right node.
if (leftNode < gains.length - 1) {
    // If there is, adjust its gain.
    gains[leftNode + 1].gain.value = gain2;
}

ऊपर बताए गए तरीके में, दो सोर्स एक साथ चलते हैं और हम बराबर पावर कर्व का इस्तेमाल करके उन्हें क्रॉसफ़ेड करते हैं (जैसा कि परिचय में बताया गया है).

आज-कल कई गेम डेवलपर, बैकग्राउंड में चलने वाले संगीत के लिए <audio> टैग का इस्तेमाल करते हैं, क्योंकि यह कॉन्टेंट स्ट्रीम करने के लिए सही है. अब <audio> टैग से कॉन्टेंट को, वेब ऑडियो कॉन्टेक्स्ट में लाया जा सकता है.

यह तकनीक काम की हो सकती है, क्योंकि <audio> टैग स्ट्रीमिंग कॉन्टेंट के साथ काम कर सकता है. इससे कॉन्टेंट के डाउनलोड होने का इंतज़ार करने के बजाय, तुरंत बैकग्राउंड म्यूज़िक चलाया जा सकता है. वेब ऑडियो एपीआई में स्ट्रीम को डालकर, उसमें बदलाव किया जा सकता है या उसका विश्लेषण किया जा सकता है. यहां दिया गया उदाहरण, <audio> टैग से चलाए गए संगीत पर एक लो पास फ़िल्टर लागू करता है:

var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
// Create the filter
var filter = context.createBiquadFilter();
// Create the audio graph.
mediaSourceNode.connect(filter);
filter.connect(context.destination);

<audio> टैग को Web Audio API के साथ इंटिग्रेट करने के बारे में, ज़्यादा जानने के लिए, यह छोटा सा लेख पढ़ें.

साउंड इफ़ेक्ट

गेम अक्सर उपयोगकर्ता के इनपुट या गेम की स्थिति में बदलाव होने पर साउंड इफ़ेक्ट चलाते हैं. हालांकि, बैकग्राउंड संगीत की तरह, साउंड इफ़ेक्ट भी बहुत जल्दी परेशान कर सकते हैं. इससे बचने के लिए, अक्सर एक जैसा लेकिन अलग-अलग आवाज़ों का एक पूल रखना फ़ायदेमंद होता है. इनमें फ़ुटस्टेप के नमूने के हल्के-फुल्के बदलाव से लेकर बहुत ज़्यादा अंतर हो सकते हैं, जैसा कि यूनिट पर क्लिक करने के जवाब में Warcraft सीरीज़ में देखा गया है.

गेम में साउंड इफ़ेक्ट की एक और खास सुविधा यह है कि एक साथ कई साउंड इफ़ेक्ट हो सकते हैं. कल्पना करें कि आप गनफ़ाइट के बीच में हैं और उसमें कई अभिनेता मशीन गन शूट कर रहे हैं. हर मशीन गन से एक सेकंड में कई बार फ़ायर होता है. इसकी वजह से, एक ही समय पर कई साउंड इफ़ेक्ट होते हैं. कई और सटीक समय वाले सोर्स से एक साथ साउंड चलाना, एक ऐसी जगह है जहां Web Audio API वाकई में लोकप्रिय है.

इस उदाहरण में, कई अलग-अलग बुलेट सैंपल से मशीन गन राउंड बनाया गया है. इसमें अलग-अलग आवाज़ के ऐसे स्रोत बनाए गए हैं जिनका प्लेबैक समय के साथ बदलता रहता है.

var time = context.currentTime;
for (var i = 0; i < rounds; i++) {
    var source = this.makeSource(this.buffers[M4A1]);
    source.noteOn(time + i - interval);
}

अगर आपके गेम में सभी मशीन गन ठीक ऐसी ही लग रही थीं, तो यह काफ़ी उबाऊ होगा. टारगेट और वीडियो की पोज़िशन से दूरी के आधार पर, इनमें आवाज़ के हिसाब से फ़र्क़ होगा. इस बारे में ज़्यादा जानकारी बाद में दी जा सकती है. हालांकि, हो सकता है कि यह काफ़ी न भी हो. अच्छी बात यह है कि Web Audio API से ऊपर दिए गए उदाहरण में, दो तरीकों से आसानी से बदलाव किया जा सकता है:

  1. गोलियों के फ़ायर होने के बीच के समय में थोड़ा बदलाव हुआ
  2. यह असल दुनिया की किसी भी गड़बड़ी को बेहतर तरीके से सिम्युलेट करने के लिए, हर सैंपल की प्लेबैकरेट (पिच में बदलाव) में बदलाव करता है.

इन तकनीकों का असल में इस्तेमाल करने के उदाहरण के लिए, पूल टेबल डेमो देखें, जिसमें रैंडम सैंपलिंग का इस्तेमाल किया जाता है. साथ ही, बॉल की टकराने की ज़्यादा दिलचस्प आवाज़ के लिए, प्रतिक्रिया देने की दर में अंतर होता है.

3D पोज़िशनल साउंड

गेम अक्सर ऐसी दुनिया में सेट होते हैं जिसमें कुछ ज्यामितीय प्रॉपर्टी होती हैं, या तो 2D या 3D में. अगर ऐसा है, तो स्टीरियो पोज़िशन किए गए ऑडियो से ऑडियो सुनने का अनुभव बेहतर हो सकता है. अच्छी बात यह है कि Web Audio API में, हार्डवेयर से तेज़ी से पोज़िशन होने वाली ऑडियो की सुविधा पहले से मौजूद है. इसे इस्तेमाल करना काफ़ी आसान है. वैसे, देख लें कि नीचे दिए गए उदाहरण के लिए, आपके फ़ोन में स्टीरियो स्पीकर लगे हों.

ऊपर दिए गए उदाहरण में, कैनवस के बीच में एक लिसनर (व्यक्ति का आइकॉन) है और माउस सोर्स की पोज़िशन (स्पीकर आइकॉन) को प्रभावित करता है. इस तरह का इफ़ेक्ट पाने के लिए, AudioPannerNode का इस्तेमाल करने का आसान उदाहरण ऊपर दिया गया है. ऊपर दिए गए सैंपल का मूल आइडिया यह है कि ऑडियो सोर्स की पोज़िशन सेट करके माउस की गतिविधि को इस तरह से सेट किया जाए:

PositionSample.prototype.changePosition = function(position) {
    // Position coordinates are in normalized canvas coordinates
    // with -0.5 < x, y < 0.5
    if (position) {
    if (!this.isPlaying) {
        this.play();
    }
    var mul = 2;
    var x = position.x / this.size.width;
    var y = -position.y / this.size.height;
    this.panner.setPosition(x - mul, y - mul, -0.5);
    } else {
    this.stop();
    }
};

वेब ऑडियो में जगह की जानकारी का इस्तेमाल करने के बारे में ज़रूरी बातें:

  • डिफ़ॉल्ट रूप से, लिसनर ऑरिजिन (0, 0, 0) पर होता है.
  • वेब ऑडियो पोज़िशनल एपीआई बिना यूनिट के होते हैं. इसलिए, मैंने डेमो साउंड को बेहतर बनाने के लिए मल्टीप्लायर उपलब्ध कराया है.
  • वेब ऑडियो, y-is-अप कार्टीज़न निर्देशांक का इस्तेमाल करता है. यह ज़्यादातर कंप्यूटर ग्राफ़िक सिस्टम से उलट होता है. इसलिए मैं ऊपर दिए गए स्निपेट में y-ऐक्सिस को बदल रहा/रही हूं.

बेहतर सेटिंग: साउंड कोन

पोज़िशनल मॉडल, काफ़ी दमदार और काफ़ी बेहतर है. यह काफ़ी हद तक OpenAL पर आधारित होता है. ज़्यादा जानकारी के लिए, ऊपर लिंक किए गए स्पेसिफ़िकेशन के सेक्शन 3 और 4 को देखें.

पोज़िशन मॉडल

Web Audio API के संदर्भ में एक ऐसा AudioListener जुड़ा होता है जिसे स्पेस में स्थिति और स्क्रीन की दिशा के ज़रिए कॉन्फ़िगर किया जा सकता है. हर सोर्स को AudioPannerNode के ज़रिए पास किया जा सकता है, जो इनपुट ऑडियो की जगह ले लेता है. पैनर नोड में स्थिति और दिशा-निर्देश के साथ-साथ एक दूरी और दिशा वाला मॉडल भी होता है.

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

var panner = context.createPanner();
panner.coneOuterGain = 0.5;
panner.coneOuterAngle = 180;
panner.coneInnerAngle = 0;

हालांकि, मेरा उदाहरण 2D में है, लेकिन यह मॉडल आसानी से तीसरे डाइमेंशन का अनुमान लगा देता है. जगह के हिसाब से 3D में सेट की गई आवाज़ के उदाहरण के लिए, यह जगह के हिसाब से सैंपल देखें. पोज़िशन के अलावा, वेब ऑडियो साउंड मॉडल में वैकल्पिक रूप से डॉप्लर शिफ़्ट के लिए वेलोसिटी भी शामिल होती है. इस उदाहरण में, डॉलर इफ़ेक्ट के बारे में ज़्यादा जानकारी दी गई है.

इस विषय पर ज़्यादा जानकारी के लिए, [जगह के हिसाब से ऑडियो मिक्स करना और WebGL[webgl] से जुड़ा यह ट्यूटोरियल पढ़ें.

रूम इफ़ेक्ट और फ़िल्टर

असल में, आवाज़ को किस तरह से पहचाना जा सकता है, यह इस बात पर निर्भर करता है कि आवाज़ किस कमरे में सुनाई दे रही है. बेसमेंट में एक ही अजीब सा दरवाज़ा बड़े खुले हॉल की तुलना में बहुत अलग दिखेगा. ज़्यादा प्रोडक्शन वैल्यू वाले गेम इन इफ़ेक्ट की नकल करना चाहेंगे, क्योंकि हर एनवायरमेंट के लिए सैंपल का एक अलग सेट बनाना काफ़ी महंगा होता है. इस वजह से, ज़्यादा ऐसेट और ज़्यादा गेम डेटा मिल सकता है.

कम शब्दों में कहें, तो ऑडियो के लिए इस्तेमाल होने वाला टर्म, इंपल्स रिस्पॉन्स है. इसमें, रॉ और इसकी असल आवाज़ में फ़र्क़ होता है. आवेगों के इन जवाबों को बड़ी सावधानी के साथ रिकॉर्ड किया जा सकता है. असल में कुछ ऐसी साइटें भी हैं, जो आपकी सुविधा के लिए, पहले से रिकॉर्ड की गई इन इंपल्स रिस्पॉन्स फ़ाइलों (ऑडियो के रूप में स्टोर) में से कई फ़ाइलों को होस्ट करती हैं.

दिए गए एनवायरमेंट से इंपल्स रिस्पॉन्स कैसे बनाए जा सकते हैं, इस बारे में ज़्यादा जानकारी के लिए Web Audio API स्पेसिफ़िकेशन के कन्वर्ज़न वाले हिस्से में मौजूद "रिकॉर्डिंग सेटअप" सेक्शन को पढ़ें.

हमारे मकसद के लिए, Web Audio API ConvolverNode की मदद से, हमारी आवाज़ों के लिए आवेगों वाले इन जवाबों को लागू करने का एक आसान तरीका उपलब्ध कराता है.

// Make a source node for the sample.
var source = context.createBufferSource();
source.buffer = this.buffer;
// Make a convolver node for the impulse response.
var convolver = context.createConvolver();
convolver.buffer = this.impulseResponseBuffer;
// Connect the graph.
source.connect(convolver);
convolver.connect(context.destination);

Web Audio API की खास जानकारी वाले पेज पर, रूम इफ़ेक्ट का यह डेमो देखें. साथ ही, यह उदाहरण देखें. इससे आपको बेहतरीन जैज़ स्टैंडर्ड के ड्राई (कच्चे) और गीले (कन्वोल्वर से प्रोसेस किए गए) को कंट्रोल करने में मदद मिलती है.

फ़ाइनल काउंटडाउन

आपने एक गेम बना लिया है, पोज़िशनल ऑडियो को कॉन्फ़िगर कर लिया है, और अब आपके ग्राफ़ में बड़ी संख्या में AudioNodes मौजूद हैं, जो साथ में चल रहे हैं. बहुत बढ़िया, लेकिन ध्यान देने लायक एक और बात है:

कई आवाज़ें एक-दूसरे के ऊपर आ जाती हैं, लेकिन कोई सामान्य आवाज़ नहीं होती. इसलिए, हो सकता है कि आप ऐसी स्थिति में हों जब आप स्पीकर की क्षमता को पार कर रहे हों. जिस तरह इमेज अपने कैनवस की सीमाओं से ज़्यादा आगे निकल जाती हैं, उसी तरह आवाज़ भी क्लिप कर सकती हैं. ऐसा तब होता है, जब वेवफ़ॉर्म अपने तय थ्रेशोल्ड से ज़्यादा हो जाता है. इससे एक अलग डिस्टॉर्शन पैदा होता है. वेवफ़ॉर्म कुछ ऐसा दिखता है:

क्लिपिंग

यहां क्लिपिंग का एक उदाहरण दिया गया है. वेवफ़ॉर्म खराब लग रहा है:

क्लिपिंग

ऊपर बताई गई बातों या इसके उलटा, हल्के-फुल्के मिक्स को सुनना ज़रूरी है, ताकि उन्हें ज़्यादा गाने सुनने के लिए मजबूर कर देना. अगर ऐसी समस्या है, तो आपको उसे ठीक करना होगा!

क्लिपिंग का पता लगाएं

तकनीकी नज़रिए से देखा जाए, तो क्लिपिंग तब होती है, जब किसी चैनल में सिग्नल की वैल्यू, मान्य रेंज यानी -1 और 1 के बीच की सीमा से ज़्यादा होती है. इसका पता लगने के बाद, विज़ुअल तौर पर सुझाव/राय देना या शिकायत करना बेहतर होता है कि ऐसा हो रहा है. सही तरीके से ऐसा करने के लिए, अपने ग्राफ़ में JavaScriptAudioNode डालें. ऑडियो ग्राफ़ इस तरह सेटअप किया जाएगा:

// Assume entire sound output is being piped through the mix node.
var meter = context.createJavaScriptNode(2048, 1, 1);
meter.onaudioprocess = processAudio;
mix.connect(meter);
meter.connect(context.destination);

साथ ही, नीचे दिए गए processAudio हैंडलर में क्लिपिंग का पता लगाया जा सकता है:

function processAudio(e) {
    var buffer = e.inputBuffer.getChannelData(0);

    var isClipping = false;
    // Iterate through buffer to check if any of the |values| exceeds 1.
    for (var i = 0; i < buffer.length; i++) {
    var absValue = Math.abs(buffer[i]);
    if (absValue >= 1) {
        isClipping = true;
        break;
    }
    }
}

आम तौर पर, परफ़ॉर्मेंस की वजहों से JavaScriptAudioNode का बहुत ज़्यादा इस्तेमाल न करें. इस मामले में, मीटरिंग को किसी अन्य तरीके से लागू करने पर, getByteFrequencyData के लिए ऑडियो ग्राफ़ में RealtimeAnalyserNode पोल हो सकता है. यह पोल रेंडर करते समय, requestAnimationFrame के हिसाब से तय किया जाएगा. यह तरीका ज़्यादा असरदार है, लेकिन इसमें ज़्यादातर सिग्नल (इसमें वे जगहें भी शामिल हैं जहां यह शायद क्लिप हो सकती है) छूट जाती है. इसकी वजह यह है कि रेंडरिंग एक सेकंड में ज़्यादा से ज़्यादा 60 बार होती है, जबकि ऑडियो सिग्नल ज़्यादा तेज़ी से बदलते हैं.

क्लिप की पहचान करना बहुत ज़रूरी है. इसलिए, हो सकता है कि हमें आने वाले समय में, MeterNode Web Audio API में पहले से मौजूद नोड दिखे.

क्लिपिंग रोकें

मास्टर AudioGainNode के फ़ायदों को अडजस्ट करके, आप मिक्स को उस लेवल तक ला सकते हैं जहां क्लिप बनाने से रोका जाता है. हालांकि, व्यावहारिक तौर पर, आपके गेम में खेलने की आवाज़ कई बातों पर निर्भर हो सकती है, इसलिए मास्टर गेन वैल्यू का वह विकल्प तय करना मुश्किल हो सकता है जो सभी स्टेट के लिए क्लिप होने से रोकता है. सामान्य तौर पर, आपको सबसे खराब मामले का पहले से अनुमान लगाने के लिए बढ़ोतरी करनी चाहिए, लेकिन यह विज्ञान से ज़्यादा कला है.

थोड़ा चीनी डालें

आम तौर पर, म्यूज़िक और गेम प्रोडक्शन में कंप्रेसर का इस्तेमाल किया जाता है. इससे सिग्नल को ठीक करने और कुल सिग्नल में बढ़ोतरी को कंट्रोल करने में मदद मिलती है. यह सुविधा, वेब ऑडियो की दुनिया में DynamicsCompressorNode के ज़रिए उपलब्ध है. इसे आपके ऑडियो ग्राफ़ में डाला जा सकता है, ताकि आपको तेज़, बेहतर, और तेज़ आवाज़ मिल सके. साथ ही, क्लिप बनाने में भी मदद मिल सके. सीधे तौर पर स्पेसिफ़िकेशन, इस नोड के बारे में बताना

डाइनैमिक कंप्रेशन का इस्तेमाल करना आम तौर पर एक अच्छा आइडिया होता है, खास तौर पर गेम में, जहां जैसा कि पहले बताया जा चुका है, आपको यह पता नहीं होता कि किस तरह की आवाज़ें और कब सुनाई देंगी. DinahMoe लैब का प्लिंक इसका सबसे अच्छा उदाहरण है, क्योंकि चलाए जाने वाली आवाज़ें पूरी तरह से आप और दूसरे लोगों पर निर्भर करती हैं. कंप्रेसर ज़्यादातर मामलों में काम का होता है. हालांकि, कुछ मामलों में यह काम नहीं करता. ऐसी स्थितियों में भी कंप्रेसर का इस्तेमाल किया जा सकता है.

इसे लागू करने के लिए आपको बस अपने ऑडियो ग्राफ़ में DynamicsCompressorNode को शामिल करना है, आम तौर पर डेस्टिनेशन से पहले के आखिरी नोड के तौर पर.:

// Assume the output is all going through the mix node.
var compressor = context.createDynamicsCompressor();
mix.connect(compressor);
compressor.connect(context.destination);

डाइनैमिक कंप्रेशन के बारे में ज़्यादा जानकारी के लिए, यह Wikipedia लेख बहुत जानकारी वाला है.

खास जानकारी देने के लिए, क्लिपिंग को ध्यान से सुनें और मास्टर गेन नोड डालकर उसे रोकें. इसके बाद, डाइनैमिक कंप्रेसर नोड का इस्तेमाल करके पूरे मिक्स को टाइट करें. आपका ऑडियो ग्राफ़ कुछ ऐसा दिख सकता है:

आखिरी नतीजा

नतीजा

Web Audio API का इस्तेमाल करके, मेरे हिसाब से गेम ऑडियो डेवलपमेंट के सबसे ज़रूरी पहलू यहां बताए गए हैं. इन तकनीकों का इस्तेमाल करके, अपने ब्राउज़र में बेहतरीन ऑडियो अनुभव बनाया जा सकता है. मेरे साइन ऑफ़ करने से पहले, मैं आपको ब्राउज़र के हिसाब से सलाह देता हूं: अगर page visibility API का इस्तेमाल करके आपका टैब बैकग्राउंड में चला जाता है, तो आवाज़ को रोक दें. ऐसा न करने पर आपके उपयोगकर्ता को खराब अनुभव मिलेगा.

वेब ऑडियो के बारे में ज़्यादा जानकारी के लिए, शुरुआत करने के बारे में बताने वाला लेख पढ़ें. अगर आपका कोई सवाल है, तो वेब ऑडियो के बारे में अक्सर पूछे जाने वाले सवाल में इसका जवाब दिया जा चुका है या नहीं. आखिर में, अगर आपका कोई और सवाल है, तो वेब-ऑडियो टैग का इस्तेमाल करके, स्टैक ओवरफ़्लो पर उन्हें पूछें.

साइन ऑफ़ करने से पहले, मैं आपको आज रीयल गेम में Web Audio API के कुछ मज़ेदार इस्तेमाल के बारे में जानकारी देता हूं: