Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ Demonstrates how to use the flutter_midi_command_web plugin.

## Getting Started

This project is a starting point for a Flutter application.
This example is intended to work with an Akai Fire midi-controller, but incoming midi events should be displayed for any midi controller, while the demonstration of sending midi data is Fire specific.

A few resources to get you started if this is your first Flutter project:

- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)

For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
Note: currently there is a bug with displaying the listview of available midi devices on app start, so you need to do a hot-reload in order to get the listview items ui to appear.
26 changes: 26 additions & 0 deletions example/lib/fire_midi.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
List<int> fireAllPads(int r, int g, int b) {
const sysexHeader = [
0xF0,
0x47,
0x7F,
0x43,
0x65,
0x02,
0x00, // mesg length - low byte
];
const sysexFooter = [
0xF7, // End of Exclusive
];
final allLeds = <int>[];
for (int idx = 0; idx < 64; idx++) {
final ledData = [
idx,
r,
g,
b,
];
allLeds.addAll(ledData);
}
final midiData = <int>[...sysexHeader, ...allLeds, ...sysexFooter];
return midiData;
}
8 changes: 8 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';

import 'package:flutter_midi_command/flutter_midi_command.dart';
import 'package:flutter_midi_command_web_example/fire_midi.dart';

void main() {
runApp(const MyApp());
Expand Down Expand Up @@ -76,6 +77,13 @@ class _MyAppState extends State<MyApp> {
}),
),
Text('Last midi: $lastMidiMesg'),
MaterialButton(
child: Text('FIRE ALL PADS OFF'),
onPressed: () {
print('send all off');
_midiCommand.sendData(
Uint8List.fromList(fireAllPads(0, 0, 0)));
})
],
);
})),
Expand Down
21 changes: 7 additions & 14 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,21 @@ packages:
path: "../../FlutterMidiCommand"
relative: true
source: path
version: "0.3.0"
version: "0.4.2"
flutter_midi_command_linux:
dependency: transitive
description:
path: "../../flutter_midi_command_linux"
relative: true
source: path
version: "0.2.0"
name: flutter_midi_command_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
flutter_midi_command_platform_interface:
dependency: transitive
description:
name: flutter_midi_command_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.4"
version: "0.4.0"
flutter_midi_command_web:
dependency: transitive
description:
Expand Down Expand Up @@ -120,7 +120,7 @@ packages:
name: js_bindings
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.5"
version: "0.0.6-dev"
matcher:
dependency: transitive
description:
Expand All @@ -142,13 +142,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
midi:
dependency: transitive
description:
name: midi
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.2"
path:
dependency: transitive
description:
Expand Down
35 changes: 25 additions & 10 deletions lib/flutter_midi_command_web.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:js_util' as js_util;
import 'dart:typed_data';

import 'package:flutter/foundation.dart';
Expand Down Expand Up @@ -41,8 +40,14 @@ class FlutterMidiCommandWeb extends MidiCommandPlatform {
.requestMIDIAccess(html.MIDIOptions(sysex: true, software: false));

// deal with bug: https://github.com/dart-lang/sdk/issues/33248
js_util.callMethod(access.inputs, 'forEach', [allowInterop(_getInputs)]);
js_util.callMethod(access.outputs, 'forEach', [allowInterop(_getOutputs)]);
// js_util.callMethod(access.inputs, 'forEach', [allowInterop(_getInputs)]);
// js_util.callMethod(access.outputs, 'forEach', [allowInterop(_getOutputs)]);
access.inputs.forEach((a, b, c) {
_getInputs(a, b, c);
});
access.outputs.forEach((a, b, c) {
_getOutputs(a, b, c);
});
}

void _getInputs(dynamic a, dynamic b, dynamic c) {
Expand Down Expand Up @@ -89,7 +94,8 @@ class FlutterMidiCommandWeb extends MidiCommandPlatform {

/// Connects to the device.
@override
void connectToDevice(MidiDevice device, {List<MidiPort>? ports}) {
Future<void> connectToDevice(MidiDevice device,
{List<MidiPort>? ports}) async {
// connect up incoming webmidi data to our rx stream of MidiPackets
final inputPorts = _webMidiInputs.where((p) => p.name == device.name);
for (var inport in inputPorts) {
Expand Down Expand Up @@ -122,18 +128,27 @@ class FlutterMidiCommandWeb extends MidiCommandPlatform {

@override
void teardown() {
//TODO: go through and call disconnect on all devics, then close rx stream
//TODO: go through and call disconnect on all devices, then close rx stream
}

/// Sends data to the currently connected device.wmidi hardware driver name
/// Sends data to the currently connected devices
///
/// Data is an UInt8List of individual MIDI command bytes.
@override
void sendData(Uint8List data, {int? timestamp, String? deviceId}) {
// _connectedDevices.values.forEach((device) {
// // print("send to $device");
// device.send(data, data.length);
// });
final outputPorts = <html.MIDIOutput>[];
_connectedDevices.forEach((device) {
outputPorts.addAll(_webMidiOutputs.where((p) => p.name == device.name));
});
print("send to devices: $data");
for (var outport in outputPorts) {
try {
outport.send(data, 1);
} catch (e, _) {
// currently bug in Dart-JS interop: https://github.com/flutter/flutter/issues/94945#issuecomment-1033596770
print('Flutter Bug: #94945 caught: $e');
}
}
}

/// Stream firing events whenever a midi package is received.
Expand Down
4 changes: 2 additions & 2 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ packages:
name: flutter_midi_command_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.4"
version: "0.4.0"
flutter_test:
dependency: "direct dev"
description: flutter
Expand All @@ -92,7 +92,7 @@ packages:
name: js_bindings
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.5"
version: "0.0.6-dev"
lints:
dependency: transitive
description:
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ dependencies:
sdk: flutter
flutter_web_plugins:
sdk: flutter
flutter_midi_command_platform_interface: ^0.3.2
flutter_midi_command_platform_interface: ^0.4.0
js: ^0.6.4
js_bindings: 0.0.5
js_bindings: 0.0.6-dev

dev_dependencies:
flutter_lints: ^1.0.0
Expand Down
18 changes: 1 addition & 17 deletions test/flutter_midi_command_web_test.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_midi_command_web/flutter_midi_command_web.dart';

void main() {
const MethodChannel channel = MethodChannel('flutter_midi_command_web');

TestWidgetsFlutterBinding.ensureInitialized();

setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async {
return '42';
});
});

tearDown(() {
channel.setMockMethodCallHandler(null);
});
//TODO
}