A Flutter plugin to send and receive MIDI

Overview

flutter_midi_command

A Flutter plugin for sending and receiving MIDI messages between Flutter and physical and virtual MIDI devices.

Wraps CoreMIDI/android.media.midi/ALSA in a thin dart/flutter layer. Supports

  • USB and BLE MIDI connections on Android
  • USB, network(session) and BLE MIDI connections on iOS and macOS.
  • ALSA Midi on Linux

To install

  • Make sure your project is created with Kotlin and Swift support.
  • Add flutter_midi_command: ^0.3.0 to your pubspec.yaml file.
  • In ios/Podfile uncomment and change the platform to 10.0 platform :ios, '10.0'
  • After building, Add a NSBluetoothAlwaysUsageDescription to info.plist in the generated Xcode project.
  • On Linux, make sure ALSA is installed.

Getting Started

This plugin is build using Swift and Kotlin on the native side, so make sure your project supports this.

Import flutter_midi_command

import 'package:flutter_midi_command/flutter_midi_command.dart';

  • Get a list of available MIDI devices by calling MidiCommand().devices which returns a list of MidiDevice
  • Start scanning for BLE MIDI devices by calling MidiCommand().startScanningForBluetoothDevices()
  • Connect to a specific MidiDevice by calling MidiCommand.connectToDevice(selectedDevice)
  • Stop scanning for BLE MIDI devices by calling MidiCommand().stopScanningForBluetoothDevices()
  • Disconnect from the current device by calling MidiCommand.disconnectDevice()
  • Listen for updates in the MIDI setup by subscribing to MidiCommand().onMidiSetupChanged
  • Listen for incoming MIDI messages on from the current device by subscribing to MidiCommand().onMidiDataReceived, after which the listener will recieve inbound MIDI messages as an UInt8List of variable length.
  • Send a MIDI message by calling MidiCommand.sendData(data), where data is an UInt8List of bytes following the MIDI spec.
  • Or use the various MidiCommand subtypes to send PC, CC, NoteOn and NoteOff messages.

See example folder for how to use.

For help getting started with Flutter, view our online documentation.

For help on editing plugin code, view the documentation.

Comments
  • Missing features

    Missing features

    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

    opened by moshikosh 11
  • Android example not working

    Android example not working

    I have tried the example v 0.3.7 on iOS and MACOS and it works fine.

    It fails to show any devices on Android. The app screen is empty with no devices listed. Using SDK 28 and 29 on android 10 on a real device and emulator.

    D/FlutterMIDICommand( 8881): tryToInitBT D/FlutterMIDICommand( 8881): Show rationale for Location D/FlutterMIDICommand( 8881): devices [Landroid.media.midi.MidiDeviceInfo;@62e62ae D/FlutterMIDICommand( 8881): list [] I/flutter ( 8881): Error showRationaleForPermission

    opened by systemcode 10
  • Bluetooth devices disappearing on iOS

    Bluetooth devices disappearing on iOS

    On iOS (Android is fine) a device will not show in the list of devices on list refresh.

    Device will initially show on connection using startScanningForBluetoothDevices, after connectToDevice and a successful connection, the device will disappear out of the list of available devices.

    Connected device will still function as if it is still connected, but is not longer in the list of devices.

    opened by jrmilholland 9
  • Allow to create virtual MIDI devices on iOS

    Allow to create virtual MIDI devices on iOS

    With this pull request, it is possible to create virtual MIDI devices on iOS. These virtual MIDI devices show up in other apps. Other apps can now send and receive MIDI to or from your own app using these virtual MIDI ports.

    While merging this pull request, please do the following steps:

    1. Merge my previous pull request to flutter_midi_command_platform_interface.git
    2. Edit pubspec.yaml and replace the references to

    Let me know if you have any questions.

    Gabriel

    opened by gatzsche 9
  • Wrong `timestamp` in iOS

    Wrong `timestamp` in iOS

    I checked the received MidiPacket.timestamp. Its range seems 0 to 255.

    But MIDI specification has 13 bit, so the range is 0 to 8192.


    I thought, https://github.com/InvisibleWrench/FlutterMidiCommand/blob/644dd94431eda60724f5ffda4103ac5e096dd263/ios/Classes/SwiftFlutterMidiCommandPlugin.swift#L1043 tsHigh type is UInt8. So we may cast it before shift operation. timestamp = UInt64(tsHigh) << 7 | UInt64(tsLow)

    Using: flutter_midi_command: 0.3.0 flutter: 2.0.4 Xcode: 12.4

    opened by noboru-i 7
  • In what unit the timestamp is for iOS?

    In what unit the timestamp is for iOS?

    Reading the iOS native MIDI docs, I found out the packet's timestamp is a value meant to be multiplied by some system factor.

    I figured maybe the MidiPacket already did that conversion so the timestamp would be at the same unit regardless of the platform. However, that does not seem to be the case.

    So, my question is: does the iOS timestamp need to be multiplied by a factor to be usable? How can I get that factor?

    opened by MikeFP 6
  • iOS app fails to launch

    iOS app fails to launch

    I was playing around with the example given and, in Android, it works fine but in iOS it does not even launch. I have simplified the sketch several times but the result remains the same. Moreover, I created a new project and just updated the xcode min iOS version to let the package work and included de package in the pubspec.yaml and then the flutter example app does not work anymore. Any idea on what could be happening?

    opened by pabolojo 6
  • Inferred type is String? but Any was expected.

    Inferred type is String? but Any was expected.

    Hello, first thanks for the package, very useful.

    I found a problem in the following code snippet(File: FlutterMidiCommandPlugin.kt, Line: 389, Column: 34).

    Error: Inferred type is String? but Any was expected.

    fun listOfDevices() : List<Map<String, Any>> {
        var list = mutableListOf<Map<String, Any>>()
    
        val devs:Array<MidiDeviceInfo> = midiManager.devices
        Log.d("FlutterMIDICommand", "devices $devs")
        devs.forEach { d -> list.add(mapOf(
                "name" to d.properties.getString(MidiDeviceInfo.PROPERTY_NAME),
                "id" to d.id.toString(),
                "type" to "native",
                "connected" to if (connectedDevices.contains(d.id.toString())) "true" else "false",
                "inputs" to listOfPorts(d.inputPortCount),
                "outputs" to listOfPorts(d.outputPortCount)
              )
        )}
    

    It must be something related to a kotlin update where the type Any is not used for null, but Any? works.

    Again, thanks for the package.

    opened by gsbruno 5
  • Network Session 1 missing

    Network Session 1 missing

    When calling MidiCommand.devices, I have always had "Network Session 1" in the list of devices but now "Network Session 1" is not found when running on ioS Simulator and Android Simulator as well as real iOS devices. This causes problems now because I cannot debug application which used that interface to connect to MIDI devices connected to the mac.

    Actual USB MIDI devices still appear as wellas Bluetooth devices.

    Using v0.2.4

    opened by systemcode 5
  • Does not build for macos deployment

    Does not build for macos deployment

    Trying to build example app to run on macos. Does not seem to work using 0.2.4 on macos

    Flutter (Channel dev, 1.24.0-6.0.pre, on Mac OS X 10.15.7, XCode 12.1

    [!] CocoaPods could not find compatible versions for pod "flutter_midi_command": In Podfile: flutter_midi_command (from Flutter/ephemeral/.symlinks/plugins/flutter_midi_command/macos)

    Specs satisfying the flutter_midi_command (from Flutter/ephemeral/.symlinks/plugins/flutter_midi_command/macos) dependency were found, but they required a higher minimum deployment target.

    opened by systemcode 5
  • android version > 6.0 can't use ble

    android version > 6.0 can't use ble

    When Android version is higher than 6.0, Bluetooth function cannot be called normally, and location permission is required

    
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    
    opened by ifredom 5
  • Potential android.media.midi bug sending SysEx over BLE

    Potential android.media.midi bug sending SysEx over BLE

    Reproduce:

    • connect BLE device
    • send data to that device
    • BLE SysEx data never gets to the device
    • All midi messages from the devices does in fact work

    Everything works over USB to the device, but not BLE.

    Hoping that what I've experienced is related to the android.media.midi bug described here. They mentioned on December 23rd that it's fixed and "will be available in a future build".

    This link above says less than 18 or 19 bytes should be working, but for me it's not. I tried breaking it up into chunks of 10 or less bytes.

    Every now and then, I'd say about 10% of the time I fresh open my app, I can send data and it does work. When it does work, the BLE midi device shows up twice in the list of devices. Very strange.

    opened by ragtimekeys 1
  • Missing plugin exception

    Missing plugin exception

    Not sure if this affects performance, but I have been getting crashalytics errors relating to a missing cancel method on Android. The errors only seem to be generated while the app is in the background and are as follows:

    MissingPluginException(No implementation found for method cancel on channel plugins.invisiblewrench.com/flutter_midi_command/rx_channel). Error thrown Instance of 'ZM'.

    opened by Jon-Salmon 1
  • android.permission.BLUETOOTH_SCAN needs to be approved by the user for Android12+

    android.permission.BLUETOOTH_SCAN needs to be approved by the user for Android12+

    When build with targetSdkVersion 31 and run on Android 12 the app crashes, after approving the location permissions by the user. The reason seems to be that the permission android.permission.BLUETOOTH_SCAN is not requested in FlutterMidiCommandPlugin at all.

    See android documentation for the changed requirements: https://developer.android.com/guide/topics/connectivity/bluetooth/permissions

    A workaround is to set targetSdkVersion of the app to a maximum of 30 (Android 11). Then the legacy layer avoid the app crash and the permissions are correctly handled.

    opened by JavaAdam 0
  • Not able to send MIDI messages to connect device

    Not able to send MIDI messages to connect device

    Hi everyone,

    I have made an app for my self designed for desktop and mobile.

    Works perfectly on desktop, but on iOS it am not able to send MIDI messages to my connected Bluetooth MIDI device.

    I can receive messages and display them, but cannot send them to the device.

    Have you experienced something similar?

    opened by PasqualeTotaro 0
  • Bluetooth connection between Android and MacOS -> No Midi device visible on Mac

    Bluetooth connection between Android and MacOS -> No Midi device visible on Mac

    Has anyone had luck using Bluetooth Midi with this package between an Android phone and Macos?

    Steps I have been following:

    1. Bluetooth pair phone to macbook
    2. open Audio Midi Setup on mac and enter bluetooth settings
    3. advertise bluetooth midi device
    4. open Flutter Midi Command example app on phone and search for bluetooth devices -> macbook is visible
    5. connect to macbook, which "appears" to be successful
    6. check midi monitor app and/or ableton for any midi devices -> None visible!

    if i run the example app in debug mode it will only show reoccuring onScanResult messages.

    Any tips? Could there be a connection bug that I could try and find in the example app or Kotlin code?

    edit: I dont have an iOS device to test it there. This comment is only regarding my Android experience.

    opened by anzbert 11
  • Bluetooth platform support should be optional

    Bluetooth platform support should be optional

    Currently there is no way for a platform plugin to indicate that it doesn't support bluetooth, so on Linux for example this causes the following exception:

    [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: UnimplementedError: get onBluetoothStateChanged has not been implemented.
    #0      MidiCommandPlatform.onBluetoothStateChanged
    package:flutter_midi_command_platform_interface/flutter_midi_command_platform_interface.dart:47
    #1      MidiCommand._listenToBluetoothState
    package:flutter_midi_command/flutter_midi_command.dart:49
    #2      new MidiCommand._
    package:flutter_midi_command/flutter_midi_command.dart:28
    #3      new MidiCommand
    package:flutter_midi_command/flutter_midi_command.dart:22
    

    Perhaps MidiCommandPlatform could have a boolean getter added that platforms could use to indicate whether or not they support bluetooth and then the code that setups the _onBluetoothStateChangedStreamSubscription stream could check that before attempting to listen to that stream?

    opened by maks 6
Owner
null
Send-a-msg - Send message to WhatsApp without saving number

Send A Message Send Message to Whatsapp without saving number ToDo add logging s

Sujal 3 Apr 3, 2022
Receive sharing photos, videos, text, URLs, or any other file types from another app.

Receive Sharing Files To Flutter App Through Other Apps Receive sharing photos, videos, text, URLs, or any other file types from another app. Visit :

Jaimil Patel 21 Dec 25, 2022
Arissendpushntfctns - Send Push notifications with Flutter and Firebase messaging II

Push notifications with Firebase messaging II Send push notifications on Android

Behruz Hurramov 6 Feb 11, 2022
Home app - A dynamic flutter app which can be used to generate alerts, set alarms and send sms or call someone

first_app A dynamic flutter app which can be used to generate alerts, set alarms

null 0 Apr 9, 2022
Flutter POS Printer - A library to discover printers, and send printer commands

Flutter POS Printer - A library to discover printers, and send printer commands

Nguyễn Đức Hiếu 2 Oct 5, 2022
Messenger is an instant messaging app & by using this you can send message to your friend and family virtually

⚡️ Flash Chat ⚡️ Our Goal ?? The objective of this project is to learn how to incorporate Firebase into our Flutter apps. We'll be using Firebase Clou

Prashant Kumar Singh 7 Dec 3, 2022
Messenger is an instant messaging app & by using this you can send message to your friend and family virtually

⚡️ Flash Chat ⚡️ Our Goal ?? The objective of this project is to learn how to incorporate Firebase into our Flutter apps. We'll be using Firebase Clou

Prashant Kumar Singh 7 Jun 19, 2022
Allows send emails from flutter using native platform functionality.

flutter_email_sender Allows send emails from flutter using native platform functionality. In android it opens default mail app via intent. In iOS MFMa

Tautvydas Šidlauskas 107 Jan 3, 2023
Send notification to flutter app using firebase messaging

Welcome Push Notification with Flutter & Firebase ⚠️ ⚠️ there is no google-services.json file attached in this project because of security issues, you

Dineth Siriwardana 1 Aug 28, 2022
Socket library for creating real-time multiplayer games. Based on TCP, with the ability to send messages over UDP (planned).

Game socket The library was published in early access and is not stable, as it is being developed in parallel with other solutions. English is not a n

Stanislav 10 Aug 10, 2022
Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.

Flutter permission_handler plugin The Flutter permission_handler plugin is build following the federated plugin architecture. A detailed explanation o

Baseflow 1.7k Dec 31, 2022
Unloc customizations of the Permission plugin for Flutter. This plugin provides an API to request and check permissions.

Flutter Permission handler Plugin A permissions plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check perm

Unloc 1 Nov 26, 2020
Klutter plugin makes it possible to write a Flutter plugin for both Android and iOS using Kotlin only.

The Klutter Framework makes it possible to write a Flutter plugin for both Android and iOS using Kotlin Multiplatform. Instead of writing platform spe

Gillian 33 Dec 18, 2022
A Flutter step_tracker plugin is collect information from user and display progress through a sequence of steps. this plugin also have privilege for fully customization from user side. like flipkart, amazon, myntra, meesho.

step_tracker plugin A Flutter step_tracker plugin is collect information from user and display progress through a sequence of steps. this plugin also

Roshan nahak 5 Oct 21, 2022
This is just the simplyfied Flutter Plugin use for one of the popular flutter plugin for social media login.

social_media_logins Flutter Plugin to login via Social Media Accounts. Available Social Media Logins: Facebook Google Apple Getting Started To use thi

Reymark Esponilla 3 Aug 24, 2022
Flutterbodydetection - A flutter plugin that uses MLKit on iOS/Android platforms to enable body pose and mask detection using Pose Detection and Selfie Segmentation APIs for both static images and live camera stream.

body_detection A flutter plugin that uses MLKit on iOS/Android platforms to enable body pose and mask detection using Pose Detection and Selfie Segmen

null 18 Dec 5, 2022
Flutter simple image crop - A simple and easy to use flutter plugin to crop image on iOS and Android

Image Zoom and Cropping plugin for Flutter A simple and easy used flutter plugin to crop image on iOS and Android. Installation Add simple_image_crop

null 97 Dec 14, 2021
Flutter blue plus - Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android and iOS

Introduction FlutterBluePlus is a bluetooth plugin for Flutter, a new app SDK to

null 141 Dec 22, 2022