Closed moshikosh closed 2 years ago
Hi Moshe, thank you for your observations. I agree with all of it.
Ports should be handled, not only devices, and it is something I'm planning to add, but haven't been able to find the time yet. Attaching info about the sender to incoming data, should not be too big of challenge to add, but I would prefer to do that at the same time as the device/port separation, as it will change the API.
Regarding timing, I have just created a new branch (timestamp) that I would like for you to try out. It supports message timestamps, in and outbound.
SendData now looks like
void sendData(Uint8List data, {int timestamp, String deviceId})
where you can optionally set a timestamp, and direct the message to a single device, defined by its id which you can get from the corresponding MidiDevice instance.
I haven't tested it thoroughly yet, but initial runs seems to work. If it works as intended, I'll merge it into master, but I would appreciate any help to test this.
Put this in your pubspec.yaml:
flutter_midi_command:
git:
url: https://github.com/InvisibleWrench/FlutterMidiCommand
ref: timestamp
Hi Morten,
Thank you for your quick response.
I will surely try the timestamp version, as it will help me a lot.
I will let you know how it works.
BTW, I have implemented the web version using an almost identical Dart API as yours.
I have not implemented it as a standard flutter plugin but it works fine.
If and when you want, I can forward you the dart and JS code so you can integrate it into your plugin.
Regards
Moshe
BTW, I have implemented the web version using an almost identical Dart API as yours. I have not implemented it as a standard flutter plugin but it works fine. If and when you want, I can forward you the dart and JS code so you can integrate it into your plugin.
I would very much like this. I have started work on a platform-package for dart/web, but I got stuck. I'm happy to incorporate your code if I can.
Thanks
Hi,
I checked the timestamp version. One very important issue that the data stream does not include the input device. Maybe you could add the device id to the midi packet. This way we could filtter out midi packets from specific devices.
Thanks Moshe
Working on it
@moshikosh have a look at the "ports" branch. It is a further development of the timestamp branch, which now lists and supports multiple entities and ports on every midi device.
I would appreciate any feedback before I merge the braking API changes into next release.
Hi @mortenboye Thank you for the new enhancements. These are very important ones.
to start with, I tested only the android version. it is working very well. I have few observations:
I wrote a general purpose plugin which includes the following 3 function:
class CStartupParams { static int m_pNativeInitNanoTime = 0; static int m_FlutterInitNanoTime = 0;
static int toFlutterNanoTime(int nativeNanoTime) { int diff = nativeNanoTime - CStartupParams.m_pNativeInitNanoTime; diff += CStartupParams.m_FlutterInitNanoTime; return diff; }
static int toNativeNanoTime(int flutterNanoTime) { int diff = flutterNanoTime - CStartupParams.m_FlutterInitNanoTime; diff += CStartupParams.m_pNativeInitNanoTime; return diff; }
static dynamic getStartupParams() async { var pParam = await FlutterMidiPlugin.startupParams; if (pParam != null && pParam["systemNanoTime"] != null) m_pNativeInitNanoTime = pParam["systemNanoTime"]; m_FlutterInitNanoTime = DateTime.now().microsecondsSinceEpoch * CConstsAndGlobals.NANOS_PER_MICROSECOND; return pParam; }
}
another issue is the inability to close specific ports on device. some times it is required to to redirect output to a different device than the input. currently, if I close a device, it closes all ports. for now, i manage it in the application level, so i do not close the device until i know that i need to close all ports. that forces me to filter out incoming packet from the unwanted device.
last issue is that we cannot to open a port immediately after connecting to the device, that forces the application to open a port in two steps. first open, what for the "deviceOpened " notifaction, get devices list, and check if the device is opened and then connect to the port.
i believe that all of this should be transparent to the application. actully, what i developed before started checking you plugin , is some code the opens all devices the list of devices includes only the opened ones. this way ' the application does need to connect to the device, and only open the ports it needs.
thats all for now
again, thank you Moshe
one more thing the plugin requires location services permissions, which cannot be acceptable by midi users. but the problem is that if the manifest does not include that permission, the plugin crashes.
I thank that there is no need to ask for COARSE location, it has no meaning in the context of midi devices.
thanks
The location permissions are required on Android to connect to Bluetooth (MIDI) devices.
did you try it without requesting location permission ? i know that users tend to not approve usage of location services. anyway, currently, i do not call startScan...
i will try later to remove the permission request and see if it works.
thanks
hi @mortenboye I managed to build and run successfully on iOS as well. it runs ok on macOS, but I am unable to build release mode. so in debug mode, macOS run ok as well.
Just bare in mind that the terminology for "input" and "output" ports is different on Android with respect to other platform.
while on iOS, macOS and Web, input means "from the device", on Android , it means "to the device".
this forced me to normalize the terminology in the application level.
you might consider to to "normalize" the directions within the plugin, this way the application will not have to worry about it.
besides that, it runs excellent and the performance is sufficient to my needs.
When you let me know that you are done with all changes, I will forward my implementation of the web interface. it is not written as a plugin. you may convert it into a plugin and incorporate it into your plugin.
if you want to know what I use it for, you can go to http://www.midiatorapp.com.
Thanks Moshe
Hi, First, thank you for the package, it helps a lot.
in the current version, you treat devices only and not ports. there might be devices that have only input or only output ports (like a metronome) also there might be a need to use different input and out put devices. currently, sending data will be forwarded to all opened devices, with the ability to target specific device or port. the same is true for input, all inputs from all connected devices are forwarded to the application and it cannot tell where the data came from.
the problem rises when used in MacOS where you try to send data to IAC driver, the data is echoed back to the application, so you cant tell if it came from a different device or just an echo of the sent data.
to conclude, I think there API should target specific ports and should include port info or handle on all operations.
another issue is with timing.
currently, there is no way to tell the time a midi message was received from the midi device (of course we can take the time from the computer or mobile device, but it is a higher level clock and not device driver clock), but it is not that a critical issue.
but when sending data, a very important element is to tell the device or the device driver, when to play the data.
currently, we have to time all sends through application level timers, these timers are very sensitive to every activity on the mobile or the computer. I know the the MIDI spec and the implementations of the drivers on the platforms, enable the developers to specify the time to play, but this option is exposed to the developer in your plugin.
I think that it will help a lot to add this parameter to the SendData API.
Thanks again Moshe