مشكلة 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
المشاهدات
742
x32x01
x32x01
x32x01
الردود
0
المشاهدات
694
x32x01
x32x01
x32x01
الردود
0
المشاهدات
663
x32x01
x32x01
x32x01
الردود
0
المشاهدات
931
x32x01
x32x01
x32x01
الردود
0
المشاهدات
393
x32x01
x32x01
الوسوم : الوسوم
dllimport intptr memory corruption midi small basic small visual basic sound playmusic win api windows 64 bit winmm dll
الدخول أو التسجيل السريع
نسيت كلمة مرورك؟
إحصائيات المنتدى
المواضيع
2,320
المشاركات
2,533
أعضاء أكتب كود
567
أخر عضو
Mohaned
عودة
أعلى