MidiMon 1.00, a USB MIDI app
Jean-Michel BRUCK (3009) 362 posts |
I did the same thing, the MidiMan application launches without error, but in the routing the input menu is on 2 lines and unreadable…. @Rick
I’m going to dig. Note when Rhapsody plays a score, it sends a MIDI_TxStop. I haven’t yet fully understood the relationship between the beat with or without Fastclock…
Lots of documents to interpret, (in English!!!) It’s easy to make a mistake. Google translate helps me well, but requires verification. For MIDI API I don’t know if you knew ESP, I use it with my RiscPC and I find that their approach to MIDI connections is very good, especially once you start to have some equipment. I would like to have the same principle for audio with RISC OS, (Alsa?) we could direct the sound to USB/internal and even SPDIF Back to MIDI and Rhapsody.
This is exactly what I’ve been doing for 5 years…another day |
Rick Murray (539) 13850 posts |
From political manifestos to end of term essays to deploying the server update… …I bet there are legions who would say those exact same words.
’tis okay. We all screw up from time to time. The trick is to screw up the little things and try to get the big things right.
There’s not really a relationship. It’s an either/or. MIDI beat – this happens, if I remember correctly, 24 times per crotchet (quarter note). Thus it depends upon the BPM, but if the pace is 90 BPM, the MIDI ticks will be running at 2,160 BPM, or about 36 per second. I think there’s a complicated interrelationship between that and the RISC OS sound system (re. TEMPO and BEATS etc in BASIC), but I’ve never really delved into that as my keyboard spews out beat messages. That’s one way of timing received notes. The other way is the fast clock. In this case, a counter increments every millisecond (or 1,000 times per second, just to put the MIDI beat into context) and when each MIDI message is received, it’s timestamped accordingly. This allows for far greater accuracy. There was, for a while, some code in my module that faked this by using the centisecond timer and multiplying it by ten, but now that is actually uses the high resolution timer, there’s no need for the fakery. But I think that code may be around still to act as a fallback in case the fast ticker can’t be accessed or isn’t present on the machine.
Shouldn’t bother mine either. It will just send a “stop” message to the MIDI device, and disable acting upon the MIDI beat events (though I’m not entirely sure if it should be doing that or if it should be left to IgnoreTiming to tell it to stop). The problem is that my module is not using the fast clock by default because the docs imply that one should call FastClock to turn it on. Clearly at some point this changed. But, then, I think the available MIDI user guide dates from something like 1988?
I knew of them, but didn’t do anything with music at that time, other than listening to it. The main push behind this, for me, is basically because “write a piece of music that isn’t complete crap” would be an entry on my bucket list if I bothered to write stuff like that down. I always thought I would, I got my piano many years ago and started messing with USB MIDI many years ago, but, you know, there’s always reasons why not to do something (like waiting a decade for MelIDI…) and when you’re 30-something there’s always later. Well, I’m approaching half a century which means that my “laters” may be somewhat restricted. I mean, if I get as many years as mom did, that means the millennium is further away than my demise. As to Acorn, RISC OS, the BBC Micro… To have as much life ahead as going back to when I got my Beeb, I’d need to make it to 87. Well, that was a bit darker than expected. I think my little inner goth is leaking out again. 🌘🦇🖤 Anyway, I’d like to create something. But, first, some software to try to make that happen. Therefore…… |
Rick Murray (539) 13850 posts |
Jean-Michel, here you go: https://heyrick.eu/blog/files/jmbmidi010.zip (~14K) The version is still 0.10, however it has a note in the module header that it’s a test version for you… *Help Modules [...] MIDI 0.10 (06 Sep 2023) USB MIDI [test build for Jean-Michel Bruck] [...] (and I note with mild annoyance that “SharedUnixLibrary” is too long so it messes up the formatting) It has been lightly tested as follows: 1. The MIDI beat timing hasn’t been tested at all, but it ought to default to being active, if that’s the sort of timing you want. 2. It defaults to FastClock timing. If you use the supplied “miditestZ” (don’t worry if your machine freezes, just press some keys on the piano, and Esc to quit), it’ll say something like: *miditestz 3 bytes: &90, 60, 58 648389 3 bytes: &90, 62, 64 648459 3 bytes: &90, 64, 67 648534 3 bytes: &90, 60, 0 648577 3 bytes: &90, 62, 0 648609 3 bytes: &90, 64, 0 648665 (just like Peter’s one) Which means: 3, Rhapsody semi-realtime input now works. (yay!) Full realtime still crashes, but that’s to be expected if there’s a bug there. Anyway, it’s a step forward. If this works well, and doesn’t mess up other stuff, then I’ll roll these changes into an official v0.11 release. Have fun! |
Jean-Michel BRUCK (3009) 362 posts |
Thanks Rick I found addendum sheets for the Acorn MIDI manual, tomorrow I will scan them to make them available. We are heading in the right direction… |
Rick Murray (539) 13850 posts |
Is it being recognised by the module?
|
Peter Everett (9846) 59 posts |
I’ve uploaded a corrected version of Midi Support (230906), all neat and tidy … I hope. |
Lauren Etc. (8147) 52 posts |
Just in time, I had just downloaded the previous version. Haha. I did get it to work with at least my cheap interface, and it works at least partially with MidiMon. Otherwise I’ve been busy so I haven’t had time to dig into it too deeply yet but hopefully will get to more of it tomorrow. |
Jean-Michel BRUCK (3009) 362 posts |
@Rick
yes,I do not know if I had specified, but I use a keyboard and expandeur therefore 2 ports. MIDI USB information: Timestamp type is Fast Clock MIDI Clock is 0 (Song Position = 0) Current TX channel is 0 (real channel 1 on real port 0). MIDI device (#0) is USB13, VID 0499, PID 170F, Manufacturer Yamaha Corporation Product Steinberg UR22mkII using IN file handle 214 Endpoint 5 Size 512, and OUT file handle 213 Endpoint 2 Size 512. number of cables 1. MIDI device (#1) is USB15, VID 0763, PID 3111, Manufacturer M-Audio Product Keystation Mini 32 MK3 using IN file handle 233 Endpoint 1 Size 64, and OUT file handle 217 Endpoint 2 Size 64. number of cables 1. Both devices are very well recognized and Fastclock is running and does not stop during capture. MidiUsbDebug MIDI USB debug information: RealTime -> RX? No RealTime ignore? No Ticker in use Yes RX interval 2 cs Clock stopped ? No Device #0: USB device "USB13", "Steinberg UR22mkII " IN file handle 214 OUT file handle 213 IN Endpoint 5 OUT Endpoint 2 IN size 512 OUT size 512 cables 1 Device #1: USB device "USB15", "Keystation Mini 32 MK3" IN file handle 233 OUT file handle 217 IN Endpoint 1 OUT Endpoint 2 IN size 64 OUT size 64 cables 1 RX interval is good It seems that the buffer is not filling? I added the two Acorn leaflets to my site, they are additions to the manuals. @Peter, I will test this version. |
Peter Everett (9846) 59 posts |
Jean-Michel, |
Rick Murray (539) 13850 posts |
Mixing and matching is a no-no at this point. Your modules, mine, ESPs… Best to reboot and start with a clean machine each time. |
Peter Everett (9846) 59 posts |
Absolutely, without a reboot it’s so easy to be misled, and mixing where there’s maybe no real need, or was no designed intention is interesting but… |
Jean-Michel BRUCK (3009) 362 posts |
You are both right, these are tests that I am doing to see what we have lost, it is a real shame that the sources are no longer available. In any case, congratulations for your work. After checking, the notes entered in SemiRealTime do not have the correct duration, so the timing in ms is not correct. |
Rick Murray (539) 13850 posts |
I would suggest that you look at how the score is set up. You might find the timing is correct if you change the tempo. So the question is – is the timing relationship correct? If you play, for example, a crotchet followed by two quavers, is the result a note followed by two notes half as long? I have noticed that the semi real time timing is way off, but it seems the note intervals are correct. So it looks like it’s just a translation issue.
No, the interpretation is not correct.
Fast Clock is milliseconds. Beat is something else and it depends upon the tempo. Briefly, 24 ticks (IIRC) per crotchet/quarter note. The rate of the crotchets depends upon the tempo 1. If 90 BPM, then 90 of them per minute. Multiply by 24 to get the MIDI beat. You can go through a long winded way of translating that into absolute time (it’ll be about every 28 ms for 90 BPM); but to be honest your best bet is to just stick with milliseconds. That does not change. Here’s a question to ponder. When you start a score in Rhapsody, there’s nothing. And unlike Maestro there’s no way to specify a tempo for the score (that I have found) except to manually add a tempo marker to the score. So what tempo is it running at when there is no marker? What’s the default tempo?
I’ve not looked at Peter’s stuff in much detail, but my assumption is that unlike my all-on-one module, his is split into parts. MTimer makes the high resolution timer available, USBMidi talks to the USB device, and MIDI gathers all the bits and presents an interface like the original Acorn API.
As long as something presents an interface like the Acorn MIDI module, it should work. I think the ESP plan was to split MIDI into parts in order to have specific drivers for podules, serial ports, softsynth, etc and allowing a fairly flexible degree of mix and match and rerouting; instead of trying to bung an ever increasing set of hardware devices into a single module. Mine supports rerouting now (thanks Ian!) via a new API (and an app supplied), but unlike previous incarnations (the Acorn ones), it is only intended to work with USB as that’s pretty much the only viable option on modern machines. Therefore it is all built into the one module. Anyway, as long as something provides the expected responses, Rhapsody ought to work just fine.
Clearly something got it’s knickers in a twist. It happens.
Debugging, stable, RISC OS. (just be glad it’s written in BASIC so you don’t have to contend with DDT where you get the joy of experiencing debugger bugs as well as your own bugs) 1 It is usual that tempo counts crotchets. But, music being a historical mishmash, the rule is “that but not always”. More at https://heyrick.eu/blog/index.php?diary=20230815 |
Rick Murray (539) 13850 posts |
I’ve dropped a dead simple MIDI tester program here: https://heyrick.eu/blog/files/simpletest.zip (1.67K) It will ask the MIDI module for the next bit of MIDI data, not caring what port is it coming from. If the module is receiving anything, it ought to show up. This program also sets bit 30 to the Init call, to demand that all system messages are placed into the receive buffer. So… it can be very chatty (depending on your keyboard). This is a snippet of my keyboard’s output when hammering the auto-drum machine button twice quickly. Port Bytes Data Time Annotation ---- ----- ----------- ------- -------------------------------------- 0 1 &F8 4901323 SysReal: Timing beat tick 0 1 &FA 4901336 SysReal: Start 0 1 &F8 4901346 SysReal: Timing beat tick (after 23ms) 0 3 &98, 51, 54 4901349 Note on (channel 9) 0 3 &98, 81, 27 4901349 Note on (channel 9) 0 3 &99, 35, 82 4901349 Note on (channel 10) 0 3 &99, 42, 84 4901349 Note on (channel 10) 0 1 &FE 4901352 SysReal: Active Sense 0 3 &98, 51, 0 4901354 Note off (channel 9) 0 3 &98, 81, 0 4901354 Note off (channel 9) 0 3 &99, 35, 0 4901354 Note off (channel 10) 0 3 &99, 42, 0 4901354 Note off (channel 10) 0 1 &F8 4901373 SysReal: Timing beat tick (after 27ms) 0 1 &F8 4901401 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901428 SysReal: Timing beat tick (after 27ms) 0 1 &F8 4901455 SysReal: Timing beat tick (after 27ms) 0 1 &F8 4901482 SysReal: Timing beat tick (after 27ms) 0 1 &F8 4901510 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901536 SysReal: Timing beat tick (after 26ms) 0 1 &FE 4901552 SysReal: Active Sense (after 200ms) 0 1 &F8 4901564 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901592 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901618 SysReal: Timing beat tick (after 26ms) 0 1 &F8 4901646 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901672 SysReal: Timing beat tick (after 26ms) 0 3 &98, 70, 36 4901675 Note on (channel 9) 0 3 &99, 42, 41 4901675 Note on (channel 10) 0 3 &98, 70, 0 4901680 Note off (channel 9) 0 3 &99, 42, 0 4901680 Note off (channel 10) 0 1 &F8 4901700 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901726 SysReal: Timing beat tick (after 26ms) 0 1 &FE 4901752 SysReal: Active Sense (after 200ms) 0 1 &F8 4901754 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901782 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901808 SysReal: Timing beat tick (after 26ms) 0 1 &F8 4901836 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901862 SysReal: Timing beat tick (after 26ms) 0 1 &F8 4901890 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901918 SysReal: Timing beat tick (after 28ms) 0 1 &FC 4901930 SysReal: Stop 0 1 &F8 4901944 SysReal: Timing beat tick (after 26ms) 0 1 &FE 4901952 SysReal: Active Sense (after 200ms) 0 1 &F8 4901972 SysReal: Timing beat tick (after 28ms) 0 1 &F8 4901998 SysReal: Timing beat tick (after 26ms) 0 1 &F8 4902026 SysReal: Timing beat tick (after 28ms) That lot spans about two thirds of a second. If you use this in a TaskWindow, use Zap (not Edit) and open it to full screen, or the redraws will go mental. Like I said, it’s very chatty. ;) |
Peter Everett (9846) 59 posts |
Pretty much spot on. The delay through the support system from when a note is received by USB to when MIDI puts it in the buffer that the user reads is far less than a ms. The quantisation due to USB’s frame and our 1ms timer will be of the order of a ms or so. @Jean-Michel I quickly added Rx timestamping by putting the current time in r1 within the read swi’s and the code has just stayed like that. Now this is plainly not correct because it adds the variable delay caused by polling etc. to the timestamp. I can change this to store the stamp when the data is received, not difficult. |
Jean-Michel BRUCK (3009) 362 posts |
@Rick I install Peter’s configuration and simplest receives fine (my keyboard only sends notes) @Peter,
For capturing Rhapsody simply checks in a loop, the RxCommands on all ports, and uses the note and timestamp data.
Can this correct the position of the first note?
I am testing with both configurations. We should achieve the same result. I think it’s time for me (not my ARMX6) to do a power off reset, see you tomorrow. |
Peter Everett (9846) 59 posts |
I doubt it. The issue with my code just introduces unecessary additional jitter. |
Rick Murray (539) 13850 posts |
<spits tea across the room> You have more faith in Rick than I do. ;) Seriously, though, thanks. But for your module, I can’t imagine the jitter would be more than a few millisecs, technically there but not exactly likely to make a difference. After all, serial MIDI itself only runs at 32-something kilobits, with each command one after the other, so some degree of jitter is inherent.
It’s rather interesting. Ports are open, so it’s finding the device, it just doesn’t seem to be getting any data from it.
? …but it’s me, Dave, and Ian who are responsible for this MIDI module. Maybe over the weekend I’ll see about making a debug version for you to try to uncover something about what may or may not be going on. Mais, alors, je va a un ville proche de moi cet dimanche pour un expo génial “il était un fois”, quand tout le monde sont habillés comme au tourne du siècle – et pour ça, on dire de le commencement du vingtième siècle, parce qu’au dernier fois actuellement c’était la célèbre Y2K…;) |
Peter Everett (9846) 59 posts |
Rick, |
Peter Everett (9846) 59 posts |
Something else I’ve just thought of. |
Rick Murray (539) 13850 posts |
So I should try dropping in endless wake-up calls? Seems a weird way of doing things.
I’m not sure it’s that configurable… but surely yours ought to be sending out periodic ActiveSense messages? |
Peter Everett (9846) 59 posts |
I don’t know what the best or correct way of doing this is. All I know is what I did made it work.
It just sends the notes. Active sense was for detecting if a DIN serial MIDI connection had been unplugged. It is not really required for USB connections. |
Colin (478) 2433 posts |
You could try putting usb_wakeuprx before emptying the buffer in UpCall_RXdataPresent. The idea of wakeuprx in the upcall is to queue a pending transfer that takes place when the current transfer which you are handling has finished so putting it before processing the buffer may help if the buffer manager is not playing fair – It’s such a complicated way of doing things. Is it possible that the midi device is returning transfers with 0 bytes – usually usb waits until there is data. I’ve seen I think it was an etherusb device which could be configured either way. If the device returns 0 bytes RXDataPresent will not be called. so the whole process stops. Then you are left with polling. Can I have an upcall from the callback handler instead and bypass the USB buffer altogether then I’d able to handle 0 byte transfers. |
Lauren Etc. (8147) 52 posts |
Just to break in real quick, it’s time for me to put on my dunce hat for the pitch bend issue earlier. There were two issues: |
Colin Ferris (399) 1818 posts |
Druck ages ago wrote for Red Squirrel a pass through for Internet SWIs to Window equivalents could the same done for USB? |