Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for connecting to MIDI devices #199

Closed
ghost23 opened this issue Apr 5, 2021 · 8 comments · Fixed by #190
Closed

Support for connecting to MIDI devices #199

ghost23 opened this issue Apr 5, 2021 · 8 comments · Fixed by #190
Labels
enhancement New feature or request

Comments

@ghost23
Copy link

ghost23 commented Apr 5, 2021

Hello,

this is a feature request. I am interested in building a flutter app for Windows that can connect to midi devices and read data from them. I understand that the Win32 library has such functionality. It would be nice to have access to it through this flutter plugin.

Thank you 🙂

@timsneath
Copy link
Contributor

Yeah, check out the mciSendCommand function and similar. There's a simple example here: https://github.com/timsneath/win32/blob/dart2.13/example/midi.dart
(although note that this is from the Dart 2.13 development branch of this package, which requires you to be on the dev or master channel of Flutter at present).

Let me know if you're missing APIs and I can add them.

@ghost23
Copy link
Author

ghost23 commented Apr 6, 2021

I see. That is going in the right direction. If I see that correctly, those functions can be found here: https://github.com/timsneath/win32/blob/dart2.13/lib/src/winmm.dart

If I understand MCI correctly though, it is rather for playing midi files (so output only) rather than recording Midi Data.

So I think there are some methods missing for my usecase (which I took from here: https://docs.microsoft.com/en-us/windows/win32/multimedia/recording-midi-audio)

midiInGetNumDevs
midiInGetDevCaps
midiInOpen
midiInClose

midiInAddBuffer
midiInReset
midiInStart
midiInStop

I am actually not yet sure, if that's all I'd need, but so far it seems like it.

@timsneath timsneath linked a pull request Apr 6, 2021 that will close this issue
@timsneath
Copy link
Contributor

Hi @ghost23, thanks -- that's very useful. I've updated the development branch with these features. If you add a dependency to this package like this:

dependencies:
  win32:
    git: 
      url: https://github.com/timsneath/win32.git
      ref: dart2.13

you should be able to use this in your app. Please let me know if you're missing anything else, and I'll add it in for you.

When Dart 2.13 is released, I'll publish this as win32 2.1.0.

@ghost23
Copy link
Author

ghost23 commented Apr 7, 2021

Cool. I will try this on the weekend. Thank you for the quick replies!

@timsneath timsneath added the enhancement New feature or request label Apr 7, 2021
@ghost23
Copy link
Author

ghost23 commented Apr 10, 2021

Hi @timsneath .

So I finally got some time to test this. To speed things up, I found this quick example that shows how to use Win32 to read in MIDI Data from a device: https://gist.github.com/yoggy/1485181

In order to be sure that this actually works, I created a quick console app in Visual Studio and simply pasted in the code from the example. Started it while I had a Midi keyboard connected and tadaa, it worked.

So now I attempted at replicating this in a flutter app. I created this little test project: https://github.com/ghost23/windows_midi

There are some minor issues I was facing. Namely that some constants are missing like:

MIM_OPEN | Int32 | 961
MIM_CLOSE | Int32 | 962
MIM_DATA | Int32 | 963
MIM_LONGDATA | Int32 | 964
MIM_ERROR | Int32 | 965
MIM_LONGERROR | Int32 | 966
MIM_MOREDATA | Int32 | 972

CALLBACK_FUNCTION | Int32 | 196608

But that's not too much of a problem, one can find the values easily online.

When I run the app, I can connect to my MIDI device just fine.

You do this via:

final rv = midiInOpen(hMidiDevice, nMidiDeviceNum, pointer.address, 0, CALLBACK_FUNCTION);

(https://github.com/ghost23/windows_midi/blob/main/lib/main.dart#L133)

My problem now is that it seems I have setup the Pointer variable hMidiDevice wrong, but I have no idea, what to do differently. What happens is that if I try to use that variable later on in:

final rs = midiInStart(hMidiDevice.address);

(https://github.com/ghost23/windows_midi/blob/main/lib/main.dart#L142)

Then as a result I get the MMSYSERR_INVALHANDLE error, which indicates to me, the correct handle has not been stored in the Pointer variable hMidiDevice.

It is not that obvious to how to correctly port the original example into dart using your Win32 library, so I was hoping you might have an idea, what I might be doing wrong here?!

@ghost23
Copy link
Author

ghost23 commented Apr 10, 2021

Typical, just a few minutes after posting this I figured, instead of trying to call:

final rs = midiInStart(hMidiDevice.address);

perhaps I should rather call:

final rs = midiInStart(hMidiDevice.value);

Now I am one step further. midiInStart() now answers with MMSYSERR_NOERROR. Perfect.

But now as soon as I press a key on my Midi Keyboard I now get the error:

../../third_party/dart/runtime/vm/runtime_entry.cc: 3506: error: Cannot invoke native callback outside an isolate.
version=2.13.0-222.0.dev (dev) (Fri Apr 9 12:15:17 2021 -0700) on "windows_x64"
pid=17524, thread=416, isolate_group=(nil)(0000000000000000), isolate=(nil)(0000000000000000)
isolate_instructions=0, vm_instructions=7fff03edd1d0
  pc 0x00007fff03fbc202 fp 0x000000d789c7f460 FlutterDesktopGetDpiForMonitor+0x6056fb
-- End of DumpStackTrace
Lost connection to device.

Am I doing something wrong with my callback function?

@ghost23
Copy link
Author

ghost23 commented Apr 10, 2021

I wonder if this has something to do with it: dart-lang/sdk#40529 (comment)

@timsneath
Copy link
Contributor

Taking a brief look at the threading issue.

I've added the constants -- thanks for letting me know. Those things are always a nightmare to detect.

I've now merged the dart2.13 branch into main, so you can switch your pubspec.yaml to the following now to pick up the latest:

  win32:
    git: https://github.com/timsneath/win32.git

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants