Author Topic: MIDI-piano v2  (Read 3651 times)

0 Members and 1 Guest are viewing this topic.

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
MIDI-piano v2
« on: February 19, 2021, 12:24:41 pm »
Hello !
I made the midi piano program.
The keyboard map is adjustable. The sounds can be varied as desired for the keyboard.
Windows uses midi. By default, the gm.dls sound samples sound, but there are many nice midi sound samples available for download online that need to be installed on windows.



download:
https://drive.google.com/file/d/17hyvEQSaTlSGJmxrhMAqQgNiFi6HvpbB/view?usp=sharing

FellippeHeitor

  • Guest
Re: MIDI-piano v2
« Reply #1 on: February 19, 2021, 12:40:47 pm »
Sooooo cool! I knew you could use the API to play full midi files, but controlling each note is another level!

Thanks for another great contribution, MasterGy.

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: MIDI-piano v2
« Reply #2 on: February 19, 2021, 12:46:52 pm »
Woo hoo!  This looks great!  I had to see this just as i was about to leave home.  Cant wait to get back and try it out!

- Dav

Offline jakeh0916

  • Newbie
  • Posts: 9
    • View Profile
Re: MIDI-piano v2
« Reply #3 on: February 19, 2021, 12:55:44 pm »
Wow, this is great. Definitely gonna download and give this thing a whirl B-)

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: MIDI-piano v2
« Reply #4 on: February 19, 2021, 01:05:42 pm »
Looks great @MasterGy

The only thing I'd say is you might want to change the variable types of lphMidiOut and hMidiOut from LONG to _OFFSET since they are handles and handles are 4 bytes in 32 bit and 8 in 64. Also, midiOutGetNumDevs returns UINT, which is an _UNSIGNED LONG in QB64. Might be a good idea to change midiOutOpen to _UNSIGNED LONG as well since it returns an MMRESULT, which is an _UNSIGNED LONG in QB64. Same with midiOutClose and midiOutShortMsg. Right now all your functions are returning a signed SINGLE. I'm thinking you might also want a BYVAL before lphMidiOut, too. Otherwise, awesome!

EDIT:
Something else I saw in your code: midiOutGetNumDevs doesn't show to have any arguments on the MSDN. It should be declared as midiOutGetNumDevs~&() in your declare block
« Last Edit: February 19, 2021, 01:29:23 pm by SpriggsySpriggs »
Shuwatch!

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: MIDI-piano v2
« Reply #5 on: February 19, 2021, 02:11:00 pm »
Thank you for your answers ! I hope you have fun!
SpriggsySpriggs, I don't quite understand what kind of error you see. The variable types at the beginning of the program are taken care of by DEFLNG A-Z and work.
I don't understand your last paragraph either. What's your advice ? What would you fix over? And what problem are you solving?

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: MIDI-piano v2
« Reply #6 on: February 19, 2021, 02:16:36 pm »
@MasterGy
I'm simply talking about your declarations for your functions. While they may not error out they still should be declared properly.

This:
Code: QB64: [Select]
  1. Declare Dynamic Library "winmm" 'the way they are declared now is that all below functions are returning SIGNED SINGLEs
  2.     Function midiOutGetNumDevs (numdevs As Integer)
  3.     Function midiOutOpen (lphMidiOut As Long, Byval uDeviceID As Long, Byval dwCallback As Long, Byval dwInstance As Long, Byval dwFlags As Long)
  4.     Function midiOutClose (ByVal hMidiOut As Long)
  5.     Function midiOutShortMsg (ByVal hMidiOut As Long, Byval dwMsg As Long)

Should be this:
Code: QB64: [Select]
  1. Declare Dynamic Library "winmm" 'all below functions return _UNSIGNED LONGs (per the MSDN)
  2.     Function midiOutGetNumDevs~& () 'this function takes no arguments and should not have anything in it
  3.     Function midiOutOpen~& (ByVal lphMidiOut As _Offset, Byval uDeviceID As _Unsigned Long, Byval dwCallback As _Offset, Byval dwInstance As _Offset, Byval dwFlags As Long) 'dwCallback and dwInstance are both long pointers (offsets) as well as lphMidiOut
  4.     Function midiOutClose~& (ByVal hMidiOut As _Offset) 'hMidiOut is a handle and is 4 bytes in 32 bit and 8 bytes in 64. A long is only 4 bytes.
  5.     Function midiOutShortMsg~& (ByVal hMidiOut As _Offset, Byval dwMsg As Long) 'same here. Should be an _Offset so it will be 4 in 32 and 8 in 64

I found more than I initially said. DEFLNG doesn't take care of your functions. Besides, DEFLNG makes the variables SIGNED rather than _UNSIGNED anyways. Yes, your program might work just fine but it's better to have stuff defined correctly for future adaptations and edits. Everything I'm telling you about these functions comes from the MSDN:

https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutopen
https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutshortmsg
https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutclose
https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midioutgetnumdevs

How they are represented in WinAPI C/C++:
Code: C++: [Select]
  1. MMRESULT midiOutOpen(
  2.   LPHMIDIOUT phmo, //this is a long pointer which is an offset
  3.   UINT       uDeviceID, //uint translates to an unsigned long in QB64
  4.   DWORD_PTR  dwCallback, //DWORD_PTR means long pointer. A long pointer is an offset
  5.   DWORD_PTR  dwInstance, //DWORD_PTR means long pointer. A long pointer is an offset
  6.   DWORD      fdwOpen
  7. ); //MMRESULT is an unsigned long
  8.  
  9. MMRESULT midiOutShortMsg(
  10.   HMIDIOUT hmo, //this is a handle, which is an offset. A handle is 4 bytes in 32 bit and 8 in 64. So is an offset.
  11.   DWORD    dwMsg
  12. ); //this returns an unsigned long as well
  13.  
  14. MMRESULT midiOutClose(
  15.   HMIDIOUT hmo //a handle, which is an offset
  16. ); //returns an unsigned long
  17.  
  18. UINT midiOutGetNumDevs(); //takes no arguments and returns a UINT (unsigned long)
  19.  

Extra info about some basic variable translation can be found here:
https://www.qb64.org/wiki/Windows_Libraries
https://www.qb64.org/wiki/C_Libraries
« Last Edit: February 19, 2021, 02:54:55 pm by SpriggsySpriggs »
Shuwatch!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: MIDI-piano v2
« Reply #7 on: February 19, 2021, 09:26:40 pm »
The acoustics are better in SCREEN 0! Aside from that, anyway to post the code here, instead of that communist Google site?

Funny thing about how API lets you get away with various declarations. It stings you sometimes, but not always. My guess would be adding things in the future, with alternative declarations might be problematic, which I think Indy already covered.

What would be even cooler is this on a touch screen, if QB64 ever gets touchscreen support. Small BASIC has a bit of that, but this is one instance where phones are too small to be of any use. A surface, or other larger screen device you could pop in your lap and play, well, that would be interesting for instrumental apps.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: MIDI-piano v2
« Reply #8 on: February 19, 2021, 10:20:38 pm »
Funny thing about how API lets you get away with various declarations. It stings you sometimes, but not always. My guess would be adding things in the future, with alternative declarations might be problematic, which I think Indy already covered.
@Pete
Yes, with DLLs, there is some room to fudge but it's better to get in the habit of making sure everything is set correctly. Just because it works doesn't mean it will always work or that it is working correctly.
Shuwatch!

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: MIDI-piano v2
« Reply #9 on: February 20, 2021, 12:38:54 pm »
Hi SpriggsySpriggs! I rewrote the declaratory part at your suggestion. There may be something that escaped my attention, but so the program doesn’t start.

  [ You are not allowed to view this attachment ]  

About 6 years ago, I suffered from speaking MIDI from QB. I needed it because I came up with an algorithm that creates music in a mathematical way at the touch of a button, which I’ve already written about here. To do this, I had to solve this problem.


&t=317s

&t=324s
I remember that long ago, at the cost of great suffering, I managed to sound the midi. I also studied the microsoft links you provided and many example programs in different languages. I was already on the verge of madness because I didn’t understand why it didn’t work. Eventually, for some reason, I put in DEFLNG and was very happy that it was finally working. It finally worked and I didn’t care why. I needed its application, not the decoration.
Now, these days, I thought I was making a piano program, the well-functioning API connection written 6 years ago was already there, I built the piano interface for that.
Then I exposed it here and rewrote it at your suggestion, but it may work carelessly, and so it doesn’t, it works.
I ask that if you have time, rewrite the patch in the source code so that it works.

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: MIDI-piano v2
« Reply #10 on: February 20, 2021, 02:50:38 pm »
This works very nice, @MasterGy.  Good job.  The program is working for me.  Have you by any chance been able to connect a MIDI keyboard to your PC and play it with QB64 using API calls?  I've been trying to do that, by getting midiInStart and midiConnect API's to work, but it's not working yet.  I need to studying more on these.  I have some small PureBasic code I'm trying to port that works by calling these same API's.

Thanks for sharing your great work here.

- Dav

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: MIDI-piano v2
« Reply #11 on: February 20, 2021, 03:28:54 pm »
@Dav

Would it work with MIDI over USB? I have a MIDI keyboard and would be happy to assist you with this. I'd love it if you shared the code you have.
« Last Edit: February 20, 2021, 04:10:01 pm by SpriggsySpriggs »
Shuwatch!

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: MIDI-piano v2
« Reply #12 on: February 20, 2021, 04:23:08 pm »
@Dav
Would it work with MIDI over USB? I have a MIDI keyboard and would be happy to assist you with this. I'd love it if you shared the code you have.

Hey thanks, @SpriggsySprings!  Yes, I'm trying to do the same - MIDI over USB, using one of these.  It works using the purebasic code I found Here, I'm tryin to port that to QB64.

- Dav

« Last Edit: February 20, 2021, 04:24:22 pm by Dav »

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: MIDI-piano v2
« Reply #13 on: February 20, 2021, 04:53:37 pm »
I see that really the only hurdle here would be the callback function. We can just follow the pattern of what Michael Caulkins did with his callback function for the Win32 application demo. This will be a fun project to work on, @Dav
Shuwatch!

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: MIDI-piano v2
« Reply #14 on: February 20, 2021, 04:57:58 pm »
Thanks Dav! Find joy in it! Unfortunately, I can't help further combining MIDI. What I was dealing with is different.

http://tukorgravirozas.fw.hu/mastergy/5hang/index.html
http://tukorgravirozas.fw.hu/mastergy/algzene/index.html

(translate the website into your own language)
At the time, I was using dos-based qb4.5, I first built the midi connection on it, and ran it with dosbox. At the time, I switched to qb64 because I liked the speed and the windows compatibility. I think SpriggsySpriggs will be able to help with API stuff. The algorithm-music program is based on the same API as the piano program now.