অডিও ওয়ার্কলেট ডিজাইন প্যাটার্ন

অডিও ওয়ার্কলেটের পূর্ববর্তী নিবন্ধে মৌলিক ধারণা এবং ব্যবহার সম্পর্কে বিস্তারিত বলা হয়েছে। ক্রোম 66-এ এটি চালু হওয়ার পর থেকে প্রকৃত অ্যাপ্লিকেশনগুলিতে কীভাবে এটি ব্যবহার করা যেতে পারে তার আরও উদাহরণের জন্য অনেক অনুরোধ এসেছে। অডিও ওয়ার্কলেট WebAudio-এর সম্পূর্ণ সম্ভাবনাকে আনলক করে, কিন্তু এটির সুবিধা নেওয়া চ্যালেঞ্জিং হতে পারে কারণ এটির জন্য বেশ কয়েকটি JS API-এর সাথে মোড়ানো সমসাময়িক প্রোগ্রামিং বোঝার প্রয়োজন। এমনকি ডেভেলপারদের জন্য যারা WebAudio এর সাথে পরিচিত, অডিও ওয়ার্কলেটকে অন্যান্য API (যেমন WebAssembly) এর সাথে একীভূত করা কঠিন হতে পারে।

এই নিবন্ধটি পাঠককে কীভাবে বাস্তব-বিশ্বের সেটিংসে অডিও ওয়ার্কলেট ব্যবহার করতে হয় এবং এর সম্পূর্ণ শক্তিতে আঁকার জন্য টিপস অফার করতে হয় সে সম্পর্কে আরও ভাল বোঝার সুযোগ দেবে। পাশাপাশি কোড উদাহরণ এবং লাইভ ডেমো পরীক্ষা করতে ভুলবেন না!

রিক্যাপ: অডিও ওয়ার্কলেট

ডাইভিং করার আগে, আসুন অডিও ওয়ার্কলেট সিস্টেমের আশেপাশের শর্তাবলী এবং তথ্যগুলিকে দ্রুত পুনরুদ্ধার করি যা পূর্বে এই পোস্টে চালু করা হয়েছিল৷

  • বেসঅডিও কনটেক্সট : ওয়েব অডিও এপিআই এর প্রাথমিক বস্তু।
  • অডিও ওয়ার্কলেট : অডিও ওয়ার্কলেট অপারেশনের জন্য একটি বিশেষ স্ক্রিপ্ট ফাইল লোডার। বেসঅডিও কনটেক্সট এর অন্তর্গত। একটি BaseAudioContext একটি অডিও ওয়ার্কলেট থাকতে পারে। লোড করা স্ক্রিপ্ট ফাইলটি AudioWorkletGlobalScope-এ মূল্যায়ন করা হয় এবং AudioWorkletProcessor দৃষ্টান্ত তৈরি করতে ব্যবহৃত হয়।
  • অডিও ওয়ার্কলেট গ্লোবালস্কোপ : অডিও ওয়ার্কলেট অপারেশনের জন্য একটি বিশেষ জেএস গ্লোবাল স্কোপ। WebAudio-এর জন্য একটি ডেডিকেটেড রেন্ডারিং থ্রেডে চলে। একটি BaseAudioContext একটি AudioWorkletGlobalScope থাকতে পারে।
  • AudioWorkletNode : একটি AudioNode অডিও ওয়ার্কলেট অপারেশনের জন্য ডিজাইন করা হয়েছে। একটি বেসঅডিও কনটেক্সট থেকে তাত্ক্ষণিক। একটি BaseAudioContext-এ নেটিভ অডিও নোডের মতোই একাধিক AudioWorkletNodes থাকতে পারে।
  • AudioWorkletProcessor : AudioWorkletNode-এর প্রতিরূপ। AudioWorkletNode-এর প্রকৃত সাহস ব্যবহারকারী-প্রদানকৃত কোড দ্বারা অডিও স্ট্রীম প্রক্রিয়াকরণ করে। যখন একটি AudioWorkletNode তৈরি করা হয় তখন এটি AudioWorkletGlobalScope-এ তাৎক্ষণিকভাবে দেখানো হয়। একটি AudioWorkletNode এর সাথে মিলে একটি AudioWorkletProcessor থাকতে পারে।

নকশা নিদর্শন

WebAssembly এর সাথে অডিও ওয়ার্কলেট ব্যবহার করা

WebAssembly AudioWorkletProcessor এর জন্য একটি নিখুঁত সহচর। এই দুটি বৈশিষ্ট্যের সংমিশ্রণ ওয়েবে অডিও প্রক্রিয়াকরণে বিভিন্ন সুবিধা নিয়ে আসে, তবে দুটি সবচেয়ে বড় সুবিধা হল: ক) ওয়েবঅডিও ইকোসিস্টেমে বিদ্যমান C/C++ অডিও প্রসেসিং কোড আনা এবং খ) JS JIT সংকলনের ওভারহেড এড়ানো এবং অডিও প্রসেসিং কোডে আবর্জনা সংগ্রহ।

আগেরটি অডিও প্রসেসিং কোড এবং লাইব্রেরিতে বিদ্যমান বিনিয়োগের সাথে বিকাশকারীদের জন্য গুরুত্বপূর্ণ, তবে পরবর্তীটি API-এর প্রায় সমস্ত ব্যবহারকারীর জন্য গুরুত্বপূর্ণ। WebAudio-এর জগতে, স্থিতিশীল অডিও স্ট্রিমের জন্য সময় বাজেট বেশ চাহিদাপূর্ণ: এটি 44.1Khz এর নমুনা হারে মাত্র 3ms। এমনকি অডিও প্রসেসিং কোডে সামান্য হেঁচকিও সমস্যা সৃষ্টি করতে পারে। বিকাশকারীকে দ্রুত প্রক্রিয়াকরণের জন্য কোডটি অপ্টিমাইজ করতে হবে, তবে জেএস আবর্জনার পরিমাণও কমিয়ে আনতে হবে। WebAssembly ব্যবহার করা একটি সমাধান হতে পারে যা একই সময়ে উভয় সমস্যার সমাধান করে: এটি দ্রুত এবং কোড থেকে কোন আবর্জনা তৈরি করে না।

পরবর্তী বিভাগে বর্ণনা করা হয়েছে কিভাবে WebAssembly একটি অডিও ওয়ার্কলেটের সাথে ব্যবহার করা যেতে পারে এবং সাথে কোডের উদাহরণ এখানে পাওয়া যাবে। Emscripten এবং WebAssembly (বিশেষ করে এমস্ক্রিপ্টেন আঠালো কোড) কীভাবে ব্যবহার করবেন তার প্রাথমিক টিউটোরিয়ালের জন্য, অনুগ্রহ করে এই নিবন্ধটি দেখুন।

ঠিককরা

এটি সব দুর্দান্ত শোনাচ্ছে, তবে জিনিসগুলিকে সঠিকভাবে সেট আপ করার জন্য আমাদের কিছুটা কাঠামোর প্রয়োজন৷ প্রথম ডিজাইনের প্রশ্নটি হল কিভাবে এবং কোথায় একটি WebAssembly মডিউল ইনস্ট্যান্ট করা যায়। Emscripten এর আঠালো কোড আনার পরে, মডিউল ইনস্ট্যান্টেশনের জন্য দুটি পথ আছে:

  1. audioContext.audioWorklet.addModule() এর মাধ্যমে AudioWorkletGlobalScope-এ আঠালো কোড লোড করে একটি WebAssembly মডিউল চালু করুন।
  2. প্রধান সুযোগে একটি WebAssembly মডিউল চালু করুন, তারপর AudioWorkletNode-এর কনস্ট্রাক্টর বিকল্পগুলির মাধ্যমে মডিউলটি স্থানান্তর করুন।

সিদ্ধান্তটি মূলত আপনার ডিজাইন এবং পছন্দের উপর নির্ভর করে, কিন্তু ধারণা হল WebAssembly মডিউল AudioWorkletGlobalScope-এ একটি WebAssembly উদাহরণ তৈরি করতে পারে, যা একটি AudioWorkletProcessor উদাহরণের মধ্যে একটি অডিও প্রসেসিং কার্নেলে পরিণত হয়।

WebAssembly মডিউল ইনস্ট্যান্টিয়েশন প্যাটার্ন A: .addModule() কল ব্যবহার করে
WebAssembly মডিউল ইনস্ট্যান্টিয়েশন প্যাটার্ন A: .addModule() কল ব্যবহার করে

প্যাটার্ন A সঠিকভাবে কাজ করার জন্য, আমাদের কনফিগারেশনের জন্য সঠিক WebAssembly আঠালো কোড তৈরি করতে Emscripten-এর কয়েকটি বিকল্পের প্রয়োজন:

-s BINARYEN_ASYNC_COMPILATION=0 -s SINGLE_FILE=1 --post-js mycode.js

এই বিকল্পগুলি AudioWorkletGlobalScope-এ একটি WebAssembly মডিউলের সিঙ্ক্রোনাস সংকলন নিশ্চিত করে। এটি mycode.js এ AudioWorkletProcessor এর ক্লাস সংজ্ঞাও যুক্ত করে যাতে মডিউলটি শুরু হওয়ার পরে এটি লোড করা যায়। সিঙ্ক্রোনাস কম্পাইলেশন ব্যবহার করার প্রাথমিক কারণ হল audioWorklet.addModule() এর প্রতিশ্রুতি রেজোলিউশন AudioWorkletGlobalScope-এ প্রতিশ্রুতির রেজোলিউশনের জন্য অপেক্ষা করে না। প্রধান থ্রেডে সিঙ্ক্রোনাস লোডিং বা সংকলন সাধারণত সুপারিশ করা হয় না কারণ এটি একই থ্রেডের অন্যান্য কাজগুলিকে ব্লক করে, কিন্তু এখানে আমরা নিয়মটি বাইপাস করতে পারি কারণ সংকলনটি AudioWorkletGlobalScope-এ ঘটে, যা মূল থ্রেডের বাইরে চলে। (আরো তথ্যের জন্য এটি দেখুন।)

WASM মডিউল ইনস্ট্যান্টিয়েশন প্যাটার্ন B: AudioWorkletNode কনস্ট্রাক্টরের ক্রস-থ্রেড ট্রান্সফার ব্যবহার করে
WASM মডিউল ইনস্ট্যান্টিয়েশন প্যাটার্ন B: AudioWorkletNode কনস্ট্রাক্টরের ক্রস-থ্রেড ট্রান্সফার ব্যবহার করে

প্যাটার্ন বি উপযোগী হতে পারে যদি অ্যাসিঙ্ক্রোনাস ভারী-উত্তোলনের প্রয়োজন হয়। এটি সার্ভার থেকে আঠালো কোড আনা এবং মডিউল কম্পাইল করার জন্য প্রধান থ্রেড ব্যবহার করে। তারপর এটি AudioWorkletNode এর কন্সট্রাক্টরের মাধ্যমে WASM মডিউল স্থানান্তর করবে। AudioWorkletGlobalScope অডিও স্ট্রিম রেন্ডার করা শুরু করার পরে যখন আপনাকে গতিশীলভাবে মডিউলটি লোড করতে হবে তখন এই প্যাটার্নটি আরও বেশি বোধগম্য হয়। মডিউলের আকারের উপর নির্ভর করে, রেন্ডারিংয়ের মাঝখানে এটি কম্পাইল করা স্ট্রীমে সমস্যা সৃষ্টি করতে পারে।

WASM হিপ এবং অডিও ডেটা

WebAssembly কোড শুধুমাত্র একটি ডেডিকেটেড WASM হিপের মধ্যে বরাদ্দ করা মেমরিতে কাজ করে। এটির সুবিধা নেওয়ার জন্য, অডিও ডেটাকে WASM হিপ এবং অডিও ডেটা অ্যারেগুলির মধ্যে পিছনে পিছনে ক্লোন করতে হবে। উদাহরণ কোডে HeapAudioBuffer ক্লাস এই অপারেশনটি সুন্দরভাবে পরিচালনা করে।

WASM হিপের সহজ ব্যবহারের জন্য HeapAudioBuffer ক্লাস
WASM হিপের সহজ ব্যবহারের জন্য HeapAudioBuffer ক্লাস

WASM হিপকে সরাসরি অডিও ওয়ার্কলেট সিস্টেমে একীভূত করার জন্য আলোচনার অধীনে একটি প্রাথমিক প্রস্তাব রয়েছে। JS মেমরি এবং WASM স্তূপের মধ্যে এই অপ্রয়োজনীয় ডেটা ক্লোনিং থেকে পরিত্রাণ পাওয়া স্বাভাবিক বলে মনে হয়, তবে নির্দিষ্ট বিবরণগুলি কাজ করা দরকার।

হ্যান্ডলিং বাফার সাইজ অমিল

একটি AudioWorkletNode এবং AudioWorkletProcessor জোড়া একটি নিয়মিত AudioNode এর মত কাজ করার জন্য ডিজাইন করা হয়েছে; AudioWorkletNode অন্যান্য কোডের সাথে মিথস্ক্রিয়া পরিচালনা করে যখন AudioWorkletProcessor অভ্যন্তরীণ অডিও প্রক্রিয়াকরণের যত্ন নেয়। যেহেতু একটি নিয়মিত AudioNode একবারে 128 টি ফ্রেম প্রসেস করে, তাই AudioWorkletProcessorকে একটি মূল বৈশিষ্ট্য হতে একই কাজ করতে হবে। এটি অডিও ওয়ার্কলেট ডিজাইনের একটি সুবিধা যা অডিও ওয়ার্কলেট প্রসেসরের মধ্যে অভ্যন্তরীণ বাফারিংয়ের কারণে কোনও অতিরিক্ত বিলম্ব না হওয়া নিশ্চিত করে, তবে একটি প্রসেসিং ফাংশনের জন্য 128 ফ্রেমের চেয়ে আলাদা বাফার আকারের প্রয়োজন হলে এটি একটি সমস্যা হতে পারে। এই ধরনের ক্ষেত্রে সাধারণ সমাধান হল একটি রিং বাফার ব্যবহার করা, যা একটি বৃত্তাকার বাফার বা FIFO নামেও পরিচিত।

এখানে অডিও ওয়ার্কলেটপ্রসেসরের একটি ডায়াগ্রাম রয়েছে যা ভিতরে দুটি রিং বাফার ব্যবহার করে একটি WASM ফাংশন মিটমাট করে যা 512 ফ্রেম ভিতরে এবং বাইরে নেয়। (এখানে 512 নম্বরটি নির্বিচারে বাছাই করা হয়েছে।)

AudioWorkletProcessor এর `process()` পদ্ধতির ভিতরে RingBuffer ব্যবহার করা
AudioWorkletProcessor এর `process()` পদ্ধতির ভিতরে RingBuffer ব্যবহার করা

ডায়াগ্রামের জন্য অ্যালগরিদম হবে:

  1. AudioWorkletProcessor তার ইনপুট থেকে ইনপুট রিংবাফারে 128টি ফ্রেম পুশ করে।
  2. ইনপুট রিংবাফারে 512 ফ্রেমের চেয়ে বেশি বা সমান হলেই নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন৷
    1. ইনপুট রিংবাফার থেকে 512 ফ্রেম টানুন।
    2. প্রদত্ত WASM ফাংশন সহ 512 ফ্রেম প্রক্রিয়া করুন।
    3. আউটপুট রিংবাফারে 512 ফ্রেম পুশ করুন।
  3. AudioWorkletProcessor তার আউটপুট পূরণ করতে আউটপুট RingBuffer থেকে 128টি ফ্রেম টানে।

ডায়াগ্রামে দেখানো হয়েছে, ইনপুট ফ্রেমগুলি সর্বদা ইনপুট রিংবাফারে জমা হয় এবং এটি বাফারের সবচেয়ে পুরানো ফ্রেম ব্লককে ওভাররাইট করে বাফার ওভারফ্লো পরিচালনা করে। এটি একটি রিয়েল-টাইম অডিও অ্যাপ্লিকেশনের জন্য একটি যুক্তিসঙ্গত জিনিস। একইভাবে, আউটপুট ফ্রেম ব্লক সবসময় সিস্টেম দ্বারা টানা হবে। আউটপুট রিংবাফারে বাফার আন্ডারফ্লো (পর্যাপ্ত ডেটা নয়) এর ফলে নীরবতা স্ট্রীমে একটি সমস্যা সৃষ্টি করবে।

ScriptProcessorNode (SPN) কে AudioWorkletNode দিয়ে প্রতিস্থাপন করার সময় এই প্যাটার্নটি কার্যকর। যেহেতু SPN ডেভেলপারকে 256 এবং 16384 ফ্রেমের মধ্যে একটি বাফার সাইজ বাছাই করার অনুমতি দেয়, তাই AudioWorkletNode-এর সাথে SPN-এর ড্রপ-ইন প্রতিস্থাপন কঠিন হতে পারে এবং রিং বাফার ব্যবহার করা একটি চমৎকার সমাধান প্রদান করে। একটি অডিও রেকর্ডার একটি দুর্দান্ত উদাহরণ যা এই ডিজাইনের উপরে তৈরি করা যেতে পারে।

যাইহোক, এটি বোঝা গুরুত্বপূর্ণ যে এই নকশাটি শুধুমাত্র বাফার আকারের অমিলের সাথে মিলিত হয় এবং এটি প্রদত্ত স্ক্রিপ্ট কোড চালানোর জন্য বেশি সময় দেয় না। যদি কোডটি রেন্ডার কোয়ান্টামের টাইমিং বাজেটের মধ্যে কাজটি শেষ করতে না পারে (44.1Khz এ ~3ms), এটি পরবর্তী কলব্যাক ফাংশনের শুরুর সময়কে প্রভাবিত করবে এবং শেষ পর্যন্ত সমস্যা সৃষ্টি করবে।

WASM হিপের চারপাশে মেমরি ম্যানেজমেন্টের কারণে WebAssembly-এর সাথে এই ডিজাইনটি মিশ্রিত করা জটিল হতে পারে। লেখার সময়, WASM হিপের ভিতরে এবং বাইরে যাওয়া ডেটা অবশ্যই ক্লোন করতে হবে তবে মেমরি পরিচালনাকে কিছুটা সহজ করতে আমরা HeapAudioBuffer ক্লাস ব্যবহার করতে পারি। অপ্রয়োজনীয় ডেটা ক্লোনিং কমাতে ব্যবহারকারী-বরাদ্দ মেমরি ব্যবহার করার ধারণা ভবিষ্যতে আলোচনা করা হবে।

RingBuffer ক্লাস এখানে পাওয়া যাবে।

ওয়েবঅডিও পাওয়ারহাউস: অডিও ওয়ার্কলেট এবং শেয়ার্ডঅ্যারেবাফার

এই নিবন্ধের শেষ নকশা প্যাটার্ন হল এক জায়গায় একাধিক কাটিং এজ এপিআই স্থাপন করা; অডিও ওয়ার্কলেট, শেয়ার্ডঅ্যারেবাফার , অ্যাটমিক্স এবং ওয়ার্কার । এই অ-তুচ্ছ সেটআপের সাথে, এটি একটি মসৃণ ব্যবহারকারীর অভিজ্ঞতা বজায় রেখে একটি ওয়েব ব্রাউজারে চালানোর জন্য C/C++ এ লেখা বিদ্যমান অডিও সফ্টওয়্যারের জন্য একটি পথ আনলক করে।

শেষ ডিজাইন প্যাটার্নের একটি ওভারভিউ: অডিও ওয়ার্কলেট, শেয়ার্ডঅ্যারেবাফার এবং ওয়ার্কার
শেষ ডিজাইন প্যাটার্নের একটি ওভারভিউ: অডিও ওয়ার্কলেট, শেয়ার্ডঅ্যারেবাফার এবং ওয়ার্কার

এই ডিজাইনের সবচেয়ে বড় সুবিধা হল শুধুমাত্র অডিও প্রসেসিং এর জন্য একটি DedicatedWorkerGlobalScope ব্যবহার করা। ক্রোমে, WorkerGlobalScope WebAudio রেন্ডারিং থ্রেডের তুলনায় কম অগ্রাধিকারের থ্রেডে চলে কিন্তু AudioWorkletGlobalScope-এর তুলনায় এর বেশ কিছু সুবিধা রয়েছে। DedicatedWorkerGlobalScope সুযোগে উপলব্ধ API পৃষ্ঠের পরিপ্রেক্ষিতে কম সীমাবদ্ধ। এছাড়াও আপনি Emscripten থেকে আরও ভাল সমর্থন আশা করতে পারেন কারণ Worker API কয়েক বছর ধরে বিদ্যমান।

SharedArrayBuffer এই ডিজাইনটিকে দক্ষতার সাথে কাজ করার জন্য একটি গুরুত্বপূর্ণ ভূমিকা পালন করে। যদিও Worker এবং AudioWorkletProcessor উভয়ই অ্যাসিঙ্ক্রোনাস মেসেজিং ( MessagePort ) দিয়ে সজ্জিত, এটি রিয়েল-টাইম অডিও প্রসেসিংয়ের জন্য সাবঅপটিমাল কারণ পুনরাবৃত্তিমূলক মেমরি বরাদ্দ এবং মেসেজিং লেটেন্সি। তাই আমরা সামনে একটি মেমরি ব্লক বরাদ্দ করি যা দ্রুত দ্বিমুখী ডেটা স্থানান্তরের জন্য উভয় থ্রেড থেকে অ্যাক্সেস করা যেতে পারে।

ওয়েব অডিও এপিআই পিউরিস্টের দৃষ্টিকোণ থেকে, এই ডিজাইনটি সাবঅপ্টিমাল দেখাতে পারে কারণ এটি অডিও ওয়ার্কলেটকে একটি সাধারণ "অডিও সিঙ্ক" হিসাবে ব্যবহার করে এবং ওয়ার্কারে সবকিছু করে। কিন্তু জাভাস্ক্রিপ্টে C/C++ প্রকল্পের পুনর্লিখনের খরচ বিবেচনা করে নিষিদ্ধ হতে পারে বা এমনকি অসম্ভবও হতে পারে, এই ধরনের প্রকল্পের জন্য এই নকশাটি সবচেয়ে কার্যকরী বাস্তবায়নের পথ হতে পারে।

ভাগ করা রাষ্ট্র এবং পরমাণু

অডিও ডেটার জন্য একটি ভাগ করা মেমরি ব্যবহার করার সময়, উভয় পক্ষের অ্যাক্সেস সাবধানে সমন্বয় করা আবশ্যক। পারমাণবিকভাবে অ্যাক্সেসযোগ্য রাজ্যগুলি ভাগ করা এই জাতীয় সমস্যার সমাধান। আমরা এই উদ্দেশ্যে একটি SAB দ্বারা সমর্থিত Int32Array এর সুবিধা নিতে পারি।

সিঙ্ক্রোনাইজেশন মেকানিজম: SharedArrayBuffer এবং Atomics
সিঙ্ক্রোনাইজেশন মেকানিজম: SharedArrayBuffer এবং Atomics

সিঙ্ক্রোনাইজেশন মেকানিজম: SharedArrayBuffer এবং Atomics

স্টেটস অ্যারের প্রতিটি ক্ষেত্র ভাগ করা বাফার সম্পর্কে গুরুত্বপূর্ণ তথ্য উপস্থাপন করে। সবচেয়ে গুরুত্বপূর্ণ হল সিঙ্ক্রোনাইজেশনের জন্য একটি ক্ষেত্র ( REQUEST_RENDER )। ধারণাটি হল যে কর্মী এই ক্ষেত্রটি AudioWorkletProcessor দ্বারা স্পর্শ করার জন্য অপেক্ষা করে এবং অডিওটি যখন জেগে ওঠে তখন এটি প্রক্রিয়া করে। SharedArrayBuffer (SAB) এর সাথে, Atomics API এই প্রক্রিয়াটিকে সম্ভব করে তোলে।

নোট করুন যে দুটি থ্রেডের সিঙ্ক্রোনাইজেশন বরং আলগা। Worker.process() এর সূচনা AudioWorkletProcessor.process() পদ্ধতি দ্বারা ট্রিগার করা হবে, কিন্তু AudioWorkletProcessor Worker.process() শেষ না হওয়া পর্যন্ত অপেক্ষা করে না। এটি ডিজাইন দ্বারা; AudioWorkletProcessor অডিও কলব্যাক দ্বারা চালিত হয় তাই এটি সিঙ্ক্রোনাসভাবে ব্লক করা উচিত নয়। সবচেয়ে খারাপ পরিস্থিতিতে অডিও স্ট্রীম ডুপ্লিকেট বা ড্রপ আউটে ভুগতে পারে কিন্তু রেন্ডারিং পারফরম্যান্স স্থিতিশীল হলে এটি শেষ পর্যন্ত পুনরুদ্ধার হবে।

সেট আপ এবং চলমান

উপরের চিত্রে যেমন দেখানো হয়েছে, এই ডিজাইনে সাজানোর জন্য বেশ কিছু উপাদান রয়েছে: DedicatedWorkerGlobalScope (DWGS), AudioWorkletGlobalScope (AWGS), SharedArrayBuffer এবং প্রধান থ্রেড। নিম্নলিখিত পদক্ষেপগুলি প্রাথমিক পর্যায়ে কী ঘটবে তা বর্ণনা করে।

আরম্ভ
  1. [প্রধান] অডিও ওয়ার্কলেট নোড কনস্ট্রাক্টরকে ডাকা হয়।
    1. কর্মী তৈরি করুন।
    2. সংশ্লিষ্ট অডিও ওয়ার্কলেট প্রসেসর তৈরি করা হবে।
  2. [DWGS] কর্মী 2টি SharedArrayBuffers তৈরি করে। (একটি ভাগ করা রাজ্যের জন্য এবং অন্যটি অডিও ডেটার জন্য)
  3. [DWGS] কর্মী অডিও ওয়ার্কলেটনোডে SharedArrayBuffer রেফারেন্স পাঠায়।
  4. [প্রধান] AudioWorkletNode অডিও ওয়ার্কলেটপ্রসেসরে SharedArrayBuffer রেফারেন্স পাঠায়।
  5. [AWGS] AudioWorkletProcessor AudioWorkletNode সূচিত করে যে সেটআপ সম্পূর্ণ হয়েছে।

আরম্ভ করা শেষ হলে, AudioWorkletProcessor.process() কল করা শুরু হয়। রেন্ডারিং লুপের প্রতিটি পুনরাবৃত্তিতে যা ঘটতে হবে তা নিম্নোক্ত।

রেন্ডারিং লুপ
SharedArrayBuffers এর সাথে মাল্টি-থ্রেডেড রেন্ডারিং
SharedArrayBuffers এর সাথে মাল্টি-থ্রেডেড রেন্ডারিং
  1. [AWGS] প্রতি রেন্ডার কোয়ান্টামের জন্য AudioWorkletProcessor.process(inputs, outputs) কল করা হয়।
    1. inputs ইনপুট এসএবি- তে পুশ করা হবে।
    2. আউটপুট SAB- এ অডিও ডেটা ব্যবহার করে outputs পূরণ করা হবে।
    3. সেই অনুযায়ী নতুন বাফার সূচক সহ রাজ্য SAB আপডেট করে।
    4. আউটপুট SAB আন্ডারফ্লো থ্রেশহোল্ডের কাছাকাছি হলে, আরও অডিও ডেটা রেন্ডার করতে ওয়াক ওয়ার্কার।
  2. [DWGS] কর্মী AudioWorkletProcessor.process() থেকে জেগে ওঠা সংকেতের জন্য অপেক্ষা করছে (ঘুমছে)। যখন এটি জেগে ওঠে:
    1. স্টেটস SAB থেকে বাফার ইনডেক্স আনে।
    2. আউটপুট SAB পূরণ করতে ইনপুট SAB থেকে ডেটা সহ প্রক্রিয়া ফাংশন চালান।
    3. সেই অনুযায়ী বাফার সূচক সহ রাজ্য SAB আপডেট করে।
    4. ঘুমাতে যায় এবং পরবর্তী সংকেতের জন্য অপেক্ষা করে।

উদাহরণ কোডটি এখানে পাওয়া যেতে পারে, কিন্তু মনে রাখবেন যে এই ডেমোটি কাজ করার জন্য SharedArrayBuffer পরীক্ষামূলক পতাকাটি সক্রিয় করা আবশ্যক। কোডটি সরলতার জন্য বিশুদ্ধ JS কোড দিয়ে লেখা হয়েছিল, তবে প্রয়োজন হলে এটি WebAssembly কোড দিয়ে প্রতিস্থাপন করা যেতে পারে। এই ধরনের কেস HeapAudioBuffer ক্লাসের সাথে মেমরি ম্যানেজমেন্ট মোড়ানোর মাধ্যমে অতিরিক্ত যত্ন সহকারে পরিচালনা করা উচিত।

উপসংহার

অডিও ওয়ার্কলেটের চূড়ান্ত লক্ষ্য হল ওয়েব অডিও API কে সত্যিকারের "এক্সটেনসিবল" করা। অডিও ওয়ার্কলেটের সাথে বাকি ওয়েব অডিও এপিআই বাস্তবায়ন করা সম্ভব করার জন্য একটি বহু-বছরের প্রচেষ্টা এটির ডিজাইনে চলে গেছে। পরিবর্তে, এখন আমাদের এর ডিজাইনে উচ্চতর জটিলতা রয়েছে এবং এটি একটি অপ্রত্যাশিত চ্যালেঞ্জ হতে পারে।

সৌভাগ্যবশত, এই ধরনের জটিলতার কারণ হল ডেভেলপারদের ক্ষমতায়ন করা। AudioWorkletGlobalScope-এ WebAssembly চালাতে সক্ষম হওয়া ওয়েবে উচ্চ-পারফরম্যান্স অডিও প্রক্রিয়াকরণের জন্য বিশাল সম্ভাবনা উন্মোচন করে। C বা C++ তে লেখা বড় আকারের অডিও অ্যাপ্লিকেশনগুলির জন্য, SharedArrayBuffers এবং শ্রমিকদের সাথে একটি অডিও ওয়ার্কলেট ব্যবহার করা অন্বেষণ করার জন্য একটি আকর্ষণীয় বিকল্প হতে পারে।

ক্রেডিট

এই নিবন্ধের খসড়া পর্যালোচনা এবং অন্তর্দৃষ্টিপূর্ণ প্রতিক্রিয়া দেওয়ার জন্য ক্রিস উইলসন, জেসন মিলার, জোশুয়া বেল এবং রেমন্ড টয়কে বিশেষ ধন্যবাদ।