كيف تعمل مولدات الضوضاء الرقمية

الأساس: توليد الأرقام شبه العشوائية

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

أبسط PRNG مناسب للعمل الصوتي هو المولد الخطي المتطابق (LCG)، الذي يحسب كل قيمة كدالة خطية للقيمة السابقة، بالقياس لثابت كبير. رغم سرعته، لمولدات LCG نقاط ضعف معروفة: تُظهر ارتباطات بين العينات المتتالية يمكن أن تنتج عيوبًا مسموعة في إشارات الضوضاء. في نماذجي الأولية المبكرة، استخدمت LCG بسيطًا واستطعت سماع أنماط دورية خافتة في الإخراج عند الاستماع عبر سماعات رأس عالية الجودة.

للضوضاء بجودة الإنتاج، انتقلت إلى خوارزمية xorshift128+، وهي PRNG المستخدم داخليًا من قبل معظم محركات JavaScript لـ Math.random(). لديها فترة تبلغ 2 أس 128 ناقص 1، وخصائص إحصائية ممتازة، وتكلفة حسابية ضئيلة. النتيجة هي إشارة ضوضاء خالية من العيوب المسموعة، مع طيف مسطح مُتحقق منه في حدود 0.3 ديسيبل عبر النطاق المسموع.

من الأرقام العشوائية إلى عينات الصوت

مولد PRNG ينتج أرقامًا، لكن نظام الصوت يحتاج عينات شكل موجي بسعات ومعدلات أخذ عينات محددة. تتضمن عملية التحويل القياس وتشكيل التوزيع وإدارة المخزن المؤقت. في تطبيقي، يُخرج PRNG أعدادًا صحيحة 32 بت بدون إشارة، والتي أقوم بتطبيعها إلى قيم النقطة العائمة في نطاق سالب واحد إلى موجب واحد. هذا هو نطاق السعة القياسي للصوت الرقمي في Web Audio API.

توزيع القيم العشوائية مهم لطابع الضوضاء. التوزيع المنتظم، حيث جميع القيم في النطاق متساوية الاحتمال، ينتج ضوضاء ذات توزيع سعة مختلف قليلاً عن التوزيع الغاوسي الذي يميز الضوضاء الحرارية في الدوائر التناظرية. عمليًا، الفرق دقيق. لمعظم التطبيقات، التوزيع المنتظم مقبول تمامًا وأبسط حسابيًا.

عندما أحتاج ضوضاء موزعة غاوسيًا، أستخدم تحويل Box-Muller الذي يحول أزواجًا من الأرقام العشوائية الموزعة بشكل منتظم إلى أزواج من القيم الموزعة غاوسيًا. في اختبارات الاستماع، الفرق بين الضوضاء البيضاء المنتظمة والغاوسية شبه غير مسموع.

التشكيل الطيفي: تحويل الأبيض إلى ألوان

الضوضاء البيضاء هي المادة الخام التي تُنشأ منها جميع ألوان الضوضاء الأخرى. يتم التحويل من خلال الترشيح الرقمي. في محرك الضوضاء الخاص بي، أطبق التشكيل الطيفي باستخدام مرشحات IIR (استجابة نبضية لانهائية) وFIR (استجابة نبضية محدودة)، ولكل منهما مزايا مميزة.

للضوضاء الوردية (ميل سالب ثلاثة ديسيبل لكل أوكتاف)، أستخدم خوارزمية Voss-McCartney كطريقتي الأساسية. تحتفظ هذه الخوارزمية بمولدات أرقام عشوائية مستقلة متعددة تُحدَّث بمعدلات مختلفة. في تطبيقي، أستخدم 16 طبقة أوكتاف، مما يوفر تشكيلًا طيفيًا دقيقًا من أقل من 1 هرتز إلى أعلى من 20 كيلوهرتز.

للضوضاء البنية (ميل سالب ستة ديسيبل لكل أوكتاف)، أستخدم التكامل البسيط. التحدي مع هذا النهج هو انحراف التيار المستمر. أحل هذا بإضافة مرشح عالي التمرير لطيف جدًا من الدرجة الأولى عند 5 هرتز.

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

التوليد في الوقت الفعلي مع Web Audio API

توفر Web Audio API، المتاحة في جميع المتصفحات الحديثة، البنية التحتية لتوليد وتشغيل الضوضاء في الوقت الفعلي دون أي معالجة من جانب الخادم. في تطبيقي في WhiteNoise.top، أستخدم ثلاثة مكونات رئيسية من Web Audio API: AudioContext وAudioWorkletNode وBiquadFilterNode.

AudioWorkletNode هو المكان الذي يحدث فيه التوليد الأساسي. أسجل AudioWorkletProcessor مخصصًا يعمل على خيط منفصل عن خيط المتصفح الرئيسي، مما يضمن أن تفاعلات واجهة المستخدم لا تسبب خللاً في الصوت. تُستدعى طريقة process() للمعالج بشكل متكرر مع مخزن مؤقت للإخراج، عادة 128 عينة لكل استدعاء عند 44.1 كيلوهرتز. خط الأنابيب بأكمله يعمل في حوالي 0.01 ميلي ثانية لكل مخزن مؤقت على الأجهزة الحديثة.

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

أستخدم أيضًا BiquadFilterNode المدمج في Web Audio API للتشكيل الطيفي عندما يكون المرشح المطلوب من النوع القياسي. هذه العقد مطبقة في كود أصلي محسن، مما يجعلها أسرع بكثير من تطبيقات JavaScript المكافئة.

التحسينات والاعتبارات العملية

تحسين الأداء مصدر قلق مستمر في توليد الصوت في الوقت الفعلي. التقنية الأولى هي الحساب المسبق: للألوان التي لا تتغير ديناميكيًا، أولد مخزنًا مؤقتًا كبيرًا من الضوضاء (عادة 10 ثوانٍ) أثناء التهيئة وأكرره أثناء التشغيل. لمنع الحلقة من أن تكون مسموعة، أستخدم تلاشيًا متقاطعًا عند حدود الحلقة.

التحسين الثاني هو معالجة بنمط SIMD ضمن JavaScript. رغم أن JavaScript لا توفر تعليمات SIMD صريحة في سياق AudioWorklet، أهيكل حلقاتي الداخلية لمعالجة العينات في مجموعات من أربع. هذا النهج يعطي تسريعًا بنسبة 15 إلى 25 بالمائة.

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

استهلاك الطاقة اعتبار عملي آخر، خاصة للأجهزة المحمولة. أخفف من هذا بتقديم ميزة مؤقت توقف المولد بعد مدة محددة من المستخدم، وباستخدام Page Visibility API لإيقاف التوليد مؤقتًا عندما لا يكون تبويب المتصفح في المقدمة.

التحقق من جودة إخراج المولد

مولد الضوضاء جيد بقدر جودة إخراجه، ويجب التحقق من الجودة من خلال القياس الموضوعي. في عملية ضمان الجودة الخاصة بي، أشغل كل تكوين مولد عبر مجموعة اختبارات آلية قبل إصداره للمستخدمين.

الاختبار الأول هو التسطح الطيفي: ألتقط عينة مدتها 60 ثانية من الضوضاء البيضاء وأتحقق من أنه لا ينحرف أي حاوية تردد بأكثر من 1 ديسيبل عن المتوسط. الاختبار الثاني هو توزيع السعة باستخدام اختبار Kolmogorov-Smirnov. الاختبار الثالث هو كشف الدورية عبر دالة الارتباط الذاتي.

أخيرًا، أجري اختبارات استماع ذاتية بسماعات الرأس، للتحقق من النقرات والفرقعات والعيوب النغمية والتغيرات في المستوى أو الطابع على فترات تشغيل ممتدة. الاختبارات الآلية تلتقط معظم المشكلات، لكن الأذن البشرية تبقى الحكم النهائي لجودة الصوت.

المراجع

الأسئلة الشائعة

هل يمكن لمولد ضوضاء رقمي إنتاج إخراج عشوائي حقًا؟

لا. تستخدم مولدات الضوضاء الرقمية مولدات أرقام شبه عشوائية (PRNGs) تنتج تسلسلات حتمية. ومع ذلك، فإن PRNG المصمم جيدًا ينتج إخراجًا لا يمكن تمييزه إحصائيًا عن العشوائية الحقيقية لجميع التطبيقات الصوتية العملية.

لماذا يستخدم Web Audio API الـ AudioWorklet بدلاً من ScriptProcessorNode؟

يعمل AudioWorklet على خيط منفصل عن خيط المتصفح الرئيسي، مما يمنع عمليات واجهة المستخدم من التسبب في خلل الصوت. كان ScriptProcessorNode يعمل على الخيط الرئيسي وكان عرضة للانقطاعات. ScriptProcessorNode مهمل الآن.

ما الذي يسبب النقرات أو الفرقعات في مولد الضوضاء؟

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

كم من وحدة المعالجة المركزية يستخدم مولد الضوضاء؟

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

هل يمكنني تكرار عينة ضوضاء بدلاً من توليدها في الوقت الفعلي؟

نعم، لكنك تحتاج لتطبيق تلاشٍ متقاطع عند حدود الحلقة لمنع نقرة مسموعة. تلاشٍ متقاطع بمنحنى جيب التمام المرفوع بحوالي 4,096 عينة عند 44.1 كيلوهرتز ينشئ حلقة سلسة إدراكيًا.

Leo Chen

ليو تشين مطوّر أدوات ومهتم بالصوتيات، يركّز على بناء أدوات عملية للصوت والإنتاجية عبر الإنترنت.