- بواسطة x32x01 ||
خلي بالك وانت بتستخدم Win APIs ⚠️
لو بتشتغل بـ Small Basic أو Small Visual Basic (sVB)، خصوصًا على ويندوز 64-بت، خليك صاحي شوية 😅فيه مشكلة subtle جدًا ممكن تلعب في النتيجة من غير ما تحس.
لو شغّلت الكود ده:
Code:
Sound.PlayMusic("C") لكن اللي بيحصل فعليًا على ويندوز 64-بت؟
النغمة بتطلع أوطى (Octave 0) 🤨
الغموض بدأ منين؟ 🎵🧩
وأنا بحاول أمنع تسرب قيم الأوكتاف بين القنوات الموسيقية، قررت أحقق في الموضوع.المفاجأة كانت إن مجرد استدعاء Native Win APIs لفتح جهاز MIDI وتحديد الآلة، بيغير قيم في الذاكرة ملهاش علاقة بالكود الحالي! 😬
يعني Memory Corruption كلاسيك.
السبب الحقيقي: تعريف غلط للـ Win API 💥
بعد ما الكود اتراجع (حتى Copilot ساعد هنا 👀)، اتضح إن المشكلة بسبب تعريف دوال winmm.dll بمعاملات غلط.التعريف الغلط (بيستخدم Integer بدل IntPtr):
Code:
<DllImport("winmm.dll")>
Public Shared Function midiOutOpen(
ByRef midiOut As Integer,
uDeviceID As Integer,
dwCallback As Integer,
dwCallbackInstance As Integer,
dwFlags As UInteger
) As Integer
End Function
<DllImport("winmm.dll")>
Public Shared Function midiOutShortMsg(
midiOut As Integer,
dwMsg As UInteger
) As Integer
End Function - Integer مش مناسب لعناوين الذاكرة
- وده بيكسر الدنيا على 64-بت
الحل الصح: استخدم IntPtr 🛠️
التعريف الصحيح اللي يحترم 32 و64-بت: Code:
<DllImport("winmm.dll")>
Public Shared Function midiOutOpen(
ByRef midiOut As IntPtr,
uDeviceID As UInteger,
dwCallback As IntPtr,
dwCallbackInstance As IntPtr,
dwFlags As UInteger
) As Integer
End Function
<DllImport("winmm.dll")>
Public Shared Function midiOutShortMsg(
midiOut As IntPtr,
dwMsg As UInteger
) As Integer
End Function ✅ مفيش Memory Corruption
✅ الأوكتاف يرجع طبيعي
✅ السلوك يبقى ثابت على كل الأنظمة
حل مشكلة تسرب الأوكتاف بين القنوات 🎼
غير إصلاح الـ API، اتعمل حل ذكي لمشكلة تسرب القيم الموسيقية، من غير ما نكسر التوافق مع الأكواد القديمة.الحل الأول: Sound.IsolateMusicChannels 🔒
خاصية جديدة:Sound.IsolateMusicChannels = Trueفايدتها:
- تمنع الرموز O > < L إنها تأثر على قنوات تانية
- كل قناة تبقى مستقلة
Falseعشان يفضل متوافق مع أكواد Small Basic القديمة.
الحل التاني: رموز جديدة للنوتة الحالية 🎶
بدل:- O للأوكتاف
- L للطول
- V للأوكتاف
- S للطول
✅ القيم تطبق على النوتة الحالية بس
❌ مفيش تسرب لقنوات تانية
جرّب بنفسك: مشروع Play Guitar 🎸
تقدر تجرب الخاصية الجديدة في مشروع Play Guitarالموجود ضمن أمثلة sVB:
📎 https://marketplace.visualstudio.com/items?itemName=ModernVBNET.sVBInstaller
المشروع ده لطيف جدًا، لأن:
- تسرب الأوكتاف كان عامل حوار موسيقي ظريف
- بين الجيتار وأصوات الـ oohs 😄
Sound.IsolateMusicChannels = False- وبعدين
True
الخلاصة 🧠
- Win APIs قوية… بس خطيرة لو اتعرفت غلط
- استخدام IntPtr مش رفاهية، ده ضرورة
- Memory Bugs ممكن تطلع بأشكال غريبة جدًا (زي نغمة واطية 😅)
- Audio
- MIDI
- Native APIs