-
Notifications
You must be signed in to change notification settings - Fork 20
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
use midi-types and reorg #10
Conversation
also hide members
should require less bounds checking
Very happy to integrate with a wider midi platform. One of my dreams of rust is that you can share the code everywhere, so happy to facilitate. Definitely okay with joining the org or handing key parts over to the org to maintain. Haven't read through the pr yet as it's a decent size, so will need to do this after work. |
@btrepp wondering if you've had a chance to look this over? |
Been a while, figured I'd ping here again.. @btrepp any thoughts? |
Hi Mate. I've had a look. Overall it's okay, it's a bit hard to grok with the re-org plus type changes. I'm also not sure why notes got deleted. I loved the ability to note have to think which number is what note. I think if you prefer to use u8's over the note enum, we should make the API be generic over kinds that have I get the intent for the simplification, but I think it's gone to far and remove some of the safety nets I had put in. |
Hey, thanks for taking a look!
I hear that RE
The notes got removed because the types that they represent now exist in the shared type crate.. as I suggested in the PR description, we could add those into the
I get that, I find that doing a lot of |
Thanks for being receptive. In an embedded context I actually move much more heavily to tryInto and types that are compiler verified. Its a pain to figure out via a remote debugger that you put cable number 20 and that's why everything falls over :). Happy to have some 'unsafe' variants that auto unwrap though. Which gives enough here be dragons. There could also be something with Trait bounds and const generics, e.g being able to use a const generic on the first 16 in cable number. I think we should explore use-ability as a seperate PR though. No worries on the shared types, I think that's why having a re-org and a change in lib made it a bit hard to read. Using types in a much more common crate I am infinitely supportive of, I only built my own due to there being none at the time. With the notes. The advantage was to make it a bit easier to transpose simple songs from sheet music. I do agree that it's a bit westernized, though I am personally not to familiar with other music systems running over midi. I think this could be another one for traits bounds on the functions. E.g changing to Into, which means use whatever system you want, it just needs to be within the bounds of midi. So to simplify,
That way it's also reasonably backwards compatible for anyone who is using this crate. |
Hi, I'm the other maintainer of the rust-midi crates. Hope its ok to chime in here.
I normally wholeheartedly agree with this. Especially in embedded contexts you dont want your code to panic because some value is out of bounds. I think the decision to be a bit looser with this here was originally mine. The conversions from and into u8 for channels etc. are primarily used parsing and serializing messages. I was repeatedly running into situations where the surrounding already provided all the guarantees needed that the values were inside the bounds that we expected for example channel numbers were parsed from a u8 by masking out the other 4 bits.
Maybe a good alternative would be to keep the note numbers as a |
I'm in kind of a crunch with my day job but I hope to get to this soon. |
Hi, I can't seem to get message sending to work on this PR. I took the receiving messages example and modified it to echo the note messages back. When trying to play a note with the PR, the LED lights up fine but no MIDI message is sent (at least according to my DAW). I'm using the RP2040 Feather BSP from rp-hal. Here's the code I tested for both this repo and the PR (I can send full files if needed): Original working codefn main() -> ! {
let mut pac = pac::Peripherals::take().unwrap();
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let clocks = init_clocks_and_plls(
XOSC_CRYSTAL_FREQ,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let sio = Sio::new(pac.SIO);
let pins = Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
let usb_bus = UsbBusAllocator::new(UsbBus::new(
pac.USBCTRL_REGS,
pac.USBCTRL_DPRAM,
clocks.usb_clock,
true,
&mut pac.RESETS,
));
let mut midi = MidiClass::new(&usb_bus, 1, 1).unwrap();
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x5e4))
.manufacturer("Rose")
.product("Microphone Buttons")
.serial_number("MBTN")
.device_class(1) // from: https://www.usb.org/defined-class-codes
.device_sub_class(3)
.build();
let button_1 = pins.d12.into_pull_down_input();
let led_1 = pins.d13.into_readable_output();
let mut pins = (button_1, led_1);
loop {
if !usb_dev.poll(&mut [&mut midi]) {
continue;
}
let mut buffer = [0; 64];
if let Ok(size) = midi.read(&mut buffer) {
let buffer_reader = MidiPacketBufferReader::new(&buffer, size);
for packet in buffer_reader.into_iter() {
if let Ok(packet) = packet {
match packet.message {
Message::NoteOn(channel, note, vel) => {
midi.send_message(UsbMidiEventPacket::from_midi(
CableNumber::Cable0,
Message::NoteOn(channel, note, vel),
))
.unwrap();
pins.1.set_high().unwrap();
}
Message::NoteOff(channel, note, vel) => {
midi.send_message(UsbMidiEventPacket::from_midi(
CableNumber::Cable0,
Message::NoteOff(channel, note, vel),
))
.unwrap();
pins.1.set_low().unwrap();
}
_ => {}
}
}
}
}
}
} Non-working code using PRfn main() -> ! {
let mut pac = pac::Peripherals::take().unwrap();
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let clocks = init_clocks_and_plls(
XOSC_CRYSTAL_FREQ,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let sio = Sio::new(pac.SIO);
let pins = Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
let usb_bus = UsbBusAllocator::new(UsbBus::new(
pac.USBCTRL_REGS,
pac.USBCTRL_DPRAM,
clocks.usb_clock,
true,
&mut pac.RESETS,
));
let mut midi = MidiClass::new(&usb_bus, 1, 1).unwrap();
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x5e4))
.manufacturer("Rose")
.product("Microphone Buttons")
.serial_number("MBTN")
.device_class(1) // from: https://www.usb.org/defined-class-codes
.device_sub_class(3)
.build();
let button_1 = pins.d12.into_pull_down_input();
let led_1 = pins.d13.into_readable_output();
let mut pins = (button_1, led_1);
loop {
if !usb_dev.poll(&mut [&mut midi]) {
continue;
}
let mut buffer = [0; 64];
if let Ok(size) = midi.read(&mut buffer) {
let buffer_reader = MidiPacketBufferReader::new(&buffer, size);
for packet in buffer_reader.into_iter() {
if let Ok(packet) = packet {
match packet.message() {
MidiMessage::NoteOn(channel, note, vel) => {
midi.send_message(UsbMidiEventPacket::new(
0,
MidiMessage::NoteOn(*channel, *note, *vel),
))
.unwrap();
pins.1.set_high().unwrap();
}
MidiMessage::NoteOff(channel, note, vel) => {
midi.send_message(UsbMidiEventPacket::new(
0,
MidiMessage::NoteOff(*channel, *note, *vel),
))
.unwrap();
pins.1.set_low().unwrap();
}
_ => {}
}
}
}
}
}
} |
... I'm not 100% why but I had to set |
For the weird stuff like device classes. Usb as a spec is special. You
really have to only say the specific things. I have found different os seem
to respond to edge cases differently.
I think if list yourself as xyz, you must respond to certain messages, or
the Os drops it. So might be why you need class none
…On Tue, 1 Nov 2022, 01:57 Alex Norman, ***@***.***> wrote:
Hi, I can't seem to get message sending to work on this PR. I took the
receiving messages example and modified it to echo the note messages back.
When trying to play a note with the PR, the LED lights up fine but no MIDI
message is sent (at least according to my DAW). I'm using the RP2040
Feather BSP from rp-hal. Here's the code I tested for both this repo and
the PR (I can send full files if needed):
...
I'm not 100% why but I had to set device_class to USB_CLASS_NONE and not
set device_sub_class at all to have reliable usb-midi pre/post this PR
with usbd-midi.. I see that that isn't what you're doing in your non
working code example...
—
Reply to this email directly, view it on GitHub
<#10 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACAGFOP3QH5BJV4S2TOXADWGACBPANCNFSM5YKODH2A>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Hi, just tried that and it didn't seem to affect anything. Sorry for taking a couple days, I'll turn on email notifications for this thread so if there's anything else you want me to try out let me know! |
simplified for #11 |
I'm using both usb and serial midi in a project so I wanted to share types between the two, embedded-midi uses a platform agnostic midi-types representation of midi messages and we've extracted parsing/rendering into midi-convert. I have a PR open to bring that into
embedded-midi
, just waiting on the author to get back from a trip.Anyways.. here is a Draft Request here as I've done a massive reorg of
usbd-midi
both to usemidi-convert
(and in turn,midi-types
) but also to simplify usingusbd-midi
as a library, I took some liberties with some things that I thought were a bit more complicated than needed to be..There are a few things we could bring back into
midi-types
that you all had inusbd-midi
for instance, constants forNote::C2
,Channel1
, default Controller number naming etc etc but I figured that is all doable later.Figured I'd see if you all were interested in this and also if so, maybe you'd want to join the
rust-midi
org at the same time..