دلتا المسار بوحدات ticks؛ وتحول قراءة الملف المدمجة الزمن بحسب أحداث السرعة. [1]
الخلاصة السريعة
- ملفنا مؤلف من مسار للسرعة ومسار لأربع نغمات؛ سجلنا ثمانية أحداث بدء وانتهاء.
- حددنا 480 ticks لكل ربع نوتة، وغيرنا السرعة عند الموضعين 720 و1440.
- استغرق أول 720 ticks مقدار 0.75 ثانية، والثاني 1.5، والثالث 0.375.
- جاء الحدث عند 960 ticks في الثانية 1.25؛ الحساب بسرعة البداية وحدها أعطى 1.0.
- طابقت قراءة الملف حساب المقاطع للأحداث الثمانية، وانتهى المثال عند 2.625 ثانية.
حدد ثلاث فترات في ملفك
اخترنا دقة 480، وأحداث سرعة عند 0 و720 و1440. قيمها بالتتابع 500000 و1000000 و250000. وضعنا أربع نغمات بأرقام 60، 64، 67، 62، ووزعنا بداياتها ونهاياتها بحيث تعبر بعض الفترات بين الأحداث حدود السرعة.
السرعة هنا بالميكروثانية لكل ربع نوتة، والدقة عدد ticks لهذا الربع. [1]
في أول مقطع من اختيارنا، 720 ÷ 480 = 1.5 ربع نوتة. زمنه 1.5 × 500000 ÷ 1000000 = 0.75 ثانية. المقطع الثاني له العدد نفسه من ticks، لكننا اخترنا له قيمة سرعة مضاعفة، فاستغرق 1.5 ثانية. الثالث أعطى 0.375 ثانية. مجموعها 0.75 + 1.5 + 0.375 = 2.625.
اكتب المسارين بفرق مستقل
شغل البرنامج في مجلد لا يحتوي midi-case مع مكتبة Mido. نفذناه على Python 3.12.14 وMido 1.3.3؛ صفحة الوثائق التي قرأناها تحمل 1.3.2. ينشئ البرنامج الملف ويحفظه ثم يعيد فتحه. الأرقام مؤلفة، ولم نرسل الأحداث إلى آلة موسيقية أو منفذ صوت.
from mido import MidiFile,MidiTrack,MetaMessage,Message
from pathlib import Path
out=Path("midi-case");out.mkdir()
m=MidiFile(type=1,ticks_per_beat=480)
tempos=MidiTrack();notes=MidiTrack()
m.tracks.extend([tempos,notes])
for dt,value in [(0,500000),(720,1000000),(720,250000)]:
tempos.append(MetaMessage("set_tempo",tempo=value,time=dt))
events=[(0,"note_on",60),(240,"note_off",60),
(480,"note_on",64),(960,"note_off",64),
(1200,"note_on",67),(1680,"note_off",67),
(1920,"note_on",62),(2160,"note_off",62)]
last=0
for tick,kind,note in events:
notes.append(Message(kind,note=note,velocity=64,time=tick-last))
last=tick
m.save(str(out/"tempo-case.mid"))
seconds=0
for msg in MidiFile(str(out/"tempo-case.mid")):
seconds+=msg.time
if not msg.is_meta:
print(msg.type,msg.note,seconds) [1]في مسار السرعة كتبنا الفروق 0، 720، 720؛ جمعها أعطى مواضعنا 0، 720، 1440. بدأ جمع مسار النغمات من صفر مستقل، وأعطى الفروق 0، 240، 240، 480، 240، 480، 240، 240. لم نضف أول فرق للنغمات إلى نهاية مسار السرعة؛ فحصنا كل قائمة كما حفظناها.
احسب حدثا يعبر الحد الأول
يقع بدء النغمة 64 عند 480، ونهايتها عند 960. بين هذين الموضعين 480 ticks، لكنهما ليسا داخل مقطع سرعة واحد في ملفنا. من 480 إلى 720 لدينا 240 عند القيمة الأولى، ثم 240 أخرى عند القيمة الثانية.
الجزء الأول يستغرق 240/480 × 0.5 = 0.25 ثانية، والثاني 240/480 × 1 = 0.5. إذن الفترة بين الحدثين 0.75 ثانية. بدأ الحدث الأول عند 0.5، فوصلت النهاية إلى 0.5 + 0.75 = 1.25. هذا هو السطر الرابع الذي طبعه البرنامج.
يمكن الوصول إلى النتيجة نفسها من بداية الملف: نحسب أول 720 ثم 240 من المقطع التالي، فنحصل على 0.75 + 0.5 = 1.25. استخدمنا الطريقين لفحص الحد الفاصل، ولم نضرب فرق 480 كله بقيمة واحدة.
طابق السجل بالأحداث الثمانية
أعدنا فتح المسارين وجمعنا فروقهما، ثم حسبنا الأزمنة بكسور دقيقة مستقلة عن أزمنة القراءة المدمجة. طابقت النواتج الثمانية الجدول. أبرزنا سطر 960 لأنه أول حدث نغمة بعد حد 720؛ حدث تغيير السرعة نفسه ليس واحدا من أحداث النغمات الثمانية.

في الطريق إلى 1680، جمعنا 0.75 و1.5 ثم زمن 240 من المقطع الأخير: 240/480 × 0.25 = 0.125. جاء الناتج 2.375 ثانية. وبالطريقة نفسها صار موضع 1920 عند 2.5، ثم 2160 عند 2.625.
اختبر الافتراض الثابت عمدا
حسبنا في ضابطنا كل موضع باستعمال قيمة البداية فقط. أعطى 960/480 × 0.5 = 1 بدلا من 1.25، وأعطى 2160/480 × 0.5 = 2.25 بدلا من 2.625. نجح هذا الضابط في الأحداث الثلاثة الأولى؛ لذلك لا تكفي مطابقة بداية الملف لاختبار خريطة السرعة كلها.
كل ما قسناه هنا قراءة ملف وحساب أزمنة أحداثه. لم نختبر تأخر التشغيل أو الأداء الحي، ولم نستنتج ميزانا أو عدد موازير من نغماتنا الأربع. احتفظ بمواضع تغييرات السرعة والأحداث ونتائج المقاطع في سجل واحد؛ عند اختلاف ثوانيك، ابدأ بالحد الذي دخلته الفترة قبل تغيير أرقام النغمات.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي وراجعته أدوات ذكاء اصطناعي. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
