مترونوم أونلاين (نقر الإيقاع)

مترونوم مجاني عبر الإنترنت بتوقيت دقيق على مستوى العينة، مع عدد إيقاعات قابل للتعديل لكل مقياس، ونبضة بصرية مُشدَّدة، وزر نقر لإيجاد أي BPM بالأذن.

229 مشاهدة

— / 4

انقر بإيقاع منتظم — يلزم نقرتان على الأقل

يستخدم مجدول الاستباق (look-ahead) الخاص بواجهة Web Audio API (AudioContext.currentTime) لتوقيت دقيق على مستوى العينة — وليس setInterval بسيطًا، لذا لا يحدث أي انحراف حتى مع الحمل الثقيل على الصفحة.

لماذا تنجرف معظم مترونومات المتصفح زمنيًا

الطريقة الواضحة لبناء مترونوم بلغة جافاسكريبت هي setInterval(playClick, 60000 / bpm). تعمل هذه الطريقة لبضع ثوانٍ — ثم تتوقف عن العمل بدقة. فدالة setInterval تضمن فقط أن الاستدعاء لن يُطلق قبل التأخير المطلوب، لكنها لا تضمن أبدًا مقدار التأخر الفعلي الذي قد يحدث. تشترك حلقة جافاسكريبت الرئيسية مع كل ما تقوم به الصفحة — تحديثات DOM، وحسابات التخطيط (layout)، وجمع القمامة (garbage collection) — وأي من هذه العمليات يمكن أن يؤخر مؤقتًا معلقًا بعشرات المللي ثانية. بالنسبة لمعظم كود الواجهة هذا التأخير غير مرئي؛ أما بالنسبة للمترونوم فهو قاتل، إذ إن نقرة متأخرة 40 مللي ثانية في هذا الإيقاع و10 مللي ثانية في التالي تنجرف بشكل مسموع بدلاً من أن تبدو "غير دقيقة" فحسب، مما يضلل فعليًا الموسيقي الذي يتدرب عليها.

يعتمد الموسيقيون على المترونوم تحديدًا لأن إدراك الإنسان للزمن الثابت غير موثوق بدون مرجع خارجي — وهذا هو صميم فكرة الجهاز منذ أن سجّل يوهان ميلزل (Johann Maelzel) براءة اختراع النسخة ذات الآلية الميكانيكية عام 1815. مترونوم برمجي ينجرف بنفسه يُبطل هذا الغرض تمامًا، والحل ليس مؤقتًا أذكى: فكل مؤقت في جافاسكريبت، بما في ذلك requestAnimationFrame، يشترك في نفس عنق الزجاجة الخاص بالحلقة الرئيسية. الحل الحقيقي هو التوقف تمامًا عن مطالبة جافاسكريبت بإنتاج الصوت في اللحظة الصحيحة بنفسها.

الجدولة الاستباقية: كيف يحافظ هذا المترونوم على دقته

تستخدم هذه الأداة النمط الذي عمّمه كريس ويلسون (Chris Wilson)، العضو السابق في فريق Web Audio بمتصفح جوجل كروم، في مقالته الشهيرة والمُستشهد بها كثيرًا "A Tale of Two Clocks": الفصل التام بين منطق الجدولة وتوقيت الصوت. يعمل AudioContext الخاص بواجهة Web Audio API على خيط صوتي (audio thread) مستقل بساعة دقيقة على مستوى العينة، تُعرض على جافاسكريبت باسم AudioContext.currentTime. عند استدعاء osc.start(t) بطابع زمني مستقبلي من تلك الساعة، يقوم محرك الصوت بتشغيله بدقة في اللحظة t، بغض النظر عمّا تفعله الحلقة الرئيسية في تلك اللحظة بالذات — فهي لم تكن بحاجة أبدًا إلى "الاستيقاظ" بدقة عند لحظة الإيقاع لتحقيق ذلك.

المهمة الوحيدة للحلقة الرئيسية هي مسك الدفاتر: كل حوالي 25 مللي ثانية، يتحقق مجدول من الإيقاعات الواقعة ضمن الـ100 مللي ثانية القادمة، ويستدعي osc.start() لكل منها بقيمة currentTime المستقبلية الدقيقة. وبما أن هذه الحلقة تحتاج فقط إلى أن تكون تقريبًا في الوقت المناسب، فإن التذبذب العادي لا يسبب أي مشكلة مسموعة — إذ يظل الصوت مجدولًا بدقة على مستوى العينة. كل نقرة عبارة عن دفعة أوسيليتور (oscillator) مدتها نحو 30 مللي ثانية، بنبرة أعلى في الإيقاع الأول من كل مقياس لإحداث تشديد مسموع، متزامنة مع نبضة بصرية مطابقة.

تحل ميزة "نقر الإيقاع" (Tap Tempo) مشكلة مختلفة: إيجاد BPM لموسيقى لا تملك نوتة مكتوبة لقراءته منها. انقر بتزامن مع الإيقاع؛ تقيس الأداة الفاصل الزمني بين النقرات وتحوّله باستخدام 60000 / averageIntervalMs. يلزم نقرتان على الأقل، وحساب متوسط النقرات الأخيرة يخفف من أخطاء التوقيت الصغيرة. أي فجوة تتجاوز ثانيتين تعيد ضبط التسلسل، لأن ذلك يعني غالبًا أن الإيقاع قد فُقد بدلاً من أنه تباطأ بشكل كبير.

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

لماذا يبدو مترونوم setInterval البسيط غير منتظم مع مرور الوقت؟

تَعِد دالة setInterval فقط بأن الاستدعاء لن يُطلق قبل التأخير المطلوب — لكنه قد يُطلق لاحقًا كلما كانت الحلقة الرئيسية مشغولة بحسابات التخطيط، أو جمع القمامة، أو أي نشاط آخر في التبويب. تتراكم هذه التأخيرات الصغيرة وغير المنتظمة إيقاعًا بعد إيقاع، فتنجرف النقرة بشكل مسموع بدلاً من أن تبقى مقفلة على الإيقاع. تتجنب هذه الأداة ذلك بتفويض التوقيت الفعلي للصوت إلى ساعة الخيط الصوتي الخاصة بواجهة Web Audio API نفسها، بدلاً من الاعتماد على إطلاق مؤقت جافاسكريبت في اللحظة الصحيحة.

ما هي "الجدولة الاستباقية" ولماذا تحل مشكلة الانجراف؟

هو نمط لا تحاول فيه جافاسكريبت مطلقًا تشغيل صوت في اللحظة المستحقة بالضبط. تتحقق حلقة كل نحو 25 مللي ثانية مما إذا كانت هناك إيقاعات تقع ضمن الـ100 مللي ثانية القادمة، وتُجدول مسبقًا أوسيليتور لكل منها باستخدام AudioContext.currentTime بالإضافة إلى الإزاحة الدقيقة، عبر osc.start(الوقت_المستقبلي_الدقيق). يُطلق محرك الصوت هذا الأوسيليتور بدقة على مستوى العينة على خيطه الخاص، بمعزل عن الحلقة الرئيسية — لذا يمكن لحلقة الجدولة أن تكون غير دقيقة بينما يبقى الإيقاع الفعلي دقيقًا تمامًا.

كيف تحسب ميزة نقر الإيقاع قيمة BPM؟

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

لماذا يكون الإيقاع الأول من كل مقياس بنبرة مختلفة؟

هذا تشديد (accent) معياري في المترونومات الميكانيكية والرقمية على حد سواء: يُعزف الإيقاع الأول (downbeat) بتردد أعلى من بقية الإيقاعات، ويقترن بنبضة بصرية بلون مختلف. يتيح ذلك معرفة أين يقع "الإيقاع الأول" في نمط 3/4 أو 6/8 بنظرة واحدة أو بالأذن، وهو أمر مهم لعدّ المقاييس بشكل صحيح، خصوصًا في توقيعات زمنية قد تبدو فيها كل الإيقاعات متطابقة لولا ذلك.

ما نطاق BPM الذي يغطيه هذا المترونوم، وماذا يعني BPM؟

BPM تعني عدد الإيقاعات في الدقيقة (beats per minute) — أي عدد النبضات التي تحدث في ستين ثانية. تدعم هذه الأداة نطاقًا من 30 إلى 300 BPM، مما يغطي النطاق الكامل المستخدم في الموسيقى المكتوبة: تقع علامة Grave حول 25-45 BPM، وإيقاع المشي Andante حول 76-108، بينما يمكن أن تتجاوز مقاطع Presto 200 BPM. القيمة الافتراضية هي 120 BPM لأنها إيقاع تدريب شائع ومريح، وهي أيضًا العلامة الكلاسيكية لـ Moderato.

التعليقات

لا توجد تعليقات بعد — كن أول من يكتب تعليقًا!

أدوات مشابهة