مشكلة Win API و MIDI على ويندوز 64 بت

x32x01
  • بواسطة x32x01 ||

خلي بالك وانت بتستخدم Win APIs ⚠️

لو بتشتغل بـ Small Basic أو Small Visual Basic (sVB)، خصوصًا على ويندوز 64-بت، خليك صاحي شوية 😅
فيه مشكلة subtle جدًا ممكن تلعب في النتيجة من غير ما تحس.
لو شغّلت الكود ده:
Code:
Sound.PlayMusic("C")
المفروض النغمة C تتعزف على الأوكتاف الافتراضي 4
لكن اللي بيحصل فعليًا على ويندوز 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
راجع تعريفاتك كويس عشان Bug صغير ممكن يدوّرك كتير 🔁
 
المواضيع ذات الصلة
x32x01
الردود
0
المشاهدات
313
x32x01
x32x01
x32x01
الردود
0
المشاهدات
116
x32x01
x32x01
x32x01
الردود
0
المشاهدات
749
x32x01
x32x01
x32x01
الردود
0
المشاهدات
706
x32x01
x32x01
x32x01
الردود
0
المشاهدات
777
x32x01
x32x01
الدخول أو التسجيل السريع
نسيت كلمة مرورك؟
إحصائيات المنتدى
المواضيع
2,135
المشاركات
2,343
أعضاء أكتب كود
525
أخر عضو
sadoki
عودة
أعلى