Skip to content

Commit 69e1e1e

Browse files
authored
Merge pull request #21 from rust-embedded-community/next
Version 0.4.0
2 parents ab10d5b + 60e817b commit 69e1e1e

File tree

28 files changed

+955
-381
lines changed

28 files changed

+955
-381
lines changed

CHANGELOG.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,70 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## [0.4.0] - 2025-01-03
9+
10+
This release focuses on:
11+
12+
- Increased usability by simplifying the internal module structure.
13+
- Interfacing with third-party crates like `midi-types`.
14+
- Support for System Exclusive messages (SysEx).
15+
16+
**Important:**
17+
18+
- The `message` module containing the `Message` struct and related types is now gated behind the `message-types` feature. This feature is enabled by default.
19+
- The constants `USB_AUDIO_CLASS`, `USB_AUDIOCONTROL_SUBCLASS` and `USB_MIDISTREAMING_SUBCLASS` are now private to prevent them from being used in the device setup. Doing so would lead to incorrect enumeration on certain hosts (e.g. macOS).
20+
21+
### Added
22+
23+
- `UsbMidiEventPacket::cable_number` function.
24+
- `UsbMidiEventPacket::header` function.
25+
- `UsbMidiEventPacket::payload_bytes` function.
26+
- `UsbMidiEventPacket::as_raw_bytes` function.
27+
- `UsbMidiEventPacket::to_raw_bytes` function.
28+
- `UsbMidiEventPacket::try_from_payload_bytes` function.
29+
- `UsbMidiEventPacket::is_sysex` function.
30+
- `UsbMidiEventPacket::is_sysex_start` function.
31+
- `UsbMidiEventPacket::is_sysex_end` function.
32+
- `TryFrom<&UsbMidiEventPacket>` implementation for `Message` type.
33+
- `Message::into_packet` function.
34+
- `Message::code_index_number` function.
35+
- `CodeIndexNumber::try_from_payload` function.
36+
- `CodeIndexNumber::payload_size` function.
37+
- `CableNumber::Cable0` as default value.
38+
- `FromOverFlow<u8> for U4` implementation.
39+
- `FromClamped<u8> for U4` implementation.
40+
- Re-exports of common items in crate root.
41+
42+
### Changed
43+
44+
- Renamed `MidiClass` to `UsbMidiClass`.
45+
- Renamed `UsbMidiClass::send_message` function to `UsbMidiClass::send_packet`.
46+
- Renamed `midi_device` module to `class`.
47+
- Renamed `usb_midi` module to `packet` and moved it into crate root.
48+
- Renamed `midi_packet_reader` module to `reader`.
49+
- Renamed `MidiPacketBufferReader` to `UsbMidiPacketReader`.
50+
- Renamed `MidiPacketParsingError` to `UsbMidiEventPacketError`
51+
- Renamed `MidiReadError` to `UsbMidiReadError`
52+
- Moved `usb_midi_event_packet` code into parent `packet` module.
53+
- Moved `channel` and `notes` modules into `message` module.
54+
- Moved `message` module to crate root.
55+
- Moved `byte` submodules into `message::data` module.
56+
- Moved `from_traits` code into parent `data` module.
57+
- Consolidated separate `InvalidCableNumber` struct into `UsbMidiEventPacketError`.
58+
- Consolidated separate `InvalidCodeIndexNumber` struct into `UsbMidiEventPacketError`.
59+
- Converted `CodeIndexNumber` struct to enum.
60+
- Moved descriptor constants into class module and made them private.
61+
- Set edition to 2021.
62+
63+
### Removed
64+
65+
- `UsbMidiEventPacket::cable_number` field, use function instead.
66+
- `UsbMidiEventPacket::message` field, use `Message::try_from(&UsbMidiEventPacket)` instead.
67+
- `UsbMidiEventPacket::from_midi` function, use `Message::into_packet` instead.
68+
- `CodeIndexNumber::find_from_message` function, use `Message::code_index_number` instead.
69+
- `From<CableNumber> for U4` implementation.
70+
- `From<CodeIndexNumber> for U4` implementation.
71+
872
## [0.3.0] - 2024-05-27
973

1074
### Changed

Cargo.toml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
[package]
22
name = "usbd-midi"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
authors = [
55
"Beau Trepp <[email protected]>",
66
"Florian Jung <[email protected]>",
77
"Oliver Rockstedt <[email protected]>",
88
]
9-
edition = "2018"
9+
edition = "2021"
1010
description = "A USB MIDI implementation for usb-device."
1111
homepage = "https://github.com/rust-embedded-community/usbd-midi"
1212
repository = "https://github.com/rust-embedded-community/usbd-midi"
1313
license = "MIT"
1414
categories = ["no-std", "embedded", "hardware-support"]
1515
keywords = ["usb", "midi"]
1616

17+
[features]
18+
default = ["message-types"]
19+
message-types = ["dep:num_enum"]
20+
1721
[dependencies]
1822
usb-device = "0.3"
1923

2024
[dependencies.num_enum]
21-
version = "0.7.2"
25+
version = "0.7.3"
2226
default-features = false
27+
optional = true
2328

2429
[lints.rust]
2530
missing_docs = "warn"

README.md

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,31 @@ This crate requires the use of a HAL that implements the `usb-device` traits.
1212

1313
Turn on an LED as long as note C2 is pressed. The example only shows the hardware-independent parts.
1414

15-
```rust
15+
```rust ignore
1616
use usb_device::prelude::*;
1717
use usbd_midi::{
18-
data::{
19-
midi::{channel::Channel, message::Message, notes::Note},
20-
usb_midi::midi_packet_reader::MidiPacketBufferReader,
21-
},
22-
midi_device::MidiClass,
18+
message::{channel::Channel, notes::Note},
19+
Message,
20+
UsbMidiClass,
21+
UsbMidiPacketReader,
2322
};
2423

2524
// Prerequisites, must be setup according to the used board.
2625
let mut led = todo!(); // Must implement `embedded_hal::digital::OutputPin`.
2726
let usb_bus = todo!(); // Must be of type `usb_device::bus::UsbBusAllocator`.
2827

2928
// Create a MIDI class with 1 input and 1 output jack.
30-
let mut midi = MidiClass::new(&usb_bus, 1, 1).unwrap();
31-
32-
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x5e4))
33-
.device_class(0)
34-
.device_sub_class(0)
35-
.strings(&[StringDescriptors::default()
36-
.manufacturer("Music Company")
37-
.product("MIDI Device")
38-
.serial_number("12345678")])
39-
.unwrap()
40-
.build();
29+
let mut midi = UsbMidiClass::new(&usb_bus, 1, 1).unwrap();
30+
31+
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x5e4))
32+
.device_class(0)
33+
.device_sub_class(0)
34+
.strings(&[StringDescriptors::default()
35+
.manufacturer("Music Company")
36+
.product("MIDI Device")
37+
.serial_number("12345678")])
38+
.unwrap()
39+
.build();
4140

4241
loop {
4342
if !usb_dev.poll(&mut [&mut midi]) {
@@ -47,10 +46,10 @@ loop {
4746
let mut buffer = [0; 64];
4847

4948
if let Ok(size) = midi.read(&mut buffer) {
50-
let buffer_reader = MidiPacketBufferReader::new(&buffer, size);
51-
for packet in buffer_reader.into_iter() {
49+
let packet_reader = UsbMidiPacketReader::new(&buffer, size);
50+
for packet in packet_reader.into_iter() {
5251
if let Ok(packet) = packet {
53-
match packet.message {
52+
match Message::try_from(&packet).unwrap() {
5453
Message::NoteOn(Channel1, Note::C2, ..) => {
5554
led.set_low().unwrap();
5655
},
@@ -73,7 +72,7 @@ the `usb-device` crate:
7372

7473
Cargo.toml:
7574

76-
```
75+
```ignore
7776
usb-device = { version = ">=0.3.2", features = ["control-buffer-256"] }
7877
```
7978

examples/example-esp32s3/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ esp-backtrace = { version = "0.14.2", features = [
1313
esp-println = { version = "0.12.0", features = ["esp32s3", "log"] }
1414
usb-device = { version = "0.3.2", features = ["control-buffer-256"] }
1515
usbd-midi = { path = "../../" }
16+
midi-convert = "0.2.0"
17+
heapless = "0.8.0"

examples/example-esp32s3/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# ESP32-S3 Example
2+
3+
This example was developed and tested on an [ESP32-S3-DevKitC-1](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s3/esp32-s3-devkitc-1/index.html) using the [esp-hal crate](https://crates.io/crates/esp-hal).
4+
5+
It features:
6+
7+
- Sending and receiving of regular MIDI messages.
8+
- Sending and receiving of MIDI System Exclusive messages with buffering.
9+
- Conversion of USB MIDI packets from and to types provided by the [midi-types crate](https://crates.io/crates/midi-types).
10+
11+
It does not provide a fully production-ready setup, especially time-critical tasks like polling the USB bus in an interrupt and managing bus timeouts are out of scope of this example.
12+
13+
## Requirements
14+
15+
To build the example, an installed toolchain for the Xtensa target is required. Please refer to the [Rust on ESP book](https://docs.esp-rs.org/book/) for further instructions.
16+
17+
You can build the example by running:
18+
19+
cargo build --release
20+
21+
If [espflash](https://crates.io/crates/espflash) is installed, you can flash the example to the board and run it:
22+
23+
cargo run --release
24+
25+
## Functionality
26+
27+
- Incoming MIDI messages are logged to the console.
28+
- Pressing and releasing the *BOOT* button on the board sends MIDI messages.
29+
- A received *Device Inquiry* SysEx request is responded to the host.
30+
31+
Please note that all chosen vendor and product ids and names are just for demonstration purposes and should not be used with a real product.

0 commit comments

Comments
 (0)