অডিও ওয়ার্কলেটের পূর্ববর্তী নিবন্ধে মৌলিক ধারণা এবং ব্যবহার সম্পর্কে বিস্তারিত বলা হয়েছে। ক্রোম 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 এর আঠালো কোড আনার পরে, মডিউল ইনস্ট্যান্টেশনের জন্য দুটি পথ আছে:
-
audioContext.audioWorklet.addModule()
এর মাধ্যমে AudioWorkletGlobalScope-এ আঠালো কোড লোড করে একটি WebAssembly মডিউল চালু করুন। - প্রধান সুযোগে একটি WebAssembly মডিউল চালু করুন, তারপর AudioWorkletNode-এর কনস্ট্রাক্টর বিকল্পগুলির মাধ্যমে মডিউলটি স্থানান্তর করুন।
সিদ্ধান্তটি মূলত আপনার ডিজাইন এবং পছন্দের উপর নির্ভর করে, কিন্তু ধারণা হল WebAssembly মডিউল AudioWorkletGlobalScope-এ একটি WebAssembly উদাহরণ তৈরি করতে পারে, যা একটি AudioWorkletProcessor উদাহরণের মধ্যে একটি অডিও প্রসেসিং কার্নেলে পরিণত হয়।

.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-এ ঘটে, যা মূল থ্রেডের বাইরে চলে। (আরো তথ্যের জন্য এটি দেখুন।)

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

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

ডায়াগ্রামের জন্য অ্যালগরিদম হবে:
- AudioWorkletProcessor তার ইনপুট থেকে ইনপুট রিংবাফারে 128টি ফ্রেম পুশ করে।
- ইনপুট রিংবাফারে 512 ফ্রেমের চেয়ে বেশি বা সমান হলেই নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন৷
- ইনপুট রিংবাফার থেকে 512 ফ্রেম টানুন।
- প্রদত্ত WASM ফাংশন সহ 512 ফ্রেম প্রক্রিয়া করুন।
- আউটপুট রিংবাফারে 512 ফ্রেম পুশ করুন।
- 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
স্টেটস অ্যারের প্রতিটি ক্ষেত্র ভাগ করা বাফার সম্পর্কে গুরুত্বপূর্ণ তথ্য উপস্থাপন করে। সবচেয়ে গুরুত্বপূর্ণ হল সিঙ্ক্রোনাইজেশনের জন্য একটি ক্ষেত্র ( REQUEST_RENDER
)। ধারণাটি হল যে কর্মী এই ক্ষেত্রটি AudioWorkletProcessor দ্বারা স্পর্শ করার জন্য অপেক্ষা করে এবং অডিওটি যখন জেগে ওঠে তখন এটি প্রক্রিয়া করে। SharedArrayBuffer (SAB) এর সাথে, Atomics API এই প্রক্রিয়াটিকে সম্ভব করে তোলে।
নোট করুন যে দুটি থ্রেডের সিঙ্ক্রোনাইজেশন বরং আলগা। Worker.process()
এর সূচনা AudioWorkletProcessor.process()
পদ্ধতি দ্বারা ট্রিগার করা হবে, কিন্তু AudioWorkletProcessor Worker.process()
শেষ না হওয়া পর্যন্ত অপেক্ষা করে না। এটি ডিজাইন দ্বারা; AudioWorkletProcessor অডিও কলব্যাক দ্বারা চালিত হয় তাই এটি সিঙ্ক্রোনাসভাবে ব্লক করা উচিত নয়। সবচেয়ে খারাপ পরিস্থিতিতে অডিও স্ট্রীম ডুপ্লিকেট বা ড্রপ আউটে ভুগতে পারে কিন্তু রেন্ডারিং পারফরম্যান্স স্থিতিশীল হলে এটি শেষ পর্যন্ত পুনরুদ্ধার হবে।
সেট আপ এবং চলমান
উপরের চিত্রে যেমন দেখানো হয়েছে, এই ডিজাইনে সাজানোর জন্য বেশ কিছু উপাদান রয়েছে: DedicatedWorkerGlobalScope (DWGS), AudioWorkletGlobalScope (AWGS), SharedArrayBuffer এবং প্রধান থ্রেড। নিম্নলিখিত পদক্ষেপগুলি প্রাথমিক পর্যায়ে কী ঘটবে তা বর্ণনা করে।
সূচনা
- [প্রধান] অডিও ওয়ার্কলেট নোড কনস্ট্রাক্টরকে ডাকা হয়।
- কর্মী তৈরি করুন।
- সংশ্লিষ্ট অডিও ওয়ার্কলেট প্রসেসর তৈরি করা হবে।
- [DWGS] কর্মী 2টি SharedArrayBuffers তৈরি করে। (একটি ভাগ করা রাজ্যের জন্য এবং অন্যটি অডিও ডেটার জন্য)
- [DWGS] কর্মী অডিও ওয়ার্কলেটনোডে SharedArrayBuffer রেফারেন্স পাঠায়।
- [প্রধান] AudioWorkletNode অডিও ওয়ার্কলেটপ্রসেসরে SharedArrayBuffer রেফারেন্স পাঠায়।
- [AWGS] AudioWorkletProcessor AudioWorkletNode সূচিত করে যে সেটআপ সম্পূর্ণ হয়েছে।
আরম্ভ করা শেষ হলে, AudioWorkletProcessor.process()
কল করা শুরু হয়। রেন্ডারিং লুপের প্রতিটি পুনরাবৃত্তিতে যা ঘটতে হবে তা নিম্নোক্ত।
রেন্ডারিং লুপ

- [AWGS] প্রতি রেন্ডার কোয়ান্টামের জন্য
AudioWorkletProcessor.process(inputs, outputs)
কল করা হয়।-
inputs
ইনপুট এসএবি -তে পুশ করা হবে। - আউটপুট SAB- এ অডিও ডেটা ব্যবহার করে
outputs
পূরণ করা হবে। - সেই অনুযায়ী নতুন বাফার সূচক সহ রাজ্য SAB আপডেট করে।
- আউটপুট SAB আন্ডারফ্লো থ্রেশহোল্ডের কাছাকাছি হলে, আরও অডিও ডেটা রেন্ডার করতে ওয়াক ওয়ার্কার।
-
- [DWGS] কর্মী
AudioWorkletProcessor.process()
থেকে জেগে ওঠা সংকেতের জন্য অপেক্ষা করছে (ঘুমছে)। যখন এটি জেগে ওঠে:- স্টেটস SAB থেকে বাফার ইনডেক্স আনে।
- আউটপুট SAB পূরণ করতে ইনপুট SAB থেকে ডেটা সহ প্রক্রিয়া ফাংশন চালান।
- সেই অনুযায়ী বাফার সূচক সহ রাজ্য SAB আপডেট করে।
- ঘুমাতে যায় এবং পরবর্তী সংকেতের জন্য অপেক্ষা করে।
উদাহরণ কোডটি এখানে পাওয়া যেতে পারে, কিন্তু মনে রাখবেন যে এই ডেমোটি কাজ করার জন্য SharedArrayBuffer পরীক্ষামূলক পতাকাটি সক্রিয় করা আবশ্যক। কোডটি সরলতার জন্য বিশুদ্ধ JS কোড দিয়ে লেখা হয়েছিল, তবে প্রয়োজন হলে এটি WebAssembly কোড দিয়ে প্রতিস্থাপন করা যেতে পারে। এই ধরনের কেস HeapAudioBuffer ক্লাসের সাথে মেমরি ম্যানেজমেন্ট মোড়ানোর মাধ্যমে অতিরিক্ত যত্ন সহকারে পরিচালনা করা উচিত।
উপসংহার
অডিও ওয়ার্কলেটের চূড়ান্ত লক্ষ্য হল ওয়েব অডিও API কে সত্যিকারের "এক্সটেনসিবল" করা। অডিও ওয়ার্কলেটের সাথে বাকি ওয়েব অডিও এপিআই বাস্তবায়ন করা সম্ভব করার জন্য একটি বহু-বছরের প্রচেষ্টা এটির ডিজাইনে চলে গেছে। পরিবর্তে, এখন আমাদের এর ডিজাইনে উচ্চতর জটিলতা রয়েছে এবং এটি একটি অপ্রত্যাশিত চ্যালেঞ্জ হতে পারে।
সৌভাগ্যবশত, এই ধরনের জটিলতার কারণ হল ডেভেলপারদের ক্ষমতায়ন করা। AudioWorkletGlobalScope-এ WebAssembly চালাতে সক্ষম হওয়া ওয়েবে উচ্চ-পারফরম্যান্স অডিও প্রক্রিয়াকরণের জন্য বিশাল সম্ভাবনা উন্মোচন করে। C বা C++ তে লেখা বড় আকারের অডিও অ্যাপ্লিকেশনগুলির জন্য, SharedArrayBuffers এবং শ্রমিকদের সাথে একটি অডিও ওয়ার্কলেট ব্যবহার করা অন্বেষণ করার জন্য একটি আকর্ষণীয় বিকল্প হতে পারে।
ক্রেডিট
এই নিবন্ধের খসড়া পর্যালোচনা এবং অন্তর্দৃষ্টিপূর্ণ প্রতিক্রিয়া দেওয়ার জন্য ক্রিস উইলসন, জেসন মিলার, জোশুয়া বেল এবং রেমন্ড টয়কে বিশেষ ধন্যবাদ।
,অডিও ওয়ার্কলেটের পূর্ববর্তী নিবন্ধে মৌলিক ধারণা এবং ব্যবহার সম্পর্কে বিস্তারিত বলা হয়েছে। ক্রোম 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 এর আঠালো কোড আনার পরে, মডিউল ইনস্ট্যান্টেশনের জন্য দুটি পথ আছে:
-
audioContext.audioWorklet.addModule()
এর মাধ্যমে AudioWorkletGlobalScope-এ আঠালো কোড লোড করে একটি WebAssembly মডিউল চালু করুন। - প্রধান সুযোগে একটি WebAssembly মডিউল চালু করুন, তারপর AudioWorkletNode-এর কনস্ট্রাক্টর বিকল্পগুলির মাধ্যমে মডিউলটি স্থানান্তর করুন।
সিদ্ধান্তটি মূলত আপনার ডিজাইন এবং পছন্দের উপর নির্ভর করে, কিন্তু ধারণা হল WebAssembly মডিউল AudioWorkletGlobalScope-এ একটি WebAssembly উদাহরণ তৈরি করতে পারে, যা একটি AudioWorkletProcessor উদাহরণের মধ্যে একটি অডিও প্রসেসিং কার্নেলে পরিণত হয়।

.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-এ ঘটে, যা মূল থ্রেডের বাইরে চলে। (আরো তথ্যের জন্য এটি দেখুন।)

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

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

ডায়াগ্রামের জন্য অ্যালগরিদম হবে:
- AudioWorkletProcessor তার ইনপুট থেকে ইনপুট রিংবাফারে 128টি ফ্রেম পুশ করে।
- ইনপুট রিংবাফারে 512 ফ্রেমের চেয়ে বেশি বা সমান হলেই নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন৷
- ইনপুট রিংবাফার থেকে 512 ফ্রেম টানুন।
- প্রদত্ত WASM ফাংশন সহ 512 ফ্রেম প্রক্রিয়া করুন।
- আউটপুট রিংবাফারে 512 ফ্রেম পুশ করুন।
- 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
স্টেটস অ্যারের প্রতিটি ক্ষেত্র ভাগ করা বাফার সম্পর্কে গুরুত্বপূর্ণ তথ্য উপস্থাপন করে। সবচেয়ে গুরুত্বপূর্ণ হল সিঙ্ক্রোনাইজেশনের জন্য একটি ক্ষেত্র ( REQUEST_RENDER
)। ধারণাটি হল যে কর্মী এই ক্ষেত্রটি AudioWorkletProcessor দ্বারা স্পর্শ করার জন্য অপেক্ষা করে এবং অডিওটি যখন জেগে ওঠে তখন এটি প্রক্রিয়া করে। SharedArrayBuffer (SAB) এর সাথে, Atomics API এই প্রক্রিয়াটিকে সম্ভব করে তোলে।
নোট করুন যে দুটি থ্রেডের সিঙ্ক্রোনাইজেশন বরং আলগা। Worker.process()
এর সূচনা AudioWorkletProcessor.process()
পদ্ধতি দ্বারা ট্রিগার করা হবে, কিন্তু AudioWorkletProcessor Worker.process()
শেষ না হওয়া পর্যন্ত অপেক্ষা করে না। এটি ডিজাইন দ্বারা; AudioWorkletProcessor অডিও কলব্যাক দ্বারা চালিত হয় তাই এটি সিঙ্ক্রোনাসভাবে ব্লক করা উচিত নয়। সবচেয়ে খারাপ পরিস্থিতিতে অডিও স্ট্রীম ডুপ্লিকেট বা ড্রপ আউটে ভুগতে পারে কিন্তু রেন্ডারিং পারফরম্যান্স স্থিতিশীল হলে এটি শেষ পর্যন্ত পুনরুদ্ধার হবে।
সেট আপ এবং চলমান
উপরের চিত্রে যেমন দেখানো হয়েছে, এই ডিজাইনে সাজানোর জন্য বেশ কিছু উপাদান রয়েছে: DedicatedWorkerGlobalScope (DWGS), AudioWorkletGlobalScope (AWGS), SharedArrayBuffer এবং প্রধান থ্রেড। নিম্নলিখিত পদক্ষেপগুলি প্রাথমিক পর্যায়ে কী ঘটবে তা বর্ণনা করে।
সূচনা
- [প্রধান] অডিও ওয়ার্কলেট নোড কনস্ট্রাক্টরকে ডাকা হয়।
- কর্মী তৈরি করুন।
- সংশ্লিষ্ট অডিও ওয়ার্কলেট প্রসেসর তৈরি করা হবে।
- [DWGS] কর্মী 2টি SharedArrayBuffers তৈরি করে। (একটি ভাগ করা রাজ্যের জন্য এবং অন্যটি অডিও ডেটার জন্য)
- [DWGS] কর্মী অডিও ওয়ার্কলেটনোডে SharedArrayBuffer রেফারেন্স পাঠায়।
- [প্রধান] AudioWorkletNode অডিও ওয়ার্কলেটপ্রসেসরে SharedArrayBuffer রেফারেন্স পাঠায়।
- [AWGS] AudioWorkletProcessor AudioWorkletNode সূচিত করে যে সেটআপ সম্পূর্ণ হয়েছে।
আরম্ভ করা শেষ হলে, AudioWorkletProcessor.process()
কল করা শুরু হয়। রেন্ডারিং লুপের প্রতিটি পুনরাবৃত্তিতে যা ঘটতে হবে তা নিম্নোক্ত।
রেন্ডারিং লুপ

- [AWGS] প্রতি রেন্ডার কোয়ান্টামের জন্য
AudioWorkletProcessor.process(inputs, outputs)
কল করা হয়।-
inputs
ইনপুট এসএবি -তে পুশ করা হবে। - আউটপুট SAB- এ অডিও ডেটা ব্যবহার করে
outputs
পূরণ করা হবে। - সেই অনুযায়ী নতুন বাফার সূচক সহ রাজ্য SAB আপডেট করে।
- আউটপুট SAB আন্ডারফ্লো থ্রেশহোল্ডের কাছাকাছি হলে, আরও অডিও ডেটা রেন্ডার করতে ওয়াক ওয়ার্কার।
-
- [DWGS] কর্মী
AudioWorkletProcessor.process()
থেকে জেগে ওঠা সংকেতের জন্য অপেক্ষা করছে (ঘুমছে)। যখন এটি জেগে ওঠে:- স্টেটস SAB থেকে বাফার ইনডেক্স আনে।
- আউটপুট SAB পূরণ করতে ইনপুট SAB থেকে ডেটা সহ প্রক্রিয়া ফাংশন চালান।
- সেই অনুযায়ী বাফার সূচক সহ রাজ্য SAB আপডেট করে।
- ঘুমাতে যায় এবং পরবর্তী সংকেতের জন্য অপেক্ষা করে।
উদাহরণ কোডটি এখানে পাওয়া যেতে পারে, কিন্তু মনে রাখবেন যে এই ডেমোটি কাজ করার জন্য SharedArrayBuffer পরীক্ষামূলক পতাকাটি সক্রিয় করা আবশ্যক। কোডটি সরলতার জন্য বিশুদ্ধ JS কোড দিয়ে লেখা হয়েছিল, তবে প্রয়োজন হলে এটি WebAssembly কোড দিয়ে প্রতিস্থাপন করা যেতে পারে। এই ধরনের কেস HeapAudioBuffer ক্লাসের সাথে মেমরি ম্যানেজমেন্ট মোড়ানোর মাধ্যমে অতিরিক্ত যত্ন সহকারে পরিচালনা করা উচিত।
উপসংহার
অডিও ওয়ার্কলেটের চূড়ান্ত লক্ষ্য হল ওয়েব অডিও API কে সত্যিকারের "এক্সটেনসিবল" করা। অডিও ওয়ার্কলেটের সাথে বাকি ওয়েব অডিও এপিআই বাস্তবায়ন করা সম্ভব করার জন্য একটি বহু-বছরের প্রচেষ্টা এটির ডিজাইনে চলে গেছে। পরিবর্তে, এখন আমাদের এর ডিজাইনে উচ্চতর জটিলতা রয়েছে এবং এটি একটি অপ্রত্যাশিত চ্যালেঞ্জ হতে পারে।
সৌভাগ্যবশত, এই ধরনের জটিলতার কারণ হল ডেভেলপারদের ক্ষমতায়ন করা। AudioWorkletGlobalScope-এ WebAssembly চালাতে সক্ষম হওয়া ওয়েবে উচ্চ-পারফরম্যান্স অডিও প্রক্রিয়াকরণের জন্য বিশাল সম্ভাবনা উন্মোচন করে। C বা C++ তে লেখা বড় আকারের অডিও অ্যাপ্লিকেশনগুলির জন্য, SharedArrayBuffers এবং শ্রমিকদের সাথে একটি অডিও ওয়ার্কলেট ব্যবহার করা অন্বেষণ করার জন্য একটি আকর্ষণীয় বিকল্প হতে পারে।
ক্রেডিট
এই নিবন্ধের খসড়া পর্যালোচনা এবং অন্তর্দৃষ্টিপূর্ণ প্রতিক্রিয়া দেওয়ার জন্য ক্রিস উইলসন, জেসন মিলার, জোশুয়া বেল এবং রেমন্ড টয়কে বিশেষ ধন্যবাদ।
,অডিও ওয়ার্কলেটের পূর্ববর্তী নিবন্ধে মৌলিক ধারণা এবং ব্যবহার সম্পর্কে বিস্তারিত বলা হয়েছে। ক্রোম 66-এ এটি চালু হওয়ার পর থেকে প্রকৃত অ্যাপ্লিকেশনগুলিতে কীভাবে এটি ব্যবহার করা যেতে পারে তার আরও উদাহরণের জন্য অনেক অনুরোধ এসেছে। অডিও ওয়ার্কলেটটি ওয়েবওডিওর সম্পূর্ণ সম্ভাবনাকে আনলক করে, তবে এর সুবিধা গ্রহণ করা চ্যালেঞ্জিং হতে পারে কারণ এটির জন্য বেশ কয়েকটি জেএস এপিআইয়ের সাথে আবৃত সমবর্তী প্রোগ্রামিং বোঝার প্রয়োজন। এমনকি ওয়েবওডিওর সাথে পরিচিত এমন বিকাশকারীদের জন্যও অন্যান্য এপিআইয়ের সাথে অডিও ওয়ার্কলেটকে সংহত করা (যেমন ওয়েবসেমি) কঠিন হতে পারে।
এই নিবন্ধটি পাঠককে রিয়েল-ওয়ার্ল্ড সেটিংসে কীভাবে অডিও ওয়ার্কলেট ব্যবহার করতে হবে এবং এর সম্পূর্ণ শক্তি আঁকতে টিপস সরবরাহ করবে সে সম্পর্কে আরও ভাল ধারণা দেবে। কোডের উদাহরণগুলি এবং লাইভ ডেমোগুলিও পরীক্ষা করে দেখতে ভুলবেন না!
পুনরুদ্ধার: অডিও ওয়ার্কলেট
ডাইভিং ইন করার আগে, আসুন দ্রুত এই পোস্টে প্রবর্তিত অডিও ওয়ার্কলেট সিস্টেমের চারপাশে শর্তাদি এবং তথ্যগুলি দ্রুত পুনরুদ্ধার করা যাক।
- বেসিউডিয়োকন্টেক্সট : ওয়েব অডিও এপিআইয়ের প্রাথমিক অবজেক্ট।
- অডিও ওয়ার্কলেট : অডিও ওয়ার্কলেট অপারেশনের জন্য একটি বিশেষ স্ক্রিপ্ট ফাইল লোডার। বেসিউডিয়োকনটেক্সট এর অন্তর্গত। একটি বেসিওডিয়োকনটেক্সট একটি অডিও ওয়ার্কলেট থাকতে পারে। লোড স্ক্রিপ্ট ফাইলটি অডিওওরকলেটগ্লোবালস্কোপে মূল্যায়ন করা হয় এবং এটি অডিওওউকারলেটপ্রসেসর দৃষ্টান্ত তৈরি করতে ব্যবহৃত হয়।
- অডিওউকারলেটগ্লোবালসকোপ : অডিও ওয়ার্কলেট অপারেশনের জন্য একটি বিশেষ জেএস গ্লোবাল স্কোপ। ওয়েবোডিওর জন্য একটি ডেডিকেটেড রেন্ডারিং থ্রেডে চলে। একটি বেসিউডিয়োকনটেক্সট একটি অডিওওরকলেটগ্লোবালস্কোপ থাকতে পারে।
- অডিওউর্কলেটনোড : অডিও ওয়ার্কলেট অপারেশনের জন্য ডিজাইন করা একটি অডিওনোড। একটি বেসিউডিয়োকনটেক্সট থেকে তাত্ক্ষণিক। একটি বেসিউডিয়োকনটেক্সটকে স্থানীয় অডিওনোডগুলির মতো একাধিক অডিওওরক্লেটনোড থাকতে পারে।
- অডিওউকারলেটপ্রসেসর : অডিওওরকলেটনোডের একটি অংশ। অডিওউকারলেটনোডের প্রকৃত সাহস ব্যবহারকারী-সরবরাহিত কোড দ্বারা অডিও স্ট্রিম প্রক্রিয়াজাতকরণ। এটি অডিওওরকলেটগ্লোবালস্কোপে ইনস্ট্যান্ট করা হয় যখন একটি অডিওওরকলেটনোড তৈরি করা হয়। একটি অডিওওরকলেটনোডে একটি মিলে যাওয়া অডিওওরকলেটপ্রসেসর থাকতে পারে।
ডিজাইন প্যাটার্নস
ওয়েবসেম্বল সহ অডিও ওয়ার্লেট ব্যবহার করে
ওয়েবসেম্বলি অডিওউকারলেটপ্রসেসরের জন্য একটি নিখুঁত সহচর। এই দুটি বৈশিষ্ট্যের সংমিশ্রণটি ওয়েবে অডিও প্রসেসিংয়ে বিভিন্ন সুবিধা নিয়ে আসে তবে দুটি বৃহত্তম সুবিধা হ'ল: ক) বিদ্যমান সি/সি ++ অডিও প্রসেসিং কোডটি ওয়েবওডিয়ো বাস্তুতন্ত্রের মধ্যে নিয়ে আসা এবং খ) অডিও প্রসেসিং কোডে জেএস জেআইটি সংকলন এবং আবর্জনা সংগ্রহের ওভারহেড এড়ানো।
অডিও প্রসেসিং কোড এবং লাইব্রেরিতে বিদ্যমান বিনিয়োগের সাথে বিকাশকারীদের কাছে পূর্ববর্তীটি গুরুত্বপূর্ণ, তবে পরবর্তীটি এপিআইয়ের প্রায় সমস্ত ব্যবহারকারীর জন্য গুরুত্বপূর্ণ। ওয়েবওডিও ওয়ার্ল্ডে, স্থিতিশীল অডিও স্ট্রিমের জন্য টাইমিং বাজেট বেশ দাবী: এটি 44.1kHz এর নমুনা হারে মাত্র 3 এমএস। এমনকি অডিও প্রসেসিং কোডে একটি সামান্য হিচাপও গ্লিটস হতে পারে। বিকাশকারীকে অবশ্যই দ্রুত প্রক্রিয়াজাতকরণের জন্য কোডটি অনুকূল করতে হবে, তবে জেএস আবর্জনার পরিমাণটি উত্পন্ন হওয়ার পরিমাণও হ্রাস করতে হবে। ওয়েবসেম্ব্লিউজ ব্যবহার করা এমন একটি সমাধান হতে পারে যা একই সাথে উভয় সমস্যার সমাধান করে: এটি দ্রুত এবং কোড থেকে কোনও আবর্জনা উত্পন্ন করে না।
পরবর্তী বিভাগে বর্ণনা করা হয়েছে যে কীভাবে ওয়েবসেম্বিলিটি একটি অডিও ওয়ার্কলেটের সাথে ব্যবহার করা যেতে পারে এবং সহিত কোড উদাহরণটি এখানে পাওয়া যাবে। কীভাবে এমস্ক্রিপ্টেন এবং ওয়েবসেম্বলি (বিশেষত এমএসক্রিপ্টেন আঠালো কোড) ব্যবহার করবেন সে সম্পর্কে প্রাথমিক টিউটোরিয়ালটির জন্য, দয়া করে এই নিবন্ধটি একবার দেখুন।
সেট আপ করা হচ্ছে
এটি সমস্ত দুর্দান্ত শোনায় তবে জিনিসগুলি সঠিকভাবে সেট আপ করার জন্য আমাদের কিছুটা কাঠামো দরকার। জিজ্ঞাসা করার প্রথম ডিজাইনের প্রশ্নটি হ'ল কীভাবে এবং কোথায় একটি ওয়েবসেম্বলি মডিউল ইনস্ট্যান্ট করতে হবে। এমস্ক্রিপ্টেনের আঠালো কোড আনার পরে, মডিউল ইনস্ট্যান্টেশনের জন্য দুটি পাথ রয়েছে:
-
audioContext.audioWorklet.addModule()
এর মাধ্যমে অডিওওরকলেটগ্লোবালস্কোপে আঠালো কোডটি লোড করে একটি ওয়েবসেমি মডিউল ইনস্ট্যান্ট করুন। - মূল স্কোপে একটি ওয়েবসেম্বলি মডিউল ইনস্ট্যান্ট করুন, তারপরে অডিওউকারলেটনোডের কনস্ট্রাক্টর বিকল্পগুলির মাধ্যমে মডিউলটি স্থানান্তর করুন।
সিদ্ধান্তটি মূলত আপনার নকশা এবং পছন্দের উপর নির্ভর করে, তবে ধারণাটি হ'ল ওয়েবসেম্বলি মডিউলটি অডিওওরকলেটগ্লোবালসকোপে একটি ওয়েবসেম্বলি উদাহরণ তৈরি করতে পারে, যা অডিওউওকারলেটপ্রসেসর উদাহরণের মধ্যে একটি অডিও প্রসেসিং কার্নেল হয়ে ওঠে।

.addModule()
কল ব্যবহার করেপ্যাটার্ন এ সঠিকভাবে কাজ করার জন্য, আমাদের কনফিগারেশনের জন্য সঠিক ওয়েবসেম্বলি আঠালো কোড তৈরি করতে এমএসক্রিপ্টের কয়েকটি বিকল্পের প্রয়োজন:
-s BINARYEN_ASYNC_COMPILATION=0 -s SINGLE_FILE=1 --post-js mycode.js
এই বিকল্পগুলি অডিওওরকলেটগ্লোবালসকোপে একটি ওয়েবসেম্বলি মডিউলটির সিঙ্ক্রোনাস সংকলন নিশ্চিত করে। এটি mycode.js
-এ অডিওওরকলেটপ্রসেসরের শ্রেণীর সংজ্ঞাটিও যুক্ত করে যাতে এটি মডিউলটি শুরু করার পরে লোড করা যায়। সিঙ্ক্রোনাস সংকলনটি ব্যবহার করার প্রাথমিক কারণটি হ'ল audioWorklet.addModule()
এর প্রতিশ্রুতি রেজোলিউশন অডিওওউর্কলেটগ্লোবালসকোপে প্রতিশ্রুতিগুলির সমাধানের জন্য অপেক্ষা করে না। মূল থ্রেডে সিঙ্ক্রোনাস লোডিং বা সংকলনটি সাধারণত সুপারিশ করা হয় না কারণ এটি একই থ্রেডের অন্যান্য কাজগুলি অবরুদ্ধ করে, তবে এখানে আমরা নিয়মটি বাইপাস করতে পারি কারণ সংকলনটি অডিওওউর্কলেটগ্লোবালসকোপে ঘটে যা মূল থ্রেডের বাইরে চলে। (আরও তথ্যের জন্য এটি দেখুন))

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

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

ডায়াগ্রামের জন্য অ্যালগরিদম হবে:
- অডিওউকারলেটপ্রসেসর তার ইনপুট থেকে 128 ফ্রেমকে ইনপুট রিংবফারগুলিতে ঠেলে দেয়।
- ইনপুট রিংবফার 512 ফ্রেমের চেয়ে বেশি বা সমান হলে নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন।
- ইনপুট রিংবফার থেকে 512 ফ্রেম টানুন।
- প্রদত্ত WASM ফাংশন সহ 512 ফ্রেম প্রক্রিয়া।
- আউটপুট রিংবফার 512 ফ্রেমে চাপুন।
- অডিওউকারলেটপ্রসেসর আউটপুট রিংবফার থেকে 128 ফ্রেমগুলি তার আউটপুটটি পূরণ করতে টানছে।
ডায়াগ্রামে যেমন দেখানো হয়েছে, ইনপুট ফ্রেমগুলি সর্বদা ইনপুট রিংবফারগুলিতে জমা হয় এবং এটি বাফারের প্রাচীনতম ফ্রেম ব্লকটি ওভাররাইটিং করে বাফার ওভারফ্লো পরিচালনা করে। রিয়েল-টাইম অডিও অ্যাপ্লিকেশনটির জন্য এটি করা যুক্তিসঙ্গত জিনিস। একইভাবে, আউটপুট ফ্রেম ব্লক সর্বদা সিস্টেম দ্বারা টানা হবে। আউটপুট রিংবফারগুলিতে বাফার আন্ডারফ্লো (পর্যাপ্ত ডেটা নয়) স্রোতে একটি গ্লিচ সৃষ্টি করে নীরবতার ফলে।
স্ক্রিপ্টপ্রসেসরনোড (এসপিএন) অডিওউওকারলেটনোডের সাথে প্রতিস্থাপন করার সময় এই প্যাটার্নটি কার্যকর। যেহেতু এসপিএন বিকাশকারীকে 256 এবং 16384 ফ্রেমের মধ্যে একটি বাফার আকার বাছাই করতে দেয়, তাই অডিওউর্কলেটনোডের সাথে এসপিএন এর ড্রপ-ইন প্রতিস্থাপনটি কঠিন হতে পারে এবং একটি রিং বাফার ব্যবহার করা একটি দুর্দান্ত কাজ সরবরাহ করে। একটি অডিও রেকর্ডার একটি দুর্দান্ত উদাহরণ হবে যা এই ডিজাইনের শীর্ষে নির্মিত হতে পারে।
তবে এটি বোঝা গুরুত্বপূর্ণ যে এই নকশাটি কেবল বাফার আকারের অমিলকে মিলিয়ে দেয় এবং এটি প্রদত্ত স্ক্রিপ্ট কোডটি চালানোর জন্য আরও বেশি সময় দেয় না। কোডটি যদি রেন্ডার কোয়ান্টামের সময় বাজেটের মধ্যে টাস্কটি শেষ করতে না পারে (44.1kHz এ 3 এমএস), এটি পরবর্তী কলব্যাক ফাংশনের সূত্রপাতের সময়কে প্রভাবিত করবে এবং শেষ পর্যন্ত গ্লিটস সৃষ্টি করবে।
ওয়েসম হিপের চারপাশে মেমরি ম্যানেজমেন্টের কারণে এই নকশাটিকে ওয়েবসেম্বলির সাথে মিশ্রিত করা জটিল হতে পারে। লেখার সময়, ওয়াসম হিপের ভিতরে এবং বাইরে যাওয়া ডেটা অবশ্যই ক্লোন করা উচিত তবে আমরা মেমরি ম্যানেজমেন্টকে কিছুটা সহজ করার জন্য হ্যাপিডিওবফার ক্লাসটি ব্যবহার করতে পারি। রিডানড্যান্ট ডেটা ক্লোনিং হ্রাস করতে ব্যবহারকারী-বরাদ্দযুক্ত মেমরি ব্যবহার করার ধারণাটি ভবিষ্যতে আলোচনা করা হবে।
রিংবফার ক্লাসটি এখানে পাওয়া যাবে।
ওয়েবওডিয়ো পাওয়ার হাউস: অডিও ওয়ার্কলেট এবং শেয়ারডারাইবফার
এই নিবন্ধের শেষ ডিজাইনের প্যাটার্নটি হ'ল বেশ কয়েকটি কাটিয়া প্রান্ত এপিআইকে এক জায়গায় রাখা; অডিও ওয়ার্কলেট, শারডারাইবফার , অ্যাটমিকস এবং কর্মী । এই অ-তুচ্ছ সেটআপের সাহায্যে এটি একটি মসৃণ ব্যবহারকারীর অভিজ্ঞতা বজায় রেখে ওয়েব ব্রাউজারে চালানোর জন্য সি/সি ++ এ লিখিত বিদ্যমান অডিও সফ্টওয়্যারটির জন্য একটি পথ আনলক করে।

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

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

- [এডাব্লুজিএস]
AudioWorkletProcessor.process(inputs, outputs)
প্রতিটি রেন্ডার কোয়ান্টামের জন্য কল করা হয়।-
inputs
ইনপুট এসএবিতে ঠেলে দেওয়া হবে। - আউটপুট এসএবিতে অডিও ডেটা গ্রহণ করে
outputs
পূরণ করা হবে। - আপডেটগুলি সেই অনুযায়ী নতুন বাফার সূচকগুলির সাথে এসএবি বলেছে ।
- যদি আউটপুট এসএবি আন্ডারফ্লো থ্রেশহোল্ডের কাছাকাছি চলে যায় তবে আরও অডিও ডেটা রেন্ডার করতে কর্মীকে জাগিয়ে তুলুন।
-
- [ডিডাব্লুজিএস] কর্মী
AudioWorkletProcessor.process()
থেকে জাগ্রত সংকেতের জন্য অপেক্ষা করে (ঘুম)। যখন এটি জেগে ওঠে:- রাজ্য এসএবি থেকে বাফার সূচকগুলি আনতে পারে।
- আউটপুট এসএবি পূরণ করতে ইনপুট এসএবি থেকে ডেটা সহ প্রক্রিয়া ফাংশনটি চালান।
- আপডেটগুলি সেই অনুযায়ী বাফার সূচকগুলির সাথে এসএবি বলে ।
- ঘুমাতে যায় এবং পরবর্তী সিগন্যালের জন্য অপেক্ষা করুন।
উদাহরণ কোডটি এখানে পাওয়া যাবে, তবে নোট করুন যে এই ডেমোটি কাজ করার জন্য শারডারাইবফার পরীক্ষামূলক পতাকা অবশ্যই সক্ষম করতে হবে। কোডটি সরলতার জন্য খাঁটি জেএস কোডের সাথে লেখা হয়েছিল, তবে প্রয়োজনে এটি ওয়েবসেমি কোডের সাথে প্রতিস্থাপন করা যেতে পারে। এই জাতীয় কেসটি হ্যাপিডিওবফার ক্লাসের সাথে মেমরি ম্যানেজমেন্ট মোড়ক করে অতিরিক্ত যত্ন সহকারে পরিচালনা করা উচিত।
উপসংহার
অডিও ওয়ার্কলেটের চূড়ান্ত লক্ষ্য হ'ল ওয়েব অডিও এপিআইকে সত্যই "এক্সটেনসিবল" করা। অডিও ওয়ার্কলেটের সাথে বাকী ওয়েব অডিও এপিআই বাস্তবায়ন করা সম্ভব করার জন্য একটি বহু বছরের প্রচেষ্টা তার নকশায় গিয়েছিল। পরিবর্তে, এখন এর নকশায় আমাদের উচ্চতর জটিলতা রয়েছে এবং এটি একটি অপ্রত্যাশিত চ্যালেঞ্জ হতে পারে।
ভাগ্যক্রমে, এই জাতীয় জটিলতার কারণটি নিখুঁতভাবে বিকাশকারীদের ক্ষমতায়িত করা। অডিওওরকলেটগ্লোবালস্কোপে ওয়েবসেমি চালাতে সক্ষম হওয়ায় ওয়েবে উচ্চ-পারফরম্যান্স অডিও প্রসেসিংয়ের বিশাল সম্ভাবনা আনলক করে। সি বা সি ++ এ লিখিত বৃহত আকারের অডিও অ্যাপ্লিকেশনগুলির জন্য, শারডারাইবফার এবং কর্মীদের সাথে একটি অডিও ওয়ার্কলেট ব্যবহার করে অন্বেষণ করার জন্য আকর্ষণীয় বিকল্প হতে পারে।
ক্রেডিট
এই নিবন্ধটির একটি খসড়া পর্যালোচনা করার জন্য এবং অন্তর্দৃষ্টিপূর্ণ প্রতিক্রিয়া দেওয়ার জন্য ক্রিস উইলসন, জেসন মিলার, জোশুয়া বেল এবং রেমন্ড টয়কে বিশেষ ধন্যবাদ।